[1.0 Review] CLI 動詞・名詞階層と alias / exit code の凍結 #3
Labels
No labels
priority/P0
priority/P1
priority/P2
release/v0.1.0
status/blocked
status/planned
type/bug
type/design
type/test-gap
type/tracker
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
natsukium/felis#3
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
背景
felis の CLI は5つの control surface(CLI / config / keymap / env / wire)のうち「CLI」として薄いラッパであることが設計上意図されている。現行は歴史的経緯で動詞の配置が分散している:
felis(bare) /felis attach <id>/felis -- <cmd>→ window launch (execfelis-client)felis sessions {list,info,spawn,send,capture,search,kill,evict,switch,switch-all,retarget-all,tag}→ headlessfelis window retarget(+ aliasfelis ssh <dest>) → headlessだが対象は windowfelis frontend <name>→ execfelis daemon status/felis config {path,check,show-effective}/felis doctor/felis bridge/felis notifications subscribecontrol-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を必須にした安全側の決定は妥当。ただ barefelisが暗黙にfelis-clientを exec する唯一の例外が残る。1.0 でfelis frontend felisを正規形にするか、現行の「bare = default frontend」糖衣を維持するか。4. exit code 1 / 2 の二分
0成功 /1domain failure /2unreachable+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 で凍結した決定」として書き直す。sshalias を残すならcontrol-surfaces.mdに「なぜsshが permanent か」の根拠を追記し、--to-socketが alias で使えないことをcli.mdの usage error 表に明記(現状はされているが、1.0 の alias 契約として再確認)。cli.mdの冒頭テーブルに脚注ではなく独立した行として昇格させ、スクリプトは terminal object を見るべきことをdoctorのfailedカウントと同様に強調。判定基準
control-surfaces.mdの placement criterion(window 無し → CLI verb / 恒久的宣言 → config / 対話的 → keymap / 子環境 → env)に照らして一意に決まること。fj issue searchやfelis --helpの出力が、初見ユーザが「どの名詞の下を探せばいいか」を推測できること。cc @natsukium
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.