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 steps to follow after scaffolding. Steps marked blocking must complete before proceeding.

#### Inherited from

```ts
Omit.postScaffold
```

***

### repository?

```ts
Expand Down
18 changes: 18 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,14 @@ Human-readable description for this field

***

### discovery?

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

***

### env?

```ts
Expand Down Expand Up @@ -67,6 +75,16 @@ Named resolver prefixed by resource type (e.g., 'postgres:host'). The CLI resolv

***

### setupHint?

```ts
optional setupHint: string;
```

Short actionable instruction for obtaining this field's value.

***

### value?

```ts
Expand Down
64 changes: 64 additions & 0 deletions docs/static/schemas/plugin-manifest.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,13 @@
"type": "boolean",
"default": false,
"description": "When true, this plugin is excluded from the template plugins manifest (appkit.plugins.json) during sync."
},
"postScaffold": {
"type": "array",
"description": "Ordered steps to follow after scaffolding. Steps marked blocking must complete before proceeding.",
"items": {
"$ref": "#/$defs/postScaffoldStep"
}
}
},
"additionalProperties": false,
Expand Down Expand Up @@ -220,6 +227,13 @@
"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"
},
"setupHint": {
"type": "string",
"description": "Short actionable instruction for obtaining this field's value."
}
},
"additionalProperties": false
Expand Down Expand Up @@ -405,6 +419,56 @@
}
]
},
"discoveryDescriptor": {
"type": "object",
"description": "How to discover candidate values for this field via CLI commands.",
"required": ["cliCommand", "selectField"],
"properties": {
"cliCommand": {
"type": "string",
"description": "CLI command to list candidate values. Use <PROFILE> as a placeholder for the Databricks CLI profile."
},
"selectField": {
"type": "string",
"description": "jq-style field to extract the value from each result (e.g. '.id')."
},
"displayField": {
"type": "string",
"description": "jq-style field for human-readable display (e.g. '.name')."
},
"dependsOn": {
"type": "string",
"description": "Field name in the same resource that must be resolved first."
},
"shortcut": {
"type": "string",
"description": "Optional command that returns a single value directly instead of a list."
}
},
"additionalProperties": false
},
"postScaffoldStep": {
"type": "object",
"description": "A single post-scaffolding step.",
"required": ["step", "instruction"],
"properties": {
"step": {
"type": "integer",
"minimum": 1,
"description": "Step number (sequential, starting from 1)."
},
"instruction": {
"type": "string",
"description": "What to do in this step."
},
"blocking": {
"type": "boolean",
"default": false,
"description": "When true, this step must finish before proceeding to the next."
}
},
"additionalProperties": false
},
"configSchemaProperty": {
"type": "object",
"required": ["type"],
Expand Down
62 changes: 60 additions & 2 deletions docs/static/schemas/template-plugins.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,12 @@
},
"version": {
"type": "string",
"const": "1.0",
"enum": ["1.0", "1.1"],
"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",
Expand All @@ -25,6 +28,38 @@
},
"additionalProperties": false,
"$defs": {
"scaffolding": {
"type": "object",
"description": "Template-level metadata for constructing the scaffolding CLI command.",
"required": ["command", "flags", "rules"],
"properties": {
"command": {
"type": "string",
"description": "The base CLI command for scaffolding."
},
"flags": {
"type": "object",
"description": "Map of flag name to flag descriptor.",
"additionalProperties": {
"type": "object",
"required": ["required", "description"],
"properties": {
"required": { "type": "boolean" },
"description": { "type": "string" },
"pattern": { "type": "string" },
"default": { "type": "string" }
},
"additionalProperties": false
}
},
"rules": {
"type": "array",
"items": { "type": "string" },
"description": "Rules for constructing the scaffolding command."
}
},
"additionalProperties": false
},
"templatePlugin": {
"type": "object",
"required": [
Expand Down Expand Up @@ -69,6 +104,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 steps to follow after scaffolding.",
"items": {
"$ref": "plugin-manifest.schema.json#/$defs/postScaffoldStep"
}
},
"resources": {
"type": "object",
"required": ["required", "optional"],
Expand Down Expand Up @@ -98,7 +140,23 @@
"$ref": "plugin-manifest.schema.json#/$defs/resourceType"
},
"resourceFieldEntry": {
"$ref": "plugin-manifest.schema.json#/$defs/resourceFieldEntry"
"allOf": [
{ "$ref": "plugin-manifest.schema.json#/$defs/resourceFieldEntry" },
{
"properties": {
"resolution": {
"type": "string",
"enum": [
"user-provided",
"platform-injected",
"static",
"cli-resolved"
],
"description": "Computed during sync. Indicates how the field's value is provided: user-provided (needs --set), platform-injected (auto-set at deploy), static (has a default value), or cli-resolved (resolved by the CLI during init)."
}
}
}
]
},
"resourceRequirement": {
"$ref": "plugin-manifest.schema.json#/$defs/resourceRequirement"
Expand Down
22 changes: 21 additions & 1 deletion packages/appkit/src/plugins/analytics/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,33 @@
"fields": {
"id": {
"env": "DATABRICKS_WAREHOUSE_ID",
"description": "SQL Warehouse ID"
"description": "SQL Warehouse ID",
"setupHint": "Run 'databricks warehouses list' to find your 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>"
}
}
}
}
],
"optional": []
},
"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"
}
],
"config": {
"schema": {
"type": "object",
Expand Down
15 changes: 14 additions & 1 deletion packages/appkit/src/plugins/files/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,26 @@
"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)",
"setupHint": "Provide the full volume path, e.g. /Volumes/catalog/schema/volume_name.",
"discovery": {
"cliCommand": "databricks volumes list <catalog>.<schema> --profile <PROFILE> -o json",
"selectField": ".full_name",
"displayField": ".name"
}
}
}
}
],
"optional": []
},
"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" }
],
"config": {
"schema": {
"type": "object",
Expand Down
17 changes: 16 additions & 1 deletion packages/appkit/src/plugins/genie/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,28 @@
"fields": {
"id": {
"env": "DATABRICKS_GENIE_SPACE_ID",
"description": "Default Genie Space ID"
"description": "Default Genie Space ID",
"setupHint": "Find your Genie Space ID in the AI/BI Genie UI."
}
}
}
],
"optional": []
},
"postScaffold": [
{
"step": 1,
"instruction": "Configure Genie Space aliases in the plugin config spaces map"
},
{
"step": 2,
"instruction": "Build UI components to send natural language queries via the Genie tRPC procedures"
},
{
"step": 3,
"instruction": "Update tests/smoke.spec.ts selectors for your app"
}
],
"config": {
"schema": {
"type": "object",
Expand Down
35 changes: 32 additions & 3 deletions packages/appkit/src/plugins/lakebase/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,24 @@
"fields": {
"branch": {
"description": "Full Lakebase Postgres branch resource name. Obtain by running `databricks postgres list-branches projects/{project-id}`, select the desired item from the output array and use its .name value.",
"examples": ["projects/{project-id}/branches/{branch-id}"]
"examples": ["projects/{project-id}/branches/{branch-id}"],
"setupHint": "Run 'databricks postgres list-branches projects/{project-id}' to find your branch.",
"discovery": {
"cliCommand": "databricks postgres list-branches projects/{project-id} --profile <PROFILE> -o json",
"selectField": ".name"
}
},
"database": {
"description": "Full Lakebase Postgres database resource name. Obtain by running `databricks postgres list-databases {branch-name}`, select the desired item from the output array and use its .name value. Requires the branch resource name.",
"examples": [
"projects/{project-id}/branches/{branch-id}/databases/{database-id}"
]
],
"setupHint": "Run 'databricks postgres list-databases {branch-name}' to find your database. Requires the branch first.",
"discovery": {
"cliCommand": "databricks postgres list-databases {branch} --profile <PROFILE> -o json",
"selectField": ".name",
"dependsOn": "branch"
}
},
"host": {
"env": "PGHOST",
Expand Down Expand Up @@ -60,5 +71,23 @@
}
],
"optional": []
}
},
"postScaffold": [
{
"step": 1,
"instruction": "Define your schema in server/server.ts startup"
},
{
"step": 2,
"instruction": "Write tRPC procedures using pool.query() in server/server.ts"
},
{
"step": 3,
"instruction": "Build React frontend consuming tRPC procedures"
},
{
"step": 4,
"instruction": "Update tests/smoke.spec.ts selectors for your app"
}
]
}
2 changes: 1 addition & 1 deletion packages/appkit/src/registry/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export {
type ResourcePermission,
};

// Re-export generated base type from shared (schema-derived, used directly).
// Re-export generated base types from shared (schema-derived, used directly).
export type { ResourceFieldEntry } from "shared";

// Import shared base types for strict extension below.
Expand Down
Loading
Loading