Подача плагина в каталог плагинов

Каталог плагинов — справочник плагинов Hermes, который проверяют вручную. Попадание в него и есть знак доверия: пользователи ставят плагин из каталога по имени и ровно на том коммите, который прочитал мейнтейнер. На этой странице собраны все правила: как попасть в каталог и как там остаться.

Первоисточник правил приёма — файл plugin-catalog/README.md в репозитории. Раздел с правилами ниже повторяет его слово в слово, а тест роняет сборку, если тексты разойдутся.

Перед подачей

  • Публичный репозиторий. В repo указан https://-адрес, который любой может клонировать (GitHub или GitLab).

  • Плагин, который загружается на закрепляемом коммите. В дереве есть манифест plugin.yaml и минимум одна точка входа, которую Hermes умеет загружать: __init__.py (Python), desktop/plugin.js (десктоп), plugin.json (переносимый Agent Plugin) или dashboard/manifest.json (веб-дашборд). Если плагин лежит в монорепозитории, укажите его каталог в subdir. Структуру описывает руководство разработчика плагинов.

  • Только публичные поверхности. Расширяйте Hermes через хуки, middleware, API ctx.register_*, плагины провайдеров и SDK десктопных плагинов. Код Hermes и разметку десктопа во время работы не патчьте. Если нужного хука нет, смотрите Запрос на хук.

  • Валидация проходит локально. Запустите ту же проверку, что и CI каталога, на checkout коммита, который собираетесь закрепить:

    hermes plugins validate /path/to/your-plugin --install-deps

    Она проверяет манифест и requires_hermes, загружается ли плагин, совпадают ли объявленные capabilities с тем, что плагин регистрирует на самом деле, config_schema и requires_env, Python-зависимости на соответствие базовым ограничениям Hermes, сканер безопасности установки, а также правила desktop surface и no core override. Исправьте все ошибки до открытия PR и прочитайте предупреждения: ревьюер их прочтёт.

Открытие PR

  1. Добавьте один файл, plugin-catalog/<name>.yaml, в NousResearch/hermes-agent. Поля описаны в схеме записи из README и в разделе Из чего состоит запись. Закрепите sha полным 40-символьным коммитом, а version возьмите в кавычки.
  2. В описании PR напишите, что делает плагин, какие поверхности Hermes он использует и обо всём, что требует раскрыть правило 13. Если у плагина есть интерфейс, приложите скриншоты.
  3. Дождитесь зелёного статуса задачи CI каталога. Она клонирует ваш репозиторий на закреплённом коммите и запускает hermes plugins validate.
  4. Мейнтейнер читает закреплённое дерево и либо вливает PR, либо просит правок, либо отклоняет заявку. Нарушения правил 3 и 9 — это отказ, а не просьба поправить баг: чтобы попасть в каталог, плагину нужно менять устройство.

Страница вашего плагина /docs/plugins/<name> строится из того же файла. README на закреплённом коммите показывается там по умолчанию, а screenshots: наполняет галерею. Отдельную карточку поддерживать не нужно.

