| name | pty-bridge |
| description | Manage interactive terminal sessions (SSH, REPLs, databases, TUI apps) via the pty-bridge CLI. Use whenever the standard Bash tool can't handle a program that needs a real PTY — SSH logins, interactive REPLs (python, psql, mysql, node), commands that prompt for a password or confirmation, or TUI apps (vim, htop, less). Reach for this skill any time a command hangs, ignores piped input, or misbehaves under plain Bash. |
pty-bridge
pty-bridge is a CLI that manages interactive terminal sessions with full PTY support. Use it when the standard Bash tool can't handle interactive programs — SSH, REPLs, database CLIs, TUI apps, or any command that expects a real terminal.
Setup
If pty-bridge is not available, install it from GitHub:
npm i -g github:briqt/pty-bridge --install-links
Requirements: Node.js 18+. Supported on macOS, Linux, and Windows.
When to Use
- SSH into remote servers
- Interactive REPLs (python, node, irb, psql, mysql, etc.)
- Programs that prompt for passwords or confirmations
- TUI applications (htop, vim, less, etc.)
- Any command that hangs or misbehaves with the regular Bash tool
Commands
pty-bridge [--timeout <ms>] <command> [options]
pty-bridge start <command> [args...]
pty-bridge read <id> [--full] [--buffer <type>]
pty-bridge write <id> <input>
pty-bridge exec <id> <command> [--wait <ms>]
[--wait-for-idle <ms>]
pty-bridge sendkey <id> <key>
pty-bridge wait-for <id> <pattern> [--timeout <s>]
pty-bridge snapshot <id>
pty-bridge list
pty-bridge kill <id>
pty-bridge resize <id> <cols> <rows>
pty-bridge status
Global Options
pty-bridge --timeout 60000 exec <id> "slow-command"
Start Options
pty-bridge start ssh user@host --keepalive 30
pty-bridge start cmd --wait 1000
pty-bridge start cmd --cols 200 --rows 50
Read Options
pty-bridge read <id> --buffer normal
pty-bridge read <id> --buffer alternate
pty-bridge read <id> --buffer active
Exec Options
pty-bridge exec <id> "make build" --wait-for-idle 500
pty-bridge exec <id> "make build" --wait-for-idle 500 --wait 10000
Snapshot
pty-bridge snapshot <id>
Special Keys
enter, tab, escape, space, backspace, delete, up, down, left, right, home, end, pageup, pagedown, ctrl-a through ctrl-z, ctrl-\, ctrl-]
Workflow Patterns
SSH Session (recommended)
pty-bridge start ssh user@host --keepalive 30
pty-bridge read <id>
echo -n "password" | pty-bridge write <id> --stdin
pty-bridge sendkey <id> enter
pty-bridge read <id>
pty-bridge exec <id> "ls -la"
pty-bridge exec <id> "df -h"
pty-bridge exec <id> "apt update" --wait 5000
pty-bridge exec <id> "exit"
Wait for Service Startup
pty-bridge start ssh user@host --keepalive 30
pty-bridge exec <id> "docker compose up -d"
pty-bridge exec <id> "docker logs -f myservice" --wait 1000
pty-bridge wait-for <id> "Uvicorn running" --timeout 120
pty-bridge wait-for <id> "Started" --timeout 300
Interactive REPL
pty-bridge start python3
pty-bridge exec <id> "print('hello')"
pty-bridge exec <id> "2 + 2"
pty-bridge sendkey <id> ctrl-d
Handling Prompts
pty-bridge start some-installer
pty-bridge read <id>
pty-bridge write <id> "yes"
pty-bridge sendkey <id> enter
pty-bridge read <id>
Output Format Convention
- stdout: command output (the actual PTY content)
- stderr: metadata line in
[key=value ...] format, e.g. [lines=42 alive=true buffer=normal exitCode=0]
read returns output on stdout, session metadata on stderr — parse stderr for session state
exec returns command output on stdout — check isAlive and exitCode in the stderr line or JSON response
snapshot prints a header line [buffer=... cursor=... size=...] then the screen content
status output is human-readable text (parse with regex if needed)
Error Recovery
| Symptom | Cause | Action |
|---|
command not found: pty-bridge | Not installed | npm i -g github:briqt/pty-bridge --install-links |
connect ENOENT or socket timeout | Daemon died or not started | pty-bridge status; daemon auto-starts on next start |
| SSH password prompt | Interactive auth required | Use pty-bridge write <id> "password" --stdin then sendkey enter |
wait-for timeout | Pattern never appeared | Check the partial output returned; pattern may have a typo or the command failed silently |
Cannot find module @lydell/node-pty-… | No prebuilt binary for this platform | Supported: linux/darwin/win32 × x64/arm64. Reinstall with --install-links |
| PTY output is empty/garbled | TUI app in alternate screen | Use snapshot <id> instead of read; or read <id> --buffer alternate |
Important Notes
- Prefer
exec over write + sendkey enter — exec combines write, enter, wait, and read into one call, returning only the new output.
read is incremental by default — it returns only output since the last read. Use read <id> --full to get the entire buffer.
exec does NOT advance the read cursor — if you call exec then read, the read will include the same output that exec already returned. This is by design: exec is a self-contained operation that doesn't interfere with incremental read state.
- Use
wait-for for long operations — instead of sleep N && read, use wait-for <id> "pattern" --timeout N to block until specific output appears.
write sends text as-is — use sendkey enter afterward to submit (or just use exec).
- For secrets, pipe via stdin:
echo -n "password" | pty-bridge write <id> --stdin
- Always
kill sessions when done to free resources.
- The daemon auto-exits after 5 minutes when no alive sessions remain.
- Use
ctrl-c via sendkey to interrupt stuck commands.
- Terminal defaults to 120x40. Use
--cols/--rows on start or resize for TUI apps that need specific dimensions.
- Use
--timeout <ms> (global flag, before the command) to override the default 30s client socket timeout for slow operations.