From f439de6cdc191a599c771a078e376f210439d157 Mon Sep 17 00:00:00 2001 From: Hare Date: Sun, 24 May 2026 08:10:21 +0900 Subject: [PATCH] docs: replace gui mvp with tui spawned pod panel --- TODO.md | 2 +- tickets/native-gui-mvp.md | 91 -------------------------------- tickets/tui-spawned-pod-panel.md | 60 +++++++++++++++++++++ 3 files changed, 61 insertions(+), 92 deletions(-) delete mode 100644 tickets/native-gui-mvp.md create mode 100644 tickets/tui-spawned-pod-panel.md diff --git a/TODO.md b/TODO.md index 03201b31..b56a15ad 100644 --- a/TODO.md +++ b/TODO.md @@ -9,12 +9,12 @@ - Pod: Inbound PodEvent ハンドリングの重複を統合 → [tickets/pod-inbound-pod-event-dedup.md](tickets/pod-inbound-pod-event-dedup.md) - llm-worker のエラー耐性 - ストリーム途中失敗時の継続 → [tickets/llm-worker-stream-continuation.md](tickets/llm-worker-stream-continuation.md) -- ネイティブ GUI クライアント MVP → [tickets/native-gui-mvp.md](tickets/native-gui-mvp.md) - E2E テストハーネス(`tests/e2e/`、opt-in) → [tickets/e2e-harness.md](tickets/e2e-harness.md) - TUI 拡充 - TUI command mode / registry / completion → [tickets/tui-command-mode.md](tickets/tui-command-mode.md) - command modeから任意タイミングで Compact を発火 → [tickets/tui-system-command-compact.md](tickets/tui-system-command-compact.md) - navigation mode / block focus の設計 → [tickets/tui-navigation-mode-design.md](tickets/tui-navigation-mode-design.md) + - spawned child Pod の一覧と一時 attach → [tickets/tui-spawned-pod-panel.md](tickets/tui-spawned-pod-panel.md) - user manifest env override 時の spawn scope overlay 前提ズレ → [tickets/tui-user-manifest-env-overlay.md](tickets/tui-user-manifest-env-overlay.md) - ユーザーマニフェストのモデル設定 wizard → [tickets/tui-user-model-setup.md](tickets/tui-user-model-setup.md) - メモリ機構 diff --git a/tickets/native-gui-mvp.md b/tickets/native-gui-mvp.md deleted file mode 100644 index 89e70039..00000000 --- a/tickets/native-gui-mvp.md +++ /dev/null @@ -1,91 +0,0 @@ -# ネイティブ GUI クライアント MVP - -## 背景 - -TUI は ratatui の `insert_before` を使った append-only モデルで動いており、ツール呼び出しのライブ更新(引数のストリーミングプレビュー、状態遷移の視覚化)のような「既に描いた領域の書き換え」が本質的に苦手である。`tickets/tui-tool-call-ui.md` で妥協的な拡張策(inline viewport を可変化してアクティブフレームを保持)は立てたが、terminal のスクロールバックモデルと live-updating な LLM UX の相性は根本的に悪く、どう組んでも制約と妥協がついて回る。 - -一方、GUI 側ならそもそも**全領域が毎フレーム再描画される retained-mode**なので、ツールフレームの live 更新・折り畳み・インタラクティブな介入といった操作が自然に書ける。TUI は軽量・ssh 親和のクライアントとして残し、**リッチな対話は GUI クライアントに切り出す**方針を取る。 - -## 方針 - -### アーキテクチャ - -- **プロセス分離 + ソケット接続を維持**。GUI は独立バイナリとして動き、Pod はこれまで通り別プロセス。 -- **通信は既存の `protocol` クレート**(`Method` / `Event`)をそのまま使う。GUI と TUI は同じ protocol を喋る。 -- **Pod の spawn は GUI から直接行う**。manifest を選択 → `pod` バイナリを subprocess として起動 → その socket に接続、という流れ。daemon 層は導入しない。 -- **MVP は単一 Pod**。複数 Pod の並列管理は本チケットの範囲外とし、GUI 側の protocol 抽象が固まってから別チケットで拡張する。 - -### GUI フレームワーク: GPUI - -- Rust ネイティブ + async-aware で、`protocol` クレートを直接リンクできる。 -- GPU 加速の retained-mode で、ツールフレームの live 更新が素直に書ける。 -- virtualized list / text input / scrollable 履歴など、LLM チャット UI に必要な部品が一通り揃っている。 -- 既知のリスク: プラットフォーム成熟度(macOS > Linux > Windows)、独立ライブラリとしての新しさ、Markdown レンダラ等のウィジェット生態系が Tauri/Iced より薄い。本 MVP は Linux only なのでプラットフォーム面のリスクは受容できる。 - -### プラットフォーム - -- **Linux only**。macOS / Windows は MVP の範囲外。GPUI の Linux サポートが動作する前提で組む。 - -## MVP スコープ - -### 含む - -1. **Pod の spawn と接続** - - manifest ファイルを選ぶ UI(ファイルダイアログ or CLI 引数) - - `pod` バイナリを subprocess として起動し、その socket に接続 - - 接続確立後は TUI と同じ protocol で対話 -2. **現 TUI の機能相当** - - 入力フィールド + 送信 - - ストリーミングテキストの表示(`TextDelta` → 追記) - - ターンヘッダ / ターン統計 / ステータスバー相当の情報表示 - - セッション再開時の履歴復元(`Event::History`) - - エラー表示 - - cancel / graceful shutdown -3. **ツール呼び出しのフレーム更新 UI** - - `tickets/tui-tool-call-ui.md` で定義したライフサイクル(Pending → Streaming → Executing → Done/Error)をそのまま GPUI 側で実装 - - TUI と違い inline viewport の制約が無いので、履歴スクロール内でも自由に再描画できる - - `ToolCallArgsDelta` を毎フレーム反映してライブプレビュー - - 完了済みフレームは履歴内に状態が焼き込まれた形で残る -4. **Pod の明示的 shutdown** - - GUI から shutdown 操作を行い、Pod subprocess を graceful に終了させる - - shutdown 完了後は GUI 自体も正常終了する - -### 含まない - -- 複数 Pod の並列表示・切替(別チケット) -- daemon 層の導入 -- macOS / Windows サポート -- ツール結果のリッチレンダリング(Markdown 整形、シンタックスハイライト、diff 表示等) -- ツール実行への対話的介入(permission ask/reply の UI 実装は `tickets/permission-extension-point.md` 側) -- protocol の拡張(compact 通知・R-R パターン等は `tickets/protocol-design.md` 側で進行し、GUI は完了次第追従する) -- GUI 内での manifest 編集 -- テーマカスタマイズ、キーバインドカスタマイズ - -## 設計で決めること - -- **GPUI のイベントループと Tokio ランタイムの統合**: GPUI 側の executor に Pod からの socket イベントをどう流し込むか -- **socket client の置き場所**: 現 `crates/tui/src/client.rs` と同等のクライアントを別 crate に切り出して共有するか、GUI crate 内に閉じて持つか -- **Pod subprocess のライフサイクル管理**: GUI プロセスが落ちたときの Pod 側の後処理(orphan prevention)、Pod が異常終了したときの GUI 側の復帰 UX -- **ツールフレームのデータモデル**: `OutputItem` 列に載せるか別コレクションで持つか(TUI 側の設計議論と共通部分あり。共有可能なら abstract して流用) -- **履歴スクロールの挙動**: 下端追従(chat 流儀)と手動スクロール時の追従停止 -- **入力エリアの多行対応**: 単一行でよいか、複数行 + Ctrl+Enter 送信等 - -## 完了条件 - -- Linux 上で GUI バイナリが起動し、manifest を指定すると `pod` subprocess を起動して socket 接続する。 -- 基本的なチャット(user 入力 → assistant 応答のストリーミング → ターン統計)が TUI と同等に動く。 -- ツール呼び出しが 1 フレームとして表示され、`ToolCallArgsDelta` がライブでプレビューされ、完了時に視覚的に状態が変わる。 -- セッション再開時に履歴(ツール呼び出し含む)が復元される。 -- GUI から shutdown 操作で Pod を正常終了させられ、GUI 自体も正常終了する。 - -## 新規クレート構成(案) - -- `crates/gui/` (GPUI を使うバイナリ) -- socket client を共有する場合は `crates/client/` を新設し、TUI と GUI がそれぞれ依存する形に整理する選択肢もある - -## 範囲外(再掲・重要なもの) - -- 複数 Pod の並列管理・切替。単一 Pod に集中する。 -- macOS / Windows。Linux only で完結させる。 -- protocol の新規イベント追加。既存 protocol で足りる範囲に留める。 -- TUI の廃止。TUI は軽量クライアントとして並行して残る。 diff --git a/tickets/tui-spawned-pod-panel.md b/tickets/tui-spawned-pod-panel.md new file mode 100644 index 00000000..f221c697 --- /dev/null +++ b/tickets/tui-spawned-pod-panel.md @@ -0,0 +1,60 @@ +# TUI: spawned child Pod の一覧と一時 attach + +## 背景 + +insomnia の開発では、親 Pod が複数の実装 Pod / reviewer Pod を spawn し、並列に作業させる運用が増えている。現在、spawned child の状態確認や出力確認は主に tool (`ListPods`, `ReadPodOutput`, `SendToPod`, `StopPod`) 経由で行っているが、TUI 上では親 Pod の会話と child Pod の進捗を行き来しにくい。 + +ネイティブ GUI は将来的には便利だが、現時点で必要なタスクではない。まず TUI のまま、現在の Pod が spawn した child Pod を一覧し、一時的に attach / view できる UI を用意したい。 + +## 要件 + +- TUI 上で、現在の Pod が spawn した child Pod を一覧できる。 + - source は spawned child registry / Pod state persistence を使う。 + - ホスト上の全 Pod を無条件に見せる UI にはしない。 + - current parent から見える child Pod だけを対象にする。 +- 各 child row には最低限以下を表示する。 + - pod name + - alive / stopped / unreachable などの状態 + - delegated scope の概要 + - 最終更新時刻または最終出力時刻(取得できる範囲) + - 未読出力の有無または最終 assistant text preview(可能なら) +- TUI から child Pod に一時 attach / view できる。 + - 親 Pod の TUI を完全に終了せず、child の履歴 / streaming 出力を確認できる。 + - 戻る操作で親 Pod view に戻れる。 + - 最小実装では read-only view でもよい。child へ入力を送る操作は後続でもよい。 +- child view 中でも、どの Pod を見ているか視覚的に分かる。 + - status line / title / breadcrumb など。 +- child が stopped / unreachable の場合は明確に表示し、attach 失敗を診断する。 +- 既存 tool の `ListPods` / `ReadPodOutput` / `SendToPod` / `StopPod` の意味を変えない。 +- visibility は parent-child 関係に基づけ、Pod discovery の global list と混ぜない。 + +## 操作案 + +詳細 keybinding は実装時に確定する。 + +候補: + +- command mode から `:pods` で child Pod list を開く。 +- list 上で Enter すると child view へ一時 attach。 +- `Esc` / `b` / command で parent view へ戻る。 +- child view から `:send` などで入力する機能は後続 ticket にしてよい。 + +## 完了条件 + +- 親 Pod の TUI で spawned child Pod の一覧を表示できる。 +- live child Pod を選択すると、その child の snapshot / streaming output を TUI 上で確認できる。 +- parent view に戻れる。 +- stopped / unreachable child は一覧上で状態が分かり、attach 失敗が診断される。 +- ホスト全 Pod ではなく、parent から見える child Pod だけが対象である。 +- `cargo fmt --check` +- `cargo check --workspace` +- `cargo test -p tui -p pod -p protocol` + +## 範囲外 + +- ネイティブ GUI クライアント。 +- 複数 Pod view の同時分割表示。 +- child Pod への full interactive input。 +- child Pod の自動再起動。 +- host-wide Pod browser。 +- Pod discovery tool の visibility model 変更。