アーキテクチャ
概要
ccmux は約 2,800 行の Rust コードで、6 つのモジュールで構成されています:
src/
├── main.rs # エントリーポイント、イベントループ、panic hook
├── app.rs # ワークスペース/タブ状態、レイアウトツリー、入力処理
├── pane.rs # PTY 管理、vt100 エミュレーション、シェル検出
├── ui.rs # ratatui 描画、テーマ、レイアウト
├── filetree.rs # ファイルツリー走査、ナビゲーション
└── preview.rs # シンタックスハイライト付きファイルプレビューターミナルエミュレーション
ccmux は vt100 クレートでターミナルエミュレーションを行います(単純な ANSI ストリッピングではありません)。Claude Code はカーソル移動、色、代替スクリーンバッファ、スピナーなどの複雑なターミナル機能を使うため、これが不可欠です。
PTY リーダースレッド メインスレッド
┌──────────────┐ ┌──────────────┐
│ read(PTY) │ │ イベントポーリング │
│ ↓ │ mpsc │ ↓ │
│ vt100.parse()│ ──────→ │ dirty チェック │
│ ↓ │ channel │ ↓ │
│ イベント送信 │ │ UI 描画 │
└──────────────┘ └──────────────┘各ペインは独自のリーダースレッドを持ち、PTY から読み取ったバイトを vt100::Parser に投入し、mpsc チャネルでメインスレッドに通知します。
レイアウトツリー
ペインレイアウトは二分木で表現されます:
enum LayoutNode {
Leaf { pane_id: usize },
Split {
direction: Vertical | Horizontal,
ratio: f32, // 0.0..1.0
first: Box<LayoutNode>,
second: Box<LayoutNode>,
},
}再帰的な分割を自然にサポートし、レイアウト計算が直感的です。ratio フィールドにより、マウスドラッグでペイン境界のリサイズが可能です。
レンダリングパイプライン
- dirty フラグチェック — 変更があった時のみ描画(PTY 出力、キー入力、マウスイベント、リサイズ)
- レイアウト計算 — 二分木から各ペインの
Rectを計算 - PTY リサイズ — サイズが変わった時のみ更新(キャッシュ)
- セル単位描画 — vt100 スクリーンバッファを読み、ゼロアロケーションで ratatui セルにマッピング
- 選択オーバーレイ — 選択テキストに青いハイライトを適用
パフォーマンス
- バイナリサイズ: 約 2 MB
- 起動時間: 約 0.5 秒
- アイドル時 CPU: ほぼ 0%(dirty フラグによる差分描画)
- セル描画: ゼロアロケーション
- npm パッケージ: 1.9 KB(バイナリは初回インストール時にダウンロード)
- スクロールバック: ペインあたり 10,000 行(約 1 MB/ペイン)
OSC 検出
ccmux は bash の PROMPT_COMMAND に OSC 7(カレントディレクトリ通知)を注入します。PTY リーダースレッドが以下のシーケンスを検出します:
- OSC 7 (
\x1b]7;file://HOST/PATH\x07) → ファイルツリーとタブ名を更新 - OSC 0/2 (
\x1b]0;TITLE\x07) → Claude Code の実行を検出(タイトルに “claude” を含む)
依存クレート
| クレート | 用途 |
|---|---|
ratatui + crossterm | TUI フレームワーク + ターミナルバックエンド |
portable-pty | クロスプラットフォーム PTY(Windows は ConPTY) |
vt100 | ターミナルエミュレーション |
syntect | シンタックスハイライト |
arboard | クリップボードアクセス |
unicode-width | CJK 文字幅計算 |
anyhow | エラーハンドリング |
セキュリティ
- OOM 防止 — ファイルプレビューは 10MB 制限、バイナリ判定は 8KB のみ読み取り
- シンボリックリンク防護 — ファイルツリーでシンボリックリンクをスキップ
- Mutex poison 回復 —
unwrap_or_else(|e| e.into_inner())を使用 - panic hook — クラッシュ時にターミナル状態を復元
- リソース制限 — 最大 16 ペイン、ディレクトリあたり 500 エントリ
Last updated on