---
title: Plugin
description: Plugin protocol schemas
---

{/* ⚠️  AUTO-GENERATED — DO NOT EDIT. Run build-docs.ts to regenerate. Hand-written docs go in content/docs/guides/. */}

@module studio/plugin

Studio Plugin Protocol

Defines the specification for Studio plugins — a VS Code-like extension model

that allows each metadata type to contribute custom viewers, designers,

sidebar groups, actions, and commands.

## Architecture

Like VS Code extensions, Studio plugins have two layers:

1. **Manifest (Declarative)** — JSON-serializable contribution points

2. **Activation (Imperative)** — Runtime registration of React components & handlers

```

┌─────────────────────────────────────────────────────────┐

│                    Studio Host                          │

│  ┌───────────────────────────────────────────────────┐  │

│  │              Plugin Registry                      │  │

│  │  ┌──────────┐ ┌──────────┐ ┌──────────┐         │  │

│  │  │ Object   │ │  Flow    │ │  Agent   │  ...     │  │

│  │  │ Plugin   │ │  Plugin  │ │  Plugin  │         │  │

│  │  └──────────┘ └──────────┘ └──────────┘         │  │

│  └───────────────────────────────────────────────────┘  │

│                                                         │

│  ┌─── Sidebar ───┐  ┌──── Main Panel ────────────────┐ │

│  │ [plugin icons] │  │  PluginHost renders viewer     │ │

│  │ [plugin groups]│  │  from highest-priority plugin  │ │

│  └────────────────┘  └────────────────────────────────┘ │

└─────────────────────────────────────────────────────────┘

```

@example

```typescript

import \{ StudioPluginManifestSchema \} from '@objectstack/spec/studio';

const manifest = StudioPluginManifestSchema.parse(\{

id: 'objectstack.object-designer',

name: 'Object Designer',

version: '1.0.0',

contributes: \{

metadataViewers: [\{

id: 'object-explorer',

metadataTypes: ['object', 'objects'],

label: 'Object Explorer',

priority: 100,

modes: ['preview', 'design', 'data'],

\}],

\},

\});

```

<Callout type="info">
**Source:** `packages/spec/src/studio/plugin.zod.ts`
</Callout>

## TypeScript Usage

```typescript
import { ActionContribution, ActivationEvent, CommandContribution, MetadataIconContribution, MetadataViewerContribution, PanelContribution, PanelLocation, SidebarGroupContribution, StudioPluginContributions, StudioPluginManifest, ViewMode } from '@objectstack/spec/studio';
import type { ActionContribution, ActivationEvent, CommandContribution, MetadataIconContribution, MetadataViewerContribution, PanelContribution, PanelLocation, SidebarGroupContribution, StudioPluginContributions, StudioPluginManifest, ViewMode } from '@objectstack/spec/studio';

// Validate data
const result = ActionContribution.parse(data);
```

---

## ActionContribution

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **id** | `string` | ✅ | Unique action identifier |
| **label** | `string` | ✅ | Action display label |
| **icon** | `string` | optional | Lucide icon name |
| **location** | `Enum<'toolbar' \| 'contextMenu' \| 'commandPalette'>` | ✅ | UI location |
| **metadataTypes** | `string[]` | ✅ | Applicable metadata types |


---


---

## CommandContribution

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **id** | `string` | ✅ | Unique command identifier |
| **label** | `string` | ✅ | Command display label |
| **shortcut** | `string` | optional | Keyboard shortcut |
| **icon** | `string` | optional | Lucide icon name |


---

## MetadataIconContribution

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **metadataType** | `string` | ✅ | Metadata type |
| **label** | `string` | ✅ | Display label |
| **icon** | `string` | ✅ | Lucide icon name |


---

## MetadataViewerContribution

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **id** | `string` | ✅ | Unique viewer identifier |
| **metadataTypes** | `string[]` | ✅ | Metadata types this viewer can handle |
| **label** | `string` | ✅ | Viewer display label |
| **priority** | `number` | ✅ | Viewer priority (higher wins) |
| **modes** | `Enum<'preview' \| 'design' \| 'code' \| 'data' \| 'history'>[]` | ✅ | Supported view modes |


---

## PanelContribution

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **id** | `string` | ✅ | Unique panel identifier |
| **label** | `string` | ✅ | Panel display label |
| **icon** | `string` | optional | Lucide icon name |
| **location** | `Enum<'bottom' \| 'right' \| 'modal'>` | ✅ | Panel location |


---

## PanelLocation

### Allowed Values

* `bottom`
* `right`
* `modal`


---

## SidebarGroupContribution

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **key** | `string` | ✅ | Unique group key |
| **label** | `string` | ✅ | Group display label |
| **icon** | `string` | optional | Lucide icon name |
| **metadataTypes** | `string[]` | ✅ | Metadata types in this group |
| **order** | `number` | ✅ | Sort order (lower = higher) |


---

## StudioPluginContributions

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **metadataViewers** | `Object[]` | ✅ |  |
| **sidebarGroups** | `Object[]` | ✅ |  |
| **actions** | `Object[]` | ✅ |  |
| **metadataIcons** | `Object[]` | ✅ |  |
| **panels** | `Object[]` | ✅ |  |
| **commands** | `Object[]` | ✅ |  |


---

## StudioPluginManifest

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **id** | `string` | ✅ | Plugin ID (dot-separated lowercase) |
| **name** | `string` | ✅ | Plugin display name |
| **version** | `string` | ✅ | Plugin version |
| **description** | `string` | optional | Plugin description |
| **author** | `string` | optional | Author |
| **contributes** | `Object` | ✅ |  |
| **activationEvents** | `string[]` | ✅ |  |


---

## ViewMode

### Allowed Values

* `preview`
* `design`
* `code`
* `data`
* `history`


---

