Skip to main content

plugin/packages/plugin

19Stars2Forks5Issues0Watchers

Enables remote control of DSH from mobile devices, supporting sessions, approvals, questions, and file transfers over LAN or Tailscale.

Evidence4/5methodologySourceInstallMaintenanceDSH versionSecurity scan
Machine-auditedInstall commandRepo verifieddsh-plugin topicLicenseREADMEAI wiki

ⓘ This plugin is a sub-package of the Blank-not-black/dsh-Remote monorepo — stars and activity count the whole repository.

Language
JavaScript
License
MIT
Branch
main
deepseek-harnessdshdsh-pluginmobileremote-control

Install

cmdweb profile
$ dsh plugin --profile web add dsh-remote-plugin

Run the command above in your terminal to install this plugin via the dsh CLI. You can switch Profile in the top-right corner. New to dsh? Read the beginner tutorial

Install via your agent

Install the DeepSeek Harness plugin Blank-not-black/dsh-Remote/packages/plugin for me: review the repository at https://github.com/Blank-not-black/dsh-Remote first, then run the install command and verify the plugin loads successfully.

Paste this instruction to the DSH Web GUI assistant — it will install and verify for you.

一句话定位

DSH 官方 bundle 插件:在 DSH Web 侧栏底部加一个 "DSH Remote" 入口,打开抽屉式快速状态面板与完整管理控制台,内置一个会随 DSH 自动启停的远程网关,让你在手机、桌面浏览器或另一台电脑上查看会话、处理审批、传输文件、统计 Token 用量,并远程启停本机 DSH。

核心能力

  • 在 DSH Web 原生侧栏底部新增 "DSH Remote" 入口(注册 sidebar.footer.action slot),点击弹出右侧抽屉抽屉式快速状态面板(/remote/plugin.html);抽屉 iframe 懒加载,关闭后立即卸载
  • 提供完整管理控制台(/remote/admin/):网关端口与运行状态、DSH 上游可达性、已连接设备、Token 用量、二维码配对、令牌轮换、网关启动 / 停止、Doctor 自检与首次连接向导
  • 内置远程网关(gateway.cjs)随 DSH 自动启停:默认监听 0.0.0.0:8787,由 systemd-run 优先拉起为独立 user 单元,回退 detached 子进程;启动前用 net.connect 做端口占用预检
  • 网关自愈:DSH 启动 / 重启或网关异常退出后自动拉起;只检测版本或上游地址变化才刷新网关,避免 VPN 或 DSH 短暂不可达造成重启风暴
  • 通过 ctx.on('session/event', ...) 监听 DSH 会话事件,把带 usage 的 assistant/message 串行投到网关 /stats/ingest 做 Token 用量聚合(gateway.js 同步提供 /stats/summary 等查询接口)
  • 提供 /remote/api/command 端到端斜杠命令桥接:客户端 → 网关 → 插件 → ctx.commands.execute(agent, line)(DSH 自带 api-proxy 白名单不含 commands.*,只能通过插件端点执行)

技术实现

  • 语言: Node.js(ESM 插件 host half + CommonJS 单文件网关 gateway.cjs)+ 零依赖纯 JS WebUI + Java(Android Capacitor 8 壳,与本插件包通过 files 字段分发)
  • 关键依赖: node:http / node:child_process / node:net / node:fs / node:os / node:path(运行时零第三方依赖);Cordis SDK(@deepseek-ai/dsh-client-runtime + @deepseek-ai/dsh-client-ui-slots,由 dsh.client.inject 注入);React(由 client half 在浏览器侧 require,产物入库无构建步骤)
  • 架构模式: 双半区 cordis bundle + 单文件网关。Host half packages/plugin/index.mjs(inject=['webServer','commands','agents'])在 DSH Web 的 httpServer 挂 /remote 前缀路由,托管移动控制台 + 管理面板静态资源 + 管理 API + 斜杠命令桥接;用 systemd-run 或 detached spawn 把 gateway.cjs 拉成独立进程,并通过 ~/.dsh-remote/gateway-port / gateway.enabled / plugin-gateway.pid / plugin-gateway.log 持久化开关与生命周期。Client half packages/plugin/client.js(inject=['slots'])通过 window.__ModuleLoader__.load 注册到 DSH 原生 sidebar.footer.action + shell.overlay slot,渲染侧栏按钮和右侧抽屉。cordis.patch.yml 把 dsh-remote 插入 profile 层栈。
  • 入口文件: packages/plugin/index.mjs(host half,export const name='dsh-remote',apply 挂路由 + 监听 session/event + 自愈)、packages/plugin/client.js(client half,定义 SidebarButton + Drawer 并 exports.apply/inject)、packages/plugin/cordis.patch.yml(bundle insert 声明)

