/** * Building guards from what somebody declared. * * A guard is a first-class thing here, not a task that happens to be named a * certain way. Two sources declare them in the same shape, a plugin manifest * and a project's `ue-mcp.yml`, and both arrive here as `GuardDeclaration` * records that are turned into pipeline guards directly. * * A guard is IMPLEMENTED BY a task, named by `class_path`, but it is not one. * The task registry holds tasks; this holds guards; a name collision between * the two is now impossible rather than load-bearing. */ import type { TaskRegistry } from "@db-lyon/flowkit"; import type { IBridge } from "../bridge.js"; import type { ToolContext } from "../types.js"; import { type BridgeGuard } from "./guard.js"; import type { GuardDeclarations } from "./guard-schema.js"; /** Where a declaration came from, so an error can say which file to open. */ export interface GuardSource { /** `ue-mcp.yml`, or a plugin's name. */ readonly label: string; } export interface BuildGuardsDeps { registry: TaskRegistry; ctx: ToolContext; /** * The bridge a guard's own calls go out on when no session is attached. * * Raw on purpose: a guard that calls the editor must not re-enter the flow * pipeline that is running it. That is a statement about the registry and * not about dialogs, so the per-session path below still puts the dialog * gate back, with no pipeline attached. */ rawBridge: IBridge; } /** * Turn declarations into pipeline guards. * * Every guard is one object with the hooks it declared, so a guard wanting * both sides is one guard that knows it is one, and ordering is a number * rather than something the name could not say. */ export declare function buildGuards(declarations: GuardDeclarations, deps: BuildGuardsDeps, source: GuardSource): Promise; /** * Refuse to start when a task is still named like a guard. * * Before guards were declared, a task with this name WAS a guard. Under the * declaration model nothing discovers it, so it becomes an ordinary task * nobody calls: a source-control write guard would keep appearing in the * config and stop gating anything, silently. * * That is the exact failure the declaration model exists to prevent, so the * migration must not reintroduce it. A leftover name is fatal and says what to * write instead. */ export declare function assertNoLegacyGuardTasks(taskNames: string[], source: GuardSource): void;