Владелец привязал хаб на сервере к сети, а лаунчер всё равно напечатал
«Headless Mode», показал http://127.0.0.1:5800 и посоветовал пробросить порт
через ssh -L. Текст был зашит и настроек не читал: инструкция вела поднимать
туннель к серверу, который уже был виден напрямую. Инструкция, не
совпадающая с реальностью, хуже отсутствующей — тот же класс дефекта, что и
снятая заглушка про «вход через веб невозможен».
Теперь сообщение читает web_api_host из hub_settings.json: при 127.0.0.1
показывает проброс порта и подсказывает про enable_lan_access.py, при
сетевой привязке — реальный адрес из hostname -I и напоминание про токен.
Добавлен --rotate: смена токена понадобилась немедленно, потому что
выданный токен был вставлен в переписку и скомпрометирован. Без флага
поведение прежнее — повторный запуск токен не трогает.
Проверено: без --rotate токен сохраняется, с --rotate меняется; bash -n на
лаунчере проходит; переводы строк LF.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1. Главное: ERR_CONNECTION_REFUSED в окне приложения.
browserProc.WaitForExit() возвращался МГНОВЕННО, когда Edge уже был
запущен: новый msedge.exe передаёт окно работающему экземпляру и сразу
завершается. Лаунчер считал, что окно закрыли, и убивал сервер, пока
страница ещё грузилась.
Браузер теперь запускается с отдельным профилем (--user-data-dir), то
есть процесс живёт столько же, сколько окно. Плюс подстраховка: выход
браузера быстрее пяти секунд не считается закрытием окна.
Та же ловушка была в Linux-лаунчере — исправлена там же.
Проверено вживую: сервер отвечает 200 И окно приложения живо
(«Hermes Hub — Панель управления»).
2. Установщик по галочке «Запустить сейчас» открывал ДЕСКТОП. Владелец
получал десктопное окно и принимал его за старую версию — внешне оно
и правда другое. Теперь запускается веб-интерфейс, подпись галочки
уточнена. Десктоп остаётся доступен своим ярлыком.
Тесты: 373 passed, ruff чисто. Установщик пересобран.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Три дефекта из установки владельца на вторую машину.
1. Веб-сервер падал сразу: «web server process terminated unexpectedly».
Установщик ставит в venv Hermes только customtkinter, pillow, pyyaml и
psutil — fastapi и uvicorn отсутствовали в списке вовсе. Добавлены во
все шесть мест: проверка, сообщение, pip, uv, перепроверка.
Поэтому на Windows открывался только десктоп: веб физически не мог
стартовать.
2. Лаунчер показывал голое «terminated unexpectedly» без причины — та же
болезнь, что у кода 12. Теперь перехватывает вывод процесса и выводит
последние строки ошибки в окне.
3. Окно тормозило при перетаскивании и продолжало двигаться несколько
секунд после отпускания мыши. _RouteDiagram перерисовывал всю канву на
КАЖДОЕ событие <Configure>, а при перетаскивании их сотни; очередь не
успевала разгребаться. Гашение в приложении существовало, но
_handle_debounced_resize был пустой заглушкой.
Перерисовка сведена к одной после затишья. Замерено: 199 событий
давали 199 перерисовок, теперь 4.
Тесты: 373 passed, ruff чисто. Установщик пересобран.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Три дефекта, найденные при установке владельцем на две машины.
1. Linux: лаунчер писал «Web server failed to respond», хотя сервер
поднимался нормально — в логе старт API, планировщик квот и прогрев
кэша без ошибок. Причина в самой проверке: sys импортировался ТОЛЬКО
внутри except, а использовался в успешной ветке. На здоровом ответе
возникал NameError, его ловил тот же except, и проверка всегда
возвращала отказ.
Доказано исполнением на живом сервере: старая логика -> код 1,
новая -> код 0.
2. Windows: при нечитаемом манифесте мастер показывал зашитые
InstalledVersion = "0.1.0" и InstalledDate = "19.08.2026" как факт.
Владелец видел «старую версию» на свежей установке, хотя проверка
показала правильный путь и версию 0.1.1. Заглушки заменены на
«не определена» — выдуманный факт хуже отсутствующего.
3. Манифест писался одним File.WriteAllText: прерванная запись оставляла
пустой файл, и разбор версии падал на первом символе — ровно это и
случилось у владельца (JSONDecodeError, char 0). Запись переведена на
временный файл с переносом.
Попутно: git_commit в манифесте был зашит как "8cddc9f", то есть манифест
сообщал неправду о происхождении сборки. Теперь сборщик проставляет
фактический коммит.
Тесты: 373 passed, ruff чисто. Установщик пересобран.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Владелец получил «Ошибка установки (Код: 12)» на чистой машине.
Причина: scripts/verify_multi_provider_router.py, который установщик
запускает после развёртывания, требовал РОВНО 16 профилей и дословно
заданные цепочки ролей. Миграция из A9 законно доводит конфигурацию до
22 профилей, добавляя claude и grok. Проверено: скрипт падал с
«Expected 16 profiles, got 22», то есть установка обрывалась на любой
машине, где миграция отработала.
Проверки переписаны структурными: есть ли профили у каждого провайдера,
непусты ли цепочки ролей и ссылаются ли они только на существующие
профили. Смысл проверки — работоспособна ли маршрутизация, а не совпадает
ли конфигурация с зафиксированной когда-то. Скрипт проходит 10/10.
Отдельно: код 12 возвращался и при отказе проверки, и из общего catch —
владелец видел число без причины. Непредвиденный сбой отделён в код 15,
обе ветки теперь пишут пояснение в интерфейс установщика.
Тесты: 373 passed, ruff чисто. Установщик пересобран.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Владелец: «для винды я думаю нужен exe». Справедливо — «склонируй
репозиторий и собери» это не установка.
HermesHubSetup.exe требовал, чтобы рядом лежали src/, launcher/, assets/,
config/ и scripts/: PerformInstall берёт их из sourceRoot. Поэтому одного
файла не хватало, и на целевую машину пришлось бы копировать репозиторий.
Теперь содержимое упаковывается при сборке и вшивается в exe ресурсом
(/resource:payload.zip,payload). Если рядом с exe и уровнем выше
исходников нет, установщик распаковывает вшитое во временный каталог и
работает с ним. Прежнее поведение сохранено: при запуске из репозитория
используются файлы на диске, ресурс не трогается.
Проверено исполнением: exe скопирован в пустой каталог, из него извлечены
assets, config, launcher, scripts, src; src/antigravity_provider и
launcher/HermesHubWeb.exe на месте. Размер 11.78 МБ.
Тест сборки установщика приведён к реальным ссылкам: добавлена
System.IO.Compression.FileSystem, без неё ZipFile не разрешался.
Тесты: 373 passed, ruff чисто.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>