mcpField
T
tty7

tty7

github.com/l0ng-ai開発1.4k114 回インストール1 日前に更新
リポジトリ

tty7 について

tty7 は tty7 サーバーを操作する非対話型コマンドラインクライアントです。ターミナルのペイン管理やコーディングエージェントへの作業委任に使え、コマンド実行、ペイン操作、状態待機に対応します。

主な機能

  1. 01同期・バックグラウンドのコマンド実行
  2. 02ペインへのテキストやキー送信
  3. 03ペイン内容の取得と表示
  4. 04コマンドやエージェントの状態待機
  5. 05プロセス、ポート、サーバー状態の確認

活用シーン

  1. 01表示中のペインで開発サーバーを起動
  2. 02REPL、SSH、デバッガーの操作
  3. 03他のペインのプロセスや出力を確認
  4. 04コーディングエージェントへの作業委任

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/l0ng-ai/tty7 --skill tty7

インストール後、Claude Code で/tty7を入力して読み込まれたか確認します。

同梱ファイルreferences/commands.mdreferences/delegation.md

詳細

コマンドラインから tty7 を操作する

tty7 は、tty7 サーバーの薄い非対話型クライアントです。すべての動詞は結果を返して終了します。--json を指定すると、出力が機械可読になります。GUI を起動しておく必要はありません。ペインを管理しているのはサーバーです。

まず、自分がいる場所を確認しましょう

tty7 doctor

1 つの表で、ほかの操作を始める前に必要な情報をすべて確認できます。サーバーに接続できるか、方言が一致しているか、各エージェントのステータスフックがインストールされているか、そして TTY7_CONFIG_DIR/TTY7_WS/TTY7_PANE が設定されているか、つまり tty7 のペイン内で実行しているかどうかです。

ペイン内にいるかどうかは、2 つの理由で重要です。アドレスを取る動詞(split、send、exec、capture、procs、wait、pane close)は、既定で $TTY7_PANE を使います。また、run --keep はそのペインを $TTY7_WS に格納します。tty7 シェルの外では、明示的にターゲットを指定する必要があります。推測するのではなく、その旨をエラーで知らせます。

フックの行は、別のエージェントに作業を委任する予定なら重要です。フックがないとエージェントはステータスを報告しないため、そのエージェントに対する tty7 wait はタイムアウトするだけです。

tty7 doctor でサーバーに接続できないと表示された場合は、そこで止めてユーザーに伝えてください。自分の判断で tty7 server start を実行してはいけません。依頼されていないサーバーを起動すると、ユーザーの GUI が接続する先が変わります。

ここでは何をしますか?

4 つの作業に、それぞれ異なる形があります。

  1. 自分の作業を妨げるべきでない処理や、実際の TTY が必要な処理を実行する — 開発サーバー、長時間のテスト実行、TUI などです。コマンドの実行を参照してください。
  2. 時間をかけて状態を保つものとやり取りする — REPL、ssh、デバッガーなどです。同じ基本操作を使います。送信、読み取り、繰り返し。
  3. このマシン上で何が起きているか確認する — ほかのペイン、ほかのエージェント、ポートなどです。周囲を確認する操作は読み取り専用です。
  4. 別のコーディングエージェントに作業を任せる — 1 人のワーカー、または複数への一斉委任です。まず references/delegation.md を読み、概要は以下を参照してください。

起動して、作業を行い、ターミナルや見ている人を必要とせずに終了する処理には、引き続き Bash ツールが適しています。プロセスが自分のターンを越えて動き続ける場合、実際の PTY が必要な場合、またはユーザーが tty7 ウィンドウで見られるようにする場合に、ペインを使う価値があります。最後のケースが、ペインを使う主な目的であることもよくあります。

アドレス

形式意味安定性
%42ペインはい — ペインは存続中ずっと同じ ID を保持します
@7マシン全体をツリー順に番号付けしたタブいいえ — ワークスペースやタブが追加または削除されるたびに変わります
@<full tab UUID>ID で指定した同じタブはい
api/76698a44/完全な UUID名前、固有の ID プレフィックス、または ID で指定したワークスペースはい

