Zum Hauptinhalt springen
C

dsh-console-plugin

chenjun25/dsh-console-plugin

Pair a phone with this computer's DSH instance by QR code or a six-digit code, then drive it remotely — send instructions, view images, answer approvals — from the panel, with public-tunnel support for pairing across networks.

Installation

dsh plugin --profile web add github:chenjun25/dsh-console-plugin

README

DSH控制台面板(dsh-console)

在 DSH 里加一块配对面板:手机扫一下二维码(或输 6 位码)就连上这台电脑的 DSH, 之后在手机 App 里收发会话、看历史、传文件。手机不在同一个网络时走公网隧道。

全部能力都在本机跑(局域网服务 + DSH 自己的会话服务),局域网内使用不依赖任何云端。


配套 App:鸿蒙「DSH控制台」

本插件是电脑这一侧,手机端要装鸿蒙 App 「DSH控制台」 配合使用。 App 只在应用商店下载,本仓不提供安装包。


能干的事

能力说明
扫码配对面板出二维码,手机 App「扫一扫」直接连上。二维码里是一次性票据,5 分钟过期、兑换即焚,长期访问码不进二维码
6 位码配对面板出 6 位数字,App 里输进去就行,手机自己找同一网络里的电脑,不用填 IP。码 15 分钟有效,用掉即作废
异地配对DSH 装在云服务器 / 手机和电脑不在同一 WiFi 时,打开「异地配对」开关,面板给出 6 位异地配对码,App 输进去也能连
公网访问开通公网访问服务后,手机在蜂窝网也能连回这台电脑(隧道由插件自己拉,不用另装东西)
状态灯顶部主卡两盏:手机连没连、这台电脑的 DSH 会话服务通不通,互不干扰
升级卡面板里直接显示 npm 上的最新版号,能一键升级 / 回滚
网页聊天DSH 侧栏底部多一个「网页聊天」入口,把网页版对话放进右侧栏,和会话并排

安装

方式 A · 一条命令装(推荐)

dsh plugin --profile web add dsh-console-plugin

--profile 后面写你自己的 profile 名(默认是 web)。这个参数不能省,省掉会直接报 required option '--profile <name>' not specified。

刚发的版本有时会装到上一个,那是 pnpm 的「最小发布龄」供应链策略在拦新包,等一会儿再装, 或者指定版本号 / 关掉这条策略:

dsh plugin --profile web add dsh-console-plugin@latest --config.minimumReleaseAge=0

方式 B · 插件页安装

DSH 侧栏 → 插件 → 「添加插件」→ 选 dsh-console-plugin-<版本>.tgz。

方式 C · 写进 profile(开发用)

profile 的 package.json 里:

"dependencies": { "dsh-console-plugin": "link:<你的插件目录绝对路径>" }

再把 "dsh-console-plugin" 加进该文件的 dsh.profile.bundles 数组,然后跑一次 pnpm install。

⚠️ 不要在 profile 的 cordis.patch.yml 里再写一遍 insert。 loader 行放在包自己的 cordis.patch.yml 里(包里已经带了)。 profile 那个文件只放 id 定向的配置覆盖 —— 重复 insert 会让插件加载两次。

配置项(一般不用动)

写在 profile 的 cordis.patch.yml 里,按 id 定向覆盖:

- id: dsh-console
  config:
    port: 8899           # 局域网服务端口
    name: "我的电脑"      # 面板上显示的节点名,默认取系统主机名
    allowShiftPort: false # 端口被占用时要不要自动往后顺延

面板上有什么

挂在 设置 → 导航列表 → DSH控制台,也挂在插件页的配置区,侧栏底部还有两个入口。

