Manifiesto del plugin
Manifiesto del plugin
Cada plugin incluye un archivo manifest.json junto a su código fuente. El manifiesto declara los metadatos del plugin, los recursos de Databricks que este necesita y cualquier regla estructurada que un agente de scaffolding deba respetar al ejecutar databricks apps init. Se consume en tres etapas:
- Creación —
import manifest from "./manifest.json"y adjúntalo a la subclasePluginmediantestatic manifest. - Sincronización —
appkit plugin sync --writeagrupa los manifiestos de los paquetes instalados y de los plugins locales enappkit.plugins.json. - Inicialización —
databricks apps initleeappkit.plugins.jsonpara determinar la selección de plugins, las solicitudes de recursos y la generación de.env/databricks.yml/app.yaml.
Esta página documenta el contrato de manifiesto v2.0. El JSON Schema se publica en https://databricks.github.io/appkit/schemas/plugin-manifest.schema.json; haz referencia a él mediante $schema para habilitar la validación en el editor.
Patrón recomendado
Escribe el manifiesto en JSON, impórtalo en el módulo del plugin y afirma el tipo:
// packages/my-plugin/src/index.ts
import { Plugin, toPlugin } from "@databricks/appkit";
import type { PluginManifest } from "@databricks/appkit";
import manifest from "./manifest.json";
class MyPlugin extends Plugin {
static manifest = manifest as PluginManifest<"my-plugin">;
// ...
}
export const myPlugin = toPlugin(MyPlugin);// packages/my-plugin/src/manifest.json
{
"$schema": "https://databricks.github.io/appkit/schemas/plugin-manifest.schema.json",
"name": "my-plugin",
"displayName": "My Plugin",
"description": "A custom plugin",
"resources": {
"required": [],
"optional": []
}
}JSON es el formato canónico de creación: es lo que lee appkit plugin sync. Los manifiestos JS (manifest.js / manifest.cjs) se ignoran de forma predeterminada y requieren --allow-js-manifest para habilitarlos (ejecuta código del plugin; requiere confianza). Para conocer el comportamiento completo de la CLI, consulta Gestión de plugins.
Campos obligatorios
| Campo | Tipo | Notas |
|---|---|---|
name | string | Identificador del plugin. En minúsculas, comienza con una letra, solo [a-z0-9-]. |
displayName | string | Se muestra en la UI y en las indicaciones de la CLI. |
description | string | Resumen breve. |
resources.required | ResourceRequirement[] | Recursos sin los cuales el plugin no puede ejecutarse. |
resources.optional | ResourceRequirement[] | Recursos que mejoran el comportamiento, pero no son obligatorios. |
Recursos
Un requisito de recurso declara un recurso de Databricks del que depende el plugin. La estructura se determina por type; cada tipo fija sus valores válidos de permission (validados por el esquema como una unión discriminada):
type | Permisos |
|---|---|
secret | READ, WRITE, MANAGE |
job | CAN_VIEW, CAN_MANAGE_RUN, CAN_MANAGE |
sql_warehouse | CAN_USE, CAN_MANAGE |
serving_endpoint | CAN_VIEW, CAN_QUERY, CAN_MANAGE |
volume | READ_VOLUME, WRITE_VOLUME |
vector_search_index | SELECT |
uc_function | EXECUTE |
uc_connection | USE_CONNECTION |
database | CAN_CONNECT_AND_CREATE |
postgres | CAN_CONNECT_AND_CREATE |
genie_space | CAN_VIEW, CAN_RUN, CAN_EDIT, CAN_MANAGE |
experiment | CAN_READ, CAN_EDIT, CAN_MANAGE |
app | CAN_USE |
Todo requisito tiene:
alias— etiqueta legible para personas que se usa en la UI o en la salida de la CLI.resourceKey— clave estable de máquina ([a-z][a-z0-9-]*). Se usa para la deduplicación, el nombrado de variables de entorno y las referencias enapp.yaml. La identidad se basa enresourceKey, no enalias.description— explica por qué se necesita este recurso; aparece en los prompts interactivos.fields— mapa de nombre de campo → entrada de campo (ver más abajo). Al menos una entrada cuando está presente.permission— debe coincidir con el enum permitido para ese tipo.
Los tipos de recurso de valor único (por ejemplo, sql_warehouse) suelen declarar un único campo (id). Los tipos de varios valores (por ejemplo, secret, database) declaran varios (scope + key, instance_name + database_name).
Entrada de campo
{
"id": {
"env": "DATABRICKS_WAREHOUSE_ID",
"description": "SQL Warehouse ID",
"examples": ["1234abcd5678efgh"],
"discovery": { "type": "kind", "resourceKind": "warehouse" }
}
}| Propiedad | Descripción |
|---|---|
env | Nombre de la variable de entorno que se escribe en .env y app.yaml. Debe coincidir con ^[A-Z][A-Z0-9_]*$. |
description | Se muestra en los prompts interactivos y en las descripciones de las variables del bundle. |
examples | Valores de ejemplo que se muestran en las descripciones de los campos. |
localOnly | Cuando es true, el campo se genera únicamente para el .env local: la plataforma Databricks Apps lo inyecta automáticamente al hacer deploy, por lo que se excluye de app.yaml y databricks.yml. |
bundleIgnore | Se excluye de las variables de databricks.yml (pero se sigue escribiendo en .env). |
value | Valor predeterminado estático. |
resolve | Nombre del resolvedor del lado de la CLI, con el formato <resource_type>:<field> (p. ej., postgres:host). La CLI completa el valor mediante llamadas a la API durante la inicialización. |
discovery | Describe cómo la CLI lista los valores candidatos; consulta más abajo. |
Recursos dependientes de la configuración
El manifiesto distingue entre required y optional para el análisis estático. Cuando un recurso solo se vuelve obligatorio según la configuración en runtime del plugin, decláralo como optional en el manifiesto y anúlalo en runtime mediante un método estático getResourceRequirements(config) en la clase del plugin. Consulta Crear plugins personalizados.
Descubrimiento de recursos
El descubrimiento describe cómo la CLI propone valores candidatos para un campo durante el init interactivo. Hay dos variantes dentro de discovery, diferenciadas por type:
Variante kind (recomendada)
{
"discovery": {
"type": "kind",
"resourceKind": "warehouse"
}
}La variante kind hace referencia a un tipo de recurso de Databricks conocido para el cual AppKit se encarga del comando de listado y de la forma de la respuesta. Esta es la forma preferida para recursos propios de Databricks: los autores de plugins declaran qué listar y AppKit define cómo listarlo.
Valores admitidos de resourceKind:
resourceKind | Listado mediante |
|---|---|
warehouse | databricks warehouses list |
genie_space | databricks genie list-spaces |
volume | databricks volumes list {catalog} {schema} |
postgres_project | databricks postgres list-projects |
postgres_branch | databricks postgres list-branches {project} |
postgres_database | databricks postgres list-databases {branch} |
Opciones admitidas en la variante kind:
| Propiedad | Descripción |
|---|---|
select | Nombre del campo de la respuesta analizada de la CLI que se usa como valor seleccionado (p. ej. "id", "name", "full_name"). Por defecto, el identificador natural del tipo. |
display | Nombre del campo que se muestra al usuario durante la selección. Por defecto, select. |
dependsOn | Nombre de un campo hermano dentro del mismo recurso que debe resolverse primero (consulta Dependencias entre campos). |
shortcut | Comando de vía rápida de valor único que devuelve exactamente un valor y omite la selección interactiva. |
Variante cli (vía de escape)
Para los recursos que no estén en el mapa kind, recurre a la variante cli:
{
"discovery": {
"type": "cli",
"cliCommand": "databricks custom-resource list --profile <PROFILE> --output json",
"selectField": ".id",
"displayField": ".name"
}
}| Propiedad | Descripción |
|---|---|
cliCommand | Comando completo de la Databricks CLI. Debe incluir el marcador de posición literal <PROFILE>: el ejecutor lo sustituye por el perfil de CLI del usuario. Los metacaracteres de shell (;, |, &, `, $, saltos de línea) se rechazan: los ejecutores pasan los argumentos mediante argv y nunca ejecutan la cadena con shell-exec. |
selectField | Ruta al estilo jq del campo que se usa como valor seleccionado (por ejemplo, .id, .name). |
displayField | Ruta al estilo jq del campo que se muestra al usuario. Su valor predeterminado es selectField. |
dependsOn | Campo hermano que debe resolverse primero. |
shortcut | Comando de vía rápida para un único valor. Misma restricción de metacaracteres que cliCommand. |
La variante cli es deliberadamente mínima y podría volverse más estricta en versiones futuras. Prefiere la variante kind para cualquier recurso que AppKit ya conozca: te da una única fuente de verdad para el comando y las reglas de extracción, y garantiza la compatibilidad futura a medida que AppKit refina el contrato de descubrimiento.
Dependencias entre campos
Cuando el listado de un recurso depende de otro (por ejemplo, listar volúmenes requiere un catálogo y un esquema; listar branches de Postgres requiere un project), usa dependsOn para declarar el orden:
{
"fields": {
"project": {
"discovery": { "type": "kind", "resourceKind": "postgres_project", "select": "name" }
},
"branch": {
"discovery": {
"type": "kind",
"resourceKind": "postgres_branch",
"select": "name",
"dependsOn": "project"
}
}
}
}dependsOn hace referencia al nombre de un campo hermano dentro del mismo recurso. La CLI pide los valores en orden de dependencia y sustituye el valor resuelto en el comando padre (por ejemplo, {project} en databricks postgres list-branches {project}).
El esquema valida el grafo de dependencias en tiempo de análisis:
- Se rechazan las referencias colgantes (
dependsOnque apunta a un hermano inexistente). - Se rechazan los ciclos, indicando la cadena correspondiente (
a → b → a).
Prompts transitorios (parents)
Algunos comandos con variantes de kind necesitan valores que no son campos hermanos del recurso: son entradas de query que el runner recopila una sola vez y luego descarta. AppKit las declara en el propio kind mediante un arreglo parents en RESOURCE_KIND_COMMANDS.
El único kind que usa parents actualmente es volume:
volume → parents: ["catalog", "schema"]Antes de invocar databricks volumes list {catalog} {schema} --profile <PROFILE> --output json, el runner pide al usuario cada entrada de parents como texto libre y sustituye el valor en el marcador de posición {name} correspondiente. A diferencia de dependsOn, los valores recopilados no se guardan como campos del recurso: solo existen mientras dura la llamada de listado.
Los autores de plugins no declaran parents en su manifiesto; forma parte del contrato de kind que gestiona AppKit y aparece en el JSON Schema publicado junto al template de comando de cada kind.
Reglas de scaffolding
scaffolding.rules es el punto de traspaso, a nivel de plugin, hacia los agentes de scaffolding (ejecutores basados en LLM, workflows de CLI personalizados, la skill databricks-apps). Admite hasta tres listas breves de directivas — must, should, never — que el agente respeta al invocar databricks apps init con este plugin seleccionado.
{
"scaffolding": {
"rules": {
"should": [
"After init, run any database migrations for your chosen ORM before first request",
"After init, verify Lakebase connectivity with 'psql $PGHOST -c \"select 1\"'"
]
}
}
}| Categoría | Semántica |
|---|---|
must | El agente debe realizar la acción. |
should | Acción recomendada: el agente la aplica salvo que se anule. |
never | El agente no debe realizar la acción. |
Contrato de redacción
- Cada entrada es una única directiva breve, limitada a 120 caracteres por el esquema. Los textos largos no superan la validación; divídelos en elementos concretos y accionables.
- El esquema aplica tanto la deduplicación dentro de cada grupo (no puede haber dos entradas con el mismo texto dentro de
must/should/never) como la deduplicación entre grupos (una entrada no puede pertenecer a dos grupos a la vez). - Usa la convención de prefijos
Before init/After initcuando el orden importe, para que los consumidores puedan secuenciar las directivas de forma coherente.
Criterio de sustituibilidad
Una regla pertenece al manifiesto solo si no puede expresarse como datos estructurados en algún otro sitio: un permiso de recurso, un descriptor discovery, una cadena dependsOn, una marca requiredByTemplate, un campo de configuración o los espacios env / value / resolve del campo.
Ejemplos de lo que sí supera el criterio:
"After init, run any database migrations for your chosen ORM before first request": secuenciación en runtime, que no se deriva de la forma de ningún recurso."After init, configure the 'spaces' map in plugin config with alias-to-Space-ID mappings": indicaciones para rellenar la configuración que el esquema no puede codificar.
Ejemplos de lo que no lo supera (y que conviene modelar en su lugar):
- "El plugin X requiere
READ_VOLUMEsobre su volumen" → ya está codificado en el campopermissiondel recurso. - "El ejecutor debe listar las branches de Postgres después de elegir un project" → ya está codificado mediante
dependsOn. - "Solicitar al usuario el catálogo y el esquema antes de listar los volúmenes" → ya está codificado mediante
RESOURCE_KIND_COMMANDS.volume.parents.
Si acabas escribiendo prosa que el esquema podría capturar, extiende el esquema en su lugar.
El bloque de reglas se propaga sin cambios desde el manifiesto del plugin hasta el manifiesto de template sincronizado. Consulta Plantillas — propagación de scaffolding.rules para ver cómo la CLI combina las reglas a nivel de plugin con el bloque de reglas a nivel de template.
Campos opcionales
| Campo | Descripción |
|---|---|
author | Nombre del autor u organización. |
version | Versión del plugin, en formato semver (X.Y.Z o X.Y.Z-prerelease). |
repository | URL del código fuente del plugin. |
keywords | Palabras clave para descubrimiento. |
license | Identificador SPDX. |
onSetupMessage | Mensaje que se muestra una sola vez tras la inicialización. Úsalo para indicaciones breves; para directivas accionables que un agente deba cumplir, usa mejor scaffolding.rules. |
hidden | Cuando es true, el plugin se excluye del manifiesto del template sincronizado. |
devOnly | Cuando es true, createApp solo registra el plugin si NODE_ENV === "development"; en cualquier otro entorno se omite por completo (no se construye, no expone rutas y no se validan sus recursos). Úsalo para herramientas exclusivas de desarrollo que nunca deban ejecutarse en una aplicación desplegada. |
stability | "beta" o "ga". Los plugins en beta pueden romper la compatibilidad entre versiones menores: consulta Niveles de estabilidad de plugins. |
config.schema | JSON Schema de la configuración de runtime del plugin (lo usan el generador de tipos y la validación). |
Consulta también
- Creación de plugins personalizados: cómo crear un plugin desde cero.
- Gestión de plugins:
appkit plugin sync,create,validate,add-resource. - Plantillas: cómo el manifiesto de template sincronizado controla
databricks apps init. - Referencia de la API de
PluginManifest: tipo de TypeScript.