Skill
dsh
指挥本机运行的 dsh(DeepSeek Harness,127.0.0.1:3080)——不用打开网页端。用户说"给 dsh 下指令 / 让 dsh 干活 / 跑个任务 / 新建会话 / 切换模式或模型 / 配置大模型 / 看已装插件 / 建工作目录 / 看 dsh 会话"等时使用。通过 dshctl CLI(~/.local/bin/dshctl)驱动:会话管理、发送指令、模型/模式/权限切换、配置 OpenAI 兼容模型与视觉能力、工作区与目录、审批应答、实时事件流。
- Source
- Qidianyan
- License
- MIT
- Updated
- Updated 2 days ago
Readme
# dshctl — 用命令行指挥 DeepSeek Harness(dsh),无需打开网页端
[](https://github.com/Qidianyan/dshctl/actions/workflows/ci.yml)
[](LICENSE)
**dshctl** 是 [DeepSeek Harness(dsh)](https://github.com/deepseek-ai/deepseek-harness)的命令行遥控器:新建会话与工作目录、给 agent 下指令、切换模型与模式(agent preset)、配置 OpenAI 兼容模型与视觉能力、切换权限、查看会话记录、处理审批——**全部在终端完成,不用打开浏览器**。附带一个 Claude Code Skill,让你在 Claude Code 会话里用一句话直接指挥 dsh。
> 社区项目,与 DeepSeek 官方无关联。dsh 是 DeepSeek AI 的开源 agent harness(MIT)。
## 这是什么?具体是怎么工作的?
dsh 的 Web UI(`dsh web` 启动,默认 `http://127.0.0.1:3080`)只是一个浏览器壳:Host 进程本身暴露了完整的 HTTP API,网页端的每个按钮背后都是一次 RPC。dshctl 直接调用这套 API,把网页端的全部能力搬进终端:
```text
┌────────────┐ POST /api/<method> (JSON RPC) ┌──────────────────┐
│ │ ─────────────────────────────────► │ │
│ dshctl │ WebSocket /api/events.mux (下行) │ dsh web Host │ ──► 模型/工具/沙箱
│ (终端/CI) │ ◄───────────────────────────────── │ (127.0.0.1:3080)│
└────────────┘ 实时事件流 + 审批请求 └──────────────────┘
```
- **RPC**:`POST /api/<method>`,请求体 `{"type":"client-request","rpcId","method","payload"}`,响应 `{"result":{"ok":true,"value"|"error"}}`。约 50 个方法覆盖会话、工作区、模型、模式、设置、凭证等(见 dsh 源码 `packages/host/apiproxy/src/api/rpc-map.ts`)。
- **事件流**:`ws://<host>/api/events.mux`(下行专用)推送会话事件、工具调用、待审批请求;审批应答走 `POST /api/respond`。
- **安全模型**:API 默认只监听 loopback,无 token(浏览器同源信任 + content-type 防线);部分敏感方法(凭证、设置)额外只允许 loopback 调用。dshctl 只在本机使用。
组成(全部零第三方依赖):
| 文件 | 说明 |
|---|---|
| `dshctl` | Python 3 单文件 CLI(仅标准库 urllib),~900 行 |
| `watch.mjs` | Node ≥21(全局 WebSocket)实时事件流/待审批探测 |
| `SKILL.md` | Claude Code 用户级 Skill(教 Claude 用 dshctl 指挥 dsh) |
| `install.sh` | 一键安装(拷贝 skill + 建 PATH 链接) |
## 前提要求
- 正在运行的 dsh:`npx @deepseek-ai/dsh web`(或从源码 `pnpm dsh web`),默认地址 `http://127.0.0.1:3080`;自定义地址用环境变量 `DSH_URL` 覆盖
- Python 3.9+(macOS/Linux 自带)
- Node.js 21+(仅 `watch`/`approvals` 需要 WebSocket;其余命令不依赖 Node)
- 模型:用 `dshctl add-model` 写入 OpenAI 兼容路由,或在网页端 **Settings → Models** 配置(密钥进本机凭证库,不进 git)
## 安装
```sh
git clone https://github.com/Qidianyan/dshctl.git
cd dshctl
./install.sh # 安装 skill 到 ~/.claude/skills/dsh/ 并链接 dshctl 到 ~/.local/bin
```
安装后新开终端(或 `hash -r`)即可使用 `dshctl`。不想要 skill 也可以只把 `dshctl`/`watch.mjs` 放进任意同一目录,加执行权限即可(`watch.mjs` 必须与 `dshctl` 同目录)。
## 快速开始
```sh
dshctl status # 先确认 Host 在线
dshctl ask "总结当前目录这个仓库" # 一条龙:新建会话→发送→等待→打印最终回复
dshctl sessions # 看所有会话
dshctl send <sessionId> "继续,把测试也修了" # 往同一会话追加指令
dshctl watch <sessionId> # 实时看它在干什么(Ctrl-C 退出)
```
Claude Code 用户:安装 skill 后,在任何会话里直接说「让 dsh 用极简模式跑个任务」,Claude 会自动使用 dshctl。
## 配置模型
不必打开网页端。`add-model` 经 Host 的 `settings.mutate` 写入 `llm-pi-ai`,密钥经 `credentials.set` 进本机凭证库,**不回显、不进 git**。`--base-url` 是模型接口;`--url` / `DSH_URL` 才是 Host 地址。
```sh
dshctl add-model --id my-gateway --base-url https://api.example.com/v1 --key "$DSH_MODEL_API_KEY" --model my-model --context 1M --vision --set-vision
dshctl models
dshctl vision show
```
`--vision` 把该模型标为收图;`--set-vision` 同时把它设成纯文本对话贴图时的视觉能力(Host 需暴露 `doneos-vision` 设置分节)。`--discover` 只列出接口上的模型,不写入。`--key -` 从 stdin 读密钥。
## 命令参考
```text
dshctl status Host 概览(版本/默认模型/附带会话数)
会话与任务
sessions [-a] 会话列表(-a 含子代理会话)
new [目录] [-p 模式] 新建会话(目录默认 Host 启动目录)
send <sid> <文本> [--steer] 发送/追加指令(--steer 打断当前 turn 转向)
ask [-C 目录] [-p 模式] [-t 秒] "任务" 新建+发送+等待完成+打印回复
watch <sid> [-v] [--since N] [--exit-on-idle] 实时事件流
log <sid> [-n N] [-v] 会话记录(-v 含思考/工具结果/注入上下文)
rename <sid> <标题> 改名
fork <sid> [atSeq] 分叉(需已有完成的 turn)
cancel <sid> 取消当前 turn
search <关键词> 全文搜索(取决于部署是否开启索引)
模型与模式
models [sid] 模型目录([多模态] = 接受图片);带 sid 显示该会话当前模型
use-model <sid> <provider> <model> [effort] 切模型(effort 如 off/high/max)
add-model --id <路由> --base-url <https://…/v1> [--key …] [--model <id>] [--context 1M] [--vision] [--set-vision]
配置 OpenAI 兼容提供方(settings.mutate + credentials.set,不回显密钥)
vision [show|set <provider> <model>|clear] 纯文本对话的可选视觉能力(doneos-vision)
plugins 本机 web profile 已装 / 已禁用插件
providers provider 列表(●=活跃)
modes 模式(agent preset)列表
use-mode <sid> <模式> 切模式(仅空白会话;更稳妥是 new -p)
slash 命令(人类命令通道,不触发模型 turn)
cmd <sid> /permission <read-only|workspace-write|danger-full-access>
cmd <sid> /plan [off|消息] 进入/退出计划模式
cmd <sid> /goal <目标>|clear|pause|resume
cmd <sid> /compact 压缩上下文
目录与工作区
mkdir <父目录> <名> [--ws] 建文件夹(--ws 同时纳为 dsh 工作区)
ws-add <路径> 将已有目录纳为工作区
workspaces 工作区列表
ls [路径] 列本地目录
审批(agent 请求敏感操作时)
approvals <sid> 列出待审批(给出 rpcId + approvalId)
approve|reject <sid> <rpcId> <approvalId> 应答
其他
skills <sid> 该会话可用的 skills
raw <method> '<json>' 原始 RPC 兜底(升级后探测 API 用)
```
## 模式(agent preset)选择指南
模式决定会话挂载哪些工具与系统提示,**只在建会话时选择**(`new -p` / `ask -p`;已开跑的会话锁定,换模式就新开会话)。四个系统模式:
| 模式 | 一句话 | 什么时候选 |
|---|---|---|
| `standard` 标准模式 | 完整编码 agent:bash、文件读写搜索、web 搜索、todo、计划模式、上下文压缩、子代理、workflow | **默认答案**:日常编码、修 bug、跑测试、仓库调研 |
| `code` PTC 模式 | standard 全部能力 + Code Mode SDK:模型写一个 TypeScript 程序把多步工具操作合成一次 `run_code` 执行(5 次往返 → 1 次) | 大批量跨文件修改、系统性迁移、多阶段管道等往返多的任务 |
| `minimal` 极简模式 | 只有持久 bash + str_replace_editor,固定短提示,无压缩/web/子代理 | 小而明确的任务、最省 token、要最可预测的行为;**不适合长对话**(无上下文压缩) |
| `cordis` 创造模式 | standard + 自我修改运行时(`cordis_mount` 挂载/实验插件、preset 创作指导) | 要 dsh 帮你创作/修改 agent preset;⚠️ 会执行模型写的 JS,等同 shell 权限,慎用 |
计划模式(`/plan`)不是第五种模式,而是 standard/code/cordis 会话内的一个状态:先产出方案、经批准后才动手。
## 审批工作流
会话权限默认 `workspace-write`;agent 要做超出策略的操作时会挂起等待审批:
```sh
dshctl watch <sid> # 看到 "⚠️ 待审批: approvalId=… rpcId=… 工具=…"
dshctl approvals <sid> # 随时列出待审批项
dshctl approve <sid> <rpcId> <approvalId>
dshctl reject <sid> <rpcId> <approvalId>
dshctl cmd <sid> /permission danger-full-access # 整体放开(慎用)
```
> 注意:**不要**用 `send` 发送 "/xxx" 文本——dsh 会把它当普通消息交给模型解释执行(浪费 token)。slash 命令一律走 `dshctl cmd`(内部走 `commands/execute`,不触发模型 turn)。
## 兼容性
- 在 dsh **0.1.0-rc.6**(npx 发布版)上全量验证:22/22 命令通过、四种模式建会话核验、端到端模型调用、审批链路。
- 0.1.0-rc.5 及更早版本的事件流是 SSE `GET /api/events.mux` 而非 WebSocket,`watch`/`approvals` 可能不兼容;其余 RPC 命令不受影响。
- dsh 处于 developer preview,wire 协议会变。升级后如遇 `bad-request`,用 `dshctl raw <method> '<json>'` 探测新方法名/参数,或来本仓库提 issue。
## 故障排除
| 症状 | 处理 |
|---|---|
| `无法连接 http://127.0.0.1:3080` | dsh 没在跑:`npx @deepseek-ai/dsh web`;自定义端口设 `DSH_URL` |
| `agent-preset-locked` | 会话已开跑,模式锁定——新开会话时用 `-p` 指定 |
| `fork-unavailable` | 会话还没有完成的 turn,先让它跑完一轮 |
| `model-unavailable` | 该 provider 未配置凭证/模型不可用:`dshctl providers` 查看,或 `dshctl add-model` / 网页端 Settings → Models |
| watch 连不上 | dsh 版本差异(SSE/WS);确认版本 ≥ rc.6 |
## 开发与 CI
GitHub Actions(`.github/workflows/ci.yml`)在每次 push/PR 时运行:
- `python3 -m py_compile` 语法检查 + `--help` 冒烟
- 无服务场景:`DSH_URL` 指向死端口时必须以友好错误退出(非零退出码 + 指引信息)
- `node --check watch.mjs` 语法检查
- `install.sh` 以 `sh -n` 做 shell 语法检查
## License
MIT © 2026 Qidianyan。DeepSeek Harness 及其商标归 DeepSeek AI 所有;本项目是独立的社区配套工具。
Install
# Skills are files: copy them into $DSH_HOME/skills/dsh (defaults to ~/.dsh/skills/dsh)
Profile: web
With the hub plugin installed, ask your agent to install it by name — it resolves the same plan shown here.
dsh plugin --profile web add github:stvlynn/dsh.fish#path:packages/dsh-plugin-hub
install qidianyan-dsh from the hub