kit-zeason
dsh-simple-CLI
Minimal DeepSeek Harness extension tailored for contemporary CLI mobilization.
- Stars
- 1
- Language
- JavaScript
- Created
- Aug 13, 2026
- Updated
- Aug 15, 2026
Introduction
dsh-simple-cli — Interactive Terminal Profile for DeepSeek Harness
dsh-simple-cli turns DeepSeek Harness (dsh) into an interactive terminal chat, like Claude Code: type a message, watch the answer stream in, keep the conversation going. It is launched as the dsh-cli command (equivalent to dsh --profile cli).
English · 中文
What it is
dsh ships with web / headless profiles. This repo adds a cli profile that runs entirely in the terminal, Claude-Code style:
- Streaming output with reasoning & tool calls — assistant text, model reasoning (
▸ 推理, dim gray) and tool invocations (⛭ name: args+✓/✗result) stream in live, matching the TUI experience. Reasoning is collapsed to its latest line while thinking (web-style) and renders are coalesced to ~30fps, so fast thinking does not flicker the terminal @file picker — type@in the input to browse the working directory (type to filter, ↑/↓ navigate, Enter enters a folder or picks a file, Esc closes); picking inserts@relative/path, and on submit each referenced text file is attached to the message (up to 64 KB each, truncated with a note; binary files stay as a path mention)──input area — a separator line frames the input box; Enter submits, Shift+Enter / Ctrl+Enter insert a newline (multi-line messages; requires the kitty keyboard protocol — Windows Terminal 1.19+, kitty, WezTerm, iTerm2, Konsole, foot — otherwise Ctrl+J or Alt+Enter work as a fallback), ↑/↓ navigate history or logical lines- Status bar — under the input: current model & permission, with the switching commands always in view
- Continuous conversation — multi-turn context on a single Agent session
- Tool-call approvals — inline
y/n/ Enter on the same input area under the "ask" policy - Commands —
/newfresh session ·/model [provider/]<model>switch model (bare/modelopens a filterable picker) ·/preset [id]switch agent preset (bare/presetopens a filterable picker) ·/permission ask|neverswitch approval policy ·/clear·/exit; an optional first message can be passed as an argument - Default color scheme — every role has its own color (user green, reasoning gray, tools yellow/cyan…); override via the
DSH_CLI_THEMEenv var (see below)
Requirements
- Node.js ≥ 22 (tested on 24)
dsh≥ 0.1.0-rc.6 on PATH:npm i -g @deepseek-ai/dsh- PowerShell 5.1+ / pwsh for
install.ps1(Windows & Unix)
Install
One-click (Windows & Unix, PowerShell)
git clone https://github.com/kit-zeason/dsh-simple-CLI.git
cd dsh-simple-CLI
.\install.ps1 # install into $DSH_HOME/profiles/cli, shim onto PATH, verify
.\install.ps1 -Force # re-install / overwrite existing profile files
The installer:
- creates
$DSH_HOME/profiles/cli(default~/.dsh/profiles/cli) - copies the
dsh-simple-clibundle into the profile'snode_modules - writes the profile manifest (
package.json,cordis.patch.yml,pnpm-workspace.yaml) - installs the global
dsh-clicommand shim - verifies
dsh --profile cli --help
No git clone needed — install a specific published release directly:
Invoke-WebRequest -Uri https://raw.githubusercontent.com/kit-zeason/dsh-simple-CLI/main/install.ps1 -OutFile install.ps1
.\install.ps1 -Version 0.1.0 # download release v0.1.0 and install it
.\install.ps1 -Version 0.1.0 -Force # re-install, overwriting existing profile files
-Version accepts 0.1.0 or v0.1.0; without it, the script installs the
checkout it is part of (e.g. your clone of main).
Manual (any OS)
$profiles = Join-Path $env:USERPROFILE '.dsh\profiles'
New-Item -ItemType Directory -Force -Path "$profiles\cli\node_modules\dsh-simple-cli\lib"
Copy-Item package.json, cordis.patch.yml "$profiles\cli\node_modules\dsh-simple-cli\"
Copy-Item lib\index.js, lib\startup.js "$profiles\cli\node_modules\dsh-simple-cli\lib\"
Copy-Item profile\package.json, profile\cordis.patch.yml, profile\pnpm-workspace.yaml "$profiles\cli\"
# optional: put bin\dsh-cli(.cmd/.ps1) somewhere on PATH
Usage
dsh-cli # start interactive chat
dsh --profile cli # same
dsh-cli "run the tests" # send a first task, then keep chatting
┌───────────────────────────────────────────────┐
│ dsh-cli: DeepSeek Harness 交互模式(/help …) │
│ ▸ 推理 let me check the repo layout… │ ← dim gray, streaming
│ ⛭ pwsh: Get-ChildItem -Recurse . │ ← yellow
│ ✓ Directory: … │ ← cyan
│ 这里是最新的文件清单:… │ ← streaming reply
│───────────────────────────────────────────────│
│ > 输入你的消息… (Shift+Enter 换行, Enter 发送) │ ← input area
│ 模型: deepseek/deepseek-v4-flash · 权限: ask … │ ← status bar
└───────────────────────────────────────────────┘
Commands (type them in the input area):
| Command | Effect |
|---|---|
/model | open the model picker (browse or keyword-search, then pick) |
/model <name> | switch model (same provider), e.g. /model deepseek-v4-flash |
/model <provider>/<name> | switch provider + model |
/preset | open the preset picker (标准 / PTC / 极简 / 创造 + your own) |
/preset <id> | switch preset (live on a blank session, else applies on /new) |
/permission ask / never | switch the approval policy (aliases: /perm) |
/new | start a fresh session |
/clear | clear the scrollback |
/help, /exit | help / quit (Ctrl+C also quits) |
Presets: each session is composed from one DSH agent preset (the same mechanism as the web app — 标准/standard, PTC/code, 极简/minimal, 创造/cordis). The default is standard; set a persistent default in $DSH_HOME/settings.yaml under agent-presets.default, and author your own presets in $DSH_HOME/.agent-presets/ (a directory with agent.cordis.yml + optional preset.yml).
Tool approval prompt (inline on the same input area):
? [授权] pwsh: … — y 允许一次 / n 拒绝 / 回车 允许
Color scheme (override via env DSH_CLI_THEME=<path-to-json>; each value is an SGR parameter string):
{ "user": "1;92", "reasoning": "2;90", "toolCall": "33",
"toolResult": "36", "toolError": "1;31", "system": "35", "status": "36" }
How it works
Three layers, all plain files:
| Layer | Where | What |
|---|---|---|
| bundle | repo root (npm package dsh-simple-cli) | cordis.patch.yml + lib/ — the runner plugin |
| profile | $DSH_HOME/profiles/cli | manifest listing bundles @deepseek-ai/dsh-base + dsh-simple-cli |
| shim | npm global bin dir | dsh-cli → dsh --profile cli |
- Bundle resolution (
resolveBundleDir) checks the dsh install directory first, then the profile's ownnode_modules— so dropping the bundle atprofiles/cli/node_modules/dsh-simple-cliis enough. - Dependencies — every runtime import (
@deepseek-ai/dsh-agent,dsh-llm,dsh-session,schemastery,commander, …) resolves up the directory tree into the sharedprofiles/node_modulesthat ships with dsh. Nopnpm installneeded. - Runner —
lib/index.jscreates one Agent through the core registry, then renders thesession/eventfirehose live:assistant/chunkdeltas stream reasoning / text / tool-call arguments,tool/call+tool/resultdraw the tool lines, andapproval/requestis answered inline on the same input area. Non-TTY stdin (pipes / CI) falls back to a plain readline loop. - UI —
lib/ui.jsis a dependency-free raw-mode mini-TUI (ANSI only): scrollback +──separator + multi-line editor + status bar;lib/theme.jsholds the palette. - Note —
dshrewrites the profile'scordis.ymlto[]on every launch; keep your changes incordis.patch.yml.
Repository layout
dsh-simple-cli/
├── README.md # this file
├── LICENSE # MIT
├── package.json # the dsh-simple-cli bundle package
├── cordis.patch.yml # bundle patch (loader patch list)
├── lib/
│ ├── index.js # cli-runner plugin: agent loop, event renderer, /model /permission
│ ├── startup.js # cli-startup plugin: command-line parsing
│ ├── ui.js # raw-mode mini-TUI: input area, streaming view, status bar
│ ├── theme.js # color palette + DSH_CLI_THEME override
│ └── refs.js # @file references: find + attach referenced file contents
├── test/
│ ├── ui.test.mjs # Tui unit tests (node test/ui.test.mjs)
│ └── refs.test.mjs # @file reference unit tests (node test/refs.test.mjs)
├── profile/ # cli profile template
│ ├── package.json
│ ├── cordis.patch.yml
│ └── pnpm-workspace.yaml
├── bin/ # dsh-cli command shims
│ ├── dsh-cli.cmd # Windows cmd
│ ├── dsh-cli.ps1 # PowerShell
│ └── dsh-cli # POSIX sh
└── install.ps1 # one-click installer
Development
Edit the bundle sources in this repo, then sync the running copy:
Copy-Item -Recurse -Force .\lib, .\package.json, .\cordis.patch.yml "$HOME\.dsh\profiles\cli\node_modules\dsh-simple-cli\"
Troubleshooting
dsh --profile clisays the profile does not exist — the profile directory needspackage.json; run.\install.ps1.cordis.ymlkeeps coming back as[]— expected;dshregenerates it. Editcordis.patch.ymlinstead.- Renamed the bundle — keep
nameinpackage.json, the plugin names incordis.patch.yml, and the profile bundle list in sync.
Roadmap
- Cross-session ↑/↓ history persistence under
$DSH_HOME /sessionssession list- Publish to npm (
dsh-simple-cli) so others candsh plugin --profile cli add dsh-simple-cli
License
MIT © godzeason
中文
这是什么
dsh-simple-cli 给 DeepSeek Harness(dsh)加了一个纯终端交互式 profile(启动命令为 dsh-cli):像 Claude Code 一样在终端里持续对话,流式输出、↑/↓ 历史、工具调用授权提示。
特性
- 流式输出(含推理与工具调用):正文、模型推理(
▸ 推理,暗灰)与工具调用(⛭ 名称: 参数+✓/✗结果)实时流入,与 TUI 体验一致。思考时推理折叠为单行、实时显示最新一行(网页端风格),渲染合并到约 30fps,快速思考不会导致终端闪屏 @文件选择器:输入@即可浏览工作目录(继续输入过滤、↑/↓ 选择、Enter 进入目录或选中文件、Esc 关闭);选中后插入@相对路径,提交时每个被引用的文本文件会作为附件注入消息(单个上限 64KB,超出截断并注明;二进制文件只保留路径引用)──输入区:分隔线框住输入框;Enter 发送,Shift+Enter / Ctrl+Enter 换行(支持多行消息;需要终端支持 kitty 键盘协议——Windows Terminal 1.19+、kitty、WezTerm、iTerm2、Konsole、foot 等——否则可用 Ctrl+J 或 Alt+Enter 兜底换行),↑/↓ 翻历史或跨行移动- 状态栏:输入区下方实时显示当前模型与权限,并常驻切换命令提示
- 多轮持续对话:同一 Agent 会话保持上下文连续
- 工具授权:agent 请求调用工具时("ask" 策略)在同一输入区内联应答
y/n/回车 - 命令:
/new新会话 ·/model [provider/]<model>切换模型(裸/model弹出可过滤的模型选择框) ·/preset [id]切换预设(裸/preset弹出可过滤的预设选择框) ·/permission ask|never切换权限 ·/clear·/exit;支持可选首条消息参数 - 默认配色:各角色分色(用户绿、推理灰、工具黄/青…);可用
DSH_CLI_THEME环境变量覆盖
安装
一键安装(Windows / Unix,PowerShell)
git clone https://github.com/kit-zeason/dsh-simple-CLI.git
cd dsh-simple-CLI
.\install.ps1 # 安装到 $DSH_HOME/profiles/cli,注册 dsh-cli 命令并自检
.\install.ps1 -Force # 覆盖已有 profile 配置文件
脚本会:创建 profile 目录 → 复制 bundle → 写 profile 清单 → 安装全局 dsh-cli shim → 验证 dsh --profile cli --help。
不想 clone?可直接下载安装脚本并指定版本安装:
Invoke-WebRequest -Uri https://raw.githubusercontent.com/kit-zeason/dsh-simple-CLI/main/install.ps1 -OutFile install.ps1
.\install.ps1 -Version 0.1.0 # 下载 release v0.1.0 并安装
.\install.ps1 -Version 0.1.0 -Force # 重新安装,覆盖已有 profile 配置
-Version 接受 0.1.0 或 v0.1.0;不带该参数时安装脚本所在目录的代码(如 clone 的 main)。
手动安装(任意平台)
$profiles = Join-Path $env:USERPROFILE '.dsh\profiles'
New-Item -ItemType Directory -Force -Path "$profiles\cli\node_modules\dsh-simple-cli\lib"
Copy-Item package.json, cordis.patch.yml "$profiles\cli\node_modules\dsh-simple-cli\"
Copy-Item lib\index.js, lib\startup.js "$profiles\cli\node_modules\dsh-simple-cli\lib\"
Copy-Item profile\package.json, profile\cordis.patch.yml, profile\pnpm-workspace.yaml "$profiles\cli\"
使用
dsh-cli # 开始交互对话
dsh --profile cli # 等价
dsh-cli "run the tests" # 先发一条任务,之后继续对话
界面示意:
┌──────────────────────────────────────────────┐
│ dsh-cli: DeepSeek Harness 交互模式(/help …) │
│ ▸ 推理 let me check the repo layout… │ ← 暗灰,流式
│ ⛭ pwsh: Get-ChildItem -Recurse . │ ← 黄色
│ ✓ Directory: … │ ← 青色
│ 这里是最新的文件清单:… │ ← 流式正文
│──────────────────────────────────────────────│
│ > 输入你的消息… (Shift+Enter 换行, Enter 发送) │ ← 输入区
│ 模型: deepseek/deepseek-v4-flash · 权限: ask … │ ← 状态栏
└──────────────────────────────────────────────┘
命令一览:
| 命令 | 作用 |
|---|---|
/model | 弹出模型选择框(浏览或输入关键字过滤后选中) |
/model <name> | 切换模型(保持 provider),如 /model deepseek-v4-flash |
/model <provider>/<name> | 同时切换 provider 与模型 |
/preset | 弹出预设选择框(标准 / PTC / 极简 / 创造 + 自定义) |
/preset <id> | 切换预设(空白会话立即生效,否则 /new 后生效) |
/permission ask / never | 切换权限策略(别名 /perm) |
/new | 开启新会话 |
/clear | 清空回滚区 |
/help、/exit | 帮助 / 退出(Ctrl+C 也可退出) |
预设:每个会话由一个 DSH agent preset(与网页端同一套机制——标准/standard、PTC/code、极简/minimal、创造/cordis)组装而成。默认是 standard;可在 $DSH_HOME/settings.yaml 的 agent-presets.default 设置持久默认值,自定义 preset 放在 $DSH_HOME/.agent-presets/(一个含 agent.cordis.yml 与可选 preset.yml 的目录)。
工具授权提示(同一输入区内联):
? [授权] pwsh: … — y 允许一次 / n 拒绝 / 回车 允许
配色覆盖(DSH_CLI_THEME=<json文件路径>,值为 SGR 参数串):
{ "user": "1;92", "reasoning": "2;90", "toolCall": "33",
"toolResult": "36", "toolError": "1;31", "system": "35", "status": "36" }
工作原理
三层结构,全是普通文件:
| 层 | 位置 | 内容 |
|---|---|---|
| bundle | 仓库根(npm 包 dsh-simple-cli) | cordis.patch.yml + lib/ 运行器插件 |
| profile | $DSH_HOME/profiles/cli | 清单:@deepseek-ai/dsh-base + dsh-simple-cli |
| shim | npm 全局 bin | dsh-cli → dsh --profile cli |
- bundle 解析:先查 dsh 安装目录,再查 profile 自身
node_modules,因此把 bundle 放进profiles/cli/node_modules/dsh-simple-cli即可 - 依赖:所有运行时 import 沿目录树上溯到 dsh 自带的共享
profiles/node_modules,无需 pnpm install - 运行器:
lib/index.js通过核心注册表建一个 Agent,把session/event事件流实时渲染:assistant/chunk增量流式显示推理/正文/工具参数,tool/call+tool/result绘制工具行,approval/request在同一输入区内联应答;非 TTY(管道/CI)自动回退为普通 readline 循环 - UI:
lib/ui.js是无依赖的 raw 模式迷你 TUI(纯 ANSI):回滚区 +──分隔线 + 多行编辑器 + 状态栏;lib/theme.js提供配色 - 注意:
dsh每次启动会把 profile 的cordis.yml重写为[],改动请写在cordis.patch.yml
仓库结构
dsh-simple-cli/
├── README.md # 本文件(中英双语)
├── LICENSE # MIT
├── package.json # dsh-simple-cli bundle 包
├── cordis.patch.yml # bundle patch(loader patch 列表)
├── lib/
│ ├── index.js # cli-runner 插件:agent 循环 / 事件渲染 / /model /permission
│ ├── startup.js # cli-startup 插件:命令行解析
│ ├── ui.js # raw 模式迷你 TUI:输入区 / 流式视图 / 状态栏
│ ├── theme.js # 配色 + DSH_CLI_THEME 覆盖
│ └── refs.js # @file 引用:查找并附加引用文件内容
├── test/
│ ├── ui.test.mjs # Tui 单元测试(node test/ui.test.mjs)
│ └── refs.test.mjs # @file 引用单元测试(node test/refs.test.mjs)
├── profile/ # cli profile 模板
│ ├── package.json
│ ├── cordis.patch.yml
│ └── pnpm-workspace.yaml
├── bin/ # dsh-cli 命令 shim
│ ├── dsh-cli.cmd # Windows cmd
│ ├── dsh-cli.ps1 # PowerShell
│ └── dsh-cli # POSIX sh
└── install.ps1 # 一键安装脚本
开发
改完本仓库的 bundle 源码后,同步运行副本:
Copy-Item -Recurse -Force .\lib, .\package.json, .\cordis.patch.yml "$HOME\.dsh\profiles\cli\node_modules\dsh-simple-cli\"
已知的坑
dsh --profile cli报 profile 不存在 → 需先建profiles/cli/package.json,跑一遍.\install.ps1cordis.yml总被重置为[]→ 正常现象,改cordis.patch.yml- 改 bundle
name→ 同步cordis.patch.yml里的插件名和 profile 的 bundles 列表
路线图
- 跨会话 ↑/↓ 历史持久化(存
$DSH_HOME) /sessions历史会话列表- 发布 npm(
dsh-simple-cli),他人可dsh plugin --profile cli add dsh-simple-cli
License
MIT © godzeason