deepseek-harness-rs README

The project's README from github.com/xizheyin/deepseek-harness-rs. As one markdown file: README.md.

dsh-rs

用 Rust 构建的 DeepSeek 终端编程 Agent

在真实代码仓库里持续对话:搜索和阅读代码、应用补丁、运行命令,并在长会话中保存、恢复与压缩上下文。

CI Version 0.1.0-alpha.0 Rust 1.85.0 MIT License

快速开始 · 能力概览 · 会话恢复 · 安全边界 · 项目状态

[!WARNING] dsh 当前是 0.1.0-alpha.0 预发布版本,源码安装候选已通过 Phase 0–11 验收,但尚无受支持的稳定发行版、预编译包或 crates.io 发布。

dsh-rs 是项目名,安装后的命令是 dsh。这是一个独立的社区开源项目,Agent 内核以固定版本的 DeepSeek Harness 为行为参考, 再用适合 Rust CLI 的类型、并发模型和安全边界重新实现;它不是官方产品,也不是 TypeScript 源码的逐行翻译。

dsh-rs 在终端中读取文件、展示补丁并完成修改

Phase 11 增强界面的真实安装版 PTY 证据;模型响应来自离线 loopback fixture,不调用真实 API,也不消耗额度。

快速开始

仓库固定使用 Rust 1.85.0。安装 Rustup 后,在仓库根目录执行:

cargo install --locked --path .
export DEEPSEEK_API_KEY='你的 DeepSeek API Key'
dsh --workspace .

默认 --tui auto 会在有颜色、xterm*、非 tmux/Screen/Zellij 且初始窗口至少 44×12 时启用增强界面。看到 ❯ 后直接输入任务并按回车;其他环境会保守使用 零 ESC 的 dsh > 线性界面。可用 --tui enhanced 或 --tui linear 明确选择; --reduced-motion 会关闭增强界面的周期动画;--no-color、NO_COLOR 和 TERM=dumb 会强制线性界面。例如:

请先了解这个项目,再告诉我最值得修复的三个问题。

若你愿意让经过工作区路径、冲突和大小检查的内置文件修改自动提交,可显式使用:

dsh --workspace . --approval-mode auto-edit

该模式不自动批准 Shell 或插件,也不用于 --prompt/管道脚本。选择会写入当前会话, 恢复时继续生效;空闲时可用 /permission 查看,并用 /permission ask 或 /permission auto-edit 随时切换。显式启动参数会覆盖并保存恢复会话中的旧选择。

需要定义、引用、实现或类型提示等精确代码导航时,可显式配置本机语言服务器:

dsh --workspace . --lsp-config /absolute/path/to/lsp.json

配置示例和 rust-analyzer 路径说明见配置文档。

如果任务依赖“今天”“明天”或经过了多久,可显式给每个模型步骤附上当前时区的 可恢复时间快照:

dsh --workspace . --time-zone Asia/Shanghai

时区必须是规范 IANA 名称;该功能不猜测系统时区,也不会增加审批。

API Key 只从进程环境按请求读取。不要把真实密钥写入提示词、工具参数或 Shell 命令,因为这些内容本来就是模型和会话可见的。

能力概览

