@jingyi0605/codingns4dsh 0.1.1 → 0.1.7-rc.2
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 +4 -4
- package/README.md +14 -5
- package/data/build/dist/client/account-bar.js +57 -3
- package/data/build/dist/client/bundle.js +36245 -267
- package/data/build/dist/client/cli-slots.js +60 -18
- package/data/build/dist/client/dsh-h5-bootstrap.d.ts +2 -0
- package/data/build/dist/client/dsh-h5-bootstrap.js +79 -13
- package/data/build/dist/client/features/file-management-panel.d.ts +5 -0
- package/data/build/dist/client/features/file-management-panel.js +48 -0
- package/data/build/dist/client/features/file-management.d.ts +4 -0
- package/data/build/dist/client/features/file-management.js +50 -0
- package/data/build/dist/client/features/index.d.ts +10 -1
- package/data/build/dist/client/features/index.js +12 -1
- package/data/build/dist/client/features/login-protection-panel.js +1 -1
- package/data/build/dist/client/features/login-protection-session.d.ts +2 -0
- package/data/build/dist/client/features/login-protection-session.js +18 -0
- package/data/build/dist/client/features/peer-host.d.ts +4 -0
- package/data/build/dist/client/features/peer-host.js +89 -0
- package/data/build/dist/client/features/reverse-proxy-panel.js +23 -7
- package/data/build/dist/client/features/reverse-proxy.d.ts +1 -2
- package/data/build/dist/client/features/reverse-proxy.js +75 -5
- package/data/build/dist/client/features/types.d.ts +9 -0
- package/data/build/dist/client/features/workspace-session-enhancement-panel.js +10 -0
- package/data/build/dist/client/features/workspace-session-enhancement.js +18 -1
- package/data/build/dist/client/file-management-dom.d.ts +12 -0
- package/data/build/dist/client/file-management-dom.js +527 -0
- package/data/build/dist/client/git-management.js +24 -5
- package/data/build/dist/client/host-navigation.d.ts +29 -0
- package/data/build/dist/client/host-navigation.js +29 -0
- package/data/build/dist/client/host-router.d.ts +3 -0
- package/data/build/dist/client/host-router.js +2 -0
- package/data/build/dist/client/index.d.ts +6 -1
- package/data/build/dist/client/index.js +30 -10
- package/data/build/dist/client/locale.js +36 -7
- package/data/build/dist/client/peer-host-connection-button.d.ts +13 -0
- package/data/build/dist/client/peer-host-connection-button.js +69 -0
- package/data/build/dist/client/peer-host-management-api.d.ts +40 -0
- package/data/build/dist/client/peer-host-management-api.js +33 -0
- package/data/build/dist/client/peer-host-management-panel.d.ts +13 -0
- package/data/build/dist/client/peer-host-management-panel.js +181 -0
- package/data/build/dist/client/peer-host-native-session-ui.d.ts +60 -0
- package/data/build/dist/client/peer-host-native-session-ui.js +372 -0
- package/data/build/dist/client/peer-host-scoped-client.d.ts +67 -0
- package/data/build/dist/client/peer-host-scoped-client.js +316 -0
- package/data/build/dist/client/peer-host-session-controller.d.ts +30 -0
- package/data/build/dist/client/peer-host-session-controller.js +95 -0
- package/data/build/dist/client/quick-phrase-slot.js +14 -0
- package/data/build/dist/client/remote-web-context.js +26 -4
- package/data/build/dist/client/session-changed-files-view.d.ts +15 -0
- package/data/build/dist/client/session-changed-files-view.js +337 -0
- package/data/build/dist/client/settings-bridge.d.ts +14 -4
- package/data/build/dist/client/settings-bridge.js +59 -12
- package/data/build/dist/client/settings-section.js +17 -4
- package/data/build/dist/client/subscription-slot.js +21 -8
- package/data/build/dist/client/workspace-session-rightbar-dom.d.ts +28 -0
- package/data/build/dist/client/workspace-session-rightbar-dom.js +291 -0
- package/data/build/dist/dsh-capabilities/client/config-forms-adapter.js +25 -33
- package/data/build/dist/dsh-capabilities/client/settings-scope-adapter.d.ts +7 -1
- package/data/build/dist/dsh-capabilities/client/settings-scope-adapter.js +34 -11
- package/data/build/dist/dsh-capabilities/matrix.js +9 -0
- package/data/build/dist/dsh-capabilities/routes.js +35 -0
- package/data/build/dist/dsh-capabilities/settings-store.d.ts +12 -0
- package/data/build/dist/dsh-capabilities/settings-store.js +34 -0
- package/data/build/dist/dsh-capabilities/types.d.ts +1 -1
- package/data/build/dist/features/host-router.d.ts +26 -0
- package/data/build/dist/features/host-router.js +110 -0
- package/data/build/dist/features/registry.js +3 -0
- package/data/build/dist/host/cli-adapters/codex-driver.d.ts +13 -1
- package/data/build/dist/host/cli-adapters/codex-driver.js +528 -72
- package/data/build/dist/host/cli-adapters/command-code-driver.d.ts +21 -2
- package/data/build/dist/host/cli-adapters/command-code-driver.js +408 -105
- package/data/build/dist/host/cli-adapters/driver.d.ts +2 -0
- package/data/build/dist/host/cli-adapters/dsh-message-projector.d.ts +2 -0
- package/data/build/dist/host/cli-adapters/dsh-message-projector.js +47 -28
- package/data/build/dist/host/cli-adapters/dsh-tool-history.js +37 -0
- package/data/build/dist/host/cli-adapters/feature.js +94 -10
- package/data/build/dist/host/cli-adapters/json-rpc-process.d.ts +6 -0
- package/data/build/dist/host/cli-adapters/json-rpc-process.js +14 -3
- package/data/build/dist/host/cli-adapters/kimi-driver.js +3 -3
- package/data/build/dist/host/cli-adapters/model-catalog.d.ts +6 -0
- package/data/build/dist/host/cli-adapters/model-catalog.js +8 -0
- package/data/build/dist/host/cli-adapters/opencode-driver.js +14 -2
- package/data/build/dist/host/cli-adapters/pi-driver.js +2 -2
- package/data/build/dist/host/cli-adapters/process-utils.d.ts +8 -0
- package/data/build/dist/host/cli-adapters/process-utils.js +48 -0
- package/data/build/dist/host/cli-adapters/registry.d.ts +6 -1
- package/data/build/dist/host/cli-adapters/registry.js +41 -7
- package/data/build/dist/host/cli-adapters/rpc-driver-utils.js +23 -4
- package/data/build/dist/host/cli-adapters/standard-stream-driver.d.ts +3 -0
- package/data/build/dist/host/cli-adapters/standard-stream-driver.js +36 -15
- package/data/build/dist/host/dsh-device-runtime.d.ts +2 -0
- package/data/build/dist/host/dsh-device-runtime.js +55 -29
- package/data/build/dist/host/features/auth.js +10 -2
- package/data/build/dist/host/features/file-management.d.ts +5 -0
- package/data/build/dist/host/features/file-management.js +267 -0
- package/data/build/dist/host/features/git-management.js +24 -2
- package/data/build/dist/host/features/index.d.ts +2 -0
- package/data/build/dist/host/features/index.js +6 -0
- package/data/build/dist/host/features/peer-host.d.ts +22 -0
- package/data/build/dist/host/features/peer-host.js +322 -0
- package/data/build/dist/host/features/types.d.ts +4 -0
- package/data/build/dist/host/host-router.d.ts +3 -0
- package/data/build/dist/host/host-router.js +2 -0
- package/data/build/dist/host/index-injection.d.ts +17 -0
- package/data/build/dist/host/index-injection.js +24 -0
- package/data/build/dist/host/index.d.ts +4 -1
- package/data/build/dist/host/index.js +41 -6
- package/data/build/dist/host/lan-access-dsh.d.ts +34 -1
- package/data/build/dist/host/lan-access-dsh.js +145 -26
- package/data/build/dist/host/modules/peer-host/host-api-proxy-service.d.ts +52 -0
- package/data/build/dist/host/modules/peer-host/host-api-proxy-service.js +166 -0
- package/data/build/dist/host/modules/peer-host/host-ws-connector.d.ts +31 -0
- package/data/build/dist/host/modules/peer-host/host-ws-connector.js +108 -0
- package/data/build/dist/host/modules/peer-host/host-ws-proxy-service.d.ts +26 -0
- package/data/build/dist/host/modules/peer-host/host-ws-proxy-service.js +159 -0
- package/data/build/dist/host/modules/peer-host/peer-host-aggregate-service.d.ts +50 -0
- package/data/build/dist/host/modules/peer-host/peer-host-aggregate-service.js +97 -0
- package/data/build/dist/host/modules/peer-host/peer-host-diagnostics.d.ts +19 -0
- package/data/build/dist/host/modules/peer-host/peer-host-diagnostics.js +54 -0
- package/data/build/dist/host/modules/peer-host/peer-host-handshake.d.ts +44 -0
- package/data/build/dist/host/modules/peer-host/peer-host-handshake.js +133 -0
- package/data/build/dist/host/modules/peer-host/peer-host-relay.d.ts +65 -0
- package/data/build/dist/host/modules/peer-host/peer-host-relay.js +196 -0
- package/data/build/dist/host/modules/peer-host/peer-host-session.d.ts +42 -0
- package/data/build/dist/host/modules/peer-host/peer-host-session.js +152 -0
- package/data/build/dist/host/modules/peer-host/peer-host-store.d.ts +92 -0
- package/data/build/dist/host/modules/peer-host/peer-host-store.js +323 -0
- package/data/build/dist/host/modules/peer-host/peer-host-ws-gateway.d.ts +34 -0
- package/data/build/dist/host/modules/peer-host/peer-host-ws-gateway.js +156 -0
- package/data/build/dist/host/native-session-bridge.d.ts +18 -2
- package/data/build/dist/host/native-session-bridge.js +232 -8
- package/data/build/dist/host/remote-web-runtime.js +26 -1
- package/data/build/dist/host/rpc.js +8 -3
- package/data/build/dist/host/session-changes.d.ts +5 -0
- package/data/build/dist/host/session-changes.js +163 -0
- package/data/build/dist/host/settings.js +6 -0
- package/data/build/dist/index.d.ts +1 -1
- package/data/build/dist/index.js +1 -1
- package/data/build/dist/shared/contracts/cli-adapter.d.ts +23 -2
- package/data/build/dist/shared/contracts/config.d.ts +15 -0
- package/data/build/dist/shared/contracts/config.js +10 -0
- package/data/build/dist/shared/contracts/dsh-device.d.ts +2 -0
- package/data/build/dist/shared/contracts/errors.d.ts +14 -0
- package/data/build/dist/shared/contracts/errors.js +15 -0
- package/data/build/dist/shared/contracts/feature.d.ts +2 -0
- package/data/build/dist/shared/contracts/file-management.d.ts +6 -0
- package/data/build/dist/shared/contracts/file-management.js +3 -0
- package/data/build/dist/shared/contracts/peer-host.d.ts +116 -15
- package/data/build/dist/shared/contracts/peer-host.js +19 -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/index.d.ts +4 -3
- package/data/build/dist/shared/index.js +2 -2
- package/data/build/dist/transport/debug.d.ts +5 -0
- package/data/build/dist/transport/debug.js +23 -1
- package/data/build/dist/transport/dsh-transport.d.ts +2 -0
- package/data/build/dist/transport/dsh-transport.js +11 -0
- package/data/build/dist/transport/webrtc-client.d.ts +2 -0
- package/data/build/dist/transport/webrtc-client.js +2 -1
- package/data/build/dist/transport/webrtc-host.d.ts +2 -0
- package/data/build/dist/transport/webrtc-host.js +6 -3
- package/dsh.bundle.patch +10 -0
- package/package.json +23 -11
- package/profile/README.md +2 -2
- package/profile/package.json +2 -2
- package/profile/version.json +1 -1
- package/version.json +1 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { createElement, useEffect, useState } from 'react';
|
|
1
|
+
import { createElement, useEffect, useRef, useState } from 'react';
|
|
2
|
+
import { sameSettingsValue } from '../../dsh-capabilities/settings-store.js';
|
|
2
3
|
import { CODINGNS_CONTROL_STATION_URL, CODINGNS_CONTROL_BASE_URL_FIELD, CODINGNS_CONTROL_BASE_URLS_FIELD, CODINGNS_H5_LOGIN_URL, DEFAULT_CODINGNS_CONTROL_BASE_URLS, } from '../../shared/contracts/config.js';
|
|
3
4
|
import { CODINGNS_RPC_CHANNEL } from '../../shared/contracts/transport.js';
|
|
4
5
|
import { dshFormRootStyle, dshPopupSurfaceStyle, dshSettingsButtonStyle, dshSettingsFieldLabelStyle, dshSettingsFieldStyle, dshSettingsNoteStyle, dshSettingsPrimaryButtonStyle, dshSettingsRowStyle, dshThemeColor, } from '../theme.js';
|
|
@@ -25,14 +26,23 @@ export function ReverseProxyPanel({ services, enabled, snapshot, notify }) {
|
|
|
25
26
|
const [selectedDeviceId, setSelectedDeviceId] = useState('');
|
|
26
27
|
const [busy, setBusy] = useState(false);
|
|
27
28
|
const [h5UrlCopied, setH5UrlCopied] = useState(false);
|
|
29
|
+
// 设置快照更新与写入互相触发时必须能收敛:同一个目标地址只写入一次,
|
|
30
|
+
// 否则一旦 Host 规范化或拒绝写入,就会形成 effect → publish → effect 的
|
|
31
|
+
// 无限重渲染(React #185)。
|
|
32
|
+
const lastPersistedControlBaseUrl = useRef(null);
|
|
28
33
|
useEffect(() => {
|
|
29
34
|
const saved = snapshot.value?.controlBaseUrl;
|
|
30
35
|
const resolved = resolveControlBaseUrl(saved);
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
+
const nextUrls = uniqueControlBaseUrls(snapshot.value?.controlBaseUrls, resolved);
|
|
37
|
+
// 内容未变化时保留原有状态引用,避免设置通知引起无意义的渲染。
|
|
38
|
+
setControlBaseUrls((current) => (sameSettingsValue(current, nextUrls) ? current : nextUrls));
|
|
39
|
+
setControlBaseUrl((current) => (current === resolved ? current : resolved));
|
|
40
|
+
if (snapshot.status !== 'ready' || !snapshot.writable || saved === resolved)
|
|
41
|
+
return;
|
|
42
|
+
if (lastPersistedControlBaseUrl.current === resolved)
|
|
43
|
+
return;
|
|
44
|
+
lastPersistedControlBaseUrl.current = resolved;
|
|
45
|
+
void settings.set(CODINGNS_CONTROL_BASE_URL_FIELD, resolved).catch(() => undefined);
|
|
36
46
|
}, [settings, snapshot.status, snapshot.writable, snapshot.value?.controlBaseUrl, snapshot.value?.controlBaseUrls]);
|
|
37
47
|
useEffect(() => {
|
|
38
48
|
void callCodingNsRpc(rpc, 'auth/snapshot', {})
|
|
@@ -106,7 +116,13 @@ export function ReverseProxyPanel({ services, enabled, snapshot, notify }) {
|
|
|
106
116
|
async function loadDevicesInternal() {
|
|
107
117
|
const next = await callCodingNsRpc(rpc, 'auth/dsh/device/list', {});
|
|
108
118
|
setDevices(next);
|
|
109
|
-
const
|
|
119
|
+
const hasCurrentDevice = typeof next.currentDeviceId === 'string' && next.currentDeviceId.length > 0;
|
|
120
|
+
const current = !hasCurrentDevice
|
|
121
|
+
? undefined
|
|
122
|
+
: next.devices.find((device) => device.dshDeviceId === next.currentDeviceId && device.status === 'active');
|
|
123
|
+
const preferred = hasCurrentDevice
|
|
124
|
+
? current?.dshDeviceId ?? ''
|
|
125
|
+
: next.devices.find((device) => device.online && device.status === 'active')?.dshDeviceId ?? '';
|
|
110
126
|
setSelectedDeviceId(preferred);
|
|
111
127
|
}
|
|
112
128
|
const addControlBaseUrl = async () => {
|
|
@@ -2,6 +2,7 @@ import { ReverseProxyPanel } from './reverse-proxy-panel.js';
|
|
|
2
2
|
import { startDshH5Bootstrap } from '../dsh-h5-bootstrap.js';
|
|
3
3
|
import { callCodingNsRpc } from '../settings-bridge.js';
|
|
4
4
|
import { LOGIN_PROTECTION_SESSION_EVENT, readLoginProtectionSession } from './login-protection-session.js';
|
|
5
|
+
import { CODINGNS_DSH_ERROR_CODES } from '../../shared/index.js';
|
|
5
6
|
function isRemoteWebContext() {
|
|
6
7
|
return globalThis.__CODINGNS4DSH_REMOTE_WEB_CONTEXT__ === true;
|
|
7
8
|
}
|
|
@@ -32,24 +33,42 @@ export const reverseProxyFeature = {
|
|
|
32
33
|
* 接入连接后,流与订阅必须登记到 context.resources,由停用自动清理。
|
|
33
34
|
*/
|
|
34
35
|
start(context) {
|
|
36
|
+
const runtime = globalThis;
|
|
37
|
+
const epoch = Symbol('codingns4dsh.reverse-proxy');
|
|
38
|
+
runtime.__CODINGNS4DSH_REVERSE_PROXY_EPOCH__ = epoch;
|
|
39
|
+
const isCurrent = () => runtime.__CODINGNS4DSH_REVERSE_PROXY_EPOCH__ === epoch;
|
|
35
40
|
if (isRemoteWebContext()) {
|
|
36
41
|
// 远程 DSH Web 的外层已经拥有有效 Tunnel;这里只保留设置 UI 和其它
|
|
37
42
|
// 插件贡献,禁止同一页面重新申请票据并建立第二条中继连接。
|
|
38
|
-
return () => {
|
|
43
|
+
return () => { if (isCurrent())
|
|
44
|
+
delete runtime.__CODINGNS4DSH_REVERSE_PROXY_EPOCH__; };
|
|
45
|
+
}
|
|
46
|
+
// 页面级 Transport 已经在启动期由 DSH 或 Desktop 登记,动态功能不能在
|
|
47
|
+
// Cordis 启动后再次接管全局 Connection:两个 owner 会竞争同一个
|
|
48
|
+
// generation,插件自己的中继连接还会覆盖页面真实的传输实现。
|
|
49
|
+
// 独立 H5 页面使用专用入口(startDshH5BrowserBootstrap),不经过功能模块。
|
|
50
|
+
if (hasPageConnection(context.services)) {
|
|
51
|
+
return () => { if (isCurrent())
|
|
52
|
+
delete runtime.__CODINGNS4DSH_REVERSE_PROXY_EPOCH__; };
|
|
39
53
|
}
|
|
40
54
|
const abort = new AbortController();
|
|
41
55
|
let disposeConnection;
|
|
42
56
|
let retryTimer;
|
|
43
57
|
let stopped = false;
|
|
44
58
|
let waitingForLogin = false;
|
|
59
|
+
let attemptInFlight = false;
|
|
60
|
+
let connected = false;
|
|
61
|
+
let transportUnavailable = false;
|
|
45
62
|
const onLoginProtectionSession = () => {
|
|
46
63
|
waitingForLogin = false;
|
|
47
|
-
|
|
64
|
+
if (!connected)
|
|
65
|
+
void attempt();
|
|
48
66
|
};
|
|
49
67
|
globalThis.addEventListener(LOGIN_PROTECTION_SESSION_EVENT, onLoginProtectionSession);
|
|
50
68
|
const attempt = async () => {
|
|
51
|
-
if (stopped || waitingForLogin)
|
|
69
|
+
if (!isCurrent() || stopped || waitingForLogin || connected || transportUnavailable || attemptInFlight)
|
|
52
70
|
return;
|
|
71
|
+
attemptInFlight = true;
|
|
53
72
|
try {
|
|
54
73
|
const auth = await readAuthSnapshot(context.services.rpc);
|
|
55
74
|
if (auth.status !== 'authenticated') {
|
|
@@ -62,19 +81,38 @@ export const reverseProxyFeature = {
|
|
|
62
81
|
waitingForLogin = true;
|
|
63
82
|
return;
|
|
64
83
|
}
|
|
84
|
+
if (!isCurrent())
|
|
85
|
+
return;
|
|
65
86
|
const dispose = await startBrowserRelayConnection(context.services.rpc, abort.signal, loginProtectionToken);
|
|
87
|
+
if (!isCurrent()) {
|
|
88
|
+
await dispose();
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
66
91
|
if (stopped || abort.signal.aborted) {
|
|
67
92
|
await dispose();
|
|
68
93
|
return;
|
|
69
94
|
}
|
|
70
95
|
disposeConnection = dispose;
|
|
96
|
+
connected = true;
|
|
97
|
+
if (retryTimer !== undefined) {
|
|
98
|
+
clearTimeout(retryTimer);
|
|
99
|
+
retryTimer = undefined;
|
|
100
|
+
}
|
|
71
101
|
}
|
|
72
102
|
catch (error) {
|
|
73
|
-
if (stopped || abort.signal.aborted)
|
|
103
|
+
if (!isCurrent() || stopped || abort.signal.aborted)
|
|
104
|
+
return;
|
|
105
|
+
if (isTransportAlreadyRegistered(error)) {
|
|
106
|
+
// 这是生命周期冲突,不是网络瞬断;继续定时重试只会刷屏。
|
|
107
|
+
transportUnavailable = true;
|
|
74
108
|
return;
|
|
109
|
+
}
|
|
75
110
|
console.error('codingns4dsh: 中继连接建立失败,将在稍后重试', error);
|
|
76
111
|
scheduleRetry();
|
|
77
112
|
}
|
|
113
|
+
finally {
|
|
114
|
+
attemptInFlight = false;
|
|
115
|
+
}
|
|
78
116
|
};
|
|
79
117
|
const scheduleRetry = () => {
|
|
80
118
|
if (retryTimer !== undefined || stopped || abort.signal.aborted)
|
|
@@ -84,18 +122,50 @@ export const reverseProxyFeature = {
|
|
|
84
122
|
void attempt();
|
|
85
123
|
return async () => {
|
|
86
124
|
stopped = true;
|
|
125
|
+
connected = false;
|
|
87
126
|
globalThis.removeEventListener(LOGIN_PROTECTION_SESSION_EVENT, onLoginProtectionSession);
|
|
88
127
|
abort.abort();
|
|
89
128
|
if (retryTimer !== undefined)
|
|
90
129
|
clearTimeout(retryTimer);
|
|
91
130
|
await disposeConnection?.();
|
|
131
|
+
if (isCurrent())
|
|
132
|
+
delete runtime.__CODINGNS4DSH_REVERSE_PROXY_EPOCH__;
|
|
92
133
|
};
|
|
93
134
|
},
|
|
94
135
|
settingsPanel: ReverseProxyPanel,
|
|
95
136
|
};
|
|
137
|
+
/**
|
|
138
|
+
* 本页是否已经由 DSH Client 持有页面级 Connection。
|
|
139
|
+
*
|
|
140
|
+
* 功能模块运行在 DSH Client 内部,页面级 Transport 已由 DSH 或 Desktop 在启动期
|
|
141
|
+
* 登记。这里只读取显式的连接服务:页面级 Transport 全局同时被 Desktop 壳、Host
|
|
142
|
+
* 启动页注入行和中继 iframe 桥三方写入,用它的存在性推断运行环境无法区分
|
|
143
|
+
* 「Desktop 页面」「Host 自己的 Web 页面」和「普通浏览器页面」,一旦它的写入策略
|
|
144
|
+
* 变化,中继模块的启停就会跟着漂移。
|
|
145
|
+
*/
|
|
146
|
+
function hasPageConnection(services) {
|
|
147
|
+
const ctx = services.uiContext;
|
|
148
|
+
if (ctx === undefined || typeof ctx.get !== 'function')
|
|
149
|
+
return false;
|
|
150
|
+
try {
|
|
151
|
+
return ctx.get('connection') !== undefined;
|
|
152
|
+
}
|
|
153
|
+
catch {
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
function isTransportAlreadyRegistered(error) {
|
|
158
|
+
return typeof error === 'object' && error !== null
|
|
159
|
+
&& error.code === CODINGNS_DSH_ERROR_CODES.TRANSPORT_NOT_READY;
|
|
160
|
+
}
|
|
96
161
|
/** 浏览器侧真实中继连接;refresh token 和 access token 只经过 Host RPC。 */
|
|
97
162
|
export async function startBrowserRelayConnection(rpc, signal, loginProtectionToken) {
|
|
98
|
-
const bootstrap = await startDshH5Bootstrap({
|
|
163
|
+
const bootstrap = await startDshH5Bootstrap({
|
|
164
|
+
rpc,
|
|
165
|
+
signal,
|
|
166
|
+
...(loginProtectionToken === undefined ? {} : { loginProtectionToken }),
|
|
167
|
+
getLoginProtectionToken: readLoginProtectionSession,
|
|
168
|
+
});
|
|
99
169
|
const state = globalThis;
|
|
100
170
|
state.__CODINGNS4DSH_RELAY_MODE__ = bootstrap.relayMode;
|
|
101
171
|
return async () => {
|
|
@@ -5,6 +5,9 @@ import type { FeatureModule } from '../../shared/contracts/feature.js';
|
|
|
5
5
|
import type { CodingNsSettings } from '../../shared/contracts/config.js';
|
|
6
6
|
import type { CodingNsLocale } from '../locale.js';
|
|
7
7
|
import type { CodingNsSettingsSnapshot, CodingNsSettingsStore } from '../../dsh-capabilities/settings-store.js';
|
|
8
|
+
import type { PeerHostScopedClient } from '../peer-host-scoped-client.js';
|
|
9
|
+
import type { HostRouter } from '../host-router.js';
|
|
10
|
+
import type { PeerHostSessionController } from '../peer-host-session-controller.js';
|
|
8
11
|
/** 一次 Codingns4DSH RPC 的结果,与 DSH Connection 的结果形状一致。 */
|
|
9
12
|
export type CodingNsRpcResult = {
|
|
10
13
|
readonly ok: true;
|
|
@@ -26,6 +29,12 @@ export interface CodingNsClientServices {
|
|
|
26
29
|
readonly dshVersion: string;
|
|
27
30
|
readonly settings: CodingNsSettingsStore<CodingNsSettings>;
|
|
28
31
|
readonly rpc: CodingNsRpcClient;
|
|
32
|
+
/** PeerHost 远端资源适配器;请求始终绑定 HostScope。 */
|
|
33
|
+
readonly peerHost: PeerHostScopedClient;
|
|
34
|
+
/** 所有跨 Host 资源共用的 generation 路由器。 */
|
|
35
|
+
readonly hostRouter: HostRouter;
|
|
36
|
+
/** 远端会话的唯一控制入口;与 hostRouter 共享 generation 和清理生命周期。 */
|
|
37
|
+
readonly peerHostSession: PeerHostSessionController;
|
|
29
38
|
/** DSH Typert Remote;归档会话模块只通过运行时探测调用可选方法。 */
|
|
30
39
|
readonly remote?: unknown;
|
|
31
40
|
/** Codingns4DSH 自有终端 Remote;调试页不能依赖已停用的 DSH 官方 terminal。 */
|
|
@@ -83,6 +83,16 @@ export function WorkspaceSessionEnhancementPanel({ services, enabled, snapshot,
|
|
|
83
83
|
disabled,
|
|
84
84
|
onChange: (event) => updateSetting('showQuickPhrases', event.currentTarget.checked),
|
|
85
85
|
style: { flex: '0 0 auto', accentColor: dshThemeColor.accent },
|
|
86
|
+
})), createElement('label', {
|
|
87
|
+
style: dshSettingsListRowStyle,
|
|
88
|
+
}, createElement('span', { style: { minWidth: 0 } }, createElement('strong', { style: { display: 'block', fontSize: 13, lineHeight: 1.4 } }, t('workspace.rememberConversationRightbarRatio')), createElement('span', { style: { display: 'block', marginTop: 3, ...dshSettingsHelpStyle } }, t('workspace.rememberConversationRightbarRatioDescription'))), createElement('input', {
|
|
89
|
+
type: 'checkbox',
|
|
90
|
+
role: 'switch',
|
|
91
|
+
'aria-label': t('workspace.rememberConversationRightbarRatio'),
|
|
92
|
+
checked: value.rememberConversationRightbarRatio,
|
|
93
|
+
disabled,
|
|
94
|
+
onChange: (event) => updateSetting('rememberConversationRightbarRatio', event.currentTarget.checked),
|
|
95
|
+
style: { flex: '0 0 auto', accentColor: dshThemeColor.accent },
|
|
86
96
|
})));
|
|
87
97
|
}
|
|
88
98
|
//# sourceMappingURL=workspace-session-enhancement-panel.js.map
|
|
@@ -6,6 +6,7 @@ import { startWorkspaceSessionVisibilityDom } from '../workspace-session-visibil
|
|
|
6
6
|
import { WorkspaceSessionEnhancementPanel } from './workspace-session-enhancement-panel.js';
|
|
7
7
|
import { registerSubscriptionSlot } from '../subscription-slot.js';
|
|
8
8
|
import { registerQuickPhraseSlot } from '../quick-phrase-slot.js';
|
|
9
|
+
import { startWorkspaceSessionRightbarDom } from '../workspace-session-rightbar-dom.js';
|
|
9
10
|
/** DSH 0.1.6 原生会话行增强:Logo 与归档会话入口共用同一生命周期。 */
|
|
10
11
|
export const workspaceSessionEnhancementFeature = {
|
|
11
12
|
descriptor: {
|
|
@@ -16,7 +17,7 @@ export const workspaceSessionEnhancementFeature = {
|
|
|
16
17
|
runtime: 'client',
|
|
17
18
|
ui: {
|
|
18
19
|
label: '工作区会话增强',
|
|
19
|
-
description: '在原生工作区会话行显示 Agent Logo
|
|
20
|
+
description: '在原生工作区会话行显示 Agent Logo、归档入口、工作区隐藏/恢复入口和订阅/用量信息,提供本地快捷会话,并可记忆对话窗口与右侧栏宽度比例。',
|
|
20
21
|
labelKey: 'feature.workspaceSession.label',
|
|
21
22
|
descriptionKey: 'feature.workspaceSession.description',
|
|
22
23
|
order: 35,
|
|
@@ -30,6 +31,7 @@ export const workspaceSessionEnhancementFeature = {
|
|
|
30
31
|
let logoDom;
|
|
31
32
|
let archiveDom;
|
|
32
33
|
let visibilityDom;
|
|
34
|
+
let rightbarDom;
|
|
33
35
|
let adapterRefreshTimer;
|
|
34
36
|
let disposeSubscription;
|
|
35
37
|
let disposeQuickPhrases;
|
|
@@ -68,6 +70,14 @@ export const workspaceSessionEnhancementFeature = {
|
|
|
68
70
|
visibilityDom?.dispose();
|
|
69
71
|
visibilityDom = undefined;
|
|
70
72
|
};
|
|
73
|
+
const enableRightbarMemory = () => {
|
|
74
|
+
if (rightbarDom === undefined)
|
|
75
|
+
rightbarDom = startWorkspaceSessionRightbarDom();
|
|
76
|
+
};
|
|
77
|
+
const disableRightbarMemory = () => {
|
|
78
|
+
rightbarDom?.dispose();
|
|
79
|
+
rightbarDom = undefined;
|
|
80
|
+
};
|
|
71
81
|
const enableSubscription = () => {
|
|
72
82
|
if (disposeSubscription !== undefined || context.services.slots === undefined)
|
|
73
83
|
return;
|
|
@@ -91,6 +101,7 @@ export const workspaceSessionEnhancementFeature = {
|
|
|
91
101
|
archiveDom?.dispose();
|
|
92
102
|
archiveDom = undefined;
|
|
93
103
|
disableWorkspaceVisibility();
|
|
104
|
+
disableRightbarMemory();
|
|
94
105
|
disableSubscription();
|
|
95
106
|
disableQuickPhrases();
|
|
96
107
|
};
|
|
@@ -151,6 +162,12 @@ export const workspaceSessionEnhancementFeature = {
|
|
|
151
162
|
enableQuickPhrases();
|
|
152
163
|
else
|
|
153
164
|
disableQuickPhrases();
|
|
165
|
+
const rememberConversationRightbarRatio = workspaceSettings?.rememberConversationRightbarRatio
|
|
166
|
+
?? DEFAULT_WORKSPACE_SESSION_ENHANCEMENT_SETTINGS.rememberConversationRightbarRatio;
|
|
167
|
+
if (rememberConversationRightbarRatio)
|
|
168
|
+
enableRightbarMemory();
|
|
169
|
+
else
|
|
170
|
+
disableRightbarMemory();
|
|
154
171
|
};
|
|
155
172
|
sync();
|
|
156
173
|
const unsubscribe = context.services.settings.subscribe(sync);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { CodingNsRpcClient } from './features/types.js';
|
|
2
|
+
export interface FileManagementDomOptions {
|
|
3
|
+
readonly menuEnhancement: boolean;
|
|
4
|
+
readonly fileEditor: boolean;
|
|
5
|
+
}
|
|
6
|
+
export interface FileManagementDomController {
|
|
7
|
+
setOptions(options: FileManagementDomOptions): void;
|
|
8
|
+
dispose(): void;
|
|
9
|
+
}
|
|
10
|
+
/** 给 DSH 原生文件树和文本查看器补充文件操作,不接管 DSH 自己的渲染状态。 */
|
|
11
|
+
export declare function startFileManagementDom(rpc: CodingNsRpcClient, initialOptions: FileManagementDomOptions): FileManagementDomController;
|
|
12
|
+
//# sourceMappingURL=file-management-dom.d.ts.map
|