@dsh-mobile/pairing

September 1, 2026 · View on GitHub

DSH Mobile 的 Host 插件。正式版可安装在日常 :3080 或 lab :3082 web profile 中;每个 DSH 进程独立提供配对管理、回环 Host Gateway、WebRTC Direct 与加密 Tunnel Fallback。

数据路径

  1. Host Gateway 只监听回环地址,提供信令和加密 Tunnel 入口。产品 UI 在 APK 里,Gateway 不提供浏览器 Shell。
  2. Quick Tunnel 或手工配置的 Custom Endpoint 将这个有界 Gateway 暴露为 Public Endpoint。
  3. GET /pair 铸造五分钟、单次使用的 v4 offer;Android QR 使用 dsh-mobile://pair 深链。
  4. Automatic 立刻走加密 Tunnel;同网 Direct 只在短宽限内可以抢赢,迟到的 Direct 不得抢走已打开的 Tunnel。
  5. 首配签发的 Device Token 持续有效,直到 Host 侧撤销。

没有 TURN、运行时 CDN 或维护者域名依赖。Tunnel Fallback 可以走用户自己的 Host Public Endpoint,也可以显式选择官方或自托管的加密 Relay。Relay 只转发密文消息;超过旧单帧上限的 sealed frame 由 Client/Host transport 透明分片和重组。

在 GUI 中配对

打开 设置 → 插件 → 插件配置 → DSH Mobile

  • 展开卡片可查看当前 Public Endpoint 和 Host Identity。
  • 二维码只给 Android APK。
  • “刷新二维码”会立即铸造新的五分钟单次 offer。
  • “打开完整设备管理”还可查看设备、刷新既有设备二维码和执行 Host 侧撤销。

配置位置

正式版安装:

pnpm add github:NOirBRight/dsh-mobile-pairing#v0.1.12

然后把 @dsh-mobile/pairing 加入 profile 的 dsh.profile.bundles。包内的 cordis.patch.yml 会插入 Remote loader;默认配置面向日常 :3080

- id: dsh-mobile-pairing
  config:
    dshHost: 127.0.0.1
    dshPort: 3080
    gatewayBind: 127.0.0.1
    gatewayPort: 0

lab profile 使用 :3082 时,将该 profile 的配置覆盖为 dshPort: 3082 和独立的 gatewayPort。产品默认是一台 Host 一个 Gateway(gatewayPort: 0);手机只连接二维码里的 Public Endpoint,不会连到维护者机器。可选的 dsh-pair-mux 只跑在操作者自己的 Host 上回环,后端端口必须由环境变量显式给出。

默认说明
appUrldsh-mobile://pairAndroid QR / Deep Link 入口
endpointModequickGUI 只显示 quick(临时地址)和 relay(Relay);custom 仅作为旧配置兼容模式保留
customEndpointUrl旧 operator overlay 兼容字段;不在当前 GUI 选项中显示
relayUrlrelay 模式下必填,必须是无凭据的 WSS URL
gatewayBind / gatewayPort127.0.0.1 / 0Host Gateway 始终只允许回环绑定
cloudflaredPathcloudflared默认 Quick Tunnel 可执行文件
quickTunnelCommand / quickTunnelArgscloudflared 默认 argv可换成 natapp / cpolar / frpc 等能打印 HTTPS URL 的命令
quickTunnelEndpointPatterntrycloudflare.com从子进程日志里抽出 HTTPS 端点的正则
stunUrls[stun:stun.cloudflare.com:3478]仅 STUN;TURN/TURNS 会 fail loud
dshHost / dshPort127.0.0.1 / 3080有界 Gateway 的 DSH 上游;lab 写成 3082
codeTtlMs300000首配 offer/code 有效期

Quick Tunnel 其它提供者

默认是 cloudflared。下面只是配置样例,不打进 APK,也不作为产品默认依赖。{gateway} 会换成回环 Gateway URL。

# natapp
quickTunnelCommand: natapp
quickTunnelArgs: ['-authtoken', 'YOUR_TOKEN']
quickTunnelEndpointPattern: 'https://[a-z0-9-]+\\.natapp4?\\.cc\\b'

