[1.0 Review] CLI 動詞・名詞階層と alias / exit code の凍結 #3

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

背景

felis の CLI は5つの control surface(CLI / config / keymap / env / wire)のうち「CLI」として薄いラッパであることが設計上意図されている。現行は歴史的経緯で動詞の配置が分散している:

  • felis (bare) / felis attach <id> / felis -- <cmd> → window launch (exec felis-client)
  • felis sessions {list,info,spawn,send,capture,search,kill,evict,switch,switch-all,retarget-all,tag} → headless
  • felis window retarget (+ alias felis ssh <dest>) → headlessだが対象は window
  • felis frontend <name> → exec
  • felis daemon status / felis config {path,check,show-effective} / felis doctor / felis bridge / felis notifications subscribe

control-surfaces.mdcli.md に意図的な asymmetry として文書化されているが、1.0 で凍結する前に一貫性を再評価したい。

現状の問題 / 凍結前に決めるべき点

1. 名詞階層の不統一

  • attach はトップレベルだが switchsessions 配下。attachsessions の一員に見えるが、実際は window launch(GUI exec)で sessions switch は IPC push。ユーザからは「session を attach/switch する」という同一対象に見えるのに階層が違う。
  • window retargetwindow 名前空間だが sessions retarget-allsessions 配下。同一操作(carrier への re-dial)の scope 違いで名前空間が分かれる。
  • daemon status はトップレベルだが sessions list は daemon の roster 取得。daemon オブジェクトと sessions オブジェクトの線引きが曖昧。
  • notifications subscribe がトップレベル notifications 名詞なのは、wire 上 Observer モードが独立しているためだが、CLI からは sessions 由来のイベントに見える。

問い: 1.0 では felis {sessions,window,daemon,config,doctor} の名詞分割をこのまま凍結するか? 代替案:

  • felis session {attach,list,spawn,...} (単数) に統一し、felis window {attach,retarget}felis session {attach,retarget} に統合。
  • あるいは felis daemon {sessions, status} のように daemon 所有物を明確化。

2. alias felis ssh <dest>

window retarget --host の permanent alias として凍結すると宣言されている。小文字の ssh が felis のサブコマンドに見えるのは発見性が高い反面、ssh 本体との混同・--to-socket 等のローカル carrier が alias では使えない非対称が生まれる。1.0 で permanent とするなら ssh(1) との衝突を許容する決定として記録が必要。

3. frontend <name> の必須名前空間

cargo の implicit external subcommand を拒否し frontend を必須にした安全側の決定は妥当。ただ bare felis が暗黙に felis-client を exec する唯一の例外が残る。1.0 で felis frontend felis を正規形にするか、現行の「bare = default frontend」糖衣を維持するか。

4. exit code 1 / 2 の二分

0 成功 / 1 domain failure / 2 unreachable+usage error の三分は cli.md で厳密。ただし searchnotifications subscribe --once が grep-shaped で 1 を「見つからなかった」に使う例外がある。スクリプトから 1 が二義的になる。一般の Unix と同様に許容するか、machine output の event で判断させる形に統一するか。

5. --format human|json|jsonl のクラス固定

Point は json のみ、Stream は jsonl のみという verb クラス固定は設計として強い。将来 listjson を許す余地を完全に閉じる決定でもある。--json 単一フラグを意図的に拒否しているが、1.0 でこのまま誤用を exit 2 にするか。

提案

  • 互換性を無視できる今のうちに、名詞階層を一枚の表で再設計し reference/cli.mdreference/control-surfaces.md の「Deliberate asymmetries」節を「1.0 で凍結した決定」として書き直す。
  • ssh alias を残すなら control-surfaces.md に「なぜ ssh が permanent か」の根拠を追記し、--to-socket が alias で使えないことを cli.md の usage error 表に明記(現状はされているが、1.0 の alias 契約として再確認)。
  • exit code の grep-shaped 例外を cli.md の冒頭テーブルに脚注ではなく独立した行として昇格させ、スクリプトは terminal object を見るべきことを doctorfailed カウントと同様に強調。

判定基準

  • 新しい名詞割当が control-surfaces.md の placement criterion(window 無し → CLI verb / 恒久的宣言 → config / 対話的 → keymap / 子環境 → env)に照らして一意に決まること。
  • fj issue searchfelis --help の出力が、初見ユーザが「どの名詞の下を探せばいいか」を推測できること。

cc @natsukium

