@viogus/dsh-rtk
把符合条件的 bash 命令交给 rtk(Rust Token Killer)执行,让工具输出在进入模型之前就被压缩:插件调用本机 rtk 重写命令并采纳其结果;rtk 未安装时,执行器行为与原生完全一致。
安装
dsh plugin --profile web add @viogus/dsh-rtk
沙箱测试结果
| 阶段 | 结果 |
|---|---|
| 1 安装 | ✓ |
| 2 列装 | ✓ |
| 3 挂载 | ✓ |
| 4 启动 | — |
四阶段在隔离沙箱里跑:安装(有网)→ 列装 → 挂载 → 启动(后三步断网)。
README
dsh-rtk






在 DeepSeek Harness(dsh)的 bash 执行器里,把符合条件的 shell 命令路由给 rtk(Rust Token Killer)执行 —— 压缩工具输出、省 token、其余一概不变。
[English version](README.md)
提示:workspace-write 会话只有压缩,没有账本与备份。
改写本身在所有模式下都生效。问题出在隔离:dsh 只允许写工作区、/tmp 与平台临时目录,
而 rtk 把history.db、recall.db与tee/放在~/Library/Application Support/rtk
—— 不在可写范围内。这些写入会被静默拒绝,于是 rtk gain 始终为空、也不会留下
tee 备份。两种解法:运行
[scripts/allow-rtk-state-in-sandbox.mjs](scripts/allow-rtk-state-in-sandbox.mjs)
(apply后重启 harness)只放开这一个目录;或把该会话切到danger-full-access。
详见[沙箱会话](#沙箱会话workspace-write)。
目录
- [快速示例](#快速示例)
- [环境要求](#环境要求)
- [为什么需要它](#为什么需要它)
- [工作原理](#工作原理)
- [安装与启用](#安装与启用)
- [从
@deeptrial/dsh-bash-rtk迁移](#从-deeptrialdsh-bash-rtk-迁移) - [API / 配置](#api--配置)
- [哪些命令会被路由](#哪些命令会被路由)
- [沙箱会话](#沙箱会话workspace-write)
- [与其他省 token 插件的实测对比](#与其他省-token-插件的实测对比)
- [开发](#开发)
- [更新日志](#更新日志)
- [许可证](#许可证)
快速示例
插件在 resolve() 边界重写命令 —— 在实际执行之前:
输入 (command) · 解析后的输出 · 原因
git status · rtk git status · rtk 有对应规则
ls -la · rtk ls -la · rtk 同样路由 ls —— 与本插件的列表无关
tree · rtk tree · rtk 1.0 新增 —— 无需本插件发版即可生效
head -5 notes.txt · rtk read notes.txt --head-lines 5 · rtk 自己的非前缀式重写,原样采纳
git status \ · grep x · rtk git status \ · grep x · rtk 只重写它认识的片段,其余原样保留
cd /tmp · cd /tmp · rtk 拒绝改写 —— 恒等
git status(无 rtk) · git status · 二进制缺失 —— 恒等回退
其余一切 —— 工作目录、超时、环境变量、退出码、沙箱隔离 —— 均原样继承。
环境要求
- Node.js: >= 20.0.0
- rtk:
rtk --version在 PATH 上退出码为 0(需单独安装,例如cargo install rtk) - 委托式设计所需的最低 rtk:
0.25.0(rtk rewrite在该版本引入);本说明的所有内容以rtk 1.1.0为验证基准,CI 每次推送都会重跑该验证。没有上界 —— 见[版本说明](#版本说明)。
为什么需要它
LLM agent 在冗长的工具输出上浪费大量 token(git log、cargo build、pytest 输出……)。rtk 已知道如何把这些输出压缩 30–90%。本插件把这套过滤接到 dsh 的 bash 执行器上,让每个符合条件的命令自动走 rtk —— 且对实际运行内容零语义改动。
工作原理
model → dsh bash 工具 → RtkBashExecutor.resolve()
│
▼
rtk rewrite <命令>
│
┌───────────────┴────────────────┐
打印出重写结果 什么都不打印
│ │
原样执行该结果 原样执行原命令
两道关卡决定路由(见 [src/wrap.ts](src/wrap.ts) 与 [src/rtk.ts](src/rtk.ts)):
1. 映射表属于 rtk,不属于本插件。 resolve() 会启动 rtk rewrite <命令> 并采纳它在 stdout 上打印的内容。插件不维护任何命令表:当 rtk 新增规则时,升级 rtk 就等于升级插件的覆盖面,插件本身无需发版。退出码被刻意忽略 —— rtk 用它表达自己面向 Claude Code 的权限协议,而这里没有对应物。
2. 成本过滤器,而非策略。 命令会按顶层控制符(&&、||、;、|、|&、&、换行)切分,再逐段检查首词:shell 关键字与 cd、echo、export 等日常内建命令本身不构成可路由段。只有当每一段都是这类内建命令时,整条命令才会被跳过 —— cd repo && cargo test 会交给 rtk,并返回 cd repo && rtk cargo test。任何无法被证明「绝不被改写」的命令都会交给 rtk 判断。若 PATH 上找不到 rtk 二进制,整个变换就是恒等:部署行为与原始执行器完全一致。
rtk 是按词法切分命令的,而不是整串匹配:它只重写自己认识的片段,管道、&&/;、重定向与命令替换都逐字节保留。因此复合命令会被路由,而不是被跳过。
版本说明
本插件不捆绑、不锁定 rtk 版本。构造执行器时会探测 PATH 上的 rtk --version(见 [src/rtk.ts](src/rtk.ts) 的 probeRtkAvailable),随后就让这同一个二进制去做重写。因此:
- rtk 发布新版本时,任何在本地升级了
rtk的用户会自动获得新规则乃至新命令 —— 无需更新本插件。 - 本插件版本(本仓库)与 rtk 版本相互独立,请勿混为一谈。本说明给出的是测试所基于的最低 rtk 版本,而非锁步版本号。
RTK_BIN可覆盖二进制路径,RTK_TIMEOUT_MS可覆盖单次重写超时(默认 2000 ms);超时按「无重写」处理。
要求:rtk在PATH上(rtk --version退出码为 0)。插件不会安装或管理 rtk —— 你必须自行安装并更新 rtk(例如cargo install rtk或下载发布二进制)。当 rtk 缺失时,插件静默退化为透传。
兼容性与版本对齐
本插件依赖 @deepseek-ai/dsh-* 系列包,DeepSeek Harness 将它们与 dsh 聚合包分开发布到 npm。这些子包(以及 dsh 本身)都以预发布形式(x.y.z-rc.n)发布。在朴素的 node-semver 语义下,只有当某比较符与候选版本同 major.minor.patch 元组且自身也带预发布标签时,预发布版本才满足范围 —— 所以上界写成 <0.3.0-0 而不是 <0.3.0。运行时的 loader 比这更宽松:dsh-app-boot 用 includePrerelease: true 校验 engines.dsh 与插件的 dsh peer 范围,因此这些 peer 范围可匹配所有 0.1.x/0.2.x 预发布。但 peer 范围只是提示:真正决定 bundle 是否挂载的是下面写的 engines.dsh 门禁。
实际范围(见 package.json 的 peerDependencies)为:
"@deepseek-ai/cordis": "~4.0.4" "@deepseek-ai/dsh-bash-local": ">=0.0.1-rc.1 <0.3.0-0" "@deepseek-ai/dsh-bash-sandbox": ">=0.0.1-rc.1 <0.3.0-0" "@deepseek-ai/dsh-shell": ">=0.0.1-rc.1 <0.3.0-0"
四项 peer 都在 peerDependenciesMeta 中标记为 optional,因此在它们缺失时插件仍可安装并加载(此时退化为透传)。注意 cordis 一项:dsh 在运行时注入容器,但注入的是带 scope 的 @deepseek-ai/cordis —— 也正是本插件为获取 Context/Service 类型而 import 的包。npm 上不带 scope 的 cordis 是另一条更旧的线(4.0.0-rc.11),此处不可使用。
本package.json 与 dsh.plugin.json 声明同一个目标范围:
"engines": { "dsh": ">=0.2.1-rc.1 <0.3.0-0" }
dsh.plugin.json 另外带 "dshTarget": "0.2.1-rc.1",即本版本实测过的运行时。范围同时写进
package.json 是因为 dsh-app-boot 决定是否挂载 bundle 时读的是它;dsh.plugin.json 则是
插件工具界面展示的那份。
插件版本与 dsh 版本的对应关系
插件的 major.minor 跟随 dsh 的 major.minor;patch 归插件自己,用于纯插件修复。
dsh 开新 minor 线时插件跟着开新 minor(即使代码没变),这样配对关系一眼可见:
插件版本 · dsh 目标范围 · 实测基准
0.2.3 · >=0.2.1-rc.1 <0.3.0-0 · 0.2.1-rc.1
0.2.0 – 0.2.2 · >=0.1.0-rc.6 <0.3.0-0 · 0.2.0-rc.2
0.2.3 起故意不再放行 0.1.x 与 0.2.0-rc.2:loader 会拒绝在旧核心上挂载,
而不是挂上一个没验过的组合。仍停留在 0.2.0-rc.2 的话请锁 0.2.2。
已知的版本错位:dsh(聚合包,即npx @deepseek-ai/dsh安装的)与其@deepseek-ai/dsh-子包处于独立的 semver 轨道。上述范围锁定到已发布*的子包版本,因此普通dsh plugin add能干净解析。跟进匹配更新请关注 releases。
安装与启
…(truncated)
以上内容来自 npm 上的 README,我们只做格式化,不改内容。
版本
npm 上共发布:7,最后更新 2026-10-26