Commit graph

32 commits

Author SHA1 Message Date
Hermes Team
fa7bbef8af feat(antigravity): выход через прокси вместо патча бинарника
Вход через терминал прошёл: agy запустился в изолированном каталоге ag-5 и
опознал аккаунт владельца. Отказал Google: «Eligibility check failed: not
currently available in your location». Проверка смотрит на адрес выхода.

У владельца есть узлы 3x-ui в разных странах. Поэтому обход делается выходом
через разрешённую страну, а не патчем чужого бинарника: ничего не ломается при
обновлении Antigravity и не выполняется сторонний код.

Адрес задаётся общий в настройках и отдельный на профиль — разным аккаунтам
может требоваться разная страна. Применяется к запросу каталога моделей, к
вызовам моделей и к сценарию входа в терминале.

Пишутся и заглавные, и строчные имена переменных: Go читает HTTPS_PROXY,
многие библиотеки — https_proxy; ALL_PROXY нужен для socks5.

Адрес проверяется по существу, а не по схеме: приписать socks5:// можно чему
угодно, и тогда мусор выглядел бы принятым, а обращения провайдера молча
ломались бы без внятной причины.

695 passed, 2 skipped; ruff чисто; релизный гейт пройден.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-01 16:49:04 +07:00
Hermes Team
28f35f863f fix(antigravity): терминал не открывался из-за подменённого HOME; видно работающую сборку
Мастер честно сообщил: «Терминал /usr/bin/xfce4-terminal завершился сразу с
кодом 1, окно не открылось» — новая проверка запуска сработала.

Причина в моей же правке. Терминал запускался с HOME, подменённым на каталог
профиля, а клиенты X11 берут ключ авторизации из ~/.Xauthority: в
agy_profiles/ag-5 такого файла нет и быть не может, поэтому подключиться к
дисплею терминал не мог. Подменять HOME терминалу и не требуется — это делает
сценарий входа, уже внутри окна, перед самым запуском agy.

Заодно устранено побочное действие в запросе: сценарий входа создавался внутри
функции ПОИСКА терминала. Теперь его готовит start_native_agy_login, а поиск
только отвечает на вопрос и ничего не создаёт.

Владелец не мог понять, обновился ли хаб: на Linux строка сборки в боковой
панели была пуста, потому что заполнялась из панели обновлений, а та
подтягивается только при открытии. Теперь номер берётся из снапшота и
показывается вместе со временем запуска процесса.

Показывается running_commit — снятый ОДИН РАЗ при старте процесса. Поле commit
читается из манифеста на диске при каждом запросе, поэтому переживший
обновление процесс рапортует им свежий номер при старом поведении; на этом я
уже спотыкался при разборе окон консоли. Снятое при старте значение отвечает на
настоящий вопрос: какой код сейчас в памяти.

678 passed, 2 skipped; ruff чисто; релизный гейт пройден.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-01 16:04:07 +07:00
Hermes Team
884a632049 fix(antigravity): хаб отказывался открыть терминал, стоя на рабочем столе
Мастер сообщил «Графический дисплей не обнаружен», хотя окно хаба было открыто
на рабочем столе владельца. Причина: хаб запускается через nohup и наследует
окружение той оболочки, из которой его запустили. Запуск по SSH или службой
оставляет процесс без DISPLAY.

Наследование не единственный источник. Измерено на сервере владельца:
loginctl show-user ochenstarik -p Display даёт c1, а show-session c1 —
Type=x11, Display=:10, Active=yes. Спросить у системы честнее, чем сдаться.

Теперь дисплей ищется сначала в окружении, затем у systemd, и найденное
значение передаётся в окружение терминала — иначе окно не открылось бы даже
при верном обнаружении. Отказ остаётся правомерным, только когда графического
сеанса не знает и systemd; в сообщении перечисляется всё проверенное, включая
сам loginctl.

XAUTHORITY не выставляем: клиенты X11 по умолчанию берут ~/.Xauthority того же
пользователя, а хаб работает под ним же.

674 passed, 2 skipped; ruff чисто; релизный гейт пройден.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-01 15:38:27 +07:00
Hermes Team
6cb0d7c636 fix(profiles): пустые слоты появлялись сами, потому что запрос пути создавал каталог
Владелец спросил, откуда 25 каталогов профилей, когда заводил единицы.
Проверено исполнением: обращение к get_profile_dir создавало каталог. Спросили
четыре пути — появились четыре каталога.

