org-attach: 組織ペインへの tmux attach コマンドを生成(read-only)
組織の生きているペイン(secretary / dispatcher / worker)へ人間が自分のターミナルから
tmux で直接 attach するための attach コマンド文字列を生成して表示する スキル。
このスキルは 何も attach しない・どのペインも変更しない。論理ペイン一覧(broker)と
tmux 側の pane_id↔session マッピングを pane_id(%N)で join し、各ペインへの attach コマンドを
role + name(task_id) ラベル付きで印字するだけ。コピーした人間がコマンドを自分の端末に貼って入る。
輸送層 両系(frame C / 二フレーム) — このスキルは broker(tmux) フレーム専用:
このスキルは tmux backend(socket claude-org-broker)上の detached tmux session への attach を
前提とする。broker フレーム: 各 broker ペインは claude-org-broker-{pid}-{seq} という独立した detached
tmux session(1 ペイン = 1 session)として存在し、tmux attach -t <session> で入れる ―
本スキルの attach モデルが意味を持つ主フレームはこちら。renga フレーム(opt-in,
ORG_TRANSPORT=renga)は概念が異なる: renga のペインは所属タブ内のタイルであって、独立した
detached session ではない。「detached session へ attach し直す」概念がそのまま写像せず、ペイン単位の
tmux attach -t <session> は存在しない。よって ORG_TRANSPORT=renga では本スキルの broker/tmux
attach 形は適用外で、org のペインが並ぶタブを表示して直接見る。org が全ペインを同一タブへ置くのは
org 側の配置規則であり、規範の正本は契約
docs/contracts/backend-interface-contract.md
§4.2 の SINGLE-TAB MUST(本スキルはこれを再掲せず参照する)。したがってその org のタブを表示している
間は 1 画面で全ペインが見えるが、別のタブを表示している間は org のペインは視界に入らない。そのときは
org のタブへ切り替えるか、renga の org サイドバー(全タブ横断でタブとペインを一覧する cross-tab パネル。
renga src/app/org_sidebar.rs:1-3)から該当ペインを選ぶ。
この適用外は transport が renga の場合に限る: 外側フレームが renga でも ORG_TRANSPORT が broker の
構成では detached tmux session が実在するので本スキルは適用される(その場合に必要なのは attach 打鍵の
Ctrl+B 衝突回避で、手順は
docs/operations/dispatcher-view.md「外側フレームが renga の
場合」)。本スキルは ORG_TRANSPORT=renga のときだけ「broker(tmux) 専用ツールです」と明示して停止する
(下記 Step 0)。
(既定の二フレーム注記(Refs #604): org-attach は本質的に broker/tmux ツールなので header を
broker 主軸で書く。輸送層全体の既定は二つのフレームで指す対象が異なる ― 運用既定は renga
(broker 実走 dogfood が Epic #6 Issue G まで未活性)だが、コード既定は tools/transport.py: DEFAULT_TRANSPORT が runtime 0.1.28 (Epic #586) で renga→broker にフリップ済み。broker tool を
使う手保守スキルのうち
.claude/skills/org-attention-stop/SKILL.md は header を
「既定 broker / opt-in renga」のコード既定フレームで書く ― 本スキルはこの broker 主軸の先例に倣う。
(.claude/skills/org-attention-start/SKILL.md は逆に「既定 renga」
の運用既定フレームで書かれており、両者は指す対象が異なるだけで矛盾しない。)総説は root
CLAUDE.md「輸送層(transport)両系」節、契約面は
docs/contracts/backend-interface-contract.md
Surface 8。)
権限フレーム: list_panes は broker の ops-tier ツール(secretary / dispatcher のみ付与、
worker には付与されない)。したがって org-attach は 窓口(Secretary)/ ディスパッチャー面のスキルで、
人間は窓口セッションから実行する。
なぜ /usr/bin/tmux 絶対パス必須か(最重要)
zsh では tmux は oh-my-zsh の tmux プラグインで alias 化けする(tmux is an alias for _zsh_tmux_plugin_run)。素の tmux ... を出力すると、人間の zsh に貼った瞬間に alias 経由で
別物(プラグインのラッパ)が走り、-L claude-org-broker の socket 指定や attach -r -t <session> が
意図通り効かない。生成する全コマンドで実体パス /usr/bin/tmux を使い、出力にもその理由を 1 行添える。
Step 0: 輸送フレームを確認する(renga なら停止)
まず ORG_TRANSPORT を read-only で読む(この 1 コマンドだけが Step 0 の許可対象):
printenv ORG_TRANSPORT
renga transport(ORG_TRANSPORT=renga)ならこのスキルは適用外なので attach コマンドを生成せず停止する。
ORG_TRANSPORT=renga(明示)の場合 → 次の旨を伝えて停止する(attach コマンドは生成しない):
「現在は renga transport(ORG_TRANSPORT=renga)で稼働しています。renga のペインは所属タブ内のタイルで、
detached tmux session への attach という概念がそのまま適用されません。組織のペインはすべて同じタブに
置かれるので、その組織のタブを表示している間はそのまま画面で見られます。別のタブを表示中なら、組織の
タブへ切り替えるか、renga の org サイドバー(全タブ横断でタブとペインを一覧するパネル)から該当ペインを
選んでください。ペイン状況の一覧は /org-dashboard を使ってください。」
- それ以外(無設定 /
broker) → broker(tmux) フレームとして Step 1 へ進む。
Step 1: 論理ペイン一覧を取得(broker)
mcp__org-broker__list_panes
戻り値は 1 論理ペイン = 1 レコードで、主に次のフィールドを持つ:
id: tmux backend では これが tmux の pane_id(%N 文字列)そのもの。
(runtime broker_queue_event.schema.json: "Backend-native pane id: int on WezTerm,
string (e.g. "%3") on tmux" / dispatcher/runner.py: "broker/tmux backend emits tmux
pane_id strings of the form %N"。WezTerm backend では int になるが、本スキルが対象とする
tmux socket claude-org-broker では %N 文字列で来る。)
name: ペイン名(worker-{task_id} / dispatcher / secretary 等)
role: secretary / dispatcher / curator / worker
focused, geometry(x / y / width / height), cwd
重要 — attach 可能なのは broker が spawn した子ペイン(dispatcher / worker)だけ:
窓口(root secretary)は broker 起動時に logical pane(bookkeeping entry、register_logical_pane)
として登録されるだけで、adapter 実ペインを持たず id / pane_id が null(%N 無し)。よって
broker socket の detached session には出現せず attach 対象外である(窓口は org を起動した人間の
手元 terminal でそのまま動くので、そもそも attach 不要)。id が %N のレコードだけが attach 可能。
一次参照: docs/operations/broker-dogfood-runbook.md
§8(attach 導線の正準ガイド・「対象範囲(重要)」節)。
list_panes が空 / 取得不可なら「組織ペインが見つかりません。/org-start 済みか確認してください」と
報告して停止する。list_panes が [tool_not_authorized] を返したら ops-tier 権限が無い
(worker セッションから呼んでいる等)ので、窓口 / ディスパッチャー面で実行するよう案内する。
補足が要れば mcp__org-broker__list_peers(read-only)で peer 名と cwd を突き合わせてもよい
(join には必須ではない)。
list_peers の直前に
.claude/skills/org-delegate/references/capability-first-drive-operational-gate.md
を Read し、monitoring-read-only の分岐を適用する。 全タブ列挙では予約名が別 org のペインと
衝突しうるので、素の名前突き合わせは他 org のペインに自 org のラベルを付けて人間に提示しうる。
縮退時(capability 形かつ未承認)の帰結: 列挙結果を破棄する。破棄しても Step 3 の pane-id
join は継続し、表示するラベル(role / name(task_id))は list_panes 由来のままである — join key
も表示元も list_panes なので、落ちるのは peer 名 / cwd の補足だけで本スキルの出力は成立する。
承認済み(first_drive が recorded)のときの帰結: 共有 reference §1-2 の三値判定を対象名に
適用し、「在」と確定したレコードの補足だけを表示に使う。「不在」「unknown」のレコードは自 org の
ものとして表示しない(unknown はその旨を添えて出す)。判定手順と評価順の正本は §1-2。
どちらの帰結でも、この列挙は表示補助にしか使わないため attach 可否・join・lifecycle 判定の
いずれにも波及させない(本スキルは read-only であり、縮退が破壊的な後段に繋がる経路を持たない)。
旧版 fallback(capability を広告しない backend。現行では org-broker)ではこの承認判定に入らず、挙動は変わらない。
Step 2: tmux 側の pane_id ↔ session マッピングを取得
/usr/bin/tmux -L claude-org-broker list-panes -a -F '#{pane_id} #{session_name}'
-L claude-org-broker: runtime の BROKER_SOCKET。組織の tmux はこの socket 上にある
-a: 全 session の全ペインを列挙
-F '#{pane_id} #{session_name}': 各行を %N <session> の固定 2 列に整形して頑健にパースする
(tmux のデフォルト行は session:window.pane: [geometry] [history] %N (active) 形で、ここからも
session 名と %N を取れるが、明示 -F の方が確実)
出力例(1 行 = 1 ペイン、各 broker ペインは独立 session claude-org-broker-{pid}-{seq}):
%0 claude-org-broker-1912-1
%5 claude-org-broker-1912-14
%6 claude-org-broker-1912-17
socket 接続自体が落ちている場合は error connecting to ... claude-org-broker が返る。その時は
「tmux socket claude-org-broker に繋がりません(組織が起動していない可能性)。/org-start 済みか
確認してください」と報告して停止する。
Step 3: pane_id(%N)で join
list_panes の id(%N)を key に、Step 2 の %N → <session> マッピングと突き合わせる:
list_panes.id (%N) ⨝ tmux pane_id (%N) → 各論理ペインの session 名
join 前に、まず id が null(%N 無し)の logical pane を除外する。これらは attach 対象外で、
join に回さず別枠で報告する(下記)。id が %N のレコードだけを tmux マッピングと突き合わせる。
両側でマッチしないエントリは失敗にせず一覧で報告する(実運用で起こる):
id が null の logical pane(通常は窓口 = secretary): これは drift ではなく正常。
adapter 実ペインを持たないので attach できない。「(logical pane / attach 対象外。窓口は人間の手元
terminal)」と注記して別枠表示する(attach コマンドは出さない)。
- list_panes に
%N があるが tmux に同 %N が無い: backend 再起動 / pane が死んだ直後の drift。
「session 解決不可」として attach コマンドは出さず、行だけ「(tmux 側に %N 無し)」と注記して出す。
- tmux にあるが list_panes に無い: 組織外の手動 session / 孤児 session。「(broker 未登録 session)」
として、role/name は不明のまま attach コマンドだけ参考表示する(人間判断に委ねる)。
Step 4: attach コマンドを生成して出力
join できた各ペインについて、role + name(task_id) ラベル付きで次を出力する:
- 読取書込 attach(既定):
/usr/bin/tmux -L claude-org-broker attach -t <session>
- 読取専用 attach(オプション): 同じコマンドに
-r を付ける
→ /usr/bin/tmux -L claude-org-broker attach -r -t <session>
-r = read-only attach。覗くだけで誤入力でペインを壊さない
- 今の tmux を分割して並べる(外側が tmux =
$TMUX 設定ありのとき): 各ペインについて
/usr/bin/tmux split-window -d -h "TMUX= /usr/bin/tmux -L claude-org-broker attach -t <session>" \; select-layout even-horizontal
を 1 行ずつ出す(既定は左右並べ)。続けて、並べる枚数が多いとき用に末尾を \; select-layout tiled
に替えた版も併記する
-d: 新しいペインへフォーカスを移さない。無いと 1 行目の実行後に入力先が attach 先(dispatcher / worker)
に移り、次の行がそちらへ打ち込まれる
\; select-layout even-horizontal: 分割のたびに左右均等幅へ並べ直す。横長画面で 2 枚なら左右に並ぶ
(tiled だと上下に重なる)。最後に 1 回だけだと、-h 分割を重ねる途中で幅が尽きて
no space for new pane で後続の分割が失敗するので、分割ごとに並べ直す形は崩さない
\; select-layout tiled(併記版): 自分のペインを含めた合計が 4 枚以上になるなど、左右並べでは 1 枚の
幅が足りないときに使う。格子状に並べるので幅切れしにくい
- 外側の
/usr/bin/tmux split-window は -L を付けず、$TMUX が指す人間自身の tmux を分割する。
内側の TMUX= は「tmux の中から tmux を起動する」入れ子拒否
(sessions should be nested with care, unset $TMUX to force)を外すためのもの
- 外側の tmux が broker socket(
claude-org-broker の session に attach 中の端末)だと、組織の
session 自体を分割してしまう。broker に attach していない自分の tmux から実行する
- 読取専用で並べたいときは内側の
attach に -r を付ける
- 分割ペインの中でデタッチすると内側の attach が終わり、その分割ペインも閉じる(組織のペインは生き続ける)
- デタッチ: attach 中に
Ctrl-b d を押すと、ペインを動かしたまま自分だけ抜ける
(ペインは生き続ける ― close ではない)
- 別セッションへの切替(tmux 3.2a の既定キー。
man tmux の DEFAULT KEY BINDINGS / attach-session -r):
- 読取書込 attach:
Ctrl-b s(セッション一覧から選ぶ choose-tree)
- 読取専用
-r attach: Ctrl-b ( / Ctrl-b )(前 / 次のセッション)、Ctrl-b L(直前のセッション)。
read-only クライアントで効くのは detach-client / switch-client に bind したキーだけなので、
Ctrl-b s(choose-tree)は効かない
- 入れ子(分割ペインの中): 外側の tmux も既定 prefix
Ctrl-b だと外側が先に受け取るため、内側へは
prefix を 2 回押す(Ctrl-b Ctrl-b d でデタッチ、Ctrl-b Ctrl-b ( で切替。既定の Ctrl-b Ctrl-b は
send-prefix)
Ctrl-b は tmux prefix の既定値: prefix を変更している場合は設定した prefix に読み替える。
さらに、attach する端末が renga の場合はこの打鍵が届かない — renga の org サイドバーは既定で
有効なあいだ Ctrl+B(tmux prefix Ctrl-b と同じ物理入力)を消費して PTY へ渡さないため、
detach できず抜けられなくなる。attach する前に
docs/operations/dispatcher-view.md の
「外側フレームが renga の場合」の回避策(renga 設定 [ui] org_sidebar = "off"、または tmux prefix
の変更)を適用すること。
出力末尾に「tmux は zsh で alias 化けするため、必ず実体パス /usr/bin/tmux を使うこと」と、上記
Ctrl-b の読み替え(tmux prefix の既定値であること・renga の画面から attach する場合は先に
docs/operations/dispatcher-view.md「外側フレームが renga の
場合」の回避策が要ること)を添える。
出力フォーマット(worked example)
Step 1 / Step 2 が次を返したとする:
list_panes(論理ペイン。窓口 = secretary は id が null の logical pane):
| id | role | name |
|---|
null | secretary | secretary |
%5 | dispatcher | dispatcher |
%6 | worker | worker-feat-org-attach-skill |
/usr/bin/tmux -L claude-org-broker list-panes -a -F '#{pane_id} #{session_name}'
(secretary は logical pane なので broker socket に出ない点に注意):
%5 claude-org-broker-1912-14
%6 claude-org-broker-1912-17
logical pane 除外 → %N を持つ dispatcher / worker のみ join → 生成する出力:
組織ペインへの attach コマンド(broker/tmux フレーム・read-only スキル:表示のみ、自動 attach はしません)
※ これらを自分のターミナルに貼って入る
■ dispatcher (dispatcher) session=claude-org-broker-1912-14
読取書込 : /usr/bin/tmux -L claude-org-broker attach -t claude-org-broker-1912-14
読取専用 : /usr/bin/tmux -L claude-org-broker attach -r -t claude-org-broker-1912-14
■ worker (worker-feat-org-attach-skill) session=claude-org-broker-1912-17
読取書込 : /usr/bin/tmux -L claude-org-broker attach -t claude-org-broker-1912-17
読取専用 : /usr/bin/tmux -L claude-org-broker attach -r -t claude-org-broker-1912-17
■ 今の tmux を分割して並べる(自分の tmux の中から。broker に attach 中の端末では使わない)
/usr/bin/tmux split-window -d -h "TMUX= /usr/bin/tmux -L claude-org-broker attach -t claude-org-broker-1912-14" \; select-layout even-horizontal
/usr/bin/tmux split-window -d -h "TMUX= /usr/bin/tmux -L claude-org-broker attach -t claude-org-broker-1912-17" \; select-layout even-horizontal
(読取専用で並べるなら内側の attach に -r を付ける)
自分のペインを含めて 4 枚以上になり幅が足りないときは、格子状に並べる tiled 版を使う:
/usr/bin/tmux split-window -d -h "TMUX= /usr/bin/tmux -L claude-org-broker attach -t claude-org-broker-1912-14" \; select-layout tiled
/usr/bin/tmux split-window -d -h "TMUX= /usr/bin/tmux -L claude-org-broker attach -t claude-org-broker-1912-17" \; select-layout tiled
(logical pane / attach 対象外)
- secretary (secretary): 窓口は logical pane(pane_id 無し・broker socket 非出現)。
org を起動した人間の手元 terminal でそのまま見えるので attach 不要。
- 既定は読取書込。覗くだけなら -r を付ける(誤入力でペインを壊さない)。
- 抜けるとき: Ctrl-b d(デタッチ。ペインは動いたまま自分だけ抜ける)。
- 別セッションへ切替: 読取書込なら Ctrl-b s(一覧から選ぶ)。-r 付きでは Ctrl-b s は効かないので
Ctrl-b ( / Ctrl-b )(前 / 次)、Ctrl-b L(直前)を使う。
- 分割ペイン(入れ子)の中では prefix を 2 回押す(例: Ctrl-b Ctrl-b d でデタッチ)。
- 上記 Ctrl-b は tmux prefix の既定値。変更していれば設定した prefix に読み替える。
renga の画面から attach する場合は、org サイドバー(既定で有効)が Ctrl+B(tmux prefix Ctrl-b と
同じ物理入力)を消費して PTY へ渡さないため上の打鍵が届かない(detach できず抜けられなくなる)。
先に docs/operations/dispatcher-view.md「外側フレームが renga の場合」の回避策
(renga 設定 [ui] org_sidebar = "off"、または tmux prefix の変更)を適用すること。
- tmux は zsh で alias 化けするため、必ず実体パス /usr/bin/tmux を使うこと。
unmatched があった場合の追記例:
(参考) join できなかったエントリ:
- broker %3 (worker / worker-foo) : tmux 側に %3 無し(pane drift の可能性、attach 不可)
- tmux session claude-org-broker-1912-9 (%9) : broker 未登録 session(組織外/孤児の可能性)
/usr/bin/tmux -L claude-org-broker attach -r -t claude-org-broker-1912-9
やらないこと(read-only 不変条件)
- 自分で
attach / split-window しない(コマンド文字列を出すだけ)
- ペインを spawn / close / rename / send_keys / send_message しない
.state/ / registry / tmux のいずれも変更しない
- 書込み・spawn・送信系の broker / tmux ツールは
allowed-tools に含めない
(許可は list_panes / list_peers と read-only な tmux list-panes / list-sessions のみ)
- 状況の一覧だけが目的なら
/org-dashboard、作業委譲は
/org-delegate を使う(本スキルは attach 用コマンド出力専用)