Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

97 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

cf-vfs

cf-vfs is a tree-shakable byte-oriented virtual filesystem and Bash-compatible runtime for Cloudflare Workers. The default shell API executes independent, complete source units; an optional /shell/interactive entry point preserves shell state between units. One SQLite-backed Durable Object owns a strongly consistent pathname namespace. Files up to 8 MiB can be stored inline and read by shell utilities; large payloads live as immutable R2 objects and are intentionally opaque to the shell.

import { DurableObject } from "cloudflare:workers";
import { Shell, type RemoteExecuteTextOptions } from "@corca-ai/cf-vfs/shell";
import { defaultShellCommands } from "@corca-ai/cf-vfs/shell/commands/default";
import { DurableObjectFileSystem } from "@corca-ai/cf-vfs/storage/do-sql";
import { R2OpaqueStore } from "@corca-ai/cf-vfs/storage/r2";

interface Env {
  WORKSPACES: DurableObjectNamespace<WorkspaceFiles>;
  FILE_BODIES: R2Bucket;
}

export class WorkspaceFiles extends DurableObject<Env> {
  private readonly fileSystem: DurableObjectFileSystem;
  private readonly shell: Shell;

  constructor(ctx: DurableObjectState, env: Env) {
    super(ctx, env);
    this.fileSystem = new DurableObjectFileSystem(ctx.storage, {
      opaqueStore: new R2OpaqueStore(env.FILE_BODIES),
      workspaceId: ctx.id.toString(),
    });
    this.shell = new Shell({
      fileSystem: this.fileSystem,
      commands: defaultShellCommands,
    });
  }

  executeText(options: RemoteExecuteTextOptions) {
    return this.shell.executeText(options);
  }

  override async alarm() {
    await this.fileSystem.drainGarbage();
  }
}

export async function execute(env: Env, workspaceId: string) {
  const workspace = env.WORKSPACES.getByName(workspaceId);
  return workspace.executeText({
    script: `find src -name '*.ts' | sort > files.txt`,
    cwd: "/workspace",
  });
}

WorkspaceFiles extends only Cloudflare's required DurableObject; the cf-vfs parts are composed normally. DurableObjectFileSystem stores paths and inline bytes in ctx.storage (SQLite), while R2OpaqueStore connects the FILE_BODIES R2 binding for opaque-body verification and garbage collection. WORKSPACES routes each workspace to its Durable Object. See Getting started for the Wrangler bindings, migration, and direct-to-R2 upload path.

From a repository checkout, run npm run repl for a local line-oriented session backed by Node's in-memory SQLite. npm run repl:sqlite runs the same terminal UI against a disposable SQLite-backed Durable Object in local workerd, exercising Cloudflare's storage API as well as the shared SQL VFS.

This is an application runtime, not an operating-system shell or POSIX ABI. It does not launch processes, mount a host filesystem, or provide OS TTY/job control. The supported language is an explicit versioned subset, and every parser, execution, stream, mutation, and storage boundary is bounded.

The pre-1.0 stream-first redesign is intentionally breaking. The old { command, input } structured executor and text/binary storage split have been removed.

Read docs/index.md for setup, language and command semantics, the SQLite/R2 lifecycle, limits, benchmarks, and compatibility details.

License

MIT

About

Virtual file-system for Cloudflare Durable Objects and R2

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages