@blue-soda/dsh-remote 0.5.0 → 0.5.1
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 +3 -3
- package/cordis.patch.yml +2 -2
- package/dist/client.github.js +11 -6
- package/dist/client.js +11 -6
- package/dist/index.js +32 -4
- package/dist/index.js.map +2 -2
- package/dsh-plugin.json +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -23,7 +23,7 @@ Continue DeepSeek Harness sessions and experimental Codex workspaces from anothe
|
|
|
23
23
|
Add the current package version to the `web` profile, then restart Harness:
|
|
24
24
|
|
|
25
25
|
```sh
|
|
26
|
-
dsh plugin --profile web add -w @blue-soda/dsh-remote@0.
|
|
26
|
+
dsh plugin --profile web add -w @blue-soda/dsh-remote@0.5.1
|
|
27
27
|
```
|
|
28
28
|
|
|
29
29
|
### dsh-TUI Host
|
|
@@ -31,7 +31,7 @@ dsh plugin --profile web add -w @blue-soda/dsh-remote@0.4.29
|
|
|
31
31
|
Remote can also run as a Host in a terminal-only [dsh-TUI](https://github.com/ccch1mneyyy/dsh-TUI) profile:
|
|
32
32
|
|
|
33
33
|
```sh
|
|
34
|
-
dsh plugin --profile dsh-tui add -w @blue-soda/dsh-remote@0.
|
|
34
|
+
dsh plugin --profile dsh-tui add -w @blue-soda/dsh-remote@0.5.1
|
|
35
35
|
```
|
|
36
36
|
|
|
37
37
|
After starting dsh-TUI, manage Remote with `/remote`, `/remote login`, `/remote status`, and `/remote logout`.
|
|
@@ -43,7 +43,7 @@ After starting dsh-TUI, manage Remote with `/remote`, `/remote login`, `/remote
|
|
|
43
43
|
- Open workspaces on another authorized computer without replacing the native Harness interface.
|
|
44
44
|
- Use the official workspace file tree and bounded read-only previews on supported Harness versions.
|
|
45
45
|
- Use an optional Host-local terminal and authorized loopback development-service previews.
|
|
46
|
-
- Open Host Codex projects in the existing Remote UI through the optional experimental Codex domain.
|
|
46
|
+
- Open Host Codex projects in the existing Remote UI through the optional experimental Codex domain. It is **off by default** since 0.5.1: turn it on in the DeepSeek Remote settings card, which starts `codex app-server` on the Host and applies immediately.
|
|
47
47
|
- Reach the Host without opening a public listening port or configuring router port forwarding.
|
|
48
48
|
|
|
49
49
|
## Compatibility
|
package/cordis.patch.yml
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
enabled: true
|
|
13
13
|
serverUrl: https://sakakibara.ink:8443
|
|
14
14
|
codex:
|
|
15
|
-
enabled:
|
|
15
|
+
enabled: false
|
|
16
16
|
binary: codex
|
|
17
17
|
- id: ds-harness-remote-tui
|
|
18
18
|
name: '@blue-soda/dsh-remote'
|
|
@@ -26,5 +26,5 @@
|
|
|
26
26
|
enabled: true
|
|
27
27
|
serverUrl: https://sakakibara.ink:8443
|
|
28
28
|
codex:
|
|
29
|
-
enabled:
|
|
29
|
+
enabled: false
|
|
30
30
|
binary: codex
|
package/dist/client.github.js
CHANGED
|
@@ -131,6 +131,11 @@
|
|
|
131
131
|
// src/defaults.ts
|
|
132
132
|
var DEFAULT_REMOTE_SERVER_URL = "https://sakakibara.ink:8443";
|
|
133
133
|
|
|
134
|
+
// src/panel-authorization.ts
|
|
135
|
+
function authorizationStillNeeded(storedLocally, deviceCount) {
|
|
136
|
+
return deviceCount > 0 ? !1 : !storedLocally;
|
|
137
|
+
}
|
|
138
|
+
|
|
134
139
|
// src/client.ts
|
|
135
140
|
var clientModuleId = "@blue-soda/dsh-remote", pendingWorkspaceSelectionKey = "dsh-remote:pending-workspace-selection", deepSeekWorkspaceIcon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAAACVBMVEUAAADy8vXx8fUsA3vyAAAAAXRSTlMAQObYZgAAAOxJREFUWMPtlsEOwyAMQxP+/6OnTZMGxHGcot3wDYgfhkJbs6urprzveGtu9d1NgEdto8w93GuA7zPS2RFg7ynsCOAokbtAmLr2YaeKgJ6fxpT8jCAC0qSqPyNoO5DXdvyouj4ClFAdYaDxK09uiBDCIYBf6CxLesnR0uF2pG+JmhCqrUb0AOvjjoQaYDTCEAAgMg5grhAeAQIB+/M15IcKlnUIp4CkTCd0AKb4zVsRSJVGYEVzT0agK107IMGMEurvromEpaX4wzk/IKw378kq4LafED6Oowxfk7AP2q8W16EdM3p29Eyvrv6vF0WIBfBziKyCAAAAAElFTkSuQmCC", gptWorkspaceIcon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAAAclBMVEX////v7+++wMf////s7O3k5OTExcrX2Ny6vMTv8PPW19yXmqRqboJmaHd3eoaqrLPs7fGMjpfb3eKlpq1eYXOxs7pWWWd+gY5HSVdRVGVub3k+QU74+Pg4OkcvMT1ISlUoKjUiIy4fICueoKkaGyUSFB21Bp+qAAAAAXRSTlMAQObYZgAABChJREFUWMPtl916qjoQhlsdEwIECEgMYCBxx/u/xT1DrFUL1LO1DtY8LSLJvPnmB4gfH//sr7TPDfvdebf/xXZbkE/4zZ0MVhGHd9zJDsv+7F3//Z69tT5wljAu3tXw+TIlzXKJlhflYmJ+5uF5WpWhb54X+C/zZCmT2wJA4dJZwus0UYjIGqWyMhVbEp4yKNRRqlv0opW5PJLJ4rFJXvP4JKDRMqturBZjkMVJFYjR6iHQDQDI4+k2k51wZbWrqwp4mR/1CVYATyko9TFGxBUqL5IvMbXSWt0T8bkGgFLqgqZBI/Uxbx5UAxLaNcCNLBpttM7wbCc1pmJOpWAsDtey68UaQMyrFgb9uxLPjqg3+nGluyKN0XUdWw0BJ0NvTFFqgzpr9J+Dh4w0Ga1qkqBNswagxdRgFPAbgHRQG5jumGWyMxrTIaRRa4AzFs0YrNMXgI4MJWnsKYFhGNMnIh/mBOPsV8CZBFjN9w8ArowxnZzDr5IcvxTaKpxJCVsoI3SWysz1UM4AqQdzlCgho1IKrK+x1mKFzisANtgEU8E7GwHDgOqxe4w9tnM166wbaA2xBMBLrTWcAGYGdCiYVUJUrMCF+7l6gklrW1RwPi8ByjuActANqhKzVWoYrFGcCFzbDgNaBrTWpncFQMcI2DfWoAiDqRCiHcYM/ZdCEKkZqfR8spj4F0CiJjv2gHL6URNoCQDaYacL6O1oFDO2eQDUFP7AKdCRdC4CRDZaNifbjA41l/uYb/SZMAFNTBGzY7sG4J2jTsJgToOzIzXF3HZqBpSOAGduXbkGEKV1OqVGqRJpRxtvwbSw5IqAiUJItwBCOT9R32FCGo3nCkAN3t0UTBRC6zDONcBeOee9pr4T+ASbnDOdc5OmtREwEEB5w8Wqgt4bOV5c7Lt9iiK8zdP/IsBbutUGX4gNwEVCqd3FUt/xYnRWt7BvPBYQjwjAGXa3ASguHVAZ/WXKlA3eZDX1wRegFsr7E2wAlB9xFbx/7MV70kFT8aqNgLL3F8nFBmA3hrn/IJHjKJOK2oj1WI4Z4FzwN/81AOhgYD6v2xbIvaZIurLC9AfvB1WLTYAoXejF1xeBL5cpBIyEbmxkZymIXwDQh1BAfOrhI1lfwtgz8tozF5T4ttf3+32AyxC6klwAgw/YVTHpoK82xYt3wLP/Bw4AAI4D7/01TLKXBj9NEz2wEuGiKpoy68S/FwCLMQAZ3gXhihaCa25vQo6RyToOz9PE6wYjJgGi1YnqZX8qMIK+TDlnargGzSv4NvFjlwXf/nfLLMrAB4O/Xl3BH0d+RIASFgDA8IYMIXgr2+cBsbDdPSwAAHjSZFmb3txETCKIxc0uWwI8rxsLJcTiVndNwyMgKljbbNN2/zcEAja2+4RgIDYN2Bu/WtAOaEodnu2dnzz/7I/Y/w/LaEcX/MdfAAAAAElFTkSuQmCC", ENABLED_QR_PROVIDERS = ["github"], QR_LOGIN_ENABLED = !1, defaultQrProvider = ENABLED_QR_PROVIDERS[0] ?? "wechat";
|
|
136
141
|
function isEnabledQrProvider(provider) {
|
|
@@ -940,7 +945,7 @@
|
|
|
940
945
|
}
|
|
941
946
|
function RemotePluginOptions(props) {
|
|
942
947
|
let { t } = props, [open, setOpen] = React.useState(props.view === "page"), [serverUrl, setServerUrl] = React.useState(""), [codexEnabled, setCodexEnabled] = React.useState(!0), [codexBinary, setCodexBinary] = React.useState("codex"), [portsBusy, setPortsBusy] = React.useState(!1), [previewPorts, setPreviewPorts] = React.useState(""), [associations, setAssociations] = React.useState({}), [loaded, setLoaded] = React.useState(!1), [writable, setWritable] = React.useState(!1), [busy, setBusy] = React.useState(!1), [terminalEnabled, setTerminalEnabled] = React.useState(!1), [terminalBusy, setTerminalBusy] = React.useState(!1), [codexBusy, setCodexBusy] = React.useState(!1), [acpBackends, setAcpBackends] = React.useState([]), [acpAvailability, setAcpAvailability] = React.useState({}), [acpChecking, setAcpChecking] = React.useState({}), [acpCheckResults, setAcpCheckResults] = React.useState({}), [addingAcp, setAddingAcp] = React.useState(!1), [acpName, setAcpName] = React.useState(""), [acpCommand, setAcpCommand] = React.useState(""), [acpArguments, setAcpArguments] = React.useState("acp"), [reconnectBusy, setReconnectBusy] = React.useState(!1), [hostStatus, setHostStatus] = React.useState(void 0), [hostName, setHostName] = React.useState(""), [hostDeviceId, setHostDeviceId] = React.useState(""), [notice, setNotice] = React.useState(void 0), [error, setError] = React.useState(void 0), [settingsView, setSettingsView] = React.useState(void 0), persistedServerUrl = settingsView?.config.serverUrl ?? DEFAULT_REMOTE_SERVER_URL, association = associations.client ?? associations.host, serverDirty = settingsView !== void 0 && serverUrl !== persistedServerUrl, draftDirty = serverDirty, applyView = (view) => {
|
|
943
|
-
setSettingsView(view), setServerUrl(view.config.serverUrl ?? DEFAULT_REMOTE_SERVER_URL), setCodexEnabled(view.config.codex?.enabled ?? !
|
|
948
|
+
setSettingsView(view), setServerUrl(view.config.serverUrl ?? DEFAULT_REMOTE_SERVER_URL), setCodexEnabled(view.config.codex?.enabled ?? !1), setCodexBinary(view.config.codex?.binary ?? "codex"), setTerminalEnabled(view.config.terminal?.enabled ?? !0), setPreviewPorts((view.config.loopback?.ports ?? []).join(", ")), setAcpBackends((view.config.acp?.backends ?? []).map((item) => ({ id: item.id, enabled: item.enabled !== !1 }))), setAcpAvailability(view.acpAvailability ?? {}), setAssociations(view.associations ?? (view.association === void 0 ? {} : { host: view.association })), setWritable(view.writable), setLoaded(!0);
|
|
944
949
|
}, load = async () => {
|
|
945
950
|
let [view, status] = await Promise.all([
|
|
946
951
|
props.control("settings.get"),
|
|
@@ -1568,9 +1573,9 @@
|
|
|
1568
1573
|
setDevices([]), setNeedsAuthorization(!1), setAuthorizationResolved(!0), setSelectedHost(void 0), setWorkspaces([]), setCodexWorkspaces([]), setShowAllWorkspaces(!1), setShowAllCodexWorkspaces(!1), setWorkspaceBackend("harness"), setCodexWorkspaceId(void 0), setPath(""), setAddingWorkspace(!1), setDirectory(void 0);
|
|
1569
1574
|
return;
|
|
1570
1575
|
}
|
|
1576
|
+
let storedLocally;
|
|
1571
1577
|
try {
|
|
1572
|
-
|
|
1573
|
-
setNeedsAuthorization(local?.stored !== !0);
|
|
1578
|
+
storedLocally = (await props.control("authorization.local"))?.stored === !0, setNeedsAuthorization(!storedLocally);
|
|
1574
1579
|
} catch {
|
|
1575
1580
|
setNeedsAuthorization(!1);
|
|
1576
1581
|
} finally {
|
|
@@ -1578,7 +1583,7 @@
|
|
|
1578
1583
|
}
|
|
1579
1584
|
try {
|
|
1580
1585
|
let nextDevices = await props.control("devices");
|
|
1581
|
-
if (setDevices(nextDevices), setNeedsAuthorization(
|
|
1586
|
+
if (setDevices(nextDevices), storedLocally !== void 0 && setNeedsAuthorization(authorizationStillNeeded(storedLocally, nextDevices.length)), selectedHost !== void 0) {
|
|
1582
1587
|
let nextSelectedHost = nextDevices.find((device) => device.deviceId === selectedHost.deviceId);
|
|
1583
1588
|
nextSelectedHost === void 0 ? (setSelectedHost(void 0), setWorkspaces([]), setCodexWorkspaces([]), setShowAllWorkspaces(!1), setShowAllCodexWorkspaces(!1), setWorkspaceBackend("harness"), setCodexWorkspaceId(void 0), setPath(""), setAddingWorkspace(!1), setDirectory(void 0)) : setSelectedHost(nextSelectedHost);
|
|
1584
1589
|
}
|
|
@@ -2291,7 +2296,7 @@
|
|
|
2291
2296
|
try {
|
|
2292
2297
|
let loaded = await control("settings.get");
|
|
2293
2298
|
if (cancelled) return;
|
|
2294
|
-
setView(loaded), setEnabled(loaded.config.codex?.enabled ?? !
|
|
2299
|
+
setView(loaded), setEnabled(loaded.config.codex?.enabled ?? !1), setBinary(loaded.config.codex?.binary ?? "codex");
|
|
2295
2300
|
} catch (cause) {
|
|
2296
2301
|
cancelled || setError(cause instanceof Error ? cause.message : String(cause));
|
|
2297
2302
|
}
|
|
@@ -2304,7 +2309,7 @@
|
|
|
2304
2309
|
if (view === void 0 || busy || settledState === "ready" || settledState === "disabled") return;
|
|
2305
2310
|
let timer = setInterval(() => {
|
|
2306
2311
|
control("settings.get").then((next) => {
|
|
2307
|
-
setView(next), setEnabled(next.config.codex?.enabled ?? !
|
|
2312
|
+
setView(next), setEnabled(next.config.codex?.enabled ?? !1), setBinary(next.config.codex?.binary ?? "codex");
|
|
2308
2313
|
}).catch(() => {
|
|
2309
2314
|
});
|
|
2310
2315
|
}, 2e3);
|
package/dist/client.js
CHANGED
|
@@ -131,6 +131,11 @@
|
|
|
131
131
|
// src/defaults.ts
|
|
132
132
|
var DEFAULT_REMOTE_SERVER_URL = "https://sakakibara.ink:8443";
|
|
133
133
|
|
|
134
|
+
// src/panel-authorization.ts
|
|
135
|
+
function authorizationStillNeeded(storedLocally, deviceCount) {
|
|
136
|
+
return deviceCount > 0 ? !1 : !storedLocally;
|
|
137
|
+
}
|
|
138
|
+
|
|
134
139
|
// src/client.ts
|
|
135
140
|
var clientModuleId = "@blue-soda/dsh-remote", pendingWorkspaceSelectionKey = "dsh-remote:pending-workspace-selection", deepSeekWorkspaceIcon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAAACVBMVEUAAADy8vXx8fUsA3vyAAAAAXRSTlMAQObYZgAAAOxJREFUWMPtlsEOwyAMQxP+/6OnTZMGxHGcot3wDYgfhkJbs6urprzveGtu9d1NgEdto8w93GuA7zPS2RFg7ynsCOAokbtAmLr2YaeKgJ6fxpT8jCAC0qSqPyNoO5DXdvyouj4ClFAdYaDxK09uiBDCIYBf6CxLesnR0uF2pG+JmhCqrUb0AOvjjoQaYDTCEAAgMg5grhAeAQIB+/M15IcKlnUIp4CkTCd0AKb4zVsRSJVGYEVzT0agK107IMGMEurvromEpaX4wzk/IKw378kq4LafED6Oowxfk7AP2q8W16EdM3p29Eyvrv6vF0WIBfBziKyCAAAAAElFTkSuQmCC", gptWorkspaceIcon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAAAclBMVEX////v7+++wMf////s7O3k5OTExcrX2Ny6vMTv8PPW19yXmqRqboJmaHd3eoaqrLPs7fGMjpfb3eKlpq1eYXOxs7pWWWd+gY5HSVdRVGVub3k+QU74+Pg4OkcvMT1ISlUoKjUiIy4fICueoKkaGyUSFB21Bp+qAAAAAXRSTlMAQObYZgAABChJREFUWMPtl916qjoQhlsdEwIECEgMYCBxx/u/xT1DrFUL1LO1DtY8LSLJvPnmB4gfH//sr7TPDfvdebf/xXZbkE/4zZ0MVhGHd9zJDsv+7F3//Z69tT5wljAu3tXw+TIlzXKJlhflYmJ+5uF5WpWhb54X+C/zZCmT2wJA4dJZwus0UYjIGqWyMhVbEp4yKNRRqlv0opW5PJLJ4rFJXvP4JKDRMqturBZjkMVJFYjR6iHQDQDI4+k2k51wZbWrqwp4mR/1CVYATyko9TFGxBUqL5IvMbXSWt0T8bkGgFLqgqZBI/Uxbx5UAxLaNcCNLBpttM7wbCc1pmJOpWAsDtey68UaQMyrFgb9uxLPjqg3+nGluyKN0XUdWw0BJ0NvTFFqgzpr9J+Dh4w0Ga1qkqBNswagxdRgFPAbgHRQG5jumGWyMxrTIaRRa4AzFs0YrNMXgI4MJWnsKYFhGNMnIh/mBOPsV8CZBFjN9w8ArowxnZzDr5IcvxTaKpxJCVsoI3SWysz1UM4AqQdzlCgho1IKrK+x1mKFzisANtgEU8E7GwHDgOqxe4w9tnM166wbaA2xBMBLrTWcAGYGdCiYVUJUrMCF+7l6gklrW1RwPi8ByjuActANqhKzVWoYrFGcCFzbDgNaBrTWpncFQMcI2DfWoAiDqRCiHcYM/ZdCEKkZqfR8spj4F0CiJjv2gHL6URNoCQDaYacL6O1oFDO2eQDUFP7AKdCRdC4CRDZaNifbjA41l/uYb/SZMAFNTBGzY7sG4J2jTsJgToOzIzXF3HZqBpSOAGduXbkGEKV1OqVGqRJpRxtvwbSw5IqAiUJItwBCOT9R32FCGo3nCkAN3t0UTBRC6zDONcBeOee9pr4T+ASbnDOdc5OmtREwEEB5w8Wqgt4bOV5c7Lt9iiK8zdP/IsBbutUGX4gNwEVCqd3FUt/xYnRWt7BvPBYQjwjAGXa3ASguHVAZ/WXKlA3eZDX1wRegFsr7E2wAlB9xFbx/7MV70kFT8aqNgLL3F8nFBmA3hrn/IJHjKJOK2oj1WI4Z4FzwN/81AOhgYD6v2xbIvaZIurLC9AfvB1WLTYAoXejF1xeBL5cpBIyEbmxkZymIXwDQh1BAfOrhI1lfwtgz8tozF5T4ttf3+32AyxC6klwAgw/YVTHpoK82xYt3wLP/Bw4AAI4D7/01TLKXBj9NEz2wEuGiKpoy68S/FwCLMQAZ3gXhihaCa25vQo6RyToOz9PE6wYjJgGi1YnqZX8qMIK+TDlnargGzSv4NvFjlwXf/nfLLMrAB4O/Xl3BH0d+RIASFgDA8IYMIXgr2+cBsbDdPSwAAHjSZFmb3txETCKIxc0uWwI8rxsLJcTiVndNwyMgKljbbNN2/zcEAja2+4RgIDYN2Bu/WtAOaEodnu2dnzz/7I/Y/w/LaEcX/MdfAAAAAElFTkSuQmCC", ENABLED_QR_PROVIDERS = ["github"], QR_LOGIN_ENABLED = !1, defaultQrProvider = ENABLED_QR_PROVIDERS[0] ?? "wechat";
|
|
136
141
|
function isEnabledQrProvider(provider) {
|
|
@@ -940,7 +945,7 @@
|
|
|
940
945
|
}
|
|
941
946
|
function RemotePluginOptions(props) {
|
|
942
947
|
let { t } = props, [open, setOpen] = React.useState(props.view === "page"), [serverUrl, setServerUrl] = React.useState(""), [codexEnabled, setCodexEnabled] = React.useState(!0), [codexBinary, setCodexBinary] = React.useState("codex"), [portsBusy, setPortsBusy] = React.useState(!1), [previewPorts, setPreviewPorts] = React.useState(""), [associations, setAssociations] = React.useState({}), [loaded, setLoaded] = React.useState(!1), [writable, setWritable] = React.useState(!1), [busy, setBusy] = React.useState(!1), [terminalEnabled, setTerminalEnabled] = React.useState(!1), [terminalBusy, setTerminalBusy] = React.useState(!1), [codexBusy, setCodexBusy] = React.useState(!1), [acpBackends, setAcpBackends] = React.useState([]), [acpAvailability, setAcpAvailability] = React.useState({}), [acpChecking, setAcpChecking] = React.useState({}), [acpCheckResults, setAcpCheckResults] = React.useState({}), [addingAcp, setAddingAcp] = React.useState(!1), [acpName, setAcpName] = React.useState(""), [acpCommand, setAcpCommand] = React.useState(""), [acpArguments, setAcpArguments] = React.useState("acp"), [reconnectBusy, setReconnectBusy] = React.useState(!1), [hostStatus, setHostStatus] = React.useState(void 0), [hostName, setHostName] = React.useState(""), [hostDeviceId, setHostDeviceId] = React.useState(""), [notice, setNotice] = React.useState(void 0), [error, setError] = React.useState(void 0), [settingsView, setSettingsView] = React.useState(void 0), persistedServerUrl = settingsView?.config.serverUrl ?? DEFAULT_REMOTE_SERVER_URL, association = associations.client ?? associations.host, serverDirty = settingsView !== void 0 && serverUrl !== persistedServerUrl, draftDirty = serverDirty, applyView = (view) => {
|
|
943
|
-
setSettingsView(view), setServerUrl(view.config.serverUrl ?? DEFAULT_REMOTE_SERVER_URL), setCodexEnabled(view.config.codex?.enabled ?? !
|
|
948
|
+
setSettingsView(view), setServerUrl(view.config.serverUrl ?? DEFAULT_REMOTE_SERVER_URL), setCodexEnabled(view.config.codex?.enabled ?? !1), setCodexBinary(view.config.codex?.binary ?? "codex"), setTerminalEnabled(view.config.terminal?.enabled ?? !0), setPreviewPorts((view.config.loopback?.ports ?? []).join(", ")), setAcpBackends((view.config.acp?.backends ?? []).map((item) => ({ id: item.id, enabled: item.enabled !== !1 }))), setAcpAvailability(view.acpAvailability ?? {}), setAssociations(view.associations ?? (view.association === void 0 ? {} : { host: view.association })), setWritable(view.writable), setLoaded(!0);
|
|
944
949
|
}, load = async () => {
|
|
945
950
|
let [view, status] = await Promise.all([
|
|
946
951
|
props.control("settings.get"),
|
|
@@ -1568,9 +1573,9 @@
|
|
|
1568
1573
|
setDevices([]), setNeedsAuthorization(!1), setAuthorizationResolved(!0), setSelectedHost(void 0), setWorkspaces([]), setCodexWorkspaces([]), setShowAllWorkspaces(!1), setShowAllCodexWorkspaces(!1), setWorkspaceBackend("harness"), setCodexWorkspaceId(void 0), setPath(""), setAddingWorkspace(!1), setDirectory(void 0);
|
|
1569
1574
|
return;
|
|
1570
1575
|
}
|
|
1576
|
+
let storedLocally;
|
|
1571
1577
|
try {
|
|
1572
|
-
|
|
1573
|
-
setNeedsAuthorization(local?.stored !== !0);
|
|
1578
|
+
storedLocally = (await props.control("authorization.local"))?.stored === !0, setNeedsAuthorization(!storedLocally);
|
|
1574
1579
|
} catch {
|
|
1575
1580
|
setNeedsAuthorization(!1);
|
|
1576
1581
|
} finally {
|
|
@@ -1578,7 +1583,7 @@
|
|
|
1578
1583
|
}
|
|
1579
1584
|
try {
|
|
1580
1585
|
let nextDevices = await props.control("devices");
|
|
1581
|
-
if (setDevices(nextDevices), setNeedsAuthorization(
|
|
1586
|
+
if (setDevices(nextDevices), storedLocally !== void 0 && setNeedsAuthorization(authorizationStillNeeded(storedLocally, nextDevices.length)), selectedHost !== void 0) {
|
|
1582
1587
|
let nextSelectedHost = nextDevices.find((device) => device.deviceId === selectedHost.deviceId);
|
|
1583
1588
|
nextSelectedHost === void 0 ? (setSelectedHost(void 0), setWorkspaces([]), setCodexWorkspaces([]), setShowAllWorkspaces(!1), setShowAllCodexWorkspaces(!1), setWorkspaceBackend("harness"), setCodexWorkspaceId(void 0), setPath(""), setAddingWorkspace(!1), setDirectory(void 0)) : setSelectedHost(nextSelectedHost);
|
|
1584
1589
|
}
|
|
@@ -2291,7 +2296,7 @@
|
|
|
2291
2296
|
try {
|
|
2292
2297
|
let loaded = await control("settings.get");
|
|
2293
2298
|
if (cancelled) return;
|
|
2294
|
-
setView(loaded), setEnabled(loaded.config.codex?.enabled ?? !
|
|
2299
|
+
setView(loaded), setEnabled(loaded.config.codex?.enabled ?? !1), setBinary(loaded.config.codex?.binary ?? "codex");
|
|
2295
2300
|
} catch (cause) {
|
|
2296
2301
|
cancelled || setError(cause instanceof Error ? cause.message : String(cause));
|
|
2297
2302
|
}
|
|
@@ -2304,7 +2309,7 @@
|
|
|
2304
2309
|
if (view === void 0 || busy || settledState === "ready" || settledState === "disabled") return;
|
|
2305
2310
|
let timer = setInterval(() => {
|
|
2306
2311
|
control("settings.get").then((next) => {
|
|
2307
|
-
setView(next), setEnabled(next.config.codex?.enabled ?? !
|
|
2312
|
+
setView(next), setEnabled(next.config.codex?.enabled ?? !1), setBinary(next.config.codex?.binary ?? "codex");
|
|
2308
2313
|
}).catch(() => {
|
|
2309
2314
|
});
|
|
2310
2315
|
}, 2e3);
|
package/dist/index.js
CHANGED
|
@@ -13429,7 +13429,11 @@ function resolveConfig(input2 = {}, env = process.env) {
|
|
|
13429
13429
|
jitter: reconnect.jitter ?? 0.2
|
|
13430
13430
|
},
|
|
13431
13431
|
codex: {
|
|
13432
|
-
|
|
13432
|
+
// Off by default (2026-10-14). Carrying another agent's workspaces is a capability the user opts into, not
|
|
13433
|
+
// one that quietly starts a second process on their machine: the domain launches `codex app-server`, probes
|
|
13434
|
+
// an account and, while unavailable, retries every minute. The bundled profile patch says the same thing, so
|
|
13435
|
+
// an install that never touches the switch has it off.
|
|
13436
|
+
enabled: parsed.codex?.enabled ?? false,
|
|
13433
13437
|
binary: parsed.codex?.binary ?? "codex"
|
|
13434
13438
|
},
|
|
13435
13439
|
acp: { enabled: parsed.acp?.enabled ?? true, backends: [.../* @__PURE__ */ new Set(["codex", "cursor", "kimi", ...parsed.acp?.backends?.map((item) => item.id) ?? []])].map((id4) => {
|
|
@@ -13458,7 +13462,7 @@ function normalizeServerUrl(value) {
|
|
|
13458
13462
|
}
|
|
13459
13463
|
|
|
13460
13464
|
// src/version.ts
|
|
13461
|
-
var PLUGIN_VERSION = "0.5.
|
|
13465
|
+
var PLUGIN_VERSION = "0.5.1";
|
|
13462
13466
|
|
|
13463
13467
|
// src/server-api.ts
|
|
13464
13468
|
var ENABLED_QR_PROVIDERS = ["github"];
|
|
@@ -21879,7 +21883,9 @@ var ClientModeRuntime = class {
|
|
|
21879
21883
|
};
|
|
21880
21884
|
}
|
|
21881
21885
|
async devices() {
|
|
21882
|
-
if (!await this.recoverHostAuthorization())
|
|
21886
|
+
if (!await this.recoverHostAuthorization()) {
|
|
21887
|
+
throw new ClientModeError("AUTH_REQUIRED", "This device is not authorized on the Server yet.");
|
|
21888
|
+
}
|
|
21883
21889
|
this.requireIdentity();
|
|
21884
21890
|
const serverDevices = await this.server.listDevices();
|
|
21885
21891
|
const remoteDevices = serverDevices.filter((device) => device.deviceId !== this.host?.hostStatus().deviceId);
|
|
@@ -26059,6 +26065,24 @@ var PluginControlRuntime = class {
|
|
|
26059
26065
|
*/
|
|
26060
26066
|
verifiedDeepSeekToken;
|
|
26061
26067
|
verifiedDeepSeekAuthorization;
|
|
26068
|
+
/**
|
|
26069
|
+
* Whether a sign-in the user asked for is in flight.
|
|
26070
|
+
*
|
|
26071
|
+
* Only a sign-in the user started may register this device. DSH's own platform session is not consent on its
|
|
26072
|
+
* own: accepting it without a click silently signed a new device into whichever DeepSeek account DSH happened
|
|
26073
|
+
* to hold, and with account creation enabled on the Server that produced a brand-new *empty* account - the
|
|
26074
|
+
* "new device lands in an empty account" report.
|
|
26075
|
+
*
|
|
26076
|
+
* The grant itself is deliberately not compared against what DSH held when the flow started. The user asked for
|
|
26077
|
+
* this sign-in and completed it in the browser, so the account DSH holds afterwards is the one they authorized;
|
|
26078
|
+
* when the platform hands back the same grant - re-authorizing as the same account does exactly that - refusing
|
|
26079
|
+
* it would only loop the user through the browser again. The cost is that a browser page the user opens and
|
|
26080
|
+
* then abandons also ends in an authorization, with the account DSH already held; they still asked for it, and
|
|
26081
|
+
* the alternative was the silent-consent bug above.
|
|
26082
|
+
*
|
|
26083
|
+
* `undefined` means no sign-in is in flight, which is also the state after a completed authorization.
|
|
26084
|
+
*/
|
|
26085
|
+
deepSeekSignIn;
|
|
26062
26086
|
register(connection, webServer) {
|
|
26063
26087
|
const statusStream = new ControlStatusStream(() => this.streamStatus());
|
|
26064
26088
|
return registerControlRoute(
|
|
@@ -26167,13 +26191,15 @@ var PluginControlRuntime = class {
|
|
|
26167
26191
|
throw new ClientModeError("METHOD_NOT_ALLOWED", "DeepSeek account sign-in is unavailable in this profile.");
|
|
26168
26192
|
}
|
|
26169
26193
|
const session = await this.deepseekSession.read();
|
|
26170
|
-
|
|
26194
|
+
const counted = session !== void 0 && this.deepSeekSignIn !== void 0;
|
|
26195
|
+
if (!counted) {
|
|
26171
26196
|
const started = await this.deepseekSession.startSignIn({
|
|
26172
26197
|
callbackOrigin: typeof value.callbackOrigin === "string" ? value.callbackOrigin : "",
|
|
26173
26198
|
loginSource: value.loginSource === "desktop" ? "desktop" : "web",
|
|
26174
26199
|
locale: typeof value.locale === "string" ? value.locale : "en",
|
|
26175
26200
|
timezoneOffsetSeconds: typeof value.timezoneOffsetSeconds === "number" ? value.timezoneOffsetSeconds : 0
|
|
26176
26201
|
});
|
|
26202
|
+
this.deepSeekSignIn = true;
|
|
26177
26203
|
return {
|
|
26178
26204
|
status: "deepseek-sign-in-required",
|
|
26179
26205
|
...started.authorizeUrl === void 0 ? {} : { authorizeUrl: started.authorizeUrl }
|
|
@@ -26186,6 +26212,7 @@ var PluginControlRuntime = class {
|
|
|
26186
26212
|
this.verifiedDeepSeekToken = session.token;
|
|
26187
26213
|
this.verifiedDeepSeekAuthorization = authorization;
|
|
26188
26214
|
}
|
|
26215
|
+
this.deepSeekSignIn = void 0;
|
|
26189
26216
|
} else {
|
|
26190
26217
|
if (typeof value.email !== "string" || typeof value.password !== "string") {
|
|
26191
26218
|
throw new ClientModeError("INVALID_MESSAGE", "Email and password are required for account authorization.");
|
|
@@ -26305,6 +26332,7 @@ var PluginControlRuntime = class {
|
|
|
26305
26332
|
const config = resolveConfig(this.settings.get());
|
|
26306
26333
|
this.verifiedDeepSeekToken = void 0;
|
|
26307
26334
|
this.verifiedDeepSeekAuthorization = void 0;
|
|
26335
|
+
this.deepSeekSignIn = void 0;
|
|
26308
26336
|
if (config.serverUrl !== void 0) {
|
|
26309
26337
|
await Promise.all([
|
|
26310
26338
|
this.client?.clearClientAuthorization(),
|