Windows (Native) — Ранняя бета

warning Ранняя бета Поддержка Windows (Native) находится на стадии ранней беты. Она устанавливается, запускается и проходит нашу проверку Windows-footgun lint, но ещё не прошла полевых испытаний в масштабах наших путей Linux/macOS/WSL2. Ожидаются шероховатости — особенно в обработке подпроцессов, особенностях путей и не-ASCII выводе в консоль. Пожалуйста, создавайте issues с шагами воспроизведения, когда на что-то натыкаетесь. Если вам нужно проверенное решение сегодня, используйте установщик Linux/macOS под WSL2.

Hermes работает нативно на Windows 10 и Windows 11 — без WSL, без Cygwin, без Docker. Эта страница — глубокое погружение: что работает нативно, что только в WSL, что на самом деле делает установщик и какие специфические для Windows настройки вам могут понадобиться.

Если вы просто хотите установить, однострочник на главной странице или странице установки — всё, что нужно. Возвращайтесь сюда, когда что-то вас удивит.

tip Хотите WSL? Если вы предпочитаете настоящее окружение POSIX (для встроенного терминала панели управления, семантики fork, файловых наблюдателей в стиле Linux и т.д.), смотрите Руководство по Windows (WSL2). Обе установки не мешают друг другу: нативные данные находятся в %LOCALAPPDATA%\\hermes, данные WSL — в ~/.hermes.

Быстрая установка

Откройте PowerShell (или Windows Terminal) и выполните:

irm https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.ps1 | iex

Права администратора не требуются. Установщик помещает файлы в %LOCALAPPDATA%\\hermes\\ и добавляет hermes в ваш User PATH — откройте новый терминал после завершения.

Параметры установщика (требуется форма scriptblock для передачи параметров):

& ([scriptblock]::Create((irm https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.ps1))) -NoVenv -SkipSetup -Branch main
Параметр По умолчанию Назначение
-Branch main Клонировать конкретную ветку (полезно для тестирования PR)
-NoVenv нет Пропустить создание venv (для продвинутых — вы управляете Python сами)
-SkipSetup нет Пропустить мастер hermes setup после установки
-HermesHome %LOCALAPPDATA%\\hermes Изменить каталог данных
-InstallDir %LOCALAPPDATA%\\hermes\\hermes-agent Изменить расположение кода

Что на самом деле делает установщик

Сверху вниз, по порядку:

  1. Устанавливает uv — быстрый менеджер Python от Astral. Устанавливается в %USERPROFILE%\\.local\\bin.

  2. Устанавливает Python 3.11 через uv. Установленный Python не требуется.

  3. Устанавливает Node.js 22 (winget, если доступен, иначе портативный Node tarball, распакованный в %LOCALAPPDATA%\\hermes\\node). Используется для инструмента браузера и моста WhatsApp.

  4. Устанавливает портативный Git — если git уже есть в PATH, установщик использует его; иначе загружает облегчённый, самодостаточный PortableGit (~45 МБ, из официального релиза git-for-windows) в %LOCALAPPDATA%\\hermes\\git. Без прав администратора, без реестра Windows Installer, без помех другим программам.

  5. Клонирует репозиторий в %LOCALAPPDATA%\\hermes\\hermes-agent и создаёт внутри virtualenv.

  6. Многоуровневая uv pip install — сначала пробует .[all], откатывается к последовательно меньшим наборам ([messaging,dashboard,ext][messaging].), если зависимость git+https сбоит из-за лимитов GitHub. Предотвращает режим отказа «один сбой — голая установка».

  7. Автоустановка SDK мессенджеров на основе .env — если присутствуют TELEGRAM_BOT_TOKEN / DISCORD_BOT_TOKEN / SLACK_BOT_TOKEN / SLACK_APP_TOKEN / WHATSAPP_ENABLED, выполняет python -m ensurepip --upgrade и целевые вызовы pip install, чтобы SDK каждой платформы был импортируемым.

  8. Устанавливает HERMES_GIT_BASH_PATH в разрешённый bash.exe, чтобы Hermes находил его детерминированно в новых оболочках.

  9. Добавляет %LOCALAPPDATA%\\hermes\\bin в User PATH — открывает команду hermes после открытия нового терминала.

  10. Запускает hermes setup — обычный мастер первого запуска (модель, провайдер, инструменты). Пропустить с параметром -SkipSetup.

Матрица возможностей

Всё, кроме встроенной терминальной панели дашборда, работает нативно на Windows.

