API 参考
JSON-RPC 2.0 协议
socket 上每行一条 JSON-RPC 2.0 报文,以 \n 分帧。所有请求必须带 id(不支持通知),params 必须是对象。
method 一览
| method | params | result(成功) |
|---|---|---|
pty/read | { top? | bottom? | start?+end? } | { screen, cursor, size } |
pty/write | { action } | { written } |
pty/wait | { match?, timeout? } | { matched, screen, cursor, size, waitedMs } |
pty/status | {} | { running, exitCode, pid } |
pty/resize | { cols, rows } | {} |
pty/kill | {} | {} |
pty/status — 查询会话状态
jsonc
→ {"jsonrpc":"2.0","method":"pty/status","params":{},"id":1}
← {"jsonrpc":"2.0","result":{"running":true,"exitCode":null,"pid":1234},"id":1}running:boolean,会话是否运行中。exitCode:number | null,已退出时为退出码,否则为null。pid:number,被托管进程的 pid。
pty/read — 读取当前屏幕
jsonc
→ {"jsonrpc":"2.0","method":"pty/read","params":{},"id":2}
← {"jsonrpc":"2.0","result":{"screen":"root@host:~$\n","cursor":{"row":1,"col":14},"size":{"cols":100,"rows":30}},"id":2}screen:string,当前终端屏幕的纯文本(已去 ANSI 控制序列,每行尾部空格被去除,多行以\n分隔)。语义为终端当前真实画面,非历史日志。cursor:object,光标位置,row/col为 1-based。size:object,终端尺寸{ cols, rows }。
pty/read 支持截取当前屏的部分行。top/bottom 与 start+end 为互斥的两组:
jsonc
→ {"jsonrpc":"2.0","method":"pty/read","params":{"top":3},"id":3}
→ {"jsonrpc":"2.0","method":"pty/read","params":{"bottom":3},"id":4}
→ {"jsonrpc":"2.0","method":"pty/read","params":{"start":2,"end":5},"id":5}top: N— 取顶部 N 行。bottom: N— 取底部 N 行。start/end— 取 1-based 闭区间[start, end],必须成对给出。- 校验:
top/bottom互斥;start/end必须成对;两组不能混用;越界自动 clamp。
pty/write — 写入数据
action 为单个动作对象或动作数组:
jsonc
→ {"jsonrpc":"2.0","method":"pty/write","params":{"action":{"text":"echo hello"}},"id":6}
← {"jsonrpc":"2.0","result":{"written":11},"id":6}
→ {"jsonrpc":"2.0","method":"pty/write","params":{"action":{"key":"Enter"}},"id":7}
← {"jsonrpc":"2.0","result":{"written":1},"id":7}
→ {"jsonrpc":"2.0","method":"pty/write","params":{"action":[{"text":"ls"},{"key":"Enter"}]},"id":8}
← {"jsonrpc":"2.0","result":{"written":5},"id":8}action内text与key二选一,不能同时给出;空对象、空数组被拒绝。written:number,实际写入的 UTF-8 字节数(数组动作返回合计)。
write 支持的键名(action.key,区分大小写):
| 类别 | 键名 |
|---|---|
| 方向 | ArrowUp ArrowDown ArrowLeft ArrowRight |
| 编辑 | Enter Tab Backspace Delete Home End PageUp PageDown Insert Escape Space |
| 功能 | F1 … F12 |
| 组合 | Ctrl+字母(Ctrl+A…Ctrl+Z)、Shift+字母、Alt+字母、Alt+Enter、Ctrl+Enter、Ctrl+Space 等,可组合修饰符(如 Ctrl+Alt+Del) |
单字符文本可直接用 text 字段;key 无法解析时返回 -32602 无效参数错误。
pty/wait — 等待某段输出出现
jsonc
→ {"jsonrpc":"2.0","method":"pty/wait","params":{"match":"hello","timeout":6000},"id":9}
← {"jsonrpc":"2.0","result":{"matched":true,"screen":"hello\n","cursor":{"row":2,"col":1},"size":{"cols":100,"rows":30},"waitedMs":45},"id":9}- 在当前屏幕中按子串匹配
match;未给match时只按timeout等待一段固定时长。 timeout:最大等待毫秒,默认10000。matched:boolean,是否在超时前匹配到。screen:匹配时或超时时的当前屏幕。waitedMs:实际耗时(毫秒)。
pty/resize — 调整终端尺寸
jsonc
→ {"jsonrpc":"2.0","method":"pty/resize","params":{"cols":120,"rows":40},"id":11}
← {"jsonrpc":"2.0","result":{},"id":11}pty/kill — 终止会话并关闭端点
jsonc
→ {"jsonrpc":"2.0","method":"pty/kill","params":{},"id":12}
← {"jsonrpc":"2.0","result":{},"id":12}发起 pty/kill 后,会话被终止、端点关闭、服务进程退出,当前连接被服务端关闭。
错误响应
jsonc
→ {"jsonrpc":"2.0","method":"pty/unknown","params":{},"id":13}
← {"jsonrpc":"2.0","error":{"code":-32601,"message":"Method not found: pty/unknown"},"id":13}
→ {"jsonrpc":"2.0","method":"pty/write","params":{"action":{"text":"x","key":"Enter"}},"id":14}
← {"jsonrpc":"2.0","error":{"code":-32602,"message":"write 动作内 text 与 key 只能二选一"},"id":14}- 错误对象形如
{ code, message, data? },code/message见下表。 - 正常请求的响应回显请求的
id;无法解析的报文(连id都取不到)返回id: null。
错误码
| code | 含义 |
|---|---|
-32700 | 解析错误(非法 JSON) |
-32600 | 无效请求(结构不合法 / 旧 {op} 协议被拒绝 / 缺 id) |
-32601 | 方法不存在 |
-32602 | 无效参数(如 text/key 互斥、top/bottom 互斥、未知键名) |
-32603 | 内部错误 |
-32000 | 服务端错误 |
程序化 API(TypeScript)
createSocketPty
typescript
import { createSocketPty } from "@ai-zen/socket-pty";
const server = createSocketPty({
endpoint: { type: "unix", path: "/tmp/v.sock" }, // 或 { type:"tcp", port:5174, host:"127.0.0.1" }
command: "bash", // Windows 上请用 "powershell.exe" / "cmd.exe"
cols: 100,
rows: 30,
cwd: "/path/to/workdir", // 可选
});
const address = await server.listen();endpoint 必填,地址由调用方指定。
PtyServer 实例方法
| 方法 | 说明 |
|---|---|
listen(): Promise<string> | 监听端点并创建会话,返回连接地址 |
address(): string | 实际监听地址 |
session(): IPtySession | null | 当前会话 |
close({ kill? }): Promise<void> | 关闭端点(kill: true 时终止会话),幂等 |
会话对象方法
回调 server.session 返回 IPtySession,提供同步读屏等能力:
typescript
const session = server.session;
await session?.readScreen(); // 整屏
await session?.readScreen({ bottom: 5 }); // 底部 5 行
await session?.readScreen({ start: 2, end: 6 }); // 第 2..6 行| 方法 / 属性 | 说明 |
|---|---|
readScreen(sel?) | 读当前屏幕,返回 { screen, cursor, size } |
wait(opts) | 等待输出,返回 { matched, screen, cursor, size, waitedMs } |
write(data): number | 写原始数据,返回 UTF-8 字节数 |
resize(cols, rows) | 调整尺寸 |
kill(signal?) | 终止 |
pid / running / exitCode | 进程信息 |
主入口导出的类型与协议
主入口 @ai-zen/socket-pty 还导出以下内容(供脚本端到端测试与协议构造复用):
- 类型:
IPtyLike、IPtySession、ReadResult、ScreenSelection、TermCursor、TermSize、WaitResult、PtyServerOptions、SocketEndpoint、PtySessionOptions、XtermScreenOptions、XtermTerminal。 - 协议常量/工具:
JsonRpcErrorCode、JsonRpcErrorMessage、Methods、JSONRPC、makeRequest、makeResult、makeError、parseRequest、encodeRequest、resolveKey、resolveAction、methodToOp。 - 渲染器:
XtermRenderer、createRenderer。
CLI 选项(socket-pty serve)
| 选项 | 说明 |
|---|---|
--cmd <命令> | 要托管的命令(必填)。Windows 上需带 .exe 后缀,如 powershell.exe / cmd.exe |
--socket <路径> | Unix domain socket 监听路径(与 --port 二选一,必给其一) |
--port <端口> | TCP 监听端口,1-65535 的具体端口(与 --socket 二选一,必给其一) |
--cols <n> | 终端列数(默认 100) |
--rows <n> | 终端行数(默认 30) |
--cwd <路径> | 工作目录 |
-h / --help | 帮助 |
--socket 与 --port 二选一,不能同时给出;两者都不给、或 --port 不是 1-65535 的具体端口时,serve 报错退出。
CLI 另提供 socket-pty mcp 子命令,用于启动 MCP 管理器(见 MCP 适配)。