293 lines
7.6 KiB
TypeScript
293 lines
7.6 KiB
TypeScript
/**
|
|
* Color group with five container variants and an OnContainer text color.
|
|
*/
|
|
export interface ThemeColorGroup {
|
|
container: string;
|
|
containerHover: string;
|
|
containerActive: string;
|
|
containerLine: string;
|
|
onContainer: string;
|
|
}
|
|
|
|
/**
|
|
* Color group for interactive palette entries (Main + Container sub-groups).
|
|
*/
|
|
export interface ThemePaletteGroup {
|
|
main: string;
|
|
mainHover: string;
|
|
mainActive: string;
|
|
mainLine: string;
|
|
onMain: string;
|
|
container: string;
|
|
containerHover: string;
|
|
containerActive: string;
|
|
containerLine: string;
|
|
onContainer: string;
|
|
}
|
|
|
|
/**
|
|
* Full color token set for a plugin theme.
|
|
* Property names map directly to the folds design-token contract.
|
|
*/
|
|
export interface PluginThemeColors {
|
|
background: ThemeColorGroup;
|
|
surface: ThemeColorGroup;
|
|
surfaceVariant: ThemeColorGroup;
|
|
primary: ThemePaletteGroup;
|
|
secondary: ThemePaletteGroup;
|
|
success: ThemePaletteGroup;
|
|
warning: ThemePaletteGroup;
|
|
critical: ThemePaletteGroup;
|
|
other: {
|
|
focusRing: string;
|
|
shadow: string;
|
|
overlay: string;
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Theme definition supplied by a plugin.
|
|
*/
|
|
export interface PluginTheme {
|
|
id: string;
|
|
name: string;
|
|
kind: 'light' | 'dark';
|
|
colors: PluginThemeColors;
|
|
/** Optional extra CSS injected alongside the theme variables. */
|
|
extraCss?: string;
|
|
}
|
|
|
|
/**
|
|
* A command argument definition.
|
|
*/
|
|
export interface CommandArg {
|
|
name: string;
|
|
type?: 'string' | 'number' | 'boolean';
|
|
required?: boolean;
|
|
description?: string;
|
|
}
|
|
|
|
/**
|
|
* A command registered by a plugin.
|
|
*/
|
|
export interface PluginCommand {
|
|
name: string;
|
|
description?: string;
|
|
args?: string[] | CommandArg[];
|
|
run: (args: Record<string, unknown>, ctx: PluginContext) => string | void | Promise<string | void>;
|
|
}
|
|
|
|
/** Callback invoked for outgoing or incoming messages. */
|
|
export type MessageInterceptor = (msg: MessageContext) => void | Promise<void>;
|
|
|
|
/**
|
|
* Message context passed to interceptors.
|
|
*/
|
|
export interface MessageContext {
|
|
content: string;
|
|
roomId: string;
|
|
eventType: string;
|
|
formatted?: string;
|
|
metadata?: Record<string, unknown>;
|
|
}
|
|
|
|
/**
|
|
* Custom renderer function.
|
|
* The return type is `unknown` so the package stays framework-agnostic.
|
|
* Hosts using React should cast to `ReactNode` at the call-site.
|
|
*/
|
|
export type CustomRenderer = (data: unknown, defaultRenderer?: () => unknown) => unknown;
|
|
|
|
/**
|
|
* A single setting definition within a plugin's settings schema.
|
|
*/
|
|
export interface SettingDefinition {
|
|
type: 'string' | 'number' | 'boolean' | 'select' | 'color';
|
|
label?: string;
|
|
description?: string;
|
|
default?: unknown;
|
|
options?: Array<{ value: unknown; label: string }>;
|
|
}
|
|
|
|
/** The full settings schema for a plugin. */
|
|
export type SettingsSchema = Record<string, SettingDefinition>;
|
|
|
|
/**
|
|
* Options for a notification emitted by a plugin.
|
|
*/
|
|
export interface NotificationOptions {
|
|
title: string;
|
|
body: string;
|
|
type?: 'info' | 'success' | 'error' | 'warning';
|
|
duration?: number;
|
|
actions?: Array<{ label: string; action: () => void }>;
|
|
}
|
|
|
|
/**
|
|
* The context provided to plugins when they are initialized.
|
|
* All APIs are available through this object.
|
|
*/
|
|
export interface PluginContext {
|
|
/** Plugin ID */
|
|
pluginId: string;
|
|
|
|
/** Commands API */
|
|
commands: {
|
|
register: (command: PluginCommand) => void;
|
|
unregister: (name: string) => void;
|
|
execute: (name: string, args: Record<string, unknown>) => Promise<string | void>;
|
|
};
|
|
|
|
/** Messages API */
|
|
messages: {
|
|
onBeforeSend: (interceptor: MessageInterceptor) => void;
|
|
onReceive: (interceptor: MessageInterceptor) => void;
|
|
};
|
|
|
|
/** UI API — framework-agnostic renderer registry */
|
|
ui: {
|
|
registerRenderer: (type: string, renderer: CustomRenderer) => void;
|
|
unregisterRenderer: (type: string) => void;
|
|
registerButton: (button: UIButtonDefinition) => void;
|
|
unregisterButton: (buttonId: string) => void;
|
|
};
|
|
|
|
/** Settings API */
|
|
settings: {
|
|
define: (schema: SettingsSchema) => void;
|
|
get: <T = unknown>(key: string) => T | undefined;
|
|
set: (key: string, value: unknown) => void;
|
|
};
|
|
|
|
/** Themes API */
|
|
themes: {
|
|
register: (theme: PluginTheme) => void;
|
|
unregister: (themeId: string) => void;
|
|
};
|
|
|
|
/**
|
|
* Generic event emitter API.
|
|
* Wire up any event client (Matrix, socket.io, Node EventEmitter, etc.)
|
|
* via the `eventClient` option passed to `createPluginContext`.
|
|
*/
|
|
events: {
|
|
on: (eventType: string, handler: (...args: any[]) => void) => void;
|
|
off: (eventType: string, handler: (...args: any[]) => void) => void;
|
|
};
|
|
|
|
/** Background tasks API */
|
|
timers: {
|
|
setInterval: (callback: () => void, ms: number) => number;
|
|
setTimeout: (callback: () => void, ms: number) => number;
|
|
clearInterval: (id: number) => void;
|
|
clearTimeout: (id: number) => void;
|
|
};
|
|
|
|
/** Send a notification through the host application. */
|
|
notify: (options: NotificationOptions | string) => void | Promise<void>;
|
|
|
|
/** Logging API */
|
|
log: (...args: any[]) => void;
|
|
warn: (...args: any[]) => void;
|
|
error: (...args: any[]) => void;
|
|
|
|
/** Require another loaded plugin's exports. */
|
|
require: (pluginId: string) => unknown;
|
|
}
|
|
|
|
/**
|
|
* Custom settings section that a plugin can inject into the settings UI.
|
|
* The `component` value is `unknown` to remain framework-agnostic.
|
|
* Hosts using React should treat it as `ReactNode`.
|
|
*/
|
|
export interface PluginSettingsSection {
|
|
id: string;
|
|
name: string;
|
|
icon?: string;
|
|
component: unknown;
|
|
}
|
|
|
|
/** UI locations where plugins can inject content. */
|
|
export type UILocation =
|
|
| 'room-header'
|
|
| 'message-actions'
|
|
| 'user-menu'
|
|
| 'room-menu'
|
|
| 'composer-actions'
|
|
| 'channel-list'
|
|
| 'direct-messages'
|
|
| 'home-section'
|
|
| 'search-notification-section'
|
|
| 'text-composer-toolbar'
|
|
| 'sidebar-actions';
|
|
|
|
/**
|
|
* Button positioning configuration for plugins.
|
|
* Allows buttons to be placed before or after existing elements or groups.
|
|
*/
|
|
export interface UIButtonPosition {
|
|
/** Place button before this element/group ID */
|
|
before?: string;
|
|
/** Place button after this element/group ID */
|
|
after?: string;
|
|
/**
|
|
* Optional group ID this button belongs to.
|
|
* Buttons in the same group are rendered together.
|
|
*/
|
|
group?: string;
|
|
/** Order within the group (lower numbers appear first) */
|
|
order?: number;
|
|
}
|
|
|
|
/**
|
|
* Definition for a UI button registered by a plugin.
|
|
* Framework-agnostic - the component/element is passed as unknown.
|
|
*/
|
|
export interface UIButtonDefinition {
|
|
/** Unique ID for this button */
|
|
id: string;
|
|
/** Location where the button should appear */
|
|
location: UILocation;
|
|
/** Button label or tooltip */
|
|
label: string;
|
|
/** Optional icon identifier */
|
|
icon?: string;
|
|
/** Positioning configuration */
|
|
position?: UIButtonPosition;
|
|
/**
|
|
* The actual button component or render function.
|
|
* Framework-agnostic - hosts using React should cast to ReactNode.
|
|
*/
|
|
component: unknown;
|
|
/** Optional callback when clicked (if component doesn't handle it) */
|
|
onClick?: () => void | Promise<void>;
|
|
}
|
|
|
|
/**
|
|
* The main plugin interface that all plugins must implement.
|
|
*/
|
|
export interface Plugin {
|
|
name?: string;
|
|
version?: string;
|
|
dependencies?: Record<string, string>;
|
|
|
|
/** Called when the plugin is loaded. */
|
|
onLoad: (context: PluginContext) => void | Promise<void>;
|
|
|
|
/** Called when the plugin is unloaded or disabled. */
|
|
onUnload?: () => void | Promise<void>;
|
|
|
|
/** Exposed API surface for other plugins to consume via `context.require()`. */
|
|
exports?: unknown;
|
|
}
|
|
|
|
/**
|
|
* A single log entry produced by a plugin.
|
|
*/
|
|
export interface PluginLogEntry {
|
|
pluginId: string;
|
|
level: 'log' | 'warn' | 'error';
|
|
timestamp: number;
|
|
args: unknown[];
|
|
}
|