CLI
The Arble CLI is a complete client, not a companion to the desktop app. Every capability the UI exposes — sessions, agents, memory, permissions, connectors, desktop and mobile control — is reachable from the terminal, with the same permission gate and the same audit log behind it.
This makes Arble scriptable. An agent run you’d normally start by typing into a window can instead be a line in a Makefile, a cron entry, or a step in CI. The CLI is the same client the app uses, talking to the same local daemon, so there’s no drift between what you can automate and what you can do by hand.
Installation
The CLI is a single static binary with no runtime dependency. It talks to the Arble daemon over a local socket when one is running, and over HTTPS when you point it at a remote endpoint.
macOS. Homebrew is the supported path:
brew install arble/tap/arble
Linux. The install script detects your architecture and places the binary
in /usr/local/bin:
curl -fsSL https://arble.ai/install.sh | sh
Windows. Use winget, or download the standalone .exe from the
releases page:
winget install Arble.CLI
npm. Useful when you want the CLI pinned per-project rather than installed globally:
pnpm add -D @arble/cli
Standalone binary. Download and verify a release directly when you can’t use a package manager. Checksums and signatures are published alongside each artifact:
curl -fsSLO https://releases.arble.ai/v1.8.2/arble-linux-arm64
Docker. The image ships the CLI with no daemon, for CI and headless use. Mount a config directory to persist credentials between runs:
docker run --rm -v ~/.arble:/root/.arble arble/cli:1.8 agents ls
Confirm the install and see which daemon you’re connected to with
arble version.
Authentication
The CLI authenticates once and stores a credential in the OS keychain — not in a
config file. Everything after that reads the stored credential unless you override it with
ARBLE_API_KEY.
Login. Opens a browser for the device authorization flow, then writes the
credential to the keychain. API token. For headless environments where no
browser exists, create a token in the dashboard and export it — the CLI prefers
ARBLE_API_KEY over the keychain when both are present.
arble login
export ARBLE_API_KEY=arb_live_9f2c...
Local mode vs remote mode. By default the CLI connects to the daemon on your machine, and nothing leaves the device. Setting an endpoint switches it to a hosted or self-hosted Arble instance:
arble config set endpoint https://arble.internal.example.com
Local mode still requires login — the credential identifies you to your own daemon, which is what makes the audit log meaningful on a shared machine.
Organizations. An account can belong to several organizations; commands operate against the active one. Profiles. A profile bundles an endpoint, an organization and a credential under one name — use them to keep a local machine, a staging instance and a production instance separate without re-authenticating.
arble orgs ls
arble orgs use acme-eng
arble profiles ls
arble profiles use staging
Check what the CLI thinks it is before running anything destructive:
$ arble whoami
lori@example.com
org acme-eng
profile staging
endpoint https://arble.internal.example.com
scopes sessions:write agents:run memory:read
To drop the credential from the keychain, run arble logout.
Projects
A project scopes everything Arble does: which memory an agent reads, which permissions are
already granted, which connectors are available. A directory becomes a project when it has
an arble.json, the same way a directory becomes a repository when it has a
.git.
arble projects create api-gateway # initialize arble.json here
arble projects use billing-web # set the active project
arble projects rm infra-tooling # delete the project and its memory
$ arble projects ls
NAME SESSIONS MEMORY UPDATED
api-gateway * 3 2.4 MB 12m ago
billing-web 0 840 KB 3d ago
infra-tooling 1 6.1 MB 1h ago
Inside a directory with an arble.json the active project is inferred, so
use is rarely needed. Pass --project to any command to override it
for a single invocation — the pattern kubectl uses for namespaces.
Sessions
A session is a conversation with accumulated context: the messages, the tool calls, and the permission grants made along the way. Agents run inside sessions. Killing a session discards its context; pausing it keeps the context and stops the work.
arble sessions new --title "Payment retry audit"
arble sessions resume ses_3pLwRt9 # reattach, context intact
arble sessions pause ses_8kQ2mVx # stop agents, keep context
arble sessions kill ses_8kQ2mVx # end and release context
$ arble sessions ls
ID TITLE STATE AGENTS AGE
ses_8kQ2mVx Payment retry audit running 2 4m
ses_3pLwRt9 Migrate auth handlers paused 0 2h
ses_7nBcYs4 Flaky test triage completed 0 1d
A paused session costs nothing. Export writes the full transcript — messages, tool calls, arguments, results and approvals — as JSON. This is the artifact to attach to an incident review:
arble sessions export ses_7nBcYs4 --format json > triage.json
Running agents
arble run is the primary command. It takes an instruction, plans, calls tools,
and streams what it’s doing.
Single agent. Runs in the foreground and streams to your terminal. Ctrl-C cancels cleanly, mid-tool-call:
arble run "Find every handler that retries without a backoff and list the files"
Multiple agents. Fan out independent work across parallel agents in one session. Each gets its own context; results are collected when all finish:
arble run \
--parallel \
--task "Audit the retry logic in services/payments" \
--task "Audit the retry logic in services/billing" \
--task "Audit the retry logic in services/webhooks"
Background agents. Returns immediately with an agent ID; the work continues after your shell exits. Detached mode is the same plus surviving a daemon restart, for work measured in hours.
$ arble run --background \
"Reproduce the failing integration suite and summarize the first failure"
agt_5wTn9Kd started session=ses_8kQ2mVx
arble agents attach agt_5wTn9Kd # reattach to a running stream
arble agents ls
arble agents kill agt_5wTn9Kd
Interactive mode opens a REPL against a session — the terminal equivalent of the desktop window. Streaming mode emits newline-delimited events instead of rendered output, which is the form to pipe into another process:
arble run --interactive --session ses_3pLwRt9
arble run --stream json "List the open PRs touching services/payments" \
| jq -r 'select(.type=="tool_call") | .tool'
Memory
Memory is per-project and persistent. Agents read it automatically at the start of a run and write to it when they learn something durable. The CLI gives you direct access so you can seed it, inspect it, and prune it.
arble memory search "why we pinned the postgres driver"
arble memory add "Staging shares the production Redis. Never flush from staging."
arble memory rm mem_2fQx8Lp
arble memory summarize --older-than 90d
arble memory export > memory.json
Search is semantic, not substring, and returns ranked entries with their source.
summarize collapses related entries into fewer, denser ones — worth
running on a project that’s been active for months, since a smaller memory means less
context spent per run.
Memory is not a log. Entries should be facts that stay true — a
constraint, a decision, a gotcha — not a record of what happened in one session. Use
arble sessions export for that.
Skills
A skill is a packaged procedure: instructions, and optionally the tools and files that go with it. Where a tool is a single capability, a skill is a way of working — a deploy checklist, a review standard, a release process.
arble skills install @acme/release-checklist
arble skills install ./skills/incident-review # local path
arble skills disable @arble/pr-description # hidden from the planner
arble skills update @acme/release-checklist # compatible range
arble skills install @acme/release-checklist@2.0.4 # pin exactly
arble skills rm @arble/pr-description
$ arble skills ls
NAME VERSION STATE SCOPE
@acme/release-checklist 2.1.0 enabled project
@acme/incident-review 0.4.2 enabled project
@arble/pr-description 1.0.0 disabled global
Disabling is the right way to narrow what an agent considers, rather than uninstalling. Skills are pinned by default.
Connectors
A connector is an authenticated link to an external account. Enabling one adds its tools to the registry; authenticating it makes those tools usable.
arble connectors enable notion
arble connectors disable slack # revoke tool access, keep the credential
arble connectors auth linear # run or refresh the OAuth flow
arble connectors status github # scopes, expiry, last call, tools
$ arble connectors ls
NAME STATE AUTH TOOLS
github enabled ok 8
slack enabled ok 4
linear enabled expired 6
notion disabled — 0
postgres enabled ok 3
Disabling revokes tool access immediately without discarding the credential, which is the right move when you want an agent to stop being able to reach something for a while.
MCP
Arble speaks Model Context Protocol natively. An MCP server’s tools land in the same registry as built-in tools and pass the same permission gate. See MCP server for the protocol details; this section covers the commands.
arble mcp add postgres --command "npx -y @modelcontextprotocol/server-postgres"
arble mcp add acme-internal --url https://mcp.acme.example.com/mcp
arble mcp permissions postgres # per tool, not per server
arble mcp rm acme-internal # its tools leave the registry immediately
$ arble mcp health
SERVER TRANSPORT STATUS LATENCY VERSION TOOLS
postgres stdio connected 11ms 2.0.1 3
acme-internal http connected 130ms 0.9.4 9
github stdio error — 1.4.2 0
Run arble mcp health first when an agent reports a tool as unavailable.
Permissions
Every tool call passes a permission gate, whether it originated in the desktop app, a CI job, or your shell. The CLI is where you inspect and change the rules.
arble permissions grant filesystem.write --scope "~/Projects/api-gateway"
arble permissions grant network.http --scope "api.github.com"
arble permissions revoke network.http --scope "api.github.com"
arble permissions grant github.create_pr --always
arble permissions revoke terminal.exec --always
$ arble permissions audit --since 24h
TIME AGENT TOOL DECISION SCOPE
14:02:11 agt_5wTn9Kd filesystem.read auto ~/Projects/api-gateway
14:02:19 agt_5wTn9Kd github.create_pr approved acme/api-gateway
14:03:40 agt_5wTn9Kd postgres.query denied production
In the foreground, a call needing approval pauses and prompts. In --background
or CI it fails closed instead — an unattended run never silently grants itself
something. Declare the full set up front and use --no-prompt so the job fails
fast on anything you didn’t anticipate rather than hanging on a prompt no one will
answer.
Desktop
Desktop control is built in, not a connector — the CLI drives the machine the daemon
runs on. Every command here requires the desktop permission and appears in the
audit log.
arble desktop open "Figma"
arble desktop open ~/Documents/spec.pdf
arble desktop screenshot --window "Safari" --out ./shot.png
arble desktop clipboard read
echo "hello" | arble desktop clipboard write
arble desktop windows ls
arble desktop windows focus "Terminal"
arble desktop click 640 480 # screen points, origin top-left
arble desktop type "SELECT count(*) FROM orders;"
arble desktop key cmd+shift+4
arble desktop run ./automations/export-report.yaml
Chain steps from a file rather than a long shell pipeline, so the sequence is reviewable and rerunnable.
Mobile
A paired phone is addressable from the terminal. Pair once with
arble mobile pair; after that the device appears as a target for these commands.
arble mobile notify "Migration finished — 14 tables, 0 errors"
arble mobile clipboard write "https://github.com/acme/api-gateway/pull/482"
arble mobile open "shortcuts://run-shortcut?name=Standup"
arble mobile shortcut "Log Deploy"
arble mobile camera --out ./whiteboard.jpg
arble mobile mic --duration 30s --transcribe
Camera and microphone always prompt on the device itself, regardless of CLI flags. There is no way to capture silently.
Automation
Anything you can run once, you can run on a schedule or in response to an event. Automations are defined from the CLI and stored server-side, so they run whether or not your shell is open.
Schedules use cron syntax, evaluated in the project’s timezone. Triggers are event-driven, firing on a webhook or a connector event:
arble schedule create nightly-triage \
--cron "0 7 * * 1-5" \
--task "Summarize failing CI runs from the last 24 hours and post to #eng-alerts"
arble triggers create pr-review \
--on github.pull_request.opened \
--max-retries 3 \
--task "Review the diff against @acme/release-checklist and comment"
arble schedule ls
arble jobs ls
arble jobs logs job_4hVn2Qs
Every scheduled or triggered run becomes a job, inspected the same way regardless of what started it. Jobs in the same queue run serially; different queues run in parallel — use one queue per resource that can’t tolerate concurrent writes. Retries use exponential backoff, and only errors the tool marked retryable are retried; a permission denial is never retried.
Logs
Logs are structured records of what ran. Every line carries a session ID, an agent ID and a tool name, which is what makes filtering useful rather than decorative.
arble logs --follow # live, current project
arble logs --since 2h --until 30m # time-bounded
arble logs --agent agt_5wTn9Kd --tool postgres.query --level error
arble logs --grep "connection refused" --since 7d
arble logs --json --since 1h \
| jq -r 'select(.level=="error") | "\(.tool)\t\(.message)"'
arble logs --follow --json >> ~/.arble/logs/api-gateway.ndjson
Narrowing flags intersect. --json emits newline-delimited objects — the
shape to pipe into jq, or ship to a log aggregator.
Observability
Metrics answer a different question than logs: not what happened in one run, but whether runs are getting slower, more expensive, or less reliable.
$ arble metrics --since 7d
RUNS 412
SUCCESS 94.2%
p50 DURATION 18s
p95 DURATION 2m41s
TOOL CALLS 3,891
RETRIES 57
MEMORY 2.4 MB
arble metrics tools --sort p95 --since 7d # slowest calls first
arble metrics failures --since 7d # grouped by error
arble metrics retries --since 7d
arble metrics tools --sort calls
arble metrics memory
High retry counts on a single tool usually mean a flaky upstream, not a flaky agent. Call
counts by tool are how you find a connector that’s installed but never chosen —
and either fix its description or remove it. Memory growth without bound is a signal to run
arble memory summarize. Add --json to any metrics command to feed a
dashboard.
Configuration
Configuration resolves in this order, most specific first: command-line flags, environment
variables, project arble.json, then the user config file. This means a project
can set a default that CI overrides without editing anything.
Config file. ~/.arble/config.toml holds profiles and global
defaults. Credentials are never written here:
[profiles.local]
endpoint = "unix:///var/run/arble.sock"
org = "acme-eng"
[profiles.staging]
endpoint = "https://arble.staging.example.com"
org = "acme-eng"
log_level = "debug"
Project config. arble.json is checked into the repository and
shared with your team, setting defaults for anyone working in the directory:
{
"project": "api-gateway",
"skills": ["@acme/release-checklist@2.1.0"],
"connectors": ["github", "postgres"],
"permissions": {
"filesystem.write": ["./src", "./tests"],
"network.http": ["api.github.com"]
}
}
Secrets are stored in the keychain and referenced by name; values are never printed, and are redacted from logs and traces. Workspaces group several projects that share memory and connectors — the right structure for a monorepo where one agent needs to reason across services.
arble config get endpoint
arble config set log_level debug
arble secrets set GITHUB_TOKEN
arble secrets ls
arble workspaces create platform --projects api-gateway,billing-web
Debugging
-v shows tool calls and decisions; -vv adds full arguments and
results. Both write to stderr, so piping stdout still works.
A trace is the complete record of one run: every call, its arguments, its result, its duration, and the permission decision that let it through. The tree rendering is faster to read when you’re looking for where a run went wrong:
$ arble trace agt_5wTn9Kd --tree
run Fix the failing auth test 41.2s
├─ filesystem.read tests/auth_test.py 0.1s
├─ terminal.exec pytest tests/auth_test.py -x 12.8s
├─ filesystem.read src/auth/session.py 0.1s
├─ filesystem.write src/auth/session.py 0.1s
└─ terminal.exec pytest tests/auth_test.py -x 27.9s
arble trace agt_5wTn9Kd --timing # sort spans by duration
arble permissions audit --agent agt_5wTn9Kd
When a run stops early, permissions audit usually explains it before the trace
does. --dry-run plans and prints the tool calls an agent would make without
executing any of them — use it before pointing an unfamiliar automation at
production:
arble run --dry-run \
"Drop the staging replica and recreate it from the latest snapshot"
Scripting
The CLI is designed to compose. Human-readable output goes to stdout, diagnostics to stderr,
and --json makes any command machine-readable. Exit codes are meaningful, so
set -e behaves.
#!/usr/bin/env bash
set -euo pipefail
result=$(arble run --json --no-prompt \
"List files in src/ that import the deprecated retry helper")
count=$(echo "$result" | jq '.files | length')
if [ "$count" -gt 0 ]; then
arble mobile notify "$count files still use the deprecated retry helper"
fi
In PowerShell, ConvertFrom-Json gives you objects directly. For anything with
real control flow, drive the CLI as a subprocess rather than parsing rendered output:
$result = arble run --json --no-prompt "Summarize open PRs older than 14 days" |
ConvertFrom-Json
$result.summary | Set-Content pr-report.md
import json, subprocess
out = subprocess.run(
["arble", "run", "--json", "--no-prompt",
"Audit retry logic in services/payments"],
capture_output=True, text=True, check=True,
)
report = json.loads(out.stdout)
With cron, use an absolute path and set the profile explicitly — cron’s
environment is not your shell’s. Prefer arble schedule where you can:
scheduled runs get retries, queueing and job logs, which a cron entry does not.
0 7 * * 1-5 ARBLE_PROFILE=local /usr/local/bin/arble run \
--no-prompt "Summarize overnight CI failures"
CI/CD
In CI, run in remote mode with a scoped API token. Grant only the permissions the job needs,
and always pass --no-prompt so an unexpected approval fails the build instead of
hanging it.
# GitHub Actions
- name: Review the diff
env:
ARBLE_API_KEY: ${{ secrets.ARBLE_API_KEY }}
ARBLE_PROJECT: api-gateway
run: |
arble run --no-prompt --json \
"Review the changes in this PR against @acme/release-checklist" \
> review.json
# GitLab CI
review:
image: arble/cli:1.8
variables:
ARBLE_PROJECT: api-gateway
script:
- arble run --no-prompt "Review the changes on this branch"
Azure DevOps, Jenkins, Buildkite and CircleCI all follow the same shape:
install the CLI or use the Docker image, expose ARBLE_API_KEY from the
platform’s secret store, and invoke arble run --no-prompt. Nothing about
the CLI is platform-specific — if it runs a shell and holds a secret, it works.
// Jenkins
withCredentials([string(credentialsId: 'arble-key', variable: 'ARBLE_API_KEY')]) {
sh 'arble run --no-prompt "Summarize the changes in this build"'
}
Two rules for any pipeline: use a token scoped to exactly the permissions the job needs, and
treat a nonzero exit as a real failure rather than something to || true away.
Command reference
Every command accepts --json, --project, --profile
and -v. arble help <command> is authoritative — this
table is a map, not a spec.
Authentication & projects
| Command | Description |
|---|---|
| arble login | Authenticate and store a credential in the keychain |
| arble logout | Remove the stored credential |
| arble whoami | Show the active identity, org, profile and endpoint |
| arble orgs ls|use | List or switch organizations |
| arble projects create | Initialize a project in the current directory |
| arble projects ls | List projects |
| arble projects use | Set the active project |
| arble projects rm | Delete a project and its memory |
Sessions & agents
| Command | Description |
|---|---|
| arble sessions new | Create a session |
| arble sessions ls | List sessions and their state |
| arble sessions resume | Reattach with context intact |
| arble sessions pause | Stop agents, keep context |
| arble sessions kill | End the session |
| arble sessions export | Export the full transcript |
| arble run | Run an agent |
| arble agents ls | List running agents |
| arble agents attach | Attach to a running agent’s stream |
| arble agents kill | Cancel an agent |
Memory, skills, permissions
| Command | Description |
|---|---|
| arble memory search | Semantic search |
| arble memory add|rm | Add or delete an entry |
| arble memory summarize | Collapse related entries |
| arble memory export | Export as JSON |
| arble skills install|rm | Install from registry or path, or uninstall |
| arble skills ls | List installed skills |
| arble skills enable|disable | Toggle planner visibility |
| arble skills update | Update within the compatible range |
| arble permissions grant|revoke | Grant or revoke a capability, optionally scoped |
| arble permissions ls | Show current rules |
| arble permissions audit | Show what ran under them |
Connectors & MCP
| Command | Description |
|---|---|
| arble connectors ls | List connectors and state |
| arble connectors enable|disable | Toggle tool access |
| arble connectors auth | Run or refresh the OAuth flow |
| arble connectors status | Scopes, expiry and contributed tools |
| arble mcp add|rm | Add or remove a local or remote server |
| arble mcp ls | List servers |
| arble mcp health | Probe status, latency and version |
| arble mcp permissions | Inspect per-tool permissions |
Desktop, mobile, automation
| Command | Description |
|---|---|
| arble desktop open | Open an app or file |
| arble desktop screenshot | Capture screen or window |
| arble desktop clipboard | Read or write the clipboard |
| arble desktop windows | List or focus windows |
| arble desktop click|type|key | Simulate input |
| arble desktop run | Run an automation file |
| arble mobile pair | Pair a device |
| arble mobile notify | Send a notification |
| arble mobile open|shortcut | Open an app or deep link, or run a shortcut |
| arble mobile camera|mic | Capture, with on-device approval |
| arble schedule create|ls|rm | Manage cron schedules |
| arble triggers create|ls|rm | Manage event triggers |
| arble jobs ls|logs | List job runs, or logs for one job |
Logs, config, debug
| Command | Description |
|---|---|
| arble logs | Live or historical logs |
| arble metrics | Aggregated metrics |
| arble config get|set|ls | Read and write configuration |
| arble profiles ls|use | Manage profiles |
| arble secrets set|ls | Manage secrets |
| arble trace | Full execution trace |
| arble version | CLI and daemon versions |
| arble help | Help for any command |
Environment variables
| Variable | Purpose |
|---|---|
| ARBLE_API_KEY | API token. Takes precedence over the keychain credential. |
| ARBLE_PROFILE | Profile to use, equivalent to --profile. |
| ARBLE_PROJECT | Active project, equivalent to --project. |
| ARBLE_ENDPOINT | Daemon or instance endpoint. Overrides the profile’s endpoint. |
| ARBLE_LOG_LEVEL | error, warn, info, debug or trace. Default info. |
| ARBLE_CONFIG | Path to the config file. Default ~/.arble/config.toml. |
Environment variables override config files and are overridden by flags.
Exit codes
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | General error — the command ran and failed |
| 2 | Usage error — unknown flag, missing argument |
| 3 | Not authenticated, or the credential expired |
| 4 | Permission denied, including a --no-prompt run that needed approval |
| 5 | Not found — project, session, agent or connector |
| 6 | Conflict — the resource is in a state that forbids the operation |
| 7 | Timeout |
| 8 | Cancelled, including a graceful Ctrl-C |
| 130 | Interrupted by SIGINT before the CLI could shut down cleanly |
In scripts, distinguish 4 from 1. A permission denial means the
grant is wrong and retrying won’t help; a general error may be transient.
Best practices
- Use profiles rather than editing the endpoint — switching contexts should be one word, not a config change.
- Check in
arble.jsonso a teammate cloning the repository gets the same skills, connectors and permission scopes. - Always pass
--no-promptin CI, so a missing grant fails the build instead of hanging it. - Scope every permission —
filesystem.write --scope ./src, never barefilesystem.write. - Use scoped API tokens per pipeline, not one token shared across every job.
- Prefer
arble scheduleto cron; you get retries, queueing and job logs for free. - Put jobs that touch the same resource in the same queue so they can’t run concurrently.
- Use
--dry-runthe first time you point an automation at anything you can’t easily undo. - Pipe
--jsonintojqrather than parsing rendered tables — the table format is not a stable interface. - Read
arble permissions auditbeforearble tracewhen a run stops early; it’s usually the answer. - Write memory entries as durable facts, and use
arble sessions exportfor what happened in one run. - Run
arble memory summarizeperiodically on long-lived projects; unbounded memory costs context on every run. - Pin skill versions in
arble.jsonso a registry update can’t change how an agent behaves mid-sprint. - Run
arble mcp healthbefore debugging an agent that says a tool is unavailable. - Treat
arble sessions exportoutput as the artifact for incident reviews — it contains the arguments and approvals, not just the summary.
FAQ
Does the CLI need the desktop app installed?
No. The app and the CLI are both clients of the same daemon. Install the daemon alone for a headless machine, or point the CLI at a remote instance and install nothing locally.
Can I use the CLI fully offline?
Yes, in local mode with a local model. Connectors and remote MCP servers need network access, but sessions, memory, permissions and desktop control do not.
How do I stop an agent mid-run?
Ctrl-C in the foreground, or arble agents kill <id> for a background
one. Both cancel cooperatively — an in-flight tool call is given the chance to stop
cleanly before it’s terminated.
What happens to a background agent if my shell exits?
It keeps running; the daemon owns it, not your shell. Use --detach if it
also needs to survive a daemon restart.
Is the output format stable enough to parse?
Parse --json, not the rendered tables. The JSON shape is versioned; table
layout changes between releases.
How do I run against a self-hosted instance?
Set the endpoint on a profile and switch to it. Everything else is identical — the CLI doesn’t distinguish hosted from self-hosted.
Can two people share a project?
Yes. Projects belong to the organization, and memory and permission grants are shared. Sessions are per-user unless explicitly shared.
Does a CI run see my local permission grants?
No. Grants are per-profile and per-project, and a CI token carries its own scopes. This is deliberate — a local convenience grant should never widen what a pipeline can do.
Where are credentials stored?
In the OS keychain — Keychain on macOS, Secret Service on Linux, Credential
Manager on Windows. Never in config.toml, and never in
arble.json.
How do I see which version the daemon is running?
arble version prints both the CLI and daemon versions. They don’t
have to match exactly, but the CLI warns when the gap is wide enough to matter.