Accéder au contenu principal

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édactionimport manifest from "./manifest.json", puis rattachez-le à la sous-classe Plugin via static manifest.
  • Synchronisationappkit plugin sync --write agrège les manifestes des paquets installés et des plugins locaux dans appkit.plugins.json.
  • Initialisationdatabricks apps init lit appkit.plugins.json pour 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.

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

ChampTypeNotes
namestringIdentifiant du plugin. En minuscules, commence par une lettre, [a-z0-9-] uniquement.
displayNamestringAffiché dans l'UI et les prompt de la CLI.
descriptionstringBrève description.
resources.requiredResourceRequirement[]Ressources sans lesquelles le plugin ne peut pas fonctionner.
resources.optionalResourceRequirement[]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) :

typePermissions
secretREAD, WRITE, MANAGE
jobCAN_VIEW, CAN_MANAGE_RUN, CAN_MANAGE
sql_warehouseCAN_USE, CAN_MANAGE
serving_endpointCAN_VIEW, CAN_QUERY, CAN_MANAGE
volumeREAD_VOLUME, WRITE_VOLUME
vector_search_indexSELECT
uc_functionEXECUTE
uc_connectionUSE_CONNECTION
databaseCAN_CONNECT_AND_CREATE
postgresCAN_CONNECT_AND_CREATE
genie_spaceCAN_VIEW, CAN_RUN, CAN_EDIT, CAN_MANAGE
experimentCAN_READ, CAN_EDIT, CAN_MANAGE
appCAN_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 dans app.yaml. L'identité repose sur resourceKey, pas sur alias.
  • 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
envNom de la variable d'environnement écrite dans .env et app.yaml. Doit correspondre à ^[A-Z][A-Z0-9_]*$.
descriptionAffichée dans les prompt interactives et les descriptions de variables du bundle.
examplesExemples de valeurs affichés dans les descriptions de champs.
localOnlySi 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.
bundleIgnoreExclu des variables de databricks.yml (mais toujours écrit dans .env).
valueValeur par défaut statique.
resolveNom 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.
discoveryDé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 :

resourceKindListé via
warehousedatabricks warehouses list
genie_spacedatabricks genie list-spaces
volumedatabricks volumes list {catalog} {schema}
postgres_projectdatabricks postgres list-projects
postgres_branchdatabricks postgres list-branches {project}
postgres_databasedatabricks postgres list-databases {branch}

Options prises en charge par la variante kind :

PropriétéDescription
selectNom 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.
displayNom du champ affiché à l'utilisateur lors de la sélection. Par défaut, select.
dependsOnNom d'un champ voisin au sein de la même ressource qui doit être résolu au préalable (voir Dépendances entre champs).
shortcutCommande 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
cliCommandCommande 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.
selectFieldChemin de style jq vers le champ utilisé comme valeur sélectionnée (p. ex. .id, .name).
displayFieldChemin de style jq vers le champ affiché à l'utilisateur. Vaut selectField par défaut.
dependsOnChamp frère qui doit être résolu au préalable.
shortcutCommande 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 (dependsOn pointant 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égorieSémantique
mustL'agent doit effectuer l'action.
shouldAction recommandée — l'agent l'applique sauf indication contraire.
neverL'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, should ou never) 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 init lorsque 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_VOLUME sur son volume » → déjà encodé dans le champ permission de 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

ChampDescription
authorNom de l'auteur ou de l'organisation.
versionVersion du plugin, au format semver (X.Y.Z ou X.Y.Z-prerelease).
repositoryURL des sources du plugin.
keywordsMots-clés de découverte.
licenseIdentifiant SPDX.
onSetupMessageMessage 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.
hiddenLorsque la valeur est true, le plugin est exclu du manifeste de modèle synchronisé.
devOnlyLorsque 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.schemaSchéma JSON de la configuration runtime du plugin (utilisé par le générateur de types et pour la validation).

Voir aussi

Databricks Developer Hub

Prêt à lancer votre prochaine application agentique en quelques minutes ?

Lire la documentation