Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,28 @@ comparator, and the alias rules all live in `provider-presets.ts` and are unit-t
without React. The component test covers: a query with zero hits in the active tab
leaves `tier` untouched; tab click with a non-empty query does not clear the query; an
in-flight Accounts login keeps its `LoginHint` and paste field across a chip click.

## What changed against this doc during the build

Five things the plan did not anticipate, each found by an independent reviewer or by
driving the surface:

- **The group heading is not sticky.** A sticky bar needs an opaque background, and
`.modal-card` is a translucent glass panel, so it seamed against the card behind it —
and it read as a grey slab. It is now a small-caps `<h4>` with a hairline rule that
scrolls with the content; the chips above are already the index.
- **The chip lookup cannot use `CSS.escape`.** Group ids come from `useId`, which emits
colons, so selecting on one needs `CSS.escape` — and `CSS` does not exist in the
happy-dom environment the GUI tests run in, so a chip click would have thrown
`ReferenceError` on CI rather than merely being untested. The heading carries a
`data-catalog-group` attribute instead.
- **The jump scrolls the list itself**, and focuses with `preventScroll`. `.modal-card`
is also a scroll container, so both `scrollIntoView` and a plain `focus()` could drag
the search field out of view while jumping between groups.
- **Loading and empty states key off what is actually on screen.** Using the total match
count meant the unfiltered Accounts bucket — which almost always holds an OpenAI login
row — kept a still-loading Free tab from ever saying it was loading. `visibleCount` is
the selected tab's own row count while browsing.
- **The login/preset dedupe is a named helper**, `dropPresetsCoveredByAccounts`, rather
than a `Set` inside the memo, so the rule that a login row outranks a preset of the
same id has its own unit test.
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# 060 — Delivery record

Four dependent pull requests onto `dev`, one per work phase, every push `--no-verify`,
no local test suite run at any point. Verified 2026-09-12.

| PR | branch | base | head | live CI run |
|---|---|---|---|---|
| #4324 | `codex/provider-catalog-plan` | `dev` | `67657b9655` | `34666254983` success |
| #4325 | `codex/provider-catalog-local-tab` | #4324 head | `7ae08971c7` | `34668670304` success |
| #4328 | `codex/provider-catalog-note-popup` | #4325 head | `e3fdf8fd26` | `34668670844` success |
| #4331 | `codex/provider-catalog-unified-search` | #4328 head | `68e6b028d7` | `34668669980` success |

Ancestry is a real chain, checked with `git merge-base --is-ancestor`:
`67657b9655` ⊂ `7ae08971c7` ⊂ `e3fdf8fd26` ⊂ `68e6b028d7`. Each PR's diff against its
own base carries only that phase's work; no parent commit is replayed.

## Two CI facts that are easy to misread

**Cancelled duplicate runs leave FAILURE rows on a live head.** Pushing the rebased
chain started overlapping workflow runs, and the concurrency group cancelled the older
ones. A cancelled run's `ci` aggregator concludes *failure* with
`needed job(s) did not pass: changes=cancelled`, and that row stays attached to the same
head SHA as the live green run. On `e3fdf8fd26` the failing `ci` is job `103485691739`
on cancelled run `34668670665`; the live aggregator `103488063420` on `34668670844`
succeeded. Read the run, not the rollup.

**A cancelled required check is not a passing one.** All three `enforce-target`
attempts on `e3fdf8fd26` were cancelled the same way, which left #4328 `UNSTABLE` even
though its product CI was green — `gh pr checks` maps a cancelled required check to
fail. Re-running `34668680065` produced a success on that exact head and the PR went
`CLEAN`. This was found by an independent auditor, not by reading the rollup.

#4324 reports `BLOCKED` because `dev` requires a pull-request review; that is branch
protection, not a check failure.

## What CI proved that local runs did not

The test suite was never run in this worktree, by instruction. Two defects were caught
that a local run would have caught instantly, and both were found by static review
instead:

