El manifiesto del plugin

En esta página

Todo plugin en sandbox tiene un archivo emdash-plugin.jsonc en su directorio raíz. Está junto a package.json cuando el plugin también es un paquete de npm. El manifiesto identifica el plugin, declara el acceso y el almacenamiento que necesita y aporta información para su ficha en el registro y para sus versiones. La CLI de plugins lo lee al validar, compilar, empaquetar, publicar y preparar versiones automatizadas.

El archivo usa JSON con comentarios (JSONC), por lo que los comentarios y las comas finales son válidos. Conserve la propiedad $schema creada por emdash-plugin init; los editores usan el esquema generado para el autocompletado, mientras que emdash-plugin validate realiza la comprobación completa.

El siguiente ejemplo incluye cada grupo de campos:

{
	"$schema": "./node_modules/@emdash-cms/plugin-cli/schemas/emdash-plugin.schema.json",

	"slug": "gallery",
	"publisher": "did:plc:abc123def456",

	"license": "MIT",
	"author": { "name": "Jane Doe", "url": "https://example.com" },
	"security": { "email": "[email protected]" },
	"name": "Gallery",
	"description": "Image galleries for EmDash content.",
	"keywords": ["gallery", "images"],
	"sections": {
		"installation": { "file": "./docs/installation.md" },
		"faq": { "file": "./docs/faq.md" },
	},

	"capabilities": ["content:read"],
	"allowedHosts": [],
	"storage": {
		"galleries": { "indexes": ["contentId"] },
	},

	"admin": {
		"pages": [{ "path": "/gallery", "label": "Gallery", "icon": "image" }],
	},

	"repo": "https://github.com/example/plugin-gallery",
	"release": {
		"requires": { "env:emdash": ">=0.37.0" },
		"artifacts": {
			"icon": { "file": "./images/icon.png" },
			"screenshots": [{ "file": "./images/editor.png", "lang": "en" }],
		},
	},
}

Identidad y versión

CampoObligatorioReglas
slugSíEmpieza por una letra minúscula y después usa letras minúsculas, dígitos, - o _; máximo 64 caracteres.
publisherSíDID o handle de la cuenta de Atmosphere. Se recomienda un DID porque los handles pueden cambiar de propietario.
versionA vecesSemver 2.0 sin metadatos de compilación. Omítalo cuando package.json aporte la versión.

El publisher y el slug identifican el paquete en el registro. El slug también se usa en las URL de las rutas del plugin, por lo que no es el nombre del paquete de npm: use gallery para un paquete como @example/plugin-gallery.

Mantenga un único valor de versión

La compilación concilia version con package.json#version:

  • Si ambos archivos establecen la versión, los valores deben coincidir.
  • Si un solo archivo establece la versión, la compilación usa esa.
  • Si ninguno de los dos archivos establece la versión, la compilación falla.

Para un paquete de npm, mantenga la versión en package.json y omítala en el manifiesto. Un plugin solo de registro, sin package.json, debe establecer version en el manifiesto.

Perfil del paquete

El perfil del paquete aporta la información estable que se muestra en todas las versiones.

CampoObligatorioReglas
licenseSíExpresión SPDX no vacía, de hasta 256 caracteres.
author o authorsSíUse una de las dos formas. author tiene un name de hasta 64 grafemas y un url o email opcional; authors acepta de 1 a 32 entradas.
security o securityContactsSíUse una de las dos formas. Cada contacto debe contener un email, un url o ambos; la lista acepta de 1 a 8 entradas.
nameNoNombre para mostrar, de hasta 100 grafemas. Si falta, se usa el slug.
descriptionNoDescripción breve, de hasta 140 grafemas.
keywordsNoHasta cinco cadenas no vacías, cada una de no más de 64 grafemas.
sectionsNoSecciones largas en CommonMark para description, installation, faq, changelog y security.

Cada sección puede ser una cadena en línea o una referencia a un archivo relativa al manifiesto:

"sections": {
	"description": "A longer description written in CommonMark.",
	"installation": { "file": "./docs/installation.md" },
	"security": { "file": "./SECURITY.md" },
}

Cada sección resuelta está limitada a 20 000 bytes y 2000 grafemas. Una referencia a un archivo debe permanecer dentro del directorio del manifiesto; se rechazan las rutas absolutas y las rutas con .. que se salgan de él.

publish crea el perfil del paquete en la primera versión. Las versiones posteriores no reemplazan sus campos de perfil. Edite un perfil publicado con emdash-plugin update-package: el comando muestra una vista previa de los cambios de forma predeterminada y solo los escribe con --yes.

Contrato de confianza

El contrato de confianza se compone de capabilities, allowedHosts y storage. Estos campos indican a un operador a qué puede acceder el plugin y qué colecciones propias crea.

La siguiente declaración permite lecturas de contenido, permite solicitudes a una API y a sus subdominios, y crea una colección de almacenamiento:

"capabilities": ["content:read", "network:request"],
"allowedHosts": ["api.example.com", "*.cdn.example.com"],
"storage": {
	"events": {
		"indexes": ["savedAt", ["collection", "savedAt"]],
		"uniqueIndexes": ["eventId"],
	},
}

