[v0.1/SSH Review] グローバル carrier と window retarget carrier の非対称 #39

Closed
opened 2026-09-03 16:30:49 +09:00 by natsukium · 1 comment
Owner

現状

  • headless verb はグローバル --host で carrier を決める: felis --host user@remote sessions listconn::resolveCarrier::Ssh を作る。
  • window retarget は verb-local --host で carrier を決める: felis window retarget --host user@remote / felis ssh user@remoteretarget()resolve(None, ...) で自デーモンを決め、verb 引数の carrier は RetargetTarget として push される。
  • 両者を混ぜた felis --host a ssh bretarget() { if global_carrier { reject } } で exit 2 になる(main.rs:retarget)。control-surfaces.md "Deliberate asymmetries" として文書化されているが、ユーザからは同一概念("どこに繋ぐか")が二つの位置に現れる。
  • 補足: --socket--host は排他(clap conflicts_with)。retarget 側は --host / --to-socket / default の三択で、alias felis ssh--host 固定(--to-socket は使えない)。

問い(1.0 でしか変えられない)

carrier 指定の「グローバル vs verb-local」分離をこのまま凍結するか? CLI 全体で統一した carrier 記法に直すか?

破壊的変更案

  • 案A: 現行の deliberate asymmetry を維持し、エラーメッセージと docs を強化。 reject_global_carrier の文面を felis --host は headless verb の宛先、felis ssh/window retarget --host は window の行き先、と明確に区別して表記。cli.md "Re-point a window across daemons" の usage error 表を normative として凍結。
  • 案B: carrier を常に verb-local に統一。 felis --host X sessions listfelis sessions --host X list または felis -- sessions list --host X のように verb 側に寄せる。グローバル --host を廃止し、すべての carrier 指定を verb の引数に。--host--socket の排他は各 verb で再宣言。
  • 案C: felis ssh をトップレベル verb から外し、felis window retarget に一本化。 alias を deprecated にし、正規形を felis window retarget --host のみに。ssh という語が felis サブコマンドに見える混同(#3 でも指摘)を解消。

判定基準

  • felis --help のトップレベル flags と felis window retarget --help / felis ssh --help の flags を並べたとき、ユーザが「どの --host がどこに効くか」を推測できること。
  • reference/control-surfaces.md の placement criterion(window なし → CLI verb / window 自体 → window 名前空間)に照らして、carrier 指定の位置が一意に決まること。
  • cli_completions.rs の carrier 解決が二重に持たずに済むこと(現行は __complete-sessions--host/--socket/--ssh-arg を転送)。

対象ファイル

  • crates/felis-cli/src/main.rs (Cli::host/ssh_arg vs WindowOp::Retarget / Cmd::Ssh), crates/felis-cli/src/conn.rs, crates/felis-cli/src/cli_sessions.rs (RetargetCarrierFlags, RetargetArgs), docs/reference/cli.md, docs/reference/control-surfaces.md, docs/how-to/attach-over-ssh.md

cc @natsukium

## 現状 - headless verb はグローバル `--host` で carrier を決める: `felis --host user@remote sessions list`。`conn::resolve` が `Carrier::Ssh` を作る。 - window retarget は verb-local `--host` で carrier を決める: `felis window retarget --host user@remote` / `felis ssh user@remote`。`retarget()` が `resolve(None, ...)` で自デーモンを決め、verb 引数の carrier は `RetargetTarget` として push される。 - 両者を混ぜた `felis --host a ssh b` は `retarget() { if global_carrier { reject } }` で exit 2 になる(`main.rs:retarget`)。`control-surfaces.md` "Deliberate asymmetries" として文書化されているが、ユーザからは同一概念("どこに繋ぐか")が二つの位置に現れる。 - 補足: `--socket` と `--host` は排他(clap `conflicts_with`)。retarget 側は `--host` / `--to-socket` / default の三択で、alias `felis ssh` は `--host` 固定(`--to-socket` は使えない)。 ## 問い(1.0 でしか変えられない) carrier 指定の「グローバル vs verb-local」分離をこのまま凍結するか? CLI 全体で統一した carrier 記法に直すか? ## 破壊的変更案 - **案A: 現行の deliberate asymmetry を維持し、エラーメッセージと docs を強化。** `reject_global_carrier` の文面を `felis --host` は headless verb の宛先、`felis ssh`/`window retarget --host` は window の行き先、と明確に区別して表記。`cli.md` "Re-point a window across daemons" の usage error 表を normative として凍結。 - **案B: carrier を常に verb-local に統一。** `felis --host X sessions list` を `felis sessions --host X list` または `felis -- sessions list --host X` のように verb 側に寄せる。グローバル `--host` を廃止し、すべての carrier 指定を verb の引数に。`--host` と `--socket` の排他は各 verb で再宣言。 - **案C: `felis ssh` をトップレベル verb から外し、`felis window retarget` に一本化。** alias を deprecated にし、正規形を `felis window retarget --host` のみに。`ssh` という語が felis サブコマンドに見える混同(#3 でも指摘)を解消。 ## 判定基準 - `felis --help` のトップレベル flags と `felis window retarget --help` / `felis ssh --help` の flags を並べたとき、ユーザが「どの `--host` がどこに効くか」を推測できること。 - `reference/control-surfaces.md` の placement criterion(window なし → CLI verb / window 自体 → window 名前空間)に照らして、carrier 指定の位置が一意に決まること。 - `cli_completions.rs` の carrier 解決が二重に持たずに済むこと(現行は `__complete-sessions` が `--host`/`--socket`/`--ssh-arg` を転送)。 ## 対象ファイル - `crates/felis-cli/src/main.rs` (`Cli::host`/`ssh_arg` vs `WindowOp::Retarget` / `Cmd::Ssh`), `crates/felis-cli/src/conn.rs`, `crates/felis-cli/src/cli_sessions.rs` (`RetargetCarrierFlags`, `RetargetArgs`), `docs/reference/cli.md`, `docs/reference/control-surfaces.md`, `docs/how-to/attach-over-ssh.md` cc @natsukium
Author
Owner

Triaged as duplicate of #23. The global-carrier versus retarget-destination grammar must be decided together with the destination spelling and alias; #23 already owns that exact breaking CLI change and its generated-surface cascade. A separate issue would allow the two halves of one grammar to land inconsistently.

Triaged as duplicate of #23. The global-carrier versus retarget-destination grammar must be decided together with the destination spelling and alias; #23 already owns that exact breaking CLI change and its generated-surface cascade. A separate issue would allow the two halves of one grammar to land inconsistently.
Sign in to join this conversation.
No description provided.