@linxin666/dsh-remote-web-ui 0.3.6 → 0.3.10
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.i18n.yaml +2 -2
- package/README.md +77 -468
- package/README.zh.md +83 -113
- package/lib/client.js +993 -203
- package/lib/client.js.map +1 -1
- package/lib/index.js +1136 -1466
- package/lib/types/client/FooterRemoteEntry.d.ts +6 -7
- package/lib/types/client/FooterRemoteEntry.d.ts.map +1 -1
- package/lib/types/client/FooterRemoteEntry.js +1 -1
- package/lib/types/client/RemoteEntry.d.ts +7 -4
- package/lib/types/client/RemoteEntry.d.ts.map +1 -1
- package/lib/types/client/RemoteEntry.js +7 -10
- package/lib/types/client/RemotePanel.d.ts +2 -2
- package/lib/types/client/RemotePanel.d.ts.map +1 -1
- package/lib/types/client/RemotePanel.js +2 -2
- package/lib/types/client/RemoteSettingsCard.d.ts +9 -5
- package/lib/types/client/RemoteSettingsCard.d.ts.map +1 -1
- package/lib/types/client/RemoteSettingsCard.js +56 -3
- package/lib/types/client/deep-link.d.ts +10 -13
- package/lib/types/client/deep-link.d.ts.map +1 -1
- package/lib/types/client/deep-link.js +14 -74
- package/lib/types/client/index.d.ts +2 -6
- package/lib/types/client/index.d.ts.map +1 -1
- package/lib/types/client/index.js +79 -39
- package/lib/types/client/locales.d.ts +32 -12
- package/lib/types/client/locales.d.ts.map +1 -1
- package/lib/types/client/locales.js +42 -22
- package/lib/types/client/mobile-adapt.d.ts +49 -0
- package/lib/types/client/mobile-adapt.d.ts.map +1 -0
- package/lib/types/client/mobile-adapt.js +1002 -0
- package/lib/types/client/pair-api.d.ts +24 -6
- package/lib/types/client/pair-api.d.ts.map +1 -1
- package/lib/types/client/pair-api.js +9 -14
- package/lib/types/client/remote-channel.d.ts +3 -0
- package/lib/types/client/remote-channel.d.ts.map +1 -1
- package/lib/types/client/remote-channel.js +35 -3
- package/lib/types/client/settings-form.d.ts +35 -43
- package/lib/types/client/settings-form.d.ts.map +1 -1
- package/lib/types/client/settings-form.js +60 -53
- package/lib/types/firewall.d.ts +75 -0
- package/lib/types/firewall.d.ts.map +1 -0
- package/lib/types/firewall.js +184 -0
- package/lib/types/gate.d.ts +11 -5
- package/lib/types/gate.d.ts.map +1 -1
- package/lib/types/gate.js +11 -5
- package/lib/types/index.d.ts +39 -10
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/index.js +206 -58
- package/lib/types/inner-auth.d.ts +32 -0
- package/lib/types/inner-auth.d.ts.map +1 -0
- package/lib/types/inner-auth.js +72 -0
- package/lib/types/lan-bind-plan.d.ts +55 -0
- package/lib/types/lan-bind-plan.d.ts.map +1 -0
- package/lib/types/lan-bind-plan.js +60 -0
- package/lib/types/lan-bind.d.ts +69 -0
- package/lib/types/lan-bind.d.ts.map +1 -0
- package/lib/types/lan-bind.js +128 -0
- package/lib/types/loopback-proxy.d.ts +9 -2
- package/lib/types/loopback-proxy.d.ts.map +1 -1
- package/lib/types/loopback-proxy.js +24 -2
- package/lib/types/pairing.d.ts +15 -3
- package/lib/types/pairing.d.ts.map +1 -1
- package/lib/types/pairing.js +20 -6
- package/lib/types/remote-api.d.ts +30 -13
- package/lib/types/remote-api.d.ts.map +1 -1
- package/lib/types/remote-api.js +55 -42
- package/lib/types/remote-channel-boot.d.ts +21 -2
- package/lib/types/remote-channel-boot.d.ts.map +1 -1
- package/lib/types/remote-channel-boot.js +65 -3
- package/lib/types/remote-channel-rules.d.ts +8 -0
- package/lib/types/remote-channel-rules.d.ts.map +1 -1
- package/lib/types/remote-channel-rules.js +9 -2
- package/lib/types/remote-methods.d.ts +45 -11
- package/lib/types/remote-methods.d.ts.map +1 -1
- package/lib/types/remote-methods.js +56 -27
- package/lib/types/remote-presence-pet.d.ts +51 -0
- package/lib/types/remote-presence-pet.d.ts.map +1 -0
- package/lib/types/remote-presence-pet.js +101 -0
- package/lib/types/routes.d.ts +76 -4
- package/lib/types/routes.d.ts.map +1 -1
- package/lib/types/routes.js +336 -19
- package/lib/types/tunnel.d.ts.map +1 -1
- package/lib/types/tunnel.js +7 -1
- package/package.json +20 -18
- package/src/client/FooterRemoteEntry.tsx +9 -10
- package/src/client/RemoteEntry.tsx +13 -14
- package/src/client/RemotePanel.tsx +5 -16
- package/src/client/RemoteSettingsCard.tsx +72 -13
- package/src/client/deep-link.ts +14 -75
- package/src/client/index.ts +82 -39
- package/src/client/locales.ts +42 -22
- package/src/client/mobile-adapt.ts +954 -0
- package/src/client/pair-api.ts +26 -15
- package/src/client/remote-channel.ts +31 -3
- package/src/client/settings-form.ts +78 -92
- package/src/dsh-home.ts +1 -1
- package/src/firewall.ts +230 -0
- package/src/gate.ts +11 -5
- package/src/index.ts +235 -65
- package/src/inner-auth.ts +85 -0
- package/src/lan-bind-plan.ts +81 -0
- package/src/lan-bind.ts +145 -0
- package/src/loopback-proxy.ts +34 -0
- package/src/pairing.persist.test.ts +1 -1
- package/src/pairing.ts +20 -6
- package/src/remote-api.ts +67 -45
- package/src/remote-channel-boot.ts +70 -3
- package/src/remote-channel-rules.ts +17 -2
- package/src/remote-methods.ts +58 -27
- package/src/remote-presence-pet.ts +129 -0
- package/src/routes.ts +358 -19
- package/src/tunnel.ts +7 -1
- package/assets/apple-touch-icon.png +0 -0
- package/assets/mobile-icon-192.png +0 -0
- package/assets/mobile-icon-512.png +0 -0
- package/assets/mobile-service-worker.js +0 -63
- package/lib/mobile.js +0 -17658
- package/lib/mobile.js.map +0 -1
- package/lib/types/mobile/PairRequiredView.d.ts +0 -7
- package/lib/types/mobile/PairRequiredView.d.ts.map +0 -1
- package/lib/types/mobile/PairRequiredView.js +0 -28
- package/lib/types/mobile/PairRequiredView.test.d.ts +0 -2
- package/lib/types/mobile/PairRequiredView.test.d.ts.map +0 -1
- package/lib/types/mobile/PairRequiredView.test.js +0 -24
- package/lib/types/mobile/api.d.ts +0 -145
- package/lib/types/mobile/api.d.ts.map +0 -1
- package/lib/types/mobile/api.js +0 -103
- package/lib/types/mobile/index.d.ts +0 -10
- package/lib/types/mobile/index.d.ts.map +0 -1
- package/lib/types/mobile/index.js +0 -38
- package/lib/types/mobile/markdown.d.ts +0 -34
- package/lib/types/mobile/markdown.d.ts.map +0 -1
- package/lib/types/mobile/markdown.js +0 -285
- package/lib/types/mobile/markdown.test.d.ts +0 -2
- package/lib/types/mobile/markdown.test.d.ts.map +0 -1
- package/lib/types/mobile/markdown.test.js +0 -79
- package/lib/types/mobile/messages.d.ts +0 -149
- package/lib/types/mobile/messages.d.ts.map +0 -1
- package/lib/types/mobile/messages.js +0 -561
- package/lib/types/mobile/messages.test.d.ts +0 -2
- package/lib/types/mobile/messages.test.d.ts.map +0 -1
- package/lib/types/mobile/messages.test.js +0 -356
- package/lib/types/mobile/mobile-styles.d.ts +0 -6
- package/lib/types/mobile/mobile-styles.d.ts.map +0 -1
- package/lib/types/mobile/mobile-styles.js +0 -1438
- package/lib/types/mobile/mobile-theme.d.ts +0 -22
- package/lib/types/mobile/mobile-theme.d.ts.map +0 -1
- package/lib/types/mobile/mobile-theme.js +0 -70
- package/lib/types/mobile/mobile-theme.test.d.ts +0 -2
- package/lib/types/mobile/mobile-theme.test.d.ts.map +0 -1
- package/lib/types/mobile/mobile-theme.test.js +0 -71
- package/lib/types/mobile/mux.d.ts +0 -128
- package/lib/types/mobile/mux.d.ts.map +0 -1
- package/lib/types/mobile/mux.js +0 -305
- package/lib/types/mobile/mux.test.d.ts +0 -2
- package/lib/types/mobile/mux.test.d.ts.map +0 -1
- package/lib/types/mobile/mux.test.js +0 -267
- package/lib/types/mobile/pairing.d.ts +0 -31
- package/lib/types/mobile/pairing.d.ts.map +0 -1
- package/lib/types/mobile/pairing.js +0 -62
- package/lib/types/mobile/rpc.d.ts +0 -38
- package/lib/types/mobile/rpc.d.ts.map +0 -1
- package/lib/types/mobile/rpc.js +0 -83
- package/lib/types/mobile/theme-toggle.d.ts +0 -12
- package/lib/types/mobile/theme-toggle.d.ts.map +0 -1
- package/lib/types/mobile/theme-toggle.js +0 -26
- package/lib/types/mobile/views/App.d.ts +0 -57
- package/lib/types/mobile/views/App.d.ts.map +0 -1
- package/lib/types/mobile/views/App.js +0 -150
- package/lib/types/mobile/views/App.test.d.ts +0 -2
- package/lib/types/mobile/views/App.test.d.ts.map +0 -1
- package/lib/types/mobile/views/App.test.js +0 -52
- package/lib/types/mobile/views/ChatView.d.ts +0 -63
- package/lib/types/mobile/views/ChatView.d.ts.map +0 -1
- package/lib/types/mobile/views/ChatView.js +0 -821
- package/lib/types/mobile/views/ChatView.stream.test.d.ts +0 -2
- package/lib/types/mobile/views/ChatView.stream.test.d.ts.map +0 -1
- package/lib/types/mobile/views/ChatView.stream.test.js +0 -236
- package/lib/types/mobile/views/ChatView.test.d.ts +0 -2
- package/lib/types/mobile/views/ChatView.test.d.ts.map +0 -1
- package/lib/types/mobile/views/ChatView.test.js +0 -718
- package/lib/types/mobile/views/SessionListView.d.ts +0 -27
- package/lib/types/mobile/views/SessionListView.d.ts.map +0 -1
- package/lib/types/mobile/views/SessionListView.js +0 -139
- package/lib/types/mobile/views/SessionListView.test.d.ts +0 -2
- package/lib/types/mobile/views/SessionListView.test.d.ts.map +0 -1
- package/lib/types/mobile/views/SessionListView.test.js +0 -167
- package/lib/types/mobile/views/WorkspaceView.d.ts +0 -21
- package/lib/types/mobile/views/WorkspaceView.d.ts.map +0 -1
- package/lib/types/mobile/views/WorkspaceView.js +0 -93
- package/lib/types/mobile/views/WorkspaceView.test.d.ts +0 -2
- package/lib/types/mobile/views/WorkspaceView.test.d.ts.map +0 -1
- package/lib/types/mobile/views/WorkspaceView.test.js +0 -183
- package/lib/types/mobile-api.d.ts +0 -65
- package/lib/types/mobile-api.d.ts.map +0 -1
- package/lib/types/mobile-api.js +0 -404
- package/lib/types/mobile-pending.d.ts +0 -38
- package/lib/types/mobile-pending.d.ts.map +0 -1
- package/lib/types/mobile-pending.js +0 -59
- package/lib/types/mobile-pwa.d.ts +0 -6
- package/lib/types/mobile-pwa.d.ts.map +0 -1
- package/lib/types/mobile-pwa.js +0 -17
- package/lib/types/mobile-routes.d.ts +0 -13
- package/lib/types/mobile-routes.d.ts.map +0 -1
- package/lib/types/mobile-routes.js +0 -217
- package/lib/types/paired-model-catalog.d.ts +0 -17
- package/lib/types/paired-model-catalog.d.ts.map +0 -1
- package/lib/types/paired-model-catalog.js +0 -311
- package/src/mobile/PairRequiredView.test.tsx +0 -28
- package/src/mobile/PairRequiredView.tsx +0 -58
- package/src/mobile/api.ts +0 -229
- package/src/mobile/index.tsx +0 -41
- package/src/mobile/markdown.test.ts +0 -91
- package/src/mobile/markdown.ts +0 -291
- package/src/mobile/messages.test.ts +0 -402
- package/src/mobile/messages.ts +0 -685
- package/src/mobile/mobile-styles.ts +0 -1439
- package/src/mobile/mobile-theme.test.ts +0 -84
- package/src/mobile/mobile-theme.ts +0 -76
- package/src/mobile/mux.test.ts +0 -314
- package/src/mobile/mux.ts +0 -336
- package/src/mobile/pairing.ts +0 -77
- package/src/mobile/rpc.ts +0 -90
- package/src/mobile/theme-toggle.tsx +0 -47
- package/src/mobile/views/App.test.tsx +0 -62
- package/src/mobile/views/App.tsx +0 -213
- package/src/mobile/views/ChatView.stream.test.tsx +0 -268
- package/src/mobile/views/ChatView.test.tsx +0 -816
- package/src/mobile/views/ChatView.tsx +0 -1342
- package/src/mobile/views/SessionListView.test.tsx +0 -207
- package/src/mobile/views/SessionListView.tsx +0 -244
- package/src/mobile/views/WorkspaceView.test.tsx +0 -227
- package/src/mobile/views/WorkspaceView.tsx +0 -245
- package/src/mobile-api.ts +0 -418
- package/src/mobile-pending.ts +0 -88
- package/src/mobile-pwa.ts +0 -19
- package/src/mobile-routes.ts +0 -231
- package/src/paired-model-catalog.ts +0 -272
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import type { MuxFrame } from '@deepseek-ai/dsh-host-apiproxy/api/events';
|
|
2
|
-
import type { RpcRequest } from '@deepseek-ai/dsh-host-apiproxy/api/rpc';
|
|
3
|
-
export interface PendingApproval {
|
|
4
|
-
rpcId: string;
|
|
5
|
-
approvalId: string;
|
|
6
|
-
toolName: string;
|
|
7
|
-
callId?: string;
|
|
8
|
-
reason?: string;
|
|
9
|
-
}
|
|
10
|
-
export interface PendingQuestion {
|
|
11
|
-
rpcId: string;
|
|
12
|
-
questions: Array<{
|
|
13
|
-
id: string;
|
|
14
|
-
question: string;
|
|
15
|
-
detail?: string;
|
|
16
|
-
header?: string;
|
|
17
|
-
options?: Array<{
|
|
18
|
-
label: string;
|
|
19
|
-
description?: string;
|
|
20
|
-
}>;
|
|
21
|
-
multiSelect?: boolean;
|
|
22
|
-
}>;
|
|
23
|
-
}
|
|
24
|
-
export interface PendingState {
|
|
25
|
-
approvals: PendingApproval[];
|
|
26
|
-
questions: PendingQuestion[];
|
|
27
|
-
}
|
|
28
|
-
export declare class PendingTracker {
|
|
29
|
-
private readonly sessions;
|
|
30
|
-
/** Process one mux frame and update the pending state. */
|
|
31
|
-
onFrame(frame: RpcRequest<MuxFrame>): void;
|
|
32
|
-
private _getOrInit;
|
|
33
|
-
/** Query pending items for a session. */
|
|
34
|
-
pending(sessionId: string): PendingState;
|
|
35
|
-
/** Clear all pending state for a session. */
|
|
36
|
-
clear(sessionId: string): void;
|
|
37
|
-
}
|
|
38
|
-
//# sourceMappingURL=mobile-pending.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mobile-pending.d.ts","sourceRoot":"","sources":["../../src/mobile-pending.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,2CAA2C,CAAA;AACzE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wCAAwC,CAAA;AAExE,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,KAAK,CAAC;QACf,EAAE,EAAE,MAAM,CAAA;QACV,QAAQ,EAAE,MAAM,CAAA;QAChB,MAAM,CAAC,EAAE,MAAM,CAAA;QACf,MAAM,CAAC,EAAE,MAAM,CAAA;QACf,OAAO,CAAC,EAAE,KAAK,CAAC;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,WAAW,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;QACxD,WAAW,CAAC,EAAE,OAAO,CAAA;KACtB,CAAC,CAAA;CACH;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,eAAe,EAAE,CAAA;IAC5B,SAAS,EAAE,eAAe,EAAE,CAAA;CAC7B;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA+F;IAExH,0DAA0D;IAC1D,OAAO,CAAC,KAAK,EAAE,UAAU,CAAC,QAAQ,CAAC,GAAG,IAAI;IA8B1C,OAAO,CAAC,UAAU;IASlB,yCAAyC;IACzC,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY;IAWxC,6CAA6C;IAC7C,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;CAG/B"}
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
export class PendingTracker {
|
|
2
|
-
sessions = new Map();
|
|
3
|
-
/** Process one mux frame and update the pending state. */
|
|
4
|
-
onFrame(frame) {
|
|
5
|
-
const payload = frame.payload;
|
|
6
|
-
if (payload.type === 'approval/requested') {
|
|
7
|
-
const state = this._getOrInit(payload.sessionId);
|
|
8
|
-
state.approvals.set(payload.approvalId, {
|
|
9
|
-
rpcId: frame.rpcId,
|
|
10
|
-
approvalId: payload.approvalId,
|
|
11
|
-
toolName: payload.toolName,
|
|
12
|
-
callId: payload.callId,
|
|
13
|
-
reason: payload.reason,
|
|
14
|
-
});
|
|
15
|
-
}
|
|
16
|
-
else if (payload.type === 'approval/resolved') {
|
|
17
|
-
const state = this.sessions.get(payload.sessionId);
|
|
18
|
-
if (state) {
|
|
19
|
-
state.approvals.delete(payload.approvalId);
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
else if (payload.type === 'question/requested') {
|
|
23
|
-
const state = this._getOrInit(payload.sessionId);
|
|
24
|
-
state.questions.push({
|
|
25
|
-
rpcId: frame.rpcId,
|
|
26
|
-
questions: payload.questions,
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
else if (payload.type === 'question/resolved') {
|
|
30
|
-
const state = this.sessions.get(payload.sessionId);
|
|
31
|
-
if (state) {
|
|
32
|
-
state.questions = state.questions.filter(q => q.rpcId !== payload.questionRpcId);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
_getOrInit(sessionId) {
|
|
37
|
-
let state = this.sessions.get(sessionId);
|
|
38
|
-
if (!state) {
|
|
39
|
-
state = { approvals: new Map(), questions: [] };
|
|
40
|
-
this.sessions.set(sessionId, state);
|
|
41
|
-
}
|
|
42
|
-
return state;
|
|
43
|
-
}
|
|
44
|
-
/** Query pending items for a session. */
|
|
45
|
-
pending(sessionId) {
|
|
46
|
-
const state = this.sessions.get(sessionId);
|
|
47
|
-
if (!state) {
|
|
48
|
-
return { approvals: [], questions: [] };
|
|
49
|
-
}
|
|
50
|
-
return {
|
|
51
|
-
approvals: Array.from(state.approvals.values()),
|
|
52
|
-
questions: state.questions,
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
/** Clear all pending state for a session. */
|
|
56
|
-
clear(sessionId) {
|
|
57
|
-
this.sessions.delete(sessionId);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
/** PWA registration for the standalone /m mobile surface. */
|
|
2
|
-
export declare const MOBILE_PWA_SCOPE = "/m/";
|
|
3
|
-
export declare const MOBILE_SERVICE_WORKER_URL = "/m/service-worker.js";
|
|
4
|
-
/** Register the mobile shell worker when the current browser supports it. */
|
|
5
|
-
export declare function registerMobilePwa(serviceWorker?: Pick<ServiceWorkerContainer, 'register'> | undefined): Promise<void>;
|
|
6
|
-
//# sourceMappingURL=mobile-pwa.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mobile-pwa.d.ts","sourceRoot":"","sources":["../../src/mobile-pwa.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAC7D,eAAO,MAAM,gBAAgB,QAAQ,CAAA;AACrC,eAAO,MAAM,yBAAyB,yBAAyB,CAAA;AAE/D,6EAA6E;AAC7E,wBAAsB,iBAAiB,CACrC,aAAa,GAAE,IAAI,CAAC,sBAAsB,EAAE,UAAU,CAAC,GAAG,SAAkF,GAC3I,OAAO,CAAC,IAAI,CAAC,CAWf"}
|
package/lib/types/mobile-pwa.js
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
/** PWA registration for the standalone /m mobile surface. */
|
|
2
|
-
export const MOBILE_PWA_SCOPE = '/m/';
|
|
3
|
-
export const MOBILE_SERVICE_WORKER_URL = '/m/service-worker.js';
|
|
4
|
-
/** Register the mobile shell worker when the current browser supports it. */
|
|
5
|
-
export async function registerMobilePwa(serviceWorker = typeof navigator === 'undefined' ? undefined : navigator.serviceWorker) {
|
|
6
|
-
if (serviceWorker === undefined)
|
|
7
|
-
return;
|
|
8
|
-
try {
|
|
9
|
-
await serviceWorker.register(MOBILE_SERVICE_WORKER_URL, {
|
|
10
|
-
scope: MOBILE_PWA_SCOPE,
|
|
11
|
-
updateViaCache: 'none',
|
|
12
|
-
});
|
|
13
|
-
}
|
|
14
|
-
catch {
|
|
15
|
-
// HTTP LAN origins cannot register workers; the online mobile UI still works.
|
|
16
|
-
}
|
|
17
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The mobile surface's page routes: /m canonicalizes to /m/, which serves the
|
|
3
|
-
* standalone phone UI. The page and worker live in the /m/ scope so the PWA
|
|
4
|
-
* can cache only its static shell; the paired-device data channel remains at
|
|
5
|
-
* /m/api and is never handled by the worker.
|
|
6
|
-
*/
|
|
7
|
-
import type { WebRoute } from '@deepseek-ai/dsh-host-webserver';
|
|
8
|
-
/**
|
|
9
|
-
* Build the mobile page routes.
|
|
10
|
-
* @returns Exact routes for the canonical page, static shell, and PWA assets.
|
|
11
|
-
*/
|
|
12
|
-
export declare function makeMobileRoutes(): WebRoute[];
|
|
13
|
-
//# sourceMappingURL=mobile-routes.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mobile-routes.d.ts","sourceRoot":"","sources":["../../src/mobile-routes.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAA;AAwH/D;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,QAAQ,EAAE,CA8F7C"}
|
|
@@ -1,217 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The mobile surface's page routes: /m canonicalizes to /m/, which serves the
|
|
3
|
-
* standalone phone UI. The page and worker live in the /m/ scope so the PWA
|
|
4
|
-
* can cache only its static shell; the paired-device data channel remains at
|
|
5
|
-
* /m/api and is never handled by the worker.
|
|
6
|
-
*/
|
|
7
|
-
import { readFile } from 'node:fs/promises';
|
|
8
|
-
import { existsSync } from 'node:fs';
|
|
9
|
-
import { fileURLToPath } from 'node:url';
|
|
10
|
-
import { gzipSync } from 'node:zlib';
|
|
11
|
-
const MOBILE_ROOT = '/m/';
|
|
12
|
-
const MOBILE_BUNDLE_URL = '/m/mobile.js';
|
|
13
|
-
const MOBILE_MANIFEST_URL = '/m/manifest.webmanifest';
|
|
14
|
-
const MOBILE_WORKER_URL = '/m/service-worker.js';
|
|
15
|
-
const MOBILE_OFFLINE_URL = '/m/offline.html';
|
|
16
|
-
/** The standalone mobile bundle (built artifact, next to this file's own lib output). */
|
|
17
|
-
function mobileBundlePath() {
|
|
18
|
-
return fileURLToPath(new URL('../lib/mobile.js', import.meta.url));
|
|
19
|
-
}
|
|
20
|
-
/** A package asset available to the host after a registry or git install. */
|
|
21
|
-
function mobileAssetPath(name) {
|
|
22
|
-
return fileURLToPath(new URL('../assets/' + name, import.meta.url));
|
|
23
|
-
}
|
|
24
|
-
/** The mobile page shell: self-contained, with no document-level user data. */
|
|
25
|
-
function pageHtml(bundleUrl) {
|
|
26
|
-
return [
|
|
27
|
-
'<!doctype html>',
|
|
28
|
-
'<html lang="zh-CN">',
|
|
29
|
-
'<head>',
|
|
30
|
-
'<meta charset="utf-8">',
|
|
31
|
-
'<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, viewport-fit=cover">',
|
|
32
|
-
'<meta name="theme-color" content="#f3f5f9">',
|
|
33
|
-
'<meta name="referrer" content="no-referrer">',
|
|
34
|
-
'<meta name="mobile-web-app-capable" content="yes">',
|
|
35
|
-
'<meta name="apple-mobile-web-app-capable" content="yes">',
|
|
36
|
-
'<meta name="apple-mobile-web-app-title" content="DSH Remote">',
|
|
37
|
-
'<link rel="manifest" href="/m/manifest.webmanifest">',
|
|
38
|
-
'<link rel="apple-touch-icon" href="/m/apple-touch-icon.png">',
|
|
39
|
-
'<title>远程访问</title>',
|
|
40
|
-
'</head>',
|
|
41
|
-
'<body>',
|
|
42
|
-
'<div id="root"></div>',
|
|
43
|
-
'<script type="module" src="' + bundleUrl + '"></script>',
|
|
44
|
-
'</body>',
|
|
45
|
-
'</html>',
|
|
46
|
-
].join('');
|
|
47
|
-
}
|
|
48
|
-
/** The installable app identity and icon declarations for the /m scope. */
|
|
49
|
-
function manifestJson() {
|
|
50
|
-
return JSON.stringify({
|
|
51
|
-
id: MOBILE_ROOT,
|
|
52
|
-
name: 'DSH Remote',
|
|
53
|
-
short_name: 'DSH Remote',
|
|
54
|
-
start_url: MOBILE_ROOT,
|
|
55
|
-
scope: MOBILE_ROOT,
|
|
56
|
-
display: 'standalone',
|
|
57
|
-
background_color: '#151424',
|
|
58
|
-
theme_color: '#f3f5f9',
|
|
59
|
-
icons: [
|
|
60
|
-
{ src: '/m/icon-192.png', sizes: '192x192', type: 'image/png', purpose: 'any' },
|
|
61
|
-
{ src: '/m/icon-512.png', sizes: '512x512', type: 'image/png', purpose: 'any maskable' },
|
|
62
|
-
],
|
|
63
|
-
}, null, 2);
|
|
64
|
-
}
|
|
65
|
-
/** A static fallback that contains no paired-device, session, or workspace data. */
|
|
66
|
-
function offlineHtml() {
|
|
67
|
-
return [
|
|
68
|
-
'<!doctype html>',
|
|
69
|
-
'<html lang="zh-CN">',
|
|
70
|
-
'<head>',
|
|
71
|
-
'<meta charset="utf-8">',
|
|
72
|
-
'<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">',
|
|
73
|
-
'<meta name="theme-color" content="#151424">',
|
|
74
|
-
'<title>DSH Remote</title>',
|
|
75
|
-
'<style>body{margin:0;background:#151424;color:#f3f5f9;font:16px system-ui,sans-serif}main{box-sizing:border-box;display:grid;min-height:100vh;place-content:center;padding:32px;text-align:center}h1{margin:0 0 12px;font-size:24px}p{margin:0;color:#c4c7d8;line-height:1.5}</style>',
|
|
76
|
-
'</head>',
|
|
77
|
-
'<body><main><h1>DSH Remote</h1><p>Cannot reach the running DSH host. Restore the connection and reopen the app.</p></main></body>',
|
|
78
|
-
'</html>',
|
|
79
|
-
].join('');
|
|
80
|
-
}
|
|
81
|
-
/** Send a small static UTF-8 body with revalidation headers. */
|
|
82
|
-
function writeStatic(res, status, type, body) {
|
|
83
|
-
res.writeHead(status, {
|
|
84
|
-
'content-type': type + '; charset=utf-8',
|
|
85
|
-
'cache-control': 'no-cache',
|
|
86
|
-
'referrer-policy': 'no-referrer',
|
|
87
|
-
});
|
|
88
|
-
res.end(body);
|
|
89
|
-
}
|
|
90
|
-
/** Send the worker with the same scope it registers for, without HTTP caching. */
|
|
91
|
-
function writeServiceWorker(res, body) {
|
|
92
|
-
res.writeHead(200, {
|
|
93
|
-
'content-type': 'text/javascript; charset=utf-8',
|
|
94
|
-
'cache-control': 'no-cache',
|
|
95
|
-
'referrer-policy': 'no-referrer',
|
|
96
|
-
'service-worker-allowed': MOBILE_ROOT,
|
|
97
|
-
});
|
|
98
|
-
res.end(body);
|
|
99
|
-
}
|
|
100
|
-
/** Send a PNG body without decoding it to UTF-8. */
|
|
101
|
-
function writePng(res, status, body) {
|
|
102
|
-
res.writeHead(status, {
|
|
103
|
-
'content-type': 'image/png',
|
|
104
|
-
'cache-control': 'public, max-age=31536000, immutable',
|
|
105
|
-
'referrer-policy': 'no-referrer',
|
|
106
|
-
});
|
|
107
|
-
res.end(body);
|
|
108
|
-
}
|
|
109
|
-
/** Canonicalize the old /m route while retaining pair and workspace query parameters. */
|
|
110
|
-
function redirectToMobileRoot(req, res) {
|
|
111
|
-
const url = new URL(req.url ?? '/m', 'http://x');
|
|
112
|
-
res.writeHead(308, {
|
|
113
|
-
location: MOBILE_ROOT + url.search,
|
|
114
|
-
'cache-control': 'no-store',
|
|
115
|
-
'referrer-policy': 'no-referrer',
|
|
116
|
-
});
|
|
117
|
-
res.end();
|
|
118
|
-
}
|
|
119
|
-
/**
|
|
120
|
-
* Build the mobile page routes.
|
|
121
|
-
* @returns Exact routes for the canonical page, static shell, and PWA assets.
|
|
122
|
-
*/
|
|
123
|
-
export function makeMobileRoutes() {
|
|
124
|
-
const handlePage = (_req, res) => {
|
|
125
|
-
writeStatic(res, 200, 'text/html', pageHtml(MOBILE_BUNDLE_URL));
|
|
126
|
-
};
|
|
127
|
-
const handleManifest = (_req, res) => {
|
|
128
|
-
writeStatic(res, 200, 'application/manifest+json', manifestJson());
|
|
129
|
-
};
|
|
130
|
-
const handleOffline = (_req, res) => {
|
|
131
|
-
writeStatic(res, 200, 'text/html', offlineHtml());
|
|
132
|
-
};
|
|
133
|
-
// The bundle is immutable for the process lifetime (a rebuild requires a
|
|
134
|
-
// host restart), so the body is read from disk once, not per phone.
|
|
135
|
-
let bundleBody;
|
|
136
|
-
let bundleGzip;
|
|
137
|
-
const handleBundle = async (req, res) => {
|
|
138
|
-
if (bundleBody === undefined) {
|
|
139
|
-
const path = mobileBundlePath();
|
|
140
|
-
if (!existsSync(path)) {
|
|
141
|
-
writeStatic(res, 503, 'text/plain', 'mobile bundle not built: run pnpm --filter @linxin666/dsh-remote-web-ui build');
|
|
142
|
-
return;
|
|
143
|
-
}
|
|
144
|
-
try {
|
|
145
|
-
bundleBody = await readFile(path, 'utf8');
|
|
146
|
-
bundleGzip = gzipSync(Buffer.from(bundleBody, 'utf8'));
|
|
147
|
-
}
|
|
148
|
-
catch {
|
|
149
|
-
writeStatic(res, 500, 'text/plain', 'failed to read the mobile bundle');
|
|
150
|
-
return;
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
const acceptEncoding = req.headers['accept-encoding'] ?? '';
|
|
154
|
-
const acceptsGzip = typeof acceptEncoding === 'string' && acceptEncoding.includes('gzip') && bundleGzip !== undefined;
|
|
155
|
-
if (acceptsGzip) {
|
|
156
|
-
res.writeHead(200, {
|
|
157
|
-
'content-type': 'text/javascript; charset=utf-8',
|
|
158
|
-
'content-encoding': 'gzip',
|
|
159
|
-
'cache-control': 'no-cache',
|
|
160
|
-
vary: 'Accept-Encoding',
|
|
161
|
-
'referrer-policy': 'no-referrer',
|
|
162
|
-
});
|
|
163
|
-
res.end(bundleGzip);
|
|
164
|
-
}
|
|
165
|
-
else {
|
|
166
|
-
res.writeHead(200, {
|
|
167
|
-
'content-type': 'text/javascript; charset=utf-8',
|
|
168
|
-
'cache-control': 'no-cache',
|
|
169
|
-
vary: 'Accept-Encoding',
|
|
170
|
-
'referrer-policy': 'no-referrer',
|
|
171
|
-
});
|
|
172
|
-
res.end(bundleBody);
|
|
173
|
-
}
|
|
174
|
-
};
|
|
175
|
-
let workerBody;
|
|
176
|
-
const handleWorker = async (_req, res) => {
|
|
177
|
-
if (workerBody === undefined) {
|
|
178
|
-
const path = mobileAssetPath('mobile-service-worker.js');
|
|
179
|
-
if (!existsSync(path)) {
|
|
180
|
-
writeStatic(res, 503, 'text/plain', 'mobile service worker not found');
|
|
181
|
-
return;
|
|
182
|
-
}
|
|
183
|
-
try {
|
|
184
|
-
workerBody = await readFile(path, 'utf8');
|
|
185
|
-
}
|
|
186
|
-
catch {
|
|
187
|
-
writeStatic(res, 500, 'text/plain', 'failed to read the mobile service worker');
|
|
188
|
-
return;
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
writeServiceWorker(res, workerBody);
|
|
192
|
-
};
|
|
193
|
-
const makeIconHandler = (asset) => async (_req, res) => {
|
|
194
|
-
const path = mobileAssetPath(asset);
|
|
195
|
-
if (!existsSync(path)) {
|
|
196
|
-
writeStatic(res, 404, 'text/plain', asset + ' not found');
|
|
197
|
-
return;
|
|
198
|
-
}
|
|
199
|
-
try {
|
|
200
|
-
writePng(res, 200, await readFile(path));
|
|
201
|
-
}
|
|
202
|
-
catch {
|
|
203
|
-
writeStatic(res, 500, 'text/plain', 'failed to read ' + asset);
|
|
204
|
-
}
|
|
205
|
-
};
|
|
206
|
-
return [
|
|
207
|
-
{ kind: 'exact', path: '/m', handler: redirectToMobileRoot },
|
|
208
|
-
{ kind: 'exact', path: MOBILE_ROOT, handler: handlePage },
|
|
209
|
-
{ kind: 'exact', path: MOBILE_BUNDLE_URL, handler: handleBundle },
|
|
210
|
-
{ kind: 'exact', path: MOBILE_MANIFEST_URL, handler: handleManifest },
|
|
211
|
-
{ kind: 'exact', path: MOBILE_WORKER_URL, handler: handleWorker },
|
|
212
|
-
{ kind: 'exact', path: MOBILE_OFFLINE_URL, handler: handleOffline },
|
|
213
|
-
{ kind: 'exact', path: '/m/apple-touch-icon.png', handler: makeIconHandler('apple-touch-icon.png') },
|
|
214
|
-
{ kind: 'exact', path: '/m/icon-192.png', handler: makeIconHandler('mobile-icon-192.png') },
|
|
215
|
-
{ kind: 'exact', path: '/m/icon-512.png', handler: makeIconHandler('mobile-icon-512.png') },
|
|
216
|
-
];
|
|
217
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import type { ApiProxy } from '@deepseek-ai/dsh-host-apiproxy/api';
|
|
2
|
-
import type { WebRoute } from '@deepseek-ai/dsh-host-webserver';
|
|
3
|
-
import type { PairingService } from './pairing.ts';
|
|
4
|
-
export declare const PAIRED_MODEL_CATALOG_PATHS: {
|
|
5
|
-
readonly catalog: "/api/pair/model-catalog";
|
|
6
|
-
readonly discover: "/api/pair/model-catalog/discover";
|
|
7
|
-
readonly upsert: "/api/pair/model-catalog/upsert";
|
|
8
|
-
};
|
|
9
|
-
export interface PairedModelCatalogDeps {
|
|
10
|
-
service: PairingService;
|
|
11
|
-
apiProxy: ApiProxy;
|
|
12
|
-
/** The LAN IP literals the host fence accepts, mirroring the /api/pair fence. */
|
|
13
|
-
lanAddresses: readonly string[];
|
|
14
|
-
}
|
|
15
|
-
/** Build the narrow paired-device model catalog routes. */
|
|
16
|
-
export declare function makePairedModelCatalogRoutes(deps: PairedModelCatalogDeps): WebRoute[];
|
|
17
|
-
//# sourceMappingURL=paired-model-catalog.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"paired-model-catalog.d.ts","sourceRoot":"","sources":["../../src/paired-model-catalog.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAqF,MAAM,oCAAoC,CAAA;AACrJ,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAA;AAE/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AA6BlD,eAAO,MAAM,0BAA0B;;;;CAI7B,CAAA;AAEV,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,cAAc,CAAA;IACvB,QAAQ,EAAE,QAAQ,CAAA;IAClB,iFAAiF;IACjF,YAAY,EAAE,SAAS,MAAM,EAAE,CAAA;CAChC;AAsJD,2DAA2D;AAC3D,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,sBAAsB,GAAG,QAAQ,EAAE,CA2ErF"}
|