Back to home

rekey

dsh-link

DshLink:macOS 桌面客户端,一键连接本地或远程 DeepSeek Harness Web UI(dsh web),远程连接自动建立 SSH 隧道。基于 Tauri v2,仅提供源码,需自行编译。

Stars
0
Language
Rust
Created
Aug 15, 2026
Updated
Aug 15, 2026

Introduction

DshLink

DshLink 是一个 macOS 图形客户端,用于连接和管理 DeepSeek Harness Web UI(dsh web)。

  • 本地 target:直接使用宿主机上的 dsh 启动 dsh web
  • 远程 target:支持任意 user@host:sshPort,通过 SSH 启动或复用远端 dsh web,并建立本地 SSH 隧道访问。
  • 管理界面:target 列表、连接状态、日志、弹窗确认。
  • 内容界面:每个已连接 target 对应一个独立的 DSH 窗口。

平台支持与编译产物

本项目的平台支持状态:

  • 当前实际支持并验证的平台只有 macOS。
  • Tauri v2、Rust core、SSH/隧道等底层技术具备跨平台的可能性,但 Windows / Linux 尚未实现对应适配,也未经测试。
  • 以下实现目前是 macOS 专属或按 macOS 行为验证的:
    • 本地 dsh 发现:/bin/zsh -lc
    • ATS 本地网络例外:Info.plist
    • manager 窗口关闭 / Dock 重开:RunEvent::Reopen
    • WKWebView 行为
  • 因此:跨平台只是技术栈层面的可能性,不是当前产品承诺。

本项目只提供源码,不提供任何编译后产物。

  • 不发布 .app.dmg.exe.msi、AppImage、deb/rpm 等二进制包。
  • 仓库内不包含 CI 发布产物。
  • 想使用需要自行准备工具链并编译。

技术栈

Tauri v2
├── Rust 后端:连接管理、SSH、隧道、进程生命周期
├── SvelteKit + TypeScript 前端:manager 窗口
└── WKWebView:独立 dsh 窗口

功能

  • 本地 dsh 自动发现(从 Finder 启动时也能通过登录 shell 找到 dsh)
  • local / ssh-alias / ssh-manual 三种 target 形态
  • 远端已有健康实例检测并直接复用
  • 远端无实例时自动启动 dsh web,断开后默认保留运行
  • 不健康远端进程弹窗:强制重启 / 取消
  • SSH 隧道只绑定 127.0.0.1
  • macOS ATS 本地网络例外
  • 实时状态事件、内存日志面板
  • 关闭 manager 窗口不退出,Dock 点击可重新打开
  • Cmd+Q 退出时清理本地 dsh 和 SSH 隧道,远端 dsh 保留

环境要求

本机

  • macOS
  • Xcode Command Line Tools
  • Rust / cargo
  • Node.js 22+ / npm
  • 宿主机已安装 dsh 且可从登录 shell 的 PATH 找到

远端

  • 可 SSH 登录的 Linux/macOS 主机
  • 远端已安装 dsh 和 Node.js
  • v1 只支持 SSH key / ssh-agent 认证

开发运行

npm install
npm run tauri dev

自行构建

项目不提供编译产物,按以下步骤在本机构建。

发布构建

npm install
npm run tauri build

调试构建 .app

npx tauri build --debug --bundles app

macOS 产物位于:

src-tauri/target/debug/bundle/macos/DshLink.app

发布构建产物通常位于:

src-tauri/target/release/bundle/macos/

分发给他人时,签名、公证和 Gatekeeper 策略需要自行处理,本项目不提供 Developer ID 配置或签名产物。

核心链路 smoke 测试

core-smoke 是独立于 GUI 的核心链路测试入口:

cargo run --bin core-smoke -- local-start --port 3190 --wait-ms 6000

cargo run --bin core-smoke -- ssh-preflight --target <SSH_TARGET>

cargo run --bin core-smoke -- remote-detect \
  --target <SSH_TARGET> --target-id example-remote --remote-port 3080

cargo run --bin core-smoke -- remote-connect \
  --target <SSH_TARGET> --target-id example-remote \
  --remote-port 3080 --local-port 3080 --wait-ms 6000

