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
8 changes: 4 additions & 4 deletions apps/dev-playground/client/src/appKitTypes.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,10 +119,10 @@ declare module "@databricks/appkit-ui/react" {
result: Array<{
/** @sqlType STRING */
string_value: string;
/** @sqlType STRING */
number_value: string;
/** @sqlType STRING */
boolean_value: string;
/** @sqlType INT */
number_value: number;
/** @sqlType BOOLEAN */
boolean_value: boolean;
/** @sqlType STRING */
date_value: string;
/** @sqlType STRING */
Expand Down
141 changes: 141 additions & 0 deletions docs/docs/plugins/stability.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
---
sidebar_position: 2
---

# Plugin Stability Tiers

AppKit plugins have a three-tier stability system that communicates API maturity and breaking-change expectations.

## Tiers

| Tier | Import Path | Contract |
|------|------------|---------|
| **Experimental** | `@databricks/appkit/experimental` | Very unstable. May be dropped entirely. No guarantee of promotion. |
| **Preview** | `@databricks/appkit/preview` | API may change between minor releases. On a path to stable. |
| **Stable** | `@databricks/appkit` | Production ready. Follows semver strictly. |

The import path is the primary stability signal. Importing from `/experimental` or `/preview` is explicit consent to potential breaking changes.

## Promotion Path

Promotion is one-way. Plugins can enter at any tier.

```
experimental ──→ preview ──→ stable
└──→ (dropped)
```

## Usage

### Importing Plugins by Tier

```typescript
// Stable plugins
import { server, analytics } from "@databricks/appkit";

// Preview plugins
import { somePreviewPlugin } from "@databricks/appkit/preview";

// Experimental plugins
import { someExperimentalPlugin } from "@databricks/appkit/experimental";
```

### UI Components

`@databricks/appkit-ui` mirrors the same pattern:

```typescript
import { SomeComponent } from "@databricks/appkit-ui/react/preview";
import { someUtil } from "@databricks/appkit-ui/js/experimental";
```

## CLI Commands

### Listing Plugins with Stability

```bash
npx appkit plugin list
```

The output includes a STABILITY column showing each plugin's tier.

### Creating a Plugin with Stability

```bash
npx appkit plugin create
```

The interactive flow prompts for a stability level (defaults to stable).

### Promoting a Plugin

```bash
# Promote from experimental to preview
npx appkit plugin promote my-plugin --to preview

# Promote from preview to stable
npx appkit plugin promote my-plugin --to stable

# Preview changes without modifying files
npx appkit plugin promote my-plugin --to preview --dry-run
```

The promote command:
- Updates the plugin's `manifest.json` stability field
- Rewrites import paths across your project's `.ts`/`.tsx` files
- Runs `plugin sync` to update `appkit.plugins.json`

**Options:**
- `--dry-run` -- Show what would change without writing
- `--skip-imports` -- Only update the manifest
- `--skip-sync` -- Don't auto-run sync

## Manifest Field

The `stability` field in `manifest.json` is optional. When absent, the plugin is considered stable.

```json
{
"name": "my-plugin",
"displayName": "My Plugin",
"description": "An experimental feature",
"stability": "experimental",
"resources": { "required": [], "optional": [] }
}
```

Valid values: `"experimental"`, `"preview"`, `"stable"`.

## Template Manifest (appkit.plugins.json)

When `plugin sync` discovers non-stable plugins, it includes their stability in the output:

```json
{
"version": "1.1",
"plugins": {
"my-plugin": {
"name": "my-plugin",
"stability": "experimental",
"package": "@databricks/appkit"
}
}
}
```

Only stable plugins can be marked `requiredByTemplate`. Non-stable plugins always remain optional during init.

## For Third-Party Plugin Authors

The import paths (`/experimental`, `/preview`) only apply to first-party plugins shipped inside `@databricks/appkit`. Third-party plugins declare stability via the `stability` field in their `manifest.json`. CLI tooling (`plugin list`, `plugin sync`) surfaces this information to users.

## Current Plugins by Tier

All built-in plugins are currently **stable**:

- `server` -- Express HTTP server
- `analytics` -- SQL query execution
- `files` -- Multi-volume file browser
- `genie` -- Genie Space integration
- `lakebase` -- Postgres Autoscaling
28 changes: 25 additions & 3 deletions docs/static/appkit-ui/styles.gen.css
Original file line number Diff line number Diff line change
Expand Up @@ -831,9 +831,6 @@
.max-w-\[calc\(100\%-2rem\)\] {
max-width: calc(100% - 2rem);
}
.max-w-full {
max-width: 100%;
}
.max-w-max {
max-width: max-content;
}
Expand Down Expand Up @@ -4514,6 +4511,11 @@
width: calc(var(--spacing) * 5);
}
}
.\[\&_\[data-slot\=scroll-area-viewport\]\>div\]\:\!block {
& [data-slot=scroll-area-viewport]>div {
display: block !important;
}
}
.\[\&_a\]\:underline {
& a {
text-decoration-line: underline;
Expand Down Expand Up @@ -4637,11 +4639,26 @@
color: var(--muted-foreground);
}
}
.\[\&_table\]\:block {
& table {
display: block;
}
}
.\[\&_table\]\:max-w-full {
& table {
max-width: 100%;
}
}
.\[\&_table\]\:border-collapse {
& table {
border-collapse: collapse;
}
}
.\[\&_table\]\:overflow-x-auto {
& table {
overflow-x: auto;
}
}
.\[\&_table\]\:text-xs {
& table {
font-size: var(--text-xs);
Expand Down Expand Up @@ -4851,6 +4868,11 @@
width: 100%;
}
}
.\[\&\>\*\]\:min-w-0 {
&>* {
min-width: calc(var(--spacing) * 0);
}
}
.\[\&\>\*\]\:focus-visible\:relative {
&>* {
&:focus-visible {
Expand Down
20 changes: 20 additions & 0 deletions packages/appkit-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,26 @@
"development": "./src/js/index.ts",
"default": "./dist/js/index.js"
},
"./js/experimental": {
"development": "./src/js/experimental.ts",
"default": "./dist/js/experimental.js"
},
"./js/preview": {
"development": "./src/js/preview.ts",
"default": "./dist/js/preview.js"
},
"./react": {
"development": "./src/react/index.ts",
"default": "./dist/react/index.js"
},
"./react/experimental": {
"development": "./src/react/experimental.ts",
"default": "./dist/react/experimental.js"
},
"./react/preview": {
"development": "./src/react/preview.ts",
"default": "./dist/react/preview.js"
},
"./package.json": "./package.json",
"./styles.css": {
"development": "./src/react/styles/globals.css",
Expand Down Expand Up @@ -111,7 +127,11 @@
"publishConfig": {
"exports": {
"./js": "./dist/js/index.js",
"./js/experimental": "./dist/js/experimental.js",
"./js/preview": "./dist/js/preview.js",
"./react": "./dist/react/index.js",
"./react/experimental": "./dist/react/experimental.js",
"./react/preview": "./dist/react/preview.js",
"./package.json": "./package.json",
"./styles.css": "./dist/styles.css"
}
Expand Down
2 changes: 2 additions & 0 deletions packages/appkit-ui/src/js/experimental.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Experimental JS utilities -- very unstable, may be dropped entirely.
// Import from '@databricks/appkit-ui/js/preview' once promoted.
2 changes: 2 additions & 0 deletions packages/appkit-ui/src/js/preview.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Preview JS utilities -- APIs may change between minor releases.
// Import from '@databricks/appkit-ui/js' once graduated to stable.
2 changes: 2 additions & 0 deletions packages/appkit-ui/src/react/experimental.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Experimental React components -- very unstable, may be dropped entirely.
// Import from '@databricks/appkit-ui/react/preview' once promoted.
2 changes: 2 additions & 0 deletions packages/appkit-ui/src/react/preview.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Preview React components -- APIs may change between minor releases.
// Import from '@databricks/appkit-ui/react' once graduated to stable.
9 changes: 8 additions & 1 deletion packages/appkit-ui/tsdown.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,14 @@ export default defineConfig([
{
publint: true,
name: "@databricks/appkit-ui",
entry: ["src/js/index.ts", "src/react/index.ts"],
entry: [
"src/js/index.ts",
"src/js/experimental.ts",
"src/js/preview.ts",
"src/react/index.ts",
"src/react/experimental.ts",
"src/react/preview.ts",
],
outDir: "dist",
platform: "browser",
minify: false,
Expand Down
10 changes: 10 additions & 0 deletions packages/appkit/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@
"development": "./src/index.ts",
"default": "./dist/index.js"
},
"./experimental": {
"development": "./src/experimental.ts",
"default": "./dist/experimental.js"
},
"./preview": {
"development": "./src/preview.ts",
"default": "./dist/preview.js"
},
"./type-generator": {
"types": "./dist/type-generator/index.d.ts",
"development": "./src/type-generator/index.ts",
Expand Down Expand Up @@ -92,6 +100,8 @@
"publishConfig": {
"exports": {
".": "./dist/index.js",
"./experimental": "./dist/experimental.js",
"./preview": "./dist/preview.js",
"./dist/shared/src/plugin": "./dist/shared/src/plugin.d.ts",
"./type-generator": "./dist/type-generator/index.js",
"./package.json": "./package.json"
Expand Down
3 changes: 3 additions & 0 deletions packages/appkit/src/experimental.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// Experimental plugins -- very unstable, may be dropped entirely.
// Plugins here have no guarantee of promotion to preview or stable.
// Import from '@databricks/appkit/preview' once a plugin is promoted.
3 changes: 3 additions & 0 deletions packages/appkit/src/preview.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// Preview plugins -- APIs may change between minor releases.
// These plugins are on a path to stable and will graduate.
// Import from '@databricks/appkit' once a plugin graduates to stable.
2 changes: 1 addition & 1 deletion packages/appkit/tsdown.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export default defineConfig([
{
publint: true,
name: "@databricks/appkit",
entry: "src/index.ts",
entry: ["src/index.ts", "src/experimental.ts", "src/preview.ts"],
outDir: "dist",
hash: false,
format: "esm",
Expand Down
23 changes: 23 additions & 0 deletions packages/shared/src/cli/commands/plugin/create/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,28 @@ async function runPluginCreate(): Promise<void> {
process.exit(0);
}

const stability = await select<"stable" | "preview" | "experimental">({
message: "Plugin stability level",
options: [
{ value: "stable", label: "Stable", hint: "API follows semver" },
{
value: "preview",
label: "Preview",
hint: "Heading to stable, API may change",
},
{
value: "experimental",
label: "Experimental",
hint: "Very unstable, may be dropped",
},
],
initialValue: "stable" as "stable" | "preview" | "experimental",
});
if (isCancel(stability)) {
cancel("Cancelled.");
process.exit(0);
}

const resourceTypes = await multiselect({
message: "Which Databricks resources does this plugin need?",
options: RESOURCE_TYPE_OPTIONS.map((o) => ({
Expand Down Expand Up @@ -153,6 +175,7 @@ async function runPluginCreate(): Promise<void> {
name: (name as string).trim(),
displayName: (displayName as string).trim(),
description: (description as string).trim(),
stability: stability === "stable" ? undefined : stability,
resources,
version: DEFAULT_VERSION,
};
Expand Down
Loading
Loading