#リモート tmux
リモート tmux は、リモートマシンで動作している tmux セッションを、tmux のコントロールモード(tmux -CC)を使って SSH 経由で cmux にミラーリングします。単なる SSH ターミナルではなく、リモートセッションを cmux のネイティブな UI(ワークスペース・タブ・分割・スクロールバック・コピー)として再投影し、その裏で cmux が実際の tmux サーバーを操作します。ベータ機能フラグであり、ローカルのターミナルには影響しません。
#tmux と cmux の対応
cmux と tmux はレイアウトの入れ子が逆向きです。cmux ではペインがタブの列を持ちます(各タブが 1 つのターミナル)。tmux ではウィンドウがペインの分割を持ちます。リモート tmux は、tmux の構造を cmux の構造へ投影することで両者を橋渡しします。
| tmux | cmux |
|---|---|
session | サイドバーの専用ワークスペース。 |
window | そのワークスペース内のタブ。 |
pane | そのタブ内の、ネイティブな分割の中のペイン。 |
新しく追加された機能は「タブの中のペイン」です。これまで cmux のタブは 1 つのターミナルだけを保持していましたが、複数のペインを持つ tmux ウィンドウは、1 つのタブの中でネイティブな cmux の分割レイアウトとして描画されるようになりました(各リモートペインは通常のクロムを備えたネイティブな cmux のターミナルペインです)。橋渡しは双方向で、そのタブ内でペインを分割・クローズすると tmux の split-window が実行され、タブを並べ替えると swap-window で tmux のウィンドウが並べ替えられます。
#必要なもの
到達可能な SSH ホスト(cmux は ~/.ssh/config を読み込みます)と、tmux がインストールされていること。コントロールモード(tmux -CC)は tmux の標準機能なので、特別なビルドは不要です(全機能を使うには新しめの tmux を推奨)。cmux は SSH の ControlMaster 接続で接続し、デタッチしてもリモートの tmux サーバーは動作し続けます。
#有効にする
設定 → ベータ機能 を開き、「リモート tmux」をオンにします。デフォルトはオフなので、オプトインするまでローカルのターミナルには何も影響しません。
#接続する
ターミナルで cmux ssh-tmux <宛先>(~/.ssh/config のエイリアスまたは user@host)を実行します。cmux はそのホストの tmux セッションをミラーリングする新しいウィンドウを開きます。各セッションはワークスペースに、各ウィンドウはタブに、複数ペインのウィンドウはタブ内の分割になります。
非対話で認証されるホスト(ssh-agent や ~/.ssh/config の鍵)はプロンプトなしで接続されます。対話的な認証(パスワード、ホストキーの確認、多要素認証)が必要なホストでは、cmux がそのターミナル内で ssh を実行するため、その場で認証でき、その後 cmux がミラーウィンドウを開きます。--port と --identity を指定できます。
cmux ssh-tmux dev@example.com
cmux ssh-tmux my-ssh-alias --port 2222 --identity ~/.ssh/id_ed25519remote.tmux.* のソケットコマンド(下記)でより細かく制御できます。たとえば remote.tmux.mirror は、専用ウィンドウを開く代わりに、ホストのセッションを現在のウィンドウのサイドバーにミラーリングします。
#「Permission denied」が出る場合
宛先はそのまま ssh に渡されるため、エイリアスにはログインに必要な設定をすべて含める必要があります。特に User(未指定だと ssh はローカルのユーザー名を使います)と IdentityFile です:
Host my-ssh-alias
HostName 203.0.113.10
User dev
IdentityFile ~/.ssh/id_ed25519または cmux ssh-tmux dev@my-ssh-alias のようにユーザーを明示指定してください。素の ssh <宛先> でログインできない場合は、cmux ssh-tmux <宛先> でも接続できません。
#仕組み
cmux は ssh … tmux -CC attach を起動し、組み込みの tmux ビューアーに頼らずコントロールモードのストリームを自前で解析します。そのためプロトコルや %begin/%end のコマンド対応付けは完全に cmux が管理します。各リモートペインは tmux の %output を流し込む専用のターミナルサーフェスに描画され、キー入力やマウスなどの入力は tmux の send-keys でリモートへ送られます。ペインのサイズやリフローはリモートの tmux サーバーが管理し、cmux はそれに追従してローカルではリフローしません。
#サポートしている機能
- サイズ調整: リモートクライアントを描画中のグリッドに合わせてリサイズします(refresh-client -C)。TUI が tmux のデフォルトの 80×24 のままになりません。
- 分割: ミラーされたウィンドウでペインを分割・クローズすると tmux の split-window に伝播し、cmux と tmux のレイアウトが同期します。プログラムからの分割(cmux new-split やソケット経由の surface.split)は accepted を返し、surface id は含まれません。新しいペインは tmux がレイアウト変更を確定した後に非同期で追加されます。ルーティングされる分割が適用できないオプション(起動コマンド、作業ディレクトリ、分割位置、左/上への配置)を含むリクエストは、リモートセッションを変更する前に拒否されます。
- 並べ替え: ミラーされたタブをドラッグで並べ替えると、swap-window で tmux のウィンドウが並べ替えられます。
- 作業ディレクトリ: リモートペインの現在のフォルダーを追跡し、タブに表示します。
- 貼り付けとドロップ: 貼り付けたテキストやドロップした画像・ファイルは tmux の paste-buffer -p 経由で渡されるため、リモートのアプリ(コーディングエージェントなど)は本物のブラケットペーストを受け取ります。画像はローカルパスではなく [Image #N] として届きます。
- マウス: リモートアプリがマウスモードのとき、クリック・スクロール・ドラッグがリモートアプリに届きます。ネイティブな cmux のテキスト選択・コピーには、Shift を押しながらドラッグしてください(マウスモードのアプリを実行している通常のターミナルと同じ挙動です)。
- Unicode に正しい出力: tmux が更新の途中でマルチバイト文字を分割しても文字は保持されるため、罫線素片などの幅広な内容も乱れずに描画されます。
#ソケットコマンド
この機能はソケットコマンドからも操作できます(ベータ機能フラグでゲートされます)。host は SSH の宛先または ~/.ssh/config のエイリアス、session は tmux のセッション名です。
| メソッド | パラメータ | 説明 |
|---|---|---|
remote.tmux.sessions | host, port?, identity_file? | ホスト上の tmux セッションを一覧表示します。 |
remote.tmux.attach | host, session, create? | セッションにコントロールクライアントで接続します(create で「接続または作成」)。 |
remote.tmux.mirror | host | ホスト上のすべてのセッションを、それぞれワークスペースとしてミラーリングします(ウィンドウがタブになります)。 |
remote.tmux.window | host, port?, identity_file? | ホスト上のすべてのセッションをミラーリングする専用ウィンドウを開きます(cmux ssh-tmux のエントリポイント)。ホストが必要とする場合は、対話的認証のために実行すべき ssh コマンドを返します。 |
remote.tmux.detach | host, session | コントロールクライアントをデタッチします。リモートセッションは動作し続けます。 |
remote.tmux.state | host, session | コントロールクライアントの観測状態を報告します(診断用)。 |
ダッシュで始まる host や identity ファイルは、SSH オプションインジェクション対策として境界で拒否されます。
{ "method": "remote.tmux.mirror", "params": { "host": "dev.example.com" } }#制限事項
- 一時的な SSH の切断は自動的に再接続されます: セッション中に接続が途切れると、ミラーは固まり、cmux は上限付きの指数バックオフで再試行し、再開時にペインを再シードします。ミラーが完全に閉じるのは、リモートセッション自体が終了したとき、またはミラーウィンドウを閉じたり cmux を終了したときだけで、再起動時には復元されません(cmux ssh-tmux で再接続してください)。
- ブラケットペーストとして paste-buffer -p で渡されるのは単一行の貼り付け・ドロップ(ファイルや画像のパスなど)のみです。複数行のテキストは通常のキー入力として送られるため、リモートアプリは 1 回の貼り付けとして扱いません。
- 作業ディレクトリのライブ更新はコントロールモードのサブスクリプション(tmux 3.2 以降)を使用します。それより古い tmux では初期フォルダーは表示されますが、cd しても更新されません。
- プライマリスクリーンのスクロールバックはリサイズ時に折り返し直されません。cmux はリフローを tmux に任せるため、古い行はアプリが再描画するまで以前の幅のままになることがあります。リサイズ時に再描画するフルスクリーンの TUI は影響を受けません。