mcpField
P
pty-bridge

pty-bridge

github.com/briqt开发365 次安装2 周前更新
代码仓库

关于 pty-bridge

pty-bridge 是用于管理交互式终端会话的命令行工具,提供完整 PTY 支持,适合需要真实终端的命令和程序。它支持会话输入、输出读取、命令执行及所有权控制,并可在 macOS、Linux 和 Windows 上使用。

主要功能

  1. 01启动和管理 PTY 会话
  2. 02增量或按范围读取终端输出
  3. 03发送文本和特殊按键
  4. 04运行命令并等待完成
  5. 05跟踪会话所有权

适用场景

  1. 01交互使用 SSH 会话
  2. 02操作 REPL 和数据库命令行工具
  3. 03处理密码提示和 TUI 应用
  4. 04监控命令及服务输出

MCP 相关

输入将 pty-bridge 描述为管理终端会话的命令行工具和技能,未说明 MCP 接口。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/briqt/pty-bridge --skill pty-bridge

安装后在 Claude Code 中输入/pty-bridge确认已加载。

详细介绍

pty-bridge

pty-bridge 是一个 CLI,可管理具备完整 PTY 支持的交互式终端会话。当标准 Bash 工具无法处理交互式程序时,请使用它,例如 SSH、REPL、数据库 CLI、TUI 应用,或任何需要真实终端的命令。

本手册要求使用 pty-bridge 1.5.0+。技能文件与 CLI 分别安装:

pty-bridge --version
pty-bridge doctor --json    # inspects an existing daemon; never starts one
npm i -g github:briqt/pty-bridge --install-links
npx skills add briqt/pty-bridge -g -y

doctor 会报告 CLI/Node 路径、原生 PTY 可用性、套接字以及正在运行的守护进程版本。安装新的 CLI 不会替换已有的守护进程或其会话。没有版本字段的旧版守护进程需要先停止运行,新的运行时功能才会生效。

设置

如果无法使用 pty-bridge,请从 GitHub 安装(而非 npm 注册表):

npm i -g github:briqt/pty-bridge --install-links

要求:Node.js 18+。支持 macOS、Linux 和 Windows。

适用场景

  • 通过 SSH 登录远程服务
  • 交互式 REPL(python、node、irb、psql、mysql 等)
  • 会提示输入密码或进行确认的程序
  • TUI 应用(htop、vim、less 等)
  • 任何使用常规 Bash 工具时会挂起或行为异常的命令

隔离(必需)

同一 OS 用户下的所有 Agent 共用一个守护进程。除非用户要求接管,否则绝不从 list 中选择会话。

  1. 为此对话设置一个稳定的所有者,并在每次会修改状态的调用中传入该所有者(工具调用可能使用新的 shell):
    export PTY_BRIDGE_OWNER="agent-$(uuidgen | cut -c1-8)"
    pty-bridge start ssh user@host --keepalive 30 --owner "$PTY_BRIDGE_OWNER" --json
    # Store sessionId and owner from the JSON response.
    pty-bridge exec <id> "pwd" --owner <stored-owner> --wait-exit
    
  2. 仅使用 start 返回的 sessionId(--json)或 Session: <id>。同时保存会话 ID 和所有者。
  3. 修改其他所有者的会话(write / exec / sendkey / kill / resize)会被拒绝。仅当用户明确要求接管时才使用 --force。
  4. list 会显示 owner=,方便你查看哪些会话属于自己。

命令

pty-bridge [--timeout <ms>] <command> [options]

pty-bridge start <command> [args...]                # Start a PTY session
pty-bridge read <id> [options]                      # Read output (see Read options)
pty-bridge write <id> <input>                       # Send input (or pipe via stdin)
pty-bridge exec <id> <command> [options]            # Execute command and return new output
pty-bridge sendkey <id> <key>                       # Send special key
pty-bridge wait-for <id> <pattern> [--timeout <s>]  # Block until pattern appears (default: 30s)
pty-bridge snapshot <id>                            # Capture current visible screen
pty-bridge list                                     # Active sessions + lost-session tombstones
pty-bridge kill <id>                                # Terminate a session
pty-bridge resize <id> <cols> <rows>                # Resize terminal (sends SIGWINCH to the child)
pty-bridge status                                   # Daemon PID, memory, lost sessions
全局选项
pty-bridge --timeout 60000 exec <id> "slow-command"   # Client RPC timeout in ms (must be BEFORE the subcommand)

