pty-bridge について
pty-bridgeは、完全なPTYサポートを備えた対話型ターミナルセッション管理用コマンドラインツールです。実端末を必要とするコマンドを扱うユーザーやエージェント向けで、macOS、Linux、Windowsに対応し、入力、出力取得、コマンド実行、所有権管理を行えます。
主な機能
- 01PTYセッションの開始と管理
- 02端末出力の差分・範囲読み取り
- 03テキストと特殊キーの送信
- 04コマンド実行と終了待ち
- 05セッション所有権の追跡
活用シーン
- 01SSHセッションの操作
- 02REPLやデータベースCLIの利用
- 03パスワード入力やTUIアプリの操作
- 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 は、完全な PTY サポートで対話型ターミナルセッションを管理する CLI です。標準の 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 ユーザーのすべてのエージェントが、1 つのデーモンを共有します。ユーザーから引き継ぎを依頼されていない限り、list からセッションを選ばないでください。
- この会話で使用する安定した owner を設定し、すべての変更を伴う呼び出しで渡します(ツール呼び出しでは新しいシェルが使われる場合があります)。
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 startが返したsessionId(--json)またはSession: <id>のみを使用します。ID と owner の両方を保存してください。- 別の owner のセッションを変更する操作(
write/exec/sendkey/kill/resize)は拒否されます。--forceは、ユーザーが明示的に引き継ぎを希望した場合にのみ使用してください。 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 の制限時間には --rpc-timeout-ms を使用します(サブコマンドの前後どちらでも指定できます)。従来の --timeout も引き続き使用できますが、wait-for --timeout の単位は秒です。コマンドの待機時間には exec --wait を使用します。RPC タイムアウトは max(30000, waitMs+5000) まで自動的に延長されます。
read --help、exec --help などのサブコマンドのヘルプ呼び出しもサポートされています。
Start オプション
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
Read オプション
不明なフラグを指定するとエラーになります(無視されません)。--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 を使用してください。
Exec オプション
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>:$?)を追加します。シェル(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:メタデータを示す1行
[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 バイトオフセットです。- Raw の
lostBytes>0は、古い出力が削除されたことを示します。出力がすべてそろっていると見なさず、欠落部分を報告してください。上限付きの読み取りで進むのは、実際に返されたバイト分までです。 truncated=trueの場合は、read <id> --from <cursor>(または--from-exec)で続きを取得してください。list/statusは、Warning: daemon restarted at <iso>, N session(s) lostを出力する場合があります。その場合、該当する PTY は失われています。リモートのnohupジョブは実行中のままかもしれません。再ログインし、listから別のエージェントのセッションを推測しないでください。
エラーからの復旧
| 症状 | 原因 | 対処 |
|---|---|---|
command not found: pty-bridge | インストールされていません | npm i -g github:briqt/pty-bridge --install-links |
connect ENOENT またはデーモン起動エラー | デーモンが停止しました | pty-bridge status を実行してください。次の start で再起動します。list で lost の tombstone を確認してください。 |
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 を実行しないでください) |
| 不明なオプション | タイプミスまたは未対応のフラグです | フラグは無視されません。フラグ名を修正してください |
重要な注意事項
- シェルでは、
--waitの値を推測するより--wait-exitを優先してください。REPL/TUI では、--wait-exitを付けずにexec/writeを使用してください。 readはデフォルトで差分を読み取ります。--full/--from/--lastは差分読み取り用カーソルを進めません。execはreadのカーソルを進めません。- タイムアウトは失敗を意味しません。
still_runningまたは RPC タイムアウトを理由にexecを再送信しないでください。 writeはテキストをそのまま送信します。後からsendkey enterを実行してください(またはexec/--wait-exitを使用してください)。- シークレット:
echo -n "password" | pty-bridge write <id> --stdin --owner "$PTY_BRIDGE_OWNER" - 完了したら自分のセッションを
killしてください。稼働中のセッションがない状態が5分続くとデーモンは自動終了します(正常終了時に tombstone は消去されます)。 sendkeyでctrl-cを送信すると、応答しなくなったコマンドを中断できます。- ターミナルのデフォルトサイズは120x40です。
resizeを実行すると、子プロセスの TTY サイズが変更されます。 - RPC のミリ秒と
wait-for --timeoutの秒を区別するには、--rpc-timeout-msを優先してください。 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 経由のファイル転送には、PTY での base64 よりファイル/SFTP チャネルを優先してください。RPC タイムアウトが発生しても、送信済みのコマンドは実行中の可能性があります。再送信せず、読み取りを再開してください。