dsh-plugin-weapp-gateway 0.8.23 → 0.8.34

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.
Files changed (71) hide show
  1. package/LICENSE +21 -21
  2. package/PROTOCOL.md +1545 -1486
  3. package/README.md +503 -464
  4. package/THIRD-PARTY-NOTICES/dsh-cost-meter.txt +31 -31
  5. package/bin/setup-ip.mjs +474 -474
  6. package/cordis.patch.yml +50 -50
  7. package/docs/agent-team-app-integration.md +945 -0
  8. package/docs/blog-mobile-gateway.md +542 -542
  9. package/docs/dsh-0.1.5-rc.2-compatibility-audit.md +255 -255
  10. package/docs/dsh-0.1.6-alpha.1-compatibility-audit.md +122 -122
  11. package/docs/dsh-0.1.7-rc.1-compatibility-audit.md +52 -52
  12. package/docs/dsh-0.2.0-rc.2-plugin-management-mobile-integration.md +109 -109
  13. package/docs/dsh-rc2-mobile-integration.md +155 -155
  14. package/docs/file-upload-app-integration.md +250 -0
  15. package/docs/multi-gateway-app-integration.md +141 -125
  16. package/docs/multi-gateway-phase1-acceptance.md +179 -179
  17. package/docs/multi-gateway-todo.md +137 -137
  18. package/docs/remote-gateway-refactor-plan.md +52 -52
  19. package/docs/runtime-architecture.architecture.json +264 -264
  20. package/docs/runtime-architecture.html +15001 -15001
  21. package/docs/runtime-architecture.visual-check.html +32 -32
  22. package/docs/runtime-architecture.visual-check.json +548 -548
  23. package/docs/session-agent-preset-app-integration.md +93 -93
  24. package/docs/turn-outline-app-integration.md +196 -0
  25. package/docs/typert-remote-gateway-feature-checklist.md +294 -294
  26. package/docs/voice-input-implementation.md +219 -219
  27. package/docs/workspace-changes-mobile-integration.md +32 -32
  28. package/helper/dsh_mobile_gateway_helper.py +227 -227
  29. package/lib/account-bridge.mjs +57 -57
  30. package/lib/client.js +1409 -1361
  31. package/lib/cloudflare-tunnel.mjs +314 -314
  32. package/lib/cloudflared-binary.mjs +135 -135
  33. package/lib/context-bridge.mjs +3338 -1715
  34. package/lib/cost-meter-bridge.mjs +794 -794
  35. package/lib/cost-meter-dashboard-bridge.mjs +1655 -1449
  36. package/lib/devices.js +273 -245
  37. package/lib/dsh-host-adapter.mjs +508 -426
  38. package/lib/file-upload.mjs +205 -0
  39. package/lib/gateway-probe.mjs +6 -6
  40. package/lib/gateway-state.mjs +57 -57
  41. package/lib/gateway-tools.mjs +36 -36
  42. package/lib/history-cache.mjs +66 -0
  43. package/lib/index.mjs +4390 -3803
  44. package/lib/plugin-management.mjs +251 -233
  45. package/lib/public-endpoint-check.mjs +61 -61
  46. package/lib/relay-connector.mjs +213 -181
  47. package/lib/relay-state.mjs +83 -76
  48. package/lib/session-follower.mjs +140 -136
  49. package/lib/session-resume-bridge.mjs +86 -0
  50. package/lib/session-target.mjs +29 -0
  51. package/lib/speech-input.mjs +192 -192
  52. package/lib/vendor/cost-meter/aliyun-balance.mjs +123 -123
  53. package/lib/vendor/cost-meter/coding-plans.mjs +1668 -1668
  54. package/lib/vendor/cost-meter/credentials-shim.mjs +8 -8
  55. package/lib/vendor/cost-meter/custom-balance.mjs +281 -281
  56. package/lib/vendor/cost-meter/factory-quota.mjs +69 -69
  57. package/lib/vendor/cost-meter/gateway-quota-adapters.mjs +1006 -1006
  58. package/lib/vendor/cost-meter/gateway-quotas.mjs +664 -664
  59. package/lib/vendor/cost-meter/home-paths-shim.mjs +13 -13
  60. package/lib/vendor/cost-meter/net.mjs +183 -183
  61. package/lib/vendor/cost-meter/opendesign.mjs +204 -204
  62. package/lib/vendor/cost-meter/tokenrhythm-balance.mjs +95 -95
  63. package/lib/vendor/cost-meter/workbuddy-accounts.mjs +44 -44
  64. package/lib/vendor/cost-meter/workbuddy-transport.mjs +38 -38
  65. package/lib/vendor/cost-meter/workbuddy.mjs +356 -356
  66. package/lib/web-restart.mjs +47 -47
  67. package/lib/wire-json.mjs +7 -7
  68. package/lib/workspace-changes-bridge.mjs +32 -32
  69. package/package.json +54 -54
  70. package/relay/agent-connector.js +588 -569
  71. package/relay/vendor/tweetnacl.js +2391 -2391
