import type { TaskConstructor, TaskDefinition, FlowDefinition } from "@db-lyon/flowkit"; import type { ToolDef } from "../types.js"; import type { PluginEntry } from "../flow/schema.js"; import { type PluginManifest } from "./manifest.js"; import { type InjectionPlan } from "./injection.js"; import { type ProvisionPlan } from "./provision.js"; /** Per-plugin record surfaced to the `plugins` introspection category. */ export interface PluginRecord { name: string; version: string; actionPrefix: string; pkgDir: string; manifestPath: string; minServerVersion?: string; uePluginDependency?: string; /** Final injected action names, by category. */ injected: Record; /** Categories this plugin contributes as new top-level MCP tools. Map * category name -> action names provided. */ provided: Record; /** Knowledge files attached, by category. */ knowledge: Record; /** Plugin-supplied flow names. */ flows: string[]; /** Plugin-supplied task names registered in the flow registry. */ tasks: string[]; /** Validation status: "active" if loaded; anything else means skipped. */ status: "active" | "skipped"; statusReason?: string; } export interface PluginLoadResult { /** Tools with plugin actions merged into target categories. */ tools: ToolDef[]; /** Per-plugin records for introspection. */ records: PluginRecord[]; /** Task constructors to register with the flow registry. */ taskRegistrations: Array<{ name: string; ctor: TaskConstructor; }>; /** Class-path → constructor pairs for explicit registry resolution. */ classPathRegistrations: Array<{ classPath: string; ctor: TaskConstructor; }>; /** Plugin-contributed task definitions to merge into the FlowConfig. */ taskDefs: Record; /** Plugin-contributed flow definitions to merge into the FlowConfig. */ flowDefs: Record; /** Per-category markdown to append to AI-facing docs. */ knowledgeByCategory: Record; } /** * Main plugin loading entry point. Walks the user's `plugins:` array, resolves * each package from node_modules, loads its manifest, validates, dynamically * imports its task classes, and computes injection plans. * * Failures are isolated per-plugin: a broken plugin is skipped with a loud * warning, never partially injected. */ export declare function loadPlugins(tools: ToolDef[], entries: PluginEntry[], projectDir: string | undefined, serverVersion: string): Promise; type TaskReg = { name: string; ctor: TaskConstructor; }; /** * What a native module's handlers surface into. `inject` merges into an * existing built-in category (actions prefixed with `actionPrefix`); `provide` * provisions a new top-level category the plugin owns (actions unprefixed - the * category is the namespace). */ export type NativeHandlerSurface = { kind: "inject"; plan: InjectionPlan; taskRegistrations: TaskReg[]; } | { kind: "provide"; plan: ProvisionPlan; taskRegistrations: TaskReg[]; }; /** * Surface a native module's handlers as MCP actions. Returns null when the * manifest declares no `nativeModule.category` (handlers stay bridge-only). * * When `category` is a built-in (per `builtInCategories`) the result is an * `inject` plan: each handler `h` becomes `(action="_h")`. * Otherwise it's a `provide` plan that owns a new `` tool with * unprefixed actions `(action="h")`. Either way `h` dispatches to the * bare bridge method `h` via a generic BridgeTask, carrying the handler's * `timeoutSeconds`. Pure and disk-free so it can be unit-tested directly. */ export declare function nativeHandlerSurface(manifest: PluginManifest, pluginName: string, builtInCategories: Set): NativeHandlerSurface | null; /** * Duck-type check that a class behaves like a BaseTask subclass. We can't use * `instanceof BaseTask` here because npm 7+ installs peerDependencies into * the consumer's node_modules, giving the plugin its own copy of * `@db-lyon/flowkit` with a distinct BaseTask identity. `instanceof` then * fails across module instances even though the classes are behaviourally * identical. The prototype-chain check is sufficient because the registry * only invokes `.run()` on instances. */ export declare function looksLikeBaseTask(TaskClass: unknown): boolean; export {};