UNPKG

@struktoai/mirage-core

Version:

A Unified Virtual Filesystem For AI Agents

720 lines • 31.2 kB
export type JsonValue = null | boolean | number | string | JsonValue[] | { [k: string]: JsonValue; }; export type PageFetch = (cursor: string | null) => Promise<Record<string, unknown>>; /** * What a mount lets commands do, a cumulative ladder. READ lists and * reads. WRITE also creates, changes and deletes. EXEC also lets the * interpreter commands (python3, js) run code: a script file named as * their operand must sit on an EXEC mount, while inline code and -m need * one somewhere in the workspace (imports are not checked by path). * Shell scripts need no EXEC, since the shell checks each of their * commands like a typed one; a ./script whose shebang names python3 * reaches python3, which does check. */ export declare const MountMode: Readonly<{ readonly READ: "read"; readonly WRITE: "write"; readonly EXEC: "exec"; }>; export type MountMode = (typeof MountMode)[keyof typeof MountMode]; /** * How a mount is exposed to the outside world. * * `workspace` is the default: the mount lives only inside mirage's own filesystem * and is reached through the command surface, with nothing registered with * the kernel. `fuse` and `fskit` additionally expose it as a real mountpoint. * * `fskit` is macOS 15.4+ only and needs no kernel extension. It has no * `direct_io` equivalent, so it serves correct reads only for mounts that * set `sizesAlwaysKnown`; the mount-time guard warns about mounts whose * size-unknown files will read as empty. Writes are also limited: appends and * metadata ops persist, but the macFUSE FSKit shim flushes pages a file did * not already have (a new file, or truncate-then-write) as NUL bytes (pinned * in `integ/fuse/truth_fskit.json`). There is deliberately no `auto`: * auto-selecting fskit would silently degrade every API-backed mount. * * `nfs` mounts through the operating system's own NFS client, so nothing is * installed: mirage serves NFSv3 on a local port and runs the system `mount`. * Linux and macOS; Linux needs root to mount. It is read-only for now, and * like fskit it reads only as far as the size a file reports, so it serves * mounts that set `sizesAlwaysKnown`. */ export declare const MountBackend: Readonly<{ readonly WORKSPACE: "workspace"; readonly FUSE: "fuse"; readonly FSKIT: "fskit"; readonly NFS: "nfs"; }>; export type MountBackend = (typeof MountBackend)[keyof typeof MountBackend]; /** Backends that register a real mountpoint with the kernel. */ export declare const KERNEL_BACKENDS: readonly MountBackend[]; export declare const MOUNT_MODE_RANK: Readonly<Record<MountMode, number>>; /** The weaker of two mount modes on the READ < WRITE < EXEC lattice. */ export declare function weakerMode(a: MountMode, b: MountMode): MountMode; /** * What the dispatcher treats as nonexistent for one session. * * A sibling of `SessionState.mountModes`: per-session narrowing that the * entry points enforce, null-on-the-session means unrestricted. Hiding is * "does not exist", never "forbidden" — matching paths answer ENOENT * and drop out of listings, which is what makes a hide the way a profile * keeps a session away from a mount: naming mounts only narrows their * modes, and a refusal would hand back the name. * * `paths` are exact virtual paths; hiding a path hides its whole * subtree (a name you cannot see cannot be a parent you traverse), so * a mount root entry hides the mount. `patterns` are globs: one with * no `/` matches any single name component anywhere; one containing * `/` is anchored to the full virtual path, with `*` crossing slashes * exactly as GNU `find -path` does. */ export interface HiddenPaths { readonly paths?: readonly string[]; readonly patterns?: readonly string[]; } /** * One `show` entry of a profile's path axis, compiled. * * `path` is the entry as written: an exact subtree or an anchored * pattern, always absolute (a slashless name pattern is refused at * validation, because a show anchors to a place and a name pattern * names none). `mode` is what the entry states for its subtree; null * for a list-form entry, which inherits the mount's. */ export interface ShowEntry { readonly path: string; readonly mode: MountMode | null; } /** * The `show` half of one session's path axis. * * A sibling of `HiddenPaths`: per-session state the entry points read, * null-on-the-session means the document states no show. An entry does * two things, each on the one anchor-depth rule: it re-opens a subtree * inside a hidden region when its anchor is deeper than the hide's, * and it states the mode in force below its anchor when it carries * one. */ export interface ShownPaths { readonly entries: readonly ShowEntry[]; } /** * What the session view treats as unset for one session. * * Enforced where env leaves the session: `get` misses, `snapshot` * omits, expansion sees unset. Field names differ from `HiddenPaths` * on purpose — the planes' matching semantics differ, so the specs * are not interchangeable. */ export interface HiddenVars { readonly names?: readonly string[]; readonly patterns?: readonly string[]; } export type ProcessScope = 'session' | 'workspace'; /** * What exists for one session, compiled once from its profile. * * The one answer to "is this here?" for everything a session touches: * paths (hides, re-opened by deeper shows), variables and processes. * The views filter what they list through it and the op * boundary answers a hidden path as absent from it; nothing else asks * the profile what exists. `DEFAULT_VISIBILITY` hides nothing. * * `shown` re-opens a hidden subtree and states a subtree's mode; * `processes` is whose processes the session sees. */ export interface Visibility { readonly paths: HiddenPaths | null; readonly shown: ShownPaths | null; readonly vars: HiddenVars | null; readonly processes: ProcessScope; } export declare const DEFAULT_VISIBILITY: Visibility; /** * Coerce a mount mode, accepting cumulative filesystem aliases. * * The mode ladder is cumulative (exec implies write implies read), so * only the cumulative spellings `r`, `rw`, `rwx` alias the modes; * bit-style forms like `w` or `x` are rejected. */ export declare function parseMountMode(value: string): MountMode; /** * How a mount decides whether cached bytes may be served. * * FRESH revalidates against the backend's content token before serving a * cached copy; BOUNDED serves without revalidating, within the staleness * bound the mount declares. * * PINNED names the content a commit's fingerprint records. There is no * version layer to pin to, so a mount declaring it is refused at mount time * rather than quietly degraded to head: the vocabulary is published, so * someone will type it, and an informative refusal costs one branch over a * generic invalid-value error. */ export declare const ReadPolicy: Readonly<{ readonly FRESH: "fresh"; readonly BOUNDED: "bounded"; readonly PINNED: "pinned"; }>; export type ReadPolicy = (typeof ReadPolicy)[keyof typeof ReadPolicy]; /** * Whether replacements carry the version they were based on. Unconditional * existing-file rewrites are last-write-wins. Shared rewrites that observed * a missing file require atomic create-only under either policy. * Conditional writes also protect the version the mount last saw. Staged * names a staging layer not implemented here and is refused at mount time. * Mirrors Python's `WritePolicy`. */ export declare const WritePolicy: Readonly<{ readonly UNCONDITIONAL: "unconditional"; readonly CONDITIONAL: "conditional"; readonly STAGED: "staged"; }>; export type WritePolicy = (typeof WritePolicy)[keyof typeof WritePolicy]; /** * What a backend's cached listings can be checked against under fresh. * * NONE: nothing, so a listing the running command did not write itself is * listed again. MOUNT: one version covers every listing of the mount, and a * stat of the mount root answers it. FOLDER: each listing carries its own * folder's version, and a stat of that folder answers it. The stored version * and the stat's fingerprint must be the same kind of token, since the gate * compares them with `===`. */ export declare const ListingVersion: Readonly<{ readonly NONE: "none"; readonly MOUNT: "mount"; readonly FOLDER: "folder"; }>; export type ListingVersion = (typeof ListingVersion)[keyof typeof ListingVersion]; /** Maximum lifetime in seconds for cached bodies and listings. */ export declare const DEFAULT_READ_TTL = 600; /** * One mount's read policy and the bound that goes with it. * * The bound is set under FRESH too, so every cache entry carries one. Two * workspaces sharing one Redis cache under different policies would otherwise * write entries the other refuses to serve, and bounce them between cold reads * indefinitely. * * It is stamped when the entry is written and enforced by the store, so the * bound that applies is the writing mount's, not the reading mount's. Those are * the same mount inside one workspace; they differ across a shared cache, a * lowered `ttl` and a restored snapshot, and there the older bound stands until * the entry expires. Making the reader authoritative needs a write timestamp * every store can read back, which redis does not keep. */ export interface ReadSpec { readonly policy: ReadPolicy; readonly ttl: number; } /** * The policy a mount takes when it declares none, and the one pinned onto the * three synthetic anchors (`/dev`, the history view, the implicit `/` root). * * Those three are installed outside `normalizeMounts`, so they never meet the * capability verdict; none of them caches reads, so inheriting a workspace-level * `fresh` would stamp on them exactly the combination the verdict refuses. */ export declare const DEFAULT_READ_SPEC: ReadSpec; /** * What the cache write path needs to know about a path's mount. * * Answered per path against the mount table pinned at command start, so a * fill that lands after the command is stamped with the bound of the mount * that produced the bytes rather than whatever holds the prefix by then. * `cacheable` is read first and short-circuits, so `ttl` is never consulted * for a path that is not being cached. */ export interface CacheFacts { readonly cacheable: boolean; readonly ttl: number; /** Whether the mount's writes are conditional, so a line keeps a path's version even where it keeps no bytes. */ readonly keepsVersions?: boolean; } /** * Behaviour when a remote VFS's live fingerprint differs from the * value recorded at snapshot time. */ export declare const DriftPolicy: Readonly<{ /** Raise ContentDriftError on first mismatch. */ readonly STRICT: "strict"; /** Skip drift checks entirely. */ readonly OFF: "off"; }>; export type DriftPolicy = (typeof DriftPolicy)[keyof typeof DriftPolicy]; /** * Behaviour when a command's output exceeds its limit cap. * TRUNCATE returns the truncated bytes + a notice on stderr. * ERROR returns no stdout and exits 1 with the same notice. */ export declare const OnExceed: Readonly<{ readonly ERROR: "error"; readonly TRUNCATE: "truncate"; }>; export type OnExceed = (typeof OnExceed)[keyof typeof OnExceed]; /** * A bound on a result: the policy layer's limit arm and the shape * every cap config parses into. Carries its fields inline (the Deny * precedent: an action is its payload). `kind` is the wire * discriminant; `aggr` is the composition law (AND to the tightest * per bound, ANY on error mode) and `layered` the resolution law (each * field from the most specific layer that sets it). `walkLimit` caps the * entries one walk lists on a mount, -1 for no cap. */ export declare class Limit { readonly kind: "limit"; readonly maxBytes: number | null; readonly maxLines: number | null; readonly timeoutSeconds: number | null; readonly walkLimit: number | null; /** The fields the limit names, null among them; the rest inherit. Mirrors Python's model_fields_set. */ readonly fieldsSet: ReadonlySet<keyof NonNullable<ConstructorParameters<typeof Limit>[0]>>; private readonly exceed; constructor(init?: Partial<Pick<Limit, 'maxBytes' | 'maxLines' | 'timeoutSeconds' | 'walkLimit' | 'onExceed'>>); get onExceed(): OnExceed; /** * Each field from the first limit that names it, most specific first: a * layer naming one bound inherits the others from the layers below it, and * one naming a bound as null lifts it. Returns null when nothing is * configured. Mirrors Python's Limit.layered. */ static layered(limits: Iterable<Limit | null>): Limit | null; private named; /** * Aggregate several limits using each field's declared rule. * * Reads the rules off LIMIT_AGGR rather than naming the fields here, so a * new bound composes as soon as it is declared — the same property Python * gets from walking `model_fields` for each field's `Aggr(rule)`. Returns * null when nothing is configured. Used wherever bounds stack (policy * composition, cross-mount fan-out, layered configs). */ static aggr(limits: Iterable<Limit | null>): Limit | null; } /** * Provenance of a result: who produced it, and where. * * Rides the IO envelope from the dispatch site to the workspace * boundary; merge keeps the rightmost producer, so this names the * last command that ran; it does not describe every byte of a list. Post-layer policies * (output caps today; budgets and attribution later) read it as * context. Facts only: no policy reads a decision off the envelope; * the one a chain hands down is written beside it as * `IOResult.refusal` after the last method has spoken. `declared` is * the bound the command's own registration declared, * when the dispatch site knows it (e.g. a CLI leaf). `native` is set when * a native program a runtime runs produced it, writing as it goes, so a * redirect writes it as it arrives. */ export interface Producer { readonly command: string; readonly prefixes: readonly string[]; readonly declared: Limit | null; readonly native?: boolean; } export type RefusalKind = 'deny' | 'pending' | 'failed'; /** * Why a line did not run, for the caller that reads the result. * * stderr keeps bash's voice (`<cmd>: Permission denied`), which says * nothing about who refused or why; this record carries that beside * the envelope, so a host or an agent adapter can show the reason * without the shell having to. null on every run that was not * refused, and absent on the 127 `command not found` row, which must * not reveal that the word names anything. `kind` is `deny` for a * policy's refusal, `pending` for an ask the host has not answered, * `failed` for a policy that raised and so refused by default; * `policy` is the class name of the policy that spoke, empty for an * ask, which belongs to the host; `askId` is the approval to quote, * for `pending`. Mirrors the Python `Refusal`. */ export interface Refusal { readonly kind: RefusalKind; readonly reason: string; readonly policy: string; readonly askId: string | null; } export declare const VFSName: Readonly<{ readonly DISK: "disk"; readonly S3: "s3"; readonly RAM: "ram"; readonly GITHUB: "github"; readonly WANDB: "wandb"; readonly LINEAR: "linear"; readonly GCAL: "gcal"; readonly GDOCS: "gdocs"; readonly GSHEETS: "gsheets"; readonly GSLIDES: "gslides"; readonly GDRIVE: "gdrive"; readonly ONEDRIVE: "onedrive"; readonly SHAREPOINT: "sharepoint"; readonly DROPBOX: "dropbox"; readonly BOX: "box"; readonly AIRTABLE: "airtable"; readonly SLACK: "slack"; readonly DISCORD: "discord"; readonly GMAIL: "gmail"; readonly TRELLO: "trello"; readonly MONGODB: "mongodb"; readonly GRIDFS: "gridfs"; readonly NOTION: "notion"; readonly LANGFUSE: "langfuse"; readonly JAEGER: "jaeger"; readonly SSH: "ssh"; readonly REDIS: "redis"; readonly GCS: "gcs"; readonly OCI: "oci"; readonly R2: "r2"; readonly EMAIL: "email"; readonly OPFS: "opfs"; readonly SUPABASE: "supabase"; readonly POSTGRES: "postgres"; readonly LANCEDB: "lancedb"; readonly CHROMA: "chroma"; readonly DIFY: "dify"; readonly MEM0: "mem0"; readonly QDRANT: "qdrant"; readonly HF_BUCKETS: "hf_buckets"; readonly HF_DATASETS: "hf_datasets"; readonly HF_MODELS: "hf_models"; readonly HF_SPACES: "hf_spaces"; readonly NEXTCLOUD: "nextcloud"; readonly DATABRICKS_VOLUME: "databricks_volume"; readonly TIDB_FILESYSTEM: "tidb_filesystem"; readonly MINIO: "minio"; readonly CEPH: "ceph"; readonly SEAWEEDFS: "seaweedfs"; readonly WASABI: "wasabi"; readonly BACKBLAZE: "backblaze"; readonly DIGITALOCEAN: "digitalocean"; readonly TENCENT: "tencent"; readonly ALIYUN: "aliyun"; readonly SCALEWAY: "scaleway"; readonly QINGSTOR: "qingstor"; readonly HISTORY: "history"; readonly BIN: "bin"; }>; export type VFSName = (typeof VFSName)[keyof typeof VFSName]; /** * POSIX file type (the `st_mode` kind), the switch behavior branches on. * * One per entry, always present. Directory and symlink are their own * kinds; every regular file is FILE and carries its content shape on * `FileStat.content`. Distinct from ContentType, which is only a * rendering hint for a FILE. Mirrors `FileType` in `mirage/types.py`. * * The full POSIX set is enumerated so the model is comprehensive. * DIRECTORY, FILE, SYMLINK, CHAR_DEVICE (the /dev mount) and FIFO (a * process substitution's /dev/fd/N) are produced today; BLOCK_DEVICE and * SOCKET are declared but not yet emitted, and the render/derivation tables * (find letter, st_mode bits, ls char) grow a row for one the moment a * backend starts producing it. */ /** `ls` sort keys: name is the default, time `-t`, size `-S`, version * `-v`, extension `-X`, width `--sort=width`, and none `-U`. */ export type LsSortBy = 'name' | 'time' | 'size' | 'version' | 'extension' | 'width' | 'none'; /** Which timestamp `ls` shows and sorts by: `-u`/`--time=atime`, * `-c`/`--time=ctime`, `--time=birth`, else the modification time. */ export type LsTimeKind = 'mtime' | 'atime' | 'ctime' | 'birth'; export type LsIndicator = 'none' | 'slash' | 'file-type' | 'classify'; export type CopyDeref = 'always' | 'command_line' | 'never'; export type LsLinkMode = 'all' | 'directory' | 'none'; /** * How a command resolves a command-line operand's last component when it is * a symlink: never (lstat(2): `rm`, `stat`), always (open(2): `cat`, * `stat -L`), or only once a stat shows it leads to a directory (`ls` with no * option that settles it). */ export declare const Follow: Readonly<{ readonly NONE: "none"; readonly LAST: "last"; readonly DIRECTORY: "directory"; }>; export type Follow = (typeof Follow)[keyof typeof Follow]; /** * What one command line does, as its own command reads its options: the * admission gate, the router and the fan-out ask this instead of reading the * options themselves. `follows` is how its operands' last component * resolves; `walks` that its traversal enters the mounts below its operands * (`find`, `du`, `grep -r`; not `du -x`); `readsSubtree` that it reads below * the paths it names, whether or not it crosses a mount (`du -x`, `tar -c`, * `cp -r`); `writes` that it may change files, false only when its options * leave a writing command nothing to change (`sort` without `-o`, `tar -t`); * `subtree` that an operand is a whole subtree it moves or removes (`rm`, * `rmdir`, `mv`); `moveTarget` the directory a move names by option * (`mv -t DIR`), as typed, null when it names none. Mirrors Python's * `LineFacts`. */ export declare class LineFacts { readonly follows: Follow; readonly walks: boolean; readonly readsSubtree: boolean; readonly writes: boolean; readonly subtree: boolean; readonly moveTarget: string | null; constructor(init?: Partial<Omit<LineFacts, 'with'>>); /** A copy with some fields replaced, the mirror of Python's `dataclasses.replace`. */ with(update: Partial<Omit<LineFacts, 'with'>>): LineFacts; } export declare const FileType: Readonly<{ readonly DIRECTORY: "directory"; readonly FILE: "file"; readonly SYMLINK: "symlink"; readonly CHAR_DEVICE: "char_device"; readonly BLOCK_DEVICE: "block_device"; readonly FIFO: "fifo"; readonly SOCKET: "socket"; }>; export type FileType = (typeof FileType)[keyof typeof FileType]; /** * A regular file's content shape: the rendering hint (file/ls color). * * Only meaningful for a FILE; a directory or symlink carries none. Not a * node kind: nothing branches control flow on it. Mirrors `ContentType` * in `mirage/types.py`. */ export declare const ContentType: Readonly<{ readonly TEXT: "text"; readonly BINARY: "binary"; readonly JSON: "json"; readonly CSV: "csv"; readonly IMAGE_PNG: "image/png"; readonly IMAGE_JPEG: "image/jpeg"; readonly IMAGE_GIF: "image/gif"; readonly ZIP: "application/zip"; readonly GZIP: "application/gzip"; readonly PDF: "application/pdf"; }>; export type ContentType = (typeof ContentType)[keyof typeof ContentType]; export declare const LINK_TARGET_KEY = "link_target"; export declare const DEVICE_NUMBERS_KEY = "device_numbers"; export declare const LIVE_KEY = "mirage.live"; /** * The metadata fields a `setattr` writes, all optional. * * Spelled the way the op, the Context bag and the guest bridge * spell them, so one fact keeps one name from a shell line down to a * guest's utime. `nofollow` is not a field but the AT_SYMLINK_NOFOLLOW * bit: it writes the link entry's own attrs rather than its target's. * Lives here rather than beside either consumer because `ws.vfs` * and the runtime bridge both take it and neither may import the * other. */ export interface SetAttrFields { mode?: number; uid?: number | string; gid?: number | string; atime?: string; mtime?: string; nofollow?: boolean; } export declare class FileStat { readonly name: string; readonly size: number | null; readonly modified: string | null; readonly fingerprint: string | null; readonly revision: string | null; readonly type: FileType; readonly content: ContentType | null; readonly mode: number | null; readonly uid: number | string | null; readonly gid: number | string | null; readonly atime: string | null; readonly ctime: string | null; readonly birthtime: string | null; readonly dev: number | null; readonly extra: Record<string, unknown>; constructor(init: Pick<FileStat, 'name' | 'type'> & Partial<Pick<FileStat, 'size' | 'modified' | 'fingerprint' | 'revision' | 'content' | 'mode' | 'uid' | 'gid' | 'atime' | 'ctime' | 'birthtime' | 'dev' | 'extra'>>); with(update: Partial<NonNullable<ConstructorParameters<typeof FileStat>[0]>>): FileStat; } /** * A directory's listing as a backend answers it, when one fetch proves more * than the directory's own children. * * A backend's `readdir` answers a plain list of its children's stats, or this * when the fetch says more: a day of messages that also lists its `files/` * subdirectory, a board whose lists come with their cards. The dispatcher * keeps every listing it is handed, so entering a seeded directory costs no * second identical fetch. * * - `entries`: the listed directory's own children, each filled in as `stat` * would fill it. * - `seeds`: descendant listings the same fetch proved, keyed by path relative * to the listed directory (`files`, `2026-01-05/Report__17`). * - `partial`: the entries are a filtered or truncated view (a glob the * backend narrowed, a fetch it did not finish), so they are kept as entries * but not as the directory's listing. `seeds` stay full listings of the * children it did report. * - `window`: the fetch was capped (the newest N messages, the last N days), * so the entries are everything to show but prove nothing absent: a child * that drops out of the window has not been deleted. Kept as listings that * evict nothing. * - `version`: the version the listing was read at, for a backend that * declares a `listingVersion`; a `fresh` mount checks it before serving the * listing again. */ export declare class DirListing { readonly entries: readonly FileStat[]; readonly seeds: ReadonlyMap<string, readonly FileStat[]>; readonly partial: boolean; readonly window: boolean; readonly version: string | null; constructor(init: { entries: readonly FileStat[]; seeds?: ReadonlyMap<string, readonly FileStat[]>; partial?: boolean; window?: boolean; version?: string | null; }); } export declare const FileChangeKind: Readonly<{ readonly CREATE: "create"; readonly UPDATE: "update"; readonly DELETE: "delete"; readonly MOVE: "move"; readonly UNKNOWN: "unknown"; }>; export type FileChangeKind = (typeof FileChangeKind)[keyof typeof FileChangeKind]; export declare class FileMetadata { readonly fingerprint: string | null; readonly size: number | null; readonly modified: string | null; constructor(init?: Partial<Pick<FileMetadata, 'fingerprint' | 'size' | 'modified'>>); } export declare class FileEvent { readonly kind: FileChangeKind; readonly path: PathSpec; readonly timestamp: Date; readonly previousPath: PathSpec | null; readonly metadata: FileMetadata | null; constructor(init: Pick<FileEvent, 'kind' | 'path' | 'timestamp'> & Partial<Pick<FileEvent, 'previousPath' | 'metadata'>>); } export declare class Delta { readonly changes: readonly FileEvent[]; readonly checkpoint: string | null; constructor(init: Pick<Delta, 'changes' | 'checkpoint'>); } export declare const OverflowPolicy: Readonly<{ readonly COLLAPSE: "collapse"; readonly DROP_OLDEST: "drop_oldest"; readonly ERROR: "error"; }>; export type OverflowPolicy = (typeof OverflowPolicy)[keyof typeof OverflowPolicy]; export declare const CapacityState: { readonly QUOTA: "quota"; readonly ELASTIC: "elastic"; readonly NA: "na"; readonly UNKNOWN: "unknown"; }; export type CapacityState = (typeof CapacityState)[keyof typeof CapacityState]; export interface CapacityResult { state: CapacityState; total?: number | null; used?: number | null; available?: number | null; inodes?: number | null; inodesUsed?: number | null; inodesFree?: number | null; } export type ReadStreamFn<Args extends unknown[] = [path: PathSpec]> = (...args: Args) => AsyncIterable<Uint8Array>; export type CopyFn<Args extends unknown[] = [src: PathSpec, target: PathSpec]> = (...args: Args) => Promise<void>; export type MoveFn<Args extends unknown[] = [src: PathSpec, target: PathSpec]> = (...args: Args) => Promise<void>; /** Native copy only asks for files or directories; backend ops supply their full arguments. */ export type FindFn<Args extends unknown[] = [src: PathSpec, options: { type: 'f' | 'd'; unreadable?: string[]; }]> = (...args: Args) => Promise<string[]>; export type ReaddirFn<Args extends unknown[] = [path: PathSpec]> = (...args: Args) => Promise<string[]>; export type StatFn<Args extends unknown[] = [path: PathSpec]> = (...args: Args) => Promise<FileStat>; /** * What proving a running command's `.` and `..` reads. * * The command tier reaches its backend past the dispatcher, so * `Mount.runCommand` binds the dispatcher's facts for it: `stat` is the dispatcher's * stat (throwing when nothing is there) and `follow` the namespace's link * resolution, null while it holds none. The kernel walk (`followPaths`) * rewrites an operand to its link's target before the handler runs; * `follow` is how that operand is still known for the one its dotted * spelling names. Mirrors Python's WalkProbe. */ export interface WalkProbe { readonly stat: StatFn; readonly follow: ((path: string) => string) | null; } export interface NativeCopy { copy: CopyFn; find: FindFn; dirCopy?: CopyFn; /** * Lets the per-entry policy path (--update/--backup, which cannot use a * whole-tree dirCopy) still materialize directories that hold no files. */ mkdir?: CopyFn<[path: PathSpec]>; } export interface PrimitiveCopy { read: ReadStreamFn; write: CopyFn<[target: PathSpec, data: Uint8Array | AsyncIterable<Uint8Array>]>; mkdir: CopyFn<[path: PathSpec]>; readdir: ReaddirFn; /** A store-to-store copy between two mounts, tried before the bytes move; * EXDEV or ENOTSUP from it says the stores cannot. */ copy?: CopyFn; } export type CopyStrategy = NativeCopy | PrimitiveCopy; export interface NativeMove { rename: MoveFn; } export interface PrimitiveMove { read: ReadStreamFn; write: MoveFn<[target: PathSpec, data: Uint8Array | AsyncIterable<Uint8Array>]>; mkdir: MoveFn<[path: PathSpec]>; readdir: ReaddirFn; unlink: MoveFn<[path: PathSpec]>; rmdir: MoveFn<[path: PathSpec]>; /** Throws when the source's mount cannot condition its delete. */ checkUnlink?: (path: PathSpec) => void; copy?: CopyFn; } export type MoveStrategy = NativeMove | PrimitiveMove; /** A resource query and backend-specific arguments, validated by the backend. */ export interface SearchQuery { readonly query: string; readonly options?: Readonly<Record<string, JsonValue>>; } export type WalkErrno = 'ENOENT' | 'ELOOP'; export declare class PathSpec { readonly virtual: string; readonly directory: string; readonly vfsPath: string; readonly pattern: string | null; readonly resolved: boolean; readonly rawPath: string; readonly dotted: string | null; readonly walkError: WalkErrno | null; constructor(init: Pick<PathSpec, 'virtual' | 'directory' | 'vfsPath'> & Partial<Pick<PathSpec, 'pattern' | 'resolved' | 'rawPath' | 'dotted' | 'walkError'>>); get mountPath(): string; get dir(): PathSpec; child(name: string): string; /** Join components for workspace dispatch, preserving the unproven walk. */ join(...parts: string[]): PathSpec; /** Lexical parent with its spelled ancestors, for workspace dispatch. */ get parent(): PathSpec; /** * Wrap a resolved path, or resolve a supplied spelling against cwd. * Existing specs retain their metadata; vfsPath can override the backend key. * Supply cwd for relative strings, dotted walks and inherited walk errors; * omit it for an already resolved virtual path. */ static fromStrPath(path: string | PathSpec, vfsPath?: string, cwd?: string | PathSpec): PathSpec; } export declare function wordText(word: string | PathSpec): string; /** A JSON object received from a service, before its fields are checked. */ export type JsonObject = Record<string, unknown>; /** An optional byte range requested by a file read. */ export interface ReadRange { offset?: number; size?: number; } //# sourceMappingURL=types.d.ts.map