┌──────────────────────────────────────────────────────────────┐
│  [DFY]  DSH控制台        ● 手机 · 刚刚活跃  ● DSH 正常        │
│         DeepSeek Harness · 我的电脑                          │
└──────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────┐
│ 扫码连接                          [ 刷新二维码 ] [ 展开 ]     │
│  ┌──────────┐                                                │
│  │  二维码   │  ← 折叠区,点「展开」才显示                     │
│  └──────────┘                                                │
└──────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────┐
│ 6 位配对码                                                   │
│    ╔═══════════════╗                                         │
│    ║   627681      ║   ← 方框包住,15 分钟倒计时                │
│    ╚═══════════════╝   [ 换一个新码 ]                        │
│    有效 12:34,用掉即作废                                     │
└──────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────┐
│ 异地配对                                            [ 开关 ] │
│ 默认只允许同一局域网内配对。DSH 部署在云服务器 / 异地时打开。│
│  ── 打开后才出现 ──                                          │
│ 异地配对码    ******  👁    剩余 09:12    [ 换一个码 ]        │
└──────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────┐
│ 插件升级   当前版本 x.y.z   [ 检测更新 ] [ 升级 ] [ 回滚 ]     │
└──────────────────────────────────────────────────────────────┘
┌───────────────────────────┬──────────────────────────────────┐
│ 局域网直连     ● 已连接    │ 公网访问          ○ 未开通服务    │
└───────────────────────────┴──────────────────────────────────┘

两盏灯是两回事,别混:

  • 手机 · 刚刚活跃 / 手机 · 未连接 —— App 在前台时每 60 秒有心跳;切后台/锁屏后心跳停。 只要最近 10 分钟内来过请求就算连着。未连接标灰,不算错误(可能只是还没配对)。
  • DSH 正常 / 连不上 DSH:… —— 这台电脑进程内能不能拿到会话服务,跟手机通不通完全无关。 手机连不上时先看这盏:它红了是电脑的问题;它绿而手机灯灰,才是网络/配对的问题。

配色全部走主题变量(--dsw-alias-*),深色 / 浅色主题都跟着走。

侧栏两个入口:

  • 底栏「DSH控制台」—— 打开上面这块面板。真有新版本时图标上会带一个「可更新」小徽标。
  • 底栏「网页聊天」—— 在右侧栏开一个网页聊天标签页,内容就是 chat.deepseek.com。 只在 DSH 桌面端可用(需要宿主提供 webview 通道);加载失败会显示「重新加载」按钮。

怎么配对

同一个网络(最常见)

手机 App → 电脑节点 → 二选一:

方式操作
扫一扫对着面板二维码点「扫一扫」,扫完直接连上
输 6 位码把面板上那 6 位数字输进去,手机自动找同一网络里的电脑,不用填 IP

不在同一个网络

前提:先开通公网访问服务。

  1. 面板上打开「异地配对」开关(默认关,安全闸门)
  2. 下面会冒出一张「异地配对码」卡,6 位数字,15 分钟自动换一个
  3. 手机 App 输这个码就能连上

开关打开期间,任何拿到你公网地址的人都能尝试配对 —— 票据 5 分钟一次性、 异地码 15 分钟作废、公网来源输错 20 次锁 15 分钟。配好之后建议把它关掉。


公网访问与隧道

  • 公网访问靠 frpc 这个独立可执行文件。需要时插件自动下载到 ~/.dsh/frp (Windows 下是 frpc.exe),下载后先对 size、再对 sha256,任何一项不符一律不落盘。
  • 下载失败(没网 / 取不到清单 / 校验不过)时,「公网访问」卡下面会直接显示原因。 也可以自己把 frpc 丢进 ~/.dsh/frp 手动解决 —— 用户手放的 frpc 永远优先,插件不会覆盖。
  • 没开通公网访问服务的用户完全不受影响:不下载、不启动,面板上也不会多出东西。

端口

局域网服务默认 8899。6 位码那条路手机侧只探 8899,所以:

  • 端口被占时插件直接启动失败并打出该怎么办的日志,不偷偷挪(偷偷挪会让手机扫不到这台电脑)。
  • 确实要换端口,配 "port": 8900,并且让手机端同步改。
  • "allowShiftPort": true 才会恢复「占用就往后顺延 20 个端口」的行为,一般不需要。

接口

局域网路由(手机连这个)

前缀无、端口 8899,请求带 ?token=<访问码> 或 x-dsh-console-token 头。