В коде зашит список «стандартных» слотов — ag-orch-primary, ag-orch-fallback,
ag-1..ag-20, ag-w1..ag-w10 — в двух местах: agy_subprocess и
model_discovery_service. Любой обход этого списка материализовал их все. Отсюда
ag-w1..ag-w4, ag-cold-*, ag-spare-* — владелец их не создавал.

Спросить, где профиль жил бы, и завести его — разные действия. Создание теперь
запрашивается явно, create=True, и это делают только те, кто действительно
заводит профиль.

Тесты и сценарий проверки, опиравшиеся на побочное создание, приведены к новому
поведению: они проверяют изоляцию пути, а не то, что каталог возник сам.

669 passed, 2 skipped; ruff чисто; релизный гейт пройден.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-01 15:27:33 +07:00
Hermes Team
f188a18136 fix(accounts): отказ проверки переживал более свежий каталог моделей
В карточке владельца рядом стояли «Проверен: не работает — Please sign in» и
«Получено 11 моделей · 13:25:53». Источники разные: красная строка берётся из
состояния проверки, список — из кэша каталога, и обновляются они независимо.
Каталог был получен позже отказа, то есть провайдер с тех пор ответил, а
карточка продолжала утверждать обратное.

Теперь, если каталог получен без ошибки и позже неудачной проверки, вердикт
показывается как устаревший с предложением проверить заново. Объявлять аккаунт
рабочим не за что — проверка после этого не выполнялась, и выдумывать её
результат нельзя.

Отдельно установлено: поле commit в /api/health читается из файла на диске при
каждом запросе, поэтому устаревший процесс рапортует свежий коммит. Различать
сборки по нему нельзя.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-01 14:03:56 +07:00
Hermes Team
0ad946eccd fix(accounts): мастер подключения замирал на шаге 3
Владелец видел «сохранение аккаунта и запуск проверки» и ждал. Зависанием это
не было: действие честно дожидалось проверки у провайдера. Для Antigravity она
идёт через CLI и в худшем случае складывается из 90 с на захват замка профиля,
65 на каталог моделей и 90 на пробный вызов — около четырёх минут молчания при
обещанной в интерфейсе «минуте на этап».

Сохранение учётных данных и назначение роли занимают миллисекунды. Теперь
действие возвращается сразу, а опрос провайдера ставится в фон; карточка
обновляется, когда он закончится, — снапшот и так опрашивается по таймеру.

Провайдеры с ключом поведения не меняют: их подключение проверяется
предварительной проверкой до сохранения и возвращается сразу, как требует A54.
Если фоновая служба не работает, проверка по-прежнему выполняется на месте —
иначе результата не будет вовсе.

Надпись в мастере исправлена: обещание «до минуты на этап» не соответствовало
действительности.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-01 13:23:55 +07:00
Hermes Team
001cd1f91d fix(installer): установка на Linux падала на защищённом системном Python
Установка на сервере владельца прервалась на проверке: «No module named
'fastapi'». Причин две, и обе в установщике.

Первая: запуск через sudo. Установка пользовательская — всё ложится в
$HOME/.hermes и $HOME/.local/bin, root не нужен. Под sudo домашним каталогом
становится /root, венв Hermes там не находится, и установщик уходит на
системный python. Копия при этом ложится в /root/.hermes, где владелец её не
видит. Теперь запуск через sudo распознаётся и отклоняется с объяснением;
осознанный обход остаётся через HERMES_ALLOW_ROOT=1.

Вторая: системный python в Ubuntu 24.04 помечен EXTERNALLY-MANAGED (PEP 668) и
отклоняет pip install — и обычный, и с --user. Установщик обе неудачи проглатывал
(|| true) и продолжал работу до отказа на проверке. Теперь при защищённом
системном python создаётся собственное окружение $HERMES_HOME/venv, а неудача
установки зависимостей прекращает установку с внятным кодом возврата.
--break-system-packages не применяется: имя флага не преувеличивает.

Пусковик научен той же ветке — иначе запуск уходил бы на системный python,
где зависимостей нет и быть не может.

