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

手机远程接入 EarhartZhao/dsh-mobile-plugin

DeepSeek 客户端
EarhartZhao8 天前有提交已提供中文文档扫描:含敏感能力兼容 / 相关生态

让手机安全连上本地 dsh,无需公网 IP 或开放端口

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

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

相关生态插件(非 dsh 原生,按其对应运行时安装)
git clone https://github.com/EarhartZhao/dsh-mobile-plugin.git

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:仅索引
是什么
生态应用
桌面端 / Web 外壳,不以 dsh plugin add 安装
装得上吗
本站尚未做安装检查
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 8 天前
档位由哪些信号合成

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

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

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

可执行外部命令读写/删除本地文件发起外部网络请求
查看扫描证据(共 30 处,展示前 30 条)
  • 发起网络请求
    src/bridge.ts:128
    fetch(request: Request): Promise<Response>
  • 发起网络请求
    src/bridge.ts:1292
    const response = await this.options.carrier.fetch(request)
  • 发起网络请求
    src/events.ts:206
    }, private readonly carrier?: { fetch(request: Request): Promise<Response> }, private readonly onStreamError?: (name: GatewayStreamName, error: unknow
  • 发起网络请求
    src/events.ts:431
    const response = await this.carrier.fetch(request)
  • 发起网络请求
    src/hub-check.ts:301
    const reply = await connection.request(
  • 读取本地文件
    src/identity.ts:59
    const raw = await readFile(this.filePath, 'utf8')
  • 写入本地文件
    src/identity.ts:76
    await mkdir(dirname(this.filePath), { recursive: true })
  • 写入本地文件
    src/identity.ts:79
    await writeFile(tmp, JSON.stringify(identity, null, 2), { encoding: 'utf8', mode: 0o600 })
  • 写入本地文件
    src/identity.ts:80
    await rename(tmp, this.filePath)
  • 删除本地文件
    src/identity.ts:82
    await rm(tmp, { force: true }).catch(() => undefined)
  • 读取本地文件
    src/index.ts:80
    ?? `${PLUGIN_VERSION}-${Math.trunc(statSync(PLUGIN_LOADED_FROM).mtimeMs).toString(36)}`
  • 读取本地文件
    src/index.ts:243
    const manifest = JSON.parse(readFileSync(join(process.cwd(), 'package.json'), 'utf8')) as { version?: unknown }
  • 执行外部命令来自配置/变量
    src/index.ts:931
    child = spawn(command, ['-c', configPath], {
  • 读取本地文件
    src/installed-version.ts:32
    const parsed: unknown = JSON.parse(readFileSync(path, 'utf8'))
  • 读取本地文件
    src/instance-id.ts:137
    raw = await readFile(this.filePath, 'utf8')
  • 写入本地文件
    src/instance-id.ts:163
    await mkdir(dirname(this.filePath), { recursive: true })
  • 写入本地文件
    src/instance-id.ts:166
    await writeFile(tmp, JSON.stringify(record, null, 2), { encoding: 'utf8', mode: 0o600 })
  • 写入本地文件
    src/instance-id.ts:167
    await rename(tmp, this.filePath)
  • 删除本地文件
    src/instance-id.ts:169
    await rm(tmp, { force: true }).catch(() => undefined)
  • 读取本地文件
    src/profile-migration.ts:226
    return await readFile(path, 'utf8')
  • 读取本地文件
    src/profile-migration.ts:245
    return JSON.parse(await readFile(join(dir, 'package.json'), 'utf8')) as ProfileManifest
  • 写入本地文件
    src/profile-migration.ts:269
    await writeFile(temporary, content, { mode: 0o600 })
  • 写入本地文件
    src/profile-migration.ts:270
    await rename(temporary, path)
  • 读取本地文件
    src/profile-migration.ts:311
    const manifestText = await readFile(join(location.dir, 'package.json'), 'utf8')
  • 读取本地文件
    src/tokens.ts:125
    const raw = await readFile(this.filePath, 'utf8')
  • 写入本地文件
    src/tokens.ts:167
    await mkdir(dirname(this.filePath), { recursive: true })
  • 写入本地文件
    src/tokens.ts:170
    await writeFile(tmp, JSON.stringify(data, null, 2), { encoding: 'utf8', mode: 0o600 })
  • 写入本地文件
    src/tokens.ts:171
    await rename(tmp, this.filePath)
  • 删除本地文件
    src/tokens.ts:173
    await rm(tmp, { force: true }).catch(() => undefined)
  • 写入本地文件
    src/tokens.ts:374
    async rename(deviceId: string, name: string): Promise<boolean> {
扫描于 2026/11/2(1 天前) · 范围 全包扫描(包内未声明入口) · 来源 GitHub 仓库

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

依赖的 DSH / Cordis 模块
@deepseek-ai/cordis@deepseek-ai/cosmokit@deepseek-ai/schemastery
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

通过出站 NATS 桥把手机应用安全连接到本地 DeepSeek Harness 实例。

README

由 DeepSeek 最新模型翻译生成
简体中文 · English dsh-mobile-plugin Cordis 插件,把本地 DeepSeek Harness 安全地带到手机上。 插件主动连接 NATS Hub,把 dsh 的 RPC 与实时事件桥接给 dsh-mobile。电脑不需要公网 IP,也不需要开放任何入站端口。 快速开始 · 安装 · 首次配置 · 连接 App · 自建 Hub 为什么需要它 dsh 通常跑在家用电脑或办公电脑上,没有公网 IP。手机直接访问不到它,而把 dsh 暴露到公网又会扩大攻击面。 本插件把连接方向反过来:电脑和手机都主动连接同一个 NATS Hub。Hub 只负责转发,插件仍运行在 dsh 进程内,因此会话、审批、提问、文件与工具事件都来自同一个宿主。
展开完整文档(README 剩余 1 节)
简体中文 · English

dsh-mobile-plugin

Cordis 插件,把本地 DeepSeek Harness 安全地带到手机上。

插件主动连接 NATS Hub,把 dsh 的 RPC 与实时事件桥接给 dsh-mobile。电脑不需要公网 IP,也不需要开放任何入站端口。

快速开始 · 安装 · 首次配置 · 连接 App · 自建 Hub

为什么需要它

dsh 通常跑在家用电脑或办公电脑上,没有公网 IP。手机直接访问不到它,而把 dsh 暴露到公网又会扩大攻击面。

本插件把连接方向反过来:电脑和手机都主动连接同一个 NATS Hub。Hub 只负责转发,插件仍运行在 dsh 进程内,因此会话、审批、提问、文件与工具事件都来自同一个宿主。

flowchart LR
Phone["dsh-mobileAndroid / iOS"] -->|"WSS 8443C 端账号 + 设备令牌"| Hub["NATS Hub"]
Hub -->|"Leaf 7422"| Local["本机 NATS Leaf"]
Local -->|"localhost:4222"| Plugin["dsh-mobile-plugin"]
Plugin --> DSH["deepseek-harnessWeb / Desktop"]

核心能力

| 连接 | 安全 | 移动体验 |
| 宿主主动出站连接,不开放入站端口 | 扫码配对,设备令牌可单独吊销 | 完整 RPC、实时事件流与历史分页 |
| 复用 dsh Typert Remote 与事件词汇 | Hub CA 随二维码下发,不内置账号 | 子智能体、审批、提问、队列与文件 |
| 本机 NATS 探测、启动与链路诊断 | 每台安装自动生成独立 instanceId | 插件页与回环控制台使用同一套配置 |
| 支持 npm、Release tarball、Git 与本地 link | 密钥不进入移动端 wire 或诊断结果 | 控制台内检查更新,升级后提示重启 |

快速开始

开始前准备三样东西:

1. 能运行 dsh web 的电脑。
2. NATS Hub 地址、C 端账号密码,以及 Hub 的 ca.crt。
3. 本机 nats-server 与 leaf.conf;没有时按 AI 接入清单准备。

在 dsh 的「插件」页安装并启用:

@dsh-earhartzhao/dsh-mobile-plugin

然后打开插件配置区,按页面顺序完成:

1. 连接 Hub:填写 Hub 地址、账号和密码。
2. 获取 CA:粘贴 ca.crt,或点击「从 Hub 获取 CA」。
3. 启动本机 NATS:状态显示已连接后继续。
4. 配对手机:生成二维码,用 dsh-mobile 扫码。

App 0.1.7 支持插件 >=0.2.2 <0.3.0,当前 mobileApi 为 2。版本或能力不匹配时,App 会在连接阶段明确报错。

安装

npm(推荐)

pnpm add @dsh-earhartzhao/dsh-mobile-plugin@latest

发布的 npm 包已经包含 lib/,安装时不会运行构建脚本,不需要配置 allowBuilds。也可以直接在 dsh 插件页按包名安装。npm 网页可能对部分网络环境返回 403,这不影响 registry 安装;包元数据可以直接从 npm registry 查看。

pnpm 11 默认有 24 小时的新版本发布年龄门禁。当天刚发布的版本可能暂时解析不到;需要立即安装时请显式指定版本。长期使用时可以把整包名加入 profile 的 pnpm-workspace.yaml:

minimumReleaseAgeExclude:
- '@dsh-earhartzhao/dsh-mobile-plugin'

Release 预构建包

每次发布都会在 GitHub Releases 提供预构建 tarball:

https://github.com/EarhartZhao/dsh-mobile-plugin/releases/latest/download/dsh-mobile-plugin.tgz

这种方式同样不运行构建脚本,适合无法访问 npm registry 的机器。

Git 源码

pnpm add github:EarhartZhao/dsh-mobile-plugin

Git 安装会执行 prepare 构建。pnpm 10+ 首次会以 ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED 拒绝,并按 commit 给出精确的 allowBuilds 键。新机器优先使用 npm 或 Release 包,避免每个 commit 都重新批准构建。

开发机使用 link: 引用本仓库

在 profile 的 package.json 中使用:

{
"dependencies": {
"@dsh-earhartzhao/dsh-mobile-plugin": "link:<本仓库路径>" } }

使用 link:,不要使用 file:。file: 会复制当前内容,源码变化后 pnpm 不会自动重打包。Windows 上还要保持本仓库的 node_modules 没有符号链接;本仓库因此固定 nodeLinker: hoisted。

安装后必须启用

包被加入 profile 依赖还不够。插件页里的「启用」会把包名写进 dsh.profile.bundles,包内 cordis.patch.yml 提供的 mobile-bridge 行才会生效。

没启用时 /mobile-bridge 会直接返回 404。装好后如果仍显示「declares no dsh.bundle」,通常是 profile 里物化了旧副本;在 profile 目录重新执行 pnpm install。

从旧裸包名 dsh-mobile-plugin 迁移

0.2.27 起包名改为 @dsh-earhartzhao/dsh-mobile-plugin。旧 profile 里按包名断言的覆盖行不会自动匹配新包,Hub 配置会静默失效。

先停止 dsh,再运行:

node scripts/migrate-to-scoped.mjs ~/.dsh/profiles/web

脚本会安装新包、原地替换 dsh.profile.bundles 中的旧包名、修正 id: mobile-bridge 行的 name,并移除旧依赖。修改前会备份 cordis.patch.yml;备份中含有明文密码,不要提交。

升级后重启 dsh

宿主始终使用启动时加载的 JavaScript。升级插件后,磁盘上的版本可能已经是新版本,但运行中的仍是旧代码。

从 0.2.45 起,控制台更新按钮可以直接完成升级;如果宿主返回 already-installed,插件会自动执行一次替换,不需要用户先卸载再安装。升级完成后仍需重启 dsh:

- 终端启动:按 Ctrl+C,重新运行 dsh web。
- 桌面版:使用菜单「重启应用与 Host」。

控制台会在「插件版本」旁提示磁盘版本与运行版本不一致。

首次配置

手机使用插件里配置的 Hub 凭证,App 不内置任何账号。因此必须先配置插件,再生成二维码。

1. Hub 地址与账号

打开「侧边栏 → 插件 → @dsh-earhartzhao/dsh-mobile-plugin」,或访问:

http://127.0.0.1:3080/mobile-bridge

Hub 地址可以填写完整的 wss://<host>:8443,也可以只填主机或 IP。缺 scheme 时自动补 wss://,缺端口时自动补 8443。

2. Hub CA

手机不内置任何 CA,信任锚来自二维码。自签 Hub 必须配置 ca.crt。

- 已经有 ca.crt:直接粘贴并保存。
- 不知道 CA 在哪:点击「从 Hub 获取 CA」。
- Hub 只发送叶子证书:按钮会给出在 Hub 上拼 fullchain 的命令。

CA 是公开材料,不包含私钥;ca.key 应留在管理机,不能上传到 Hub。

3. 本机 NATS Leaf

点击「启动本地 NATS」。插件会先探测 natsUrl,端口已监听时直接复用;否则启动已经安装好的 nats-server。

查找顺序:

1. NATS_SERVER_PATH / NATS_CONFIG_PATH 环境变量。
2. 控制台「手动指定路径」。
3. $DSH_HOME/mobile-bridge/、~/.nats-leaf/、~/.config/nats/。
4. 平台常见目录与 PATH。

新电脑还没有 nats-server 和 leaf.conf 时,把 docs/04-ai-onboarding.md 整页交给这台电脑上的 AI,按清单安装并完成自检。

4. 测试与配对

「测试 Hub 账号」会逐段检查:

| 检查项 | 失败时通常意味着 |
| local | 插件没有连上本机 NATS |
| credentials | Hub 账号或密码错误 |
| hub-path | 本机 Leaf 没有桥接到 Hub |
| certificate | 二维码 CA 与 Hub 实际证书不匹配 |

全部通过后点击「生成配对二维码」,用 App 扫码。凭证或 CA 未配置时不会发码,避免手机拿到一个必然失败的二维码。

实例 ID

instanceId 是这台安装在 Hub 上的命名空间:

svc.dsh.<instanceId>.<method>
evt.dsh.<instanceId>.<eventKey>.mux

字段留空表示自动生成。第一次启动时会生成 8 位 ID(4 位毫秒时间戳 + 4 位随机),写入 $DSH_HOME/mobile-bridge/instances.json。
- 同一台电脑上的不同 dsh 配置档各自拥有独立 ID。
- 升级、重装、重启不会改变 ID。
- 修改 ID 或更换安装路径后,已配对手机需要重新扫码。
- 多个实例共用同一个 ID 会互相抢答,事件也会串流。

凭证与配置分层

| 层 | 位置 | 用途 |
| 组合层 | 包内 cordis.patch.yml | 非密默认值与 mobile-bridge 行 |
| 用户层 | 配置档的 cordis.patch.yml | 本机 Hub 地址、账号、CA 与实例名 |
| 凭据层 | 环境变量或 dsh-credentials-local | 推荐的正式密码托管方式 |

控制台「保存」写的是配置档覆盖行。hubPass 标记为 secret,非本机请求只能得知是否已配置;但当前值仍会以明文保存在配置档文件中,因此不要提交或公开分享该文件。

已知边界

- 大文件不走 NATS。 Hub 单条消息约 1 MiB,插件只传有界文件窗口;更大的文件需要独立下载端点。
- 目录列表没有游标。 宿主默认最多返回 2000 项,超出时只标记 truncated。
- CA 指纹尚未强制校验。 App 会保存并展示指纹,但 RN WebSocket 暂时拿不到对端证书。
- 没有系统级后台推送。 审批与提问提醒目前只在 App 前台有效。
- 文件变更流不是操作系统监视器。 只覆盖 dsh 自己记录的读写事件。

开发与验证

需要 Node.js 22+ 与 pnpm 11。本地集成测试还需要 nats-server。

pnpm install
pnpm run typecheck
pnpm run typecheck:client
pnpm test
pnpm run build

对运行中的宿主做端到端验收:

node scripts/fake-app.mjs nats://127.0.0.1:4222 <pairCode> home
node scripts/watch-probe.mjs nats://127.0.0.1:4222 home <scratchPath>

发布由 v* tag 触发。CI 会校验 tag、package.json、src/bridge.ts 的 PLUGIN_VERSION 与测试断言一致,然后构建并发布 tarball。发布流程见 AGENTS.md。

文档

| 文档 | 内容 |
| 00-plugin-plan.md | 定位、架构、安装方式与决策记录 |
| 01-auth-pairing.md | 双层凭证、配对流程与 token 存储 |
| 02-nats-server.md | 复用现有 NATS Hub 的改动清单 |
| 03-nats-self-host.md | 从零搭建 Hub、TLS、Leaf 与验收 |
| 04-ai-onboarding.md | 新电脑接入清单,可直接交给 AI 执行 |

历史版本说明见 GitHub Releases。
预览分享卡片长什么样 ↓EarhartZhao/dsh-mobile-plugin
分享 · DeepSeek Harness Hub
EarhartZhao/dsh-mobile-plugin

让手机安全连上本地 dsh,无需公网 IP 或开放端口

这是你的仓库?认领条目

回到顶部