cargo run --bin core-smoke -- remote-force-restart \
  --target <SSH_TARGET> --target-id example-remote \
  --remote-port 3199 --local-port 3199 --wait-ms 6000

cargo run --bin core-smoke -- remote-stop \
  --target <SSH_TARGET> --target-id example-remote

自动化验收

scripts/acceptance-core.sh <SSH_TARGET> <EXISTING_REMOTE_PORT>

例如:

scripts/acceptance-core.sh your-ssh-alias 3080

脚本覆盖:

  1. local 启动 / 健康检查 / 停止 / 进程清理
  2. SSH alias 与 user@host:port 解析
  3. SSH preflight
  4. 远端已有健康实例检测
  5. 复用已有实例并建立隧道
  6. 新实例启动、断连保留、显式 stop
  7. unhealthy 检测、确认前不杀、force-restart、stop 清理
  8. 非 dsh PID 停止拒绝

人工 GUI 清单见 docs/manual-qa.md

配置

客户端配置保存在:

~/Library/Application Support/dev.dshlink.client/config.json

字段对齐 docs/v1-spec.md 第 5 节,核心字段如下:

{
  "version": 1,
  "targets": [
    {
      "id": "local",
      "name": "Local",
      "kind": "local",
      "localPort": 3080,
      "dshBin": null,
      "localWorkspace": "~"
    },
    {
      "id": "example-remote",
      "name": "Example Remote",
      "kind": "ssh",
      "sshMode": "alias",
      "sshAlias": "your-ssh-alias",
      "localPort": 3080,
      "remoteHost": "127.0.0.1",
      "remotePort": 3080,
      "remoteWorkspace": "~",
      "remoteDshBin": null
    }
  ]
}

手动 SSH target 也支持:

sshUser
sshHost
sshPort
identityFile

连接语义

场景行为
关闭 DSH 窗口只关窗口,连接保持
点击断开local 杀 dsh;remote 只关隧道,远端 dsh 保留
停止远端只杀受本客户端管理的 dsh web 进程
关闭 manager 窗口隐藏,App 继续运行
Cmd+Q 退出清理 local dsh 和 SSH 隧道,远端 dsh 保留
复用已有实例本地端口必须等于远端实际端口,避免 trusted-host 不匹配

远端状态目录

客户端在远端使用:

~/.dsh-link/
├── lib/
│   ├── detect.sh
│   ├── start.sh
│   ├── stop.sh
│   └── VERSION
└── remote/
    └── <targetId>/
        ├── web.pid
        ├── web.port
        └── web.log

远端 dsh web 由客户端启动时只绑定 127.0.0.1

项目结构

docs/
  v1-spec.md        # 规格与实现进度
  manual-qa.md      # 人工 GUI 验收清单
scripts/
  acceptance-core.sh
src/                 # SvelteKit manager 前端
src-tauri/
  src/core/          # local / remote / ssh / 隧道 / 健康检查
  src/connection.rs  # ConnectionManager、状态事件、日志
  src/lib.rs         # Tauri commands 与生命周期
  src/bin/core-smoke.rs
  scripts/           # 远端 helper
  Info.plist         # ATS 本地网络例外

安全说明

  • 远端 dsh web 只绑定 127.0.0.1,不暴露公网。
  • SSH 隧道只绑定本机 127.0.0.1
  • v1 只使用 SSH key / ssh-agent,不处理密码。
  • 强制重启前验证 PID 命令行,拒绝停止非 dsh 进程。
  • dsh 窗口只允许访问本地 dsh 地址,外链交给系统浏览器。

已知限制

  • v1 当前仅实际支持 macOS;Windows / Linux 未适配、未验证。
  • v1 不支持 SSH 密码认证。
  • v1 不支持远端端口自动协商。
  • 复用远端实例时,本地端口必须与远端实际端口一致。
  • 不提供编译后产物,需要用户自行编译。

文档

  • 完整规格:docs/v1-spec.md
  • 人工验收:docs/manual-qa.md

License

MIT