Проверено исполнением на сервере под непривилегированным пользователем:
окружение создано, зависимости установлены, HERMES_HUB_LINUX_VERIFY_OK,
запуск через sudo отклонён с кодом 3.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-01 12:56:47 +07:00
Hermes Team
9641957d5b fix(antigravity): вход завершался успешно, а agy требовал войти снова
agy 2.0 читает учётные данные не из .gemini/oauth_creds.json — это формат
Gemini CLI. Свой токен он берёт из .gemini/antigravity-cli/antigravity-oauth-token
в виде {"auth_method": ..., "token": {...}}. Хаб этот файл никогда не создавал,
поэтому «Авторизация успешно завершена» соседствовала с ответом
«Please sign in to view available models».

Установлено сравнением рабочего профиля владельца с неработающим: оба имели
oauth_creds.json одинакового размера, различие было только в этом файле.
Значение auth_method («consumer») взято из рабочего профиля, а не выведено
из общих соображений.

Срок годности пишется в обоих видах: expiry_date в миллисекундах для формата
Node и expiry строкой RFC3339 для Go-шного oauth2.Token.

Заодно устранён рост номеров профилей: слот выбирался до входа, когда почта
ещё неизвестна, и повторный вход тем же аккаунтом занимал очередной свободный
слот — один аккаунт владельца расползся на ag-2, ag-3, ag-4. Теперь после
опознания почты учётные данные возвращаются в слот, который этот аккаунт уже
занимает. Функция проверки двойников в проекте была, но её никто не вызывал.

Версия поднята до 0.1.3, чтобы отличать сборки на глаз. Проверка версии в
тестах сверяется с исходником, а не с записанным числом.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-01 10:37:27 +07:00
Hermes Team
eeeed36358 fix(installer): установка на Linux не останавливала работающий хаб
Установщик копировал файлы, но работающий сервер не трогал. Процесс
продолжал выполнять прежний код из памяти, и владелец видел старый
интерфейс при новом номере сборки: раздача статики читает файлы с диска,
а вся логика действий живёт в загруженном модуле. Три сборки подряд
ставились в файлы, но не в работу — отсюда «сброс не работает»,
«очистка не работает», «версия не изменилась».

Добавлен шаг 0: остановка процессов хаба до копирования. Ищутся только
процессы текущего пользователя и только по признакам хаба
(antigravity_provider.router.web, hermes_hub_web_entry). Сначала обычное
завершение, десять секунд ожидания, затем принудительное. Если процессы
всё же остались, установка НЕ прерывается — файлы обновляются, а владельцу
сообщается, что старый код продолжит работать, пока он их не снимет.

В итоговом сообщении сказано, что хаб остановлен и его надо запустить
заново, и дана команда для проверки, что поднялся новый код.

609 passed, ruff clean.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-01 02:12:22 +07:00
Hermes Team
b2ca7cdd4d fix: версия в интерфейсе была зашита в разметке; установка падала на занятом файле
Версия. В index.html номер стоял руками в двух местах, а в app.js был
запасным значением '0.1.1'. Номер сборки приходил из API и обновлялся,
версия — нет: владелец обновился до e6eab12 и увидел v0.1.1. Подъём
версии в пяти местах бэкенда до экрана не доходил вовсе. Теперь версия
берётся только из API; если сервер её не передал, пишется Н/Д с причиной,
а не правдоподобный номер.

Установка. Отказ остановки прежнего хаба прерывал установку целиком, и
владелец получал голый код 15. Теперь неудачная остановка не отменяет
установку: причина показывается, работа продолжается, и если файл
действительно занят, об этом скажет копирование с именем файла.

Копирование файлов получило повтор: процесс мог не успеть отпустить файл
после остановки. Пять попыток с паузой вместо отказа с первой.

599 passed, ruff clean.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-31 21:46:30 +07:00
Hermes Team
e6eab12616 chore(release): версия 0.1.2
Владелец просил менять версию сборки. Прежнее указание держать 0.1.1
отменено этим.

Поднято во всех пяти местах, где версия объявлена: version.py,
pyproject.toml, HermesHubSetup.cs, install-linux.sh и
config/compatibility.json. Последний ловится тестом на совпадение с
__version__ — без него прогон падал.

599 passed, ruff clean, релизный гейт 10/10.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-31 21:38:01 +07:00
ochenstarik-ui
ddeba2db0e fix(a54): validate accounts synchronously and manage Windows runtime lifecycle 2026-08-31 20:54:19 +07:00
Hermes Team
d4c4facc94 fix(installer): нормализация переводов строк молча зависела от нерабочего python3
Нормализация в сборщике делалась через sed -i, а на Windows в Git Bash это
ненадёжно. Замена на Python сначала не сработала по неожиданной причине:
python3 здесь — заглушка Microsoft Store, которая печатает "Python" и не
выполняет ничего. Нормализация тихо становилась пустой операцией, а сборщик
при этом рапортовал об успехе.

