Управление пакетами
hermes pm управляет бинарниками инструментов Hermes и окружениями Python-зависимостей.
Приложение он не обновляет: сам Hermes обновляйте тем
способом, который соответствует установке.
Пины, установленное состояние и выбор среды выполнения
У каждого файла своя роль:
| Файл | Роль |
|---|---|
pm/lock.json | Точные версии управляемых инструментов, URL под каждую целевую платформу и хеши SHA-256. |
pm/pyproject.toml и pm/uv.lock | Собственные Python-требования менеджера зависимостей и их зафиксированное разрешение. |
pyproject.toml и uv.lock | Python-требования, extras, платформенные маркеры и закоммиченное разрешение зависимостей. |
facts.json хранилища инструментов | Записи установленных инструментов, их идентичность, экспортируемые переменные окружения и дайджесты реально развёрнутых файлов. |
facts.json конкретной установки | Выбранное Python-окружение, штамп его входных данных и включённые extras. |
manifest.json полезной нагрузки | Относительная раскладка полезной нагрузки и готовый контракт запуска от сборщика бандла. |
install-stamp.json | Происхождение сборки и объявленный владелец дистрибуции и обновлений. |
Запись в lock-файле ещё не доказывает, что пакет установлен. hermes pm doctor
сравнивает установленное состояние с lock-файлом и проверяет фактические байты.
При запуске выполняется проверка подешевле: сверка версий с апстримом при каждом старте не делается.
Для самоуправляемых установок из исходников лаунчер ещё до импортов сравнивает
записанный PM штамп последней успешной синхронизации зависимостей с текущими входными данными.
Если отметки о завершении нет или она устарела, запускается синхронизация, после чего
та же команда перезапускается на управляемом Python, и только потом загружаются
зависимости приложения. Неудачная синхронизация оставляет прежний выбор, а попытка
повторяется при следующем запуске; маркер отложенного обновления для этого не нужен.
У developer-чекаутов и пакетных установок владелец остаётся прежним.
Старые апдейтеры после подмены дерева исходников ещё могут выполнить старый Python-код.
Поэтому совместимые точки входа запускают новый дочерний процесс, ждут его завершения
и возвращают его код выхода. Бутстрап дочернего процесса просит PM подготовить
обязательные инструменты и выбрать поколение Python до импортов приложения. Завершение
обновления идёт уже в этом интерпретаторе, с контекстом обновления и квитанцией.
Родительский процесс не очищает sys.modules, не импортирует граф нового приложения
и не возвращается к запасному пути через pip.
Нынешние обновления из исходников передают выбранный чекаут новому владельцу этапа
завершения. Его бутстрап-Python отключает инициализацию site-packages и только потом
просит PM синхронизировать записанные extras и включённые плагины. Дальше выбранный
Python отвечает за сборку фронтенда, обслуживание профилей и конфигурации, перезапуск
шлюзов и проверку среды выполнения. Тем же путём идут Git, повторы для уже актуальной
версии и запасной вариант через ZIP. Исходная команда на время ожидания держит
блокировку обновления; если результата завершения нет или он неудачный, об успехе
она сообщить не может. Связанные сбои PM остаются в квитанции обновления, а прерванные
перезапуски сохраняют обязательство перед парком шлюзов.
Сбои зависимостей или сборки никогда не повторяются через pip или повторное скачивание исходников.
Повреждённые файлы зависимостей чините командой hermes pm repair. Подробнее — в заметке для разработчиков
о владельце этапа завершения обновления из исходников.
Установки из исходников и пакетные сборки
Установщики из исходников ставят обязательные инструменты и Python и выбирают
Python-extra all. Именованные опциональные инструменты ставятся по запросу.
Для канонической установки из исходников десктоп проверяет и запускает опубликованный
лаунчер установки. Интерпретатором и выбором зависимостей распоряжается PM. Подставлять
вместо этой команды угаданный путь к venv десктоп не станет. Переопределения
разработчика сохраняют выбранный ими интерпретатор.
Нативные десктопные бандлы перед упаковкой раскладывают поддерживаемый набор
инструментов и все Python-extras, совместимые с целевой платформой. --extra all и --all-extras —
не синонимы. Зависимости, которые на целевой платформе не запустятся, по-прежнему
отсекаются платформенными маркерами.
Полный сборщик десктопа объединяет PM с провайдерами упаковки для Node и нативного кода.
Из чистого чекаута на релизном теге команда python scripts/bundles/desktop.py --tag vX.Y.Z
готовит зависимости и собирает установщик. С --prepare-only работа останавливается
после подготовки; её результат, привязанный к конкретному заданию, потом подаётся так:
python scripts/bundles/desktop.py --prepared .build/desktop-job/prepared.json.
--work и --cache задают отдельные корневые каталоги, которыми владеет сборка. Рабочий
каталог создаёт этап подготовки, а не вызывающий код. Вместо тега можно передать полный
SHA коммита через --commit; чекаут должен ему соответствовать.
Подготовка использует изолированное состояние PM, закреплённые инструменты, свежие Python-окружения с привязкой к путям, полное объединение JS-воркспейсов, нативные биндинги и утилиты упаковки. Переиспользуемые кэши зависимостей — это не живые установки и не переносимые виртуальные окружения. Подготовленный результат привязан к исходникам, целевой платформе и путям: если входные данные пропали или изменились, использование завершится ошибкой, а не запуском загрузки. После перемещения или изменения входных данных подготовку нужно повторить. Подписи и нотаризации сеть по-прежнему может понадобиться. Требования к нативным компиляторам и ограничения проверки релизов описаны в руководстве по сборке десктопа.
Базовая полезная нагрузка пакетного приложения неизменяема. Hermes запускает бэкенд прямо из неё, а не копирует чекаут исходников при первом запуске. Сборщик бандла проверяет её файлы и записывает пути запуска в штамп сборки десктопа. Electron берёт эти пути как есть, ничего не прощупывая и не чиня. Дополнительные закреплённые инструменты могут жить в доступном для записи хранилище инструментов. Для Python-дополнений используется полноценное записываемое окружение вне подписанного пакета. Его первое поколение сохраняет поставленные с приложением extras вместе с новыми требованиями. Последующие поколения берут за основу записанный набор extras.
Для Termux есть отдельная сборка под bionic и запечатанный APT-пакет. Docker запекает среду выполнения в образ и отключает установку зависимостей по требованию. Nix поставляет среду выполнения через деривации. Их ограничения описаны в руководствах по Termux, Docker и Nix.
Записываемое состояние
Корень данных по умолчанию — ~/.hermes на POSIX и
%LOCALAPPDATA%\hermes в Windows. HERMES_HOME и профили могут поменять
корень данных, с которым работает процесс.
| Состояние | Расположение по умолчанию |
|---|---|
| Общие записываемые записи инструментов | tools/ в разрешённом корне Hermes по умолчанию. |
| Докачиваемые загрузки | cache/partials/ в том же корне, а не внутри подписанной полезной нагрузки. |
| Выбор и журнал конкретной установки | installs/INSTALL_KEY/ в корне состояния зависимостей. |
| Поколения Python | installs/INSTALL_KEY/environments/. |
| Квитанции синхронизации и обновления | logs/update_receipts/ в активном домашнем каталоге. |
Ключ установки выводится из канонического пути к исходникам или к репозиторию полезной нагрузки. Поэтому у разных чекаутов разные выборы Python. Профили, которые делят одну установку, могут добавлять зависимости в одно и то же окружение, а конфигурация и учётные данные у каждого профиля остаются своими.
Не правьте вручную facts и пути поколений. Лаунчеры определяют выбранное окружение до импортов сторонних пакетов. Уже запущенные процессы сохраняют свои импорты до перезапуска. Сборка мусора не трогает выбранные поколения и поколения под управлением аренды, у которых есть живые читатели.
Загрузки одного и того же частичного URL делят общую блокировку. Неудачная или
приостановленная передача не может опубликовать частично скачанный файл, а сборка
мусора не удалит файлы идущей передачи. Докачка переиспользует диапазоны, только если
совпадают записанная длина, валидатор и (если есть) хеш. Без сильного ETag или
закреплённого хеша прерванная передача начинается заново, чтобы не смешать разные версии.
Маленькие файлы в .locks/ остаются и после завершения, чтобы ожидающие процессы
пользовались той же блокировкой.
Опциональные Python-зависимости и плагины
Встроенная функция запрашивает extra проекта через pm.ensure_import.
Каталоговые плагины объявляют Python-требования в pyproject.toml. Если проектный
файл автор не написал, PM объединяет устаревшие списки pip_dependencies и
python_dependencies из plugin.yaml или plugin.yml. Старый проектный файл,
сгенерированный PM, эти списки не перекрывает. Согласие пользователя, состав
зависимостей и проверки актуальности опираются на один и тот же читатель объявлений.
PM готовит требования ядра, включённые extras и требования включённых плагинов вместе. Разрешение зависимостей стартует от существующего lock-файла. Совместимые транзитивные версии могут поменяться, но объявленные ограничения и точные пины остаются обязательными. Каждый кандидат получает свежий воркспейс с явно заданными исходниками, затравкой lock-файла и входными данными подготовленного окружения. Сгенерированный воркспейс и расширенный lock-файл лежат вне поставляемых исходников. Восстановление копирует записанные воркспейс и lock-файл, включая входные данные сборки плагинов, а не разрешает зависимости заново по отредактированным живым манифестам.
Включение плагинов и подготовленные обновления кода передаются изолированному воркеру PM как данные. Под блокировкой установки он выясняет предлагаемое объединение зависимостей, проверяет кандидата и публикует файлы конфигурации или плагинов и метаданные вместе с выбором окружения. Входные данные, изменившиеся во время подготовки, он отклоняет. Надёжный журнал позволяет восстановиться ещё до импортов приложения, в том числе после обновлений только кода, которым новое окружение не нужно.
Изменения выбора плагинов, включая включение наборов, проходят через ту же транзакцию допуска. Перед каждым изменением PM читает свежий выбор под общей блокировкой. Неудачный кандидат не заменяет выбранное окружение и втихую не отключает другие плагины. Даже если подготовка прошла успешно, запущенному процессу Hermes может понадобиться перезапуск, чтобы новое окружение заработало.
Обычные обновления приложения Hermes пользовательские каталоги плагинов не трогают. Явное обновление плагина может поменять файлы выбранного плагина. Обёртка без объявленных Python-зависимостей в общее окружение не входит. Её внешний sidecar-процесс остаётся в отдельном владении. См. руководство по плагинам.
Политика отложенной установки
Установкой по требованию управляет security.allow_lazy_installs. Уже установленные
зависимости остаются рабочими, даже если параметр выставлен в false.
hermes config set security.allow_lazy_installs false
Явные команды установки — отдельная история, к установке по требованию они не относятся. Однако при отключённой отложенной установке замороженный список функций бандла всё равно ограничивает запрашиваемые имена Python-extras. Явный допуск плагина — тоже отдельная операция, а не запрос функции по требованию. Не считайте этот параметр песочницей или общим запретом на ручную установку пакетов. Docker вдобавок выставляет в образе внутренний флаг отключения отложенной установки.
PM — менеджер зависимостей, а не песочница для кода плагинов. Ставя плагин, вы доверяете и ему, и его зависимостям.
Опциональные инструменты безопасности
Закреплёнными пакетами bws и iron-proxy в
pm/security_packages.py владеет PM. Их версии, URL артефактов и хеши SHA-256
берутся из pm/lock.json. Загрузка и публикация идут через общее хранилище
инструментов, а не через собственные установщики в $HERMES_HOME/bin.
Для iron-proxy PM дополнительно получает закреплённые файлы подписей и проверяет, что контрольные суммы релиза покрывают закреплённый архив. При раскладке пакета вызывается проверщик подписей самой интеграции. Проверка GPG по-прежнему выполняется, только если соответствующая программа есть в системе. Зафиксированные в lock-файле файлы происхождения должны быть доступны и совпадать по хешам. Явный отказ при проверке подписи прерывает установку. На внешние исполняемые файлы гарантии PM по хешам и подписям не распространяются.
bws и iron-proxy сначала берут исполняемый файл из PATH и только потом смотрят на выбор PM.
Отложенная установка подчиняется политике PM. Явные команды
установки проверяют и чинят управляемые записи, в том числе запросы с --force.
Рабочий процесс разработчика
Активация просит PM подготовить или синхронизировать тулчейн для чекаута исходников, а затем делает его доступным в оболочке. Python-интерпретатор вашего редактора она не выбирает и установленное десктопное приложение на этот чекаут не перенаправляет.
Подготовка чекаута
Работайте в обычном терминале, не внутри пакетного приложения Hermes. Если активно
какое-то виртуальное окружение Python, сначала выйдите из него. В Windows используйте
нативный PowerShell с Git.
На ARM64 PM перед каждой сборкой зависимостей из чекаута готовит инструменты Visual Studio C++,
Clang, нативный Rust и статические библиотеки разработки OpenSSL — это касается
setup, activate.ps1, install.ps1, hermes update и восстановления. Существующие
установки он переиспользует, а недостающие компоненты доставляет. Для недостающих
компонентов Visual Studio нужны права администратора: интерактивная установка
спросит их через окно UAC, а для CI, ssh и запуска по расписанию понадобится
PowerShell от имени администратора. OpenSSL ставится через
триплет vcpkg arm64-windows-static-md. Повреждённая общая установка
даёт ошибку с предложением восстановления, а не удаляется автоматически. Переменные
окружения компилятора и OpenSSL действуют только на сборку зависимостей в PM и
никогда — на вашу оболочку.
На других платформах по-прежнему нужны нативные компиляторы и библиотеки для зависимостей, у которых нет совместимых wheel-пакетов.
Для закреплённого Python на macOS PM по умолчанию выставляет AR в /usr/bin/ar: sysconfig
поставляемого интерпретатора всё ещё указывает на временный каталог LLVM его поставщика.
Это относится и к сборке из исходников, и к сборке бандлов. Явно заданные AR и CC
имеют приоритет; тулчейн интерпретатора, переданного вызывающей стороной (например,
Python из Nix), PM не меняет. Значение CC по умолчанию для текущего пина не нужно.
Склонируйте репозиторий и переключитесь на нужную ветку до подготовки зависимостей:
git clone https://github.com/NousResearch/hermes-agent.git
cd hermes-agent
Для изолированной разработки задайте отдельный домашний каталог данных до первой команды PM. Возвращаясь к этому чекауту, используйте те же значения.
Bash, из корня репозитория:
export HERMES_HOME="$HOME/hermes-dev-data"
export HERMES_RUNTIME_DIR="$HERMES_HOME/tools"
source ./activate
PowerShell, из корня репозитория:
$env:HERMES_HOME = Join-Path $HOME 'hermes-dev-data'
$env:HERMES_RUNTIME_DIR = Join-Path $env:HERMES_HOME 'tools'
. .\activate.ps1
HERMES_RUNTIME_DIR в этих примерах — переопределение для разработки, действующее
только в текущем процессе. Благодаря ему бутстрап и PM пишут в одно и то же хранилище.
Не прописывайте такой путь насовсем в установленный MSIX или бандл macOS. Активация
запускает ветку setup-скрипта, которая касается только среды выполнения: ставит
инструменты и синхронизирует Python-extra all. dev она не выбирает и JS-воркспейсы
не ставит. Команды, локальные для установки, она поддерживает и чинит уже существующие
обёртки в PATH, которыми владеет, но новых удобств в PATH не создаёт и конфигурацию
приложения не загружает. Пользовательскую часть установки из setup она тоже пропускает:
настройку оболочки, .env и встроенные навыки.
Если нужен полный процесс установки, запустите setup-скрипт отдельно.
Пока Python нет, бутстрап оболочки скачивает закреплённый интерпретатор. Как только Python запускается, работа с зависимостями передаётся PM. Приватный движок PM сначала готовит свою небольшую зафиксированную среду выполнения и только потом разрешает зависимости приложения. Его проект не зависит от воркспейса приложения: сломанная зависимость приложения не должна мешать запуску менеджера зависимостей.
uv — внутренняя деталь реализации PM. Код приложения, процессы установки и вызовы из сборки запрашивают Python-операции, а не исполняемые файлы uv или их аргументы. Не меняйте окружение Hermes напрямую через pip или uv.
В среде выполнения PM есть ruamel.yaml, packaging, tomli-w и truststore, но не
дерево зависимостей приложения. В ней работают команды CLI, а также установки и
восстановления, которые запрашивает приложение. Поиск путей и установленных инструментов
только на чтение выполняется локально. Проверки актуальности окружения идут через
готовый воркер PM. В импорты уже работающего агента PM свои зависимости никогда не
добавляет. Собственные читатели и писатели YAML
используют ruamel; сторонним пакетам в окружении приложения по-прежнему может
понадобиться PyYAML. Квитанции о сбоях обходятся только стандартной библиотекой.
CLI и воркер PM активируют truststore до импорта своих HTTPS-клиентов.
Так используется системное хранилище сертификатов, даже если вкомпилированные в
бутстрап-Python пути OpenSSL его не находят. Ни зависимости приложения, ни
переопределение пути к сертификатам не нужны. После первой установки PM при следующем
вызове пересобирает своё небольшое окружение на управляемом Python; дальнейшие вызовы
его переиспользуют.
pm.venv_is_current() проверяет через уже существующий воркер PM, даже когда
отложенная установка отключена. Ради проверки PM никогда не бутстрапится. Если среда
выполнения менеджера недоступна, функция возвращает false и не качает ни инструменты,
ни зависимости. Чтобы заранее подготовить PM, выполните явный hermes pm install.
Нативные бандлы и Docker-образы раскладывают этот же lock-файл PM через общий сборщик среды выполнения. Termux передаёт этому сборщику проверенный офлайн-набор wheel-пакетов. Nix собирает lock-файл PM отдельной деривацией. Упакованные воркеры используют только записанный каталог зависимостей PM и никогда — библиотеки приложения.
Активация существующей установки
В каждой новой оболочке восстановите значения домашнего каталога для разработки и перейдите в чекаут. Затем активируйте его — отдельную команду setup помнить не нужно:
| Оболочка | Войти | Выйти |
|---|---|---|
| Bash | source ./activate | deactivate |
| fish | source ./activate.fish | deactivate |
| PowerShell | . .\activate.ps1 | deactivate |
Точка с пробелом в начале команды PowerShell обязательны. Если выполнить
.\activate.ps1 без dot-sourcing, область видимости сессии будет другой.
activate написан на синтаксисе Bash. Для этого рецепта используйте именно Bash,
а не sh, и не рассчитывайте, что стартовый файл Zsh поведёт себя как Bash; у fish
есть собственный activate.fish, который работает так же.
Каждая активация вызывает путь install/sync в PM и доверяет записанному дайджесту
инструментов, не пересчитывая хеш каждой записи. Недостающий инструмент PM всё равно
поставит, а устаревшее поколение зависимостей пересоберёт; при намеренной установке
побайтовая проверка сохраняется. Чтобы перепроверить фактические байты, запустите
python -m pm.cli install или hermes update. Если setup падает, ошибка возвращается
до того, как окружение активированной оболочки изменится, — в том числе при повторном
source уже активного окружения.
После синхронизации активация добавляет установленные инструменты PM в начало PATH и
выставляет PYTHONPATH на этот чекаут и выбранное для него дерево зависимостей. Ещё она
определяет hermes как функцию оболочки для этого worktree. Функция запускает CLI
этого чекаута и перекрывает установленную команду, включая псевдоним MSIX.
Работает она, только пока оболочка находится внутри этого worktree, а снаружи отказывается,
поэтому соседний worktree команду не унаследует. В приглашении появляется префикс
с именем ветки, который пропадает за пределами дерева. Системный PATH активация
не меняет и привычный префикс venv в приглашение не ставит.
Начинайте с чистой оболочки, а не вкладывайте это в другой venv.
deactivate восстанавливает значения окружения, сохранённые скриптом активации,
и убирает функцию и префикс приглашения.
Пакеты при этом не удаляются, а запущенные вами процессы не останавливаются.
Чтобы выполнить одну команду или скрипт в этом окружении без активации оболочки,
поставьте перед ней scripts/run-in-hermes-env. Он применяет то же окружение
только к этой команде: сначала синхронизирует, если наследовать нечего или
унаследованное окружение устарело, а саму оболочку не трогает. Так же
перезапускает себя scripts/run_tests.sh, и Python-скрипты репозитория
передают себя этому запуску из своего shebang.
scripts/run-in-hermes-env python scripts/release.py --help
Перед работой проверьте интерпретатор и исходники:
python -c "import sys, pm; print(sys.executable); print(pm.__file__)"
python -c "import httpx; print(httpx.__file__)"
node --version
npm --version
hermes --version
python должен указывать на интерпретатор из хранилища PM, а pm.__file__ — вести
внутрь этого чекаута. Зависимости берутся из выбранного окружения, которое может
лежать вне репозитория. Если импорт не находится, значит, setup или выбор окружения
требуют внимания, даже если сам source ./activate завершился успешно.
Работа с этим деревом исходников
Пока оболочка внутри worktree, hermes — это CLI именно этого worktree. За его
пределами функция отказывается работать, так что запустить дерево другого чекаута
или провалиться в установленную команду она не может:
hermes setup
hermes
hermes --tui
python -m pm.cli status
Эти команды работают с выбранным домашним каталогом для разработки. Правка исходного файла видна следующему процессу. После правок перезапустите затронутые CLI, шлюз или бэкенд. Для изменений только в Python-коде переустанавливать все зависимости не нужно.
Для JavaScript-воркспейсов один раз выполните npm ci в корне репозитория, а затем
запускайте команду нужного воркспейса. Например:
npm run build --workspace ui-tui
npm run dev --workspace apps/desktop
Сайт устроен отдельно: npm ci --prefix website, затем
npm run build:fast --prefix website. Активация PM поставляет инструменты, но не эти
каталоги node_modules и не собранные ассеты. Для нативной сборки десктопа есть
дополнительные требования — см. руководство по сборке десктопа.
Обновление зависимостей без смены ветки
После смены ветки или lock-файла снова выполните source скрипта активации — он
синхронизирует и выберет новые зависимости (source ./activate в Bash или
. .\activate.ps1 в PowerShell). Чтобы синхронизировать без активации оболочки:
python -m pm.cli install
После отдельной синхронизации заново активируйте окружение и перезапустите затронутые
процессы. Для диагностики инструментов есть python -m pm.cli doctor, а
python -m pm.cli status покажет последнюю квитанцию синхронизации. Не запускайте
hermes update только ради обновления feature-ветки: это обновление приложения,
и оно может сменить ветку исходников.
Имена управляемых инструментов и имена Python-extras — разные интерфейсы:
python -m pm.cli install chromium
python -c "from pm import sync_venv; sync_venv(['anthropic'], explicit=True)"
Первая команда ставит инструмент. Вторая добавляет объявленный extra среды выполнения
к уже существующему выбору Python для этой установки. Extras накапливаются через
синхронизацию PM. Группы зависимостей dev и test относятся только к отдельному
тестовому окружению, а не к выбранному venv приложения. После изменения extras
заново активируйте окружение, прежде чем запускать другой Python-процесс.
Синхронизация после правки pyproject.toml
-
Отредактируйте
pyproject.toml. Каждую зависимость закрепите так, как требует политика закрепления зависимостей. Платформенные ограничения выражайте маркерами PEP 508 или закрывайте весь extra целиком в[tool.hermes.extras-platforms]. -
Перезафиксируйте зависимости:
hermes pm lockКоманда заново разрешает
uv.lockпоpyproject.tomlс теми же настройками, что проверяет CI, включая 14-дневный карантинexclude-newer. Окружения она не меняет. Если lock-файл уже актуален, она так и скажет и ничего не запишет. (hermes pm lock --bump NAME VERSION— другая операция: она закрепляет управляемый инструмент вpm/lock.jsonиuv.lockне трогает.) -
Снова выполните source скрипта активации (
source ./activateили. .\activate.ps1в PowerShell), чтобы синхронизировать venv приложения и тестовый интерпретатор с новым lock-файлом. Активация покрывает[all]. Если вы добавили extra по выбору, не входящий в[all],hermes pm lockнапечатает команду, которая заодно поставит его в тестовый интерпретатор, напримерsource ./activate --test-extras all,NAME. -
Закоммитьте
pyproject.tomlиuv.lockвместе.
Для JS-зависимостей обновите манифест и lock-файл пакета-владельца. Не правьте facts PM или сгенерированные воркспейсы и не ставьте пакеты прямо в выбранное поколение.
Тестовые окружения и окружения для редактора
source ./activate (или . .\activate.ps1 в PowerShell) и оба прямых скрипта
setup-hermes готовят изолированный тестовый интерпретатор из зафиксированных групп
зависимостей dev и test. Его использует scripts/run_tests.sh, который заново
активирует окружение, если изменились чекаут или входные данные его зависимостей.
Venv приложения, установщики и бандлы ни одну из этих групп не выбирают. По умолчанию
для разработки покрывается [all]; чтобы изменить покрытие тестов, передайте
--test-extras=anthropic при POSIX-активации или -TestExtras anthropic в PowerShell;
эти аргументы выбирают extras среды выполнения только в тестовом интерпретаторе.
В изолированной среде, где активация недоступна (например, в dev-оболочке Nix),
вызывающая сторона может явно передать HERMES_PYTHON с pytest или собрать
независимое одноразовое окружение:
python -m pm.build_env --source . --out .venv --group dev --group test
Каталог вывода не должен существовать. Чтобы пересоздать окружение, остановите его
процессы и сознательно удалите только это одноразовое окружение. Затем запустите
scripts/run_tests.sh (в Windows — через Bash). Тестовая группа зависимостей включает
тесты нативного лаунчера и никогда не попадает в упакованную среду выполнения.
Для отладки в редакторе выберите этот независимый интерпретатор, укажите рабочим
каталогом этот чекаут и запускайте hermes как скрипт. Держите его HERMES_HOME
отдельно от рабочего. Активация в терминале не настраивает уже запущенный редактор.
Не направляйте редактор на временное поколение PM или на Python-интерпретатор
подписанного приложения.
Python-интерфейсы операций
Для работы с Python-зависимостями используйте публичный модуль pm:
| Операция | За что отвечает |
|---|---|
pm.sync_venv(extras, explicit=True) | Готовит и выбирает полное объединение зависимостей приложения, включая включённые плагины. |
pm.sync_venv(repair=True, explicit=True) | Воспроизводит записанный набор зависимостей в новом поколении приложения. |
pm.build_environment(source=..., out=..., explicit=True) | Собирает и проверяет свежий вывод, которым владеет вызывающая сторона. Без поиска плагинов и без выбора окружения приложения. |
pm.lock_project(source, explicit=True) | Обновляет lock-файл явно указанного проекта, не выбирая окружение. |
pm.ensure_environment(name, requirements, explicit=True) | Готовит и выбирает изолированное поколение зависимостей. Возвращает путь к его Python. |
pm.ensure_python_tool(name, requirements, executable, explicit=True) | Готовит изолированный инструмент и возвращает путь к его исполняемому файлу. |
pm.environment_python(name) / pm.python_tool(name, executable) | Читают выбранные пути, ничего не устанавливая. |
pm.venv_is_current() | Спрашивает у готового воркера PM, актуальны ли зависимости приложения. Возвращает false, если среда выполнения менеджера недоступна. |
pm.stage_manager_runtime(...) — исключение для бутстрапа. Эта функция раскладывает
собственную зафиксированную среду выполнения PM напрямую через приватный движок,
потому что через свой воркер эта среда собрать себя не может. uv вызывающей стороне
она не раскрывает.
pm.build_env — интерфейс командной строки для явных сборок и работы с lock-файлами.
Поддерживаемые опции покажет python -m pm.build_env --help. По умолчанию сборки
проекта используют закоммиченный lock-файл. --resolve разрешает зависимости перед сборкой.
--python задаёт явный интерпретатор для сборки. --sealed убирает ссылки .pth
времени сборки. --offline и --cache управляют получением зависимостей.
Для сборок окружения приложения PM уже должен запускаться в вызывающем Python. Бутстрапом интерпретатора такие сборки не служат. Они не меняют импорты работающего приложения и не заменяют выбранное им окружение. Декларативные сборки uv2nix в Nix остаются под управлением Nix. Команды пакетных менеджеров для посторонних проектов или песочниц агента самим Hermes не управляют.
Команды
hermes pm --help
hermes pm doctor
hermes pm status
hermes pm install
hermes pm install chromium
| Команда | Что делает |
|---|---|
pm install [names...] | Ставит указанные пакеты. Без имён — готовит обязательные инструменты и Python, добавляет эти инструменты в PATH и затем синхронизирует extra all. Голый install заодно ставит опциональные инструменты по умолчанию (agent-browser и Chromium, cua-driver); если их загрузка не удалась, печатается предупреждение, но установка не падает. Если назвать пакет, от которого вы раньше отказались, отказ отменяется. |
pm install --without NAME | Голый install без опционального пакета по умолчанию NAME (agent-browser или cua-driver) с запоминанием этого выбора. Последующие голые install и hermes update тоже будут его пропускать. На этом построены флаги установщиков --skip-browser / -SkipBrowser и --skip-computer-use / -SkipComputerUse. |
pm install --tools-only | Ставит это замыкание инструментов, добавляет его в PATH и останавливается. Синхронизация venv не запускается. |
pm env [names...] | Печатает в JSON значения окружения, которые PM добавляет для установленных пакетов. Недостающие пакеты не ставит, хотя холодный запуск Hermes может сначала подготовить собственную среду Python. |
pm doctor | Сверяет идентичность, файлы и дайджесты установленных инструментов с lock-файлом. |
pm repair | Пересобирает записанный набор Python-зависимостей в новом поколении, проверяет его и выбирает. Пины, функции и конфигурацию плагинов не обновляет. |
pm status | Печатает последнюю квитанцию синхронизации/обновления в JSON или сообщает, что квитанций нет. |
pm gc | Удаляет записи хранилища инструментов без ссылок, подходящие под удаление частичные загрузки и неиспользуемые поколения Python под управлением аренды, а также состояние installs/INSTALL_KEY/ удалённых checkout (worktree, убранный из всё ещё существующего каталога .worktrees/, или клон в корне данных; checkout, которых этот процесс не видит, например установка хоста, видимая из контейнера с общим корнем данных, остаются, как и любое состояние, чья блокировка установки или аренда поколения ещё удерживается). Чистильщик worktree, который запускается при старте, тоже освобождает такие осиротевшие каталоги состояния. |
pm env не выводит унаследованные переменные процесса, в том числе учётные данные.
Но локальные пути установки в его выводе видны — просмотрите его, прежде чем кому-то отправлять.
Команды для мейнтейнеров
Эти команды меняют входные данные зависимостей или раскладывают артефакты сборки. Механизм обновления установленного приложения они не заменяют.
| Команда | Что делает |
|---|---|
pm lock | Перезафиксирует uv.lock по pyproject.toml. Окружения не меняет; если lock-файл актуален, ничего не пишет. |
pm lock --bump NAME VERSION | Разрешает и хеширует артефакты для поддерживаемых целевых платформ, затем записывает пин инструмента в pm/lock.json. |
pm update [names...] | Запрашивает версии в апстриме, меняет пины инструментов и ставит изменившиеся инструменты. |
pm update --check | Запрос без записи. Код выхода 1 может означать, что есть обновления; чтобы отличить это от ошибки, смотрите вывод. |
pm update --target TARGET | Разрешает версии для указанной целевой платформы. |
pm update --uv / --npm | Заодно обновляет разрешение Python- или npm-зависимостей. |
pm update --termux [--check] | Перезакрепляет архивы пула termux, которые скользящий пул уже убрал (таблица пинов runtime-lib и строки lock-файла bionic). --check только сообщает, ничего не записывая, и завершается с кодом 1, если какой-то пин выбыл. |
pm install --target TARGET NAME... | Раскладывает явно указанные пакеты для другой платформы, не записывая их как установленную среду выполнения хоста. Цель win32 git закрепляет самораспаковывающийся архив PortableGit: при раскладке запускается распаковщик вендора, поэтому нужен хост на Windows. |
pm bundle --out DIR [--ref REF] | Раскладывает снимок исходников, нативные инструменты, facts и Python-зависимости. Подписанный десктопный установщик не создаёт. |
Полный сборщик десктопа вдобавок собирает JavaScript-интерфейсы, генерирует лаунчеры и вызывает нативную упаковку. Мейнтейнерам — сюда: Building the Desktop Installers.
Повторы сетевых запросов
PM повторяет запросы при временных HTTP-сбоях во время загрузки инструментов,
хеширования артефактов и поиска версий. На каждую проверку или передачу — не больше
четырёх попыток. Паузы между ними — 1, 2 и 4 секунды. Заголовок Retry-After может
удлинить паузу, но не больше чем до 30 секунд. О каждом повторе в лог пишется причина,
задержка и номер следующей попытки.
Повторяются HTTP-статусы 408, 429, 500, 502, 503 и 504. Сбросы соединения, таймауты, временные сбои DNS и оборванные тела ответов тоже приводят к повтору. Загрузки по диапазонам сохраняют уже полученные байты. С серверами без поддержки диапазонов приходится начинать поток заново. Пауза прерывает ожидание перед повтором и сохраняет частичную загрузку.
Плохие хеши, ошибки сертификатов, ошибки локальной файловой системы и прочие постоянные сбои PM не повторяет. Если проверка прошла успешно, а GET по диапазону вернул 403 или 404, остаётся запасной путь через CDN: одна последовательная попытка скачать недостающие диапазоны. Распаковка, проверка и публикация не повторяются. Запросы к Python- и npm-пакетам подчиняются собственным политикам повторов uv и npm.
Диагностика
- Медленная сборка Python-зависимостей: потоковые команды uv в PM включают подробный вывод. Логи бандлов и сборок показывают активность пакетов и stdout/stderr бэкенда сборки прямо во время сборки, а не только после сбоя.
- Инструмент отсутствует или устарел: посмотрите вывод
hermes pm doctor, затем выполните явную установку через PM на записываемой установке. - Новому окружению нужен перезапуск: перезапустите затронутый процесс Hermes. Не подкладывайте второе дерево site-packages в его живые импорты.
- Конфликт зависимостей: посмотрите
hermes pm status. Исправьте требования плагина и только потом повторяйте допуск. - Повреждённые Python-зависимости: выполните
hermes pm repair, затем перезапустите Hermes. Восстановление воспроизводит сохранённые воркспейс и lock-файл выбранного поколения, не разбирая конфигурацию плагинов. Если запись нечитаема или сохранённого lock-файла нет, восстановление завершается ошибкой, а урезанный набор зависимостей не выбирается. Пока ни одного поколения нет, восстановление берёт поставляемый или закоммиченный lock-файл и записанный набор функций. - Прерванная установка зависимостей: при запуске до активации зависимостей запрашивается то же восстановление PM. Число автоматических попыток ограничено;
pm repairповторяет его явно. Неудачное восстановление сохраняет прежний выбор и его маркер повтора. - Повреждён исполняемый файл Python или исходники приложения: восстановите или переустановите их через владельца пакета. Без этих файлов PM работать не может. Файлы подписанной полезной нагрузки восстановление зависимостей никогда не меняет.
- Неизвестный пакет или extra: используйте объявленное имя.
pm installпринимает имена пакетов, а не имена Python-extras или спецификации pip.