/** * The filesystem interface the workspace speaks (build contract §3.2). * * Vendored verbatim from just-bash's `IFileSystem` (`vercel-labs/just-bash`, * `dist/fs/interface.d.ts`, v3.2.0) so that `@vendoai/vendo/core` — the package every * consumer installs — carries the SHAPE without the ~50 MB bash interpreter * behind it. The runtime dependency belongs to whoever actually runs bash * (`@vendoai/vendo`), never to core. * * Keep this structurally identical to upstream: a `WorkspaceFs` must stay * assignable to `new Bash({ fs })`. The one deliberate omission is upstream's * optional `readFileBytes?(path): Promise` — it is optional * precisely so external implementations may skip it, and just-bash falls back * to `readFileBuffer` when it is absent (documented upstream). Omitting an * optional member does not affect assignability. * * --------------------------------------------------------------------------- * just-bash — Copyright (c) Vercel, Inc. and just-bash contributors. * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at http://www.apache.org/licenses/LICENSE-2.0 * --------------------------------------------------------------------------- */ /** Supported buffer encodings. */ export type BufferEncoding = "utf8" | "utf-8" | "ascii" | "binary" | "base64" | "hex" | "latin1"; /** File content can be string or bytes. */ export type FileContent = string | Uint8Array; export interface ReadFileOptions { encoding?: BufferEncoding | null; } export interface WriteFileOptions { encoding?: BufferEncoding; } /** Directory entry with type information (Node's Dirent, narrowed). */ export interface DirentEntry { name: string; isFile: boolean; isDirectory: boolean; isSymbolicLink: boolean; } /** Stat result from the filesystem. */ export interface FsStat { isFile: boolean; isDirectory: boolean; isSymbolicLink: boolean; mode: number; size: number; mtime: Date; /** Stable filesystem identity when the backend can expose it safely. */ dev?: number | bigint; ino?: number | bigint; identity?: string; } export interface MkdirOptions { recursive?: boolean; } export interface RmOptions { recursive?: boolean; force?: boolean; } export interface CpOptions { recursive?: boolean; } /** * Abstract filesystem interface, implementable by different backends — * in-memory, a real disk, or (ours) the store. */ export interface IFileSystem { /** Read a file as decoded text. Default encoding is utf8. */ readFile(path: string, options?: ReadFileOptions | BufferEncoding): Promise; /** Read a file as raw bytes. */ readFileBuffer(path: string): Promise; /** Write content to a file, creating it if it does not exist. */ writeFile(path: string, content: FileContent, options?: WriteFileOptions | BufferEncoding): Promise; /** Append content to a file, creating it if it does not exist. */ appendFile(path: string, content: FileContent, options?: WriteFileOptions | BufferEncoding): Promise; exists(path: string): Promise; /** @throws if the path does not exist. */ stat(path: string): Promise; /** @throws if the parent does not exist (unless recursive) or the path exists. */ mkdir(path: string, options?: MkdirOptions): Promise; /** Entry names, not full paths. */ readdir(path: string): Promise; /** Optional: entry names with type information, cheaper than readdir + stat. */ readdirWithFileTypes?(path: string): Promise; /** @throws if the path does not exist (unless force) or a directory is not empty (unless recursive). */ rm(path: string, options?: RmOptions): Promise; cp(src: string, dest: string, options?: CpOptions): Promise; mv(src: string, dest: string): Promise; /** Resolve a relative path against a base path. Synchronous by contract. */ resolvePath(base: string, path: string): string; /** Every path in the filesystem (glob matching). Synchronous by contract. */ getAllPaths(): string[]; chmod(path: string, mode: number): Promise; symlink(target: string, linkPath: string): Promise; link(existingPath: string, newPath: string): Promise; readlink(path: string): Promise; /** Stat without following symlinks. */ lstat(path: string): Promise; /** POSIX realpath: resolve every symlink to the canonical physical path. */ realpath(path: string): Promise; /** Set access and modification times. `atime` is accepted for API compatibility. */ utimes(path: string, atime: Date, mtime: Date): Promise; }