Manifesto do plugin
Manifesto do plugin
Todo plugin traz um manifest.json junto ao seu código-fonte. O manifesto declara os metadados do plugin, os recursos do Databricks de que o plugin precisa e quaisquer regras estruturadas que um agente de scaffolding deve respeitar ao executar databricks apps init. Ele é consumido em três etapas:
- Autoria — use
import manifest from "./manifest.json"e anexe-o à subclassePluginpor meio destatic manifest. - Sincronização —
appkit plugin sync --writeagrega os manifestos dos pacotes instalados e dos plugins locais emappkit.plugins.json. - Init —
databricks apps initlê oappkit.plugins.jsonpara orientar a seleção de plugins, os prompts de recursos e a geração de.env/databricks.yml/app.yaml.
Esta página documenta o contrato de manifesto v2.0. O JSON Schema está publicado em https://databricks.github.io/appkit/schemas/plugin-manifest.schema.json; referencie-o via $schema para ter validação no editor.
Padrão recomendado
Escreva o manifesto em JSON, importe-o no módulo do plugin e faça a asserção de 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": []
}
}O JSON é o formato canônico de criação — é ele que o appkit plugin sync lê. Manifestos em JS (manifest.js / manifest.cjs) são ignorados por padrão e exigem a flag --allow-js-manifest para serem habilitados (executa o código do plugin; exige confiança). Para o comportamento completo da CLI, consulte Gerenciamento de plugins.
Campos obrigatórios
| Campo | Tipo | Observações |
|---|---|---|
name | string | Identificador do plugin. Minúsculas, começa com uma letra, apenas [a-z0-9-]. |
displayName | string | Exibido na interface e nos prompts da CLI. |
description | string | Resumo breve. |
resources.required | ResourceRequirement[] | Recursos sem os quais o plugin não funciona. |
resources.optional | ResourceRequirement[] | Recursos que aprimoram o comportamento, mas não são obrigatórios. |
Recursos
Um requisito de recurso declara um recurso do Databricks do qual o plugin depende. O formato é definido pelo type; cada tipo fixa seus valores válidos de permission (validados pelo schema como uma união discriminada):
type | Permissões |
|---|---|
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 tem:
alias— rótulo legível por humanos usado na UI / saída da CLI.resourceKey— chave estável de máquina ([a-z][a-z0-9-]*). Usada para deduplicação, nomeação de variáveis de ambiente e referências noapp.yaml. A identidade é definida peloresourceKey, não peloalias.description— explica por que esse recurso é necessário; aparece nos prompts interativos.fields— mapa de nome do campo → entrada do campo (veja abaixo). Pelo menos uma entrada, quando presente.permission— deve corresponder ao enum permitido para o tipo.
Tipos de recurso de valor único (por exemplo, sql_warehouse) normalmente declaram um único campo (id). Tipos de múltiplos valores (por exemplo, secret, database) declaram vários (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" }
}
}| Propriedade | Descrição |
|---|---|
env | Nome da variável de ambiente gravada em .env e app.yaml. Deve corresponder a ^[A-Z][A-Z0-9_]*$. |
description | Exibida em prompts interativos e nas descrições de variáveis do bundle. |
examples | Valores de exemplo exibidos nas descrições dos campos. |
localOnly | Quando true, o campo é gerado apenas para o .env local — a plataforma Databricks Apps o injeta automaticamente no momento do deploy, por isso ele é excluído de app.yaml e databricks.yml. |
bundleIgnore | Excluído das variáveis do databricks.yml (mas ainda é gravado no .env). |
value | Valor padrão estático. |
resolve | Nome do resolvedor no lado da CLI, no formato <resource_type>:<field> (por exemplo, postgres:host). A CLI preenche o valor a partir de chamadas de API durante o init. |
discovery | Descreve como a CLI lista os valores candidatos — veja abaixo. |
Recursos dependentes de configuration
O manifesto distingue required de optional para fins de análise estática. Quando um recurso só se torna obrigatório em função da configuration de runtime do plugin, declare-o em optional no manifesto e sobrescreva esse valor em runtime por meio de um método estático getResourceRequirements(config) na classe do plugin. Consulte Criar plugins personalizados.
Descoberta de recursos
A descoberta descreve como a CLI sugere valores candidatos para um campo durante o init interativo. Há duas variantes em discovery, distinguidas por type:
Variante kind (recomendada)
{
"discovery": {
"type": "kind",
"resourceKind": "warehouse"
}
}A variante kind faz referência a um tipo de recurso conhecido do Databricks para o qual o AppKit define o comando de listagem e o formato da resposta. Esta é a forma preferida para recursos nativos do Databricks — os autores de plugins declaram o que listar, e o AppKit define como listar.
Valores suportados de resourceKind:
resourceKind | Listado via |
|---|---|
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} |
Opções suportadas na variante kind:
| Propriedade | Descrição |
|---|---|
select | Nome do campo na resposta processada da CLI usado como valor selecionado (ex.: "id", "name", "full_name"). O padrão é o identificador natural do tipo. |
display | Nome do campo exibido ao usuário durante a seleção. O padrão é select. |
dependsOn | Nome de um campo irmão dentro do mesmo recurso que deve ser resolvido primeiro (consulte Dependências entre campos). |
shortcut | Comando de atalho de valor único que retorna exatamente um valor, ignorando a seleção interativa. |
Variante cli (válvula de escape)
Para recursos fora do mapa kind, recorra à variante cli:
{
"discovery": {
"type": "cli",
"cliCommand": "databricks custom-resource list --profile <PROFILE> --output json",
"selectField": ".id",
"displayField": ".name"
}
}| Propriedade | Descrição |
|---|---|
cliCommand | Comando completo da Databricks CLI. Deve incluir o placeholder literal <PROFILE> — o executor o substitui pelo perfil da CLI do usuário. Metacaracteres de shell (;, |, &, `, $, quebras de linha) são rejeitados — os executores passam argumentos via argv e nunca executam a string com shell-exec. |
selectField | Caminho no estilo jq para o campo usado como valor selecionado (por exemplo, .id, .name). |
displayField | Caminho no estilo jq para o campo exibido ao usuário. O padrão é selectField. |
dependsOn | Campo irmão que precisa ser resolvido primeiro. |
shortcut | Comando de atalho para valor único. Mesma restrição de metacaracteres do cliCommand. |
A variante cli é intencionalmente mínima e pode se tornar mais restritiva em versões futuras. Prefira a variante kind para qualquer recurso que o AppKit conheça: ela oferece uma única fonte de verdade para o comando e as regras de desempacotamento, além de garantir compatibilidade futura conforme o AppKit refina o contrato de descoberta.
Dependências entre campos
Quando a listagem de um recurso depende de outro (por exemplo, listar volumes exige um catalog e um schema; listar branches do Postgres exige um projeto), use dependsOn para declarar a ordem:
{
"fields": {
"project": {
"discovery": { "type": "kind", "resourceKind": "postgres_project", "select": "name" }
},
"branch": {
"discovery": {
"type": "kind",
"resourceKind": "postgres_branch",
"select": "name",
"dependsOn": "project"
}
}
}
}dependsOn referencia o nome de um campo irmão dentro do mesmo recurso. A CLI solicita os valores na ordem de dependência e substitui o valor resolvido no comando pai (por exemplo, {project} em databricks postgres list-branches {project}).
O schema valida o grafo de dependências no momento da análise:
- Referências pendentes (
dependsOnapontando para um irmão inexistente) são rejeitadas. - Ciclos são rejeitados, com a cadeia listada (
a → b → a).
Prompts transitórios (parents)
Alguns comandos da variante kind precisam de valores que não são campos irmãos no recurso — são entradas de consulta que o runner coleta uma única vez e descarta. O AppKit declara esses valores no próprio kind, por meio de um array parents em RESOURCE_KIND_COMMANDS.
Hoje, o único kind que usa parents é volume:
volume → parents: ["catalog", "schema"]Antes de invocar databricks volumes list {catalog} {schema} --profile <PROFILE> --output json, o runner pede ao usuário cada entrada de parents como texto livre e substitui o valor no placeholder {name} correspondente. Ao contrário de dependsOn, os valores coletados não são persistidos como campos do recurso — eles existem apenas durante a chamada de listagem.
Os autores de plugins não declaram parents no manifesto; isso faz parte do contrato kind, que pertence ao AppKit, e aparece no JSON Schema publicado junto com o template de comando de cada kind.
Regras de scaffolding
scaffolding.rules é o ponto de repasse, no nível do plugin, para os agentes de scaffolding (executores guiados por LLM, workflows de CLI personalizados, a skill databricks-apps). Ele contém até três listas curtas de diretivas — must, should, never — que o agente respeita ao invocar databricks apps init com esse plugin selecionado.
{
"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\"'"
]
}
}
}| Categoria | Semântica |
|---|---|
must | O agente deve executar a ação. |
should | Ação recomendada — o agente a aplica, a menos que seja substituída. |
never | O agente não deve executar a ação. |
Contrato de autoria
- Cada entrada é uma única diretiva curta, limitada a 120 caracteres pelo schema. Textos longos não passam na validation; divida-os em itens acionáveis distintos.
- O schema impõe tanto a deduplicação por bucket (duas entradas não podem ter o mesmo texto dentro de
must/should/never) quanto a deduplicação entre buckets (uma entrada não pode pertencer a dois buckets ao mesmo tempo). - Use a convenção de prefixos
Before init/After initquando a ordem importar, para que os consumidores possam sequenciar as diretivas de forma consistente.
Critério de substituibilidade
Uma regra só deve estar no manifesto se não puder ser expressa como dados estruturados em outro lugar — uma permissão de recurso, um descritor discovery, uma cadeia dependsOn, uma flag requiredByTemplate, um campo de configuração ou o slot env / value / resolve do campo.
Exemplos do que passa pelo critério:
"After init, run any database migrations for your chosen ORM before first request"— sequenciamento em runtime, não derivável de nenhum formato de recurso."After init, configure the 'spaces' map in plugin config with alias-to-Space-ID mappings"— orientação de preenchimento de configuração que o schema não consegue codificar.
Exemplos do que não passa (e deve ser modelado no schema):
- "O plugin X exige
READ_VOLUMEem seu volume" → já codificado no campopermissiondo recurso. - "O runner deve listar as branches do Postgres depois que um projeto for escolhido" → já codificado via
dependsOn. - "Solicitar ao usuário o catálogo e o schema antes de listar os volumes" → já codificado via
RESOURCE_KIND_COMMANDS.volume.parents.
Se perceber que está escrevendo em prosa algo que o schema poderia capturar, estenda o schema.
O bloco de regras é propagado sem alterações do manifesto do plugin para o manifesto do modelo sincronizado. Consulte Templates — propagação de scaffolding.rules para ver como a CLI mescla as regras no nível do plugin com o bloco de regras no nível do modelo.
Campos opcionais
| Campo | Descrição |
|---|---|
author | Nome do autor ou da organização. |
version | Versão do plugin, no formato semver (X.Y.Z ou X.Y.Z-prerelease). |
repository | URL do código-fonte do plugin. |
keywords | Palavras-chave para descoberta. |
license | Identificador SPDX. |
onSetupMessage | Mensagem exibida uma única vez após o init. Use para dicas curtas; prefira scaffolding.rules para diretivas acionáveis que um agente deve aplicar. |
hidden | Quando true, o plugin é excluído do manifesto de modelo sincronizado. |
devOnly | Quando true, o createApp só registra o plugin se NODE_ENV === "development"; em qualquer outro ambiente ele é totalmente ignorado (não é construído, não expõe rotas e seus recursos não são validados). Use para ferramentas exclusivas de desenvolvimento que nunca devem ser executadas em um app implantado. |
stability | "beta" ou "ga". Plugins beta podem quebrar entre versões menores — consulte Níveis de estabilidade de plugins. |
config.schema | JSON Schema da configuração de runtime do plugin (usado pelo gerador de tipos e para validação). |
Veja também
- Criar plugins personalizados — como construir um plugin do zero.
- Gerenciamento de plugins —
appkit plugin sync,create,validate,add-resource. - Modelos — como o manifesto de modelo sincronizado orienta o
databricks apps init. - Referência da API
PluginManifest— tipo TypeScript.