@jingyi0605/codingns4dsh 0.2.1-beta.7 → 0.2.1-beta.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.en.md +3 -3
- package/README.md +9 -3
- package/data/build/dist/bootstrap/dsh-peer-host-preboot-shim.d.ts.map +1 -1
- package/data/build/dist/bootstrap/dsh-peer-host-preboot-shim.js +26 -1
- package/data/build/dist/bootstrap/dsh-peer-host-preboot-shim.js.map +1 -1
- package/data/build/dist/client/account-bar.d.ts.map +1 -1
- package/data/build/dist/client/account-bar.js +33 -21
- package/data/build/dist/client/account-bar.js.map +1 -1
- package/data/build/dist/client/avatar/desktop-bridge.js +1 -1
- package/data/build/dist/client/avatar/desktop-bridge.js.map +1 -1
- package/data/build/dist/client/avatar/desktop-view.d.ts +6 -2
- package/data/build/dist/client/avatar/desktop-view.d.ts.map +1 -1
- package/data/build/dist/client/avatar/desktop-view.js +48 -13
- package/data/build/dist/client/avatar/desktop-view.js.map +1 -1
- package/data/build/dist/client/avatar/floating.d.ts +5 -2
- package/data/build/dist/client/avatar/floating.d.ts.map +1 -1
- package/data/build/dist/client/avatar/floating.js +16 -5
- package/data/build/dist/client/avatar/floating.js.map +1 -1
- package/data/build/dist/client/avatar/notification-bubble.d.ts +24 -5
- package/data/build/dist/client/avatar/notification-bubble.d.ts.map +1 -1
- package/data/build/dist/client/avatar/notification-bubble.js +253 -66
- package/data/build/dist/client/avatar/notification-bubble.js.map +1 -1
- package/data/build/dist/client/avatar/notification-surface.d.ts +16 -0
- package/data/build/dist/client/avatar/notification-surface.d.ts.map +1 -0
- package/data/build/dist/client/avatar/notification-surface.js +54 -0
- package/data/build/dist/client/avatar/notification-surface.js.map +1 -0
- package/data/build/dist/client/avatar/reaction-badge.d.ts.map +1 -1
- package/data/build/dist/client/avatar/reaction-badge.js +11 -2
- package/data/build/dist/client/avatar/reaction-badge.js.map +1 -1
- package/data/build/dist/client/bundle.js +2628 -566
- package/data/build/dist/client/bundle.js.map +1 -1
- package/data/build/dist/client/cli-slots.d.ts.map +1 -1
- package/data/build/dist/client/cli-slots.js +26 -2
- package/data/build/dist/client/cli-slots.js.map +1 -1
- package/data/build/dist/client/client.assistant-notifications.js.map +1 -1
- package/data/build/dist/client/client.assistant-workbench.js +235 -109
- package/data/build/dist/client/client.assistant-workbench.js.map +1 -1
- package/data/build/dist/client/client.delegate-command.js +6 -6
- package/data/build/dist/client/client.delegate-command.js.map +1 -1
- package/data/build/dist/client/client.manager.js +46 -9
- package/data/build/dist/client/client.manager.js.map +1 -1
- package/data/build/dist/client/client.native-workspace-store.js +39 -3
- package/data/build/dist/client/client.native-workspace-store.js.map +1 -1
- package/data/build/dist/client/client.session-translation.js +54 -0
- package/data/build/dist/client/client.session-translation.js.map +1 -0
- package/data/build/dist/client/client.theme.js +2 -0
- package/data/build/dist/client/client.theme.js.map +1 -1
- package/data/build/dist/client/client.transport.js +123 -11
- package/data/build/dist/client/client.transport.js.map +1 -1
- package/data/build/dist/client/desktop-assistant.js +57927 -387
- package/data/build/dist/client/features/assistant-conversation-message.d.ts +2 -1
- package/data/build/dist/client/features/assistant-conversation-message.d.ts.map +1 -1
- package/data/build/dist/client/features/assistant-conversation-message.js +59 -24
- package/data/build/dist/client/features/assistant-conversation-message.js.map +1 -1
- package/data/build/dist/client/features/assistant-notification-store.d.ts +8 -2
- package/data/build/dist/client/features/assistant-notification-store.d.ts.map +1 -1
- package/data/build/dist/client/features/assistant-notification-store.js +45 -1
- package/data/build/dist/client/features/assistant-notification-store.js.map +1 -1
- package/data/build/dist/client/features/assistant-record-style.js +11 -4
- package/data/build/dist/client/features/assistant-record-style.js.map +1 -1
- package/data/build/dist/client/features/assistant-workbench.d.ts +4 -0
- package/data/build/dist/client/features/assistant-workbench.d.ts.map +1 -1
- package/data/build/dist/client/features/assistant-workbench.js +27 -1
- package/data/build/dist/client/features/assistant-workbench.js.map +1 -1
- package/data/build/dist/client/features/global-voice-assistant.d.ts.map +1 -1
- package/data/build/dist/client/features/global-voice-assistant.js +46 -8
- package/data/build/dist/client/features/global-voice-assistant.js.map +1 -1
- package/data/build/dist/client/features/index.d.ts +1 -0
- package/data/build/dist/client/features/index.d.ts.map +1 -1
- package/data/build/dist/client/features/index.js +3 -0
- package/data/build/dist/client/features/index.js.map +1 -1
- package/data/build/dist/client/features/peer-host.d.ts.map +1 -1
- package/data/build/dist/client/features/peer-host.js +130 -17
- package/data/build/dist/client/features/peer-host.js.map +1 -1
- package/data/build/dist/client/features/session-translation.d.ts +3 -0
- package/data/build/dist/client/features/session-translation.d.ts.map +1 -0
- package/data/build/dist/client/features/session-translation.js +116 -0
- package/data/build/dist/client/features/session-translation.js.map +1 -0
- package/data/build/dist/client/index.d.ts.map +1 -1
- package/data/build/dist/client/index.js +6 -1
- package/data/build/dist/client/index.js.map +1 -1
- package/data/build/dist/client/locales/assistantWorkbench.d.ts +17 -3
- package/data/build/dist/client/locales/assistantWorkbench.d.ts.map +1 -1
- package/data/build/dist/client/locales/assistantWorkbench.js +15 -11
- package/data/build/dist/client/locales/assistantWorkbench.js.map +1 -1
- package/data/build/dist/client/locales/panels.d.ts.map +1 -1
- package/data/build/dist/client/locales/panels.js +62 -0
- package/data/build/dist/client/locales/panels.js.map +1 -1
- package/data/build/dist/client/peer-host-native-projection.d.ts +4 -0
- package/data/build/dist/client/peer-host-native-projection.d.ts.map +1 -1
- package/data/build/dist/client/peer-host-native-projection.js +40 -1
- package/data/build/dist/client/peer-host-native-projection.js.map +1 -1
- package/data/build/dist/client/peer-host-remote-events.d.ts +14 -0
- package/data/build/dist/client/peer-host-remote-events.d.ts.map +1 -1
- package/data/build/dist/client/peer-host-remote-events.js +92 -3
- package/data/build/dist/client/peer-host-remote-events.js.map +1 -1
- package/data/build/dist/client/session-file-links.d.ts +11 -0
- package/data/build/dist/client/session-file-links.d.ts.map +1 -0
- package/data/build/dist/client/{peer-host-file-links.js → session-file-links.js} +13 -3
- package/data/build/dist/client/session-file-links.js.map +1 -0
- package/data/build/dist/client/session-translation-chat.d.ts +6 -0
- package/data/build/dist/client/session-translation-chat.d.ts.map +1 -0
- package/data/build/dist/client/session-translation-chat.js +686 -0
- package/data/build/dist/client/session-translation-chat.js.map +1 -0
- package/data/build/dist/client/style.css +2561 -0
- package/data/build/dist/client/subscription-slot.d.ts.map +1 -1
- package/data/build/dist/client/subscription-slot.js +5 -1
- package/data/build/dist/client/subscription-slot.js.map +1 -1
- package/data/build/dist/client/theme.d.ts +2 -0
- package/data/build/dist/client/theme.d.ts.map +1 -1
- package/data/build/dist/client/theme.js +3 -0
- package/data/build/dist/client/theme.js.map +1 -1
- package/data/build/dist/client/workspace-session-visibility-dom.d.ts.map +1 -1
- package/data/build/dist/client/workspace-session-visibility-dom.js +43 -15
- package/data/build/dist/client/workspace-session-visibility-dom.js.map +1 -1
- package/data/build/dist/dsh-capabilities/client/assistant-session-navigation-adapter.d.ts +9 -1
- package/data/build/dist/dsh-capabilities/client/assistant-session-navigation-adapter.d.ts.map +1 -1
- package/data/build/dist/dsh-capabilities/client/assistant-session-navigation-adapter.js +65 -0
- package/data/build/dist/dsh-capabilities/client/assistant-session-navigation-adapter.js.map +1 -1
- package/data/build/dist/host/cli-adapters/acp-cli-driver.d.ts +21 -0
- package/data/build/dist/host/cli-adapters/acp-cli-driver.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/acp-cli-driver.js +100 -3
- package/data/build/dist/host/cli-adapters/acp-cli-driver.js.map +1 -1
- package/data/build/dist/host/cli-adapters/codex-driver.d.ts +11 -1
- package/data/build/dist/host/cli-adapters/codex-driver.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/codex-driver.js +80 -14
- package/data/build/dist/host/cli-adapters/codex-driver.js.map +1 -1
- package/data/build/dist/host/cli-adapters/codex-file-citations.d.ts +13 -0
- package/data/build/dist/host/cli-adapters/codex-file-citations.d.ts.map +1 -0
- package/data/build/dist/host/cli-adapters/codex-file-citations.js +271 -0
- package/data/build/dist/host/cli-adapters/codex-file-citations.js.map +1 -0
- package/data/build/dist/host/cli-adapters/command-code-acp-loader.d.ts +8 -1
- package/data/build/dist/host/cli-adapters/command-code-acp-loader.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/command-code-acp-loader.js +45 -2
- package/data/build/dist/host/cli-adapters/command-code-acp-loader.js.map +1 -1
- package/data/build/dist/host/cli-adapters/command-code-driver.d.ts +8 -2
- package/data/build/dist/host/cli-adapters/command-code-driver.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/command-code-driver.js +32 -3
- package/data/build/dist/host/cli-adapters/command-code-driver.js.map +1 -1
- package/data/build/dist/host/cli-adapters/command-code-history.d.ts +27 -0
- package/data/build/dist/host/cli-adapters/command-code-history.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/command-code-history.js +131 -1
- package/data/build/dist/host/cli-adapters/command-code-history.js.map +1 -1
- package/data/build/dist/host/cli-adapters/delegation-mention-rewrite.js +9 -9
- package/data/build/dist/host/cli-adapters/delegation-mention-rewrite.js.map +1 -1
- package/data/build/dist/host/cli-adapters/dsh-message-projector.d.ts +13 -1
- package/data/build/dist/host/cli-adapters/dsh-message-projector.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/dsh-message-projector.js +95 -12
- package/data/build/dist/host/cli-adapters/dsh-message-projector.js.map +1 -1
- package/data/build/dist/host/cli-adapters/feature.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/feature.js +287 -19
- package/data/build/dist/host/cli-adapters/feature.js.map +1 -1
- package/data/build/dist/host/cli-adapters/grok-driver.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/grok-driver.js +108 -47
- package/data/build/dist/host/cli-adapters/grok-driver.js.map +1 -1
- package/data/build/dist/host/cli-adapters/legacy-session-settings.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/legacy-session-settings.js +7 -2
- package/data/build/dist/host/cli-adapters/legacy-session-settings.js.map +1 -1
- package/data/build/dist/host/cli-adapters/opencode-driver.d.ts +4 -2
- package/data/build/dist/host/cli-adapters/opencode-driver.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/opencode-driver.js +78 -31
- package/data/build/dist/host/cli-adapters/opencode-driver.js.map +1 -1
- package/data/build/dist/host/cli-adapters/opencode-v2-protocol.d.ts +1 -1
- package/data/build/dist/host/cli-adapters/opencode-v2-protocol.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/opencode-v2-protocol.js +83 -9
- package/data/build/dist/host/cli-adapters/opencode-v2-protocol.js.map +1 -1
- package/data/build/dist/host/cli-adapters/provider-subscription.d.ts +5 -1
- package/data/build/dist/host/cli-adapters/provider-subscription.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/provider-subscription.js +90 -25
- package/data/build/dist/host/cli-adapters/provider-subscription.js.map +1 -1
- package/data/build/dist/host/cli-adapters/registry.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/registry.js +22 -5
- package/data/build/dist/host/cli-adapters/registry.js.map +1 -1
- package/data/build/dist/host/cli-adapters/session-store.d.ts +1 -0
- package/data/build/dist/host/cli-adapters/session-store.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/session-store.js +3 -0
- package/data/build/dist/host/cli-adapters/session-store.js.map +1 -1
- package/data/build/dist/host/cli-bridge/bridge-server.js +2 -2
- package/data/build/dist/host/cli-bridge/bridge-server.js.map +1 -1
- package/data/build/dist/host/cli-bridge/command-code-mod.js +21 -21
- package/data/build/dist/host/cli-bridge/command-code-mod.js.map +1 -1
- package/data/build/dist/host/cli-bridge/dispatch.js +19 -19
- package/data/build/dist/host/cli-bridge/dispatch.js.map +1 -1
- package/data/build/dist/host/cli-bridge/injections.d.ts +32 -0
- package/data/build/dist/host/cli-bridge/injections.d.ts.map +1 -1
- package/data/build/dist/host/cli-bridge/injections.js +137 -1
- package/data/build/dist/host/cli-bridge/injections.js.map +1 -1
- package/data/build/dist/host/cli-bridge/mcp-stdio-entry.js +20 -20
- package/data/build/dist/host/cli-bridge/mcp-stdio-entry.js.map +1 -1
- package/data/build/dist/host/desktop-assistant/controller.d.ts +3 -0
- package/data/build/dist/host/desktop-assistant/controller.d.ts.map +1 -1
- package/data/build/dist/host/desktop-assistant/controller.js +49 -4
- package/data/build/dist/host/desktop-assistant/controller.js.map +1 -1
- package/data/build/dist/host/desktop-assistant/mac-agent.d.ts.map +1 -1
- package/data/build/dist/host/desktop-assistant/mac-agent.js +15 -3
- package/data/build/dist/host/desktop-assistant/mac-agent.js.map +1 -1
- package/data/build/dist/host/desktop-assistant/win-agent.d.ts.map +1 -1
- package/data/build/dist/host/desktop-assistant/win-agent.js +21 -3
- package/data/build/dist/host/desktop-assistant/win-agent.js.map +1 -1
- package/data/build/dist/host/features/assistant-management-tools.d.ts +2 -1
- package/data/build/dist/host/features/assistant-management-tools.d.ts.map +1 -1
- package/data/build/dist/host/features/assistant-management-tools.js +10 -3
- package/data/build/dist/host/features/assistant-management-tools.js.map +1 -1
- package/data/build/dist/host/features/assistant-notification-events.js +1 -1
- package/data/build/dist/host/features/assistant-notification-events.js.map +1 -1
- package/data/build/dist/host/features/assistant-notifications.d.ts +8 -1
- package/data/build/dist/host/features/assistant-notifications.d.ts.map +1 -1
- package/data/build/dist/host/features/assistant-notifications.js +114 -12
- package/data/build/dist/host/features/assistant-notifications.js.map +1 -1
- package/data/build/dist/host/features/global-voice-rpc.d.ts +2 -2
- package/data/build/dist/host/features/global-voice-rpc.d.ts.map +1 -1
- package/data/build/dist/host/features/global-voice-rpc.js +89 -2
- package/data/build/dist/host/features/global-voice-rpc.js.map +1 -1
- package/data/build/dist/host/features/index.d.ts +1 -0
- package/data/build/dist/host/features/index.d.ts.map +1 -1
- package/data/build/dist/host/features/index.js +3 -0
- package/data/build/dist/host/features/index.js.map +1 -1
- package/data/build/dist/host/features/peer-host.d.ts.map +1 -1
- package/data/build/dist/host/features/peer-host.js +41 -5
- package/data/build/dist/host/features/peer-host.js.map +1 -1
- package/data/build/dist/host/features/session-translation-service.d.ts +31 -0
- package/data/build/dist/host/features/session-translation-service.d.ts.map +1 -0
- package/data/build/dist/host/features/session-translation-service.js +451 -0
- package/data/build/dist/host/features/session-translation-service.js.map +1 -0
- package/data/build/dist/host/features/session-translation.d.ts +5 -0
- package/data/build/dist/host/features/session-translation.d.ts.map +1 -0
- package/data/build/dist/host/features/session-translation.js +37 -0
- package/data/build/dist/host/features/session-translation.js.map +1 -0
- package/data/build/dist/host/features/types.d.ts +6 -1
- package/data/build/dist/host/features/types.d.ts.map +1 -1
- package/data/build/dist/host/image-artifact-store.d.ts +21 -0
- package/data/build/dist/host/image-artifact-store.d.ts.map +1 -0
- package/data/build/dist/host/image-artifact-store.js +136 -0
- package/data/build/dist/host/image-artifact-store.js.map +1 -0
- package/data/build/dist/host/index.d.ts.map +1 -1
- package/data/build/dist/host/index.js +3 -0
- package/data/build/dist/host/index.js.map +1 -1
- package/data/build/dist/host/modules/peer-host/peer-host-native-dispatch.d.ts +7 -1
- package/data/build/dist/host/modules/peer-host/peer-host-native-dispatch.d.ts.map +1 -1
- package/data/build/dist/host/modules/peer-host/peer-host-native-dispatch.js +23 -4
- package/data/build/dist/host/modules/peer-host/peer-host-native-dispatch.js.map +1 -1
- package/data/build/dist/host/modules/peer-host/peer-host-native-protocol.d.ts +1 -1
- package/data/build/dist/host/modules/peer-host/peer-host-native-protocol.d.ts.map +1 -1
- package/data/build/dist/host/modules/peer-host/peer-host-native-protocol.js +2 -0
- package/data/build/dist/host/modules/peer-host/peer-host-native-protocol.js.map +1 -1
- package/data/build/dist/host/native-session-bridge.d.ts +16 -1
- package/data/build/dist/host/native-session-bridge.d.ts.map +1 -1
- package/data/build/dist/host/native-session-bridge.js +69 -9
- package/data/build/dist/host/native-session-bridge.js.map +1 -1
- package/data/build/dist/host/rpc.js +4 -4
- package/data/build/dist/host/rpc.js.map +1 -1
- package/data/build/dist/host/session-changes.d.ts.map +1 -1
- package/data/build/dist/host/session-changes.js +196 -13
- package/data/build/dist/host/session-changes.js.map +1 -1
- package/data/build/dist/host/settings.d.ts.map +1 -1
- package/data/build/dist/host/settings.js +8 -0
- package/data/build/dist/host/settings.js.map +1 -1
- package/data/build/dist/shared/assistant-message-timeline.d.ts +11 -0
- package/data/build/dist/shared/assistant-message-timeline.d.ts.map +1 -1
- package/data/build/dist/shared/assistant-message-timeline.js +19 -0
- package/data/build/dist/shared/assistant-message-timeline.js.map +1 -1
- package/data/build/dist/shared/assistant-notifications.d.ts +35 -1
- package/data/build/dist/shared/assistant-notifications.d.ts.map +1 -1
- package/data/build/dist/shared/assistant-notifications.js +8 -0
- package/data/build/dist/shared/assistant-notifications.js.map +1 -1
- package/data/build/dist/shared/assistant-session-messages.d.ts +13 -0
- package/data/build/dist/shared/assistant-session-messages.d.ts.map +1 -0
- package/data/build/dist/shared/assistant-session-messages.js +155 -0
- package/data/build/dist/shared/assistant-session-messages.js.map +1 -0
- package/data/build/dist/shared/contracts/assistant.d.ts +13 -0
- package/data/build/dist/shared/contracts/assistant.d.ts.map +1 -1
- package/data/build/dist/shared/contracts/cli-adapter.d.ts +25 -2
- package/data/build/dist/shared/contracts/cli-adapter.d.ts.map +1 -1
- package/data/build/dist/shared/contracts/config.d.ts +6 -0
- package/data/build/dist/shared/contracts/config.d.ts.map +1 -1
- package/data/build/dist/shared/contracts/config.js +3 -0
- package/data/build/dist/shared/contracts/config.js.map +1 -1
- package/data/build/dist/shared/contracts/session-translation.d.ts +58 -0
- package/data/build/dist/shared/contracts/session-translation.d.ts.map +1 -0
- package/data/build/dist/shared/contracts/session-translation.js +23 -0
- package/data/build/dist/shared/contracts/session-translation.js.map +1 -0
- package/data/build/dist/shared/contracts/version.d.ts +1 -1
- package/data/build/dist/shared/contracts/version.js +1 -1
- package/data/build/dist/shared/delegation-carrier.js +6 -6
- package/data/build/dist/shared/delegation-carrier.js.map +1 -1
- package/data/build/dist/shared/desktop-assistant.d.ts +10 -3
- package/data/build/dist/shared/desktop-assistant.d.ts.map +1 -1
- package/data/build/dist/shared/desktop-assistant.js +46 -14
- package/data/build/dist/shared/desktop-assistant.js.map +1 -1
- package/data/build/dist/shared/index.d.ts +2 -1
- package/data/build/dist/shared/index.d.ts.map +1 -1
- package/data/build/dist/shared/index.js +2 -1
- package/data/build/dist/shared/index.js.map +1 -1
- package/package.json +17 -15
- package/profile/README.md +2 -2
- package/profile/package.json +2 -2
- package/profile/version.json +1 -1
- package/version.json +1 -1
- package/data/build/dist/client/peer-host-file-links.d.ts +0 -8
- package/data/build/dist/client/peer-host-file-links.d.ts.map +0 -1
- package/data/build/dist/client/peer-host-file-links.js.map +0 -1
|
@@ -1569,6 +1569,28 @@ window.__ModuleLoader__.load({
|
|
|
1569
1569
|
});
|
|
1570
1570
|
return parts;
|
|
1571
1571
|
}
|
|
1572
|
+
/** 将同一正文位置连续发生的工具归入一个 DSH 风格 step;正文仍保持原有穿插位置。 */
|
|
1573
|
+
function assistantMessageStepTimeline(text, calls = []) {
|
|
1574
|
+
const parts = assistantMessageTimeline(text, calls);
|
|
1575
|
+
const grouped = [];
|
|
1576
|
+
for (const part of parts) {
|
|
1577
|
+
if (part.kind === "text") {
|
|
1578
|
+
grouped.push(part);
|
|
1579
|
+
continue;
|
|
1580
|
+
}
|
|
1581
|
+
const previous = grouped.at(-1);
|
|
1582
|
+
if (previous?.kind === "tool-step") grouped[grouped.length - 1] = {
|
|
1583
|
+
...previous,
|
|
1584
|
+
calls: [...previous.calls, part.call]
|
|
1585
|
+
};
|
|
1586
|
+
else grouped.push({
|
|
1587
|
+
kind: "tool-step",
|
|
1588
|
+
key: `tool-step-${part.call.id}`,
|
|
1589
|
+
calls: [part.call]
|
|
1590
|
+
});
|
|
1591
|
+
}
|
|
1592
|
+
return grouped;
|
|
1593
|
+
}
|
|
1572
1594
|
//#endregion
|
|
1573
1595
|
//#region src/client/features/assistant-record-style.ts
|
|
1574
1596
|
/** 工具记录和通话记录共享交互反馈,选择器只作用于这两类组件。 */
|
|
@@ -1594,14 +1616,21 @@ window.__ModuleLoader__.load({
|
|
|
1594
1616
|
}, (0, react.createElement)("path", { d: "m9 5 7 7-7 7" }));
|
|
1595
1617
|
}
|
|
1596
1618
|
const recordCss = `
|
|
1597
|
-
.codingns-assistant-tool-summary{list-style:none;cursor:pointer
|
|
1619
|
+
.codingns-assistant-tool-summary{list-style:none;cursor:pointer}
|
|
1598
1620
|
.codingns-assistant-tool-summary::-webkit-details-marker{display:none}
|
|
1599
|
-
.codingns-assistant-tool-summary:hover,.codingns-assistant-record-button:hover{
|
|
1600
|
-
.codingns-assistant-tool-summary:active,.codingns-assistant-record-button:active{
|
|
1621
|
+
.codingns-assistant-tool-summary:hover,.codingns-assistant-record-button:hover{color:${require_theme.dshThemeColor.labelPrimary}!important}
|
|
1622
|
+
.codingns-assistant-tool-summary:active,.codingns-assistant-record-button:active{color:${require_theme.dshThemeColor.labelPrimary}!important}
|
|
1601
1623
|
.codingns-assistant-tool-summary:focus-visible,.codingns-assistant-record-button:focus-visible{outline:2px solid ${require_theme.dshThemeColor.accent};outline-offset:2px}
|
|
1602
|
-
.codingns-assistant-tool-details[open]>.codingns-assistant-tool-summary{border-radius:9px 9px 0 0}
|
|
1603
1624
|
.codingns-assistant-tool-details[open] .codingns-assistant-tool-name{white-space:normal!important;overflow-wrap:anywhere}
|
|
1604
1625
|
.codingns-assistant-tool-details[open]>.codingns-assistant-tool-summary .codingns-assistant-record-chevron{transform:rotate(90deg)}
|
|
1626
|
+
.codingns-assistant-tool-step-summary{list-style:none;cursor:pointer}
|
|
1627
|
+
.codingns-assistant-tool-step-summary::-webkit-details-marker{display:none}
|
|
1628
|
+
.codingns-assistant-tool-step-summary:hover{color:${require_theme.dshThemeColor.labelPrimary}!important}
|
|
1629
|
+
.codingns-assistant-tool-step-summary:active{color:${require_theme.dshThemeColor.labelPrimary}!important}
|
|
1630
|
+
.codingns-assistant-tool-step-summary:focus-visible{outline:2px solid ${require_theme.dshThemeColor.accent};outline-offset:2px}
|
|
1631
|
+
.codingns-assistant-tool-step-details[open]>.codingns-assistant-tool-step-summary .codingns-assistant-step-chevron{transform:rotate(180deg)}
|
|
1632
|
+
.codingns-assistant-tool-step-details[open] .codingns-assistant-tool-step-body{padding-inline:4px}
|
|
1633
|
+
.codingns-assistant-tool-step-details[open] .codingns-assistant-tool-step-preview{white-space:normal;overflow-wrap:anywhere}
|
|
1605
1634
|
.codingns-assistant-voice-dialog[open]{display:flex;flex-direction:column}
|
|
1606
1635
|
.codingns-assistant-voice-dialog::backdrop{background:${require_theme.dshThemeColor.overlay}}
|
|
1607
1636
|
`;
|
|
@@ -1660,9 +1689,9 @@ window.__ModuleLoader__.load({
|
|
|
1660
1689
|
}
|
|
1661
1690
|
/** 文字聊天、实时字幕与通话历史共用同一时间线,不额外生成工具汇总区。 */
|
|
1662
1691
|
function AssistantMessageContentView({ text, calls, t }) {
|
|
1663
|
-
return (0, react.createElement)(react.Fragment, null, ...
|
|
1692
|
+
return (0, react.createElement)(react.Fragment, null, ...assistantMessageStepTimeline(text, calls).map((part) => part.kind === "tool-step" ? (0, react.createElement)(AssistantToolStepView, {
|
|
1664
1693
|
key: part.key,
|
|
1665
|
-
calls:
|
|
1694
|
+
calls: part.calls,
|
|
1666
1695
|
t
|
|
1667
1696
|
}) : (0, react.createElement)("div", {
|
|
1668
1697
|
key: part.key,
|
|
@@ -1674,14 +1703,15 @@ window.__ModuleLoader__.load({
|
|
|
1674
1703
|
}, part.text)));
|
|
1675
1704
|
}
|
|
1676
1705
|
/** 工具信息单独展示,不拼入消息正文,字幕与语音合成都只使用原始 text。 */
|
|
1677
|
-
function AssistantToolCallsView({ calls, t }) {
|
|
1706
|
+
function AssistantToolCallsView({ calls, t, compact = false }) {
|
|
1678
1707
|
if (!calls?.length) return null;
|
|
1679
1708
|
return (0, react.createElement)("div", {
|
|
1680
1709
|
"data-codingns-assistant-tools": true,
|
|
1710
|
+
"data-codingns-assistant-tools-compact": compact,
|
|
1681
1711
|
style: {
|
|
1682
1712
|
display: "grid",
|
|
1683
|
-
gap:
|
|
1684
|
-
marginBlock: 6,
|
|
1713
|
+
gap: 2,
|
|
1714
|
+
marginBlock: compact ? 0 : 6,
|
|
1685
1715
|
textAlign: "left",
|
|
1686
1716
|
whiteSpace: "normal",
|
|
1687
1717
|
minWidth: 0
|
|
@@ -1689,26 +1719,113 @@ window.__ModuleLoader__.load({
|
|
|
1689
1719
|
}, (0, react.createElement)(AssistantRecordStyle), ...calls.map((call) => (0, react.createElement)(AssistantToolCallView, {
|
|
1690
1720
|
key: call.id,
|
|
1691
1721
|
call,
|
|
1692
|
-
t
|
|
1722
|
+
t,
|
|
1723
|
+
compact
|
|
1693
1724
|
})));
|
|
1694
1725
|
}
|
|
1726
|
+
/** 一个 step 只显示摘要;展开后才加载其中的工具调用明细。 */
|
|
1727
|
+
function AssistantToolStepView({ calls, t }) {
|
|
1728
|
+
if (calls.length === 0) return null;
|
|
1729
|
+
const running = calls.some((call) => call.state === "running");
|
|
1730
|
+
const failed = calls.some((call) => call.state === "failed");
|
|
1731
|
+
const status = running ? "running" : failed ? "failed" : calls.every((call) => call.state === "cancelled") ? "cancelled" : "completed";
|
|
1732
|
+
const latestCall = calls[calls.length - 1];
|
|
1733
|
+
const latestArguments = assistantToolArgumentPreview(latestCall, t);
|
|
1734
|
+
const summary = calls.map((call) => assistantToolStepPreview(call, t)).filter((value, index, all) => all.indexOf(value) === index).join(t("awb.call.separator"));
|
|
1735
|
+
return (0, react.createElement)("div", {
|
|
1736
|
+
"data-codingns-assistant-tool-step": true,
|
|
1737
|
+
style: {
|
|
1738
|
+
marginBlock: 6,
|
|
1739
|
+
textAlign: "left",
|
|
1740
|
+
whiteSpace: "normal",
|
|
1741
|
+
minWidth: 0,
|
|
1742
|
+
color: require_theme.dshThemeColor.labelSecondary,
|
|
1743
|
+
fontSize: require_theme.uiFontSize(13),
|
|
1744
|
+
lineHeight: 1.6
|
|
1745
|
+
}
|
|
1746
|
+
}, (0, react.createElement)(AssistantRecordStyle), (0, react.createElement)("details", { className: "codingns-assistant-tool-step-details" }, (0, react.createElement)("summary", {
|
|
1747
|
+
className: "codingns-assistant-tool-step-summary",
|
|
1748
|
+
title: t("awb.call.stepDetails"),
|
|
1749
|
+
"aria-label": `${t("awb.call.step")} · ${summary} · ${t(`awb.call.tool.${status}`)}`,
|
|
1750
|
+
style: {
|
|
1751
|
+
display: "flex",
|
|
1752
|
+
alignItems: "center",
|
|
1753
|
+
gap: 8,
|
|
1754
|
+
minWidth: 0,
|
|
1755
|
+
padding: "2px 0",
|
|
1756
|
+
color: require_theme.dshThemeColor.labelSecondary
|
|
1757
|
+
}
|
|
1758
|
+
}, (0, react.createElement)(AssistantStepChevron), (0, react.createElement)("span", {
|
|
1759
|
+
className: "codingns-assistant-tool-step-preview",
|
|
1760
|
+
"data-latest-tool": latestCall.name,
|
|
1761
|
+
title: latestCall.name,
|
|
1762
|
+
style: {
|
|
1763
|
+
minWidth: 0,
|
|
1764
|
+
overflow: "hidden",
|
|
1765
|
+
textOverflow: "ellipsis",
|
|
1766
|
+
whiteSpace: "nowrap"
|
|
1767
|
+
}
|
|
1768
|
+
}, summary, " · ", (0, react.createElement)("code", { style: {
|
|
1769
|
+
color: require_theme.dshThemeColor.labelPrimary,
|
|
1770
|
+
fontFamily: require_theme.dshThemeColor.codeFont,
|
|
1771
|
+
fontSize: "0.92em"
|
|
1772
|
+
} }, latestCall.name), latestArguments ? ` · ${latestArguments}` : "")), (0, react.createElement)("div", {
|
|
1773
|
+
className: "codingns-assistant-tool-step-body",
|
|
1774
|
+
style: {
|
|
1775
|
+
display: "grid",
|
|
1776
|
+
gap: 1,
|
|
1777
|
+
padding: "4px 0 5px 21px"
|
|
1778
|
+
}
|
|
1779
|
+
}, (0, react.createElement)(AssistantToolCallsView, {
|
|
1780
|
+
calls,
|
|
1781
|
+
t,
|
|
1782
|
+
compact: true
|
|
1783
|
+
}))));
|
|
1784
|
+
}
|
|
1785
|
+
function assistantToolStepPreview(call, t) {
|
|
1786
|
+
if (call.name.includes("read") || call.kind === "attachment") return t("awb.call.stepRead");
|
|
1787
|
+
if (call.name.includes("search") || call.kind === "web-search") return t("awb.call.stepSearch");
|
|
1788
|
+
if (call.name.includes("workspace") || call.kind === "workspace") return t("awb.call.stepWorkspace");
|
|
1789
|
+
return t("awb.call.stepTool");
|
|
1790
|
+
}
|
|
1791
|
+
function assistantToolArgumentPreview(call, t) {
|
|
1792
|
+
try {
|
|
1793
|
+
const args = JSON.parse(call.arguments);
|
|
1794
|
+
if (args === null || typeof args !== "object" || Array.isArray(args)) return "";
|
|
1795
|
+
const record = args;
|
|
1796
|
+
for (const key of [
|
|
1797
|
+
"query",
|
|
1798
|
+
"queries",
|
|
1799
|
+
"text",
|
|
1800
|
+
"url",
|
|
1801
|
+
"fileName",
|
|
1802
|
+
"filename",
|
|
1803
|
+
"file",
|
|
1804
|
+
"title",
|
|
1805
|
+
"message"
|
|
1806
|
+
]) {
|
|
1807
|
+
const value = record[key];
|
|
1808
|
+
const preview = typeof value === "string" ? value : Array.isArray(value) ? value.filter((item) => typeof item === "string").join(t("awb.call.separator")) : "";
|
|
1809
|
+
if (preview.trim()) return preview.trim().slice(0, 120);
|
|
1810
|
+
}
|
|
1811
|
+
} catch {}
|
|
1812
|
+
return "";
|
|
1813
|
+
}
|
|
1695
1814
|
/** 整个标题栏就是展开入口;实时状态更新不替换 details,保留用户的展开状态。 */
|
|
1696
|
-
function AssistantToolCallView({ call, t }) {
|
|
1815
|
+
function AssistantToolCallView({ call, t, compact = false }) {
|
|
1697
1816
|
const label = t(call.kind === "web-search" ? "awb.call.webSearch" : call.kind === "attachment" ? "awb.call.attachment" : "awb.call.workspace");
|
|
1698
1817
|
const status = t(`awb.call.tool.${call.state}`);
|
|
1699
|
-
const
|
|
1700
|
-
const
|
|
1701
|
-
return (0, react.createElement)("
|
|
1818
|
+
const argumentPreview = compact ? assistantToolArgumentPreview(call, t) : "";
|
|
1819
|
+
const rowColor = call.state === "failed" ? require_theme.dshThemeColor.error : require_theme.dshThemeColor.labelSecondary;
|
|
1820
|
+
return (0, react.createElement)("div", {
|
|
1821
|
+
"data-codingns-assistant-tool-row": call.name,
|
|
1702
1822
|
"data-codingns-assistant-tool": call.name,
|
|
1703
1823
|
"data-state": call.state,
|
|
1704
1824
|
style: {
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
fontSize: require_theme.uiFontSize(12),
|
|
1710
|
-
lineHeight: 1.4,
|
|
1711
|
-
minWidth: 0
|
|
1825
|
+
minWidth: 0,
|
|
1826
|
+
color: rowColor,
|
|
1827
|
+
fontSize: require_theme.uiFontSize(13),
|
|
1828
|
+
lineHeight: 1.65
|
|
1712
1829
|
}
|
|
1713
1830
|
}, (0, react.createElement)("details", { className: "codingns-assistant-tool-details" }, (0, react.createElement)("summary", {
|
|
1714
1831
|
className: "codingns-assistant-tool-summary",
|
|
@@ -1718,98 +1835,53 @@ window.__ModuleLoader__.load({
|
|
|
1718
1835
|
display: "flex",
|
|
1719
1836
|
alignItems: "center",
|
|
1720
1837
|
gap: 8,
|
|
1721
|
-
|
|
1722
|
-
|
|
1838
|
+
minWidth: 0,
|
|
1839
|
+
padding: "1px 0"
|
|
1723
1840
|
}
|
|
1724
|
-
}, (0, react.createElement)("span", { style: {
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
width: 28,
|
|
1729
|
-
height: 28,
|
|
1730
|
-
borderRadius: 8,
|
|
1731
|
-
color,
|
|
1732
|
-
background: `color-mix(in srgb, ${color} 9%, transparent)`
|
|
1733
|
-
} }, (0, react.createElement)(AssistantToolIcon, { kind: call.kind })), (0, react.createElement)("span", { style: {
|
|
1734
|
-
flex: "1 1 auto",
|
|
1735
|
-
minWidth: 0,
|
|
1736
|
-
display: "grid",
|
|
1737
|
-
gap: 1
|
|
1738
|
-
} }, (0, react.createElement)("strong", { style: {
|
|
1739
|
-
fontSize: require_theme.uiFontSize(12),
|
|
1740
|
-
fontWeight: 600
|
|
1741
|
-
} }, label), (0, react.createElement)("span", {
|
|
1742
|
-
className: "codingns-assistant-tool-name",
|
|
1841
|
+
}, (0, react.createElement)(AssistantRecordChevron), (0, react.createElement)("span", { style: { flexShrink: 0 } }, label), (0, react.createElement)("span", { style: {
|
|
1842
|
+
color: require_theme.dshThemeColor.labelTertiary,
|
|
1843
|
+
flexShrink: 0
|
|
1844
|
+
} }, "·"), (0, react.createElement)("span", {
|
|
1743
1845
|
title: call.name,
|
|
1744
1846
|
style: {
|
|
1745
|
-
|
|
1746
|
-
fontFamily: require_theme.dshThemeColor.codeFont,
|
|
1747
|
-
fontSize: require_theme.uiFontSize(11),
|
|
1847
|
+
minWidth: 0,
|
|
1748
1848
|
overflow: "hidden",
|
|
1749
1849
|
textOverflow: "ellipsis",
|
|
1750
|
-
whiteSpace: "nowrap"
|
|
1751
|
-
|
|
1752
|
-
}, call.name)), (0, react.createElement)("span", { style: {
|
|
1753
|
-
display: "grid",
|
|
1754
|
-
justifyItems: "end",
|
|
1755
|
-
gap: 3,
|
|
1756
|
-
flexShrink: 0
|
|
1757
|
-
} }, (0, react.createElement)("span", {
|
|
1758
|
-
role: "status",
|
|
1759
|
-
style: {
|
|
1760
|
-
display: "inline-flex",
|
|
1761
|
-
alignItems: "center",
|
|
1762
|
-
gap: 4,
|
|
1763
|
-
color,
|
|
1764
|
-
padding: "1px 6px",
|
|
1765
|
-
borderRadius: 5,
|
|
1766
|
-
background: `color-mix(in srgb, ${color} 9%, transparent)`,
|
|
1767
|
-
fontSize: require_theme.uiFontSize(11),
|
|
1768
|
-
whiteSpace: "nowrap"
|
|
1850
|
+
whiteSpace: "nowrap",
|
|
1851
|
+
fontFamily: require_theme.dshThemeColor.codeFont
|
|
1769
1852
|
}
|
|
1770
|
-
}, (0, react.createElement)("
|
|
1771
|
-
"
|
|
1853
|
+
}, call.name, argumentPreview ? ` · ${argumentPreview}` : "")), (0, react.createElement)("div", {
|
|
1854
|
+
className: "codingns-assistant-tool-body",
|
|
1772
1855
|
style: {
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1856
|
+
display: "grid",
|
|
1857
|
+
gap: 0,
|
|
1858
|
+
margin: "2px 0 4px 22px",
|
|
1859
|
+
border: `0.5px solid ${require_theme.dshThemeColor.border}`,
|
|
1860
|
+
borderRadius: 6,
|
|
1861
|
+
overflow: "hidden",
|
|
1862
|
+
minWidth: 0
|
|
1777
1863
|
}
|
|
1778
|
-
}),
|
|
1779
|
-
|
|
1780
|
-
title: startedAt.toLocaleString(),
|
|
1864
|
+
}, ...[[t("awb.call.arguments"), call.arguments], [t("awb.call.result"), call.result]].map(([heading, value], index) => (0, react.createElement)("div", {
|
|
1865
|
+
key: heading,
|
|
1781
1866
|
style: {
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1867
|
+
display: "grid",
|
|
1868
|
+
gridTemplateColumns: "max-content minmax(0, 1fr)",
|
|
1869
|
+
gap: 12,
|
|
1870
|
+
alignItems: "baseline",
|
|
1871
|
+
padding: "7px 10px",
|
|
1872
|
+
minWidth: 0,
|
|
1873
|
+
...index === 0 ? {} : { borderTop: `0.5px solid ${require_theme.dshThemeColor.border}` }
|
|
1786
1874
|
}
|
|
1787
|
-
}, startedAt.toLocaleTimeString([], {
|
|
1788
|
-
hour: "2-digit",
|
|
1789
|
-
minute: "2-digit",
|
|
1790
|
-
second: "2-digit",
|
|
1791
|
-
hour12: false
|
|
1792
|
-
}))), (0, react.createElement)(AssistantRecordChevron)), (0, react.createElement)("div", { style: {
|
|
1793
|
-
display: "grid",
|
|
1794
|
-
gap: 8,
|
|
1795
|
-
padding: "9px 10px 10px",
|
|
1796
|
-
borderTop: `1px solid ${require_theme.dshThemeColor.border}`,
|
|
1797
|
-
minWidth: 0
|
|
1798
|
-
} }, ...[[t("awb.call.arguments"), call.arguments], [t("awb.call.result"), call.result]].map(([heading, value]) => (0, react.createElement)("div", {
|
|
1799
|
-
key: heading,
|
|
1800
|
-
style: { minWidth: 0 }
|
|
1801
1875
|
}, (0, react.createElement)("small", { style: {
|
|
1802
|
-
color: require_theme.dshThemeColor.
|
|
1876
|
+
color: require_theme.dshThemeColor.labelTertiary,
|
|
1803
1877
|
fontSize: require_theme.uiFontSize(11),
|
|
1804
|
-
|
|
1878
|
+
whiteSpace: "nowrap"
|
|
1805
1879
|
} }, heading), (0, react.createElement)("pre", {
|
|
1806
1880
|
tabIndex: 0,
|
|
1807
1881
|
"aria-label": heading,
|
|
1808
1882
|
style: {
|
|
1809
|
-
margin:
|
|
1810
|
-
|
|
1811
|
-
borderRadius: 6,
|
|
1812
|
-
background: require_theme.dshThemeColor.cardBackground,
|
|
1883
|
+
margin: 0,
|
|
1884
|
+
color: require_theme.dshThemeColor.labelSecondary,
|
|
1813
1885
|
maxHeight: 160,
|
|
1814
1886
|
overflowY: "auto",
|
|
1815
1887
|
overscrollBehavior: "contain",
|
|
@@ -1822,18 +1894,23 @@ window.__ModuleLoader__.load({
|
|
|
1822
1894
|
}
|
|
1823
1895
|
}, value || "—"))))));
|
|
1824
1896
|
}
|
|
1825
|
-
function
|
|
1897
|
+
function AssistantStepChevron() {
|
|
1826
1898
|
return (0, react.createElement)("svg", {
|
|
1827
|
-
|
|
1828
|
-
|
|
1899
|
+
className: "codingns-assistant-step-chevron",
|
|
1900
|
+
width: 14,
|
|
1901
|
+
height: 14,
|
|
1829
1902
|
viewBox: "0 0 24 24",
|
|
1830
1903
|
fill: "none",
|
|
1831
1904
|
stroke: "currentColor",
|
|
1832
|
-
strokeWidth: 1.
|
|
1905
|
+
strokeWidth: 1.8,
|
|
1833
1906
|
strokeLinecap: "round",
|
|
1834
1907
|
strokeLinejoin: "round",
|
|
1835
|
-
"aria-hidden": true
|
|
1836
|
-
|
|
1908
|
+
"aria-hidden": true,
|
|
1909
|
+
style: {
|
|
1910
|
+
flexShrink: 0,
|
|
1911
|
+
color: require_theme.dshThemeColor.labelTertiary
|
|
1912
|
+
}
|
|
1913
|
+
}, (0, react.createElement)("path", { d: "m6 9 6 6 6-6" }));
|
|
1837
1914
|
}
|
|
1838
1915
|
//#endregion
|
|
1839
1916
|
//#region src/client/features/assistant-realtime-call.ts
|
|
@@ -2968,12 +3045,7 @@ window.__ModuleLoader__.load({
|
|
|
2968
3045
|
flexDirection: "column",
|
|
2969
3046
|
gap: configuring ? 11 : 16
|
|
2970
3047
|
}
|
|
2971
|
-
}, !loaded ? (0, react.createElement)("div", {
|
|
2972
|
-
role: "status",
|
|
2973
|
-
style: require_theme.dshSettingsHelpStyle
|
|
2974
|
-
}, t("awb.loading"), " ", button(t("awb.retry"), () => {
|
|
2975
|
-
refresh().catch((cause) => setError(message(cause)));
|
|
2976
|
-
})) : null, noticeText ? (0, react.createElement)("div", {
|
|
3048
|
+
}, !loaded ? (0, react.createElement)(AssistantLoadingView, { t }) : null, noticeText ? (0, react.createElement)("div", {
|
|
2977
3049
|
role: "alert",
|
|
2978
3050
|
style: {
|
|
2979
3051
|
color: require_theme.dshThemeColor.error,
|
|
@@ -3176,6 +3248,19 @@ window.__ModuleLoader__.load({
|
|
|
3176
3248
|
model
|
|
3177
3249
|
}));
|
|
3178
3250
|
}
|
|
3251
|
+
/** 首次读取期间使用居中的动态状态,避免把正常等待误显示成失败或重试入口。 */
|
|
3252
|
+
function AssistantLoadingView({ t }) {
|
|
3253
|
+
return (0, react.createElement)("div", {
|
|
3254
|
+
"data-codingns-assistant-loading": true,
|
|
3255
|
+
role: "status",
|
|
3256
|
+
"aria-live": "polite",
|
|
3257
|
+
"aria-label": t("awb.loading"),
|
|
3258
|
+
style: assistantLoadingStyle
|
|
3259
|
+
}, (0, react.createElement)("style", null, assistantLoadingCss), (0, react.createElement)("div", {
|
|
3260
|
+
"aria-hidden": true,
|
|
3261
|
+
style: assistantLoadingOrbStyle
|
|
3262
|
+
}, (0, react.createElement)("span", { className: "codingns-assistant-loading-ring" }), (0, react.createElement)("span", { className: "codingns-assistant-loading-core" }), (0, react.createElement)("span", { className: "codingns-assistant-loading-dot codingns-assistant-loading-dot-one" }), (0, react.createElement)("span", { className: "codingns-assistant-loading-dot codingns-assistant-loading-dot-two" }), (0, react.createElement)("span", { className: "codingns-assistant-loading-dot codingns-assistant-loading-dot-three" })), (0, react.createElement)("div", { style: assistantLoadingLabelStyle }, t("awb.loadingHint")));
|
|
3263
|
+
}
|
|
3179
3264
|
/** 内层菜单先消费 Escape,外层窗口只处理尚未消费的关闭按键。 */
|
|
3180
3265
|
function handleAssistantWorkbenchEscape(event, onClose) {
|
|
3181
3266
|
if (event.key !== "Escape" || event.defaultPrevented) return;
|
|
@@ -3210,6 +3295,47 @@ window.__ModuleLoader__.load({
|
|
|
3210
3295
|
gap: 8,
|
|
3211
3296
|
justifyItems: "center"
|
|
3212
3297
|
};
|
|
3298
|
+
const assistantLoadingStyle = {
|
|
3299
|
+
flex: "1 1 auto",
|
|
3300
|
+
minHeight: "min(420px, 45vh)",
|
|
3301
|
+
display: "flex",
|
|
3302
|
+
flexDirection: "column",
|
|
3303
|
+
alignItems: "center",
|
|
3304
|
+
justifyContent: "center",
|
|
3305
|
+
gap: 18,
|
|
3306
|
+
color: require_theme.dshThemeColor.labelSecondary
|
|
3307
|
+
};
|
|
3308
|
+
const assistantLoadingOrbStyle = {
|
|
3309
|
+
position: "relative",
|
|
3310
|
+
width: 76,
|
|
3311
|
+
height: 76,
|
|
3312
|
+
borderRadius: "50%",
|
|
3313
|
+
background: `radial-gradient(circle at 35% 28%, ${require_theme.dshThemeColor.accent}33, transparent 58%)`,
|
|
3314
|
+
boxShadow: `0 0 0 1px ${require_theme.dshThemeColor.border}, 0 0 42px ${require_theme.dshThemeColor.accent}24`
|
|
3315
|
+
};
|
|
3316
|
+
const assistantLoadingLabelStyle = {
|
|
3317
|
+
fontSize: require_theme.uiFontSize(13),
|
|
3318
|
+
letterSpacing: "0.04em"
|
|
3319
|
+
};
|
|
3320
|
+
const assistantLoadingCss = `
|
|
3321
|
+
[data-codingns-assistant-loading] .codingns-assistant-loading-ring,
|
|
3322
|
+
[data-codingns-assistant-loading] .codingns-assistant-loading-core,
|
|
3323
|
+
[data-codingns-assistant-loading] .codingns-assistant-loading-dot{position:absolute;display:block;border-radius:50%}
|
|
3324
|
+
[data-codingns-assistant-loading] .codingns-assistant-loading-ring{inset:7px;border:1px solid ${require_theme.dshThemeColor.accent}88;border-top-color:transparent;border-left-color:${require_theme.dshThemeColor.accent};animation:codingns-assistant-loading-spin 2.8s linear infinite}
|
|
3325
|
+
[data-codingns-assistant-loading] .codingns-assistant-loading-core{inset:22px;background:${require_theme.dshThemeColor.accent};box-shadow:0 0 18px ${require_theme.dshThemeColor.accent}aa;animation:codingns-assistant-loading-breathe 1.8s ease-in-out infinite}
|
|
3326
|
+
[data-codingns-assistant-loading] .codingns-assistant-loading-dot{width:6px;height:6px;background:${require_theme.dshThemeColor.labelPrimary};box-shadow:0 0 10px ${require_theme.dshThemeColor.accent};animation:codingns-assistant-loading-pulse 1.8s ease-in-out infinite}
|
|
3327
|
+
[data-codingns-assistant-loading] .codingns-assistant-loading-dot-one{top:4px;left:35px}
|
|
3328
|
+
[data-codingns-assistant-loading] .codingns-assistant-loading-dot-two{right:7px;bottom:20px;animation-delay:.22s}
|
|
3329
|
+
[data-codingns-assistant-loading] .codingns-assistant-loading-dot-three{left:7px;bottom:20px;animation-delay:.44s}
|
|
3330
|
+
@keyframes codingns-assistant-loading-spin{to{transform:rotate(360deg)}}
|
|
3331
|
+
@keyframes codingns-assistant-loading-breathe{0%,100%{transform:scale(.82);opacity:.72}50%{transform:scale(1.08);opacity:1}}
|
|
3332
|
+
@keyframes codingns-assistant-loading-pulse{0%,100%{transform:scale(.65);opacity:.36}50%{transform:scale(1.15);opacity:1}}
|
|
3333
|
+
@media (prefers-reduced-motion:reduce){
|
|
3334
|
+
[data-codingns-assistant-loading] .codingns-assistant-loading-ring,
|
|
3335
|
+
[data-codingns-assistant-loading] .codingns-assistant-loading-core,
|
|
3336
|
+
[data-codingns-assistant-loading] .codingns-assistant-loading-dot{animation:none}
|
|
3337
|
+
}
|
|
3338
|
+
`;
|
|
3213
3339
|
const backdrop = {
|
|
3214
3340
|
position: "fixed",
|
|
3215
3341
|
inset: 0,
|
|
@@ -4236,6 +4362,14 @@ window.__ModuleLoader__.load({
|
|
|
4236
4362
|
question: t("awb.notifications.question"),
|
|
4237
4363
|
approval: t("awb.notifications.approval")
|
|
4238
4364
|
};
|
|
4365
|
+
const icon = reaction === "question" ? (0, react.createElement)("span", {
|
|
4366
|
+
"data-codingns-avatar-reaction-glyph": "speech",
|
|
4367
|
+
style: { display: "inline-flex" }
|
|
4368
|
+
}, speechIcon()) : {
|
|
4369
|
+
success: "✓",
|
|
4370
|
+
concerned: "!",
|
|
4371
|
+
approval: "…"
|
|
4372
|
+
}[reaction];
|
|
4239
4373
|
return (0, react.createElement)("span", {
|
|
4240
4374
|
role: "status",
|
|
4241
4375
|
"aria-label": labels[reaction],
|
|
@@ -4243,21 +4377,50 @@ window.__ModuleLoader__.load({
|
|
|
4243
4377
|
"data-codingns-avatar-reaction": reaction,
|
|
4244
4378
|
style: {
|
|
4245
4379
|
position: "absolute",
|
|
4246
|
-
|
|
4380
|
+
left: "50%",
|
|
4247
4381
|
top: 0,
|
|
4248
|
-
|
|
4249
|
-
|
|
4382
|
+
transform: "translateX(-50%)",
|
|
4383
|
+
width: 30,
|
|
4384
|
+
height: 26,
|
|
4385
|
+
boxSizing: "border-box",
|
|
4386
|
+
display: "grid",
|
|
4387
|
+
placeItems: "center",
|
|
4388
|
+
padding: 0,
|
|
4389
|
+
borderRadius: 11,
|
|
4250
4390
|
background: "#fff",
|
|
4251
4391
|
color: "#242424",
|
|
4252
4392
|
border: "1px solid #b8c3d3",
|
|
4393
|
+
lineHeight: 1,
|
|
4253
4394
|
pointerEvents: "none"
|
|
4254
4395
|
}
|
|
4255
|
-
},
|
|
4256
|
-
|
|
4257
|
-
|
|
4258
|
-
|
|
4259
|
-
|
|
4260
|
-
|
|
4396
|
+
}, icon);
|
|
4397
|
+
}
|
|
4398
|
+
/** 提问状态使用发言气泡:圆角轮廓、右下尾巴和三个空心圆点。 */
|
|
4399
|
+
function speechIcon() {
|
|
4400
|
+
return (0, react.createElement)("svg", {
|
|
4401
|
+
width: 20,
|
|
4402
|
+
height: 20,
|
|
4403
|
+
viewBox: "0 0 24 24",
|
|
4404
|
+
fill: "none",
|
|
4405
|
+
stroke: "currentColor",
|
|
4406
|
+
strokeWidth: 1.9,
|
|
4407
|
+
strokeLinecap: "round",
|
|
4408
|
+
strokeLinejoin: "round",
|
|
4409
|
+
"aria-hidden": true,
|
|
4410
|
+
focusable: false
|
|
4411
|
+
}, (0, react.createElement)("path", { d: "M12 3H9a7 7 0 0 0-7 7v2a7 7 0 0 0 7 7h5.5l3.5 2.5.8-4.45A7 7 0 0 0 21 12v-2a7 7 0 0 0-7-7h-2Z" }), (0, react.createElement)("circle", {
|
|
4412
|
+
cx: 7.5,
|
|
4413
|
+
cy: 11,
|
|
4414
|
+
r: 1.45
|
|
4415
|
+
}), (0, react.createElement)("circle", {
|
|
4416
|
+
cx: 12,
|
|
4417
|
+
cy: 11,
|
|
4418
|
+
r: 1.45
|
|
4419
|
+
}), (0, react.createElement)("circle", {
|
|
4420
|
+
cx: 16.5,
|
|
4421
|
+
cy: 11,
|
|
4422
|
+
r: 1.45
|
|
4423
|
+
}));
|
|
4261
4424
|
}
|
|
4262
4425
|
//#endregion
|
|
4263
4426
|
//#region src/client/avatar/spritesheet.ts
|
|
@@ -7392,6 +7555,7 @@ window.__ModuleLoader__.load({
|
|
|
7392
7555
|
var module = { exports: {} };
|
|
7393
7556
|
var exports = module.exports;
|
|
7394
7557
|
const require_assistant_notifications = require("@jingyi0605/codingns4dsh/client.assistant-notifications.js");
|
|
7558
|
+
const require_session_translation = require("@jingyi0605/codingns4dsh/client.session-translation.js");
|
|
7395
7559
|
//#region src/shared/contracts/version.ts
|
|
7396
7560
|
/** 当前经过完整验证的 DSH 版本;源文件由根目录 version.json 同步。 */
|
|
7397
7561
|
const DSH_VERSION = "0.2.1-alpha.2";
|
|
@@ -7425,7 +7589,7 @@ window.__ModuleLoader__.load({
|
|
|
7425
7589
|
return /^0\.1\.5(?:-|$)/u.test(version);
|
|
7426
7590
|
}
|
|
7427
7591
|
/** Codingns4DSH 插件自身的 npm 版本。 */
|
|
7428
|
-
const CODINGNS_VERSION = "0.2.1-beta.
|
|
7592
|
+
const CODINGNS_VERSION = "0.2.1-beta.9";
|
|
7429
7593
|
/** 判断宿主版本是否落在当前插件声明的 DSH 兼容范围内;范围省略上界时不校验上限。 */
|
|
7430
7594
|
function isDshVersionCompatible(version) {
|
|
7431
7595
|
const match = /^>=([^ ]+)(?: <=([^ ]+))?$/u.exec(DSH_COMPATIBILITY);
|
|
@@ -7670,8 +7834,10 @@ window.__ModuleLoader__.load({
|
|
|
7670
7834
|
const CODINGNS_FILE_MANAGEMENT_FIELD = "fileManagement";
|
|
7671
7835
|
const CODINGNS_MOBILE_ACCESS_FIELD = "mobileAccess";
|
|
7672
7836
|
const CODINGNS_SUBSCRIPTION_USAGE_FIELD = "subscriptionUsage";
|
|
7837
|
+
const CODINGNS_SESSION_TRANSLATION_FIELD = "sessionTranslation";
|
|
7673
7838
|
const CODINGNS_ASSISTANT_FIELD = "assistant";
|
|
7674
|
-
const
|
|
7839
|
+
const DEFAULT_CODINGNS_CONTROL_BASE_URL = "https://channel.codingns.com:1443";
|
|
7840
|
+
const DEFAULT_CODINGNS_CONTROL_BASE_URLS = [DEFAULT_CODINGNS_CONTROL_BASE_URL];
|
|
7675
7841
|
/** 控制站的网页登录地址,用于注册 Codingns4DSH 账号。 */
|
|
7676
7842
|
const CODINGNS_CONTROL_STATION_URL = "https://channel.codingns.com:1443";
|
|
7677
7843
|
/** 独立 H5 登录页面地址;登录控制站后可从设置页复制给其他设备。 */
|
|
@@ -7705,7 +7871,28 @@ window.__ModuleLoader__.load({
|
|
|
7705
7871
|
quickPhrases: DEFAULT_QUICK_PHRASES.map((phrase) => ({ ...phrase })),
|
|
7706
7872
|
quickPhrasesSeeded: true
|
|
7707
7873
|
};
|
|
7708
|
-
|
|
7874
|
+
const DEFAULT_CODINGNS_SETTINGS = {
|
|
7875
|
+
controlBaseUrl: DEFAULT_CODINGNS_CONTROL_BASE_URL,
|
|
7876
|
+
controlBaseUrls: [...DEFAULT_CODINGNS_CONTROL_BASE_URLS],
|
|
7877
|
+
modules: {},
|
|
7878
|
+
agentAdapters: {},
|
|
7879
|
+
agentAdapterPreferences: {},
|
|
7880
|
+
subagentBridge: DEFAULT_SUBAGENT_BRIDGE_SETTINGS,
|
|
7881
|
+
sessionTranslation: require_session_translation.DEFAULT_SESSION_TRANSLATION_SETTINGS,
|
|
7882
|
+
terminalEnhancement: DEFAULT_TERMINAL_ENHANCEMENT_SETTINGS,
|
|
7883
|
+
workspaceSessionEnhancement: DEFAULT_WORKSPACE_SESSION_ENHANCEMENT_SETTINGS,
|
|
7884
|
+
fileManagement: DEFAULT_FILE_MANAGEMENT_SETTINGS,
|
|
7885
|
+
mobileAccess: DEFAULT_MOBILE_ACCESS_SETTINGS,
|
|
7886
|
+
subscriptionUsage: DEFAULT_SUBSCRIPTION_USAGE_SETTINGS,
|
|
7887
|
+
assistant: DEFAULT_ASSISTANT_SETTINGS,
|
|
7888
|
+
lanAccessDsh: {
|
|
7889
|
+
autoStart: false,
|
|
7890
|
+
listenHost: "0.0.0.0",
|
|
7891
|
+
listenPort: 13080,
|
|
7892
|
+
dshPort: 0,
|
|
7893
|
+
pwa: DEFAULT_LAN_ACCESS_DSH_PWA_SETTINGS
|
|
7894
|
+
}
|
|
7895
|
+
};
|
|
7709
7896
|
function captureRestartFeatureStates(descriptors, settings, dshVersion) {
|
|
7710
7897
|
const states = {};
|
|
7711
7898
|
for (const descriptor of descriptors) if (descriptor.activation === "restart") states[descriptor.name] = isFeatureDshVersionCompatible(descriptor, dshVersion) && isFeatureEnabled(descriptor, settings);
|
|
@@ -7872,6 +8059,12 @@ window.__ModuleLoader__.load({
|
|
|
7872
8059
|
return CODINGNS_MODULES_FIELD;
|
|
7873
8060
|
}
|
|
7874
8061
|
});
|
|
8062
|
+
Object.defineProperty(exports, "CODINGNS_SESSION_TRANSLATION_FIELD", {
|
|
8063
|
+
enumerable: true,
|
|
8064
|
+
get: function() {
|
|
8065
|
+
return CODINGNS_SESSION_TRANSLATION_FIELD;
|
|
8066
|
+
}
|
|
8067
|
+
});
|
|
7875
8068
|
Object.defineProperty(exports, "CODINGNS_SETTINGS_ENTRY_IDS", {
|
|
7876
8069
|
enumerable: true,
|
|
7877
8070
|
get: function() {
|
|
@@ -7926,6 +8119,12 @@ window.__ModuleLoader__.load({
|
|
|
7926
8119
|
return DEFAULT_CODINGNS_CONTROL_BASE_URLS;
|
|
7927
8120
|
}
|
|
7928
8121
|
});
|
|
8122
|
+
Object.defineProperty(exports, "DEFAULT_CODINGNS_SETTINGS", {
|
|
8123
|
+
enumerable: true,
|
|
8124
|
+
get: function() {
|
|
8125
|
+
return DEFAULT_CODINGNS_SETTINGS;
|
|
8126
|
+
}
|
|
8127
|
+
});
|
|
7929
8128
|
Object.defineProperty(exports, "DEFAULT_FILE_MANAGEMENT_SETTINGS", {
|
|
7930
8129
|
enumerable: true,
|
|
7931
8130
|
get: function() {
|
|
@@ -16031,6 +16230,59 @@ window.__ModuleLoader__.load({
|
|
|
16031
16230
|
}
|
|
16032
16231
|
});
|
|
16033
16232
|
|
|
16233
|
+
window.__ModuleLoader__.load({
|
|
16234
|
+
id: "@jingyi0605/codingns4dsh",
|
|
16235
|
+
chunk: "client.session-translation.js",
|
|
16236
|
+
factory: () => { const require = __codingnsOwnerRequire;
|
|
16237
|
+
var module = { exports: {} };
|
|
16238
|
+
var exports = module.exports;
|
|
16239
|
+
//#region src/shared/contracts/session-translation.ts
|
|
16240
|
+
const SESSION_TRANSLATION_ADAPTER_IDS = [
|
|
16241
|
+
"command-code",
|
|
16242
|
+
"claude-code",
|
|
16243
|
+
"kimi",
|
|
16244
|
+
"gemini",
|
|
16245
|
+
"pi",
|
|
16246
|
+
"codex",
|
|
16247
|
+
"opencode",
|
|
16248
|
+
"grok",
|
|
16249
|
+
"mcode",
|
|
16250
|
+
"zcode",
|
|
16251
|
+
"codebuddy",
|
|
16252
|
+
"workbuddy",
|
|
16253
|
+
"cursor-cli",
|
|
16254
|
+
"kiro-cli",
|
|
16255
|
+
"qoder",
|
|
16256
|
+
"qoder-cn",
|
|
16257
|
+
"antigravity",
|
|
16258
|
+
"doubao"
|
|
16259
|
+
];
|
|
16260
|
+
const DEFAULT_SESSION_TRANSLATION_SETTINGS = {
|
|
16261
|
+
inputLanguage: "en",
|
|
16262
|
+
outputLanguage: "zh",
|
|
16263
|
+
bilingual: false
|
|
16264
|
+
};
|
|
16265
|
+
/** 所有内置外部 Agent 均可在会话模型选择器中开启翻译;DSH 原生 Agent 不在其中。 */
|
|
16266
|
+
function isSessionTranslationAdapter(adapterId) {
|
|
16267
|
+
return SESSION_TRANSLATION_ADAPTER_IDS.includes(adapterId);
|
|
16268
|
+
}
|
|
16269
|
+
//#endregion
|
|
16270
|
+
Object.defineProperty(exports, "DEFAULT_SESSION_TRANSLATION_SETTINGS", {
|
|
16271
|
+
enumerable: true,
|
|
16272
|
+
get: function() {
|
|
16273
|
+
return DEFAULT_SESSION_TRANSLATION_SETTINGS;
|
|
16274
|
+
}
|
|
16275
|
+
});
|
|
16276
|
+
Object.defineProperty(exports, "isSessionTranslationAdapter", {
|
|
16277
|
+
enumerable: true,
|
|
16278
|
+
get: function() {
|
|
16279
|
+
return isSessionTranslationAdapter;
|
|
16280
|
+
}
|
|
16281
|
+
});
|
|
16282
|
+
return module.exports;
|
|
16283
|
+
}
|
|
16284
|
+
});
|
|
16285
|
+
|
|
16034
16286
|
window.__ModuleLoader__.load({
|
|
16035
16287
|
id: "@jingyi0605/codingns4dsh",
|
|
16036
16288
|
chunk: "client.theme.js",
|
|
@@ -16092,6 +16344,8 @@ window.__ModuleLoader__.load({
|
|
|
16092
16344
|
primaryForeground: "var(--dsw-alias-label-primary-foreground, #fff)",
|
|
16093
16345
|
success: "var(--dsw-alias-state-success-primary, #16803c)",
|
|
16094
16346
|
error: "var(--dsw-alias-state-error-primary, #b42318)",
|
|
16347
|
+
warning: "var(--dsw-alias-state-warning-primary, #d99a00)",
|
|
16348
|
+
warningForeground: "#3d2c00",
|
|
16095
16349
|
fieldBorder: "var(--dsw-alias-border-l4, #d9d9d9)",
|
|
16096
16350
|
menuBorder: "var(--dsw-alias-border-l3, #d9d9d9)",
|
|
16097
16351
|
switchThumb: "var(--dsw-static-neutral-00, #fff)",
|
|
@@ -17652,11 +17906,53 @@ window.__ModuleLoader__.load({
|
|
|
17652
17906
|
"cli.thinkingLevelTitle": "Thinking level ({model})",
|
|
17653
17907
|
"cli.adapterEnabled": "{name} enabled",
|
|
17654
17908
|
"cli.adapterDisabled": "{name} disabled",
|
|
17909
|
+
"cli.translationConversation": "Translate conversation",
|
|
17910
|
+
"cli.translationConversationToggle": "Toggle conversation translation",
|
|
17655
17911
|
"lan.fieldListenPort": "listen port",
|
|
17656
17912
|
"lan.fieldDshPort": "DSH local port",
|
|
17657
17913
|
"lan.fieldMustBeNumber": "{field} must be a number",
|
|
17658
17914
|
"lan.fieldMustBeInteger": "{field} must be an integer from {minimum} to 65535",
|
|
17659
|
-
"workspace.sessionSettingsSaved": "Workspace session settings saved"
|
|
17915
|
+
"workspace.sessionSettingsSaved": "Workspace session settings saved",
|
|
17916
|
+
"feature.sessionTranslation.label": "Session translation",
|
|
17917
|
+
"feature.sessionTranslation.description": "Translate selected external Agent requests and replies while keeping tools, commands, paths, and original history unchanged.",
|
|
17918
|
+
"translation.inputTitle": "Translate requests before sending",
|
|
17919
|
+
"translation.inputLanguage": "Request language",
|
|
17920
|
+
"translation.outputTitle": "Translate visible replies",
|
|
17921
|
+
"translation.outputLanguage": "Reply language",
|
|
17922
|
+
"translation.modelTitle": "Translation model",
|
|
17923
|
+
"translation.modelFollowDefault": "Use the default DSH model",
|
|
17924
|
+
"translation.modelUnavailable": "Saved model is unavailable",
|
|
17925
|
+
"translation.modelLoading": "Loading available DSH models…",
|
|
17926
|
+
"translation.modelEmpty": "No DSH text models are available.",
|
|
17927
|
+
"translation.modelHelp": "DeepSeek official and configured third-party models are available here. Translation requests always disable thinking.",
|
|
17928
|
+
"translation.detailsTitle": "Translation details",
|
|
17929
|
+
"translation.viewDetails": "View translation details",
|
|
17930
|
+
"translation.statusTranslated": "Translated",
|
|
17931
|
+
"translation.statusFailed": "Translation failed; original kept",
|
|
17932
|
+
"translation.statusNotNeeded": "Already in the target language; translation skipped",
|
|
17933
|
+
"translation.detectedLanguage": "Detected language",
|
|
17934
|
+
"translation.modelNotUsed": "Not used; translation was unnecessary",
|
|
17935
|
+
"translation.originalText": "Original text",
|
|
17936
|
+
"translation.translatedText": "Translated / sent text",
|
|
17937
|
+
"translation.modelUsed": "Model used",
|
|
17938
|
+
"translation.modelUnknown": "Model information unavailable",
|
|
17939
|
+
"translation.modelOfficial": "DeepSeek official",
|
|
17940
|
+
"translation.modelThirdParty": "Third-party",
|
|
17941
|
+
"translation.saveRejected": "The translation settings could not be saved.",
|
|
17942
|
+
"translation.saved": "Translation settings saved",
|
|
17943
|
+
"translation.language.zh": "简体中文",
|
|
17944
|
+
"translation.language.en": "English",
|
|
17945
|
+
"translation.language.fr": "Français",
|
|
17946
|
+
"translation.language.de": "Deutsch",
|
|
17947
|
+
"translation.language.ja": "日本語",
|
|
17948
|
+
"translation.adapter.claude": "Claude Code",
|
|
17949
|
+
"translation.adapter.codex": "Codex",
|
|
17950
|
+
"translation.adapter.pi": "Pi",
|
|
17951
|
+
"translation.adapter.opencode": "OpenCode",
|
|
17952
|
+
"translation.adapter.antigravity": "Antigravity",
|
|
17953
|
+
"translation.adapter.grok": "Grok",
|
|
17954
|
+
"translation.adapter.cursor": "Cursor",
|
|
17955
|
+
"translation.adapter.kiro": "Kiro"
|
|
17660
17956
|
};
|
|
17661
17957
|
const zh$9 = {
|
|
17662
17958
|
"common.listSeparator": "、",
|
|
@@ -17665,11 +17961,53 @@ window.__ModuleLoader__.load({
|
|
|
17665
17961
|
"cli.thinkingLevelTitle": "思考等级({model})",
|
|
17666
17962
|
"cli.adapterEnabled": "已启用 {name}",
|
|
17667
17963
|
"cli.adapterDisabled": "已停用 {name}",
|
|
17964
|
+
"cli.translationConversation": "翻译对话",
|
|
17965
|
+
"cli.translationConversationToggle": "切换对话翻译",
|
|
17668
17966
|
"lan.fieldListenPort": "监听端口",
|
|
17669
17967
|
"lan.fieldDshPort": "DSH 本地端口",
|
|
17670
17968
|
"lan.fieldMustBeNumber": "{field} 必须是数字",
|
|
17671
17969
|
"lan.fieldMustBeInteger": "{field} 必须是 {minimum} 到 65535 的整数",
|
|
17672
|
-
"workspace.sessionSettingsSaved": "工作区会话设置已保存"
|
|
17970
|
+
"workspace.sessionSettingsSaved": "工作区会话设置已保存",
|
|
17971
|
+
"feature.sessionTranslation.label": "会话翻译",
|
|
17972
|
+
"feature.sessionTranslation.description": "为选定的外部 Agent 翻译请求和回复,同时保留工具、命令、路径与原始历史。",
|
|
17973
|
+
"translation.inputTitle": "发送前翻译请求",
|
|
17974
|
+
"translation.inputLanguage": "请求目标语言",
|
|
17975
|
+
"translation.outputTitle": "翻译界面回复",
|
|
17976
|
+
"translation.outputLanguage": "回复语言",
|
|
17977
|
+
"translation.modelTitle": "翻译模型",
|
|
17978
|
+
"translation.modelFollowDefault": "跟随 DSH 默认模型",
|
|
17979
|
+
"translation.modelUnavailable": "已保存的模型当前不可用",
|
|
17980
|
+
"translation.modelLoading": "正在加载可用的 DSH 模型…",
|
|
17981
|
+
"translation.modelEmpty": "当前没有可用的 DSH 文本模型。",
|
|
17982
|
+
"translation.modelHelp": "这里可以选择 DeepSeek 官方模型或已配置的第三方模型;翻译请求始终关闭思考。",
|
|
17983
|
+
"translation.detailsTitle": "翻译详情",
|
|
17984
|
+
"translation.viewDetails": "查看翻译详情",
|
|
17985
|
+
"translation.statusTranslated": "已翻译",
|
|
17986
|
+
"translation.statusFailed": "翻译失败,已保留原文",
|
|
17987
|
+
"translation.statusNotNeeded": "原文已是目标语言,无需翻译",
|
|
17988
|
+
"translation.detectedLanguage": "检测到的语言",
|
|
17989
|
+
"translation.modelNotUsed": "未调用,原文无需翻译",
|
|
17990
|
+
"translation.originalText": "原文",
|
|
17991
|
+
"translation.translatedText": "译文 / 实际发送文本",
|
|
17992
|
+
"translation.modelUsed": "实际翻译模型",
|
|
17993
|
+
"translation.modelUnknown": "暂无模型信息",
|
|
17994
|
+
"translation.modelOfficial": "DeepSeek 官方",
|
|
17995
|
+
"translation.modelThirdParty": "第三方",
|
|
17996
|
+
"translation.saveRejected": "会话翻译设置未能保存。",
|
|
17997
|
+
"translation.saved": "会话翻译设置已保存",
|
|
17998
|
+
"translation.language.zh": "简体中文",
|
|
17999
|
+
"translation.language.en": "英语",
|
|
18000
|
+
"translation.language.fr": "法语",
|
|
18001
|
+
"translation.language.de": "德语",
|
|
18002
|
+
"translation.language.ja": "日语",
|
|
18003
|
+
"translation.adapter.claude": "Claude Code",
|
|
18004
|
+
"translation.adapter.codex": "Codex",
|
|
18005
|
+
"translation.adapter.pi": "Pi",
|
|
18006
|
+
"translation.adapter.opencode": "OpenCode",
|
|
18007
|
+
"translation.adapter.antigravity": "Antigravity",
|
|
18008
|
+
"translation.adapter.grok": "Grok",
|
|
18009
|
+
"translation.adapter.cursor": "Cursor",
|
|
18010
|
+
"translation.adapter.kiro": "Kiro"
|
|
17673
18011
|
};
|
|
17674
18012
|
//#endregion
|
|
17675
18013
|
//#region src/client/locales/peerHost.ts
|
|
@@ -18622,7 +18960,9 @@ window.__ModuleLoader__.load({
|
|
|
18622
18960
|
"awb.notifications.question": "需要回答",
|
|
18623
18961
|
"awb.notifications.approval": "等待审批",
|
|
18624
18962
|
"awb.notifications.questionTag": "问题",
|
|
18625
|
-
"awb.notifications.approvalTag": "
|
|
18963
|
+
"awb.notifications.approvalTag": "权限申请",
|
|
18964
|
+
"awb.notifications.requestPrefix": "有",
|
|
18965
|
+
"awb.notifications.requestSuffix": "需要你来处理",
|
|
18626
18966
|
"awb.notifications.autoClose": "通知自动关闭",
|
|
18627
18967
|
"awb.notifications.autoCloseHint": "启用后,失败、提问与审批的气泡在设定时间后自动收起;完成提示始终固定 10 秒关闭。未读记录仍会保留。",
|
|
18628
18968
|
"awb.notifications.autoCloseDuration": "自动关闭时间",
|
|
@@ -18630,13 +18970,16 @@ window.__ModuleLoader__.load({
|
|
|
18630
18970
|
"awb.notifications.seconds": "秒",
|
|
18631
18971
|
"awb.notifications.open": "查看会话",
|
|
18632
18972
|
"awb.notifications.dismiss": "收起提醒",
|
|
18973
|
+
"awb.notifications.collapse": "收起通知",
|
|
18974
|
+
"awb.notifications.expand": "展开通知",
|
|
18633
18975
|
"awb.notifications.list": "提醒列表",
|
|
18976
|
+
"awb.notifications.clearAll": "一键清理",
|
|
18977
|
+
"awb.notifications.clearAllLabel": "一键清理全部通知",
|
|
18634
18978
|
"awb.notifications.unread": "{count} 条未读",
|
|
18635
18979
|
"awb.notifications.pending": "{count} 项待处理",
|
|
18980
|
+
"awb.notifications.unreadFilterLabel": "筛选未读通知:{count} 条未读",
|
|
18981
|
+
"awb.notifications.pendingFilterLabel": "筛选待处理通知:{count} 项待处理",
|
|
18636
18982
|
"awb.notifications.empty": "暂无提醒",
|
|
18637
|
-
"awb.notifications.next": "下一页",
|
|
18638
|
-
"awb.notifications.previous": "上一页",
|
|
18639
|
-
"awb.notifications.closeList": "关闭提醒列表",
|
|
18640
18983
|
"awb.notifications.disconnected": "远端暂不可达",
|
|
18641
18984
|
"awb.notifications.expired": "提醒已失效",
|
|
18642
18985
|
"awb.notifications.actionUnavailable": "通知操作暂不可用,请重试",
|
|
@@ -18681,6 +19024,14 @@ window.__ModuleLoader__.load({
|
|
|
18681
19024
|
"awb.call.arguments": "调用参数",
|
|
18682
19025
|
"awb.call.result": "返回结果",
|
|
18683
19026
|
"awb.call.toolDetails": "查看参数与结果",
|
|
19027
|
+
"awb.call.step": "执行步骤",
|
|
19028
|
+
"awb.call.stepDetails": "展开查看步骤中的工具调用",
|
|
19029
|
+
"awb.call.separator": "、",
|
|
19030
|
+
"awb.call.toolCount": "{count} 次调用",
|
|
19031
|
+
"awb.call.stepRead": "已读取文件",
|
|
19032
|
+
"awb.call.stepSearch": "已搜索网页",
|
|
19033
|
+
"awb.call.stepWorkspace": "已调用工具",
|
|
19034
|
+
"awb.call.stepTool": "已执行操作",
|
|
18684
19035
|
"awb.preparationUnsupported": "当前 Host 不支持仅准备资源,请更新 Host 后再操作。",
|
|
18685
19036
|
"awb.title": "智能助理",
|
|
18686
19037
|
"awb.create": "创建助理",
|
|
@@ -18750,7 +19101,8 @@ window.__ModuleLoader__.load({
|
|
|
18750
19101
|
"awb.resetFinalConfirm": "确定要重置助理吗?助理配置、对话和派生索引将被清空,无法从此界面撤销。原始项目会话和下载素材会保留。",
|
|
18751
19102
|
"awb.confirm": "确认",
|
|
18752
19103
|
"awb.busy": "处理中…",
|
|
18753
|
-
"awb.loading": "
|
|
19104
|
+
"awb.loading": "正在准备助理",
|
|
19105
|
+
"awb.loadingHint": "正在准备你的对话…",
|
|
18754
19106
|
"awb.retry": "重试",
|
|
18755
19107
|
"awb.summary": "历史交流摘要",
|
|
18756
19108
|
"awb.saved": "配置已保存",
|
|
@@ -18777,6 +19129,8 @@ window.__ModuleLoader__.load({
|
|
|
18777
19129
|
"awb.notifications.approval": "Approval needed",
|
|
18778
19130
|
"awb.notifications.questionTag": "Question",
|
|
18779
19131
|
"awb.notifications.approvalTag": "Permission request",
|
|
19132
|
+
"awb.notifications.requestPrefix": "There is a",
|
|
19133
|
+
"awb.notifications.requestSuffix": "waiting for your response",
|
|
18780
19134
|
"awb.notifications.autoClose": "Auto-close notices",
|
|
18781
19135
|
"awb.notifications.autoCloseHint": "When enabled, failure, question and approval notices collapse after the selected time; completion notices always close after 10 seconds. Unread records remain available.",
|
|
18782
19136
|
"awb.notifications.autoCloseDuration": "Auto-close time",
|
|
@@ -18784,13 +19138,16 @@ window.__ModuleLoader__.load({
|
|
|
18784
19138
|
"awb.notifications.seconds": " seconds",
|
|
18785
19139
|
"awb.notifications.open": "View session",
|
|
18786
19140
|
"awb.notifications.dismiss": "Collapse notice",
|
|
19141
|
+
"awb.notifications.collapse": "Collapse notifications",
|
|
19142
|
+
"awb.notifications.expand": "Expand notifications",
|
|
18787
19143
|
"awb.notifications.list": "Notice list",
|
|
19144
|
+
"awb.notifications.clearAll": "Clear all",
|
|
19145
|
+
"awb.notifications.clearAllLabel": "Clear all notifications",
|
|
18788
19146
|
"awb.notifications.unread": "{count} unread",
|
|
18789
19147
|
"awb.notifications.pending": "{count} pending",
|
|
19148
|
+
"awb.notifications.unreadFilterLabel": "Filter unread notifications: {count} unread",
|
|
19149
|
+
"awb.notifications.pendingFilterLabel": "Filter pending notifications: {count} pending",
|
|
18790
19150
|
"awb.notifications.empty": "No notices",
|
|
18791
|
-
"awb.notifications.next": "Next page",
|
|
18792
|
-
"awb.notifications.previous": "Previous page",
|
|
18793
|
-
"awb.notifications.closeList": "Close notice list",
|
|
18794
19151
|
"awb.notifications.disconnected": "Remote host unavailable",
|
|
18795
19152
|
"awb.notifications.expired": "Notice expired",
|
|
18796
19153
|
"awb.notifications.actionUnavailable": "Notice action is unavailable. Please try again.",
|
|
@@ -18835,6 +19192,14 @@ window.__ModuleLoader__.load({
|
|
|
18835
19192
|
"awb.call.arguments": "Arguments",
|
|
18836
19193
|
"awb.call.result": "Result",
|
|
18837
19194
|
"awb.call.toolDetails": "View arguments and result",
|
|
19195
|
+
"awb.call.step": "Execution step",
|
|
19196
|
+
"awb.call.stepDetails": "Expand to view the tools in this step",
|
|
19197
|
+
"awb.call.separator": ", ",
|
|
19198
|
+
"awb.call.toolCount": "{count} calls",
|
|
19199
|
+
"awb.call.stepRead": "Read files",
|
|
19200
|
+
"awb.call.stepSearch": "Searched the web",
|
|
19201
|
+
"awb.call.stepWorkspace": "Called tools",
|
|
19202
|
+
"awb.call.stepTool": "Completed an action",
|
|
18838
19203
|
"awb.preparationUnsupported": "This Host does not support preparing resources without applying settings. Update the Host before proceeding.",
|
|
18839
19204
|
"awb.title": "Assistant",
|
|
18840
19205
|
"awb.create": "Create assistant",
|
|
@@ -18904,7 +19269,8 @@ window.__ModuleLoader__.load({
|
|
|
18904
19269
|
"awb.resetFinalConfirm": "Reset your assistant? Settings, conversation, and derived indexes will be cleared and cannot be restored from this page. Original project sessions and downloaded assets are kept.",
|
|
18905
19270
|
"awb.confirm": "Confirm",
|
|
18906
19271
|
"awb.busy": "Working…",
|
|
18907
|
-
"awb.loading": "
|
|
19272
|
+
"awb.loading": "Preparing assistant",
|
|
19273
|
+
"awb.loadingHint": "Preparing your conversation…",
|
|
18908
19274
|
"awb.retry": "Retry",
|
|
18909
19275
|
"awb.summary": "Conversation summary",
|
|
18910
19276
|
"awb.saved": "Configuration saved",
|
|
@@ -20061,6 +20427,7 @@ window.__ModuleLoader__.load({
|
|
|
20061
20427
|
const require_transport = require("@jingyi0605/codingns4dsh/client.transport.js");
|
|
20062
20428
|
const require_model_catalog_cache = require("@jingyi0605/codingns4dsh/client.model-catalog-cache.js");
|
|
20063
20429
|
const require_assistant_notifications = require("@jingyi0605/codingns4dsh/client.assistant-notifications.js");
|
|
20430
|
+
const require_session_translation = require("@jingyi0605/codingns4dsh/client.session-translation.js");
|
|
20064
20431
|
const require_theme = require("@jingyi0605/codingns4dsh/client.theme.js");
|
|
20065
20432
|
const require_react_dom$1 = require("@jingyi0605/codingns4dsh/client.react-dom.js");
|
|
20066
20433
|
const require_manager = require("@jingyi0605/codingns4dsh/client.manager.js");
|
|
@@ -27448,7 +27815,7 @@ window.__ModuleLoader__.load({
|
|
|
27448
27815
|
const method = channel === "/codingns" ? endpoint : channel === "/api" ? endpoint.replace(/^codingns\//u, "") : "";
|
|
27449
27816
|
if (peerHostId === null) {
|
|
27450
27817
|
const input = CATALOG_ENDPOINTS.has(method) ? {
|
|
27451
|
-
...asRecord$
|
|
27818
|
+
...asRecord$8(payload),
|
|
27452
27819
|
catalogHostId: "local"
|
|
27453
27820
|
} : payload;
|
|
27454
27821
|
return rpc.call(channel, endpoint, input, signal);
|
|
@@ -27472,18 +27839,18 @@ window.__ModuleLoader__.load({
|
|
|
27472
27839
|
});
|
|
27473
27840
|
let envelope = null;
|
|
27474
27841
|
try {
|
|
27475
|
-
envelope = asRecord$
|
|
27842
|
+
envelope = asRecord$8(JSON.parse(response.body));
|
|
27476
27843
|
} catch {}
|
|
27477
27844
|
if (response.status < 200 || response.status >= 300) {
|
|
27478
|
-
const error = asRecord$
|
|
27845
|
+
const error = asRecord$8(envelope?.error);
|
|
27479
27846
|
return failure$1(typeof error?.code === "string" ? error.code : "PEER_HOST_PROXY_UNREACHABLE", typeof error?.message === "string" ? error.message : require_transport.resolveCodingNsTranslator(locale)("cli.peerHostRpcFailed", { status: response.status }));
|
|
27480
27847
|
}
|
|
27481
|
-
const result = asRecord$
|
|
27848
|
+
const result = asRecord$8(envelope?.result);
|
|
27482
27849
|
if (result?.ok === true && Object.hasOwn(result, "value")) return {
|
|
27483
27850
|
ok: true,
|
|
27484
27851
|
value: result.value
|
|
27485
27852
|
};
|
|
27486
|
-
const error = asRecord$
|
|
27853
|
+
const error = asRecord$8(result?.error);
|
|
27487
27854
|
if (result?.ok === false && typeof error?.code === "string" && typeof error.message === "string") return failure$1(error.code, error.message);
|
|
27488
27855
|
return failure$1("PEER_HOST_RESPONSE_INVALID", require_transport.resolveCodingNsTranslator(locale)("cli.peerHostRpcInvalid"));
|
|
27489
27856
|
} };
|
|
@@ -27502,7 +27869,7 @@ window.__ModuleLoader__.load({
|
|
|
27502
27869
|
}
|
|
27503
27870
|
};
|
|
27504
27871
|
}
|
|
27505
|
-
function asRecord$
|
|
27872
|
+
function asRecord$8(value) {
|
|
27506
27873
|
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
|
|
27507
27874
|
}
|
|
27508
27875
|
//#endregion
|
|
@@ -28344,7 +28711,7 @@ window.__ModuleLoader__.load({
|
|
|
28344
28711
|
}, hostStatus === null ? t("terminal.readingStatus") : t("terminal.currentStatus", {
|
|
28345
28712
|
status: hostStatus.effectiveEnabled ? t("terminal.enhanced") : t("terminal.basic"),
|
|
28346
28713
|
platform: platformLabel(hostStatus.platform, t)
|
|
28347
|
-
})), (0, react.createElement)(Field, {
|
|
28714
|
+
})), (0, react.createElement)(Field$1, {
|
|
28348
28715
|
label: t("terminal.newDefault"),
|
|
28349
28716
|
help: t("terminal.defaultProfileHelp")
|
|
28350
28717
|
}, (0, react.createElement)("select", {
|
|
@@ -28359,7 +28726,7 @@ window.__ModuleLoader__.load({
|
|
|
28359
28726
|
key: profile.profileId,
|
|
28360
28727
|
value: profile.profileId,
|
|
28361
28728
|
disabled: !profile.available
|
|
28362
|
-
}, profile.label))), hostStatus?.fallbackReason === void 0 ? null : (0, react.createElement)("small", { style: helpStyle }, hostStatus.fallbackReason)), (0, react.createElement)(Field, {
|
|
28729
|
+
}, profile.label))), hostStatus?.fallbackReason === void 0 ? null : (0, react.createElement)("small", { style: helpStyle }, hostStatus.fallbackReason)), (0, react.createElement)(Field$1, {
|
|
28363
28730
|
label: t("terminal.bindingScope"),
|
|
28364
28731
|
help: t("terminal.workspaceBindingHelp")
|
|
28365
28732
|
}, (0, react.createElement)("select", {
|
|
@@ -28398,7 +28765,7 @@ window.__ModuleLoader__.load({
|
|
|
28398
28765
|
value: appearance.cursorColor,
|
|
28399
28766
|
disabled,
|
|
28400
28767
|
onChange: (cursorColor) => updateAppearance({ cursorColor })
|
|
28401
|
-
}), (0, react.createElement)(Field, { label: t("terminal.cursorBlink") }, (0, react.createElement)("label", { style: {
|
|
28768
|
+
}), (0, react.createElement)(Field$1, { label: t("terminal.cursorBlink") }, (0, react.createElement)("label", { style: {
|
|
28402
28769
|
display: "flex",
|
|
28403
28770
|
alignItems: "center",
|
|
28404
28771
|
justifyContent: "space-between",
|
|
@@ -28426,7 +28793,7 @@ window.__ModuleLoader__.load({
|
|
|
28426
28793
|
step: .1,
|
|
28427
28794
|
disabled,
|
|
28428
28795
|
onChange: (lineHeight) => updateAppearance({ lineHeight })
|
|
28429
|
-
}), (0, react.createElement)(Field, { label: t("terminal.cursorShape") }, (0, react.createElement)("select", {
|
|
28796
|
+
}), (0, react.createElement)(Field$1, { label: t("terminal.cursorShape") }, (0, react.createElement)("select", {
|
|
28430
28797
|
value: appearance.cursorStyle,
|
|
28431
28798
|
disabled,
|
|
28432
28799
|
onChange: (event) => updateAppearance({ cursorStyle: parseCursorStyle(event.currentTarget.value) }),
|
|
@@ -28441,7 +28808,7 @@ window.__ModuleLoader__.load({
|
|
|
28441
28808
|
onChange: (scrollback) => updateAppearance({ scrollback })
|
|
28442
28809
|
})));
|
|
28443
28810
|
}
|
|
28444
|
-
function Field({ label, help, children }) {
|
|
28811
|
+
function Field$1({ label, help, children }) {
|
|
28445
28812
|
return (0, react.createElement)("div", { style: {
|
|
28446
28813
|
display: "flex",
|
|
28447
28814
|
flexDirection: "column",
|
|
@@ -28457,7 +28824,7 @@ window.__ModuleLoader__.load({
|
|
|
28457
28824
|
}, "ⓘ");
|
|
28458
28825
|
}
|
|
28459
28826
|
function ColorField({ label, value, disabled, onChange }) {
|
|
28460
|
-
return (0, react.createElement)(Field, { label }, (0, react.createElement)("div", { style: rowStyle$2 }, (0, react.createElement)("input", {
|
|
28827
|
+
return (0, react.createElement)(Field$1, { label }, (0, react.createElement)("div", { style: rowStyle$2 }, (0, react.createElement)("input", {
|
|
28461
28828
|
type: "color",
|
|
28462
28829
|
value,
|
|
28463
28830
|
disabled,
|
|
@@ -28470,7 +28837,7 @@ window.__ModuleLoader__.load({
|
|
|
28470
28837
|
}), (0, react.createElement)("code", { style: { flex: 1 } }, value)));
|
|
28471
28838
|
}
|
|
28472
28839
|
function NumberField({ label, value, min, max, step, disabled, onChange }) {
|
|
28473
|
-
return (0, react.createElement)(Field, { label }, (0, react.createElement)("div", { style: rowStyle$2 }, (0, react.createElement)("input", {
|
|
28840
|
+
return (0, react.createElement)(Field$1, { label }, (0, react.createElement)("div", { style: rowStyle$2 }, (0, react.createElement)("input", {
|
|
28474
28841
|
type: "number",
|
|
28475
28842
|
value,
|
|
28476
28843
|
min,
|
|
@@ -28930,11 +29297,11 @@ window.__ModuleLoader__.load({
|
|
|
28930
29297
|
const iterator = (await api.follow())[Symbol.asyncIterator]();
|
|
28931
29298
|
const first = await iterator.next();
|
|
28932
29299
|
await iterator.return?.();
|
|
28933
|
-
const value = asRecord$
|
|
29300
|
+
const value = asRecord$7(asRecord$7(first.value)?.value);
|
|
28934
29301
|
const records = Array.isArray(value?.items) ? value.items : [];
|
|
28935
29302
|
const globalArchived = readStringArray(value?.archivedSessionIds);
|
|
28936
29303
|
return records.flatMap((item) => {
|
|
28937
|
-
const record = asRecord$
|
|
29304
|
+
const record = asRecord$7(item);
|
|
28938
29305
|
const workspaceId = readString$1(record?.workspaceId);
|
|
28939
29306
|
if (workspaceId === void 0) return [];
|
|
28940
29307
|
const path = readString$1(record?.path);
|
|
@@ -28950,12 +29317,12 @@ window.__ModuleLoader__.load({
|
|
|
28950
29317
|
}
|
|
28951
29318
|
async function readSessionList(api) {
|
|
28952
29319
|
if (api?.list === void 0) return [];
|
|
28953
|
-
const result = asRecord$
|
|
29320
|
+
const result = asRecord$7(unwrapRemoteValue$1(await api.list({})));
|
|
28954
29321
|
return (Array.isArray(result?.items) ? result.items : []).flatMap((item) => {
|
|
28955
|
-
const record = asRecord$
|
|
29322
|
+
const record = asRecord$7(item);
|
|
28956
29323
|
const sessionId = readString$1(record?.sessionId);
|
|
28957
29324
|
if (sessionId === void 0) return [];
|
|
28958
|
-
const titleValue = asRecord$
|
|
29325
|
+
const titleValue = asRecord$7(asRecord$7(record?.projections)?.values)?.title;
|
|
28959
29326
|
const cwd = readString$1(record?.cwd);
|
|
28960
29327
|
const workspaceIdValue = readString$1(record?.workspaceId);
|
|
28961
29328
|
const archivedAt = typeof record?.archivedAt === "number" && Number.isFinite(record.archivedAt) ? record.archivedAt : 0;
|
|
@@ -29027,7 +29394,7 @@ window.__ModuleLoader__.load({
|
|
|
29027
29394
|
"value",
|
|
29028
29395
|
"data"
|
|
29029
29396
|
]) {
|
|
29030
|
-
const workspace = asRecord$
|
|
29397
|
+
const workspace = asRecord$7(value[key]);
|
|
29031
29398
|
const id = readString$1(workspace?.workspaceId) ?? readString$1(workspace?.workspaceID) ?? readString$1(workspace?.id);
|
|
29032
29399
|
if (id !== void 0) return id;
|
|
29033
29400
|
}
|
|
@@ -29414,8 +29781,8 @@ window.__ModuleLoader__.load({
|
|
|
29414
29781
|
}
|
|
29415
29782
|
function normalizeRemote(value) {
|
|
29416
29783
|
if (!isRecord$5(value)) return {};
|
|
29417
|
-
const workspace = asRecord$
|
|
29418
|
-
const session = asRecord$
|
|
29784
|
+
const workspace = asRecord$7(readRemoteProperty(value, "workspace")) ?? asRecord$7(readRemoteProperty(value, "workspaceController"));
|
|
29785
|
+
const session = asRecord$7(readRemoteProperty(value, "session")) ?? asRecord$7(readRemoteProperty(value, "sessionController"));
|
|
29419
29786
|
return {
|
|
29420
29787
|
...workspace ? { workspace } : {},
|
|
29421
29788
|
...session ? { session } : {}
|
|
@@ -29438,12 +29805,12 @@ window.__ModuleLoader__.load({
|
|
|
29438
29805
|
return result === void 0 ? [] : [result];
|
|
29439
29806
|
}) : [];
|
|
29440
29807
|
}
|
|
29441
|
-
function asRecord$
|
|
29808
|
+
function asRecord$7(value) {
|
|
29442
29809
|
return isRecord$5(value) ? value : void 0;
|
|
29443
29810
|
}
|
|
29444
29811
|
/** DSH Remote 的直接调用返回 RemoteResult;测试桩和旧宿主可能直接返回 value。 */
|
|
29445
29812
|
function unwrapRemoteValue$1(value) {
|
|
29446
|
-
const record = asRecord$
|
|
29813
|
+
const record = asRecord$7(value);
|
|
29447
29814
|
if (record === void 0 || typeof record.ok !== "boolean") return value;
|
|
29448
29815
|
return record.ok ? record.value : void 0;
|
|
29449
29816
|
}
|
|
@@ -29462,8 +29829,8 @@ window.__ModuleLoader__.load({
|
|
|
29462
29829
|
const WORKSPACE_SESSION_HIDDEN_FILTER_CHECK_ATTRIBUTE = "data-codingns-hidden-workspace-filter-check";
|
|
29463
29830
|
const WORKSPACE_SESSION_HIDDEN_FILTER_BOUND_ATTRIBUTE = "data-codingns-hidden-workspace-filter-bound";
|
|
29464
29831
|
const MENU_ATTRIBUTE$1 = "aria-haspopup";
|
|
29465
|
-
const WORKSPACE_MENU_PATTERN = /(
|
|
29466
|
-
const WORKSPACE_FILTER_PATTERN = /(
|
|
29832
|
+
const WORKSPACE_MENU_PATTERN = /(?:更多|菜单|选项|操作|more|menu|option|action)/iu;
|
|
29833
|
+
const WORKSPACE_FILTER_PATTERN = /(?:视图选项|筛选选项|筛选会话|分组方式|排序方式|view\s*options?|filter\s*(?:options?|sessions?)|group\s*by|sort\s*by)/iu;
|
|
29467
29834
|
/**
|
|
29468
29835
|
* 给原生工作区菜单增加隐藏动作,并通过工作区筛选菜单控制恢复列表。
|
|
29469
29836
|
*
|
|
@@ -29536,6 +29903,7 @@ window.__ModuleLoader__.load({
|
|
|
29536
29903
|
workspaceIds.add(workspaceId);
|
|
29537
29904
|
bindWorkspaceMenuTriggers(header, workspaceId, () => {
|
|
29538
29905
|
activeMenuWorkspaceId = workspaceId;
|
|
29906
|
+
activeFilterTrigger = void 0;
|
|
29539
29907
|
activeMenuKind = "workspace";
|
|
29540
29908
|
menuContextPending = true;
|
|
29541
29909
|
scheduleScan();
|
|
@@ -29546,6 +29914,7 @@ window.__ModuleLoader__.load({
|
|
|
29546
29914
|
bindWorkspaceFilterTriggers(dom, (trigger) => {
|
|
29547
29915
|
if (suppressFilterTrigger) return;
|
|
29548
29916
|
activeFilterTrigger = trigger;
|
|
29917
|
+
activeMenuWorkspaceId = void 0;
|
|
29549
29918
|
activeMenuKind = "filter";
|
|
29550
29919
|
menuContextPending = true;
|
|
29551
29920
|
scheduleScan();
|
|
@@ -29553,8 +29922,14 @@ window.__ModuleLoader__.load({
|
|
|
29553
29922
|
});
|
|
29554
29923
|
const menus = findWorkspaceMenus(dom);
|
|
29555
29924
|
knownNativeMenus = new Set(menus);
|
|
29925
|
+
const menuContextFresh = menuContextPending;
|
|
29556
29926
|
if (menus.length > 0) menuContextPending = false;
|
|
29557
|
-
|
|
29927
|
+
const currentMenu = [...menus].reverse().find(isVisibleMenu);
|
|
29928
|
+
const currentMenuKind = currentMenu === void 0 ? activeMenuKind : isWorkspaceFilterMenu(currentMenu) ? "filter" : "workspace";
|
|
29929
|
+
const filterContextFresh = menuContextFresh && activeMenuKind === "filter";
|
|
29930
|
+
const filterMenus = currentMenuKind === "filter" ? selectFilterMenus(menus, menuWorkspaceIds, activeMenuWorkspaceId, filterContextFresh) : [];
|
|
29931
|
+
const currentMenuOwnsFilterAction = currentMenu !== void 0 && currentMenu.querySelector(`[data-codingns-hidden-workspace-filter]`) !== null;
|
|
29932
|
+
if (currentMenuKind === "filter" && (filterContextFresh || currentMenuOwnsFilterAction)) injectFilterMenuAction(dom, filterMenus, showHiddenWorkspaces, () => {
|
|
29558
29933
|
showHiddenWorkspaces = !showHiddenWorkspaces;
|
|
29559
29934
|
scheduleScan();
|
|
29560
29935
|
}, (menu) => closeFilterMenu(activeFilterTrigger, menu, () => {
|
|
@@ -29563,10 +29938,11 @@ window.__ModuleLoader__.load({
|
|
|
29563
29938
|
suppressFilterTrigger = false;
|
|
29564
29939
|
};
|
|
29565
29940
|
}), t);
|
|
29566
|
-
else injectWorkspaceMenuActions(selectWorkspaceMenus(menus), dom, activeMenuWorkspaceId, workspaceIds, menuWorkspaceIds, (workspaceId) => updateVisibility(workspaceId, true), t);
|
|
29941
|
+
else injectWorkspaceMenuActions(selectWorkspaceMenus(menus, menuContextFresh, menuWorkspaceIds), dom, menuContextFresh ? activeMenuWorkspaceId : void 0, workspaceIds, menuWorkspaceIds, (workspaceId) => updateVisibility(workspaceId, true), t);
|
|
29567
29942
|
if (menus.length === 0 && !menuContextPending) {
|
|
29568
29943
|
activeMenuWorkspaceId = void 0;
|
|
29569
29944
|
activeMenuKind = void 0;
|
|
29945
|
+
activeFilterTrigger = void 0;
|
|
29570
29946
|
}
|
|
29571
29947
|
if (showHiddenWorkspaces) injectHiddenWorkspaceFooter(dom, headers, workspaces, hiddenWorkspaceIds, (workspaceId) => updateVisibility(workspaceId, false), t);
|
|
29572
29948
|
} finally {
|
|
@@ -29674,25 +30050,26 @@ window.__ModuleLoader__.load({
|
|
|
29674
30050
|
let current = item.parentElement;
|
|
29675
30051
|
for (let depth = 0; depth < 8 && current !== null; depth += 1, current = current.parentElement) counts.set(current, (counts.get(current) ?? 0) + 1);
|
|
29676
30052
|
}
|
|
29677
|
-
const candidates = [...counts.keys()].filter((element) => (counts.get(element) ?? 0) >= 3 &&
|
|
30053
|
+
const candidates = [...counts.keys()].filter((element) => (counts.get(element) ?? 0) >= 3 && isWorkspaceFilterMenu(element));
|
|
29678
30054
|
return candidates.filter((element) => !candidates.some((other) => other !== element && element.contains(other)));
|
|
29679
30055
|
}
|
|
29680
30056
|
/**
|
|
29681
30057
|
* 菜单 Portal 在关闭时可能短暂保留旧节点。先过滤不可见节点,再按菜单内容
|
|
29682
30058
|
* 区分筛选菜单和工作区操作菜单,避免旧筛选菜单抢走当前工作区菜单的注入目标。
|
|
29683
30059
|
*/
|
|
29684
|
-
function selectFilterMenus(menus, menuWorkspaceIds, activeWorkspaceId) {
|
|
30060
|
+
function selectFilterMenus(menus, menuWorkspaceIds, activeWorkspaceId, allowUnidentified) {
|
|
29685
30061
|
const visible = menus.filter(isVisibleMenu);
|
|
29686
|
-
const candidates =
|
|
29687
|
-
|
|
29688
|
-
|
|
30062
|
+
const candidates = visible.filter(isWorkspaceFilterMenu);
|
|
30063
|
+
const owned = candidates.filter((menu) => menu.querySelector(`[${WORKSPACE_SESSION_HIDDEN_FILTER_ATTRIBUTE}]`) !== null);
|
|
30064
|
+
if (owned.length > 0) return [owned[owned.length - 1]];
|
|
30065
|
+
if (allowUnidentified && candidates.length > 0) return [candidates[candidates.length - 1]];
|
|
30066
|
+
if (!allowUnidentified) return [];
|
|
30067
|
+
const fallback = visible.filter((menu) => menuWorkspaceIds.get(menu) === void 0 && (activeWorkspaceId === void 0 || resolveWorkspaceId(menu) !== activeWorkspaceId) && menu.querySelector(`[data-codingns-hidden-workspace-menu]`) === null);
|
|
29689
30068
|
return fallback.length > 0 ? [fallback[fallback.length - 1]] : [];
|
|
29690
30069
|
}
|
|
29691
|
-
function selectWorkspaceMenus(menus) {
|
|
29692
|
-
const
|
|
29693
|
-
|
|
29694
|
-
const available = candidates.length > 0 ? candidates : visible.length > 0 ? visible : menus;
|
|
29695
|
-
return available.length > 0 ? [available[available.length - 1]] : [];
|
|
30070
|
+
function selectWorkspaceMenus(menus, allowUnidentified, menuWorkspaceIds) {
|
|
30071
|
+
const candidates = menus.filter(isVisibleMenu).filter((menu) => !isWorkspaceFilterMenu(menu) && (allowUnidentified || resolveWorkspaceId(menu) !== void 0 || menuWorkspaceIds.get(menu) !== void 0));
|
|
30072
|
+
return candidates.length > 0 ? [candidates[candidates.length - 1]] : [];
|
|
29696
30073
|
}
|
|
29697
30074
|
function isVisibleMenu(menu) {
|
|
29698
30075
|
if (menu.hasAttribute("hidden") || menu.getAttribute("aria-hidden") === "true" || menu.getAttribute("data-state") === "closed") return false;
|
|
@@ -29700,7 +30077,8 @@ window.__ModuleLoader__.load({
|
|
|
29700
30077
|
return style.display !== "none" && style.visibility !== "hidden";
|
|
29701
30078
|
}
|
|
29702
30079
|
function isWorkspaceFilterMenu(element) {
|
|
29703
|
-
|
|
30080
|
+
const label = `${element.textContent ?? ""} ${element.getAttribute("aria-label") ?? ""} ${element.getAttribute("title") ?? ""}`;
|
|
30081
|
+
return WORKSPACE_FILTER_PATTERN.test(label);
|
|
29704
30082
|
}
|
|
29705
30083
|
function injectWorkspaceMenuActions(menus, dom, activeWorkspaceId, workspaceIds, menuWorkspaceIds, onHide, t) {
|
|
29706
30084
|
for (const menu of menus) {
|
|
@@ -30550,13 +30928,14 @@ window.__ModuleLoader__.load({
|
|
|
30550
30928
|
setProviderId(selection.providerId ?? null);
|
|
30551
30929
|
}
|
|
30552
30930
|
const intervalMins = props.getRefreshIntervalMins?.() ?? require_native_workspace_store.DEFAULT_SUBSCRIPTION_USAGE_SETTINGS.refreshIntervalMins;
|
|
30553
|
-
const cacheKey = `${adapterId}|${selection.providerId ?? ""}|${selection.modelId ?? ""}`;
|
|
30931
|
+
const cacheKey = `${adapterId}|${selection.providerId ?? ""}|${selection.modelId ?? ""}|${sessionId}`;
|
|
30554
30932
|
const cached = subscriptionUsageCache.get(cacheKey);
|
|
30555
30933
|
if (cached !== void 0 && cached.usage.provider?.capability !== "new-api" && isSubscriptionUsageFresh(cached.capturedAt, Date.now(), intervalMins)) {
|
|
30556
30934
|
if (active) setUsage(cached.usage);
|
|
30557
30935
|
return;
|
|
30558
30936
|
}
|
|
30559
30937
|
const next = await loadUsage(props.rpc, cacheKey, {
|
|
30938
|
+
sessionId,
|
|
30560
30939
|
adapterId,
|
|
30561
30940
|
...selection.providerId ? { providerId: selection.providerId } : {},
|
|
30562
30941
|
...selection.modelId ? { modelId: selection.modelId } : {}
|
|
@@ -30609,6 +30988,7 @@ window.__ModuleLoader__.load({
|
|
|
30609
30988
|
(async () => {
|
|
30610
30989
|
try {
|
|
30611
30990
|
const result = await require_model_catalog_cache.callCliRpc(props.rpc, "subscription/reset", {
|
|
30991
|
+
sessionId: props.sessionId?.trim() ?? "",
|
|
30612
30992
|
adapterId,
|
|
30613
30993
|
...providerId === null ? {} : { providerId }
|
|
30614
30994
|
});
|
|
@@ -32953,7 +33333,8 @@ window.__ModuleLoader__.load({
|
|
|
32953
33333
|
adapterId: next.adapterId,
|
|
32954
33334
|
...next.modelId ? { modelId: next.modelId } : {},
|
|
32955
33335
|
...next.effortId ? { effortId: next.effortId } : {},
|
|
32956
|
-
...next.serviceTierId ? { serviceTierId: next.serviceTierId } : {}
|
|
33336
|
+
...next.serviceTierId ? { serviceTierId: next.serviceTierId } : {},
|
|
33337
|
+
...next.translationEnabled === void 0 ? {} : { translationEnabled: next.translationEnabled }
|
|
32957
33338
|
};
|
|
32958
33339
|
selections.set(sessionId, normalized);
|
|
32959
33340
|
selectionLastUsed.set(sessionId, Date.now());
|
|
@@ -33321,6 +33702,7 @@ window.__ModuleLoader__.load({
|
|
|
33321
33702
|
adapterId,
|
|
33322
33703
|
modelId: model.id,
|
|
33323
33704
|
effortId: effort ?? "default",
|
|
33705
|
+
translationEnabled: currentSelection.translationEnabled === true,
|
|
33324
33706
|
...tier ? { serviceTierId: tier } : {}
|
|
33325
33707
|
});
|
|
33326
33708
|
};
|
|
@@ -33370,6 +33752,7 @@ window.__ModuleLoader__.load({
|
|
|
33370
33752
|
adapterId: selection.adapterId,
|
|
33371
33753
|
modelId: next.id,
|
|
33372
33754
|
effortId: nextEffort ?? "default",
|
|
33755
|
+
translationEnabled: selection.translationEnabled === true,
|
|
33373
33756
|
...nextTier ? { serviceTierId: nextTier } : {}
|
|
33374
33757
|
});
|
|
33375
33758
|
setOpen(false);
|
|
@@ -33382,6 +33765,7 @@ window.__ModuleLoader__.load({
|
|
|
33382
33765
|
adapterId: selection.adapterId,
|
|
33383
33766
|
modelId: model.id,
|
|
33384
33767
|
effortId: effort,
|
|
33768
|
+
translationEnabled: selection.translationEnabled === true,
|
|
33385
33769
|
...tier ? { serviceTierId: tier } : {}
|
|
33386
33770
|
});
|
|
33387
33771
|
setOpen(false);
|
|
@@ -33398,7 +33782,19 @@ window.__ModuleLoader__.load({
|
|
|
33398
33782
|
adapterId: selection.adapterId,
|
|
33399
33783
|
modelId: model.id,
|
|
33400
33784
|
...selection.effortId ? { effortId: selection.effortId } : {},
|
|
33401
|
-
serviceTierId
|
|
33785
|
+
serviceTierId,
|
|
33786
|
+
translationEnabled: selection.translationEnabled === true
|
|
33787
|
+
});
|
|
33788
|
+
};
|
|
33789
|
+
const translationAvailable = require_session_translation.isSessionTranslationAdapter(selection.adapterId);
|
|
33790
|
+
const toggleTranslation = (next) => {
|
|
33791
|
+
if (model === void 0) return;
|
|
33792
|
+
update({
|
|
33793
|
+
adapterId: selection.adapterId,
|
|
33794
|
+
modelId: model.id,
|
|
33795
|
+
...selection.effortId ? { effortId: selection.effortId } : {},
|
|
33796
|
+
...selection.serviceTierId ? { serviceTierId: selection.serviceTierId } : {},
|
|
33797
|
+
translationEnabled: next
|
|
33402
33798
|
});
|
|
33403
33799
|
};
|
|
33404
33800
|
const menu = loading ? [(0, react.createElement)("div", {
|
|
@@ -33411,6 +33807,15 @@ window.__ModuleLoader__.load({
|
|
|
33411
33807
|
"aria-hidden": true,
|
|
33412
33808
|
style: modelSpinnerStyle
|
|
33413
33809
|
}), (0, react.createElement)("span", void 0, t("cli.loadingModel")))] : pane === "root" ? [
|
|
33810
|
+
...translationAvailable ? [(0, react.createElement)("div", {
|
|
33811
|
+
key: "translation",
|
|
33812
|
+
className: "codingns4dsh-translation-toggle",
|
|
33813
|
+
style: serviceTierRowStyle
|
|
33814
|
+
}, (0, react.createElement)("span", { style: serviceTierLabelStyle }, t("cli.translationConversation")), (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Switch, {
|
|
33815
|
+
checked: selection.translationEnabled === true,
|
|
33816
|
+
onChange: toggleTranslation,
|
|
33817
|
+
label: t("cli.translationConversationToggle")
|
|
33818
|
+
}))] : [],
|
|
33414
33819
|
...serviceTierAvailable ? [(0, react.createElement)("div", {
|
|
33415
33820
|
key: "service-tier",
|
|
33416
33821
|
className: "codingns4dsh-service-tier",
|
|
@@ -33602,6 +34007,7 @@ window.__ModuleLoader__.load({
|
|
|
33602
34007
|
padding: "0 10px",
|
|
33603
34008
|
display: "flex",
|
|
33604
34009
|
alignItems: "center",
|
|
34010
|
+
justifyContent: "space-between",
|
|
33605
34011
|
gap: 8,
|
|
33606
34012
|
fontSize: require_theme.uiFontSize(14),
|
|
33607
34013
|
lineHeight: "22px"
|
|
@@ -38816,10 +39222,10 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
38816
39222
|
}));
|
|
38817
39223
|
}
|
|
38818
39224
|
function readSessionIds(value) {
|
|
38819
|
-
const record = asRecord$
|
|
39225
|
+
const record = asRecord$6(value);
|
|
38820
39226
|
if (record === void 0) return [];
|
|
38821
39227
|
const result = /* @__PURE__ */ new Set();
|
|
38822
|
-
const byId = asRecord$
|
|
39228
|
+
const byId = asRecord$6(record.byId);
|
|
38823
39229
|
if (byId !== void 0) {
|
|
38824
39230
|
for (const sessionId of Object.keys(byId)) if (sessionId.trim() !== "") result.add(sessionId);
|
|
38825
39231
|
}
|
|
@@ -38835,7 +39241,7 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
38835
39241
|
const items = record[key];
|
|
38836
39242
|
if (!Array.isArray(items)) continue;
|
|
38837
39243
|
for (const item of items) {
|
|
38838
|
-
const itemRecord = asRecord$
|
|
39244
|
+
const itemRecord = asRecord$6(item);
|
|
38839
39245
|
const candidate = itemRecord?.sessionId ?? itemRecord?.id;
|
|
38840
39246
|
if (typeof candidate === "string" && candidate.trim() !== "") result.add(candidate);
|
|
38841
39247
|
}
|
|
@@ -38876,10 +39282,10 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
38876
39282
|
const iterator = (await api.follow())[Symbol.asyncIterator]();
|
|
38877
39283
|
const first = await iterator.next();
|
|
38878
39284
|
await iterator.return?.();
|
|
38879
|
-
const unwrapped = asRecord$
|
|
38880
|
-
const value = Array.isArray(unwrapped?.items) ? unwrapped : asRecord$
|
|
39285
|
+
const unwrapped = asRecord$6(unwrapRemoteValue(first.value));
|
|
39286
|
+
const value = Array.isArray(unwrapped?.items) ? unwrapped : asRecord$6(unwrapped?.value);
|
|
38881
39287
|
return (Array.isArray(value?.items) ? value.items : []).flatMap((item) => {
|
|
38882
|
-
const record = asRecord$
|
|
39288
|
+
const record = asRecord$6(item);
|
|
38883
39289
|
const workspaceId = record?.workspaceId;
|
|
38884
39290
|
if (typeof workspaceId !== "string" || workspaceId.trim() === "") return [];
|
|
38885
39291
|
const rawSessionIds = record?.sessionIds;
|
|
@@ -38893,16 +39299,16 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
38893
39299
|
});
|
|
38894
39300
|
}
|
|
38895
39301
|
async function readCurrentSession(api, sessionId, uiContext) {
|
|
38896
|
-
const store = asRecord$
|
|
39302
|
+
const store = asRecord$6(require_native_workspace_store.readNativeService(uiContext, "sessions", "list"));
|
|
38897
39303
|
if (typeof store?.getSnapshot === "function") {
|
|
38898
|
-
const snapshot = asRecord$
|
|
38899
|
-
const byId = asRecord$
|
|
38900
|
-
if (byId !== void 0) return sessionItem(asRecord$
|
|
38901
|
-
return sessionItem(asRecord$
|
|
39304
|
+
const snapshot = asRecord$6(store.getSnapshot());
|
|
39305
|
+
const byId = asRecord$6(snapshot?.byId);
|
|
39306
|
+
if (byId !== void 0) return sessionItem(asRecord$6(byId[sessionId]));
|
|
39307
|
+
return sessionItem(asRecord$6((Array.isArray(snapshot?.items) ? snapshot.items : []).find((item) => asRecord$6(item)?.sessionId === sessionId)));
|
|
38902
39308
|
}
|
|
38903
39309
|
if (api?.list === void 0) return void 0;
|
|
38904
39310
|
const result = await readLegacySessionList(api);
|
|
38905
|
-
return sessionItem(asRecord$
|
|
39311
|
+
return sessionItem(asRecord$6((Array.isArray(result?.items) ? result.items : []).find((item) => asRecord$6(item)?.sessionId === sessionId)));
|
|
38906
39312
|
}
|
|
38907
39313
|
function sessionItem(session) {
|
|
38908
39314
|
if (session === void 0) return void 0;
|
|
@@ -38917,7 +39323,7 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
38917
39323
|
async function readLegacySessionList(api) {
|
|
38918
39324
|
const previous = legacySessionLists.get(api);
|
|
38919
39325
|
if (previous !== void 0 && Date.now() < previous.expiresAt) return previous.promise;
|
|
38920
|
-
const promise = Promise.resolve().then(() => api.list({})).then((value) => asRecord$
|
|
39326
|
+
const promise = Promise.resolve().then(() => api.list({})).then((value) => asRecord$6(unwrapRemoteValue(value)));
|
|
38921
39327
|
const entry = {
|
|
38922
39328
|
promise,
|
|
38923
39329
|
expiresAt: Infinity
|
|
@@ -38941,11 +39347,11 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
38941
39347
|
const result = value.replaceAll("\\", "/").replace(/\/+/u, "/").replace(/\/+$/u, "") || "/";
|
|
38942
39348
|
return /^[A-Za-z]:\//u.test(result) ? result.toLowerCase() : result;
|
|
38943
39349
|
}
|
|
38944
|
-
function asRecord$
|
|
39350
|
+
function asRecord$6(value) {
|
|
38945
39351
|
return typeof value === "object" && value !== null ? value : void 0;
|
|
38946
39352
|
}
|
|
38947
39353
|
function unwrapRemoteValue(value) {
|
|
38948
|
-
const record = asRecord$
|
|
39354
|
+
const record = asRecord$6(value);
|
|
38949
39355
|
if (record === void 0 || typeof record.ok !== "boolean") return value;
|
|
38950
39356
|
return record.ok ? record.value : void 0;
|
|
38951
39357
|
}
|
|
@@ -40682,7 +41088,7 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
40682
41088
|
function registerSessionChangedFilesView(ctx, rpc, remote, locale) {
|
|
40683
41089
|
const runtime = globalThis;
|
|
40684
41090
|
if (runtime.__CODINGNS4DSH_SESSION_CHANGED_FILES_VIEW__ !== void 0) return void 0;
|
|
40685
|
-
const slots = asRecord$
|
|
41091
|
+
const slots = asRecord$5(ctx)?.slots;
|
|
40686
41092
|
if (typeof slots?.inject !== "function" || typeof slots.register !== "function") return void 0;
|
|
40687
41093
|
if (isSlotIdRegistered(slots, "conversation.view", "codingns4dsh/session-changed-files")) return void 0;
|
|
40688
41094
|
if (isSlotIdRegistered(slots, "conversation.session.header.actions", `codingns4dsh/session-changed-files/counter`)) return void 0;
|
|
@@ -40997,7 +41403,7 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
40997
41403
|
function fileIcon(name) {
|
|
40998
41404
|
return name.includes(".") ? "·" : "□";
|
|
40999
41405
|
}
|
|
41000
|
-
function asRecord$
|
|
41406
|
+
function asRecord$5(value) {
|
|
41001
41407
|
return typeof value === "object" && value !== null ? value : void 0;
|
|
41002
41408
|
}
|
|
41003
41409
|
async function call(rpc, endpoint, payload) {
|
|
@@ -41326,8 +41732,39 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
41326
41732
|
},
|
|
41327
41733
|
settingsPanel: FileManagementPanel
|
|
41328
41734
|
};
|
|
41735
|
+
//#endregion
|
|
41736
|
+
//#region src/client/settings-anchor.ts
|
|
41737
|
+
/**
|
|
41738
|
+
* 设置区锚点解析。
|
|
41739
|
+
*
|
|
41740
|
+
* 账户入口(登录/注销、PeerHost 管理)是命令式挂到 DSH 侧栏底部的,必须先找到
|
|
41741
|
+
* 一个稳定的落点。历史上只认原生齿轮按钮 `button[aria-label="设置"]`,它在
|
|
41742
|
+
* DSH Desktop 下**根本不会渲染**:
|
|
41743
|
+
*
|
|
41744
|
+
* 1. Desktop 的 preload 无条件暴露 `dshDesktop`
|
|
41745
|
+
* (`exposeInMainWorld("dshDesktop", …)`),
|
|
41746
|
+
* 2. `@deepseek-ai/dsh-client-ui-settings-account` 的 `apply` 见到该全局就注册
|
|
41747
|
+
* `settings.launcher` 单槽位(账户菜单),
|
|
41748
|
+
* 3. `@deepseek-ai/dsh-client-ui-settings-general` 渲染
|
|
41749
|
+
* `renderSlot("settings.launcher", …, { fallback: 齿轮按钮 })`,
|
|
41750
|
+
* 而单槽位一旦有条目就只渲染条目,fallback 不进入 DOM。
|
|
41751
|
+
*
|
|
41752
|
+
* 结果就是入口锚点为空、`scan()` 直接返回,左下角既没有账户图标也进不去
|
|
41753
|
+
* PeerHost 管理。这里把槽位出口 `[data-slot="settings.launcher"]` 作为兜底锚点:
|
|
41754
|
+
* 它由 DSH 槽位契约提供(`dsh-client-ui-renderer` 的 `SlotOutlet` 始终输出
|
|
41755
|
+
* `data-slot="<slotKey>"`,渲染 fallback 时也输出),与具体按钮实现无关,
|
|
41756
|
+
* 因此 Web 与 Desktop 都成立。
|
|
41757
|
+
*/
|
|
41758
|
+
/**
|
|
41759
|
+
* 原生设置齿轮按钮;Web 浏览器下 `settings.launcher` 无条目,由它作为 fallback 渲染。
|
|
41760
|
+
*
|
|
41761
|
+
* DSH 的 `aria-label` 来自 locale 词典(`dsh-client-ui-settings-general` 的 `trigger`
|
|
41762
|
+
* 键:zh 为「设置」、en 为 `Settings`),因此选择器必须同时覆盖 DSH 0.2.0-rc.2 支持
|
|
41763
|
+
* 的两种语言,不能把中文标签当作唯一的语言无关契约。其它语言走槽位出口兜底。
|
|
41764
|
+
*/
|
|
41765
|
+
const SETTINGS_BUTTON_SELECTOR = "button[aria-label=\"设置\"], button[aria-label=\"Settings\"]";
|
|
41329
41766
|
/** 锚点候选按优先级排列:原生齿轮优先,槽位出口兜底。 */
|
|
41330
|
-
const SETTINGS_ANCHOR_SELECTORS = [
|
|
41767
|
+
const SETTINGS_ANCHOR_SELECTORS = [SETTINGS_BUTTON_SELECTOR, "[data-slot=\"settings.launcher\"]"];
|
|
41331
41768
|
/**
|
|
41332
41769
|
* 按优先级挑选设置区锚点。
|
|
41333
41770
|
*
|
|
@@ -41444,17 +41881,18 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
41444
41881
|
observeDom = true;
|
|
41445
41882
|
return;
|
|
41446
41883
|
}
|
|
41447
|
-
const
|
|
41448
|
-
|
|
41449
|
-
|
|
41450
|
-
return;
|
|
41451
|
-
}
|
|
41452
|
-
const container = settingsAnchorContainer(match);
|
|
41884
|
+
const existing = root.querySelector(`button[${ACCOUNT_ATTRIBUTE}]`);
|
|
41885
|
+
let match = existing?.parentElement === null || existing?.parentElement === void 0 ? null : matchForAccountContainer(existing.parentElement);
|
|
41886
|
+
let container = match === null ? null : settingsAnchorContainer(match);
|
|
41453
41887
|
if (container === null) {
|
|
41888
|
+
match = resolveSettingsAnchor((selector) => root.querySelector(selector));
|
|
41889
|
+
container = match === null ? null : settingsAnchorContainer(match);
|
|
41890
|
+
}
|
|
41891
|
+
if (match === null || container === null) {
|
|
41454
41892
|
observeDom = true;
|
|
41455
41893
|
return;
|
|
41456
41894
|
}
|
|
41457
|
-
let button = container.querySelector(`button[${ACCOUNT_ATTRIBUTE}]`);
|
|
41895
|
+
let button = existing ?? container.querySelector(`button[${ACCOUNT_ATTRIBUTE}]`);
|
|
41458
41896
|
if (button === null) {
|
|
41459
41897
|
button = createAccountButton(root, isDesktopPage());
|
|
41460
41898
|
button.addEventListener("click", (event) => {
|
|
@@ -41463,8 +41901,13 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
41463
41901
|
toggleMenu(button);
|
|
41464
41902
|
});
|
|
41465
41903
|
}
|
|
41466
|
-
if (
|
|
41467
|
-
|
|
41904
|
+
if (button.parentElement !== container) {
|
|
41905
|
+
if (match.kind === "launcher-slot") container.append(button);
|
|
41906
|
+
else container.insertBefore(button, container.firstChild);
|
|
41907
|
+
}
|
|
41908
|
+
root.querySelectorAll(`button[${ACCOUNT_ATTRIBUTE}]`).forEach((node) => {
|
|
41909
|
+
if (node !== button) node.remove();
|
|
41910
|
+
});
|
|
41468
41911
|
observeDom = false;
|
|
41469
41912
|
observer?.disconnect();
|
|
41470
41913
|
container.dataset.codingnsAccountRow = "true";
|
|
@@ -41481,12 +41924,9 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
41481
41924
|
};
|
|
41482
41925
|
const updateAccountLayout = (container, anchor, button, kind) => {
|
|
41483
41926
|
if (kind === "launcher-slot") {
|
|
41484
|
-
const row = container.parentElement;
|
|
41485
|
-
if (row === null) return;
|
|
41486
41927
|
const mode = "desktop";
|
|
41487
41928
|
if (button.dataset.codingnsWide === mode) return;
|
|
41488
41929
|
button.dataset.codingnsWide = mode;
|
|
41489
|
-
row.style.flexWrap = "nowrap";
|
|
41490
41930
|
button.style.order = "2";
|
|
41491
41931
|
button.style.marginLeft = "auto";
|
|
41492
41932
|
return;
|
|
@@ -41528,9 +41968,8 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
41528
41968
|
};
|
|
41529
41969
|
const observerCallback = () => {
|
|
41530
41970
|
if (disposed || rendering || renderQueued) return;
|
|
41531
|
-
const match = resolveSettingsAnchor((selector) => root.querySelector(selector));
|
|
41532
41971
|
const button = root.querySelector(`button[${ACCOUNT_ATTRIBUTE}]`);
|
|
41533
|
-
if (
|
|
41972
|
+
if (button !== null && button.parentElement !== null && matchForAccountContainer(button.parentElement) !== null) return;
|
|
41534
41973
|
renderQueued = true;
|
|
41535
41974
|
queueMicrotask(() => {
|
|
41536
41975
|
renderQueued = false;
|
|
@@ -41987,6 +42426,17 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
41987
42426
|
function isWide(parent, settings) {
|
|
41988
42427
|
return parent.clientWidth > 96 || getComputedStyle(settings).display !== "none" && settings.getBoundingClientRect().width > 70;
|
|
41989
42428
|
}
|
|
42429
|
+
function matchForAccountContainer(container) {
|
|
42430
|
+
if (container.matches("[data-slot=\"settings.launcher\"]")) return {
|
|
42431
|
+
kind: "launcher-slot",
|
|
42432
|
+
node: container
|
|
42433
|
+
};
|
|
42434
|
+
const settings = container.querySelector(SETTINGS_BUTTON_SELECTOR);
|
|
42435
|
+
return settings === null || settings.parentElement !== container ? null : {
|
|
42436
|
+
kind: "settings-button",
|
|
42437
|
+
node: settings
|
|
42438
|
+
};
|
|
42439
|
+
}
|
|
41990
42440
|
function formatPercent(value) {
|
|
41991
42441
|
return `${Math.round(value)}%`;
|
|
41992
42442
|
}
|
|
@@ -42998,6 +43448,7 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
42998
43448
|
"codingnsTerminal/shells",
|
|
42999
43449
|
"codingnsTerminal/write",
|
|
43000
43450
|
"codingnsAssistantNotifications/sourceStream",
|
|
43451
|
+
"fileUploads/upload",
|
|
43001
43452
|
"fileReferences/list",
|
|
43002
43453
|
"skills/list"
|
|
43003
43454
|
]);
|
|
@@ -43059,6 +43510,8 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
43059
43510
|
let localHostId;
|
|
43060
43511
|
let hasAggregate = false;
|
|
43061
43512
|
let sessionWorkspaceIds = /* @__PURE__ */ new Map();
|
|
43513
|
+
const sessionRunningOverrides = /* @__PURE__ */ new Map();
|
|
43514
|
+
const completedSessionTransitions = /* @__PURE__ */ new Set();
|
|
43062
43515
|
const listeners = /* @__PURE__ */ new Set();
|
|
43063
43516
|
return {
|
|
43064
43517
|
hasAggregate: () => hasAggregate,
|
|
@@ -43066,6 +43519,11 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
43066
43519
|
const next = projectAggregate(results);
|
|
43067
43520
|
const nextWorkspaceIds = new Set(next.workspaces.map((workspace) => workspace.workspaceId));
|
|
43068
43521
|
const nextSessionIds = new Set(next.sessions.map((session) => session.sessionId));
|
|
43522
|
+
for (const candidate of next.sessions) {
|
|
43523
|
+
const previous = sessions.find((session) => session.sessionId === candidate.sessionId);
|
|
43524
|
+
if (previous?.running !== true || candidate.running !== false) continue;
|
|
43525
|
+
if (sessionRunningOverrides.get(candidate.sessionId) !== true || candidate.updatedAt > previous.updatedAt) completedSessionTransitions.add(candidate.sessionId);
|
|
43526
|
+
}
|
|
43069
43527
|
const retainedSessions = [...next.sessions];
|
|
43070
43528
|
const retainedSessionWorkspaceIds = new Map(next.sessionWorkspaceIds);
|
|
43071
43529
|
const retainedWorkspaces = next.workspaces.map((workspace) => ({
|
|
@@ -43094,7 +43552,7 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
43094
43552
|
const projectedNext = {
|
|
43095
43553
|
...next,
|
|
43096
43554
|
workspaces: retainedWorkspaces,
|
|
43097
|
-
sessions: retainedSessions,
|
|
43555
|
+
sessions: retainedSessions.map((session) => applyRunningOverride(session, sessionRunningOverrides)),
|
|
43098
43556
|
sessionWorkspaceIds: retainedSessionWorkspaceIds
|
|
43099
43557
|
};
|
|
43100
43558
|
const nextLocalHostId = projectedNext.localHostId ?? localHostId;
|
|
@@ -43109,6 +43567,23 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
43109
43567
|
for (const listener of [...listeners]) listener();
|
|
43110
43568
|
return true;
|
|
43111
43569
|
},
|
|
43570
|
+
setSessionRunning(sessionId, running) {
|
|
43571
|
+
if (sessionRunningOverrides.get(sessionId) === running) return false;
|
|
43572
|
+
sessionRunningOverrides.set(sessionId, running);
|
|
43573
|
+
const current = sessions.find((session) => session.sessionId === sessionId);
|
|
43574
|
+
if (current === void 0 || current.running === running) return false;
|
|
43575
|
+
sessions = sessions.map((session) => session.sessionId === sessionId ? {
|
|
43576
|
+
...session,
|
|
43577
|
+
running
|
|
43578
|
+
} : session);
|
|
43579
|
+
for (const listener of [...listeners]) listener();
|
|
43580
|
+
return true;
|
|
43581
|
+
},
|
|
43582
|
+
consumeCompletedSessionTransitions() {
|
|
43583
|
+
const result = [...completedSessionTransitions];
|
|
43584
|
+
completedSessionTransitions.clear();
|
|
43585
|
+
return result;
|
|
43586
|
+
},
|
|
43112
43587
|
setWorkspaceOrder(nextOrderedWorkspaceIds) {
|
|
43113
43588
|
const next = normalizeWorkspaceOrder(nextOrderedWorkspaceIds);
|
|
43114
43589
|
if (sameIds(orderedWorkspaceIds, next)) return false;
|
|
@@ -43215,6 +43690,13 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
43215
43690
|
...session.parentSessionId === void 0 ? {} : { parentSessionId: require_primitives_adapter.createVirtualSessionId(session.scope.targetHostId ?? session.scope.hostId, session.parentSessionId) }
|
|
43216
43691
|
};
|
|
43217
43692
|
}
|
|
43693
|
+
function applyRunningOverride(session, overrides) {
|
|
43694
|
+
const running = overrides.get(session.sessionId);
|
|
43695
|
+
return running === void 0 || running === session.running ? session : {
|
|
43696
|
+
...session,
|
|
43697
|
+
running
|
|
43698
|
+
};
|
|
43699
|
+
}
|
|
43218
43700
|
function sameWorkspaces(previous, next) {
|
|
43219
43701
|
if (previous.length !== next.length) return false;
|
|
43220
43702
|
return previous.every((workspace, index) => {
|
|
@@ -43335,12 +43817,12 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
43335
43817
|
const refreshStates = /* @__PURE__ */ new WeakMap();
|
|
43336
43818
|
/** 合并并按 Host 侧顺序排列工作区;快照形状不符时原样返回,注入失败不影响本机数据。 */
|
|
43337
43819
|
function mergeWorkspaceSnapshot(snapshot, virtual, orderedWorkspaceIds, localHostId, hasAggregate) {
|
|
43338
|
-
const record = asRecord$
|
|
43820
|
+
const record = asRecord$4(snapshot);
|
|
43339
43821
|
if (record === null || !Array.isArray(record.items)) return snapshot;
|
|
43340
43822
|
const baseItems = record.items;
|
|
43341
43823
|
const byId = new Map(virtual.map((workspace) => [workspace.workspaceId, workspace]));
|
|
43342
43824
|
const items = hasAggregate ? baseItems.flatMap((item) => {
|
|
43343
|
-
const workspace = asRecord$
|
|
43825
|
+
const workspace = asRecord$4(item);
|
|
43344
43826
|
const id = workspace?.workspaceId;
|
|
43345
43827
|
const ref = typeof id === "string" ? require_primitives_adapter.parseVirtualWorkspaceId(id) : null;
|
|
43346
43828
|
if (ref === null || ref.hostId === localHostId || ref.targetHostId === null) return [item];
|
|
@@ -43351,7 +43833,7 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
43351
43833
|
}];
|
|
43352
43834
|
}) : baseItems;
|
|
43353
43835
|
const known = new Set(items.flatMap((item) => {
|
|
43354
|
-
const workspaceId = asRecord$
|
|
43836
|
+
const workspaceId = asRecord$4(item)?.workspaceId;
|
|
43355
43837
|
if (typeof workspaceId !== "string") return [];
|
|
43356
43838
|
const normalized = normalizeWorkspaceId(workspaceId, localHostId);
|
|
43357
43839
|
return normalized === workspaceId ? [workspaceId] : [workspaceId, normalized];
|
|
@@ -43370,7 +43852,7 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
43370
43852
|
function normalizeRemoteWorkspaceDisplayPaths(items) {
|
|
43371
43853
|
let changed = false;
|
|
43372
43854
|
const normalized = items.map((item) => {
|
|
43373
|
-
const record = asRecord$
|
|
43855
|
+
const record = asRecord$4(item);
|
|
43374
43856
|
const workspaceId = record?.workspaceId;
|
|
43375
43857
|
if (record === null || typeof workspaceId !== "string" || require_primitives_adapter.parseVirtualWorkspaceId(workspaceId) === null) return item;
|
|
43376
43858
|
const displayPath = createPeerHostWorkspaceDisplayPath(workspaceId);
|
|
@@ -43427,18 +43909,18 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
43427
43909
|
};
|
|
43428
43910
|
}
|
|
43429
43911
|
function mergeBlankSessionCwds(snapshot, workspaceSnapshot) {
|
|
43430
|
-
const state = asRecord$
|
|
43912
|
+
const state = asRecord$4(snapshot);
|
|
43431
43913
|
const byId = state?.byId;
|
|
43432
|
-
const workspaceState = asRecord$
|
|
43914
|
+
const workspaceState = asRecord$4(workspaceSnapshot);
|
|
43433
43915
|
const items = Array.isArray(workspaceState?.items) ? workspaceState.items : [];
|
|
43434
43916
|
if (state === null || !isRecord$4(byId) || items.length === 0) return snapshot;
|
|
43435
43917
|
let changed = false;
|
|
43436
43918
|
const nextById = { ...byId };
|
|
43437
43919
|
for (const [id, value] of Object.entries(byId)) {
|
|
43438
|
-
const session = asRecord$
|
|
43920
|
+
const session = asRecord$4(value);
|
|
43439
43921
|
if (session === null || session.blank !== true) continue;
|
|
43440
|
-
const displayPath = asRecord$
|
|
43441
|
-
const record = asRecord$
|
|
43922
|
+
const displayPath = asRecord$4(items.find((item) => {
|
|
43923
|
+
const record = asRecord$4(item);
|
|
43442
43924
|
return Array.isArray(record?.sessionIds) && record.sessionIds.includes(id);
|
|
43443
43925
|
}))?.path;
|
|
43444
43926
|
if (typeof displayPath !== "string" || displayPath === "" || session.cwd === displayPath) continue;
|
|
@@ -43531,18 +44013,18 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
43531
44013
|
function orderWorkspaceItems(items, orderedWorkspaceIds, localHostId) {
|
|
43532
44014
|
if (orderedWorkspaceIds.length === 0 || items.length < 2) return items;
|
|
43533
44015
|
if (localHostId === void 0 && items.some((item) => {
|
|
43534
|
-
const workspaceId = asRecord$
|
|
44016
|
+
const workspaceId = asRecord$4(item)?.workspaceId;
|
|
43535
44017
|
return typeof workspaceId === "string" && require_primitives_adapter.parseVirtualWorkspaceId(workspaceId) === null;
|
|
43536
44018
|
})) return items;
|
|
43537
44019
|
const hasLocalItem = localHostId !== void 0 && items.some((item) => {
|
|
43538
|
-
const workspaceId = asRecord$
|
|
44020
|
+
const workspaceId = asRecord$4(item)?.workspaceId;
|
|
43539
44021
|
return typeof workspaceId === "string" && require_primitives_adapter.parseVirtualWorkspaceId(workspaceId) === null;
|
|
43540
44022
|
});
|
|
43541
44023
|
const hasLocalOrder = localHostId !== void 0 && orderedWorkspaceIds.some((id) => require_primitives_adapter.parseVirtualWorkspaceId(id)?.hostId === localHostId);
|
|
43542
44024
|
if (hasLocalItem && !hasLocalOrder) return items;
|
|
43543
44025
|
const ranks = new Map(orderedWorkspaceIds.map((id, index) => [id, index]));
|
|
43544
44026
|
const entries = items.map((item, index) => {
|
|
43545
|
-
const workspaceId = asRecord$
|
|
44027
|
+
const workspaceId = asRecord$4(item)?.workspaceId;
|
|
43546
44028
|
return {
|
|
43547
44029
|
item,
|
|
43548
44030
|
index,
|
|
@@ -43580,7 +44062,7 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
43580
44062
|
}
|
|
43581
44063
|
return merged.length === original.length && merged.every((id, index) => id === original[index]) ? void 0 : merged;
|
|
43582
44064
|
}
|
|
43583
|
-
function asRecord$
|
|
44065
|
+
function asRecord$4(value) {
|
|
43584
44066
|
return isRecord$4(value) ? value : null;
|
|
43585
44067
|
}
|
|
43586
44068
|
function isRecord$4(value) {
|
|
@@ -44400,6 +44882,8 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
44400
44882
|
peers = /* @__PURE__ */ new Map();
|
|
44401
44883
|
routes = /* @__PURE__ */ new Map();
|
|
44402
44884
|
generations = /* @__PURE__ */ new Set();
|
|
44885
|
+
/** 事件早于聚合摘要到达时暂存,待会话进入可见作用域后重放。 */
|
|
44886
|
+
pendingSessionStatuses = /* @__PURE__ */ new Map();
|
|
44403
44887
|
sequence = 0;
|
|
44404
44888
|
instanceId = globalThis.crypto?.randomUUID?.() ?? `${Date.now()}-${Math.random()}`;
|
|
44405
44889
|
constructor(options) {
|
|
@@ -44408,8 +44892,35 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
44408
44892
|
setPeers(scopes) {
|
|
44409
44893
|
this.peers.clear();
|
|
44410
44894
|
for (const scope of scopes) if (scope.targetHostId !== null) this.peers.set(scope.targetHostId, scope);
|
|
44895
|
+
for (const [key, pending] of this.pendingSessionStatuses) if (pending.scope.targetHostId === null || !this.peers.has(pending.scope.targetHostId)) this.pendingSessionStatuses.delete(key);
|
|
44411
44896
|
for (const generation of this.generations) this.sync(generation);
|
|
44412
44897
|
}
|
|
44898
|
+
/** 聚合摘要建立会话作用域后调用,补发此前因作用域未知而暂存的状态事件。 */
|
|
44899
|
+
replayPendingSessionStatuses() {
|
|
44900
|
+
for (const generation of this.generations) {
|
|
44901
|
+
if (generation.clientId === void 0 || generation.controller.signal.aborted) continue;
|
|
44902
|
+
this.replayPendingSessionStatusesForGeneration(generation);
|
|
44903
|
+
}
|
|
44904
|
+
}
|
|
44905
|
+
/**
|
|
44906
|
+
* 摘要从 running 变为 idle、但事件流没有覆盖到这次变化时,补投递完成边沿。
|
|
44907
|
+
* 调用方必须只对确认发生过 true -> false 的会话调用,不能把普通 idle 摘要当未读。
|
|
44908
|
+
*/
|
|
44909
|
+
replayCompletedSessionStatus(sessionId, scope) {
|
|
44910
|
+
const frame = {
|
|
44911
|
+
type: "emit",
|
|
44912
|
+
event: "api-session/status",
|
|
44913
|
+
args: [sessionId, false]
|
|
44914
|
+
};
|
|
44915
|
+
let delivered = false;
|
|
44916
|
+
for (const generation of this.generations) {
|
|
44917
|
+
if (generation.clientId === void 0 || generation.controller.signal.aborted || !this.options.accepts(sessionId, scope)) continue;
|
|
44918
|
+
generation.sessionStatuses.delete(sessionId);
|
|
44919
|
+
this.deliverSessionStatus(generation, scope, sessionId, false, frame);
|
|
44920
|
+
delivered = true;
|
|
44921
|
+
}
|
|
44922
|
+
if (!delivered) this.rememberPendingSessionStatus(scope, sessionId, frame);
|
|
44923
|
+
}
|
|
44413
44924
|
ownsResult(payload) {
|
|
44414
44925
|
const eventId = record$1(record$1(payload)?.args)?.eventId;
|
|
44415
44926
|
return typeof eventId === "string" && eventId.startsWith(EVENT_PREFIX);
|
|
@@ -44435,6 +44946,7 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
44435
44946
|
controller: new AbortController(),
|
|
44436
44947
|
queue: new EventQueue(),
|
|
44437
44948
|
workers: /* @__PURE__ */ new Map(),
|
|
44949
|
+
sessionStatuses: /* @__PURE__ */ new Map(),
|
|
44438
44950
|
prepared: false
|
|
44439
44951
|
};
|
|
44440
44952
|
const abort = () => {
|
|
@@ -44479,6 +44991,7 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
44479
44991
|
for (const worker of generation.workers.values()) this.stop(generation, worker);
|
|
44480
44992
|
}
|
|
44481
44993
|
this.routes.clear();
|
|
44994
|
+
this.pendingSessionStatuses.clear();
|
|
44482
44995
|
}
|
|
44483
44996
|
sync(generation) {
|
|
44484
44997
|
if (generation.clientId === void 0 || generation.controller.signal.aborted) return;
|
|
@@ -44512,6 +45025,7 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
44512
45025
|
if (frame?.type !== "ready" || typeof frame.clientId !== "string") throw new Error("远端事件流缺少 ready 帧");
|
|
44513
45026
|
clientId = frame.clientId;
|
|
44514
45027
|
attempt = 0;
|
|
45028
|
+
this.replayPendingSessionStatusesForGeneration(generation);
|
|
44515
45029
|
if (!generation.prepared) {
|
|
44516
45030
|
generation.prepared = true;
|
|
44517
45031
|
try {
|
|
@@ -44532,7 +45046,12 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
44532
45046
|
async deliver(generation, worker, scope, clientId, frame, signal) {
|
|
44533
45047
|
if (frame?.type === "emit" && frame.event === "api-session/status") {
|
|
44534
45048
|
const args = frame.args;
|
|
44535
|
-
if (Array.isArray(args)
|
|
45049
|
+
if (!Array.isArray(args) || typeof args[0] !== "string" || typeof args[1] !== "boolean") return;
|
|
45050
|
+
if (!this.options.accepts(args[0], scope)) {
|
|
45051
|
+
this.rememberPendingSessionStatus(scope, args[0], frame);
|
|
45052
|
+
return;
|
|
45053
|
+
}
|
|
45054
|
+
this.deliverSessionStatus(generation, scope, args[0], args[1], frame);
|
|
44536
45055
|
return;
|
|
44537
45056
|
}
|
|
44538
45057
|
if (frame?.type === "cancel" && typeof frame.eventId === "string") {
|
|
@@ -44566,6 +45085,42 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
44566
45085
|
eventId: id
|
|
44567
45086
|
});
|
|
44568
45087
|
}
|
|
45088
|
+
deliverSessionStatus(generation, scope, sessionId, running, frame) {
|
|
45089
|
+
const previous = generation.sessionStatuses.get(sessionId);
|
|
45090
|
+
if (!running && previous !== true) generation.queue.push({
|
|
45091
|
+
...record$1(frame),
|
|
45092
|
+
args: [sessionId, true]
|
|
45093
|
+
});
|
|
45094
|
+
this.options.onSessionStatus?.(sessionId, running, scope);
|
|
45095
|
+
generation.queue.push(frame);
|
|
45096
|
+
generation.sessionStatuses.set(sessionId, running);
|
|
45097
|
+
}
|
|
45098
|
+
rememberPendingSessionStatus(scope, sessionId, frame) {
|
|
45099
|
+
if (scope.targetHostId === null) return;
|
|
45100
|
+
const key = `${scope.targetHostId}:${sessionId}`;
|
|
45101
|
+
const pending = this.pendingSessionStatuses.get(key) ?? {
|
|
45102
|
+
scope,
|
|
45103
|
+
sessionId,
|
|
45104
|
+
frames: []
|
|
45105
|
+
};
|
|
45106
|
+
const previousArgs = record$1(pending.frames.at(-1))?.args;
|
|
45107
|
+
const args = record$1(frame)?.args;
|
|
45108
|
+
if (Array.isArray(previousArgs) && Array.isArray(args) && previousArgs[1] === args[1]) return;
|
|
45109
|
+
pending.frames.push(frame);
|
|
45110
|
+
if (pending.frames.length > 8) pending.frames.shift();
|
|
45111
|
+
this.pendingSessionStatuses.set(key, pending);
|
|
45112
|
+
}
|
|
45113
|
+
replayPendingSessionStatusesForGeneration(generation) {
|
|
45114
|
+
for (const pending of [...this.pendingSessionStatuses.values()]) {
|
|
45115
|
+
if (!this.options.accepts(pending.sessionId, pending.scope)) continue;
|
|
45116
|
+
this.pendingSessionStatuses.delete(`${pending.scope.targetHostId}:${pending.sessionId}`);
|
|
45117
|
+
for (const frame of pending.frames) {
|
|
45118
|
+
const args = record$1(frame)?.args;
|
|
45119
|
+
if (!Array.isArray(args) || typeof args[1] !== "boolean") continue;
|
|
45120
|
+
this.deliverSessionStatus(generation, pending.scope, pending.sessionId, args[1], frame);
|
|
45121
|
+
}
|
|
45122
|
+
}
|
|
45123
|
+
}
|
|
44569
45124
|
cancel(generation, worker, eventId, id) {
|
|
44570
45125
|
worker.pending.delete(eventId);
|
|
44571
45126
|
this.routes.delete(id);
|
|
@@ -44622,110 +45177,6 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
44622
45177
|
});
|
|
44623
45178
|
}
|
|
44624
45179
|
//#endregion
|
|
44625
|
-
//#region node_modules/.pnpm/@deepseek-ai+dsh-util-workspace-path@0.2.1-alpha.2_@deepseek-ai+cordis@4.0.4/node_modules/@deepseek-ai/dsh-util-workspace-path/lib/index.js
|
|
44626
|
-
/**
|
|
44627
|
-
* The `dsh-resource://file/…` address grammar: how a file is named across the
|
|
44628
|
-
* Sidebar and the resource model, built and parsed without touching a
|
|
44629
|
-
* filesystem.
|
|
44630
|
-
* @module
|
|
44631
|
-
*/
|
|
44632
|
-
/** The scheme and type every file address opens with. */
|
|
44633
|
-
const FILE_ADDRESS_PREFIX = "dsh-resource://file/";
|
|
44634
|
-
/** Component-encode one id or path segment, keeping `:` literal for drive letters. */
|
|
44635
|
-
function encodeSegment(segment) {
|
|
44636
|
-
return encodeURIComponent(segment).replace(/%3A/gi, ":");
|
|
44637
|
-
}
|
|
44638
|
-
/** Encode a `/`-separated path segment by segment. */
|
|
44639
|
-
function encodePath(path) {
|
|
44640
|
-
return path.split("/").map(encodeSegment).join("/");
|
|
44641
|
-
}
|
|
44642
|
-
/** Whether a decoded first path segment is a Windows drive (`C:`). */
|
|
44643
|
-
function isDriveSegment(segment) {
|
|
44644
|
-
return segment !== void 0 && /^[A-Za-z]:$/.test(segment);
|
|
44645
|
-
}
|
|
44646
|
-
/**
|
|
44647
|
-
* Build the address of a file read through one Session.
|
|
44648
|
-
* @param sessionId - the Session whose Host workspace resolves the path.
|
|
44649
|
-
* @param path - absolute or workspace-relative path; backslashes are normalized to `/`, and leading `./` prefixes are dropped.
|
|
44650
|
-
* @returns the `dsh-resource://file/session/<sessionId>/<path>` address.
|
|
44651
|
-
*/
|
|
44652
|
-
function sessionFileAddress(sessionId, path) {
|
|
44653
|
-
const normalized = path.replace(/\\/g, "/").replace(/^(?:\.\/)+/, "");
|
|
44654
|
-
return `${FILE_ADDRESS_PREFIX}session/${encodeSegment(sessionId)}/${encodePath(normalized)}`;
|
|
44655
|
-
}
|
|
44656
|
-
/**
|
|
44657
|
-
* Read a file address back into its parts without resolving `.` or `..`.
|
|
44658
|
-
* Query and fragment suffixes are ignored; encoded path segments are decoded.
|
|
44659
|
-
* @param address - a candidate address.
|
|
44660
|
-
* @returns the parts, or `undefined` when the string is not a `dsh-resource://file/` URI in a known scope with a path, or a segment is not validly encoded.
|
|
44661
|
-
*/
|
|
44662
|
-
function parseFileAddress(address) {
|
|
44663
|
-
try {
|
|
44664
|
-
if (!address.startsWith(FILE_ADDRESS_PREFIX)) return void 0;
|
|
44665
|
-
const end = address.search(/[?#]/);
|
|
44666
|
-
const [scope, ...rest] = address.slice(20, end === -1 ? void 0 : end).split("/");
|
|
44667
|
-
if (scope === "session") {
|
|
44668
|
-
const [id, ...segments] = rest;
|
|
44669
|
-
if (id === void 0 || id === "" || segments.length === 0) return void 0;
|
|
44670
|
-
return {
|
|
44671
|
-
scope,
|
|
44672
|
-
sessionId: decodeURIComponent(id),
|
|
44673
|
-
path: segments.map(decodeURIComponent).join("/")
|
|
44674
|
-
};
|
|
44675
|
-
}
|
|
44676
|
-
if (scope === "absolute") {
|
|
44677
|
-
const unc = rest[0] === "" && rest.length > 1;
|
|
44678
|
-
const segments = (unc ? rest.slice(1) : rest).map(decodeURIComponent);
|
|
44679
|
-
if (segments.length === 0 || segments[0] === "") return void 0;
|
|
44680
|
-
if (unc) return {
|
|
44681
|
-
scope,
|
|
44682
|
-
path: `//${segments.join("/")}`
|
|
44683
|
-
};
|
|
44684
|
-
return {
|
|
44685
|
-
scope,
|
|
44686
|
-
path: isDriveSegment(segments[0]) ? segments.join("/") : `/${segments.join("/")}`
|
|
44687
|
-
};
|
|
44688
|
-
}
|
|
44689
|
-
return;
|
|
44690
|
-
} catch {
|
|
44691
|
-
return;
|
|
44692
|
-
}
|
|
44693
|
-
}
|
|
44694
|
-
//#endregion
|
|
44695
|
-
//#region src/client/peer-host-file-links.ts
|
|
44696
|
-
/**
|
|
44697
|
-
* 在原生资源入口规范远端链接,保留资源里的虚拟会话身份和导航参数。
|
|
44698
|
-
* 右栏文件树、消息与预览内链接共用这个入口;不扫描消息正文或当前选择。
|
|
44699
|
-
*/
|
|
44700
|
-
function installPeerHostFileLinkRouting(uiContext, workspacePathForSession) {
|
|
44701
|
-
const sidebar = uiContext.get("sidebarRight");
|
|
44702
|
-
if (typeof sidebar?.openResource !== "function") return void 0;
|
|
44703
|
-
const originalOpen = sidebar.openResource;
|
|
44704
|
-
const originalOpenIn = sidebar.openResourceIn;
|
|
44705
|
-
const resolve = (address, options) => {
|
|
44706
|
-
const file = parseFileAddress(address);
|
|
44707
|
-
if (file?.scope !== "session") return [address, options];
|
|
44708
|
-
const location = normalizePeerHostFileLocation(file.path, workspacePathForSession(file.sessionId));
|
|
44709
|
-
if (location.path === file.path) return [address, options];
|
|
44710
|
-
const suffix = address.search(/[?#]/u);
|
|
44711
|
-
return [sessionFileAddress(file.sessionId, location.path) + (suffix < 0 ? "" : address.slice(suffix)), location.line === void 0 ? options : {
|
|
44712
|
-
...options,
|
|
44713
|
-
params: {
|
|
44714
|
-
line: location.line,
|
|
44715
|
-
...options?.params
|
|
44716
|
-
}
|
|
44717
|
-
}];
|
|
44718
|
-
};
|
|
44719
|
-
const open = (address, options) => originalOpen.call(sidebar, ...resolve(address, options));
|
|
44720
|
-
const openIn = originalOpenIn === void 0 ? void 0 : (sessionId, address, options) => originalOpenIn.call(sidebar, sessionId, ...resolve(address, options));
|
|
44721
|
-
sidebar.openResource = open;
|
|
44722
|
-
if (openIn !== void 0) sidebar.openResourceIn = openIn;
|
|
44723
|
-
return () => {
|
|
44724
|
-
if (sidebar.openResource === open) sidebar.openResource = originalOpen;
|
|
44725
|
-
if (openIn !== void 0 && sidebar.openResourceIn === openIn) sidebar.openResourceIn = originalOpenIn;
|
|
44726
|
-
};
|
|
44727
|
-
}
|
|
44728
|
-
//#endregion
|
|
44729
45180
|
//#region src/shared/session-reference.ts
|
|
44730
45181
|
/**
|
|
44731
45182
|
* 生成 DSH 原生会话引用使用的 canonical URI。
|
|
@@ -44832,15 +45283,15 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
44832
45283
|
async function readRemoteCandidates(value) {
|
|
44833
45284
|
const result = await value;
|
|
44834
45285
|
if (Array.isArray(result)) return result.flatMap(asRemoteCandidate);
|
|
44835
|
-
const record = asRecord$
|
|
45286
|
+
const record = asRecord$3(result);
|
|
44836
45287
|
if (record?.ok === true && Array.isArray(record.value)) return record.value.flatMap(asRemoteCandidate);
|
|
44837
|
-
const nested = asRecord$
|
|
45288
|
+
const nested = asRecord$3(record?.ok === true ? record.value : void 0);
|
|
44838
45289
|
if (Array.isArray(nested?.candidates)) return nested.candidates.flatMap(asRemoteCandidate);
|
|
44839
45290
|
if (Array.isArray(record?.candidates)) return record.candidates.flatMap(asRemoteCandidate);
|
|
44840
45291
|
return [];
|
|
44841
45292
|
}
|
|
44842
45293
|
function asRemoteCandidate(value) {
|
|
44843
|
-
const record = asRecord$
|
|
45294
|
+
const record = asRecord$3(value);
|
|
44844
45295
|
if (record === null || typeof record.sessionId !== "string" || typeof record.mention !== "string" || typeof record.label !== "string") return [];
|
|
44845
45296
|
return [{
|
|
44846
45297
|
sessionId: record.sessionId,
|
|
@@ -44874,14 +45325,14 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
44874
45325
|
value: formatSessionReferenceMention(title, session.sessionId)
|
|
44875
45326
|
};
|
|
44876
45327
|
}
|
|
44877
|
-
function asRecord$
|
|
45328
|
+
function asRecord$3(value) {
|
|
44878
45329
|
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
|
|
44879
45330
|
}
|
|
44880
45331
|
function readSelectedRemoteHost(service, sessionId) {
|
|
44881
45332
|
const selection = service?.selection?.getSnapshot();
|
|
44882
|
-
const record = asRecord$
|
|
45333
|
+
const record = asRecord$3(selection);
|
|
44883
45334
|
if (record === null) return void 0;
|
|
44884
|
-
const selectedSessionId = typeof record.sessionId === "string" ? record.sessionId : asRecord$
|
|
45335
|
+
const selectedSessionId = typeof record.sessionId === "string" ? record.sessionId : asRecord$3(record.subagentAddress)?.parentSessionId;
|
|
44885
45336
|
if (selectedSessionId !== void 0 && selectedSessionId !== sessionId) return void 0;
|
|
44886
45337
|
const workspaceId = record.workspaceId;
|
|
44887
45338
|
if (typeof workspaceId !== "string") return void 0;
|
|
@@ -44984,10 +45435,6 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
44984
45435
|
scope.effect(() => transport.watchNavigation(), "codingns4dsh: PeerHost model catalog navigation");
|
|
44985
45436
|
});
|
|
44986
45437
|
if (navigation !== void 0) context.resources.add(() => navigation.dispose());
|
|
44987
|
-
const fileLinks = context.services.uiContext?.inject(["sidebarRight"], (scope) => {
|
|
44988
|
-
scope.effect(() => installPeerHostFileLinkRouting(scope, (sessionId) => projection.sessions().find((session) => session.sessionId === sessionId)?.cwd) ?? (() => void 0), "codingns4dsh: PeerHost file links");
|
|
44989
|
-
});
|
|
44990
|
-
if (fileLinks !== void 0) context.resources.add(() => fileLinks.dispose());
|
|
44991
45438
|
if (shim.getMode?.() === "desktop") reconnectNativeEvents(context.services.uiContext);
|
|
44992
45439
|
}
|
|
44993
45440
|
const panel = startPeerHostManagementPanel({
|
|
@@ -45126,9 +45573,9 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
45126
45573
|
return (await readPageRpcResponse(response)).result;
|
|
45127
45574
|
};
|
|
45128
45575
|
const codingNsCall = async (endpoint, payload, signal) => {
|
|
45129
|
-
const result = asRecord(await request("/codingns", endpoint, payload, signal));
|
|
45576
|
+
const result = asRecord$2(await request("/codingns", endpoint, payload, signal));
|
|
45130
45577
|
if (result?.ok === true) return result.value;
|
|
45131
|
-
const error = asRecord(result?.error);
|
|
45578
|
+
const error = asRecord$2(result?.error);
|
|
45132
45579
|
const failure = new Error(typeof error?.message === "string" ? error.message : `CodingNS RPC 失败: ${endpoint}`);
|
|
45133
45580
|
if (typeof error?.code === "string") failure.code = error.code;
|
|
45134
45581
|
throw failure;
|
|
@@ -45141,6 +45588,17 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
45141
45588
|
const scope = scopes.get(virtualSessionId);
|
|
45142
45589
|
return scope?.targetHostId === parsed.hostId ? scope : void 0;
|
|
45143
45590
|
};
|
|
45591
|
+
const scopeForFileUpload = (url) => {
|
|
45592
|
+
const virtualSessionId = url.searchParams.get("sessionId");
|
|
45593
|
+
if (virtualSessionId === null) return void 0;
|
|
45594
|
+
const parsed = require_primitives_adapter.parseVirtualSessionId(virtualSessionId);
|
|
45595
|
+
if (parsed === null) return void 0;
|
|
45596
|
+
const scope = scopes.get(virtualSessionId);
|
|
45597
|
+
return scope?.targetHostId === parsed.hostId && scope.sessionId === parsed.sessionId ? {
|
|
45598
|
+
virtualSessionId,
|
|
45599
|
+
scope
|
|
45600
|
+
} : void 0;
|
|
45601
|
+
};
|
|
45144
45602
|
const sessionExportPath = (url, scope) => {
|
|
45145
45603
|
const parsed = require_primitives_adapter.parseVirtualSessionId(url.searchParams.get("sessionId") ?? "");
|
|
45146
45604
|
if (parsed === null || scope.targetHostId !== parsed.hostId) throw new Error("远程 Session 导出作用域不匹配");
|
|
@@ -45152,16 +45610,64 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
45152
45610
|
const raw = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
|
|
45153
45611
|
return new URL(raw, typeof document === "undefined" ? "http://codingns.invalid" : document.baseURI);
|
|
45154
45612
|
};
|
|
45613
|
+
const remoteFileUploadFetch = async (url, request, init, virtualSessionId, scope) => {
|
|
45614
|
+
const signal = init?.signal ?? request?.signal;
|
|
45615
|
+
signal?.throwIfAborted();
|
|
45616
|
+
const bodyRequest = new Request(request ?? url.href, init);
|
|
45617
|
+
const bytes = new Uint8Array(await bodyRequest.arrayBuffer());
|
|
45618
|
+
const name = url.searchParams.get("name");
|
|
45619
|
+
const payload = { args: {
|
|
45620
|
+
agentId: virtualSessionId,
|
|
45621
|
+
request: {
|
|
45622
|
+
data: encodeUploadBytesBase64(bytes),
|
|
45623
|
+
...name === null ? {} : { name }
|
|
45624
|
+
}
|
|
45625
|
+
} };
|
|
45626
|
+
try {
|
|
45627
|
+
return jsonResponse({
|
|
45628
|
+
ok: true,
|
|
45629
|
+
value: decodeNativeResponseBytes(await codingNsCall("peerHost/native", {
|
|
45630
|
+
method: "fileUploads/upload",
|
|
45631
|
+
payload,
|
|
45632
|
+
scope
|
|
45633
|
+
}, signal))
|
|
45634
|
+
});
|
|
45635
|
+
} catch (error) {
|
|
45636
|
+
signal?.throwIfAborted();
|
|
45637
|
+
const code = error.code;
|
|
45638
|
+
return jsonResponse({
|
|
45639
|
+
ok: false,
|
|
45640
|
+
error: {
|
|
45641
|
+
code: typeof code === "string" ? code : "gateway/internal",
|
|
45642
|
+
message: error instanceof Error ? error.message : String(error),
|
|
45643
|
+
details: {}
|
|
45644
|
+
}
|
|
45645
|
+
});
|
|
45646
|
+
}
|
|
45647
|
+
};
|
|
45155
45648
|
const remoteSessionExportFetch = async (input, init) => {
|
|
45156
45649
|
if (fetchImpl === void 0) throw new Error("当前页面没有 fetch");
|
|
45157
45650
|
const request = typeof Request !== "undefined" && input instanceof Request ? input : void 0;
|
|
45158
45651
|
const method = (init?.method ?? request?.method ?? "GET").toUpperCase();
|
|
45159
45652
|
const url = readFetchUrl(input);
|
|
45653
|
+
if (url.pathname === "/api/session/uploadFileBinary" && method === "POST") {
|
|
45654
|
+
const parsed = require_primitives_adapter.parseVirtualSessionId(url.searchParams.get("sessionId") ?? "");
|
|
45655
|
+
const uploadScope = scopeForFileUpload(url);
|
|
45656
|
+
if (uploadScope !== void 0 && uploadScope.scope.targetHostId !== null) return remoteFileUploadFetch(url, request, init, uploadScope.virtualSessionId, uploadScope.scope);
|
|
45657
|
+
if (parsed !== null) return jsonResponse({
|
|
45658
|
+
ok: false,
|
|
45659
|
+
error: {
|
|
45660
|
+
code: "PEER_HOST_SCOPE_MISMATCH",
|
|
45661
|
+
message: t("peerHost.sessionUnavailable"),
|
|
45662
|
+
details: {}
|
|
45663
|
+
}
|
|
45664
|
+
}, 409);
|
|
45665
|
+
}
|
|
45160
45666
|
if (url.pathname !== "/api/session.export" || method !== "GET" && method !== "HEAD") return fetchImpl(input, init);
|
|
45161
45667
|
const scope = scopeForSessionExport(url);
|
|
45162
45668
|
if (scope === void 0 || scope.targetHostId === null) return fetchImpl(input, init);
|
|
45163
45669
|
const headers = init?.headers === void 0 && request === void 0 ? void 0 : Object.fromEntries(new Headers(init?.headers ?? request?.headers).entries());
|
|
45164
|
-
const response = asRecord(await codingNsCall("peerHost/request", {
|
|
45670
|
+
const response = asRecord$2(await codingNsCall("peerHost/request", {
|
|
45165
45671
|
peerHostId: scope.targetHostId,
|
|
45166
45672
|
scope,
|
|
45167
45673
|
path: sessionExportPath(url, scope),
|
|
@@ -45193,7 +45699,7 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
45193
45699
|
}
|
|
45194
45700
|
return;
|
|
45195
45701
|
}
|
|
45196
|
-
const object = asRecord(value);
|
|
45702
|
+
const object = asRecord$2(value);
|
|
45197
45703
|
if (object === null) return void 0;
|
|
45198
45704
|
for (const item of Object.values(object)) {
|
|
45199
45705
|
const found = findScope(item);
|
|
@@ -45203,8 +45709,8 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
45203
45709
|
const scopeForNativeRequest = (method, value) => {
|
|
45204
45710
|
if (method === "userQuestions/answer" || method === "userQuestions/attachWait") return findScope(questionAgentId(value));
|
|
45205
45711
|
if (method.startsWith("messageFeedback/") || method === "sessionFeedback/record") {
|
|
45206
|
-
const input = asRecord(value);
|
|
45207
|
-
const request = asRecord(asRecord(input?.args)?.request ?? input?.request);
|
|
45712
|
+
const input = asRecord$2(value);
|
|
45713
|
+
const request = asRecord$2(asRecord$2(input?.args)?.request ?? input?.request);
|
|
45208
45714
|
return findScope(request?.sessionId);
|
|
45209
45715
|
}
|
|
45210
45716
|
const direct = findScope(value);
|
|
@@ -45212,9 +45718,9 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
45212
45718
|
return method === "session/modelCatalog" && !containsResourceId(value) ? navigationScope() : void 0;
|
|
45213
45719
|
};
|
|
45214
45720
|
const scopeForPluginRequest = (endpoint, value) => {
|
|
45215
|
-
if ((endpoint === "cli/catalog" || endpoint === "cli/models" || endpoint === "cli/catalog/refresh") && asRecord(value)?.catalogHostId === "local") return void 0;
|
|
45721
|
+
if ((endpoint === "cli/catalog" || endpoint === "cli/models" || endpoint === "cli/catalog/refresh") && asRecord$2(value)?.catalogHostId === "local") return void 0;
|
|
45216
45722
|
if (endpoint.startsWith("fileManagement/")) {
|
|
45217
|
-
const input = asRecord(value);
|
|
45723
|
+
const input = asRecord$2(value);
|
|
45218
45724
|
const workspace = findScope(input?.workspaceId);
|
|
45219
45725
|
const session = findScope(input?.sessionId);
|
|
45220
45726
|
if (hasVirtualResourceScope(value)) {
|
|
@@ -45225,7 +45731,7 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
45225
45731
|
return workspace ?? session;
|
|
45226
45732
|
}
|
|
45227
45733
|
if (isDebugPluginEndpoint(endpoint)) {
|
|
45228
|
-
const input = asRecord(value);
|
|
45734
|
+
const input = asRecord$2(value);
|
|
45229
45735
|
return findScope(input?.workspaceId) ?? findScope(input?.sessionId);
|
|
45230
45736
|
}
|
|
45231
45737
|
const direct = findScope(value);
|
|
@@ -45238,8 +45744,8 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
45238
45744
|
if (selection !== void 0) {
|
|
45239
45745
|
const direct = findScope(selection);
|
|
45240
45746
|
if (direct !== void 0) return direct;
|
|
45241
|
-
const selected = asRecord(selection);
|
|
45242
|
-
const sessionId = selected?.sessionId ?? asRecord(selected?.subagentAddress)?.parentSessionId;
|
|
45747
|
+
const selected = asRecord$2(selection);
|
|
45748
|
+
const sessionId = selected?.sessionId ?? asRecord$2(selected?.subagentAddress)?.parentSessionId;
|
|
45243
45749
|
const session = typeof sessionId === "string" ? require_primitives_adapter.parseVirtualSessionId(sessionId) : null;
|
|
45244
45750
|
const workspace = typeof selected?.workspaceId === "string" ? require_primitives_adapter.parseVirtualWorkspaceId(selected.workspaceId) : null;
|
|
45245
45751
|
const hostId = session?.hostId ?? workspace?.targetHostId;
|
|
@@ -45263,7 +45769,7 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
45263
45769
|
};
|
|
45264
45770
|
const containsResourceId = (value) => {
|
|
45265
45771
|
if (Array.isArray(value)) return value.some(containsResourceId);
|
|
45266
|
-
const record = asRecord(value);
|
|
45772
|
+
const record = asRecord$2(value);
|
|
45267
45773
|
if (record === null) return false;
|
|
45268
45774
|
for (const [key, child] of Object.entries(record)) {
|
|
45269
45775
|
if ((key === "workspaceId" || key === "sessionId" || key === "parentSessionId") && typeof child === "string" && child !== "") return true;
|
|
@@ -45275,14 +45781,14 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
45275
45781
|
const containsVirtualResourceId = (value) => {
|
|
45276
45782
|
if (typeof value === "string") return require_primitives_adapter.parseVirtualSessionId(value) !== null || require_primitives_adapter.parseVirtualWorkspaceId(value) !== null;
|
|
45277
45783
|
if (Array.isArray(value)) return value.some(containsVirtualResourceId);
|
|
45278
|
-
const record = asRecord(value);
|
|
45784
|
+
const record = asRecord$2(value);
|
|
45279
45785
|
return record !== null && Object.values(record).some(containsVirtualResourceId);
|
|
45280
45786
|
};
|
|
45281
45787
|
const hasUnresolvedVirtualNativeScope = (method, value) => {
|
|
45282
45788
|
if (method === "userQuestions/answer" || method === "userQuestions/attachWait") return false;
|
|
45283
45789
|
if (method.startsWith("messageFeedback/") || method === "sessionFeedback/record") {
|
|
45284
|
-
const input = asRecord(value);
|
|
45285
|
-
const request = asRecord(asRecord(input?.args)?.request ?? input?.request);
|
|
45790
|
+
const input = asRecord$2(value);
|
|
45791
|
+
const request = asRecord$2(asRecord$2(input?.args)?.request ?? input?.request);
|
|
45286
45792
|
return typeof request?.sessionId === "string" && require_primitives_adapter.parseVirtualSessionId(request.sessionId) !== null;
|
|
45287
45793
|
}
|
|
45288
45794
|
return containsVirtualResourceId(value);
|
|
@@ -45293,13 +45799,13 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
45293
45799
|
return (key === "sessionId" || key === "parentSessionId" || key === "childSessionId") && parsed !== null && parsed.hostId === (scope.targetHostId ?? scope.hostId) ? parsed.sessionId : value;
|
|
45294
45800
|
}
|
|
45295
45801
|
if (Array.isArray(value)) return value.map((item) => rewriteCliPayload(item, scope, key));
|
|
45296
|
-
const record = asRecord(value);
|
|
45802
|
+
const record = asRecord$2(value);
|
|
45297
45803
|
if (record === null) return value;
|
|
45298
45804
|
return Object.fromEntries(Object.entries(record).map(([childKey, child]) => [childKey, rewriteCliPayload(child, scope, childKey)]));
|
|
45299
45805
|
};
|
|
45300
45806
|
const remotePluginRpc = async (scope, endpoint, payload, signal) => {
|
|
45301
45807
|
if (scope.targetHostId === null) throw new Error("PeerHost 插件请求缺少目标 Host");
|
|
45302
|
-
const response = asRecord(await codingNsCall("peerHost/request", {
|
|
45808
|
+
const response = asRecord$2(await codingNsCall("peerHost/request", {
|
|
45303
45809
|
peerHostId: scope.targetHostId,
|
|
45304
45810
|
scope,
|
|
45305
45811
|
path: `/api/codingns/${endpoint}`,
|
|
@@ -45308,7 +45814,7 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
45308
45814
|
rpcId: createRequestId(),
|
|
45309
45815
|
method: endpoint,
|
|
45310
45816
|
payload: endpoint.startsWith("git/") ? {
|
|
45311
|
-
...asRecord(payload),
|
|
45817
|
+
...asRecord$2(payload),
|
|
45312
45818
|
workspaceId: scope.workspaceId
|
|
45313
45819
|
} : endpoint.startsWith("cli/") ? rewriteCliPayload(payload, scope) : rewritePluginResourcePayload(payload, scope)
|
|
45314
45820
|
})
|
|
@@ -45318,7 +45824,7 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
45318
45824
|
if (status < 200 || status >= 300) {
|
|
45319
45825
|
let error = null;
|
|
45320
45826
|
try {
|
|
45321
|
-
error = asRecord(asRecord(JSON.parse(body))?.error);
|
|
45827
|
+
error = asRecord$2(asRecord$2(JSON.parse(body))?.error);
|
|
45322
45828
|
} catch {}
|
|
45323
45829
|
if (typeof error?.code === "string" && typeof error.message === "string") return {
|
|
45324
45830
|
ok: false,
|
|
@@ -45330,21 +45836,21 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
45330
45836
|
throw new Error(`远端 Host 插件 RPC 失败: HTTP ${status}`);
|
|
45331
45837
|
}
|
|
45332
45838
|
try {
|
|
45333
|
-
const envelope = asRecord(JSON.parse(body));
|
|
45839
|
+
const envelope = asRecord$2(JSON.parse(body));
|
|
45334
45840
|
return endpoint.startsWith("git/") ? projectGitWorkspaceIds(envelope?.result, scope.workspaceId, require_primitives_adapter.createVirtualWorkspaceId(scope.targetHostId, scope.workspaceId)) : envelope?.result;
|
|
45335
45841
|
} catch {
|
|
45336
45842
|
throw new Error("远端 Host 插件 RPC 响应不是 JSON");
|
|
45337
45843
|
}
|
|
45338
45844
|
};
|
|
45339
45845
|
const mergeRemoteAdapterMap = async (localResult, signal) => {
|
|
45340
|
-
const localEnvelope = asRecord(localResult);
|
|
45846
|
+
const localEnvelope = asRecord$2(localResult);
|
|
45341
45847
|
if (localEnvelope?.ok !== true || !Array.isArray(localEnvelope.value)) return localResult;
|
|
45342
45848
|
const rows = [...localEnvelope.value];
|
|
45343
45849
|
for (const [targetHostId, scope] of remoteHostScopes) try {
|
|
45344
|
-
const remoteEnvelope = asRecord(await remotePluginRpc(scope, "cli/session/adapter-map", {}, signal));
|
|
45850
|
+
const remoteEnvelope = asRecord$2(await remotePluginRpc(scope, "cli/session/adapter-map", {}, signal));
|
|
45345
45851
|
if (remoteEnvelope?.ok !== true || !Array.isArray(remoteEnvelope.value)) continue;
|
|
45346
45852
|
for (const raw of remoteEnvelope.value) {
|
|
45347
|
-
const row = asRecord(raw);
|
|
45853
|
+
const row = asRecord$2(raw);
|
|
45348
45854
|
const sessionId = typeof row?.sessionId === "string" ? row.sessionId : "";
|
|
45349
45855
|
const adapterId = typeof row?.adapterId === "string" ? row.adapterId : "";
|
|
45350
45856
|
if (sessionId !== "" && adapterId !== "") rows.push({
|
|
@@ -45359,7 +45865,7 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
45359
45865
|
};
|
|
45360
45866
|
};
|
|
45361
45867
|
const openRemoteStream = (method, payload, scope, signal) => (async function* () {
|
|
45362
|
-
const opened = asRecord(await codingNsCall("peerHost/nativeStream", {
|
|
45868
|
+
const opened = asRecord$2(await codingNsCall("peerHost/nativeStream", {
|
|
45363
45869
|
method,
|
|
45364
45870
|
payload,
|
|
45365
45871
|
scope
|
|
@@ -45368,7 +45874,7 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
45368
45874
|
if (streamId === "") throw new Error("PeerHost 原生 Remote 未返回 streamId");
|
|
45369
45875
|
try {
|
|
45370
45876
|
while (!(signal?.aborted ?? false)) {
|
|
45371
|
-
const next = asRecord(await codingNsCall("peerHost/nativeStreamNext", {
|
|
45877
|
+
const next = asRecord$2(await codingNsCall("peerHost/nativeStreamNext", {
|
|
45372
45878
|
streamId,
|
|
45373
45879
|
scope
|
|
45374
45880
|
}, signal));
|
|
@@ -45392,6 +45898,9 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
45392
45898
|
scope
|
|
45393
45899
|
}, signal),
|
|
45394
45900
|
accepts: (agentId, scope) => scopes.get(agentId)?.targetHostId === scope.targetHostId,
|
|
45901
|
+
onSessionStatus: (sessionId, running) => {
|
|
45902
|
+
projection.setSessionRunning(sessionId, running);
|
|
45903
|
+
},
|
|
45395
45904
|
prepare: async () => {
|
|
45396
45905
|
if (nativeSessionPrepared) return;
|
|
45397
45906
|
nativeSessionPrepared = true;
|
|
@@ -45407,7 +45916,7 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
45407
45916
|
return pending;
|
|
45408
45917
|
};
|
|
45409
45918
|
const rememberCreatedSession = (scope, value) => {
|
|
45410
|
-
const sessionId = asRecord(value)?.sessionId;
|
|
45919
|
+
const sessionId = asRecord$2(value)?.sessionId;
|
|
45411
45920
|
if (typeof sessionId !== "string") return;
|
|
45412
45921
|
const parsed = require_primitives_adapter.parseVirtualSessionId(sessionId);
|
|
45413
45922
|
if (parsed === null) return;
|
|
@@ -45437,17 +45946,22 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
45437
45946
|
};
|
|
45438
45947
|
/** 父会话目录早于聚合到达时,复用新建会话的临时作用域与清理机制。 */
|
|
45439
45948
|
const rememberSubagentCatalog = (scope, value) => {
|
|
45440
|
-
const catalog = asRecord(asRecord(asRecord(value)?.projections)?.values)?.subagentCatalog;
|
|
45441
|
-
if (!Array.isArray(catalog)) return;
|
|
45949
|
+
const catalog = asRecord$2(asRecord$2(asRecord$2(value)?.projections)?.values)?.subagentCatalog;
|
|
45950
|
+
if (!Array.isArray(catalog)) return false;
|
|
45951
|
+
let changed = false;
|
|
45442
45952
|
for (const child of catalog) {
|
|
45443
|
-
const id = asRecord(child)?.id;
|
|
45444
|
-
if (typeof id === "string" && !scopes.has(id))
|
|
45953
|
+
const id = asRecord$2(child)?.id;
|
|
45954
|
+
if (typeof id === "string" && !scopes.has(id)) {
|
|
45955
|
+
rememberCreatedSession(scope, { sessionId: id });
|
|
45956
|
+
changed = true;
|
|
45957
|
+
}
|
|
45445
45958
|
}
|
|
45959
|
+
return changed;
|
|
45446
45960
|
};
|
|
45447
45961
|
return {
|
|
45448
45962
|
hooks: {
|
|
45449
45963
|
rpc: async ({ method, payload, signal }) => {
|
|
45450
|
-
const value = asRecord(payload);
|
|
45964
|
+
const value = asRecord$2(payload);
|
|
45451
45965
|
const channel = typeof value?.channel === "string" ? value.channel : "/codingns";
|
|
45452
45966
|
const body = value?.payload;
|
|
45453
45967
|
if (channel === "/api" && method === "$events/result" && events.ownsResult(body)) try {
|
|
@@ -45482,7 +45996,7 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
45482
45996
|
message: t("peerHost.debugWorkspaceUnavailable")
|
|
45483
45997
|
}
|
|
45484
45998
|
};
|
|
45485
|
-
const workspaceId = asRecord(body)?.workspaceId;
|
|
45999
|
+
const workspaceId = asRecord$2(body)?.workspaceId;
|
|
45486
46000
|
const scope = endpoint.startsWith("git/") ? findScope(workspaceId) : scopeForPluginRequest(endpoint, body);
|
|
45487
46001
|
if (endpoint.startsWith("git/") && typeof workspaceId === "string" && require_primitives_adapter.parseVirtualWorkspaceId(workspaceId) !== null && scope === void 0) return {
|
|
45488
46002
|
ok: false,
|
|
@@ -45525,9 +46039,17 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
45525
46039
|
payload: body,
|
|
45526
46040
|
scope
|
|
45527
46041
|
}, signal));
|
|
45528
|
-
|
|
45529
|
-
|
|
45530
|
-
|
|
46042
|
+
const createsSession = method === "session/create" || method === "session/fork";
|
|
46043
|
+
const refreshesNativeList = method === "session/rename" || method === "workspace/archiveSession" || method === "workspace/unarchiveSession";
|
|
46044
|
+
if (createsSession) rememberCreatedSession(scope, created);
|
|
46045
|
+
if (createsSession || refreshesNativeList) {
|
|
46046
|
+
let aggregateRefresh;
|
|
46047
|
+
try {
|
|
46048
|
+
aggregateRefresh = requestPeerHostAggregateRefresh();
|
|
46049
|
+
} catch {
|
|
46050
|
+
aggregateRefresh = void 0;
|
|
46051
|
+
}
|
|
46052
|
+
if (refreshesNativeList) Promise.resolve(aggregateRefresh).then(() => refreshPeerHostNativeSessions(uiContext)).catch(() => void 0);
|
|
45531
46053
|
}
|
|
45532
46054
|
return {
|
|
45533
46055
|
ok: true,
|
|
@@ -45549,7 +46071,7 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
45549
46071
|
return result;
|
|
45550
46072
|
},
|
|
45551
46073
|
openStream: ({ method, payload, signal }) => {
|
|
45552
|
-
const value = asRecord(payload);
|
|
46074
|
+
const value = asRecord$2(payload);
|
|
45553
46075
|
const channel = typeof value?.channel === "string" ? value.channel : "/api";
|
|
45554
46076
|
const body = value?.payload;
|
|
45555
46077
|
if (channel === "/api" && method === "$events") return events.open((localSignal) => openDshGatewayStream(method, body, localSignal), signal);
|
|
@@ -45565,16 +46087,13 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
45565
46087
|
const stream = openRemoteStream(method, body, scope, signal);
|
|
45566
46088
|
if (method !== "session/follow") return stream;
|
|
45567
46089
|
return (async function* () {
|
|
45568
|
-
let emitted = false;
|
|
45569
46090
|
try {
|
|
45570
46091
|
for await (const chunk of stream) {
|
|
45571
|
-
|
|
45572
|
-
rememberSubagentCatalog(scope, chunk);
|
|
45573
|
-
scheduleAggregateRefresh();
|
|
46092
|
+
if (rememberSubagentCatalog(scope, chunk)) scheduleAggregateRefresh();
|
|
45574
46093
|
yield chunk;
|
|
45575
46094
|
}
|
|
45576
46095
|
} finally {
|
|
45577
|
-
if (!
|
|
46096
|
+
if (!(signal?.aborted ?? false)) scheduleAggregateRefresh();
|
|
45578
46097
|
}
|
|
45579
46098
|
})();
|
|
45580
46099
|
}
|
|
@@ -45608,7 +46127,7 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
45608
46127
|
return scope === void 0 ? hasVirtualResourceScope(value) : scope.targetHostId !== null;
|
|
45609
46128
|
}
|
|
45610
46129
|
if (method?.startsWith("git/") || method?.startsWith("codingns/git/")) {
|
|
45611
|
-
const workspaceId = asRecord(value)?.workspaceId;
|
|
46130
|
+
const workspaceId = asRecord$2(value)?.workspaceId;
|
|
45612
46131
|
return typeof workspaceId === "string" && require_primitives_adapter.parseVirtualWorkspaceId(workspaceId) !== null;
|
|
45613
46132
|
}
|
|
45614
46133
|
const cli = method === void 0 ? void 0 : method === "cli/catalog" || method === "cli/models" ? method : method.startsWith("codingns/cli/") ? method.slice(9) : void 0;
|
|
@@ -45681,6 +46200,13 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
45681
46200
|
}
|
|
45682
46201
|
refreshModelCatalogForScope(navigationScope());
|
|
45683
46202
|
const changed = projection.setAggregate(aggregate, orderedWorkspaceIds);
|
|
46203
|
+
for (const sessionId of projection.consumeCompletedSessionTransitions()) {
|
|
46204
|
+
const scope = scopes.get(sessionId);
|
|
46205
|
+
if (scope === void 0) continue;
|
|
46206
|
+
projection.setSessionRunning(sessionId, false);
|
|
46207
|
+
events.replayCompletedSessionStatus(sessionId, scope);
|
|
46208
|
+
}
|
|
46209
|
+
events.replayPendingSessionStatuses();
|
|
45684
46210
|
const readyHosts = new Set(aggregate.filter((host) => host.availability === "ready" && host.workspaces.length > 0).map((host) => host.targetHostId));
|
|
45685
46211
|
events.setPeers([...remoteHostScopes.values()].filter((scope) => readyHosts.has(scope.targetHostId)));
|
|
45686
46212
|
return changed;
|
|
@@ -45693,8 +46219,8 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
45693
46219
|
return endpoint.startsWith("cli/") || endpoint.startsWith("git/") || endpoint.startsWith("debug/") || endpoint.startsWith("fileManagement/") || endpoint === "terminal/status" ? endpoint : void 0;
|
|
45694
46220
|
}
|
|
45695
46221
|
function questionAgentId(value) {
|
|
45696
|
-
const input = asRecord(value);
|
|
45697
|
-
return asRecord(input?.args)?.agentId ?? input?.agentId;
|
|
46222
|
+
const input = asRecord$2(value);
|
|
46223
|
+
return asRecord$2(input?.args)?.agentId ?? input?.agentId;
|
|
45698
46224
|
}
|
|
45699
46225
|
function hasVirtualQuestionAgent(method, value) {
|
|
45700
46226
|
if (method !== "userQuestions/answer" && method !== "userQuestions/attachWait") return false;
|
|
@@ -45705,19 +46231,19 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
45705
46231
|
return endpoint.startsWith("debug/") || endpoint === "terminal/status";
|
|
45706
46232
|
}
|
|
45707
46233
|
function hasVirtualResourceScope(value) {
|
|
45708
|
-
const input = asRecord(value);
|
|
46234
|
+
const input = asRecord$2(value);
|
|
45709
46235
|
return typeof input?.workspaceId === "string" && require_primitives_adapter.parseVirtualWorkspaceId(input.workspaceId) !== null || typeof input?.sessionId === "string" && require_primitives_adapter.parseVirtualSessionId(input.sessionId) !== null;
|
|
45710
46236
|
}
|
|
45711
46237
|
/** 只投影响应中的工作区标识;Diff、提交正文和文件路径均保持原文。 */
|
|
45712
46238
|
function projectGitWorkspaceIds(value, workspaceId, virtualWorkspaceId) {
|
|
45713
46239
|
if (Array.isArray(value)) return value.map((item) => projectGitWorkspaceIds(item, workspaceId, virtualWorkspaceId));
|
|
45714
|
-
const record = asRecord(value);
|
|
46240
|
+
const record = asRecord$2(value);
|
|
45715
46241
|
if (record === null) return value;
|
|
45716
46242
|
return Object.fromEntries(Object.entries(record).map(([key, child]) => [key, key === "workspaceId" && child === workspaceId ? virtualWorkspaceId : projectGitWorkspaceIds(child, workspaceId, virtualWorkspaceId)]));
|
|
45717
46243
|
}
|
|
45718
46244
|
/** 只还原调试与文件请求的顶层资源标识,配置、文件正文和路径必须原样保存。 */
|
|
45719
46245
|
function rewritePluginResourcePayload(value, scope) {
|
|
45720
|
-
const input = asRecord(value);
|
|
46246
|
+
const input = asRecord$2(value);
|
|
45721
46247
|
if (input === null) return value;
|
|
45722
46248
|
const result = { ...input };
|
|
45723
46249
|
const workspace = typeof input.workspaceId === "string" ? require_primitives_adapter.parseVirtualWorkspaceId(input.workspaceId) : null;
|
|
@@ -45818,7 +46344,7 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
45818
46344
|
/** 只借用原生导航数据,不修改选择策略,也不从后台保留会话推断前台。 */
|
|
45819
46345
|
function readNativeNavigationStore(uiContext) {
|
|
45820
46346
|
try {
|
|
45821
|
-
const store = asRecord(asRecord(uiContext?.get("uiWorkspace"))?.selection);
|
|
46347
|
+
const store = asRecord$2(asRecord$2(uiContext?.get("uiWorkspace"))?.selection);
|
|
45822
46348
|
if (typeof store?.getSnapshot !== "function" || typeof store.subscribe !== "function") return void 0;
|
|
45823
46349
|
return store;
|
|
45824
46350
|
} catch {
|
|
@@ -45827,14 +46353,14 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
45827
46353
|
}
|
|
45828
46354
|
/** 把虚拟会话摘要并入 session/list 结果;形状不符时保持本机结果不变。 */
|
|
45829
46355
|
function mergeSessionListResult(result, projection) {
|
|
45830
|
-
const envelope = asRecord(result);
|
|
46356
|
+
const envelope = asRecord$2(result);
|
|
45831
46357
|
if (envelope?.ok !== true) return result;
|
|
45832
|
-
const value = asRecord(envelope.value);
|
|
46358
|
+
const value = asRecord$2(envelope.value);
|
|
45833
46359
|
if (value === null || !Array.isArray(value.items)) return result;
|
|
45834
46360
|
const virtual = projection.sessions();
|
|
45835
46361
|
if (virtual.length === 0) return result;
|
|
45836
46362
|
const known = new Set(value.items.flatMap((item) => {
|
|
45837
|
-
const id = asRecord(item)?.sessionId;
|
|
46363
|
+
const id = asRecord$2(item)?.sessionId;
|
|
45838
46364
|
return typeof id === "string" ? [id] : [];
|
|
45839
46365
|
}));
|
|
45840
46366
|
for (const session of virtual) if (session.adapterId !== void 0) publishSessionAdapter(session.sessionId, session.adapterId);
|
|
@@ -45850,7 +46376,7 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
45850
46376
|
function createRequestId() {
|
|
45851
46377
|
return typeof globalThis.crypto?.randomUUID === "function" ? globalThis.crypto.randomUUID() : `${Date.now()}-${Math.random()}`;
|
|
45852
46378
|
}
|
|
45853
|
-
function asRecord(value) {
|
|
46379
|
+
function asRecord$2(value) {
|
|
45854
46380
|
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
|
|
45855
46381
|
}
|
|
45856
46382
|
/**
|
|
@@ -45869,8 +46395,8 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
45869
46395
|
}
|
|
45870
46396
|
const metadata = fields.get("metadata");
|
|
45871
46397
|
if (typeof metadata !== "string") throw new TypeError("connection: invalid binary response fields");
|
|
45872
|
-
const envelope = asRecord(JSON.parse(metadata));
|
|
45873
|
-
const result = asRecord(envelope?.result);
|
|
46398
|
+
const envelope = asRecord$2(JSON.parse(metadata));
|
|
46399
|
+
const result = asRecord$2(envelope?.result);
|
|
45874
46400
|
if (envelope === null || result === null) throw new TypeError("connection: invalid server-response envelope");
|
|
45875
46401
|
fields.delete("metadata");
|
|
45876
46402
|
if (result.ok !== true) {
|
|
@@ -45881,7 +46407,7 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
45881
46407
|
if (!Array.isArray(attachments) || attachments.length === 0) throw new TypeError("connection: invalid binary response result");
|
|
45882
46408
|
const root = { value: result.value };
|
|
45883
46409
|
for (const rawAttachment of attachments) {
|
|
45884
|
-
const attachment = asRecord(rawAttachment);
|
|
46410
|
+
const attachment = asRecord$2(rawAttachment);
|
|
45885
46411
|
const path = attachment?.path;
|
|
45886
46412
|
const part = attachment?.part;
|
|
45887
46413
|
if (attachment?.codec !== "bytes" || typeof part !== "string" || !Array.isArray(path)) throw new TypeError("connection: invalid binary response attachment");
|
|
@@ -45926,8 +46452,8 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
45926
46452
|
function refreshDshModelCatalog(uiContext) {
|
|
45927
46453
|
if (uiContext === void 0) return;
|
|
45928
46454
|
try {
|
|
45929
|
-
const service = asRecord(uiContext.get("modelDirectories"));
|
|
45930
|
-
const catalog = service === null ? null : asRecord(service.catalog);
|
|
46455
|
+
const service = asRecord$2(uiContext.get("modelDirectories"));
|
|
46456
|
+
const catalog = service === null ? null : asRecord$2(service.catalog);
|
|
45931
46457
|
if (catalog === null) return;
|
|
45932
46458
|
const resetGeneration = catalog.resetGeneration;
|
|
45933
46459
|
const refresh = catalog.refresh;
|
|
@@ -46109,6 +46635,20 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
46109
46635
|
for (let index = 0; index < binary.length; index += 1) bytes[index] = binary.charCodeAt(index);
|
|
46110
46636
|
return bytes.buffer;
|
|
46111
46637
|
}
|
|
46638
|
+
function encodeUploadBytesBase64(bytes) {
|
|
46639
|
+
let binary = "";
|
|
46640
|
+
for (const byte of bytes) binary += String.fromCharCode(byte);
|
|
46641
|
+
if (typeof btoa === "function") return btoa(binary);
|
|
46642
|
+
const nodeBuffer = globalThis.Buffer;
|
|
46643
|
+
if (nodeBuffer !== void 0) return nodeBuffer.from(bytes).toString("base64");
|
|
46644
|
+
throw new Error("当前运行时不支持 Base64 编码");
|
|
46645
|
+
}
|
|
46646
|
+
function jsonResponse(value, status = 200) {
|
|
46647
|
+
return new Response(JSON.stringify(value), {
|
|
46648
|
+
status,
|
|
46649
|
+
headers: { "content-type": "application/json; charset=utf-8" }
|
|
46650
|
+
});
|
|
46651
|
+
}
|
|
46112
46652
|
/** PeerHost 启用状态说明;安装动作发生在启动页 preboot 阶段。 */
|
|
46113
46653
|
function PeerHostPanel({ services, enabled }) {
|
|
46114
46654
|
const t = require_transport.useCodingNsTranslator(services.locale);
|
|
@@ -47917,15 +48457,40 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
47917
48457
|
}
|
|
47918
48458
|
//#endregion
|
|
47919
48459
|
//#region src/client/avatar/notification-bubble.ts
|
|
47920
|
-
|
|
48460
|
+
/** 返回形象中心在通知面板坐标系中的投影;仅供旧调用方和布局测试使用。 */
|
|
48461
|
+
function assistantNotificationTailStyle(avatarCenter, regionStart, regionSize, side = "bottom") {
|
|
48462
|
+
if (side === "left" || side === "right") return {};
|
|
48463
|
+
const margin = 36;
|
|
48464
|
+
const target = avatarCenter - regionStart;
|
|
48465
|
+
const rootTarget = target - Math.sign(target - regionSize / 2) * 10;
|
|
48466
|
+
const center = Math.max(margin, Math.min(Math.max(margin, regionSize - margin), rootTarget));
|
|
48467
|
+
const bottomAngle = Math.max(-20, Math.min(20, -Math.atan2(target - center, 30) * 180 / Math.PI));
|
|
48468
|
+
const angle = side === "top" ? -bottomAngle : bottomAngle;
|
|
48469
|
+
return {
|
|
48470
|
+
"--codingns-assistant-tail-offset": `${Math.round(center)}px`,
|
|
48471
|
+
"--codingns-assistant-tail-target": `${Math.round(target)}px`,
|
|
48472
|
+
"--codingns-assistant-tail-angle": `${Math.round(angle * 10) / 10}deg`
|
|
48473
|
+
};
|
|
48474
|
+
}
|
|
48475
|
+
/** 实际面板边缘使用的目标投影,允许目标落在圆角外侧后由轮廓算法自然收敛。 */
|
|
48476
|
+
function assistantNotificationTailTarget(avatarCenter, regionStart) {
|
|
48477
|
+
return avatarCenter - regionStart;
|
|
48478
|
+
}
|
|
48479
|
+
function isPendingNotice(notice) {
|
|
48480
|
+
return (notice.kind === "question" || notice.kind === "approval") && notice.lifecycle === "active";
|
|
48481
|
+
}
|
|
48482
|
+
function AssistantNotificationBubble({ frame, t, error, onOpen, onDismiss, onAutoClose, onPresented, autoClose = false, autoCloseSeconds = 30, onExpandedChange, onCollapsedChange, onClearAll, onSizeChange, tailSide = "bottom", tailTarget, tailStyle }) {
|
|
47921
48483
|
const [expanded, setExpanded] = (0, react.useState)(false);
|
|
47922
|
-
const [
|
|
48484
|
+
const [collapsed, setCollapsed] = (0, react.useState)(false);
|
|
48485
|
+
const [listFilter, setListFilter] = (0, react.useState)("all");
|
|
48486
|
+
const [processing, setProcessing] = (0, react.useState)(false);
|
|
47923
48487
|
const bubble = (0, react.useRef)(null);
|
|
48488
|
+
const shellBox = (0, react.useRef)(null);
|
|
47924
48489
|
const autoCloseTimer = (0, react.useRef)(void 0);
|
|
47925
48490
|
const snapshot = "items" in frame ? frame : void 0;
|
|
47926
48491
|
const primary = snapshot === void 0 ? frame : snapshot.primary;
|
|
47927
|
-
const items = snapshot
|
|
47928
|
-
const attentionItems = snapshot === void 0 ? primary === void 0 || primary === null ? [] : [primary] : [...snapshot.primary === null || snapshot.primary.presentation === "collapsed" ? [] : [snapshot.primary], ...items.filter((notice) => notice.presentation !== "collapsed" && (!notice.read || (notice
|
|
48492
|
+
const items = snapshot === void 0 ? [] : [...snapshot.primary !== null && !snapshot.items.some((notice) => notice.noticeId === snapshot.primary.noticeId) ? [snapshot.primary] : [], ...snapshot.items];
|
|
48493
|
+
const attentionItems = snapshot === void 0 ? primary === void 0 || primary === null ? [] : [primary] : [...snapshot.primary === null || snapshot.primary.presentation === "collapsed" ? [] : [snapshot.primary], ...items.filter((notice) => notice.presentation !== "collapsed" && (!notice.read || isPendingNotice(notice)) && notice.noticeId !== snapshot.primary?.noticeId)];
|
|
47929
48494
|
const multiple = attentionItems.length > 1 || snapshot !== void 0 && Math.max(snapshot.unreadCount, snapshot.pendingCount) > 1;
|
|
47930
48495
|
const mainNotice = attentionItems[0] ?? (snapshot === void 0 ? primary ?? void 0 : void 0);
|
|
47931
48496
|
const presented = attentionItems[0] ?? (snapshot === void 0 ? primary ?? void 0 : void 0);
|
|
@@ -47934,8 +48499,18 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
47934
48499
|
onExpandedChange?.(expanded);
|
|
47935
48500
|
}, [expanded, onExpandedChange]);
|
|
47936
48501
|
(0, react.useEffect)(() => {
|
|
47937
|
-
|
|
48502
|
+
setCollapsed(false);
|
|
48503
|
+
}, [frame.generation]);
|
|
48504
|
+
(0, react.useEffect)(() => {
|
|
48505
|
+
setListFilter("all");
|
|
47938
48506
|
}, [frame.generation, snapshot?.reset]);
|
|
48507
|
+
(0, react.useEffect)(() => {
|
|
48508
|
+
const node = shellBox.current;
|
|
48509
|
+
if (onSizeChange === void 0 || node === null || typeof ResizeObserver === "undefined") return;
|
|
48510
|
+
const observer = new ResizeObserver(() => onSizeChange(Math.ceil(node.getBoundingClientRect().height)));
|
|
48511
|
+
observer.observe(node);
|
|
48512
|
+
return () => observer.disconnect();
|
|
48513
|
+
}, [onSizeChange]);
|
|
47939
48514
|
(0, react.useEffect)(() => {
|
|
47940
48515
|
if (presented === void 0 || presented === null) return;
|
|
47941
48516
|
const node = bubble.current;
|
|
@@ -47947,7 +48522,8 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
47947
48522
|
const connectionGeneration = "connectionGeneration" in presented ? presented.connectionGeneration : void 0;
|
|
47948
48523
|
autoCloseTimer.current = setTimeout(() => {
|
|
47949
48524
|
autoCloseTimer.current = void 0;
|
|
47950
|
-
|
|
48525
|
+
if (onAutoClose !== void 0) onAutoClose(presented.noticeId, frame.generation, connectionGeneration);
|
|
48526
|
+
else onDismiss(presented.noticeId, frame.generation, connectionGeneration);
|
|
47951
48527
|
}, autoCloseSeconds * 1e3);
|
|
47952
48528
|
};
|
|
47953
48529
|
const confirm = () => {
|
|
@@ -47983,26 +48559,62 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
47983
48559
|
presented?.connectionGeneration,
|
|
47984
48560
|
createdAt,
|
|
47985
48561
|
frame.generation,
|
|
48562
|
+
expanded,
|
|
48563
|
+
collapsed,
|
|
47986
48564
|
autoClose,
|
|
47987
48565
|
autoCloseSeconds,
|
|
47988
48566
|
onPresented,
|
|
47989
|
-
onDismiss
|
|
48567
|
+
onDismiss,
|
|
48568
|
+
onAutoClose
|
|
47990
48569
|
]);
|
|
47991
|
-
const
|
|
47992
|
-
|
|
47993
|
-
|
|
47994
|
-
|
|
47995
|
-
|
|
47996
|
-
const
|
|
48570
|
+
const clearableCount = snapshot === void 0 ? 0 : [...snapshot.items, ...snapshot.primary === null ? [] : [snapshot.primary]].filter((notice) => !notice.read && !isPendingNotice(notice)).length;
|
|
48571
|
+
const showClearAll = snapshot !== void 0 && clearableCount > 0 && onClearAll !== void 0;
|
|
48572
|
+
const hasNotificationCounts = snapshot !== void 0 && (snapshot.unreadCount > 0 || snapshot.pendingCount > 0);
|
|
48573
|
+
const showCollapseButton = !collapsed && (mainNotice !== void 0 || hasNotificationCounts);
|
|
48574
|
+
const showExpandButton = collapsed && (mainNotice !== void 0 || hasNotificationCounts);
|
|
48575
|
+
const showTopRow = showCollapseButton || showExpandButton || showClearAll || hasNotificationCounts;
|
|
48576
|
+
const showBubble = !collapsed && (!expanded || snapshot === void 0) && mainNotice !== void 0;
|
|
48577
|
+
const showFilterTags = snapshot !== void 0 && hasNotificationCounts && (multiple || items.length > 1);
|
|
48578
|
+
const listItems = listFilter === "unread" ? items.filter((notice) => !notice.read && !isPendingNotice(notice)) : listFilter === "pending" ? items.filter((notice) => isPendingNotice(notice)) : items;
|
|
48579
|
+
const tail = tailSide !== "top" && (showBubble || expanded && snapshot !== void 0) ? (0, react.createElement)("span", {
|
|
48580
|
+
"aria-hidden": true,
|
|
48581
|
+
"data-codingns-notification-tail": tailSide,
|
|
48582
|
+
style: {
|
|
48583
|
+
...tailBox(tailSide),
|
|
48584
|
+
...tailStyle
|
|
48585
|
+
}
|
|
48586
|
+
}, (0, react.createElement)("svg", {
|
|
48587
|
+
width: 56,
|
|
48588
|
+
height: 36,
|
|
48589
|
+
viewBox: `0 0 56 36`,
|
|
48590
|
+
"aria-hidden": true,
|
|
48591
|
+
style: tailSvg(tailSide)
|
|
48592
|
+
}, (0, react.createElement)("path", {
|
|
48593
|
+
d: `${notificationTailCurve} Z`,
|
|
48594
|
+
fill: notificationTheme.surface
|
|
48595
|
+
}))) : null;
|
|
48596
|
+
const toggleFilter = (filter) => {
|
|
48597
|
+
setCollapsed(false);
|
|
48598
|
+
onCollapsedChange?.(false);
|
|
48599
|
+
setListFilter(listFilter === filter ? "all" : filter);
|
|
48600
|
+
setExpanded(true);
|
|
48601
|
+
};
|
|
48602
|
+
const requestLine = (notice, compact = false) => {
|
|
48603
|
+
const approval = notice.kind === "approval";
|
|
48604
|
+
const tagStyle = compact ? approval ? compactApprovalTag : compactRequestTag : approval ? approvalInlineTag : requestInlineTag;
|
|
48605
|
+
return (0, react.createElement)("span", { style: requestPrompt }, t("awb.notifications.requestPrefix"), (0, react.createElement)("span", { style: tagStyle }, approval ? t("awb.notifications.approvalTag") : t("awb.notifications.questionTag")), t("awb.notifications.requestSuffix"));
|
|
48606
|
+
};
|
|
48607
|
+
const row = (notice, variant) => (0, react.createElement)("section", {
|
|
47997
48608
|
key: notice.noticeId,
|
|
47998
48609
|
"data-codingns-notice-id": notice.noticeId,
|
|
47999
48610
|
"data-codingns-notice-kind": notice.kind,
|
|
48000
|
-
style: variant === "primary" ? primaryCard :
|
|
48001
|
-
}, (0, react.createElement)("div", { style: cardHeading }, (0, react.createElement)("span", {
|
|
48611
|
+
style: variant === "primary" ? primaryCard : compactCard
|
|
48612
|
+
}, (0, react.createElement)("div", { style: cardBody }, (0, react.createElement)("div", { style: cardHeading }, (0, react.createElement)("span", {
|
|
48002
48613
|
"aria-hidden": true,
|
|
48003
48614
|
style: {
|
|
48004
48615
|
...kindMark,
|
|
48005
|
-
background: noticeKindColor[notice.kind]
|
|
48616
|
+
background: noticeKindColor[notice.kind],
|
|
48617
|
+
...noticeKindForeground[notice.kind] === void 0 ? {} : { color: noticeKindForeground[notice.kind] }
|
|
48006
48618
|
}
|
|
48007
48619
|
}, icons[notice.kind]), (0, react.createElement)("div", {
|
|
48008
48620
|
style: {
|
|
@@ -48010,9 +48622,9 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
48010
48622
|
flex: "1 1 auto"
|
|
48011
48623
|
},
|
|
48012
48624
|
title: `${notice.hostLabel} · ${notice.workspaceLabel} · ${notice.sessionTitle}`
|
|
48013
|
-
}, (0, react.createElement)("div", { style: cardMeta }, `${notice.hostLabel} · ${notice.workspaceLabel}`), (0, react.createElement)("div", { style: cardTitle }, notice.sessionTitle))), variant === "compact" ?
|
|
48625
|
+
}, (0, react.createElement)("div", { style: cardMeta }, `${notice.hostLabel} · ${notice.workspaceLabel}`), (0, react.createElement)("div", { style: cardTitle }, notice.sessionTitle))), variant === "compact" ? notice.kind === "question" || notice.kind === "approval" ? (0, react.createElement)("div", { style: compactPrompt }, requestLine(notice, true)) : (0, react.createElement)("span", { style: compactStatus }, notificationStatus(notice, t)) : null, variant !== "compact" ? (0, react.createElement)("div", { style: messageText }, notice.kind === "question" || notice.kind === "approval" ? requestLine(notice) : (0, react.createElement)("span", null, (0, react.createElement)("span", { "aria-hidden": true }, icons[notice.kind] + " "), notice.text), "errorExcerpt" in notice && notice.errorExcerpt ? (0, react.createElement)("div", null, notice.errorExcerpt) : null) : null, notice.availability !== "ready" ? (0, react.createElement)("span", { role: "status" }, t(notice.availability === "disconnected" ? "awb.notifications.disconnected" : "awb.notifications.expired")) : null), (0, react.createElement)("div", { style: actionRow }, (0, react.createElement)("button", {
|
|
48014
48626
|
type: "button",
|
|
48015
|
-
style:
|
|
48627
|
+
style: notificationActionButton,
|
|
48016
48628
|
disabled: notice.availability !== "ready",
|
|
48017
48629
|
"aria-label": [
|
|
48018
48630
|
t("awb.notifications.open"),
|
|
@@ -48020,94 +48632,107 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
48020
48632
|
notice.workspaceLabel,
|
|
48021
48633
|
notice.sessionTitle
|
|
48022
48634
|
].join(" · "),
|
|
48635
|
+
title: t("awb.notifications.open"),
|
|
48636
|
+
"data-codingns-notification-action": "open",
|
|
48023
48637
|
onClick: () => onOpen(notice.noticeId, frame.generation, "connectionGeneration" in notice ? notice.connectionGeneration : void 0)
|
|
48024
|
-
},
|
|
48638
|
+
}, notificationActionIcon("open")), (0, react.createElement)("button", {
|
|
48025
48639
|
type: "button",
|
|
48026
|
-
style:
|
|
48640
|
+
style: notificationActionButton,
|
|
48027
48641
|
"aria-label": [
|
|
48028
48642
|
t("awb.notifications.dismiss"),
|
|
48029
48643
|
notice.hostLabel,
|
|
48030
48644
|
notice.workspaceLabel,
|
|
48031
48645
|
notice.sessionTitle
|
|
48032
48646
|
].join(" · "),
|
|
48647
|
+
title: t("awb.notifications.dismiss"),
|
|
48648
|
+
"data-codingns-notification-action": "dismiss",
|
|
48033
48649
|
onClick: () => {
|
|
48034
48650
|
clearTimeout(autoCloseTimer.current);
|
|
48035
48651
|
autoCloseTimer.current = void 0;
|
|
48036
48652
|
onDismiss(notice.noticeId, frame.generation, "connectionGeneration" in notice ? notice.connectionGeneration : void 0);
|
|
48037
48653
|
}
|
|
48038
|
-
},
|
|
48654
|
+
}, notificationActionIcon("dismiss"))));
|
|
48655
|
+
const capabilityNotices = collapsed ? [] : snapshot?.capabilities?.filter((capability) => capability.reason && (!capability.completed || !capability.error || !capability.requests || !capability.resolve || !capability.navigation)).map((capability) => (0, react.createElement)("div", {
|
|
48656
|
+
key: capability.hostId,
|
|
48657
|
+
role: "status",
|
|
48658
|
+
style: panel
|
|
48659
|
+
}, capability.reason)) ?? [];
|
|
48039
48660
|
return (0, react.createElement)("div", {
|
|
48661
|
+
ref: shellBox,
|
|
48040
48662
|
"data-codingns-assistant-notifications": true,
|
|
48041
48663
|
style: shell,
|
|
48042
48664
|
onPointerDown: (event) => event.stopPropagation(),
|
|
48043
48665
|
onClick: (event) => event.stopPropagation()
|
|
48044
|
-
},
|
|
48666
|
+
}, (0, react.createElement)("style", null, notificationBubbleCss), tail, showTopRow ? (0, react.createElement)("div", {
|
|
48667
|
+
"data-codingns-notification-toolbar": true,
|
|
48668
|
+
style: topRow
|
|
48669
|
+
}, showCollapseButton || showExpandButton ? (0, react.createElement)("button", {
|
|
48045
48670
|
type: "button",
|
|
48046
|
-
style:
|
|
48047
|
-
"aria-expanded":
|
|
48048
|
-
"aria-label":
|
|
48049
|
-
|
|
48050
|
-
t("awb.notifications.unread", { count: snapshot.unreadCount }),
|
|
48051
|
-
t("awb.notifications.pending", { count: snapshot.pendingCount })
|
|
48052
|
-
].join(" · "),
|
|
48671
|
+
style: toolbarIconButton,
|
|
48672
|
+
"aria-expanded": !collapsed,
|
|
48673
|
+
"aria-label": t(collapsed ? "awb.notifications.expand" : "awb.notifications.collapse"),
|
|
48674
|
+
title: t(collapsed ? "awb.notifications.expand" : "awb.notifications.collapse"),
|
|
48053
48675
|
onClick: () => {
|
|
48054
|
-
|
|
48055
|
-
|
|
48056
|
-
|
|
48057
|
-
|
|
48058
|
-
}
|
|
48676
|
+
const nextCollapsed = !collapsed;
|
|
48677
|
+
setCollapsed(nextCollapsed);
|
|
48678
|
+
setExpanded(!nextCollapsed);
|
|
48679
|
+
onCollapsedChange?.(nextCollapsed);
|
|
48059
48680
|
}
|
|
48060
|
-
},
|
|
48681
|
+
}, notificationToolbarIcon(collapsed ? "expand" : "collapse")) : null, !collapsed && showClearAll ? (0, react.createElement)("button", {
|
|
48682
|
+
type: "button",
|
|
48683
|
+
style: processing ? clearAllButtonBusy : clearAllButton,
|
|
48684
|
+
disabled: processing,
|
|
48685
|
+
"aria-label": t("awb.notifications.clearAllLabel"),
|
|
48686
|
+
title: t("awb.notifications.clearAllLabel"),
|
|
48687
|
+
onClick: () => {
|
|
48688
|
+
if (processing || snapshot === void 0 || onClearAll === void 0) return;
|
|
48689
|
+
setProcessing(true);
|
|
48690
|
+
Promise.resolve(onClearAll(snapshot.generation)).catch(() => void 0).finally(() => setProcessing(false));
|
|
48691
|
+
}
|
|
48692
|
+
}, notificationToolbarIcon("clear")) : null, showFilterTags ? [snapshot.unreadCount > 0 ? (0, react.createElement)("button", {
|
|
48693
|
+
key: "unread-filter",
|
|
48694
|
+
type: "button",
|
|
48695
|
+
style: listFilter === "unread" ? filterButtonActive : filterButton,
|
|
48696
|
+
"data-codingns-notification-filter": true,
|
|
48697
|
+
"aria-expanded": expanded,
|
|
48698
|
+
"aria-pressed": listFilter === "unread",
|
|
48699
|
+
"aria-label": t("awb.notifications.unreadFilterLabel", { count: snapshot.unreadCount }),
|
|
48700
|
+
title: t("awb.notifications.unreadFilterLabel", { count: snapshot.unreadCount }),
|
|
48701
|
+
onClick: () => toggleFilter("unread")
|
|
48702
|
+
}, notificationToolbarIcon("unread"), (0, react.createElement)("span", { style: notificationCountBadge }, formatNotificationCount(snapshot.unreadCount))) : null, snapshot.pendingCount > 0 ? (0, react.createElement)("button", {
|
|
48703
|
+
key: "pending-filter",
|
|
48704
|
+
type: "button",
|
|
48705
|
+
style: listFilter === "pending" ? filterButtonActive : filterButton,
|
|
48706
|
+
"data-codingns-notification-filter": true,
|
|
48707
|
+
"aria-expanded": expanded,
|
|
48708
|
+
"aria-pressed": listFilter === "pending",
|
|
48709
|
+
"aria-label": t("awb.notifications.pendingFilterLabel", { count: snapshot.pendingCount }),
|
|
48710
|
+
title: t("awb.notifications.pendingFilterLabel", { count: snapshot.pendingCount }),
|
|
48711
|
+
onClick: () => toggleFilter("pending")
|
|
48712
|
+
}, notificationToolbarIcon("pending"), (0, react.createElement)("span", { style: notificationPendingBadge }, formatNotificationCount(snapshot.pendingCount))) : null] : null) : null, showBubble ? (0, react.createElement)("div", {
|
|
48061
48713
|
ref: bubble,
|
|
48062
48714
|
role: "status",
|
|
48063
48715
|
"aria-live": "polite",
|
|
48064
48716
|
style: bubblePanel
|
|
48065
|
-
}, (0, react.createElement)("
|
|
48066
|
-
"
|
|
48067
|
-
style:
|
|
48068
|
-
}, (0, react.createElement)("
|
|
48069
|
-
|
|
48070
|
-
height: 22,
|
|
48071
|
-
viewBox: "0 0 36 22",
|
|
48072
|
-
fill: require_theme.dshThemeColor.menuBackground,
|
|
48073
|
-
stroke: require_theme.dshThemeColor.accent,
|
|
48074
|
-
strokeWidth: 1.5,
|
|
48075
|
-
strokeLinecap: "round",
|
|
48076
|
-
strokeLinejoin: "round",
|
|
48077
|
-
style: { display: "block" }
|
|
48078
|
-
}, (0, react.createElement)("path", { d: "M2 1 C7 2 12 8 18 19 C19 21 21 21 22 19 C27 9 31 3 34 1" }))), (0, react.createElement)("div", { style: bubbleContent }, multiple ? attentionItems.map((notice) => row(notice, "compact")) : row(mainNotice, "primary"))) : null, expanded && snapshot ? (0, react.createElement)("div", {
|
|
48717
|
+
}, (0, react.createElement)("div", {
|
|
48718
|
+
"data-codingns-notification-scroll": true,
|
|
48719
|
+
style: bubbleContent
|
|
48720
|
+
}, multiple ? attentionItems.map((notice) => row(notice, "compact")) : row(mainNotice, "primary"))) : null, !collapsed && expanded && snapshot ? (0, react.createElement)("div", {
|
|
48721
|
+
ref: bubble,
|
|
48079
48722
|
role: "region",
|
|
48080
48723
|
"aria-label": t("awb.notifications.list"),
|
|
48081
|
-
|
|
48082
|
-
|
|
48083
|
-
|
|
48084
|
-
|
|
48085
|
-
|
|
48086
|
-
|
|
48087
|
-
|
|
48088
|
-
|
|
48089
|
-
|
|
48090
|
-
} }, ...items.map((notice) => row(notice, "list"))), items.length === 0 ? (0, react.createElement)("p", null, t("awb.notifications.empty")) : null, onPage ? (0, react.createElement)("div", { style: {
|
|
48091
|
-
display: "flex",
|
|
48092
|
-
gap: 6
|
|
48093
|
-
} }, (0, react.createElement)("button", {
|
|
48094
|
-
type: "button",
|
|
48095
|
-
style: button,
|
|
48096
|
-
disabled: cursors.length <= 1,
|
|
48097
|
-
onClick: () => page(false)
|
|
48098
|
-
}, t("awb.notifications.previous")), (0, react.createElement)("button", {
|
|
48099
|
-
type: "button",
|
|
48100
|
-
style: button,
|
|
48101
|
-
disabled: !snapshot.cursor,
|
|
48102
|
-
onClick: () => page(true)
|
|
48103
|
-
}, t("awb.notifications.next"))) : null) : null, error ? (0, react.createElement)("div", {
|
|
48724
|
+
"data-codingns-notification-scroll": true,
|
|
48725
|
+
style: bubblePanel
|
|
48726
|
+
}, (0, react.createElement)("div", {
|
|
48727
|
+
"data-codingns-notification-scroll": true,
|
|
48728
|
+
style: {
|
|
48729
|
+
...bubbleContent,
|
|
48730
|
+
maxHeight: 180
|
|
48731
|
+
}
|
|
48732
|
+
}, ...listItems.map((notice) => row(notice, "compact"))), listItems.length === 0 ? (0, react.createElement)("p", null, t("awb.notifications.empty")) : null) : null, !collapsed && error ? (0, react.createElement)("div", {
|
|
48104
48733
|
role: "alert",
|
|
48105
48734
|
style: panel
|
|
48106
|
-
}, error) : null, ...
|
|
48107
|
-
key: capability.hostId,
|
|
48108
|
-
role: "status",
|
|
48109
|
-
style: panel
|
|
48110
|
-
}, capability.reason)) ?? []);
|
|
48735
|
+
}, error) : null, ...capabilityNotices);
|
|
48111
48736
|
}
|
|
48112
48737
|
/** 可见 DOM 与视口相交后才确认首展;后台挂载和零面积节点不消耗提醒时长。 */
|
|
48113
48738
|
function assistantNotificationIsVisible(node) {
|
|
@@ -48142,140 +48767,242 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
48142
48767
|
/** 网页气泡作为形象的兄弟区域定位;字幕优先保留原侧,通知避让到另一侧或形象旁。 */
|
|
48143
48768
|
function floatingAssistantNotificationLayout(x, y, width, height, viewportWidth, viewportHeight, captionAbove) {
|
|
48144
48769
|
const bubbleWidth = Math.max(0, Math.min(320, viewportWidth - 24));
|
|
48145
|
-
const
|
|
48770
|
+
const clearance = 30;
|
|
48771
|
+
const aboveSpace = Math.max(0, y - 22 - clearance), belowSpace = Math.max(0, viewportHeight - y - height - 22 - clearance);
|
|
48146
48772
|
const above = captionAbove === void 0 ? aboveSpace >= belowSpace : !captionAbove;
|
|
48147
48773
|
const space = above ? aboveSpace : belowSpace;
|
|
48148
48774
|
const left = Math.max(12 - x, Math.min((width - bubbleWidth) / 2, viewportWidth - x - bubbleWidth - 12));
|
|
48149
48775
|
if (captionAbove !== void 0 && space < 72) {
|
|
48150
48776
|
const leftSpace = Math.max(0, x - 22), rightSpace = Math.max(0, viewportWidth - x - width - 22);
|
|
48151
48777
|
const sideWidth = Math.min(320, Math.max(leftSpace, rightSpace));
|
|
48152
|
-
if (sideWidth >= 150)
|
|
48153
|
-
|
|
48154
|
-
|
|
48155
|
-
|
|
48156
|
-
|
|
48157
|
-
|
|
48778
|
+
if (sideWidth >= 150) {
|
|
48779
|
+
const onLeft = leftSpace >= rightSpace;
|
|
48780
|
+
return {
|
|
48781
|
+
style: {
|
|
48782
|
+
left: onLeft ? -sideWidth - 10 : width + 10,
|
|
48783
|
+
top: 0,
|
|
48784
|
+
width: sideWidth,
|
|
48785
|
+
maxHeight: Math.min(276, height, Math.max(0, viewportHeight - y - 12))
|
|
48786
|
+
},
|
|
48787
|
+
tail: onLeft ? "right" : "left"
|
|
48788
|
+
};
|
|
48789
|
+
}
|
|
48158
48790
|
const stackedAbove = captionAbove;
|
|
48159
48791
|
const stackedSpace = (stackedAbove ? aboveSpace : belowSpace) - 190;
|
|
48160
48792
|
if (stackedSpace >= 36) return {
|
|
48161
|
-
|
|
48162
|
-
|
|
48163
|
-
|
|
48164
|
-
|
|
48793
|
+
style: {
|
|
48794
|
+
left,
|
|
48795
|
+
width: bubbleWidth,
|
|
48796
|
+
maxHeight: Math.min(276, stackedSpace),
|
|
48797
|
+
...stackedAbove ? { bottom: height + 200 } : { top: height + 200 }
|
|
48798
|
+
},
|
|
48799
|
+
tail: stackedAbove ? "bottom" : "top"
|
|
48165
48800
|
};
|
|
48166
48801
|
}
|
|
48167
48802
|
return {
|
|
48168
|
-
|
|
48169
|
-
|
|
48170
|
-
|
|
48171
|
-
|
|
48803
|
+
style: {
|
|
48804
|
+
left,
|
|
48805
|
+
width: bubbleWidth,
|
|
48806
|
+
maxHeight: Math.min(276, space),
|
|
48807
|
+
...above ? { bottom: height + clearance } : { top: height + clearance }
|
|
48808
|
+
},
|
|
48809
|
+
tail: above ? "bottom" : "top"
|
|
48172
48810
|
};
|
|
48173
48811
|
}
|
|
48174
|
-
/** 将气泡尾巴指向头像中心;侧置气泡也不能固定在自己的左边角。 */
|
|
48175
|
-
function assistantNotificationTailStyle(avatarCenter, regionLeft, regionWidth) {
|
|
48176
|
-
const min = 20, max = Math.max(min, regionWidth - 20);
|
|
48177
|
-
const center = Math.max(min, Math.min(max, avatarCenter - regionLeft));
|
|
48178
|
-
return { "--codingns-assistant-tail-left": `${Math.round(center)}px` };
|
|
48179
|
-
}
|
|
48180
48812
|
const icons = {
|
|
48181
48813
|
completed: "✓",
|
|
48182
48814
|
error: "!",
|
|
48183
48815
|
question: "?",
|
|
48184
|
-
approval: "
|
|
48816
|
+
approval: "!"
|
|
48185
48817
|
};
|
|
48186
48818
|
const noticeKindColor = {
|
|
48187
48819
|
completed: require_theme.dshThemeColor.success,
|
|
48188
48820
|
error: require_theme.dshThemeColor.error,
|
|
48189
48821
|
question: require_theme.dshThemeColor.accent,
|
|
48190
|
-
approval: require_theme.dshThemeColor.
|
|
48822
|
+
approval: require_theme.dshThemeColor.warning
|
|
48191
48823
|
};
|
|
48824
|
+
/** 黄色填充上的图标与标签改用深色前景,避免白字对比度不足。 */
|
|
48825
|
+
const noticeKindForeground = { approval: require_theme.dshThemeColor.warningForeground };
|
|
48192
48826
|
function notificationStatus(notice, t) {
|
|
48193
48827
|
if (notice.kind === "completed") return t("awb.notifications.completed");
|
|
48194
48828
|
if (notice.kind === "error") return t("awb.notifications.error");
|
|
48195
48829
|
if (notice.kind === "question") return t("awb.notifications.question");
|
|
48196
48830
|
return t("awb.notifications.approval");
|
|
48197
48831
|
}
|
|
48832
|
+
/** 独立伴随页没有 DSH 主题变量,回退色固定为夜间灰;宿主页面仍可通过变量覆盖。 */
|
|
48833
|
+
const notificationTheme = {
|
|
48834
|
+
labelPrimary: "var(--dsw-alias-label-primary, #f1f2f4)",
|
|
48835
|
+
labelSecondary: "var(--dsw-alias-label-secondary, #b7bac1)",
|
|
48836
|
+
border: "var(--dsw-alias-border-l2, #5b5e66)",
|
|
48837
|
+
surface: "var(--dsw-alias-bg-layer-3, #303237)",
|
|
48838
|
+
card: "var(--dsw-alias-bg-layer-1, #3b3d43)",
|
|
48839
|
+
button: "var(--dsw-alias-button-elevated-fill, #44474e)",
|
|
48840
|
+
shadow: "var(--dsw-elevation-prominent, 0 12px 36px rgba(0, 0, 0, 0.42))"
|
|
48841
|
+
};
|
|
48198
48842
|
const button = {
|
|
48199
48843
|
...require_theme.dshSettingsButtonStyle,
|
|
48200
48844
|
minHeight: 36,
|
|
48201
48845
|
touchAction: "manipulation",
|
|
48202
48846
|
whiteSpace: "normal",
|
|
48203
48847
|
borderRadius: 999,
|
|
48204
|
-
fontWeight: 650
|
|
48848
|
+
fontWeight: 650,
|
|
48849
|
+
color: notificationTheme.labelPrimary,
|
|
48850
|
+
background: notificationTheme.button,
|
|
48851
|
+
borderColor: notificationTheme.border
|
|
48205
48852
|
};
|
|
48853
|
+
/** 外壳按实际内容收缩,避免原生为形象预留的高度变成大片不透明背景。 */
|
|
48206
48854
|
const shell = {
|
|
48207
|
-
|
|
48208
|
-
|
|
48855
|
+
position: "relative",
|
|
48856
|
+
isolation: "isolate",
|
|
48857
|
+
width: "100%",
|
|
48858
|
+
maxWidth: 320,
|
|
48859
|
+
height: "auto",
|
|
48860
|
+
maxHeight: "var(--codingns-notification-max-height, min(276px, calc(100vh - 24px)))",
|
|
48861
|
+
minHeight: 0,
|
|
48209
48862
|
display: "flex",
|
|
48210
48863
|
flexDirection: "column",
|
|
48211
48864
|
gap: 6,
|
|
48865
|
+
padding: 10,
|
|
48866
|
+
boxSizing: "border-box",
|
|
48212
48867
|
pointerEvents: "auto",
|
|
48213
|
-
color:
|
|
48214
|
-
fontSize: require_theme.uiFontSize(13)
|
|
48868
|
+
color: notificationTheme.labelPrimary,
|
|
48869
|
+
fontSize: require_theme.uiFontSize(13),
|
|
48870
|
+
background: notificationTheme.surface,
|
|
48871
|
+
border: `1px solid ${notificationTheme.border}`,
|
|
48872
|
+
borderRadius: "24px 24px 24px 8px",
|
|
48873
|
+
boxShadow: notificationTheme.shadow
|
|
48215
48874
|
};
|
|
48216
48875
|
const panel = {
|
|
48217
|
-
|
|
48218
|
-
|
|
48219
|
-
|
|
48876
|
+
position: "relative",
|
|
48877
|
+
zIndex: 1,
|
|
48878
|
+
padding: 10,
|
|
48879
|
+
background: notificationTheme.surface,
|
|
48880
|
+
border: `1px solid ${notificationTheme.border}`,
|
|
48220
48881
|
borderRadius: 18,
|
|
48221
|
-
boxShadow:
|
|
48882
|
+
boxShadow: notificationTheme.shadow,
|
|
48222
48883
|
minWidth: 0,
|
|
48223
48884
|
boxSizing: "border-box",
|
|
48224
|
-
maxHeight: "min(276px, calc(100vh - 24px))",
|
|
48885
|
+
maxHeight: "var(--codingns-notification-max-height, min(276px, calc(100vh - 24px)))",
|
|
48225
48886
|
overflowY: "auto"
|
|
48226
48887
|
};
|
|
48227
48888
|
const bubblePanel = {
|
|
48228
|
-
...panel,
|
|
48229
48889
|
position: "relative",
|
|
48230
|
-
|
|
48890
|
+
display: "flex",
|
|
48891
|
+
flexDirection: "column",
|
|
48892
|
+
flex: "0 1 auto",
|
|
48893
|
+
minWidth: 0,
|
|
48894
|
+
minHeight: 0,
|
|
48895
|
+
padding: 0,
|
|
48231
48896
|
overflow: "visible",
|
|
48232
|
-
|
|
48233
|
-
|
|
48234
|
-
|
|
48235
|
-
|
|
48897
|
+
border: "none",
|
|
48898
|
+
borderRadius: 0,
|
|
48899
|
+
boxShadow: "none",
|
|
48900
|
+
maxHeight: "var(--codingns-notification-max-height, min(276px, calc(100vh - 24px)))",
|
|
48901
|
+
background: "transparent",
|
|
48902
|
+
outline: "none"
|
|
48236
48903
|
};
|
|
48237
48904
|
const bubbleContent = {
|
|
48238
48905
|
position: "relative",
|
|
48239
48906
|
zIndex: 1,
|
|
48240
48907
|
display: "grid",
|
|
48908
|
+
gridAutoRows: "max-content",
|
|
48909
|
+
alignContent: "start",
|
|
48241
48910
|
gap: 8,
|
|
48242
|
-
|
|
48911
|
+
minHeight: 0,
|
|
48912
|
+
flex: "0 1 auto",
|
|
48913
|
+
maxHeight: "var(--codingns-notification-max-height, min(276px, calc(100vh - 24px)))",
|
|
48243
48914
|
overflowY: "auto",
|
|
48244
48915
|
overscrollBehavior: "contain",
|
|
48245
|
-
|
|
48246
|
-
|
|
48247
|
-
const bubbleTail = {
|
|
48248
|
-
position: "absolute",
|
|
48249
|
-
left: "var(--codingns-assistant-tail-left, 50%)",
|
|
48250
|
-
bottom: -21,
|
|
48251
|
-
width: 36,
|
|
48252
|
-
height: 22,
|
|
48253
|
-
marginLeft: -18,
|
|
48254
|
-
zIndex: 0,
|
|
48255
|
-
pointerEvents: "none"
|
|
48916
|
+
boxSizing: "border-box",
|
|
48917
|
+
padding: 0
|
|
48256
48918
|
};
|
|
48919
|
+
const notificationTailCurve = "M1 0 C12 0 20 8 23 18 C24 24 25 30 28 36 C31 30 32 24 33 18 C36 8 44 0 55 0";
|
|
48920
|
+
function tailBox(side) {
|
|
48921
|
+
const base = {
|
|
48922
|
+
position: "absolute",
|
|
48923
|
+
zIndex: 0,
|
|
48924
|
+
pointerEvents: "none"
|
|
48925
|
+
};
|
|
48926
|
+
const renderHeight = 36;
|
|
48927
|
+
if (side === "top") return {
|
|
48928
|
+
...base,
|
|
48929
|
+
top: -24,
|
|
48930
|
+
left: "var(--codingns-assistant-tail-offset, 50%)",
|
|
48931
|
+
width: 56,
|
|
48932
|
+
height: renderHeight,
|
|
48933
|
+
marginLeft: -28
|
|
48934
|
+
};
|
|
48935
|
+
if (side === "left") return {
|
|
48936
|
+
...base,
|
|
48937
|
+
left: -24,
|
|
48938
|
+
top: "var(--codingns-assistant-tail-offset, 50%)",
|
|
48939
|
+
width: renderHeight,
|
|
48940
|
+
height: 56,
|
|
48941
|
+
marginTop: -28
|
|
48942
|
+
};
|
|
48943
|
+
if (side === "right") return {
|
|
48944
|
+
...base,
|
|
48945
|
+
right: -24,
|
|
48946
|
+
top: "var(--codingns-assistant-tail-offset, 50%)",
|
|
48947
|
+
width: renderHeight,
|
|
48948
|
+
height: 56,
|
|
48949
|
+
marginTop: -28
|
|
48950
|
+
};
|
|
48951
|
+
return {
|
|
48952
|
+
...base,
|
|
48953
|
+
bottom: -24,
|
|
48954
|
+
left: "var(--codingns-assistant-tail-offset, 50%)",
|
|
48955
|
+
width: 56,
|
|
48956
|
+
height: renderHeight,
|
|
48957
|
+
marginLeft: -28
|
|
48958
|
+
};
|
|
48959
|
+
}
|
|
48960
|
+
function tailSvg(side) {
|
|
48961
|
+
const angle = "var(--codingns-assistant-tail-angle, 0deg)";
|
|
48962
|
+
if (side === "bottom") return {
|
|
48963
|
+
display: "block",
|
|
48964
|
+
transformOrigin: "50% 0%",
|
|
48965
|
+
transform: `rotate(${angle})`
|
|
48966
|
+
};
|
|
48967
|
+
if (side === "top") return {
|
|
48968
|
+
display: "block",
|
|
48969
|
+
transformOrigin: "50% 50%",
|
|
48970
|
+
transform: `rotate(180deg) rotate(${angle})`
|
|
48971
|
+
};
|
|
48972
|
+
return {
|
|
48973
|
+
display: "block",
|
|
48974
|
+
position: "absolute",
|
|
48975
|
+
left: "50%",
|
|
48976
|
+
top: "50%",
|
|
48977
|
+
transform: `translate(-50%, -50%) rotate(${side === "left" ? 90 : -90}deg)`
|
|
48978
|
+
};
|
|
48979
|
+
}
|
|
48980
|
+
const notificationBubbleCss = "[data-codingns-notification-scroll]{scrollbar-width:none;-ms-overflow-style:none}[data-codingns-notification-scroll]::-webkit-scrollbar{display:none;width:0;height:0}[data-codingns-notification-filter], [data-codingns-notification-filter]:focus, [data-codingns-notification-filter]:focus-visible{border:1px solid var(--dsw-alias-border-l2,#5b5e66)!important;outline:none!important;box-shadow:none!important}";
|
|
48257
48981
|
const primaryCard = {
|
|
48258
48982
|
display: "grid",
|
|
48983
|
+
gridTemplateColumns: "minmax(0, 1fr) auto",
|
|
48984
|
+
alignItems: "center",
|
|
48259
48985
|
gap: 9,
|
|
48260
48986
|
padding: 5,
|
|
48261
48987
|
minWidth: 0
|
|
48262
48988
|
};
|
|
48263
48989
|
const compactCard = {
|
|
48264
48990
|
display: "grid",
|
|
48991
|
+
gridTemplateColumns: "minmax(0, 1fr) auto",
|
|
48992
|
+
alignItems: "center",
|
|
48265
48993
|
gap: 7,
|
|
48266
48994
|
padding: "10px 11px",
|
|
48267
48995
|
minWidth: 0,
|
|
48268
|
-
background:
|
|
48269
|
-
border: `1px solid ${
|
|
48996
|
+
background: notificationTheme.card,
|
|
48997
|
+
border: `1px solid ${notificationTheme.border}`,
|
|
48270
48998
|
borderRadius: 15,
|
|
48271
|
-
boxShadow:
|
|
48999
|
+
boxShadow: "0 1px 2px rgba(0, 0, 0, 0.24)"
|
|
48272
49000
|
};
|
|
48273
|
-
const
|
|
49001
|
+
const cardBody = {
|
|
48274
49002
|
display: "grid",
|
|
48275
|
-
gap:
|
|
48276
|
-
padding: "10px 0",
|
|
49003
|
+
gap: 8,
|
|
48277
49004
|
minWidth: 0,
|
|
48278
|
-
|
|
49005
|
+
minInlineSize: 0
|
|
48279
49006
|
};
|
|
48280
49007
|
const cardHeading = {
|
|
48281
49008
|
display: "flex",
|
|
@@ -48284,7 +49011,7 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
48284
49011
|
minWidth: 0
|
|
48285
49012
|
};
|
|
48286
49013
|
const cardMeta = {
|
|
48287
|
-
color:
|
|
49014
|
+
color: notificationTheme.labelSecondary,
|
|
48288
49015
|
fontSize: require_theme.uiFontSize(11),
|
|
48289
49016
|
lineHeight: 1.3,
|
|
48290
49017
|
overflowWrap: "anywhere"
|
|
@@ -48302,43 +49029,104 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
48302
49029
|
width: 24,
|
|
48303
49030
|
height: 24,
|
|
48304
49031
|
borderRadius: "50%",
|
|
48305
|
-
color:
|
|
49032
|
+
color: "#fff",
|
|
48306
49033
|
fontSize: require_theme.uiFontSize(13),
|
|
48307
49034
|
fontWeight: 800,
|
|
48308
|
-
boxShadow:
|
|
49035
|
+
boxShadow: "0 1px 2px rgba(0, 0, 0, 0.28)"
|
|
48309
49036
|
};
|
|
48310
49037
|
const messageText = {
|
|
48311
|
-
color:
|
|
49038
|
+
color: notificationTheme.labelPrimary,
|
|
48312
49039
|
whiteSpace: "pre-wrap",
|
|
48313
49040
|
overflowWrap: "anywhere",
|
|
48314
49041
|
lineHeight: 1.5,
|
|
48315
49042
|
maxHeight: 120,
|
|
48316
49043
|
overflowY: "auto"
|
|
48317
49044
|
};
|
|
48318
|
-
const
|
|
49045
|
+
const topRowButton = {
|
|
48319
49046
|
...button,
|
|
49047
|
+
height: 28,
|
|
49048
|
+
minHeight: 28,
|
|
49049
|
+
padding: "2px 10px",
|
|
49050
|
+
fontSize: require_theme.uiFontSize(12)
|
|
49051
|
+
};
|
|
49052
|
+
const toolbarIconButton = {
|
|
49053
|
+
...topRowButton,
|
|
49054
|
+
width: 28,
|
|
49055
|
+
minWidth: 28,
|
|
49056
|
+
padding: 4,
|
|
49057
|
+
display: "inline-grid",
|
|
49058
|
+
placeItems: "center"
|
|
49059
|
+
};
|
|
49060
|
+
const filterButton = {
|
|
49061
|
+
...topRowButton,
|
|
48320
49062
|
alignSelf: "end",
|
|
48321
|
-
|
|
48322
|
-
|
|
48323
|
-
|
|
49063
|
+
display: "inline-flex",
|
|
49064
|
+
alignItems: "center",
|
|
49065
|
+
justifyContent: "center",
|
|
49066
|
+
gap: 4,
|
|
49067
|
+
minWidth: 46,
|
|
49068
|
+
padding: "2px 7px",
|
|
49069
|
+
background: notificationTheme.button,
|
|
49070
|
+
boxShadow: "0 1px 2px rgba(0, 0, 0, 0.24)"
|
|
48324
49071
|
};
|
|
48325
|
-
const
|
|
48326
|
-
|
|
48327
|
-
padding: "4px 9px",
|
|
48328
|
-
borderRadius: 999,
|
|
48329
|
-
color: require_theme.dshThemeColor.primaryForeground,
|
|
49072
|
+
const filterButtonActive = {
|
|
49073
|
+
...filterButton,
|
|
48330
49074
|
background: require_theme.dshThemeColor.accent,
|
|
48331
|
-
|
|
48332
|
-
|
|
48333
|
-
|
|
48334
|
-
|
|
48335
|
-
|
|
49075
|
+
borderColor: require_theme.dshThemeColor.accent,
|
|
49076
|
+
color: require_theme.dshThemeColor.primaryForeground
|
|
49077
|
+
};
|
|
49078
|
+
const notificationCountBadge = {
|
|
49079
|
+
display: "inline-grid",
|
|
49080
|
+
placeItems: "center",
|
|
49081
|
+
minWidth: 16,
|
|
49082
|
+
height: 16,
|
|
49083
|
+
padding: "0 4px",
|
|
49084
|
+
boxSizing: "border-box",
|
|
49085
|
+
borderRadius: 8,
|
|
49086
|
+
color: notificationTheme.labelPrimary,
|
|
49087
|
+
background: notificationTheme.card,
|
|
49088
|
+
fontSize: require_theme.uiFontSize(10),
|
|
49089
|
+
lineHeight: 1,
|
|
49090
|
+
fontWeight: 750
|
|
49091
|
+
};
|
|
49092
|
+
const notificationPendingBadge = {
|
|
49093
|
+
...notificationCountBadge,
|
|
49094
|
+
color: require_theme.dshThemeColor.warningForeground,
|
|
49095
|
+
background: require_theme.dshThemeColor.warning
|
|
49096
|
+
};
|
|
49097
|
+
const topRow = {
|
|
49098
|
+
display: "flex",
|
|
49099
|
+
width: "100%",
|
|
49100
|
+
flexShrink: 0,
|
|
49101
|
+
alignItems: "center",
|
|
49102
|
+
justifyContent: "center",
|
|
49103
|
+
flexWrap: "nowrap",
|
|
49104
|
+
gap: 6
|
|
49105
|
+
};
|
|
49106
|
+
const clearAllButton = {
|
|
49107
|
+
...toolbarIconButton,
|
|
49108
|
+
alignSelf: "end",
|
|
49109
|
+
background: notificationTheme.button,
|
|
49110
|
+
borderColor: notificationTheme.border,
|
|
49111
|
+
color: notificationTheme.labelPrimary,
|
|
49112
|
+
borderRadius: 10,
|
|
49113
|
+
boxShadow: "none"
|
|
49114
|
+
};
|
|
49115
|
+
const clearAllButtonBusy = {
|
|
49116
|
+
...clearAllButton,
|
|
49117
|
+
opacity: .6,
|
|
49118
|
+
cursor: "default"
|
|
49119
|
+
};
|
|
49120
|
+
const requestPrompt = {
|
|
49121
|
+
display: "inline-flex",
|
|
49122
|
+
alignItems: "center",
|
|
49123
|
+
flexWrap: "wrap",
|
|
49124
|
+
gap: 6,
|
|
49125
|
+
lineHeight: 1.5
|
|
48336
49126
|
};
|
|
48337
49127
|
const requestInlineTag = {
|
|
48338
49128
|
display: "inline-flex",
|
|
48339
49129
|
alignItems: "center",
|
|
48340
|
-
verticalAlign: "middle",
|
|
48341
|
-
margin: "0 6px 2px 2px",
|
|
48342
49130
|
padding: "3px 8px",
|
|
48343
49131
|
borderRadius: 999,
|
|
48344
49132
|
color: require_theme.dshThemeColor.primaryForeground,
|
|
@@ -48349,23 +49137,114 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
48349
49137
|
letterSpacing: "0.02em",
|
|
48350
49138
|
boxShadow: require_theme.dshThemeColor.subtleShadow
|
|
48351
49139
|
};
|
|
49140
|
+
const compactPrompt = {
|
|
49141
|
+
fontSize: require_theme.uiFontSize(12),
|
|
49142
|
+
lineHeight: 1.4,
|
|
49143
|
+
color: notificationTheme.labelPrimary
|
|
49144
|
+
};
|
|
49145
|
+
const compactRequestTag = {
|
|
49146
|
+
...requestInlineTag,
|
|
49147
|
+
padding: "2px 7px",
|
|
49148
|
+
fontSize: require_theme.uiFontSize(10)
|
|
49149
|
+
};
|
|
49150
|
+
const approvalInlineTag = {
|
|
49151
|
+
...requestInlineTag,
|
|
49152
|
+
background: require_theme.dshThemeColor.warning,
|
|
49153
|
+
color: require_theme.dshThemeColor.warningForeground
|
|
49154
|
+
};
|
|
49155
|
+
const compactApprovalTag = {
|
|
49156
|
+
...compactRequestTag,
|
|
49157
|
+
background: require_theme.dshThemeColor.warning,
|
|
49158
|
+
color: require_theme.dshThemeColor.warningForeground
|
|
49159
|
+
};
|
|
48352
49160
|
const compactStatus = {
|
|
48353
|
-
color:
|
|
49161
|
+
color: notificationTheme.labelSecondary,
|
|
48354
49162
|
fontSize: require_theme.uiFontSize(11),
|
|
48355
49163
|
lineHeight: 1.3,
|
|
48356
49164
|
paddingLeft: 32
|
|
48357
49165
|
};
|
|
48358
49166
|
const actionRow = {
|
|
48359
49167
|
display: "flex",
|
|
48360
|
-
|
|
48361
|
-
|
|
49168
|
+
flexDirection: "column",
|
|
49169
|
+
alignItems: "stretch",
|
|
49170
|
+
justifyContent: "center",
|
|
49171
|
+
gap: 6,
|
|
49172
|
+
flex: "0 0 auto"
|
|
48362
49173
|
};
|
|
48363
|
-
const
|
|
49174
|
+
const notificationActionButton = {
|
|
48364
49175
|
...button,
|
|
48365
|
-
|
|
48366
|
-
|
|
49176
|
+
width: 28,
|
|
49177
|
+
height: 28,
|
|
49178
|
+
minHeight: 28,
|
|
49179
|
+
padding: 0,
|
|
49180
|
+
display: "inline-grid",
|
|
49181
|
+
placeItems: "center",
|
|
49182
|
+
borderRadius: 10,
|
|
48367
49183
|
fontSize: require_theme.uiFontSize(12)
|
|
48368
49184
|
};
|
|
49185
|
+
/** 操作按钮只保留图标,文字语义通过 aria-label 和 title 传达,避免气泡底部堆叠长文案。 */
|
|
49186
|
+
function notificationActionIcon(action) {
|
|
49187
|
+
if (action === "dismiss") return (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.IconTrashOutlineMedium, { size: 16 });
|
|
49188
|
+
return (0, react.createElement)("svg", {
|
|
49189
|
+
width: 16,
|
|
49190
|
+
height: 16,
|
|
49191
|
+
viewBox: "0 0 24 24",
|
|
49192
|
+
fill: "none",
|
|
49193
|
+
stroke: "currentColor",
|
|
49194
|
+
strokeWidth: 2,
|
|
49195
|
+
strokeLinecap: "round",
|
|
49196
|
+
strokeLinejoin: "round",
|
|
49197
|
+
"aria-hidden": true,
|
|
49198
|
+
focusable: false
|
|
49199
|
+
}, (0, react.createElement)("path", { d: "M2.5 12s3.5-6 9.5-6 9.5 6 9.5 6-3.5 6-9.5 6-9.5-6-9.5-6Z" }), (0, react.createElement)("circle", {
|
|
49200
|
+
cx: 12,
|
|
49201
|
+
cy: 12,
|
|
49202
|
+
r: 2.5
|
|
49203
|
+
}));
|
|
49204
|
+
}
|
|
49205
|
+
function notificationToolbarIcon(icon) {
|
|
49206
|
+
if (icon === "clear") return (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.IconTrashOutlineMedium, { size: 16 });
|
|
49207
|
+
if (icon === "pending") return (0, react.createElement)("svg", {
|
|
49208
|
+
width: 16,
|
|
49209
|
+
height: 16,
|
|
49210
|
+
viewBox: "0 0 24 24",
|
|
49211
|
+
fill: "none",
|
|
49212
|
+
stroke: "currentColor",
|
|
49213
|
+
strokeWidth: 1.8,
|
|
49214
|
+
strokeLinecap: "round",
|
|
49215
|
+
strokeLinejoin: "round",
|
|
49216
|
+
"aria-hidden": true,
|
|
49217
|
+
focusable: false
|
|
49218
|
+
}, [
|
|
49219
|
+
(0, react.createElement)("path", {
|
|
49220
|
+
key: "hand",
|
|
49221
|
+
d: "M9 14V6.5a1.5 1.5 0 0 1 3 0v4a1.5 1.5 0 0 1 3 0v1a1.5 1.5 0 0 1 3 0v1a1.5 1.5 0 0 1 3 0v4c0 4-2.5 6-6.5 6h-1c-2.2 0-3.6-.8-5.1-2.3L4.2 15a1.7 1.7 0 0 1 2.4-2.4L9 15Z"
|
|
49222
|
+
}),
|
|
49223
|
+
(0, react.createElement)("path", {
|
|
49224
|
+
key: "fingers",
|
|
49225
|
+
d: "M12 10.5v3M15 11.5v3M18 12.5V15"
|
|
49226
|
+
}),
|
|
49227
|
+
(0, react.createElement)("path", {
|
|
49228
|
+
key: "tap",
|
|
49229
|
+
d: "M6.7 8.9a4.5 4.5 0 1 1 8.2-1.6"
|
|
49230
|
+
})
|
|
49231
|
+
]);
|
|
49232
|
+
return (0, react.createElement)("svg", {
|
|
49233
|
+
width: 16,
|
|
49234
|
+
height: 16,
|
|
49235
|
+
viewBox: "0 0 24 24",
|
|
49236
|
+
fill: "none",
|
|
49237
|
+
stroke: "currentColor",
|
|
49238
|
+
strokeWidth: 1.8,
|
|
49239
|
+
strokeLinecap: "round",
|
|
49240
|
+
strokeLinejoin: "round",
|
|
49241
|
+
"aria-hidden": true,
|
|
49242
|
+
focusable: false
|
|
49243
|
+
}, (0, react.createElement)("path", { d: icon === "collapse" ? "M6 9l6 6 6-6" : icon === "expand" ? "M6 15l6-6 6 6" : icon === "unread" ? "M6 10a6 6 0 0 1 12 0c0 5 2 5 2 7H4c0-2 2-2 2-7Zm3 10h6" : "" }));
|
|
49244
|
+
}
|
|
49245
|
+
function formatNotificationCount(count) {
|
|
49246
|
+
return count > 99 ? "99+" : String(count);
|
|
49247
|
+
}
|
|
48369
49248
|
//#endregion
|
|
48370
49249
|
//#region src/client/avatar/floating.ts
|
|
48371
49250
|
const POSITION_KEY = "codingns-assistant-avatar-position";
|
|
@@ -48482,11 +49361,15 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
48482
49361
|
};
|
|
48483
49362
|
const captionLayout = floatingCallCaptionLayout(position.x, position.y, size, height, viewport.width, viewport.height);
|
|
48484
49363
|
const notificationLayout = notification === void 0 ? void 0 : floatingAssistantNotificationLayout(position.x, position.y, size, height, viewport.width, viewport.height, call ? captionLayout.above : void 0);
|
|
49364
|
+
const notificationTailStyle = notificationLayout === void 0 ? {} : assistantNotificationTailStyle(size / 2, Number(notificationLayout.style.left ?? 0), Number(notificationLayout.style.width ?? size), notificationLayout.tail);
|
|
48485
49365
|
const notificationStyle = notificationLayout === void 0 ? void 0 : {
|
|
48486
49366
|
position: "absolute",
|
|
48487
|
-
...notificationLayout,
|
|
48488
|
-
|
|
49367
|
+
...notificationLayout.style,
|
|
49368
|
+
maxHeight: void 0,
|
|
49369
|
+
"--codingns-notification-max-height": `${Number(notificationLayout.style.maxHeight ?? 276)}px`,
|
|
49370
|
+
...notificationTailStyle
|
|
48489
49371
|
};
|
|
49372
|
+
const notificationNode = typeof notification === "function" ? notification(notificationLayout?.tail ?? "bottom", notificationLayout === void 0 ? void 0 : notificationLayout.tail === "left" || notificationLayout.tail === "right" ? assistantNotificationTailTarget(height / 2, Number(notificationLayout.style.top ?? 0)) : assistantNotificationTailTarget(size / 2, Number(notificationLayout.style.left ?? 0)), notificationTailStyle) : notification;
|
|
48490
49373
|
return (0, react.createElement)("div", {
|
|
48491
49374
|
...kind === "avatar" ? { "data-codingns-floating-avatar": true } : { "data-codingns-floating-call": true },
|
|
48492
49375
|
style: {
|
|
@@ -48544,7 +49427,7 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
48544
49427
|
t,
|
|
48545
49428
|
...captionLayout,
|
|
48546
49429
|
onOpen
|
|
48547
|
-
}) : null,
|
|
49430
|
+
}) : null, notificationNode && notificationStyle ? (0, react.createElement)("div", {
|
|
48548
49431
|
"data-codingns-floating-notification-region": true,
|
|
48549
49432
|
style: {
|
|
48550
49433
|
...notificationStyle,
|
|
@@ -48554,7 +49437,7 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
48554
49437
|
touchAction: "pan-y",
|
|
48555
49438
|
userSelect: "text"
|
|
48556
49439
|
}
|
|
48557
|
-
},
|
|
49440
|
+
}, notificationNode) : null);
|
|
48558
49441
|
}
|
|
48559
49442
|
function readPosition(width, height, positionKey) {
|
|
48560
49443
|
if (typeof window === "undefined") return {
|
|
@@ -48687,6 +49570,10 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
48687
49570
|
...record.unchanged === void 0 ? {} : { unchanged: record.unchanged }
|
|
48688
49571
|
};
|
|
48689
49572
|
}
|
|
49573
|
+
/** 空快照只代表通知中心已经返回结果,不应被当成需要挂载气泡的通知。 */
|
|
49574
|
+
function assistantNotificationSnapshotHasNotifications(snapshot) {
|
|
49575
|
+
return snapshot.primary !== null || snapshot.unreadCount > 0 || snapshot.pendingCount > 0 || snapshot.capabilities.some((entry) => Boolean(entry.reason) && (!entry.completed || !entry.error || !entry.requests || !entry.resolve || !entry.navigation));
|
|
49576
|
+
}
|
|
48690
49577
|
//#endregion
|
|
48691
49578
|
//#region src/client/avatar/desktop-bridge.ts
|
|
48692
49579
|
/** 普通浏览器即使连接到 Desktop 的 Host,也只能使用页面内形象。 */
|
|
@@ -48757,7 +49644,7 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
48757
49644
|
for (const event of status.noticeEvents) {
|
|
48758
49645
|
if (disposed) return;
|
|
48759
49646
|
if (event.ownerId !== ownerId || event.generation !== status.generation || !Number.isSafeInteger(event.sequence) || event.sequence <= (noticeAck?.sequence ?? 0) || typeof event.noticeId !== "string" || !Number.isSafeInteger(event.noticeGeneration)) continue;
|
|
48760
|
-
const handler = event.type === "notice-presented" ? hooks.onNoticePresented : event.type === "notice-action" && (event.action === "open" || event.action === "dismiss") ? hooks.onNoticeAction : void 0;
|
|
49647
|
+
const handler = event.type === "notice-presented" ? hooks.onNoticePresented : event.type === "notice-action" && (event.action === "open" || event.action === "collapse" || event.action === "dismiss" || event.action === "dismiss-all") ? hooks.onNoticeAction : void 0;
|
|
48761
49648
|
if (!handler) break;
|
|
48762
49649
|
try {
|
|
48763
49650
|
await handler(event);
|
|
@@ -48911,6 +49798,8 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
48911
49798
|
presented = /* @__PURE__ */ new Set();
|
|
48912
49799
|
opens = /* @__PURE__ */ new Map();
|
|
48913
49800
|
knownNotices = /* @__PURE__ */ new Map();
|
|
49801
|
+
/** 最近一次前台选择;串行队列执行前再次校验,避免旧选择晚到时误读新会话。 */
|
|
49802
|
+
sessionSelectionKey;
|
|
48914
49803
|
constructor(rpc, navigate, intervalMs = 750, now = Date.now) {
|
|
48915
49804
|
this.rpc = rpc;
|
|
48916
49805
|
this.navigate = navigate;
|
|
@@ -48944,6 +49833,7 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
48944
49833
|
this.presented.clear();
|
|
48945
49834
|
this.opens.clear();
|
|
48946
49835
|
this.knownNotices.clear();
|
|
49836
|
+
this.sessionSelectionKey = void 0;
|
|
48947
49837
|
this.publish({ loading: enabled });
|
|
48948
49838
|
if (enabled) {
|
|
48949
49839
|
if (typeof this.rpc.open === "function") {
|
|
@@ -49104,6 +49994,52 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
49104
49994
|
});
|
|
49105
49995
|
await this.refresh(true);
|
|
49106
49996
|
}
|
|
49997
|
+
/** 一键清理只清空当前代次的气泡展示;DSH 侧未读、待处理与请求身份都由 Host 原样保留。 */
|
|
49998
|
+
async clearAll(generation) {
|
|
49999
|
+
const epoch = this.epoch;
|
|
50000
|
+
this.requireFrame(generation);
|
|
50001
|
+
await this.enqueue(async (signal) => {
|
|
50002
|
+
await this.call("clear-all", { generation }, signal);
|
|
50003
|
+
this.assertCurrent(epoch, signal);
|
|
50004
|
+
}, epoch).catch((error) => {
|
|
50005
|
+
if (epoch === this.epoch && this.enabled && !this.disposed) this.publish({
|
|
50006
|
+
...this.snapshot,
|
|
50007
|
+
error: message(error),
|
|
50008
|
+
errorNoticeId: void 0,
|
|
50009
|
+
errorGeneration: void 0
|
|
50010
|
+
});
|
|
50011
|
+
throw error;
|
|
50012
|
+
});
|
|
50013
|
+
await this.refresh(true);
|
|
50014
|
+
}
|
|
50015
|
+
/** 当前会话一旦被 DSH 选中即提交会话级已读;空选择只取消尚未发出的旧选择。 */
|
|
50016
|
+
markSessionRead(target) {
|
|
50017
|
+
const key = target === void 0 ? void 0 : JSON.stringify([
|
|
50018
|
+
target.hostId,
|
|
50019
|
+
target.workspaceId,
|
|
50020
|
+
target.sessionId
|
|
50021
|
+
]);
|
|
50022
|
+
this.sessionSelectionKey = key;
|
|
50023
|
+
if (target === void 0 || !this.enabled || this.disposed) return Promise.resolve();
|
|
50024
|
+
if (this.snapshot.frame === void 0) return this.refresh(true).then(() => this.sessionSelectionKey === key ? this.markSessionRead(target) : void 0);
|
|
50025
|
+
const epoch = this.epoch;
|
|
50026
|
+
return this.enqueue(async (signal) => {
|
|
50027
|
+
if (this.sessionSelectionKey !== key) return;
|
|
50028
|
+
const frame = this.snapshot.frame;
|
|
50029
|
+
if (frame === void 0) return;
|
|
50030
|
+
await this.call("read-session", {
|
|
50031
|
+
generation: frame.generation,
|
|
50032
|
+
...target
|
|
50033
|
+
}, signal);
|
|
50034
|
+
this.assertCurrent(epoch, signal);
|
|
50035
|
+
}, epoch).then(() => this.refresh(true)).catch((error) => {
|
|
50036
|
+
if (epoch === this.epoch && this.enabled && !this.disposed) this.publish({
|
|
50037
|
+
...this.snapshot,
|
|
50038
|
+
error: message(error)
|
|
50039
|
+
});
|
|
50040
|
+
throw error;
|
|
50041
|
+
});
|
|
50042
|
+
}
|
|
49107
50043
|
/** 查看由 Host 返回可信目标,公开导航成功后才标记已读。 */
|
|
49108
50044
|
open(noticeId, generation, expectedConnectionGeneration) {
|
|
49109
50045
|
try {
|
|
@@ -49169,6 +50105,7 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
49169
50105
|
this.presented.clear();
|
|
49170
50106
|
this.opens.clear();
|
|
49171
50107
|
this.knownNotices.clear();
|
|
50108
|
+
this.sessionSelectionKey = void 0;
|
|
49172
50109
|
this.listeners.clear();
|
|
49173
50110
|
this.snapshot = { loading: false };
|
|
49174
50111
|
}
|
|
@@ -49320,6 +50257,52 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
49320
50257
|
}
|
|
49321
50258
|
//#endregion
|
|
49322
50259
|
//#region src/dsh-capabilities/client/assistant-session-navigation-adapter.ts
|
|
50260
|
+
/** 读取 DSH 的唯一前台会话选择源;没有该能力的旧宿主不猜测当前会话。 */
|
|
50261
|
+
function readAssistantSessionSelectionStore(context) {
|
|
50262
|
+
try {
|
|
50263
|
+
const selection = (context?.get?.("uiWorkspace"))?.selection;
|
|
50264
|
+
if (typeof selection !== "object" || selection === null) return void 0;
|
|
50265
|
+
const store = selection;
|
|
50266
|
+
return typeof store.getSnapshot === "function" && typeof store.subscribe === "function" ? store : void 0;
|
|
50267
|
+
} catch {
|
|
50268
|
+
return;
|
|
50269
|
+
}
|
|
50270
|
+
}
|
|
50271
|
+
/** 将本地/远端虚拟选择归一化为 Host 可匹配的会话三元组。 */
|
|
50272
|
+
function normalizeAssistantSessionSelection(value, context) {
|
|
50273
|
+
const record = asRecord$1(value);
|
|
50274
|
+
if (record === void 0) return void 0;
|
|
50275
|
+
const rawSessionId = text$1(record.sessionId) ?? text$1(asRecord$1(record.subagentAddress)?.parentSessionId);
|
|
50276
|
+
const rawWorkspaceId = text$1(record.workspaceId) ?? text$1(asRecord$1(record.workspace)?.workspaceId) ?? (rawSessionId === void 0 ? void 0 : readSessionWorkspaceId(context, rawSessionId));
|
|
50277
|
+
if (rawSessionId === void 0 || rawWorkspaceId === void 0) return void 0;
|
|
50278
|
+
const session = require_primitives_adapter.parseVirtualSessionId(rawSessionId);
|
|
50279
|
+
const workspace = require_primitives_adapter.parseVirtualWorkspaceId(rawWorkspaceId);
|
|
50280
|
+
if (session !== null && workspace !== null && session.hostId !== workspace.hostId) return void 0;
|
|
50281
|
+
const hostId = session?.hostId ?? workspace?.targetHostId ?? "local";
|
|
50282
|
+
const workspaceId = workspace?.workspaceId ?? (hostId !== "local" && rawWorkspaceId.startsWith(`${hostId}:`) ? rawWorkspaceId.slice(hostId.length + 1) : rawWorkspaceId);
|
|
50283
|
+
const sessionId = session?.sessionId ?? rawSessionId;
|
|
50284
|
+
return {
|
|
50285
|
+
hostId: hostId === "local" ? "local" : hostId,
|
|
50286
|
+
workspaceId,
|
|
50287
|
+
sessionId
|
|
50288
|
+
};
|
|
50289
|
+
}
|
|
50290
|
+
/** 从原生 Workspace 列表按成员关系反查当前会话,保留远端虚拟 ID。 */
|
|
50291
|
+
function readSessionWorkspaceId(context, sessionId) {
|
|
50292
|
+
try {
|
|
50293
|
+
const snapshot = require_native_workspace_store.readNativeWorkspaceSnapshot(context);
|
|
50294
|
+
const exact = snapshot?.items.find((workspace) => workspace.sessionIds.includes(sessionId));
|
|
50295
|
+
if (exact !== void 0) return exact.workspaceId;
|
|
50296
|
+
const parsed = require_primitives_adapter.parseVirtualSessionId(sessionId);
|
|
50297
|
+
if (parsed === null) return void 0;
|
|
50298
|
+
return (snapshot?.items.find((workspace) => workspace.sessionIds.some((candidate) => {
|
|
50299
|
+
const value = require_primitives_adapter.parseVirtualSessionId(candidate);
|
|
50300
|
+
return value?.hostId === parsed.hostId && value.sessionId === parsed.sessionId;
|
|
50301
|
+
})))?.workspaceId;
|
|
50302
|
+
} catch {
|
|
50303
|
+
return;
|
|
50304
|
+
}
|
|
50305
|
+
}
|
|
49323
50306
|
/** Host 负责目标与连接代次校验,本适配器只把可信目标交给原生导航。 */
|
|
49324
50307
|
async function openAssistantNotificationSession(services, target, signal) {
|
|
49325
50308
|
signal?.throwIfAborted();
|
|
@@ -49356,6 +50339,12 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
49356
50339
|
return;
|
|
49357
50340
|
}
|
|
49358
50341
|
}
|
|
50342
|
+
function asRecord$1(value) {
|
|
50343
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
|
|
50344
|
+
}
|
|
50345
|
+
function text$1(value) {
|
|
50346
|
+
return typeof value === "string" && value.trim() !== "" ? value : void 0;
|
|
50347
|
+
}
|
|
49359
50348
|
//#endregion
|
|
49360
50349
|
//#region src/client/features/global-voice-assistant.ts
|
|
49361
50350
|
const GLOBAL_ASSISTANT_BUTTON_SIZE = 38;
|
|
@@ -49483,18 +50472,43 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
49483
50472
|
notificationsEnabled,
|
|
49484
50473
|
notificationKey
|
|
49485
50474
|
]);
|
|
50475
|
+
(0, react.useEffect)(() => {
|
|
50476
|
+
const context = services.uiContext;
|
|
50477
|
+
if (context === void 0) return void 0;
|
|
50478
|
+
const attach = (scope) => {
|
|
50479
|
+
const selection = readAssistantSessionSelectionStore(scope);
|
|
50480
|
+
if (selection === void 0) return void 0;
|
|
50481
|
+
const sync = () => {
|
|
50482
|
+
notifications.markSessionRead(normalizeAssistantSessionSelection(selection.getSnapshot(), scope)).catch(() => void 0);
|
|
50483
|
+
};
|
|
50484
|
+
sync();
|
|
50485
|
+
return selection.subscribe(sync);
|
|
50486
|
+
};
|
|
50487
|
+
if (typeof context.inject === "function") {
|
|
50488
|
+
const fiber = context.inject(["uiWorkspace"], (scope) => {
|
|
50489
|
+
const unsubscribe = attach(scope);
|
|
50490
|
+
if (unsubscribe === void 0) return;
|
|
50491
|
+
scope.effect(() => unsubscribe, "codingns4dsh: assistant notification session read");
|
|
50492
|
+
});
|
|
50493
|
+
return () => {
|
|
50494
|
+
fiber.dispose();
|
|
50495
|
+
};
|
|
50496
|
+
}
|
|
50497
|
+
return attach(context);
|
|
50498
|
+
}, [notifications, services.uiContext]);
|
|
49486
50499
|
const presentNotice = (0, react.useCallback)((noticeId, generation, kind) => {
|
|
49487
50500
|
notifications.acknowledge(noticeId, generation, "presented", kind).catch(() => void 0);
|
|
49488
50501
|
}, [notifications]);
|
|
49489
50502
|
const dismissNotice = (0, react.useCallback)((noticeId, generation, connectionGeneration) => {
|
|
49490
50503
|
notifications.acknowledge(noticeId, generation, "dismiss", void 0, connectionGeneration).catch(() => void 0);
|
|
49491
50504
|
}, [notifications]);
|
|
50505
|
+
const collapseNotice = (0, react.useCallback)((noticeId, generation, connectionGeneration) => {
|
|
50506
|
+
notifications.acknowledge(noticeId, generation, "collapse", void 0, connectionGeneration).catch(() => void 0);
|
|
50507
|
+
}, [notifications]);
|
|
49492
50508
|
const openNotice = (0, react.useCallback)((noticeId, generation, connectionGeneration) => {
|
|
49493
50509
|
notifications.open(noticeId, generation, connectionGeneration).catch(() => void 0);
|
|
49494
50510
|
}, [notifications]);
|
|
49495
|
-
const
|
|
49496
|
-
notifications.page(cursor);
|
|
49497
|
-
}, [notifications]);
|
|
50511
|
+
const clearAllNotices = (0, react.useCallback)((generation) => notifications.clearAll(generation), [notifications]);
|
|
49498
50512
|
(0, react.useEffect)(() => {
|
|
49499
50513
|
if (adapter !== void 0) {
|
|
49500
50514
|
setSnapshot({
|
|
@@ -49763,7 +50777,7 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
49763
50777
|
userText: partialText || liveUserText,
|
|
49764
50778
|
assistantText: liveAssistantText
|
|
49765
50779
|
} : void 0;
|
|
49766
|
-
const noticeFrame = notificationsEnabled ? notificationSnapshot.frame : void 0;
|
|
50780
|
+
const noticeFrame = notificationsEnabled && notificationSnapshot.frame !== void 0 && assistantNotificationSnapshotHasNotifications(notificationSnapshot.frame) ? notificationSnapshot.frame : void 0;
|
|
49767
50781
|
const reaction = assistantNotificationReaction(noticeFrame);
|
|
49768
50782
|
const desktopNotification = desktopAssistantNotification(noticeFrame, notificationSnapshot.errorNoticeId === noticeFrame?.primary?.noticeId ? notificationSnapshot.error : void 0);
|
|
49769
50783
|
const desktopNotificationSnapshot = readDesktopAssistantNotificationSnapshot(noticeFrame);
|
|
@@ -49781,7 +50795,9 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
49781
50795
|
onNoticePresented: (event) => notifications.acknowledge(event.noticeId, event.noticeGeneration, "presented", event.noticeKind, event.connectionGeneration),
|
|
49782
50796
|
onNoticeAction: async (event) => {
|
|
49783
50797
|
await notifications.refresh(true);
|
|
49784
|
-
|
|
50798
|
+
if (event.action === "dismiss-all") return notifications.clearAll(event.noticeGeneration);
|
|
50799
|
+
if (event.action === "open") return notifications.open(event.noticeId, event.noticeGeneration, event.connectionGeneration);
|
|
50800
|
+
return notifications.acknowledge(event.noticeId, event.noticeGeneration, event.action === "collapse" ? "collapse" : "dismiss", void 0, event.connectionGeneration);
|
|
49785
50801
|
}
|
|
49786
50802
|
});
|
|
49787
50803
|
const nativeFloating = floatingEnabled && desktopAvatar.native;
|
|
@@ -49793,7 +50809,7 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
49793
50809
|
borderRadius: 12,
|
|
49794
50810
|
overflowWrap: "anywhere"
|
|
49795
50811
|
}
|
|
49796
|
-
}, notificationSnapshot.error) : void 0 : (0, react.createElement)(AssistantNotificationBubble, {
|
|
50812
|
+
}, notificationSnapshot.error) : void 0 : (tail, tailTarget, tailStyle) => (0, react.createElement)(AssistantNotificationBubble, {
|
|
49797
50813
|
frame: noticeFrame,
|
|
49798
50814
|
t,
|
|
49799
50815
|
error: notificationSnapshot.error,
|
|
@@ -49801,8 +50817,12 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
49801
50817
|
autoCloseSeconds: notificationSettings.autoCloseSeconds,
|
|
49802
50818
|
onPresented: presentNotice,
|
|
49803
50819
|
onDismiss: dismissNotice,
|
|
50820
|
+
onAutoClose: collapseNotice,
|
|
49804
50821
|
onOpen: openNotice,
|
|
49805
|
-
|
|
50822
|
+
onClearAll: clearAllNotices,
|
|
50823
|
+
tailSide: tail,
|
|
50824
|
+
tailTarget,
|
|
50825
|
+
tailStyle
|
|
49806
50826
|
});
|
|
49807
50827
|
return (0, react.createElement)("div", {
|
|
49808
50828
|
"data-codingns-global-voice": "true",
|
|
@@ -50950,6 +51970,928 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
50950
51970
|
}
|
|
50951
51971
|
};
|
|
50952
51972
|
//#endregion
|
|
51973
|
+
//#region src/client/session-translation-chat.ts
|
|
51974
|
+
/**
|
|
51975
|
+
* 把翻译状态和查看原文的入口放回对应消息块,不占用 AI 回复底部的统一操作栏。
|
|
51976
|
+
*/
|
|
51977
|
+
function TranslationAction(props) {
|
|
51978
|
+
const source = props.record === void 0 ? readEventSource(props.services, props.sessionId) : void 0;
|
|
51979
|
+
const [, refresh] = (0, react.useState)(0);
|
|
51980
|
+
const [open, setOpen] = (0, react.useState)(false);
|
|
51981
|
+
const rootRef = (0, react.useRef)(null);
|
|
51982
|
+
const buttonRef = (0, react.useRef)(null);
|
|
51983
|
+
const popupRef = (0, react.useRef)(null);
|
|
51984
|
+
const [popupPosition, setPopupPosition] = (0, react.useState)(null);
|
|
51985
|
+
(0, react.useEffect)(() => {
|
|
51986
|
+
if (source === void 0) return void 0;
|
|
51987
|
+
return source.subscribe(() => refresh((value) => value + 1));
|
|
51988
|
+
}, [source]);
|
|
51989
|
+
useDismissOnOutsidePointer(rootRef, open, () => setOpen(false), { portal: popupRef });
|
|
51990
|
+
(0, react.useLayoutEffect)(() => {
|
|
51991
|
+
if (!open || typeof window === "undefined") {
|
|
51992
|
+
setPopupPosition(null);
|
|
51993
|
+
return;
|
|
51994
|
+
}
|
|
51995
|
+
const updatePosition = () => {
|
|
51996
|
+
const button = buttonRef.current;
|
|
51997
|
+
if (button === null) return;
|
|
51998
|
+
const rect = button.getBoundingClientRect();
|
|
51999
|
+
const edge = 12;
|
|
52000
|
+
const gap = 8;
|
|
52001
|
+
const width = Math.max(1, Math.min(420, window.innerWidth - 24));
|
|
52002
|
+
const availableAbove = Math.max(0, rect.top - gap - edge);
|
|
52003
|
+
const availableBelow = Math.max(0, window.innerHeight - rect.bottom - gap - edge);
|
|
52004
|
+
const preferredHeight = Math.min(440, window.innerHeight * .65);
|
|
52005
|
+
const placement = availableAbove >= preferredHeight || availableBelow < preferredHeight && availableAbove > availableBelow ? "above" : "below";
|
|
52006
|
+
const maxHeight = Math.min(preferredHeight, placement === "above" ? availableAbove : availableBelow);
|
|
52007
|
+
const desiredLeft = props.popupAlign === "end" ? rect.right - width : rect.left;
|
|
52008
|
+
const maxLeft = Math.max(edge, window.innerWidth - edge - width);
|
|
52009
|
+
setPopupPosition({
|
|
52010
|
+
left: Math.min(maxLeft, Math.max(edge, desiredLeft)),
|
|
52011
|
+
top: placement === "above" ? rect.top - gap : rect.bottom + gap,
|
|
52012
|
+
width,
|
|
52013
|
+
maxHeight,
|
|
52014
|
+
placement
|
|
52015
|
+
});
|
|
52016
|
+
};
|
|
52017
|
+
updatePosition();
|
|
52018
|
+
window.addEventListener("resize", updatePosition);
|
|
52019
|
+
window.addEventListener("scroll", updatePosition, true);
|
|
52020
|
+
return () => {
|
|
52021
|
+
window.removeEventListener("resize", updatePosition);
|
|
52022
|
+
window.removeEventListener("scroll", updatePosition, true);
|
|
52023
|
+
};
|
|
52024
|
+
}, [open, props.popupAlign]);
|
|
52025
|
+
const record = props.record ?? (source === void 0 || props.lookupText === void 0 ? void 0 : findTranslationRecordForText(source.getSnapshot(), props.lookupText, props.outputKind, props.turn, props.step));
|
|
52026
|
+
if (record === void 0) return null;
|
|
52027
|
+
const failed = record.failed === true;
|
|
52028
|
+
const alreadyTargetLanguage = record.alreadyTargetLanguage === true;
|
|
52029
|
+
const statusText = failed ? props.translationT("translation.statusFailed") : alreadyTargetLanguage ? props.translationT("translation.statusNotNeeded") : props.translationT("translation.statusTranslated");
|
|
52030
|
+
const model = formatModel(record.model, props.translationT);
|
|
52031
|
+
const detailsId = `codingns-translation-details-${safeDomId(props.messageId)}`;
|
|
52032
|
+
const details = open && popupPosition !== null ? (0, react.createElement)("div", {
|
|
52033
|
+
ref: popupRef,
|
|
52034
|
+
role: "dialog",
|
|
52035
|
+
"aria-label": props.translationT("translation.detailsTitle"),
|
|
52036
|
+
id: detailsId,
|
|
52037
|
+
style: {
|
|
52038
|
+
position: "fixed",
|
|
52039
|
+
zIndex: 2147483647,
|
|
52040
|
+
left: popupPosition.left,
|
|
52041
|
+
top: popupPosition.top,
|
|
52042
|
+
width: popupPosition.width,
|
|
52043
|
+
maxHeight: popupPosition.maxHeight,
|
|
52044
|
+
boxSizing: "border-box",
|
|
52045
|
+
...popupPosition.placement === "above" ? { transform: "translateY(-100%)" } : {},
|
|
52046
|
+
overflow: "auto",
|
|
52047
|
+
padding: "10px 12px",
|
|
52048
|
+
border: `1px solid ${require_theme.dshThemeColor.border}`,
|
|
52049
|
+
borderRadius: 8,
|
|
52050
|
+
color: require_theme.dshThemeColor.labelPrimary,
|
|
52051
|
+
background: require_theme.dshThemeColor.menuBackground,
|
|
52052
|
+
boxShadow: "0 8px 24px color-mix(in srgb, CanvasText 16%, transparent)",
|
|
52053
|
+
fontSize: require_theme.uiFontSize(12),
|
|
52054
|
+
lineHeight: 1.45
|
|
52055
|
+
}
|
|
52056
|
+
}, (0, react.createElement)("div", { style: {
|
|
52057
|
+
display: "flex",
|
|
52058
|
+
justifyContent: "space-between",
|
|
52059
|
+
gap: 10,
|
|
52060
|
+
fontWeight: 600
|
|
52061
|
+
} }, (0, react.createElement)("span", void 0, props.translationT("translation.detailsTitle")), (0, react.createElement)("span", { style: {
|
|
52062
|
+
color: failed ? require_theme.dshThemeColor.error : alreadyTargetLanguage ? require_theme.dshThemeColor.accent : require_theme.dshThemeColor.success,
|
|
52063
|
+
fontWeight: 400
|
|
52064
|
+
} }, statusText)), record.sourceLanguage === void 0 ? null : (0, react.createElement)("div", { style: {
|
|
52065
|
+
marginTop: 8,
|
|
52066
|
+
color: require_theme.dshThemeColor.labelSecondary
|
|
52067
|
+
} }, `${props.translationT("translation.detectedLanguage")}: ${props.translationT(`translation.language.${record.sourceLanguage}`)}`), (0, react.createElement)(DetailBlock, {
|
|
52068
|
+
label: props.translationT("translation.originalText"),
|
|
52069
|
+
value: record.original
|
|
52070
|
+
}), (0, react.createElement)(DetailBlock, {
|
|
52071
|
+
label: props.translationT("translation.translatedText"),
|
|
52072
|
+
value: record.translated
|
|
52073
|
+
}), (0, react.createElement)("div", { style: {
|
|
52074
|
+
marginTop: 8,
|
|
52075
|
+
color: require_theme.dshThemeColor.labelSecondary
|
|
52076
|
+
} }, `${props.translationT("translation.modelUsed")}: ${alreadyTargetLanguage ? props.translationT("translation.modelNotUsed") : model}`)) : null;
|
|
52077
|
+
const renderedDetails = details === null ? null : typeof document === "undefined" ? details : (0, import_react_dom.createPortal)(details, document.body);
|
|
52078
|
+
return (0, react.createElement)("div", {
|
|
52079
|
+
ref: rootRef,
|
|
52080
|
+
style: {
|
|
52081
|
+
position: "relative",
|
|
52082
|
+
display: "inline-flex",
|
|
52083
|
+
alignItems: "center",
|
|
52084
|
+
verticalAlign: "middle",
|
|
52085
|
+
...props.inline === true ? { marginInlineStart: 4 } : {}
|
|
52086
|
+
},
|
|
52087
|
+
"data-codingns-translation-action": props.messageId
|
|
52088
|
+
}, (0, react.createElement)("button", {
|
|
52089
|
+
ref: buttonRef,
|
|
52090
|
+
type: "button",
|
|
52091
|
+
title: `${statusText} · ${props.translationT("translation.viewDetails")}`,
|
|
52092
|
+
"aria-label": `${statusText} · ${props.translationT("translation.viewDetails")}`,
|
|
52093
|
+
"aria-expanded": open,
|
|
52094
|
+
"aria-controls": detailsId,
|
|
52095
|
+
onClick: () => setOpen((value) => !value),
|
|
52096
|
+
style: translationButtonStyle
|
|
52097
|
+
}, (0, react.createElement)(TranslationGlyph), (0, react.createElement)("span", {
|
|
52098
|
+
"aria-hidden": true,
|
|
52099
|
+
style: {
|
|
52100
|
+
position: "absolute",
|
|
52101
|
+
top: 1,
|
|
52102
|
+
right: 1,
|
|
52103
|
+
display: "grid",
|
|
52104
|
+
placeItems: "center",
|
|
52105
|
+
width: 10,
|
|
52106
|
+
height: 10,
|
|
52107
|
+
zIndex: 1,
|
|
52108
|
+
boxSizing: "border-box",
|
|
52109
|
+
border: "1.5px solid var(--dsw-alias-bg-base, Canvas)",
|
|
52110
|
+
borderRadius: "50%",
|
|
52111
|
+
color: "#fff",
|
|
52112
|
+
background: failed ? require_theme.dshThemeColor.error : alreadyTargetLanguage ? require_theme.dshThemeColor.accent : require_theme.dshThemeColor.success,
|
|
52113
|
+
fontSize: 6,
|
|
52114
|
+
fontWeight: 700,
|
|
52115
|
+
lineHeight: 1
|
|
52116
|
+
}
|
|
52117
|
+
}, failed ? "!" : "✓")), renderedDetails);
|
|
52118
|
+
}
|
|
52119
|
+
function TranslationGlyph() {
|
|
52120
|
+
return (0, react.createElement)("svg", {
|
|
52121
|
+
viewBox: "0 0 24 24",
|
|
52122
|
+
width: 16,
|
|
52123
|
+
height: 16,
|
|
52124
|
+
fill: "none",
|
|
52125
|
+
stroke: "currentColor",
|
|
52126
|
+
strokeWidth: 1.5,
|
|
52127
|
+
strokeLinecap: "round",
|
|
52128
|
+
strokeLinejoin: "round",
|
|
52129
|
+
"aria-hidden": true
|
|
52130
|
+
}, (0, react.createElement)("path", { d: "M3.5 5.5h10M8.5 3.5v2M12.5 5.5c0 4.4-3.3 7.2-8 9" }), (0, react.createElement)("path", { d: "M5.5 8.5c1.4 2 3.4 3.7 6 4.8M14.5 19.5l3-8 3 8M15.7 17h3.6" }));
|
|
52131
|
+
}
|
|
52132
|
+
const messageActionButtonStyle = {
|
|
52133
|
+
position: "relative",
|
|
52134
|
+
display: "inline-flex",
|
|
52135
|
+
alignItems: "center",
|
|
52136
|
+
justifyContent: "center",
|
|
52137
|
+
width: 28,
|
|
52138
|
+
height: 28,
|
|
52139
|
+
padding: 0,
|
|
52140
|
+
border: 0,
|
|
52141
|
+
borderRadius: "var(--dsw-radius-sm, 6px)",
|
|
52142
|
+
color: require_theme.dshThemeColor.labelTertiary,
|
|
52143
|
+
background: "transparent",
|
|
52144
|
+
cursor: "pointer"
|
|
52145
|
+
};
|
|
52146
|
+
const translationButtonStyle = {
|
|
52147
|
+
...messageActionButtonStyle,
|
|
52148
|
+
transition: "background-color 100ms ease, color 100ms ease"
|
|
52149
|
+
};
|
|
52150
|
+
function DetailBlock({ label, value }) {
|
|
52151
|
+
return (0, react.createElement)("div", { style: { marginTop: 8 } }, (0, react.createElement)("div", { style: {
|
|
52152
|
+
marginBottom: 3,
|
|
52153
|
+
color: require_theme.dshThemeColor.labelSecondary,
|
|
52154
|
+
fontWeight: 600
|
|
52155
|
+
} }, label), (0, react.createElement)("pre", { style: {
|
|
52156
|
+
margin: 0,
|
|
52157
|
+
whiteSpace: "pre-wrap",
|
|
52158
|
+
overflowWrap: "anywhere",
|
|
52159
|
+
fontFamily: "inherit"
|
|
52160
|
+
} }, value));
|
|
52161
|
+
}
|
|
52162
|
+
/** 按原生 user 节点的结构渲染用户消息,并把翻译按钮放在复制按钮前。 */
|
|
52163
|
+
function UserMessageNodeView(props) {
|
|
52164
|
+
const data = props.node.data;
|
|
52165
|
+
const parts = splitUserContent(data.content);
|
|
52166
|
+
const record = readInputRecord({ source: data.source });
|
|
52167
|
+
if (record === void 0) return null;
|
|
52168
|
+
const translationRecord = inputRecordForAction(record);
|
|
52169
|
+
const labels = Array.isArray(data.referenceLabels) ? data.referenceLabels.filter((label) => typeof label === "string") : [];
|
|
52170
|
+
const skillNames = Array.isArray(data.skillNames) ? data.skillNames.filter((name) => typeof name === "string") : [];
|
|
52171
|
+
const showBubble = parts.text !== "" || parts.rest.length > 0;
|
|
52172
|
+
const compactImages = parts.attachments.filter((attachment) => attachment.type === "image").length > 1;
|
|
52173
|
+
const messageId = `user-${String(data.seq ?? props.node.id ?? "message")}`;
|
|
52174
|
+
const chatT = props.t;
|
|
52175
|
+
return (0, react.createElement)("div", {
|
|
52176
|
+
"data-chat-flow-kind": "user",
|
|
52177
|
+
style: {
|
|
52178
|
+
display: "flex",
|
|
52179
|
+
flexDirection: "column",
|
|
52180
|
+
alignItems: "flex-end",
|
|
52181
|
+
gap: 6
|
|
52182
|
+
}
|
|
52183
|
+
}, (0, react.createElement)("div", { style: {
|
|
52184
|
+
display: "flex",
|
|
52185
|
+
flexDirection: "column",
|
|
52186
|
+
alignItems: "flex-end",
|
|
52187
|
+
gap: 8,
|
|
52188
|
+
minWidth: 0,
|
|
52189
|
+
maxWidth: "min(calc(var(--dsh-chat-content-width, 748px) * .702), 82%)"
|
|
52190
|
+
} }, parts.attachments.length > 0 ? (0, react.createElement)("div", {
|
|
52191
|
+
"data-message-attachments": true,
|
|
52192
|
+
style: {
|
|
52193
|
+
display: "flex",
|
|
52194
|
+
flexWrap: "wrap",
|
|
52195
|
+
justifyContent: "flex-end",
|
|
52196
|
+
gap: 8,
|
|
52197
|
+
maxWidth: "100%"
|
|
52198
|
+
}
|
|
52199
|
+
}, ...parts.attachments.map((attachment, index) => attachment.type === "image" ? (0, react.createElement)("div", { key: `image-${index}` }, props.renderMessageImages({
|
|
52200
|
+
images: [{ attachment: attachment.attachment }],
|
|
52201
|
+
align: "end",
|
|
52202
|
+
compact: compactImages
|
|
52203
|
+
})) : createFileAttachment(attachment.file, index))) : null, showBubble ? (0, react.createElement)("div", { style: {
|
|
52204
|
+
boxSizing: "border-box",
|
|
52205
|
+
maxWidth: "100%",
|
|
52206
|
+
padding: "10px 16px",
|
|
52207
|
+
borderRadius: "var(--dsw-radius-xl, 18px)",
|
|
52208
|
+
color: require_theme.dshThemeColor.labelPrimary,
|
|
52209
|
+
background: "var(--dsw-specific-bubble, var(--dsw-alias-interactive-bg-hover, rgba(127,127,127,.08)))",
|
|
52210
|
+
fontSize: "var(--dsh-content-font-size, 14px)",
|
|
52211
|
+
lineHeight: "calc(22px + var(--dsh-content-font-delta, 0px))",
|
|
52212
|
+
whiteSpace: "pre-wrap",
|
|
52213
|
+
wordBreak: "break-word"
|
|
52214
|
+
} }, (0, _deepseek_ai_dsh_client_ui_primitives.projectUserText)(parts.text, labels, skillNames, "skill", typeof props.openFile === "function" && typeof props.openSkill === "function" ? {
|
|
52215
|
+
openFile: props.openFile,
|
|
52216
|
+
openSkill: props.openSkill
|
|
52217
|
+
} : void 0), ...parts.rest.map((block, index) => (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.JsonBlock, {
|
|
52218
|
+
key: `extra-${index}`,
|
|
52219
|
+
label: chatT("message.extraBlock"),
|
|
52220
|
+
payload: block,
|
|
52221
|
+
truncatedLabel: (total) => chatT("json.truncated", { total })
|
|
52222
|
+
}))) : null), (0, react.createElement)("div", { style: {
|
|
52223
|
+
display: "flex",
|
|
52224
|
+
alignItems: "center",
|
|
52225
|
+
alignSelf: "flex-end",
|
|
52226
|
+
height: "calc(28px + var(--dsh-content-font-delta, 0px))",
|
|
52227
|
+
gap: 8,
|
|
52228
|
+
color: require_theme.dshThemeColor.labelTertiary
|
|
52229
|
+
} }, typeof data.time === "number" ? (0, react.createElement)("span", { style: {
|
|
52230
|
+
paddingRight: 12,
|
|
52231
|
+
color: require_theme.dshThemeColor.labelTertiary,
|
|
52232
|
+
fontSize: "var(--dsh-content-font-size-secondary, 13px)",
|
|
52233
|
+
whiteSpace: "nowrap"
|
|
52234
|
+
} }, formatMessageTime(data.time)) : null, translationRecord === void 0 ? null : (0, react.createElement)(TranslationAction, {
|
|
52235
|
+
messageId,
|
|
52236
|
+
sessionId: props.sessionId,
|
|
52237
|
+
services: props.services,
|
|
52238
|
+
translationT: props.translationT,
|
|
52239
|
+
popupAlign: "end",
|
|
52240
|
+
record: translationRecord
|
|
52241
|
+
}), (0, react.createElement)(CopyAction, {
|
|
52242
|
+
text: parts.text,
|
|
52243
|
+
t: chatT
|
|
52244
|
+
})));
|
|
52245
|
+
}
|
|
52246
|
+
function createFileAttachment(file, index) {
|
|
52247
|
+
const name = typeof file.name === "string" ? file.name : "";
|
|
52248
|
+
const bytes = typeof file.bytes === "number" ? file.bytes : 0;
|
|
52249
|
+
return (0, react.createElement)("span", {
|
|
52250
|
+
key: `file-${index}`,
|
|
52251
|
+
title: name,
|
|
52252
|
+
style: {
|
|
52253
|
+
display: "inline-flex",
|
|
52254
|
+
alignItems: "center",
|
|
52255
|
+
minWidth: 0,
|
|
52256
|
+
maxWidth: "100%",
|
|
52257
|
+
gap: 8,
|
|
52258
|
+
padding: "8px 10px",
|
|
52259
|
+
border: `1px solid ${require_theme.dshThemeColor.border}`,
|
|
52260
|
+
borderRadius: 8,
|
|
52261
|
+
color: require_theme.dshThemeColor.labelPrimary,
|
|
52262
|
+
background: require_theme.dshThemeColor.surfaceSubtle
|
|
52263
|
+
}
|
|
52264
|
+
}, (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.FileTypeIcon, {
|
|
52265
|
+
path: name,
|
|
52266
|
+
style: { flex: "none" }
|
|
52267
|
+
}), (0, react.createElement)("span", { style: {
|
|
52268
|
+
display: "flex",
|
|
52269
|
+
flexDirection: "column",
|
|
52270
|
+
minWidth: 0,
|
|
52271
|
+
textAlign: "left"
|
|
52272
|
+
} }, (0, react.createElement)("span", { style: {
|
|
52273
|
+
overflow: "hidden",
|
|
52274
|
+
textOverflow: "ellipsis",
|
|
52275
|
+
whiteSpace: "nowrap"
|
|
52276
|
+
} }, name), (0, react.createElement)("span", { style: {
|
|
52277
|
+
color: require_theme.dshThemeColor.labelSecondary,
|
|
52278
|
+
fontSize: 11
|
|
52279
|
+
} }, [(0, _deepseek_ai_dsh_client_ui_primitives.fileExtension)(name).toUpperCase().slice(0, 8), (0, _deepseek_ai_dsh_client_ui_primitives.fileSizeText)(bytes)].filter(Boolean).join(" "))));
|
|
52280
|
+
}
|
|
52281
|
+
function CopyAction({ text, t: chatT }) {
|
|
52282
|
+
const [copied, setCopied] = (0, react.useState)(false);
|
|
52283
|
+
const timer = (0, react.useRef)(void 0);
|
|
52284
|
+
(0, react.useEffect)(() => () => {
|
|
52285
|
+
if (timer.current !== void 0) clearTimeout(timer.current);
|
|
52286
|
+
}, []);
|
|
52287
|
+
return (0, react.createElement)("button", {
|
|
52288
|
+
type: "button",
|
|
52289
|
+
title: copied ? chatT("copied") : chatT("copy"),
|
|
52290
|
+
"aria-label": copied ? chatT("copied") : chatT("copy"),
|
|
52291
|
+
onClick: () => {
|
|
52292
|
+
(0, _deepseek_ai_dsh_client_ui_primitives.writeClipboard)(text).then((success) => {
|
|
52293
|
+
if (!success) return;
|
|
52294
|
+
setCopied(true);
|
|
52295
|
+
if (timer.current !== void 0) clearTimeout(timer.current);
|
|
52296
|
+
timer.current = setTimeout(() => {
|
|
52297
|
+
timer.current = void 0;
|
|
52298
|
+
setCopied(false);
|
|
52299
|
+
}, 1e3);
|
|
52300
|
+
});
|
|
52301
|
+
},
|
|
52302
|
+
style: messageActionButtonStyle
|
|
52303
|
+
}, (0, react.createElement)(copied ? _deepseek_ai_dsh_client_ui_primitives.IconCheckOutlineRegular : _deepseek_ai_dsh_client_ui_primitives.IconCopyOutlineRegular));
|
|
52304
|
+
}
|
|
52305
|
+
function splitUserContent(content) {
|
|
52306
|
+
const text = [];
|
|
52307
|
+
const attachments = [];
|
|
52308
|
+
const rest = [];
|
|
52309
|
+
if (typeof content === "string") return {
|
|
52310
|
+
text: content,
|
|
52311
|
+
attachments,
|
|
52312
|
+
rest
|
|
52313
|
+
};
|
|
52314
|
+
if (!Array.isArray(content)) return {
|
|
52315
|
+
text: "",
|
|
52316
|
+
attachments,
|
|
52317
|
+
rest
|
|
52318
|
+
};
|
|
52319
|
+
for (const value of content) {
|
|
52320
|
+
const block = asRecord(value);
|
|
52321
|
+
if (block?.type === "text" && typeof block.text === "string") text.push(block.text);
|
|
52322
|
+
else if (block?.type === "image" && block.attachment !== void 0) attachments.push({
|
|
52323
|
+
type: "image",
|
|
52324
|
+
attachment: block.attachment
|
|
52325
|
+
});
|
|
52326
|
+
else if (block?.type === "file" && asRecord(block.attachment) !== void 0) attachments.push({
|
|
52327
|
+
type: "file",
|
|
52328
|
+
file: asRecord(block.attachment)
|
|
52329
|
+
});
|
|
52330
|
+
else rest.push(value);
|
|
52331
|
+
}
|
|
52332
|
+
return {
|
|
52333
|
+
text: text.join(""),
|
|
52334
|
+
attachments,
|
|
52335
|
+
rest
|
|
52336
|
+
};
|
|
52337
|
+
}
|
|
52338
|
+
function formatMessageTime(time) {
|
|
52339
|
+
const date = new Date(time);
|
|
52340
|
+
const now = /* @__PURE__ */ new Date();
|
|
52341
|
+
const options = date.getFullYear() === now.getFullYear() && date.getMonth() === now.getMonth() && date.getDate() === now.getDate() ? {
|
|
52342
|
+
hour: "2-digit",
|
|
52343
|
+
minute: "2-digit"
|
|
52344
|
+
} : {
|
|
52345
|
+
...date.getFullYear() === now.getFullYear() ? {} : { year: "numeric" },
|
|
52346
|
+
month: "2-digit",
|
|
52347
|
+
day: "2-digit",
|
|
52348
|
+
hour: "2-digit",
|
|
52349
|
+
minute: "2-digit"
|
|
52350
|
+
};
|
|
52351
|
+
return new Intl.DateTimeFormat(void 0, options).format(date);
|
|
52352
|
+
}
|
|
52353
|
+
/** DSH assistant-step renderer: keep each translated text/reasoning block's source action adjacent to that block. */
|
|
52354
|
+
function AssistantTranslationNodeView(props) {
|
|
52355
|
+
const data = props.node.data;
|
|
52356
|
+
const blocks = Array.isArray(data.blocks) ? data.blocks : [];
|
|
52357
|
+
const streaming = data.status === "running";
|
|
52358
|
+
const chatT = props.t;
|
|
52359
|
+
const markdownLabels = (0, react.useMemo)(() => createMarkdownLabels(chatT), [chatT]);
|
|
52360
|
+
const pathImages = (0, react.useMemo)(() => ({ resolve: resolveMarkdownImagePath }), []);
|
|
52361
|
+
const eventSnapshot = readEventSource(props.services, props.sessionId)?.getSnapshot();
|
|
52362
|
+
const hasTranslation = blocks.some((block) => {
|
|
52363
|
+
if (block.kind !== "reasoning" && block.kind !== "text") return false;
|
|
52364
|
+
const outputKind = block.kind === "reasoning" ? "reasoning" : "assistant";
|
|
52365
|
+
const embedded = readRecord(block);
|
|
52366
|
+
if (embedded !== void 0 && (embedded.outputKind === void 0 || embedded.outputKind === outputKind)) return true;
|
|
52367
|
+
return eventSnapshot !== void 0 && findTranslationRecordForText(eventSnapshot, block.text, outputKind, data.turn, data.step) !== void 0;
|
|
52368
|
+
});
|
|
52369
|
+
const turn = props.node.location?.kind === "turn" || props.node.location?.kind === "step" ? props.node.location.turn : void 0;
|
|
52370
|
+
const tail = typeof props.useTurnData === "function" ? props.useTurnData("turn-tail") : void 0;
|
|
52371
|
+
const finalNode = data.finalNode;
|
|
52372
|
+
const fileOwner = turn?.status === "closed" && finalNode !== void 0 && tail?.closing?.finalNode?.seq === finalNode.seq ? {
|
|
52373
|
+
turn,
|
|
52374
|
+
seq: finalNode.seq,
|
|
52375
|
+
openFile: (path) => {
|
|
52376
|
+
props.openFile(path);
|
|
52377
|
+
}
|
|
52378
|
+
} : void 0;
|
|
52379
|
+
const mentions = fileOwner === void 0 || typeof props.fileMentions !== "function" ? void 0 : props.fileMentions(fileOwner);
|
|
52380
|
+
const turnProcess = props.turnProcess;
|
|
52381
|
+
const reasoningHidden = turnProcess !== void 0 && turnProcess.foldable === true && turnProcess.spec?.answerStep === data.step && turnProcess.spec?.inlineReasoning === true && turnProcess.open !== true;
|
|
52382
|
+
const rendered = [];
|
|
52383
|
+
const last = blocks.length - 1;
|
|
52384
|
+
const messageId = typeof finalNode?.messageId === "string" ? finalNode.messageId : `turn-${data.turn}-step-${data.step}`;
|
|
52385
|
+
if (!hasTranslation || !(streaming || data.status === "interrupted" || blocks.some((block) => block.kind !== "tool-call"))) return null;
|
|
52386
|
+
for (let index = 0; index < blocks.length; index += 1) {
|
|
52387
|
+
const block = blocks[index];
|
|
52388
|
+
if (block === void 0) continue;
|
|
52389
|
+
if (props.groupPart === "reasoning" && block.kind !== "reasoning") continue;
|
|
52390
|
+
if (props.groupPart === "response" && block.kind === "reasoning") continue;
|
|
52391
|
+
const running = streaming && index === last;
|
|
52392
|
+
if (block.kind === "text") {
|
|
52393
|
+
const translationRecord = readRecord(block);
|
|
52394
|
+
rendered.push((0, react.createElement)("div", {
|
|
52395
|
+
key: `text-${index}`,
|
|
52396
|
+
"data-codingns-translation-inline": true,
|
|
52397
|
+
style: { minWidth: 0 }
|
|
52398
|
+
}, (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.MarkdownText, {
|
|
52399
|
+
text: block.text,
|
|
52400
|
+
streaming,
|
|
52401
|
+
labels: markdownLabels,
|
|
52402
|
+
fileMentions: mentions,
|
|
52403
|
+
pathImages
|
|
52404
|
+
}), (0, react.createElement)(TranslationAction, {
|
|
52405
|
+
messageId: `${messageId}-text-${index}`,
|
|
52406
|
+
sessionId: props.sessionId,
|
|
52407
|
+
services: props.services,
|
|
52408
|
+
translationT: props.translationT,
|
|
52409
|
+
lookupText: block.text,
|
|
52410
|
+
outputKind: "assistant",
|
|
52411
|
+
turn: data.turn,
|
|
52412
|
+
step: data.step,
|
|
52413
|
+
inline: true,
|
|
52414
|
+
...translationRecord === void 0 ? {} : { record: translationRecord }
|
|
52415
|
+
})));
|
|
52416
|
+
continue;
|
|
52417
|
+
}
|
|
52418
|
+
if (block.kind === "reasoning") {
|
|
52419
|
+
rendered.push((0, react.createElement)(AssistantReasoningBlock, {
|
|
52420
|
+
key: `reasoning-${index}`,
|
|
52421
|
+
messageId: `${messageId}-reasoning-${index}`,
|
|
52422
|
+
sessionId: props.sessionId,
|
|
52423
|
+
services: props.services,
|
|
52424
|
+
translationT: props.translationT,
|
|
52425
|
+
chatT,
|
|
52426
|
+
text: block.text,
|
|
52427
|
+
turn: data.turn,
|
|
52428
|
+
step: data.step,
|
|
52429
|
+
running,
|
|
52430
|
+
hidden: reasoningHidden,
|
|
52431
|
+
reveal: () => turnProcess?.setOpen?.(true),
|
|
52432
|
+
useGroupAction: props.useGroupAction,
|
|
52433
|
+
renderFactorySlot: props.renderFactorySlot,
|
|
52434
|
+
markdownLabels,
|
|
52435
|
+
pathImages,
|
|
52436
|
+
mentions
|
|
52437
|
+
}));
|
|
52438
|
+
continue;
|
|
52439
|
+
}
|
|
52440
|
+
if (block.kind === "image") {
|
|
52441
|
+
const imageGroup = [block];
|
|
52442
|
+
while (index + 1 < blocks.length && blocks[index + 1]?.kind === "image") {
|
|
52443
|
+
const next = blocks[index + 1];
|
|
52444
|
+
if (next?.kind !== "image") break;
|
|
52445
|
+
imageGroup.push(next);
|
|
52446
|
+
index += 1;
|
|
52447
|
+
}
|
|
52448
|
+
rendered.push((0, react.createElement)("div", {
|
|
52449
|
+
key: `images-${index}`,
|
|
52450
|
+
style: { alignSelf: "flex-start" }
|
|
52451
|
+
}, props.renderMessageImages({
|
|
52452
|
+
images: imageGroup.map((image) => ({ attachment: image.attachment })),
|
|
52453
|
+
align: "start"
|
|
52454
|
+
})));
|
|
52455
|
+
continue;
|
|
52456
|
+
}
|
|
52457
|
+
if (block.kind === "other") rendered.push((0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.JsonBlock, {
|
|
52458
|
+
key: `other-${index}`,
|
|
52459
|
+
label: chatT("message.unknownBlock"),
|
|
52460
|
+
payload: block.block,
|
|
52461
|
+
truncatedLabel: (total) => chatT("json.truncated", { total })
|
|
52462
|
+
}));
|
|
52463
|
+
}
|
|
52464
|
+
return (0, react.createElement)("div", {
|
|
52465
|
+
"data-streaming": streaming || void 0,
|
|
52466
|
+
style: {
|
|
52467
|
+
display: "flex",
|
|
52468
|
+
flexDirection: "column",
|
|
52469
|
+
gap: 16,
|
|
52470
|
+
minWidth: 0,
|
|
52471
|
+
color: require_theme.dshThemeColor.labelPrimary,
|
|
52472
|
+
fontSize: "var(--dsh-content-font-size, 14px)",
|
|
52473
|
+
lineHeight: "calc(24px + var(--dsh-content-font-delta, 0px))"
|
|
52474
|
+
}
|
|
52475
|
+
}, ...rendered, data.status === "interrupted" ? (0, react.createElement)("span", { style: {
|
|
52476
|
+
alignSelf: "flex-start",
|
|
52477
|
+
padding: "0 6px",
|
|
52478
|
+
borderRadius: "var(--dsw-radius-sm, 4px)",
|
|
52479
|
+
color: require_theme.dshThemeColor.labelTertiary,
|
|
52480
|
+
background: require_theme.dshThemeColor.surfaceSubtle,
|
|
52481
|
+
fontSize: 11,
|
|
52482
|
+
lineHeight: "18px"
|
|
52483
|
+
} }, chatT("message.stopped")) : null);
|
|
52484
|
+
}
|
|
52485
|
+
function AssistantReasoningBlock(props) {
|
|
52486
|
+
const [expanded, setExpanded] = (0, react.useState)(false);
|
|
52487
|
+
const groupRef = props.useGroupAction?.(props.hidden, props.reveal);
|
|
52488
|
+
const summary = props.text.split("\n").map((line) => line.replace(/[`*_#>]/gu, "").trim()).find(Boolean) ?? "";
|
|
52489
|
+
const markdown = props.renderFactorySlot === void 0 ? (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.MarkdownText, {
|
|
52490
|
+
text: props.text,
|
|
52491
|
+
streaming: props.running,
|
|
52492
|
+
labels: props.markdownLabels,
|
|
52493
|
+
fileMentions: props.mentions,
|
|
52494
|
+
pathImages: props.pathImages,
|
|
52495
|
+
variant: "compact"
|
|
52496
|
+
}) : props.renderFactorySlot("conversation.chat.reasoning.content", {
|
|
52497
|
+
text: props.text,
|
|
52498
|
+
running: props.running
|
|
52499
|
+
});
|
|
52500
|
+
return (0, react.createElement)("div", {
|
|
52501
|
+
ref: groupRef,
|
|
52502
|
+
hidden: props.hidden,
|
|
52503
|
+
"data-turn-process-inline": props.hidden || void 0
|
|
52504
|
+
}, (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.DisclosureRow, {
|
|
52505
|
+
icon: (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.IconThinkOutlineRegular, { size: 14 }),
|
|
52506
|
+
title: props.chatT("message.think"),
|
|
52507
|
+
open: expanded,
|
|
52508
|
+
expandable: true,
|
|
52509
|
+
expandOnRowClick: true,
|
|
52510
|
+
running: props.running,
|
|
52511
|
+
onToggle: () => setExpanded((value) => !value),
|
|
52512
|
+
collapsedContent: (0, react.createElement)("span", { style: {
|
|
52513
|
+
minWidth: 0,
|
|
52514
|
+
overflow: "hidden",
|
|
52515
|
+
color: require_theme.dshThemeColor.labelSecondary,
|
|
52516
|
+
fontSize: "var(--dsh-content-font-size-secondary, 13px)",
|
|
52517
|
+
textOverflow: "ellipsis",
|
|
52518
|
+
whiteSpace: "nowrap"
|
|
52519
|
+
} }, (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.TextShimmer, {
|
|
52520
|
+
active: props.running,
|
|
52521
|
+
children: summary
|
|
52522
|
+
}))
|
|
52523
|
+
}, expanded ? (0, react.createElement)("div", {
|
|
52524
|
+
"data-codingns-translation-inline": true,
|
|
52525
|
+
style: { paddingTop: 8 }
|
|
52526
|
+
}, markdown, (0, react.createElement)(TranslationAction, {
|
|
52527
|
+
messageId: props.messageId,
|
|
52528
|
+
sessionId: props.sessionId,
|
|
52529
|
+
services: props.services,
|
|
52530
|
+
translationT: props.translationT,
|
|
52531
|
+
lookupText: props.text,
|
|
52532
|
+
outputKind: "reasoning",
|
|
52533
|
+
...props.turn === void 0 ? {} : { turn: props.turn },
|
|
52534
|
+
...props.step === void 0 ? {} : { step: props.step },
|
|
52535
|
+
inline: true
|
|
52536
|
+
})) : null));
|
|
52537
|
+
}
|
|
52538
|
+
function createMarkdownLabels(chatT) {
|
|
52539
|
+
return {
|
|
52540
|
+
code: {
|
|
52541
|
+
copyLabel: chatT("copy"),
|
|
52542
|
+
copiedLabel: chatT("copied"),
|
|
52543
|
+
toolbarLabels: {
|
|
52544
|
+
codeLabel: chatT("codeBlock.title"),
|
|
52545
|
+
wrapLabel: chatT("codeBlock.wrap"),
|
|
52546
|
+
unwrapLabel: chatT("codeBlock.unwrap")
|
|
52547
|
+
}
|
|
52548
|
+
},
|
|
52549
|
+
footnotes: chatT("markdown.footnotes")
|
|
52550
|
+
};
|
|
52551
|
+
}
|
|
52552
|
+
function resolveMarkdownImagePath(value) {
|
|
52553
|
+
if (typeof document === "undefined" || !value.startsWith("/") || /^[/\\]{2}/u.test(value) || /[\u0000-\u001f\u007f]/u.test(value)) return void 0;
|
|
52554
|
+
const base = document.baseURI;
|
|
52555
|
+
if (!/^https?:/u.test(base) && !base.startsWith("dsh-app://app/")) return void 0;
|
|
52556
|
+
try {
|
|
52557
|
+
return new URL(`api/file?path=${encodeURIComponent(value)}`, base).href;
|
|
52558
|
+
} catch {
|
|
52559
|
+
return;
|
|
52560
|
+
}
|
|
52561
|
+
}
|
|
52562
|
+
/**
|
|
52563
|
+
* 注册两个有实际翻译记录的消息渲染器;DSH 的用户气泡内容仍由统一主题令牌控制。
|
|
52564
|
+
*/
|
|
52565
|
+
function registerSessionTranslationChatUi(services) {
|
|
52566
|
+
const slots = services.slots;
|
|
52567
|
+
if (slots?.inject === void 0 || slots.register === void 0) return () => void 0;
|
|
52568
|
+
const removeStyles = installSessionTranslationChatStyles();
|
|
52569
|
+
const translationT = services.locale.bind("codingns");
|
|
52570
|
+
const removeUserRenderer = slots.inject("conversation.chat.node", () => slots.register({
|
|
52571
|
+
name: "conversation.chat.node",
|
|
52572
|
+
key: "user",
|
|
52573
|
+
priority: -100,
|
|
52574
|
+
locale: "chat",
|
|
52575
|
+
inject: (sessionId) => ({
|
|
52576
|
+
services,
|
|
52577
|
+
sessionId,
|
|
52578
|
+
translationT
|
|
52579
|
+
})
|
|
52580
|
+
}, UserMessageNodeView));
|
|
52581
|
+
const removeAssistantRenderer = slots.inject("conversation.chat.node", () => slots.register({
|
|
52582
|
+
name: "conversation.chat.node",
|
|
52583
|
+
key: "assistant-step",
|
|
52584
|
+
priority: -100,
|
|
52585
|
+
locale: "chat",
|
|
52586
|
+
inject: (sessionId) => ({
|
|
52587
|
+
services,
|
|
52588
|
+
sessionId,
|
|
52589
|
+
translationT
|
|
52590
|
+
})
|
|
52591
|
+
}, AssistantTranslationNodeView));
|
|
52592
|
+
return () => {
|
|
52593
|
+
removeAssistantRenderer();
|
|
52594
|
+
removeUserRenderer();
|
|
52595
|
+
removeStyles();
|
|
52596
|
+
};
|
|
52597
|
+
}
|
|
52598
|
+
function installSessionTranslationChatStyles() {
|
|
52599
|
+
if (typeof document === "undefined") return () => void 0;
|
|
52600
|
+
const styleId = "codingns-session-translation-chat";
|
|
52601
|
+
if (document.head.querySelector(`style[data-plugin-css="${styleId}"]`) !== null) return () => void 0;
|
|
52602
|
+
const style = document.createElement("style");
|
|
52603
|
+
style.dataset.plugin = "codingns4dsh";
|
|
52604
|
+
style.dataset.pluginCss = styleId;
|
|
52605
|
+
style.textContent = `
|
|
52606
|
+
[data-codingns-translation-inline] > div:not([data-codingns-translation-action]){display:contents}
|
|
52607
|
+
[data-codingns-translation-inline] > div:not([data-codingns-translation-action]) > p:last-child{display:inline;margin:0}
|
|
52608
|
+
`;
|
|
52609
|
+
document.head.appendChild(style);
|
|
52610
|
+
return () => style.remove();
|
|
52611
|
+
}
|
|
52612
|
+
function readEventSource(services, sessionId) {
|
|
52613
|
+
const sessions = services.sessions;
|
|
52614
|
+
try {
|
|
52615
|
+
return sessions?.binding?.(sessionId)?.eventSource;
|
|
52616
|
+
} catch {
|
|
52617
|
+
return;
|
|
52618
|
+
}
|
|
52619
|
+
}
|
|
52620
|
+
function findTranslationRecordForText(snapshot, text, outputKind, turn, step) {
|
|
52621
|
+
const entries = snapshot.entries ?? [];
|
|
52622
|
+
for (let index = entries.length - 1; index >= 0; index -= 1) {
|
|
52623
|
+
const event = readEntryEvent(entries[index]);
|
|
52624
|
+
if (event === void 0 || !event.type.startsWith("assistant/")) continue;
|
|
52625
|
+
const eventData = asRecord(event.data);
|
|
52626
|
+
if (turn !== void 0 && typeof eventData?.turn === "number" && eventData.turn !== turn) continue;
|
|
52627
|
+
if (step !== void 0 && typeof eventData?.step === "number" && eventData.step !== step) continue;
|
|
52628
|
+
const candidates = [];
|
|
52629
|
+
collectRecordCandidates(event.data, candidates, /* @__PURE__ */ new Set());
|
|
52630
|
+
for (const candidate of candidates) {
|
|
52631
|
+
const record = readRecord(candidate);
|
|
52632
|
+
if (record === void 0 || record.translated !== text) continue;
|
|
52633
|
+
if (outputKind !== void 0 && record.outputKind !== void 0 && record.outputKind !== outputKind) continue;
|
|
52634
|
+
return record;
|
|
52635
|
+
}
|
|
52636
|
+
}
|
|
52637
|
+
}
|
|
52638
|
+
function collectRecordCandidates(value, candidates, seen, depth = 0) {
|
|
52639
|
+
if (Array.isArray(value)) {
|
|
52640
|
+
for (const item of value) collectRecordCandidates(item, candidates, seen, depth + 1);
|
|
52641
|
+
return;
|
|
52642
|
+
}
|
|
52643
|
+
const record = asRecord(value);
|
|
52644
|
+
if (record === void 0 || seen.has(record) || depth > 7) return;
|
|
52645
|
+
seen.add(record);
|
|
52646
|
+
if (readRecord(record) !== void 0 || asRecord(record.codingnsTranslation) !== void 0) candidates.push(record);
|
|
52647
|
+
for (const key of [
|
|
52648
|
+
"codingnsTranslation",
|
|
52649
|
+
"source",
|
|
52650
|
+
"message",
|
|
52651
|
+
"content",
|
|
52652
|
+
"stream",
|
|
52653
|
+
"chunk",
|
|
52654
|
+
"block",
|
|
52655
|
+
"data"
|
|
52656
|
+
]) if (record[key] !== void 0) collectRecordCandidates(record[key], candidates, seen, depth + 1);
|
|
52657
|
+
}
|
|
52658
|
+
function readEntryEvent(value) {
|
|
52659
|
+
const record = asRecord(value);
|
|
52660
|
+
return asRecord(record?.event) ?? (typeof record?.type === "string" ? record : void 0);
|
|
52661
|
+
}
|
|
52662
|
+
function readRecord(value) {
|
|
52663
|
+
const record = asRecord(value);
|
|
52664
|
+
const candidate = asRecord(record?.codingnsTranslation) ?? record;
|
|
52665
|
+
if (candidate?.original === void 0 || candidate.translated === void 0) return void 0;
|
|
52666
|
+
if (typeof candidate.original !== "string" || typeof candidate.translated !== "string") return void 0;
|
|
52667
|
+
const targetLanguage = readLanguage(candidate.targetLanguage);
|
|
52668
|
+
if (targetLanguage === void 0) return void 0;
|
|
52669
|
+
const model = readModel(candidate.model);
|
|
52670
|
+
const outputKind = candidate.outputKind === "assistant" || candidate.outputKind === "reasoning" ? candidate.outputKind : void 0;
|
|
52671
|
+
return {
|
|
52672
|
+
original: candidate.original,
|
|
52673
|
+
translated: candidate.translated,
|
|
52674
|
+
...candidate.sourceLanguage === "zh" || candidate.sourceLanguage === "en" || candidate.sourceLanguage === "fr" || candidate.sourceLanguage === "de" || candidate.sourceLanguage === "ja" ? { sourceLanguage: candidate.sourceLanguage } : {},
|
|
52675
|
+
targetLanguage,
|
|
52676
|
+
bilingual: candidate.bilingual === true,
|
|
52677
|
+
...outputKind === void 0 ? {} : { outputKind },
|
|
52678
|
+
...candidate.alreadyTargetLanguage === true ? { alreadyTargetLanguage: true } : {},
|
|
52679
|
+
...model === void 0 ? {} : { model },
|
|
52680
|
+
...candidate.failed === true ? { failed: true } : {}
|
|
52681
|
+
};
|
|
52682
|
+
}
|
|
52683
|
+
function readModel(value) {
|
|
52684
|
+
const record = asRecord(value);
|
|
52685
|
+
if (typeof record?.provider !== "string" || typeof record.model !== "string" || record.provider.trim() === "" || record.model.trim() === "") return void 0;
|
|
52686
|
+
return {
|
|
52687
|
+
provider: record.provider,
|
|
52688
|
+
model: record.model
|
|
52689
|
+
};
|
|
52690
|
+
}
|
|
52691
|
+
function readInputRecord(value) {
|
|
52692
|
+
const candidate = asRecord(asRecord(asRecord(value)?.source)?.codingnsTranslationInput);
|
|
52693
|
+
if (candidate?.original === void 0 || candidate.translated === void 0) return void 0;
|
|
52694
|
+
if (typeof candidate.original !== "string" || typeof candidate.translated !== "string") return void 0;
|
|
52695
|
+
const targetLanguage = candidate.targetLanguage;
|
|
52696
|
+
if (targetLanguage !== "en" && targetLanguage !== "fr" && targetLanguage !== "de" && targetLanguage !== "ja") return void 0;
|
|
52697
|
+
const model = readModel(candidate.model);
|
|
52698
|
+
return {
|
|
52699
|
+
original: candidate.original,
|
|
52700
|
+
translated: candidate.translated,
|
|
52701
|
+
...candidate.sourceLanguage === "zh" || candidate.sourceLanguage === "en" || candidate.sourceLanguage === "fr" || candidate.sourceLanguage === "de" || candidate.sourceLanguage === "ja" ? { sourceLanguage: candidate.sourceLanguage } : {},
|
|
52702
|
+
targetLanguage,
|
|
52703
|
+
...candidate.alreadyTargetLanguage === true ? { alreadyTargetLanguage: true } : {},
|
|
52704
|
+
...model === void 0 ? {} : { model },
|
|
52705
|
+
...candidate.failed === true ? { failed: true } : {}
|
|
52706
|
+
};
|
|
52707
|
+
}
|
|
52708
|
+
function inputRecordForAction(record) {
|
|
52709
|
+
return {
|
|
52710
|
+
original: record.original,
|
|
52711
|
+
translated: record.translated,
|
|
52712
|
+
...record.sourceLanguage === void 0 ? {} : { sourceLanguage: record.sourceLanguage },
|
|
52713
|
+
targetLanguage: record.targetLanguage,
|
|
52714
|
+
bilingual: false,
|
|
52715
|
+
...record.alreadyTargetLanguage === true ? { alreadyTargetLanguage: true } : {},
|
|
52716
|
+
...record.model === void 0 ? {} : { model: record.model },
|
|
52717
|
+
...record.failed === true ? { failed: true } : {}
|
|
52718
|
+
};
|
|
52719
|
+
}
|
|
52720
|
+
function readLanguage(value) {
|
|
52721
|
+
return value === "zh" || value === "en" || value === "fr" || value === "de" || value === "ja" ? value : void 0;
|
|
52722
|
+
}
|
|
52723
|
+
function formatModel(model, t) {
|
|
52724
|
+
return model === void 0 ? t("translation.modelUnknown") : `${model.provider} / ${model.model}`;
|
|
52725
|
+
}
|
|
52726
|
+
function safeDomId(value) {
|
|
52727
|
+
return encodeURIComponent(value).replace(/%/gu, "-");
|
|
52728
|
+
}
|
|
52729
|
+
function asRecord(value) {
|
|
52730
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
|
|
52731
|
+
}
|
|
52732
|
+
//#endregion
|
|
52733
|
+
//#region src/client/features/session-translation.ts
|
|
52734
|
+
const languageLabelKeys = {
|
|
52735
|
+
zh: "translation.language.zh",
|
|
52736
|
+
en: "translation.language.en",
|
|
52737
|
+
fr: "translation.language.fr",
|
|
52738
|
+
de: "translation.language.de",
|
|
52739
|
+
ja: "translation.language.ja"
|
|
52740
|
+
};
|
|
52741
|
+
const sessionTranslationFeature = {
|
|
52742
|
+
descriptor: {
|
|
52743
|
+
name: "sessionTranslation",
|
|
52744
|
+
version: "0.1.0",
|
|
52745
|
+
enabledByDefault: false,
|
|
52746
|
+
dependencies: ["cliAdapters"],
|
|
52747
|
+
runtime: "client",
|
|
52748
|
+
ui: {
|
|
52749
|
+
label: "Session translation",
|
|
52750
|
+
description: "Translate selected external Agent requests and replies without changing tools, commands, paths, or original history.",
|
|
52751
|
+
labelKey: "feature.sessionTranslation.label",
|
|
52752
|
+
descriptionKey: "feature.sessionTranslation.description",
|
|
52753
|
+
order: 32,
|
|
52754
|
+
defaultOpen: true
|
|
52755
|
+
}
|
|
52756
|
+
},
|
|
52757
|
+
start: (context) => {
|
|
52758
|
+
return registerSessionTranslationChatUi(context.services);
|
|
52759
|
+
},
|
|
52760
|
+
settingsPanel: SessionTranslationPanel
|
|
52761
|
+
};
|
|
52762
|
+
function SessionTranslationPanel({ services, enabled, snapshot, notify }) {
|
|
52763
|
+
const t = require_transport.useCodingNsTranslator(services.locale);
|
|
52764
|
+
const value = snapshot.value?.sessionTranslation ?? require_native_workspace_store.DEFAULT_CODINGNS_SETTINGS.sessionTranslation ?? require_session_translation.DEFAULT_SESSION_TRANSLATION_SETTINGS;
|
|
52765
|
+
const disabled = !enabled || snapshot.status === "loading" || !snapshot.writable;
|
|
52766
|
+
const [catalog, setCatalog] = (0, react.useState)(null);
|
|
52767
|
+
(0, react.useEffect)(() => {
|
|
52768
|
+
let active = true;
|
|
52769
|
+
require_model_catalog_cache.callCliRpc(services.rpc, "translation/models", {}, AbortSignal.timeout(1e4)).then((value) => {
|
|
52770
|
+
if (active) setCatalog(value);
|
|
52771
|
+
}).catch(() => void 0);
|
|
52772
|
+
return () => {
|
|
52773
|
+
active = false;
|
|
52774
|
+
};
|
|
52775
|
+
}, [services.rpc]);
|
|
52776
|
+
const save = (patch) => {
|
|
52777
|
+
const next = Object.fromEntries(Object.entries({
|
|
52778
|
+
...value,
|
|
52779
|
+
...patch
|
|
52780
|
+
}).filter(([, item]) => item !== void 0));
|
|
52781
|
+
services.settings.set(require_native_workspace_store.CODINGNS_SESSION_TRANSLATION_FIELD, next).then((written) => {
|
|
52782
|
+
if (!written) throw new Error(t("translation.saveRejected"));
|
|
52783
|
+
notify({
|
|
52784
|
+
kind: "success",
|
|
52785
|
+
message: t("translation.saved")
|
|
52786
|
+
});
|
|
52787
|
+
}).catch((error) => notify({
|
|
52788
|
+
kind: "error",
|
|
52789
|
+
message: error instanceof Error ? error.message : String(error)
|
|
52790
|
+
}));
|
|
52791
|
+
};
|
|
52792
|
+
return (0, react.createElement)("div", {
|
|
52793
|
+
"aria-disabled": disabled,
|
|
52794
|
+
style: {
|
|
52795
|
+
...require_theme.dshFormRootStyle,
|
|
52796
|
+
display: "flex",
|
|
52797
|
+
flexDirection: "column",
|
|
52798
|
+
gap: 0,
|
|
52799
|
+
opacity: disabled ? .55 : 1,
|
|
52800
|
+
pointerEvents: disabled ? "none" : "auto"
|
|
52801
|
+
}
|
|
52802
|
+
}, (0, react.createElement)("div", { style: {
|
|
52803
|
+
...require_theme.dshSettingsSectionHeaderStyle,
|
|
52804
|
+
marginTop: 0
|
|
52805
|
+
} }, (0, react.createElement)("span", { style: require_theme.dshSettingsFieldLabelStyle }, t("translation.inputTitle"))), (0, react.createElement)(Field, { label: t("translation.inputLanguage") }, (0, react.createElement)("select", {
|
|
52806
|
+
value: value.inputLanguage,
|
|
52807
|
+
disabled,
|
|
52808
|
+
style: require_theme.dshSettingsFieldStyle,
|
|
52809
|
+
onChange: (event) => save({ inputLanguage: readInputLanguage(event.currentTarget.value) })
|
|
52810
|
+
}, ...[
|
|
52811
|
+
"en",
|
|
52812
|
+
"fr",
|
|
52813
|
+
"de",
|
|
52814
|
+
"ja"
|
|
52815
|
+
].map((language) => (0, react.createElement)("option", {
|
|
52816
|
+
key: language,
|
|
52817
|
+
value: language
|
|
52818
|
+
}, t(languageLabelKeys[language]))))), (0, react.createElement)("div", { style: {
|
|
52819
|
+
...require_theme.dshSettingsSectionHeaderStyle,
|
|
52820
|
+
marginTop: 12
|
|
52821
|
+
} }, (0, react.createElement)("span", { style: require_theme.dshSettingsFieldLabelStyle }, t("translation.outputTitle"))), (0, react.createElement)(Field, { label: t("translation.outputLanguage") }, (0, react.createElement)("select", {
|
|
52822
|
+
value: value.outputLanguage,
|
|
52823
|
+
disabled,
|
|
52824
|
+
style: require_theme.dshSettingsFieldStyle,
|
|
52825
|
+
onChange: (event) => save({ outputLanguage: readOutputLanguage(event.currentTarget.value) })
|
|
52826
|
+
}, ...[
|
|
52827
|
+
"zh",
|
|
52828
|
+
"en",
|
|
52829
|
+
"fr",
|
|
52830
|
+
"de",
|
|
52831
|
+
"ja"
|
|
52832
|
+
].map((language) => (0, react.createElement)("option", {
|
|
52833
|
+
key: language,
|
|
52834
|
+
value: language
|
|
52835
|
+
}, t(languageLabelKeys[language]))))), (0, react.createElement)("div", { style: {
|
|
52836
|
+
...require_theme.dshSettingsSectionHeaderStyle,
|
|
52837
|
+
marginTop: 12
|
|
52838
|
+
} }, (0, react.createElement)("span", { style: require_theme.dshSettingsFieldLabelStyle }, t("translation.modelTitle"))), (0, react.createElement)(ModelField, {
|
|
52839
|
+
value,
|
|
52840
|
+
catalog,
|
|
52841
|
+
disabled,
|
|
52842
|
+
t,
|
|
52843
|
+
onChange: (model) => save({ translationModel: model })
|
|
52844
|
+
}));
|
|
52845
|
+
}
|
|
52846
|
+
function Field({ label, children }) {
|
|
52847
|
+
return (0, react.createElement)("label", { style: {
|
|
52848
|
+
...require_theme.dshSettingsListRowStyle,
|
|
52849
|
+
alignItems: "flex-start",
|
|
52850
|
+
flexDirection: "column",
|
|
52851
|
+
gap: 6
|
|
52852
|
+
} }, (0, react.createElement)("span", { style: require_theme.dshSettingsFieldLabelStyle }, label), children ?? null);
|
|
52853
|
+
}
|
|
52854
|
+
function ModelField({ value, catalog, disabled, t, onChange }) {
|
|
52855
|
+
const selectedKey = value.translationModel === void 0 ? "" : JSON.stringify([value.translationModel.provider, value.translationModel.model]);
|
|
52856
|
+
const models = catalog?.models ?? [];
|
|
52857
|
+
const hasSelected = selectedKey !== "" && models.some((model) => JSON.stringify([model.provider, model.model]) === selectedKey);
|
|
52858
|
+
return (0, react.createElement)("div", { style: {
|
|
52859
|
+
width: "100%",
|
|
52860
|
+
display: "grid",
|
|
52861
|
+
gap: 6
|
|
52862
|
+
} }, (0, react.createElement)("select", {
|
|
52863
|
+
value: selectedKey,
|
|
52864
|
+
disabled,
|
|
52865
|
+
style: require_theme.dshSettingsFieldStyle,
|
|
52866
|
+
onChange: (event) => onChange(readTranslationModel(event.currentTarget.value))
|
|
52867
|
+
}, (0, react.createElement)("option", { value: "" }, t("translation.modelFollowDefault")), !hasSelected && selectedKey !== "" && (0, react.createElement)("option", { value: selectedKey }, t("translation.modelUnavailable")), ...models.map((model) => (0, react.createElement)("option", {
|
|
52868
|
+
key: JSON.stringify([model.provider, model.model]),
|
|
52869
|
+
value: JSON.stringify([model.provider, model.model])
|
|
52870
|
+
}, `${isOfficialProvider(model.provider) ? t("translation.modelOfficial") : t("translation.modelThirdParty")} · ${model.label}`))), catalog === null ? (0, react.createElement)("span", { style: require_theme.dshSettingsHelpStyle }, t("translation.modelLoading")) : models.length === 0 ? (0, react.createElement)("span", { style: require_theme.dshSettingsHelpStyle }, t("translation.modelEmpty")) : (0, react.createElement)("span", { style: require_theme.dshSettingsHelpStyle }, t("translation.modelHelp")));
|
|
52871
|
+
}
|
|
52872
|
+
function readTranslationModel(value) {
|
|
52873
|
+
if (value === "") return void 0;
|
|
52874
|
+
try {
|
|
52875
|
+
const parsed = JSON.parse(value);
|
|
52876
|
+
if (!Array.isArray(parsed) || typeof parsed[0] !== "string" || typeof parsed[1] !== "string" || parsed[0].trim() === "" || parsed[1].trim() === "") return void 0;
|
|
52877
|
+
return {
|
|
52878
|
+
provider: parsed[0],
|
|
52879
|
+
model: parsed[1]
|
|
52880
|
+
};
|
|
52881
|
+
} catch {
|
|
52882
|
+
return;
|
|
52883
|
+
}
|
|
52884
|
+
}
|
|
52885
|
+
function isOfficialProvider(provider) {
|
|
52886
|
+
return /^(?:deepseek(?:-official)?|official-deepseek)$/iu.test(provider.trim());
|
|
52887
|
+
}
|
|
52888
|
+
function readInputLanguage(value) {
|
|
52889
|
+
return value === "fr" || value === "de" || value === "ja" ? value : "en";
|
|
52890
|
+
}
|
|
52891
|
+
function readOutputLanguage(value) {
|
|
52892
|
+
return value === "en" || value === "fr" || value === "de" || value === "ja" ? value : "zh";
|
|
52893
|
+
}
|
|
52894
|
+
//#endregion
|
|
50953
52895
|
//#region src/features/host-router.ts
|
|
50954
52896
|
/** 统一管理当前 Host/PeerHost 的完整作用域和 generation。 */
|
|
50955
52897
|
var HostRouter = class {
|
|
@@ -51179,7 +53121,8 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
51179
53121
|
fileManagementFeature,
|
|
51180
53122
|
peerHostFeature,
|
|
51181
53123
|
globalVoiceAssistantFeature,
|
|
51182
|
-
subagentCollapsedLineageFeature
|
|
53124
|
+
subagentCollapsedLineageFeature,
|
|
53125
|
+
sessionTranslationFeature
|
|
51183
53126
|
];
|
|
51184
53127
|
/**
|
|
51185
53128
|
* 汇总需要在设置页显示的模块,按 ui.order 升序。
|
|
@@ -58317,6 +60260,118 @@ ${scope} [data-dockkit-strip-tabs] {
|
|
|
58317
60260
|
};
|
|
58318
60261
|
}
|
|
58319
60262
|
//#endregion
|
|
60263
|
+
//#region node_modules/.pnpm/@deepseek-ai+dsh-util-workspace-path@0.2.1-alpha.2_@deepseek-ai+cordis@4.0.4/node_modules/@deepseek-ai/dsh-util-workspace-path/lib/index.js
|
|
60264
|
+
/**
|
|
60265
|
+
* The `dsh-resource://file/…` address grammar: how a file is named across the
|
|
60266
|
+
* Sidebar and the resource model, built and parsed without touching a
|
|
60267
|
+
* filesystem.
|
|
60268
|
+
* @module
|
|
60269
|
+
*/
|
|
60270
|
+
/** The scheme and type every file address opens with. */
|
|
60271
|
+
const FILE_ADDRESS_PREFIX = "dsh-resource://file/";
|
|
60272
|
+
/** Component-encode one id or path segment, keeping `:` literal for drive letters. */
|
|
60273
|
+
function encodeSegment(segment) {
|
|
60274
|
+
return encodeURIComponent(segment).replace(/%3A/gi, ":");
|
|
60275
|
+
}
|
|
60276
|
+
/** Encode a `/`-separated path segment by segment. */
|
|
60277
|
+
function encodePath(path) {
|
|
60278
|
+
return path.split("/").map(encodeSegment).join("/");
|
|
60279
|
+
}
|
|
60280
|
+
/** Whether a decoded first path segment is a Windows drive (`C:`). */
|
|
60281
|
+
function isDriveSegment(segment) {
|
|
60282
|
+
return segment !== void 0 && /^[A-Za-z]:$/.test(segment);
|
|
60283
|
+
}
|
|
60284
|
+
/**
|
|
60285
|
+
* Build the address of a file read through one Session.
|
|
60286
|
+
* @param sessionId - the Session whose Host workspace resolves the path.
|
|
60287
|
+
* @param path - absolute or workspace-relative path; backslashes are normalized to `/`, and leading `./` prefixes are dropped.
|
|
60288
|
+
* @returns the `dsh-resource://file/session/<sessionId>/<path>` address.
|
|
60289
|
+
*/
|
|
60290
|
+
function sessionFileAddress(sessionId, path) {
|
|
60291
|
+
const normalized = path.replace(/\\/g, "/").replace(/^(?:\.\/)+/, "");
|
|
60292
|
+
return `${FILE_ADDRESS_PREFIX}session/${encodeSegment(sessionId)}/${encodePath(normalized)}`;
|
|
60293
|
+
}
|
|
60294
|
+
/**
|
|
60295
|
+
* Read a file address back into its parts without resolving `.` or `..`.
|
|
60296
|
+
* Query and fragment suffixes are ignored; encoded path segments are decoded.
|
|
60297
|
+
* @param address - a candidate address.
|
|
60298
|
+
* @returns the parts, or `undefined` when the string is not a `dsh-resource://file/` URI in a known scope with a path, or a segment is not validly encoded.
|
|
60299
|
+
*/
|
|
60300
|
+
function parseFileAddress(address) {
|
|
60301
|
+
try {
|
|
60302
|
+
if (!address.startsWith(FILE_ADDRESS_PREFIX)) return void 0;
|
|
60303
|
+
const end = address.search(/[?#]/);
|
|
60304
|
+
const [scope, ...rest] = address.slice(20, end === -1 ? void 0 : end).split("/");
|
|
60305
|
+
if (scope === "session") {
|
|
60306
|
+
const [id, ...segments] = rest;
|
|
60307
|
+
if (id === void 0 || id === "" || segments.length === 0) return void 0;
|
|
60308
|
+
return {
|
|
60309
|
+
scope,
|
|
60310
|
+
sessionId: decodeURIComponent(id),
|
|
60311
|
+
path: segments.map(decodeURIComponent).join("/")
|
|
60312
|
+
};
|
|
60313
|
+
}
|
|
60314
|
+
if (scope === "absolute") {
|
|
60315
|
+
const unc = rest[0] === "" && rest.length > 1;
|
|
60316
|
+
const segments = (unc ? rest.slice(1) : rest).map(decodeURIComponent);
|
|
60317
|
+
if (segments.length === 0 || segments[0] === "") return void 0;
|
|
60318
|
+
if (unc) return {
|
|
60319
|
+
scope,
|
|
60320
|
+
path: `//${segments.join("/")}`
|
|
60321
|
+
};
|
|
60322
|
+
return {
|
|
60323
|
+
scope,
|
|
60324
|
+
path: isDriveSegment(segments[0]) ? segments.join("/") : `/${segments.join("/")}`
|
|
60325
|
+
};
|
|
60326
|
+
}
|
|
60327
|
+
return;
|
|
60328
|
+
} catch {
|
|
60329
|
+
return;
|
|
60330
|
+
}
|
|
60331
|
+
}
|
|
60332
|
+
//#endregion
|
|
60333
|
+
//#region src/client/session-file-links.ts
|
|
60334
|
+
/**
|
|
60335
|
+
* 在原生资源入口规范本地及远端链接,保留资源里的会话身份和导航参数。
|
|
60336
|
+
* 右栏文件树、消息与预览内链接共用这个入口;不扫描消息正文或当前选择。
|
|
60337
|
+
*/
|
|
60338
|
+
function installSessionFileLinkRouting(uiContext, workspacePathForSession) {
|
|
60339
|
+
const sidebar = uiContext.get("sidebarRight");
|
|
60340
|
+
if (typeof sidebar?.openResource !== "function") return void 0;
|
|
60341
|
+
const originalOpen = sidebar.openResource;
|
|
60342
|
+
const originalOpenIn = sidebar.openResourceIn;
|
|
60343
|
+
const resolve = (address, options) => {
|
|
60344
|
+
const file = parseFileAddress(address);
|
|
60345
|
+
if (file?.scope !== "session") return [address, options];
|
|
60346
|
+
const location = normalizePeerHostFileLocation(file.path, workspacePathForSession(file.sessionId));
|
|
60347
|
+
if (location.path === file.path) return [address, options];
|
|
60348
|
+
const suffix = address.search(/[?#]/u);
|
|
60349
|
+
return [sessionFileAddress(file.sessionId, location.path) + (suffix < 0 ? "" : address.slice(suffix)), location.line === void 0 ? options : {
|
|
60350
|
+
...options,
|
|
60351
|
+
params: {
|
|
60352
|
+
line: location.line,
|
|
60353
|
+
...options?.params
|
|
60354
|
+
}
|
|
60355
|
+
}];
|
|
60356
|
+
};
|
|
60357
|
+
const open = (address, options) => originalOpen.call(sidebar, ...resolve(address, options));
|
|
60358
|
+
const openIn = originalOpenIn === void 0 ? void 0 : (sessionId, address, options) => originalOpenIn.call(sidebar, sessionId, ...resolve(address, options));
|
|
60359
|
+
sidebar.openResource = open;
|
|
60360
|
+
if (openIn !== void 0) sidebar.openResourceIn = openIn;
|
|
60361
|
+
return () => {
|
|
60362
|
+
if (sidebar.openResource === open) sidebar.openResource = originalOpen;
|
|
60363
|
+
if (openIn !== void 0 && sidebar.openResourceIn === openIn) sidebar.openResourceIn = originalOpenIn;
|
|
60364
|
+
};
|
|
60365
|
+
}
|
|
60366
|
+
/** 独立于 PeerHost 开关,按资源所属会话的最新目录识别路径平台。 */
|
|
60367
|
+
function installNativeSessionFileLinkRouting(uiContext) {
|
|
60368
|
+
const sessions = require_native_workspace_store.readNativeService(uiContext, "sessions", "list");
|
|
60369
|
+
return installSessionFileLinkRouting(uiContext, (sessionId) => {
|
|
60370
|
+
const workspace = require_native_workspace_store.readNativeWorkspaceSnapshot(uiContext)?.items.find((item) => item.sessionIds.includes(sessionId));
|
|
60371
|
+
return workspace?.workspacePath ?? sessions?.getSnapshot().byId?.[sessionId]?.cwd ?? workspace?.path;
|
|
60372
|
+
});
|
|
60373
|
+
}
|
|
60374
|
+
//#endregion
|
|
58320
60375
|
//#region node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/core/util.js
|
|
58321
60376
|
function getEnumValues(entries) {
|
|
58322
60377
|
const numericValues = Object.values(entries).filter((v) => typeof v === "number");
|
|
@@ -63938,6 +65993,13 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
63938
65993
|
require_model_catalog_cache.debugInfo("codingns4dsh: client apply entered", { dshVersion });
|
|
63939
65994
|
ensureCryptoRandomUUID();
|
|
63940
65995
|
ctx.effect(() => require_transport.registerCodingNsLocale(ctx), "codingns4dsh: client dictionaries");
|
|
65996
|
+
ctx.inject([
|
|
65997
|
+
"sidebarRight",
|
|
65998
|
+
"sessions",
|
|
65999
|
+
"workspaces"
|
|
66000
|
+
], (scope) => {
|
|
66001
|
+
scope.effect(() => installNativeSessionFileLinkRouting(scope) ?? (() => void 0), "codingns4dsh: session file links");
|
|
66002
|
+
});
|
|
63941
66003
|
ctx.inject([
|
|
63942
66004
|
"slots",
|
|
63943
66005
|
"connection",
|
|
@@ -64194,5 +66256,5 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
64194
66256
|
});
|
|
64195
66257
|
|
|
64196
66258
|
})();
|
|
64197
|
-
// codingns-client-revision:
|
|
66259
|
+
// codingns-client-revision: 357fbcae0ed92ae51010b9952fb1be86dedea3232628e2c830758032a3e1c1ee
|
|
64198
66260
|
//# sourceMappingURL=bundle.js.map
|