import { T as ToolHost } from '../tool-host-BqJRPr_T.js'; import { B as Bridge } from '../types-D_TzdBsK.js'; import '../types-ITRQFAir.js'; type FileKind = "file" | "dir"; type FileEntry = { path: string; name: string; kind: FileKind; size?: number; mtime?: string; hasChildren?: boolean; disabled?: boolean; }; type FileSnapshotNode = FileEntry & { children?: FileSnapshotNode[]; }; /** * Adapter the host provides — getters/setters over the SAME controlled props it * passes to react-fancy's `` (`value`/`path`/`expandedPaths`), plus * `listChildren` (wire to your `provider.loadChildren` or the loaded cache) and, * for snapshot mode, an optional `requestSnapshot`. */ type FilesBridgeAdapter = { /** Current directory (the `path` prop). */ getPath: () => string; setPath: (path: string) => void; /** Selected path(s) — normalize FileBrowser's `value` (string | string[] | null) to an array. */ getSelection: () => string[]; setSelection: (paths: string[]) => void; /** Expanded folder paths (the `expandedPaths` prop). */ getExpanded: () => string[]; setExpanded: (next: string[] | ((prev: string[]) => string[])) => void; /** Direct children of a path — wire to `provider.loadChildren` (async) or the loaded/snapshot cache. */ listChildren: (path: string) => Promise | FileEntry[]; /** Optional (snapshot mode): fetch/refresh a snapshot subtree so an agent can pull remote state on demand. */ requestSnapshot?: (path: string, depth?: number) => Promise | FileSnapshotNode[]; /** * Create a folder. **Supplying this is the opt-in** — `files_create_folder` * is registered only when it is present, so an agent cannot be handed a write * a host never wired, and the advertised tool list tells the truth about what * is possible. * * Pairs with `FileBrowser`'s `onCreateFolder` (react-fancy 5.18+): the same * operation the human has, given to the agent. */ createFolder?: (input: { parentPath: string; name: string; }) => Promise | void; }; type FilesBridgeOptions = { adapter: FilesBridgeAdapter; /** Identity tagged onto agent-driven actions. */ agent?: { id: string; name?: string; color?: string; }; /** * Optional containment root. When set, every agent-supplied path is checked * with {@link assertPathWithinRoot} before it reaches the adapter: a `..` * segment or an absolute path outside `root` is rejected. This is a * fail-closed, string-level guard (no filesystem access — the bridge runs in * the browser). It is NOT sufficient on its own: a host over a real * filesystem MUST additionally resolve symlinks/junctions (realpath) and * enforce the root, because a link under `root` can still point outside it. * When `root` is unset the bridge does no containment and the adapter is * SOLELY responsible for sandboxing what `listChildren`/`requestSnapshot` expose. */ root?: string; /** * Stage writes for human confirmation. Default **true**, matching the * catalog bridge's destructive ops. * * This bridge writes to a filesystem on the strength of a model's output, so * the safe mode is the default and turning it off is the deliberate act. */ pendingMode?: boolean; /** Host confirm hook for staged writes. Resolves true to proceed. */ confirm?: (req: { action: string; path: string; label: string; }) => Promise | boolean; }; /** * Fail-closed, filesystem-free path containment. Throws when `path` contains a * `..` segment, or is absolute and not within `root`. Relative paths without * `..` pass (resolved within root by the host). String-level only — see the * `root` docs: hosts over a real fs must ALSO realpath to defeat symlinks. */ /** * Why a folder NAME cannot be used, or `null`. * * `assertPathWithinRoot` inspects the parent path; the name is appended to it * afterwards, so `{ parentPath: "/root", name: "../.." }` clears that check and * still escapes. A name containing a separator is not a name. */ declare function invalidFolderName(name: string): string | null; declare function assertPathWithinRoot(root: string, path: string): void; /** * registerFilesBridge — an MCP tool set over a react-fancy ``'s * controlled state, so a human and an agent share one file browser. The agent * lists a folder's children, navigates, expands/collapses folders, selects * entries, and (in snapshot mode) requests a fresh subtree — driving the same * `value`/`path`/`expandedPaths` props, no DOM scraping. Every mutation * broadcasts AgentActivity (presence) and pushes an undo entry. Mirrors the * map / whiteboard / flow bridges in shape. * * Read-only browse in v1: no content preview (pair with fancy-code's * FileViewer) and no write ops (rename/delete/upload) — those arrive later * behind a pendingMode-gated iteration. */ declare function registerFilesBridge(host: ToolHost, options: FilesBridgeOptions): Bridge; export { type FilesBridgeAdapter, type FilesBridgeOptions, assertPathWithinRoot, invalidFolderName, registerFilesBridge };