ObjectStackObjectStack

Plugin schema — Studio Protocol reference

Defines the specification for Studio plugins — a VS Code-like extension model that allows each metadata type to contribute custom viewers, designers.

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  │ │
│  └────────────────┘  └────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
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'],
    }],
  },
});

Source: packages/spec/src/studio/plugin.zod.ts

TypeScript Usage

import { ActionContributionSchema, ActionContributionLocationSchema, CommandContributionSchema, MetadataIconContributionSchema, MetadataViewerContributionSchema, PanelContributionSchema, PanelLocationSchema, SidebarGroupContributionSchema, StudioPluginContributionsSchema, StudioPluginManifestSchema, ViewModeSchema } from '@objectstack/spec/studio';
import type { ActionContribution, ActionContributionLocation, CommandContribution, MetadataIconContribution, MetadataViewerContribution, PanelContribution, PanelLocation, SidebarGroupContribution, StudioPluginContributions, StudioPluginManifest, ViewMode } from '@objectstack/spec/studio';

// Validate data
const result = ActionContributionSchema.parse(data);

ActionContribution

Properties

PropertyTypeRequiredDescription
idstring✅Unique action identifier
labelstring✅Action display label
iconstringoptionalLucide icon name
locationEnum<'toolbar' | 'contextMenu' | 'commandPalette'>✅UI location
metadataTypesstring[]optional (default: [])Applicable metadata types

ActionContributionLocation

Allowed Values

  • toolbar
  • contextMenu
  • commandPalette

CommandContribution

Properties

PropertyTypeRequiredDescription
idstring✅Unique command identifier
labelstring✅Command display label
shortcutstringoptionalKeyboard shortcut
iconstringoptionalLucide icon name

MetadataIconContribution

Properties

PropertyTypeRequiredDescription
metadataTypestring✅Metadata type
labelstring✅Display label
iconstring✅Lucide icon name

MetadataViewerContribution

Properties

PropertyTypeRequiredDescription
idstring✅Unique viewer identifier
metadataTypesstring[]✅Metadata types this viewer can handle
labelstring✅Viewer display label
prioritynumberoptional (default: 0)Viewer priority (higher wins)
modesEnum<'preview' | 'design' | 'code' | 'data' | 'history'>[]optional (default: ["preview"])Supported view modes

PanelContribution

Properties

PropertyTypeRequiredDescription
idstring✅Unique panel identifier
labelstring✅Panel display label
iconstringoptionalLucide icon name
locationEnum<'bottom' | 'right' | 'modal'>optional (default: "bottom")Panel location

PanelLocation

Allowed Values

  • bottom
  • right
  • modal

SidebarGroupContribution

Properties

PropertyTypeRequiredDescription
keystring✅Unique group key
labelstring✅Group display label
iconstringoptionalLucide icon name
metadataTypesstring[]✅Metadata types in this group
ordernumberoptional (default: 100)Sort order (lower = higher)

StudioPluginContributions

Properties

PropertyTypeRequiredDescription
metadataViewers{ id: string; metadataTypes: string[]; label: string; priority?: number; … }[]optional (default: [])
sidebarGroups{ key: string; label: string; icon?: string; metadataTypes: string[]; … }[]optional (default: [])
actions{ id: string; label: string; icon?: string; location: Enum<'toolbar' | 'contextMenu' | 'commandPalette'>; … }[]optional (default: [])
metadataIcons{ metadataType: string; label: string; icon: string }[]optional (default: [])
panels{ id: string; label: string; icon?: string; location?: Enum<'bottom' | 'right' | 'modal'> }[]optional (default: [])
commands{ id: string; label: string; shortcut?: string; icon?: string }[]optional (default: [])

Nested Shape: StudioPluginContributions.metadataViewers[number]

PropertyTypeRequiredDescription
idstring✅Unique viewer identifier
metadataTypesstring[]✅Metadata types this viewer can handle
labelstring✅Viewer display label
prioritynumberoptional (default: 0)Viewer priority (higher wins)
modesEnum<'preview' | 'design' | 'code' | 'data' | 'history'>[]optional (default: ["preview"])Supported view modes

Nested Shape: StudioPluginContributions.sidebarGroups[number]

PropertyTypeRequiredDescription
keystring✅Unique group key
labelstring✅Group display label
iconstringoptionalLucide icon name
metadataTypesstring[]✅Metadata types in this group
ordernumberoptional (default: 100)Sort order (lower = higher)

Nested Shape: StudioPluginContributions.actions[number]

PropertyTypeRequiredDescription
idstring✅Unique action identifier
labelstring✅Action display label
iconstringoptionalLucide icon name
locationEnum<'toolbar' | 'contextMenu' | 'commandPalette'>✅UI location
metadataTypesstring[]optional (default: [])Applicable metadata types

Nested Shape: StudioPluginContributions.metadataIcons[number]

PropertyTypeRequiredDescription
metadataTypestring✅Metadata type
labelstring✅Display label
iconstring✅Lucide icon name

Nested Shape: StudioPluginContributions.panels[number]

PropertyTypeRequiredDescription
idstring✅Unique panel identifier
labelstring✅Panel display label
iconstringoptionalLucide icon name
locationEnum<'bottom' | 'right' | 'modal'>optional (default: "bottom")Panel location

Nested Shape: StudioPluginContributions.commands[number]

PropertyTypeRequiredDescription
idstring✅Unique command identifier
labelstring✅Command display label
shortcutstringoptionalKeyboard shortcut
iconstringoptionalLucide icon name

StudioPluginManifest

Properties

PropertyTypeRequiredDescription
idstring✅Plugin ID (dot-separated lowercase)
namestring✅Plugin display name
versionstringoptional (default: "0.0.1")Plugin version
descriptionstringoptionalPlugin description
authorstringoptionalAuthor
contributes{ metadataViewers?: object[]; sidebarGroups?: object[]; actions?: object[]; metadataIcons?: object[]; … }optional (has default)

ViewMode

Allowed Values

  • preview
  • design
  • code
  • data
  • history

On this page