Manifeste de plugin
Manifeste de plugin
Chaque plugin est livré avec un fichier manifest.json placé à côté de son code source. Le manifeste déclare les métadonnées du plugin, les ressources Databricks dont celui-ci a besoin, ainsi que toute règle structurée qu'un agent de génération d'ossature doit respecter lors de l'exécution de databricks apps init. Il est exploité à trois étapes :
- Rédaction —
import manifest from "./manifest.json", puis rattachez-le à la sous-classePluginviastatic manifest. - Synchronisation —
appkit plugin sync --writeagrège les manifestes des paquets installés et des plugins locaux dansappkit.plugins.json. - Initialisation —
databricks apps initlitappkit.plugins.jsonpour piloter la sélection des plugins, les prompts de ressources et la génération des fichiers.env/databricks.yml/app.yaml.
Cette page documente le contrat de manifeste v2.0. Le schéma JSON est publié à l'adresse https://databricks.github.io/appkit/schemas/plugin-manifest.schema.json ; référencez-le via $schema pour bénéficier de la validation dans l'éditeur.
Modèle recommandé
Rédigez le manifeste au format JSON, importez-le dans le module du plugin, puis assertez le type :
// 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": []
}
}Le JSON est le format de référence pour la déclaration — c'est celui que lit appkit plugin sync. Les manifestes JS (manifest.js / manifest.cjs) sont ignorés par défaut et doivent être activés explicitement avec --allow-js-manifest (cela exécute le code du plugin ; une relation de confiance est requise). Pour le comportement complet de la CLI, voir Gestion des plugins.
Champs obligatoires
| Champ | Type | Notes |
|---|---|---|
name | string | Identifiant du plugin. En minuscules, commence par une lettre, [a-z0-9-] uniquement. |
displayName | string | Affiché dans l'UI et les prompt de la CLI. |
description | string | Brève description. |
resources.required | ResourceRequirement[] | Ressources sans lesquelles le plugin ne peut pas fonctionner. |
resources.optional | ResourceRequirement[] | Ressources qui enrichissent le comportement sans être obligatoires. |
Ressources
Une exigence de ressource déclare une ressource Databricks dont dépend le plugin. La structure est indexée par type ; chaque type fixe ses valeurs de permission valides (validées par le schéma sous forme d'union discriminée) :
type | Permissions |
|---|---|
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 |
Chaque exigence comporte :
alias— libellé lisible par un humain, utilisé dans l'UI ou les sorties de la CLI.resourceKey— clé machine stable ([a-z][a-z0-9-]*). Utilisée pour la déduplication, le nommage des variables d'environnement et les références dansapp.yaml. L'identité repose surresourceKey, pas suralias.description— explique pourquoi cette ressource est nécessaire ; s'affiche dans les prompts interactifs.fields— correspondance nom de champ → entrée de champ (voir ci-dessous). Au moins une entrée lorsque ce champ est présent.permission— doit correspondre à l'énumération autorisée pour le type.
Les types de ressource à valeur unique (par exemple sql_warehouse) déclarent généralement un seul champ (id). Les types à valeurs multiples (par exemple secret, database) en déclarent plusieurs (scope + key, instance_name + database_name).
Entrée de champ
{
"id": {
"env": "DATABRICKS_WAREHOUSE_ID",
"description": "SQL Warehouse ID",
"examples": ["1234abcd5678efgh"],
"discovery": { "type": "kind", "resourceKind": "warehouse" }
}
}| Propriété | Description |
|---|---|
env | Nom de la variable d'environnement écrite dans .env et app.yaml. Doit correspondre à ^[A-Z][A-Z0-9_]*$. |
description | Affichée dans les prompt interactives et les descriptions de variables du bundle. |
examples | Exemples de valeurs affichés dans les descriptions de champs. |
localOnly | Si true, le champ n'est généré que pour le .env local — la plateforme Databricks Apps l'injecte automatiquement au moment du déploiement, il est donc exclu de app.yaml et de databricks.yml. |
bundleIgnore | Exclu des variables de databricks.yml (mais toujours écrit dans .env). |
value | Valeur par défaut statique. |
resolve | Nom du résolveur côté CLI, au format <resource_type>:<field> (par ex. postgres:host). La CLI renseigne la valeur à partir d'appels d'API lors de l'initialisation. |
discovery | Décrit la manière dont la CLI liste les valeurs candidates — voir ci-dessous. |
Ressources dépendantes de la configuration
Le manifeste distingue required de optional pour l'analyse statique. Lorsqu'une ressource ne devient requise qu'en fonction de la configuration runtime du plugin, déclarez-la sous optional dans le manifeste, puis surchargez ce comportement au runtime via une méthode statique getResourceRequirements(config) définie sur la classe du plugin. Voir Créer des plugins personnalisés.
Découverte des ressources
La découverte décrit la façon dont la CLI propose des valeurs candidates pour un champ lors de l'initialisation interactive. Il existe deux variantes sous discovery, différenciées par type :
Variante kind (recommandée)
{
"discovery": {
"type": "kind",
"resourceKind": "warehouse"
}
}La variante kind fait référence à un type de ressource Databricks bien connu pour lequel AppKit fournit la commande de listage et la structure de la réponse. C'est la forme à privilégier pour les ressources Databricks natives : les auteurs de plugins déclarent ce qu'il faut lister, et AppKit se charge du comment.
Valeurs resourceKind prises en charge :
resourceKind | Listé 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} |
Options prises en charge par la variante kind :
| Propriété | Description |
|---|---|
select | Nom du champ de la réponse CLI analysée utilisé comme valeur sélectionnée (par ex. "id", "name", "full_name"). Par défaut, l'identifiant naturel du type. |
display | Nom du champ affiché à l'utilisateur lors de la sélection. Par défaut, select. |
dependsOn | Nom d'un champ voisin au sein de la même ressource qui doit être résolu au préalable (voir Dépendances entre champs). |
shortcut | Commande de raccourci à valeur unique qui renvoie exactement une valeur, sans passer par la sélection interactive. |
Variante cli (solution de repli)
Pour les ressources absentes de la table kind, utilisez la variante cli :
{
"discovery": {
"type": "cli",
"cliCommand": "databricks custom-resource list --profile <PROFILE> --output json",
"selectField": ".id",
"displayField": ".name"
}
}| Propriété | Description |
|---|---|
cliCommand | Commande Databricks CLI complète. Doit contenir le marqueur littéral <PROFILE> — le runner y substitue le profil CLI de l'utilisateur. Les métacaractères du shell (;, |, &, `, $, sauts de ligne) sont rejetés : les exécuteurs transmettent les arguments via argv et n'exécutent jamais la chaîne avec shell-exec. |
selectField | Chemin de style jq vers le champ utilisé comme valeur sélectionnée (p. ex. .id, .name). |
displayField | Chemin de style jq vers le champ affiché à l'utilisateur. Vaut selectField par défaut. |
dependsOn | Champ frère qui doit être résolu au préalable. |
shortcut | Commande raccourcie pour une valeur unique. Mêmes restrictions sur les métacaractères que cliCommand. |
La variante cli est volontairement minimale et pourrait se durcir dans les versions futures. Privilégiez la variante kind pour toute ressource connue d'AppKit : elle vous offre une source de vérité unique pour la commande et les règles de désencapsulation, et garantit la compatibilité ascendante à mesure qu'AppKit affine le contrat de découverte.
Dépendances entre champs
Lorsque la liste d'une ressource dépend d'une autre (par exemple, lister les volumes nécessite un catalogue et un schéma ; lister les branches Postgres nécessite un projet), utilisez dependsOn pour déclarer l'ordre :
{
"fields": {
"project": {
"discovery": { "type": "kind", "resourceKind": "postgres_project", "select": "name" }
},
"branch": {
"discovery": {
"type": "kind",
"resourceKind": "postgres_branch",
"select": "name",
"dependsOn": "project"
}
}
}
}dependsOn référence le nom d'un champ frère au sein de la même ressource. La CLI affiche les prompts dans l'ordre des dépendances et injecte la valeur résolue dans la commande parente (par exemple {project} dans databricks postgres list-branches {project}).
Le schéma valide le graphe de dépendances au moment de l'analyse :
- Les références orphelines (
dependsOnpointant vers un champ frère inexistant) sont rejetées. - Les cycles sont rejetés, avec la chaîne concernée indiquée (
a → b → a).
Prompts transitoires (parents)
Certaines commandes propres à une variante de kind ont besoin de valeurs qui ne sont pas des champs voisins de la ressource : ce sont des entrées de query que le runner collecte une seule fois puis met de côté. AppKit les déclare sur le kind lui-même, via un tableau parents dans RESOURCE_KIND_COMMANDS.
Aujourd'hui, le seul kind qui utilise parents est volume :
volume → parents: ["catalog", "schema"]Avant d'invoquer databricks volumes list {catalog} {schema} --profile <PROFILE> --output json, le runner invite l'utilisateur à saisir librement chaque entrée parents et substitue la valeur au placeholder {name} correspondant. Contrairement à dependsOn, les valeurs collectées ne sont pas persistées en tant que champs de ressource : elles n'existent que le temps de l'appel de listage.
Les auteurs de plugins ne déclarent pas parents dans leur manifeste ; cet élément fait partie du contrat kind géré par AppKit et apparaît dans le JSON Schema publié, aux côtés du modèle de commande de chaque kind.
Règles de génération d'ossature
scaffolding.rules est le point de passage, au niveau du plugin, vers les agents de génération d'ossature (exécuteurs pilotés par LLM, flux de travail CLI personnalisés, compétence databricks-apps). Il contient jusqu'à trois courtes listes de directives — must, should, never — que l'agent respecte lorsqu'il invoque databricks apps init avec ce plugin sélectionné.
{
"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\"'"
]
}
}
}| Catégorie | Sémantique |
|---|---|
must | L'agent doit effectuer l'action. |
should | Action recommandée — l'agent l'applique sauf indication contraire. |
never | L'agent ne doit pas effectuer l'action. |
Contrat de rédaction
- Chaque entrée est une directive unique et concise, limitée à 120 caractères par le schéma. Un texte trop long échoue à la validation ; découpez-le en éléments distincts et actionnables.
- Le schéma impose à la fois une déduplication au sein de chaque groupe (jamais deux entrées ayant le même texte dans
must,shouldounever) et une déduplication inter-groupes (une entrée ne peut pas appartenir à deux groupes à la fois). - Utilisez la convention de préfixe
Before init/After initlorsque l'ordre importe, afin que les consommateurs puissent séquencer les directives de manière cohérente.
Critère de substituabilité
Une règle a sa place dans le manifeste uniquement si elle ne peut être exprimée sous forme de données structurées ailleurs — une permission de ressource, un descripteur discovery, une chaîne dependsOn, un indicateur requiredByTemplate, un champ de configuration ou l'emplacement env / value / resolve du champ.
Exemples de règles qui passent le critère :
"After init, run any database migrations for your chosen ORM before first request"— séquencement au runtime, non déductible de la forme d'une ressource."After init, configure the 'spaces' map in plugin config with alias-to-Space-ID mappings"— indication de remplissage de configuration que le schéma ne peut pas encoder.
Exemples de règles qui ne passent pas (et qu'il faut plutôt modéliser) :
- « Le plugin X requiert
READ_VOLUMEsur son volume » → déjà encodé dans le champpermissionde la ressource. - « Le runner doit lister les branches Postgres une fois qu'un project est choisi » → déjà encodé via
dependsOn. - « Demander à l'utilisateur le catalogue et le schéma avant de lister les volumes » → déjà encodé via
RESOURCE_KIND_COMMANDS.volume.parents.
Si vous en venez à rédiger en prose ce que le schéma pourrait exprimer, étendez plutôt le schéma.
Le bloc de règles est propagé tel quel du manifeste du plugin vers le manifeste de modèle synchronisé. Voir Templates — propagation de scaffolding.rules pour savoir comment la CLI fusionne les règles au niveau du plugin avec le bloc de règles au niveau du modèle.
Champs optionnels
| Champ | Description |
|---|---|
author | Nom de l'auteur ou de l'organisation. |
version | Version du plugin, au format semver (X.Y.Z ou X.Y.Z-prerelease). |
repository | URL des sources du plugin. |
keywords | Mots-clés de découverte. |
license | Identifiant SPDX. |
onSetupMessage | Message affiché une seule fois après l'initialisation. À utiliser pour de courtes indications ; préférez scaffolding.rules pour les directives concrètes qu'un agent doit appliquer. |
hidden | Lorsque la valeur est true, le plugin est exclu du manifeste de modèle synchronisé. |
devOnly | Lorsque la valeur est true, createApp n'enregistre le plugin que si NODE_ENV === "development" ; dans tout autre environnement, il est entièrement ignoré (non instancié, aucune route, ressources non validées). À utiliser pour l'outillage réservé au développement qui ne doit jamais s'exécuter dans une application déployée. |
stability | "beta" ou "ga". Les plugins en bêta peuvent introduire des ruptures d'une version mineure à l'autre — voir Niveaux de stabilité des plugins. |
config.schema | Schéma JSON de la configuration runtime du plugin (utilisé par le générateur de types et pour la validation). |
Voir aussi
- Créer des plugins personnalisés — créer un plugin de A à Z.
- Gestion des plugins —
appkit plugin sync,create,validate,add-resource. - Modèles — comment le manifeste de modèle synchronisé pilote
databricks apps init. - Référence de l'API
PluginManifest— type TypeScript.