Capabilities y hosts

Los tres campos están vacíos de forma predeterminada. El scaffold escribe explícitamente los valores vacíos para que quien revise vea que el plugin no solicita acceso ni colecciones adicionales.

network:request requiere al menos un nombre de host simple en allowedHosts. network:request:unrestricted requiere una lista vacía porque permite deliberadamente cualquier host público. Capabilities y seguridad es la referencia canónica de cada capability, sus implicaciones, los patrones de host y la aplicación en tiempo de ejecución.

Almacenamiento

Cada clave de storage nombra una colección propia del plugin. Sus indexes y uniqueIndexes determinan por qué campos puede filtrar u ordenar el plugin. Storage explica los nombres de colección, el diseño de índices, las consultas y la paginación.

Cambiar cualquier parte del contrato de confianza requiere una nueva versión del plugin, porque los sitios instalados consintieron la declaración anterior. Use una versión mayor cuando el contrato se amplíe.

Páginas de administración y widgets

Los plugins en sandbox renderizan páginas de administración y widgets del panel con Block Kit. El manifiesto declara dónde aparecen:

"admin": {
	"pages": [{ "path": "/settings", "label": "Settings", "icon": "settings" }],
	"widgets": [{ "id": "recent-events", "title": "Recent events", "size": "half" }],
}

Las rutas de página empiezan por / y contienen letras, dígitos, /, _ o -. Los ID de widget usan los mismos caracteres de identificador en minúsculas que los slugs de plugin. Los tamaños de widget son full, half o third.

Una página también puede establecer group para unirse a una carpeta plegable de la barra lateral. La coincidencia distingue entre mayúsculas y minúsculas, y se ignoran los espacios en blanco circundantes. Si un grupo coincide con el grupo de una colección que se muestra en la barra lateral, la página se coloca en esa carpeta; las páginas que comparten cualquier otro grupo, de cualquier plugin, forman una carpeta con esa etiqueta en la sección Plugins.

Un plugin que declare una página o un widget debe definir una ruta llamada admin en src/plugin.ts. La comprobación del paquete falla si falta esa ruta, porque EmDash no tendría a qué llamar para obtener la respuesta de Block Kit.

Campos de la versión

release describe una versión concreta. La URL repo de nivel superior se escribe en los registros de versión y, además, la configuración de versiones automatizadas la usa para vincular el perfil del paquete con su repositorio de GitHub.

CampoFinalidad
repoURL HTTPS del repositorio de código fuente. La configuración de versiones automatizadas requiere una URL canónica de un repositorio público de GitHub.
release.requiresRequisitos del host, con env:<name> o un DID de paquete como clave y rangos semver como valores.
release.artifacts.iconImagen que se muestra como icono de la versión.
release.artifacts.bannerImagen de banner para el listado de la versión.
release.artifacts.screenshotsGalería ordenada de capturas de pantalla con hasta ocho entradas.

Use env:emdash y env:astro para establecer los rangos de versiones de EmDash y Astro que pueden instalar la versión:

"release": {
	"requires": {
		"env:emdash": ">=0.37.0",
		"env:astro": ">=5.0.0 <7.0.0",
	},
}

EmDash comprueba estos requisitos antes de la instalación. Un rango no válido hace fallar la validación del manifiesto; una versión incompatible no se instala.

Las rutas de los archivos de artefactos son relativas al manifiesto y deben permanecer dentro de su directorio. Se admiten PNG, JPEG y WebP. Cada archivo está limitado a 1 MiB y 8192 píxeles en cualquiera de sus dimensiones. Una propiedad opcional lang identifica una imagen localizada con una etiqueta de idioma BCP 47. Al publicar, estos archivos se suben por separado del paquete del plugin y se registran su tipo medido, sus dimensiones, su suma de comprobación y su referencia de blob en el servidor de datos personales (PDS).

Fijación del publisher

publisher evita una publicación accidental desde la cuenta de Atmosphere equivocada. Prefiera el DID de la cuenta:

"publisher": "did:plc:abc123def456", // jane.example.com

Antes de publicar o de preparar versiones automatizadas, la CLI compara el publisher del manifiesto con la sesión activa. Un handle se resuelve a su DID actual para la comparación. Una discrepancia falla con MANIFEST_PUBLISHER_MISMATCH; no existe ninguna opción para forzarlo.

Si está activa la sesión equivocada, ejecute emdash-plugin whoami y luego cambie a la cuenta fijada:

emdash-plugin switch did:plc:abc123def456

Cambie el publisher del manifiesto solo cuando transfiera el paquete a otra cuenta.

Validar el manifiesto

Valide el manifiesto antes de compilar o publicar:

emdash-plugin validate

Pase un archivo o un directorio para validar un manifiesto distinto:

emdash-plugin validate ./packages/plugin-gallery

La validación se realiza sin conexión. Informa de propiedades duplicadas, campos desconocidos, valores no válidos, formas mutuamente excluyentes y errores entre campos, como network:request sin una lista allowedHosts no vacía.

Continúe con la CLI de plugins para los comandos de compilación o con Empaquetar y publicar para el flujo de publicación.