🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

手机遥控 wlxyxykj/dsh-phone-remote

DeepSeek Harness
wlxyxykj33 天前有提交已提供中文文档扫描:含敏感能力

dsh-phone-remote · 手机遥控

30.3/100
综合分
1
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/10/5 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

自动兼容检查有告警:未发布到 npm registry,仅可从源码安装。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add wlxyxykj/dsh-phone-remote
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:需留意
是什么
dsh 原生插件 · other
装得上吗
实装验证未通过(unknown),装前请到仓库确认最近更新与 issue
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
更新放缓:最近一次提交在 33 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
⚠︎ 实装验证未通过(unknown · 2026/10/1) ——可能是验证环境差异,装前建议到 GitHub 仓库确认最近更新与 issue。
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查⚠ 装前注意

未发布到 npm registry,仅可从源码安装

展开查看检查明细 ↓

以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。

✗npm 包dsh-phone-remote(未发布到 npm,仅可源码安装)
✓Node 引擎要求 >=20 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明

验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/6 14:18:25

安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

读写/删除本地文件
查看扫描证据(共 15 处,展示前 15 条)
  • 读取本地文件
    lib/index.js:308
    stat = statSync(absolute);
  • 读取本地文件
    lib/server.js:38
    app: readFileSync(new URL("./app.html", import.meta.url), "utf8"),
  • 读取本地文件
    lib/server.js:39
    panel: readFileSync(new URL("./panel.html", import.meta.url), "utf8")
  • 读取本地文件
    lib/server.js:45
    body: readFileSync(new URL("./markdown.js", import.meta.url), "utf8"),
  • 读取本地文件
    lib/server.js:699
    stat = statSync(entry.path);
  • 读取本地文件
    lib/server.js:713
    const stream = createReadStream(entry.path);
  • 写入本地文件
    lib/session.js:253
    mkdirSync(directory, { recursive: true });
  • 写入本地文件
    lib/session.js:263
    const out = createWriteStream(partial);
  • 写入本地文件
    lib/session.js:274
    renameSync(partial, file);
  • 删除本地文件
    lib/session.js:277
    unlinkSync(partial);
  • 读取本地文件
    lib/store.js:41
    const parsed = JSON.parse(readFileSync(file, "utf8"));
  • 写入本地文件
    lib/store.js:53
    mkdirSync(dirname(file), { recursive: true });
  • 写入本地文件
    lib/store.js:56
    writeFileSync(tmp, JSON.stringify(state, null, 2), { encoding: "utf8", mode: 0o600 });
  • 写入本地文件
    lib/store.js:57
    renameSync(tmp, file);
  • 写入本地文件
    lib/store.js:61
    writeFileSync(file, JSON.stringify(state, null, 2), { encoding: "utf8", mode: 0o600 });
