vfs — the virtual filesystem

SYNOPSIS

readFile(path, [options])      Read a file's content
writeFile(path, content)       Write content to a file
mkdir(path, [options])         Create a directory
rm(path, [options])            Remove a file or directory
stat(path)                     Get file/directory metadata
exists(path)                   Check if a path exists
walk(path)                     Recursively iterate files
rename(oldPath, newPath)       Move or rename
copyFile(src, dest)            Copy a file

DESCRIPTION

The VFS is a POSIX-like asynchronous filesystem backed by LightningFS, which stores all data in IndexedDB. It is persistent — content survives tab closes, page refreshes, and browser restarts. Every subsystem uses it: the shell (via VfsAdapter), git (via isomorphic-git), the file browser UI, and agent tools (read_file, write_file, edit_file).

All paths are absolute and normalized. There is no relative path resolution at the VFS layer — the shell and tools resolve relative paths before calling VFS methods.

DIRECTORY LAYOUT

PERSISTENCE

The VFS is backed by IndexedDB (database name: browser-fs). Data persists across page reloads and tab closes. To persist work to the real local filesystem, use the mount command to bridge a local directory into the VFS.

DEFAULT CONTENT

On first initialization or reset, default content from packages/vfs-root/ is copied into the VFS. This includes:

MOUNT

The mount command bridges a real local directory into the VFS using the browser's File System Access API (FileSystemDirectoryHandle). All reads and writes under the mount point are transparently proxied to the real directory — no copying occurs. Changes are immediately visible on both sides.

mount /workspace/myproject       Mount a local dir (opens picker)
mount list                       Show active mount points
mount unmount /workspace/myapp   Remove a mount point

Mounted directories are live bridges, not snapshots. Writing a file under the mount path writes directly to disk. This is the primary mechanism for working on real projects.

RESTRICTED FILESYSTEM

RestrictedFS wraps VirtualFS with path-based access control, used to enforce scoop sandboxes. Each scoop gets a RestrictedFS configured with its allowed paths.

The cone has unrestricted access to the entire filesystem.

SERVING FILES

There is no real HTTP server. The serve and open commands use a preview service worker (preview-sw.ts) that intercepts /preview/* requests and serves content directly from the VFS. This works entirely in-browser with no network traffic.

serve /workspace/myapp           Serve a directory (opens browser tab)
open /workspace/myapp/index.html Open a single file in a browser tab

AUTO-DISCOVERED SCRIPTS

Files with specific extensions on the VFS are automatically discovered and registered as shell commands:

Run commands in the terminal to see all discovered scripts.

ERROR HANDLING

All filesystem errors are thrown as FsError, which carries a POSIX-compatible error code and the offending path:

SKILLS

Skills are installed at /workspace/skills/ on the VFS. Each skill is a directory containing a SKILL.md file and optional companion assets or .jsh scripts. Native workspace skills are auto-loaded into the system prompt. Compatibility skills from .agents/skills/ and .claude/skills/ are also discovered from reachable VFS paths.

SEE ALSO

man scoop, man jsh, man skill, man cone