AiHummer доки
v1.0.x
RU EN

Plugin SDK

v1.0.x · обновлено 2026-06-27

Плагин описывается одним manifest.json. Тот же контракт, что проверяет манифест на этапе разработки, платформа применяет и на этапе установки, поэтому манифест, прошедший validate, — это манифест, который примет маркетплейс. CLI aihummer plugin покрывает весь цикл: от заготовки до подписи и публикации.

Один манифест, один контракт

У плагина ровно один источник истины — его manifest.json. Он объявляет, какой это вид плагина (kind), как его настраивать (config[]), какие у него возможности, и — для host-native сервисов — шаги install[] и команду запуска, которые выполняет SystemdDeployer. Поскольку разработка и установка используют один и тот же контракт валидации, «валидный манифест» и «устанавливаемый плагин» означают одно и то же.

[!NOTE] Манифест описывает контракт плагина, а не его витринное имя. Машинный slug берётся из имени директории/бандла (private side-load) или из поля сабмишна (public) — см. Публикация плагина.

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>

# Открыть PR в публичный каталог AiHummer/marketplace-catalog
aihummer plugin publish --public --dir <dir> --key <priv> \
  --artifact-url <url> --publisher <name> \
  --description <text> --icon <url> [--screenshot <url> ...] \
  [--channel stable|beta] [--register-key <pub>]
КомандаЧто делает
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 своего инстанса.
publish --publicОткрывает PR в AiHummer/marketplace-catalog.

Подробности обоих режимов публикации — на странице Публикация плагина.

Поля манифеста

Обязательность поля зависит от вида (kind) и от того, публичный ли это плагин. Базовые и идентификационные поля:

ПолеТипОбязательноНазначение
kindstringвсегдаВид: connector | service | openapi | mcp.
versionstringдаВерсия плагина (semver), напр. 1.0.0.
contractstringдля каналовID контракта, напр. aihummer.channel.v1.
scopestringнетМодель доступа: shared (по умолчанию) или personal.
capabilitiesstring[]нетЗаявленные возможности.
configobject[]нетПоля формы настройки; у каждого обязателен key, плюс label, secret, required.
oauthobjectнетOAuth2 (authorize_url, token_url, scopes[]) для подключения аккаунта пользователя.
signaturestringдля подписиbase64 ed25519-подпись релизной идентичности (встраивает sign).

Поля по виду — ровно одно из блоков заполняется в зависимости от kind:

ПолеДля видаОбязательноНазначение
host_native.exec_startconnector, serviceдаКоманда запуска долгоживущего сервиса.
host_native.runtimeconnector, service, mcpнетnode | python | binary.
host_native.installconnector, service, mcpнетШаги установки (массив shell-команд), выполняются на хосте после распаковки.
host_native.portconnector, serviceнетПредпочтительный TCP-порт (deployer может переназначить через $PORT).
host_native.health_pathconnector, serviceнетПуть health-check (по умолчанию /healthz).
openapi.spec_urlopenapiдаURL спецификации OpenAPI 3.x.
openapi.base_urlopenapiнетПереопределение servers[0].url.
openapi.allowed_hostsopenapiнетEgress-allowlist для синтезированных инструментов.
openapi.authopenapiнетМаппинг securityScheme → имя секрета.
openapi.tool_prefixopenapiнетПрефикс имён инструментов.
mcp.transportmcpдаstdio или http.
mcp.command / mcp.argsmcp (stdio)да для stdioИсполняемый файл сервера и аргументы.
mcp.urlmcp (http)да для httpURL MCP-эндпоинта.
mcp.auth_header / mcp.secret_token_keymcp (http)нетЗаголовок и ключ секрета для bearer-токена.

Поля витрины и идентичности (для публичных плагинов)

Чтобы плагин попал в публичный каталог, манифест должен нести идентичность издателя и витринные поля. Для приватного side-load они не требуются — такой плагин доверяется на уровне инстанса.

ПолеТипОбязательноНазначение
visibilitystringнетpublic | private | unlisted. Пусто = legacy/первопартийный (без требования идентичности).
publisherstringдля publicNamespace издателя, ^[a-z0-9][a-z0-9-]{1,38}$. Публичные слаги именуются @publisher/slug.
publisher_key_idstringдля publickey id ключа, которым подписан артефакт.
descriptionstringдля publicТекст витрины (блурб) в каталоге.
iconstringдля publicИконка плагина: https://-URL или data:-URI.
screenshotsstring[]нетСкриншоты витрины (массив 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 }
  ]
}

Манифест zero-code вида 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) и публикуется в одном из двух режимов:

  • Приватно (для себя) — side-load в свой инстанс через Admin UI или publish --private. Артефакт не покидает инстанс.
  • Публично (для всех)publish --public открывает PR в публичный каталог; после ревью AiHummer контрподписывает релиз и публикует его в community-каталог.

Полный разбор — на странице Публикация плагина.

Куда дальше