Правила приёма

  1. Ручное слияние. Записи добавляются только через PR в репозиторий hermes-agent, который проверяет и вливает мейнтейнер. Самообслуживаемого реестра и автоматического приёма нет.

  2. Точный SHA обязателен. Каждая запись закрепляет полный 40-символьный SHA коммита. Ветки, теги и короткие SHA загрузчик отклоняет. При установке репозиторий клонируется и переключается ровно на этот коммит.

  3. Никакого самообновляющегося кода. Плагин из каталога не должен сам скачивать и подменять свои файлы (встроенная «проверка обновлений», загрузчики подписанных релизов, удалённые загрузчики plugin.js). Закрепление по точному SHA и есть модель доверия: самообновление позволяет установленной копии уйти на коммит, который никто не проверял. Обновления доходят до пользователей только через PR с повышением SHA в этот репозиторий и hermes plugins update <name>. Хотите механизм обновления — оставьте его в отдельной сборке плагина и вырежьте из сборки для каталога.

  4. Повышение SHA — это новый PR. Обновление пина записи оформляется новым PR, чей дифф (старый SHA → новый SHA) проверяют заново, как любое другое изменение. Ревьюеры должны смотреть диапазон upstream-коммитов, который принимается.

  5. Подача владельцем или крупным контрибьютором либо курируемая пачка от мейнтейнеров. Запись может подать владелец репозитория плагина или один из его основных контрибьюторов; сторонние подачи чужих репозиториев «мимоходом» отклоняются. Мейнтейнеры Hermes также могут добавлять записи пачками по итогам проверенного обзора плагинов сообщества (каждый пин проверен и просканирован на закреплённом коммите, проверки на самообновление и хранилище учётных данных пройдены, интерфейс на английском в первую очередь). Авторы записей, добавленных таким образом, сохраняют контроль: PR владельца с правкой или удалением его записи принимается по запросу, а повышения SHA остаются PR владельца или мейнтейнера по правилу 4.

  6. Заявленные возможности должны соответствовать действительности. Блок capabilities: (инструменты, хуки, middleware, переменные окружения) обязан совпадать с тем, что плагин реально регистрирует на закреплённом коммите. Иначе валидация отклоняет запись: незаявленное расширение возможностей считается проблемой безопасности.

  7. Сканер установки работает при приёме. hermes plugins validate включает проверку security scan: находки уровня dangerous отклоняют запись, находки caution попадают в лог CI как предупреждения, и ревьюер читает их перед слиянием. Взамен установка на закреплённом SHA принимает caution без запроса (dangerous по-прежнему блокирует). Предупреждения нужно читать; сливать, пропуская их, нельзя.

  8. Десктопные плагины остаются в пределах SDK. desktop/plugin.js работает в рендерере десктопа с полными правами приложения (загрузчик изолирует ошибки, но не возможности), поэтому плагин из каталога может пользоваться только SDK плагинов: никаких патчей прототипов (X.prototype.y =, Object.defineProperty(...prototype), никаких eval/new Function, никакого import() чего-либо, кроме @hermes/plugin-sdk / react (включая чанки бандла приложения, blob- и http-URL), никакой вставки script-тегов, никакого доступа к внутренним хранилищам приложения или его разметке (выбор data-slot / data-tour / data-sidebar / data-testid-элементов из document или MutationObserver на document.body, чтобы перекрашивать, прятать, кликать или переписывать интерфейс ядра). hermes plugins validate отклоняет такое при приёме (проверка desktop surface); если плагину нужна возможность, которой в SDK нет, он просит хук в SDK, а не обходит ограничение патчем.

  9. Никаких подмен ядра Hermes во время работы. Плагин из каталога расширяет Hermes только через публичные поверхности: хуки, middleware, профили провайдеров и остальные API register_*, а также слоты и маршруты SDK десктопа. Он не должен подменять, оборачивать или перепривязывать «на месте» функции, методы, атрибуты модулей и приватные словари ядра (AIAgent.<method> = ..., setattr(server, ...), sys.modules[...], запись в таблицы модуля ядра). Два плагина, патчащие один и тот же шов, незаметно ломают друг друга, а каждый релиз ядра может сломать оба. hermes plugins validate отклоняет такое при приёме (проверка no core override). Если нужного хука нет, заведите issue с описанием: мы лучше добавим шов, чем внесём в каталог патч.

  10. Политика безопасности зависимостей — на стороне плагина. Четырнадцатидневный карантин exclude-newer в Hermes распространяется только на собственные зависимости Hermes; python_dependencies / pyproject.toml плагина устанавливаются по политике плагина (без карантина, но в рамках базовых ограничений ядра Hermes). Ревьюеры читают список зависимостей на закреплённом SHA: «голые» нижние границы (>=X без верхней) и нижние границы на самый свежий релиз получают просьбу указать самую старую совместимую по API нижнюю границу и добавить верхнюю, а авторам настоятельно рекомендуется вести собственный релизный карантин (uv --exclude-newer в их CI); см. раздел «Dependency security policy» в руководстве разработчика. Одной лишь свежей нижней границы недостаточно, чтобы задержать запись.

  11. Учётные данные приходят через Hermes и никогда из файлов. Секреты плагин получает только по маршрутам Hermes. Объявленные им секреты из requires_env и config_schema читаются через agent.secret_scope.get_secret(NAME), который учитывает активный профиль (прямое чтение os.environ при мультиплексировании может взять ключ другого профиля). Вход по подписке (сейчас Codex / ChatGPT) используется только через credentialed_provider_request с requires_auth: токен подставляет Hermes, и плагин его не хранит. Плагин никогда не читает файлы .env, auth.json Hermes, чужой логин (файл токена CLI вендора, профиль браузера, связку ключей) и вообще любое другое хранилище учётных данных напрямую, никогда не обновляет, не ротирует и не записывает OAuth-токены и не выдаёт себя за клиент другого вендора. Если у Hermes нет маршрута для нужных плагину учётных данных, попросите его в issue или PR; плагин не должен обходить это ограничение.

  12. Подтверждения и автономные запуски соблюдаются. Плагин никогда не обходит систему подтверждений Hermes: никакого автоматического одобрения, отключения защит и запуска дочерних процессов Hermes или оболочки, которые наследуют режим YOLO или неинтерактивный режим, чтобы выполнять команды, которые никто не одобрял. Всё, что ждёт человека (запрос, OAuth-поток в браузере), должно чисто завершаться ошибкой или по таймауту в cron, шлюзе сообщений и других автономных запусках, а не подвешивать агента.

  13. Рискованное поведение раскрывается. Всё, что пользователю хотелось бы знать до установки, указывается в описании PR и в README плагина: сетевые вызовы к сторонним сервисам, чтение за пределами собственных данных плагина, shell-команды, долгоживущие фоновые процессы, хранимые учётные данные. Телеметрия и отчёты об использовании включаются только по согласию. Ревьюеры резюмируют это строками раскрытия в PR записи; неописанное поведение, найденное при ревью, — повод запросить правки.

  14. Метаданные совместимости достоверны. requires_hermes — нижняя граница SemVer (">=0.21.5"), а не дата CalVer, и не новее текущего релиза (иначе загрузчик пропустит плагин). version соответствует закреплённому коду, а Python-зависимости разрешаются в пределах базовых ограничений Hermes (CI запускает именно hermes plugins validate --install-deps).

  15. Никаких скинов и форков встроенных плагинов. Изменение встроенного плагина — это PR в hermes-agent, а не конкурирующая запись, и скины, копирующие вендора, не размещаются под брендом Nous.

  16. Одна запись на линию плагина. Форк плагина сообщества, уже стоящего в каталоге, добавляется, только если он существенно отличается от оригинала: другой транспорт или архитектура либо возможность, которой нет в оригинале, если автор отклонил её или 30 дней не отвечает на PR. Улучшения плагина из каталога отправляются автору в виде PR в его репозиторий. Форк с переименованием, ребрендингом или мелкими правками отклоняется в пользу оригинала. Принятый форк называет источник в своей строке раскрытия (Derived from <entry>).

  17. Никаких исполняемых данных, которые нельзя просканировать. Всё, что ревьюер и сканер установки читают на закреплённом коммите, должно быть исходным кодом, который они способны прочитать. Плагин не должен поставлять скомпилированный бинарник (нативный исполняемый файл или библиотеку любой ОС; определяется по заголовку файла, а не по расширению: ELF, Mach-O, PE/MZ, WebAssembly), закоммиченный байткод Python (.pyc/.pyo, включая кэши без исходника или с поддельным хешем, которые выполняются вместо соседнего .py) или архив, чьё содержимое не является проверяемым исходным кодом. Обычный текстовый архив с исходниками (.tar.gz из .py/.ts/.md, который плагин распаковывает) читается как любой другой исходный код; архив с припрятанным бинарником — нет. Сканер не читает машинный код, а контрольная сумма в том же коммите доказывает лишь то, что файл не менялся после коммита, но не то, откуда он взялся. Если плагину действительно нужен нативный компонент, бинарник должен собираться публичными GitHub Actions самого репозитория плагина из исходников этого репозитория и сопровождаться аттестацией сборки GitHub (actions/attest-build-provenance), которая привязывает его к этому workflow и коммиту; проверка сверяет аттестацию с закреплённым коммитом (gh attestation verify --repo <owner/repo> --source-digest <pinned sha>). Бинарник, который машина пользователя скачивает при настройке, допустим только из официального источника upstream-инструмента, с закреплением по контрольной сумме и с раскрытием (правило 13); его нельзя ни включать в плагин, ни брать с неофициального зеркала.

Обновление записи

Обновление пина (повышение sha до более нового коммита) проходит через тот же PR и то же ревью. Ревьюер читает диапазон коммитов, который вы принимаете. Повысьте version в том же PR, чтобы метка, которую видят пользователи, соответствовала коду, и заново закрепите URL из image / screenshots, если в них зашит старый sha.

Установленные плагины сравнивают записанный sha с актуальным пином: hermes plugins list --json показывает update_available, вкладка Plugins в десктопе — кнопку Update to 1.4.0, а hermes plugins update <name> переключает плагин ровно на новый пин.

Если мейнтейнер включил ваш плагин в каталог в составе пачки и вы хотите изменить или убрать запись, откройте PR на её файл. Записи остаются под контролем владельцев.

Исключение и удаление из каталога

  • Исключение удаляет файл записи: так поступают с заброшенными и вытесненными плагинами, с теми, что занимают чужое имя, и с теми, что перестали соответствовать правилам. Пользователи, уже установившие плагин, сохраняют его, а вернуться в каталог можно, как только проблема будет устранена. Если новое правило затрагивает уже включённые плагины, их авторы получают issue в своём репозитории с объяснением изменения и временем на обновление, прежде чем что-либо будет убрано.
  • Удаление вносит плагин в removed.yaml — список, который заведён для инцидентов безопасности и нарушений политики. Установщики отказываются работать с любой записью из этого списка, а уже установленные копии перестают обновляться и не могут быть включены.

Запрос на хук

Если плагину нужно то, чего плагинная поверхность не даёт, заведите issue в hermes-agent и опишите, что нужно и зачем. Мы охотнее добавим полноценный шов, чем внесём в каталог патч, а плагин, который будет использовать хук, — как раз тот конкретный потребитель, который новому хуку и нужен.

перевод и редактура:

обновлено

⌕ ESC