dsh-mobile 0.3.3 → 0.3.5
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/CHANGELOG.md +12 -0
- package/README.en.md +15 -7
- package/README.md +14 -7
- package/cordis.patch.yml +3 -0
- package/lib/client.js +25 -6
- package/lib/client.js.map +1 -1
- package/lib/index.d.mts +1 -1
- package/lib/index.mjs +38 -13
- package/lib/index.mjs.map +1 -1
- package/package.json +8 -6
package/lib/index.d.mts
CHANGED
|
@@ -312,7 +312,7 @@ declare function parseGatewayConfig(raw: unknown): ResolvedGatewayConfig;
|
|
|
312
312
|
//#endregion
|
|
313
313
|
//#region src/compatibility.d.ts
|
|
314
314
|
/** DeepSeek Harness prereleases verified by this plugin release. */
|
|
315
|
-
declare const SUPPORTED_DSH_VERSIONS: readonly ["0.1.0-rc.5", "0.1.0-rc.6", "0.1.0-rc.7", "0.1.1-rc.2", "0.1.2-alpha.1"];
|
|
315
|
+
declare const SUPPORTED_DSH_VERSIONS: readonly ["0.1.0-rc.5", "0.1.0-rc.6", "0.1.0-rc.7", "0.1.1-rc.2", "0.1.2-alpha.1", "0.1.2-alpha.2"];
|
|
316
316
|
/**
|
|
317
317
|
* Reject an unverified DeepSeek Harness Host before opening the LAN listener.
|
|
318
318
|
* @param version - Version reported by the installed DSH WebServer package.
|
package/lib/index.mjs
CHANGED
|
@@ -710,7 +710,8 @@ const SUPPORTED_DSH_VERSIONS = Object.freeze([
|
|
|
710
710
|
"0.1.0-rc.6",
|
|
711
711
|
"0.1.0-rc.7",
|
|
712
712
|
"0.1.1-rc.2",
|
|
713
|
-
"0.1.2-alpha.1"
|
|
713
|
+
"0.1.2-alpha.1",
|
|
714
|
+
"0.1.2-alpha.2"
|
|
714
715
|
]);
|
|
715
716
|
/**
|
|
716
717
|
* Reject an unverified DeepSeek Harness Host before opening the LAN listener.
|
|
@@ -2049,6 +2050,8 @@ const RUNTIME_MODULE = "@deepseek-ai/dsh-client-runtime";
|
|
|
2049
2050
|
const RENDERER_MODULE = "@deepseek-ai/dsh-client-ui-renderer";
|
|
2050
2051
|
const SIDEBAR_MODULE = "@deepseek-ai/dsh-client-ui-sidebar";
|
|
2051
2052
|
const SETTINGS_MODULE = "@deepseek-ai/dsh-client-ui-settings";
|
|
2053
|
+
const API_GATEWAY_MODULE = "@deepseek-ai/dsh-api-gateway";
|
|
2054
|
+
const API_REMOTES_MODULE = "@deepseek-ai/dsh-api-remotes";
|
|
2052
2055
|
const MOBILE_LAYOUT_DEPENDENCY_PROFILES = Object.freeze([Object.freeze({
|
|
2053
2056
|
slots: RUNTIME_MODULE,
|
|
2054
2057
|
dependencies: Object.freeze([RUNTIME_MODULE, "@deepseek-ai/dsh-client-ui-theme"])
|
|
@@ -2062,6 +2065,7 @@ const MOBILE_LAYOUT_DEPENDENCY_PROFILES = Object.freeze([Object.freeze({
|
|
|
2062
2065
|
])
|
|
2063
2066
|
})]);
|
|
2064
2067
|
const MOBILE_CSRF_FETCH_BOOTSTRAP = `(()=>{const nativeFetch=window.fetch.bind(window);window.fetch=(input,init)=>{const source=input instanceof Request?input:undefined;const method=String(init?.method??source?.method??'GET').toUpperCase();if(method==='GET'||method==='HEAD')return nativeFetch(input,init);const raw=typeof input==='string'?input:input instanceof URL?input.href:source?.url;if(raw===undefined||new URL(raw,location.href).origin!==location.origin)return nativeFetch(input,init);const headers=new Headers(init?.headers??source?.headers);if(!headers.has(${JSON.stringify(CSRF_HEADER)})){const prefix=${JSON.stringify(`${CSRF_COOKIE}=`)};const token=document.cookie.split(';').map(value=>value.trim()).find(value=>value.startsWith(prefix))?.slice(prefix.length);if(token!==undefined)headers.set(${JSON.stringify(CSRF_HEADER)},token)}return nativeFetch(input,{...init,headers})};})();`;
|
|
2068
|
+
const MOBILE_AUTHENTICATED_TRANSPORT_BOOTSTRAP = `(()=>{if(window.__DSH_TRANSPORT__!==undefined)throw new Error('DSH Mobile cannot replace an existing transport override');window.__DSH_TRANSPORT__={fetch:(input,init)=>window.fetch(input,init),ownsHost:true}})();`;
|
|
2065
2069
|
const PAIR_PAGE = `<!doctype html>
|
|
2066
2070
|
<html lang="en">
|
|
2067
2071
|
<meta charset="utf-8">
|
|
@@ -2096,12 +2100,21 @@ function ensureMobileViewport(html) {
|
|
|
2096
2100
|
function orderAuthenticatedSettings(entries, slotsProvider) {
|
|
2097
2101
|
const mobile = entries.filter((entry) => entry !== null && typeof entry === "object" && entry.id === MOBILE_CLIENT_MODULE);
|
|
2098
2102
|
const settings = entries.filter((entry) => entry !== null && typeof entry === "object" && entry.id === SETTINGS_MODULE);
|
|
2099
|
-
if (mobile.length === 0 || settings.length === 0) return;
|
|
2103
|
+
if (mobile.length === 0 || settings.length === 0) return false;
|
|
2100
2104
|
if (mobile.length !== 1 || settings.length !== 1) throw new Error("upstream DSH mobile settings graph is ambiguous");
|
|
2101
2105
|
if (!Array.isArray(mobile[0]?.inject) || !mobile[0].inject.includes(CONNECTION_MODULE) || !mobile[0].inject.includes(SIDEBAR_MODULE)) throw new Error("dsh-mobile client has unsupported dependencies");
|
|
2102
|
-
if (!Array.isArray(settings[0]?.inject)
|
|
2106
|
+
if (!Array.isArray(settings[0]?.inject)) throw new Error("upstream DSH settings module has unsupported dependencies");
|
|
2107
|
+
const remoteSettings = !settings[0].inject.includes(CONNECTION_MODULE);
|
|
2108
|
+
if (remoteSettings) {
|
|
2109
|
+
if (!settings[0].inject.includes(API_REMOTES_MODULE) || slotsProvider !== RENDERER_MODULE) throw new Error("upstream DSH settings module has unsupported dependencies");
|
|
2110
|
+
const remotes = entries.filter((entry) => entry !== null && typeof entry === "object" && entry.id === API_REMOTES_MODULE);
|
|
2111
|
+
const gateway = entries.filter((entry) => entry !== null && typeof entry === "object" && entry.id === API_GATEWAY_MODULE);
|
|
2112
|
+
if (remotes.length !== 1 || !Array.isArray(remotes[0]?.inject) || !remotes[0].inject.includes(API_GATEWAY_MODULE) || gateway.length !== 1 || !Array.isArray(gateway[0]?.inject) || !gateway[0].inject.includes(CONNECTION_MODULE)) throw new Error("upstream DSH settings Remote graph has unsupported dependencies");
|
|
2113
|
+
if (!gateway[0].inject.includes(MOBILE_CLIENT_MODULE)) gateway[0].inject = [...gateway[0].inject, MOBILE_CLIENT_MODULE];
|
|
2114
|
+
}
|
|
2103
2115
|
mobile[0].inject = [CONNECTION_MODULE, slotsProvider];
|
|
2104
2116
|
if (!settings[0].inject.includes(MOBILE_CLIENT_MODULE)) settings[0].inject = [...settings[0].inject, MOBILE_CLIENT_MODULE];
|
|
2117
|
+
return remoteSettings;
|
|
2105
2118
|
}
|
|
2106
2119
|
function revisionedMobileBatchPath(entries) {
|
|
2107
2120
|
const key = createHash("sha256").update(DSH_MOBILE_VERSION).update(JSON.stringify(entries)).digest("hex");
|
|
@@ -2128,7 +2141,7 @@ function rewriteMobileIndexWithBatch(html) {
|
|
|
2128
2141
|
if (dependencyProfile === void 0) throw new Error("upstream DSH layout module has unsupported dependencies");
|
|
2129
2142
|
layout[0].url = MOBILE_LAYOUT_PATH;
|
|
2130
2143
|
layout[0].rev = `dsh-mobile-layout-${DSH_MOBILE_VERSION}`;
|
|
2131
|
-
orderAuthenticatedSettings(entries, dependencyProfile.slots);
|
|
2144
|
+
const remoteSettings = orderAuthenticatedSettings(entries, dependencyProfile.slots);
|
|
2132
2145
|
let mobileBatch;
|
|
2133
2146
|
if (parsed.batches !== void 0) {
|
|
2134
2147
|
if (!Array.isArray(parsed.batches)) throw new Error("upstream DSH boot manifest batches are malformed");
|
|
@@ -2163,7 +2176,7 @@ function rewriteMobileIndexWithBatch(html) {
|
|
|
2163
2176
|
batches
|
|
2164
2177
|
})).digest("hex").slice(0, 16);
|
|
2165
2178
|
}
|
|
2166
|
-
const replacement = `${MOBILE_CSRF_FETCH_BOOTSTRAP}window.__DSH_MOBILE_FRONTEND__="dedicated";${assignment[0]}${JSON.stringify(parsed)};`;
|
|
2179
|
+
const replacement = `${remoteSettings ? MOBILE_AUTHENTICATED_TRANSPORT_BOOTSTRAP : ""}${MOBILE_CSRF_FETCH_BOOTSTRAP}window.__DSH_MOBILE_FRONTEND__="dedicated";${assignment[0]}${JSON.stringify(parsed)};`;
|
|
2167
2180
|
return Object.freeze({
|
|
2168
2181
|
html: ensureMobileViewport(`${html.slice(0, start)}${replacement}${html.slice(scriptEnd)}`),
|
|
2169
2182
|
...mobileBatch === void 0 ? {} : { batch: mobileBatch }
|
|
@@ -3767,12 +3780,15 @@ var MobileAccessGateway = class {
|
|
|
3767
3780
|
};
|
|
3768
3781
|
const data = (chunk) => {
|
|
3769
3782
|
buffer = Buffer.concat([buffer, chunk]);
|
|
3770
|
-
|
|
3783
|
+
const end = buffer.indexOf("\r\n\r\n");
|
|
3784
|
+
if (end < 0) {
|
|
3785
|
+
if (buffer.length >= MAX_HEADER_BYTES) failed(/* @__PURE__ */ new Error("upstream WebSocket headers are too large"));
|
|
3786
|
+
return;
|
|
3787
|
+
}
|
|
3788
|
+
if (end + 4 > MAX_HEADER_BYTES) {
|
|
3771
3789
|
failed(/* @__PURE__ */ new Error("upstream WebSocket headers are too large"));
|
|
3772
3790
|
return;
|
|
3773
3791
|
}
|
|
3774
|
-
const end = buffer.indexOf("\r\n\r\n");
|
|
3775
|
-
if (end < 0) return;
|
|
3776
3792
|
cleanup();
|
|
3777
3793
|
const lines = buffer.subarray(0, end).toString("latin1").split("\r\n");
|
|
3778
3794
|
if (lines.shift() !== "HTTP/1.1 101 Switching Protocols") {
|
|
@@ -6685,6 +6701,14 @@ function launchedProfileName(argv) {
|
|
|
6685
6701
|
}
|
|
6686
6702
|
return "web";
|
|
6687
6703
|
}
|
|
6704
|
+
/** Resolve the launcher-owned Desktop profile, or the CLI profile outside Desktop. */
|
|
6705
|
+
function releaseProfileDirectory(ctx, dshHome, argv) {
|
|
6706
|
+
const desktopProfiles = ctx.get("desktopProfiles");
|
|
6707
|
+
const desktopDirectory = desktopProfiles?.current?.dir;
|
|
6708
|
+
if (typeof desktopDirectory === "string" && isAbsolute(desktopDirectory)) return desktopDirectory;
|
|
6709
|
+
if (desktopProfiles !== void 0 || ctx.get("desktopRuntime") !== void 0) return void 0;
|
|
6710
|
+
return join(dshHome, "profiles", launchedProfileName(argv));
|
|
6711
|
+
}
|
|
6688
6712
|
async function profileDependencySpec(profileDirectory) {
|
|
6689
6713
|
try {
|
|
6690
6714
|
const value = JSON.parse(await readFile(join(profileDirectory, "package.json"), "utf8")).dependencies?.[PACKAGE_NAME];
|
|
@@ -6930,7 +6954,7 @@ var PluginReleaseManager = class {
|
|
|
6930
6954
|
/** Read cached release metadata and suppress external lookup failures. */
|
|
6931
6955
|
async status(force = false) {
|
|
6932
6956
|
if (!force && this.cache !== void 0 && this.cache.expiresAt > this.now()) return this.cache.status;
|
|
6933
|
-
const updateSupported = isRegistryPluginSpec(await profileDependencySpec(this.profileDirectory));
|
|
6957
|
+
const updateSupported = isRegistryPluginSpec(this.profileDirectory === void 0 ? void 0 : await profileDependencySpec(this.profileDirectory));
|
|
6934
6958
|
const [npmResult, androidResult] = await Promise.allSettled([fetchNpmVersion(this.fetcher), fetchAndroidVersion(this.fetcher)]);
|
|
6935
6959
|
const latestVersion = npmResult.status === "fulfilled" ? npmResult.value : void 0;
|
|
6936
6960
|
const androidVersion = androidResult.status === "fulfilled" ? androidResult.value : void 0;
|
|
@@ -6960,11 +6984,13 @@ var PluginReleaseManager = class {
|
|
|
6960
6984
|
}
|
|
6961
6985
|
}
|
|
6962
6986
|
async updateOnce() {
|
|
6987
|
+
const profileDirectory = this.profileDirectory;
|
|
6988
|
+
if (profileDirectory === void 0) throw new Error("plugin_update_unsupported");
|
|
6963
6989
|
const status = await this.status(true);
|
|
6964
6990
|
if (!status.updateSupported) throw new Error("plugin_update_unsupported");
|
|
6965
6991
|
if (!status.updateAvailable || status.latestVersion === void 0) throw new Error("plugin_update_unavailable");
|
|
6966
|
-
await this.runner(
|
|
6967
|
-
const installed = await this.installedVersionReader(
|
|
6992
|
+
await this.runner(profileDirectory, status.latestVersion);
|
|
6993
|
+
const installed = await this.installedVersionReader(profileDirectory);
|
|
6968
6994
|
if (installed !== status.latestVersion) throw new Error("plugin_update_failed");
|
|
6969
6995
|
this.cache = void 0;
|
|
6970
6996
|
return Object.freeze({
|
|
@@ -7358,8 +7384,7 @@ async function apply(ctx, config) {
|
|
|
7358
7384
|
const stateDirectory = dirname(template.stateFile);
|
|
7359
7385
|
const remoteDirectory = join(stateDirectory, "remote");
|
|
7360
7386
|
const configuredDshHome = process.env.DSH_HOME?.trim();
|
|
7361
|
-
const
|
|
7362
|
-
const releaseManager = new PluginReleaseManager({ profileDirectory: join(dshHome, "profiles", launchedProfileName(process.argv.slice(2))) });
|
|
7387
|
+
const releaseManager = new PluginReleaseManager({ profileDirectory: releaseProfileDirectory(ctx, configuredDshHome === void 0 || configuredDshHome === "" ? dirname(stateDirectory) : resolve(configuredDshHome), process.argv.slice(2)) });
|
|
7363
7388
|
const remoteProviderStore = new JsonRemoteProviderStore(join(remoteDirectory, "provider.json"), configuredRemoteProvider(process.env));
|
|
7364
7389
|
const initialRemoteProvider = (await remoteProviderStore.load()).provider;
|
|
7365
7390
|
const cpolarComponent = new CpolarComponentManager({ stateDirectory });
|