扫描于 2026/11/4(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

README

由 DeepSeek 最新模型翻译生成
展开完整文档(README 剩余 1 节)
dsh-phone-remote · 手机遥控

用手机控制 DSH 桌面版里跑着的智能体:手机上说一句话,电脑上的智能体就干活,输出实时推到手机,随时能叫停。

Phone control for DeepSeek Harness (DSH Desktop): serve a token-protected mobile page from
this computer so you can drive the agent from your phone.

目录

- 它能干什么
- 前提条件
- 安装(DSH 桌面版)
- 使用:三步上手
- 界面导览
- 配置
- 访问控制与安全
- 手机连不上?逐个排查
- 升级 / 卸载
- 工作原理
- 开发与测试
- License

它能干什么

DSH 桌面版自带的界面只监听 127.0.0.1,手机打不开。这个插件在电脑上再起一个只服务手机的小网页:

| 在手机上你能做 | 说明 |
| 看会话列表 | 电脑上所有会话(含正在运行的那个)都在列表里 |
| 选一个会话继续聊 | 和电脑上是同一个会话、同一份上下文 |
| 新建会话 | 可以指定工作目录,智能体就在那个目录里干活 |
| 发指令 | 智能体真的会在电脑上执行:跑命令、改文件、查资料 |
| 传文件给智能体 | 用 📎 把手机里的文件(照片、PDF、表格…)传到电脑,智能体直接读 |
| 把产出下回手机 | 智能体说一句「发你手机」,手机页就出现下载卡片,点一下存到手机 |
| 实时看输出 | 一个字一个字推过来;工具调用显示成可展开的小卡片 |
| 随时叫停 | 运行中按钮变成 ■,点一下停止当前回合 |

电脑上还有一个控制台(只有本机能打开),用来出示二维码、查看/重置口令、管理访问白名单。

前提条件

| 项目 | 要求 |
| 电脑 | 装有 DSH 桌面版(本插件在 DSH 0.2.0-rc.2 上实测通过) |
| 手机 | 任意浏览器即可(Safari / Chrome / 国产浏览器都行;微信内置浏览器可能限制流式推送,建议用系统浏览器) |
| 网络 | 手机要能直接访问到电脑的某个 IP:同一个 Wi-Fi 最省事;不同网络见 手机连不上? |
| 端口 | 默认用 8790;被占用时会自动往后找(8791、8792…),以控制台/日志显示的为准 |

安装(DSH 桌面版)

方式一:图形界面(推荐)

1. 打开 DSH 桌面版 → 设置 → 插件
2. 点 添加插件
3. 在输入框里粘贴这一行(GitHub 地址,公开仓库,不需要任何账号):

github:wlxyxykj/dsh-phone-remote

也可以填本地路径:插件目录,或打好的 .tgz 文件路径。
4. 点 安装,等它把依赖装完(几秒)
5. 重启一次 DSH 桌面版 ← 必须,见下方说明
6. 重启后回到 设置 → 插件,应能看到 dsh-phone-remote 处于已启用状态

为什么必须重启?
DSH 宿主进程按「模块 URL」缓存插件代码,进程活着的时候不会重新读取磁盘上的插件模块。
所以安装或升级插件代码之后必须重启一次;改配置项则可以热生效,不用重启。

方式二:命令行

DSH 自带命令行,桌面版用户也可以用:

dsh plugin --profile desktop add github:wlxyxykj/dsh-phone-remote

装完同样重启一次 DSH 桌面版;重启后到「设置 → 插件」确认它是启用状态(有些情况下需要在那里手动打开开关)。

怎么确认装好了

重启后,设置 → 插件里能看到 dsh-phone-remote;或者直接打开控制台:

http://127.0.0.1:8790/

能打开就说明跑起来了。启动日志里也会打印一段横幅:

[dsh-phone-remote]
┌─ DSH 手机遥控已就绪 ───────────────────────────────── │ 监听 0.0.0.0:8790 │ 电脑面板 http://127.0.0.1:8790/ │ 访问控制 开放(任何能连到本机的设备都可以,凭口令访问) │ 手机打开: │ http://192.168.x.x:8790/m?t=xxxxxxxx WLAN └──────────────────────────────────────────────────────

使用:三步上手

日常使用只需记住一件事:插件是跟着 DSH 桌面版自动启动的,你不需要单独启动它。
DSH 开着 → 插件在跑 → 手机能连;关掉 DSH → 端口关闭 → 手机连不上。
想让手机随时能连,就把 DSH 桌面版设为开机自启(Windows 设置 → 应用 → 启动,或把 DeepSeek Harness.exe 的快捷方式放进 shell:startup)。

手机连不上时,先看控制台上的地址是不是变了:校园网/宽带的公网 IP 可能每次都不一样,变了就重新扫一次二维码(口令不用改)。想让它永远不变,见 用 Tailscale。

第 1 步:在电脑上打开控制台

浏览器打开 http://127.0.0.1:8790/

这个页面只在本机能开(手机打不开,故意的),里面是:手机链接 + 二维码 + 口令 + 访问控制 + 会话概览。

第 2 步:手机扫码进来

手机连和电脑同一个 Wi-Fi,然后用相机扫面板上的二维码:

- 二维码里已经带了口令,扫完直接进入,不用手输;
- 手机浏览器会记住口令(存成 Cookie,重启电脑也还在);
- 也可以在手机浏览器里手动输入面板上那条链接(形如 http://192.168.1.23:8790/m?t=xxxxxxxx)。

第 3 步:指挥智能体

| 想做的事 | 在手机上怎么操作 |
| 切换会话 | 左上角 ☰ → 点会话 |
| 新建会话 | ☰ → 底部「+ 新建会话并接管」,可填工作目录 |
| 发指令 | 底部输入框输入,点 ↑ 发送 |
| 看输出 | 自动流式显示;工具调用是一条可展开的卡片,点开看完整输出 |
| 叫停 | 运行中发送按钮变成 ■,点一下停止当前回合 |

不需要在手机上确认任何授权弹窗——远程会话默认已经设成 approvalPolicy: never,发指令就直接执行。

第 4 步(可选):传文件 / 收文件

手机 → 电脑:给智能体喂文件

1. 手机页面底部点 📎,选文件(可多选,单个最大 25 MB);
2. 上传完成后输入框上方出现文件小标签(⏳ 上传中 → 📎 已就绪,点 ✕ 可移除);
3. 正常发指令即可——文件会写进这个会话的工作目录下的 .phone-uploads/,指令里自动附上路径,智能体用它自带的文件工具直接读。

落地路径形如 .phone-uploads/20260930-220145-合同.pdf。
你只要说「读一下我刚传的合同,把关键条款列出来」就行。

电脑 → 手机:把产出拿回来

智能体需要把文件给你时,它会调用工具 phone_send_file;你也可以直接说:

把这个报告发我手机上

手机页面上会出现一张下载卡片(文件名 + 大小 + 备注),点一下就存到手机。
卡片刷新后仍在(有效期 2 小时,单文件最大 25 MB)。

如果点下载没反应,长按卡片选「在新标签页打开」——部分手机浏览器对内联下载有限制。

界面导览

电脑控制台 http://127.0.0.1:8790/

| 区域 | 内容 |
| 手机访问链接 | 所有可用地址(Wi-Fi / 有线 / Tailscale 等),带二维码和「复制」按钮;点链接即复制含口令的完整地址 |
| 状态 | 监听地址、访问口令(显示/复制)、会话数、运行中的会话数、新会话默认目录 |
| 访问控制 | 白名单开关、白名单列表、最近访问过的客户端(被拦的会标「已拦截」,旁边就是「允许」按钮) |
| 会话 | 最近有活动的会话一览 |
| 安全须知 | 口令等于操作权等提醒 |

控制台每 5 秒自动刷新,换了网络后新地址会自动出现在列表里。

手机页 /m

| 区域 | 内容 |
| 顶栏 | 当前会话名、连接/运行状态、☰ 会话列表、⟳ 手动重连 |
| 消息流 | 你说的(右侧气泡)、智能体回答(Markdown 渲染)、工具调用卡片、折叠的「💭 思考过程」、文件下载卡片、错误提示 |
| 底栏 | 📎 上传文件、输入框、发送/停止按钮;上传中的文件显示为小标签 |
| 口令页 | 如果这个浏览器没有口令,会先显示「需要访问口令」的输入框 |

配置

两种改法,任选一种(改配置不用重启,保存即生效):

A. 在 DSH 设置里改(推荐):设置 → 插件 → dsh-phone-remote,会看到完整的设置表单——开关、监听地址/端口、访问口令、新会话默认目录、授权策略、权限开关、IP 白名单,每项都带说明。
(插件导出了配置 schema,所以设置页能渲染出这些字段。)

B. 改 profile 的 cordis.patch.yml($DSH_HOME/profiles/<profile>/cordis.patch.yml),加一行:

- id: phone-remote
name: 'dsh-phone-remote'
config:
port: 8790
cwd: 'D:\work\my-project'
allowCancel: false

配置项

| 键 | 默认 | 说明 |
| enabled | true | false 时插件完全不启动(不监听、不注册工具) |
| host | 0.0.0.0 | 监听地址。0.0.0.0 = 所有网卡都能访问;改成 127.0.0.1 就只有本机能用 |
| port | 8790 | 起始端口;被占用时自动向后找,最多试到 8799 |
| token | 空 | 访问口令。留空 = 复用已保存的,没有就随机生成 24 位并写入 $DSH_HOME/dsh-phone-remote.json |
| cwd | 空 | 手机上新建会话时的默认工作目录 |
| agentPreset | 空 | 手机上新建会话使用的 Agent preset(如 standard) |
| approvalPolicy | never | 远程会话的授权策略。never = 不再逐条询问(推荐);ask = 跟随桌面端弹窗 |
| allowCreate | true | 是否允许手机新建会话 |
| allowCancel | true | 是否允许手机叫停回合 |
| exposePanel | true | 是否提供本机控制台 / |
| allowFrom | [] | IP 白名单(写死在配置里)。非空 = 名单由配置管理,且面板不能改;留空则在面板上管理 |
| strictAllowlist | false | 严格模式:白名单连持有正确口令的设备也拦。默认 false = 口令优先,带对口令的设备换任何网络都能连。仅作首次默认值,之后以面板上的开关为准 |

访问控制与安全

口令是怎么工作的

- 口令是 24 位随机字符(约 120 bit),暴力猜解不可行;
- 二维码/链接里带着它(?t=...),所以扫码等于自动带钥匙;
- 服务端校验通过后会种一个 HttpOnly + SameSite=Strict 的 Cookie,之后这个浏览器就不用再带;
- 校验用 SHA-256 常数时间比较;每个 IP 每分钟失败超过 20 次会被限流(429)。

口令说了算:换任何网络都能连(默认行为)

带着正确口令的设备一律放行,白名单不会拦它。 这是默认行为,也是这个插件最实用的地方:

- 手机换 Wi-Fi、切流量、IP 变了,都不用回电脑上点「允许」;
- 只要你不点「重置口令」,那个链接/二维码可以一直用(口令存在 $DSH_HOME/dsh-phone-remote.json,重启电脑、升级插件都不变);
- 白名单只对没带口令就敲门的设备生效(端口扫描、误打误撞输网址的人)——它们会被直接 403,连口令输入框都看不到。

白名单(默认开着也没关系)

白名单列表里可以放:203.0.113.42(单个 IP)、203.0.113.(整个前缀)、10.0.0.0/8(CIDR 网段)。

在控制台「访问控制」里可以:

| 按钮 | 作用 |
| 启用/关闭「仅白名单」 | 是否对没带口令的设备做 IP 过滤 |
| 切换严格模式 | 打开后白名单变成硬门禁:名单外的设备即使口令正确也被拒绝(这是老行为,只在你想把访问锁死在几个 IP 时才用) |
| 最近访问的客户端 → 允许 | 把某个被拦的 IP 加进名单 |

什么时候才该开严格模式? 当你怀疑链接外泄、想把访问彻底钉死在固定 IP 时。
代价是手机每换一次网络都要回电脑点一次「允许」——日常用不着。

两条必须知道的安全提醒

1. 链接/二维码就是钥匙,别截图外发、别丢群里;
2. 目前是明文 HTTP,链路上的中间人理论上能嗅探到口令。要彻底解决就用 Tailscale 之类的加密隧道,或者用完就把配置里的 enabled 设为 false。

用 Tailscale:固定地址 + 加密(推荐)

手机用移动数据时 IP 会变、白名单难维护、明文传输有风险——Tailscale 一次解决这三件事:它把你的设备组成一个私有网络,每台设备拿到固定的 100.x.y.z 地址,设备之间端到端加密。

1. 电脑和手机都装 Tailscale,登录同一个账号;
2. 电脑上执行 tailscale ip -4 拿到形如 100.101.102.103 的地址(控制台链接列表里也会多出一条,排在最前面);
3. 手机浏览器打开 http://100.101.102.103:8790/m?t=<口令>,之后无论在 Wi-Fi 还是流量下都能用。

想收得更紧(二选一):

| 方案 | 做法 | 效果 |
| A. 只换地址 | 保持 host: '0.0.0.0',白名单写 100.64.0.0/10 | 公网仍能连到端口,但一律 403,只有你的 tailnet 能进 |
| B. 只监听 Tailscale 网卡 | 配置 host: '100.101.102.103' | 公网连 TCP 都连不上,最彻底 |

方案 B 的注意点:Tailscale 必须在 DSH 启动前已经连上,否则那个地址不存在。
插件遇到这种情况会自动退回监听 0.0.0.0 并打一条告警,不会整个起不来(此时请确保白名单是开的)。

国内提示:login.tailscale.com 偶尔不好访问,连不上可以换 ZeroTier,原理一样(插件同样会把它的网卡排在前面)。

手机连不上?逐个排查

按顺序试,基本三步内能定位:

1. 手机和电脑网络通不通

- 同一个 Wi-Fi 是最省事的(注意有些公共/校园 Wi-Fi 开了「客户端隔离」,同网段也互相不通);
- 电脑有公网 IP 时,手机用移动数据也可能直接连上(取决于网络是否放行);
- 都通不了就用手机开热点,让电脑连手机热点——控制台几秒内会自动列出新地址,扫新的码即可;
- 想随时随地用,见上面的 Tailscale。

2. 电脑上的控制台打得开吗

- 打不开 → 插件没跑起来:确认 设置 → 插件 里是启用状态,并重启一次 DSH 桌面版;
- 端口不是 8790 → 被占用了,看控制台标题/启动日志里的实际端口。

3. 手机显示什么

| 手机上的现象 | 原因 | 怎么办 |
| 「此设备未授权访问」 | 白名单开着,手机 IP 不在名单里 | 回电脑控制台 → 访问控制 → 最近访问 → 点「允许」;或关掉白名单 |
| 「需要访问口令」输入框 | 链接里没带口令,或这个浏览器没存过 | 粘贴面板上的口令,或重新扫码 |
| 黑屏 / 「页面没能启动」卡片 | 页面脚本没加载成功 | 下拉刷新;不行就重新扫码 |
| 页面能开但没反应 | 局域网能开页面、流式被中间设备掐断 | 换系统浏览器(别用微信内置) |
| 一直转圈 | 网络到了但服务没回 | 确认电脑没休眠、插件还在运行 |

4. 还是不行?放行防火墙

Windows 防火墙可能拦了入站端口。管理员 PowerShell 执行一次(端口按实际的改):

New-NetFirewallRule -DisplayName "DSH Phone Remote" -Direction Inbound -Action Allow
-Protocol TCP -LocalPort 8790 -Profile Private

Wi-Fi 被 Windows 标成「公用网络」时,-Profile Private 不生效;要么把该网络改成专用网络,要么用 -Profile Any(暴露面更大,慎用)。

5. 忘记口令了怎么办

打开电脑控制台 → 状态 → 显示 就能看到口令;点 重置口令 会作废旧链接和所有已登录的手机,然后重新扫码即可。

升级 / 卸载

DSH 目前不支持插件自动更新,升级要手动来:

升级:设置 → 插件 → 卸载 dsh-phone-remote → 重新「添加插件」新版本 → 重启 DSH 卸载:设置 → 插件 → 卸载 dsh-phone-remote → 重启 DSH

命令行方式:

dsh plugin --profile desktop remove dsh-phone-remote # 卸载
dsh plugin --profile desktop add github:wlxyxykj/dsh-phone-remote#v1.3.0 # 装指定版本

用 GitHub 安装时可以用 tag 锁定版本,例如 github:wlxyxykj/dsh-phone-remote#v1.3.0。

工作原理

┌──────────────┐ 扫码/链接 ┌────────────────────┐ 局域网/公网 ┌──────────────────────┐ │ 手机浏览器 │ ─────────────▶ │ 电脑控制台 (仅本机) │ ◀───────────── │ DSH 桌面版宿主进程 │ │ /m?t=<口令> │ ◀───────────── │ 127.0.0.1:8790 │ │ ctx.sessionController│ │ 发指令/看输出 │ SSE 流式推送 │ 二维码/白名单 │ │ (真正在跑 Agent) │ └──────────────┘ └────────────────────┘ └──────────────────────┘

- 插件作为 DSH 的一个 bundle 被加载,在宿主进程里监听一个端口;
- 手机面 /m 与 /api/m/ 需要口令;控制台 /、/api/panel/、/api/qr 只接受 127.0.0.1;
- 发指令走 ctx.sessionController(list / create / resolveAgent / prompt / cancel / follow),输出通过 follow 的 SSE 流推送;远程会话在第一条指令前就被设成 approvalPolicy: never;
- 口令、白名单存在 $DSH_HOME/dsh-phone-remote.json(旧版本名 mobile-remote.json 会被自动沿用)。

文件结构

| 文件 | 作用 |
| lib/index.js | 插件入口:配置、口令、启动监听、注册 phone_remote 工具、卸载清理 |
| lib/server.js | HTTP 路由、口令校验、IP 白名单、SSE、端口顺延、优雅停止 |
| lib/session.js | 到 DSH 宿主服务的桥接 |
| lib/app.html | 手机页(原生 JS,无前端依赖) |
| lib/panel.html | 电脑控制台 |
| lib/markdown.js | 零依赖 Markdown 渲染器(转 DOM 只用 textContent,模型输出的 HTML 不会被当标签执行) |
| lib/qr.js | 零依赖 QR 编码器(字节模式,版本 1–10,EC L/M/Q/H) |
| lib/net.js / lib/store.js | 局域网地址探测 / 状态文件读写 |
| locale/.json | 插件在 DSH 里的显示名与描述(中文/英文) |

另外注册了两个给 Agent 用的工具:

| 工具 | 作用 |
| phone_remote | 你说「给我手机遥控的链接」,它返回链接和控制台地址 |
| phone_send_file | 把电脑上的文件推到手机(你在手机页看到下载卡片),说「这个文件发我手机」即可 |

文件传输的两个方向用的是不同机制:上传是把文件写进会话工作目录后,把路径写进指令(Agent 用自己的文件工具读,不依赖模型的附件能力); 下发是把文件登记到插件的下载表,再通过手机正在监听的 SSE 流推一张卡片过去,下载走 /api/m/download/<id>(同样要口令)。

开发与测试

node --test "test/.test.mjs"

97 项测试,覆盖:HTTP 路由 / 口令栅栏 / 限流、IP 白名单(含真实非回环地址的拦截测试)、 SSE 流、会话桥接、文件上传与下载(含越权、超限、过期文件、SSE 推送)、插件装配、Markdown 渲染、QR 编码。

其中有 4 项是与两套独立 QR 实现(node-qrcode、qrcode-generator)的逐模块交叉比对,需要 scratch/ 下的参考实现;克隆下来没有它时会自动跳过,其余 93 项照常通过。

License

MIT © tofar
预览分享卡片长什么样 ↓wlxyxykj/dsh-phone-remote
分享 · DeepSeek Harness Hub
wlxyxykj/dsh-phone-remote

dsh-phone-remote · 手机遥控

这是你的仓库?认领条目

回到顶部