3.3 KiB
3.3 KiB
Client crate の切り出し
背景
protocol を喋る socket クライアントは現在 crates/tui/src/client.rs に閉じている。今後の二つの方向で、TUI 内に閉じていることが障害になる:
- GUI MVP (
tickets/native-gui-mvp.md): GUI バイナリも同じ protocol を喋る。チケット側の検討事項にも「socket client を別 crate に切り出して共有するか、GUI crate 内に閉じて持つか」が挙げられている (native-gui-mvp.md:67)。 - E2E ハーネス (
tickets/e2e-harness.md): TUI バイナリを PTY で叩くのは脆く、GUI バイナリは MVP 中。E2E から protocol を直接喋る入口として client crate が要る。
TUI 内に置いたまま GUI と E2E から再利用しようとすると、TUI のレンダリング都合と client の責務が混ざる。先に切り出しておく。
方針
crates/client/を新設し、socket への接続・Method送信・Event受信・graceful shutdown までの低レベル機能を移す。- TUI / GUI / E2E は当 crate を依存先として呼び出す。Pod の subprocess 起動も client crate 側で扱うのが自然か、別 crate / 上位呼び出し側に残すかは設計で詰める(GUI が subprocess を直接 spawn する流儀との整合)。
- 移行は機能等価で、TUI に regression を起こさないこと。
検討事項
- crate 名:
clientで良いか、より具体的な名前にするか(pod-client等。feedback_crate_naming.mdの方針に従いプレフィックスは付けない)。 - subprocess spawn 責務: client crate に含めるか、呼び出し側に残すか。GUI MVP では「GUI から直接 pod を spawn」する流儀なので、spawn と connect を分離して両方公開しておくのが妥当そう。
- 公開 API の境界: 生 socket /
JsonLineReaderまでを露出するか、もう一段抽象化したリクエスト/サブスクライブ API にするか。 - 非同期ランタイム: tokio 前提で良いか(GUI の GPUI executor との統合は GUI 側で吸収する)。
- error 型: TUI の
client.rs内で持っている error をそのまま move するか、再設計するか。
要件
crates/client/が新設され、現crates/tui/src/client.rs相当の機能を提供する。- TUI は新 crate に依存して動作し、既存テスト・既存挙動が通る。
- API は GUI / E2E から呼べる粒度で公開されている(最低限: 接続、
Method送信、Eventストリーム購読、shutdown)。 - pod subprocess を spawn する経路をどこに置くかが決まり、必要なら本 crate からも呼べる。
完了条件
- 上記要件が満たされる。
- TUI が新 crate を使って従来通り動く(
cargo test -p tui/ TUI 手動起動で regression 無し)。 - E2E ハーネス(
tickets/e2e-harness.md)が本 crate に依存して protocol を喋れる状態になる。
範囲外
- GUI バイナリ実装そのもの(
tickets/native-gui-mvp.md)。 - protocol の拡張・互換破壊。
- TUI のリファクタリングを切り出し以上にやること(責務移動だけに留める)。
- daemon 層の導入。
依存 / 関連
tickets/native-gui-mvp.mdtickets/e2e-harness.mdcrates/tui/src/client.rscrates/protocol/