edabchann
dsh-neotui
Neo-TUI: mouse-driven terminal UI client for DeepSeek Harness
- Stars
- 0
- Language
- JavaScript
- Created
- Aug 14, 2026
- Updated
- Aug 16, 2026
Introduction
dsh-neotui
dsh-neotui 是 DeepSeek Harness 的终端客户端:以 Vim/Nvim 风格的 NORMAL / INSERT 模式、Yazi 风格文件选择器和鼠标交互,访问与 WebUI 相同的 Host 会话、工具、审批、任务和设置能力。
本仓库发布两个 npm 包:
| 包 | 用途 |
|---|---|
dsh-neotui | TUI 客户端、核心界面和 dsh-neotui 命令 |
dsh-neotui-app | 将 TUI、API gateway 和 Host 服务装配成 DSH profile 的 bundle |
0.2.0 亮点
- 三栏 Yazi 风格文件与工作区选择器:路径编辑、模糊筛选、隐藏项、Nerd Font 图标和 Kitty 图片预览;
- 图片附件栏、附件管理器、
dd删除和等比例 Kitty 预览; - 会话树筛选、跨会话模糊定位和稳定的历史分页;
- NORMAL / INSERT 模式与可编辑的快捷键目录;
- 独立的命令、设置和插件目录,插件支持即时筛选;
- Queue / Steering、Goal、TODO、Plan Review、后台任务和 Subagent 状态;
- grapheme-aware framebuffer、CJK/组合字符、Kitty keyboard、SGR mouse、OSC 8/52。
完整变化见 CHANGELOG.md。
安装与启动
独立 DSH profile
dsh plugin --profile dsh-neotui add dsh-neotui-app
dsh --profile dsh-neotui
常用参数:
dsh --profile dsh-neotui --session <session-id>
dsh --profile dsh-neotui --cwd ~/work
dsh --profile dsh-neotui --host 127.0.0.1 --port 3981
出于安全原因,--host 0.0.0.0 会被拒绝。能够执行工具的 Host 不应直接暴露到不受信任的网络。
连接已有 Web Host
dsh --profile dsh-neotui --attach 3080
也可以直接运行客户端:
node bin/dsh-tui.js
node bin/dsh-tui.js --base http://127.0.0.1:3080
默认连接 http://127.0.0.1:3080;可通过 --base、DSH_URL 或 DSH_WEB_URL 覆盖。--attach 不会启动或替换 WebUI。
从源码运行
.
├── app/ dsh-neotui-app bundle
├── bin/dsh-tui.js 客户端入口
├── src/ TUI 核心
└── test/ 单元、终端协议与 PTY 测试
使用本地 profile:
mkdir -p ~/.dsh/profiles/node_modules
ln -sfn "$(pwd)" ~/.dsh/profiles/node_modules/dsh-neotui
ln -sfn "$(pwd)/app" ~/.dsh/profiles/node_modules/dsh-neotui-app
dsh --profile dsh-neotui
只调试客户端时,保证目标 Host 已运行即可:
node bin/dsh-tui.js --base http://127.0.0.1:3080
交互模型
NORMAL / INSERT
NORMAL:单字符用于导航和操作;INSERT:键盘输入交给消息编辑器;i或点击输入框进入 INSERT;Esc离开 INSERT;- INSERT 中
Esc不会中断当前回合; - NORMAL 中
Esc会中断正在运行的回合,否则返回上一级; - NORMAL 中连续两次
Ctrl+C退出,INSERT 中Ctrl+C清空输入。
底栏始终显示当前模式。按 Ctrl+Space 打开快捷键、命令、设置和插件目录。
输入与附件
| 模式 | 按键 | 功能 |
|---|---|---|
| INSERT | Enter | 发送 |
| INSERT | Shift+Enter / Ctrl+J | 换行 |
| INSERT | Ctrl+L | 展开/折叠输入栏 |
| INSERT | ↑ / ↓ | 在首尾行浏览输入历史 |
| INSERT | Ctrl+Shift+C | 复制输入框选区 |
| INSERT | Ctrl+O | 打开文件选择器 |
| NORMAL | Ctrl+O | 打开附件管理器 |
文件选择器支持:
| 按键 | 功能 |
|---|---|
↑ / ↓ | 移动光标 |
← / → | 返回上级 / 进入目录 |
Space | 选择或取消文件 |
Enter | 确认上传 |
/ | 筛选当前目录 |
Ctrl+/ | 清除筛选并退出筛选模式 |
Ctrl+F | 编辑路径,支持 ~、$HOME 和环境变量 |
Ctrl+. | 显示/隐藏隐藏项 |
Esc | 关闭 |
附件管理器支持 Enter 预览、Shift+Enter 或双击用默认程序打开、dd 删除。当前 Host 内容协议只接受文本和图片;普通文件不会被伪装成可发送附件。
Kitty graphics 可用时,图片在文件选择器和附件预览中等比例显示;否则回退到 MIME、尺寸和文件大小信息。
Queue / Steering
模型运行时,Enter 的策略由 busyEnter 决定:
queue:加入下一回合队列;steer:追加到当前回合。
Ctrl+Y 切换策略,Ctrl+U 打开队列。队列面板使用 e 编辑、s steering、d 删除、Esc 关闭。
快捷键
以下是默认绑定。控制面板中的快捷键页以 MODE / KEY / FUNCTION 三列显示,并允许编辑用户覆盖;配置写入 $DSH_HOME/tui-config.json。
| 模式 | 按键 | 功能 |
|---|---|---|
| ALL | Ctrl+Space / F7 | 控制面板 |
| NORMAL | / | 筛选会话树;Ctrl+/ 退出 |
| NORMAL | Ctrl+F | 跨会话模糊定位 |
| NORMAL | Ctrl+B | 显示/隐藏侧栏 |
| NORMAL | Ctrl+M | 模型与思考强度 |
| NORMAL | F8 / F9 | 权限策略 / Agent 模式 |
| NORMAL | Ctrl+W | 工作区 |
| NORMAL | Ctrl+Shift+W | 添加工作区 |
| NORMAL | Ctrl+T | 轨迹视图 |
| NORMAL | Shift+Tab | 对话/轨迹切换 |
| NORMAL | Ctrl+E | 按 step 快速跳转 |
| NORMAL | Ctrl+J | 后台任务与 Subagent |
| NORMAL | Ctrl+U | 消息队列 |
| NORMAL | Ctrl+G | Goal / TODO |
| NORMAL | Ctrl+S | Settings |
| NORMAL | Ctrl+A | Subagent |
| NORMAL | Ctrl+K | Skills |
| ALL | Ctrl+Q | 退出 |
| NORMAL | t / b | 展开/折叠思考块 / 工具块 |
| NORMAL | g g / G | 对话顶部 / 底部 |
| NORMAL | [ / ] | 上一个 / 下一个提问终点 |
| NORMAL | PgUp / PgDn | 翻页;到顶时加载更早历史 |
快捷键目录中:Enter 编辑当前 JSON 配置项,Shift+Tab 在 NORMAL / INSERT / ALL 间轮换,Alt+Enter 恢复默认。保存前会校验 JSON、模式和按键字段;错误文本会保留以便继续修改。
Slash 命令
输入 / 后使用 Tab、↑、↓ 补全。TUI 本地命令包括:
| 命令 | 功能 |
|---|---|
/reload | 重新绘制并载入界面状态 |
/restart | 重启 TUI 并恢复会话 handoff |
/model | 模型选择 |
/theme | 切换主题 |
/permission | 权限选择 |
/goal | Goal 面板 |
Host 提供的 /compact、/export、/feedback、/plan 等命令会动态出现在命令页;实际清单以当前 Host 的 commands/list 为准。
面板与工具卡
TUI 支持:
- 工作区和分组会话树:新建、打开、重命名、移动、归档、删除和导出;
- terminal、read、search、web、diff 和 generic presentation;
run_code嵌套子调用树;- 工具审批、AskUser 单选/多选、Plan Review;
- Goal、TODO、后台任务和 Subagent;
- 独立插件清单及
/筛选; - dark、light、gruvbox 主题。
所有 Buffer 都是模态的:点击外部只会吞掉事件,不会关闭 Buffer。退出必须使用界面明确提示的按键或操作。
鼠标与终端能力
- 点击工作区、会话、标签、工具块和输入框;
- 拖动侧栏分隔线;
- 滚轮浏览对话、列表和弹窗;
- 输入框拖选并通过 OSC 52 复制;
- 右键消息、轨迹 step 和工作区树打开菜单;
- SGR mouse、bracketed paste、Kitty keyboard、OSC 8、OSC 52;
- ANSI truecolor 差量 framebuffer;
- CJK、组合字符和 ZWJ emoji 的 grapheme-aware 渲染。
不同终端、tmux 和 SSH 环境对 Kitty graphics、keyboard、OSC 52 的支持不同。WezTerm 和 Kitty 是图片预览的推荐终端。
配置
TUI 设置:
$DSH_HOME/tui-config.json
包含显示名、默认折叠状态、运行中 Enter 策略和快捷键覆盖。主题保存在:
$DSH_HOME/tui-theme.txt
DSH_TUI_USER_PREFIX 可覆盖默认用户名。
测试
npm test # 单元与协议测试
npm run test:pty # 真实 PTY 生命周期
npm run test:rc # 完整发布候选验证
PTY 测试会验证 alternate screen、SGR mouse、界面渲染、退出恢复和常见运行时错误。需要可用的 DSH Host;Host 不可用时测试会明确输出 SKIP。
脚本化 smoke:
node bin/dsh-tui.js --script test/smoke.script --plain
当前限制
- TUI 与 Host 必须使用兼容的事件、RPC 和内容块契约;
- 当前 Host 不支持通用二进制文件内容块,文件选择器只会发送图片;
- Kitty 图片效果受终端实现、cell 尺寸和复用器支持影响;
- 超长工具输出可能由 Host 截断,TUI 会显示工具提供的恢复位置;
- 快捷键覆盖配置已持久化并经过校验,部分旧 handler 仍使用内置 dispatch,后续版本会继续统一动态绑定。
代码结构
src/api.js HTTP RPC、WebSocket 和 respond
src/term.js raw mode、鼠标、paste、Kitty keyboard
src/screen.js cell framebuffer 与 ANSI diff
src/text.js grapheme、显示宽度和截断
src/md.js Markdown、代码块和 OSC 8
src/widgets.js Input、Popup、ScrollView、Menu、StatusBar
src/views.js App、ChatView、会话树和主路由
src/panels.js Workspace、Trajectory、Queue、Jobs、Settings
src/file-picker.js 三栏文件/目录选择器与图片预览
app/ DSH bundle 与 Cordis patch
许可证
MIT