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

口袋工作台 just-a-FA-for-name/DSHgo

DeepSeek Harness
just-a-FA-for-name9 天前有提交已提供中文文档扫描:含敏感能力

DSHgo - 把 DeepSeek Harness dsh 工作台装进口袋:手机端 App内置 Tailscale+…

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

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

自动兼容检查有告警:未发布到 npm registry,仅可从源码安装;安装清单取自 pc-plugin/package.json。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add just-a-FA-for-name/DSHgo
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

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

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

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

未发布到 npm registry,仅可从源码安装;安装清单取自 pc-plugin/package.json

展开查看检查明细 ↓

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

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

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

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

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

可执行外部命令读写/删除本地文件发起外部网络请求
查看扫描证据(共 80 处,展示前 58 条)
  • 读取本地文件
    pc-plugin/bridge/dsh-phone-proxy.cjs:35
    const transportScript = fs.readFileSync(path.join(__dirname, 'transport.js'));
  • 执行外部命令固定命令
    pc-plugin/bridge/dsh-phone-proxy.cjs:89
    execFile('powershell', ['-NoProfile', '-ExecutionPolicy', 'Bypass', '-File', DISCOVER], { timeout: 10000, windowsHide: true }, async (err, out) => {
  • 发起网络请求
    pc-plugin/bridge/dsh-phone-proxy.cjs:101
    const req = http.request({ host: '127.0.0.1', port, method: 'GET', path: '/', headers: { host: AUTHORITY, origin: 'http://' + AUTHORITY, cookie: pair
  • 读取本地文件
    pc-plugin/bridge/dsh-phone-proxy.cjs:123
    const raw = fs.readFileSync(CLI_LOG, 'utf8').split(String.fromCharCode(0)).join('');
  • 发起网络请求
    pc-plugin/bridge/dsh-phone-proxy.cjs:136
    const req = http.request(
  • 发起网络请求
    pc-plugin/bridge/dsh-phone-proxy.cjs:211
    const upstream = http.request(
  • 发起网络请求
    pc-plugin/bridge/dsh-phone-proxy.cjs:314
    const up = http.request(target, (u) => {
  • 读取本地文件
    pc-plugin/bridge/dsh-phone-proxy.cjs:352
    fs.stat(full, (e, st) => {
  • 读取本地文件
    pc-plugin/bridge/dsh-phone-proxy.cjs:361
    return fs.readFile(full, (e2, buf) => {
  • 读取本地文件
    pc-plugin/bridge/dsh-phone-proxy.cjs:374
    fs.createReadStream(full).pipe(res);
  • 发起网络请求
    pc-plugin/bridge/dsh-phone-proxy.cjs:469
    const r = http.request({ host: '127.0.0.1', port, method: req.method, path, headers }, (up) => {
  • 发起网络请求
    pc-plugin/bridge/dsh-phone-proxy.cjs:482
    const r = http.request({ host: '127.0.0.1', port, method: req.method, path: pathOverride || req.url, headers });
  • 发起网络请求
    pc-plugin/bridge/resumable-upload.cjs:39
    const up = http.get({ host: '127.0.0.1', port, path: '/', headers }, response => {
  • 发起网络请求
    pc-plugin/bridge/resumable-upload.cjs:68
    const up = http.request({ host: '127.0.0.1', port, method: 'POST', path: record.target, headers }, response => {
  • 读取本地文件
    pc-plugin/bridge/resumable-upload.cjs:87
    pipeline(fs.createReadStream(record.file), up).catch(reject);
  • 写入本地文件
    pc-plugin/bridge/resumable-upload.cjs:181
    await pipeline(req, limit, fs.createWriteStream(record.file, { flags: 'r+', start: offset }));
  • 发起网络请求
    pc-plugin/bridge/transport.js:69
    const response = await fetch(new URL(url, base).href, { ...init, credentials: 'same-origin', cache: 'no-store', signal: controller.signal });
  • 发起网络请求
    pc-plugin/bridge/transport.js:95
    const response = await fetch(url, { method: 'POST', body: request.body,
  • 读取本地文件
    pc-plugin/connection.test.cjs:16
    const full = fs.readFileSync(file, 'utf8').replace(/ /g,'\n');
  • 发起网络请求
    pc-plugin/connection.test.cjs:37
    const req = http.request({ host: '127.0.0.1', port, ...options });
  • 读取本地文件
    pc-plugin/connection.test.cjs:205
    .find(p => fs.existsSync(p));
  • 读取本地文件
    pc-plugin/connection.test.cjs:206
    const source = fs.readFileSync(sourcePath, 'utf8');
  • 发起网络请求
    pc-plugin/connection.test.cjs:219
    await assert.rejects(context.window.fetch({ url: '/api/run', method: 'POST' }));
  • 发起网络请求
    pc-plugin/connection.test.cjs:222
    await assert.rejects(context.window.fetch('/api/run', { method: 'POST' }));
  • 发起网络请求
    pc-plugin/connection.test.cjs:225
    await assert.rejects(context.window.fetch('/api/read', { signal: { aborted: true } }));
  • 发起网络请求
    pc-plugin/connection.test.cjs:229
    assert.equal(await context.window.fetch('/api/read'), 'ok');
  • 删除本地文件
    pc-plugin/connection.test.cjs:237
    t.after(() => fs.rmSync(home, {recursive: true, force: true}));
  • 执行外部命令固定命令
    pc-plugin/connection.test.cjs:238
    const install = () => execFileSync('powershell.exe', [
  • 写入本地文件
    pc-plugin/connection.test.cjs:243
    fs.writeFileSync(path.join(destination, 'lib/index.js'), 'outdated plugin');
  • 读取本地文件
    pc-plugin/connection.test.cjs:245
    assert.equal(fs.readFileSync(path.join(destination, 'lib/index.js'), 'utf8'),
  • 读取本地文件
    pc-plugin/connection.test.cjs:246
    fs.readFileSync(path.join(__dirname, 'lib/index.js'), 'utf8'));
  • 读取本地文件
    pc-plugin/connection.test.cjs:247
    assert.equal(fs.existsSync(path.join(destination, 'lib/lib')), false);
  • 写入本地文件
    pc-plugin/lib/index.js:46
    try { mkdirSync(dir, { recursive: true }); } catch {}
  • 执行外部命令来自配置/变量
    pc-plugin/lib/index.js:115
    const child = spawn(process.execPath, [script], {
  • 执行外部命令来自配置/变量
    pc-plugin/lib/index.js:144
    const child = spawn(executable, args, {
  • 执行外部命令来自配置/变量
    pc-plugin/lib/index.js:162
    execFile(bin, ["serve", "--bg", String(cfg.bridgePort)], { timeout: 8000 }, (err) => resolve({ok:!err,missing:err?.code==='ENOENT'}));
  • 执行外部命令固定命令
    pc-plugin/lib/index.js:205
    execFile("taskkill", ["/PID", String(child.pid), "/T", "/F"], { timeout: 3000 }, () => {});
  • 删除本地文件
    pc-plugin/upload.test.cjs:35
    await fs.rm(directory, { recursive: true, force: true });
  • 发起网络请求
    pc-plugin/upload.test.cjs:39
    const response = await fetch(base + url, { method, body, headers: { cookie } });
  • 发起网络请求
    pc-plugin/upload.test.cjs:54
    const partial = http.request(f.base + endpoint + '?offset=0', { method: 'PUT',
  • 发起网络请求
    pc-plugin/upload.test.cjs:61
    assert.equal((await f.request(endpoint)).offset, 0);
  • 读取本地文件
    pc-plugin/upload.test.cjs:62
    assert.equal((await fs.stat(path.join(f.directory, created.id))).size, 0);
  • 发起网络请求
    pc-plugin/upload.test.cjs:65
    assert.equal((await f.request(endpoint + '?offset=' + offset, 'PUT', data.subarray(offset, end))).offset, end);
  • 发起网络请求
    pc-plugin/upload.test.cjs:68
    assert.equal((await f.request(endpoint + '?offset=0', 'PUT', data.subarray(0, end))).status, 409);
  • 发起网络请求
    pc-plugin/upload.test.cjs:69
    assert.equal((await f.request(endpoint)).offset, end);
  • 读取本地文件
    pc-plugin/upload.test.cjs:108
    assert.equal((await fs.readdir(f.directory)).length, 1);
  • 读取本地文件
    pc-plugin/upload.test.cjs:136
    assert.equal((await fs.stat(path.join(f.directory,id))).size, 0);
  • 读取本地文件
    phone-app/mobile-ui.test.cjs:40
    if (!fs.existsSync(executable)) { t.skip('Set DSH_TEST_BROWSER to a Chromium browser'); return; }
  • 执行外部命令来自配置/变量
    phone-app/mobile-ui.test.cjs:42
    const browser = spawn(executable, [
  • 删除本地文件
    phone-app/mobile-ui.test.cjs:56
    try { fs.rmSync(profile, {recursive: true, force: true, maxRetries: 5, retryDelay: 100}); } catch {}
  • 读取本地文件
    phone-app/mobile-ui.test.cjs:59
    for (let i = 0; i < 100 && !fs.existsSync(activeFile); i++) {
  • 读取本地文件
    phone-app/mobile-ui.test.cjs:62
    assert.ok(fs.existsSync(activeFile), 'browser debugging endpoint started');
  • 读取本地文件
    phone-app/mobile-ui.test.cjs:63
    const [port, socketPath] = fs.readFileSync(activeFile, 'utf8').trim().split(/ ? /);
  • 发起网络请求
    phone-app/mobile-ui.test.cjs:66
    const pages = await (await fetch('http://127.0.0.1:' + port + '/json/list')).json();
  • 读取本地文件
    phone-app/mobile-ui.test.cjs:131
    const script = fs.readFileSync(path.join(__dirname, 'res/raw/mobile_ui.js'), 'utf8');
  • 读取本地文件
    phone-app/mobile-ui.test.cjs:340
    const script=fs.readFileSync(path.join(__dirname,'../pc-plugin/bridge/transport.js'),'utf8').split('/* Runs before DSH boot.')[0];
  • 写入本地文件
    phone-app/native-policy.test.cjs:24
    fs.writeFileSync(path.join(directory,'PolicyAudit.java'),source);
  • 删除本地文件
    phone-app/native-policy.test.cjs:28
    }finally{fs.rmSync(directory,{recursive:true,force:true});}
扫描于 2026/11/3(0 天前) · 范围 全包扫描 · 来源 GitHub 仓库

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

给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
展开完整介绍(100 字)↓

DSHgo - 把 DeepSeek Harness (dsh) 工作台装进口袋:手机端 App(内置 Tailscale)+ dsh PC 插件,开包即用。有问题 B 站视频下方交流 @Fa2517

README

由 DeepSeek 最新模型翻译生成
DSHgo 把 DeepSeek Harness (dsh) 的工作台装进口袋。 点开手机 App 就是电脑上正在跑的实时会话——可看、可操作、可语音。 手机端一个 APK(Tailscale 隧道内核内置),PC 端一个 dsh 插件 + Tailscale,开包即用。 - 作者:Fa2517(bilibili) - 版本:v1.2 · 本项目完全开源 · 更新日志 - 有任何问题,欢迎在 B 站视频下方留言交流 → @Fa2517;GitHub Issues 也行,但最好在 B 站知会一声 功能 | 🔒 内置加密隧道 | Tailscale 内核编译进 APK,App 内登录建隧道,装一个 App 就够 | | 🎯 应用专用隧道 | 只允许 DSHgo 使用 VPN,显式下发 MagicDNS,其他应用保持原有网络 | | 🧭 万能抓取 | 隧道接通后自动识别远程工作台并直连,不挑主机名/端口 | | 👀 实时监控 | 电脑上正在跑的会话、子智能体、后台任务,手机实时可见可操作 | | 🎨 DSHgo / ZCode go 双模式 | 顶栏一键切换;切 ZCode 自动关隧道、切回自动开 | | 🪟 站点小窗 | 悬浮窗查看本地监控页(默认关闭,可选开关);页面里的 127.0.0.1 请求自动穿隧道回电脑 |
展开完整文档(README 剩余 1 节)
DSHgo

把 DeepSeek Harness (dsh) 的工作台装进口袋。 点开手机 App 就是电脑上正在跑的实时会话——可看、可操作、可语音。

手机端一个 APK(Tailscale 隧道内核内置),PC 端一个 dsh 插件 + Tailscale,开包即用。

- 作者:Fa2517(bilibili)
- 版本:v1.2 · 本项目完全开源 · 更新日志
- 有任何问题,欢迎在 B 站视频下方留言交流 → @Fa2517;GitHub Issues 也行,但最好在 B 站知会一声

功能

| 🔒 内置加密隧道 | Tailscale 内核编译进 APK,App 内登录建隧道,装一个 App 就够 |
| 🎯 应用专用隧道 | 只允许 DSHgo 使用 VPN,显式下发 MagicDNS,其他应用保持原有网络 |
| 🧭 万能抓取 | 隧道接通后自动识别远程工作台并直连,不挑主机名/端口 |
| 👀 实时监控 | 电脑上正在跑的会话、子智能体、后台任务,手机实时可见可操作 |
| 🎨 DSHgo / ZCode go 双模式 | 顶栏一键切换;切 ZCode 自动关隧道、切回自动开 |
| 🪟 站点小窗 | 悬浮窗查看本地监控页(默认关闭,可选开关);页面里的 127.0.0.1 请求自动穿隧道回电脑 |
| 🎤 语音输入 | 麦克风权限自动申请,开箱即用 |
| 🌗 弱网优化 | 连接状态提示、加载失败退避重试、实时流式转发 |
| 📎 手机上传文件 | 系统选择器、多选、分块进度和网络中断后继续上传;从「+ → 文件」添加 |
| ☰ 手机抽屉导航 | 侧边栏默认收起,顶栏图标展开,选会话/点遮罩/返回键收起 |
| 🐟 可选大肥鱼主题 | 顶部连接徽章、侧栏与输入卡片、连接/错误插画;设置中随时切换,保留当前页面 |
| 🧾 免 root 诊断 | 有界本地状态日志,手动导出 ZIP;支持关闭和清除,不采集聊天或连接地址 |
| 🎞 开机动画 | 右往左拉出;哔哩哔哩与 FA 2517 同组出现,浅色渐变背景 |

V1.2 在 SM-F7310 上验证了约 32 MiB 文件回执和合成 PNG 图片加载;尚不能保证所有图片来源和设备。文件断点恢复需要同时更新电脑插件;App / 桥接进程重启后需重新选择文件。详细测试范围见 验收记录。

安装

PC 端(一次性)
1. 安装 Tailscale 并登录(与手机同账号)
2. 安装 DeepSeek Harness(dsh 桌面版)
3. 进入 pc-plugin/ 双击 install.bat,重启 dsh

手机端
1. 安装 DSHRemote.apk(Releases 下载)
2. 打开 → 登录 Tailscale(仅此一次)→ 允许 VPN / 麦克风授权

更新到 v1.2:手机覆盖安装(保留原签名),电脑端重新运行插件安装脚本并重启 dsh。两端需要同时更新,具体原因与操作见 V1.2 发布说明。

之后每次打开 App 自动:建隧道 → 发现电脑 → 进入工作台。

详细文档见 docs/使用说明.md。

仓库结构

phone-app/ Android 端源码(无 Gradle,build.bat 一键打包) pc-plugin/ PC 端 dsh 插件(install.bat 一键安装,dsh 启动即用) docs/ 使用说明

从源码构建手机端

cd phone-app
copy build-env.example.bat build-env.bat :: 填入本机 JDK / Android SDK / libtailscale.aar 路径
build.bat

- 需要:JDK 17、Android SDK(build-tools 34、platform 34)
- libtailscale.aar:用 tailscale-android 源码经 gomobile bind 产出
- 签名密钥首次构建自动生成(build/dsh.keystore),勿提交到任何仓库

设计说明

- PC 插件零 dsh 内部依赖:只用 apply(ctx, config) 插件形态 + node 内置模块监督外部进程(dsh web 登录签发 + 桥接 + tailscale serve),dsh 版本升级不影响插件
- 桥接自愈:端口被占用自动让位、进程挂掉 30 秒内重启;App 的 web 端口每回启动用 cookie 实测自动挑选(同进程可能托管多个 web 根)
- 本地端口穿透:串流到手机的本地页面里的 127.0.0.1:* 请求自动代理回电脑,任何本地监控面板无需改动即可在手机使用

隐私

- 全程 Tailscale(WireGuard)加密隧道,仅自己设备可达
- 凭据经 Android Keystore 加密存储,不出设备
- App 不收集、不上传任何个人信息

特别鸣谢

特别鸣谢我的朋友 catnaut!

感谢他提供一天“爽吃 Astra”的套餐,帮助我快速完成这个项目。非常感谢!

License

MIT · Made with ❤ by Fa2517
· 有问题视频下方聊,B 站见!

诊断与主题

手机设置 → 故障排查 → 本地诊断日志(默认开启)。在真实 5G 复现后,点击「导出诊断包」,选择保存位置,将 ZIP 与复现时间、操作一起反馈。无须 root、ADB 或 READ_LOGS 权限;不自动发送。日志只含数字状态事件,约 768 KiB 循环保存,不含聊天、文件名、IP、域名、Cookie、Token 或系统日志。可关闭记录、手动清除。

设置 → 显示 → 主题风格 →「大肥鱼 · 海盐蓝」。保留原有五种主题,切换只更新当前界面颜色与装饰,不重建 WebView。仍按手机竖屏触控适配。
代码沿用 MIT 许可;新增大肥鱼插画独立遵循 素材署名与许可,不能将图片视为 MIT 素材。
预览分享卡片长什么样 ↓just-a-FA-for-name/DSHgo
分享 · DeepSeek Harness Hub
just-a-FA-for-name/DSHgo

DSHgo - 把 DeepSeek Harness dsh 工作台装进口袋:手机端 App内置 Tailscale+…

回到顶部