Тринадцать файлов существовали только на диске ПК владельца, в рабочей копии, отставшей от origin/main на 122 коммита. Их реализация и тесты давно влиты: tests/test_a42_provider_connect.py, test_a49_subagents_skills_memory.py, test_a51_hub_controls_hermes.py, test_a52_local_models_supervisor_dual.py, test_a55_account_connection.py, test_a56_context_compression.py и другие. Постановок, объясняющих, что эти тесты обязаны доказывать, в репозитории не было. Правило записано в agents/AGENTS.md: задание живёт в репозитории, а не в переписке и не в личных папках на диске. A48, A50 и A54 не переносятся: они уже есть на origin под другими именами, содержимое совпадает с точностью до перевода строки в конце файла. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
12 KiB
Задание A43: интерфейс по макетам и работающий холст
Дата поступления
2026-08-31
База
origin/main (ff303b5) — туда уже слиты правки ревьюера по вебу и A41 (чистая первая установка).
git fetch origin --prune
git checkout -b antigravity/a43-frontend-canvas origin/main
В main напрямую не пушить.
Порядок исполнения
Два прохода: Flash реализует, Pro проводит аудит. Пункт P0-5 написан для аудитора.
Это задание по интерфейсу. Провайдеры, обнаружение моделей и квоты — задание A42, туда не залезать. Пересечение файлов: app.js и workflow.js правит только это задание; A42 работает в Python.
Исполнитель работает на машине владельца (Windows), где хаб запущен и есть живой снапшот с подключёнными аккаунтами. Это принципиально: макет надо сверять с работающим интерфейсом, а не с воображаемым.
Задача
Владелец: «криво отрисовано», «окно интерактивно ужасно, посмотри как сделано у n8n», «вообще весь интерфейс не соответствует фронтенду, просто посмотри как отрисовано в макете».
Что уже сделано ревьюером — не переделывать
В базовой ветке уже исправлено, проверено и закоммичено:
app.js экран маршрутизации читал currentSnapshot.profiles — такого ключа
в снапшоте нет (поле называется all_profiles). Отсюда пустая колонка
аккаунтов, счётчик «0 аккаунтов» и иконки-заглушки в цепочках.
app.js убрана полоса квоты с зашитым width:80%, одинаковая у всех аккаунтов
workflow.css подписи связей центрируются (не было text-anchor) и получили обводку
workflow.js список моделей берётся из discovered_models провайдера, а не из
preferred_models профиля; настроенная модель всегда есть в списке
Последнее чинило скрытую подмену: если модели агента не было в списке, ни один вариант не выбирался, показывался первый, и сохранение записывало агенту не ту модель.
Про генераторы интерфейса
Владелец спрашивал про github.com/abi/screenshot-to-code. Ревьюер проверил и не рекомендует: инструмент выдаёт самостоятельную страницу на Tailwind без данных, а клиент здесь без сборки и без npm, всё держится на привязке к /api/snapshot (решение зафиксировано в docs/web-api/CONTRACT.md §1). Переподключать сгенерированную страницу к снапшоту, действиям и опросу состояния дороже, чем сверстать по макету.
Опираться на макеты из Desktop/фронтенд/ напрямую.
P0-1. Холст ведёт себя как холст
Сейчас workflow.css:28 задаёт .workflow-canvas фиксированную высоту 430 px и overflow:hidden, а обработчики мыши висят только на узлах и портах (workflow.js:171). Колесо не обрабатывается, полотно не двигается. Всё, что выехало за 430 px, недостижимо — узел не вернуть, связь не увидеть.
Требуется поведение, привычное по n8n:
- Панорамирование полотна — перетаскиванием пустого места и средней кнопкой.
- Масштаб колесом с курсором как центром, а не только кнопками.
- Холст тянется по высоте окна, а не заперт в 430 px.
- Вписать в экран — кнопка уже есть (
fitWorkflowGraph), она должна учитывать панорамирование. - Узел нельзя утащить в недосягаемость: либо границы, либо «вписать» всегда возвращает всё в поле зрения.
Связи и узлы считаются в одной системе координат — это ревьюер проверил, ошибки там нет. При добавлении панорамирования сохранить это свойство: смещение обязано применяться к обоим слоям одинаково, иначе связи отклеятся от узлов.
P0-2. Экраны соответствуют макетам
Пройти по макетам из Desktop/фронтенд/ и привести экраны в соответствие: сетка, отступы, типографика, состояния карточек, расположение панелей.
- Расхождения перечислить списком до начала работы — что именно не совпадает на каждом экране. Список приложить к отчёту.
- Скриншот до и после по каждому экрану. Это единственный способ показать владельцу результат: он сравнивает глазами.
- Три темы остаются рабочими — светлая, средняя, тёмная. Средняя была реализована в стилях, но отсутствовала в списке выбора; проверить, что все три переключаются.
- Ничего не ломать в данных. Экран берёт данные из снапшота; если макет требует поля, которого в снапшоте нет, — показать
Н/Дс причиной и назвать это в отчёте, а не придумать значение.
P0-3. Пустые состояния и честность
- Пустое — это пустое, а не ошибка. Нет подключённых аккаунтов — экран говорит об этом и предлагает подключить, а не показывает ноль как поломку.
- Загрузка отличается от отсутствия. «Список моделей ещё не получен» и «моделей нет» — разные сообщения.
- Ни одного зашитого числа в интерфейсе. Полоса с
width:80%уже убрана; поискать оставшиеся такие же. Любой процент, столбик или счётчик обязан приходить из снапшота.
P0-4. Проверка исполнением
Прогнать тесты недостаточно — дефекты этого задания видны только глазами.
- Открыть хаб и пройти все экраны на живом снапшоте владельца.
- Холст: подвигать полотно, покрутить колесо, утащить узел за край и вернуть кнопкой «вписать».
- Инспектор агента: убедиться, что показанная модель совпадает с настроенной, а список содержит модели провайдера.
- Маршрутизация: колонка аккаунтов заполнена, счётчик совпадает с числом подключённых, перетаскивание работает.
- Три темы переключить и посмотреть каждый экран.
P0-5. Аудит вторым проходом
- Сверить скриншоты с макетами, а не с описанием работы. Совпадение проверяется глазами, а не отчётом исполнителя.
- Связи не отклеились от узлов ни на одном масштабе и смещении — проверить на нескольких значениях.
- Зашитые числа искать целенаправленно по всему клиенту.
- Проверить, что данные не потерялись: экраны, которые работали, продолжают работать.
- Побочные изменения объяснить.
- Пропущенный пункт назвать пропущенным.
Ограничения
- Без сборки, без npm, без фреймворка — решение зафиксировано в
docs/web-api/CONTRACT.md§1. Tailwind, React и генераторы страниц не вносить. - Python не трогать: провайдеры и квоты — задание A42.
- Учётные данные и
~/.hermes/agy_profiles/не трогать. - Версию
0.1.1не поднимать. - Правило честности без исключений.
Критерии приёмки
- Ветка в
origin,git statusчист. - Холст панорамируется и масштабируется колесом; высота не заперта; связи держатся за узлы на любом масштабе и смещении — проверено.
- Расхождения с макетами перечислены списком; по каждому экрану приложены скриншоты до и после.
- Три темы работают на всех экранах.
- Пустые состояния показываются как пустые, загрузка отличается от отсутствия.
- Зашитых чисел в интерфейсе не осталось.
- Экран маршрутизации, инспектор агента и список аккаунтов проверены на живом снапшоте.
ruff check .чисто; релизный гейт не ухудшен.- Отчёт:
START_HEAD,FINAL_HEAD,origin/main,git status,X passed / Y skipped / Z failed. Наorigin/mainсейчас 491 passed.
Главное
Владелец смотрит на готовый макет и на работающую программу и видит разные вещи. Плюс холст, из которого узел можно утащить за край и не вернуть. Задание закрывает ровно это: чтобы экран совпадал с макетом, а граф вёл себя как граф, к которому владелец привык в n8n.
Порядок сдачи
Передать точный FINAL_COMMIT_SHA.