A17 (Pro): «Работает» — ветка else в определении здоровья, она означает «мы не знаем о проблемах», а подана как утверждение. Отказы попадают в статус только после боевого сбоя, поэтому непроверенный профиль автоматически зелёный. Плюс «Проверить подключение» не вызывает модель вовсе — Grok её проходит и не работает. A18 (Flash): действия смены модели не существует ни среди семнадцати, ни в клиенте; десктоп это умеет, но логика заперта в методе интерфейса. И выбирать не из чего: кэш моделей пуст по всем провайдерам, потому что agy models нестабильна — в одном прогоне 40 секунд, в следующем висит больше двух минут. A19: два установщика. Windows — ярлык, открывающий веб окном приложения через --app без адресной строки (проверено на машине владельца: Edge и Chrome есть, окно открывается). Linux — скрипт установки, .desktop и удаление с сохранением данных, плюс честная подсказка про проброс порта при пустом DISPLAY. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
147 lines
12 KiB
Markdown
147 lines
12 KiB
Markdown
# Задание A19: два установщика — Windows и Linux, запуск веб-интерфейса окном приложения
|
||
|
||
## Дата поступления
|
||
2026-08-23
|
||
|
||
## База
|
||
Проверочный HEAD на момент выдачи: **`fb23bff`**.
|
||
|
||
## Ветка
|
||
`antigravity/installers`
|
||
|
||
## Кому
|
||
Отдельная задача, не пересекается по файлам ни с A17, ни с A18. Брать тому, кто освободится первым.
|
||
|
||
---
|
||
|
||
## Порядок работы с git
|
||
|
||
```
|
||
cd <каталог репозитория>; git fetch origin --prune; git status
|
||
git checkout main; git pull --ff-only origin main
|
||
git checkout -b antigravity/installers
|
||
git commit -m "..." <- сначала коммит
|
||
git push -u origin antigravity/installers
|
||
```
|
||
|
||
В конце — push и проверка `git log --oneline -1 origin/antigravity/installers`, `git status` чистый.
|
||
|
||
---
|
||
|
||
## Чего хочет владелец
|
||
|
||
Дословно: «сделай задание на 2 установочника. линукс и виндовс. в винде будет так же создаваться ярлык. при запуске будет открываться окно браузерное но без настроек браузера а как наша десктоп программа. а у линукс ссылка на открытие окна в браузере».
|
||
|
||
**Так можно, и это стандартный приём.** Chromium-браузеры умеют режим приложения: `--app=URL` открывает окно без адресной строки, вкладок и меню — визуально обычное окно программы.
|
||
|
||
Проверено ревьюером на машине владельца:
|
||
|
||
```
|
||
Edge : C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe — есть
|
||
Chrome : C:\Program Files\Google\Chrome\Application\chrome.exe — есть
|
||
|
||
msedge.exe --app=http://127.0.0.1:5800/ --window-size=1400,900
|
||
-> окно приложения открылось, адресной строки нет
|
||
```
|
||
|
||
## Как это должно работать целиком
|
||
|
||
Один ярлык делает три вещи по порядку:
|
||
|
||
1. поднимает веб-сервер, если он ещё не запущен;
|
||
2. дожидается готовности — опрашивает `GET /api/health`, а не спит фиксированное время;
|
||
3. открывает окно приложения на `http://127.0.0.1:<порт>/`.
|
||
|
||
Закрытие окна **не должно оставлять висящий сервер**. Решите, как: сервер завершается вместе с окном, либо живёт как фоновая служба и ярлык к нему просто подключается. Второе удобнее для сервера владельца, первое — для десктопа. Выберите и обоснуйте в отчёте.
|
||
|
||
Команда запуска сервера сейчас:
|
||
|
||
```
|
||
python -m antigravity_provider.router.web
|
||
```
|
||
|
||
Порт по умолчанию 5800, слушает `127.0.0.1`. Настройки читаются из `hub_settings.json` (`web_api_host`, `web_api_port`, `web_api_token`).
|
||
|
||
---
|
||
|
||
## P0-1. Windows
|
||
|
||
**Опираться на существующий установщик**, а не писать новый: `installer/HermesHubSetup.cs` — 1043 строки, в нём уже есть обнаружение Hermes, экран переустановки с показом версий, зеркальное развёртывание `MirrorDirectoryRecursive`, флаги `/silent`, `/uninstall`, `/repair`, `/reinstall` и запись `deployment_manifest.json`. Всё это переиспользуется.
|
||
|
||
Что добавить:
|
||
|
||
1. **Ярлык, открывающий веб-интерфейс окном приложения.** Существующий ярлык на десктопное приложение сохранить: десктоп остаётся рабочим и удалять его никто не просил. Итого два ярлыка с понятными именами, либо один на веб и один на десктоп в подпапке меню — на ваше усмотрение, но владелец должен понимать, что чем открывается.
|
||
|
||
2. **Поиск браузера в порядке**: Edge, Chrome, затем любой Chromium из реестра. **Если ни одного нет — не молчать**: показать понятное сообщение и предложить открыть обычный браузер по адресу. Неработающий ярлык хуже отсутствующего.
|
||
|
||
3. **Иконка окна.** В режиме `--app` окно берёт иконку из профиля браузера. Если удастся задать свою через `--user-data-dir` с отдельным профилем — хорошо, но **это не обязательное требование**: не тратьте на него больше часа и напишите в отчёте, чем кончилось.
|
||
|
||
4. Флаг тихой установки должен ставить и веб-ярлык тоже.
|
||
|
||
## P0-2. Linux
|
||
|
||
Здесь всё пишется с нуля, но проще: ни реестра, ни `pythonw`, ни возни с venv чужого приложения.
|
||
|
||
1. **Скрипт установки** `installer/install-linux.sh`: проверяет Python и Hermes, ставит зависимости, разворачивает плагин зеркалом (удаляя устаревшие файлы, как это делает Windows-версия), пишет `deployment_manifest.json`.
|
||
|
||
2. **`.desktop`-файл** в `~/.local/share/applications/` — это и есть «ссылка на открытие окна в браузере», о которой просит владелец. Запускает тот же скрипт: сервер, ожидание готовности, затем браузер.
|
||
|
||
3. **Порядок поиска браузера на Linux**: `google-chrome`, `chromium`, `chromium-browser`, `microsoft-edge`. Ни одного не нашлось — открывать `xdg-open` обычным браузером и **сказать пользователю, что окно будет с адресной строкой**, а не притворяться, что всё как задумано.
|
||
|
||
4. **Учесть headless.** У владельца Ubuntu Server с Xubuntu: он может работать и через SSH без экрана. Если `DISPLAY` и `WAYLAND_DISPLAY` пусты — браузер не запускать, а **напечатать адрес и подсказать проброс порта**:
|
||
|
||
```
|
||
ssh -L 5800:127.0.0.1:5800 user@server
|
||
```
|
||
|
||
Это честный путь, и он единственный рабочий для аккаунтов Antigravity и Claude: их авторизация требует redirect на localhost и на сервере без экрана не работает в принципе. Codex, Grok и OpenCode подключаются без проброса.
|
||
|
||
5. **Удаление** `installer/uninstall-linux.sh`: убирает программу и `.desktop`, но **не трогает** `~/.hermes/config/router_profiles.yaml`, каталоги профилей, `hub_settings.json`, журналы и телеметрию. То же правило, что и в Windows-версии.
|
||
|
||
## P0-3. Порт путей уже почти сделан
|
||
|
||
`paths.py` кроссплатформенный: при отсутствии `LOCALAPPDATA` уходит в `~/.hermes`. A15 провёл через него семь из восьми мест. Осталось `hermes_hub_app.py:37` — **это чинит A17, не трогайте**.
|
||
|
||
В `agy_subprocess.py` два упоминания `LOCALAPPDATA` уместны: строка 41 — комментарий, строка 414 — список переменных окружения для подпроцесса на Windows.
|
||
|
||
## P0-4. Проверка на настоящем Linux обязательна
|
||
|
||
Заявления «должно работать» не принимаются. Если под рукой нет машины — **сказать об этом прямо в отчёте**, и проверку сделает владелец на своём сервере. Это нормальный исход, а вот необоснованное «проверено» — нет.
|
||
|
||
Минимум, что должно быть проверено вживую или явно отмечено как непроверенное:
|
||
|
||
- установка проходит на чистой Ubuntu;
|
||
- `.desktop` появляется в меню и запускает окно;
|
||
- при пустом `DISPLAY` печатается подсказка про проброс порта, а не падает;
|
||
- удаление сохраняет данные пользователя.
|
||
|
||
---
|
||
|
||
## Ограничения
|
||
|
||
- Ваши файлы: `installer/**`, `launcher/**`, `scripts/install*.ps1`, `scripts/uninstall*.ps1`, новые `installer/*-linux.sh`, `docs/` в части установки. **Не ваши:** `src/**` целиком — там работают A17 и A18.
|
||
- Понадобилась правка в `src/` — скажите, будет заказана отдельно.
|
||
- Данные пользователя при переустановке и удалении не трогать.
|
||
- Тег `v0.1.1` не создавать.
|
||
|
||
## Критерии приёмки
|
||
|
||
1. Ветка в `origin`, `git status` чист.
|
||
2. Windows: установщик создаёт ярлык, открывающий веб-интерфейс окном приложения без адресной строки; ярлык десктопа сохранён.
|
||
3. Ярлык поднимает сервер, **дожидается `/api/health`** и только потом открывает окно.
|
||
4. Закрытие окна не оставляет висящий процесс сервера; выбранное поведение обосновано в отчёте.
|
||
5. Браузер не найден — понятное сообщение и запасной путь, а не тишина.
|
||
6. Linux: скрипт установки, `.desktop`, скрипт удаления; зеркальное развёртывание удаляет устаревшие файлы.
|
||
7. При пустом `DISPLAY` печатается адрес и команда проброса порта.
|
||
8. Удаление сохраняет `router_profiles.yaml`, профили, `hub_settings.json`, журналы.
|
||
9. Тихая установка ставит веб-ярлык.
|
||
10. В отчёте отдельно сказано, что проверено на настоящем Linux, а что нет.
|
||
11. Сборка Windows-установщика без предупреждений компилятора; `ruff check .` чисто.
|
||
12. Отчёт: `START_HEAD`, `FINAL_HEAD`, `origin/main`, `git status`, `X passed / Y skipped / Z failed`.
|
||
|
||
## Главное
|
||
|
||
Владелец должен запустить один ярлык и увидеть окно программы — без консоли, без адресной строки, без чтения инструкций. На сервере — открыть адрес и получить то же самое. Всё остальное в этом задании обслуживает эти два сценария.
|
||
|
||
## Порядок сдачи
|
||
Передать точный `FINAL_COMMIT_SHA`. Сдано только после появления коммита в `origin`.
|