## 背景 felis の CLI は5つの control surface(CLI / config / keymap / env / wire)のうち「CLI」として薄いラッパであることが設計上意図されている。現行は歴史的経緯で動詞の配置が分散している: - `felis` (bare) / `felis attach <id>` / `felis -- <cmd>` → window launch (exec `felis-client`) - `felis sessions {list,info,spawn,send,capture,search,kill,evict,switch,switch-all,retarget-all,tag}` → headless - `felis window retarget` (+ alias `felis ssh <dest>`) → headlessだが対象は window - `felis frontend <name>` → exec - `felis daemon status` / `felis config {path,check,show-effective}` / `felis doctor` / `felis bridge` / `felis notifications subscribe` `control-surfaces.md` と `cli.md` に意図的な asymmetry として文書化されているが、1.0 で凍結する前に一貫性を再評価したい。 ## 現状の問題 / 凍結前に決めるべき点 ### 1. 名詞階層の不統一 - `attach` はトップレベルだが `switch` は `sessions` 配下。`attach` も `sessions` の一員に見えるが、実際は window launch(GUI exec)で `sessions switch` は IPC push。ユーザからは「session を attach/switch する」という同一対象に見えるのに階層が違う。 - `window retarget` は `window` 名前空間だが `sessions retarget-all` は `sessions` 配下。同一操作(carrier への re-dial)の scope 違いで名前空間が分かれる。 - `daemon status` はトップレベルだが `sessions list` は daemon の roster 取得。`daemon` オブジェクトと `sessions` オブジェクトの線引きが曖昧。 - `notifications subscribe` がトップレベル `notifications` 名詞なのは、wire 上 Observer モードが独立しているためだが、CLI からは `sessions` 由来のイベントに見える。 **問い:** 1.0 では `felis {sessions,window,daemon,config,doctor}` の名詞分割をこのまま凍結するか? 代替案: - `felis session {attach,list,spawn,...}` (単数) に統一し、`felis window {attach,retarget}` を `felis session {attach,retarget}` に統合。 - あるいは `felis daemon {sessions, status}` のように daemon 所有物を明確化。 ### 2. alias `felis ssh <dest>` `window retarget --host` の permanent alias として凍結すると宣言されている。小文字の `ssh` が felis のサブコマンドに見えるのは発見性が高い反面、`ssh` 本体との混同・`--to-socket` 等のローカル carrier が alias では使えない非対称が生まれる。1.0 で permanent とするなら `ssh(1)` との衝突を許容する決定として記録が必要。 ### 3. `frontend <name>` の必須名前空間 cargo の implicit external subcommand を拒否し `frontend` を必須にした安全側の決定は妥当。ただ bare `felis` が暗黙に `felis-client` を exec する唯一の例外が残る。1.0 で `felis frontend felis` を正規形にするか、現行の「bare = default frontend」糖衣を維持するか。 ### 4. exit code 1 / 2 の二分 `0` 成功 / `1` domain failure / `2` unreachable+usage error の三分は `cli.md` で厳密。ただし `search` と `notifications subscribe --once` が grep-shaped で `1` を「見つからなかった」に使う例外がある。スクリプトから `1` が二義的になる。一般の Unix と同様に許容するか、machine output の `event` で判断させる形に統一するか。 ### 5. `--format human|json|jsonl` のクラス固定 Point は `json` のみ、Stream は `jsonl` のみという verb クラス固定は設計として強い。将来 `list` に `json` を許す余地を完全に閉じる決定でもある。`--json` 単一フラグを意図的に拒否しているが、1.0 でこのまま誤用を `exit 2` にするか。 ## 提案 - 互換性を無視できる今のうちに、名詞階層を一枚の表で再設計し `reference/cli.md` と `reference/control-surfaces.md` の「Deliberate asymmetries」節を「1.0 で凍結した決定」として書き直す。 - `ssh` alias を残すなら `control-surfaces.md` に「なぜ `ssh` が permanent か」の根拠を追記し、`--to-socket` が alias で使えないことを `cli.md` の usage error 表に明記(現状はされているが、1.0 の alias 契約として再確認)。 - exit code の grep-shaped 例外を `cli.md` の冒頭テーブルに脚注ではなく独立した行として昇格させ、スクリプトは terminal object を見るべきことを `doctor` の `failed` カウントと同様に強調。 ## 判定基準 - 新しい名詞割当が `control-surfaces.md` の placement criterion(window 無し → CLI verb / 恒久的宣言 → config / 対話的 → keymap / 子環境 → env)に照らして一意に決まること。 - `fj issue search` や `felis --help` の出力が、初見ユーザが「どの名詞の下を探せばいいか」を推測できること。 cc @natsukium
Author
Owner

Superseded by the implementation-sized v0.1.0 work in #23, with bridge/schema follow-through in #21 and #29. #12 is now the release tracker; this issue remains as review history.

Superseded by the implementation-sized v0.1.0 work in #23, with bridge/schema follow-through in #21 and #29. #12 is now the release tracker; this issue remains as review history.
Sign in to join this conversation.
No description provided.