Теперь интерпретатор выбирается проверкой: python3, python, py — берётся
первый, который действительно исполняет код. Не нашёлся ни один — сборка
прерывается с объяснением, потому что установщик без нормализации ломается
на Linux с "$'\r': command not found".

Проверено побайтово на собранной поставке: в прологе ноль байтов 0d, маркер
на своём месте, среди .sh и .py файлов поставки ни одного с возвратом
каретки.

Отдельно отмечу для истории: тревога о возврате CRLF была поднята по ошибке
измерения — grep -c с шаблоном возврата каретки в этой оболочке давал ложные
срабатывания. Сама поставка была исправна и до правки.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-31 01:54:12 +07:00
ochenstarik-ui
c7539b36d4 feat(hub): A34 восстановление подключения аккаунтов, OpenRouter, NVIDIA, удаление десктопа
1. P0-1: Восстановлены все веб-обработчики в app.js (openAddAccountWizard,
   handleNodeAccountChange, handleNodeModelChange, handleRefreshProviderModels,
   checkUpdates), связаны с потоками startDeviceAuth и startRedirectAuth,
   выбор слота обязателен и понятен пользователю.
2. P0-2: Добавлены адаптеры OpenRouter и NVIDIA NIM с поддержкой динамического
   base_url, множественных аккаунтов без ограничений, GET /models и честным
   отображением квот/«Н/Д».
3. P0-3: В мастере подключения локального провайдера реализована кнопка автопоиска
   (discover_local_models), отображение серверов, ошибок портов и автозаполнение.
