Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions docs/docs/api/appkit/Interface.PluginManifest.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,22 @@ Omit.onSetupMessage

***

### postScaffold?

```ts
optional postScaffold: PostScaffoldStep[];
```

Ordered guidance for human or agent follow-up after scaffolding.

#### Inherited from

```ts
Omit.postScaffold
```

***

### repository?

```ts
Expand Down
20 changes: 20 additions & 0 deletions docs/docs/api/appkit/Interface.ResourceFieldEntry.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,16 @@ Human-readable description for this field

***

### discovery?

```ts
optional discovery: DiscoveryDescriptor;
```

CLI discovery metadata for non-interactive resolution.

***

### env?

```ts
Expand Down Expand Up @@ -57,6 +67,16 @@ When true, this field is only generated for local .env files. The Databricks App

***

### resolution?

```ts
optional resolution: ResourceResolution;
```

How this field's value is supplied to the app.

***

### resolve?

```ts
Expand Down
72 changes: 72 additions & 0 deletions docs/static/schemas/plugin-manifest.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,13 @@
"type": "string",
"description": "Message displayed to the user after project initialization. Use this to inform about manual setup steps (e.g. environment variables, resource provisioning)."
},
"postScaffold": {
"type": "array",
"description": "Ordered guidance for human or agent follow-up after scaffolding.",
"items": {
"$ref": "#/$defs/postScaffoldStep"
}
},
"hidden": {
"type": "boolean",
"default": false,
Expand Down Expand Up @@ -220,10 +227,53 @@
"type": "string",
"pattern": "^[a-z_]+:[a-zA-Z]+$",
"description": "Named resolver prefixed by resource type (e.g., 'postgres:host'). The CLI resolves this value during the init prompt flow."
},
"discovery": {
"$ref": "#/$defs/discoveryDescriptor"
},
"resolution": {
"$ref": "#/$defs/resourceResolution"
}
},
"additionalProperties": false
},
"discoveryDescriptor": {
"type": "object",
"required": ["cliCommand", "selectField"],
"properties": {
"cliCommand": {
"type": "string",
"minLength": 1,
"description": "CLI command to list candidate values. Use <PROFILE> as a placeholder for the Databricks CLI profile."
},
"selectField": {
"type": "string",
"minLength": 1,
"description": "jq-style selector for the machine-readable value to capture from the CLI output."
},
"displayField": {
"type": "string",
"minLength": 1,
"description": "jq-style selector for a human-readable label to display alongside the selected value."
},
"dependsOn": {
"type": "string",
"minLength": 1,
"description": "Field name in the same resource that must be resolved before running this discovery command."
},
"shortcut": {
"type": "string",
"minLength": 1,
"description": "Optional direct CLI command that returns a single preferred value."
}
},
"additionalProperties": false
},
"resourceResolution": {
"type": "string",
"enum": ["user-provided", "platform-injected"],
"description": "How this field's value is supplied to the app."
},
"resourceRequirement": {
"type": "object",
"description": "Declares a resource requirement for a plugin. Can be defined statically in a manifest or dynamically via getResourceRequirements().",
Expand Down Expand Up @@ -405,6 +455,28 @@
}
]
},
"postScaffoldStep": {
"type": "object",
"required": ["step", "instruction"],
"properties": {
"step": {
"type": "integer",
"minimum": 1,
"description": "Step number in the ordered post-scaffold flow."
},
"instruction": {
"type": "string",
"minLength": 1,
"description": "Instruction to follow after scaffolding completes."
},
"blocking": {
"type": "boolean",
"default": false,
"description": "When true, this step must finish before continuing."
}
},
"additionalProperties": false
},
"configSchemaProperty": {
"type": "object",
"required": ["type"],
Expand Down
163 changes: 163 additions & 0 deletions docs/static/schemas/template-plugins.schema.v2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://databricks.github.io/appkit/schemas/template-plugins.schema.v2.json",
"title": "AppKit Template Plugins Manifest V2",
"description": "Aggregated plugin manifest for AppKit templates. Read by Databricks CLI during init to discover available plugins, resource requirements, and scaffold guidance.",
"type": "object",
"required": ["version", "scaffolding", "plugins"],
"properties": {
"$schema": {
"type": "string",
"description": "Reference to the JSON Schema for validation"
},
"version": {
"type": "string",
"const": "2.0",
"description": "Schema version for the template plugins manifest"
},
"scaffolding": {
"$ref": "#/$defs/scaffolding"
},
"plugins": {
"type": "object",
"description": "Map of plugin name to plugin manifest with package source",
"additionalProperties": {
"$ref": "#/$defs/templatePlugin"
}
}
},
"additionalProperties": false,
"$defs": {
"templatePlugin": {
"type": "object",
"required": [
"name",
"displayName",
"description",
"package",
"resources"
],
"description": "Plugin manifest with package source information",
"properties": {
"name": {
"type": "string",
"pattern": "^[a-z][a-z0-9-]*$",
"description": "Plugin identifier. Must be lowercase, start with a letter, and contain only letters, numbers, and hyphens.",
"examples": ["analytics", "server", "my-custom-plugin"]
},
"displayName": {
"type": "string",
"minLength": 1,
"description": "Human-readable display name for UI and CLI",
"examples": ["Analytics Plugin", "Server Plugin"]
},
"description": {
"type": "string",
"minLength": 1,
"description": "Brief description of what the plugin does",
"examples": ["SQL query execution against Databricks SQL Warehouses"]
},
"package": {
"type": "string",
"minLength": 1,
"description": "NPM package name or relative path that provides this plugin",
"examples": ["@databricks/appkit", "./plugins/custom-plugin"]
},
"requiredByTemplate": {
"type": "boolean",
"default": false,
"description": "When true, this plugin is required by the template and cannot be deselected during CLI init."
},
"onSetupMessage": {
"type": "string",
"description": "Human-facing message displayed after project initialization to explain manual setup steps."
},
"postScaffold": {
"type": "array",
"description": "Ordered follow-up guidance for a human or agent after scaffolding.",
"items": {
"$ref": "plugin-manifest.schema.json#/$defs/postScaffoldStep"
}
},
"resources": {
"type": "object",
"required": ["required", "optional"],
"description": "Databricks resource requirements for this plugin",
"properties": {
"required": {
"type": "array",
"description": "Resources that must be available for the plugin to function",
"items": {
"$ref": "#/$defs/resourceRequirement"
}
},
"optional": {
"type": "array",
"description": "Resources that enhance functionality but are not mandatory",
"items": {
"$ref": "#/$defs/resourceRequirement"
}
}
},
"additionalProperties": false
}
},
"additionalProperties": false
},
"scaffoldingFlag": {
"type": "object",
"required": ["required", "description"],
"properties": {
"required": {
"type": "boolean"
},
"description": {
"type": "string",
"minLength": 1
},
"pattern": {
"type": "string",
"minLength": 1
},
"default": {
"type": "string"
}
},
"additionalProperties": false
},
"scaffolding": {
"type": "object",
"required": ["command", "flags", "rules"],
"properties": {
"command": {
"type": "string",
"minLength": 1
},
"flags": {
"type": "object",
"minProperties": 1,
"additionalProperties": {
"$ref": "#/$defs/scaffoldingFlag"
}
},
"rules": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
}
}
},
"additionalProperties": false
},
"resourceType": {
"$ref": "plugin-manifest.schema.json#/$defs/resourceType"
},
"resourceFieldEntry": {
"$ref": "plugin-manifest.schema.json#/$defs/resourceFieldEntry"
},
"resourceRequirement": {
"$ref": "plugin-manifest.schema.json#/$defs/resourceRequirement"
}
}
}
35 changes: 33 additions & 2 deletions packages/appkit/src/plugins/analytics/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,14 @@
"fields": {
"id": {
"env": "DATABRICKS_WAREHOUSE_ID",
"description": "SQL Warehouse ID"
"description": "SQL Warehouse ID",
"discovery": {
"cliCommand": "databricks warehouses list --profile <PROFILE> -o json",
"selectField": ".id",
"displayField": ".name",
"shortcut": "databricks experimental aitools tools get-default-warehouse --profile <PROFILE>"
},
"resolution": "user-provided"
}
}
}
Expand All @@ -32,5 +39,29 @@
}
}
}
}
},
"onSetupMessage": "Run 'databricks warehouses list' to find your SQL Warehouse ID.",
"postScaffold": [
{
"step": 1,
"instruction": "Create SQL query files in config/queries/"
},
{
"step": 2,
"instruction": "Run: npm run typegen",
"blocking": true
},
{
"step": 3,
"instruction": "Read client/src/appKitTypes.d.ts for generated types"
},
{
"step": 4,
"instruction": "Write UI code using the generated types"
},
{
"step": 5,
"instruction": "Update tests/smoke.spec.ts selectors for your app"
}
]
}
21 changes: 19 additions & 2 deletions packages/appkit/src/plugins/files/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,13 @@
"fields": {
"path": {
"env": "DATABRICKS_VOLUME_FILES",
"description": "Volume path for file storage (e.g. /Volumes/catalog/schema/volume_name)"
"description": "Volume path for file storage (e.g. /Volumes/catalog/schema/volume_name)",
"discovery": {
"cliCommand": "databricks volumes list <CATALOG> <SCHEMA> --profile <PROFILE> -o json",
"selectField": ".full_name",
"displayField": ".name"
},
"resolution": "user-provided"
}
}
}
Expand All @@ -37,5 +43,16 @@
}
}
}
}
},
"onSetupMessage": "Provide the full volume path, e.g. /Volumes/catalog/schema/volume_name.",
"postScaffold": [
{
"step": 1,
"instruction": "Use the files plugin API to read/write volume files in your tRPC procedures"
},
{
"step": 2,
"instruction": "Build UI for file upload/download using tRPC"
}
]
}
Loading
Loading