LayerFS for Cursor

previewv0.1.0

Cursor coding agents work on LayerFS Branches and Workspaces instead of git worktrees.

Earson · for Cursor

Install

Paste this into a coding agent on the machine that will run it. It installs v0.1.0 at 1802b525cc with LayerFS v1.1.0 at ad78914e36, the commit it was tested with. It runs the author’s build, so read it first.

Install prompt · v0.1.0
Install LayerFS for Cursor 0.1.0 for me. Plugin id `cursor-agents`, package `layerfs-cursor-agents`. Cursor only. Do not add Claude Code skills, hooks, or configuration.

Do these steps in order. If anything fails, stop and give me the exact error, and don't retry it on your own.

1. Clone https://github.com/Ephemeral-AI-Lab/layerfs and check out commit ad78914e36b258b360daf13aec164b5655814689 (v1.1.0). Use exactly this commit: it is the one this version was tested with. `git rev-parse HEAD` must print ad78914e36b258b360daf13aec164b5655814689. If it does not, stop. Export `LAYERFS_REPO` as that checkout.
2. Clone https://github.com/earsonlau/layerfs-cursor-agents beside it and check out commit 1802b525cca2ff9730678c01f8aefcc107223940. `git rev-parse HEAD` must print 1802b525cca2ff9730678c01f8aefcc107223940. Its `layerfs.json` `commit` must be ad78914e36b258b360daf13aec164b5655814689.
3. Check the tools, once each. Stop if either is missing or Node is older than 20.
   `node -v`
   `git --version`
4. From the plugin repository root, run setup once, with `--layerfs` set to the checkout from step 1.
   On Linux, pass `--build-native` so the in-process Store addon is built:
   `node bin/layerfs-cursor-setup.js --build-native --layerfs "$LAYERFS_REPO"`
   On macOS and Windows, do not pass `--build-native`. Those routes use the worker. The native build throws on Windows, and macOS does not need a Rust toolchain for Store calls. Setup ignores the flag there:
   `node bin/layerfs-cursor-setup.js --layerfs "$LAYERFS_REPO"`
   Add a flag only when you already know the value: `--home`, `--prefix`, `--settings-file`, `--project`, `--store-path`, `--image`, `--daemon`, `--volume`, `--docker`, `--bundle`, `--container-prefix`, `--cursor-project`.
   Use `--settings-file` for the env file. Node reserves `--env-file`, so that name never reaches this script.
   On macOS and Windows, `--image` and `--bundle` are required or the worker start fails. Stop with that error.
   On Windows the process stays in the foreground to keep the worker alive. Leave it running and use another terminal for the later steps.
5. Source the env file the script writes (by default `layerfs.env` in the plugin repository) in the shell you will use for LayerFS:
   `set -a && source layerfs.env && set +a`
   If the script said the shim directory is not on PATH, prepend that directory to PATH in this shell.
6. Check, once each:
   `node bin/layerfs-cursor-setup.js check`
   `layerfs help`
   `node --test`
7. Read `.cursor/skills/layerfs-agent/SKILL.md` before editing the project. Do not create a git worktree.

Report what you ran and what each step returned. If anything fails, stop and give me the exact error, and don't retry it on your own.

Cursor coding agents work on LayerFS Branches and Workspaces instead of git worktrees. One task gets one Branch. File edits go through fs.*. Bash runs as workspace.mount, then exec, commit, and unmount. Each LayerFS call is attempted once.

Plugin id: cursor-agents. Package: layerfs-cursor-agents 0.1.0. This repository is for Cursor only. It does not install Claude Code skills, hooks, or configuration, and it does not ship a history dashboard.

The LayerFS commit this version was built against is commit in layerfs.json: ad78914e36b258b360daf13aec164b5655814689 (LayerFS v1.1.0).

What it adds

  • A Cursor skill at .cursor/skills/layerfs-agent/SKILL.md. The same skill is at .agents/skills/layerfs-agent/SKILL.md for agents that look there.
  • layerfs-cursor-setup, which checks out that LayerFS commit, links the official layerfs command onto PATH, and writes LAYERFS_* settings.
  • On Linux, Store calls stay in the agent process. On macOS and Windows the setup starts the home worker with @layerfs/runtime and sets LAYERFS_WORKER_ENDPOINT.

How it works

