deepseek-harness
deepseek-ai
DeepSeek Harness: Everything is a Plugin.
PROJECT TOPICS
PROJECT README
一千万以内,最好的遥控器。
来小d给我整个活,哇~哇~哇~哇~哇。
希望你用的开心^_^
Android 手机 (DshRemote App)
│ HTTPS + WebSocket(/api/events.mux)
▼
Caddy 反代 (https://<你的机器>.ts.net:8443 → localhost:3080)
│
▼
DSH 宿主 (dsh web, 127.0.0.1:3080)
│ ┌─ @deepseek-ai/dsh-base
│ ├─ @deepseek-ai/dsh-web-app
│ ├─ @liustack/modlens (图像/OCR 引擎)
│ ├─ dsh-better-sidebar (侧边栏增强)
│ └─ dsh-remote-control (本仓库:给手机提供的 /remote/* 接口)
▼
LLM(DeepSeek 等)
dsh-remote-control 是本仓库自带的服务端插件,负责暴露 /remote/* 路由(列目录、上传下载文件、删除重命名等)给手机 App。/plan 进入计划模式,让模型先出方案、审过再动手。/plan、/goal、/compact、/permission 等命令(走真实宿生命令通道,不是当文字发)。计划审批、工具批准、AI 提问这三类决策,都以卡片形式内联在对话流底部,不会弹窗盖住聊天内容:
确认执行 / 继续规划(带左侧色条 + 图标,长计划可滚动)。允许一次 / 拒绝。三泳道(输入 / 模型 / 工具)时间线,展示每个回合的:轮次、步骤、耗时、工具调用、token 统计(含缓存命中)。
通过 dsh-remote-control 服务端插件,在手机上浏览电脑工作区目录,上传 / 下载 / 删除 / 重命名 / 复制文件。
dsh-remote/
├── DshRemote/ Android 客户端源码(Kotlin + Jetpack Compose)
│ └── app/src/main/java/dev/dsh/remote/
│ ├── data/ 数据模型、DSH API、设置存储
│ ├── net/ RPC 客户端、WebSocket 客户端
│ ├── ui/ 各界面(主页/会话/轨迹/文件/设置…)
│ ├── service/ 前台服务(后台收通知)
│ └── MainActivity.kt
├── remote-control/ dsh-remote-control 服务端插件
│ ├── lib/host.js 注册 HTTP + SSE 路由(/remote/*)
│ ├── cordis.patch.yml 把插件挂进 profile 的 patch
│ └── package.json bundle 声明
├── web-profile/ DSH web profile 部署模板(package.json)
│ (APK 通过 GitHub Releases 分发,不随源码进 git)
├── convert-icons.js SVG → Android VectorDrawable 图标转换
├── render-launcher-whale.js 启动图标渲染脚本
├── launcher-whale-wifi.svg 启动图标素材
├── keystore.properties.example 签名配置模板
└── README.md
电脑端(Windows 示例):
# 1) 装 DSH harness
mkdir dsh-app && cd dsh-app
npm install @deepseek-ai/dsh
# 2) 装插件(进入 web profile)
npx dsh plugin --profile web add dsh-better-sidebar @liustack/modlens
npx dsh plugin --profile web add "file:C:/path/to/dsh-remote/remote-control"
# 3) 启动
npx dsh web
手机端:从 Releases 页面下载最新 DshRemote-1.3.1.apk → 设置里填服务器地址 → 连接。
想要外网访问 + HTTPS,再补 第四步 Tailscale 和 第五步 Caddy。
npm config set registry https://registry.npmmirror.com)DSH 是一个 npm 包,装到本地一个目录里即可:
mkdir -p ~/dsh-app && cd ~/dsh-app
npm init -y
npm install @deepseek-ai/dsh
装完后,dsh 命令在 node_modules/.bin/ 下:
# 直接用 npx 调用(推荐,不用配 PATH)
npx dsh --version
# 输出:0.1.0-rc.6
也可以
npm install -g @deepseek-ai/dsh全局安装,然后直接dsh --version。
DSH 的数据(会话、设置、profile)默认放在 ~/.dsh(Windows 是 C:\Users\<你>\.dsh)。
DSH 的 profile 是一个「插件 bundle 栈」。本项目的 web profile 由下面 5 个 bundle 组成:
| bundle | 作用 |
|---|---|
@deepseek-ai/dsh-base |
DSH 核心 |
@deepseek-ai/dsh-web-app |
网页 UI(也承载 /api RPC 与 WebSocket) |
@liustack/modlens |
图像识别/OCR(手机端看图要用) |
dsh-better-sidebar |
侧边栏增强 |
dsh-remote-control |
本仓库的插件:给手机提供 /remote/* 文件接口 |
npx dsh plugin --profile web add dsh-better-sidebar @liustack/modlens
# 本仓库的 remote-control 用本地路径(把路径换成你 clone 下来的位置)
npx dsh plugin --profile web add "file:C:/path/to/dsh-remote/remote-control"
dsh plugin 会把剩余参数转发给 profile 目录里的 pnpm,等价于在该目录执行 pnpm add。
把本仓库 web-profile/package.json 复制到 ~/.dsh/profiles/web/,把 dsh-remote-control 的 file: 路径改成你本机的绝对路径,然后:
cd ~/.dsh/profiles/web
npm install
装完可以用 npx dsh --dump-config 检查 bundle 栈是否正确。
cd ~/dsh-app
npx dsh web
默认监听 127.0.0.1:3080。浏览器打开 http://127.0.0.1:3080 应该能看到 DSH 的网页界面。
常用参数:
# 换端口
npx dsh web --port 8080
# 允许外部(Tailscale)域名通过浏览器信任墙
npx dsh web --trusted-host "desktop-xxxx.tailxxxx.ts.net:8443"
手机 App 是通过 HTTPS + WebSocket 连接的,所以还需要下面两步把 3080 暴露出去。
Tailscale 让你电脑和手机进同一个私有网络,不需要公网 IP、不用在路由器开端口。
desktop-xxxx.tailxxxx.ts.netTailscale 的安装和登录步骤官方文档已经写得很清楚,这里只引用,不重复展开。只要电脑和手机能互相 ping 通就算组网成功。
App 用 HTTPS 连你的 DSH,需要一个 HTTPS 端点。最简单的是用 Caddy 做反代 + 自签证书(App 端已做 TrustAll,接受自签证书)。
Caddyfile:{
servers {
protocols h1 h2
}
}
https://desktop-xxxx.tailxxxx.ts.net:8443 {
tls internal
reverse_proxy localhost:3080
}
把 desktop-xxxx.tailxxxx.ts.net 换成你电脑的 Tailscale 名字。
caddy run --config Caddyfile
https://desktop-xxxx.tailxxxx.ts.net:8443,能打开 DSH 网页即成功。注意:
dsh web启动时要带--trusted-host "desktop-xxxx.tailxxxx.ts.net:8443",否则浏览器的信任墙会拦掉非本机的 Host 头。
DshRemote-*.apk(Android 8.0+),或按 如何自己构建 App 自己打包。https://desktop-xxxx.tailxxxx.ts.net:8443
如果你要改代码自己打 APK:
| 依赖 | 版本 |
|---|---|
| JDK | 21 |
| Gradle | 8.11.1 |
| Android SDK | compileSdk 35 |
用 Android Studio 打开 DshRemote/ 即可(会提示装 SDK)。命令行构建:
cd DshRemote
# 生成签名密钥(只需一次)
keytool -genkey -v -keystore keystore/my-release.keystore \
-alias myalias -keyalg RSA -keysize 2048 -validity 10000
# 配置签名
cp keystore.properties.example keystore.properties
# 编辑 keystore.properties,填上你的 keystore 路径/别名/密码
# 构建
gradle assembleRelease
产物在 DshRemote/app/build/outputs/apk/release/。
说明:
keystore.properties已被.gitignore忽略,签名的私钥和密码不会进仓库。示例里只是占位符。
POST /api/<method>,信封 {"type":"client-request","rpcId":"<uuid>","method":"...","payload":{...}},响应 {"type":"server-response","rpcId":...,"result":{"ok":true,"value":...}}。/api/events.mux,帧类型包括 session/event(会话事件流)、session/queue、session/jobs、session/projection、question/requested(AI 提问/计划审批)、approval/requested(工具批准)等。POST /api/commands/execute,payload {"args":{"agentId":"<sessionId>","line":"/plan"}},用于执行 /plan、/goal、/compact、/permission 等宿生命令(不是当普通消息发)。| 模块 | 职责 |
|---|---|
net/RpcClient.kt |
HTTP RPC 信封编解码 |
net/WsClient.kt |
WebSocket mux 事件流 |
data/DshApi.kt |
封装所有 DSH 方法(session/workspace/agentPreset/goal/commands…) |
data/Models.kt |
数据模型 + foldChat(把事件流折叠成聊天项) |
ui/AppViewModel.kt |
连接、会话切换、事件处理、决策应答 |
ui/MainScreen.kt |
主界面/首页/会话视图 |
ui/ChatScreen.kt |
聊天流 + 输入区 + 内联决策卡 |
ui/TrajectoryScreen.kt |
三泳道轨迹面板 |
ui/Markdown.kt |
Markdown 渲染 |
ui/theme/ |
深浅色主题(跟随系统) |
service/DshForegroundService.kt |
前台服务,后台收通知 |
lib/host.js 在 web profile 的 webServer 上注册路由:
GET /remote/list — 列目录GET /remote/file — 下载文件POST /remote/upload — 上传文件(base64)POST /remote/delete / POST /remote/rename / POST /remote/copy — 文件操作Q:连不上 / 转圈?
先确认:① dsh web 在跑;② 手机和电脑 Tailscale 能互通;③ Caddy 在跑;④ 地址填的是 https://...:8443(带 https)。
Q:计划模式 /plan 不生效?
/plan 是宿生命令,必须走命令通道(App 的「命令」按钮、或输入框里以 / 开头发送),不能当普通文字消息发。详见 App 内「命令」菜单。
Q:能看到图片 / OCR 吗?
需要 @liustack/modlens 插件已装,App 端会自动走它。
Q:能改服务器地址吗? 能,设置页里随时改,改完自动重连。
https://<你的机器>.ts.net:8443,自签证书所以会提示「证书不受信任」,这也在预期内。keystore.properties、*.keystore、*.jks(签名私钥)。~/.dsh 下的 .credentials.yaml、remote-control.token、settings.yaml、sessions/(含你的密钥和会话)。本项目采用 GNU General Public License v3.0 (GPL-3.0)(全文见 LICENSE)。
要点:
CLASSIFICATION EVIDENCE
系统优先读取 GitHub Topics,再与站内分类词典和词根规则比对。当前命中: 无有效分类标签。