4. P0-4: Полностью удален устаревший десктопный интерфейс CustomTkinter
   (router/ui/** 20 файлов, hermes_hub_app.py), зависимости customtkinter и pillow
   убраны из pyproject.toml и инсталляторов, оставлен единый ярлык «Hermes Hub».
5. 418 passed, 1 skipped, 4 deselected, ruff чисто.
2026-08-31 00:23:27 +07:00
Hermes Team
2ca42a39c4 fix(installer): установщик Linux собирался с CRLF и падал на первой строке
У владельца на сервере:

    install-linux.sh: line 7: $'\r': command not found
    line 31: syntax error near unexpected token `elif'

Причину я назвал верно в 1d5e44a, но закрыл не там. .gitattributes нормализует
переводы строк при записи в git; объекты действительно чистые — проверено
git cat-file. Но сборка идёт на Windows, где рабочая копия хранится с CRLF, а
build_installer_linux.sh копирует именно из РАБОЧЕЙ КОПИИ. К .gitattributes
это отношения не имеет, поэтому сборка 44808bd уехала с \r.

Диагностику дополнительно запутал git show: он применяет преобразование
переводов строк при выводе, из-за чего индекс выглядел испорченным, хотя не
был.

Исправлено там, где надёжно: сборщик нормализует переводы строк в поставке
перед упаковкой. Теперь неважно, как настроен checkout на машине сборки.
Рабочая копия shell-скриптов тоже приведена к LF.

Проверено на распакованной поставке: ни одного .sh или .py с CR (кроме
самого сборщика, который на целевой машине не исполняется), пролог без CR,
bash -n на install-linux.sh и hermes-hub-web.sh проходит.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-25 10:37:05 +07:00
Hermes Team
44808bdc4e feat(web): скрипт открытия хаба в домашнюю сеть, с подтверждением цели
Владелец хочет попадать в хаб на сервере по сети, а не через SSH-туннель.
Для этого нужны привязка к 0.0.0.0 и токен: без токена при небlocalhost
привязке сервер отказывается стартовать.

Скрипт ДОПОЛНЯЕТ hub_settings.json, а не переписывает: рядом лежат тема,
интервал обновления квот и параметры маршрутизации. Запись атомарная,
повторный запуск сохраняет прежний токен.

Изменение требует явного --yes, а каталог печатается всегда. Причина не
теоретическая: при отладке скрипт молча взял HERMES_HOME из окружения и
записал настройки не в тестовую копию, а в живой хаб рабочей машины,
привязав его к сети. Откачено, наружу ничего не вышло — адрес читается при
старте, процесс не перезапускался, netstat подтвердил только 127.0.0.1.
Предпросмотр по умолчанию закрывает этот класс ошибки.

Попутно install-linux.sh разворачивает scripts/: они входили в поставку, но
на установленной машине не оказывались, поэтому вспомогательных инструментов
там просто не было.

Проверено на копии настроек: предпросмотр не меняет файл, применение
сохраняет прежние ключи, повторный запуск не меняет токен, посторонний
каталог не затрагивается.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-25 10:27:16 +07:00
Hermes Team
290e23070e feat(installer): самодостаточный установщик для Linux, без копирования репозитория
install-linux.sh читал исходники из $REPO_ROOT, поэтому на каждую машину
приходилось приносить весь клон git. Добавлен build_installer_linux.sh: он
собирает один файл dist/hermes-hub-setup.sh — пролог на shell, строка-маркер
и tar.gz побайтово следом. Пролог обрезает себя по маркеру, распаковывает
хвост во временный каталог и запускает оттуда install-linux.sh. Состав
поставки тот же, что у виндового payload, плюс installer/; виндовые .exe и
__pycache__ из линуксовой поставки вычищаются.

Убран запасной коммит-литерал 'fb23bff' в манифесте: при сборке без git он
подставлял чужой номер сборки, из-за чего установленная версия выглядела
определённой, не будучи ею. Теперь коммит берётся из BUILD_COMMIT, который
кладёт сборщик, иначе — 'не определён'.

Проверено: распаковка проходит, в поставке лежат свежие server.py и app.js,
секретов, ключей и почт в ней нет.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-25 09:10:32 +07:00
Hermes Team
bca88a56a6 fix(launcher): браузер убивал сервер, установщик запускал десктоп вместо веба
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>
2026-08-24 10:07:33 +07:00
Hermes Team
ef6a9e1acd fix: веб-сервер не запускался на Windows, диаграмма тормозила при перетаскивании
Три дефекта из установки владельца на вторую машину.

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>
2026-08-24 09:59:41 +07:00
Hermes Team
57e7ca2edd fix: проверка готовности всегда врала, установщик показывал зашитую версию
Три дефекта, найденные при установке владельцем на две машины.

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>
2026-08-24 09:47:00 +07:00
Hermes Team
36b449bc6c fix(installer): ошибка 12 при установке — проверка требовала конфигурацию от 20 августа
Владелец получил «Ошибка установки (Код: 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>
2026-08-24 09:35:36 +07:00
Hermes Team
8f62adb760 feat(installer): самодостаточный exe для Windows
Владелец: «для винды я думаю нужен 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>
2026-08-24 09:21:08 +07:00
Hermes Team
2e445c28ef feat(installer): A19 — установщики Windows и Linux, запуск веб-интерфейса окном приложения 2026-08-23 22:14:47 +07:00
Hermes Team
999e0fb08e feat(router): A9 — миграция конфигурации, квоты провайдеров, реальные модели, перехват Hermes и токены Codex 2026-08-23 12:45:08 +07:00
Hermes Team
d2d2a69357 feat(installer): implement P0-4bis reinstall detection, UI screen, and user data preservation 2026-08-22 21:25:39 +07:00
Hermes Team
ee5108eb3e fix(deployment): implement self-healing bootstrap, Claude & Grok profiles, non-interactive test mode, mirror installer, and comprehensive doctor CLI 2026-08-22 21:22:21 +07:00
Hermes Team
9d93a1739b feat(security): isolate subprocess credentials, implement selection explanation matrix, and resolve installer registry isolation 2026-08-21 10:17:19 +07:00
Hermes Team
8314d46c43 fix: update canonical installer with dependency resolution and close release blockers 2026-08-20 18:17:08 +07:00
Hermes Team
42dfe2caa6 feat: production update feed architecture, host allowlist, and truthful release gate 2026-08-20 17:25:30 +07:00
Hermes Team
2a97e80a3e fix: close P0 release blockers 2026-08-20 16:25:11 +07:00
Hermes Team
7609ad87c2 feat(hub): product stabilization, native windows ux v3, provider icons, and architecture roadmap 2026-08-20 11:01:52 +07:00
Hermes Team
fdf9eccbdb feat: initialize standalone Hermes Hub 2026-08-20 00:17:11 +07:00