Plugin SDK Reference
All adapter interfaces from @omnilux/plugin-sdk. Plugins register adapters via context.registerAdapter(type, id, adapter).
DownloadClientAdapter
Integrates with download client services.
typescript
interface DownloadClientAdapter {
testConnection(config: DownloadClientConfig): Promise<ConnectionTestResult>;
addDownload(config: DownloadClientConfig, params: AddDownloadParams): Promise<Download>;
getDownloads(config: DownloadClientConfig, filter?: DownloadFilter): Promise<Download[]>;
getDownload(config: DownloadClientConfig, downloadId: string): Promise<Download | null>;
pauseDownload(config: DownloadClientConfig, downloadId: string): Promise<void>;
resumeDownload(config: DownloadClientConfig, downloadId: string): Promise<void>;
removeDownload(
config: DownloadClientConfig,
downloadId: string,
options?: { deleteData?: boolean },
): Promise<void>;
getStats(config: DownloadClientConfig): Promise<DownloadClientStats>;
setSpeedLimits(
config: DownloadClientConfig,
downloadId: string,
limits: {
downloadBytesPerSecond?: number | null;
uploadBytesPerSecond?: number | null;
},
): Promise<void>;
getLabels(config: DownloadClientConfig): Promise<string[]>;
setLabel(
config: DownloadClientConfig,
downloadId: string,
label: string | null,
): Promise<void>;
}Key types
typescript
interface DownloadClientConfig {
id?: string | number;
name?: string;
type: string;
baseUrl?: string;
apiKey?: string;
username?: string;
password?: string;
enabled?: boolean;
defaultCategory?: string;
defaultSavePath?: string;
defaultLabels?: string[];
}
interface AddDownloadParams {
source: string;
sourceType?: 'magnet' | 'torrent' | 'nzb' | 'url' | 'file';
title?: string;
category?: string;
savePath?: string;
paused?: boolean;
priority?: number;
labels?: string[];
}
interface Download {
id: string;
name: string;
state: string;
progress: number;
etaSeconds?: number;
sizeBytes?: number;
downloadedBytes?: number;
uploadedBytes?: number;
downloadRateBytesPerSecond?: number;
uploadRateBytesPerSecond?: number;
ratio?: number;
savePath?: string;
category?: string;
labels?: string[];
}IndexerAdapter
Integrates with search indexers and content sources.
typescript
interface IndexerAdapter {
testConnection(config: IndexerConfig): Promise<ConnectionTestResult>;
search(config: IndexerConfig, query: SearchQuery): Promise<SearchResult[]>;
getRssItems(
config: IndexerConfig,
options?: { categories?: string[]; limit?: number },
): Promise<SearchResult[]>;
}Key types
typescript
interface SearchQuery {
text: string;
mediaType?: string;
categories?: string[];
seasonNumber?: number;
episodeNumber?: number;
year?: number;
imdbId?: string;
tmdbId?: number;
tvdbId?: number;
limit?: number;
offset?: number;
}
interface SearchResult {
id: string;
title: string;
guid?: string;
protocol?: 'torrent' | 'nzb' | 'http' | string;
downloadUrl?: string;
sizeBytes?: number;
seeders?: number;
peers?: number;
ageHours?: number;
quality?: string;
mediaType?: string;
categories?: string[];
indexerName?: string;
score?: number;
}VpnAdapter
Manages VPN connections (WireGuard, SOCKS5).
typescript
interface VpnAdapter {
connect(config: VpnConfig): Promise<VpnStatus>;
disconnect(config?: VpnConfig): Promise<VpnStatus>;
getStatus(config?: VpnConfig): Promise<VpnStatus>;
enableKillSwitch(config: VpnConfig, rules?: KillSwitchRules): Promise<void>;
disableKillSwitch(config?: VpnConfig): Promise<void>;
getPublicIp(config?: VpnConfig): Promise<string | null>;
}Key types
typescript
interface VpnConfig {
provider?: string;
connectionMode?: 'wireguard' | 'openvpn' | 'socks5' | 'custom' | string;
endpoint?: string;
username?: string;
password?: string;
enabled?: boolean;
killSwitchEnabled?: boolean;
}
interface VpnStatus {
state: 'disconnected' | 'connecting' | 'connected' | 'error';
publicIp?: string;
connectedAt?: string;
provider?: string;
connectionMode?: string;
killSwitchEnabled?: boolean;
}ScannerAdapter
File scanning (antivirus, malware detection).
typescript
interface ScannerAdapter {
scanFile(config: ScannerConfig, filePath: string): Promise<ScanResult>;
scanDirectory(
config: ScannerConfig,
directoryPath: string,
options?: { recursive?: boolean; include?: string[]; exclude?: string[] },
): Promise<ScanResult[]>;
updateDefinitions(config?: ScannerConfig): Promise<void>;
getStatus(config?: ScannerConfig): Promise<ScannerStatus>;
}Key types
typescript
interface ScanResult {
path: string;
verdict: 'clean' | 'infected' | 'error' | 'skipped';
threat?: string;
error?: string;
durationMs: number;
}
interface ScannerStatus {
ready: boolean;
enabled: boolean;
engine?: string;
lastUpdatedAt?: string;
message?: string;
}SearchAdapter
Search pipeline: release scoring, auto-grab, RSS sync.
typescript
interface SearchAdapter {
scoreRelease(input: ReleaseScoreInput): Promise<ReleaseScoreResult>;
autoGrab(input: AutoGrabParams): Promise<AutoGrabResult>;
runRssSync(input?: {
dryRun?: boolean;
limit?: number;
}): Promise<RssSyncResult>;
runWantedSearch(input?: WantedSearchParams): Promise<WantedSearchResult>;
}Key types
typescript
interface ReleaseScoreInput {
release: SearchResult;
requestId?: string | number;
qualityProfileId?: string | number;
}
interface ReleaseScoreResult {
score: number;
accepted: boolean;
reasons?: string[];
}
interface AutoGrabResult {
grabbed: boolean;
release?: SearchResult;
reason?: string;
}IptvSourceAdapter
IPTV channel source integration.
typescript
interface IptvSourceAdapter {
importM3u(config: IptvSourceConfig, source: string): Promise<IptvImportResult>;
browseCatalog(
config: IptvSourceConfig,
query?: IptvCatalogQuery,
): Promise<IptvCatalogItem[]>;
importChannel(
config: IptvSourceConfig,
channelId: string,
): Promise<IptvCatalogItem | null>;
refreshEpg(config: IptvSourceConfig): Promise<void>;
}GameSourceAdapter
Game download source integration.
typescript
interface GameSourceAdapter {
getSources(config?: GameSourceConfig): Promise<GameSourceRecord[]>;
checkAvailability(
config: GameSourceConfig,
sourceId: string,
): Promise<GameAvailability>;
bulkImport(
config: GameSourceConfig,
sourceIds: string[],
): Promise<BulkImportResult>;
}NotificationAgentAdapter
Notification delivery (Discord, Telegram, email, etc.).
typescript
interface NotificationAgentAdapter {
send(
config: NotificationAgentConfig,
payload: NotificationPayload,
): Promise<void>;
testConnection(
config: NotificationAgentConfig,
): Promise<ConnectionTestResult>;
getCapabilities(
config?: NotificationAgentConfig,
): Promise<NotificationAgentCapabilities>;
}Key types
typescript
interface NotificationPayload {
eventType?: string;
title?: string;
message?: string;
mediaType?: string;
mediaTitle?: string;
imageUrl?: string;
}
interface NotificationAgentCapabilities {
supportedEvents?: string[];
supportsRichText?: boolean;
supportsAttachments?: boolean;
supportsImages?: boolean;
}MetadataProviderAdapter
Metadata lookups (TMDB, TVDB, MusicBrainz, IGDB).
typescript
interface MetadataProviderAdapter {
search(
config: MetadataProviderConfig,
query: MetadataSearchQuery,
): Promise<MetadataRecord[]>;
getMetadata(
config: MetadataProviderConfig,
metadataId: string,
): Promise<MetadataRecord | null>;
getImages(
config: MetadataProviderConfig,
metadataId: string,
): Promise<MetadataImage[]>;
}Key types
typescript
interface MetadataRecord {
id: string;
provider: string;
mediaType?: string;
title: string;
originalTitle?: string;
overview?: string;
year?: number;
releaseDate?: string;
posterUrl?: string;
backdropUrl?: string;
genres?: string[];
}
interface MetadataImage {
url: string;
type: 'poster' | 'backdrop' | 'banner' | 'logo' | 'thumb' | string;
language?: string;
width?: number;
height?: number;
}Shared types
typescript
interface ConnectionTestResult {
ok: boolean;
message: string;
latencyMs?: number;
details?: Record<string, unknown>;
}PluginContext
Every plugin receives a PluginContext instance:
typescript
interface PluginContext {
pluginId: string;
pluginVersion: string;
registerAdapter<T>(type: string, id: string, adapter: T): void;
getAdapter<T>(type: string, id: string): T | undefined;
getAdaptersOfType<T>(type: string): T[];
registerRoutes(routes: PluginRouteDefinition[]): void;
registerJob(job: PluginJobRegistration): void;
registerSettingsPanel(panel: PluginSettingsPanelRegistration): void;
db: PluginDatabase;
settings: PluginSettings;
on<T>(event: string, listener: (payload: T) => void | Promise<void>): () => void;
emit<T>(event: string, payload: T): void | Promise<void>;
log: PluginLogger;
core: PluginCoreApi;
}