- `CSS.escape` in the chip jump would have thrown `ReferenceError` under bun/happy-dom,
taking the new chip test red. Replaced with a `data-catalog-group` attribute lookup
before it ever reached CI.
- A third defect did reach CI: `gui/tests/fr-localization.test.ts` rejects a French
value identical to its English source, and `modal.tab.local` is `"Local"` in both.
"Local" is genuinely the same word in French and the Local *badge* was already on that
allowlist, so the tab joined it. Fixed at the root of the stack and the two children
were rebased onto it, which is why #4328 and #4331 were force-pushed once.

Local checks that were run: `bun x tsc --noEmit`, `cd gui && bun x tsc --noEmit -p
tsconfig.json`, and `bun run structure:check`. Everything else is **NOT RUN** locally.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion docs-site/src/content/docs/guides/web-dashboard.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ badge or the version value to read the full value.
| **Windows tray** | Install a per-user login tray for one-click proxy start, stop, restart, dashboard access, and status. The tray is a controller, not a proxy restart service. |
| **Codex autostart** | Allow an already-installed Codex launcher shim to run `ocx ensure`. This toggle does not install a shim or background service. |
| **Providers** | Add, edit, set the default (enabled providers only), enable/disable, and remove providers; manage OAuth account pools and API-key pools where supported. Removing the current default switches to the first remaining enabled provider when one exists; otherwise deletion is refused and the current default is kept. Provider Settings can disable live model discovery for endpoints with missing, slow, or oversized `/models` catalogs. For Claude (Anthropic) OAuth pools, each logged-in account shows its own 5-hour and weekly rate-limit bars (usage is per credential); a failed probe keeps the last-known bars and marks them unavailable until the next successful refresh. The Provider Overview shown when no provider is selected carries a **Refresh all quotas** control that forces one server-side re-read of every configured provider; a provider whose upstream probe fails keeps its last-good row, so the status line reports that the check completed rather than claiming every value is fresh, and each row's own age stays the per-provider freshness signal. |
| **Add provider** | Search registry-backed presets for account login, API-key services, local servers, or a custom endpoint. |
| **Add provider** | One search above the tabs reaches all four at once — Accounts, Free, Local, Paid. While a query is live the results are grouped by tab with a count each, and the selected tab stays put rather than jumping. Local runtimes (Ollama, vLLM, LM Studio, LiteLLM) have their own tab, and a long provider note clamps to two lines with the full text one click away. |
| **Codex Auth** | Add ChatGPT/Codex pool accounts, select the next-session account, refresh 5h / weekly / 30d quotas, enable or disable quota auto-switch, set its 1–100% threshold, and configure transient-failure failover. |
| **Subagents** | Feature up to five bare native or namespaced routed models in the `spawn_agent` override list. |
| **Models** | Toggle native GPT and routed models, set provider allowlists and context caps, choose v1/base/v2, and configure the v2 thread limit. Configured providers stay visible as zero-model groups when discovery is off or returns no rows. |
Expand Down
2 changes: 1 addition & 1 deletion docs-site/src/content/docs/ko/guides/web-dashboard.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ bun run dev:gui
| **Windows 트레이** | 로그인할 때 사용자 전용 트레이를 시작하고 프록시 시작·중지·재시작·대시보드·상태를 클릭으로 제어합니다. 트레이는 재시작 서비스가 아닙니다. |
| **Codex 자동 시작** | 이미 설치된 Codex launcher shim이 `ocx ensure`를 실행하도록 허용합니다. 이 토글은 shim이나 백그라운드 서비스를 설치하지 않습니다. |
| **Providers** | 프로바이더를 추가, 편집, 기본으로 설정(활성만), 활성화/비활성화, 제거하고, 지원되는 OAuth 계정 풀과 API key 풀을 관리합니다. 현재 기본 프로바이더를 제거하면 남아 있는 첫 번째 활성 프로바이더로 전환됩니다(있는 경우); 없으면 삭제가 거부되고 현재 기본이 유지됩니다. Claude(Anthropic) OAuth 풀에서는 로그인한 계정마다 자체 5시간·주간 한도 막대가 표시되며(사용량은 자격 증명 단위), 조회 실패 시 마지막 값을 유지하고 일시 불가 상태로 표시합니다. 프로바이더를 선택하지 않았을 때 보이는 Provider Overview에는 **전체 할당량 갱신** 버튼이 있어 설정된 모든 프로바이더를 서버에서 한 번에 다시 읽습니다. 조회에 실패한 프로바이더는 마지막 값을 유지하므로, 상태 문구는 모든 값이 새로 왔다고 말하지 않고 조회가 끝났다고만 알리며, 각 행의 확인 시각이 프로바이더별 신선도를 보여 줍니다. |
| **Add provider** | 레지스트리 기반 프리셋에서 계정 로그인, API key 서비스, 로컬 서버, custom endpoint를 검색합니다. |
| **Add provider** | 탭 위의 검색창 하나가 계정·무료·로컬·유료 네 탭을 한 번에 찾습니다. 검색 중에는 선택한 탭이 움직이지 않고, 결과를 탭별로 묶어 개수와 함께 보여 줍니다. 로컬 런타임(Ollama, vLLM, LM Studio, LiteLLM)은 별도 탭을 쓰며, 긴 설명은 두 줄로 줄고 클릭하면 전체가 열립니다. |
| **Codex Auth** | ChatGPT/Codex 풀 계정을 추가하고, 다음 세션 계정을 선택하고, 5시간 / 주간 / 30일 할당량을 갱신하며, 할당량 자동 전환을 켜거나 끄고 1~100% 임계값과 일시적 실패 failover를 설정합니다. |
| **Subagents** | `spawn_agent` override 목록에 네이티브 또는 라우팅 모델을 최대 5개까지 우선 노출합니다. |
| **Models** | 네이티브 GPT와 라우팅 모델을 켜고 끄고, 프로바이더 allowlist와 컨텍스트 상한, v1/base/v2, v2 thread 수를 설정합니다. |
Expand Down
2 changes: 1 addition & 1 deletion docs-site/src/content/docs/ru/guides/web-dashboard.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ bun run dev:gui
| **Трей Windows** | Устанавливает пользовательский значок входа для запуска, остановки, перезапуска, панели и состояния прокси одним щелчком. Трей не является службой перезапуска. |
| **Автозапуск Codex** | Разрешает уже установленному launcher shim Codex выполнять `ocx ensure`. Переключатель не устанавливает shim или фоновую службу. |
| **Providers** | Добавление, редактирование, назначение провайдера по умолчанию (только включённые), включение/отключение и удаление провайдеров; управление пулами OAuth-аккаунтов и пулами API-ключей там, где они поддерживаются. При удалении текущего провайдера по умолчанию выбирается первый оставшийся включённый провайдер, если он есть; иначе удаление отклоняется и текущий default сохраняется. Для пулов Claude (Anthropic) OAuth у каждого вошедшего аккаунта свои полосы 5-часового и недельного лимита (использование по учётным данным); при сбое опроса сохраняются последние известные значения с пометкой недоступности. Обзор Providers, который показывается, когда провайдер не выбран, содержит кнопку **Обновить все квоты**: она принудительно перечитывает на сервере все настроенные провайдеры за один раз. Провайдер с неудачным опросом сохраняет последнее известное значение, поэтому статус сообщает лишь о завершении проверки, а не о том, что все значения свежие; время проверки в каждой строке остаётся признаком актуальности для конкретного провайдера. |
| **Add provider** | Поиск по пресетам из реестра: вход по аккаунту, сервисы с API-ключом, локальные серверы или пользовательская конечная точка. |
| **Add provider** | Одно поле поиска над вкладками ищет сразу по всем четырём — Аккаунты, Бесплатные, Локальные, Платные. Во время поиска выбранная вкладка не переключается, а результаты группируются по вкладкам с количеством. У локальных сред выполнения (Ollama, vLLM, LM Studio, LiteLLM) своя вкладка, а длинное описание сворачивается до двух строк и открывается целиком по клику. |
| **Codex Auth** | Добавление аккаунтов пула ChatGPT/Codex, выбор аккаунта для следующей сессии, обновление квот 5 ч / недельных / 30-дневных, включение или отключение автопереключения, настройка его порога 1–100% и failover при временных сбоях. |
| **Subagents** | Выделение до пяти «голых» нативных или маршрутизируемых моделей с пространством имён в списке переопределений `spawn_agent`. |
| **Models** | Включение и отключение нативных GPT и маршрутизируемых моделей, настройка списков разрешённых провайдеров и лимитов контекста, выбор v1/base/v2 и настройка лимита потоков v2. |
Expand Down
2 changes: 1 addition & 1 deletion docs-site/src/content/docs/zh-cn/guides/web-dashboard.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ bun run dev:gui
| **Windows 托盘** | 安装用户登录托盘,一键控制代理启动、停止、重启、面板和状态。托盘不是代理重启服务。 |
| **Codex 自动启动** | 允许已安装的 Codex launcher shim 运行 `ocx ensure`。此开关不会安装 shim 或后台服务。 |
| **Providers** | 添加、编辑、设为默认(仅已启用)、启用/禁用、删除 provider,并在支持时管理 OAuth 账号池和 API key 池。删除当前默认时,会切换到剩余的第一个已启用 provider(若存在);否则拒绝删除并保留当前默认。Claude(Anthropic)OAuth 池中,每个已登录账号显示各自的 5 小时与周限额条(用量按凭证计);探测失败时保留上次已知数值并标记为暂时不可用。 未选中任何 provider 时显示的 Providers 概览带有**刷新全部额度**按钮,会在服务端一次性重新读取所有已配置的 provider;上游探测失败的 provider 会保留上次已知数值,因此状态文案只表示检查已完成,而不声称每个数值都是最新的,各行自身的检查时间仍是该 provider 的新鲜度信号。 |
| **Add provider** | 搜索 registry preset,选择账号登录、API key 服务、本地服务器或自定义 endpoint。 |
| **Add provider** | 标签页上方的单个搜索框可同时搜索账号、免费、本地、付费四个标签页。搜索时选中的标签页不会跳转,结果按标签页分组并显示数量。本地运行时(Ollama、vLLM、LM Studio、LiteLLM)拥有独立标签页,过长的说明会截断为两行,点击即可查看全文。 |
| **Codex Auth** | 添加 ChatGPT/Codex 池账号,选择下一 session 的账号,刷新 5h / 每周 / 30d 配额,启用或停用配额自动切换,设置其 1–100% 阈值和临时故障 failover。 |
| **Subagents** | 在 `spawn_agent` override 列表中置顶最多五个原生或路由模型。 |
| **Models** | 开关原生 GPT 与路由模型,配置 provider allowlist、上下文上限、v1/base/v2 以及 v2 thread 数量。 |
Expand Down
2 changes: 1 addition & 1 deletion docs-site/src/content/docs/zh-tw/guides/web-dashboard.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ GUI session 簽發到服務的頁面中,並在到期或代理重啟時靜默
| **Windows 托盤** | 安裝使用者登入托盤,一鍵控制代理啟動、停止、重啟、面板和狀態。托盤不是代理重啟服務。 |
| **Codex 自動啟動** | 允許已安裝的 Codex launcher shim 執行 `ocx ensure`。此開關不會安裝 shim 或後臺服務。 |
| **Providers** | 新增、編輯、啟用/停用、刪除 provider,並在支援時管理 OAuth 帳號池和 API key 池。 |
| **Add provider** | 搜尋 registry preset,選擇帳號登入、API key 服務、本機伺服器或自訂 endpoint。 |
| **Add provider** | 分頁上方的單一搜尋框可同時搜尋帳號、免費、本機、付費四個分頁。搜尋時選取的分頁不會跳轉,結果依分頁分組並顯示數量。本機執行環境(Ollama、vLLM、LM Studio、LiteLLM)有專屬分頁,過長的說明會截斷為兩行,點擊即可查看全文。 |
| **Codex Auth** | 新增 ChatGPT/Codex 池帳號,選擇下一 session 的帳號,重新整理 5h / 每週 / 30d 配額,啟用或停用配額自動切換,設定其 1–100% 閾值和臨時故障 failover。 |
| **Subagents** | 在 `spawn_agent` override 列表中置頂最多五個原生或路由模型。 |
| **Models** | 開關原生 GPT 與路由模型,設定 provider allowlist、上下文上限、v1/base/v2 以及 v2 thread 數量。 |
Expand Down
Loading
Loading