适用场景

  • 想在 DSH 主进程里直接获得手机 / 桌面远程控制能力,而不希望另外启动 systemd 服务或独立 Node 进程——DSH 起来,网关就在;DSH 重启,网关自动刷新。
  • 想让手机 / 桌面 / 另一台电脑通过统一令牌接入 DSH,查看会话、处理工具审批与提问、互传文件,并在管理面板里直接启动 / 重启本机 DSH。
  • 想在 DSH 侧栏内集成一个零构建、零依赖的"快速状态 + 管理"组合(抽屉做轻量监控,深链接跳到完整管理控制台),而不必为它单独占一个标签页。

前置依赖与兼容性

依赖最低版本说明
DSH未声明通过 dsh.bundle.patch 把 dsh-remote 插入 profile 层栈;dsh.client.inject 注入 @deepseek-ai/dsh-client-runtime 与 @deepseek-ai/dsh-client-ui-slots;插件 host half 依赖 Cordis ctx.webServer / ctx.commands / ctx.agents 三个服务;网关通过 DSH_UPSTREAM(默认 http://127.0.0.1:3080)反向代理
Node>=18来自 packages/plugin/package.json:44-46;单文件网关打包目标 node22-linux-x64 / node22-win-x64 / node22-macos-arm64
平台Linux / Windows / macOS插件侧栏、抽屉、管理面板、网关启停跨平台可用;远程启停本机 DSH 仅 Linux(依赖 systemd user 服务,Windows 返回 PLATFORM_UNSUPPORTED)
原生模块无运行时零第三方 npm 依赖;Android APK 由仓库内 Capacitor 8 工程构建(构建期依赖 @capacitor/core 等)
systemd仅 Linux远程启停 DSH 走 systemctl --user,macOS / Windows 暂不支持

安装方式

dsh plugin --profile web add github:Blank-not-black/dsh-Remote/packages/plugin

配置项

配置类型说明默认值
DSH_REMOTE_GATEWAY_PORT环境变量内置网关监听端口;存在时优先于文件和默认值未设置(读文件或默认 8787)
~/.dsh-remote/gateway-port文件写入单个端口数字即生效(写入单个整数即可)未设置时默认 8787
DSH_REMOTE_GATEWAY环境变量让插件侧管理面板代理到外部网关地址;用于绕过本机自起的内置网关未设置(指向本机端口)
DSH_REMOTE_AUTOSTART环境变量设为 0 彻底禁用插件自动管理网关(连自愈也不做)未设置(默认启用自愈)
~/.dsh-remote/gateway.enabled文件持久化用户意图:on / off;抽屉面板"启动 / 停止网关"按钮会写此文件未设置时默认 on
DSH_REMOTE_TOKEN / TOKEN_FILE / TOKEN环境变量覆盖令牌文件位置或直接提供令牌;环境变量提供时不走"轮换令牌"~/.dsh-remote/token,首次启动自动生成 24 字节 base64url
DSH_REMOTE_FS_ROOT环境变量透传给网关,文件传输额外允许的目录根(Linux / macOS 用 :,Windows 用 ;)~(用户主目录)+ DSH 已登记工作区自动放行
DSH_REMOTE_FS_MAX_UPLOAD环境变量透传给网关,单文件上传字节上限2147483648(2GB)
DSH_HEALTH_PATH环境变量透传给网关,/health 探测 DSH 上游可达性的路径/
DSH_REMOTE_CORS_ORIGINS环境变量透传给网关,额外允许的跨域来源(逗号分隔,* 放行全部)未设置(默认仅同源、Capacitor / ionic / localhost)
DSH_REMOTE_DSH_SERVICE环境变量透传给网关,远程启停 DSH 使用的 systemd user 服务名dsh-web
DSH_REMOTE_DSH_CONTROL_TIMEOUT_MS / DSH_REMOTE_DSH_CONTROL_POLL_MS环境变量透传给网关,远程启停 DSH 单次命令限时 / 阶段间轮询间隔(毫秒)45000 / 500
DSH_REMOTE_ANNOUNCEMENTS_URL环境变量透传给网关,中央公告源 HTTPS 地址,设为空字符串彻底禁用https://vm-0-2-ubuntu.tail1f6fc4.ts.net/announcements.json
DSH_REMOTE_FEEDBACK_URL环境变量透传给网关,用户反馈提交端点https://vm-0-2-ubuntu.tail1f6fc4.ts.net/submit
GATEWAY_WS_PING_MS / GATEWAY_WS_PONG_TIMEOUT_MS / GATEWAY_WS_IDLE_MS / GATEWAY_WS_TICKET_TTL_MS / GATEWAY_WS_UPGRADE_TIMEOUT_MS环境变量透传给网关,WebSocket 心跳 / Pong 等待 / 空闲 / 短时 ticket TTL / 升级超时(毫秒)30000 / 90000 / 180000 / 90000 / 15000
HTTP_PROXY / HTTPS_PROXY / ALL_PROXY / NO_PROXY(含小写变体)环境变量透传给网关代理变量,影响网关 → DSH 上游的 HTTP 请求透传宿主机代理变量

注:插件 host half 本身只接受表内前 5 个配置;其余配置通过 systemd-run / detached spawn 时透传给子网关进程,由网关自身解析生效。

常见问题

Q: 安装到 web profile 后侧栏没出现 "DSH Remote" 入口怎么办?

A: 必须完整重启 DSH Web 进程(systemctl --user restart dsh-web,或手动停掉旧 dsh web 再启动)。cordis 的插件注册只在进程启动时扫描一次,热重载或仅刷新页面不会重新加载 cordis.patch.yml。重启后还需要在 DSH Web 浏览器端 Ctrl+F5 强刷一次,避免缓存住旧 chunk。

Q: 抽屉面板里显示"网关未运行",怎么处理?

A: 在抽屉面板点"启动网关"按钮,或重启 DSH Web 让插件自愈拉起。启动前插件会做 127.0.0.1 端口占用预检(net.connect),端口被占用会直接拒绝并提示修改端口。要禁用自愈可设置 DSH_REMOTE_AUTOSTART=0 或写入 ~/.dsh-remote/gateway.enabled=off(前者优先级更高)。

Q: 自带网关和单独跑 gateway.js 有什么区别?

A: 插件版本始终与 DSH 同进程路径绑定:DSH 启动就拉起网关、DSH 重启就刷新网关,自愈逻辑写在插件里(端口 / 上游变化才重启,避免 VPN 抖动误重启)。单独跑 gateway.js 是一个独立 Node 进程,DSH 重启或网关崩溃后不会自动恢复,需要外部 systemd / launchd 或手动拉起。两种模式共用同一份 gateway.cjs 二进制能力,配置项一致。

Q: 改了网关端口,手机怎么连不上?

A: 端口优先级是 DSH_REMOTE_GATEWAY_PORT 环境变量 → ~/.dsh-remote/gateway-port 文件 → 8787。改了端口必须同步三处:手机"设置 → 服务器"的地址、路由器的防火墙放行、局域网 IP 后的端口号。插件管理面板的"网关配置"会显示当前实际端口和来源(env / file / default),改完先在那里确认,再去手机上配。

Q: 斜杠命令(/xxx)是怎么从手机发到 DSH 的?

A: 手机端 → 网关 /remote/api/command(带 Bearer 令牌)→ 插件同名前缀路由 → ctx.agents.get(sessionId) 拿已发布的 live Agent,拿不到时 ctx.agents.resume({ resumeSessionId }) 兜底 → ctx.commands.execute(agent, line, signal) 执行。DSH 自带的 api-proxy 白名单不含 commands.*,所以这类调用必须经插件中转;执行失败或命令不存在时返回 executed:false,前端会自动回退成普通文本。

Q: Windows 上能用吗?

A: 插件侧栏入口、抽屉、管理面板、网关启停(/admin/api/gateway start/stop)跨平台都可用;但"远程启停本机 DSH"功能依赖 systemd user 服务,Windows 调用 /admin/api/dsh 会返回 PLATFORM_UNSUPPORTED。Linux 下若 systemctl 不可达(DBUS / user bus 失败)会返回 SYSTEMD_UNAVAILABLE,并细分命令超时、权限不足、服务失败等错误码,UI 直接显示细分原因而不是笼统的 502。

上手难度

入门 — 安装一行命令 dsh plugin --profile web add github:...,装完重启 DSH Web + Ctrl+F5 强刷即可在侧栏看到入口;抽屉面板提供一键启动 / 停止网关、端口配置、二维码配对和 Doctor 自检,按提示走普通用户就能跑通。进阶配置(端口、文件根、DSH systemd 服务名、CORS 等)通过环境变量或面板接口设置,普通用户基本无需关心。

已知问题与限制

  • 端口被占时拒绝启动,不自动换端口:插件启动前会做端口占用预检(net.connect 127.0.0.1),若端口被其他进程占用会直接返回错误并提示用户改端口(写 ~/.dsh-remote/gateway-port 或设 DSH_REMOTE_GATEWAY_PORT),不会自动选下一个可用端口
  • 自愈策略保守:仅当网关版本或 DSH 上游地址变化时才重启网关;DSH HTTP 临时不可达 / VPN 抖动不会触发重启(避免重启风暴)。若 DSH 长期无法连通,需手动重启 DSH Web 才会刷新网关
  • 远程启停 DSH 仅 Linux:Windows 调用 /admin/api/dsh 返回 PLATFORM_UNSUPPORTED;macOS 同理(systemctl 不存在);Linux 下还细分 SYSTEMCTL_NOT_FOUND / SYSTEMD_UNAVAILABLE / PERMISSION_DENIED / COMMAND_TIMEOUT / COMMAND_FAILED 等错误码
  • 升级后侧栏入口或面板内容没更新 = 浏览器缓存:DSH Web 端必须 Ctrl+F5 强刷;手机端需要完全退出 App 后重开,避免旧静态资源缓存
  • 环境变量提供令牌时不支持"轮换令牌":DSH_REMOTE_TOKEN / TOKEN_FILE / TOKEN 启动时覆盖令牌文件,但通过环境变量启动的网关执行 /admin/api/token/rotate 会失败;如需轮换令牌,需改回 ~/.dsh-remote/token 文件方式
  • 网关刚启动时管理面板短暂显示 plugin 模式:管理面板数据默认代理本地网关(/remote/admin/api/state),网关不可用时回退返回插件模式状态;自愈逻辑触发后下个轮询周期即可见网关数据
  • 不要用 systemctl --user restart dsh-remote-gateway.service 重启网关:插件拉起的网关可能是 transient 进程(systemd-run 起)或 detached 子进程,标准 systemctl 重启方式会报 "Unit not found";正确做法是插件面板"启动网关"按钮,或 pgrep -f "node .../gateway.cjs" 拿精确 PID 后 kill,再 systemctl --user restart dsh-web 让插件自愈拉起
  • LAN IP 列表依赖系统网卡枚举:插件用 node:os 的 networkInterfaces() 枚举 IPv4,遇到权限不足或网卡驱动未就绪会返回空数组;此时面板不显示局域网 IP,需用 DSH_REMOTE_GATEWAY 强制指定外部网关地址绕过
  • macOS Apple Silicon 单文件网关为预览产物:仓库仅正式发布 node22-linux-x64 与 node22-win-x64 单文件网关,macOS arm64 标记为独立预览产物未承诺与主版本同步(不影响插件模式使用)

Read the usage guide →

Install steps, key points, FAQ and compatibility for this plugin — auto-derived from indexed fields.

Listing badge

Listed on deepseek-plugin.org
[![Listed on deepseek-plugin.org](https://img.shields.io/badge/listed_on-deepseek--plugin.org-007EC6)](https://deepseek-plugin.org/plugins/Blank-not-black/dsh-Remote/packages/plugin)

Paste this markdown into your GitHub README to link back to this listing. The badge only states the listing — not a security endorsement.

← Back to plugin directory