@N を使う直前に必ず解決し直してください。タブを作成または削除する手順をまたいでキャッシュしてはいけません。ペイン ID、タブ ID、ワークスペース ID は安全に記憶できます。タブを作成したあとで再び指定するつもりなら、@N をもう一度数えるのではなく、tty7 tab new --json が返す ID を使ってください。

アドレスが必要な場所では、記号は省略できます。%42 と 42 は同じペインを、@7 と 7 は同じタブを指します。--json からコピーした ID は、そのまま貼り付けて使えます。

tty7 シェル内でアドレスを省略すると、「このペイン」/「このワークスペース」を意味します。明示的なアドレスは常に環境変数より優先されます。

コマンドの実行:3 つの形式

ブロッキング実行、実際の終了コードを取得
tty7 run -- cargo test          # streams to your stdout, exits with cargo's code
tty7 run --cwd /path -- make
tty7 run --keep -- cargo build  # leaves the pane as a new tab afterwards

コマンドの出力は発生と同時に標準出力へストリーミングされ、tty7 はコマンド自身の終了コードで終了します。Bash 呼び出しに最も近い方法で、違いは PTY を使うことと、ユーザーがその実行を見られることです。

知っておくべき点が 3 つあります。--keep にはワークスペースが必要なので、tty7 シェル内、または --ws <workspace> を指定した場合にのみ使えます。--json を使うと、ストリーミング出力の後に JSON オブジェクトが出力されます。結合されたストリームは JSON として解析できないため、最後の行を読んでください。また、ペインの幅は 120 列で変更できないため、より広いターミナルを前提とした出力は折り返されます。

すでにあるペインでブロッキング実行
tty7 exec "$PANE" --timeout 900 -- cargo test   # prints its output, exits with its code

exec はペインのシェルプロンプトにコマンドを入力します。そのペインの作業ディレクトリ、環境、履歴を使い、プロンプトが戻るまで待機して、コマンドの出力をテキストとして表示し(capture --plain と同様です。エスケープシーケンスを保持するには --raw を使います)、コマンド自身の終了コードで終了します。これは、先に設定したペイン(cd した状態、有効化済みの venv、遠端で tty7 のシェル統合が有効な ssh セッションなど)で次のコマンドを実行するための方法です。送信/待機/キャプチャ/推測を繰り返す必要はありません。

必要な条件と、満たされない場合に表示される内容は次のとおりです。ペインのシェルで tty7 のシェル統合が有効になっている必要があります(プロンプトマークを一度も送信したことのないペインでは拒否されます)。また、ペインがプロンプトで待機中である必要があります(処理中の場合は拒否されます。先に wait --until free を実行してください)。-- の後の文字列は1行のシェルコマンドになるため、引用符で囲めば &&、パイプ、リダイレクトを使えます。例:tty7 exec %3 -- 'make && ./run'。誰も見守っていない場合は、必ず --timeout を指定してください。シェルが実行しないコマンド(dquote> で待機する閉じていない引用符など)には、待機の終わりがありません。タイムアウトすると終了コード 124 で終了し、コマンドは実行中のままになります。

ノンブロッキング:時間を置いてやり取りするペイン

これこそ、tty7 を使いたくなる機能です。ペインを取得し、作業を送信して、後で戻ってきます。

PANE=$(tty7 split --v)                  # or --h; splits $TTY7_PANE, prints "%83"
tty7 send "$PANE" 'npm run dev' --enter

split は新しいペインのアドレスを標準出力に表示します。これは変数に取り込んで使います。軸を指定しないと使用方法エラーになります。--v は新しいペインを下に配置し、--h は右に配置します。

$TTY7_PANE を分割すると、ユーザーから見えるレイアウトが変わります。通常はそれが目的です。ユーザーは起動した開発サーバーを確認できます。分割したことを伝え、使い終わったらペインを閉じてください。

tty7 ペイン内にいない場合は分割対象がないため、まず作業場所を自分で作成してください。tty7 new --json /path/to/repo を使うと、両方の ID を一度に取得できます。ペインを探すために ws tree を調べる必要はありません。

