DeepSeek Harness plugin

dsh-cli

Interactive terminal (REPL) profile bundle for DeepSeek Harness — a Claude Code-style CLI surface over dsh-base

Jump to install

Source facts

Repository
studyinglx/dsh-cli
Latest update
Aug 17, 2026
Category
Tools & Capabilities
GitHub stars
1
Format
plugin
Catalog evidence
Upstream dsh.bundle evidence
Evidence path
package.json#dsh.bundle
Checked against
0.1.0-rc.8
Upstream check date
2026-08-20

This evidence comes from the upstream catalog. This site has not installed, run, or security-reviewed the plugin.

Install

Start with a prompt that asks an agent to review the GitHub repository and source. Switch to the command if you want to install it yourself.

Copy this prompt into DSH, Codex, or another agent and ask it to review the GitHub repository and source first.

Do not install or run any commands yet. Read this plugin's GitHub repository, README, and relevant source code. Then answer the questions below clearly and directly so I can decide whether it fits my needs:

1. What is this plugin, and what problem does it solve?
2. Who is it for, and what are its typical use cases?
3. How is it used after installation? Include one minimal example.
4. What known limitations or privacy, security, compatibility, or maintenance risks does it have?
5. Give a clear recommendation: recommend, conditionally recommend, or do not recommend, with reasons.

Distinguish statements documented by the repository, inferences from source code, and unknowns. If evidence is insufficient, say so explicitly. Do not guess or simply repeat the README.

GitHub: https://github.com/studyinglx/dsh-cli
Plugin: dsh-cli
Author: studyinglx

Check the source files

Read the README and other files from this plugin directory before installing.

File explorer3 files
README.mdSource · read only

dsh-cli-interactive

在无头服务器上把 DeepSeek Harness 变成 Claude Code 风格的交互式终端 CLI

这是一个 out-of-tree 的 dsh profile bundle:叠加在官方 dsh-base 之上, 复用 dsh 的全部核心能力(agent 循环、会话持久化、工具、凭据、settings、沙箱审批), 只把官方 dsh-headless 的"提交一次任务就退出"换成持久 REPL 循环—— 同一个 agent 反复对话、回复流式输出、审批在终端应答、每轮结束后会话落盘、 随时 --resume 找回旧会话。不挂载任何 Host / HTTP / 浏览器插件。

