SDK de complementos
Un complemento se describe por uno manifest.json. El contrato que valida el manifiesto durante el desarrollo es el mismo que la plataforma aplica en el momento de la instalación, por lo que un manifiesto que pasa validate es un manifiesto que el mercado aceptará. El aihummer plugin La CLI cubre todo el ciclo de vida: desde la creación del esqueleto hasta la firma y publicación.
Un manifiesto, un contrato
Un complemento tiene exactamente una fuente de verdad: la suya manifest.json. Declara el tipo de complemento (kind), cómo está configurado (config[]), sus capacidades, y — para los servicios nativos del anfitrión — la install[] pasos y el comando de inicio que el DesplegadorSystemd se ejecuta. Debido a que el desarrollo y la instalación utilizan el mismo contrato de validación, “manifiesto válido” y “plugin instalable” significan lo mismo.
[!NOTE] El manifiesto describe el de un complemento contrato, no su nombre en la página de la tienda. El máquina
slugproviene del nombre del directorio/paquete (carga lateral privada) o de la entrega que llenas «Mis complementos» al publicar un complemento comunitario — ver Publicando un complemento.
CLI
aihummer plugin agrupa los comandos de desarrollo, empaquetado y publicación:
# Scaffold a manifest (kind: connector | service | openapi | mcp)
aihummer plugin init <kind> [dir]
# Validate a manifest against the install contract
aihummer plugin validate <manifest.json>
# Generate an ed25519 author key (writes <prefix>.key and <prefix>.pub)
aihummer plugin keygen [--out <prefix>]
# Build and package the plugin into a release tarball + .sha256
aihummer plugin package <dir> [--out <file>] [--slug <slug>] [--build "<cmd>"]
# Sign the release identity (slug\0version\0source_ref); with --manifest the
# signature is embedded into the manifest.signature field
aihummer plugin sign --key <priv> [--manifest <m.json>] <bundle|dir>
# Upload a private plugin into your own instance (side-load)
aihummer plugin publish --private --instance <url> --token <admin> <bundle.tar.gz>
Publicar un comunidad complemento para todos, tú haces no utiliza un comando CLI — subes el artefacto empaquetado y firmado desde tu Mis complementos en el gabinete personal (subir → revisión de IA → moderación). Ver Enviar un complemento.
| Comando | Lo que hace |
|---|---|
init <kind> [dir] |
Escribe un iniciador manifest.json para la clase elegida. |
validate <m.json> |
Valida el manifiesto con el mismo contrato que la instalación. |
keygen |
Genera el par de claves del autor: .key (privado, mantener en secreto) y .pub, imprime el key id. |
package <dir> |
Construcciones (opcional) --build) y se empaqueta en <slug>-<version>.tar.gz con un --strip-components=1 diseño, escribe .sha256. Nunca empaques .env, *.key, node_modules, .git. |
sign --key <priv> |
Señales de la identidad de la liberación; imprime la firma y key id; con --manifest incrusta la firma en el manifiesto. |
publish --private |
Sube un paquete a la instancia de su POST /v1/admin/modules/upload. |
Ambos caminos de publicación — carga lateral privada y publicación comunitaria a través del gabinete personal — se detallan en Publicando un complemento.
Campos del manifiesto
Si un campo es obligatorio depende de la amable y sobre si el complemento es público. Campos de base e identidad:
| Campo | Tipo | Requerido | Propósito |
|---|---|---|---|
kind |
cadena | siempre | Tipo: connector | service | openapi | mcp. |
version |
cadena | sí | Versión del plugin (semver), p. ej. 1.0.0. |
contract |
cadena | para canales | ID del contrato, por ejemplo aihummer.channel.v1. |
scope |
cadena | no | Modelo de acceso: shared (predeterminado) o personal. |
capabilities |
cadena[] | no | Capacidades declaradas. |
config |
objeto[] | no | Configurar los campos del formulario; cada uno necesita key, más label, secret, required. |
oauth |
objeto | no | OAuth2 (authorize_url, token_url, scopes[]) para conectar la cuenta de un usuario. |
signature |
cadena | cuando se firme | firma ed25519 en base64 sobre la identidad de la versión (incrustada por sign). |
Campos específicos de tipo — exactamente uno el bloque se llena dependiendo de kind:
| Campo | Por amable | Requerido | Propósito |
|---|---|---|---|
host_native.exec_start |
conector, servicio | sí | Comando que ejecuta el servicio de larga duración. |
host_native.runtime |
conector, servicio, mcp | no | node | python | binary. |
host_native.install |
conector, servicio, mcp | no | Pasos de instalación (arreglo de comandos de shell), ejecutar en el host después de la extracción. |
host_native.port |
conector, servicio | no | Puerto TCP preferido (el implementador puede reasignar a través de $PORT). |
host_native.health_path |
conector, servicio | no | Ruta de verificación de salud (predeterminada /healthz). |
openapi.spec_url |
openapi | sí | URL de la especificación OpenAPI 3.x. |
openapi.base_url |
openapi | no | Anular servers[0].url. |
openapi.allowed_hosts |
openapi | no | Lista de permitidos de salida para las herramientas sintetizadas. |
openapi.auth |
openapi | no | Mapa securityScheme → nombre secreto. |
openapi.tool_prefix |
openapi | no | Prefijo del nombre de la herramienta. |
mcp.transport |
mcp | sí | stdio o http. |
mcp.command / mcp.args |
mcp (stdio) | sí para stdio | Ejecutable del servidor y argumentos. |
mcp.url |
mcp (http) | sí para http | URL del endpoint MCP. |
mcp.auth_header / mcp.secret_token_key |
mcp (http) | no | Encabezado y clave secreta para el token bearer. |
Campos de página de la tienda e identidad (para plugins de la comunidad)
El manifiesto también puede contener la identidad del editor y los campos de la página de la tienda. Para un comunidad plugin estos son los que muestra el catálogo, pero normalmente los ingresas en el «Mis complementos» página de la tienda en su gabinete personal en el momento de la presentación (nombre, descripciones, ícono, capturas de pantalla, categoría, enlace de donación) en lugar de a mano en el manifiesto. Una carga lateral privada no necesita ninguno de ellos; dicho complemento es confiable a nivel de instancia.
| Campo | Tipo | Requerido | Propósito |
|---|---|---|---|
visibility |
cadena | no | public | private | unlisted. Vacío = legado/propietario original (sin requisito de identidad). |
publisher |
cadena | para el público | Espacio de nombres del editor, ^[a-z0-9][a-z0-9-]{1,38}$. Los slugs públicos se llaman @publisher/slug. |
publisher_key_id |
cadena | para el público | key id de la clave con la que está firmado el artefacto. |
description |
cadena | para el público | Descripción breve de la página de la tienda en el catálogo. |
icon |
cadena | para el público | Icono del complemento: un https:// URL o un data: URI. |
screenshots |
cadena[] | no | Capturas de pantalla de la página de la tienda (arreglo de https:// URLs; cada una no vacía). |
[!TIP] Correr
aihummer plugin validateantes de que lo envíes. La instalación y validación los contratos son idénticos, por lo que un manifiesto que pase localmente será aceptado en ambos por el implementador del mercado y por la revisión del mercado en su gabinete personal.
Manifestaciones mínimas
A service andamio (qué aihummer plugin init service escribe):
{
"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 }
]
}
Cero código openapi el manifiesto es aún más corto — solo apunta a la especificación:
{
"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 }
]
}
Un mcp manifiesto (transporte 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"] }
}
Del manifiesto al mercado
Después de la validación, se empaqueta un complemento (package), firmado (sign) y publicado de una de dos maneras:
- Privado (para ti) — cargar lateralmente en tu instancia a través de la interfaz de administración o
publish --private. El artefacto nunca abandona la instancia. - Comunidad (para todos) — sube el artefacto empaquetado y firmado desde el Mis complementos en tu gabinete personal; después de la revisión de IA y la moderación humana, se firma y se publica a la comunidad catálogo.
Ver Publicando un complemento para la guía completa.
¿A dónde vamos después?
- Publicando un complemento — carga lateral privada y publicación comunitaria a través del gabinete personal, revisión y moderación.
- Integraciones sin código — el
openapiymcptipos en detalle. - Instalar y actualizar — qué impulsa
install[], la puerta de salud, la confianza y las actualizaciones firmadas. - Mercado: visión general y niveles — dónde cada tipo vive y cómo el catálogo oficial difiere de la comunidad.