Skip to content
dsh.fish
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),无需打开网页端

[![CI](https://github.com/Qidianyan/dshctl/actions/workflows/ci.yml/badge.svg)](https://github.com/Qidianyan/dshctl/actions/workflows/ci.yml)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](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

Source