使用 --rpc-timeout-ms 设置 RPC 时间预算(可放在子命令之前或之后);旧版 --timeout 仍可用,但 wait-for --timeout 表示秒。使用 exec --wait 设置命令等待时间预算。RPC 超时会自动延长至 max(30000, waitMs+5000)。 支持 read --help、exec --help 及其他子命令的帮助调用。

启动选项
pty-bridge start ssh user@host --keepalive 30 --owner "$PTY_BRIDGE_OWNER"
pty-bridge start cmd --wait 1000
pty-bridge start cmd --cols 200 --rows 50
读取选项

未知标志会报错(不会被忽略)。--full、--from、--from-exec 和 --last/--lines 不能同时使用。

pty-bridge read <id>                      # Incremental new output (advances cursor)
pty-bridge read <id> --full               # Entire rendered buffer (does not advance cursor)
pty-bridge read <id> --from 12:40          # Rendered line 12, UTF-8 byte column 40
pty-bridge read <id> --from 12            # From line 12 (resume cursor from exec metadata)
pty-bridge read <id> --from-exec          # From last exec start (after an RPC timeout)
pty-bridge read <id> --last 60            # Last 60 lines
pty-bridge read <id> --lines 60           # Alias of --last
pty-bridge read <id> --raw [--full]       # Unwrapped PTY bytes (no xterm line wrapping)
pty-bridge read <id> --max-bytes 100000   # Truncate; 0 = unlimited (default 256000)
pty-bridge read <id> --buffer normal      # normal | alternate | active (default)

snapshot 是当前的可见屏幕(cols×rows),而不是日志末尾。快照看起来为空通常表示屏幕已清除或处于替代屏幕模式——请使用 read --last 或 read --raw。

执行选项
pty-bridge exec <id> "ls -la"                                    # wait 200ms, then return output so far --owner "$PTY_BRIDGE_OWNER"
pty-bridge exec <id> "make build" --wait-for-idle 500            # poll until output idle (max 5s unless --wait) --owner "$PTY_BRIDGE_OWNER"
pty-bridge exec <id> "make build" --wait-exit --wait 120000      # shell only: wait until command exits --owner "$PTY_BRIDGE_OWNER"
pty-bridge exec <id> "dmesg" --max-bytes 100000 --owner "$PTY_BRIDGE_OWNER"

--wait-exit 会追加一个哨兵(cmd; echo PTYBRIDGE_DONE_<token>:$?)。仅在 shell(bash/ssh)中使用。不要在 python/mysql/vim 中使用。

Wait-for 选项
pty-bridge wait-for <id> "Uvicorn running" --timeout 120
pty-bridge wait-for <id> "Started" --from-now --timeout 60   # ignore history
pty-bridge wait-for <id> "Started" --from 0                  # full buffer (legacy)

默认搜索范围是最后 200 行加上新的输出,因此数小时前的旧 Started 不会匹配。

特殊按键

enter、tab、escape、space、backspace、delete、up、down、left、right、home、end、pageup、pagedown、ctrl-a 到 ctrl-z、ctrl-\、ctrl-]

工作流模式

SSH 会话(推荐)
export PTY_BRIDGE_OWNER="agent-<unique-conversation-id>"
# Retain this literal owner between tool calls, and pass it again each time.
pty-bridge start ssh user@host --keepalive 30 --owner "$PTY_BRIDGE_OWNER"
# If password / MFA prompt:
echo -n "password" | pty-bridge write <id> --stdin --owner "$PTY_BRIDGE_OWNER"
pty-bridge sendkey <id> enter --owner "$PTY_BRIDGE_OWNER"
pty-bridge read <id>
# Prefer --wait-exit for shell commands so you get done/failed + exitCode:
pty-bridge exec <id> "ls -la" --wait-exit --wait 15000 --owner "$PTY_BRIDGE_OWNER"
pty-bridge exec <id> "apt update" --wait-exit --wait 120000 --owner "$PTY_BRIDGE_OWNER"
pty-bridge exec <id> "exit" --wait-exit --wait 5000 --owner "$PTY_BRIDGE_OWNER"
等待服务启动
pty-bridge exec <id> "docker compose up -d" --wait-exit --wait 60000 --owner "$PTY_BRIDGE_OWNER"
pty-bridge exec <id> "docker logs -f myservice" --wait 1000 --owner "$PTY_BRIDGE_OWNER"
pty-bridge wait-for <id> "Uvicorn running" --from-now --timeout 120
交互式 REPL
pty-bridge start python3
pty-bridge exec <id> "print('hello')"          # no --wait-exit (not a shell) --owner "$PTY_BRIDGE_OWNER"
pty-bridge sendkey <id> ctrl-d

