arc service 管理具名 AFS 後臺例項。arc afs、MCP 橋接、以及 blocklet 服務,都依賴一個正在執行的例項。
對照版本:arc 2.0.0-beta.48,commit 5a5316bde(main,2026-09-10)——不是釋出出去的那個同版本號二進位制;同一個 2.0.0-beta.48 曾同時對應兩份不同的構建,所以本頁釘的是 commit,不是 semver。arc service 現在是九個真子命令(arc service <verb> [options]),每個都有自己的 --help 和 Examples: 塊——不再是一條命令帶一個positional action choice 列表。--json 拒絕路徑在 ArcBlock/arc#5205 之後重測過(error 物件在 stdout——下面 --json 契約 再次糾正這一點);delete 在 ArcBlock/arc#5279 之後成為主動詞名(rm/remove 現在是 alias);子命令化和每條失敗行統一的 ERROR: 字首都來自 ArcBlock/arc#6301。例項名 positional 在 ArcBlock/arc#5713 退役:指定例項的唯一寫法是 --instance / -i。複製 dump 前先跑 arc --version;動詞和 flag 仍可能變。下面的 --help 是英文(LC_ALL=C)——ArcBlock/arc#5244 之後,幫助/報錯文本永遠是英文,不隨你系統的 locale 變化。
下面的例項名、home 路徑和連接埠都簡化成易讀的 docs514a / /tmp/arc-svc-docs-514/... 形式;報錯文本、欄位名、退出碼和 JSON 結構都是真實跑出來的原樣。
arc service <verb> [options]verb 是下面之一:list(ls、ps)、start、stop、restart、status、delete(rm、remove)、gc(prune)、url、logs(log)。用 --instance <name> / -i 指定例項。省略 --instance 即種子例項 default(home ~,連接埠 4900)。其它名字由核心分配連接埠,除非你傳 --port。
不要 stop / delete 你沒啟動的種子例項。本頁 dump 用的是一次性 registry,沒有碰本機 :4900 上的 default。
隔離
隔離靠具名例項加 --home。ARC_HOME 已退役:CLI 會警告並忽略取值。
export ARC_INSTANCES_DIR=/tmp/arc-svc-docs-514/instances
arc service start --instance docs514b --home /tmp/arc-svc-docs-514/home-bARC_SERVICE_PORT 仍在,但只作用於未具名的種子例項。優先用名字,或傳 --port。
下面 dump 省略了 stderr 上的 splash banner。
子命令
每個子命令都有自己的 --help 和自己的 Examples:(見本頁底部的 --help 一節)。arc service <壞動詞> 和不帶動詞的 arc service 都列印下面這張組級列表,不是某個動詞自己的。
| 子命令 | Alias | 作用 |
|---|---|---|
list | ls、ps | 列出每個本地例項的狀態、連接埠和 home |
start | 啟動一個例項;首次用即建立 | |
stop | 停下正在跑的例項,保留記錄和資料 | |
restart | 按記錄重啟例項——不接受重新配置;要改配置用 stop 再 start | |
status | 報告一個例項是否在跑,以及跑在哪個連接埠 | |
delete | rm、remove | 刪除一個例項:它的記錄和資料 |
gc | prune | 清掉處理程序已經不在了的註冊記錄 |
url | 列印例項的 base URL(以及它的 blocklet URL) | |
logs | log | 列印例項的 daemon 日誌 |
Flags
每個子命令都接受共享的全域 flag——--json、--view、--home、--instance / -i、--print——外加它自己的額外 flag:
| Flag | 子命令 | 含義 |
|---|---|---|
-i、--instance | 全部 | 這條命令作用在哪個本地 ARC 例項。省略即 default。指定例項的唯一寫法 |
--home | 全部 | 例項根。用於 start(建立)、arc did init。在 restart 上它是拿來跟記錄裡的 home 做一致性核對的,不是新配置——一致就是 no-op,指向別的路徑會被拒絕(見 失敗路徑) |
--print | 全部 | 把結果裡的單個欄位(例如 url、port)以純文本列印——不是一種 view,會覆蓋 --json/--view。見下面的 --print |
--port | start | 監聽連接埠(0–65535)。0 = 自動分配。省略時:default 用 4900,具名例項用記錄裡的連接埠或自動分配 |
--host | start | 繫結地址(localhost、0.0.0.0、:: 或單播 IP)。預設 localhost |
--advertise | start | 繫結非 loopback 時通過 mDNS 宣告(預設 true;--no-advertise 關閉) |
--blocklet | start | 要服務的 blocklet 父目錄或單個 blocklet 目錄(可重複)。記在例項上 |
--space-root | start | 用 arc space init 建好的 Folder-as-DID-Space。省略則從 --home 派生 |
--force | delete | 先停再刪。預設 false |
--dry-run | delete | 列印會刪掉什麼,不實際刪除。預設 false |
--yes | delete | 跳過 TTY 確認提示。預設 false |
--follow | logs | 流式輸出新寫入的行。預設 false |
--yaml 已刪除,從未真正實現——見 總覽。
restart 自己的 --help 裡沒有 start 那組配置 flag——傳了會被一條專門的報錯拒絕,不是 yargs 通用的「unknown argument」(那條通用路徑是真正被刪除的 flag,比如 --blocklet-dir,才會撞上的;見已刪除與已退役):
$ arc service restart --instance docs514a --port 4910
ERROR: restart does not reconfigure. use `stop` then `start` to change --port--home 是唯一的例外:它是全域 flag,所以 restart --home <和記錄一致的路徑> 會靜默成功(no-op),只有指向不同路徑才會被拒絕——報錯和退出碼都跟上面的配置 flag 守衛不一樣:
$ arc service restart --instance docs514a --home /tmp/somewhere-else
ERROR: --instance "docs514a" and --home "/tmp/somewhere-else" name different instances (instance "docs514a" is registered at "/tmp/arc-svc-docs-514/home-a")(退出碼 5,而 --port/--host/--advertise/--space-root/--blocklet 是 1。)
狀態
| 狀態 | 含義 |
|---|---|
starting | 記錄已佔用,處理程序還沒到 up |
up | 處理程序在聽連接埠 |
stopped | 經 stop 退出。start / restart 會複用這條記錄 |
dead | 處理程序沒經過乾淨 stop 就沒了。gc 只清這種 |
list 對每個非 up 的行都顯示記錄裡的連接埠,並加 * 字尾標註這是最後已知值而非即時值(stopped/dead 都會加);只有完全沒有記錄過連接埠時(一個從沒到過 up 的例項)才顯示 -:
NAME ID PORT STATUS HOME SOURCES
docs514a b719db414c5cc62 61497* stopped /tmp/arc-svc-docs-514/home-a 1status 的退出碼:up 是 0,starting / stopped 是 3,dead 是 4。非 up 時它照樣報上一次的 pid / port / URL,並明確標註(--json 裡是 lastKnown,人類視圖裡是一行 Note:)。
Start、list、status、url
空 registry:
$ export ARC_INSTANCES_DIR=/tmp/arc-svc-docs-514/instances
$ arc service list
NAME ID PORT STATUS HOME SOURCES
(no instances)啟動一個具名例項。連接埠 61497 是核心分配的,不是 4900:
$ arc service start --instance docs514a --home /tmp/arc-svc-docs-514/home-a
Instance: docs514a
ID: b719db414c5cc624
Status: up
PID: 95665
Port: 61497
URL: http://127.0.0.1:61497
Home: /tmp/arc-svc-docs-514/home-a
Space: /tmp/arc-svc-docs-514/home-a/.afs/spaces
Sources: -
Version: 2.0.0-beta.48
Commit: 5a5316bde
Checkout: /tmp/arc-svc-docs-514/project
Host: localhost
Started: 2026-09-10T01:52:25.130Z (up 2s)進度、日誌路徑、build id、endpoints 走 stderr。例項記錄走 stdout——這次捕獲的 stderr(banner 已省略):
Starting AFS service...
AFS Service started
Log: /tmp/arc-svc-docs-514/home-a/.afs/daemon.log
Build: 2.0.0-beta.48+5a5316bde (debug)
Exec: /path/to/arc/runtimes/node/dist/cli.mjs
Endpoints:
http://127.0.0.1:61497/ AUP Web Client
http://127.0.0.1:61497/explorer Explorer UI
http://127.0.0.1:61497/ws WebSocket (Explorer)
http://127.0.0.1:61497/afs/* REST API
http://127.0.0.1:61497/mcp MCP Streamable HTTPBuild / Exec 來自 daemon 啟動時寫的 <home>/.afs/daemon.build.json;老 daemon 沒有這個 sidecar 時這兩行直接不打,不猜。Version / Commit / Checkout 描述的是真正在服務這個例項的那個 binary——見下面的身份欄位。
用 --blocklet 記錄 blocklet 源(可重複)。同一個 flag 既接受父目錄,也接受單個 blocklet 目錄:
$ arc service start --instance docs514b --home /tmp/arc-svc-docs-514/home-b \
--blocklet /path/to/arc/blocklets/afs-preview-fixture --host 127.0.0.1 --no-advertise
Instance: docs514b
ID: b719db414c5cc625
Status: up
PID: 95666
Port: 61498
URL: http://127.0.0.1:61498
Home: /tmp/arc-svc-docs-514/home-b
Space: /tmp/arc-svc-docs-514/home-b/.afs/spaces
Sources: /path/to/arc/blocklets/afs-preview-fixture
Version: 2.0.0-beta.48
Commit: 5a5316bde
Checkout: /tmp/arc-svc-docs-514/project
Host: 127.0.0.1
Started: 2026-09-10T01:49:56.435Z (up 7s)這次的 stderr 在被省略的 banner 和 AFS Service started 之間多了一行 Extra blocklet dirs:,Endpoints: 之後多了一個 Blocklet: 塊:
Starting AFS service...
Extra blocklet dirs: /path/to/arc/blocklets/afs-preview-fixture
AFS Service started
Log: /tmp/arc-svc-docs-514/home-b/.afs/daemon.log
Build: 2.0.0-beta.48+5a5316bde (debug)
Exec: /path/to/arc/runtimes/node/dist/cli.mjs
Endpoints:
http://127.0.0.1:61498/ AUP Web Client
http://127.0.0.1:61498/explorer Explorer UI
http://127.0.0.1:61498/ws WebSocket (Explorer)
http://127.0.0.1:61498/afs/* REST API
http://127.0.0.1:61498/mcp MCP Streamable HTTP
Blocklet: afs-preview-fixture
http://afs-preview-fixture.localhost:61498/
http://localhost:61498/?blocklet=afs-preview-fixture (Safari / universal)$ arc service list
NAME ID PORT STATUS HOME SOURCES
docs514a b719db414c5cc624 61497 up /tmp/arc-svc-docs-514/home-a 0
docs514b b719db414c5cc625 61498 up /tmp/arc-svc-docs-514/home-b 1status 報得出 start 報過的每一件事——對一個不是你剛起的例項也一樣,stdout/stderr 的分法也一樣:
$ arc service status --instance docs514b
Instance: docs514b
ID: b719db414c5cc625
Status: up
PID: 95666
Port: 61498
URL: http://127.0.0.1:61498
Home: /tmp/arc-svc-docs-514/home-b
Space: /tmp/arc-svc-docs-514/home-b/.afs/spaces
Sources: /path/to/arc/blocklets/afs-preview-fixture
Version: 2.0.0-beta.48
Commit: 5a5316bde
Checkout: /tmp/arc-svc-docs-514/project
Host: 127.0.0.1
Started: 2026-09-10T01:49:56.435Z (up 3m)日誌路徑、build id、endpoints、blocklet URL,以及(非 loopback 繫結時的)LAN 診斷走 stderr;記錄走 stdout。start 和 status 對同一個例項報同一個 URL——兩邊都用登錄檔裡的 http://127.0.0.1:<port> 形式。加 --json 時 stderr 的這些塊不打,全部作為資料出現在 payload 裡。
如果這臺機器的 project root 裡有很多 blocklet,status 只展開你用 --blocklet 點名的那些,其餘只報個數——這是對著一個完整的 dev checkout 跑出來的真實數字,不是編的:
Blocklets: 51 route(s) served — 50 not expanded; `arc service url` or --json lists them all--json 裡的 urls.blocklets 永遠是全的。
$ arc service url --instance docs514b
http://127.0.0.1:61498/stderr(banner 已省略),和 start 同一套印表機:
Blocklet: afs-preview-fixture
http://afs-preview-fixture.localhost:61498/
http://localhost:61498/?blocklet=afs-preview-fixture (Safari / universal)$ arc service url --instance docs514b --print url
http://127.0.0.1:61498--print url 只把例項 URL 寫到 stdout(這次捕獲沒有尾斜槓),退出碼 0。$(arc service url --instance NAME) 仍是這一行。Agent 要 blocklet 地址用 --json 裡的 Host URL(http://afs-preview-fixture.localhost:…)。?blocklet= 是 Safari 兜底,掛不上 /blocklets/<name> 的 RPC。
身份欄位
Version / Commit / Branch / Sha / Checkout 描述的是服務這個例項的那個 binary,不是你敲的那個 arc。daemon 在啟動時算好並寫進自己的登錄檔行,所以在任何 shell 裡 status 出來的值,和 curl http://127.0.0.1:<port>/.well-known/arc/instance 一致。
對 up 的例項,status 會直接問 daemon,答案放在 live 裡:
"live": {
"ok": true,
"url": "http://127.0.0.1:61498/.well-known/arc/instance",
"record": { "version": "2.0.0-beta.48", "commit": "5a5316bde", "pid": 95666, "port": 61498, "blocklets": 1 }
}登錄檔行和 daemon 不一致時——arc upgrade 就是這種情況,它在處理程序不重啟的前提下換掉 binary——兩個值都報,不一致的欄位列在 drift 裡:
"drift": [{ "field": "version", "registry": "2.0.0-beta.48", "live": "2.0.0-beta.49" }]這個探針是盡力而為。如果處理程序還活著但 loopback 上一時沒人應答——這條是從一個被 SIGSTOP 暫停的 daemon 上抓到的,所以措辭是超時而不是拒絕連線——status 會退回純登錄檔檢視並說明原因,退出碼不變:
Live: unreachable (The operation was aborted due to timeout) — registry values only(處理程序徹底沒了而不只是暫時無應答時報的是 dead——見狀態——這種情況根本不做探針。)
Restart、logs、stop、delete、gc
restart 複用記錄,不接受新的 --port:
$ arc service restart --instance docs514b
Instance: docs514b
ID: b719db414c5cc625
Status: up
PID: 95700
Port: 61498
URL: http://127.0.0.1:61498
Home: /tmp/arc-svc-docs-514/home-b
Space: /tmp/arc-svc-docs-514/home-b/.afs/spaces
Sources: /path/to/arc/blocklets/afs-preview-fixture
Version: 2.0.0-beta.48
Commit: 5a5316bde
Checkout: /tmp/arc-svc-docs-514/project
Host: 127.0.0.1
Started: 2026-09-10T01:58:00.472Z (up 3s)stderr 打的是 AFS Service restarted(不是 started),其它跟上面 start 的 stderr 一樣。
$ arc service logs --instance docs514b
{"ts":"2026-09-10T01:58:01.683Z","level":"info","service":"arc-node","ns":"node:boot","message":"boot vault-ready +652ms"}
{"ts":"2026-09-10T01:58:01.686Z","level":"info","service":"arc-node","ns":"node:boot","message":"boot did-space-ready +656ms"}
{"ts":"2026-09-10T01:58:02.235Z","level":"info","service":"arc-node","ns":"node:boot","message":"[code-agents] recover ok: claimed=0 marked=0 orphaned=0 deferred=0 locksScanned=0 locksReclaimed=0"}後面的 boot 行省略。--follow 會先重打已有行再流式輸出。
$ arc service stop --instance docs514b
Service stopped: docs514bstopped 的例項照樣報上一次的 pid / port / URL,並且明說這些是歷史值(退出碼 3):
$ arc service status --instance docs514b
Instance: docs514b
ID: b719db414c5cc625
Status: stopped
PID: 95700
Port: 61498
URL: http://127.0.0.1:61498
Home: /tmp/arc-svc-docs-514/home-b
Space: /tmp/arc-svc-docs-514/home-b/.afs/spaces
Sources: /path/to/arc/blocklets/afs-preview-fixture
Version: 2.0.0-beta.48
Commit: 5a5316bde
Checkout: /tmp/arc-svc-docs-514/project
Host: 127.0.0.1
Started: 2026-09-10T01:58:00.472Z
Note: PID / Port / URL above are the LAST KNOWN values from this instance's previous run, not a live process.--json 裡同一件事是 "lastKnown": true,並且沒有 live 鍵——stopped 例項不做探針。list 對 PORT 打 <port>*(見狀態)。同名再 start 會複用記錄。
本頁每個程式碼塊都是獨立的一次捕獲;例項名在不同小節裡重複出現(docs514a、docs514b)並不意味著一條連續的工作階段——下面 delete 的四個例子都用全新的一次性名字,正因為這樣,它們誰都不是在刪一個前面例子已經刪掉的名字。
delete 現在對成功有兩種輸出形態,按 view 分——跟 arc afs delete 一樣的分法(ArcBlock/arc#6055):預設(機器、非 TTY)檢視是一句光禿禿的 OK <name>——write 的形狀——--view human 是一句說清楚刪了什麼的話。下面兩個例項在刪除前都是 stopped:
$ arc service delete --instance docs514x
OK docs514x
$ arc service delete --instance docs514y --view human
Removed instance "docs514y"正在跑的例項,delete 不帶 --force 會失敗——這也是 ArcBlock/arc#6301 字首修復真正體現出來的地方:本頁每一條失敗行現在都以 ERROR: 開頭,而舊的捕獲完全沒有字首:
$ arc service delete --instance docs514z
ERROR: instance "docs514z" is running. stop it first, or use --force--force 先停再刪——上面那條拒絕的 accept-path 對應項,同一個例項,同一個動詞:
$ arc service delete --instance docs514z --force --yes
OK docs514z--dry-run 只預覽,不動手,對 stopped 或 running 的例項都能用:
$ arc service delete --instance docs514w --dry-run
Would delete instance docs514w at /tmp/arc-svc-docs-514/home-w (dry-run)
$ arc service delete --instance docs514w --dry-run --json
{
"name": "docs514w",
"removed": false,
"home": "/tmp/arc-svc-docs-514/home-w",
"dryRun": true,
"homeRemoved": true
}homeRemoved 這裡的意思是「一次真正的執行會刪掉這個 home 目錄」,不是說已經刪了——同一個物件上的 removed: false / dryRun: true 已經說明了這一點;把這三個欄位放在一起讀,別只看 homeRemoved。
--yes 跳過互動式 TTY 確認。實際上這在真終端之外幾乎不起作用:確認本來就是只在 TTY 裡才問的設計(interactive 要求 stdin 和 stdout 都是真 TTY),所以 agent、管道、測試——包括產出本頁這些 dump 的那些呼叫——都不會看到那個提示,加不加 --yes 都一樣。給一個可能有一天會在終端裡跑的指令碼加上它仍然是對的。
gc 只收集 dead(處理程序沒走 stop 就沒了)。stopped 會留下:
$ arc service gc
Collected 1 dead instance
docs514dead
kept 1
$ arc service gc
No dead instances to collect之後 list 仍有 stopped 和 up 行;docs514dead 沒了。已經沒有 dead 時,gc 用一行說明這件事,退出碼仍然是 0。另一個完全空的 registry(零個已註冊例項,不是上面那個)用來說明 kept 是一個真的數,能數到 0,不是一個空答案——跟下面 --print 那條「渲染出零個字元,不是 falsy」的規則是同一條:
$ arc service gc --json
{
"removed": [],
"kept": 0
}--print
--print <field> 從命令的正常結果裡讀一個欄位,以純文本寫到 stdout,完全繞開 --json/--view。ArcBlock/arc#6301 改了「算沒算有值」的判據:以前是falsy(false、0、"" 都被當成不存在,列印為空還照樣退出 0——和一個真的空答案分不出來);現在是渲染出零個字元。false 和 0 分別是五個字元和一個字元,所以是真答案,照樣退出 0。查欄位用的是 Object.hasOwn,不是 in(後者會走原型鏈,讓 --print __proto__ 答出 {})。
Accept path——一個真實值是布林 false 的欄位照樣列印並退出 0(這個例項是用 --no-advertise 起的):
$ arc service status --instance docs514b --print advertise
falseAccept path——一個真實值是數字 0 的欄位照樣列印並退出 0(空 registry,所以 gc 的 kept 計數真的是零):
$ arc service gc --print kept
0(同一條規則也覆蓋 0 的連接埠;那個具體情形沒法從一次真實繫結裡跑出來——OS 從來不會真的把連接埠分配成 0——所以 CLI 自己的正控單測直接對一個合成的 { port: 0 } 物件跑:runtimes/node/test/daemon/service-print-contract.test.ts:135。)
Reject path——一個存在但沒有值的欄位(沒有 .git 的 checkout 上的 branch / sha / commit)會被拒絕,不是悄悄列印成空:
$ arc service status --instance docs514b --print branch
$ echo $?
1stderr(banner 已省略):ERROR: field "branch" in result has no value
Reject path——一個結果里根本不存在的欄位,報錯不一樣,退出碼一樣:
$ arc service status --instance docs514b --print nosuchfield
$ echo $?
1stderr:ERROR: no field "nosuchfield" in result
--print "" 以前被當成「沒給 --print」而落回完整的預設檢視——所以 arc service status --print "$FIELD" 在 $FIELD 沒設時會列印整個人類檢視,而不是報錯。現在不會了:空欄位名跟別的欄位名一樣被查,查不到,和上面 nosuchfield 一樣被拒絕:
$ arc service status --instance docs514b --print ""
$ echo $?
1stderr:ERROR: no field "" in result
--json 契約
只有成功時 JSON 才在 stdout。拒絕時 stdout 永遠是空的(0 位元組)——每一條失敗都是,不是「有些是」。 這糾正了本頁早先的一個說法,那時寫著拒絕路徑會把 { "error": "…" } 放到 stdout 上;對 arc service 來說那從來都不是真的,ArcBlock/arc#6301 的修復說明也確認修完之後的契約明確是它九個拒絕場景裡「stdout 0 位元組」。報錯文本走 stderr,帶 ERROR: 字首,處理程序以非零碼退出。
兩種不同的拒絕都落到同一個「stdout 0 位元組」形狀上——值得放在一起看,因為它們走的是不同的程式碼路徑:
$ arc service status --instance no-such-xyz --json
$ echo $?
1stderr:ERROR: no instance named "no-such-xyz". `arc service list` shows 2——這條根本沒走到動作自己的 executor,例項解析這一步就先失敗了。
$ arc service delete --instance docs514b --json
$ echo $?
1stderr:ERROR: instance "docs514b" is running. stop it first, or use --force——這條是在 delete 自己的 executor 裡跑的,executor 在成功解析出例項之後才決定失敗。
兩條路徑同一個形狀:stdout 空,stderr 帶 ERROR: 字首,退出碼非零。--json 對這些都沒有影響——它只改變一次成功的執行本來會列印什麼。
成功時,JSON 是人類檢視的超集。 終端打出來的每一條 URL / 主機名 / 路徑都在 payload 裡——logFile、endpoints、blockletUrls、lan、build——agent 永遠不需要去刮 stderr。
$ arc service status --instance docs514b --json
{
"name": "docs514b",
"id": "b719db414c5cc625",
"status": "up",
"port": 61498,
"url": "http://127.0.0.1:61498",
"home": "/tmp/arc-svc-docs-514/home-b",
"spaceRoot": "/tmp/arc-svc-docs-514/home-b/.afs/spaces",
"blocklets": [
"/path/to/arc/blocklets/afs-preview-fixture"
],
"pid": 95666,
"version": "2.0.0-beta.48",
"commit": "5a5316bde",
"branch": null,
"sha": null,
"checkout": "/tmp/arc-svc-docs-514/project",
"startedAt": "2026-09-10T01:49:56.435Z",
"urls": {
"ui": "http://127.0.0.1:61498/",
"blocklets": {
"afs-preview-fixture": "http://127.0.0.1:61498/?blocklet=afs-preview-fixture"
}
},
"host": "127.0.0.1",
"advertise": false,
"uptime": "3s",
"logFile": "/tmp/arc-svc-docs-514/home-b/.afs/daemon.log",
"endpoints": [
{ "url": "http://127.0.0.1:61498/", "label": "AUP Web Client" },
{ "url": "http://127.0.0.1:61498/explorer", "label": "Explorer UI" },
{ "url": "http://127.0.0.1:61498/ws", "label": "WebSocket (Explorer)" },
{ "url": "http://127.0.0.1:61498/afs/*", "label": "REST API" },
{ "url": "http://127.0.0.1:61498/mcp", "label": "MCP Streamable HTTP" }
],
"blockletUrls": {
"afs-preview-fixture": [
{ "url": "http://afs-preview-fixture.localhost:61498/", "label": "" },
{ "url": "http://localhost:61498/?blocklet=afs-preview-fixture", "label": "(Safari / universal)" }
]
},
"build": {
"id": "2.0.0-beta.48+5a5316bde (debug)",
"exec": "/path/to/arc/runtimes/node/dist/cli.mjs"
},
"live": {
"ok": true,
"url": "http://127.0.0.1:61498/.well-known/arc/instance",
"record": {
"version": "2.0.0-beta.48",
"commit": "5a5316bde",
"branch": null,
"sha": null,
"checkout": "/tmp/arc-svc-docs-514/project",
"pid": 95666,
"port": 61498,
"blocklets": 1
}
}
}欄位分組:前十個鍵是例項記錄;version … urls 來自登錄檔行;logFile … build 是人類檢視打過的那些;live / drift 是對活 daemon 的對帳。例項綁在非 loopback 地址上時會多一個 lan,整塊 LAN 診斷在它的 lines 裡。
list 只報記錄類欄位,不帶「列印過的事實」那幾個——它每行不打 banner,也不做探針。注意這裡 sha 有值(一個真的 git checkout),而上面單例項的例子裡是 null(一個沒有 .git 的 checkout)——兩個都是真的,來自兩次不同的執行:
$ arc service list --json
{
"instances": [
{
"name": "docs514a",
"id": "b719db414c5cc624",
"status": "up",
"port": 61497,
"url": "http://127.0.0.1:61497",
"home": "/tmp/arc-svc-docs-514/home-a",
"spaceRoot": "/tmp/arc-svc-docs-514/home-a/.afs/spaces",
"blocklets": [],
"pid": 95665,
"version": "2.0.0-beta.48",
"commit": "5a5316bde",
"branch": null,
"sha": "5a5316bdece751ee90416382b3ad851e565afa22",
"checkout": "/tmp/arc-svc-docs-514/project",
"startedAt": "2026-09-10T01:49:44.207Z",
"urls": { "ui": "http://127.0.0.1:61497/", "blocklets": {} },
"host": "localhost",
"advertise": true,
"uptime": "5s"
}
]
}list 每行的 version 就是那個例項真正在跑的 binary——一眼能看出哪些例項沒被 upgrade 覆蓋到。
$ arc service stop --instance docs514b --json
{
"name": "docs514b",
"id": "b719db414c5cc625",
"stopped": true,
"pid": 95700
}
$ arc service delete --instance docs514b --json
{
"name": "docs514b",
"removed": true,
"home": "/tmp/arc-svc-docs-514/home-b"
}--view json 和 --json 是同一個通道。
logs 是流,拒絕 --json——跟其它拒絕一樣的「stdout 0 位元組 / stderr 報錯」形狀:
$ arc service logs --instance docs514a --json
$ echo $?
1stderr:ERROR: logs is a stream and does not support --json
yargs 級錯誤(未知動詞、缺必填引數)同樣即使加了 --json 也不打 JSON——它們根本沒走到 --json 會起作用的地方,而是把子命令的 help 打到 stderr(見失敗路徑)。
失敗路徑
對已經 up 的例項再 start(退出碼 1)。提示語現在會點名你啟動時用的那個 --home,不只是光禿禿的動詞——因為 restart 在 start 時傳了 --home 的情況下也需要它:
$ arc service start --instance docs514b --home /tmp/arc-svc-docs-514/home-b
ERROR: instance "docs514b" is already running
pid 95666, port 61498, started 39s ago
use `arc service restart --instance docs514b --home /tmp/arc-svc-docs-514/home-b` or pick another namerestart --port(以及別的純配置 flag——具體哪幾個、為什麼 --home不一樣,見Flags)(退出碼 1):
$ arc service restart --instance docs514b --port 4910
ERROR: restart does not reconfigure. use `stop` then `start` to change --port--space-root 必須已經是 DID Space:
$ arc service start --instance docs514c --home /tmp/arc-svc-docs-514/home-c \
--space-root /tmp/arc-svc-docs-514/not-a-space
ERROR: /tmp/arc-svc-docs-514/not-a-space is not a DID Space. create it with `arc space init`未知動詞(退出碼 5)。yargs 把它當成「positional 不夠/不對」處理,把這個組的 --help(下面 --help 一節有全文)打到 stderr,兩者一起只加一次字首:
$ arc service foo
ERROR: Invalid values:
Argument: action, Given: "foo", Choices: list, start, stop, restart, status, delete, gc, url, logs
arc service
Manage AFS background service
Commands:
arc service list List every local instance with its status, port and home
[aliases: ls, ps]
...不帶動詞的裸 arc service 是同一個機制,原因不同(退出碼 5):
$ arc service
ERROR: Not enough non-option arguments: got 0, need at least 1
arc service
...多出來的 positional 例項名(動詞後面直接跟一個名字,沒有 --instance)在每個動詞上都會被拒絕,包括 list / gc——同一個機制,這次打的是子命令自己的 --help(退出碼 5):
$ arc service status somename
ERROR: positional instance name was removed; use `--instance <name>` / `-i`
arc service status
Report whether an instance is running, and on which port
...已刪除與已退役
這些以前寫進文件,現在沒了:
| 舊寫法 | 現在 |
|---|---|
arc service <action> [op] [dir] [options] | arc service <verb> [options] |
arc service <action> [name] | arc service <verb> --instance <name> / -i |
--blocklet-dir | --blocklet(父目錄或單個目錄) |
--save | 自動記在例項上 |
ARC_BLOCKLET_DIR | 已刪除。傳 --blocklet |
arc service blocklet-dir add/list | 已刪除 |
arc service restart --port 4900 | restart 拒絕配置 flag |
ARC_HOME | 已退役。 警告並忽略 |
真正被刪除的 flag 不再有專門的報錯——現在會撞上 yargs 自己的「未知引數」處理,它會給一個「Did you mean?」建議,並傾瀉子命令的 --help:
$ arc service start --instance docs514a --home /tmp/arc-svc-docs-514/home-a --blocklet-dir /tmp/nope
ERROR: Unknown arguments: blocklet-dir, blockletDir
Did you mean?
--blocklet
arc service start
...
$ arc service start --instance docs514a --home /tmp/arc-svc-docs-514/home-a --save
ERROR: Unknown argument: save
arc service start
...ARC_HOME 不受子命令化影響——警告照樣打,照樣在 banner 之前獨佔一行,而且不帶 ERROR: 字首(它是個 warning,不是 fail(),ArcBlock/arc#6301 的統一沒碰它):
$ ARC_HOME=/tmp/retired-home arc service list
warning: ARC_HOME is ignored; instance root comes from the service name and --home, not env--help
組級的 --help——未知動詞打出來的也是這個(見失敗路徑):
arc service
Manage AFS background service
Commands:
arc service list List every local instance with its status, port and home
[aliases: ls, ps]
arc service start Start an instance, creating it on first use
arc service stop Stop a running instance, keeping its record and data
arc service restart Restart an instance from its recorded config (does not
reconfigure — stop then start for that)
arc service status Report whether an instance is running, and on which port
arc service delete Delete an instance: its record and its data [aliases: rm,
remove]
arc service gc Drop registry records whose process is gone [aliases:
prune]
arc service url Print an instance's base URL (and its blocklets')
arc service logs Print an instance's daemon log [aliases: log]
Options:
--json Output in JSON format [boolean]
--view Output view format (json is equivalent to --json). llm is
accepted globally; commands without an llm renderer fail
closed (declare ⇒ execute; arc#6037). [string] [choices:
"default", "llm", "human", "json"] [default: "default"]
--home Instance root — to pick which instance, use --instance. Used
by `arc service start` (create) and `arc did init` (identity).
In `--standalone`, sets DID Space and configDir; mounts come
from a cwd-walk of `.afs-config/config.toml`, not from --home.
[string]
-i, --instance Named local ARC instance this command operates against (see
`arc service list`). Omit for the default instance. [string]
--print Print one result field (e.g. url, port) as plain text — not a
view; overrides --json/--view [string]
-h, --help Show help [boolean]
-v, --version Show version number [boolean]
Examples:
arc service list
Show every local instance
arc service start -i alice
Start (or create) named instance alice
arc service status -i alice
Is alice running, and on which port?
arc service logs -i alice
Print alice's recent daemon logs
arc service stop -i alice
Stop alice without deleting it
arc service delete -i alice --dry-run
Preview deleting instance alice without removing it九個子命令裡挑兩個自己的 --help——start(flag 最多的)和 delete(帶一組三個破壞性動詞專屬 flag 的)——看看其它七個跟的是什麼樣子:
arc service start
Start an instance, creating it on first use
Options:
--json Output in JSON format [boolean]
--view Output view format (json is equivalent to --json). llm is
accepted globally; commands without an llm renderer fail
closed (declare ⇒ execute; arc#6037). [string] [choices:
"default", "llm", "human", "json"] [default: "default"]
--home Instance root — to pick which instance, use --instance. Used
by `arc service start` (create) and `arc did init`
(identity). In `--standalone`, sets DID Space and configDir;
mounts come from a cwd-walk of `.afs-config/config.toml`,
not from --home. [string]
-i, --instance Named local ARC instance this command operates against (see
`arc service list`). Omit for the default instance. [string]
--print Print one result field (e.g. url, port) as plain text — not
a view; overrides --json/--view [string]
--port Port to listen on (0-65535). 0 = auto-assign. Omit: default
uses 4900; named instances use the recorded port or
auto-assign [number]
--host Bind address (localhost, 0.0.0.0, ::, or a unicast IP)
[string] [default: "localhost"]
--advertise Advertise this instance over mDNS when bind is non-loopback
(use --no-advertise to disable) [boolean] [default: true]
--blocklet Blocklet-parent or single-blocklet dir to serve
(repeatable). Recorded on the instance. [array]
--space-root Folder-as-DID-Space created with `arc space init` (omit to
derive from home) [string]
-h, --help Show help [boolean]
-v, --version Show version number [boolean]
Examples:
arc service start -i alice
Start (or create) named instance alice
arc service delete
Delete an instance: its record and its data
Options:
--json Output in JSON format [boolean]
--view Output view format (json is equivalent to --json). llm is
accepted globally; commands without an llm renderer fail
closed (declare ⇒ execute; arc#6037). [string] [choices:
"default", "llm", "human", "json"] [default: "default"]
--home Instance root — to pick which instance, use --instance. Used
by `arc service start` (create) and `arc did init` (identity).
In `--standalone`, sets DID Space and configDir; mounts come
from a cwd-walk of `.afs-config/config.toml`, not from --home.
[string]
-i, --instance Named local ARC instance this command operates against (see
`arc service list`). Omit for the default instance. [string]
--print Print one result field (e.g. url, port) as plain text — not a
view; overrides --json/--view [string]
--force Stop a running instance before deleting it [boolean] [default:
false]
--dry-run Print what would be removed without deleting it [boolean]
[default: false]
--yes Skip the TTY confirmation prompt [boolean] [default: false]
-h, --help Show help [boolean]
-v, --version Show version number [boolean]
Examples:
arc service delete -i alice --dry-run
Preview deleting instance alice without removing it其餘七個(stop、restart、status、gc、url、logs,再加組自己的 list)跟上面 start/delete 長得一樣,少的是本頁Flags表裡已經限定給 start/delete/logs 的那些——logs 只多一個 --follow。
--json、--view、--home、--instance / -i 都是全域選項(只宣告一次,作用於每一條 arc 命令)。--home 是例項根;要指定作用在哪個例項,用 --instance。見 總覽。