路径方法要访问码作用
/qrGET否二维码 PNG
/claimPOST否6 位码 / 异地配对码换访问码。错码 403、格式错 400、超限 429,成功即核销
/pair/ticketPOST否一次性票据换访问码(body {"ticket":"pt_…"})。票 5 分钟过期、用一次即焚
/newcodeGET否换一张新码
/infoGET是节点信息(设备表 / 隧道 / 公网候选 / 会员状态摘要)
/sessionsGET是读 DSH 会话列表
/attachmentGET是取附件
/cmdPOST是下指令(会话收发、切模型、文件浏览、插件清单、队列、升级…)
/cloud/status /cloud/bind /cloud/redeemGET/POST—公网短 ID 与兑换码续期
/mp/api/* /mp/pair/accept——手机端专用通道(RPC + WebSocket 复用)

错误一律 {ok:false, error:"…"},不抛异常。公网配对失败时额外带一个 reason 字段 (remote-pair-off 开关没开 / need-vip 会员没开 / code-mismatch 码不对过期 / too-many 尝试过多 / bad-format 格式错),方便 App 给不同提示。

面板数据路由(DSH 客户端半边读这个)

前缀 /api/dsh-console,走 DSH 自己的 connection.fetch.register, 带 DSH 的浏览器认证层,所以裸 curl 会 401 —— 这是对的,不是 bug。

路径方法作用
/api/dsh-console/stateGET二维码、6 位码、异地配对状态、连线状态、升级状态
/api/dsh-console/newcodePOST换一张新码
/api/dsh-console/sessionsGET会话列表(App / 排查用)
/api/dsh-console/cmdPOST下指令(App / 排查用)

面板自己只读前两条,后两条留给手机端和排查。

二维码里装的是什么

dsh-console://pair?b=http://192.168.x.x:8899&k=pt_<32位hex>&n=<节点名>&i=dsh-console&c=<公网候选>&v=<每次不同>
  • b 局域网地址(云服务器部署时会变成云内网地址,这时要用异地配对码)
  • k 一次性配对票据,不是长期访问码
  • c 公网候选地址(逗号分隔),手机断 WiFi 时靠它兜底
  • v 每次都不同,只为让二维码刷新时真的重画

安全说明

  • 二维码和 6 位码都在这台电脑的屏幕上,看得到就等于能配对 —— 别在共享场合开面板
  • 没有网页版配对页:/、/pair、/web、/pet 一律 403,配对只走手机 App
  • 二维码里是一次性票据,截屏也没用(5 分钟过期、用一次即焚)
  • 6 位码 / 异地配对码都是一次性的:换成访问码立刻作废
  • /sessions、/cmd、/attachment 这些能操控 DSH 的路由必须带访问码
  • 访问码每次进程重启会变,二维码和 6 位码里都带着它,所以自动跟着更新
  • 公网来源(带转发头)默认只能走带访问码的路由,且要会员有效;免鉴权的配对页默认一律拒绝
  • 同一个网络里拿到访问码的人可以操控这台电脑,访问码别外传

自测

node test/selftest.mjs

不需要装进 DSH 就能跑。 需要源码仓里的 test/ 目录(npm 包里只带 lib/,不带测试脚本)。 验 10 组:载荷格式、6 位码一次性、二维码真能出图、/claim 通路、 配对页已彻底删除、安全边界(401/403)、端口被占时必须报错而不是偷偷换、 客户端半边契约、宿主半边契约(必须 connection.fetch.register + sessionController.prompt)、 包清单(files 里的文件都得存在)。

自测自己占 18777 和 18888,不碰 8899,所以插件正常跑着也能跑自测。


文件结构

dsh-console-plugin/
├─ package.json              插件清单(dsh.client.inject / peerDeps / files)
├─ cordis.patch.yml          bundle patch(insert → lib/index.js)
├─ lib/
│  ├─ index.js               宿主半边:读 sessionController + 起局域网服务 + 注册 Fetch 路由
│  ├─ client.js              客户端半边:面板 UI、侧栏入口、网页聊天页、中英文案
│  ├─ lan-server.mjs         局域网 HTTP 服务:配对码、票据、业务路由、公网闸
│  ├─ tunnel.mjs             隧道生命周期(frpc 的启停)
│  ├─ frpc-bootstrap.mjs     frpc 自动下载 + sha256 校验
│  ├─ cloud-link.mjs         云链路:短 ID、会员状态快照
│  ├─ dsh-console-cloud.mjs  版号检测 + 一键升级 / 回滚
│  ├─ mp-*.mjs               手机端:协议契约 / RPC 分发 / 路由 / 长连接 / 附件
│  ├─ attachments.mjs        附件登记表
│  └─ websocket.js           最小 WebSocket 实现
├─ test/                     自测
└─ README.md                 就是本文件

MIT License · 作者 CJ

Ähnliche Plugins