Skip to Content
IPC

IPC (外部からの操作)

renga は起動中のインスタンスを外部プロセスから制御できる local-only IPC を持つ。スクリプト / エージェント / 別の Claude Code セッションから pane 操作 / 画面取得 / ライフサイクル監視が行える。

エンドポイントは Unix socket (macOS / Linux) または Named Pipe (Windows)。access control は OS レベルの socket パーミッション に委ねられ、same user でのみ到達できる (詳細は「セキュリティモデル」参照)。RENGA_SOCKET / RENGA_TOKEN 環境変数はクライアントが エンドポイントを見つけるための指標で、renga pane 内で起動した子プロセス (claude / bash / スクリプト) はこれらを継承して透過的にサブコマンドを呼び出せる。

基本サブコマンド

renga list

アクティブタブ内の全 pane をリスト:

$ renga list [ { "id": 1, "name": "secretary", "role": "leader", "focused": true, "x": 0, "y": 0, "width": 80, "height": 24 }, { "id": 2, "name": "worker-foo", "role": "worker", "focused": false, "x": 80, "y": 0, "width": 80, "height": 24 } ]

x / y / width / height は pane のターミナル上の矩形 (左上 = (0, 0)、単位はセル)。値はレイアウト計算または描画の直後に 更新され、file-tree / preview サイドバーのオフセットも反映する。 renga 起動直後など一度もレイアウト計算が走っていない状態では 4 値とも 0 になる。既存 consumer は新フィールドを無視しても動作する。

renga send

指定 pane の PTY にテキストを送る。--enter で改行を付けて実行まで流す。

renga send --name worker-foo --enter "git status" renga send --id 2 "Hello" renga send --focused $'\x1b' # Esc を送る

ターゲット指定: --name <NAME> / --id <N> / --focused。省略時は focused pane。

renga focus

キーボードフォーカスを移動。

renga focus --name secretary

renga split

pane を分割。新 pane に開始コマンドを流したり、安定名 (--id) や役割 (--role) を付けられる。

renga split --direction vertical --command "claude" --id worker-a --role worker

分割対象の pane は --target-name <NAME> / --target-id <N> / --target-focused で指定。省略時は focused pane が分割される。--direction vertical | horizontal は必須。

renga new-tab

新しいタブを開き、そのタブに新 pane を 1 つ作る。

renga new-tab --command "claude --permission-mode plan" --id worker-plan --role worker --label "plan-session"

ライフサイクル監視

renga events

pane の起動 / 終了などライフサイクルイベントを JSON Lines で購読する。

renga events --timeout 5s --count 10
Flag意味
--timeout <DUR>指定時間後に購読終了 (2s / 500ms / 1m など)
--count <N>N 件受信したら終了。 EventsDropped meta-event も 1 件とカウント

未指定だとサーバーが切断するまで無期限に流れる。片方を指定しておけば安全。

Event 種別

{ "type": "pane_started", "id": 3, "name": "worker-foo", "role": "worker", "ts_ms": 1700000000000 } { "type": "pane_exited", "id": 3, "name": "worker-foo", "role": "worker", "ts_ms": 1700000005000 } { "type": "events_dropped", "count": 17, "ts_ms": 1700000010000 } { "type": "heartbeat", "ts_ms": 1700000012000 }
  • pane_started / pane_exited: pane の開閉
  • events_dropped: 購読が遅くて event がドロップされた合算数 (subscriber 側でリコンサイル推奨)
  • heartbeat: 30 秒おきに出る keep-alive。接続が生きていることの確認以外に意味はない (無視して良い)

購読スコープと peer_inbox

