@viogus/dsh-rtk
Routes eligible bash commands through rtk (Rust Token Killer) so tool output is compressed before it reaches the model, by asking the installed rtk to rewrite each command and adopting what it prints; when rtk is absent the executor behaves exactly like the stock one.
Install
dsh plugin --profile web add @viogus/dsh-rtk
Sandbox test results
| Stage | Result |
|---|---|
| 1 install | ✓ |
| 2 list | ✓ |
| 3 mount | ✓ |
| 4 boot | — |
Four stages run in an isolated sandbox: install (network on) → list → mount → boot (last three with no network).
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)
Rendered from the README published on npm. Formatted only, not edited.
Versions
Published on npm::7,最后更新 2026-10-26