能力 当前实现
多步骤 Agent Loop 流式接收 DeepSeek 响应,关联 reasoning、文本、工具调用、结果、usage 和结束原因
只读工具并行(实验性) 同一步中的独立 read、skill、web_search、web_fetch、lsp、job_list、job_output 最多 10 个并行;结果仍按模型原顺序进入会话,其他工具(包括 read_image)保持独占执行
重复调用提醒(实验性) 模型连续第 3、5、8 次用相同参数调用同一工具时,向下一步追加建议,避免无进展循环持续消耗时间和 token
代码理解 工作区内的 list、glob、grep 和 read,输出和扫描范围均有上限
图片理解(实验性) 选择 deepseek-v4-flash-vision-exp 后,模型可用 read_image 读取工作区图片;人也可用重复 --image PATH 或交互 /image PATH 把 PNG/JPEG/WebP/GIF 附到下一条普通提示。图片会先整批校验并按 SHA-256 私有落盘,每次最多 4 张、4 MiB 原始字节
联网工具(实验性) web_search 并发执行 1–4 个 DeepSeek 原生查询并公平合并最多 8 个来源;web_fetch 匿名读取一个经过公网地址校验的 HTTP(S) 页面;两者均无需额外审批
项目指令(实验性) 有界加载用户级、根目录及已触达嵌套目录的 AGENTS.md / CLAUDE.md,写入会话并在恢复或文件工具成功后检查变化
时间上下文(实验性) 显式 --time-zone 后,每个模型步骤追加时间、时区和经过时长快照;会话恢复和上下文压缩后仍可回放,无需审批
项目 Skills(实验性) 有界发现工作区 .dsh/skills 和 .agents/skills 中的 Markdown Skill;模型先看到名称/描述目录,再用只读 skill 工具按需加载当前正文,无需审批
历史会话导航(实验性) 模型可用只读 session_search 找到同工作区已关闭会话,再搜索/精读事件,或用 session_trace / session_event_trace 查看父子会话和事件替换/来源关系;均有界、标记为非可信且无需审批
LSP 代码导航(实验性) 显式 --lsp-config 后,模型可用只读 lsp 精确查询定义、引用、实现和 hover;源码、协议、输出、超时、取消和进程组清理均有上限,无需逐次审批
文件修改 官方风格的完整文件 write、唯一/全部字面 edit 和 str_replace_editor,以及严格的单文件 apply_patch;它们都检查实际 diff、路径、符号链接和并发修改,默认审批,也可为当前会话显式启用 auto-edit
权限预设(实验性) 空闲时用 `/permission [ask
命令执行 经审批的前台或进程内后台 bash,可显式记住完全相同模式的本进程调用;后台作业通过 job_list / job_output / job_kill 管理,输出、数量和运行时间均有上限,退出时统一回收进程组
交互控制 实验性 Unicode 多行 Composer、忙时下一回合队列、动态 Dock、安全粘贴、6 套内置语义主题、可关闭的工作状态动画、源文本保持的有限表格、每个工具生命周期至多一张最终卡、回合收据、只读 Inspect/Review、审批、Ctrl+C 取消,以及严格线性后备
模型提问(实验性) 模型可暂停回合并显示 1–3 个单选、多选或自由文本问题;答案草稿可前后翻页修改,全部完成后继续当前回合
Goal 自动续跑(实验性) /goal 设置一个可随会话恢复的目标;空闲时顺序执行自动回合(默认上限 32),模型可读取、编辑、暂停、完成或在三轮均受阻后停止
Plan Mode(实验性) /plan [MESSAGE] 进入可恢复的只规划模式;模型提交完整 Markdown 计划供你审阅,只有明确批准才会在下一步退出
模型任务列表(实验性) 模型可用 todo_write 整体更新最多 64 项任务;增强界面显示当前进度摘要,线性界面输出完整清单,会话恢复后继续显示
脚本模式 --prompt 或管道输入;不会停下来等待审批,并安全拒绝写文件或 Shell 请求
长会话 有上限的本地 JSONL、会话列表与恢复、自动上下文摘要,以及空闲时手动 /compact
会话标题(实验性) 第一条人工提示立即生成安全短标题;官方非回环 DeepSeek 端点会在后台尝试一次自然语言标题;可用 /rename TITLE 手动固定,并用 /refresh-title 重试或恢复首提示标题
会话导出(实验性) 空闲时用 /export 把当前会话的原始 JSONL 精确复制到工作区根目录;文件仅所有者可读写,不覆盖同名文件
会话分支(实验性) 空闲时用 /fork [EVENT_SEQ] 从一个已完成回合创建独立、可恢复的子会话;当前父会话继续运行
Session 模型切换(实验性) 空闲时用 /model [MODEL [EFFORT]] 查看或切换下一次请求的 DeepSeek 模型与 off/high/max 推理强度;实际请求后随会话恢复
本地工具插件(实验性) 显式配置受信任的子进程工具;协议、队列、输出、超时和清理都有上限,交互调用仍需审批

使用方式

交互模式

dsh --workspace .

增强界面提供下面的 Composer 编辑键;若自动回退到线性兼容界面,则按终端的普通 整行输入方式操作。

输入 行为
/help 显示会话内帮助
/compact 空闲时把较早且边界完整的对话压成摘要;不接受参数,也不会消耗一个新回合
/rename TITLE 空闲时修改当前会话标题;标题会安全规范化、持久保存,并阻止后台自动标题再次覆盖
/refresh-title 空闲时根据第一条人工提示重试标题生成;无标题 Provider 时恢复本地 fallback,不接受参数
/export 空闲时把当前会话原始日志复制到工作区根目录;自动生成文件名,不接受参数且不覆盖已有文件
/fork [EVENT_SEQ] 从当前会话的已完成回合创建可恢复子会话;省略序号时使用最新完成回合,成功后显示 dsh --resume 命令
/model [MODEL [EFFORT]] 查看当前选择;或切换下一次请求的模型和可选 off、high、max 推理强度
/exit 或 /quit 等待清理后退出
/inspect、/review 增强界面本地切换只读详情;线性界面输出零 ESC 报告;不会发送给模型或加入队列
/focus 仅增强界面:从详情返回默认 Focus
/theme [NAME] 查询或选择 adaptive、midnight、paper、color-blind、high-contrast、mono;线性界面始终保持纯文本
`/motion [full reduced]`
/goal [OBJECTIVE] 显示或创建当前会话的 Goal;还支持 edit OBJECTIVE、pause、resume 和 clear
/plan [MESSAGE]、/plan off 空闲时进入 Plan Mode,可同时发送第一条规划要求;或手动退出。当前回合运行时需先等待或取消
Enter 空闲时发送;当前回合运行时加入下一回合 FIFO
Ctrl + J 在增强 Composer 中插入换行
方向键、Home/End、Backspace/Delete 按 Unicode 字素编辑;上下方向在边界浏览本进程已提交历史
Ctrl + R / Ctrl + _ 反向搜索历史 / 撤销;Ctrl+Z 保留给暂停
Ctrl + O 打开 Inspect;详情中再次按下可回到 Focus
Ctrl + C 取消当前回合,清理完成后继续当前会话
Ctrl + D 安全结束会话
Ctrl + Z 先清理当前回合再暂停;回到 Shell 后可用 fg 恢复

Goal 适合“持续修完这一组问题”这类需要多轮推进的任务。创建后,dsh 会在没有待发送 人工输入时自动生成下一轮;模型通过 get_goal、create_goal 和 update_goal 读取或 更新状态。每轮仍走原有工具、审批、超时、会话和进程清理路径。按 Ctrl+ C 会先取消当前轮并把 Goal 暂停,/goal resume 才会继续。Goal 的目标、状态、 修订号和已开始轮次会写入当前会话;重启后通过 --resume 可以查看,但默认保持 disarmed(未武装,不会自动发模型请求),必须显式执行 /goal resume 才会续跑。 目标默认最多自动运行 32 轮;模型工具可在创建或编辑时显式调整这个正整数上限。 当前仍不支持 Goal 图片附件或后台并行工作。

Plan Mode 适合“先调查并给我方案,确认后再改”这类任务。执行 /plan 会把模式状态写入 当前会话;/plan 先检查恢复逻辑 会进入模式并立即把后半句作为普通用户消息发送。 模式开启时,模型会收到额外的只规划指引,但这只是行为约束,不是操作系统沙箱;文件、 Shell、插件、审批、超时和取消规则都不会被绕过。模型用 exit_plan_mode 提交最多 16 KiB、 以 # 标题开头的完整 Markdown 计划后,终端会显示原文。选择批准会记录成功结果,并在 下一次模型请求前退出;选择继续规划或填写反馈会把失败结果交回模型修改;按 Esc 会保持 Plan Mode 并让你先发消息。也可以在空闲时用 /plan off 手动退出。恢复会话时模式仍会 保留;当前不支持计划图片,也不支持在正在运行的同一回合里用命令切换模式。

模型在处理多步骤任务时可以调用 todo_write 保存一份完整任务清单。每项只有 pending、in_progress 或 completed 三种状态;当前最多 64 项、每项 512 个 UTF-8 字节,并且最多一项处于进行中。增强界面会在 Dock 显示完成/进行中/待办数量和当前任务, 线性界面会打印完整的 [x]、[~]、[ ] 清单。任务列表写入 Session,恢复会话后仍可 显示;下一回合开始时 standing 摘要会清除,但历史事件不会删除。它只是模型的进度记录, 不会自动启动后台工作,也不会授予文件、Shell 或插件权限。

启动新会话时,dsh 会先读取 $DSH_HOME/AGENTS.md(未设置时是 ~/.dsh/AGENTS.md),再按顺序读取工作区根目录的 AGENTS.md、CLAUDE.md、 AGENTS.local.md 和 CLAUDE.local.md。它们会作为一条最多 64 KiB 的低优先级项目 指令紧跟第一条提示词写入 Session,因此恢复后不会重复注入;文件在重启前发生新增、修改 或删除时,会追加变化通知而不是改写历史。单个源文件最多 1 MiB,重复内容会折叠,宽泛 文件会优先让位给更具体的本地覆盖。为避免仓库中的链接读取无关宿主文件,Rust 版本不读取 指令符号链接,也不越过 --workspace 向父级寻找 .git。内置 read 成功读取文件,或 内置 apply_patch 或 str_replace_editor 确定已经提交文件后,dsh 会在当前步骤结束后检查该文件祖先目录中的 同名指令,并把新增、更新或移除通知放进下一次模型请求。失败、拒绝、取消、Shell 和插件 结果不会伪造这种触达;同一步的多个路径会合并成一条有界消息。

模型需要当前信息时可以调用 web_search。一次可给出 1–4 个查询;每个查询会先作为同一 个普通 tool/call 写入 Session,再并发使用同一个 DEEPSEEK_API_KEY 请求 DeepSeek 的 独立搜索端点。搜索整体最多 60 秒,支持 Ctrl+C 取消,不跟随重定向,也不使用系统代理。 结果按查询排名交替合并,最多保留 8 个去重 URL 及有界标题、摘要和日期,并明确标为外部 不可信内容。

模型也可以用 web_fetch 匿名读取一个明确的 HTTP(S) URL。该工具不带 API Key、Cookie、 代理或浏览器身份;它会先检查 DNS 的全部结果,只允许公网地址,并把实际连接固定到已经 检查过的地址,避免域名在检查后偷偷改指内网。跳转仅限同源且每一跳重新检查,最多 5 次; 请求最多 30 秒,响应最多 5,000,000 字节,解码内容最多 100,000 个字符,最终工具文本仍受 64 KiB 上限约束。HTML 会转换成保守的 Markdown 风格文字,脚本、隐藏内容和过深或无法 安全转换的结构不会原样交给模型。非 UTF-8 页面只支持 ASCII、ISO-8859-1/Windows-1252 这组常见标签。搜索和抓取都是只读能力,因此不会弹出文件、Shell 或插件审批;网页文字仍 可能包含恶意提示,模型只应把它当资料,并引用相关 URL。

显式传入 --lsp-config 后,模型会在普通文本搜索含糊时使用 lsp。它只接受 goToDefinition、findReferences、goToImplementation 和 hover,位置使用从 1 开始的 行号和 UTF-16 字符偏移;服务器协议内部会转换为从 0 开始。源文件必须位于工作区、不能是符号链接、 必须为 UTF-8 且不超过 4,000,000 字节。服务器按扩展名惰性启动并在本进程复用,默认查询 上限 60 秒;Ctrl+C 或超时会发送协议取消,若服务器不收敛则回收整个进程组。服务器不能 借协议要求 dsh 修改文件或运行命令。配置本身是对该本机可执行程序的信任,不是沙箱; 恢复会话时需要再次传入。

显式传入 --time-zone Asia/Shanghai 后,dsh 会在每个真正进入的模型步骤前读取一次 本机时间,并把带数值偏移和 IANA 时区的整秒时间、以及距上一条相关消息经过的时间写入 Session。它是模型可见的普通历史事实,因此恢复或压缩后不会凭空改变;恢复的新进程若还 需要新读数,必须再次传入该参数。时区必须使用规范写法,例如 UTC、Asia/Shanghai 或 America/New_York,别名和大小写错误会在创建会话或连接网络前失败。该能力不会启动 后台任务、调用工具或扩大文件/Shell 权限,但每一步会增加少量上下文。

模型需要复用较早工作时,会先用 session_search 找到一个同工作区会话 ID,再用 session_event_search 在该会话内搜索最多 20 个事件;结果包含序号、事件类型、 current/shadowed/log-only 状态和短摘要。需要核对原始事实时, session_event_read 可按序号返回完整 JSON,并附带前后各最多 50 个事件的有界语义摘要。 两种搜索都可在文本匹配前先缩小范围:跨会话搜索可限定 Session ID、 创建时间、已验证的直接父会话/根会话和持久化状态;两者都可限定事件序号、 时间、类型和表面状态。不同字段是 AND,同一数组内是 OR,时间须带 Z 或数值时区偏移。过滤会在排序和 20 条上限之前执行。 需要理解关系时,session_trace 显示已验证的父链和子会话树; session_event_trace 分开显示事件替换链、直接来源和直接派生事件。五个工具都只读取已经正常关闭且严格校验通过的本地日志,不弹审批,也不会读取当前或 仍被其他 dsh 占用的会话。完整事件若放不进普通 64 KiB 工具结果,会明确失败而不是截断 后假装“完整”。旧历史仍可能含过时或恶意内容,只能当证据,不能当指令。

如果模型在同一个步骤里发出多个互不依赖的 read、skill、web_search、web_fetch 或 lsp,dsh 会在最多 10 个在途调用的上限内重叠等�

deepseek-harness-rs (xizheyin/deepseek-harness-rs)

Searching Database…

What is this?dsh-rs (binary name dsh) is a Rust rewrite of a DeepSeek terminal coding agent. It works directly in a real code repository: it searches and reads code, applies patches, runs commands, and keeps long multi-turn sessions that can be saved, resumed, and compacted.
Is this an official DeepSeek product or a community reimplementation?It is an independent, unofficial community project. The agent kernel uses a fixed version of the official DeepSeek Harness as a behavioral reference, but is reimplemented in Rust with its own types, concurrency model, and safety boundaries rather than being a line-by-line port of the original TypeScript source.
How do I install and run it?Install Rustup to get the pinned Rust 1.85.0 toolchain, then build and run the binary from the repository root. There is currently no supported stable release, precompiled package, or crates.io publish.
Do I need a DeepSeek API key?Yes. The key is read only from the process environment at request time; you should never put a real key into prompts, tool arguments, or shell commands, since those are visible to the model and the session log.
Is this stable enough to rely on?No - it is a 0.1.0-alpha.0 pre-release that has only passed internal Phase 0-11 acceptance testing, with no supported stable release, prebuilt binary, or crates.io package yet. Many listed features (vision, web search, LSP, Goal mode, Plan mode, skills) are explicitly marked experimental.
What terminal interface does it use?By default dsh auto-detects an enhanced TUI (Composer editing, Dock, themes, animations) when the terminal supports color, is at least 44x12, and isn't tmux/Screen/Zellij; otherwise it falls back to a plain, zero-ESC linear interface, which can also be forced with --tui linear or NOCOLOR/TERM=dumb.
What is Goal mode?The /goal command sets a resumable objective. While idle, dsh automatically runs sequential turns (default cap 32) to advance it, until the model pauses, completes the goal, or gets blocked three turns in a row.
What is Plan Mode?The /plan command switches the agent into a planning-only mode where it must submit a full Markdown plan via exitplanmode before making changes; you can approve it, send it back for revision, or exit with /plan off.
Can I run it non-interactively in scripts?Yes, pass --prompt or pipe input to use script mode, which never waits for approval and automatically refuses any file-write or shell-execution request.
Creator
xizheyin
Size
5.6 MB
Stars
147
Updated
CommitAug 29
Age
2mo
Commits · 90 Days