Multi-AI Terminal v0.2.9
v0.2.9 — BAT-aligned provider auth & accounts
Task #23 of the BAT port plan (docs/bat-port-plan.md §4): provider sign-in, credentials, and account handling now follow better-agent-terminal's model.
Codex unified account store
- Capture your current codex login into a sanitized account index (
codex-accounts.json+ per-accountauth.jsonsnapshots), then switch between accounts from Provider Setup. Switching copies onlyauth.jsoninto the sharedCODEX_HOME, drops the live session, and resets the app-server pair — config, sessions, and cache are never touched. - OAuth refresh tokens rotate: switch re-snapshots the outgoing account first, a same-target switch re-captures instead of restoring a stale copy, and the server re-syncs the active account at shutdown.
- Accounts that fail with a canonical auth error are marked needs login (with the reason) and excluded from switching until you sign in again; a successful turn clears the flag unless an API key may have carried it.
- Account ids are locked to a path-safe alphabet at the API, index, and store layers — crafted
auth.jsoncontents cannot escape the store boundary.
OpenAI API key chain
- Set, inspect (presence + source only — never the value), and clear an
OPENAI_API_KEYfor codex: protected file (0600) first, environment fallback, BAT-style. Exec turns inject only the file-sourced key; login children always spawn with the key unset so codex doesn't misclassify the account.
Sign-in hardening
- Sign-in, running turns, and account mutations now mutually refuse while the other is active, with the ceremony reserved synchronously at start.
- Sign-in recipes resolve the managed runtime binaries, and failure excerpts are sanitized (environment values, one-time codes, URLs redacted; capped at 600 chars).
Claude accounts (read-only)
- Provider Setup shows the claude account index (email, subscription, active/default) when present. Read-only — the claude CLI stays the owner of its credentials.
UI
- Provider Setup gains the codex account list (active / needs-login badges, switch, capture, confirmed remove), the API-key row (password input; the key never persists in the page), and the claude read-only list. Fully localized (EN / zh-TW).
Acceptance: three-way review (codex gpt-5.6-sol implementation, Fable 5 gatekeeper fixes, grok 4.5 review — final verdict PASS). Gates: 553 server/shared + 164 web tests, browser smoke 13/13, real codex + claude turn smokes.
v0.2.9 — 供應商登入與帳號管理(BAT 對齊)
BAT 移植計畫任務 #23(docs/bat-port-plan.md §4):供應商登入、憑證與帳號處理全面採用 better-agent-terminal 的模型。
Codex 統一帳號庫
- 可將目前的 codex 登入「擷取」進消毒後的帳號索引(
codex-accounts.json+ 各帳號的auth.json快照),並在供應商設定中切換帳號。切換只複製auth.json到共用CODEX_HOME,同時斷開連線並重置 app-server — 設定檔、工作階段與快取一律不碰。 - OAuth refresh token 會輪替:切換前先回存外送帳號的最新快照;切到目前使用中的帳號時改為重新擷取,不會用舊快照蓋掉新 token;伺服器關閉時也會再同步一次。
- 遇到標準認證錯誤的帳號會標記「需要登入」(附原因)並停用切換,重新登入後恢復;成功回合會清除標記(但設有 API 金鑰時不清除,因為可能是金鑰撐起了該回合)。
- 帳號 id 在 API、索引與帳號庫三層鎖定路徑安全字元 — 偽造的
auth.json內容無法逃出帳號庫邊界。
OpenAI API 金鑰鏈
- 可設定、查看(只顯示有無與來源,絕不顯示值)、清除 codex 用的
OPENAI_API_KEY:保護檔案(0600)優先、環境變數備援,比照 BAT。exec 回合只注入檔案來源的金鑰;登入子程序一律拔除金鑰,避免 codex 誤判帳號型態。
登入強化
- 登入、進行中的回合、帳號操作三者互斥,登入儀式在開始時即同步預約。
- 登入配方改用受管 runtime 解析;失敗摘錄一律消毒(環境值、一次性代碼、URL 皆遮蔽,上限 600 字元)。
Claude 帳號(唯讀)
- 供應商設定會顯示 claude 帳號索引(email、訂閱、使用中/預設)。唯讀 — claude CLI 仍是其憑證的唯一擁有者。
介面
- 供應商設定新增:codex 帳號清單(使用中/需要登入徽章、切換、擷取、二段式移除)、API 金鑰列(密碼欄位;金鑰不會留在頁面中)、claude 唯讀清單。完整雙語(EN / zh-TW)。
驗收:三方審查(codex gpt-5.6-sol 實作、Fable 5 守門修正、grok 4.5 二審 — 最終判決 PASS)。關卡:伺服器/共用 553 + 網頁 164 測試、瀏覽器 smoke 13/13、codex 與 claude 真機回合 smoke。