UNPKG

@struktoai/mirage-core

Version:

A Unified Virtual Filesystem For AI Agents

117 lines • 7.08 kB
import type { LinkView, ReaddirPath, StatPath } from '../../../view/types.ts'; import type { Files } from '../../../workspace/files.ts'; import type { DispatchFn } from '../../../runtime/types.ts'; import { FileStat, PathSpec, type StatFn } from '../../../types.ts'; import { type FsError } from '../../../errors/types.ts'; import type { FlagValue } from '../../spec/types.ts'; import type { FsCondition } from '../../../errors/types.ts'; /** * Opt in by assigning a debug sink, as Python's module logger is off until * configured: every failed read runs the probe, and stdout may carry data. */ export declare const logger: { debug?: (message: string) => void; }; export declare function resolvePathStat(dispatch: DispatchFn, path: PathSpec): Promise<FileStat | null>; export declare function dispatchStat(dispatch: DispatchFn): StatFn; export declare function vfsStatPath(files: Files | undefined): StatPath | undefined; export declare function vfsReaddirPath(files: Files | undefined): ReaddirPath | undefined; export declare function statOrEnoent(statPath: StatPath): StatFn; /** * `path` keyed by its whole virtual path, the shape a command's paths take: * the dispatcher routes each one to its mount, so no command derives a mount * from a path's key. Mirrors Python's virtual_key. */ export declare function virtualKey(path: PathSpec): PathSpec; /** * A command's flags with every path value keyed by its whole virtual path * (`virtualKey`): a single path (awk -f) or a list of them (repeated grep -f). * Everything else passes through unchanged. Mirrors Python's virtual_flags. */ export declare function virtualFlags(bag: Record<string, FlagValue>): Record<string, FlagValue>; export declare function spelledFrom(path: PathSpec, operand: PathSpec): PathSpec; export declare function descendantPath(root: PathSpec, virtual: string): PathSpec; export declare function entryKind(stat: StatFn, path: PathSpec): Promise<{ exists: boolean; isDir: boolean; }>; export declare function nearestAncestor(stat: StatFn, path: PathSpec): Promise<[string, boolean]>; export declare function isImplicitDir(readdir: (path: PathSpec) => Promise<string[]>, path: PathSpec): Promise<boolean>; /** * Whether a failed or empty read was a read of a directory. * * Asked after failure or EOF without bytes: some drivers return an empty * stream for directories. Nonempty reads need no extra probe. One that knows * says so (gdrive, box, dropbox and disk throw EISDIR), a keyed store answers * ENOENT because a directory there is a set of keys rather than an object, * and sftp answers with an error carrying no errno at all. * * Three ways the answer can be yes, in probe-cost order. The code itself * costs nothing. The stat is one call, and a stat that ANSWERS ends the * cascade either way: a file is a file, and the later probe only makes * sense for a path stat could not see. Reaching past a successful stat * read a rule-refused file as a directory, because its parent's listing * names it. The parent listing is one call and is the only thing that can * tell a missing key from a prefix that exists only through deeper keys. * * A no leaves the original error untouched, so nothing is swallowed: the * caller rethrows what the backend said. Both probes are broad for that * same reason: a probe that fails is a negative probe, never an error to * surface. Surfacing one would replace the read's error with one from a * call the user never made, and it is the read that failed. * `isImplicitDir` narrows to a miss because for its other caller the stat * IS the operation; here it is a probe, so the wider catch belongs on this * side of the call, and each failure it absorbs is logged. Mirrors Python's * `read_hit_a_dir`. */ export declare function readHitADir(stat: (path: PathSpec) => Promise<FileStat>, readdir: (path: PathSpec) => Promise<string[]>, path: PathSpec, err: unknown): Promise<boolean>; export declare function absentDestError(stat: StatFn, target: PathSpec): Promise<FsCondition | null>; export declare function linkFollow(links: LinkView | null | undefined): ((path: string) => string) | null; export declare function linkTarget(links: LinkView | null | undefined): ((path: string) => string | null) | null; /** * The typed spelling, links before `..`, while it names the path. Mirrors * Python's walk_spelling. * * Without a trailing slash: that is a final `.`, which `dotRefusal` proves, * and a store that keeps no directories reads a slashed key as one, so * `cat reg/` there was ENOENT, not ENOTDIR. */ export declare function walkSpelling(path: PathSpec, follow: ((path: string) => string) | null): string; /** * ENOENT when the walk of a path's dots looks up a name the session cannot * see, null when it sees every one. * * `virtual` simplified the dots away, so a hidden name in front of one * (`secret/../f`, a hidden link's `lnk/../f`) is gone from the path the * hides judge, while the walk still has to find it. It answers as a missing * name does, and before `dotRefusal` proves anything a directory, so the * refusal cannot tell a hide from an absence. The walk stops at the hidden * name, so a link there is never followed. Mirrors Python's hidden_walk. */ export declare function hiddenWalk(path: PathSpec, follow: ((path: string) => string) | null, visible: (path: string) => boolean): FsError | null; /** * What a path's dot components answer, null when every one resolves. * * The kernel resolves `.` and `..` against the directory they sit in, so a * walk through a missing name fails ENOENT and one through a plain file * ENOTDIR (`cat nope/../f`, `cat f.txt/.`), where the textual simplification * in `virtual` reached `f` regardless. Each name in front of a dot is proved * a directory, in walk order, and one that is not is judged by its chain the * way a create is, so a miss under a plain file is ENOTDIR on every store. * A link in front of a dot is followed first, as the kernel walks (only * bash's `cd` reads `link/..` logically). A trailing slash is a final `.`: * an existing name in front of it has to be a directory too (`cat reg/`); a * call that creates that name (`creates`: mkdir, symlink) answers EEXIST * instead (`mkdir reg/`), however the store keeps the name. * * Only the path the spelling names is walked: a path derived from it (a * child a walker builds, a respelled match) carries the field along but no * longer spells it, while the operand the kernel walk followed through a * link (`lnk/nope/../f`) still does, which `follow` recognizes. The error * names the operand as typed and is a DotWalkError, final for every layer * that re-reads a miss. Mirrors Python's dot_refusal. */ export declare function dotRefusal(stat: StatFn, path: PathSpec, follow?: ((path: string) => string) | null, creates?: boolean): Promise<FsError | null>; export declare function resolveTarget(o: string | PathSpec, cwd: string): PathSpec; export declare function defaultPaths(paths: PathSpec[], cwd: string): PathSpec[]; //# sourceMappingURL=paths.d.ts.map