# Задание A12 (Antigravity Flash, другой ПК): интерфейс и чистка разделов ## Дата поступления 2026-08-23 ## База Проверочный HEAD на момент выдачи: **`cdfd9f1`**. ## Ветка `antigravity/interface-cleanup` ## Кому Быстрая ветка работ. Задачи описаны подробно и не требуют проектных решений — только аккуратное исполнение. --- ## Порядок работы с git — читать первым Прошлый раз работа A9 была готова, но **не отправлена в `origin`**, и трое суток её не существовало для проекта. Чтобы это не повторилось, порядок жёсткий. **Шаг 1. В самом начале — обновить локальную копию из git:** ``` cd <каталог репозитория>; git fetch origin --prune; git status ``` Если рабочее дерево чистое: ``` git checkout main; git pull --ff-only origin main ``` Если есть незакоммиченные правки — сначала сохранить их отдельной веткой, вслепую сбрасывать нельзя. **Шаг 2. Создать ветку от свежего `main` и сразу отправить её:** ``` git checkout -b antigravity/interface-cleanup git push -u origin antigravity/interface-cleanup ``` Пустая ветка в `origin` ничего не ломает и никого не обязывает. Зато с этого момента работа перестаёт зависеть от одного диска. **Шаг 3. Пушить после каждого осмысленного коммита**, не копить. **Шаг 4. В самом конце — обязательный финальный push и проверка, что он прошёл:** ``` git push origin antigravity/interface-cleanup git status git log --oneline -1 origin/antigravity/interface-cleanup ``` Последняя команда должна показать ваш финальный коммит. Если не показывает — push не прошёл, повторить. Зафиксировать фактический `BASE_SHA` через `git rev-parse --short HEAD` и указать его в отчёте. Не считать `cdfd9f1` актуальным автоматически — параллельно идёт A11. --- ## Параллельная работа: строгая граница по файлам Одновременно выполняется **A11** вторым исполнителем. **Ваши файлы:** ``` src/antigravity_provider/router/ui/** src/antigravity_provider/router/model_discovery.py src/antigravity_provider/router/model_discovery_service.py src/antigravity_provider/router/router_config.py src/antigravity_provider/router/auto_assigner.py src/antigravity_provider/router/unified_health.py installer/** tests/test_ui_*.py ``` **Не ваши** (зона A11): `hermes_plugin.py`, `router_engine.py`, `codex_oauth.py`, `profile_manager.py`, `quota_collector.py`, `adapters/**`, `agy_subprocess.py`, `docs/UI_STATE_CONTRACT.md`. Понадобился чужой файл — скажите, будет заказан отдельно. --- ## Что принято по A9 Проверено исполнением, работа хорошая: миграция конфигурации подняла 16 профилей до 22, `claude` и `grok` получили слоты, резервная копия создаётся, десять профилей владельца не тронуты, комментарии не потеряны, флаг `/reinstall` заработал, предупреждение CS0219 исчезло. **Один урок, который стоит запомнить.** Служба обнаружения моделей была написана правильно, но **недостижима**: файл назван `model_discovery_service.py`, а интерфейс импортирует `model_discovery`. Импорт в `ui/model_catalog.py` обёрнут в `except ImportError`, поэтому ошибки не возникало — выбор моделей просто оставался пустым навсегда, с надписью «Список моделей ещё не получен». Ревьюер добавил точку входа при слиянии. Защитный `except ImportError` уместен в бою, но он же прячет несобранную интеграцию. Пишете модуль для чужого потребителя — проверьте импорт **исполнением**, а не глазами. --- ## Что уже сделал Codex и переделывать не нужно У Codex закончились лимиты, его работа влита частично. Не откатывайте: - выбор модели: `ui/model_catalog.py` с честным пустым состоянием; - **карточка кликабельна целиком** (`cursor="hand2"` + привязка ``), «три точки» перестали быть единственным входом; - **окно настроек роли**: `_open_agent_settings_modal`; - **правая панель «Статус в реальном времени» убрана**, центр расширен; - жёсткие срезы `providers[:3]` и `agents[:5]` в диаграмме устранены; - причины у части `Н/Д` через `unavailable_reason`. Codex остановился ровно перед двумя пунктами ниже — они и есть основная работа задания. --- ## P0-1. Компактные карточки аккаунтов `accounts_view.py` не менялся вообще. Это самый заметный для владельца пункт. Жалобы дословно: **«аккаунты должны выглядеть как у кокпит тулс, компактно»**, **«вид не тот, не надо делать раскрывающееся окно»**, **«в аккаунтах квота так и не отображается»**. Требуется: - плотный список фиксированной высоты: провайдер, идентичность, роль, состояние авторизации, квота — одной строкой, **без раскрытия**; - **квота видна сразу**, числом и полосой, с указанием пула и периода. У Antigravity четыре пула, и «просто процент» вводит в заблуждение; - шестнадцать аккаунтов читаются без прокрутки внутрь карточек; - **дельта-отрисовку по стабильным ключам не терять** — изменение одного аккаунта не перерисовывает остальные. Данные для квоты **уже есть и настоящие**. На живых аккаунтах владельца приходят измеренные значения от провайдера: ``` ag-w2 Claude/GPT — неделя осталось 37.4% source=provider_api ag-w3 Claude/GPT — неделя осталось 90.1% source=provider_api ag-w1 Gemini — неделя осталось 99.7% source=provider_api ``` Где данных нет — `Н/Д` с причиной, а не ноль и не прочерк без объяснения. У `opencode-go` и `grok` провайдер лимитов не отдаёт, и причина уже заполняется в `unavailable_reason`. Про дельта-отрисовку: в корне репозитория лежит `COCKPIT_TOOLS_ARCHITECTURE_COMPARISON.md` — там описано, почему это важно: при пересборке всех карточек на 50 аккаунтах выходит больше тысячи операций с виджетами в UI-потоке, и окно заметно подвисает. Документ — архитектурное сравнение, а не макет: берите принцип обновления и плотность, не буквальную вёрстку. **Тест:** изменение квоты одного аккаунта не пересоздаёт виджеты остальных. ## P0-2. Разобрать дублирующие разделы `quotas_view.py` не менялся, `providers_view.py` тронут на девять строк. Жалоба: **«провайдеры и квоты и лимиты вообще не понятно для чего нужны, там всё то же, что и в аккаунты»**. Владелец прав: после появления квот в карточках аккаунтов отдельный раздел квот потерял смысл. Нужно **решение**, а не сохранение обоих на всякий случай. - **«Квоты и лимиты»** — убрать из навигации либо оставить только то, чего нет в «Аккаунтах»: сводка по провайдеру целиком, история расхода, ближайшие сбросы. Нет такого содержания — убрать раздел. - **«Провайдеры»** — оставить относящееся к провайдеру, а не к аккаунту: доступность runtime, обнаруженные модели, версия CLI, состояние авторизации в целом. В отчёте перечислить, что перенесено, что удалено и почему. Пустой раздел не оставлять: либо содержание, либо нет пункта навигации. ## P0-3. Причина у каждого Н/Д Жалоба: **«что означает н/д в маршрутизация запросов»**. Codex закрыл частично: `unavailable_reason` используется в `components.py` и на «Обзоре», но не везде. Везде, где стоит `Н/Д`, причина должна быть доступна — подсказкой при наведении и текстом рядом, если место позволяет. Формулировки конкретные: «нет телеметрии: роль ещё не вызывалась», «провайдер не отдаёт лимиты», «аккаунт не подключён». Данные для этого есть. Это претензия не к честности, а к молчаливости: владелец видит прочерк и не знает, это поломка, ненастроенное или неизмеримое. ## P0-4. Тест на достижимость службы обнаружения моделей Ревьюер добавил точку входа `router/model_discovery.py`, и выбор моделей снова собран. Но защита от повторения этой ошибки отсутствует. Требуется тест, который **падает**, если служба недостижима по согласованному пути: - модуль: `src/antigravity_provider/router/model_discovery.py` - класс: `ModelDiscoveryService` - получение экземпляра: classmethod `get()` Тест обязан отличать «службы нет» от «служба есть, но импорт не тот». Проверять через `ui/model_catalog` недостаточно — там `except ImportError` всё проглотит; импортируйте модуль напрямую. ## P0-5. Подключение Grok и Claude довести до конца После миграции из A9 слоты появились, проверено: ``` find_free_slot(grok) -> grok-worker-1 find_free_slot(claude) -> claude-orch ``` Мастер больше не должен упираться в «свободный слот не найден». Но проверить нужно **весь путь**, а не только выдачу слота: подключение, назначение роли, появление в маршрутизации, тест профиля. Жалоба владельца была **«при подключении грока ошибка»**. Принимается только пройденный вживую сценарий со скриншотами. ## P1-6. Порядок провайдеров в диаграмме A9 задал детерминированный порядок провайдеров в `unified_health.get_provider_summaries()` (по числу авторизованных профилей, затем по общему числу слотов, затем по имени) и привёл `total_providers` к пяти. Убедиться, что диаграмма на «Обзоре» этот порядок соблюдает и показывает всех пятерых, а не первых трёх. Срезы Codex убрал, но проверить связку целиком стоит — раньше `claude` и `grok` молча отбрасывались. --- ## Ограничения - Строгая граница по файлам — см. выше. - Не выдумывать числа, идентификаторы и названия моделей. Нет данных — `Н/Д` с причиной либо блок отсутствует. - Три темы сохранить, дельта-отрисовку не терять. - Мастер не ломать: шесть потоков подключения, трёхэлементная распаковка `start_profile_oauth`, `destroy()` в `_finish` выполняется всегда. - Сеть и подпроцессы — не в UI-потоке. Замерено: `agy models` в одном прогоне отвечает за 40 секунд, в следующем висит больше двух минут. - Тег `v0.1.1` не создавать. ## Критерии приёмки 1. **Ветка в `origin`**, финальный коммит виден через `git log origin/antigravity/interface-cleanup`. Ни один файл зоны A11 не изменён. 2. Карточка аккаунта компактна, фиксированной высоты, без раскрытия; квота видна сразу с указанием пула и периода; шестнадцать аккаунтов без внутренней прокрутки. 3. Дельта-отрисовка сохранена: изменение одного аккаунта не пересоздаёт виджеты остальных; проверено тестом. 4. Принято решение по «Провайдерам» и «Квотам»; перенесённое и удалённое перечислено; пустых разделов нет. 5. У каждого `Н/Д` доступна причина. 6. Есть тест, падающий при недостижимости `router/model_discovery.ModelDiscoveryService`. 7. Grok и Claude подключаются вживую: подключение, роль, маршрутизация, тест профиля. 8. Диаграмма показывает всех пятерых провайдеров в заданном порядке. 9. Прогон **в обоих окружениях** — без UI-зависимостей и с `customtkinter`/`pillow`/`psutil`; обе команды и оба результата в отчёте. На `main` полный набор даёт 307 passed, 2 skipped. 10. `ruff check .` чисто. Релизный гейт не ухудшен. 11. Отчёт: `START_HEAD`, `FINAL_HEAD`, `origin/main`, `git status`, точный `X passed / Y skipped / Z failed`. 12. **Скриншоты живого сценария с настоящими данными**: «Аккаунты» с видимыми квотами, подключение Grok, окно роли. Пустых состояний не присылать. ## Главное Владелец сказал: «надо чтобы хаб уже заработал». Квоты настоящие, роли настраиваются, подключение Grok разблокировано. Осталось, чтобы шестнадцать аккаунтов читались с одного взгляда и в каждом непонятном месте был ответ, почему там прочерк. ## Порядок сдачи Передать точный `FINAL_COMMIT_SHA`. **Сдано только после появления ветки в `origin`** — проверьте это командой перед тем, как отчитаться.