このコマンドの実体である IPC リクエスト subscribe は、購読を 1 つの pane の peer inbox にスコープするオプション項目 from_pane を取る (Issue #306):

from_pane流れてくる event
省略#306 以前とまったく同じで全 event。ライフサイクル event (pane_started / pane_exited / events_dropped / heartbeat) に加えて、宛先 pane が何であれ peer_inbox も全部流れてくる
N同じライフサイクル event に加えて、target_paneNpeer_inbox だけ
{ "type": "peer_inbox", "target_pane": 3, "from_pane": 2, "from_name": "secretary", "from_kind": "claude", "body": "please run the tests", "ts_ms": 1700000014000 }

renga eventsfrom_pane を送らないので、CLI のストリームは従来どおり変わらない — これまでと同じように、どの pane 宛のものであれ peer_inbox 行が流れてくる。from_pane はもう一方の種類の利用者向けの opt-in で、特定の 1 pane を代表して IPC を話す統合 — 同梱の renga mcp-peer のように、自分が担当する pane 宛のメッセージにしか反応しない側 — のためにある。指定しなくても失うものは無い。なお、pane を名乗らなかった購読に対して server が pane を推測することはない (hello の pid も、先行する peer 登録も、購読しているその接続に紐づく保証が無いため、推測すればいずれ別 pane に結び付いてしまう)。peer メッセージング自体はどちらの場合も従来どおりで、メッセージは受信側 pane にこれまでと同じ経路で届く (Claude は <channel> タグ、Codex は check_messages を促す nudge)。

そもそもルーティングされる event 種別は peer_inbox だけで、しかも pane を名乗った購読に対してだけである。他の種別は従来どおり全 subscriber へ broadcast される。同じ pane を名乗った購読が複数あれば、その全員にその pane 宛のメッセージが届く。pane を名乗って得られるのはキュー負荷の削減で、スコープが受け取らない event はそもそもその購読のチャネルに渡されないため、上限 256 件のキューを埋めることも、その subscriber の events_dropped に計上されることもない。

from_pane を尊重する server は hello 応答で subscribe_pane_scope capability を広告する。広告専用でどのクライアントもこれを gate に使わないため、接続方法を変えずに「from_pane を送れば実際にストリームが絞られるか」だけを判定できる。クライアント側も従来どおり target_pane を自分の pane と突き合わせる backstop を残しており、from_pane を無視して全 broadcast する古い renga に対してもこれで正しく動く (その場合のコストは余分なトラフィックだけで、結果が間違うことはない)。

購読のスコープ指定は defense in depth であって、何らかの境界ではない: 同一ユーザーで動くプロセスなら誰でも購読して任意の pane id を名乗れるので、pane を名乗ること自体は認証ではない (下の「セキュリティモデル」参照)。効果はもっと限定的だが実在するもの — 自分が対象とする pane を宣言した購読に、別の pane 宛の peer メッセージがコピーされなくなり、意図しない別 pane への配送と、そのコピーが生んでいたキュー負荷の両方が減る。

典型的なワンライナー

ワーカーペイン終了だけを拾う:

renga events --timeout 5s \ | jq -c 'select(.type == "pane_exited" and .role == "worker")'

renga inspect

指定 pane の画面内容を取得。承認プロンプト検出 / エラーバナー検出など、人間の目を使わない観測に使う。

renga inspect --name worker-foo --lines 10 --cursor
Flag意味
--lines <N>末尾 N 行を返す。可視高さを超える分はスクロールバックから遡って継ぎ足す (合計上限 2000 行、履歴行は負の行番号)。省略で可視画面全体
--cursorカーソル位置と表示状態を payload に含める

レスポンス例:

{ "status": "ok", "data": { "pane": { "id": 3, "name": "worker-foo" }, "screen": { "rows": 40, "cols": 120, "line_start": 30, "line_count": 10 }, "lines": [ { "row": 30, "text": "Running tests..." }, { "row": 39, "text": "Allow this tool use? (y/n)" } ], "text": "Running tests...\n...\nAllow this tool use? (y/n)", "cursor": { "visible": true, "row": 39, "col": 27 } } }

空行も text: "" で保持されるので、行インデックスに依存した検知ロジックが書きやすい。

エラーコード

IPC 応答のエラーは [<code>] <message> 形式で stderr に出る (renga 0.5.7+)。code は wire ABI として安定しており、substring match ではなく code で分岐するのが推奨。

Code意味
shutting_downrenga 本体がシャットダウン中。クライアント側は即停止
app_timeoutUI スレッドが応答しなかった。一過性の可能性、リトライ
parseJSON パース失敗 (protocol bug)
protocolプロトコル違反 (duplicate hello など)
internal内部不変条件違反 (parser lock poison 等)
pane_not_found指定された pane 名 / id / Focused が存在しない
pane_vanishedresolve 成功後に消えたレース (実質 pane_not_found と同扱い)
split_refusedrenga split が MAX_PANES / 最小サイズ制約で拒否
io_errorPTY write / spawn / OS レベル失敗

シェルからの分岐例:

out=$(renga send --name worker-foo --enter "ping" 2>&1) case "$out" in *"[pane_not_found]"*|*"[pane_vanished]"*) echo "worker closed" ;; *"[shutting_down]"*) exit 0 ;; *"[io_error]"*|*"[app_timeout]"*|*"[internal]"*) echo "transient: $out" ;; esac

未知の code (将来追加される可能性) は必ず非致命扱いにして、ロジックを落とさないこと。

サブスクライバ切断

renga events 購読は server 側で half-close 検知される。クライアントが read 側を閉じても、server 側の 30 秒おきの heartbeat write が失敗した時点で subscriber slot が解放される — quiet な workspace でも stale subscriber が残らない設計。

セキュリティモデル

same-user 前提の local IPC で、秘匿通信用ではない。同一ユーザーで動く他プロセスは /proc/<pid>/environ 等から RENGA_TOKEN を読める。OS レベルの user isolation が信頼境界。

RENGA_TOKEN は「PID 再利用で別 renga に誤接続しないための session token」として機能する。

Last updated on