特性

  • 交互式 REPL:输入即消息,agent 回复流式打印(增量轮询 session 事件日志)
  • 会话持久化:每轮结束后 flush 到 $DSH_HOME/sessions/*.jsonl(默认 ~/.dsh/sessions
  • --resume <sessionId>:恢复旧会话继续聊(复用官方 agents.resume()
  • 审批应答:默认 workspace-write + ask 策略下的权限询问直接在终端 y/n 应答
  • slash 命令:/help /sessions /model /permission /cancel /session /workspace /exit
  • 忙时输入不丢:agent 执行期间键入的内容排队,下一轮自动发出
  • Ctrl-C 中断当前轮(agent.cancel({kind:'user'})),再按一次退出
  • 启动参数:--model --provider --preset --once,任务位置参数可选(先跑一轮再进 REPL)
  • 输入历史持久化:$DSH_HOME/cli.history,上下键翻查,重进保留
  • Tab 补全:/he+Tab → /help/model dee+Tab → 模型名
  • --once:跑完任务(或一轮)即退出,脚本友好(dsh --profile cli --once "task"

界面

  • 紧凑 banner 盒:session id / 会话标题 / workspace·模型(provider)·策略 / 快捷提示(长路径自动掐头去尾)
  • 会话标题:首轮 prompt 截断生成(--task 或 resume 旧会话自动恢复),横幅 + 状态行显示
  • 每轮状态行:dsh-cli · session-… · "标题" · 模型 · 策略 · cwd
  • 提示符带模型名:you (deepseek-v4-flash)> /model 切换后立即反映
  • 流式输出:assistant [step N]>,step 推进处插入 [step N] 分隔(仅行首,不切断单词)
  • 内联工具行:工具调用在文本流中安全插入 ⚙ bash … 行(仅行边界,绝不切断单词;行中则走活动行)
  • 工具活动:⚙ step N · bash …(内容变化时才原位重绘:新 step / 工具开始 / 工具完成,绝不逐帧刷屏),完成 ;轮末摘要 ⚙ N tool call · S steps · ↑in ↓out tok
  • 错误轮次提示:turn 出错后提示重试 / 退出,不静默继续
  • /help 分组排版:session / info / control 三组
  • 审批提示友好化:⚠ approval required 框内分层显示工具名(亮黄粗体)/模式/原因
  • 自适应终端:TTY 下彩色 + Unicode 圆角框;管道/NO_COLOR 下自动降级纯文本(FORCE_COLOR=1 可强制着色)

目录结构

dsh-cli-interactive/
├── package.json          # 声明 dsh.bundle.patch → 安装时自动加入 profile 层栈
├── cordis.patch.yml      # 组合层(不要动插件行,只可改 persona 等配置值)
├── lib/
│   ├── ui.js             # ANSI 样式/布局助手(零依赖):色板、可见宽度、box、表格、spinner、工具摘要
│   ├── startup.js        # 命令行参数(--resume/--model/--provider/--preset/[task]/--once)
│   └── runner.js         # REPL 主循环——banner、you> 提示符、流式输出、slash 命令、审批提示、会话横幅
├── bin/dsh-cli.js        # 便捷入口:dsh-cli ≡ dsh --profile cli
├── scripts/build.mjs     # 构建脚本(node --check 语法校验 + 组装 dist/,零依赖)
├── tests/unit.mjs        # 单元冒烟测试(node tests/unit.mjs)
└── README.md

构建

零工具链、零网络依赖(Node ≥ 22 自带):

node scripts/build.mjs          # 语法校验 + 生成 dist/
npm run check                   # 只做语法校验

产物在 dist/lib/ + bin/ + cordis.patch.yml + package.json + README + LICENSE

安装到 dsh(服务器 / 本机)

前置:Node 22 + 全局 @deepseek-ai/dshnpm i -g @deepseek-ai/dsh)+ pnpm(npm i -g pnpmdsh plugin 转发给 pnpm), 密钥放 ~/.dsh/.envDEEPSEEK_API_KEY=sk-...)。

dsh plugin 首次使用会初始化 profile(bundles 起始为 [dsh-base]), 然后转发 pnpm 安装你的包;因为包声明了 dsh.bundle会自动加入 dsh.profile.bundles 层栈(无需手改 manifest)。

方案 A:从 GitHub 拉取(通用)

任意一台装有 dsh 的机器(服务器 / 本机),clone 本仓库后构建出 dist/ 再安装:

# 1. 拉取源码
git clone https://github.com/studyinglx/dsh-cli.git
cd dsh-cli

# 2. 构建出 dist/(零工具链,Node ≥ 22 自带即可)
node scripts/build.mjs

# 3. 安装到 dsh profile(本地路径指向 dist/)
dsh plugin --profile cli add file:$PWD/dist

# 4. 验证组合层(不启动)
dsh --profile cli --dump-config

# 5. 使用
dsh --profile cli                                    # 进入 REPL
dsh --profile cli "先 review 一下代码库"              # 先跑一轮,然后进入 REPL

> - dsh plugin 首次运行会自动初始化 cli profile(bundles 起始为 [dsh-base])。 > - 已安装过旧版本时,先 dsh plugin --profile cli remove dsh-cli-interactive 再 add, > 或重新 add 覆盖(pnpm 会按路径重装)。 > - 拉取到的源码可直接改(lib/、cordis.patch.yml),改完 node scripts/build.mjs > 重建再 add 即生效。

方案 B:本地路径 / 发布到 npm

# 从 dist 目录安装(本地路径)
dsh plugin --profile cli add file:/path/to/dsh-cli-interactive/dist

# 或发布到 npm 后按包名安装
npm publish
dsh plugin --profile cli add dsh-cli-interactive

# 验证组合层(不启动)
dsh --profile cli --dump-config

使用

cd /srv/workspace            # 启动目录 = workspace 根

dsh --profile cli                                    # 进入 REPL
dsh --profile cli "先 review 一下代码库"              # 先跑一轮,然后进入 REPL
dsh --profile cli --once "先 review 一下代码库"        # 跑一轮即退出(脚本友好)
dsh --profile cli --resume session-xxxx              # 恢复旧会话
dsh --profile cli --model deepseek-v4-pro            # 指定模型
dsh-cli --resume session-xxxx                        # 或用包装命令

slash 命令

| 命令 | 作用 | |---|---| | /help | 命令列表(分组排版) | | /sessions | 列出 $DSH_HOME/sessions 下最近的 20 个会话(递归嵌套布局,id/大小/时间) | | /session | 显示当前会话 id | | /workspace | 显示 workspace 根目录 | | /model [id] | 查看 / 切换模型(下一轮生效;如 deepseek-v4-flashdeepseek-v4-pro) | | /permission [ask\|never] | 查看 / 切换审批策略(写会话日志,模型会看到通知) | | /cancel | 取消正在运行的轮次 | | /exit /quit | 退出(会话已持久化) |

长任务 / 值守

agent 一轮内部会自主多轮调用工具直到停稳(whenIdle()),所以单条消息可以持续 几分钟到几小时;进程被杀则中断(会话日志保留,--resume 可续)。用 tmux 保活:

tmux new -s dsh 'cd /srv/workspace && dsh --profile cli'
# Ctrl-b d 分离,随时 tmux attach -t dsh 回来

> 管道模式(脚本友好)echo "任务" | dsh --profile cli --once 也可以正常

> 工作——readline 监听器在任何异步初始化之前注册,管道数据/EOF 不会丢失。 > 空输入(立即 EOF)同样干净退出。

架构说明(改动点对照)

官方 dsh-headless本包
headless-startup 只解析任务位置参数cli-startup 增加 --resume/--model/--provider/--preset/--once
headless-runner:提交 1 次 → 打印 → 退出cli-runner:REPL 循环 + 流式 + 审批应答 + slash 命令
无审批应答(无人应答 → unavailable → 拒绝)setup 中注册 approval/request waterfall 监听器,终端 y/n 应答
agents.create() 一次agents.create() / agents.resume()resumeSessionId 字段)
退出码 = 本轮结果交互退出码 0;轮次 error 提示但不退出

硬性约束

1. apply(ctx, config) 同步契约:apply 内绝不能 await loader(会死锁导致启动无输出); ctx.config 在 apply 返回后不可读,config 必须从 apply 第二参数取。 2. 改完必须运行 node scripts/build.mjs 做语法校验(npm run check 只校验不打包)。 3. 不要改 cordis.patch.yml 中的插件 id/name/inject 结构,只可改 persona 等配置值。 4. 不挂载 Host / HTTP / 浏览器插件,保持 headless 终端形态。 5. 零工具链、零网络依赖构建(Node ≥ 22)。 6. 会话落盘到 $DSH_HOME/sessions/<project>/<id>/session.jsonl[.zstd](嵌套布局, /sessions 按此递归遍历)。 7. 非 TTY / 管道下输出必须可 grep、无转义垃圾(颜色/spinner/Unicode 框全部按 TTY 判定降级)。

已知限制

  • 单 agent 单进程:一个 CLI 进程一个会话;多会话 = 多开 tmux/systemd 实例。
  • 进程内会话:会话仅存在于运行中的进程(与 web/headless 一致),重启后靠

$DSH_HOME/sessions/*.jsonl + --resume 恢复。

  • 无 web 功能:没有浏览器 UI、/api、多客户端并发。
  • 审批在终端:无人值守(如 cron 里跑)时审批请求会卡住等待输入——

请用 /permission neverDSH_PERMISSION_MODE=danger-full-access 预置策略。

  • 非 TTY(管道)模式下不绘制 spinner/活动行,仅输出文本与轮末摘要。
  • 默认模型/凭据解析与官方一致(~/.dsh/settings.yamlllm-deepseek 段热加载;

DEEPSEEK_API_KEY 环境层优先)。

开发提示

  • 依赖解析:bundle 的插件名 = 包名(dsh-cli-interactive)+ /startup 子路径,

与官方 @deepseek-ai/dsh-headless/startup 同款约定。

  • apply 必须同步(官方 headless 契约):runner 的 apply(ctx, config) 只做

run(ctx, config).catch(...) 就返回,run 内部才 await loader。 async apply 会与 loader settle 互相等待而死锁(启动无任何输出); ctx.config 在 apply 返回后不可读,config 必须从 apply 第二参数取。

  • 想加工具/技能:直接改 cordis.patch.yml 插入行,或在 profile 的

cordis.patch.yml$DSH_HOME/profiles/cli/cordis.patch.yml)覆盖。

  • 类型检查(可选):npm i -D typescript @types/nodenpx tsc -p tsconfig.json