/** * Path validation helpers for `get_skill_file`. * * The skill's directory is treated as a sandbox: callers (via the LLM) name a * relative path inside it. We reject the well-known escape vectors before the * filesystem ever sees the request: * * 1. NUL bytes — `\0` truncates strings in C-level syscalls (bypassing * downstream validation). * 2. Backslash normalisation — Windows-native separators are remapped to * forward slashes before the `..` scan. * 3. Absolute paths — `/foo`, drive-letter prefixes (`C:\foo`), UNC paths * (`\\server\share`). * 4. `..` segments — at any position in the path. * 5. Symlink escape — once joined and `realpath`-resolved, the result must * still live inside the skill directory. Catches symlink swaps that * happen between catalog construction and the actual read. * * Per `knowledge/doc/skills-trust.md` §8. * * Architectural translation: SDK 1.x's `canonicalizePathSync` (from the * filesystem MCP server) doesn't exist in 2.0. The 2.0 equivalent is * `fs.realpathSync` from `node:fs` — same behaviour for the cross-platform * canonicalisation we need here (Windows `subst`, drive case-folding, * symlink resolution). */ export declare class SkillPathError extends Error { readonly reason: 'null_byte' | 'absolute_path' | 'traversal' | 'symlink_escape' | 'not_found' | 'too_large' | 'invalid_path'; constructor(reason: SkillPathError['reason'], message: string); } /** Result of validating + resolving a `get_skill_file` request path. */ export interface ResolvedSkillPath { /** Canonical absolute path safe to read. */ readonly absolute: string; /** Sanitised relative path (POSIX separators, normalised). */ readonly relative: string; } /** * Validate a relative path candidate. Rejects NUL bytes, absolute paths, * and `..` traversal. Returns the normalised POSIX-form relative path. * * This is the parse-time check — symlink resolution is a separate step in * {@link resolveSkillFilePath} because it needs the skill's directory and * filesystem state. */ export declare function validateRelativePath(input: string): string; /** * Resolve a relative path against a skill's directory + verify it cannot * escape via a symlink swap. Re-canonicalises both the skill dir and the * requested file at the moment of resolution — closes the TOCTTOU window * between catalog construction and the actual read. * * Throws {@link SkillPathError} on any rejection. The caller catches and * translates to the MCP `isError: true` envelope. */ export declare function resolveSkillFilePath(skillDir: string, relInput: string): ResolvedSkillPath; //# sourceMappingURL=path.d.ts.map