read -r WS PANE < <(tty7 new --json /path/to/repo \
  | python3 -c 'import json,sys; d=json.load(sys.stdin); print(d["id"], "%%%d" % d["pane"])')

send はキーボード入力と同じように、テキストをペインに入力します。--enter はキャリッジリターンを追加します。テキストを指定しない場合は Enter を押します(tty7 send "$PANE" --enter は、すでに入力されている内容を実行します)。send は待機せず、何が起きたかも通知しません。読み取りは別の手順で行い、待機には tty7 wait を使います。

文字ではなくキー入力(Ctrl-C、Escape、矢印キーなど)を送るには --key を使います。指定できるキーは enter escape tab backtab space backspace delete up down right left home end pageup pagedown と、Ctrl 用の C-<char>、Alt 用の M-<char> です。キー入力の列は --key を繰り返して指定します。テキストとキー入力を組み合わせる場合は、テキストが先になります。^C をテキストとして入力しても何も起きません。2文字として届くためです。実際に割り込みを送るには --key C-c を使います。

コマンドラインからのテキスト入力ではできないことが2つあります。シークレット:tty7 send %3 "$TOKEN" を使うと、トークンがすべてのローカルユーザーの ps とシェル履歴に残ります。代わりにパイプで渡してください。printf %s "$TOKEN" | tty7 send %3 --stdin --enter(または --from-file PATH)を使います。バイト列は読み取ったとおりにペインへ送信され、--json にもエコーされません。遠端でのエコーはプログラム側の処理です。docker login --password-stdin、ssh-add、gpg はそれぞれエコーを無効にします。複数行のテキスト:pty では改行は Enter として扱われるため、各行は届くたびに実行されます。--paste はウィンドウに貼り付ける場合と同じ方法で送信します。ペインで有効になっていれば、ブラケット付きペーストとして囲むため、シェルやエージェントの入力欄はブロック全体をテキストとして受け取ります。--json には "bracketed" が報告されるので、どちらの方法で受け取られたか確認できます。

新しく作成したペインでは、Enter が無視されることがあります。 シェルが起動ファイル(プロンプトフレームワーク、fastfetch、ログイン時に画面へ何かを描画するものなど)の処理中だと、送信したテキストは受け取られても、その後のキャリッジリターンが失われることがあります。その結果、コマンドはプロンプト行に入力されたまま実行されません。このことは何も通知されません。send は成功し、ペインはまだ作業を開始していないように見えます。そのため、作成したばかりのペインに最初のコマンドを送信したら、画面を読み戻し、プロンプトから実際に進んだことを確認してください。

tty7 capture "$PANE" --plain | tail -3   # command still sitting on the prompt?
tty7 send "$PANE" --enter                # then give it the Enter it lost

後から原因を調べるより簡単です。確認が必要なのは、新しいペインへの最初の send だけです。

ペインを読む

画面を見たい場合は、--plain を使います
tty7 capture %83 --plain

capture はデーモンが保存した内容、つまりペインのバイト列をエスケープシーケンスも含めて返します。一方、--plain はそれをターミナルグリッドで再生し、結果のテキストを出力します。単にエスケープシーケンスを除去するだけではありません。色やカーソルのエスケープシーケンスが消えるだけでなく、ペイン幅に合わせてシェルが折り返した行は1行に戻り、\r で書き換えられるプログレスバーは最終値が表示され、TUI の画面は描画されたとおりに表示されます。人が出力を読む場合は、いつでもこちらを使ってください。

どちらの方法でも、返される内容について2つ知っておくべき点があります。capture が返すのはストリームではなくスナップショットです。新しい内容を取得するには、もう一度呼び出してください。また、デフォルトでは最新のスクロールバックセグメントが出力されます(リサイズ時にリングが分割されます)。--scrollback を指定するとリング全体が出力されます。リサイズされていないペインでは、これは最新のセグメントと同じ内容です。

結果が必要な場合は、ファイルにリダイレクトします

