前言¶
给智能体跑命令,最常见的做法是调一次 exec,把标准输出拿回来。这条路上有几个绕不开的问题:程序不会进入交互模式,npm run dev、python 这类需要 TTY 的东西跑不起来;长任务只能等结束,看不到过程;一旦遇到密码提示,密码明文进了对话上下文;人和模型也无法同时用同一个 shell。
本文介绍的插件 AyanamiiRei/agent-interactive-terminal 就是把终端做成一个有身份、有屏幕、有相位、有租约的资源。维护者是 AyanamiiRei,版本 0.6.9,MIT 协议,分类为客户端,星标还很少(目录页记为 2)。
这是什么¶
一句话:在 DeepSeek Harness 里提供有状态的 PTY 终端会话,模型读的是一份离散的屏幕快照,而不是一条字节流。
它打包了八个 terminal_* 工具、一块实时共享的 xterm 面板,以及不经过模型上下文的密码交接。仓库自述 73 个测试在 Linux 的 Node 20/22 上通过,设计细节见 docs/design.zh.md。
它不依赖任何智能体框架,TerminalRegistry、terminal_* 工具都可以单独拿到自己的运行时里用。
核心功能¶
屏幕快照,而不是字节流¶
模型读到的是渲染后的文本屏幕,附上相位和状态行。写是动作,等是查询,状态是事实,三者分开。屏幕只有一份,两种投影:给模型的是文本,给浏览器的是序列化 ANSI。
八个工具¶
| 工具 | 作用 |
|---|---|
terminal_open |
打开会话,返回 id、状态行和初始屏幕 |
terminal_send |
写入文本(默认回车提交),并等待结算 |
terminal_wait |
只等待,不写入 |
terminal_snapshot |
读取屏幕或输出尾部,可按版本号取增量 |
terminal_key |
按下具名按键,如 ctrl-c、enter、page-down |
terminal_resize |
调整终端尺寸 |
terminal_close |
关闭会话并清理进程树 |
terminal_list |
列出会话、相位、尺寸和目录 |
人和 agent 共用同一块屏幕¶
桌面端会话标题栏出现终端图标,点开后右侧是 xterm 面板,会话标签按当前顺序编号,中键关闭。键盘归属规则是:人敲键即接管,停手几秒自动交回;agent 的写入在这段时间排队,上边栏显示排队命令和取消按钮,交还后按顺序执行。
访问级别分三档:collaborate(协作)、observe(只读)、sealed(读写都断开,列表里只剩脱敏记录)。只读和断开都会拒绝排队,并返回不同的错误。授权在会话创建时给定,由服务端执行,不是前端丢按键。
密码不经过模型¶
遇到密码提示时,wait 返回 human_required 并挂起 agent,由人通过 session.write(secret, { origin: 'human' }) 回答,密码不进入模型上下文。仓库已实现密钥注入和审计。
另有工具策略开关:默认交互式优先,也可切换为一次性命令优先或强制交互式(后者会隐藏 agent 的 bash),还有“主动使用交互式终端”开关,让 REPL 任务先进入 python 等交互环境。
平台支持¶
优先使用 Unix shell(zsh/bash)。Linux 和 macOS 直接使用本机 zsh/bash,macOS 未设置 $SHELL 时默认 /bin/zsh。Windows 自动寻找 wsl.exe,可用时在 WSL 里启动 zsh(没装 zsh 就用 bash),并把生成的 rc 翻译成 WSL 路径;找不到 WSL 时退回 PowerShell 7、Windows PowerShell 或 cmd.exe。手动选 zsh/bash 但没有 WSL 会明确报错。原生 PowerShell/cmd 没有提示符标记,等待会退回屏幕内容和输出静默判断,精度不如 WSL。
主题、字体、光标、快捷键、回滚、响铃、复制粘贴、租约超时都在终端设置里,主题默认跟随 DSH,也可固定成某一套调色板。
安装与启用¶
需要 Node.js 20+ 和用于编译 node-pty 的 C++ 工具链。
在 DSH 的 Plugins → Discover 里添加市场索引:
https://raw.githubusercontent.com/AyanamiiRei/agent-interactive-terminal/main/plugin-market.json
搜索 agent-interactive-terminal 安装,或在 Add plugin 里直接填 Git 规格。首次安装要批准 node-pty 的构建脚本;升级到新版本后重启一次 DSH。
也可以手动构建:
git clone https://github.com/AyanamiiRei/agent-interactive-terminal.git
cd agent-interactive-terminal
npm install
npm run build
典型用法¶
仓库自带三个入口,适合先验证行为再接进 DSH。
npm run demo -- "git status" # 一条命令,看模型拿到的屏幕和状态行
npm run demo # 交互循环:/snap、/wait、/key、/resize、/quit
npm run attach # 浏览器 attach 示例,打开终端里打印的地址
在代码里直接用 TerminalRegistry:
import { TerminalRegistry } from 'agent-interactive-terminal'
const sessions = new TerminalRegistry({ maxSessions: 2 })
const session = await sessions.open({ name: 'build', cols: 100, rows: 30 })
await session.write('npm run dev')
const result = await session.wait({ match: ['ready in'], timeoutMs: 60_000 })
console.log(result.outcome, result.view.text)
session.takeOver()
await session.write('y', { origin: 'human' })
session.handBack()
await session.close()
也可以把 createTerminalTools(registry) 交给自己的模型运行时,不一定要跑在 DSH 里。
适用场景与注意¶
适合这几类需求:需要让 agent 驱动交互式程序(REPL、脚手架、交互式安装器);任务时长不确定、需要看过程而不是等结果;需要人和 agent 轮流操作同一个 shell;需要把密码这类敏感输入留在模型上下文之外。
几点要注意:
- 插件以当前 DSH 进程的权限运行,能读到什么、能执行什么就等于 DSH 的权限范围,安装前应通读仓库源码和许可证(MIT)。
- 首次安装要批准
node-pty构建脚本,属于原生模块编译,属于正常动作,但要自己确认过。 npm run attach的浏览器示例只绑定127.0.0.1、没有鉴权,仅供本地演示,不要暴露到网络上。- 仓库自述尚未实现:审计之外的打码区间、空闲会话回收、fish 集成,细节见
ROADMAP.md。
结尾¶
这套做法的价值在于把终端从“执行一条命令”升级成“会话级资源”:屏幕可读、按键可控、等待有条件、密码可隔离、人和 agent 能共享。仓库规模还小(目录页记为 2 颗星、版本 0.6.9),但覆盖的路径是完整的,先跑 npm run demo 就能确认是否符合你的流程。
- 目录页:https://www.skillhub.cn/plugins/AyanamiiRei/agent-interactive-terminal
- GitHub:https://github.com/AyanamiiRei/agent-interactive-terminal