Plugin SDK
[!NOTE] Результат минимального примера: команда
aihummer plugin init serviceсоздаёт файлmanifest.jsonв каталоге плагина. Проверить его можно командойaihummer plugin validate manifest.json, а установить локально — упаковав (package), подписав (sign) и загрузив в свой инстанс (publish --privateили «Загрузить плагин» в админ-панели).
Плагин описывается одним manifest.json. Тот же контракт, что проверяет
манифест на этапе разработки, платформа применяет и на этапе установки, поэтому
манифест, прошедший validate, — это манифест, который примет маркетплейс. CLI
aihummer plugin покрывает весь цикл: от заготовки до подписи и публикации.
Один манифест, один контракт
У плагина ровно один источник истины — его manifest.json. Он объявляет, какой
это вид плагина (kind), как его настраивать (config[]), какие у него
возможности, и — для отдельных сервисов — шаги install[] и команду запуска,
которые выполняет SystemdDeployer. Поскольку
разработка и установка используют один и тот же контракт валидации, «валидный
манифест» и «устанавливаемый плагин» означают одно и то же.
[!NOTE] Манифест описывает контракт плагина, а не его витринное имя. Системный идентификатор (
slug) берётся из имени каталога/пакета (частная загрузка) или из заявки, которую вы заполняете в разделе «Мои плагины» при публикации плагина сообщества — см. Публикация плагина.
CLI
aihummer plugin объединяет команды разработки, упаковки и публикации:
# Создать каркас манифеста (kind: connector | service | openapi | mcp)
aihummer plugin init <kind> [dir]
# Проверить структуру манифеста против контракта установки
aihummer plugin validate <manifest.json>
# Сгенерировать ed25519-ключ автора (пишет <prefix>.key и <prefix>.pub)
aihummer plugin keygen [--out <prefix>]
# Собрать и упаковать плагин в релизный tarball + .sha256
aihummer plugin package <dir> [--out <file>] [--slug <slug>] [--build "<cmd>"]
# Подписать релизную идентичность (slug\0version\0source_ref); с --manifest
# подпись встраивается в поле manifest.signature
aihummer plugin sign --key <priv> [--manifest <m.json>] <bundle|dir>
# Загрузить приватный плагин в свой инстанс (side-load)
aihummer plugin publish --private --instance <url> --token <admin> <bundle.tar.gz>
Чтобы опубликовать плагин для сообщества, CLI-команда не нужна — вы загружаете упакованный, подписанный артефакт из раздела «Мои плагины» (загрузка → ИИ-проверка → модерация). См. Публикация через личный кабинет.
| Команда | Что делает |
|---|---|
init <kind> [dir] |
Создаёт каркас: пишет стартовый manifest.json под выбранный вид. |
validate <m.json> |
Проверяет структуру манифеста тем же контрактом, что и установка. |
keygen |
Генерирует пару ключей автора: .key (приватный, держите в секрете) и .pub, печатает key id. |
package <dir> |
Собирает (опц. --build) и пакует в <slug>-<version>.tar.gz с раскладкой --strip-components=1, пишет .sha256. Никогда не пакует .env, *.key, node_modules, .git. |
sign --key <priv> |
Подписывает релизную идентичность; печатает подпись и key id; с --manifest встраивает подпись в манифест. |
publish --private |
Загружает пакет в POST /v1/admin/modules/upload своего инстанса. |
Подробности обоих путей публикации — частной загрузки (side-load) и публикации для сообщества через личный кабинет — на странице Публикация плагина.
Поля манифеста
Обязательность поля зависит от вида (kind) и от того, публичный ли это
плагин. Базовые и идентификационные поля:
| Поле | Тип | Обязательно | Назначение |
|---|---|---|---|
kind |
string | всегда | Вид: connector | service | openapi | mcp. |
version |
string | да | Версия плагина (semver), напр. 1.0.0. |
contract |
string | для каналов | ID контракта, напр. aihummer.channel.v1. |
scope |
string | нет | Модель доступа: shared (по умолчанию) или personal. |
capabilities |
string[] | нет | Заявленные возможности. |
config |
object[] | нет | Поля формы настройки; у каждого обязателен key, плюс label, secret, required. |
oauth |
object | нет | OAuth2 (authorize_url, token_url, scopes[]) для подключения аккаунта пользователя. |
signature |
string | для подписи | base64 ed25519-подпись релизной идентичности (встраивает sign). |
Поля по виду — ровно одно из блоков заполняется в зависимости от kind:
| Поле | Для вида | Обязательно | Назначение |
|---|---|---|---|
host_native.exec_start |
connector, service | да | Команда запуска долгоживущего сервиса. |
host_native.runtime |
connector, service, mcp | нет | node | python | binary. |
host_native.install |
connector, service, mcp | нет | Шаги установки (массив shell-команд), выполняются на хосте после распаковки. |
host_native.port |
connector, service | нет | Предпочтительный TCP-порт (deployer может переназначить через $PORT). |
host_native.health_path |
connector, service | нет | Путь health-check (по умолчанию /healthz). |
openapi.spec_url |
openapi | да | URL спецификации OpenAPI 3.x. |
openapi.base_url |
openapi | нет | Переопределение servers[0].url. |
openapi.allowed_hosts |
openapi | нет | Egress-allowlist для синтезированных инструментов. |
openapi.auth |
openapi | нет | Маппинг securityScheme → имя секрета. |
openapi.tool_prefix |
openapi | нет | Префикс имён инструментов. |
mcp.transport |
mcp | да | stdio или http. |
mcp.command / mcp.args |
mcp (stdio) | да для stdio | Исполняемый файл сервера и аргументы. |
mcp.url |
mcp (http) | да для http | URL MCP-endpoint. |
mcp.auth_header / mcp.secret_token_key |
mcp (http) | нет | Заголовок и ключ секрета для bearer-токена. |
Поля витрины и идентичности (для плагинов сообщества)
Манифест также может нести идентичность издателя и витринные поля. Для community-плагина именно они показываются в каталоге, но обычно вы вводите их в витрине «Мои плагины» в личном кабинете при отправке заявки (название, описания, иконка, скриншоты, категория, ссылка на донат), а не вручную в манифесте. Для частной загрузки они не требуются — такой плагин доверяется на уровне инстанса.
| Поле | Тип | Обязательно | Назначение |
|---|---|---|---|
visibility |
string | нет | public | private | unlisted. Пусто = legacy/первопартийный (без требования идентичности). |
publisher |
string | для public | Namespace издателя, ^[a-z0-9][a-z0-9-]{1,38}$. Публичные слаги именуются @publisher/slug. |
publisher_key_id |
string | для public | key id ключа, которым подписан артефакт. |
description |
string | для public | Текст витрины (блурб) в каталоге. |
icon |
string | для public | Иконка плагина: https://-URL или data:-URI. |
screenshots |
string[] | нет | Скриншоты витрины (массив https://-URL; каждый непустой). |
[!TIP] Запускайте
aihummer plugin validateперед отправкой. Контракт установки и валидации идентичен, поэтому манифест, прошедший проверку локально, примет и deployer маркетплейса, и проверка маркетплейса в личном кабинете.
Минимальные манифесты
Каркас вида service (то, что пишет aihummer plugin init service):
{
"version": "1.0.0",
"kind": "service",
"scope": "shared",
"contract": "aihummer.channel.v1",
"host_native": {
"runtime": "node",
"install": ["npm ci --omit=dev"],
"exec_start": "node dist/main.js",
"port": 8800,
"health_path": "/healthz"
},
"config": [
{ "key": "api_token", "label": "API token", "secret": true, "required": true }
]
}
Манифест вида openapi (без разработки) ещё короче — он просто указывает на
спецификацию:
{
"version": "1.0.0",
"kind": "openapi",
"scope": "shared",
"openapi": {
"spec_url": "https://api.example.com/openapi.json",
"tool_prefix": "example_",
"allowed_hosts": ["api.example.com"],
"auth": { "bearerAuth": "api_token" }
},
"config": [
{ "key": "api_token", "label": "API token", "secret": true, "required": true }
]
}
Манифест вида mcp (stdio-транспорт):
{
"version": "1.0.0",
"kind": "mcp",
"scope": "shared",
"host_native": { "runtime": "node", "install": ["npm ci --omit=dev"] },
"mcp": { "transport": "stdio", "command": "node", "args": ["server.js"] }
}
От манифеста к маркетплейсу
После валидации плагин упаковывается (package), подписывается (sign) и
публикуется одним из двух способов:
- Приватно (для себя) — частная загрузка в свой инстанс через админ-панель
или
publish --private. Артефакт не покидает инстанс. - Для сообщества (для всех) — загрузите упакованный, подписанный артефакт из раздела «Мои плагины» в личном кабинете; после ИИ-проверки и модерации человеком он подписывается и публикуется в каталог сообщества.
Полный разбор — на странице Публикация плагина.
Куда дальше
- Публикация плагина — частная загрузка и публикация для сообщества через личный кабинет, проверка и модерация.
- Интеграции без разработки — виды
openapiиmcpподробно. - Установка и обновления — что приводят в
действие
install[], проверка/healthz, доверие и подписанные обновления. - Маркетплейс: обзор и уровни — где находится каждый вид и чем официальный каталог отличается от каталога сообщества.