CHplus0/dsh-shell-command
DeepSeek Harness (DSH) plugin: a /! command trigger (run one command, analyze output, inspired by Claude Code's ! gesture) and a /terminal command (interactive PTY popup with on-demand history reference).
This is a DeepSeek Harness (DSH) plugin. Review its GitHub README, installation information, maintenance status, and public security signals here.
dsh-shell-command
English | 中文
一个 DeepSeek Harness 插件,把 Claude Code 的 ! 手势带到 DSH,分为两种模式:
| 命令 | 行为 |
|---|---|
/! <命令> | 执行 shell 命令,分析其输出。灵感源自 Claude Code 的 ! 前缀——在会话工作目录执行命令,并把输出交给模型即时分析 |
/terminal | 弹出交互式终端窗口;关闭本身从不向模型发送任何内容——若本次会话有过输入,转录落盘后面板会跳转到「历史」Tab 并预选中这条,是否引用给模型分析由你在那里手动决定 |
注意:DSH 的输入触发系统只支持 / 和 @ 作为触发字符,因此我们用 /! 而不是裸 ! 前缀。
安装
需要 dsh CLI 与 Node >= 22。
# 从 npm / 仓库安装
dsh plugin --profile web add dsh-shell-command
# 本地源码(开发用 live link,改源码重启即生效)
dsh plugin --profile web add "link:/path/to/dsh-shell-command"
安装后重启一次 Web 界面(dsh web)让 host 端命令加载;它会自动出现在输入框 / 菜单中。
快速上手
第一次使用 /! 命令
在输入框输入:
/! df -h
命令立即执行,输出交给模型分析。你会看到类似的消息:
Shell Command Output
Command:df -h
[输出内容]
模型随后分析磁盘使用情况,如发现问题会给出建议。
第一次使用 /terminal 会话
- 在输入框输入
/terminal - 弹出浮动终端面板,有两个Tab:会话 和 历史
- 在会话Tab尝试一些命令:
pwd ls -la git status - 点击顶部的 退出 按钮关闭终端
- 面板保持打开并自动跳转到 历史 Tab
- 刚关闭的会话已预选并展开
- 选择后续操作:
- 点击 引用并分析 将其发给模型分析
- 点击 直接退出,本次不分析 跳过并关闭面板
命令详解
/! <命令> — 单命令分析
在会话工作目录执行命令,并立即把输出交给模型分析。这是 DSH 版的 Claude Code ! 前缀。
何时使用:
- 快速状态检查:
/! git status、/! npm test - 系统诊断:
/! df -h、/! free -h、/! top -bn1 | head -20 - 文件搜索:
/! find . -name "*.log" -mtime -1 - 一次性操作,需要立即获得 AI 洞察
示例:
/! git log --oneline -10
# → 模型总结近期提交,可能发现模式
/! npm run build
# → 模型分析构建输出,标记警告或错误
/! ps aux | grep node
# → 模型解释正在运行的 Node 进程
技术细节:
- 输出有界限(
maxOutputBytes,保留尾部)并格式化用于分析 - 命令原文和生命周期记入轨迹(
command/run/command/done) - 需要活跃的模型对话(在第一条消息、模型请求之前无法使用)
/terminal — 交互式终端
交互式 PTY 弹窗(持久 shell,WebSocket 实时流)。最适合:
- 探索性调试:运行多个命令,观察行为
- 迭代测试:修改 → 测试 → 修改 循环
- 多步骤操作:设置 → 执行 → 验证 工作流
工作原理:
关闭终端永远不会自动向模型发送任何内容:
- 若本次会话没收到过任何输入 → 完全不留痕迹(不落盘、不进历史列表)
- 若收到过输入 → 转录落盘到
<工作目录>/.dsh-shell-transcripts/,面板跳转到历史Tab并预选中这条新记录
之后由你决定是否引用它进行分析(见下方历史Tab工作流程)。
会话Tab特性
- 行式终端:等宽回显 + 输入行
- 控制键:Ctrl+C/D/Z 发送原始控制字节到 shell
- 命令历史:方向键上下浏览已提交过的命令(纯客户端,最多 500 条)
- 限制:不支持 Tab 补全;完整 VT100/xterm(vim、htop)计划后续版本支持
历史Tab工作流程

关闭一个收到过输入的终端会话后,面板自动切换到历史Tab:
UI元素说明:
- 复选框(左侧):选择一条或多条历史记录用于分析
- 时间戳:每个会话的关闭时间
- 查看/收起按钮(右侧):展开预览转录内容
- 说明文本框(底部):可选的自然语言上下文,帮助模型理解
- 默认消息提示:显示不填写说明时模型会收到的默认消息:「请帮我分别分析这些历史终端记录。」
- 两个操作按钮:
- 引用并分析:将选中的记录发送给模型立即分析
- 直接退出,本次不分析:关闭面板,不向模型发送任何内容
典型工作流程:
1. 关闭终端会话(点击「退出」)
2. 面板保持打开,跳转到历史Tab
3. 刚关闭的记录已预选并自动展开
4. 查看转录预览
5.(可选)选择其他历史记录进行对比
6.(可选)在说明框添加上下文:「为什么第二次运行失败了?」
7. 点击「引用并分析」→ 模型分析选中的转录
或点击「直接退出,本次不分析」→ 面板关闭,不向模型发送任何内容
高级用法:
- 跨运行对比:选择 2-3 个相关会话(如修复前后)并询问:「这几次尝试之间有什么变化?」
- 引导式分析:使用说明框引导模型注意力:「重点关注内存使用模式」
- 选择性共享:并非每个终端会话都需要分析——只引用与当前问题相关的内容
存储:
- 转录持久化到
<工作目录>/.dsh-shell-transcripts/ - 每个会话包含:
<sessionId>-<timestamp>-<counter>.log+.meta.json元数据文件 - 保留策略:每个 session ID 保留最近 10 个会话(通过
terminalTranscriptKeep配置) - 建议将
.dsh-shell-transcripts/加入.gitignore
使用场景
场景1:使用 /! 快速诊断
你:构建失败了,让我检查一下...
你:/! npm run build
[输出显示 TypeScript 错误]
模型:错误表明 auth.ts 第42行缺少类型导入...
场景2:使用 /terminal 交互式调试
你:/terminal
终端:$ npm test
[测试失败]
终端:$ cat test/integration.spec.js | grep -A5 "failing test"
终端:$ ls -la test/fixtures/
终端:$ echo $NODE_ENV
[发现问题:缺少 fixture 文件]
终端:[点击「退出」]
[面板跳转到历史Tab,记录已自动选中]
你:[添加说明:「这个测试为什么失败?」]
你:[点击「引用并分析」]
模型:根据转录,测试失败是因为 test/fixtures/user-data.json 文件缺失...
场景3:对比多次运行
[运行1:/terminal → 安装依赖 → 检查构建时间 → 退出]
[运行2:/terminal → 启用缓存后相同步骤 → 退出]
[运行3:/terminal → 不同 Node 版本相同步骤 → 退出]
[在历史Tab]
你:[勾选全部3条记录]
你:[添加说明:「哪个配置最快,为什么?」]
你:[点击「引用并分析」]
模型:对比三次构建运行:运行2因为 npm 缓存快了3倍...
使用技巧与最佳实践
- 选择合适的工具:单命令且需要立即反馈用
/!;探索性工作流程且稍后决定是否分析用/terminal - 空会话不持久化:打开
/terminal但没输入任何命令,不会创建历史记录(这是设计如此,避免混乱) - 方向键是你的朋友:终端输入行中,↑/↓ 可回顾最近 500 条命令(客户端、会话级别)
- 说明增加上下文:好的说明(「对比错误信息」或「关注性能指标」)帮助模型更有效地分析
- 选择性分析:不必分析每个终端会话——只引用与当前问题相关的内容
- 历史是每个会话独立的:每个 DSH 对话有自己的终端历史;它们不会混在一起
配置
通过 profile 的 cordis.patch.yml 配置(Web 设置页不暴露第三方插件设置):
- insert:
- id: shell-command
name: dsh-shell-command
config:
shell: '' # '' → POSIX 用 /bin/bash,Windows 用 cmd.exe
shellArgs: [] # [] → POSIX 用 -lc,Windows 用 /d /s /c
timeoutMs: 60000 # 硬超时,到期终止整个进程树
maxOutputBytes: 32768 # /! 命令的输出尾部保留量
graceMs: 3000
analysisPrompt: '' # '' → 内置提示词;支持 {command} {cwd} {output} 占位符
terminalEnabled: true
terminalMaxTranscriptBytes: 1048576 # 内存转录上限(保留尾部)
terminalTranscriptDir: '.dsh-shell-transcripts'
terminalTranscriptKeep: 10
安全
- 在会话工作目录(
agent.session.header.cwd)执行 - 优先走 harness 的
ctx.subprocess接缝:环境已清洗(不泄漏DEEPSEEK_API_KEY/DSH_*),进程树级SIGTERM → grace → SIGKILL终止;缺失时回退node:child_process(同样清洗环境) /!命令的每个流输出有界(maxOutputBytes,超限保留尾部)- 设计上由人驱动:命令原文记入轨迹(
command/run),无沙箱审批步骤——与你自己在终端敲命令权限一致
测试
node test/unit.mjs # 纯解析/格式化测试,零依赖
node test/smoke.mjs # 完整 apply() + handler,跑在 mock context 上
node test/smoke-terminal.mjs # 终端注册表 + hasInput 追踪 + 历史引用 RPC(mock)
smoke 测试需要真实解析 @deepseek-ai/* 依赖;在 profile 外运行时先软链一次:
mkdir -p node_modules/@deepseek-ai
ln -s "$HOME/.dsh/profiles/node_modules/@deepseek-ai/"* node_modules/@deepseek-ai/
常见问题 FAQ
问:何时该用 /! 而非 /terminal?
答:单命令且需要立即 AI 分析时用 /!(状态检查、快速诊断)。需要运行多个命令并稍后决定是否分析时用 /terminal(交互式工作流程)。
问:为什么我的终端会话没出现在历史Tab?
答:空会话(没收到输入)不会持久化。如果你打开了 /terminal 但没输入任何命令,不会创建历史记录。这是设计如此,避免混乱。
问:历史转录存储在哪里?
答:在 <工作目录>/.dsh-shell-transcripts/,每个会话一个 .log 文件加一个 .meta.json 元数据文件。建议将此目录加入 .gitignore。旧记录会自动清理(默认:每个会话保留最近10条)。
问:可以手动删除历史记录吗?
答:可以,直接从 .dsh-shell-transcripts/ 删除对应的 .log 和 .meta.json 文件。历史Tab每次打开时从磁盘读取。
问:为什么 vim/htop/ncurses 在 /terminal 里不能用?
答:当前终端是行式的(回显 + 输入行),不是完整的 VT100/xterm 模拟器。完整终端模拟(使用 xterm.js)计划后续版本支持——需要引入构建流水线。
问:方向键命令回顾会跨会话持久化吗?
答:↑/↓ 历史是客户端的,关闭浏览器Tab或面板后会重置。它的作用域是当前终端窗口,不保存到磁盘。
问:「引用并分析」和直接在对话中问命令有什么区别?
答:「引用并分析」会把实际的命令转录(输出、时间戳、退出码)作为结构化数据发给模型。在对话中问依赖你的描述,可能会遗漏细节。当你希望模型看到原始输出时,用引用分析。
问:可以引用之前 DSH 对话的转录吗?
答:不可以。终端历史是会话级别的。每个 DSH 对话有自己的 .dsh-shell-transcripts/ 命名空间,历史Tab只显示当前 session ID 的记录。
问:如果输出非常长会怎样?
答:/! 和 /terminal 都有输出大小限制(maxOutputBytes / terminalMaxTranscriptBytes)。超限时保留尾部(不是头部)。这确保最近的输出始终可见。
问:为什么 /! 提示「No model request exists yet」?
答:/! 需要活跃的模型对话。先向模型发送至少一条消息(开始对话),然后 /! 就能用了。这是为了避免 UI 渲染时序问题。
已知限制
/!的输出作为 plugin 来源的消息交付(在对话中可见)- 终端模式:仅行式显示(vim/htop 需要完整 xterm 模拟,后续版本计划支持)
- API 面锁定
@deepseek-ai/dsh0.1.0-rc.x;升级 DSH 时需锁定 peer 并回归
未来优化方向
我们计划在后续版本中进行以下改进:
完整终端模拟(迁移到 xterm.js)
- 当前:行式终端(回显 + 输入行)
- 目标:完整 VT100/xterm 模拟,支持 vim、htop、ncurses 应用、oh-my-posh 等丰富终端 UI
- 需要:引入构建流水线(webpack/vite)以打包 xterm.js 及其插件
国际化支持(i18n)
- 多语言 UI 支持(英文、中文等)
- 从用户偏好自动检测语言
- 可配置的 UI 标签
其他改进
- 命令输出的语法高亮
- 会话导出/导入
- 终端历史内搜索
- 自定义键盘快捷键
贡献
欢迎贡献!你可以:
- 🐛 报告 bug 或提出功能请求
- 🔧 提交 pull request
- 📖 改进文档
- 💡 分享你的使用场景和反馈
License
MIT
Security & install evidence
This score is based solely on public repository metadata and the install evidence registered here — it is not a code security audit.
From a public plugin catalog, linked to a public GitHub repository.
The repository declares the MIT license.
Code updates within the last 180 days.
No verifiable install metadata registered yet — please review the repository instructions manually.
The inspected package metadata declares no install lifecycle scripts.