3 つの課題が、いずれも同じ 1 つの関数を書き換える。
| 課題 | 変えるもの | 触る場所 |
|---|---|---|
| i260831-02 | AICHAT_ID → --connector-id |
option() ・ usage() |
| i260901-01 | --retry-count 廃止 → --wait-min / --wait-hour |
option() ・ usage() |
| i260901-02 | AICHAT_URL → --url / --port、短い形 |
option() ・ usage() |
別々に進めると、後の 2 件が前の書き直しになる。option() は --名前 だけを探す作りで、短い形を入れるには別名の表を持つ形へ変える必要がある。3 件のうちどれを先にしても、この書き換えが 1 回目に含まれ、残り 2 件はその上に載る。
課題は 3 件のまま残す。計画だけを 1 本にする。課題は「何を解決するか」の単位、計画は「どう通すか」の単位であり、一致させる必要はない。
テスト用サーバーへ繋いで待受けを張ると、環境変数 2 つとオプション 2 つに分かれる。
$env:AICHAT_ID = 'ai-chat-lite'
$env:AICHAT_URL = 'http://localhost:8765'
node <ai-chat-lite>/src/client/chat.mjs wait --access-token 3f9c1e8a-... --retry-count 120
環境変数はプロセス一覧に出ない。待受けを 4 本起こして PID を照合しようとしたとき、Win32_Process の CommandLine には node ...\chat.mjs wait しか出ず、どれがどれか起動時刻から推測するしかなかった。
| 項目 | 決めたこと |
|---|---|
--retry-count | 廃止する。回数は内部で決める |
--timeout | 内部に隠す。呼ぶ側からは指定しない |
| 待つ長さ | --wait-min と --wait-hour(480 と 8 はどちらも 8 時間) |
| 両方を指定 | エラーにする。足さない・後勝ちにしない |
| 上限なし | 0 を無限とする |
| 既定値 | 8 時間(いまは 480 秒) |
| ログ | 開始 1 行と終了 1 行だけ。240 秒ごとの「新着なし」は出さない |
| 名乗る ID | AICHAT_ID をやめ --connector-id にする。両対応にしない |
| 接続先 | --url と --port を足す。--port は localhost のポートだけを指定する |
| 短い形 | -c -a -r -p -u -w を付ける(-w は --wait-hour) |
| テスト用の指定 | --wait-sec を足す |
--url と --port の同時指定 | エラーにする |
--connector-id の省略 | エラーにする。既定値を持たせない |
AICHAT_URL | 廃止する |
| 一覧の保ち方 | 別名の表から usage() を組み立てる |
| 得られること | 中身 |
|---|---|
| どれが誰か分かる | コマンドラインに出る。環境変数はプロセス一覧に出ない |
| シェルを問わない | bash でも PowerShell でも同じ 1 行。$env: / export / set の分岐が消える |
| 取り違えが減る | 環境変数は同じシェルに前の値が残る。引数なら毎回明示される |
単位を名前に入れずに --wait としてはいけない。いま --timeout は秒なので、秒・分・時が混ざる。名前に単位があれば取り違えない。
分と時しか指定できないと、テストが 1 件も流せない。いまのテストは --timeout 1 --retry-count 3 のように秒で指定して数秒で終わらせている(client-wait.test.mjs 7 件)。既定値が 8 時間になるため、短く待つ手段が無いと 1 件ごとに待たされる。
| 案 | 内容 | 難点 |
|---|---|---|
| A(採る) | --wait-sec を足す。単位は名前に出ている |
指定が 3 通りになる |
| B | 小数を許す(--wait-min 0.05 = 3 秒) |
読んで分からない。テストの意図が伝わらない |
| C | 環境変数でテストだけ long-poll を短くする | 環境変数が増える。本番と違う経路を通る |
案 A に決めた。「単位ごとに 1 つ」という形は --wait-min と --wait-hour を持つと決めた時点で既に選ばれている。3 つ目が増えても規則は変わらず、テストが本番と同じ経路を通る。
--url と --port を同時に指定したときエラーにする。--wait-min と --wait-hour の扱いと揃う。同じ意味を 2 通りで書けるオプションは、すべて同じ規則にした方が覚えることが減る。
頭文字が衝突する。--room と --role はどちらも r、--to と --timeout はどちらも t。大小で分けると(-r と -R)取り違える。
| 短 | 長 | 判断 |
|---|---|---|
-c | --connector-id | 付ける。毎回打つ |
-a | --access-token | 付ける。値が長い |
-r | --room | 付ける。--role には付けない(join でしか使わない) |
-p | --port | 付ける |
-u | --url | 付ける |
-n | --n | すでにある(recent の件数) |
| — | --to --out --role | 付けない。衝突するか、打つ回数が少ない |
-w | --wait-hour | 付ける。3 つとも w で始まるので、時にだけ割り当てる |
| — | --wait-min --wait-sec | 付けない。-w は時が取った |
短い形を全部に付けない。よく打つものだけに付け、残りは長い形だけにする。
-w は --wait-hour に割り当てる。時が既定の単位であり、いちばん打つ。分と秒には短い形を付けない。-w が何の単位かを覚え違えると 60 倍・3600 倍ずれるため、迷ったら長い形を書く。
--connector-id を省略できるか| 案 | 内容 | 難点 |
|---|---|---|
| A(採る) | 必須にする。無ければエラーで止める | 毎回打つ |
| B | 設計どおり path.basename(process.cwd()) を既定にする |
違う場所から叩くと別の名前で参加する。気づきにくい |
案 A に決めた。いまの実装も必須になっている(設計とは食い違っているが、動きとしてはこちら)。名乗る名前は取り違えると他プロジェクトの記録に混ざるので、暗黙の既定値を持たせない方が安全である。設計側の記述を実装に合わせて直す。
| 変数 | いまの用途 | どうするか |
|---|---|---|
AICHAT_ID | 名乗る ID | 廃止(決定済み) |
AICHAT_URL | 接続先 | 廃止する。--url / --port で足りる |
AICHAT_PORT | サーバー側の待ち受けポート | 残す。CLI のものではない |
AICHAT_DATA | サーバー側の置き場 | 残す。同上 |
CLI 側の環境変数は 2 つとも消え、0 になる。サーバー側の 2 つは役目が違うので触らない。
オプション名の一覧は 2 か所にある。放っておくとずれる(実際に usage() の --retry-count と USAGE の --access-token が抜けていた)。
| 案 | 内容 | 難点 |
|---|---|---|
| A(採る) | 別名の表を 1 つ持ち、usage() はそこから組み立てる |
USAGE の HTML は手で揃えたままになる |
| B | USAGE の表も生成する |
HTML を機械が書く仕組みが増える。他が手書きなのに 1 か所だけ生成になる |
| C | 両方とも手で揃える | いまと同じ。また抜ける |
案 A に決めた。短い形を入れるために別名の表はどうせ持つことになる。その表から usage() を組み立てれば、実物とヘルプが食い違うことはなくなる。USAGE は他プロジェクト向けの説明文なので、表だけを機械が書く形にはしない。
テストで守れる。「usage() に出る名前が別名の表と一致する」というテストを 1 件書けば、増やしたときに書き忘れても落ちる。
| いま | あと | 備考 |
|---|---|---|
$env:AICHAT_ID | --connector-id -c | 必須 |
$env:AICHAT_URL | --url -u | 接続先をそのまま |
| — | --port -p | localhost のポートだけ。--url とは併用できない |
--access-token | --access-token -a | 短い形を足すだけ |
--room | --room -r | 同上 |
--timeout | 消える | 内部で 240 秒に固定 |
--retry-count | 消える | 回数は内部で計算 |
| — | --wait-hour | 既定 8。0 で無限 |
| — | --wait-min | 分で指定する |
| — | --wait-sec | テスト・確認用(案 A を採るなら) |
--role --to --out -n | 変えない | 短い形も付けない |
テスト用サーバーへ繋いで 8 時間待つ場合。
いま(PowerShell 専用・3 行)
$env:AICHAT_ID = 'ai-chat-lite'
$env:AICHAT_URL = 'http://localhost:8765'
node ...\chat.mjs wait --access-token 3f9c1e8a-... --retry-count 120
あと(bash でも PowerShell でも同じ 1 行)
node ...\chat.mjs wait -c ai-chat-lite -p 8765 -a 3f9c1e8a-...
--wait-hour は書かない。既定が 8 時間になるため、ふだんの待受けでは省ける。
本番で待受けを張る場合はさらに短くなる。
node ...\chat.mjs wait -c ai-chat-lite
| # | やること | 理由 |
|---|---|---|
| 1 | 別名の表で option() を解決する形に変える |
土台。これが無いと短い形が入らない。この段では動きを変えない |
| 2 | --url / --port を足し AICHAT_URL を廃止 |
接続先が引数になる。テストが叩く経路がここで変わる |
| 3 | --connector-id を足し AICHAT_ID を廃止 |
CLI 側の環境変数が 0 になる |
| 4 | --wait-* を足し --timeout / --retry-count を廃止 |
いちばん動きが変わる。既定値が 480 秒から 8 時間になる |
| 5 | usage() を表から組み立て、一致を守るテストを書く |
ここまでの追加をまとめて反映できる |
| 6 | 資料とルールを直し、他プロジェクトへ周知する | 外に出る変更なので最後にまとめる |
1 段ずつ、その都度テストを全件通す。2〜4 はどれも既存の呼び出しを壊すため、まとめて変えると原因が分からなくなる。
| ファイル | 何を |
|---|---|
src/client/chat.mjs | 本体。option() ・ usage() ・ cmdWait() ・ BASE ・ USER_ID |
tests/client-wait.test.mjs | 7 件。--timeout / --retry-count を使っている |
tests/server.test.mjs | AICHAT_ID を渡している箇所 |
tools/40_test/ | テスト用サーバーの起動と後始末 |
USAGE-FOR-PROJECTS.html | コマンド × オプションの表と例 |
notes/90_rules/test-server.html | --access-token の例 |
notes/10_plan/p260829-01-設計.html | 「無ければ cwd のフォルダ名」を実装に合わせる |
~/.claude/CLAUDE.md | 待受けの例(利用者の指示を待って直す) |
| PlayWright 側 | ACCESS_TOKEN_ARGS と CLI を叩く箇所 |
--wait-min と --wait-hour を同時に指定するとエラーになる--url と --port を同時に指定するとエラーになる0 を渡すと無限に待つ(回数で止まらない)--connector-id を省くとエラーで止まるusage() に出る名前が別名の表と一致する完了 6 段すべてを通した。テストは 153 件から 176 件になり、全件通過している。
| # | やったこと | 結果 |
|---|---|---|
| 1 | 別名の表で解決する形にした | option() が短い形も受ける。定義に無い名前を渡すと例外で止まる。recent の -n だけ個別に見ていた特別扱いを外した |
| 2 | --url / --port を足した |
既定値を持たない。指定が無ければ繋ぐ直前に止まる。AICHAT_URL と AICHAT_PORT はどちらも見ない |
| 3 | --connector-id を足した |
AICHAT_ID を廃止。CLI が読む環境変数は 0 になった |
| 4 | --wait-* に替えた |
既定 8 時間・0 で上限なし・2 つ同時はエラー。ログは開始と終了の 2 行だけ。廃止した --timeout / --retry-count はエラーで知らせる |
| 5 | usage() を表から組み立てた |
定義を src/client/options.mjs に分け、テストが同じ表を読んで表示と突き合わせる(15 件)。-h も足した |
| 6 | 資料を直した | USAGE-FOR-PROJECTS・test-server・この設計。ルールと周知は別に扱う |
| 論点 | 決めたこと |
|---|---|
| 接続先の既定値 | 持たないことにした。計画では「サーバー側と同じ値を見る」としていたが、既定を本番のポートにするとテストのつもりで叩いたものが本番に入る。実際にそれが起きたため、指定を必須にした |
| 警告を出す条件 | 自分で長い設定を書いたときだけ。既定が 8 時間になったので、毎回出すと警告の意味がなくなる |
| 定義の置き場 | options.mjs に分けた。chat.mjs はトップレベルでコマンドを走らせるため import できず、テストから読めなかった |
| 廃止したオプション | 黙って無視せずエラーにした。他プロジェクトの手順に --retry-count 15 が残っており、無視すると待ち時間が効かないまま動く |
-h を先頭に置くとコマンドとして読まれ、終了コード 1 になっていた。const [, , command, ...rest] の分解で旗が command 側に入り、rest を見ていた判定が拾えなかった。引数の全体を見る WORDS を用意して直した。廃止オプションの検査も同じ穴を持っていたため併せて直っている。
connector への改名との関係connector への改名は、DB の列名・API のキー・内部の変数名を user_id から connector_id へ変える計画である。この計画とは切り離して進められる。
CLI の名前だけを先に変えてよい。--connector-id で受けた値を内部の USER_ID に渡すだけなので、DB と API はそのまま動く。先に外から見える名前を正しくしておけば、後の改名で他プロジェクトの手順を二度変えずに済む。
ただし who → connectors のコマンド改名はあちらの計画に残す。API のパスと揃えて変える方が筋が通るためである。