# cpolar
quickTunnelCommand: cpolar
quickTunnelArgs: ['http', '{gateway}']
quickTunnelEndpointPattern: 'https://[a-z0-9-]+\\.cpolar\\.(?:cn|top)\\b'

# frpc(仅旧 operator overlay 兼容;新用户使用 Relay)
quickTunnelCommand: frpc
quickTunnelArgs: ['-c', '/etc/frp/frpc.toml']
quickTunnelEndpointPattern: 'https://mobile\\.example\\.com\\b'

域名与 Relay

  • 临时域名:endpointMode: quick 自动生成,不能手工固定。
  • 旧 Custom Endpoint:仅为已有 operator overlay 保留兼容,不在当前 GUI 选项中展示;Relay 用户只选择两个预置 Relay 区域。
  • Relay:选择 endpointMode: relay 并填写 relayUrl。官方区域和 Docker 自托管部署见 relay/deploy/README.md。每个 Client Instance 使用独立 Room。
  • dsh.noirbright.top、dshweb.noirbright.top、dshapp.noirbright.top 等个人域名只能作为个人恢复基础设施,不是产品默认值或依赖。

严禁启动共享同一 DSH_HOME 的第二个 DSH 进程来承载本插件。

维护边界

  • 单一来源:本仓库是 @dsh-mobile/pairing 的唯一来源;dsh-mobile 等下游通过已发布的 tag/tarball 消费,不维护第二份源码镜像。
  • 设置图标兼容性:设置导航的远程图标通过临时 DOM patch 替换官方齿轮(官方 settings.section 暂无 icon 字段)。这是已接受的临时兼容性限制,Host 导航结构变更时静默回落为默认齿轮,不影响配对与会话功能。

验证

npm test
npm run typecheck
npm run build
npm run verify:packed
npm pack --dry-run

verify:packed 只消费已提交的 fixtures/alpha1/tarballs/*.tgzPROVENANCE.json,校验归档安全性、哈希、清单、导出、入口点与完整依赖闭包(按 npm semver 规则,并保留冲突依赖的嵌套版本),再在空缓存、空 store、无效 registry、隔离 userconfig 和显式 allowlist 环境中安装发布 tarball,冒烟测试 Host Webserver、Connection、Pairing 的根入口及其 ModuleLoader 客户端入口;捕获缺失导出与未声明的运行时依赖,无需联网或源码 node_modules,临时目录清理不跟随符号链接且不覆盖首个错误。PROVENANCE.json 同时绑定干净 alpha.1/e2e 来源证据与最终 0.1.12 root tarball 的 SHA-256/SHA-512。

Release installation (Latest)

Host pairing gateway, QR/device management, WebRTC Direct, and encrypted tunnel fallback. The release artifact targets DeepSeek Harness 0.1.2-alpha.1 and contains built Host/Client files only; it has no sibling-repository source, workstation path, link:, or workspace: dependency.

Latest installation (the URL never contains a version):

dsh plugin --profile web add --force \
  https://github.com/NOirBRight/dsh-mobile-pairing/releases/latest/download/dsh-mobile-pairing.tgz

Fixed-version installation:

dsh plugin --profile web add --force \
  https://github.com/NOirBRight/dsh-mobile-pairing/releases/download/v0.1.12/dsh-mobile-pairing.tgz

Update, uninstall, and verify:

# Update to the latest Release
dsh plugin --profile web add --force \
  https://github.com/NOirBRight/dsh-mobile-pairing/releases/latest/download/dsh-mobile-pairing.tgz
# Verify the loaded version
dsh plugin --profile web list
dsh plugin --profile web doctor
# Uninstall only this plugin
dsh plugin --profile web remove @dsh-mobile/pairing

Configuration: use the plugin section in Settings for Web UI plugins, or the profile dsh.profile.bundles entry for Host-only plugins. Start with this README's minimal YAML/JSON example and provide credentials/backend addresses explicitly.

Rollback: rerun the fixed v0.1.12 command, verify the profile list, then restart the Web service once. Inspect journalctl --user -u dsh-web.service and dsh plugin --profile web doctor; never put a source checkout in the production profile.

Release and integrity: v0.1.12 · SHA256SUMS.