输出格式约定

  • stdout:PTY 内容
  • stderr:一行元数据 [key=value ...],例如 [status=still_running cursor=42 startCursor=10 alive=true truncated=false totalBytes=1200 returnedBytes=1200]
  • status 为 done、still_running 或 failed。still_running 不表示失败——命令已被接受。请勿重新发送。
  • cursor 是下一个 --from 值:渲染后的行或 line:byte-column;使用 --raw 时,它是绝对 UTF-8 字节偏移量,缓冲区淘汰后仍保持稳定。
  • 原始输出中的 lostBytes>0 表示较旧的输出已被淘汰;应报告缺失部分,而不是将输出视为完整。有限读取不会越过实际返回的字节。
  • 如果 truncated=true,请使用 read <id> --from <cursor>(或 --from-exec)继续读取。
  • list / status 可能会输出 Warning: daemon restarted at <iso>, N session(s) lost。这些 PTY 已不存在;远程 nohup 任务可能仍在运行。请重新登录;不要根据 list 猜测其他 Agent 的会话。

错误恢复

症状原因操作
command not found: pty-bridge尚未安装npm i -g github:briqt/pty-bridge --install-links
connect ENOENT 或守护进程启动错误守护进程已退出pty-bridge status;下次执行 start 时会重新启动。检查 list 中是否有 lost 墓碑记录。
Session not found + lost 警告守护进程重启并丢弃了内存中的会话重新执行 start。不要复用旧 ID。
Session ... is owned by所有者不匹配使用你自己的 ID;只有在被要求接管时才使用 --force
RPC 超时 / status=still_running等待时限或 RPC 限制已触发;命令已经发送不要再次执行。 使用 read <id> --from-exec 或 wait-for
SSH 密码提示交互式身份验证执行 write --stdin,然后执行 sendkey enter
wait-for 超时最近 200 行及新增输出中都没有匹配内容使用 --from-now / --from 0;检查返回的输出
Cannot find module @lydell/node-pty-…没有预编译二进制文件linux/darwin/win32 × x64/arm64。使用 --install-links 重新安装
输出被换行(S\nYS)xterm 按当前列数渲染使用 read --raw(如果需要保持远程 TTY 不变,请勿执行 resize)
未知选项拼写错误 / 不支持的标志不会忽略标志;请修正标志名称

重要说明

  1. 在 Shell 中,优先使用 --wait-exit,不要猜测 --wait。对于 REPL/TUI,请使用不带 --wait-exit 的 exec / write。
  2. 默认情况下,read 是增量读取。--full / --from / --last 不会推进增量游标。
  3. exec 不会推进 read 游标。
  4. 超时 ≠ 失败。由于 still_running 或 RPC 超时,绝不要重新发送 exec。
  5. write 会原样发送文本——之后使用 sendkey enter(或 exec / --wait-exit)。
  6. 密钥:echo -n "password" | pty-bridge write <id> --stdin --owner "$PTY_BRIDGE_OWNER"
  7. 完成后,请终止自己的会话。没有存活会话时,守护进程会在 5 分钟后自动退出(正常退出会清除墓碑记录)。
  8. 通过 sendkey 发送 ctrl-c 可中断卡住的命令。
  9. 终端默认尺寸为 120x40。resize 会更改子进程的 TTY 尺寸。
  10. 优先使用 --rpc-timeout-ms,以区分 RPC 超时(毫秒)与 wait-for --timeout(秒)。
  11. 默认的 read/exec 负载上限为 256000 字节;元数据会告知是否还有更多内容。

机器可读会话与筛选

pty-bridge start bash --owner <conversation-owner> --json
pty-bridge list --owner <conversation-owner> --alive-only --json
pty-bridge exec <id> "pwd" --owner <conversation-owner> --wait-exit
pty-bridge kill <id> --owner <conversation-owner>

筛选后的列表并不授权你接管任何会话。请保留自己执行 start 时响应中的 ID 和所有者。 snapshot 会显示屏幕;要查看日志末尾,请使用 read --last 30。 对于脚本、大型导出或通过 SSH 传输文件,优先使用文件/SFTP 通道,而不是通过 PTY 传输 base64。RPC 超时意味着已提交的命令可能仍在运行:应通过读取继续查看,而不要再次提交命令。

评论

支持 Markdown