-
Notifications
You must be signed in to change notification settings - Fork 1
Filesystem
Edge adaptation of the upstream file operations subsystem.
Upstream reference: Filesystem
The filesystem subsystem gives the model safe, guarded file operations through four packages:
-
dsh-fs — abstract
FileSystemservice (ctx.fs) definingresolve,stat,lstat,readText,streamText,writeText,editText,readBytes,listDir. -
dsh-fs-local — local disk backend using
node:fs. -
dsh-tool-fs — registers four model-facing tools:
read,write,edit,read_image. - dsh-sandbox — enforces writable-root policies and path canonicalization.
Write guards (createIfAbsent, replaceIfVersion) prevent stale overwrites. Edit is atomic literal-replacement with match validation. Error codes (FS_STALE_VERSION, FS_NOT_FOUND, FS_IO_ERROR, etc.) are stable and programmatic.
EdgeFileSystem (309 lines) extends the upstream abstract FileSystem class. Every method delegates to the Cloudflare Computer VFS API (vfs.readFile, vfs.writeFile, vfs.stat, vfs.mkdir, vfs.readdir). Key adaptations:
-
AsyncLocalStorage for turn-scoped VFS bindings — each active turn gets its own
{vfs, cwd}pair viarunInScope(), so concurrent sessions on the same DO never cross-contaminate. -
readText calls stat after read to get the real
mtime:sizeversion token, matching upstream's freshness guard contract. - streamText returns a single-yield async iterable — VFS has no streaming API, so the entire content is read then yielded once.
-
writeText creates parent directories via
vfs.mkdir(parentDir, { recursive: true })before writing, since VFS paths may not exist yet. -
stat/lstat return undefined for ENOENT; other errors propagate as
FS_IO_ERROR.
dsh-tool-fs installed as-is. The four model tools (read, write, edit, read_image) use ctx.fs which resolves to EdgeFileSystem. Tool schemas, guard logic, diff output formatting, and line-number display are upstream.
The sandbox patch removes two Node.js imports:
-
node:fsrealpathSync→canonicalPath()returns the path directly (VFS has no symlinks). -
node:ostmpdir()→writableRootsomits the OS temp directory.
Removal condition: upstream provides a VFS-compatible sandbox or removes the Node.js imports.
- Tool definitions and parameter schemas (read/write/edit/read_image)
- Write guard semantics (createIfAbsent, replaceIfVersion)
- Edit atomicity and match validation
- Error codes and their stable classification
- Observation policy events (fs/write-intent, fs/edit-intent, fs/observed)
All file operations go through Cloudflare Computer's VFS, which is an in-memory filesystem scoped to the workspace container. Reads and writes are fast (no disk I/O in the traditional sense) but bounded by the container's memory allocation. Large files may hit VFS memory limits before the upstream FS_TOO_LARGE byte cap.
AsyncLocalStorage.run() is a V8 native with negligible overhead per call — well under 1 microsecond. It's invoked once per turn (in runInScope()), not per file operation. Within a turn, getStore() is a single context lookup.
Each turn's VFS binding is scoped via AsyncLocalStorage, so two sessions sharing the same DO can run file operations concurrently without cross-contamination. Previously a global activeBinding variable was used, which caused wrong-VFS bugs under interleaved async turns — replaced in 0.7.0-alpha.1.
readText calls vfs.stat() after reading the file to get the real mtime:size pair. This ensures the version token matches the actual file state, preventing false FS_STALE_VERSION errors on subsequent edits. The extra stat call adds one VFS round-trip per read.
| Component | Category | Edge Code |
|---|---|---|
| EdgeFileSystem | Replace | 309 lines — VFS delegation + AsyncLocalStorage |
| ToolFs (read/write/edit/read_image) | Reuse | One ctx.plugin() call |
| dsh-sandbox patch | Patch | Removes node:fs + node:os imports |
Key observation: EdgeFileSystem is a textbook capability-seam replacement — upstream defines the abstract
FileSystemclass, Edge provides the platform-specific backend. The tool layer and guard logic run entirely upstream code. The only patch is on the sandbox (Node.js imports), not on the filesystem itself.
- Home
- Architecture
- Core & Scope
- Session & Persistence
- Model & Context
-
Execution & Tools
- Tools
- Bash
- Subprocess 🚫
- PTY Session 🚫
- Background Jobs 🚫
- Filesystem
- LSP Navigation 🚫
- Code Runtime 🚫
-
Web Access
⚠️ -
Skills
⚠️ - Workflow 🚫
- Subagent 🚫
-
Policy & Interaction
- Goal
- Approval 🚫
- Permission Presets 🚫
-
Sandbox
⚠️ - Plan Mode 🚫
- User Interaction 🚫
- Commands 🚫
- Schedule 🚫
- Message Feedback 🚫
- Platform & Access
- Development
- 首页
- 架构
- 核心与作用域
- 会话与持久化
- 模型与上下文
- 执行与工具
- 策略与交互
- 平台与接入
- 开发