--plain が返すのは画面であり、画面は長方形です。長いビルドログで上部にスクロールして消えた内容は失われ、終了コードも画面には表示されません。ペインがプロンプトで待機しているシェルの場合は、前述の tty7 exec で両方を取得できます。それ以外、つまりペインが処理中の場合や、シェルに tty7 の連携機能がない場合は、シェルに結果を分かりやすい場所へ書き出させます。

tty7 send "$PANE" 'cargo test > /tmp/t.log 2>&1; echo $? > /tmp/t.rc' --enter
# ...wait for it to finish (below), then:
cat /tmp/t.rc /tmp/t.log

出力全体を取得でき、終了コードも正確で、途中にターミナルを挟みません。

コマンドの終了を確認する

画面をポーリングしたり、自分でループを書いたりせず、終了するまで待機します。

tty7 wait "$PANE" --until free --changed --timeout 900

free は、フォアグラウンドコマンドが終了し、ペインが何も実行していないシェルに戻ったことを意味します。--changed を付けると、「待機中に何かが実際に実行された」という条件も追加されます。これは send の直後の行で必要な条件です。これを付けないと、まだ開始していないコマンドでも、ペインが終了済みのように見えてしまいます。

最初から最後までの流れは次のとおりです。

tty7 send "$PANE" 'cargo test > /tmp/t.log 2>&1; echo $? > /tmp/t.rc' --enter
tty7 wait "$PANE" --until free --changed --timeout 900
cat /tmp/t.rc /tmp/t.log
tty7 pane close "$PANE"

終了コードはこの用途に合わせてあります。0 は指定した状態に到達したこと、124 はタイムアウトしたこと(timeout(1) の慣例に従っているため、「まだ」が「失敗」と区別できます)、1 はペインが先に終了したことを意味します。

--changed には注意点があります。デフォルトの500ミリ秒の間隔で1回ポーリングするうちにコマンドが終了すると、実行中の状態が一度も観測されないため、タイムアウトするまで待機し続けます。このようにすぐ終了するコマンドには、--interval 100 を指定するか、--changed を外して .rc ファイルを確認してください。この状況が起きると、タイムアウトメッセージにその旨が表示されます。

プロセスツリーそのもの、「そこで何が実行されているか」「このペインがどのポートを提供しているか」を確認したい場合は、tty7 procs %83 を使います。深さに応じてインデントされ、フォアグラウンドプロセスには * が付き、その後にプロセスがリッスンしているポートが表示されます。ただし、コーディングエージェントの状態を確認する方法としては適していません。エージェントが処理中のペインでも、procs は nothing running in this pane と報告するため、これを「ワーカーが停止した」と解釈するのは誤りです。エージェントについては tty7 agents で確認してください。

別のエージェントに作業を引き継ぐ

ペインには別のコーディングエージェントを置くことができ、上記のすべてのプリミティブに加え、エージェントだけが使える機能もあります。ステータスフックが working / waiting / done を報告するため、tty7 wait はプロセスツリーではなく、エージェント の完了を待つことができます。

委任には手順があります — references/delegation.md を参照してください。 ワーカーを起動する前に読んでください。ワーカー専用の git ワークツリーとワークスペースの用意、プロンプトでの納品条件を含むタスクの引き継ぎ、コマンドが実際に起動したことの確認、状態の見守り、git からの結果の収集、複数ワーカーへの作業の分散、後片付けまで、一連の流れを網羅しています。

これだけは覚えておいてください。ほかを読まなくても、次の 4 つのルールは守りましょう。

  • 対話モードを使い、-p は使わないでください。 claude -p では TUI が表示されません。ペインは空白のままで、capture --plain は何も返さず、ユーザーには空の領域が表示され、セッションは 1 ターンで終了するため、追加の指示も出せません。タスクは対話型コマンドの引数として渡してください。
  • ファイルを書き込むワーカーには、専用の git ワークツリーを用意してください。 1 つのチェックアウトで 2 つのエージェントを動かすと、互いの変更やユーザーの作業ツリーを壊してしまいます。
  • 画面ではなく git から結果を収集してください。 ワーカーにコミットするよう伝え、差分を確認してください。画面には表示できる範囲があり、上部は消えてしまいます。
  • 新しいペインに最初の入力を送った後、コマンドがプロンプトから抜けたことを確認してください — 上記の Enter が無視されていないか確認します。

