# dsh-web-remote
中文 | English
> 手机 / 外网远程访问 DeepSeek Harness(DSH)的插件。随时随地通过浏览器,或**微信 / 飞书 / Telegram / QQ官方** 机器人控制你的 DSH。 ## ✨ 功能亮点 | 功能 | 说明 | |------|------| | 🌐 **公网访问** | Cloudflare Quick Tunnel,无需公网 IP、无需注册,`cloudflared` 缺失时自动下载 | | 🖥️ **官方桌面版** | 支持 DSH 官方桌面版(`dsh-app://`):按钮注入走官方结构化通道,目标端口自动探测 | | 📡 **局域网直连** | HTTP + HTTPS **并列两条链接**:HTTP 免证书直接可开,HTTPS 自签名(点「继续前往」即可) | | 🔒 **安全认证** | 每次启动生成随机令牌;HttpOnly Cookie;局域网可免 token | | ⚡ **性能加速** | 反向代理自动 gzip 压缩,大历史会话加载更快 | | 📱 **侧边栏图标** | 手机快捷按钮常驻左下角,刷新不消失 | | 🛰️ **P2P(Tailscale)** | 装了 Tailscale 时自动把 100.x 地址列到「公网」页,免 token 直连(在外面访问家里);`/链接` 命令**同时发公网与 P2P 两条链接**,P2P 没打通时写明 `p2p未打通` | | 📶 **Tailscale 状态** | 面板直接显示「已连接 / 未登录 / 未运行」+ 手机在不在线 + **路径是直连还是中继(哪个节点)** | | 🔌 **自定义端口** | HTTP / HTTPS 端口**可分别自定义**,带同端口冲突拦截与占用检测 | | 🤖 **微信机器人** | iLink 协议直连微信,支持 AI 对话、会话控制、模型切换 | | 💬 **飞书机器人** | WebSocket 长连接,支持命令控制、会话监听通知 | | ✈️ **Telegram 机器人** | 长轮询收发消息,支持 HTTP 代理、命令控制、监听推送 | | 🐧 **QQ 官方机器人** | QQ 开放平台官方接入,WebSocket 长连接,**无需额外 QQ 号 / 公网入口** | | 🔔 **钉钉机器人** | 企业内部应用 + Stream 模式长连接,**不需要公网地址**,被动回复 + OpenAPI 主动推送 | | 👁️ **会话监听** | `/监听` 命令,Agent 思考完毕自动推送到已绑定通道 | | 🩺 **通道健康监测** | 微信/飞书/Telegram/QQ官方/钉钉 独立监测,连续 3 次失败自动告警并停止,红点直达 + 一键重连 | ## ⚡ 一句话安装 复制下面这句话给你的 DSH,它自己会装好一切: > 请帮我安装 dsh-web-remote 远程访问插件(https://github.com/godchen520/dsh-web-remote),装完告诉我如何重启 DSH Web。 不想麻烦 Agent?命令行一条: ```bash dsh plugin --profile web add github:godchen520/dsh-web-remote && dsh web ``` ## 📸 截图 **快捷按钮**(页面左下角):  **远程面板**(公网 / 局域网切换、一键复制链接、二维码、启动 / 停止):  ## 📋 安装方式 ### 方式一:GitHub 直接安装(推荐) ```bash cd $DSH_HOME/profiles/web pnpm add github:godchen520/dsh-web-remote ``` 在 `package.json` 的 `dsh.profile.bundles` 数组中添加 `"dsh-web-remote"`,重启 DSH。 > `--config.minimumReleaseAge=0` 可绕过 pnpm 11 新包发布年龄校验(如需要)。 ### 方式二:手动 patch 把本包放入 profile 的 `node_modules`,然后在 `cordis.patch.yml` 追加: ```yaml - insert: - id: web-remote name: 'dsh-web-remote' ``` > bundle 方式需重启;cordis.patch.yml 方式会被 HMR 热加载。 ## ⚙️ 配置 全部可选,不配置即开箱即用。在 `cordis.patch.yml` 里覆盖: | 参数 | 默认值 | 说明 | |------|--------|------| | `targetPort` | 自动探测 | DSH 自身端口。**显式配置最优先**;否则依次读 `DSH_WEB_URL` → `DSH_PORT` → 兜底 `3080` | | `httpPortStart` | `3081` | 局域网 HTTP 起始端口(自动跳过占用) | | `httpsPortStart` | `3082` | 局域网 HTTPS 起始端口 | | `cloudflaredPath` | `''` | 指定 cloudflared 路径;留空自动探测 / 自动下载 | | `pfxPath` | `''` | 指定 PFX 证书;留空自动生成自签名 | | `pfxPass` | `''` | PFX 密码 | | `toolsDir` | `''` | 工具与证书缓存目录;留空使用 `$DSH_HOME/tools` | | `autoStart` | `true` | 插件加载即自动启动 | | `lanOpen` | `true` | 局域网免 token(私网来源放行) | ## 📱 使用方法 1. 启动后页面左下角出现 📱 图标 2. 点击图标 → 面板显示运行状态和链接 3. 手机浏览器打开链接即可访问 DSH **公网**:`https://xxx.trycloudflare.com/?token=...` **局域网**(同 Wi-Fi;默认免 token,**并列给两条**): - `http://192.168.x.x:3081` —— **推荐**,免证书,浏览器直接打开(非安全上下文,剪贴板 API 等受限) - `https://192.168.x.x:3082` —— 自签名证书,浏览器提示不安全,需手动「高级 → 继续前往」(安全上下文) **面板功能:** - 公网标签页:可填写自定义公网 URL(如自己的 ngrok 地址) - 局域网标签页:两条链接各自的**端口号可点击直接修改**(HTTP / HTTPS 分别设置),二维码指向 HTTP 地址(手机扫码直接能开) ## 🖥️ 官方桌面版 插件支持 DSH 官方桌面版(窗口地址 `dsh-app://app/`)。与浏览器版有两点差异: | 项 | 说明 | |---|---| | **按钮注入** | 桌面版走**静态部署**渲染路径,只消费官方**结构化注入行**(`webserver/index-inject`),**不跑 `tapIndex`**。插件已同时使用两条通道,两端都覆盖 | | **目标端口** | 桌面版由宿主动态分配端口(实测 `19387`),且插件进程里**看不到** `DSH_WEB_URL`(那是注入给 agent shell 的)。需要显式指定 | 在 profile 的 `cordis.patch.yml` 里补上端口: ```yaml - id: web-remote name: dsh-web-remote config: targetPort: 19387 # 换成你桌面版的实际端口 ``` > 不配置会兜底 `3080`,桌面版下的表现是隧道 **502 Bad Gateway / Host Error**。 > 面板 `/remote/info` 会返回 `targetPort` 与 `portSource`(`config` / `env` / `default`),可用来确认实际取到了哪个端口。 ## 🤖 微信机器人 通过微信直接控制 DSH,支持: **远程控制命令:** - `/链接` — 获取公网链接(未启动自动开启) - `/停止远程` — 关闭远程服务 - `/监听` — 开启/关闭会话监听模式(思考完毕自动通知) **会话管理:** - `/会话列表` — 列出所有会话 - `/选择 N` — 选中第 N 个会话 - `/当前会话` — 查看选中会话名称 - `/历史内容` — 查看会话最近输出 **模型切换:** - `/当前模型` — 查看当前使用的模型 - `/切换模型` — 列出所有模型并切换 - `/选强度 N` — 设置思考强度 **对话:** - 直接发送内容 → 自动发到选中的会话并回传结果 - 未选择会话时提示先选择 ## 💬 飞书机器人 通过飞书直接控制 DSH,支持: **远程控制命令:** - `/链接` — 获取公网链接 - `/停止远程` — 关闭远程服务 - `/监听` — 开启/关闭会话监听模式 - `/帮助` — 显示命令列表 **绑定方式:** 在 DSH Web 面板 → 机器人标签页 → 飞书,填写 App ID 和 App Secret,点击绑定。 ## ✈️ Telegram 机器人 通过 Telegram 直接控制 DSH,支持: **远程控制命令:** - `/链接` — 获取公网链接 - `/停止远程` — 关闭远程服务 - `/监听` — 开启/关闭会话监听模式 - `/帮助` — 显示命令列表 **绑定方式:** 在 DSH Web 面板 → 机器人标签页 → Telegram,填写 Bot Token,点击绑定。 **代理支持:** 国内网络无法直连 Telegram API 时,可在面板中配置 HTTP 代理地址。 ## 🐧 QQ 官方机器人 通过 **QQ 开放平台**接入的官方机器人,支持: **远程控制命令:** - `/链接` — 获取公网链接 - `/停止` — 关闭远程服务 - `/监听` — 开启/关闭会话监听模式 - `/模型` — 查看当前模型 - `/状态` — 查看通道状态 - `/帮助` — 显示命令列表 **场景支持:** QQ 群聊 + 消息列表单聊。 **接入方式(两种,任选):** **方式一:扫码绑定(推荐,全程不用复制密钥)** 1. DSH Web 面板 → 机器人标签页 → **QQ官方** → 点「📱 扫码绑定」 2. 用**手机 QQ** 扫描面板上出现的二维码 3. 在弹出的页面里**选择你要绑定的机器人**(已创建好的)→ 确认授权 4. 凭据自动填入并连接 > 注意:扫码是**绑定已有机器人**,不会新建机器人。若还没有,先用方式二创建。 **方式二:手动填写** 1. 打开 [QQ 开放平台快捷创建](https://q.qq.com/qqbot/openclaw/login.html),用 QQ 登录后点「创建机器人」(个人主体可创建 5 个) 2. 在开放平台「开发设置」里复制 **AppID** 与 **AppSecret** 3. 面板里填入后点「确认并连接」 **特点:** | 项 | 说明 | |---|---| | 额外 QQ 号 | **不需要** —— 平台分配独立机器人身份,你的 QQ 只作为管理员 | | 公网入口 | **不需要** —— 走 WebSocket 长连接,SDK 自带心跳与 RESUME 补发 | | 备案 | **不需要** | | 会话持久化 | 支持,进程重启后可 RESUME 补上断连期间的消息 | | 主动推送 | 支持(需你曾给机器人发过消息;群聊需群主允许) | **群聊启用:** 群主把机器人拉进群即可;若允许接收全量消息,需群主在机器人设置里开启。 **说明:** 这是本插件**唯一**的 QQ 接入方式。早期版本曾提供基于 OneBot 11(NapCat)的通道, 已于 5.0.0 移除 —— 官方机器人合规稳定、无需额外 QQ 号,也不需要跑 NapCat 中间层。 ## 🔔 钉钉机器人 通过 **钉钉开放平台「企业内部应用 + 机器人」** 接入,消息接收模式用 **Stream 模式**(长连接), 因此和飞书/QQ官方一样:**不需要公网 IP、域名、证书或内网穿透**。 **远程控制命令:** 与其它通道完全一致 —— `/帮助` `/链接` `/启动` `/停止` `/监听` `/状态` `/会话列表` `/选择 N` `/当前会话` `/历史内容` `/当前模型` `/切换模型` `/选强度`, 以及**直接发一句话**(不带 `/`)转发进选中的会话。 **特点:** | 项 | 说明 | |---|---| | 账号要求 | **需要企业/组织**(个人版钉钉不支持应用机器人);自测可免费新建一个团队,自己当管理员 | | 公网入口 | **不需要** —— Stream 模式长连接(`wss-open-connection.dingtalk.com`) | | 被动回复 | 用消息自带的 `sessionWebhook`,**无需额外权限**;有效期 **1.5 小时**,过期自动回落 OpenAPI | | 主动推送 | 用 OpenAPI(单聊 `oToMessages/batchSend` / 群聊 `groupMessages/send`),需要「**企业内机器人发送消息权限**」 | | 监听通知 | 走 OpenAPI 主动推送,**不受 1.5 小时限制**;重启 DSH 后会自动恢复上次的会话目标 | | 群聊 | 需要 @机器人 才会收到消息;**主动推送不支持 @** | | 单条长度 | 自动按 4000 字分片(群聊接口 `msgParam` 上限 15000 字节) | **接入步骤:** 1. 用**企业管理员**(或让管理员给你开发者权限)登录 [钉钉开发者后台](https://open-dev.dingtalk.com) 2. 应用开发 → **创建企业内部应用** → 记下 **Client ID / Client Secret**(即 AppKey / AppSecret) 3. 应用能力 → 添加 **机器人** → 填写名称等信息 → **消息接收模式选「Stream 模式」** → 保存 4. **发布应用**:版本管理与发布 → 创建新版本(**勾选「机器人」**)→ 发布 > 没发布时,机器人不会出现在会话里,`senderStaffId` 也不会返回 —— 主动推送会拿不到 userId 5. 申请权限:开发配置 → 权限管理 → 搜索「**企业内机器人发送消息权限**」→ 申请 > 只用被动回复(收到消息才回)可以不申请;`/监听` 通知必须申请 6. 群聊场景:群设置 → 群管理 → 机器人 → 添加机器人(群需属于该应用所在企业) 7. DSH 面板 → 机器人标签页 → **钉钉** → 填 Client ID / Client Secret → 「验证并连接」 **排错:** - 面板提示「AppKey 或 AppSecret 不正确」→ 凭证预检就失败了,核对后台的 Client ID / Client Secret - 面板提示「连接超时」→ 凭证有效但没连上:确认**应用已发布**、机器人**消息接收模式是 Stream** - 收到消息不回 → 看日志里是否有 `[dingtalk] 收到消息`;群聊必须先 @机器人 - 通知推不出去 → 检查是否申请了「企业内机器人发送消息权限」,以及是否给机器人发过至少一条消息(用来记录推送目标) ## 🩺 通道健康监测 微信 / 飞书 / Telegram / QQ官方 / 钉钉 各通道独立监测: - 连续 **3 次**失败 → 自动停止该通道并告警 - 远程图标显示**红点**提示(任一通道断开即亮) - **点击红点直达**出问题的通道页,提供**一键重连**按钮 ## 🔧 兼容性 | DSH 版本 | 状态 | |---|---| | **0.2.x(0.2.0-rc.2 实测)** | ✅ 支持 | | 0.1.2-rc.1 ~ 0.1.x | ✅ 支持 | | < 0.1.2-rc.1 | ❌ 不支持(那之前 `session.events` 还是属性,没有 `snapshotEvents()`) | 本插件**不 import 任何 `@deepseek-ai/*` 官方包** —— 宿主能力(`webServer`、`subprocess`、`agents`、`sessions`、`sessionQuery` 等)全部通过 cordis 服务注入获取。因此 DSH 改动**包级导出**(例如 0.2.x 移除 `dsh-settings` 的 `settingsNamespace` / `installSettingsSection`)不会影响它。 需要跟着 DSH 适配的只有**服务接口本身**:目前用到 `session.snapshotEvents()`(0.1.2+ 的新形式)。 ## ❓ 常见问题 **Q: 局域网链接打开提示"不安全"?** A: 那是 **HTTPS 自签名证书**的预期行为(公网隧道用的是真证书,不会提示)。 **最简单的办法是用面板里并列给出的 HTTP 那条链接** —— 免证书,直接打开。 若确实需要安全上下文(剪贴板 API 等),才用 HTTPS 那条:手机浏览器选「继续访问」,Edge 需关闭"增强安全性"。 **Q: 重启 DSH 后链接变了?** A: 公网隧道每次重启会生成新地址,这是正常行为。微信绑定的 token 会自动持久化恢复。 **Q: cloudflared 下载失败?** A: 首次启动需要联网下载 cloudflared(约 10MB),之后复用缓存。可手动下载放到 `toolsDir` 目录。 **Q: 微信扫码后断开?** A: 重启 DSH 后微信会自动重连(token 已持久化)。如仍断开,重新发送 `/链接` 扫码绑定。 ## 📝 更新日志 查看 [CHANGELOG.md](CHANGELOG.md) 了解版本更新历史。 ## 🤝 贡献 欢迎贡献!请查看 [CONTRIBUTING.md](.github/CONTRIBUTING.md) 了解开发和提交流程。 ## 📄 License [MIT](LICENSE)