这是什么
DSH Pocket 把你电脑上已经在运行的 dsh web 界面搬到手机上。装好插件、重启 dsh web 之后,设置页左侧会多出一个「手机访问」入口(和「通用设置」「模型」同级);手机扫码打开的就是电脑上那个界面的实时同屏,可以发任务、看输出、点审批。README 的定位很直白:手机上的界面就是电脑上的界面——人在外面也能用。
需要先分清一点:它不是第二个 Harness,也不是重写的移动客户端,而是在你原有的 DSH 进程前面加一层反向代理,再加一套窄屏布局。
装的是什么
npm 包名 dsh-pocket,版本 2.10.6,许可证 GPL-2.0。README 对 GPL 的解释是:可以自由使用、修改、分发,但修改版必须以同样的 GPL 开源并保留版权声明,商用同样适用。
它在 package.json 里声明为 web 平台的客户端插件,并通过 dsh.bundle.patch 指向 ./cordis.patch.yml,也就是随包附带一份组装补丁;客户端一侧声明注入五个 DSH 客户端包:connection、UI slots、UI layout、locale 与会话日志导出。发布内容包含 bin、lib、client、cordis.patch.yml、README.md 与 LICENSE。运行时依赖只有 qrcode 和 qrcode-terminal,另把 @deepseek-ai/cordis ^4.0.1 列为 peer 依赖。README 称这是「一个包、一个设置页」的零依赖安装,不需要把核心与适配器分开装,也无需账号、无需服务器。包里另外提供一个命令行模式 dsh-pocket。
手机看到的到底是什么
README 描述的是一套访问模型、两个入口。代理会把 Host、Origin 改写成 loopback,并把 HTTP 与 WebSocket 全透传——这正是「电脑上在输出、手机上同步在滚」以及双向可操作的原因;另有心跳保活应对路由器 NAT 与省电机制造成的静默断链,断线自动重连。
手机端就是同一个网页界面,只是按窄屏重新排版。README 明确写下的差异只有这些:侧栏变抽屉、会话全宽、状态栏安全区、触控优化,并注明移动端适配移植自 dsh-web-mobile(MIT)。README 没有提到任何原生 App,也没有提到一个功能更少的移动专用视图。
有一项是条件性的:移动端「文件浏览」入口需要宿主提供 explorer 面板(dsh-web-ui 组件);官方 DSH 未内置时,README 说入口会自动隐藏,而不是留一个「点了没反应」的按钮。
局域网、公网,以及公网到底依赖什么
局域网:设置 →「手机访问」→ 扫「📶 局域网」二维码 → 输入局域网密码。插件会自动识别本机局域网 IP,README 特别说明 WSL 环境会自动取 Windows 物理网卡 IP。局域网访问开关默认开着,可一键关闭;关闭后局域网二维码/链接立即失效(手机打不开),而 README 说公网不受影响。
公网:点「开启公网访问」后,README 说每次都会先弹出安全免责声明,勾选「我已知情」才能继续,且服务端强制校验、无法绕过;随后建立 cloudflared 隧道——首次使用会下载 cloudflared(macOS/Linux 优先走清华镜像,Windows 走官方直连、约 50MB 且单线程会慢),成功后才出现「🌐 公网」二维码。
所以远程访问不是点对点直连,也不是只靠插件本身:它走的是 Cloudflare 隧道,README 在致谢里把公网隧道明确标注为基于 cloudflared。由此带来两个不该让读者自己猜的后果:默认「快速隧道」的公网地址由 cloudflared 随机分配、每次重启都会变,旧链接自动失效,收藏夹留不住;想要固定公网地址属于可选的「命名隧道」模式,需要 Cloudflare 账号、自己的域名和 Tunnel Token,并在该 Tunnel 的 Public Hostname 里把域名指向 http://127.0.0.1:3081。
安全模型
认证方式是一个 8 位密码,不是设备配对握手——README 没有描述按设备登记、证书或双向认证。公网始终要密码;局域网有独立的 8 位密码,默认开启,可以一键关闭,关闭后局域网扫码直连、无需密码,此时 README 给出的保护只有「仅同一局域网设备可访问」这一层网络隔离。
密码的生命周期,README 是这样写的:公网密码默认每次开启公网自动换新;一旦设成自定义的 8 位密码(英文字母大小写或数字),就不再自动换新。局域网密码可在设置页手动刷新,也可同样自定义。登录状态与电脑上的 dsh web 进程绑定:输一次可长期免输,但 dsh web 重启/更新后需重新输入一次。
限速方面,README 的原意是:同一 IP 连续输错 5 次锁定 60 秒,全局失败超阈值时短暂全锁以应对换 IP 的分布式扫描,输对后计数清零。公网判定采用 fail closed(issue #66):除本机 loopback 与局域网私网地址外,一切陌生域名一律按公网处理、强制公网密码——README 的说法是不存在「换域名绕过密码」的口子;免责声明同样是服务端强制校验。
撤销是凭据级而非设备级:README 没有提供「撤销某一台手机、其他设备不受影响」的办法。它给出的临时分享方案是把主密码或 ?token=<主密码> 链接发给对方,用完在设置页点「刷新」换掉。临时访问 PIN 曾存在,但已在 2.6.x 因撤销时会崩而被移除,现阶段 README 明确说暂不支持。
存储位置,README 写得很具体:公网密码在 $DSH_HOME/dsh-pocket/token,局域网密码在 $DSH_HOME/dsh-pocket/token-lan,开关与自定义标记在 $DSH_HOME/dsh-pocket/settings.json;命名隧道模式下 Tunnel Token 只存本机该文件、仅本机可读,设置页不回显。
运行要求
从 package.json 可以直接读到:engines.node 为 >=22,@deepseek-ai/cordis ^4.0.1 是 peer 依赖。另外需要一个在跑的 dsh web;README 的前提段落说明,如果终端提示 dsh: command not found,要先把 Harness 装上。README 没有给出最低 Harness 版本,所以本页不再设 dshTarget 字段——作者没有任何可逐字记录的兼容声明,目录留空而不替它猜。
操作系统方面,README 分别给了 macOS、Linux(含服务器)与 Windows 的说明,并单独讲了 WSL 的行为,但没有给出一个正式的支持平台清单。网络前提很具体:局域网要求手机与电脑在同一网络,Tailscale/VPN 场景下自动识别可能选不到可达地址,可以在「局域网地址」下拉框手动选择;公网模式要求隧道能正常出站,README 点名企业防火墙/校园网拦截出站是一种失败原因,并给出「手机开热点、电脑连热点、改用局域网模式」的兜底方案。本机代理/VPN(尤其 Clash 的 TUN 模式)被 README 列为隧道报 error 1033 的最常见原因。
端口与生命周期:代理默认监听 3081,可在 settings.json 写 "proxyPort" 修改;报 EADDRINUSE 说明旧进程还占着端口。装完或更新后必须重启 dsh web——README 反复强调运行中的进程仍加载旧代码。pnpm 9 的 workspace 下安装要加 -w;跨大版本更新要加 --latest。
已知限制
- 默认没有固定地址。 快速隧道的公网地址每次重启都会变,旧链接作废;固定地址要上命名隧道,随之而来的是 Cloudflare 账号、自己的域名与 Tunnel Token。
- 密码轮换取决于模式。 自定义密码后不再换新;README 还说命名隧道模式下公网密码不自动轮换,建议配合自定义密码主动管理。
- 局域网密码可以关掉。 关掉之后,README 给出的唯一保护就是「仅同一局域网设备可访问」——那是网络隔离,不是认证。
- 没有临时访客权限。 访客 PIN 已在 2.6.x 移除,README 说暂不支持,只能「分享主密码、用完刷新」。
- 隧道可能建不起来。 远程 Linux 服务器上所有 CDN 源都连不上时无法自动下载 cloudflared(issue #45),需手动安装并在
settings.json里指定"cloudflaredPath"。 - 代理会掐断隧道。 TUN 模式代理常导致隧道注册成功但数据面连不上;README 给的处置顺序是:先只关 TUN 模式 → 彻底退出代理 → 加直连规则 → 最后改用热点局域网。
- 桌面版 advanced 模式不支持。 该模式禁用网页布局,手机拿不到 layout 服务会白屏(README 说会显示明确提示层),需要切回 compatibility 后重启;桌面版还接管了更新与重启,插件里这两项自动停用。
- 重启的形态要注意。 页内点「重启 dsh web」产生的是 detached 后台进程,README 说明了日志位置与如何结束它。
- README 没有给出延迟数字、iOS/Android 的休眠或后台保活行为,也没有一份「移动端不可用的功能」清单(除文件浏览入口那一项条件说明)。所以「实时同步」应按 README 对透传链路的描述来理解,而不是一条实测延迟承诺。
什么时候用它、什么时候不要用
当 Harness 确实留在一台你带不走的电脑上——家里的台式机、办公室的机器——而你想在手机上看看任务跑到哪了、补一句提示、点个审批,又不想折腾远程桌面或 SSH,它就是对路的。局域网模式是摩擦最小的场景:同一个 WiFi、扫一次码、不向网络之外暴露。公网模式是项目的设计重点,但要把它当成一次主动选择的暴露,并且清楚它依赖 Cloudflare 的隧道基础设施。
不要把它当安全边界或零信任网关用。没有设备配对,也没有按设备撤销,而这个密码保护的是一个能在你电脑上执行代码的端点。README 自己就是这么说的:公网 = 把能执行代码的 DSH 暴露到互联网,请使用强密码、用完即关、涉密网络勿用。在公司或受限网络上,README 要求先确认合规再开公网,并说明免责声明每次开启都会弹。如果你需要给别人短时访问,请记住临时 PIN 通道已经没了,撤销意味着把大家共用的密码整体换掉。
FAQ
这是原生手机 App 吗?
不是。手机打开的就是电脑上那个网页界面,只是按窄屏重新排版——README 把抽屉布局、安全区与触控优化归功于 dsh-web-mobile。README 没有描述任何原生客户端,也没有一个功能更少的移动专用视图。
别人只拿到二维码就能进来吗?
不能,二维码只承载地址。公网始终要 8 位密码,局域网默认也要;局域网只有在你自己把那个开关关掉之后才是扫码直连,而 README 对此时剩余保护的表述是「仅同一局域网设备可访问」。
能不能只撤销某一台手机、不影响其他设备?
README 里没有按设备撤销这回事。能撤销的是凭据整体:在设置页点「刷新」换掉密码,旧密码立即失效;如果你设了自定义密码,它不会自动换新,得你自己改。README 给出的临时分享办法是把主密码或 ?token=<主密码> 链接发出去,用完再刷新。
密码和会话数据会离开我的电脑吗?
README 把密码与 Tunnel Token 都放在 $DSH_HOME 下的本机文件里,登录校验也在本机完成,没有描述把凭据发往第三方的流程。但要注意:开启公网访问后,手机与电脑之间的流量是经 Cloudflare 隧道中转的,README 对这条链路没有给出任何加密或不可查看的承诺。
需要 Cloudflare 账号、域名或自己的服务器吗?
取决于模式。默认的快速隧道不需要 Cloudflare 账号,也不需要自有服务器,但地址由 Cloudflare 分配且重启会变;固定地址则需要 Cloudflare 账号、自己的域名和 Tunnel Token。对插件本身,README 没有提出任何账号要求。

