Reference
Plugin API
TypeScript interface reference for building plugins.
FlowlibPlugin
interface FlowlibPlugin {
id: string;
name?: string;
// Lifecycle
init?: (ctx: FlowlibPluginContext) => Promise<FlowlibPluginInitResult | void>;
shutdown?: () => Promise<void> | void;
// Extensions
actions?: ActionDefinition[];
schema?: FlowlibPluginSchema;
requiredTables?: string[];
endpoints?: FlowlibPluginEndpoint[];
hooks?: FlowlibPluginHooks;
// Metadata
setupInstructions?: string;
$ERROR_CODES?: Record<string, { message: string; statusCode: number }>;
}FlowlibPluginContext
Passed to init():
interface FlowlibPluginContext {
db: DatabaseConnection;
dbType: DatabaseType;
logger: Logger;
registerTool: (def: AgentToolDefinition, executor: AgentToolExecutor) => void;
config: FlowlibConfig;
}FlowlibPluginHooks
interface FlowlibPluginHooks {
beforeFlowRun?: (ctx: FlowRunHookContext) => Promise<{ cancel?: boolean; inputs?: any } | void>;
afterFlowRun?: (ctx: FlowRunHookContext) => Promise<void>;
beforeNodeExecute?: (
ctx: NodeExecuteHookContext,
) => Promise<{ skip?: boolean; params?: any } | void>;
afterNodeExecute?: (ctx: NodeExecuteHookContext) => Promise<{ output?: any } | void>;
onRequest?: (ctx: RequestHookContext) => Promise<{ response?: any; request?: any } | void>;
onResponse?: (ctx: ResponseHookContext) => Promise<{ response?: any } | void>;
onAuthorize?: (ctx: AuthorizeHookContext) => Promise<{ allowed?: boolean } | void>;
}Hook behaviour
| Hook | Can short-circuit? | Return to modify |
|---|---|---|
beforeFlowRun | Yes ({ cancel: true }) | { inputs } to modify inputs |
afterFlowRun | No | — |
beforeNodeExecute | Yes ({ skip: true }) | { params } to override |
afterNodeExecute | No | { output } to override |
onRequest | Yes ({ response }) | { request } to modify |
onResponse | No | { response } to replace |
onAuthorize | Yes ({ allowed: false }) | { allowed: true } to allow |
FlowlibPluginEndpoint
interface FlowlibPluginEndpoint {
method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
path: string;
handler: (context: PluginEndpointContext) => Promise<PluginEndpointResponse>;
permission?: FlowlibPermission;
isPublic?: boolean;
}Endpoints are mounted at /plugins/{pluginId}{path}.
PluginEndpointContext
interface PluginEndpointContext {
body: Record<string, unknown>;
params: Record<string, string>;
query: Record<string, string | undefined>;
headers: Record<string, string | undefined>;
identity: FlowlibIdentity | null;
database: PluginDatabaseApi;
request: Request;
core: PluginEndpointCoreApi;
getFlowlib: () => FlowlibInstance;
}PluginEndpointResponse
type PluginEndpointResponse =
| { status?: number; body: unknown } // JSON response
| { status?: number; stream: ReadableStream } // Streaming response
| Response; // Raw Web API ResponseFlowlibPluginSchema
type FlowlibPluginSchema = Record<
string,
{
fields: Record<
string,
{
type: 'string' | 'number' | 'boolean' | 'text' | 'json';
primaryKey?: boolean;
required?: boolean;
unique?: boolean;
default?: any;
references?: { table: string; field: string };
}
>;
}
>;FlowlibFrontendPlugin
interface FlowlibFrontendPlugin {
id: string;
name?: string;
sidebar?: PluginSidebarContribution[];
routes?: PluginRouteContribution[];
panelTabs?: PluginPanelTabContribution[];
headerActions?: PluginHeaderActionContribution[];
components?: Record<string, ComponentType>;
providers?: ComponentType<{ children: ReactNode }>[];
apiHeaders?: () => Record<string, string>;
checkPermission?: (permission: string, ctx?: any) => boolean | undefined;
}