The skill is the procedure. Short form:

  1. Source layerfs.env. Use layerfs or LayerFS.open(process.env.LAYERFS_PROJECT).
  2. branch.fork one Branch for the task. Do not add a git worktree.
  3. Edit with fs.write, fs.edit, fs.apply, and the other fs.* calls.
  4. Run bash as sandbox.create (when you need a Sandbox), then workspace.mount, workspace.exec, workspace.commit, and workspace.unmount. Unmount in finally. On Conflict, stay in that Workspace until you resolve it or discard it.
  5. On Conflict, Busy, or NoSuchSandbox, follow refusals.md once. Do not replay the refused call.

examples/task-branch.mjs forks a Branch (or keeps it if the name is taken) and writes one file. It imports the public SDK from LAYERFS_REPO.

Setup reads layerfs.json and requires a 40-character commit. It clones Ephemeral-AI-Lab/layerfs into --layerfs (default ../layerfs, or LAYERFS_REPO when that is set) and checks out that commit. An existing checkout already on the commit is left as it is. A checkout on another commit is updated only when git status is clean: one git fetch of that commit, then one git checkout. A dirty tree is not touched. It then links @layerfs/agent and @layerfs/runtime into this repo’s node_modules (symlinks to the checkout, not copies of LayerFS source) and writes a layerfs shim that runs the official command.

On Linux it does not start a worker. On macOS and Windows it opens @layerfs/runtime with sweep: false and calls worker.start() once. macOS then closes the runtime object; the worker container keeps running. Windows keeps the setup process alive because the runtime owns the worker on stdin.

You need

  • Node.js 20 or newer, git, and npm.
  • A LayerFS checkout at the pinned commit. The setup script clones it if you do not already have one.
  • Linux, for real Store calls: the Rust 1.85.1 toolchain (rustup toolchain install 1.85.1), so the native addon can be built, and LAYERFS_STORE_PATH pointing at the project’s installed Store (global/store.sqlite on a local filesystem the daemons share).
  • Sandboxes (any OS): Docker, LAYERFS_IMAGE (an image digest), LAYERFS_VOLUME, and LAYERFS_DAEMON.
  • macOS worker: Docker, LAYERFS_IMAGE, and a sealed Linux bundle.
  • Windows worker: WSL2, Docker inside it, LAYERFS_IMAGE, and a sealed Linux bundle. The setup process must stay running; it owns the worker.

Default tests do not need Docker, Cargo, or a LayerFS checkout.

Tests

node --test uses no Docker, no Store, and no daemon. It checks the pin, the skill, refusal handling, and the setup plan with a fake filesystem.

When LAYERFS_REPO points at the pinned checkout, the same command also imports the public @layerfs/agent entry over LayerFS’s stand-in native binding and runs layerfs help. Still no Docker.

LAYERFS_CURSOR_E2E=1 node --test test/e2e.test.mjs is skipped unless that variable is 1. It then needs Docker and LAYERFS_REPO, LAYERFS_HOME, LAYERFS_STORE_PATH, LAYERFS_IMAGE, LAYERFS_VOLUME, LAYERFS_DAEMON, and LAYERFS_PROJECT, and it runs one mount, exec, commit, and unmount. A missing value or a refused call fails the test. It does not retry.

Limits

  • Cursor only. No Claude Code, DSH, Pi, or @layerfs/backend UI.
  • Packages used here are the public @layerfs/agent and @layerfs/runtime APIs. Nothing imports @layerfs/agent/internal.
  • Settings written for agents are LAYERFS_* names. The SDK does not take an options object.
  • One attempt per call. Setup does not retry a failed git, npm, or worker start. Agents do not retry a refused SDK call.
  • Linux has no worker. worker.start on Linux is InvalidInput in @layerfs/runtime, and this setup does not call it.
  • macOS and Windows need a sealed bundle and an image digest before the worker can start. This plugin does not build that image or the bundle.
  • The Windows worker dies when the setup process exits.
  • main changes only through branch.publish.
  • This repo does not modify the LayerFS checkout except for the setup script’s clone, checkout, npm install, and optional native build.
  • Conflict markers from workspace.commit exist only in the Workspace that hit the conflict.
  • The layerfs command starts a new process per call. A long loop belongs in one Node script.

License

MIT. See LICENSE.

Versions

Each version pins the plugin’s commit and the LayerFS release and commit it was tested with.

VersionDatePlugin commitLayerFS
v0.1.0newestFirst listing: Cursor skill, layerfs-cursor-setup, and one Branch per task; LayerFS pin ad78914e (#436 overlay fix).2026-10-251802b525ccv1.1.0 @ ad78914e36