Возможность Нативный Windows WSL2
CLI (hermes chat, hermes setup, hermes gateway, …)
Интерактивный TUI (hermes --tui)
Шлюз мессенджеров (Telegram, Discord, Slack, WhatsApp, 15+ платформ)
Планировщик Cron
Инструмент браузера (Chromium через Node)
Серверы MCP (stdio и HTTP)
Локальный Ollama / LM Studio / llama-server ✓ (через сеть WSL)
Веб-дашборд (сессии, задачи, метрики, конфиг)
Встроенная терминальная панель дашборда /chat ✗ (требуется POSIX PTY)
Автозапуск при входе ✓ (schtasks) ✓ (systemd)

Вкладка /chat дашборда встраивает настоящий терминал через POSIX PTY (ptyprocess). В нативном Windows нет эквивалентного примитива; pywinpty / Windows ConPTY могли бы работать, но это отдельная реализация — рассматривается как будущая работа. Остальная часть дашборда работает нативно — только эта вкладка показывает баннер «используйте WSL2 для этого».

Как Hermes выполняет shell-команды на Windows

Инструмент терминала Hermes выполняет команды через Git Bash — та же стратегия, что использует Claude Code. Это обходит разрыв между POSIX и Windows без переписывания каждого инструмента.

Порядок разрешения bash.exe:

  1. Переменная окружения HERMES_GIT_BASH_PATH, если задана.

  2. %LOCALAPPDATA%\\hermes\\git\\usr\\bin\\bash.exe (PortableGit, управляемый установщиком).

  3. %LOCALAPPDATA%\\hermes\\git\\bin\\bash.exe (старая структура Git-for-Windows).

  4. Системная установка Git-for-Windows (%ProgramFiles%\\Git\\bin\\bash.exe и т.д.).

  5. MSYS2, Cygwin или любой bash.exe в PATH как последнее средство.

Установщик явно задаёт HERMES_GIT_BASH_PATH, чтобы новым сессиям PowerShell не приходилось выполнять повторное обнаружение. Переопределите его, если хотите, чтобы Hermes использовал конкретный bash — например, ваш системный Git Bash или bash из WSL через симлинк.

Ловушка: Структура MinGit отличается от полного установщика Git-for-Windows — bash находится в usr\\bin\\bash.exe, а не в bin\\bash.exe. Hermes проверяет оба варианта. Если вы вручную распаковываете zip-архив MinGit, убедитесь, что выбрали вариант non-busybox (MinGit-*-64-bit.zip, не MinGit-*-busybox*.zip) — сборки busybox поставляют ash вместо bash, и большинство coreutils отсутствуют.

UTF-8 консоль на Windows

Стандартный stdio Python на Windows использует активную кодовую страницу консоли (обычно cp1252 или cp437). Баннер Hermes, список слэш-команд, лента инструментов, панели Rich и описания навыков — всё содержит Unicode. Без вмешательства любое из этого упадёт с UnicodeEncodeError: 'charmap' codec can't encode character….

Исправление находится в hermes_cli/stdio.py::configure_windows_stdio(), вызываемом на раннем этапе во всех точках входа (cli.py::main, hermes_cli/main.py::main, gateway/run.py::main). Он:

  1. Переключает кодовую страницу консоли на CP_UTF8 (65001) через kernel32.SetConsoleCP / SetConsoleOutputCP.

  2. Перенастраивает sys.stdout / sys.stderr / sys.stdin на UTF-8 с errors='replace'.

  3. Устанавливает PYTHONIOENCODING=utf-8 и PYTHONUTF8=1 (через setdefault, так что явные значения пользователя имеют приоритет), чтобы дочерние процессы Python наследовали UTF-8.

  4. Устанавливает EDITOR=notepad, если ни EDITOR, ни VISUAL не заданы (см. раздел о редакторе ниже).

Идемпотентно. Ничего не делает на не-Windows.

Отключение: HERMES_DISABLE_WINDOWS_UTF8=1 в окружении возвращает к устаревшему пути stdio cp1252. Полезно для поиска ошибки кодировки; вряд ли это правильная настройка при нормальной работе.

Редактор (Ctrl-X Ctrl-E, /edit)

До #21561 нажатие Ctrl-X Ctrl-E или ввод /edit молча ничего не делали на Windows. У prompt_toolkit есть жёстко заданный список POSIX-абсолютных резервов (/usr/bin/nano, /usr/bin/pico, /usr/bin/vi, …), который никогда не срабатывает на Windows — даже с полным Git for Windows.