@@ -1,47 +1,47 @@
1
- // Detached handoff process: only launched by the loopback-only management API.
2
- import { spawn } from 'node:child_process'
3
- import { openSync, closeSync, appendFileSync } from 'node:fs'
4
-
5
- const logFile = '/tmp/mobile-gateway.log'
6
- const note = (message) => {
7
- try { appendFileSync(logFile, `[${new Date().toISOString()}] web restart: ${message}\n`) } catch {}
8
- }
9
-
10
- try {
11
- const spec = JSON.parse(Buffer.from(process.argv[2] || '', 'base64url').toString())
12
- if (!Number.isSafeInteger(spec.pid) || spec.pid <= 0 || typeof spec.execPath !== 'string'
13
- || !Array.isArray(spec.execArgv) || !Array.isArray(spec.argv) || typeof spec.cwd !== 'string') {
14
- throw new Error('invalid restart handoff')
15
- }
16
- const deadline = Date.now() + 30_000
17
- while (Date.now() < deadline) {
18
- try { process.kill(spec.pid, 0) } catch (error) {
19
- if (error.code === 'ESRCH') break
20
- throw error
21
- }
22
- await new Promise((resolve) => setTimeout(resolve, 200))
23
- }
24
- try {
25
- process.kill(spec.pid, 0)
26
- throw new Error('old DSH Web process did not exit within 30 seconds')
27
- } catch (error) {
28
- if (error.code !== 'ESRCH') throw error
29
- }
30
- const fd = openSync(logFile, 'a')
31
- try {
32
- const child = spawn(spec.execPath, [...spec.execArgv, ...spec.argv], {
33
- cwd: spec.cwd, env: process.env, detached: true, stdio: ['ignore', fd, fd],
34
- })
35
- await new Promise((resolve, reject) => {
36
- child.once('spawn', resolve)
37
- child.once('error', reject)
38
- })
39
- child.unref()
40
- note(`started DSH Web pid=${child.pid}`)
41
- } finally {
42
- closeSync(fd)
43
- }
44
- } catch (error) {
45
- note(error?.message || String(error))
46
- process.exitCode = 1
47
- }
1
+ // Detached handoff process: only launched by the loopback-only management API.
2
+ import { spawn } from 'node:child_process'
3
+ import { openSync, closeSync, appendFileSync } from 'node:fs'
4
+
5
+ const logFile = '/tmp/mobile-gateway.log'
6
+ const note = (message) => {
7
+ try { appendFileSync(logFile, `[${new Date().toISOString()}] web restart: ${message}\n`) } catch {}
8
+ }
9
+
10
+ try {
11
+ const spec = JSON.parse(Buffer.from(process.argv[2] || '', 'base64url').toString())
12
+ if (!Number.isSafeInteger(spec.pid) || spec.pid <= 0 || typeof spec.execPath !== 'string'
13
+ || !Array.isArray(spec.execArgv) || !Array.isArray(spec.argv) || typeof spec.cwd !== 'string') {
14
+ throw new Error('invalid restart handoff')
15
+ }
16
+ const deadline = Date.now() + 30_000
17
+ while (Date.now() < deadline) {
18
+ try { process.kill(spec.pid, 0) } catch (error) {
19
+ if (error.code === 'ESRCH') break
20
+ throw error
21
+ }
22
+ await new Promise((resolve) => setTimeout(resolve, 200))
23
+ }
24
+ try {
25
+ process.kill(spec.pid, 0)
26
+ throw new Error('old DSH Web process did not exit within 30 seconds')
27
+ } catch (error) {
28
+ if (error.code !== 'ESRCH') throw error
29
+ }
30
+ const fd = openSync(logFile, 'a')
31
+ try {
32
+ const child = spawn(spec.execPath, [...spec.execArgv, ...spec.argv], {
33
+ cwd: spec.cwd, env: process.env, detached: true, stdio: ['ignore', fd, fd],
34
+ })
35
+ await new Promise((resolve, reject) => {
36
+ child.once('spawn', resolve)
37
+ child.once('error', reject)
38
+ })
39
+ child.unref()
40
+ note(`started DSH Web pid=${child.pid}`)
41
+ } finally {
42
+ closeSync(fd)
43
+ }
44
+ } catch (error) {
45
+ note(error?.message || String(error))
46
+ process.exitCode = 1
47
+ }
package/lib/wire-json.mjs CHANGED
@@ -1,7 +1,7 @@
1
- // Host 的摘要截断可能留下单个 UTF-16 代理项。JSON.stringify 会将其转义,
2
- // 但 Swift/Foundation 仍拒绝整帧;在传输边界统一输出有效 Unicode。
3
- // 不修改原对象、历史正文、有效 emoji 或字面量反斜杠转义文本。
4
- export function stringifyWireFrame(frame) {
5
- return JSON.stringify(frame, (_key, value) =>
6
- typeof value === 'string' ? value.replace(/[\uD800-\uDFFF]/gu, '\uFFFD') : value)
7
- }
1
+ // Host 的摘要截断可能留下单个 UTF-16 代理项。JSON.stringify 会将其转义,
2
+ // 但 Swift/Foundation 仍拒绝整帧;在传输边界统一输出有效 Unicode。
3
+ // 不修改原对象、历史正文、有效 emoji 或字面量反斜杠转义文本。
4
+ export function stringifyWireFrame(frame) {
5
+ return JSON.stringify(frame, (_key, value) =>
6
+ typeof value === 'string' ? value.replace(/[\uD800-\uDFFF]/gu, '\uFFFD') : value)
7
+ }
@@ -1,32 +1,32 @@
1
- export const WORKSPACE_CHANGES_TYPES = new Set(['workspace-changes-summary', 'workspace-changes-diff'])
2
-
3
- export async function handleWorkspaceChanges(api, msg) {
4
- const requestId = typeof msg.requestId === 'string' ? msg.requestId : undefined
5
- const failure = (code, message) => ({ kind: 'error', requestType: msg.type, requestId, code, message })
6
- if (!requestId || requestId.length > 128 || typeof msg.sessionId !== 'string' || !msg.sessionId.trim() ||
7
- msg.sessionId.length > 512 || !Number.isSafeInteger(msg.seq) || msg.seq < 0 ||
8
- (msg.type === 'workspace-changes-diff' && (!Number.isSafeInteger(msg.index) || msg.index < 0))) {
9
- return failure('bad-request', 'Invalid workspace change coordinates')
10
- }
11
- const service = api.workspaceChanges
12
- if (!service) return failure('workspace-changes-unavailable', 'Workspace changes are unavailable on this host')
13
- try {
14
- const summary = service.summary(msg.sessionId, msg.seq)
15
- let value = null
16
- if (summary) {
17
- if (msg.type === 'workspace-changes-summary') {
18
- // Do not expose host working directories or internal snapshot locations.
19
- const { turn, total, added, deleted } = summary
20
- value = { turn, total, added, deleted, files: summary.files.map(file => ({
21
- path: file.path, display: file.display, added: file.added, deleted: file.deleted,
22
- ...(file.binary === true ? { binary: true } : {}),
23
- ...(file.oversized === true ? { oversized: true } : {})
24
- })) }
25
- } else if (msg.index < summary.files.length) {
26
- value = await service.diff(msg.sessionId, msg.seq, msg.index, AbortSignal.timeout(15000)) ?? null
27
- }
28
- }
29
- return { kind: msg.type, requestId, sessionId: msg.sessionId, seq: msg.seq,
30
- ...(msg.type === 'workspace-changes-diff' ? { index: msg.index } : {}), value }
31
- } catch (_) { return failure('workspace-changes-failed', 'Unable to read workspace change snapshot') }
32
- }
1
+ export const WORKSPACE_CHANGES_TYPES = new Set(['workspace-changes-summary', 'workspace-changes-diff'])
2
+
3
+ export async function handleWorkspaceChanges(api, msg) {
4
+ const requestId = typeof msg.requestId === 'string' ? msg.requestId : undefined
5
+ const failure = (code, message) => ({ kind: 'error', requestType: msg.type, requestId, code, message })
6
+ if (!requestId || requestId.length > 128 || typeof msg.sessionId !== 'string' || !msg.sessionId.trim() ||
7
+ msg.sessionId.length > 512 || !Number.isSafeInteger(msg.seq) || msg.seq < 0 ||
8
+ (msg.type === 'workspace-changes-diff' && (!Number.isSafeInteger(msg.index) || msg.index < 0))) {
9
+ return failure('bad-request', 'Invalid workspace change coordinates')
10
+ }
11
+ const service = api.workspaceChanges
12
+ if (!service) return failure('workspace-changes-unavailable', 'Workspace changes are unavailable on this host')
13
+ try {
14
+ const summary = service.summary(msg.sessionId, msg.seq)
15
+ let value = null
16
+ if (summary) {
17
+ if (msg.type === 'workspace-changes-summary') {
18
+ // Do not expose host working directories or internal snapshot locations.
19
+ const { turn, total, added, deleted } = summary
20
+ value = { turn, total, added, deleted, files: summary.files.map(file => ({
21
+ path: file.path, display: file.display, added: file.added, deleted: file.deleted,
22
+ ...(file.binary === true ? { binary: true } : {}),
23
+ ...(file.oversized === true ? { oversized: true } : {})
24
+ })) }
25
+ } else if (msg.index < summary.files.length) {
26
+ value = await service.diff(msg.sessionId, msg.seq, msg.index, AbortSignal.timeout(15000)) ?? null
27
+ }
28
+ }
29
+ return { kind: msg.type, requestId, sessionId: msg.sessionId, seq: msg.seq,
30
+ ...(msg.type === 'workspace-changes-diff' ? { index: msg.index } : {}), value }
31
+ } catch (_) { return failure('workspace-changes-failed', 'Unable to read workspace change snapshot') }
32
+ }
package/package.json CHANGED
@@ -1,54 +1,54 @@
1
- {
2
- "name": "dsh-plugin-weapp-gateway",
3
- "version": "0.8.23",
4
- "description": "鲸尾移动网关:DeepSeek Harness 移动客户端连接与会话同步,支持安全配对、远程访问、上下文、编队、额度和语音输入",
5
- "main": "lib/index.mjs",
6
- "files": [
7
- "bin",
8
- "helper",
9
- "lib",
10
- "relay",
11
- "docs",
12
- "THIRD-PARTY-NOTICES",
13
- "locale/*.json",
14
- "cordis.patch.yml",
15
- "PROTOCOL.md"
16
- ],
17
- "repository": {
18
- "type": "git",
19
- "url": "git+https://github.com/huiikeung/dsh-plugin-weapp-gateway.git"
20
- },
21
- "homepage": "https://github.com/huiikeung/dsh-plugin-weapp-gateway#readme",
22
- "bugs": {
23
- "url": "https://github.com/huiikeung/dsh-plugin-weapp-gateway/issues"
24
- },
25
- "dependencies": {
26
- "@deepseek-ai/schemastery": "^3.18.1",
27
- "ws": "^8.18.0",
28
- "qrcode": "^1.5.4"
29
- },
30
- "bin": "bin/setup-ip.mjs",
31
- "scripts": {
32
- "test": "node test/wire-json.test.mjs && node test/setup-ip.test.mjs && node test/host-adapter.test.mjs && node test/account-bridge.test.mjs && node test/context-bridge.test.mjs && node test/cost-meter.test.mjs && node --test test/cost-meter-dashboard.test.mjs && node test/clawbot-service.test.mjs && node test/speech-input.test.mjs && node test/speech-official.test.mjs && node test/plugin-management.test.mjs && node test/plugin-updates.test.mjs && node test/session-preset.test.mjs && node test/session-follower.test.mjs && node test/completion-notifications.test.mjs && node --test test/workspace-changes.test.mjs && node test/gateway.test.mjs && node test/auth.test.mjs && node test/lan.test.mjs && node test/cloudflared-binary.test.mjs && node test/cloudflare-tunnel.test.mjs && node --test test/public-endpoint-check.test.mjs && node test/gateway-tools.test.mjs && node test/relay-connector.test.mjs && node test/cloudflare-linux.test.mjs && node test/multi-gateway.test.mjs"
33
- },
34
- "exports": {
35
- ".": "./lib/index.mjs",
36
- "./client": "./lib/client.js",
37
- "./locale/*.json": "./locale/*.json",
38
- "./package.json": "./package.json"
39
- },
40
- "dsh": {
41
- "bundle": {
42
- "patch": "./cordis.patch.yml"
43
- },
44
- "client": {
45
- "platform": "web",
46
- "inject": [
47
- "@deepseek-ai/dsh-client-runtime",
48
- "@deepseek-ai/dsh-client-ui-layout",
49
- "@deepseek-ai/dsh-client-ui-sidebar"
50
- ]
51
- }
52
- },
53
- "license": "MIT"
54
- }
1
+ {
2
+ "name": "dsh-plugin-weapp-gateway",
3
+ "version": "0.8.34",
4
+ "description": "鲸尾移动网关:DeepSeek Harness 移动客户端连接与会话同步,支持安全配对、远程访问、上下文、编队、额度和语音输入",
5
+ "main": "lib/index.mjs",
6
+ "files": [
7
+ "bin",
8
+ "helper",
9
+ "lib",
10
+ "relay",
11
+ "docs",
12
+ "THIRD-PARTY-NOTICES",
13
+ "locale/*.json",
14
+ "cordis.patch.yml",
15
+ "PROTOCOL.md"
16
+ ],
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "git+https://github.com/huiikeung/dsh-plugin-weapp-gateway.git"
20
+ },
21
+ "homepage": "https://github.com/huiikeung/dsh-plugin-weapp-gateway#readme",
22
+ "bugs": {
23
+ "url": "https://github.com/huiikeung/dsh-plugin-weapp-gateway/issues"
24
+ },
25
+ "dependencies": {
26
+ "@deepseek-ai/schemastery": "^3.18.1",
27
+ "ws": "^8.18.0",
28
+ "qrcode": "^1.5.4"
29
+ },
30
+ "bin": "bin/setup-ip.mjs",
31
+ "scripts": {
32
+ "test": "node test/wire-json.test.mjs && node --test test/history-cache.test.mjs && node test/session-target.test.mjs && node test/setup-ip.test.mjs && node test/host-adapter.test.mjs && node test/file-upload-adapter.test.mjs && node test/file-upload.test.mjs && node test/agent-team.test.mjs && node test/account-bridge.test.mjs && node test/context-bridge.test.mjs && node test/cost-meter.test.mjs && node --test test/cost-meter-dashboard.test.mjs && node test/clawbot-service.test.mjs && node test/speech-input.test.mjs && node test/speech-official.test.mjs && node test/plugin-management.test.mjs && node test/plugin-updates.test.mjs && node test/session-preset.test.mjs && node test/session-follower.test.mjs && node test/completion-notifications.test.mjs && node --test test/workspace-changes.test.mjs && node test/gateway.test.mjs && node test/auth.test.mjs && node test/lan.test.mjs && node test/cloudflared-binary.test.mjs && node test/cloudflare-tunnel.test.mjs && node --test test/public-endpoint-check.test.mjs && node test/gateway-tools.test.mjs && node test/relay-connector.test.mjs && node test/restart-reconnect.test.mjs && node test/cloudflare-linux.test.mjs && node test/multi-gateway.test.mjs"
33
+ },
34
+ "exports": {
35
+ ".": "./lib/index.mjs",
36
+ "./client": "./lib/client.js",
37
+ "./locale/*.json": "./locale/*.json",
38
+ "./package.json": "./package.json"
39
+ },
40
+ "dsh": {
41
+ "bundle": {
42
+ "patch": "./cordis.patch.yml"
43
+ },
44
+ "client": {
45
+ "platform": "web",
46
+ "inject": [
47
+ "@deepseek-ai/dsh-client-runtime",
48
+ "@deepseek-ai/dsh-client-ui-layout",
49
+ "@deepseek-ai/dsh-client-ui-sidebar"
50
+ ]
51
+ }
52
+ },
53
+ "license": "MIT"
54
+ }