前言¶
DeepSeek Harness(DSH)的 Web GUI 在桌面端通常以三栏布局工作。拿到手机上后,会碰到几个实际问题:三栏外壳挤在小屏里、原生 browse 对话框不适合远程、rc.6 的设置与特权 API 被限制在 loopback、http://隧道IP 访问时浏览器缺少 crypto.randomUUID。
@az7627/dsh-mobile-remote 是 az7627 维护的 DSH 插件。它以双面包方式接入,不改 Harness 源码、不改 npx 安装内容,目标是在 ≤760px 视口下把 Web GUI 收成单栏,把目录选择、文件管理、终端和设置做成手机可用,并通过 WireGuard 隧道地址提供远程访问增强。
这是什么¶
- npm 包:
@az7627/dsh-mobile-remote。npm 包名带作用域,因为无作用域的dsh-mobile-remote已被他人占用。 - 维护者:
az7627。 - 许可证:MIT。
- 适用范围:按 DeepSeek Harness
0.1.0-rc.6的 Web 外壳 DOM 契约实现;核心升级后需重新验证并随版本跟进。
核心功能¶
手机布局与桌面零改动¶
在 ≤760px 视口下,插件把 DSH Web GUI 的三栏外壳收成单栏:
- 侧边栏变为左滑抽屉,带遮罩和左上角菜单按钮。
details面板变为全屏覆盖层。- 拖拽把手隐藏。
- 适配 iOS safe-area。
- 输入框使用
16px,避免移动端聚焦缩放。 - 触控目标不小于
36px。
桌面端保持原有布局。所有手机规则收窄在媒体查询内,桌面布局与列宽不受影响。
弹窗与浮层手机化¶
真正的模态对话框,例如 primitives Modal 与设置面板,在手机上全屏化,内容区独立滚动。普通弹层面板,例如菜单、上下文面板,仍保留自己的盒子与背景。
菜单、列表、带背景阴影的面板等浮层如果出屏,会自动平移到屏幕内。触发器位置变化时会跟随重算。抽屉、详情面板等自带 transform 动画的表面不受干扰。资料中说明已实测 320–430px 六档宽度下,模型选择菜单始终完整在屏。
预设标签精简¶
窄屏下,Agent 预设按钮只显示图标加短标签:
- 中文:
标准/极简/PTC/创造 - 英文同理
桌面端保持全称。
目录选择页重建¶
插件把 Harness 的目录选择交互钉为 Web 目录页,并用自研界面取代内置 browse 对话框;宿主 browse 后端保留。
桌面端提供:
- 大对话框
- 左侧快捷目录
- 分栏浏览,即 Miller columns
- 四键工具栏
- 可点击面包屑路径栏
手机端提供:
- 快捷目录落地页
- 单列列表加返回键
- 全屏呈现
文件管理¶
侧边栏“设置”上方新增“文件管理”入口,与目录选择器共用同一分栏视图。
文件管理包含这些行为:
- 每打开一个目录追加一栏。
- 放不下时,底部横向滚动条自动定位到最新栏。
- 每栏有独立滚动条;展开新栏时,原栏滚动位置保持。
- 右键菜单支持:重命名、复制、粘贴、删除、下载、选择打开方式、复制文件地址、属性、新建、上传、刷新、在终端中打开。
- 粘贴时自动加
-copy-2后缀,避免重名。 - 文本可预览、编辑并保存。
- 图片、视频、音频可内联预览。
- PDF 在新标签页打开。
- 未知类型可自定义打开方式。
- 十六进制编辑按
64KB分窗,上限8MB。 - 上传上限
8MB。 - 删除非空文件夹时二次确认。
- 文件夹属性显示递归统计的真实大小。
- 隐藏文件以半透明显示。
- 手机端保留行内触控按钮。
浏览器内 PTY 终端¶
侧边栏终端按钮可打开浏览器内终端。它使用宿主侧 node-pty 会话,Windows 走 ConPTY;客户端使用 xterm.js 渲染。
支持:
- 行编辑
- ANSI 颜色
- 全屏 TUI 应用
- 终端跟随视口 fit,并同步 PTY 尺寸
- 输出为有界环形缓冲,大小
256KB - 轮询间隔
60ms - 客户端停止轮询
10分钟后自动杀掉会话,避免 PowerShell 进程泄漏
文件管理右键“在终端中打开”可在任意目录启动终端。Windows 默认使用 PowerShell(-NoProfile),其他平台使用 bash。
手机设置页可用¶
rc.6 对非 loopback 浏览器的设置作用域会被钉为内存持久化,手机上设置页容易不发请求或整页空白。
插件在可信远程会话中把连接句柄的 isLoopback 置真,并对已消费旧值的设置消费者条目做一次 fiber 重应用,让它们重新绑定到主机持久化传输。桌面 loopback 场景不受影响。
非安全上下文修复¶
手机经 http://隧道IP 这类非安全源访问时,浏览器不提供 crypto.randomUUID,可能导致设置、目录列表、模型、插件、预设等 RPC 调用失败。
插件启动时安装基于 crypto.getRandomValues 的 UUIDv4 回退。crypto.getRandomValues 在任何源都可用,因此可以恢复 crypto.randomUUID 缺失导致的 RPC 调用。
特权 API 解除 loopback 钉死¶
rc.6 会把设置、凭据、Agent 预设、模型发现等方法钉为仅本机可用,手机上可能出现 403 forbidden。
插件把同源特权调用转发到自己的 trusted-host 通道;宿主侧再以回环请求交给内置 apiProxy 分发。信任边界仍是 profile 里的 trustedHosts,也就是 WireGuard 隧道地址。
远程增强¶
插件还提供远程访问相关增强:
- 断线重连状态条。
- 通用设置中的远程访问状态行,包括绑定地址、信任来源、目录选择后端、插件版本,手机上可自查。
- PWA 增强:standalone manifest、PNG 图标、
apple-touch-icon。
安装与启用¶
先安装插件,再重启 Web 服务。
从 npm 安装:
dsh plugin --profile web add @az7627/dsh-mobile-remote
重启:
npx @deepseek-ai/dsh web
更新时,重新执行上面的 add 命令即可,pnpm 会安装最新版。
卸载:
dsh plugin --profile web remove @az7627/dsh-mobile-remote
本地开发可以用 link 安装:
dsh plugin --profile web add C:\path\to\dsh-mobile-remote
改完源码后,执行构建并重启 Web 服务即可,无需重新 add:
pnpm run build
npx @deepseek-ai/dsh web
开发流程:
pnpm install
pnpm run typecheck
pnpm test
pnpm run build
典型用法:WireGuard 手机远程访问¶
rc.6 的 webserver 只接受 127.0.0.1 / 0.0.0.0 绑定,且 CLI 有意拒绝 0.0.0.0,因此无法直接把服务绑到 10.66.66.1。远程访问采用本机绑定加 WireGuard 地址端口转发。
先做 profile 配置。profile 文件为:
~/.dsh/profiles/web/cordis.patch.yml
其中的 web-runtime 配置需要包含隧道地址的 trustedHosts,例如:
10.66.66.1
10.66.66.1:3080
配置后,手机请求才能通过 /api 信任栅栏。
再安装端口转发。这一步需要管理员权限:
netsh interface portproxy add v4tov4 listenaddress=10.66.66.1 listenport=3080 connectaddress=127.0.0.1 connectport=3080
最后以本机绑定方式启动,并在手机上访问:
http://10.66.66.1:3080
推荐无人值守启动方式:
pwsh -File scripts\start-dsh-web.ps1 -InstallPortProxy
pwsh -File scripts\start-dsh-web.ps1
pwsh -File scripts\start-dsh-web.ps1 -RegisterStartup
其中:
-InstallPortProxy:一次安装端口转发,需要管理员权限。- 不带参数:启动服务,并检测接口、端口占用、转发状态。
-RegisterStartup:可选,注册登录自启计划任务。
典型用法:验证脚本¶
验证前先启动一次性测试实例。这个实例与真实 ~/.dsh 隔离:
pwsh -File scripts\start-test-dsh.ps1
启动地址:
http://127.0.0.1:3097
针对上面的隔离实例执行实测脚本:
node scripts/verify-mobile.mjs
node scripts/verify-file-manager.mjs http://127.0.0.1:3097
node scripts/verify-terminal.mjs http://127.0.0.1:3097
node scripts/verify-settings-loopback.mjs http://127.0.0.1:3097
node scripts/verify-usage-remote.mjs http://127.0.0.1:3097
清理隔离测试目录:
pwsh -File scripts\start-test-dsh.ps1 -Remove
经过上面的步骤,可以分别在手机仿真、文件管理、终端、设置 loopback、远程 usage 信任栅栏上验证插件行为。
注意:不要用共享 ~/.dsh 的实例跑验证脚本。验证浏览器打开会话会触发加载修复,向真实会话日志写入 closers,可能与运行中实例的写入冲突,造成日志 seq gap。
适用场景与注意¶
适合这些场景:
- 想在手机上通过 WireGuard 隧道访问本机 DSH Web GUI。
- 需要手机端可用的目录选择、文件管理、终端和设置。
- 希望桌面端布局保持不变,只在小屏下启用手机适配。
- 需要在可信远程会话中调用原本被限制在 loopback 的设置、模型、预设、凭据等特权 API。
使用前需要注意:
- 插件在 dsh 进程权限下运行。安装前应检查源码和 MIT 许可证。
- 信任边界仍是 profile 中的
trustedHosts,也就是 WireGuard 隧道地址。 - 端口转发安装需要管理员权限。
- 文件管理上传和十六进制编辑都有
8MB上限。 - 终端输出环形缓冲为
256KB,轮询间隔60ms。 - 客户端停止轮询
10分钟后,插件会自动回收终端会话。 - Windows 默认使用 PowerShell(
-NoProfile),其他平台使用 bash。 - npm 包名必须带作用域:
@az7627/dsh-mobile-remote。 - 插件按
0.1.0-rc.6的 Web 外壳 DOM 契约实现,核心升级后需要重新验证。
结尾¶
@az7627/dsh-mobile-remote 把手机响应式、目录选择、文件管理、浏览器内终端、设置修复和 WireGuard 远程增强放在同一个 DSH 插件里。安装后桌面端不受影响,手机端可以通过 WireGuard 隧道地址访问 DSH Web GUI,并进行目录浏览、文件操作、终端交互和设置查看。
GitHub:az7627/dsh-mobile-remote