Manifest API Reference
PluginManifest Interface
Section titled “PluginManifest Interface”interface PluginManifest { // Identification slug: string; name: string; version: string; description?: string; author?: string;
// Classification category?: 'productivity' | 'communication' | 'analytics' | 'integration' | 'utility'; tags?: string[];
// Availability businessTypes?: BusinessType[]; premiumTiers?: string[];
// Extensions extensions: ExtensionRegistration[];
// Server Integration serverRouter?: (t: any) => any;
// Lifecycle Hooks handlers?: { onEnable?: () => Promise<void>; onDisable?: () => Promise<void>; onInstall?: () => Promise<void>; onUninstall?: () => Promise<void>; };
// UI Configuration settingsComponent?: React.ComponentType<any>; icon?: React.ComponentType<any>;}Field Descriptions
Section titled “Field Descriptions”Identification Fields
Section titled “Identification Fields”- Type:
string - Required: Yes
- Description: Unique identifier for the plugin (kebab-case)
- Example:
'timer','task-manager','ai-insights'
- Type:
string - Required: Yes
- Description: Display name shown in UI
- Example:
'Time Tracker','Task Manager'
version
Section titled “version”- Type:
string - Required: Yes
- Description: Semantic version number
- Example:
'1.0.0','2.1.3-beta'
description
Section titled “description”- Type:
string - Required: No
- Description: Brief description of plugin functionality
- Example:
'Track time spent on work units and projects'
author
Section titled “author”- Type:
string - Required: No
- Description: Plugin author or organization
- Example:
'Aether Team','john@example.com'
Classification Fields
Section titled “Classification Fields”category
Section titled “category”- Type:
'productivity' | 'communication' | 'analytics' | 'integration' | 'utility' - Required: No
- Description: Primary category for organization
- Example:
'productivity'
- Type:
string[] - Required: No
- Description: Searchable tags for discovery
- Example:
['time-tracking', 'billing', 'reporting']
Availability Fields
Section titled “Availability Fields”businessTypes
Section titled “businessTypes”- Type:
BusinessType[] - Required: No
- Default:
[](all business types) - Description: Which business types can use this plugin
- Example:
['SERVICE', 'PROJECT']or[]for all
premiumTiers
Section titled “premiumTiers”- Type:
string[] - Required: No
- Default:
[](all tiers) - Description: Required premium tier for access
- Example:
['PREMIUM', 'ENTERPRISE']
Extensions
Section titled “Extensions”extensions
Section titled “extensions”- Type:
ExtensionRegistration[] - Required: Yes (can be empty)
- Description: Array of extension registrations
- See: Extension Points Reference
extensions: [ { point: 'work-unit.detail.tabs', plugin: 'my-plugin', priority: 50, match: { businessType: ['SERVICE'] }, extension: { type: ExtensionType.TAB, id: 'my-tab', label: 'My Tab', icon: IconExample, component: MyTabComponent, } }]Server Integration
Section titled “Server Integration”serverRouter
Section titled “serverRouter”- Type:
(t: any) => any - Required: No
- Description: tRPC router factory for plugin API endpoints
- Example:
serverRouter: (t) => t.router({ getData: t.procedure .input(z.object({ id: z.string() })) .query(async ({ input }) => { return await fetchData(input.id); }),
saveData: t.procedure .input(z.object({ id: z.string(), data: z.any() })) .mutation(async ({ input }) => { return await saveData(input.id, input.data); }),})Lifecycle Hooks
Section titled “Lifecycle Hooks”handlers.onEnable
Section titled “handlers.onEnable”- Type:
() => Promise<void> - Required: No
- Description: Called when plugin is enabled by user
- Use Cases: Initialize resources, set up listeners, migrate data
onEnable: async () => { console.log('Plugin enabled'); await initializeDatabase();}handlers.onDisable
Section titled “handlers.onDisable”- Type:
() => Promise<void> - Required: No
- Description: Called when plugin is disabled by user
- Use Cases: Clean up resources, remove listeners, archive data
onDisable: async () => { console.log('Plugin disabled'); await cleanupResources();}handlers.onInstall
Section titled “handlers.onInstall”- Type:
() => Promise<void> - Required: No
- Description: Called once when plugin is first installed
- Use Cases: Run database migrations, create default data
onInstall: async () => { await runMigrations(); await createDefaultSettings();}handlers.onUninstall
Section titled “handlers.onUninstall”- Type:
() => Promise<void> - Required: No
- Description: Called when plugin is uninstalled
- Use Cases: Remove plugin data, clean up database
onUninstall: async () => { await removePluginData();}UI Configuration
Section titled “UI Configuration”settingsComponent
Section titled “settingsComponent”- Type:
React.ComponentType<any> - Required: No
- Description: Custom settings UI component
- Example:
settingsComponent: function PluginSettings({ config, onChange }) { return ( <Stack> <Switch label="Enable notifications" checked={config.notifications} onChange={(e) => onChange({ notifications: e.target.checked })} /> </Stack> );}- Type:
React.ComponentType<any> - Required: No
- Description: Icon component for plugin (from @aether/ui/icons)
- Example:
icon: IconClock
Complete Example
Section titled “Complete Example”import { definePlugin, ExtensionType } from '@aether/plugins-core';import { IconClock } from '@aether/ui/icons';import { TimerTab } from './components/TimerTab';import { timerRouter } from './server/router';
export const timerPlugin = definePlugin({ // Identification slug: 'timer', name: 'Time Tracker', version: '1.2.0', description: 'Track time spent on work units and projects', author: 'Aether Team',
// Classification category: 'productivity', tags: ['time-tracking', 'billing', 'reporting'],
// Availability businessTypes: ['SERVICE', 'PROJECT'], premiumTiers: [],
// Extensions extensions: [ { point: 'work-unit.detail.tabs', plugin: 'timer', priority: 70, match: { businessType: ['SERVICE', 'PROJECT'] }, extension: { type: ExtensionType.TAB, id: 'time-entries', label: 'Time Tracking', icon: IconClock, component: TimerTab, badge: (context) => context?.timeEntryCount } } ],
// Server Integration serverRouter: timerRouter,
// Lifecycle Hooks handlers: { onEnable: async () => { console.log('Timer plugin enabled'); }, onDisable: async () => { console.log('Timer plugin disabled'); }, },
// UI Configuration icon: IconClock,});