/** * Trust gating for canvas extensions. * * Design: `docs/canvas-extensions-design.md` §5. The argument is already written * down in `core/extensions/plugins/trust.ts`, for the same reason: * * > Its skills and commands are text the model reads, which is no worse than * > reading the repository itself, but its **hooks and MCP servers are processes** * > that start on session load. * * A canvas extension is a process **that also opens a listening socket**, so it * belongs in that record on identical grounds and needs no new mechanism. The gate * itself is shared: `isRepositorySupplied` and `shouldWithholdRepositorySupplied` * live in `plugins/trust.ts` and are used by the plugin gate too, so this module * supplies only the roots that are specific to canvas extensions. The record lives * outside the repository, so repository content cannot forge it. * * One difference from plugins, and it matters. `shouldWithholdExecutables` can * withhold a plugin's hooks and MCP servers while still loading its skills, * because a plugin has passive capabilities worth having. **A canvas has none.** * Its declaration, its actions, and its UI all come from running its code. There * is nothing to partially allow, so an untrusted canvas is withheld whole. * * What stays available is discovery: `discovery.ts` only reads directory entries, * so an untrusted canvas can still be listed, named, and offered — the person can * see what is on offer and decide to trust the workspace. Listing is not running. */ import type { DiscoveredCanvasExtension } from "./discovery.js"; /** Thrown when something tries to run a canvas the workspace has not earned. */ export declare class CanvasTrustError extends Error { readonly extensionId: string; constructor(extensionId: string, cwd: string); } /** * Whether an extension sits in the working tree, and therefore arrived with the * repository as far as anyone but its author can tell. * * Every project-scope home counts — see {@link canvasProjectScopeRoots}. None of * them can distinguish "I put this here" from "this arrived in the clone", which * is exactly why location is not the question being asked; it only decides * *whether* to ask about trust. * * User scope (`~/.copilot/extensions/`) is not project-supplied: it is outside any * repository and got there by a deliberate local act. */ export declare function isProjectSuppliedCanvas(extension: DiscoveredCanvasExtension, cwd: string): boolean; /** * Whether an extension must not be forked: it came with the repository and this * machine has not trusted the workspace. */ export declare function shouldWithholdCanvas(extension: DiscoveredCanvasExtension, cwd: string, agentDir?: string): boolean; /** A withheld extension, with the reason, so a caller can explain rather than hide. */ export interface WithheldCanvasExtension { extension: DiscoveredCanvasExtension; reason: "untrusted-workspace"; } /** Discovered extensions split into what may be forked and what may not. */ export interface GatedCanvasExtensions { runnable: DiscoveredCanvasExtension[]; withheld: WithheldCanvasExtension[]; } /** * Partition discovered extensions by trust. * * Callers should present `withheld` rather than dropping it: the point of the gate * is that the person can see a repository offers a canvas and choose, not that the * offer disappears. */ export declare function gateCanvasExtensions(extensions: DiscoveredCanvasExtension[], cwd: string, agentDir?: string): GatedCanvasExtensions; //# sourceMappingURL=trust.d.ts.map