Skip to content

Commit ec5481d

Browse files
authored
feat: add plugin commands (#110)
1 parent 64930bc commit ec5481d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+3504
-599
lines changed

CLAUDE.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,17 @@ pnpm check:fix # Auto-fix with Biome
9595
pnpm typecheck # TypeScript type checking across all packages
9696
```
9797

98+
### AppKit CLI
99+
When using the published SDK or running from the monorepo (after `pnpm build`), the `appkit` CLI is available:
100+
101+
```bash
102+
npx appkit plugin sync --write # Sync plugin manifests into appkit.plugins.json
103+
npx appkit plugin create # Scaffold a new plugin (interactive, uses @clack/prompts)
104+
npx appkit plugin validate # Validate manifest(s) against the JSON schema
105+
npx appkit plugin list # List plugins (from appkit.plugins.json or --dir)
106+
npx appkit plugin add-resource # Add a resource requirement to a plugin (interactive)
107+
```
108+
98109
### Deployment
99110
```bash
100111
pnpm pack:sdk # Package SDK for deployment

CONTRIBUTING.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,3 +112,24 @@ pnpm docs:serve # Serve built docs
112112
```
113113

114114
See [docs/README.md](./docs/README.md) for more details.
115+
116+
## Adding or changing a resource type
117+
118+
Resource types and their permissions are defined once in the plugin-manifest schema; the CLI (create, add-resource, validate) and the appkit registry types are derived from it.
119+
120+
To add or change a resource type:
121+
122+
1. **Edit the schema**`packages/shared/src/schemas/plugin-manifest.schema.json`:
123+
- Add the value to `$defs.resourceType.enum`.
124+
- Add a permission definition (e.g. `$defs.myResourcePermission`) with an `enum` array; list permissions **weakest to strongest** (this order is used for merge/escalation).
125+
- In `$defs.resourceRequirement.allOf`, add a branch with `if.properties.type.const` set to the new type and `then.properties.permission.$ref` pointing at that permission def (e.g. `#/$defs/myResourcePermission`).
126+
127+
2. **Regenerate registry types** – from the repo root:
128+
```bash
129+
pnpm exec tsx tools/generate-registry-types.ts
130+
```
131+
This updates `packages/appkit/src/registry/types.generated.ts`. The appkit build runs this automatically before compiling.
132+
133+
3. **Optional:** Add default fields for the new type in `packages/shared/src/cli/commands/plugin/create/resource-defaults.ts` (`DEFAULT_FIELDS_BY_TYPE`) so the plugin create/add-resource prompts suggest env vars.
134+
135+
For more context and alternative approaches, see [Registry types from schema](./docs/docs/development/registry-types-from-schema.md).
Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
# Enumeration: ResourceType
22

3-
Supported resource types that plugins can depend on.
4-
Each type has its own set of valid permissions.
3+
Resource types from schema $defs.resourceType.enum
54

65
## Enumeration Members
76

@@ -11,8 +10,6 @@ Each type has its own set of valid permissions.
1110
APP: "app";
1211
```
1312

14-
Databricks App dependency
15-
1613
***
1714

1815
### DATABASE
@@ -21,8 +18,6 @@ Databricks App dependency
2118
DATABASE: "database";
2219
```
2320

24-
Database (Lakebase) for persistent storage
25-
2621
***
2722

2823
### EXPERIMENT
@@ -31,8 +26,6 @@ Database (Lakebase) for persistent storage
3126
EXPERIMENT: "experiment";
3227
```
3328

34-
MLflow Experiment for ML tracking
35-
3629
***
3730

3831
### GENIE\_SPACE
@@ -41,8 +34,6 @@ MLflow Experiment for ML tracking
4134
GENIE_SPACE: "genie_space";
4235
```
4336

44-
Genie Space for AI assistant
45-
4637
***
4738

4839
### JOB
@@ -51,8 +42,6 @@ Genie Space for AI assistant
5142
JOB: "job";
5243
```
5344

54-
Databricks Job for scheduled or triggered workflows
55-
5645
***
5746

5847
### SECRET
@@ -61,8 +50,6 @@ Databricks Job for scheduled or triggered workflows
6150
SECRET: "secret";
6251
```
6352

64-
Secret scope for secure credential storage
65-
6653
***
6754

6855
### SERVING\_ENDPOINT
@@ -71,8 +58,6 @@ Secret scope for secure credential storage
7158
SERVING_ENDPOINT: "serving_endpoint";
7259
```
7360

74-
Model serving endpoint for ML inference
75-
7661
***
7762

7863
### SQL\_WAREHOUSE
@@ -81,8 +66,6 @@ Model serving endpoint for ML inference
8166
SQL_WAREHOUSE: "sql_warehouse";
8267
```
8368

84-
Databricks SQL Warehouse for query execution
85-
8669
***
8770

8871
### UC\_CONNECTION
@@ -91,8 +74,6 @@ Databricks SQL Warehouse for query execution
9174
UC_CONNECTION: "uc_connection";
9275
```
9376

94-
Unity Catalog Connection for external data sources
95-
9677
***
9778

9879
### UC\_FUNCTION
@@ -101,8 +82,6 @@ Unity Catalog Connection for external data sources
10182
UC_FUNCTION: "uc_function";
10283
```
10384

104-
Unity Catalog Function
105-
10685
***
10786

10887
### VECTOR\_SEARCH\_INDEX
@@ -111,14 +90,10 @@ Unity Catalog Function
11190
VECTOR_SEARCH_INDEX: "vector_search_index";
11291
```
11392

114-
Vector Search Index for similarity search
115-
11693
***
11794

11895
### VOLUME
11996

12097
```ts
12198
VOLUME: "volume";
12299
```
123-
124-
Unity Catalog Volume for file storage
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Type Alias: ToPlugin()\<T, U, N\>
2+
3+
```ts
4+
type ToPlugin<T, U, N> = (config?: U) => PluginData<T, U, N>;
5+
```
6+
7+
## Type Parameters
8+
9+
| Type Parameter |
10+
| ------ |
11+
| `T` |
12+
| `U` |
13+
| `N` *extends* `string` |
14+
15+
## Parameters
16+
17+
| Parameter | Type |
18+
| ------ | ------ |
19+
| `config?` | `U` |
20+
21+
## Returns
22+
23+
`PluginData`\<`T`, `U`, `N`\>

docs/docs/api/appkit/index.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ plugin architecture, and React integration.
88
| Enumeration | Description |
99
| ------ | ------ |
1010
| [RequestedClaimsPermissionSet](Enumeration.RequestedClaimsPermissionSet.md) | Permission set for Unity Catalog table access |
11-
| [ResourceType](Enumeration.ResourceType.md) | Supported resource types that plugins can depend on. Each type has its own set of valid permissions. |
11+
| [ResourceType](Enumeration.ResourceType.md) | Resource types from schema $defs.resourceType.enum |
1212

1313
## Classes
1414

@@ -53,6 +53,7 @@ plugin architecture, and React integration.
5353
| [ConfigSchema](TypeAlias.ConfigSchema.md) | Configuration schema definition for plugin config. Re-exported from the standard JSON Schema Draft 7 types. |
5454
| [IAppRouter](TypeAlias.IAppRouter.md) | Express router type for plugin route registration |
5555
| [ResourcePermission](TypeAlias.ResourcePermission.md) | Union of all possible permission levels across all resource types. |
56+
| [ToPlugin](TypeAlias.ToPlugin.md) | - |
5657

5758
## Variables
5859

docs/docs/api/appkit/typedoc-sidebar.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,11 @@ const typedocSidebar: SidebarsConfig = {
177177
type: "doc",
178178
id: "api/appkit/TypeAlias.ResourcePermission",
179179
label: "ResourcePermission"
180+
},
181+
{
182+
type: "doc",
183+
id: "api/appkit/TypeAlias.ToPlugin",
184+
label: "ToPlugin"
180185
}
181186
]
182187
},

docs/docs/plugins.md

Lines changed: 89 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,9 +205,97 @@ const AppKit = await createApp({
205205

206206
For complete configuration options, see [`createApp`](api/appkit/Function.createApp.md).
207207

208+
## Plugin management
209+
210+
AppKit includes a CLI for managing plugins. All commands are available under `npx @databricks/appkit plugin`.
211+
212+
### Create a plugin
213+
214+
Scaffold a new plugin interactively:
215+
216+
```bash
217+
npx @databricks/appkit plugin create
218+
```
219+
220+
The wizard walks you through:
221+
- **Placement**: In your repository (e.g. `plugins/my-plugin`) or as a standalone package
222+
- **Metadata**: Name, display name, description
223+
- **Resources**: Which Databricks resources the plugin needs (SQL Warehouse, Secret, etc.) and whether each is required or optional
224+
- **Optional fields**: Author, version, license
225+
226+
The command generates a complete plugin scaffold with `manifest.json`, TypeScript class, and barrel exports — ready to register in your app.
227+
228+
### Sync plugin manifests
229+
230+
Scan your project for plugins and generate `appkit.plugins.json`:
231+
232+
```bash
233+
npx @databricks/appkit plugin sync --write
234+
```
235+
236+
This discovers plugin manifests from installed packages and local imports, then writes a consolidated manifest used by deployment tooling. Plugins referenced in your `createApp({ plugins: [...] })` call are automatically marked as required.
237+
238+
Use the `--silent` flag in build hooks to suppress output:
239+
240+
```json
241+
{
242+
"scripts": {
243+
"sync": "appkit plugin sync --write --silent",
244+
"predev": "npm run sync",
245+
"prebuild": "npm run sync"
246+
}
247+
}
248+
```
249+
250+
### Validate manifests
251+
252+
Check plugin manifests against the JSON schema:
253+
254+
```bash
255+
# Validate manifest.json in the current directory
256+
npx @databricks/appkit plugin validate
257+
258+
# Validate specific files or directories
259+
npx @databricks/appkit plugin validate plugins/my-plugin appkit.plugins.json
260+
```
261+
262+
The validator auto-detects whether a file is a plugin manifest or a template manifest (from `$schema`) and reports errors with humanized paths and expected values.
263+
264+
### List plugins
265+
266+
View registered plugins from `appkit.plugins.json` or scan a directory:
267+
268+
```bash
269+
# From appkit.plugins.json (default)
270+
npx @databricks/appkit plugin list
271+
272+
# Scan a directory for plugin folders
273+
npx @databricks/appkit plugin list --dir plugins/
274+
275+
# JSON output for scripting
276+
npx @databricks/appkit plugin list --json
277+
```
278+
279+
### Add a resource to a plugin
280+
281+
Interactively add a new resource requirement to an existing plugin manifest:
282+
283+
```bash
284+
npx @databricks/appkit plugin add-resource
285+
286+
# Or specify the plugin directory
287+
npx @databricks/appkit plugin add-resource --path plugins/my-plugin
288+
```
289+
208290
## Creating custom plugins
209291

210-
If you need custom API routes or background logic, implement an AppKit plugin.
292+
If you need custom API routes or background logic, implement an AppKit plugin. The fastest way is to use the CLI:
293+
294+
```bash
295+
npx @databricks/appkit plugin create
296+
```
297+
298+
For a deeper understanding of the plugin structure, read on.
211299

212300
### Basic plugin example
213301

0 commit comments

Comments
 (0)