AiHummer
Русский
Войти
v1.0.x
{ }Swagger

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) и от того, публичный ли это плагин. Базовые и идентификационные поля:

Поле Тип Обязательно Назначение
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-эндпоинта.
mcp.auth_header / mcp.secret_token_key mcp (http) нет Заголовок и ключ секрета для bearer-токена.

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

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

Поле Тип Обязательно Назначение
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 }
  ]
}

Манифест 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-каталог.

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

Куда дальше