Flowlib
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

HookCan short-circuit?Return to modify
beforeFlowRunYes ({ cancel: true }){ inputs } to modify inputs
afterFlowRunNo
beforeNodeExecuteYes ({ skip: true }){ params } to override
afterNodeExecuteNo{ output } to override
onRequestYes ({ response }){ request } to modify
onResponseNo{ response } to replace
onAuthorizeYes ({ 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 Response

FlowlibPluginSchema

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;
}

On this page