dsh-plugin-mobile-gateway 0.7.6 → 0.8.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.
@@ -0,0 +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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "dsh-plugin-mobile-gateway",
3
- "version": "0.7.6",
4
- "description": "Mobile gateway for dsh 0.1.5-rc.1/2 with per-session Agent preset selection before the first conversation, automatic preset locking after conversation starts, and live preset updates",
3
+ "version": "0.8.1",
4
+ "description": "Authenticated mobile gateway for DeepSeek Harness with LAN and Cloudflare Tunnel access, device pairing, and session sync",
5
5
  "main": "lib/index.mjs",
6
6
  "files": [
7
7
  "bin",
@@ -26,7 +26,7 @@
26
26
  },
27
27
  "bin": "bin/setup-ip.mjs",
28
28
  "scripts": {
29
- "test": "node test/wire-json.test.mjs && node test/setup-ip.test.mjs && node test/host-adapter.test.mjs && node test/session-preset.test.mjs && node test/session-follower.test.mjs && node test/gateway.test.mjs && node test/auth.test.mjs && node test/lan.test.mjs && node test/multi-gateway.test.mjs"
29
+ "test": "node test/wire-json.test.mjs && node test/setup-ip.test.mjs && node test/host-adapter.test.mjs && node test/session-preset.test.mjs && node test/session-follower.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/gateway-tools.test.mjs && node test/multi-gateway.test.mjs"
30
30
  },
31
31
  "exports": {
32
32
  ".": "./lib/index.mjs",