diff --git a/README.md b/README.md index 1e79be7..a91a5a0 100644 --- a/README.md +++ b/README.md @@ -68,7 +68,15 @@ npm run tauri dev 右の参加者パネルは**一つのリスト**です。部屋にいる参加者と、まだ起動していないアカウント(「未起動」)が、種別ごとのグループに分かれて並びます(`user — 1` / `AI — 2` のように、件数も出ます)。名前はその参加者の色で出ます。居ない相手は色を保ったまま薄くなり、点が塗りから輪郭に変わります。自分の行には「(あなた)」が付きます。 -端末を持っているアカウントの行を押すと、その端末が診断面に出ます。行の「終了」でそのアカウントのセッションを終了できます。終了は二度押しです——一度目でボタンが「本当に終了」に変わり、数秒で戻ります。未起動のアカウントの行に端末の操作は出ません。 +端末を持っているアカウントの行を押すと、その端末が診断面に出ます。 + +行の右側に操作が二つ並びます。**一つ目がセッションの開始と終了、二つ目が編集です。** 位置は行の状態で変わりません。種別 `AI` のアカウントには、未起動なら「開始」、稼働中なら「終了」が同じ場所に出ます。種別 `user`(人間)のアカウントは起動しないので、一つ目は空のままです——その行の「編集」も他の行と同じ位置に並びます。 + +「開始」は一度押しです。「終了」は二度押しで、一度目でボタンが「本当に終了」に変わり、数秒で戻ります。取り消せない操作だけが二度押しです。 + +「開始」を押してから起動が返るまで、その行の「開始」は押せなくなり、名前の隣に「起動中」と出ます。起動に失敗した場合は「起動失敗」と出て、理由はマウスを乗せると読めます(全文は画面下の status 行に出ます)。この表示は、次にそのアカウントの「開始」を押すまで残ります。 + +未起動のアカウントの行に端末の操作は出ません。 リストの下にセッションの裏の値(部屋ソケット、セッションの生死、接続方法、起動コマンド、作業ディレクトリ、開始時刻、ウィンドウ)が出ます。部屋ソケット以外は、選んでいる端末のアカウントのものです。宛先に選べるのは部屋に居る参加者だけで、未起動のアカウントは出ません。 @@ -78,7 +86,7 @@ npm run tauri dev この端末は表示と操作のためのものです。ここに映る内容が部屋の発言になることはありません。部屋に並ぶのは channel 経由の発言だけです。 -アカウントを選び「セッション参加」を押すと、次の 2 つが行われます。 +アカウントの行の「開始」を押すと、次の 2 つが行われます。 1. そのアカウントの作業ディレクトリの `.mcp.json` へ、部屋のサイドカーを `pullcept-room--` という名前で登録します。**既存の内容はマージして保持します**が、あなたのリポジトリのファイルを書き換える操作です。登録鍵はアカウント id から決まります。アカウントごとに分けているのは同じ作業ディレクトリへ 2 つのセッションを立てたときに互いの登録を潰さないためで、名前ではなく id から導くのは改名で鍵が動かないようにするためです。前回の起動で書かれたエントリ(もう繋がらないポートを指しているもの)は、このとき掃除します。 2. `--dangerously-load-development-channels server:pullcept-room--` を付けて CLI を PTY 上の対話セッションとして起動します。 diff --git a/docs/0-requirements.md b/docs/0-requirements.md index 50d8a4e..097bd7c 100644 --- a/docs/0-requirements.md +++ b/docs/0-requirements.md @@ -300,9 +300,32 @@ liplus-desktop の `stream_parser.rs` および `spawn_stream_pty` / `spawn_stre **行の見え方。** 名前はその参加者の色で表示する。オフラインの行は色を保ったまま薄くし、点を塗りから輪郭へ変える。灰色に落として色を捨てない——色はアカウントの同一性を担っており、居ないだけで別人に見えるのは誤りである。行が示す補足は、この画面の本人なら「(あなた)」、席の無いアカウントなら「未起動」、セッションが終了して出力だけ残っているなら「終了」である。アバターは持たない。 -**行にアカウントの操作が乗る。** 端末を持つアカウントの行は、クリックで診断面の表示をその端末へ切り替える。行には「編集」(下記のモーダルを開く)が付き、稼働中であれば「終了」が付く。行の鍵がアカウント id であることが、行に操作を載せられる条件である——名前で突き合わせると、二つのアカウントが同じ名前を名乗った時点で別の行に当たる。 +**行にアカウントの操作が乗る。** 端末を持つアカウントの行は、クリックで診断面の表示をその端末へ切り替える。行の鍵がアカウント id であることが、行に操作を載せられる条件である——名前で突き合わせると、二つのアカウントが同じ名前を名乗った時点で別の行に当たる。 -端末を持たないアカウントに端末の操作は出ない。未起動のアカウントに出せる端末の操作は無い(#57 の条件を維持)。 +**セッションの開始と終了は、同じ列の同じ場所にある。** 一つのライフサイクルの両端であり、離して置く理由が無い。終了が行に来たのは #57 だが、開始は会話面の上のランチャ行に残っていた(#62 で移した。下記「ランチャ行は無い」)。 + +**行の操作は名前の後ろの二列である。一列目がライフサイクル、二列目が編集。** 列は行の状態で動かない。以前の並びは「編集」「終了」であり、終了が稼働中の行にしか出ないため、未起動の行では編集が左へずれていた。 + +- 一列目 = 「開始」または「終了」。種別 `ai` のアカウントの行にだけ出る。 +- 二列目 = 「編集」。アカウントを持つ行には常に出る。 +- **列は中身の有無に依らず幅を持つ。** ライフサイクルを持たない行——種別 `user`、および端末の操作を持たない行——も列を閉じない。閉じれば編集がその行だけ左へ寄る。 + +armed の「本当に終了」は「終了」より広く、その幅は名前の側へ伸びる。編集の位置は動かない。ライフサイクルの列を armed の幅に固定する形は採らない——パネルは 16.5rem しかなく、実測では本人の行の名前(「マスター」+「(あなた)」)が出なくなる。四秒間の一行のために、リスト全行の名前の幅を払うことになる。 + +端末を持たないアカウントに端末の操作は出ない。未起動のアカウントに出せる端末の操作は無い(#57 の条件を維持)。開始はこれに含まれない——端末の操作ではなく、端末を作る操作である。 + +**種別 `user` の行にライフサイクルは無い。** 人間は起動されるものではなく、`start_session` が既に拒否している(上記「アカウント」)。列は空のまま残り、その行の編集は他の行と同じ位置に並ぶ。 + +**開始は 2 段階にしない。** 終了が二度押しなのは取り消せないためである(下記「診断面」)。開始は取り消せる——間違えて始めたセッションは、その場所を引き継ぐ終了が終わらせる。取り消せる操作に arm を付けると、undo が効く失敗を防ぐために全ての意図的な操作が二度押しになる。 + +**起動中と起動失敗は行が読める。** 押した直後から起動が返るまで、その行の開始は押せなくなる。状態の語は名前の隣の note に入る——「未起動」「終了」と同じ場所であり、note は状態を、ボタンは行為を言う。 + +| note | 行の状態 | +|---|---| +| 起動中 | 開始を押し、起動がまだ返っていない | +| 起動失敗 | 直前の起動が失敗した。理由は `title`、全文は status 行 | + +起動に失敗した端末は破棄される(下記「診断面」)。行に残さなければ、押したこと自体が画面から消え、行は押される前と同じ「未起動」へ戻る。この記録は次にそのアカウントの開始が押された時点で消える——失敗が消えるのは、同じ問いがもう一度立てられた時である。 **宛先の選択肢は増えていない。** オフラインの行は部屋の名簿に居ないため、宛先には出ない。届かない相手を名指せる状態は、宛先を名簿から引くという判断(#43)の理由に反する。 @@ -380,7 +403,7 @@ liplus-desktop の `stream_parser.rs` および `spawn_stream_pty` / `spawn_stre 実際に起動する行は画面に表示する。書いた行と走る行が違う以上、結果を見せるほうが説明より安い。表示は起動オプションの欄の隣、つまりモーダルの中に置く。編集している欄の隣であることが条件であり、欄が移れば表示も移る。名前の欄を編集しても表示は動かない。エントリ名がアカウント id から決まるためであり、これは要点である——起動しているのはアカウントであって、改名はそれを別のものにしない。 -表示は省略記号で切らずに折り返す。切れる末尾はアプリが統合した channel エントリであり、そこが「書いた行と走る行が違う」ことの中身である。一行のランチャ行には縦の余裕が無かったが、モーダルにはある。 +表示は省略記号で切らずに折り返す。切れる末尾はアプリが統合した channel エントリであり、そこが「書いた行と走る行が違う」ことの中身である。一行のランチャ行には縦の余裕が無かったが、モーダルにはある(ランチャ行そのものは #62 で無くなった。下記「ランチャ行は無い」)。 **実測済み(2026-08-21)**: 複数の channel サーバを同時に有効化した状態で往復が成立した。`--print` での確認は無意味である(channel の読み込み自体が走らないため)ことも実測しており、確認は対話セッションでのみ可能。 @@ -408,7 +431,7 @@ liplus-desktop の `stream_parser.rs` および `spawn_stream_pty` / `spawn_stre 本人のアカウントは削除できず、種別も `user` から変えられない。部屋に居ることが「ここに居る」ことそのものであり、削除すれば居るための何かが無くなる。種別を変えれば、本人が AI の見出しの下に並び、その名前で CLI を起動する選択肢が出る。 -種別 `user` のアカウントは起動しない。人間の下に spawn する CLI は無く、`start_session` が拒否する。ランチャの選択肢にも出さない——拒否が唯一の知る手段になるのは、拒否の使い方として誤りである。稼働中のアカウントの種別は変更できない。そのセッションが起動した作業ディレクトリと起動オプションを、動いている最中に捨てることになるためである。 +種別 `user` のアカウントは起動しない。人間の下に spawn する CLI は無く、`start_session` が拒否する。その行に開始も出さない——拒否が唯一の知る手段になるのは、拒否の使い方として誤りである。稼働中のアカウントの種別は変更できない。そのセッションが起動した作業ディレクトリと起動オプションを、動いている最中に捨てることになるためである。 **名前は人間が読んで選ぶものである。** UUID などの機械的な一意化で置き換えない。宛先の選択肢に出るのはこの名前であり、そこから 1 名を選べることが目的である。id が機械的な一意性を担うのは、名前をその責務から解放するためである。新規アカウントの既定名は既存と重ならない番号を取る——既定値が同じ名前の参加者を並べるのでは、#40 の欠陥を既定で再現することになる。 @@ -428,7 +451,19 @@ liplus-desktop の `stream_parser.rs` および `spawn_stream_pty` / `spawn_stre 削除はモーダルの中にあり、終了と同じ 2 クリックを取る。一度目は武装するだけで、二度目が実行する。稼働中のアカウントと、この画面の本人のアカウントは削除を拒否する。 -**ランチャ行に残すのはアカウントの選択と参加のみである。** 「どのアカウントで参加するか」と「このアカウントの設定を編集する」は別の行為であり、種別が増えたことで分ける理由がさらに増えた。名前・色・作業ディレクトリ・起動オプションはモーダルにある。タイトルバーが持っていた本人の名前と色の欄も外した——本人がアカウントになった以上、同じ 2 値を編集する面が二つ並ぶことになる。`+` はアカウントが並ぶリストの見出しの隣に置く。作るものが現れる場所の隣であって、起動する行の上ではない。 +#### ランチャ行は無い + +会話面の上に、アカウントの選択と参加だけを持つ行があった。#59 が名前・色・作業ディレクトリ・起動オプションをモーダルへ移した結果、残ったのは `` で機能的に等価であり、形の差は追っていない。アカウントの側はキャンバスが実装より大きく遅れており、差は #46 で追う。 +- **次の一手** — 現在の実装に参加者パネルと宛先を足した、実装可能な範囲。両方とも実装済みである。この 1 枚と実装の差は、操作ボタンのうち未実装のリサイズとミュート(端末と終了は実装済みで、参加者のリストの各行に載っている)、宛先の見た目(削除可能なチップ)、そして #53 / #57 / #59 / #62 で入ったアカウントまわり(種別ごとのグループ、行の開始・終了・編集、モーダル、ランチャ行の廃止)である。宛先は ` - - -
@@ -92,7 +82,13 @@ Grouped by the kind declared when the account was made. An account that is not running is still someone, so it is listed dimmed rather than left out (#53); it is still not offered as an addressee, - because a name that cannot be reached is not one worth naming. --> + because a name that cannot be reached is not one worth naming. + + The row carries the session's whole lifecycle. 開始 was on a row of + its own above the conversation until #62, which put the two ends of + one thing on two surfaces; 終了 had already moved here (#57). The + row is two fixed columns after the name — the lifecycle, then 編集 — + so neither moves when a session starts or ends. -->