Modelos
Modelos
O AppKit usa um sistema de modelos baseado no comando databricks apps init da Databricks CLI. Os modelos definem a estrutura do projeto, e os arquivos .tmpl são processados pelo mecanismo text/template do Go para gerar uma saída personalizada.
Como funcionam os arquivos .tmpl
Qualquer arquivo terminado em .tmpl é processado pela CLI durante o databricks apps init:
- O sufixo
.tmplé removido (ex.:.env.tmpl→.env) - As expressões de modelo do Go são avaliadas e substituídas
- O arquivo renderizado é gravado no diretório de saída
Arquivos com o prefixo _ são renomeados para o prefixo . (ex.: _gitignore → .gitignore).
Variáveis de modelo
| Variável | Descrição |
|---|---|
.projectName | Nome do projeto, vindo de --name ou do prompt interativo |
.workspaceHost | URL do workspace do Databricks |
.profile | Nome do perfil da Databricks CLI (vazio ao usar autenticação baseada em host) |
.appDescription | Descrição do app |
.plugins.<name> | Não nulo para cada plugin selecionado, permitindo o uso de condicionais |
.dotEnv.content | Conteúdo do .env gerado a partir dos recursos do plugin |
.dotEnv.example | Conteúdo do .env.example gerado com marcadores de posição |
.bundle.* | Seções geradas do databricks.yml (variáveis, recursos, variáveis de destino) |
.appEnv | Entradas de env geradas no app.yaml |
Conteúdo condicional
Use condicionais de modelo do Go para incluir/excluir código com base nos plugins selecionados:
{{- if .plugins.analytics}}
import { analytics } from '@databricks/appkit';
{{- end}}appkit.plugins.json
O manifesto de plugins determina o comportamento da CLI durante o databricks apps init:
- UI de seleção de plugins — plugins selecionáveis exibidos no prompt interativo
- Prompts de recursos — recursos obrigatórios/opcionais solicitam valores ao usuário (por exemplo, o SQL Warehouse ID)
- Preenchimento do
.dotEnv— campos de recurso com a propriedadeenvsão gravados no.env - Geração do
app.yaml— campos de recurso geram entradasenv+valueFrom - Geração do
databricks.yml— campos de recurso geram variáveis de bundle e entradas de recurso do app
O manifesto sincronizado é gerado pelo appkit plugin sync --write a partir do manifest.json de cada plugin (consulte Manifesto de plugin para conhecer o contrato de autoria). O formato em disco traz um campo version que a CLI usa para negociar funcionalidades:
"1.0"/"1.1"— formatos anteriores; ainda legíveis."2.0"— formato atual. Adicionascaffolding(exigido pela CLI quandoversioné"2.0"; validado no momento do parse, e não pelo JSON Schema publicado) e o campooriginem cada entrada de campo de recurso. JSON Schema publicado emhttps://databricks.github.io/appkit/schemas/template-plugins.schema.json.
Propriedades dos campos de recurso
Cada campo de recurso no manifesto sincronizado pode ter estas propriedades:
| Propriedade | Descrição |
|---|---|
env | Nome da variável de ambiente gravada em .env e app.yaml |
description | Exibida no prompt interativo e na descrição da variável do bundle |
localOnly | Gravada apenas em .env para desenvolvimento local; excluída de app.yaml e das variáveis do bundle |
bundleIgnore | Excluída das variáveis de databricks.yml (mas mantida em .env) |
value | Valor padrão usado quando o usuário não fornece nenhuma entrada |
resolve | Preenchido automaticamente pela CLI a partir de chamadas de API, sem solicitar ao usuário (veja abaixo) |
examples | Valores de exemplo exibidos nas descrições dos campos |
discovery | Como a CLI lista os valores candidatos para o campo (veja Manifesto de plugin — Descoberta de recursos). |
origin | Campo computado da v2.0. Como o valor é determinado — veja abaixo. |
origin (v2.0)
origin é calculado no momento da sincronização a partir das demais propriedades do campo — autores de plugins não o escrevem. Ele informa aos agentes de scaffolding como cada valor chega ao app em execução:
| Origin | Gatilho | Significado |
|---|---|---|
"platform" | localOnly: true | Injetado automaticamente pelo Databricks Apps no momento do deploy. Gerado apenas para o .env local; ausente do app.yaml e das variáveis do bundle. |
"static" | value definido | Literal fixo no código. A CLI não solicita entrada. |
"cli" | resolve definido | Resolvido pela CLI a partir de chamadas de API (por exemplo, postgres:host). |
"user" | nenhum dos anteriores | O usuário deve fornecer o valor no momento da inicialização. |
A precedência segue a ordem acima (localOnly prevalece sobre value, que prevalece sobre resolve). A transformação sobrescreve qualquer origin editado manualmente na sincronização seguinte — por construção, não há como ocorrer divergência entre o valor em disco e o formato real do campo.
Resolvers
Campos com a propriedade resolve são preenchidos automaticamente pela CLI a partir de chamadas de API, em vez de prompts ao usuário. O formato é <type>:<field>.
Atualmente, apenas o tipo de recurso postgres possui um resolver. Com base nos nomes de recurso branch e database informados pelo usuário, ele deriva:
| Chave de resolução | Descrição |
|---|---|
postgres:host | Host do Postgres obtido do read-write endpoint da branch |
postgres:databaseName | Nome do banco de dados Postgres obtido do recurso de banco de dados |
postgres:endpointPath | Nome do recurso de endpoint do Lakebase obtido dos endpoints da branch |
Exemplo de definição de campo:
{
"host": {
"env": "PGHOST",
"localOnly": true,
"resolve": "postgres:host",
"description": "Postgres host for local development."
}
}Após a sincronização, o campo passa a ter "origin": "platform" (porque localOnly tem precedência sobre resolve para campos exclusivamente locais injetados no momento do deploy).
Propagação de scaffolding.rules
O bloco scaffolding.rules de cada plugin (consulte Manifesto do plugin — Regras de scaffolding) é propagado sem alterações para a respectiva entrada em appkit.plugins.json. A CLI entrega as regras mescladas em nível de plugin — junto com o scaffolding.rules de nível superior do modelo — aos agentes de scaffolding que conduzem o databricks apps init.
Modelo de mesclagem:
- Reunir as regras de cada plugin selecionado e de cada plugin com
requiredByTemplate: true. - Aplicar o
scaffolding.rulesde nível de modelo por cima. - As regras em nível de plugin sobrescrevem os padrões embutidos na skill ou definidos em nível de modelo no mesmo ponto de diretiva.
- Um
mustde plugin que entre em conflito com umneverde modelo (ou vice-versa) interrompe o fluxo de init — consulte as regras de validação abaixo.
Descritor scaffolding (v2.0)
O bloco scaffolding no nível superior do appkit.plugins.json descreve o comando de scaffolding, suas flags e as regras transversais que todo agente de scaffolding deve respeitar. Ele é obrigatório para a CLI quando version é "2.0". Essa obrigatoriedade é verificada no momento do parse — o JSON Schema publicado marca apenas version e plugins como campos obrigatórios de nível superior, já que não é capaz de expressar requisitos condicionais.
{
"scaffolding": {
"command": "databricks apps init",
"flags": {
"--name": {
"description": "Project name — sets {{.projectName}} in package.json, databricks.yml, and .env. Required for non-interactive scaffolding.",
"required": true,
"pattern": "^[a-z][a-z0-9-]*$"
},
"--features": {
"description": "Plugins to enable (comma-separated, no spaces; must match keys in this manifest's plugins map)",
"required": false,
"pattern": "^[a-zA-Z0-9_-]+(,[a-zA-Z0-9_-]+)*$"
},
"--profile": {
"description": "Databricks CLI profile to use for authentication (global flag)",
"required": false
}
},
"rules": {
"must": [
"Keep all secrets and credentials only in app.yaml, databricks.yml, and/or .env"
],
"should": [
"ask user when in doubt of resource to use for plugin"
],
"never": [
"guess resources when multiple or no options are available",
"embed secrets in files that will go to the client-bundle"
]
}
}
}| Campo | Descrição |
|---|---|
command | Comando de scaffolding que o agente deve invocar. |
flags | Mapa de nome da flag para { description, required?, pattern?, default? }. |
rules.must | Ações que o agente de scaffolding deve sempre executar. |
rules.should | Ações recomendadas — aplicadas, exceto quando substituídas por uma regra no nível do plugin. |
rules.never | Ações que o agente de scaffolding nunca deve executar. |
O exemplo acima mostra três flags. O conjunto canônico de flags distribuído com cada manifesto de modelo sincronizado é:
| Flag | Obrigatória | Descrição |
|---|---|---|
--name | sim | Nome do projeto — define {{.projectName}} em package.json, databricks.yml e .env. |
--template | não | Caminho do modelo (diretório local ou URL do GitHub). |
--version | não | Versão do AppKit a ser usada; por padrão, detectada automaticamente. |
--features | não | Plugins a habilitar (separados por vírgula, sem espaços; devem corresponder às chaves do mapa plugins). |
--set | não | Define valores de recursos (formato: plugin.resourceKey.field=value, pode ser repetida). |
--output-dir | não | Diretório onde o projeto será gravado. |
--description | não | Descrição do app. |
--run | não | Executa o app após a criação (none, dev, dev-remote). |
--auto-approve | não | Pula os prompts de recursos opcionais. Não recomendado para inicialização conduzida por agente — conflita com a regra "pergunte ao usuário em caso de dúvida". |
--profile | não | Perfil da Databricks CLI a ser usado para autenticação (flag global). |
Cada item de regra é limitado a 120 caracteres pelo schema. Textos longos não passam na validação — divida-os em diretivas acionáveis e independentes.
O descritor é canônico: o AppKit detém os valores e os distribui com cada manifesto de modelo sincronizado. Autores de agentes consumidores (scaffolders conduzidos por LLM, executores de CLI personalizados) devem tratar as listas de regras como contratos de cumprimento obrigatório, e não como sugestões.
Barreira de substituibilidade (regras de modelo)
As regras em nível de modelo passam pela mesma barreira de substituibilidade que rege as regras em nível de plugin: cada entrada deve descrever uma decisão transversal do agente que o schema ainda não seja capaz de codificar. Regras como "modificar apenas arquivos dentro do diretório do modelo" ou "listar volumes após solicitar catálogo/schema" foram omitidas de propósito — a primeira se torna irrelevante quando se lê o manifesto como fonte da verdade, e a segunda agora está codificada estruturalmente como parents: ["catalog", "schema"] no tipo de descoberta volume (consulte Manifesto do plugin — Prompts transitórios).
Veja também
- Manifesto do plugin — o lado da autoria (
manifest.json). - Gerenciamento de plugins —
appkit plugin sync,appkit plugin create. - Configuração — variáveis de ambiente.