Skip to content

Extension Manifest

Each installed extension must have a manifest.json in its directory under userData/extensions/<id>/.

json
{
  "id": "acme.my-extension",
  "name": "My Extension",
  "version": "1.0.0",
  "description": "Does something useful.",
  "author": "Acme Corp",
  "entryPoint": "/absolute/path/to/userData/extensions/acme.my-extension/dist/index.js"
}

The extension's JS bundle then calls window.__openConduit.extensionRegistry.registerExtension() to declare its contributions at runtime:

ts
window.__openConduit.extensionRegistry.registerExtension(
  { id: 'acme.my-extension', name: 'My Extension', version: '1.0.0' },
  {
    activityBarItems: [ /* ... */ ],
  }
);

manifest.json Fields

FieldTypeRequiredDescription
idstringUnique extension identifier. Reverse-domain style recommended (acme.my-ext).
namestringDisplay name
versionstringSemVer version
entryPointstringAbsolute path to the JS bundle read by the preload bridge
descriptionstringShort description
authorstringAuthor name or org
permissionsstring[]Permission strings required by write-access API methods. See Extension API → Permissions.
activate(api: ExtensionAPI) => void | Promise<void>Lifecycle hook called once after all contributions are registered. Receives the Extension API.

registerExtensionExtensionManifest

The first argument to registerExtension mirrors the on-disk manifest (without entryPoint):

ts
interface ExtensionManifest {
  id: string;
  name: string;
  version: string;
  description?: string;
  author?: string;
  contributes?: {
    activityBarItems?: ActivityBarContribution[];
    commands?: CommandContribution[];
    slashCommands?: SlashCommand[];
    settingsTab?: SettingsContribution;
    bottomPanelTabs?: BottomPanelTab[];
    tools?: ToolContribution[];
    mainViews?: MainViewContribution[];
    splitPaneViews?: SplitPaneViewContribution[];
    secondarySidebarPanels?: SecondarySidebarPanelContribution[];
    statusBarItems?: StatusBarItemContribution[];
    stores?: StoreSliceContribution[];
    messageBadges?: MessageBadgeContribution[];
    conversationModes?: ConversationModeContribution[];
  };
  permissions?: string[];
  activate?: (api: ExtensionAPI) => void | Promise<void>;
}

Contribution Points

KeyDocs
activityBarItemsActivity Bar Contributions
commandsCommand Contributions
slashCommandsSlash Commands
settingsTabSettings Contributions
bottomPanelTabsBottom Panel Contributions
toolsTool Contributions
mainViewsView Contributions → Main Views
splitPaneViewsView Contributions → Split Pane Views
secondarySidebarPanelsView Contributions → Secondary Sidebar Panels
statusBarItemsStatus Bar Contributions
storesStore Slice Contributions
messageBadgesMessage Badge Contributions
conversationModesConversation Mode Contributions
hooksExtension API

activate(api)

The activate function is called once after all contributions are registered. Use it to interact with the host application via the ExtensionAPI.

ts
window.__openConduit.extensionRegistry.registerExtension(
  {
    id: 'acme.my-extension',
    name: 'My Extension',
    version: '1.0.0',
    permissions: ['conversations.write'],
    activate(api) {
      api.ui.showNotification({ message: 'My Extension activated!' });
    },
  },
  { /* contributions */ },
);

See Extension API for the full method reference.

Released under the AGPLv3 License.