Прокладка Windows stdio в Hermes теперь устанавливает EDITOR=notepad по умолчанию. Блокнот поставляется с каждой Windows и работает как блокирующий редактор — subprocess.call(["notepad", file]) блокируется, пока окно не закроется.

Пользовательские переопределения всё ещё работают (они проверяются до setdefault):

Редактор Команда PowerShell
VS Code $env:EDITOR = "code --wait"
Notepad++ $env:EDITOR = "'C:\Program Files\Notepad++\notepad++.exe' -multiInst -nosession"
Neovim $env:EDITOR = "nvim"
Helix $env:EDITOR = "hx"

Флаг --wait в VS Code критически важен — без него редактор возвращается немедленно, и Hermes получает пустой буфер.

Установите его постоянно в вашем профиле PowerShell:

# In $PROFILE
$env:EDITOR = "code --wait"

Или как переменную окружения пользователя в Системных настройках, чтобы каждая новая оболочка подхватывала её.

Ctrl+Enter для новой строки в CLI

Windows Terminal передаёт Ctrl+Enter как выделенную последовательность клавиш. Hermes привязывает её к «вставить новую строку», чтобы вы могли составлять многострочные промпты в CLI без использования Esc-затем-Enter. Работает в Windows Terminal, встроенном терминале VS Code и любом современном хост-приложении консоли Windows, поддерживающем VT-escape-последовательности.

На устаревших консолях cmd.exe Ctrl+Enter превращается в обычный Enter — используйте Esc Enter вместо этого или обновитесь до Windows Terminal (он бесплатен и установлен по умолчанию на Windows 11).

Запуск шлюза при входе в Windows

hermes gateway install на Windows использует Планировщик заданий (Scheduled Tasks) с запасным вариантом в папку автозагрузки — права администратора не требуются.

Установка

hermes gateway install

Что происходит под капотом:

  1. schtasks /Create /SC ONLOGON /RL LIMITED /TN HermesGateway — регистрирует задачу, которая выполняется при вашем входе со стандартными (не повышенными) правами. Без запроса UAC.

  2. Если schtasks заблокирован групповой политикой, запасной вариант — создание ярлыка start /min cmd.exe /d /c <wrapper> в %APPDATA%\\Microsoft\\Windows\\Start Menu\\Programs\\Startup. Тот же эффект, немного грубее.

  3. Запускает шлюз отсоединённым через pythonw.exe — не python.exe. pythonw.exe не имеет прикреплённой консоли, что защищает его от широковещательных сообщений CTRL_C_EVENT от родственных процессов (реальная проблема, которая раньше убивала шлюз, когда вы нажимали Ctrl+C в любой программе той же группы процессов).

Флаги, используемые при запуске: DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP | CREATE_NO_WINDOW | CREATE_BREAKAWAY_FROM_JOB.

Управление

hermes gateway status      # Merged view: schtasks + Startup folder + running PID
hermes gateway start       # Starts the scheduled task now
hermes gateway stop        # Graceful SIGTERM equivalent (TerminateProcess via psutil)
hermes gateway restart
hermes gateway uninstall   # Removes schtasks entry, Startup shortcut, pid file

