Skip to main content

Plugin Ecosystem

GospeLib is built on a plugin architecture that makes the platform extensible by both the core team and the community. Every major feature -- interlinear display, AI assistant, commentary browser, journal -- is implemented as a plugin that registers capabilities through a typed manifest.

Overview

The plugin system provides:

  • 14 contribution types that plugins can register (pane types, sidebar widgets, toolbar actions, hover card tabs, gutter markers, context menu items, Study Map node renderers, and more)
  • 10 core plugins that ship with the platform
  • QuickJS WASM sandbox for safe execution of community plugins
  • Plugin Registry service for manifest submission, discovery, and versioning
  • Subscription gating so premium plugins can be tied to plan tiers

Core Plugins

These plugins ship with every GospeLib installation:

PluginDescriptionStatus
core.readerScripture reading pane with all reader featuresShipped
core.interlinearInline interlinear rows (original script, transliteration, gloss, morphology)Built, integration pending
core.witnessesManuscript witness comparison with inline diff cardsELIMINATED -- witness concept removed; manuscripts are editions
core.aiAI study assistant sidebar widget and paneBuilt, integration pending
core.commentaryCommentary browser panel and hover card tabBuilt, integration pending
core.journalChronological activity log with calendar heatmapBuilt, integration pending
core.notesRich-text note editing with TiptapPartial
core.annotationsHighlight, bookmark, and note managementShipped
core.teachLesson outline workspace (future)Stub only
core.liveshareReal-time collaborative study (future)Not started

Plugin Manifest

Each plugin declares its capabilities through a typed manifest:

interface PluginManifest {
id: string; // e.g., "core.interlinear"
name: string; // Human-readable name
version: string; // SemVer
description: string;
author: string;
permissions: string[]; // Required entitlements
contributions: {
paneTypes?: PaneTypeContrib[];
sidebarWidgets?: WidgetContrib[];
toolbarActions?: ToolbarContrib[];
hoverCardTabs?: HoverTabContrib[];
gutterMarkers?: GutterContrib[];
contextMenuItems?: MenuContrib[];
studyMapRenderers?: MapRendererContrib[];
// ... 7 more contribution types
};
}

The manifest is validated at registration time by the Plugin Registry service, which stores manifests in PostgreSQL and serves them to the web app at startup.

How Plugins Work

Registration

When the web app initializes, it loads all enabled plugin manifests and registers their contributions with the appropriate UI containers:

  1. Pane types become available in the Pane Quick Picker (+ button in pane group tab bar)
  2. Sidebar widgets appear in the left or right dock zones
  3. Toolbar actions are added to the vertical toolbar and horizontal toolbar
  4. Hover card tabs appear in the Layer 2 detail panel

Execution

Core plugins run in the main thread with full access to the application's React context, stores, and hooks. Community plugins run in a QuickJS WASM sandbox with a controlled API surface -- they can read passage data and emit events but cannot access the DOM directly.

Subscription Gating

Each plugin can declare required entitlements in its manifest. The plugin loader checks the user's plan tier before enabling a plugin. Premium plugins show a diamond indicator and a warm unlock prompt when a free-tier user encounters them.

Deep Dive: Plugin Registry Service

The Plugin Registry is a Python/FastAPI service at services/plugin-registry/ that manages the lifecycle of community plugins:

  • Submission -- Plugin authors submit manifests with metadata and a WASM bundle
  • Review -- Manifests are validated for security (no forbidden API calls, size limits)
  • Discovery -- Users browse available plugins filtered by category, rating, and compatibility
  • Versioning -- Multiple versions can coexist; the app loads the latest compatible version

The registry runs on port 8500 and stores data in PostgreSQL.