状況を確認する

tty7 ls                    # every workspace: tabs, panes, who's attached
tty7 ws tree api           # one workspace as a tree — tabs, splits, panes, cwds
tty7 pane ls               # panes with their workspace, tab, cwd, live flag
tty7 pane ls --all         # + orphans: panes the server runs that no workspace holds
tty7 agents                # every coding agent on the machine and its status
tty7 status                # server pid, uptime, pane count, build, socket
tty7 machine ls            # this machine plus any linked remotes
tty7 events                # stream server events, one per line, until interrupted

tty7 agents は知っておくと便利です。認識されたコーディングエージェントを実行中の各ペインについて、エージェント自身のメッセージとともに、idle / working / waiting / done のいずれかを報告します。自分がその一員なら、自分も一覧に含まれます。また、ステータスフックが見つからない、または古くなっているエージェントを検知すると、診断情報(JSON の diagnostics)も出力します。これは、エージェントがフリーズしているように見える場合の原因を示します。

これらのコマンドには --json を追加すると、目視ではなく解析できます。-q は成功時の出力を抑制しますが、エラーは抑制しません。

ユーザーのセッションを壊さない

このマシン上のペインはユーザーの実際の作業場所であり、中には作業中のコーディングエージェントが使っているものもあります。自分が作成していないものは、読み取り専用として扱ってください。

  • 自分が開いていないペインに send や exec を実行しないでください。 別のエージェントのペインや、ユーザーが入力中のシェルにキー入力すると、その場で進行中の作業に割り込んでしまいます。ペインに触れる前に tty7 agents を確認してください。--key では特に注意が必要です。誤って C-c を送ると、誰かの作業を終了させてしまいます。
  • 自分が作成していないものに pane close / tab close / ws rm を実行しないでください。
  • pane close --orphans は絶対に実行しないでください。 マシン上の放置されたペインをすべて閉じますが、放置されたペインでも実際のコマンドが動いている場合があります。これはユーザーが使う掃除用のコマンドです。ユーザーに案内し、自分では実行しないでください。
  • server stop や server restart は絶対に実行しないでください。 サーバーを停止すると、自分のペインも含め、マシン上のすべてのペインが終了します。本当にサーバーが応答しなくなったようなら、その旨を伝え、判断はユーザーに委ねてください。
  • 自分が作成したものは後片付けしてください。 一時的なペインを使い終えたら tty7 pane close %83 を実行してください。複数の ID を一度に指定できます。ws rm はワークスペース内のペインを切断するため、一時的なワークスペースを削除すれば十分です。残り続けるのは、中断された tty7 run です。この場合、参照元がないままペインが実行され続け、tty7 pane ls --all に表示されます。

リモートマシン

-m <machine> を指定すると、ローカルサーバーがすでに保持しているリンクを介して、任意のコマンドを実行できます。

tty7 -m devbox ls
tty7 -m devbox run -- cargo test

名前には、リンクの完全なキー(me@devbox:22)またはホスト名だけを指定します。CLI は新しい接続を確立しません。リンクが切断されている場合や、ジャンプ/プロキシのチェーンになっている場合は、その旨を表示します。その場合は GUI から接続できるユーザーに引き継いでください。

まだ実装されていない機能

ws stop、machine connect、machine disconnect は、未実装であることを示すメッセージを表示して終了します。これらを前提に計画を立てないでください。

参考資料

  • references/delegation.md — 委任のプレイブックです。worktree、引き継ぎ、進捗の見守り、収集、ファンアウト、クリーンアップについて記載されています。他のエージェントが作業に取りかかろうとしているときは、必ずお読みください。
  • references/commands.md — すべての動詞、サブコマンド、フラグを1つの表にまとめ、それぞれが出力するJSONの形式も記載しています。上記にない動詞が必要なときや、--json の出力を解析しようとしていてフィールド名を確認したいときにお読みください。

コメント