/** * Virtual Filesystem Type Definitions * * REAL types for production VFS implementation * No mocks, no stubs, actual working definitions */ import { Entity, Relation } from '../types/brainy.types.js' import { NounType, VerbType } from '../types/graphTypes.js' import { Vector } from '../coreTypes.js' // ============= Core VFS Types ============= /** * Todo item for task tracking */ export interface VFSTodo { id: string task: string priority: 'low' | 'medium' | 'high' status: 'pending' | 'in_progress' | 'completed' assignee?: string due?: string } /** * VFS-specific metadata that extends entity metadata * This is what makes a Brainy entity a "file" or "directory" */ export interface VFSMetadata { // Filesystem essentials path: string // Full absolute path name: string // Filename or directory name parent?: string // Parent directory entity ID vfsType: 'file' | 'directory' | 'symlink' isVFS?: boolean // v4.3.3: Mark as VFS entity (separates from knowledge graph) // File attributes size: number // Size in bytes (0 for directories) mimeType?: string // MIME type for files extension?: string // File extension // Permissions (POSIX-style) permissions: number // e.g., 0o755 owner: string // Owner ID group: string // Group ID // Timestamps accessed: number // Last access timestamp (ms) modified: number // Last modification timestamp (ms) // Content storage strategy storage?: { type: 'inline' | 'reference' | 'chunked' key?: string // S3/storage key for reference type chunks?: string[] // Chunk keys for chunked type compressed?: boolean // Whether content is compressed } // Extended attributes attributes?: Record // User-defined attributes rawData?: string // Base64 encoded raw file content (for small files) // Semantic enhancements (optional but powerful) tags?: string[] // User or auto-generated tags concepts?: Array<{ name: string confidence: number }> conceptNames?: string[] // Flattened concept names for O(log n) indexed queries todos?: VFSTodo[] dependencies?: string[] // For code files - what they import exports?: string[] // For code files - what they export language?: string // Programming language or human language // Import tracking (optional, present if created during import) importIds?: string[] // Import operation IDs (array because entity can be in multiple imports) projectId?: string // Project identifier grouping related imports importedAt?: number // Timestamp when imported importFormat?: string // Format of import ('excel', 'csv', 'pdf', etc.) importSource?: string // Source filename or URL // Extended metadata for various file types lineCount?: number wordCount?: number charset?: string hash?: string symlinkTarget?: string } /** * Complete VFS Entity - a file or directory in the virtual filesystem */ export interface VFSEntity extends Entity { // Entity already has: id, vector, type, data, metadata, service, createdAt, updatedAt metadata: VFSMetadata // Override to require VFS metadata // For files, data contains the actual content // For directories, data is undefined data?: Buffer | Uint8Array | string } /** * File stat information (Node.js fs.Stats compatible) */ export interface VFSStats { // Core stats size: number mode: number // File mode (permissions) uid: number // User ID gid: number // Group ID // Timestamps atime: Date // Access time mtime: Date // Modification time ctime: Date // Change time birthtime: Date // Creation time // Type checks isFile(): boolean isDirectory(): boolean isSymbolicLink(): boolean // Extended VFS stats path: string entityId: string // Underlying Brainy entity ID vector?: Vector // Semantic embedding if available connections?: number // Number of relationships } /** * Directory entry (for readdir) */ export interface VFSDirent { name: string path: string // Full path type: 'file' | 'directory' | 'symlink' entityId: string // Underlying entity ID } /** * Error codes matching Node.js fs errors */ export enum VFSErrorCode { ENOENT = 'ENOENT', // No such file or directory EEXIST = 'EEXIST', // File exists ENOTDIR = 'ENOTDIR', // Not a directory EISDIR = 'EISDIR', // Is a directory ENOTEMPTY = 'ENOTEMPTY', // Directory not empty EACCES = 'EACCES', // Permission denied EINVAL = 'EINVAL', // Invalid argument EMFILE = 'EMFILE', // Too many open files ENOSPC = 'ENOSPC', // No space left EIO = 'EIO', // I/O error ELOOP = 'ELOOP' // Too many symbolic links } /** * VFS-specific error class */ export class VFSError extends Error { code: VFSErrorCode path?: string syscall?: string constructor(code: VFSErrorCode, message: string, path?: string, syscall?: string) { super(message) this.name = 'VFSError' this.code = code this.path = path this.syscall = syscall } } // ============= Operation Options ============= export interface WriteOptions { encoding?: BufferEncoding mode?: number // File permissions flag?: string // 'w', 'wx', 'w+', etc. // VFS-specific options generateEmbedding?: boolean // Auto-generate vector (default: true) extractMetadata?: boolean // Auto-extract metadata (default: true) compress?: boolean // Compress large files (default: auto) deduplicate?: boolean // Check for duplicates (default: false) metadata?: Record // Additional metadata to attach } export interface ReadOptions { encoding?: BufferEncoding flag?: string // 'r', 'r+', etc. // VFS-specific options cache?: boolean // Use cache if available (default: true) decompress?: boolean // Auto-decompress (default: true) } export interface MkdirOptions { recursive?: boolean // Create parent directories mode?: number // Directory permissions // VFS-specific options metadata?: Partial // Additional metadata } export interface ReaddirOptions { encoding?: BufferEncoding withFileTypes?: boolean // Return Dirent objects // VFS-specific options recursive?: boolean // Include subdirectories limit?: number // Max results offset?: number // Skip N results cursor?: string // Pagination cursor filter?: { pattern?: string // Glob pattern type?: 'file' | 'directory' minSize?: number maxSize?: number modifiedAfter?: Date modifiedBefore?: Date } sort?: 'name' | 'size' | 'modified' | 'created' order?: 'asc' | 'desc' } export interface CopyOptions { overwrite?: boolean // Overwrite existing preserveTimestamps?: boolean // Keep original timestamps // VFS-specific options preserveVector?: boolean // Keep original embedding preserveRelationships?: boolean // Copy relationships too deepCopy?: boolean // For directories } // ============= Search & Semantic Operations ============= export interface SearchOptions { // Search scope path?: string // Search within this path recursive?: boolean // Include subdirectories // Search criteria type?: 'file' | 'directory' | 'any' where?: Record // Metadata filters // Result options limit?: number offset?: number includeContent?: boolean // Include file content in results includeVector?: boolean // Include embeddings explain?: boolean // Include score explanation } export interface SimilarOptions { limit?: number threshold?: number // Min similarity (0-1) type?: 'file' | 'directory' | 'any' withinPath?: string // Restrict to path } export interface SearchResult { path: string entityId: string score: number type: 'file' | 'directory' | 'symlink' size: number modified: Date explanation?: { vectorScore?: number metadataScore?: number graphScore?: number } } export interface RelatedOptions { depth?: number // Traversal depth types?: VerbType[] // Relationship types limit?: number } // ============= Streaming ============= export interface ReadStreamOptions { encoding?: BufferEncoding start?: number // Start byte end?: number // End byte highWaterMark?: number // Buffer size } export interface WriteStreamOptions { encoding?: BufferEncoding mode?: number autoClose?: boolean emitClose?: boolean } // ============= Watch ============= export interface WatchOptions { persistent?: boolean recursive?: boolean encoding?: BufferEncoding } export type WatchEventType = 'rename' | 'change' | 'error' export interface WatchListener { (eventType: WatchEventType, filename: string | null): void } // ============= VFS Configuration ============= export interface VFSConfig { // Root configuration root?: string // Root path (default: '/') rootEntityId?: string // Existing root entity ID // Performance options cache?: { enabled?: boolean maxPaths?: number // Max cached paths maxContent?: number // Max cached file content (bytes) ttl?: number // Cache TTL in ms } // Storage options storage?: { inline?: { maxSize?: number // Max size for inline storage (default: 100KB) } chunking?: { enabled?: boolean chunkSize?: number // Chunk size in bytes (default: 5MB) parallel?: number // Parallel chunk operations } compression?: { enabled?: boolean minSize?: number // Min size to compress (default: 10KB) algorithm?: 'gzip' | 'brotli' | 'zstd' } } // Intelligence options intelligence?: { enabled?: boolean // Enable AI features autoEmbed?: boolean // Auto-generate embeddings autoExtract?: boolean // Auto-extract metadata autoTag?: boolean // Auto-generate tags autoConcepts?: boolean // Auto-detect concepts } // Permissions permissions?: { defaultFile?: number // Default file permissions (0o644) defaultDirectory?: number // Default dir permissions (0o755) umask?: number // Permission mask } // Limits limits?: { maxFileSize?: number // Max file size in bytes maxPathLength?: number // Max path length maxDirectoryEntries?: number // Max files per directory } } // ============= Main VFS Interface ============= export interface IVirtualFileSystem { // Initialization init(config?: VFSConfig): Promise close(): Promise // File operations readFile(path: string, options?: ReadOptions): Promise writeFile(path: string, data: Buffer | string, options?: WriteOptions): Promise appendFile(path: string, data: Buffer | string, options?: WriteOptions): Promise unlink(path: string): Promise // Directory operations mkdir(path: string, options?: MkdirOptions): Promise rmdir(path: string, options?: { recursive?: boolean }): Promise readdir(path: string, options?: ReaddirOptions): Promise // Tree operations (NEW - prevents recursion issues) getDirectChildren(path: string): Promise getTreeStructure(path: string, options?: { maxDepth?: number includeHidden?: boolean sort?: 'name' | 'modified' | 'size' }): Promise getDescendants(path: string, options?: { includeAncestor?: boolean type?: 'file' | 'directory' }): Promise inspect(path: string): Promise<{ node: VFSEntity children: VFSEntity[] parent: VFSEntity | null stats: VFSStats }> // Metadata operations stat(path: string): Promise lstat(path: string): Promise exists(path: string): Promise chmod(path: string, mode: number): Promise chown(path: string, uid: number, gid: number): Promise utimes(path: string, atime: Date, mtime: Date): Promise // Path operations rename(oldPath: string, newPath: string): Promise copy(src: string, dest: string, options?: CopyOptions): Promise move(src: string, dest: string): Promise symlink(target: string, path: string): Promise readlink(path: string): Promise realpath(path: string): Promise // Extended attributes getxattr(path: string, name: string): Promise setxattr(path: string, name: string, value: any): Promise listxattr(path: string): Promise removexattr(path: string, name: string): Promise // Semantic operations search(query: string, options?: SearchOptions): Promise findSimilar(path: string, options?: SimilarOptions): Promise getRelated(path: string, options?: RelatedOptions): Promise> // Relationships addRelationship(from: string, to: string, type: string): Promise removeRelationship(from: string, to: string, type?: string): Promise getRelationships(path: string): Promise // Todos and metadata getTodos(path: string): Promise setTodos(path: string, todos: VFSTodo[]): Promise addTodo(path: string, todo: VFSTodo): Promise getMetadata(path: string): Promise setMetadata(path: string, metadata: Partial): Promise // Streaming (returns Node.js compatible streams) createReadStream(path: string, options?: ReadStreamOptions): NodeJS.ReadableStream createWriteStream(path: string, options?: WriteStreamOptions): NodeJS.WritableStream // Watching watch(path: string, listener: WatchListener): { close(): void } watchFile(path: string, listener: WatchListener): void unwatchFile(path: string): void // Utility getEntity(path: string): Promise getEntityById(id: string): Promise resolvePath(path: string, from?: string): Promise resolvePathToId(path: string, from?: string): Promise } // Export utility type guards export function isFile(stats: VFSStats): boolean { return stats.isFile() } export function isDirectory(stats: VFSStats): boolean { return stats.isDirectory() } export function isSymlink(stats: VFSStats): boolean { return stats.isSymbolicLink() }