hermes gateway status идемпотентен — вызывайте его тысячу раз подряд, и он никогда случайно не убьёт шлюз. (До PR #21561 он это молча делал через os.kill(pid, 0), конфликтующий с CTRL_C_EVENT на уровне C — смотрите «внутреннее устройство управления процессами» ниже, если вам интересна история.)

Почему не служба Windows?

Службы требуют прав администратора для установки и привязывают жизненный цикл шлюза к загрузке машины, а не ко входу пользователя. Типичный пользователь Hermes хочет: вошёл → шлюз доступен, вышел → шлюз отключён. Планировщик заданий делает именно это без повышения прав. Если вам действительно нужна служба, используйте nssm или sc create вручную — но вам это, вероятно, не нужно.

Структура данных

Путь Содержимое
%LOCALAPPDATA%\\hermes\\hermes-agent\\ Git-чекнут + venv. Можно безопасно удалить Remove-Item -Recurse и переустановить.
%LOCALAPPDATA%\\hermes\\git\\ PortableGit (только если установщик его предоставил).
%LOCALAPPDATA%\\hermes\\node\\ Портативный Node.js (только если установщик его предоставил).
%LOCALAPPDATA%\\hermes\\bin\\ Прокладка hermes.cmd, добавленная в User PATH.
%USERPROFILE%\\.hermes\\ Ваш конфиг, аутентификация, навыки, сессии, логи. Сохраняется при переустановках.

Разделение намеренное: %LOCALAPPDATA%\\hermes — это одноразовая инфраструктура (вы можете её удалить, и однострочник восстановит её). %USERPROFILE%\\.hermes — ваши данные (конфиг, память, навыки, история сессий) и по структуре идентична установке Linux. Зеркалируйте её между машинами, и ваш Hermes перемещается вместе с вами.

Переопределение HERMES_HOME: установите переменную окружения, указывающую на другой каталог данных. Работает так же, как на Linux.

Инструмент браузера

Инструмент браузера использует agent-browser (помощник на Node) для управления Chromium. На Windows:

Запуск Hermes на Windows — практические заметки

PATH после установки

Установщик добавляет %LOCALAPPDATA%\\hermes\\bin в ваш User PATH через [Environment]::SetEnvironmentVariable. Существующие терминалы не подхватывают это — откройте новое окно PowerShell (или вкладку Windows Terminal) после установки. Закройте и откройте заново, не делайте $env:PATH += … вручную, если не знаете, что делаете.

Проверка:

Get-Command hermes        # должно вывести C:\Users\<you>\AppData\Local\hermes\bin\hermes.cmd
hermes --version

Переменные окружения

Hermes учитывает как $env:X (в рамках процесса), так и переменные окружения пользователя (постоянные, задаются в Системные настройки → Переменные среды). Установка ключей API в %USERPROFILE%\\.hermes\\.env — это обычный путь, как и на Linux:

OPENROUTER_API_KEY=sk-or-...
TELEGRAM_BOT_TOKEN=...

Не помещайте секреты в переменные окружения пользователя, если вы специально не хотите, чтобы каждый Windows-процесс их видел (это не то, что вам нужно).

Специфичные для Windows переменные окружения

Эти влияют только на нативные установки Windows:

Переменная Эффект
HERMES_GIT_BASH_PATH Переопределить обнаружение bash.exe. Укажите любой bash — полный Git-for-Windows, bash из WSL через симлинк, MSYS2, Cygwin. Установщик задаёт это автоматически.
HERMES_DISABLE_WINDOWS_UTF8 Установите в 1, чтобы отключить прокладку UTF-8 stdio и вернуться к кодовой странице локали. Полезно для поиска ошибки кодировки.
EDITOR / VISUAL Ваш редактор для /edit и Ctrl-X Ctrl-E. Hermes по умолчанию использует notepad, если оба не заданы.

Удаление

Из PowerShell:

hermes uninstall

Это чистый путь — удаляет запись schtasks, ярлык в папке автозагрузки, прокладку hermes.cmd, удаляет %LOCALAPPDATA%\\hermes\\hermes-agent\\ и очищает User PATH. Он не трогает %USERPROFILE%\\.hermes\\ (ваш конфиг, аутентификация, навыки, сессии, логи) на случай, если вы переустанавливаете.

Чтобы удалить всё полностью:

hermes uninstall
Remove-Item -Recurse -Force "$env:USERPROFILE\.hermes"
Remove-Item -Recurse -Force "$env:LOCALAPPDATA\hermes"

Подкоманда CLI hermes uninstall также обрабатывает случай, когда запись schtasks была зарегистрирована под другим именем задачи (старые установки) — она ищет по пути установки, а не по жёстко заданному имени задачи.

Внутреннее устройство управления процессами

Это справочный материал — пропустите, если вы не отлаживаете странность «оно само себя убивает».

На Linux и macOS идиома POSIX os.kill(pid, 0) — это безоперационная проверка прав: «жив ли этот PID и могу ли я отправить ему сигнал?» На Windows Python os.kill сопоставляет sig=0 с CTRL_C_EVENT — они пересекаются по целочисленному значению 0 — и направляет его через GenerateConsoleCtrlEvent(0, pid), который транслирует Ctrl+C на всю группу процессов консоли, содержащую целевой PID. Это bpo-14484, открыт с 2012 года. Он не будет исправлен, потому что изменение сломает скрипты, зависящие от текущего поведения.

Последствие: любой код, который «проверял, жив ли PID» через os.kill(pid, 0) на Windows, молча убивал цель. Hermes перенёс все такие места (14 в 11 файлах) на gateway.status._pid_exists(), который использует psutil.pid_exists() (который, в свою очередь, использует OpenProcess + GetExitCodeProcess на Windows — без сигналов). Если вы пишете плагин или патч, используйте psutil.pid_exists() напрямую или gateway.status._pid_exists() — никогда не os.kill(pid, 0).

scripts/check-windows-footguns.py обеспечивает это в CI: любой новый вызов os.kill(pid, 0) проваливает проверку Windows footguns (blocking), если строка не содержит маркер # windows-footgun: ok — <reason>.

Частые проблемы

hermes: command not found сразу после установки. Откройте новое окно PowerShell. Установщик добавил %LOCALAPPDATA%\\hermes\\bin в User PATH, но существующие оболочки нужно перезапустить, чтобы это подхватилось. Временно вы можете выполнить & "$env:LOCALAPPDATA\hermes\bin\hermes.cmd".

WinError 193: %1 is not a valid Win32 application при запуске инструмента. Вы наткнулись на вызов shebang-скрипта, который обошёл прокладку .cmd. Hermes разрешает команды через shutil.which(cmd, path=local_bin), так что PATHEXT подхватывает .CMD — если вы вызываете инструмент через жёстко заданный путь, переключитесь на вариант .cmd (например, npx.cmd, а не npx).

[scriptblock]::Create(...) завершается ошибкой The assignment expression is not valid. Ваша загрузка install.ps1 получила UTF-8 BOM. Форма irm | iex автоматически удаляет BOM; [scriptblock]::Create((irm ...)) — нет. Повторите с простой формой irm | iex или загрузите скрипт вручную и сохраните без BOM через [IO.File]::WriteAllText($path, $text, (New-Object Text.UTF8Encoding $false)).

Шлюз не остаётся запущенным после перезагрузки. Проверьте hermes gateway status — он объединяет запись schtasks, ярлык в папке автозагрузки (если используется) и живой PID. Если schtasks зарегистрирована, но не запущена, групповая политика может блокировать триггеры ONLOGON. Выполните schtasks /Query /TN HermesGateway /V /FO LIST для просмотра причины сбоя задачи или вернитесь к пути через папку автозагрузки, удалив и переустановив с HERMES_GATEWAY_FORCE_STARTUP=1.

/edit всё ещё ничего не делает после установки $env:EDITOR. Вы установили его только в текущем процессе; закройте и откройте оболочку заново или установите на уровне пользователя в Системные настройки → Переменные среды. Проверьте с помощью echo $env:EDITOR в новом окне PowerShell.

Инструмент браузера запускается, но инструменты выходят по тайм-ауту. Chromium автоматически устанавливается при первом запуске. Если установка не удалась (лимит GitHub, сбой CDN Playwright), выполните hermes doctor — он покажет отсутствующий Chromium и выведет точную команду npx playwright install chromium для исправления.

agent-browser завершается ошибкой со странной версией Node. Установщик предоставляет Node 22 в %LOCALAPPDATA%\\hermes\\node, но ваш PATH может сначала содержать более старую системную Node 18. Переместите каталог Node от Hermes раньше в PATH или удалите системную установку, если вы не используете Node в других местах.

Китайские / японские / арабские символы отображаются как ? в CLI. Прокладка UTF-8 stdio не активировалась. Проверьте, что HERMES_DISABLE_WINDOWS_UTF8 НЕ установлен (Get-ChildItem env:HERMES_DISABLE_WINDOWS_UTF8). Если он пуст, и вы всё ещё видите ?, хост консоли (очень старый cmd.exe) может вообще не поддерживать UTF-8 — переключитесь на Windows Terminal.

Шлюз не может отправлять фотографии в Telegram — «BadRequest: payload contains invalid characters». Это не связано с Windows, но иногда проявляется в первую очередь здесь. Обычно это означает, что ваш путь к файлу содержит неэкранированные обратные слеши в теле JSON. Telegram должен получать пути, нормализованные Hermes, а не сырые Windows-пути — если вы видите это внутри своего плагина, убедитесь, что передаёте путь от Hermes, а не str(Path(...)) из пользовательского ввода.

Странности кодировки «работает на другой моей машине» после git pull. Если вы редактировали конфиг или навык Hermes на Windows с помощью редактора не в UTF-8 (Блокнот на старых версиях Windows, некоторые китайские IME), файл мог быть сохранён с BOM. Hermes допускает utf-8-sig в большинстве операций чтения конфига, но BOM внутри свёрнутого YAML-скаляра (description: >) молча ломает парсинг YAML. Сохраните файл заново как обычный UTF-8 без BOM.

Куда дальше