{"id":48794242,"url":"https://github.com/redis/agent-filesystem","last_synced_at":"2026-04-13T22:00:56.594Z","repository":{"id":350366908,"uuid":"1201821565","full_name":"redis/agent-filesystem","owner":"redis","description":null,"archived":false,"fork":false,"pushed_at":"2026-04-10T02:09:43.000Z","size":10638,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-04-10T04:07:03.915Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/redis.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-04-05T07:54:48.000Z","updated_at":"2026-04-10T02:09:46.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/redis/agent-filesystem","commit_stats":null,"previous_names":["redis/agent-filesystem"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/redis/agent-filesystem","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/redis%2Fagent-filesystem","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/redis%2Fagent-filesystem/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/redis%2Fagent-filesystem/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/redis%2Fagent-filesystem/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/redis","download_url":"https://codeload.github.com/redis/agent-filesystem/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/redis%2Fagent-filesystem/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31772642,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-13T20:17:16.280Z","status":"ssl_error","status_checked_at":"2026-04-13T20:17:08.216Z","response_time":93,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-04-13T22:00:39.933Z","updated_at":"2026-04-13T22:00:56.586Z","avatar_url":"https://github.com/redis.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Agent Filesystem\n\nAgent Filesystem, or AFS, gives agents a filesystem-shaped way to work with data, without being trapped in one machine's local disk.\n\nThe name is an explicit nod to the original Andrew File System (AFS): a shared filesystem built for distributed work. Agent Filesystem borrows that shared-filesystem inspiration and adapts it for agents, with Redis as the persistence and coordination layer.\n\nFilesystems are a great interface for agents because they already know how to read files, write files, search trees, run tools, and work in directories. But ordinary local filesystems have a few problems for agent workflows:\n\n- they are tied to one machine\n- they are hard to checkpoint, fork, and restore cleanly\n- they are awkward to share across agents, shells, and computers\n- they do not give you a simple saved source of truth\n\nAFS fixes that by:\n\n- storing workspace state in Redis\n- exposing the current workspace through sync or an optional live mount\n- letting you checkpoint and restore workspaces\n- letting you fork a workspace for parallel work\n\nIf you want the short version, AFS is:\n\n- a workspace system for agents\n- backed by Redis\n- with real directories for real tools\n\n## Why AFS Instead of the Usual Tools\n\nAFS is not trying to replace every mature filesystem or version-control tool.\n\nIf you need one shared live POSIX tree, use NFS, EFS, CephFS, NetApp, or another standard shared filesystem.\n\nIf you only need source-code branching and merging, use Git and `git worktree`.\n\nIf all work stays on one machine, local disk plus ZFS or Btrfs snapshots is simpler.\n\nAFS exists for a different shape of problem: agent workspaces that should feel like a normal directory, while also being easy to checkpoint, restore, fork, and move between machines.\n\n| If you need... | The usual good answer | Why AFS is different |\n| --- | --- | --- |\n| one shared live tree | NFS, EFS, CephFS, NetApp, SMB | AFS can expose a shared mount, but the main point is not the mount. The main point is a workspace model with checkpoints and forks. |\n| source-code branching | Git branches and `git worktree` | AFS is for whole workspaces, not just committed source. Notes, generated files, prompts, logs, scratch state, and code can all live in one workspace timeline. |\n| point-in-time rollback on one machine | ZFS or Btrfs snapshots | AFS gives you similar checkpoint and fork ideas, but with a remote saved source of truth that is not tied to one machine. |\n| normal local execution plus remote saved state | a hand-rolled sync or cache layer | AFS makes that model explicit: save state in Redis, sync or mount locally, run real tools, checkpoint when ready. |\n\nChoose something else when:\n\n- you need the strongest possible POSIX fidelity and multi-writer behavior across many clients\n- you mostly want a shared NAS for humans or services, not an agent workspace model\n- you only need Git-style branching for source code\n- you mostly store large binaries, media, or build artifacts\n\n## Why Redis\n\nRedis is not the reason to use AFS. The reason to use AFS is the workspace model above.\n\nRedis is the canonical store because it gives AFS a simple remote source of truth for workspace state, checkpoints, manifests, blobs, and metadata, while still letting agents work through normal local directories and mounts.\n\nLocal filesystems are already fast. AFS uses Redis so you can keep a remote, checkpointable, forkable source of truth without paying a huge performance penalty when you mount it locally.\n\nOn this machine, using AFS over NFS on macOS against a 33-file corpus with 7 benchmark rounds, the median timings looked like this:\n\n| Operation | Local median | AFS median |\n| --- | ---: | ---: |\n| read medium source file | 0.01 ms | 0.01 ms |\n| grep literal across corpus | 0.95 ms | 1.26 ms |\n| grep ignore-case across corpus | 1.69 ms | 3.07 ms |\n| walk tree | 0.15 ms | 0.11 ms |\n| overwrite a 2 KB file | 0.07 ms | 0.91 ms |\n| mkdir + rmdir | 0.06 ms | 2.34 ms |\n\nThe important pattern is:\n\n- reads, `ls`, and tree walks stay very close to local filesystem speed\n- search stays in the same low-millisecond range\n- writes and renames are slower than local disk, but still stay in low single-digit milliseconds\n\nSo AFS is not trying to beat your local SSD, and it is not trying to out-POSIX mature shared filesystems. It is trying to give you a remote, checkpointable, forkable workspace with enough performance that normal tools still feel normal.\n\n## Requirements\n\nAFS requires a Redis instance you provide.\n\nAFS does not start Redis for you, manage a local Redis server, or hide the\nconnection details behind a separate product flow. The CLI expects a reachable\nRedis address in `afs.config.json`, whether that Redis is local, containerized,\nhosted, or managed by something else.\n\n## 60-Second Quick Start\n\nBuild AFS:\n\n```bash\nmake\n```\n\nRun setup:\n\n```bash\n./afs setup\n```\n\nThe default path is sync mode: Redis stays the source of truth while AFS keeps\na real local folder up to date.\n\nDuring setup:\n\n- choose your Redis connection\n- keep sync mode (recommended) or choose live mount\n- choose a local path like `~/afs`\n\nSetup only writes `afs.config.json`. To start using AFS, create or import a\nworkspace, select it, and then start the service:\n\n```bash\n./afs workspace create my-repo\n./afs workspace use my-repo\n./afs up --mode sync\ncd ~/afs\nls\necho \"# Notes\" \u003e notes.md\n```\n\nIf you want to start the optional live mount instead:\n\n```bash\n./afs up --mode mount\n```\n\nIf you want to start it again later:\n\n```bash\n./afs up\n./afs status\n./afs down\n```\n\nIf you want to bring an existing folder into AFS:\n\n```bash\n./afs workspace import my-repo ./repo\n./afs workspace use my-repo\n./afs up --mode sync\n```\n\nIf you want to exclude local junk before importing, create a `.afsignore` file in that folder first.\n\nIf you want to save a known-good point:\n\n```bash\n./afs checkpoint create my-repo before-refactor\n```\n\nIf you want a second line of work:\n\n```bash\n./afs workspace fork my-repo my-repo-experiment\n```\n\n## Config File\n\nAFS stores CLI configuration in `afs.config.json` next to the `afs` binary.\nThe current config shape is nested and workspace-oriented:\n\n```json\n{\n  \"redis\": {\n    \"addr\": \"localhost:6379\",\n    \"username\": \"\",\n    \"password\": \"\",\n    \"db\": 0,\n    \"tls\": false\n  },\n  \"mode\": \"sync\",\n  \"currentWorkspace\": \"my-repo\",\n  \"localPath\": \"~/afs\",\n  \"mount\": {\n    \"backend\": \"none\",\n    \"readOnly\": false,\n    \"allowOther\": false,\n    \"mountBin\": \"\",\n    \"nfsBin\": \"\",\n    \"nfsHost\": \"127.0.0.1\",\n    \"nfsPort\": 20490\n  },\n  \"logs\": {\n    \"mount\": \"/tmp/afs-mount.log\",\n    \"sync\": \"/tmp/afs-sync.log\"\n  },\n  \"sync\": {\n    \"fileSizeCapMB\": 100\n  }\n}\n```\n\nNotable current rules:\n\n- Redis connection is required; there is no `useExistingRedis` or managed-Redis mode\n- `redisKey` is not a config setting anymore; workspace keys are derived internally\n- `workspace run` is gone; use sync mode, live mount mode, or `workspace clone`\n- `workRoot` is internal state, not a user-facing config field\n- `afs up --mode sync|mount` lets you switch the local surface from the CLI and persists the mode change\n\n## MCP Server\n\nAFS includes a workspace-first MCP server directly in the Go CLI:\n\n```bash\n./afs mcp\n```\n\nThat command serves MCP over stdio and is meant to be launched by an MCP\nclient on demand. A minimal config looks like:\n\n```json\n{\n  \"mcpServers\": {\n    \"afs\": {\n      \"command\": \"/absolute/path/to/afs\",\n      \"args\": [\"mcp\"]\n    }\n  }\n}\n```\n\nThe MCP surface is workspace-oriented: list/select/create/fork workspaces,\nread and edit files, grep a workspace, and create or restore checkpoints.\nFile-edit tools update the live workspace state and leave the workspace dirty\nuntil `checkpoint_create` is called explicitly.\n\n## The Basic Model\n\nAFS has two main concepts:\n\n- `workspace`: a codebase or state tree\n- `checkpoint`: a saved restore point inside that workspace\n\nTypical flow:\n\n1. Put a workspace into AFS with `workspace create` or `workspace import`\n2. Sync it to a normal local directory or expose it as a live mount\n3. Save stable moments with `checkpoint create`\n4. Fork it when you want a second line of work\n5. Restore a checkpoint if you want to go back\n\n## Local Surfaces\n\nThe simplest way to think about AFS is:\n\n- Redis stores the workspace state\n- AFS exposes that workspace locally either through sync mode or live mount mode\n- your editor, shell, and tools use the local folder like any other directory\n\n### Sync Mode\n\nSync mode is the default and recommended local surface.\n\n- `localPath` is a real directory on disk\n- `afs up --mode sync` starts a background sync daemon\n- local edits are reconciled with the live Redis-backed workspace root\n- `afs down` stops the sync daemon but does not remove workspace state\n\n### Live Mount Mode\n\nLive mount mode exposes the workspace directly as a Redis-backed filesystem.\n\n- `localPath` is the mountpoint\n- `afs up --mode mount` starts the mount daemon\n- edits go straight into the live Redis-backed workspace root\n- `afs down` unmounts the filesystem and stops the mount daemon\n\nOn macOS AFS uses NFS. On Linux AFS uses FUSE.\n\nBefore using live mount mode, create or import a workspace and select it with\n`afs workspace use \u003cworkspace\u003e`, and make sure `mount.backend` is configured\nto something other than `none`.\n\nCurrent macOS/NFS caveats:\n\n- overwriting the same path in place is not atomic under contention; a tight truncate-then-rewrite cycle can briefly expose an empty file to concurrent readers. If you need atomic replacement semantics, write a temp file and rename it over the destination.\n- macOS may create `._*` AppleDouble sidecar files on the NFS mount to preserve Finder metadata, resource-fork data, and some extended attributes. These files can show up in listings, tree walks, and grep results.\n\n## Most Useful Commands\n\n```bash\n./afs setup\n./afs config show --json\n./afs workspace create \u003cworkspace\u003e\n./afs workspace import \u003cworkspace\u003e \u003cdirectory\u003e\n./afs workspace list\n./afs workspace use \u003cworkspace\u003e\n./afs workspace clone \u003cworkspace\u003e \u003cdirectory\u003e\n./afs workspace fork \u003cworkspace\u003e \u003cnew-workspace\u003e\n./afs checkpoint create \u003cworkspace\u003e \u003cname\u003e\n./afs checkpoint list \u003cworkspace\u003e\n./afs checkpoint restore \u003cworkspace\u003e \u003cname\u003e\n./afs up\n./afs up --mode sync\n./afs up --mode mount\n./afs status\n./afs down\n```\n\nFor command help:\n\n```bash\n./afs --help\n./afs workspace --help\n./afs checkpoint --help\n```\n\n## `.afsignore`\n\n`afs workspace import` respects a `.afsignore` file in the source directory.\n\nUse it to skip things you do not want stored in AFS, like:\n\n- build output\n- caches\n- logs\n- machine-local settings\n- large temporary files\n\n`.afsignore` uses `.gitignore`-style patterns. For example:\n\n```gitignore\nnode_modules/\n.venv/\ndist/\n*.log\n.DS_Store\ntmp/\n```\n\nYou can also re-include something with `!`:\n\n```gitignore\n*.log\n!important.log\n```\n\nNotes:\n\n- `.afsignore` is only used when importing a directory into AFS\n- the `.afsignore` file itself is imported too, so the workspace keeps its own import rules\n- legacy `.rfsignore` files are still accepted, but `.afsignore` is the preferred name\n\n## What Gets Stored Where\n\n- Redis stores both the live workspace working copy and the immutable checkpoint history\n- `localPath` is the synced folder in sync mode or the mountpoint in live mount mode\n- `~/.afs` is reserved for AFS runtime state and internal local metadata\n- `afs.config.json` stores local CLI configuration next to the `afs` binary\n\nYou can think of Redis as the source of truth for both:\n\n- the live mutable workspace root\n- the explicit checkpoint history\n\nIn sync mode:\n\n- you work in the directory configured by `localPath`\n- AFS keeps that directory reconciled with the live Redis-backed workspace root\n- `afs down` stops the sync daemon but does not discard workspace state\n\nIn mounted filesystem mode:\n\n- you work in your chosen mountpoint\n- edits go straight into the live Redis-backed workspace root\n- `afs down` just unmounts; it does not create or sync a separate draft\n\n## Build\n\nBuild everything:\n\n```bash\nmake\n```\n\nInstall `afs` onto your `PATH`:\n\n```bash\nmake install\n```\n\nOther build targets:\n\n```bash\nmake module\nmake mount\nmake web-install\nmake web-server\nmake web-ui\nmake web-dev\nmake clean\nmake uninstall\n```\n\n## Web UI Dev\n\nTo run the local control plane and web UI together:\n\n```bash\n./afs setup        # once, if afs.config.json does not exist yet\nmake web-dev\n```\n\nThat target:\n\n- builds `afs-control-plane`\n- installs UI dependencies if `ui/node_modules` is missing\n- starts `afs-control-plane` on `http://127.0.0.1:8091`\n- starts the Vite dev server on `http://127.0.0.1:5173`\n- wires the UI to the control plane with `VITE_AFS_API_BASE_URL`\n\nIf you want to run the pieces separately:\n\n```bash\nmake web-server\nmake web-ui\n```\n\nYou can override the defaults at invocation time:\n\n```bash\nmake web-dev AFS_WEB_SERVER_ADDR=127.0.0.1:9001 AFS_WEB_API_BASE_URL=http://127.0.0.1:9001 AFS_WEB_UI_PORT=4173\n```\n\n## Clone a Workspace\n\nIf you want an explicit one-off local copy instead of a long-running sync or\nmount, clone the current saved head into a normal directory:\n\n```bash\n./afs workspace clone my-repo ~/src/my-repo\n```\n\n## Repo Contents\n\nThis repo includes:\n\n- the `afs` CLI\n- the Redis module\n- mount daemons for local filesystem access\n- the workspace-first MCP server built into `afs`\n- sandbox and web tooling\n\nBut if you are brand new here, start with:\n\n```bash\nmake\n./afs setup\n./afs workspace create demo\n./afs workspace use demo\n./afs up --mode sync\ncd ~/afs\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fredis%2Fagent-filesystem","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fredis%2Fagent-filesystem","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fredis%2Fagent-filesystem/lists"}