@jingyi0605/codingns4dsh 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1114 -0
- package/assets/provider-icons/claude-code.png +0 -0
- package/assets/provider-icons/codex.png +0 -0
- package/assets/provider-icons/command-code.svg +5 -0
- package/assets/provider-icons/deepseek-harness.svg +9 -0
- package/assets/provider-icons/gemini.png +0 -0
- package/assets/provider-icons/grok.png +0 -0
- package/assets/provider-icons/kimi.png +0 -0
- package/assets/provider-icons/opencode.png +0 -0
- package/assets/provider-icons/pi.svg +7 -0
- package/data/build/dist/bootstrap/dsh-connection-adapter.d.ts +97 -0
- package/data/build/dist/bootstrap/dsh-connection-adapter.js +169 -0
- package/data/build/dist/bootstrap/index.d.ts +38 -0
- package/data/build/dist/bootstrap/index.js +44 -0
- package/data/build/dist/client/account-bar.d.ts +9 -0
- package/data/build/dist/client/account-bar.js +398 -0
- package/data/build/dist/client/bundle.js +26167 -0
- package/data/build/dist/client/cli-catalog.d.ts +24 -0
- package/data/build/dist/client/cli-catalog.js +108 -0
- package/data/build/dist/client/cli-slots.d.ts +38 -0
- package/data/build/dist/client/cli-slots.js +297 -0
- package/data/build/dist/client/debug/ui.d.ts +12 -0
- package/data/build/dist/client/debug/ui.js +451 -0
- package/data/build/dist/client/dsh-h5-bootstrap.d.ts +64 -0
- package/data/build/dist/client/dsh-h5-bootstrap.js +293 -0
- package/data/build/dist/client/dsh-runtime-version.d.ts +3 -0
- package/data/build/dist/client/dsh-runtime-version.js +11 -0
- package/data/build/dist/client/external-tool-stream.d.ts +24 -0
- package/data/build/dist/client/external-tool-stream.js +114 -0
- package/data/build/dist/client/features/cli-adapters.d.ts +7 -0
- package/data/build/dist/client/features/cli-adapters.js +215 -0
- package/data/build/dist/client/features/debug.d.ts +4 -0
- package/data/build/dist/client/features/debug.js +24 -0
- package/data/build/dist/client/features/index.d.ts +33 -0
- package/data/build/dist/client/features/index.js +44 -0
- package/data/build/dist/client/features/lan-access-panel.d.ts +5 -0
- package/data/build/dist/client/features/lan-access-panel.js +146 -0
- package/data/build/dist/client/features/lan-access.d.ts +9 -0
- package/data/build/dist/client/features/lan-access.js +30 -0
- package/data/build/dist/client/features/login-protection-panel.d.ts +5 -0
- package/data/build/dist/client/features/login-protection-panel.js +91 -0
- package/data/build/dist/client/features/login-protection-session.d.ts +6 -0
- package/data/build/dist/client/features/login-protection-session.js +25 -0
- package/data/build/dist/client/features/login-protection.d.ts +4 -0
- package/data/build/dist/client/features/login-protection.js +23 -0
- package/data/build/dist/client/features/reverse-proxy-panel.d.ts +9 -0
- package/data/build/dist/client/features/reverse-proxy-panel.js +159 -0
- package/data/build/dist/client/features/reverse-proxy.d.ts +12 -0
- package/data/build/dist/client/features/reverse-proxy.js +112 -0
- package/data/build/dist/client/features/terminal-enhancement-panel.d.ts +5 -0
- package/data/build/dist/client/features/terminal-enhancement-panel.js +160 -0
- package/data/build/dist/client/features/terminal-enhancement.d.ts +4 -0
- package/data/build/dist/client/features/terminal-enhancement.js +24 -0
- package/data/build/dist/client/features/types.d.ts +58 -0
- package/data/build/dist/client/features/types.js +2 -0
- package/data/build/dist/client/features/workspace-session-enhancement-panel.d.ts +5 -0
- package/data/build/dist/client/features/workspace-session-enhancement-panel.js +66 -0
- package/data/build/dist/client/features/workspace-session-enhancement.d.ts +4 -0
- package/data/build/dist/client/features/workspace-session-enhancement.js +101 -0
- package/data/build/dist/client/h5-bootstrap-entry.d.ts +2 -0
- package/data/build/dist/client/h5-bootstrap-entry.js +17 -0
- package/data/build/dist/client/index.d.ts +31 -0
- package/data/build/dist/client/index.js +98 -0
- package/data/build/dist/client/lan-access.d.ts +28 -0
- package/data/build/dist/client/lan-access.js +68 -0
- package/data/build/dist/client/locale.d.ts +20 -0
- package/data/build/dist/client/locale.js +393 -0
- package/data/build/dist/client/provider-icon-assets.d.ts +2 -0
- package/data/build/dist/client/provider-icon-assets.js +23 -0
- package/data/build/dist/client/provider-icons.d.ts +19 -0
- package/data/build/dist/client/provider-icons.js +39 -0
- package/data/build/dist/client/remote-web-context.d.ts +57 -0
- package/data/build/dist/client/remote-web-context.js +939 -0
- package/data/build/dist/client/session-adapter-cache.d.ts +18 -0
- package/data/build/dist/client/session-adapter-cache.js +84 -0
- package/data/build/dist/client/settings-bridge.d.ts +32 -0
- package/data/build/dist/client/settings-bridge.js +126 -0
- package/data/build/dist/client/settings-section.d.ts +30 -0
- package/data/build/dist/client/settings-section.js +93 -0
- package/data/build/dist/client/subscription-slot.d.ts +18 -0
- package/data/build/dist/client/subscription-slot.js +223 -0
- package/data/build/dist/client/terminal/index.d.ts +4 -0
- package/data/build/dist/client/terminal/index.js +3 -0
- package/data/build/dist/client/terminal/model.d.ts +116 -0
- package/data/build/dist/client/terminal/model.js +435 -0
- package/data/build/dist/client/terminal/styles.d.ts +21 -0
- package/data/build/dist/client/terminal/styles.js +51 -0
- package/data/build/dist/client/terminal/ui.d.ts +19 -0
- package/data/build/dist/client/terminal/ui.js +257 -0
- package/data/build/dist/client/terminal/xterm-view.d.ts +13 -0
- package/data/build/dist/client/terminal/xterm-view.js +213 -0
- package/data/build/dist/client/theme.d.ts +56 -0
- package/data/build/dist/client/theme.js +186 -0
- package/data/build/dist/client/workspace-session-archive-dom.d.ts +29 -0
- package/data/build/dist/client/workspace-session-archive-dom.js +525 -0
- package/data/build/dist/client/workspace-session-fiber.d.ts +3 -0
- package/data/build/dist/client/workspace-session-fiber.js +33 -0
- package/data/build/dist/client/workspace-session-logo-dom.d.ts +26 -0
- package/data/build/dist/client/workspace-session-logo-dom.js +128 -0
- package/data/build/dist/features/index.d.ts +3 -0
- package/data/build/dist/features/index.js +2 -0
- package/data/build/dist/features/registry.d.ts +74 -0
- package/data/build/dist/features/registry.js +382 -0
- package/data/build/dist/features/resource-scope/index.d.ts +39 -0
- package/data/build/dist/features/resource-scope/index.js +161 -0
- package/data/build/dist/host/auth-session.d.ts +42 -0
- package/data/build/dist/host/auth-session.js +186 -0
- package/data/build/dist/host/cli-adapters/claude-driver.d.ts +14 -0
- package/data/build/dist/host/cli-adapters/claude-driver.js +103 -0
- package/data/build/dist/host/cli-adapters/codex-driver.d.ts +45 -0
- package/data/build/dist/host/cli-adapters/codex-driver.js +534 -0
- package/data/build/dist/host/cli-adapters/command-code-driver.d.ts +38 -0
- package/data/build/dist/host/cli-adapters/command-code-driver.js +394 -0
- package/data/build/dist/host/cli-adapters/command-code-subscription.d.ts +19 -0
- package/data/build/dist/host/cli-adapters/command-code-subscription.js +126 -0
- package/data/build/dist/host/cli-adapters/driver.d.ts +41 -0
- package/data/build/dist/host/cli-adapters/driver.js +2 -0
- package/data/build/dist/host/cli-adapters/dsh-message-projector.d.ts +37 -0
- package/data/build/dist/host/cli-adapters/dsh-message-projector.js +180 -0
- package/data/build/dist/host/cli-adapters/dsh-tool-history.d.ts +48 -0
- package/data/build/dist/host/cli-adapters/dsh-tool-history.js +373 -0
- package/data/build/dist/host/cli-adapters/feature.d.ts +7 -0
- package/data/build/dist/host/cli-adapters/feature.js +335 -0
- package/data/build/dist/host/cli-adapters/gemini-driver.d.ts +24 -0
- package/data/build/dist/host/cli-adapters/gemini-driver.js +427 -0
- package/data/build/dist/host/cli-adapters/grok-driver.d.ts +38 -0
- package/data/build/dist/host/cli-adapters/grok-driver.js +372 -0
- package/data/build/dist/host/cli-adapters/http-sse-client.d.ts +22 -0
- package/data/build/dist/host/cli-adapters/http-sse-client.js +99 -0
- package/data/build/dist/host/cli-adapters/interaction-events.d.ts +11 -0
- package/data/build/dist/host/cli-adapters/interaction-events.js +80 -0
- package/data/build/dist/host/cli-adapters/json-rpc-process.d.ts +65 -0
- package/data/build/dist/host/cli-adapters/json-rpc-process.js +256 -0
- package/data/build/dist/host/cli-adapters/kimi-driver.d.ts +21 -0
- package/data/build/dist/host/cli-adapters/kimi-driver.js +382 -0
- package/data/build/dist/host/cli-adapters/model-catalog.d.ts +22 -0
- package/data/build/dist/host/cli-adapters/model-catalog.js +89 -0
- package/data/build/dist/host/cli-adapters/opencode-driver.d.ts +55 -0
- package/data/build/dist/host/cli-adapters/opencode-driver.js +728 -0
- package/data/build/dist/host/cli-adapters/pi-driver.d.ts +43 -0
- package/data/build/dist/host/cli-adapters/pi-driver.js +312 -0
- package/data/build/dist/host/cli-adapters/process-utils.d.ts +16 -0
- package/data/build/dist/host/cli-adapters/process-utils.js +27 -0
- package/data/build/dist/host/cli-adapters/provider-subscription.d.ts +82 -0
- package/data/build/dist/host/cli-adapters/provider-subscription.js +610 -0
- package/data/build/dist/host/cli-adapters/registry.d.ts +95 -0
- package/data/build/dist/host/cli-adapters/registry.js +659 -0
- package/data/build/dist/host/cli-adapters/rpc-driver-utils.d.ts +24 -0
- package/data/build/dist/host/cli-adapters/rpc-driver-utils.js +119 -0
- package/data/build/dist/host/cli-adapters/session-probe.d.ts +20 -0
- package/data/build/dist/host/cli-adapters/session-probe.js +139 -0
- package/data/build/dist/host/cli-adapters/session-store.d.ts +68 -0
- package/data/build/dist/host/cli-adapters/session-store.js +180 -0
- package/data/build/dist/host/cli-adapters/standard-stream-driver.d.ts +45 -0
- package/data/build/dist/host/cli-adapters/standard-stream-driver.js +205 -0
- package/data/build/dist/host/cli-adapters/stream-normalizer.d.ts +25 -0
- package/data/build/dist/host/cli-adapters/stream-normalizer.js +83 -0
- package/data/build/dist/host/cli-adapters/tool-observation.d.ts +9 -0
- package/data/build/dist/host/cli-adapters/tool-observation.js +39 -0
- package/data/build/dist/host/control-api-client.d.ts +84 -0
- package/data/build/dist/host/control-api-client.js +130 -0
- package/data/build/dist/host/credential-store.d.ts +54 -0
- package/data/build/dist/host/credential-store.js +114 -0
- package/data/build/dist/host/debug.d.ts +79 -0
- package/data/build/dist/host/debug.js +295 -0
- package/data/build/dist/host/dsh-device-runtime.d.ts +39 -0
- package/data/build/dist/host/dsh-device-runtime.js +118 -0
- package/data/build/dist/host/dsh-gateway-feature.d.ts +5 -0
- package/data/build/dist/host/dsh-gateway-feature.js +55 -0
- package/data/build/dist/host/dsh-runtime-version.d.ts +12 -0
- package/data/build/dist/host/dsh-runtime-version.js +69 -0
- package/data/build/dist/host/features/auth.d.ts +11 -0
- package/data/build/dist/host/features/auth.js +273 -0
- package/data/build/dist/host/features/debug.d.ts +5 -0
- package/data/build/dist/host/features/debug.js +90 -0
- package/data/build/dist/host/features/host-status.d.ts +12 -0
- package/data/build/dist/host/features/host-status.js +54 -0
- package/data/build/dist/host/features/index.d.ts +19 -0
- package/data/build/dist/host/features/index.js +29 -0
- package/data/build/dist/host/features/lan-access-dsh.d.ts +8 -0
- package/data/build/dist/host/features/lan-access-dsh.js +45 -0
- package/data/build/dist/host/features/terminal-process.d.ts +5 -0
- package/data/build/dist/host/features/terminal-process.js +110 -0
- package/data/build/dist/host/features/terminal-status.d.ts +18 -0
- package/data/build/dist/host/features/terminal-status.js +56 -0
- package/data/build/dist/host/features/types.d.ts +41 -0
- package/data/build/dist/host/features/types.js +2 -0
- package/data/build/dist/host/index.d.ts +43 -0
- package/data/build/dist/host/index.js +135 -0
- package/data/build/dist/host/lan-access-dsh.d.ts +83 -0
- package/data/build/dist/host/lan-access-dsh.js +831 -0
- package/data/build/dist/host/native-session-bridge.d.ts +130 -0
- package/data/build/dist/host/native-session-bridge.js +317 -0
- package/data/build/dist/host/relay-tunnel-runtime.d.ts +97 -0
- package/data/build/dist/host/relay-tunnel-runtime.js +361 -0
- package/data/build/dist/host/remote-web-runtime.d.ts +78 -0
- package/data/build/dist/host/remote-web-runtime.js +559 -0
- package/data/build/dist/host/rpc-table.d.ts +32 -0
- package/data/build/dist/host/rpc-table.js +47 -0
- package/data/build/dist/host/rpc.d.ts +18 -0
- package/data/build/dist/host/rpc.js +248 -0
- package/data/build/dist/host/settings.d.ts +19 -0
- package/data/build/dist/host/settings.js +80 -0
- package/data/build/dist/host/terminal/attachment-registry.d.ts +17 -0
- package/data/build/dist/host/terminal/attachment-registry.js +49 -0
- package/data/build/dist/host/terminal/backends/conpty-backend.d.ts +39 -0
- package/data/build/dist/host/terminal/backends/conpty-backend.js +160 -0
- package/data/build/dist/host/terminal/backends/local-pty-backend.d.ts +36 -0
- package/data/build/dist/host/terminal/backends/local-pty-backend.js +178 -0
- package/data/build/dist/host/terminal/backends/tmux-backend.d.ts +40 -0
- package/data/build/dist/host/terminal/backends/tmux-backend.js +191 -0
- package/data/build/dist/host/terminal/broker/conpty-broker-client.d.ts +27 -0
- package/data/build/dist/host/terminal/broker/conpty-broker-client.js +154 -0
- package/data/build/dist/host/terminal/broker/conpty-broker-process.d.ts +10 -0
- package/data/build/dist/host/terminal/broker/conpty-broker-process.js +147 -0
- package/data/build/dist/host/terminal/broker/conpty-broker-protocol.d.ts +92 -0
- package/data/build/dist/host/terminal/broker/conpty-broker-protocol.js +134 -0
- package/data/build/dist/host/terminal/controller-factory.d.ts +37 -0
- package/data/build/dist/host/terminal/controller-factory.js +82 -0
- package/data/build/dist/host/terminal/index.d.ts +17 -0
- package/data/build/dist/host/terminal/index.js +17 -0
- package/data/build/dist/host/terminal/runtime-adapter.d.ts +77 -0
- package/data/build/dist/host/terminal/runtime-adapter.js +18 -0
- package/data/build/dist/host/terminal/runtime-manager.d.ts +41 -0
- package/data/build/dist/host/terminal/runtime-manager.js +179 -0
- package/data/build/dist/host/terminal/shell-detection.d.ts +23 -0
- package/data/build/dist/host/terminal/shell-detection.js +105 -0
- package/data/build/dist/host/terminal/startup.d.ts +33 -0
- package/data/build/dist/host/terminal/startup.js +100 -0
- package/data/build/dist/host/terminal/terminal-controller.d.ts +78 -0
- package/data/build/dist/host/terminal/terminal-controller.js +324 -0
- package/data/build/dist/host/terminal/terminal-process-service.d.ts +30 -0
- package/data/build/dist/host/terminal/terminal-process-service.js +194 -0
- package/data/build/dist/host/terminal/terminal-process-store.d.ts +45 -0
- package/data/build/dist/host/terminal/terminal-process-store.js +183 -0
- package/data/build/dist/host/terminal/terminal-service.d.ts +87 -0
- package/data/build/dist/host/terminal/terminal-service.js +528 -0
- package/data/build/dist/host/terminal/terminal-store.d.ts +49 -0
- package/data/build/dist/host/terminal/terminal-store.js +242 -0
- package/data/build/dist/index.d.ts +37 -0
- package/data/build/dist/index.js +26 -0
- package/data/build/dist/shared/contracts/auth.d.ts +122 -0
- package/data/build/dist/shared/contracts/auth.js +8 -0
- package/data/build/dist/shared/contracts/cli-adapter.d.ts +192 -0
- package/data/build/dist/shared/contracts/cli-adapter.js +2 -0
- package/data/build/dist/shared/contracts/command-code.d.ts +5 -0
- package/data/build/dist/shared/contracts/command-code.js +2 -0
- package/data/build/dist/shared/contracts/config.d.ts +113 -0
- package/data/build/dist/shared/contracts/config.js +86 -0
- package/data/build/dist/shared/contracts/debug-config.d.ts +28 -0
- package/data/build/dist/shared/contracts/debug-config.js +78 -0
- package/data/build/dist/shared/contracts/debug.d.ts +75 -0
- package/data/build/dist/shared/contracts/debug.js +121 -0
- package/data/build/dist/shared/contracts/dsh-device.d.ts +72 -0
- package/data/build/dist/shared/contracts/dsh-device.js +2 -0
- package/data/build/dist/shared/contracts/errors.d.ts +33 -0
- package/data/build/dist/shared/contracts/errors.js +41 -0
- package/data/build/dist/shared/contracts/feature.d.ts +71 -0
- package/data/build/dist/shared/contracts/feature.js +2 -0
- package/data/build/dist/shared/contracts/host-status.d.ts +14 -0
- package/data/build/dist/shared/contracts/host-status.js +2 -0
- package/data/build/dist/shared/contracts/lan-access-dsh.d.ts +30 -0
- package/data/build/dist/shared/contracts/lan-access-dsh.js +2 -0
- package/data/build/dist/shared/contracts/peer-host.d.ts +37 -0
- package/data/build/dist/shared/contracts/peer-host.js +9 -0
- package/data/build/dist/shared/contracts/signaling.d.ts +67 -0
- package/data/build/dist/shared/contracts/signaling.js +2 -0
- package/data/build/dist/shared/contracts/subscription.d.ts +69 -0
- package/data/build/dist/shared/contracts/subscription.js +2 -0
- package/data/build/dist/shared/contracts/terminal-process.d.ts +65 -0
- package/data/build/dist/shared/contracts/terminal-process.js +2 -0
- package/data/build/dist/shared/contracts/terminal.d.ts +127 -0
- package/data/build/dist/shared/contracts/terminal.js +2 -0
- package/data/build/dist/shared/contracts/transport.d.ts +45 -0
- package/data/build/dist/shared/contracts/transport.js +3 -0
- package/data/build/dist/shared/contracts/version.d.ts +19 -0
- package/data/build/dist/shared/contracts/version.js +74 -0
- package/data/build/dist/shared/index.d.ts +22 -0
- package/data/build/dist/shared/index.js +9 -0
- package/data/build/dist/transport/carrier.d.ts +38 -0
- package/data/build/dist/transport/carrier.js +268 -0
- package/data/build/dist/transport/debug.d.ts +22 -0
- package/data/build/dist/transport/debug.js +57 -0
- package/data/build/dist/transport/dsh-envelope.d.ts +41 -0
- package/data/build/dist/transport/dsh-envelope.js +107 -0
- package/data/build/dist/transport/dsh-gateway.d.ts +64 -0
- package/data/build/dist/transport/dsh-gateway.js +254 -0
- package/data/build/dist/transport/dsh-session.d.ts +55 -0
- package/data/build/dist/transport/dsh-session.js +256 -0
- package/data/build/dist/transport/dsh-transport.d.ts +57 -0
- package/data/build/dist/transport/dsh-transport.js +125 -0
- package/data/build/dist/transport/frame.d.ts +132 -0
- package/data/build/dist/transport/frame.js +168 -0
- package/data/build/dist/transport/index.d.ts +11 -0
- package/data/build/dist/transport/index.js +11 -0
- package/data/build/dist/transport/multiplexer.d.ts +63 -0
- package/data/build/dist/transport/multiplexer.js +323 -0
- package/data/build/dist/transport/webrtc-client.d.ts +65 -0
- package/data/build/dist/transport/webrtc-client.js +255 -0
- package/data/build/dist/transport/webrtc-host.d.ts +58 -0
- package/data/build/dist/transport/webrtc-host.js +252 -0
- package/data/build/dist/typert.host.d.ts +25 -0
- package/data/build/dist/typert.host.js +150 -0
- package/dsh.bundle.patch +12 -0
- package/package.json +135 -0
- package/profile/README.md +27 -0
- package/profile/cordis.patch.yml +2 -0
- package/profile/package.json +20 -0
- package/profile/scripts/check-dsh-install.mjs +71 -0
- package/profile/version.json +5 -0
- package/scripts/check-dsh-install.mjs +88 -0
- package/version.json +6 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { CodingNsCliAdapterDescriptor, CodingNsCliModel, CodingNsCliModelCatalog, CodingNsCliSessionRecord } from '../shared/contracts/cli-adapter.js';
|
|
2
|
+
import type { CodingNsRpcClient } from './features/types.js';
|
|
3
|
+
/** Client 侧访问 Host CLI 命名空间的统一入口。 */
|
|
4
|
+
export declare function callCliRpc<T>(rpc: CodingNsRpcClient, action: string, payload: unknown): Promise<T>;
|
|
5
|
+
export declare function adapterCatalogWithDsh(catalog: readonly CodingNsCliAdapterDescriptor[]): CodingNsCliAdapterDescriptor[];
|
|
6
|
+
export declare function firstModel(catalog: CodingNsCliModelCatalog): CodingNsCliModel | undefined;
|
|
7
|
+
export declare function findModel(catalog: CodingNsCliModelCatalog, modelId: string | undefined): CodingNsCliModel | undefined;
|
|
8
|
+
export declare function errorMessage(error: unknown): string;
|
|
9
|
+
/** 读取 Host 持久化的外部会话索引;兼容数组和带 items/sessions 的响应包装。 */
|
|
10
|
+
export declare function listCliSessions(rpc: CodingNsRpcClient, options?: {
|
|
11
|
+
readonly includeArchived?: boolean;
|
|
12
|
+
readonly adapterId?: string;
|
|
13
|
+
}): Promise<readonly CodingNsCliSessionRecord[]>;
|
|
14
|
+
/** 把已存在的 DSH 会话恢复到原生会话页面;插件不接管消息列表。 */
|
|
15
|
+
export declare function restoreCliSession(rpc: CodingNsRpcClient, record: CodingNsCliSessionRecord): Promise<void>;
|
|
16
|
+
/** 通过 Host 同步归档 DSH 原生会话和 Codingns4DSH 外部会话索引。 */
|
|
17
|
+
export declare function archiveCliSession(rpc: CodingNsRpcClient, sessionId: string): Promise<void>;
|
|
18
|
+
/**
|
|
19
|
+
* 使用 DSH 当前的会话路由,而不是在插件中复制会话消息组件。
|
|
20
|
+
* 旧版 DSH 使用 `/sessions/:id`,新版 workspace 页面使用同一路径的 workspace 前缀,
|
|
21
|
+
* 因此保留当前 workspace 段并只替换 session id。
|
|
22
|
+
*/
|
|
23
|
+
export declare function navigateToDshSession(sessionId: string): void;
|
|
24
|
+
//# sourceMappingURL=cli-catalog.d.ts.map
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { CODINGNS_RPC_CHANNEL } from '../shared/contracts/transport.js';
|
|
2
|
+
/** Client 侧访问 Host CLI 命名空间的统一入口。 */
|
|
3
|
+
export async function callCliRpc(rpc, action, payload) {
|
|
4
|
+
let response;
|
|
5
|
+
try {
|
|
6
|
+
response = await rpc.call(CODINGNS_RPC_CHANNEL, `cli/${action}`, payload);
|
|
7
|
+
}
|
|
8
|
+
catch (error) {
|
|
9
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
10
|
+
if (!/HTTP (?:404|405)\b/u.test(message))
|
|
11
|
+
throw error;
|
|
12
|
+
response = await rpc.call('/api', `codingns/cli/${action}`, payload);
|
|
13
|
+
}
|
|
14
|
+
if (!response.ok)
|
|
15
|
+
throw new Error(response.error.message);
|
|
16
|
+
return response.value;
|
|
17
|
+
}
|
|
18
|
+
export function adapterCatalogWithDsh(catalog) {
|
|
19
|
+
return [{ id: 'dsh', name: 'DeepSeek Harness', installed: true, enabled: true, version: null, command: null }, ...catalog];
|
|
20
|
+
}
|
|
21
|
+
export function firstModel(catalog) {
|
|
22
|
+
for (const group of catalog.groups) {
|
|
23
|
+
const model = group.models[0];
|
|
24
|
+
if (model !== undefined)
|
|
25
|
+
return model;
|
|
26
|
+
}
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
export function findModel(catalog, modelId) {
|
|
30
|
+
if (modelId === undefined)
|
|
31
|
+
return undefined;
|
|
32
|
+
for (const group of catalog.groups) {
|
|
33
|
+
const model = group.models.find((item) => item.id === modelId);
|
|
34
|
+
if (model !== undefined)
|
|
35
|
+
return model;
|
|
36
|
+
}
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
39
|
+
export function errorMessage(error) {
|
|
40
|
+
return error instanceof Error ? error.message : String(error);
|
|
41
|
+
}
|
|
42
|
+
/** 读取 Host 持久化的外部会话索引;兼容数组和带 items/sessions 的响应包装。 */
|
|
43
|
+
export async function listCliSessions(rpc, options = {}) {
|
|
44
|
+
const value = await callCliRpc(rpc, 'session/list', options);
|
|
45
|
+
const rows = Array.isArray(value)
|
|
46
|
+
? value
|
|
47
|
+
: isRecord(value) && Array.isArray(value.items)
|
|
48
|
+
? value.items
|
|
49
|
+
: isRecord(value) && Array.isArray(value.sessions)
|
|
50
|
+
? value.sessions
|
|
51
|
+
: [];
|
|
52
|
+
return rows.filter(isCliSessionRecord).map(redactCliSessionRecord);
|
|
53
|
+
}
|
|
54
|
+
/** 把已存在的 DSH 会话恢复到原生会话页面;插件不接管消息列表。 */
|
|
55
|
+
export async function restoreCliSession(rpc, record) {
|
|
56
|
+
await callCliRpc(rpc, 'session/set', {
|
|
57
|
+
sessionId: record.dshSessionId,
|
|
58
|
+
adapterId: record.adapterId,
|
|
59
|
+
...(record.modelId ? { modelId: record.modelId } : {}),
|
|
60
|
+
...(record.effortId ? { effortId: record.effortId } : {}),
|
|
61
|
+
...(record.providerSessionId ? { providerSessionId: record.providerSessionId } : {}),
|
|
62
|
+
});
|
|
63
|
+
navigateToDshSession(record.dshSessionId);
|
|
64
|
+
}
|
|
65
|
+
/** 通过 Host 同步归档 DSH 原生会话和 Codingns4DSH 外部会话索引。 */
|
|
66
|
+
export async function archiveCliSession(rpc, sessionId) {
|
|
67
|
+
await callCliRpc(rpc, 'session/archive', { sessionId });
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* 使用 DSH 当前的会话路由,而不是在插件中复制会话消息组件。
|
|
71
|
+
* 旧版 DSH 使用 `/sessions/:id`,新版 workspace 页面使用同一路径的 workspace 前缀,
|
|
72
|
+
* 因此保留当前 workspace 段并只替换 session id。
|
|
73
|
+
*/
|
|
74
|
+
export function navigateToDshSession(sessionId) {
|
|
75
|
+
if (typeof window === 'undefined' || sessionId.trim() === '')
|
|
76
|
+
return;
|
|
77
|
+
const encoded = encodeURIComponent(sessionId.trim());
|
|
78
|
+
const pathname = window.location.pathname;
|
|
79
|
+
const nextPath = /^(\/workspaces\/[^/]+\/sessions\/)[^/]+(?:\/.*)?$/u.test(pathname)
|
|
80
|
+
? pathname.replace(/^(\/workspaces\/[^/]+\/sessions\/)[^/]+(?:\/.*)?$/u, `$1${encoded}`)
|
|
81
|
+
: /^\/sessions\/[^/]+(?:\/.*)?$/u.test(pathname)
|
|
82
|
+
? pathname.replace(/^\/sessions\/[^/]+(?:\/.*)?$/u, `/sessions/${encoded}`)
|
|
83
|
+
: `/sessions/${encoded}`;
|
|
84
|
+
if (`${window.location.pathname}${window.location.search}${window.location.hash}` === `${nextPath}${window.location.search}${window.location.hash}`)
|
|
85
|
+
return;
|
|
86
|
+
window.history.pushState({}, '', nextPath);
|
|
87
|
+
window.dispatchEvent(new PopStateEvent('popstate'));
|
|
88
|
+
}
|
|
89
|
+
function isCliSessionRecord(value) {
|
|
90
|
+
if (!isRecord(value))
|
|
91
|
+
return false;
|
|
92
|
+
return typeof value.dshSessionId === 'string'
|
|
93
|
+
&& value.dshSessionId.trim() !== ''
|
|
94
|
+
&& typeof value.adapterId === 'string'
|
|
95
|
+
&& value.adapterId.trim() !== ''
|
|
96
|
+
&& (value.status === 'active' || value.status === 'idle' || value.status === 'error' || value.status === 'archived')
|
|
97
|
+
&& typeof value.createdAt === 'string'
|
|
98
|
+
&& typeof value.updatedAt === 'string';
|
|
99
|
+
}
|
|
100
|
+
/** 双重防护:即使旧 Host 错误返回 rawStoreRef,浏览器也不会把它留在状态中。 */
|
|
101
|
+
function redactCliSessionRecord(record) {
|
|
102
|
+
const { rawStoreRef: _rawStoreRef, ...safe } = record;
|
|
103
|
+
return safe;
|
|
104
|
+
}
|
|
105
|
+
function isRecord(value) {
|
|
106
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=cli-catalog.js.map
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { ReactElement } from 'react';
|
|
2
|
+
import type { CodingNsRpcClient } from './features/types.js';
|
|
3
|
+
import type { SlotRegistry } from '@deepseek-ai/dsh-client-ui-renderer/client';
|
|
4
|
+
import { type CodingNsLocale } from './locale.js';
|
|
5
|
+
interface SessionSnapshot {
|
|
6
|
+
readonly sessionId?: string;
|
|
7
|
+
readonly blank?: boolean;
|
|
8
|
+
readonly promptAttempted?: boolean;
|
|
9
|
+
readonly running?: boolean;
|
|
10
|
+
readonly queue?: readonly unknown[];
|
|
11
|
+
}
|
|
12
|
+
type SessionSelector = <Selected>(selector: (session: SessionSnapshot) => Selected) => Selected;
|
|
13
|
+
/** DSH Web 当前版本的对话工具栏 Slot 契约。Slot 包没有预声明这些业务名称,插件在此补齐类型。 */
|
|
14
|
+
declare module '@deepseek-ai/dsh-client-ui-slots' {
|
|
15
|
+
interface SlotMap {
|
|
16
|
+
'conversation.input.right': {
|
|
17
|
+
kind: 'list';
|
|
18
|
+
scope: 'session';
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
interface SessionStandardProps {
|
|
22
|
+
sessionId: string;
|
|
23
|
+
useSession: SessionSelector;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
interface CliSlotProps {
|
|
27
|
+
readonly sessionId?: string;
|
|
28
|
+
readonly useSession?: SessionSelector;
|
|
29
|
+
readonly rpc: CodingNsRpcClient;
|
|
30
|
+
readonly locale: CodingNsLocale;
|
|
31
|
+
}
|
|
32
|
+
/** 把 Agent 与模型选择器注册到同一工具栏,使用顺序保证 Agent 始终位于模型左侧。 */
|
|
33
|
+
export declare function registerCliConversationSlots(slots: SlotRegistry, rpc: CodingNsRpcClient, locale: CodingNsLocale): () => void;
|
|
34
|
+
declare function AgentSlot(props: CliSlotProps): ReactElement;
|
|
35
|
+
declare function ModelSlot(props: CliSlotProps): ReactElement | null;
|
|
36
|
+
export { AgentSlot, ModelSlot };
|
|
37
|
+
export type { SessionSnapshot };
|
|
38
|
+
//# sourceMappingURL=cli-slots.d.ts.map
|
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
import { createElement, useEffect, useState } from 'react';
|
|
2
|
+
import { adapterCatalogWithDsh, callCliRpc, findModel, firstModel } from './cli-catalog.js';
|
|
3
|
+
import { providerIconUrl } from './provider-icons.js';
|
|
4
|
+
import { publishSessionAdapter } from './session-adapter-cache.js';
|
|
5
|
+
import { dshPopupSurfaceStyle, dshThemeColor } from './theme.js';
|
|
6
|
+
import { useCodingNsTranslator } from './locale.js';
|
|
7
|
+
const CLI_STYLE_ID = 'codingns4dsh-cli-composer-style';
|
|
8
|
+
const CIRCULAR_PROVIDER_ICON_IDS = new Set(['gemini', 'grok']);
|
|
9
|
+
function installComposerStyles() {
|
|
10
|
+
if (typeof document === 'undefined' || document.querySelector(`style[data-plugin-css="${CLI_STYLE_ID}"]`) !== null)
|
|
11
|
+
return;
|
|
12
|
+
const style = document.createElement('style');
|
|
13
|
+
style.dataset.plugin = 'codingns4dsh';
|
|
14
|
+
style.dataset.pluginCss = CLI_STYLE_ID;
|
|
15
|
+
style.textContent = [
|
|
16
|
+
'html[data-codingns-agent]:not([data-codingns-agent="dsh"]) [data-slot="conversation.input.model"],',
|
|
17
|
+
'body[data-codingns-agent]:not([data-codingns-agent="dsh"]) [data-slot="conversation.input.model"]{display:none!important}',
|
|
18
|
+
'@keyframes codingns4dsh-cli-spin{to{transform:rotate(360deg)}}',
|
|
19
|
+
'.codingns4dsh-cli-spinner{animation:codingns4dsh-cli-spin .8s linear infinite}',
|
|
20
|
+
'.codingns4dsh-agent-trigger:hover:not(:disabled){background:color-mix(in srgb,currentColor 7%,transparent)}',
|
|
21
|
+
'.codingns4dsh-agent-option:hover:not(:disabled){background:color-mix(in srgb,currentColor 7%,transparent)!important}',
|
|
22
|
+
'.codingns4dsh-agent-option[data-selected="true"]{background:color-mix(in srgb,currentColor 10%,transparent)!important}',
|
|
23
|
+
'@media (prefers-reduced-motion:reduce){.codingns4dsh-cli-spinner{animation-duration:1.6s}}',
|
|
24
|
+
].join('');
|
|
25
|
+
document.head.appendChild(style);
|
|
26
|
+
}
|
|
27
|
+
const DEFAULT_SELECTION = { adapterId: 'dsh' };
|
|
28
|
+
const selections = new Map();
|
|
29
|
+
const selectionListeners = new Map();
|
|
30
|
+
/** 在 Agent 和模型两个 Slot 之间共享当前会话选择。 */
|
|
31
|
+
function useSelection(sessionId, rpc) {
|
|
32
|
+
const [selection, setSelection] = useState(() => sessionId ? selections.get(sessionId) ?? DEFAULT_SELECTION : DEFAULT_SELECTION);
|
|
33
|
+
useEffect(() => {
|
|
34
|
+
if (sessionId === undefined || sessionId.trim() === '')
|
|
35
|
+
return;
|
|
36
|
+
let active = true;
|
|
37
|
+
void callCliRpc(rpc, 'session/get', { sessionId })
|
|
38
|
+
.then((value) => {
|
|
39
|
+
if (!active)
|
|
40
|
+
return;
|
|
41
|
+
// 用户可能已在 session/get 返回前切换 Agent;旧响应不能覆盖本地最新选择。
|
|
42
|
+
if (selections.has(sessionId))
|
|
43
|
+
return;
|
|
44
|
+
publishSelection(sessionId, value);
|
|
45
|
+
})
|
|
46
|
+
.catch(() => undefined);
|
|
47
|
+
const listeners = selectionListeners.get(sessionId) ?? new Set();
|
|
48
|
+
selectionListeners.set(sessionId, listeners);
|
|
49
|
+
const listener = () => setSelection(selections.get(sessionId) ?? DEFAULT_SELECTION);
|
|
50
|
+
listeners.add(listener);
|
|
51
|
+
return () => {
|
|
52
|
+
active = false;
|
|
53
|
+
listeners.delete(listener);
|
|
54
|
+
if (listeners.size === 0) {
|
|
55
|
+
selectionListeners.delete(sessionId);
|
|
56
|
+
selections.delete(sessionId);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
}, [rpc, sessionId]);
|
|
60
|
+
const update = (next) => {
|
|
61
|
+
if (sessionId === undefined || sessionId.trim() === '')
|
|
62
|
+
return;
|
|
63
|
+
publishSelection(sessionId, next);
|
|
64
|
+
void callCliRpc(rpc, 'session/set', { sessionId, ...next })
|
|
65
|
+
.then((normalized) => publishSelection(sessionId, normalized))
|
|
66
|
+
.catch(() => undefined);
|
|
67
|
+
};
|
|
68
|
+
return [selection, update];
|
|
69
|
+
}
|
|
70
|
+
function publishSelection(sessionId, next) {
|
|
71
|
+
const normalized = {
|
|
72
|
+
adapterId: next.adapterId,
|
|
73
|
+
...(next.modelId ? { modelId: next.modelId } : {}),
|
|
74
|
+
...(next.effortId ? { effortId: next.effortId } : {}),
|
|
75
|
+
};
|
|
76
|
+
selections.set(sessionId, normalized);
|
|
77
|
+
publishSessionAdapter(sessionId, normalized.adapterId);
|
|
78
|
+
for (const listener of selectionListeners.get(sessionId) ?? [])
|
|
79
|
+
listener();
|
|
80
|
+
}
|
|
81
|
+
/** 把 Agent 与模型选择器注册到同一工具栏,使用顺序保证 Agent 始终位于模型左侧。 */
|
|
82
|
+
export function registerCliConversationSlots(slots, rpc, locale) {
|
|
83
|
+
installComposerStyles();
|
|
84
|
+
const t = locale.bind('codingns');
|
|
85
|
+
const disposeAgent = slots.inject('conversation.input.right', () => slots.register({
|
|
86
|
+
name: 'conversation.input.right',
|
|
87
|
+
id: 'codingns4dsh-agent',
|
|
88
|
+
order: -20,
|
|
89
|
+
label: t('cli.agentSelector'),
|
|
90
|
+
inject: (sessionId) => ({ rpc, sessionId, locale }),
|
|
91
|
+
}, AgentSlot));
|
|
92
|
+
const disposeModel = slots.inject('conversation.input.right', () => slots.register({
|
|
93
|
+
name: 'conversation.input.right',
|
|
94
|
+
id: 'codingns4dsh-model',
|
|
95
|
+
order: -10,
|
|
96
|
+
label: t('cli.modelSelector'),
|
|
97
|
+
inject: (sessionId) => ({ rpc, sessionId, locale }),
|
|
98
|
+
}, ModelSlot));
|
|
99
|
+
return () => {
|
|
100
|
+
disposeModel();
|
|
101
|
+
disposeAgent();
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
function AgentSlot(props) {
|
|
105
|
+
const t = useCodingNsTranslator(props.locale);
|
|
106
|
+
const session = props.useSession?.((value) => value);
|
|
107
|
+
const sessionId = props.sessionId ?? session?.sessionId;
|
|
108
|
+
const [selection, update] = useSelection(sessionId, props.rpc);
|
|
109
|
+
const [agents, setAgents] = useState([{ id: 'dsh', name: 'DeepSeek Harness', installed: true, enabled: true, version: null, command: null }]);
|
|
110
|
+
const [open, setOpen] = useState(false);
|
|
111
|
+
const locked = session !== undefined && (!session.blank || Boolean(session.promptAttempted) || Boolean(session.running) || (session.queue?.length ?? 0) > 0);
|
|
112
|
+
useEffect(() => {
|
|
113
|
+
if (typeof document === 'undefined')
|
|
114
|
+
return;
|
|
115
|
+
document.documentElement.dataset.codingnsAgent = selection.adapterId;
|
|
116
|
+
document.body?.setAttribute('data-codingns-agent', selection.adapterId);
|
|
117
|
+
return () => {
|
|
118
|
+
if (document.documentElement.dataset.codingnsAgent === selection.adapterId)
|
|
119
|
+
delete document.documentElement.dataset.codingnsAgent;
|
|
120
|
+
if (document.body?.dataset.codingnsAgent === selection.adapterId)
|
|
121
|
+
document.body.removeAttribute('data-codingns-agent');
|
|
122
|
+
};
|
|
123
|
+
}, [selection.adapterId]);
|
|
124
|
+
useEffect(() => {
|
|
125
|
+
let active = true;
|
|
126
|
+
void callCliRpc(props.rpc, 'catalog', {})
|
|
127
|
+
.then((value) => { if (active)
|
|
128
|
+
setAgents(adapterCatalogWithDsh(value)); })
|
|
129
|
+
.catch(() => undefined);
|
|
130
|
+
return () => { active = false; };
|
|
131
|
+
}, [props.rpc]);
|
|
132
|
+
useEffect(() => { if (locked)
|
|
133
|
+
setOpen(false); }, [locked]);
|
|
134
|
+
const current = agents.find((agent) => agent.id === selection.adapterId) ?? agents[0];
|
|
135
|
+
const choose = (agent) => {
|
|
136
|
+
if (locked || !agent.installed || !agent.enabled || sessionId === undefined)
|
|
137
|
+
return;
|
|
138
|
+
update({ adapterId: agent.id });
|
|
139
|
+
setOpen(false);
|
|
140
|
+
};
|
|
141
|
+
const currentIcon = providerIconUrl(current.id);
|
|
142
|
+
return createElement('div', { style: agentRootStyle }, createElement('button', { type: 'button', className: 'codingns4dsh-agent-trigger', disabled: locked, onClick: () => setOpen((value) => !value), 'aria-label': t('cli.currentAgent', { name: current.name, locked: locked ? t('cli.locked') : '' }), 'aria-haspopup': 'menu', 'aria-expanded': open, style: { ...agentTriggerStyle, cursor: locked ? 'default' : 'pointer', opacity: locked ? 0.7 : 1 } }, currentIcon === undefined
|
|
143
|
+
? createElement(ProviderIconFallback, { name: current.name, size: 20 })
|
|
144
|
+
: createElement('img', { src: currentIcon, alt: '', 'aria-hidden': true, style: applyProviderIconShape(current.id, agentTriggerIconStyle) }), createElement('span', { style: agentTriggerLabelStyle }, current.name), createElement(NativeDropdownChevron, { open, locked })), open && !locked && createElement('div', { role: 'menu', 'aria-label': t('cli.selectAgent'), style: agentMenuStyle }, ...agents.map((agent) => {
|
|
145
|
+
const selected = agent.id === selection.adapterId;
|
|
146
|
+
const available = agent.installed && agent.enabled;
|
|
147
|
+
const icon = providerIconUrl(agent.id);
|
|
148
|
+
return createElement('button', { key: agent.id, type: 'button', className: 'codingns4dsh-agent-option', role: 'menuitemradio', 'aria-checked': selected, 'data-selected': String(selected), disabled: !available, onClick: () => choose(agent), style: { ...agentOptionStyle, cursor: available ? 'pointer' : 'not-allowed', opacity: available ? 1 : 0.45 } }, createElement('span', { 'aria-hidden': true, style: agentCheckStyle }, selected ? '✓' : ''), icon === undefined
|
|
149
|
+
? createElement(ProviderIconFallback, { name: agent.name, size: 22 })
|
|
150
|
+
: createElement('img', { src: icon, alt: '', 'aria-hidden': true, style: applyProviderIconShape(agent.id, agentOptionIconStyle) }), createElement('span', { style: agentOptionLabelStyle }, agent.name), !agent.installed && createElement('span', { style: agentStatusStyle }, t('cli.notInstalled')), agent.installed && !agent.enabled && createElement('span', { style: agentStatusStyle }, t('cli.disabled')));
|
|
151
|
+
})));
|
|
152
|
+
}
|
|
153
|
+
function ProviderIconFallback(props) {
|
|
154
|
+
return createElement('span', { 'aria-hidden': true, style: { ...agentFallbackIconStyle, width: props.size, height: props.size, flexBasis: props.size } }, props.name.trim().charAt(0).toUpperCase() || '?');
|
|
155
|
+
}
|
|
156
|
+
/** Gemini 与 Grok 的原图带方形底色,只在展示时裁成圆形。 */
|
|
157
|
+
function applyProviderIconShape(adapterId, style) {
|
|
158
|
+
return CIRCULAR_PROVIDER_ICON_IDS.has(adapterId) ? { ...style, borderRadius: '50%' } : style;
|
|
159
|
+
}
|
|
160
|
+
/** 与 DSH 原生工具一致的下拉箭头;会话开始后改为锁形状态提示。 */
|
|
161
|
+
function NativeDropdownChevron({ open, locked = false }) {
|
|
162
|
+
return createElement('svg', {
|
|
163
|
+
width: 14,
|
|
164
|
+
height: 14,
|
|
165
|
+
viewBox: '0 0 14 14',
|
|
166
|
+
fill: 'none',
|
|
167
|
+
xmlns: 'http://www.w3.org/2000/svg',
|
|
168
|
+
'aria-hidden': true,
|
|
169
|
+
style: { ...nativeDropdownChevronStyle, transform: !locked && open ? 'rotate(180deg)' : undefined },
|
|
170
|
+
}, createElement('path', {
|
|
171
|
+
d: locked
|
|
172
|
+
? 'M10.5 6V4.75a3.5 3.5 0 0 0-7 0V6H3a1 1 0 0 0-1 1v4a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V7a1 1 0 0 0-1-1h-.5ZM5 4.75a2 2 0 0 1 4 0V6H5V4.75ZM7 8a.9.9 0 0 0-.5 1.648V11h1V9.648A.9.9 0 0 0 7 8Z'
|
|
173
|
+
: 'M11.8486 5.5L11.4238 5.92383L8.69727 8.65137C8.44157 8.90706 8.21562 9.13382 8.01172 9.29785C7.79912 9.46883 7.55595 9.61756 7.25 9.66602C7.08435 9.69222 6.91565 9.69222 6.75 9.66602C6.44405 9.61756 6.20088 9.46883 5.98828 9.29785C5.78438 9.13382 5.55843 8.90706 5.30273 8.65137L2.57617 5.92383L2.15137 5.5L3 4.65137L3.42383 5.07617L6.15137 7.80273C6.42595 8.07732 6.59876 8.24849 6.74023 8.3623C6.87291 8.46904 6.92272 8.47813 6.9375 8.48047C6.97895 8.48703 7.02105 8.48703 7.0625 8.48047C7.07728 8.47813 7.12709 8.46904 7.25977 8.3623C7.40124 8.24849 7.57405 8.07732 7.84863 7.80273L10.5762 5.07617L11 4.65137L11.8486 5.5Z',
|
|
174
|
+
fill: 'currentColor',
|
|
175
|
+
}));
|
|
176
|
+
}
|
|
177
|
+
const agentRootStyle = { position: 'relative', minWidth: 0, display: 'inline-flex' };
|
|
178
|
+
const agentTriggerStyle = { height: 30, maxWidth: 220, minWidth: 0, color: dshThemeColor.labelPrimary, border: 0, borderRadius: 8, padding: '0 6px', background: 'transparent', display: 'inline-flex', alignItems: 'center', gap: 7, fontSize: 14, lineHeight: '20px' };
|
|
179
|
+
const agentTriggerIconStyle = { width: 20, height: 20, flex: '0 0 20px', objectFit: 'contain' };
|
|
180
|
+
const agentTriggerLabelStyle = { minWidth: 0, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' };
|
|
181
|
+
const nativeDropdownChevronStyle = { display: 'block', flex: '0 0 14px', color: dshThemeColor.labelCaption, transformOrigin: 'center' };
|
|
182
|
+
const agentMenuStyle = { ...dshPopupSurfaceStyle, position: 'absolute', zIndex: 1100, bottom: 'calc(100% + 8px)', left: 0, minWidth: 238, maxWidth: 'min(320px, calc(100vw - 32px))', maxHeight: 'min(400px, calc(100vh - 96px))', overflowY: 'auto', padding: 5, border: 0, borderRadius: 8 };
|
|
183
|
+
const agentOptionStyle = { width: '100%', minHeight: 40, color: 'inherit', border: 0, borderRadius: 6, padding: '5px 8px 5px 4px', background: 'transparent', display: 'flex', alignItems: 'center', gap: 8, textAlign: 'left', fontSize: 14, lineHeight: '20px' };
|
|
184
|
+
const agentCheckStyle = { width: 18, flex: '0 0 18px', textAlign: 'center', fontSize: 16, lineHeight: 1 };
|
|
185
|
+
const agentOptionIconStyle = { width: 22, height: 22, flex: '0 0 22px', objectFit: 'contain' };
|
|
186
|
+
const agentOptionLabelStyle = { flex: '1 1 auto', minWidth: 0, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' };
|
|
187
|
+
const agentStatusStyle = { flex: '0 0 auto', color: dshThemeColor.labelTertiary, fontSize: 12, whiteSpace: 'nowrap' };
|
|
188
|
+
const agentFallbackIconStyle = { flexGrow: 0, flexShrink: 0, borderRadius: 5, color: '#fff', background: dshThemeColor.labelTertiary, display: 'inline-flex', alignItems: 'center', justifyContent: 'center', fontSize: 11, fontWeight: 600, lineHeight: 1 };
|
|
189
|
+
function ModelSlot(props) {
|
|
190
|
+
// 语言词典中的中文值仍保留“正在加载模型列表…”语义,切换语言时由 t() 取值。
|
|
191
|
+
const t = useCodingNsTranslator(props.locale);
|
|
192
|
+
const session = props.useSession?.((value) => value);
|
|
193
|
+
const sessionId = props.sessionId ?? session?.sessionId;
|
|
194
|
+
const [selection, update] = useSelection(sessionId, props.rpc);
|
|
195
|
+
const [catalogState, setCatalogState] = useState(null);
|
|
196
|
+
const [refreshingAdapterId, setRefreshingAdapterId] = useState(null);
|
|
197
|
+
const [open, setOpen] = useState(false);
|
|
198
|
+
const [pane, setPane] = useState('root');
|
|
199
|
+
const catalog = catalogState?.adapterId === selection.adapterId ? catalogState.value : null;
|
|
200
|
+
// 目录必须和当前适配器绑定;切换后的第一次渲染立即进入加载态,不能短暂展示旧目录。
|
|
201
|
+
const loading = selection.adapterId !== 'dsh'
|
|
202
|
+
&& (catalog === null || refreshingAdapterId === selection.adapterId);
|
|
203
|
+
useEffect(() => {
|
|
204
|
+
if (selection.adapterId === 'dsh') {
|
|
205
|
+
setCatalogState(null);
|
|
206
|
+
setRefreshingAdapterId(null);
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
let active = true;
|
|
210
|
+
const adapterId = selection.adapterId;
|
|
211
|
+
setRefreshingAdapterId(adapterId);
|
|
212
|
+
void callCliRpc(props.rpc, 'models', { adapterId })
|
|
213
|
+
.then((value) => {
|
|
214
|
+
if (!active)
|
|
215
|
+
return;
|
|
216
|
+
setCatalogState({ adapterId, value });
|
|
217
|
+
// session/set 可能在模型目录请求期间返回适配器级记忆值;不能使用
|
|
218
|
+
// effect 闭包里的旧 selection,否则会把记忆模型覆盖成目录第一项。
|
|
219
|
+
const currentSelection = sessionId === undefined
|
|
220
|
+
? selection
|
|
221
|
+
: selections.get(sessionId) ?? selection;
|
|
222
|
+
const model = findModel(value, currentSelection.modelId) ?? firstModel(value);
|
|
223
|
+
if (model === undefined)
|
|
224
|
+
return;
|
|
225
|
+
const effort = model.efforts.includes(currentSelection.effortId ?? '') ? currentSelection.effortId : defaultEffort(model.efforts);
|
|
226
|
+
if (model.id !== currentSelection.modelId || effort !== currentSelection.effortId)
|
|
227
|
+
update({ adapterId, modelId: model.id, ...(effort ? { effortId: effort } : {}) });
|
|
228
|
+
})
|
|
229
|
+
.catch(() => { if (active)
|
|
230
|
+
setCatalogState({ adapterId, value: { groups: [], currentModel: null, currentEffort: null } }); })
|
|
231
|
+
.finally(() => { if (active)
|
|
232
|
+
setRefreshingAdapterId(null); });
|
|
233
|
+
return () => { active = false; };
|
|
234
|
+
}, [props.rpc, selection.adapterId]);
|
|
235
|
+
useEffect(() => { if (selection.adapterId === 'dsh')
|
|
236
|
+
setOpen(false); }, [selection.adapterId]);
|
|
237
|
+
if (selection.adapterId === 'dsh')
|
|
238
|
+
return null;
|
|
239
|
+
const model = catalog === null ? undefined : findModel(catalog, selection.modelId) ?? firstModel(catalog);
|
|
240
|
+
const efforts = model?.efforts ?? [];
|
|
241
|
+
const effortValue = selection.effortId ?? (efforts.length > 0 ? defaultEffort(efforts) : undefined) ?? 'default';
|
|
242
|
+
const modelLabel = model?.name ?? (loading ? t('cli.loadingModel') : t('cli.noModelsAvailable'));
|
|
243
|
+
const effortLabel = efforts.find((effort) => effort === effortValue) ?? 'Default';
|
|
244
|
+
const modelUnavailable = model === undefined;
|
|
245
|
+
const triggerDisabled = !loading && modelUnavailable;
|
|
246
|
+
const chooseModel = (next) => {
|
|
247
|
+
const nextEffort = next.efforts.includes(effortValue) ? effortValue : defaultEffort(next.efforts);
|
|
248
|
+
update({ adapterId: selection.adapterId, modelId: next.id, ...(nextEffort ? { effortId: nextEffort } : {}) });
|
|
249
|
+
setOpen(false);
|
|
250
|
+
setPane('root');
|
|
251
|
+
};
|
|
252
|
+
const chooseEffort = (effort) => {
|
|
253
|
+
if (model === undefined)
|
|
254
|
+
return;
|
|
255
|
+
update({ adapterId: selection.adapterId, modelId: model.id, effortId: effort });
|
|
256
|
+
setOpen(false);
|
|
257
|
+
setPane('root');
|
|
258
|
+
};
|
|
259
|
+
const menu = loading
|
|
260
|
+
? [
|
|
261
|
+
createElement('div', { key: 'loading', role: 'status', 'aria-live': 'polite', style: modelLoadingMenuStyle }, createElement('span', { className: 'codingns4dsh-cli-spinner', 'aria-hidden': true, style: modelSpinnerStyle }), createElement('span', undefined, t('cli.loadingModel'))),
|
|
262
|
+
]
|
|
263
|
+
: pane === 'root'
|
|
264
|
+
? [
|
|
265
|
+
createElement('button', { key: 'model', type: 'button', role: 'menuitem', disabled: modelUnavailable, onClick: () => setPane('model'), style: nativeMenuCellStyle }, createElement('span', { style: nativeMenuLabelStyle }, t('cli.model')), createElement('span', { style: nativeMenuValueStyle }, modelLabel), createElement('span', { 'aria-hidden': true, style: nativeChevronStyle }, '›')),
|
|
266
|
+
createElement('button', { key: 'effort', type: 'button', role: 'menuitem', disabled: modelUnavailable, onClick: () => setPane('effort'), style: nativeMenuCellStyle }, createElement('span', undefined, t('cli.thinking')), createElement('span', { style: nativeMenuValueStyle }, effortLabel), createElement('span', { 'aria-hidden': true, style: nativeChevronStyle }, '›')),
|
|
267
|
+
]
|
|
268
|
+
: pane === 'model'
|
|
269
|
+
? [
|
|
270
|
+
createElement('button', { key: 'back', type: 'button', onClick: () => setPane('root'), style: nativeBackStyle }, t('cli.back')),
|
|
271
|
+
...((catalog?.groups ?? []).map((group) => createElement('section', { key: group.id, role: 'group', 'aria-label': group.name, style: { marginTop: 4 } }, createElement('div', { style: nativeGroupTitleStyle }, group.name), ...group.models.map((item) => createElement('button', { key: `${group.id}:${item.id}`, type: 'button', role: 'menuitemradio', 'aria-checked': item.id === model?.id, onClick: () => chooseModel(item), style: nativeOptionStyle }, createElement('span', { style: { flex: '1 1 auto', minWidth: 0, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' } }, item.name), item.id === model?.id && createElement('span', { 'aria-hidden': true }, '✓'))))))
|
|
272
|
+
]
|
|
273
|
+
: [
|
|
274
|
+
createElement('button', { key: 'back', type: 'button', onClick: () => setPane('root'), style: nativeBackStyle }, t('cli.back')),
|
|
275
|
+
createElement('div', { key: 'title', style: nativeGroupTitleStyle }, `${t('cli.thinking')}(${modelLabel})`),
|
|
276
|
+
...(efforts.length > 0 ? efforts : ['default']).map((effort) => createElement('button', { key: effort, type: 'button', role: 'menuitemradio', 'aria-checked': effort === effortValue, onClick: () => chooseEffort(effort), style: nativeOptionStyle }, createElement('span', { style: { flex: '1 1 auto' } }, effort === 'default' ? 'Default' : effort), effort === effortValue && createElement('span', { 'aria-hidden': true }, '✓'))),
|
|
277
|
+
];
|
|
278
|
+
return createElement('div', { style: { position: 'relative', minWidth: 0, display: 'inline-flex' } }, createElement('button', { type: 'button', disabled: triggerDisabled, 'aria-label': t('cli.chooseModel', { model: modelLabel, effort: effortLabel }), 'aria-busy': loading, 'aria-haspopup': 'menu', 'aria-expanded': open, onClick: () => { setPane('root'); setOpen((value) => !value); }, style: nativeTriggerStyle }, loading && createElement('span', { className: 'codingns4dsh-cli-spinner', 'aria-hidden': true, style: modelSpinnerStyle }), createElement('span', { role: loading ? 'status' : undefined, 'aria-live': loading ? 'polite' : undefined, style: { minWidth: 0, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' } }, modelLabel), !loading && createElement('span', { style: { color: dshThemeColor.labelCaption, whiteSpace: 'nowrap' } }, effortLabel), !loading && createElement(NativeDropdownChevron, { open })), open && createElement('div', { role: 'menu', 'aria-label': t('cli.chooseModelMenu'), style: nativeMenuStyle }, ...menu));
|
|
279
|
+
}
|
|
280
|
+
const nativeTriggerStyle = { minWidth: 0, maxWidth: 'min(360px, 45cqw)', height: 28, color: dshThemeColor.labelSecondary, cursor: 'pointer', background: 'transparent', border: 0, borderRadius: 24, padding: '0 4px 0 8px', display: 'inline-flex', alignItems: 'center', gap: 4, fontSize: 13, lineHeight: '20px' };
|
|
281
|
+
const nativeMenuStyle = { ...dshPopupSurfaceStyle, position: 'absolute', zIndex: 1100, right: 0, bottom: 'calc(100% + 8px)', minWidth: 240, maxWidth: 'min(420px, calc(100vw - 32px))', maxHeight: 'min(360px, calc(100vh - 96px))', overflowY: 'auto', padding: 4, border: 0, borderRadius: 20 };
|
|
282
|
+
const nativeMenuCellStyle = { width: '100%', minHeight: 40, color: 'inherit', cursor: 'pointer', background: 'transparent', border: 0, borderRadius: 10, padding: '0 10px', display: 'flex', alignItems: 'center', gap: 8, textAlign: 'left', fontSize: 14, lineHeight: '22px' };
|
|
283
|
+
const nativeMenuLabelStyle = { flex: 'none', whiteSpace: 'nowrap' };
|
|
284
|
+
const nativeMenuValueStyle = { flex: '1 1 auto', minWidth: 0, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', textAlign: 'right', color: dshThemeColor.labelTertiary };
|
|
285
|
+
const nativeChevronStyle = { flex: 'none', color: dshThemeColor.labelTertiary, fontSize: 20, lineHeight: 1 };
|
|
286
|
+
const nativeBackStyle = { width: '100%', height: 30, color: dshThemeColor.labelSecondary, cursor: 'pointer', textAlign: 'left', background: 'transparent', border: 0, borderRadius: 8, padding: '0 8px', fontSize: 13 };
|
|
287
|
+
const nativeGroupTitleStyle = { position: 'sticky', top: 0, zIndex: 1, padding: '5px 8px 3px', color: dshThemeColor.labelTertiary, background: dshThemeColor.menuBackground, fontSize: 12, fontWeight: 500, lineHeight: '18px' };
|
|
288
|
+
const nativeOptionStyle = { width: '100%', minHeight: 38, color: 'inherit', cursor: 'pointer', textAlign: 'left', background: 'transparent', border: 0, borderRadius: 10, padding: '6px 8px', display: 'flex', alignItems: 'center', gap: 8, fontSize: 14, lineHeight: '20px' };
|
|
289
|
+
const modelSpinnerStyle = { width: 12, height: 12, flex: '0 0 12px', boxSizing: 'border-box', border: '2px solid currentColor', borderRightColor: 'transparent', borderRadius: '50%' };
|
|
290
|
+
const modelLoadingMenuStyle = { minHeight: 56, padding: '0 12px', display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8, color: dshThemeColor.labelTertiary, fontSize: 13 };
|
|
291
|
+
function defaultEffort(efforts) {
|
|
292
|
+
if (efforts.length === 0)
|
|
293
|
+
return undefined;
|
|
294
|
+
return efforts.length > 2 ? efforts[efforts.length - 2] : efforts[efforts.length - 1];
|
|
295
|
+
}
|
|
296
|
+
export { AgentSlot, ModelSlot };
|
|
297
|
+
//# sourceMappingURL=cli-slots.js.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
2
|
+
import type { CodingNsRpcClient } from '../features/types.js';
|
|
3
|
+
export declare const DEBUG_KIND = "debug";
|
|
4
|
+
export declare const DEBUG_PROVIDER_ID = "codingns4dsh/debug";
|
|
5
|
+
/** 注册最小 Debug 页面;页面只负责展示和发送用户意图。 */
|
|
6
|
+
export declare function registerDebugUi(ctx: Context, rpc: CodingNsRpcClient, remote: unknown): () => void;
|
|
7
|
+
declare module '@deepseek-ai/dsh-client-ui-sidebar-right/client' {
|
|
8
|
+
interface SidebarRightTabParamsMap {
|
|
9
|
+
debug: undefined;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=ui.d.ts.map
|