arc afs 是 AFS 文件系统操作的命令组。每个子命令操作的都是一个 AFS 路径,比如 /src、/data 这类挂载出来的位置,不是你机器上的原始文件系统路径。
对照版本:arc 2.0.0-beta.50(commit a99fb2c37,main,2026-09-11)。复制 dump 前先跑 arc --version;钉住命令面的是 commit。
arc afs <subcommand> [options]跑 arc afs --help 看完整子命令列表。每个子命令都接受 概览 里说的全局 --json、--view <default|llm|human|json>、--instance / -i、--home <dir> 选项。--yaml 已删除(从未真正实现);改用 --json 或 --view json。
未识别的选项现在会被拒绝(Unknown argument: <name>,退出码 5),不会静默忽略——比如 arc afs ls --bogus-flag foo 会直接失败,而不是丢掉 --bogus-flag 继续跑。
命令作用在哪个实例上
arc afs 需要一个活着的实例才能跑。不带任何选项时,它连的是默认后台实例(用一条裸 arc service start 起的);如果没有实例在跑,每个 arc afs 子命令都会以非零退出,不会静默退回一个临时的 ad-hoc AFS:
$ arc afs ls /
ERROR: No AFS daemon is running for instance "default".
Start it with: arc service start
Or use --standalone for ad-hoc mode (no runtime state)--instance <name>/-i:全局选项。连到一个具名实例,而不是默认实例(用arc service list看你有哪些实例在跑)。省略即default--home <dir>:全局选项。实例根。用于arc service start(创建)、--standalone(ad-hoc)、arc did init。要指定作用在哪个实例,用--instance。两个都传且指向不同实例时命令失败--standalone:强制 ad-hoc 模式——直接从当前目录的.afs-config/config.toml加载 AFS,不连接任何正在运行的 daemon。没有运行时状态(你在别处加的挂载、活跃订阅等都看不到);会在 stderr 打印一行[standalone] not attached to any instance提醒你
arc service start --instance docs-demo --home ~/docs-demo # 起一个具名实例一次
arc afs ls / --instance docs-demo # 之后每次 afs 调用都显式点名读取与列目录
arc afs ls
列出目录内容。
用法
arc afs ls [path] [options][path](可选,默认/):要列出的 AFS 路径--depth <n>:最大列出深度(默认1)-l:详细列表格式,显示类型和大小-R:递归列出--limit <n>:返回条目数上限--max-children <n>:每个目录最多显示的子项数--pattern <glob>:用 glob 模式过滤条目
别名是 arc afs list。
-R 和显式给出的 --depth 互斥——-R 总是按深度 10 列出,同时给 --depth 会产生歧义,不知道该听谁的:
$ arc afs ls /demo -R --depth 2
ERROR: ls: --depth conflicts with -R (recursive always lists at depth 10) — choose one: drop --depth to use -R's depth of 10, or drop -R and pass --depth explicitly路径不存在时退出码是 1(不是 0 加空列表,也不是 5):
$ arc afs ls /demo/does-not-exist
ERROR: No data found for path: /demo/does-not-exist示例:递归、详细列表
arc afs ls /demo -l -R└── 📁 demo
├── 📄 notes.txt (fs:file) 15B
└── 📁 reports (fs:directory)
└── 📄 q1.txt (fs:file) 15Barc afs read
读文件内容。
用法
arc afs read [path] [options][path](位置参数,或用--path <path>,两者给一个即可,必须有一个):要读的路径--start-line <n>:起始行,1 起始,含边界--end-line <n>:结束行,1 起始,含边界;-1表示到文件末尾
别名是 arc afs cat。
示例
$ arc afs read /demo/notes.txt
Hello from AFS路径不存在时退出码是 1:
$ arc afs read /demo/does-not-exist.txt
ERROR: No data found for path: /demo/does-not-exist.txtarc afs stat
获取文件或目录信息。
用法
arc afs stat [path][path](位置参数,或用--path <path>,两者给一个即可,必须有一个):要查看的路径
示例
$ arc afs stat /demo/notes.txt
PATH=/demo/notes.txt
KIND=fs:file
SIZE=15
MODIFIED=2026-08-01T04:00:51.508Z路径不存在时退出码是 1,报错文本和退出码和 arc afs read 一样:
$ arc afs stat /demo/does-not-exist.txt
ERROR: No data found for path: /demo/does-not-exist.txtarc afs search
在一个 AFS 路径内搜索内容。
用法
arc afs search [path] [query][path](位置参数,或用--path <path>,两者给一个即可,必须有一个):搜索的路径[query](位置参数,或用--query <text>,两者给一个即可,必须有一个):搜索关键词
别名是 arc afs grep。不再别名 find——find 已删除(它搜的是内容,不是名字;要按名字过滤条目,改用 arc afs ls --pattern)。
示例
$ arc afs search /demo revenue
/demo/reports/q1.txtarc afs explain
解释 AFS 概念或某个路径。不带参数时打印总览(mount / path / uri 这几个概念);带上一个 topic 或一个真实的 AFS 路径时,就针对那个具体对象解释。
用法
arc afs explain [topic][topic]:概念名(mount、path、uri)或一个 AFS 路径,比如/src。也可以不用位置参数,改用--topic <value>传
示例
$ arc afs explain
AFS Overview
============
AFS (Agentic File System) is a virtual filesystem that unifies different data sources into a single namespace.
Core Concepts:
- mount: Mount a data source to a virtual path
- path: Virtual path, e.g., /src, /data
- uri: Data source address, e.g., fs://, git://, sqlite://
Data Flow:
User Path -> AFS -> /{mount} -> Provider -> Actual Data
Examples:
$ arc afs mount add /src fs:///path/to/source
$ arc afs ls /src
$ arc afs read /src/file.txtarc afs subscribe
订阅某个路径下的 AFS 事件;按 Ctrl-C 停止前,每行打印一条 JSON 事件。适合盯着一个挂载点看别的进程(构建工具、另一个 arc afs write、一个正在跑的 blocklet)改了什么。
用法
arc afs subscribe [path] [options][path](可选,默认/),比如/demo或/dev/code-agents。也可以不用位置参数,改用--path <value>传--type <pattern>,比如afs:write、afs:*(默认afs:write,支持通配符)
示例(一个终端里跑这条,另一个终端里跑 arc afs write /demo/hello.txt ...)
$ arc afs subscribe /demo
Subscribed to /demo (type=afs:write) — Ctrl-C to stop
{"type":"afs:write","path":"/demo/hello.txt","source":"fs","timestamp":1787870798884}写入与删除
arc afs write
往文件写内容。
用法
arc afs write [path] [content] [options][path](位置参数,或用--path <path>,两者给一个即可,必须有一个):要写的路径--content <text>:要写的内容--mode <mode>:replace(默认)、append、prepend、patch、create、update之一--patch <json>:patch 操作的 JSON 数组,配合--mode patch用--meta <key=value>:设置一个元数据字段,可重复--if-match <version>:乐观并发控制 token,来自之前一次stat/read/write的结果。当前版本和这个 token 不一致时,写入会被AFS_CONFLICT拒绝;不支持这个机制的 provider 会忽略这个参数(谁后写谁赢)
示例:先写后追加
$ arc afs write /demo/draft.txt --content 'first draft'
OK /demo/draft.txt
$ arc afs write /demo/draft.txt --content ' plus more' --mode append
OK /demo/draft.txt
$ arc afs read /demo/draft.txt
first draft plus morearc afs delete
删除文件或目录。
用法
arc afs delete [path] [options][path](位置参数,或用--path <path>,两者给一个即可,必须有一个):要删除的路径-r, --recursive:递归删除目录(默认false)--dry-run:只打印会删掉什么,不真的删--yes:跳过 TTY 确认提示(这个提示只在 stdin 是真实 TTY 时才出现;非交互场景——脚本、CI、本文档自己的这些示例——不管有没有--yes都不会卡在那里等)
别名是 arc afs rm。
示例:先预览,再删除
$ arc afs delete /demo/draft.txt --dry-run
Would delete /demo/draft.txt (dry-run)
$ arc afs stat /demo/draft.txt
PATH=/demo/draft.txt
KIND=fs:file
SIZE=21
$ arc afs delete /demo/draft.txt --yes
OK /demo/draft.txt执行 Action
arc afs exec
执行某个 provider 在指定路径上暴露的 action,比如 provider 自己定义的操作,不是单纯的文件读写。
用法
arc afs exec <executable_path> [options]executable_path(必填):要执行的 action 路径--args <json>:JSON 格式的参数,比如--args '{"key": "value"}'
不是每个挂载点都暴露 action。对一个连着正在跑的实例的纯 fs:// 挂载点调 action 路径,目前会得到一个通用的服务器错误,不是一条具体的信息——daemon 的 HTTP 层没有把这种情况下 AFS 底层的报错文本传上来:
$ arc afs exec /demo/.actions/foo
ERROR: Internal server error在 --standalone 模式下(没有 daemon 参与)同一条调用会得到那条具体的信息:
$ arc afs exec /demo/.actions/foo --standalone
ERROR: No actions available for path: /.actions/foo挂载管理
arc afs mount 是独立的子命令组,管理挂载了什么、挂在哪。
arc afs mount <subcommand> [options]arc afs mount add 写的是从当前目录往上找到的那个 .afs-config/config.toml——不管你有没有连着某个 --instance/--home。--home 会被直接拒掉(退出码 5),因为这个选项暗示改动会送到实例的 daemon,而它从来不会。--instance / -i 是全局的实例选择器:那个实例没在跑时,命令在 mount add 之前就失败。去掉 --home、换到正确的目录跑。要改一个正在跑的实例挂了什么 cd 进那个实例的 home 目录(就是你起它时 arc service start --home 传的那个),再跑 arc afs mount add,这样立刻对那个实例生效,不用重启。(AFS runtime boundaries 页里「mount add 不天然是一条 acceptance path」这条提醒背后的机制就是这个——从错误的目录跑 mount add,会让这个挂载出现在 mount list 里,却不出现在 ls 里。)
$ arc afs mount add /demo fs:///path/to/a/local/directory --instance docs-demo
ERROR: no instance named "docs-demo". `arc service list` shows 0
$ arc afs mount add /demo fs:///path/to/a/local/directory --home /Users/you
ERROR: --home is not supported by `arc afs mount add`. `arc afs mount` only reads and writes the `.afs-config/config.toml` found by walking up from the current directory; it never reaches an instance's daemon, so the selected instance would silently not see the change. Drop the flag to edit the cwd config, or mount into a running instance at runtime with `arc attach --to <daemon-url> --namespace <ns> --source <dir>`.cd ~/docs-demo # 这个实例的 --home 目录
arc afs mount add /demo fs:///path/to/a/local/directory
arc afs ls /demo --instance docs-demo # 立刻可见arc afs mount add
新增一个挂载。
用法
arc afs mount add <path> <uri> [options]path(必填):挂载路径,比如/srcuri(必填):provider URI,比如fs://./src--namespace <name>:挂载的 namespace--description <text>:挂载描述--sensitive-args <names>:要当作敏感凭证处理的字段名-s, --set <key=value>:直接设置一个凭证,可重复,跳过交互式输入--terminal:用终端 readline 收集凭证,而不是浏览器-f, --force:强制重新收集凭证,忽略缓存值
示例
$ arc afs mount add /demo fs:///path/to/a/local/directory
Mounted fs:///path/to/a/local/directory at /demoarc afs mount list
列出全部挂载。
用法
arc afs mount list [options]别名是 arc afs mount ls。没有 --namespace 过滤——当前目录的 .afs-config/config.toml 是一张表,没有按 namespace 分片这回事,所以传 --namespace 会被拒绝:
$ arc afs mount list --namespace anything
ERROR: --namespace is not supported by `arc afs mount list`. `arc afs mount` reads and writes the cwd `.afs-config/config.toml` as one table; there is no per-namespace slice. Drop --namespace.示例(只展示一条;你实际的列表会包含你加过的每一个挂载)
$ arc afs mount list
/demo -> fs:///path/to/a/local/directoryarc afs mount remove
取消一个挂载。
用法
arc afs mount remove <path> [options]path(必填,只能是位置参数):要移除的挂载路径。--help里也列了一个标[required]的--path选项,但把它当 flag 传、不按位置传,并不满足这个必填要求——照样报Not enough non-option arguments: got 0, need at least 1。永远按位置传这个路径--namespace <name>:不支持——arc afs mount把当前目录的.afs-config/config.toml当成一张表,没有按 namespace 分片这回事,所以remove --namespace foo会被拒绝(ERROR: --namespace is not supported by 'arc afs mount remove'),和mount list一样
别名是 arc afs mount rm。
示例
$ arc afs mount remove /demo
Unmounted /demo把路径当 --path 传、不按位置传是不行的,即便 --help 把它列成必填选项:
$ arc afs mount remove --path /demo
ERROR: Not enough non-option arguments: got 0, need at least 1arc afs mount validate
校验当前的挂载配置。
用法
arc afs mount validate示例
$ arc afs mount validate
Configuration is valid关于输出的说明
afs 命令连着一个正在跑的实例时——这是默认情况——完全不往 stderr 写东西 上的结果就是全部输出。启动日志属于 daemon,不属于你的 shell。
例外是 --standalone,因为那种模式下命令会在你自己的进程里把 AFS 启起来,这份启动日志就打到你的终端上。其中三行是不变的——一行说明当前是临时模式;一行回显它读到的是哪个/哪些 .afs-config/config.toml;再一行是来自 node:boot 的 warn 记录,只要 AFS_DID_SPACE_SCOPE_SECRET 没设置就会出现,说 DID Space 的 scope 脱敏是关的、目录名以明文存放:
[standalone] not attached to any instance — ad-hoc mode (no runtime state)
[standalone] config: /path/to/.afs-config/config.toml
{"ts":"…","level":"warn","service":"arc-node","ns":"node:boot","message":"[afs-loader] AFS_DID_SPACE_SCOPE_SECRET unset — DID Space scope de-identification is OFF (plaintext directories). Set the secret to enable; set AFS_DID_SPACE_REQUIRE_DEID=true to enforce."}把这个变量设上,第三行就没有了;把 AFS_DID_SPACE_REQUIRE_DEID=true 设上,则会把"没设置"变成直接报错。stderr 上再多出来的内容,是 node:boot 在汇报你这台机器自己的状况——比如某个挂载没能建立,或者调度器自己启动时打的一行 [code-agents] recover ok: ...——所以总行数因机器而异。认这三行,别去数行数。这些都不是命令结果本身的一部分,上面的示例里也都略掉了。