LayerFS for Herdr

previewv0.3.3

Each Herdr workspace is a LayerFS Branch: a new one in ~0.2 s, restored after restart.

jiangkoumo · for Herdr

Install

Paste this into a coding agent on the machine that will run it. It installs v0.3.3 at d2bf1a854b 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.3.3
Install LayerFS for Herdr 0.3.3 for me, in docker mode, on this Linux machine.

1. Check the tools: Linux, `node --version` (22 or newer), `docker info`, `herdr --version` (0.9 or newer), `git`, `jq`, and `cargo +1.85.1 --version` (if Rust 1.85.1 is missing, ask me before installing it with rustup). If anything is missing or this is not Linux, stop and tell me.
2. Clone https://github.com/Ephemeral-AI-Lab/layerfs and check out commit ad78914e36b258b360daf13aec164b5655814689 (v1.1.0 or later on main). Use exactly this commit: it is the one this version was tested with.
3. In that checkout build the daemon and the native binding: `cargo +1.85.1 build --manifest-path core/Cargo.toml --release --locked -p layerfs-daemon`, then `npm --prefix api install` and `npm --prefix api run build:native`. Expect `core/target/release/layerfs-daemon` and `api/binding/layerfs.node`.
4. Build the runtime image and the volume: `printf 'FROM node:22-trixie\nRUN apt-get update && apt-get install -y --no-install-recommends git procps\n' | docker build -t layerfs-rt:herdr -`, then `docker volume create layerfs-herdr`.
5. Install the plugin at the pinned commit: `herdr plugin install jiangkoumo/herdr-plugin-layerfs --ref d2bf1a854bded0a696381d04721a0c79d5af8cb0 --yes`.
6. Write the config: copy the plugin's `config.env.example` to `"$(herdr plugin config-dir layerfs)/config.env"`, keep the docker block, and set `LAYERFS_API` and `LAYERFS_DAEMON` to the checkout from step 2, `LAYERFS_IMAGE` to the output of `docker image inspect layerfs-rt:herdr | jq -r '.[0].Id'`, `LAYERFS_VOLUME=layerfs-herdr`, and `LAYERFS_STORE_PATH=/var/lib/docker/volumes/layerfs-herdr/_data/global/store.sqlite`. Herdr must run as a user that can read that path (root on a default Docker install); if it does not, stop and tell me.
7. Check it on a scratch repo: `git clone --depth 20 https://github.com/jiangkoumo/herdr-plugin-layerfs /tmp/lfs-check`, open it as a Herdr workspace (`herdr workspace create --cwd /tmp/lfs-check --label lfs-check`), then from a shell in that workspace run `LFS=$(herdr plugin list --plugin layerfs --json | jq -r '.result.plugins[0].plugin_root')`, `node "$LFS"/lfs.mjs init`, `node "$LFS"/lfs.mjs fork check` and `node "$LFS"/lfs.mjs list`. Expected: `imported`, `check ready`, and one open branch `check`. Then discard it from the new workspace with `node "$LFS"/lfs.mjs drop` and delete `/tmp/lfs-check`.

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.

Parallel agent workspaces in Herdr without copying your repo. Each workspace the plugin opens is a LayerFS Branch: forking one copies no file bytes, closing it saves it, and after Herdr or the machine restarts the plugin mounts the branches again and reopens their workspaces.

What it adds

Herdr actions, also runnable from a shell or by an agent as node <plugin_root>/lfs.mjs <command>:

  • init (LayerFS: import this repo): imports the focused repo’s HEAD as a LayerFS project.
  • fork (LayerFS: new branch workspace, or new named branch): forks the project, or the focused branch after saving it, and opens it as a workspace lfs:<name> whose first pane is inside the branch.
  • commit: saves the workspace on its branch.
  • drop: discards the workspace without saving.
  • reopen: mounts a saved branch again.
  • list (LayerFS: status): projects and branches.

Two hooks: closing a LayerFS workspace saves and unmounts it; on Herdr startup, branches whose mounts are gone are mounted and reopened.

How it works

The plugin calls @layerfs/agent from short Node processes that Herdr starts for each action and hook, and keeps a small state file mapping Herdr workspaces to branches. In docker mode (LayerFS main, Linux) the branch lives in the LayerFS Sandbox container and the workspace’s pane enters it with docker exec.

On Debian 13 (4 vCPU, Docker 29, Herdr 0.9.5) with a 603 MB repo: import 3.2 s, a new branch workspace 0.07–0.19 s, save 0.06 s, discard 0.4 s. A server restart and a reboot-style restart (containers stopped) both brought back all 3 workspaces with their saved files.

herdr plugin action invoke acts on the workspace focused in Herdr’s UI, so agents should run lfs.mjs directly: it then uses their own pane’s workspace.

You need

  • Linux with Docker, Node 22+, Herdr 0.9+, and Rust 1.85.1 to build LayerFS.
  • A LayerFS checkout at the pinned commit with the daemon and native binding built, a runtime image with git and a shell, and a Docker volume (the install prompt covers all three).

Limits

  • Docker mode reads the Store inside the Docker volume, so Herdr runs as a user that can read /var/lib/docker/volumes (root on a default install).
  • Edits a branch has not saved are lost if the machine reboots.
  • Uncommitted changes in the source repo are not imported; HEAD is.
  • The repository also has a native mode for macOS (each branch a host folder and a linked git worktree, shown under the repo in Herdr’s sidebar). It needs LayerFS PR #427, which is not on main, so it is not part of this listing.

Versions

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

VersionDatePlugin commitLayerFS
v0.3.3newestA failed fork or reopen now stops the Sandbox daemon that attempt created, through SDK sandbox.close, once its mounts are cleaned up; reused or shared daemons keep running.2026-10-26d2bf1a854bv1.1.0 @ ad78914e36
v0.3.2A failed fork is kept as a closed Branch with its error (reopen or drop to recover); reopen can adopt an existing Store Branch without a plugin record; fork from an agent pane outside the repo opens the Branch under the source repo.2026-10-26f2e7ba6b99v1.1.0 @ ad78914e36
v0.3.1drop [name] now cleans up closed Branches directly (no remount); optional --delete-git-branch deletes the Git branch only when merged. Store data is kept, so drop does not reclaim space.2026-10-2634dd08cc29v1.1.0 @ ad78914e36
v0.3.0Adds Branch merge (reports real conflicts, ignores each Branch's root .git link), keeps state until drop cleanup succeeds, and resolves the current Branch from cwd outside Herdr.2026-10-262bbd70880fv1.1.0 @ ad78914e36
v0.2.1First listing: docker mode on LayerFS main verified end to end on Debian 13; agents fork from their own pane.2026-10-25dba17fb30dv1.1.0 @ ad78914e36