
Security News
Happy Birthday, Shai-Hulud
It has been one year since Shai-Hulud made its first appearance on npm.
@ariestools/cli
Advanced tools
Aries Tools CLI — a suite by Arie Trouw for AI-client tooling, XL1 datalake provisioning, content hashing (strict + fuzzy + perceptual), XL1 wallet management, payload witnessing, and XYO protocol utilities.
npm install -g @ariestools/cli
# or
pnpm add -g @ariestools/cli
aries --help
aries info
aries secrets status
ariesi hash --algorithm pdq ./photo.jpg
ariesi plex libraries
ariesi gate pair ticker BTC_USDT
aries wallet create
aries witness url --url https://example.com
aries datalake list
The published CLI embeds the local datalake dev server. You do not need
private monorepo packages (aries-datalake-plane, etc.) installed.
# Isolated state (recommended for CI / Immortalizer)
export ARIES_HOME=/tmp/aries-test-$$
# Free ports by default (or pass --control-port / --plane-port)
aries datalake up
aries datalake list
aries datalake down
import {
createDatalakeClient,
RestPayloadsClient,
} from '@ariestools/cli/datalake'
// After `aries datalake up` (or with baseUrl + authToken options)
const control = createDatalakeClient()
const lakes = await control.list()
// …
Private workspace packages stay private; runtime daemons ship under
dist/bin/daemons/ inside this package.
The reference includes public aries commands and internal ariesi commands.
Internal commands require the private CLI build and an internal license tier;
the public installation cannot run them.
aries ai AI client tools
ariesi bank Manage bank witness settings
aries chain Run a local published-chain S3/REST server
aries datalake Provision and manage on-demand XL1 datalakes
ariesi gate Query the Gate exchange API (internal build)
ariesi hash [file] Generate a hash (sha256, xyo, fuzzy, perceptual)
aries info Display version and environment info
ariesi npmjs Inspect and lint npmjs org packages
ariesi pentair Manage Pentair ScreenLogic systems
ariesi plex Inspect and manage Plex Media Server (internal build)
aries secrets Secrets foundation, static AI instructions, and the human-only vault path
aries wallet XL1 wallet — seed phrases, accounts, transactions, contacts
aries witness Observe data and produce XYO-compliant payloads
aries xyo XYO protocol utilities
Available on every command:
| Option | Description |
|---|---|
-v, --verbose | Enable verbose output |
--help-ai | Print static AI-oriented help for a registered command path |
--version | Show version number |
--help | Show help |
aries secrets — Secrets foundation and the human-only vault pathThe current implementation provides versioned, static discovery and status,
the read-only inventory listing, local bastion profile and provider
configuration, and eight human-only commands, init, create, reveal,
set, generate, delete, list, and describe, each documented in the
next sections:
aries secrets status
aries secrets status --json
aries secrets --help-ai
aries secrets --help-ai --json
aries secrets init # human-only; no --json form
aries secrets create --name "Deploy token" --input-fd 3 3<file # human-only; value from fd 3, else the prompt
aries secrets reveal --secret-id sec_… # human-only; the value, once, to the terminal
aries secrets set --secret-id sec_… --expected-version <v> --input-fd 3 3<file # human-only; compare-and-swap replace
aries secrets generate --name "Signing key" --kind random-bytes --length 64 # human-only; drawn in-process, never printed
aries secrets delete --secret-id sec_… --expected-version <v> # human-only; compare-and-swap delete, not recoverable
aries secrets list # human-only; metadata only
aries secrets describe --secret-id sec_… # human-only; metadata only
status reports the implementation phase (human-only-storage) plus three
live observations: bastionConfigured is true when the bastion profile store
holds at least one profile and data.bastionStore names the store path and
its state (configured, empty, or unreadable — a refused or corrupt store
is reported, never thrown); data.providers carries the negotiated state of
every provider entry on the selected profile; and data.humanOnlyPath states
whether the human-only path is available on this platform. data.state is
not-initialized until a vault exists on the selected profile and
human-only-storage once one does. There is no initialized state and no
authenticated operator: init performs no operator or recovery bootstrap, so
the realm stays provisional and nothing accepts a grant.
aries --help-ai [--json] discovers registered AI-help subtrees. AI help is
embedded package content and runs before .env, settings, licensing, provider,
or broker initialization. Its manifest marks future commands as planned, the
human-only commands as human-only (risk human-only, no --json option),
and carries a humanOnlyPath block: brokered: false, humanAttested: true, the eight conditions every human-only command enforces, the platforms
on which they can be satisfied (darwin, linux), unlock: 'per-invocation', and lease: 'not-available'.
Agent-operational secret access is not implemented. This foundation cannot
connect to a bastion, create AI identities, authenticate with JWTs, manage
grants or approvals, or broker a secret to any program. The inventory listing
below observes presence metadata only: it initializes no provider and reads no
secret value. The bastion profile and provider commands record non-secret
configuration only: they contact no bastion and create no socket or vault.
The one path that touches a vault is human-only and unbrokered, described
under aries secrets init, aries secrets create, aries secrets reveal,
and the set, generate, delete, list, and describe sections below.
All eight human-only commands — init, create, reveal, set,
generate, delete, list, and describe — refuse unless standard input
and standard output are both interactive terminals, the platform provides
/dev/tty, stty, and a process-ancestry probe (an allow-list, so win32
and any unknown platform are refused outright), no AI agent host is detected
through a documented environment signal or an agent binary in the process
ancestry (an ambiguous probe fails closed), and argv carries no
structured-output option (--json, --no-json) and no delivery option
(--delivery, --destination, --output, --out, --out-file, --fd,
--env, --clipboard, --temp-file, --to) anywhere — including before
the secrets word. A secret value still has two ways in, both of them input
channels rather than delivery: the masked prompt on the attached terminal,
and --input-fd <fd> on create and set, which reads the value from a
descriptor the caller opened. Every refusal is HUMAN_CHANNEL_REQUIRED
(exit 2) with a fixed message on standard error that never reflects an argv
value and nothing at all on standard output, and the two kinds differ in
what they record: a refusal by the channel gate — a pipe, a non-terminal, an
unsupported platform, a detected or ambiguous agent host — is recorded as a
human-attested refused audit event, while an argv refusal is caught by the
preflight before any store is opened and writes no audit event at all. The
gate conditions are evaluated in the order above, so a piped or captured
caller is refused before any ps probe runs. Passing the gate refuses the
non-interactive case; it is not proof of a human, because a pseudo-terminal
remains agent-drivable.
No MCP tool and no GUI reaches this path. The aries mcp servers register no
tool that names a secret and import nothing from the secrets action tree; the
Electron shell and the dashboard import nothing from that tree either — not
the human-only modules, not the barrel that re-exports them, not the provider
seam, and not the encrypted-file vault package — and neither declares
@ariestools/cli-lib as a dependency (the dashboard reads only
secrets inventory list --json by running the packed CLI, which reads no
value). The vault package itself is not a GUI or IPC API: the only consumers
of its unlock, create, re-key, and record primitives are the human-only
command modules that handle plaintext and the provider seam they load it
through. There is no socket, no daemon, and no lease — a command unlocks the
vault for that invocation and locks it again before it returns.
~/.aries/secretsARIES_HOME relocates ~/.aries in full. Everything the CLI writes below it
is created 0600 inside 0700 directories. The three stores it owns —
config/bastions.json, realms/<realmId>/secrets-index.json, and
audit/human-attested.jsonl — are also checked when they are read: a group
or other permission bit, a foreign owner, a symlink, a non-regular file, or
an oversized one fails the command and names the chmod or chown fix
rather than repairing it. The vault files are written the same way and are
refused on a symlink, a non-regular file, or an oversized one, and their
directory is created 0700. Two rows below are operator-authored and are
never written, moved, or permission-checked by the CLI: inventory.json,
read as declarations only, and realms/<realmId>/denies.json, which refuses
every secret-touching operation in this milestone by existing at all.
| Path | Contents |
|---|---|
config/bastions.json | The bastion profile envelope: realms, bastions, endpoints, provider entries, and the active selection. Non-secret. ARIES_SECRETS_BASTIONS redirects it (absolute path). |
vaults/<providerId>/vault.json | The encrypted-file vault header, format v1: plaintext parameters only — the vault ID, PBKDF2-SHA256 at 100,000 iterations, AES-256-GCM with a 12-byte IV, and the creation time. |
vaults/<providerId>/vault-password.json | The password verifier: the PBKDF2 salt and a SHA-256 hash of the derived key. Never the password. |
vaults/<providerId>/records.json | Every secret, as ciphertext with its authenticated metadata. The display name lives inside the encrypted body. |
realms/<realmId>/secrets-index.json | The routing index: secret ID → { providerId, digest }, and nothing else. |
realms/<realmId>/denies.json | Deny records, consulted before every secret-touching operation. Nothing in this milestone writes it. |
audit/human-attested.jsonl | The hash-chained, append-only human-attested audit log: one event per line, no secret value and no grant evidence. |
inventory.json | The machine-wide managed-secret declarations, written by the operator and only read here. Presence metadata only. ARIES_SECRETS_INVENTORY redirects it. |
broker.sock is recorded on a local profile as the endpoint the future broker
would use; no socket is created, bound, or connected to in this build.
aries secrets inventory — Managed secrets visibilityaries secrets inventory list
aries secrets inventory list --repo owner/myapp
aries secrets inventory list --source env --env-file ./deploy/.env --json
secrets is always registered at the free tier, so every example works
unchanged in the internal ariesi build.
Managed secrets are declared in one schema at two scopes, each a JSON file
with a root-level inventory list:
~/.aries/secrets/inventory.json (override with ARIES_SECRETS_INVENTORY;
ARIES_HOME relocates ~/.aries) — machine-wide entries, each optionally
naming its repos. The legacy ~/.config/aries/secrets.json is still read
when the new file is absent, with a notice on stderr and
data.legacyInventoryPath under --json; move it to the new path.<repo>/.config/aries/secrets.json — entries needed by that repository's
agents. These files are safe to commit: the closed entry shape
(service, account, optional label, env, and — global only — repos)
structurally rejects value-bearing fields, so a committed file can never
become a secret store.{
"version": 1,
"inventory": [
{
"account": "ci-token",
"env": "GITHUB_TOKEN",
"label": "GitHub token",
"service": "github"
}
]
}
Presence is metadata only and never returns a value: on macOS the default
auto source probes the Keychain by (service, account) existence without
requesting the password; elsewhere (or with --source env) presence means the
mapped env variable is set and non-empty after .env loading. Repositories
are discovered below ARIES_CODE_ROOT (default ~/GitHub). The --json
envelope follows the secrets result schema and contains identifiers and
presence booleans only — suitable as the dashboard panel's data source.
aries secrets bastion — Bastion profilesaries secrets bastion add --name "Laptop bastion"
aries secrets bastion list
aries secrets bastion show # active or sole profile
aries secrets bastion show "Laptop bastion" # by display name
aries secrets bastion show --bastion bpf_… # by profile ID
aries secrets bastion use "Laptop bastion"
aries secrets bastion remove "Laptop bastion"
aries secrets bastion list --json
A bastion profile is a closed, versioned, non-secret record naming a realm,
a bastion, its endpoint, and its providers; it holds no password, token, or
key material. Profiles live in one envelope at
~/.aries/secrets/config/bastions.json (ARIES_HOME relocates ~/.aries;
ARIES_SECRETS_BASTIONS redirects the file for tests and must be absolute),
written 0600 inside a 0700 directory. A file or directory with group or
other permission bits, a foreign owner, a file over 256 KiB, or an unparseable
file fails every command with BASTION_CONFIGURATION_INVALID (exit 9), naming
only the path and the fix. A redirected store is disclosed on stderr in human
output and as data.bastionStore under --json.
add --name <displayName> [--kind local-ipc] mints the profile, realm, and
bastion identifiers, derives the audience, and records the inert socket path
<secretsRoot>/broker.sock without touching the filesystem. The first
profile written to an empty store becomes the active selection. Every new
profile starts with one encrypted-file provider entry (encrypted-local,
vault directory <secretsRoot>/vaults/encrypted-local); no vault is created.
--kind remote is refused with CAPABILITY_UNSUPPORTED until Phase 9. A
display name that collides with an existing profile ID or display name is an
error, never an overwrite.list reads the store only: it never contacts a bastion or starts a broker,
succeeds on a missing store with an empty table, and marks a remote
profile unusable in this build.show [<profile>] [--bastion <profile>] resolves by profile ID first, then
display name, else the active profile, else the sole profile; the result
names which namespace matched. With nothing selectable it fails with
BASTION_NOT_SELECTED. The endpoint is labeled not used in this build.use <profile> writes activeProfileId and nothing else. Selection is not
authorization; a remote profile is refused.remove <profile> deletes the local record and clears an active selection
that pointed at it. It revokes nothing: grants, delegations, and enrollments
at the removed realm remain in force and must be revoked at the bastion
separately, which the result states in both output forms.add, use, and remove are mutating: they print the store path on stderr
for every write, and an agent must not run them without explicit operator
instruction (the AI-help manifest carries that rule). Every command takes
--json; the envelope follows the secrets result schema and typed failures
map to the secrets exit codes.
aries secrets provider — Provider entriesaries secrets provider list
aries secrets provider show # active or sole provider
aries secrets provider show backup # by provider ID
aries secrets provider add --id backup --kind encrypted-file
aries secrets provider add --id backup --kind encrypted-file --vault-path /srv/vaults/backup
aries secrets provider configure backup --vault-path /srv/vaults/backup
aries secrets provider use backup
aries secrets provider remove backup
aries secrets provider test # active or sole provider
aries secrets provider test backup --json
aries secrets provider list --bastion "Laptop bastion" --json
A provider entry is the non-secret placement record on a bastion profile:
providerId, kind, and configurationRef (for encrypted-file, the
absolute vault directory, default <secretsRoot>/vaults/<providerId>). It
holds no password and no key material; the vault's own files hold those.
Every command takes the inherited --bastion <profile> (profile ID first,
then display name; omitted means the active profile, else the sole profile,
else BASTION_NOT_SELECTED) and --json, discloses the store as
data.bastionStore, and refuses a remote profile with
CAPABILITY_UNSUPPORTED.
add --id <providerId> --kind encrypted-file [--vault-path <dir>] appends
one entry. The kind union is closed at the option table and again at the
record parser, so memory and macos-keychain are refused by both. A
duplicate ID is an error, never an overwrite. No vault and no directory is
created: initialization needs a password and is human-only.list prints every entry with initialized — whether vault.json exists
at configurationRef, a stat only, with no unlock and no header parse —
and marks the active provider.show [<providerId>] resolves by ID, else the active provider (set by
use), else the sole provider, and carries two fixed notes: unlock is
per-invocation with no lease, and compare-and-swap is cooperative (it holds
only among writers honoring the vault store lock).configure <providerId> --vault-path <dir> replaces configurationRef
only; the kind is immutable and nothing is created, moved, or unlocked.remove <providerId> deletes the entry and clears an active provider
selection that pointed at it. The vault directory is not deleted, which the
result states in both output forms. The last provider of a profile cannot
be removed; remove the profile instead.use <providerId> records activeProviderId, which satisfies --provider
on management commands only. Placement on create and generate still
requires --provider whenever the profile lists more than one provider;
there is no default provider.test [<providerId>] resolves like show and reports the adapter's
declared capabilities, maximumSecretBytes, a bounded health check, the
per-invocation unlock mode, and the cooperative compare-and-swap caveat.
It never prompts, unlocks, lists, or reads: the adapter is built around a
locked placeholder session, and a locked vault — the designed steady state
— succeeds with health locked and exit 0. Only an unavailable provider
fails (PROVIDER_UNAVAILABLE, exit 7): not initialized (next.command
names the human-only init), a corrupt header (reported with a redacted
diagnostic, never a path), or a health check that misses its deadline
(retryable). status runs the same negotiation for every provider entry
on the selected profile and reports providerCount and per-provider rows
under the same ok-when-locked rule; it still succeeds when every provider
is unavailable.--vault-path must be absolute and is refused when equal to or inside the
resolved XL1 wallet root, or inside the directory named by XL1_WALLET_HOME
or ARIES_WALLET_HOME when either is set, so a vault never shares a
directory with a wallet store; the refusal names the rule, never the path.
add, configure, remove, and use are mutating: they print the store
path on stderr for every write, and an agent must not run them without
explicit operator instruction.
aries secrets init — Human-only vault creationaries secrets init # mints "Local bastion" when no profile exists
aries secrets init --name "Laptop bastion" # display name for the minted profile
aries secrets init --bastion "Laptop bastion" # an existing profile
aries secrets init --provider-id backup # another entry; added to the profile when absent
init is the first human-only, unbrokered command. From an interactive
terminal it resolves the bastion profile (or mints a local one when none
exists), ensures an encrypted-file provider entry for --provider-id
(default encrypted-local, vault directory
<secretsRoot>/vaults/<providerId>), refuses an existing vault at that
entry's location (VERSION_CONFLICT, exit 8; the refusal names the rule,
never the path), prompts for the vault password twice on /dev/tty with
the vault's 12-character minimum, creates the vault, opens it once to confirm
it answers under that password, locks it again, and prints the profile,
provider, and vault summary. Unlock is per-invocation: no lease, session
file, or key survives the command. The password is read from the terminal
alone — never from an environment variable or a command-line argument.
init initializes one vault and one local profile only. It performs no
operator or recovery bootstrap: the realm stays provisional in the plan's
sense, nothing accepts a grant, and neither status nor --help-ai
describes the operator as authenticated.
Every human-only command enforces these rules, each covered by a test:
HUMAN_CHANNEL_REQUIRED
(exit 2) on stderr and writes nothing to stdout;--json and no delivery option; --json, --no-json,
--delivery, --destination, --output, --fd, --env, --clipboard,
--temp-file, or --to anywhere in argv — including before the secrets
word — is refused with a fixed message before yargs runs, and the refused
value is never reflected;<secretsRoot>/audit/human-attested.jsonl; an event that cannot be
written refuses the operation (AUDIT_UNAVAILABLE);init alone is exempt, because no realm exists before it mints one);
create, reveal, set, generate, delete, list, and describe
refuse with POLICY_INVALID (exit 5) when the deny set cannot be read,
which in this milestone includes any existing
<secretsRoot>/realms/<realmId>/denies.json, since nothing writes one yet;win32 every human-only command fails with HUMAN_CHANNEL_REQUIRED and
reason platform-unsupported, which status and the manifest state.Agents must not invoke a human-only command, wrap it, or treat it as agent access: it identifies no principal, evaluates no grant, and confers nothing on any agent principal.
aries secrets create — Human-only secret storagearies secrets create --name "Deploy token" --input-fd 3 3<./token.txt # value from descriptor 3
aries secrets create --name "Deploy token" # masked prompt, typed twice
aries secrets create --name "API key" --provider backup # placement on a named entry
create stores one secret in the operator's own vault. From an interactive
terminal it resolves the bastion profile (--bastion, else the active
profile, else the sole profile — it never mints one), places the secret on
--provider (required when the profile lists more than one provider,
implied when it lists exactly one; the active provider never satisfies
placement), consults the realm's deny records, appends the intent audit
event, prompts for the vault password on /dev/tty, collects the value,
writes the record, indexes it, locks the vault, and prints the secret ID
and version — never the value.
The value comes from exactly one of two sources. --input-fd <n> reads a
trusted producer's descriptor, which must be numbered 3 or higher, open,
and not a terminal: standard input is never accepted, because it may be
model-composed or captured in a transcript. The read is bounded at 65536
bytes and exactly one trailing newline is removed. Without --input-fd
the value is typed on the terminal, masked, and confirmed. In both cases
the record is stored as text/plain, and the descriptor is read before
the password prompt so a closed or reserved descriptor is refused early.
The display name (--name, at most 256 bytes, no control characters) is
stored inside the encrypted record body, where the vault's associated data
authenticates it.
The write spans two stores under two leases and is not atomic, so its order
is fixed: the provider record is created first, then the index entry. If
the index write fails, the record is deleted again under the same session
and the command reports the index failure with provider effect none; if
that deletion cannot be proven, the command reports
PROVIDER_OUTCOME_UNKNOWN (exit 7) naming the record's opaque ID, which
may then remain in the vault unindexed until it is reconciled.
Each realm has one routing index at
<secretsRoot>/realms/<realmId>/secrets-index.json, written 0600 inside
a 0700 realm directory through the same journaled, atomic store that
holds the bastion profiles. It maps a secret ID to { providerId, digest }
and nothing else: no display name, content type, byte length, or timestamp
ever lands in it, so the file discloses routing alone. The digest is
SHA-256 over the canonical JSON of { secretId, providerId, opaqueId },
computed at create and re-verified on every resolve; opaqueId equals the
secret ID by construction, because the human path mints a canonical
22-character sec_ token that the encrypted-file vault stores verbatim.
The digest is unkeyed: it detects an accidental edit or a truncated write,
and nothing more — any party with write access to the file can recompute
it. Phase 3 replaces it with a broker-held keyed MAC. Do not delete the
index: every secret it routes becomes unreachable by ID.
aries secrets reveal — Human-only reveal to the terminalaries secrets reveal --secret-id sec_… # the value, once, then a newline
aries secrets reveal --secret-id sec_… --bastion "Laptop" # an explicit profile
reveal resolves --secret-id through the realm's secret index alone. A
missing entry is INVALID_ARGUMENT (exit 2); an entry naming a provider
the profile no longer lists, or one whose digest no longer verifies, is
BASTION_CONFIGURATION_INVALID (exit 9) — each fails closed, and no
provider is ever opened or searched to find a matching record. --provider
is refused with INVALID_ARGUMENT for the same reason: the index is the
only routing input, so a reference can never be redirected from the
command line. The command then consults the deny records, appends the
intent event, prompts for the vault password, reads the record, locks the
vault, appends the completed event, and writes the value exactly once to
standard output followed by one newline — nothing else is written there.
There is no other delivery: no destination, file, descriptor, environment,
clipboard, or temporary file, and no structured output. The value never
appears in an audit line or on standard error.
aries secrets set — Human-only compare-and-swap replacearies secrets set --secret-id sec_… --expected-version <v> --input-fd 3 3<./new.txt # value from descriptor 3
aries secrets set --secret-id sec_… --expected-version <v> # masked prompt, typed twice
set replaces one secret's value in the operator's own vault. It resolves
--secret-id through the realm's secret index alone, exactly as reveal
does (--provider is refused with INVALID_ARGUMENT), consults the deny
records, appends the intent event, prompts for the vault password, collects
the new value from --input-fd (3 or higher; read before the password prompt)
or the masked terminal prompt with confirmation, and performs one
compare-and-swap replace: --expected-version must equal the record's
current version token exactly as the last create, generate, set, or
describe printed it, or the command fails with VERSION_CONFLICT (exit 8)
and nothing changes. The display name and content type are preserved from
the record. The reference does not change, so the index is untouched; the
command prints the new version and the superseded one, never the value. A
replace whose effect the provider cannot prove is PROVIDER_OUTCOME_UNKNOWN
(exit 7), naming the record and stating that the index still routes it.
aries secrets generate — Human-only in-process generationaries secrets generate --name "Signing key" --kind random-bytes --length 64
aries secrets generate --name "Webhook token" --kind base64url-token
aries secrets generate --name "Database password" --kind password --length 24 --provider backup
generate draws a value in the operator's own process from Web Crypto and
stores it exactly as create would: placement on --provider (or the sole
provider), the deny consultation, the intent event, the password prompt,
the provider record first with the display name inside the encrypted body,
then the routing entry in the realm's index, with the same rollback when the
index write fails. It prints the secret ID, kind, size, and version — the
value is never printed, logged, audited, or returned, and exists only in the
record's ciphertext; read it back with reveal. --kind is a closed list
and --length counts the kind's unit inside an inclusive range:
| Kind | Stored as | --length | Default | Range |
|---|---|---|---|---|
random-bytes | application/octet-stream, raw bytes | bytes | 32 | 8–1024 |
base64url-token | text/plain | characters | 32 | 8–512 |
password | text/plain | characters | 32 | 8–256 |
password uses a fixed 70-symbol printable alphabet with the ambiguous
0 O 1 l I removed and no space, quote, backslash, $, backtick, or
redirection character; base64url-token uses the 64 base64url symbols. Both
are uniform: a byte that would bias the draw is rejected, never reduced. An
unlisted kind or an out-of-range length is INVALID_ARGUMENT (exit 2) before
anything runs.
aries secrets delete — Human-only compare-and-swap deletearies secrets delete --secret-id sec_… --expected-version <v>
delete resolves --secret-id through the index alone, consults the deny
records, appends the intent event, prompts for the vault password, and
deletes the record under the --expected-version guard; a stale guard is
VERSION_CONFLICT (exit 8) and nothing changes. It then removes the routing
entry from the realm's index: the tombstone is the removal itself, so the ID
no longer resolves through any command and a later describe or reveal
stops at the index with INVALID_ARGUMENT. The vault record is gone and is
not recoverable through aries: the encrypted-file provider discards the
ciphertext and keeps no tombstone, which the receipt reports as
unrecoverable. The audit line records the secret ID and the fresh tombstone
version only. If the record is deleted but the index cannot be updated, the
command reports PROVIDER_OUTCOME_UNKNOWN (exit 7) naming both facts — the
record is gone, the index may still route the ID. Until you reconcile,
describe on that ID fails either at the vault with RESOURCE_UNAVAILABLE,
with list showing it as missing, or at the index with INVALID_ARGUMENT
if the entry did go after all.
aries secrets list — Human-only metadata listingaries secrets list # the active provider, or the sole provider
aries secrets list --provider backup # one provider entry
list resolves the provider entry (--provider, else the active provider,
else the sole one), consults the deny records for the realm's catalog,
prompts for the vault password, and prints metadata alone: for every index
entry routed to that provider, the secret ID, version, incarnation, content
type, byte length, display name, and created and updated timestamps, read
from the vault's own description; an entry whose record the provider no
longer holds is shown as missing, one whose index digest does not verify
as integrity-failed (the vault is not consulted for it), and one whose
record the vault holds but will not describe as undescribable with the
failure code — a single unreadable record never hides the rest of the
catalog. Entries routed to other providers on the profile are counted, not
listed. The
command also enumerates the provider's own records and reports every record
the index does not route to that provider as unindexed, with its opaque
ID, version, byte length, and timestamps — never its value or display name.
An unindexed record is reachable by no aries command until it is reconciled,
because the index is the only routing input. No value is ever printed.
aries secrets describe — Human-only metadata for one secretaries secrets describe --secret-id sec_…
describe resolves --secret-id through the index alone (--provider is
refused), consults the deny records, prompts for the vault password, and
prints the record's current version, incarnation, created and updated
timestamps, content type, byte length, and display name — never the value,
which is decrypted only to measure it and wiped inside the library. A
record the vault does not hold is RESOURCE_UNAVAILABLE (exit 7); an ID the
index does not route is INVALID_ARGUMENT (exit 2) before any vault is
opened. The printed version is the --expected-version for the next set
or delete.
aries chain — Local published-chain server# Plain HTTP on loopback (default)
aries chain up
# Locally trusted HTTPS at https://chain.aries.test:8791 (macOS)
brew install mkcert
aries chain up --ssl auto
The server exposes the published-chain buckets at /blocks, /state, and
/indexes. --ssl auto keeps the listener on 127.0.0.1, installs or reuses
mkcert's local development CA, generates a certificate under
~/.aries/chain/tls, and adds an idempotent chain.aries.test entry to
/etc/hosts. The first run may request administrator authorization. The CA and
hosts entry remain installed after chain down; chain reset removes the
generated Aries certificate files.
| Option | Default | Description |
|---|---|---|
--port <number> | 8791 | Listener port |
--host <address> | 127.0.0.1 | Bind address; auto TLS requires the default |
--ssl off|auto | off | Enable macOS automatic local HTTPS setup |
--backing memory | memory | Ephemeral storage, wiped on shutdown |
--timeout <seconds> | 10 | Startup health-check timeout |
The ready banner prints the S3_ENDPOINT used by ariesi xyo s3 .... Aries
automatically selects path-style S3 addressing and trusts the generated CA for
the chain.aries.test endpoint. S3_CA_BUNDLE can provide a different private
CA file for another HTTPS S3-compatible endpoint.
ariesi bank — Manage bank witness settingsariesi bank capitalone config get
ariesi bank capitalone config set base-url https://api-sandbox.capitalone.com
ariesi bank capitalone config set token-url https://api-sandbox.capitalone.com/oauth2/token
ariesi bank capitalone config set client-id "$CAPITALONE_CLIENT_ID"
ariesi bank capitalone config set client-secret "$CAPITALONE_CLIENT_SECRET"
ariesi bank capitalone config set accounts-path /accounts
ariesi bank capitalone config set balances-path '/accounts/{accountId}/balances'
ariesi bank capitalone config set transactions-path '/accounts/{accountId}/transactions'
Capital One config is stored in ~/.aries/bank/capitalone.json with restricted
file permissions. ARIES_HOME overrides the ~/.aries root.
Capital One U.S. Customer Transactions is a private DevExchange product. Aries
therefore requires the endpoint paths supplied by your Capital One partner docs
for aries witness bank --resource accounts.
The public sandbox Retrieve Consumer Bank Products product is a deposit product
catalog, not personal account data. Use aries witness bank --resource products
for that API; Aries uses Capital One's documented sandbox defaults unless you
override base-url or token-url.
| Key | Env var | Default | Description |
|---|---|---|---|
env | ARIES_CAPITALONE_ENV | sandbox | Environment label: sandbox or production |
base-url | ARIES_CAPITALONE_BASE_URL | Capital One API base URL | |
token-url | ARIES_CAPITALONE_TOKEN_URL | OAuth client-credentials token URL | |
client-id | ARIES_CAPITALONE_CLIENT_ID | OAuth client id | |
client-secret | ARIES_CAPITALONE_CLIENT_SECRET | OAuth client secret | |
scope | ARIES_CAPITALONE_SCOPE | Optional OAuth scope | |
accounts-path | ARIES_CAPITALONE_ACCOUNTS_PATH | Accounts endpoint path | |
balances-path | ARIES_CAPITALONE_BALANCES_PATH | Balances endpoint path; may include {accountId} | |
transactions-path | ARIES_CAPITALONE_TRANSACTIONS_PATH | Transactions endpoint path; may include {accountId} |
config get redacts client-secret; pass --show-secrets to print it. Access
tokens are not persisted; pass --access-token or set ARIES_CAPITALONE_ACCESS_TOKEN
for one run.
ariesi pentair — Manage Pentair ScreenLogic systemsariesi pentair config get
ariesi pentair config get address
ariesi pentair config set address 192.0.2.10
ariesi pentair config set port 80
ariesi pentair config set system-name "Pentair ScreenLogic"
ariesi pentair circuit runtime set --circuit-id 6 --hours 24 --on
Pentair config is stored in ~/.aries/pentair/config.json and is used by the
Pentair witness and circuit commands. ARIES_HOME overrides the ~/.aries root.
| Key | Default | Description |
|---|---|---|
address | ScreenLogic adapter IP for direct connection; omit to use UDP discovery | |
port | 80 | ScreenLogic adapter TCP port for direct connection |
password | SCREENLOGIC_PASSWORD | ScreenLogic password for direct connection |
system-name | Pentair ScreenLogic | ScreenLogic system name for direct connection |
response-timeout | 15000 | Milliseconds to wait for each ScreenLogic command response |
search-timeout | 5000 | Milliseconds to wait for each UDP discovery attempt |
search-attempts | 3 | Number of UDP discovery attempts before failing |
series-file | ~/.aries/pentair/intellichem.jsonl | JSONL file used for saved IntelliChem samples and graphing |
config get redacts password; pass --show-secrets to print it.
ariesi pentair circuit runtime setSet the ScreenLogic circuit egg timer. Runtime values are sent to ScreenLogic as
minutes; --hours 24 becomes 1440.
| Option | Description |
|---|---|
--circuit-id <id> | Pentair circuit id to update |
--hours <n> | Runtime in hours; mutually exclusive with --minutes |
--minutes <n> | Runtime in minutes; mutually exclusive with --hours |
--on | Turn the circuit on after setting the runtime |
--json | Output as JSON |
Connection override flags are also accepted: --address, --port,
--password, --system-name, --response-timeout, --search-timeout, and
--search-attempts.
ariesi plex — Plex Media Server toolsThe Plex command is available from the internal ariesi build with
license.tier=internal.
ariesi plex librariesList libraries configured in a Plex Media Server. By default, Aries tries the local server at http://127.0.0.1:32400 and discovers the Plex token from PLEX_TOKEN, X_PLEX_TOKEN, PLEX_AUTH_TOKEN, local Plex .LocalAdminToken, or a local Plex Preferences.xml. If local API auth still blocks access, Aries falls back to the local Plex library database and then Plex Media Scanner --list.
| Option | Default | Description |
|---|---|---|
--url <url> | PLEX_URL or http://127.0.0.1:32400 | Plex server URL |
--token <token> | env/local Preferences.xml | Plex auth token |
--preferences <path> | auto-detect | Plex Preferences.xml path for token discovery |
--database <path> | auto-detect | Plex library database path for local fallback |
--no-fallback | Disable fallback to Plex Media Scanner --list when the API is unavailable | |
--json | false | Output as JSON |
ariesi plex lint [--library <name-or-id>]Run read-only lint checks against the Plex setup. The first rule, multiple-sources, reports items that have more than one original source media copy. Plex optimized versions and files matching Plex's local extras naming conventions do not count as sources.
| Option | Default | Description |
|---|---|---|
-l, --library <name-or-id> | all libraries | Plex library name or ID, e.g. Movies or 9 |
--database <path> | auto-detect | Plex library database path |
--json | false | Output as JSON |
ariesi plex items --library <name-or-id>List top-level items in a Plex library from the local Plex database, including media resolution and optimization details.
| Option | Default | Description |
|---|---|---|
-l, --library <name-or-id> | required | Plex library name or ID, e.g. Movies or 9 |
--database <path> | auto-detect | Plex library database path |
--fields <list> | media,optimizations | Comma-separated details: media, optimizations, files, all |
--limit <n> | Maximum number of items to inspect | |
--json | false | Output as JSON |
ariesi plex items optimize --tv --library <name-or-id>Queue Plex "Optimized for TV" versions for items that do not already have one. Aries inspects the local Plex database first, skips items already marked Optimized for TV, and then queues missing items through the local Plex optimizer API.
| Option | Default | Description |
|---|---|---|
-l, --library <name-or-id> | required | Plex library name or ID, e.g. Movies or 9 |
--tv | required | Optimize missing items for Plex's TV profile |
--dry-run | false | Show what would be queued without changing Plex |
--url <url> | PLEX_URL or http://127.0.0.1:32400 | Plex server URL |
--token <token> | env/local token discovery | Plex auth token |
--preferences <path> | auto-detect | Plex Preferences.xml path for token discovery |
--database <path> | auto-detect | Plex library database path |
--limit <n> | Maximum number of missing optimizations to queue | |
--inspect-limit <n> | Maximum number of library items to inspect | |
--json | false | Output as JSON |
ariesi plex items optimize queue [--library <name-or-id>]List items currently in Plex's optimizer queue. When --library is omitted, Aries lists queued optimizer items across all libraries.
| Option | Default | Description |
|---|---|---|
-l, --library <name-or-id> | all libraries | Plex library name or ID, e.g. Movies or 9 |
--url <url> | PLEX_URL or http://127.0.0.1:32400 | Plex server URL |
--token <token> | env/local token discovery | Plex auth token |
--preferences <path> | auto-detect | Plex Preferences.xml path for token discovery |
--database <path> | auto-detect | Plex library database path for library names |
--json | false | Output as JSON |
ariesi gate — Gate exchange APIThe Gate command is available from the internal ariesi build with
license.tier=internal.
A read-only client for the Gate exchange REST API (v4). It calls only unauthenticated public spot endpoints — no API key is read, and nothing is ever traded.
These options are available on every gate subcommand:
| Option | Default | Description |
|---|---|---|
--base-url <url> | ARIES_GATE_API_URL, GATE_API_URL, or https://api.gateio.ws/api/v4 | Gate API v4 base URL |
--json | false | Output as JSON |
ariesi gate pair list <symbol>List every Gate spot pair that trades <symbol>. The symbol matches on either side of the pair by default, so BTC returns both BTC_USDT (where it is the base) and ETH_BTC (where it is the quote). Pairs that are not currently tradable are hidden unless --all is passed.
| Option | Default | Description |
|---|---|---|
--side any|base|quote | any | Match the symbol only as the base or only as the quote currency |
--all | false | Include pairs whose trade status is not tradable |
ariesi gate pair list XYO
XYO_ETH XYO Network / Ethereum fee 0.2%
XYO_USDT XYO Network / Tether fee 0.2%
2 pair(s) for XYO
ariesi gate pair ticker <pair>Show the 24-hour spot ticker for a single pair — last price, change, bid/ask, high/low, and base + quote volume.
The pair can be written as one argument (BTC_USDT, BTC/USDT, BTC-USDT, or a quoted "BTC|USDT" — an unquoted pipe is consumed by the shell before Aries sees it), or as its two halves in separate arguments (BTC USDT).
ariesi gate pair ticker BTC_USDT
BTC_USDT
last 78862
change 24h +0.04%
bid / ask 78861.9 / 78862
high / low 79235.9 / 77638.6
base volume 4902.5960069814 BTC
quote volume 384979909.02896446684 USDT
aries ai — AI client toolsaries ai detectScan for installed AI clients.
| Option | Default | Description |
|---|---|---|
--json | false | Output as JSON |
aries ai lint [path]Check Claude Code and Codex AI configuration drift. The folder defaults to the current directory.
| Option | Default | Description |
|---|---|---|
--scope <all|project|home> | all | Check project config, shared/custom home config, or both |
--json | false | Output as JSON |
aries ai skills list [tool]List installed skills discovered for Claude Code, Codex, and Cursor. The optional
tool positional accepts claude, codex, or cursor; omit it to inspect all
three. Cursor currently reports no skills. Detection and listing do not modify client configuration.
| Option | Default | Description |
|---|---|---|
--json | false | Output as JSON |
AI lint also inspects shared/custom home plugin manifests and skill files for drift without changing them.
aries datalake — Provision and manage on-demand XL1 datalakesaries datalake login| Option | Default | Description |
|---|---|---|
--base-url <url> | Control-plane base URL (P0: required) | |
--token <jwt> | Pre-issued auth token (P0: required; OAuth lands in P1) |
aries datalake logout — clears stored credentials, no flags.
aries datalake create <name>| Positional | Description | |
|---|---|---|
name | required | Human-friendly name (unique per owner) |
| Option | Default | Description |
|---|---|---|
-t, --tier <small|medium|large|archive> | small | Service tier |
-s, --size <e.g. 10GB> | Capacity | |
--iops <n> | Provisioned IOPS target | |
-r, --region <us-west-2|us-east-1|eu-west-1> | Deployment region | |
--retention-days <n> | tier default | Retention in days |
--verify-hashes | false | Reject inserts whose $hash does not match the content digest |
--rate-auth-per-minute <n> | Override: authenticated requests per minute | |
--rate-anon-per-minute <n> | Override: anonymous requests per minute | |
--rate-burst-factor <n> | Override: rate-limit burst factor (1 = no burst) |
aries datalake list — no flags.
aries datalake describe [name] / aries datalake destroy [name]| Positional | Description | |
|---|---|---|
name | active default | Datalake name or id |
destroy adds:
| Option | Default | Description |
|---|---|---|
-f, --force | false | Required confirmation flag |
aries datalake use [name]Sets the default datalake for subsequent commands. Omit the name to clear.
aries datalake grant <name> <principal>| Positional | Description | |
|---|---|---|
name | required | Datalake name or id |
principal | required | User id, or the literal public |
| Option | Default | Description |
|---|---|---|
-r, --role <viewer|runner> | viewer | Role to grant |
--confirm-public | false | Required to grant public runner (anonymous writes) |
aries datalake revoke <name> <principal>Same positionals; no command-specific options.
aries datalake token [name]| Positional | Description | |
|---|---|---|
name | active default | Datalake name or id |
| Option | Default | Description |
|---|---|---|
-r, --role <viewer|runner> | viewer | Role encoded in the token |
--ttl <seconds> | server-capped | Lifetime in seconds |
aries datalake push <file> [name]| Positional | Description | |
|---|---|---|
file | required | Path to a .json (array) or .jsonl (one payload/line) file |
name | active default | Target datalake |
| Option | Default | Description |
|---|---|---|
--batch-size <n> | 500 | Max payloads per HTTP request |
--verify | false | Verify each payload's $hash against content locally before pushing |
--xl1-sdk | false | Use the real @xyo-network/xl1-protocol-sdk RestDataLakeRunner |
aries datalake fetch <hash> [name]| Positional | Description | |
|---|---|---|
hash | required | Content hash of the payload |
name | active default | Target datalake |
| Option | Default | Description |
|---|---|---|
--raw | false | Print only the raw JSON payload (no header) |
--xl1-sdk | false | Use the real @xyo-network/xl1-protocol-sdk RestDataLakeViewer |
aries datalake tail [name]| Positional | Description | |
|---|---|---|
name | active default | Datalake name or id |
| Option | Default | Description |
|---|---|---|
-f, --follow | false | Keep polling for new payloads after draining the backlog |
-n, --limit <n> | 50 | Max payloads per page |
--cursor <hash> | Resume after this hash (exclusive) | |
--schemas <csv> | Comma-separated list of schemas to include | |
--poll-interval <ms> | 1000 | Poll interval in ms when following |
aries datalake audit # default: view
aries datalake audit view # Print audit log rows
aries datalake audit purge # Delete rotated audit files older than --max-age-days
aries datalake audit view| Option | Default | Description |
|---|---|---|
-f, --follow | false | Stream new rows as they arrive (tails the most recent file) |
-n, --lines <n> | 50 | Tail this many rows (0 = start fresh in --follow mode) |
--datalake-subject <subject> | Filter by the provider-scoped datalake pseudonym stored in audit rows | |
--status <prefix> | Status code prefix filter (e.g. 4 matches 4xx) | |
--method <verb> | HTTP method filter (GET, POST, …) | |
--authenticated <true|false> | Show only authenticated or only anonymous requests | |
--grep <regex> | Regex pattern applied to the raw JSON line | |
--file <path> | File or directory (auto-detects rotation layout) |
aries datalake audit purge| Option | Default | Description |
|---|---|---|
--max-age-days <n> | required | Retention window; files older than this are deleted |
--directory <path> | <ARIES_HOME>/dev/audit | Rotation directory |
--dry-run | false | Report what would be deleted without removing anything |
aries datalake up # Start the local control + data plane dev server
aries datalake down # Stop it (clears credentials)
aries datalake status # Report whether the local dev server is running and healthy
aries datalake logs # Print recent dev server log output
aries datalake reset # Stop the dev server and wipe all local state
The original aries datalake dev up|down|status|logs|reset spellings remain
available for compatibility.
aries datalake up| Option | Default | Description |
|---|---|---|
--control-port <n> | free loopback port | Control-plane port |
--plane-port <n> | free loopback port | Data-plane port |
--control-audience <aud> | aries-datalake-control | Exact JWT audience accepted by the control plane |
--cors-origin <origin> | disabled | Exact browser origin to allow; repeat for multiple origins |
--timeout <s> | 10 | Seconds to wait for health |
--persist | false | Persist store state to disk so it survives restarts |
--audit | false | Write a JSONL audit log of every data-plane request |
--audit-rotate | false | Rotate the audit log daily (writes to <home>/dev/audit/) |
--audit-keep-days <n> | Prune rotated audit files older than this many days |
aries datalake logs| Option | Default | Description |
|---|---|---|
-f, --follow | false | Stream new lines as they arrive |
-n, --lines <n> | 50 | Number of tail lines to show |
down, status, reset take no command-specific options.
ariesi signing-pool — XL1 gas-sponsored transaction signingSigning pools are wallet-backed servers that co-sign XL1 transactions so the pool address pays gas instead of the caller. The transaction must use signature slot 0 for the pool and signature slot 1 for the caller:
addresses[0] is the signing-pool address.addresses[1] is the authenticated caller address.$signatures[0] must be null when submitted.$signatures[1] must already verify against addresses[1].signing-pool sign submits a hydrated transaction tuple
[TransactionBoundWitness, payloads[]]. For compatibility with the original
CLI helper, the input file may also be an unsigned template; in that case the
CLI fills the pool/caller slots, signs slot 1 with the active XL1 wallet, and
sends the hydrated tuple to the pool.
ariesi signing-pool create <name> --daily-limit <atto> --max-tx-gas <atto> --min-exp-blocks 10 --max-exp-blocks 500
ariesi signing-pool grant <id> <caller-address>
ariesi signing-pool sign <id> ./tx.json --output ./signed-tx.json
ariesi signing-pool dev up --xl1-node-rpc-url http://127.0.0.1:8545
The control plane rejects transactions it cannot inspect. In this phase, every
payload elevated on-chain via script: ["elevate|<payload-hash>"] must be
present in the hydrated payload array, and network.xyo.transfer is prohibited
as an elevated/on-chain payload.
ariesi signing-pool dev up # Start the local signing-pool control plane
ariesi signing-pool dev down # Stop it
ariesi signing-pool dev status # Report whether it is running and healthy
ariesi signing-pool dev logs # Print recent server log output
ariesi signing-pool dev reset # Stop the server and wipe local state
ariesi signing-pool dev up| Option | Default | Description |
|---|---|---|
--port <n> | 8790 | Control-plane port |
--timeout <s> | 10 | Seconds to wait for health |
--persist | false | Persist pool state under <ARIES_HOME>/signing-pool-dev/store |
--audience <aud> | aries-signing-pool | JWT audience accepted by the dev control plane |
--master-mnemonic <phrase> | generated | Override the dev mnemonic used to derive pool signing accounts |
--xl1-node-rpc-url <url> | $XL1_NODE_RPC_URL | XL1 node RPC URL used to read current block height |
The dev client auto-discovers a live local signing-pool state when
--base-url, $SIGNING_POOL_CONTROL_URL, and $TOKEN_POOL_CONTROL_URL are not
set.
The signing pool currently uses a narrow local helper to fill a single
$signatures[] slot without mutating the rest of the bound witness. The proper
upstream fix belongs in sdk-protocol-js: add explicit partial-signing support
to BoundWitnessBuilder, then expose that through TransactionBuilder so a
caller can build/sign slot 1 and a signing pool can later sign slot 0 while
preserving the hydrated transaction tuple and all existing signatures.
ariesi hash [file] — content hashingariesi hash [file] [options]
ariesi hash compare <hashA> <hashB> --algorithm <name> [--json]
Reads input from [file] (positional), --string, or piped stdin (priority order). Dispatches to one of 10 algorithms.
| Option | Default | Description |
|---|---|---|
-a, --algorithm <name> | sha256 | Algorithm — see the matrix below |
-s, --string <text> | Hash this string instead of a file/stdin | |
-x, --xyo | false | Shortcut for --algorithm xyo (input must be JSON) |
--base64 | false | Re-encode hex output as base64 (only for hex-output algorithms) |
--fps <n> | 1 | Frames-per-second sample rate (video-frames only) |
--frame-algorithm <phash|pdq> | phash | Per-frame hash for video-frames |
| Algorithm | Family | Input | Output | External binary | Compare metric |
|---|---|---|---|---|---|
sha256 | strict | bytes | 64-char hex | — | exact-match |
xyo | strict | JSON | 64-char hex | — | exact-match |
nilsimsa | fuzzy-byte | bytes | 64-char hex | — | nilsimsa-score |
ssdeep | fuzzy-byte | bytes | bs:h1:h2 | ssdeep | ssdeep-levenshtein ⚠ |
phash | perceptual-image | image | 16-char hex (64-bit) | — | hamming-64 |
dhash | perceptual-image | image | 16-char hex (64-bit) | — | hamming-64 |
blockhash | perceptual-image | image | 16-char hex (64-bit) | — | hamming-64 |
pdq | perceptual-image | image | 64-char hex (256-bit) — Meta PDQ via WASM | — | hamming-256 |
chromaprint | audio | audio file | JSON {duration, fingerprint[]} | fpcalc | chromaprint-windowed-hamming |
video-frames | video | video file | JSON {fps, frames:[{t,hash}]} | ffmpeg | frame-sequence-<algo>@<fps>fps |
⚠ — Approximations, not the canonical reference scores:
ssdeep-levenshtein — block-size-aware Levenshtein, without the canonical block-size attenuation curve.# macOS
brew install ssdeep chromaprint ffmpeg
# Debian/Ubuntu
apt install ssdeep libchromaprint-tools ffmpeg
# Windows
choco install ssdeep chromaprint ffmpeg
Each algorithm probes its binary at hash time and prints clear install instructions if the binary is missing.
# Strict
ariesi hash --string "hello"
ariesi hash ./payload.json --algorithm xyo
# Byte-fuzzy
ariesi hash --algorithm nilsimsa ./binary.exe
ariesi hash compare <hashA> <hashB> --algorithm nilsimsa
# Perceptual image
ariesi hash --algorithm phash ./photo.jpg
ariesi hash --algorithm pdq ./photo.jpg
ariesi hash compare <hashA> <hashB> --algorithm pdq
# Audio
ariesi hash --algorithm chromaprint ./song.mp3 > song.fp.json
ariesi hash compare "$(cat a.fp.json)" "$(cat b.fp.json)" --algorithm chromaprint --json
# Video
ariesi hash --algorithm video-frames --fps 1 ./movie.mkv > movie.fp.json
ariesi hash --algorithm video-frames --fps 1 --frame-algorithm pdq ./movie.mkv > movie-pdq.fp.json
ariesi hash compare "$(cat a.fp.json)" "$(cat b.fp.json)" --algorithm video-frames
ariesi hash compare <hashA> <hashB>| Positional | Description | |
|---|---|---|
hashA | required | First hash |
hashB | required | Second hash |
| Option | Default | Description |
|---|---|---|
-a, --algorithm <name> | required | Algorithm that produced the hashes |
--json | false | Print full result as JSON |
Plain output: <similarity>\t<metric>[\tdistance=<n>] (similarity is a 0..1 float, 1 = identical). JSON output: {"similarity":0.93,"distance":18,"metric":"hamming-256"}.
The compare command needs only the two hash strings — works against hashes generated on different machines.
ariesi npmjs — npmjs org package checksariesi npmjs list --org=xylabs
ariesi npmjs lint --org=xylabs
ariesi npmjs lint --org=xylabs --fix
ariesi npmjs lint # all auth-visible org packages
By default, package discovery uses your current npm CLI authentication via npm access list packages @<org> --json, so private or restricted org packages are included when your npm account can see them. Omit --org to list or lint all scoped packages returned by npm access list packages --json, grouped by org with a per-org summary at the end. If npm auth is unavailable for a specific --org, ariesi npmjs falls back to public package discovery and reports npm auth: unauthenticated at the end of text output. Use --public-only with --org to force public discovery.
ariesi npmjs list| Option | Default | Description |
|---|---|---|
--org <scope> | npm org scope, with or without @; omit for all auth-visible org packages | |
--public-only | false | List only public packages without using npm access |
--json | false | Output as JSON |
ariesi npmjs lintFind packages that are not marked deprecated but probably should be. V1 reports warning-only findings and exits 0 unless an operational error occurs.
| Option | Default | Description |
|---|---|---|
--org <scope> | npm org scope, with or without @; omit for all auth-visible org packages | |
--public-only | false | Lint only public packages without using npm access |
--abandoned-days <n> | 365 | Warn when latest publish is at least this many days old |
--unused-downloads <n> | 100 | Warn when weekly downloads are below this threshold |
--new-days <n> | 30 | Do not warn for low downloads until a package is at least this many days old |
--fix | false | Interactively choose lint findings to deprecate with npm deprecate |
--deprecation-message <text> | Message to pass to npm deprecate for selected packages | |
--json | false | Output as JSON |
Rules:
abandoned — latest publish date is older than the configured threshold.unused — weekly downloads are below the configured threshold and the package is not new.--fix is text-only and prompts with a default Do Nothing / optional Deprecate toggle for each package reported by lint. After selection, each selected package prompts for an optional replacement package name. Blank keeps the default message; a replacement appends Use <replacement> instead. Selected packages are deprecated with npm deprecate <package>@* <message> after Enter is pressed.
aries infoDisplay ariestools version and environment info. No command-specific options.
aries wallet — XL1 walletWallet commands are provided by the standalone @xyo-network/wallet-xl1-cli package (xl1-wallet). The Aries CLI forwards aries wallet ... to that bin and uses the wallet CLI storage layout: ~/.xl1/wallet/cli by default, overrideable with XL1_WALLET_HOME (ARIES_WALLET_HOME remains a legacy fallback).
aries wallet create # Generate a new XL1 wallet (random recovery phrase)
aries wallet import # Import an existing XL1 recovery phrase
aries wallet export # Print the recovery phrase for the active (or specified) wallet
aries wallet list # List stored wallets
aries wallet use <id> # Set the active wallet
aries wallet rename <id> <label> # Rename a stored wallet
aries wallet remove <id> # Delete a stored wallet (and its address book)
aries wallet create| Option | Default | Description |
|---|---|---|
-l, --label <text> | first available wallet# | Friendly label for the wallet |
--algorithm <secp256k1|ml-dsa-65> | secp256k1 | Wallet signing algorithm |
aries wallet import| Option | Default | Description |
|---|---|---|
-l, --label <text> | imported | Friendly label |
-p, --phrase <words> | Recovery phrase (skips interactive prompt) | |
--algorithm <secp256k1|ml-dsa-65> | secp256k1 | Wallet signing algorithm |
ml-dsa-65 wallets use QuantHDWallet and derive qm65... bech32m addresses. Wallet-JWT commands and datalake --wallet mode require secp256k1 until ML-DSA-65 has a standardized JOSE algorithm.
Wallet labels must be unique. If create is run without --label, the CLI uses the first available wallet# label, starting with wallet0.
aries wallet export| Option | Default | Description |
|---|---|---|
--id <wallet-id> | active | Wallet id or label |
aries wallet use <id> / aries wallet remove <id>| Positional | Description | |
|---|---|---|
id | required | Wallet id or label |
aries wallet rename <id> <label>| Positional | Description | |
|---|---|---|
id | required | Wallet id or current label |
label | required | New label |
aries wallet unlock # Cache the wallet password (encrypted at rest) for a TTL
aries wallet lock # Clear the cached unlocked session
aries wallet password change # Change the wallet password (re-encrypts every stored phrase)
aries wallet unlock| Option | Default | Description |
|---|---|---|
--ttl <seconds> | 900 | Session lifetime in seconds (default 15 min) |
lock and password change take no command-specific options.
aries wallet reset # Destroy all wallet data — only path forward when password is lost
Use this only when you have forgotten your wallet password. There is no other way to recover from a lost password — encrypted seed phrases cannot be decrypted without it.
reset deletes the entire wallet directory (~/.xl1/wallet/cli by default): every stored seed phrase, every derived account, every address-book entry, every saved contact, every saved network configuration, and the active session. This is irreversible unless you have a backup (see aries wallet backup).
To prevent accidental loss, the command requires two interactive confirmations:
RESET (uppercase, exactly).y to the final [y/N] prompt.Anything else cancels with no changes. There is no --force flag.
If no wallet has been initialized (e.g. on first run), reset is a no-op and prints No wallet found — no reset needed.
aries wallet account list # List derived accounts in the active wallet
aries wallet account show <offset> # Show details for a derived account
aries wallet account derive <offset> # Derive a new account at the given HD offset
aries wallet account label <offset> <label> # Label a derived account
aries wallet account remove <offset> # Remove an account from the address book
All account commands take an HD path offset positional (e.g. 0).
aries wallet account derive <offset>| Option | Default | Description |
|---|---|---|
-l, --label <text> | Friendly label for the account |
aries wallet balance [offset]| Positional | Description | |
|---|---|---|
offset | 0 | HD path offset |
aries wallet sign <file>| Positional | Description | |
|---|---|---|
file | required | Path to a JSON payload file |
| Option | Default | Description |
|---|---|---|
-o, --offset <n> | 0 | HD path offset of the signer |
-O, --output <path> | Write output to file instead of stdout |
Produces a BoundWitness.
A wallet account can mint a JWT-shaped, time-bounded permission token that a site verifies locally, without running its own login flow. Think of it as reverse OAuth: the holder signs an attestation declaring an audience (the domain they intend to use the token at) and an expiration; the site checks the signature and claims and grants the session.
The token is the standard header.payload.signature JWT format, base64url-encoded. The signing input is SHA-256(utf8("${headerB64}.${payloadB64}")) and the alg is ES256K (secp256k1 ECDSA). The header carries both kid (signer address) and pub (full public key) so verification is self-contained — no out-of-band pubkey lookup is needed.
Header fields: alg (ES256K), typ (JWT), kid (40-char lowercase hex address), pub (hex public key bytes).
Payload is an XYO Payload (must include schema). The default schema is network.xyo.auth.signin and the standard claims are iss (mirrors kid), aud, iat, exp, plus optional nbf, nonce, and any extra fields supplied via --payload-file or --claim.
Note: this is the single-signed path. A future co-signed BoundWitness flow (where the site offers a permissions BW signed by its own address and the client co-signs) is planned and will reuse the same schema and account-derivation infrastructure.
aries wallet jwt create| Option | Default | Description |
|---|---|---|
-a, --audience <domain> | required | Audience — becomes the aud claim (e.g. xyo.network) |
--ttl <seconds> | 3600 | Lifetime in seconds (mutually exclusive with --exp) |
--exp <unix-seconds> | Absolute expiration; alternative to --ttl | |
--schema <schema> | network.xyo.auth.signin | XYO schema for the payload |
--payload-file <path> | JSON file with extra payload fields (CLI flags win) | |
--claim <key=value> | Extra claim, repeatable; numeric/boolean strings are coerced | |
-o, --offset <n> | 0 | HD path offset of the signer |
-O, --output <path> | Write the token to a file instead of stdout |
aries wallet jwt verify [token]| Positional | Description | |
|---|---|---|
token | JWT to verify (omit to read from --input or stdin) |
| Option | Default | Description |
|---|---|---|
-a, --audience <domain> | If provided, fail unless aud matches | |
-i, --input <path> | Read JWT from file | |
--now <unix-seconds> | Override current time — useful for tests |
Prints { ok, header, payload, reasons? } JSON. Exits non-zero on any verification failure (signature, expiry, audience mismatch, kid/iss mismatch, public-key/address mismatch).
aries wallet jwt decode [token]Decode header and payload without verifying the signature. Useful for debugging.
aries wallet send <recipient> <amount> # Send XL1 to a recipient address
aries wallet tx sign <file> # Sign an unsigned transaction JSON file
aries wallet tx broadcast <file> # Broadcast a signed transaction JSON file
aries wallet send <recipient> <amount>| Positional | Description | |
|---|---|---|
recipient | required | Recipient address (0x…) |
amount | required | Amount in the selected unit (XL1 by default) |
| Option | Default | Description |
|---|---|---|
-o, --offset <n> | 0 | HD path offset of the sender |
--xl1 | Interpret amount as XL1 (default) | |
--milli | Interpret amount as milli XL1 | |
--micro | Interpret amount as micro XL1 | |
--nano | Interpret amount as nano XL1 | |
--pico | Interpret amount as pico XL1 | |
--femto | Interpret amount as femto XL1 | |
--atto | Interpret amount as atto XL1; must be a whole number | |
--dry-run | false | Build and sign the transfer without submitting it |
--json | false | Emit machine-readable JSON output |
--attempts <n> | 30 | Confirmation polling attempts |
--delay <ms> | 2000 | Delay between confirmation attempts |
aries wallet tx sign <file>| Positional | Description | |
|---|---|---|
file | required | Path to unsigned transaction JSON |
| Option | Default | Description |
|---|---|---|
-o, --offset <n> | 0 | HD path offset of the signer |
-O, --output <path> | Write signed tx to file instead of stdout |
aries wallet tx broadcast <file>| Positional | Description | |
|---|---|---|
file | required | Path to signed transaction JSON |
| Option | Default | Description |
|---|---|---|
-o, --offset <n> | 0 | HD path offset for client connection |
aries wallet network list # List configured networks
aries wallet network add <id> <rpcUrl> # Add a custom network
aries wallet network use <id> # Set the active network
aries wallet network remove <id> # Remove a custom network
aries wallet network add <id> <rpcUrl>| Positional | Description | |
|---|---|---|
id | required | Network id (unique) |
rpcUrl | required | Gateway RPC URL |
| Option | Default | Description |
|---|---|---|
-l, --label <text> | Friendly label | |
--chain-id <hex> | Chain id (hex) |
use and remove take a network id positional only.
aries wallet contact list # List address-book contacts
aries wallet contact add <address> <label> # Add or update a contact
aries wallet contact rename <address> <label> # Rename an existing contact
aries wallet contact remove <address> # Remove a contact
All take an address positional (0x…); add/rename also take a label positional. No additional flags.
aries wallet backup export <file> # Export address books and contacts to a JSON file
aries wallet backup import <file> # Import a wallet backup JSON file (merges into current state)
file is the only positional; no additional flags.
aries witness — Observe data and produce XYO-compliant payloadsaries witness timestamp # Capture the current timestamp
aries witness system-info # Capture system information (OS, CPU, memory, etc.)
aries witness url # Capture metadata and content from a URL
aries witness bank # Capture bank account snapshots or Capital One product catalog data
aries witness pentair # Capture Pentair ScreenLogic pool equipment state
aries witness pentair-intellichem # Capture and graph Pentair IntelliChem chemistry data
aries witness pentair-schedules # Capture Pentair ScreenLogic schedules with circuit and pump context
aries witness app # Inspect installed applications
aries witness app list # List installed macOS applications
These flags are available on every witness leaf:
| Option | Default | Description |
|---|---|---|
--json | false | Output raw JSON |
-o, --output <path> | Write output to file | |
--pretty | true | Pretty-print JSON output |
--bound-witness | false | Wrap payloads in a BoundWitness |
--binary-dir <path> | ~/.aries/binaries/ | Directory for binary artifacts |
aries witness url| Option | Default | Description |
|---|---|---|
--url <url> | required | The URL to fetch |
aries witness bankaries witness bank --provider capitalone --account-id acct-123 --from 2026-06-01 --to 2026-06-25 --json
aries witness bank --provider capitalone --access-token "$CAPITALONE_TOKEN" --include-raw --json
aries witness bank --provider capitalone --resource products --client-id "$CAPITALONE_CLIENT_ID" --client-secret "$CAPITALONE_CLIENT_SECRET" --json
| Option | Default | Description |
|---|---|---|
--provider <capitalone> | capitalone | Bank provider |
--resource <accounts|products> | accounts | accounts for private account APIs; products for Capital One's sandbox deposit product catalog |
--from <value> | Transaction window start passed as query param from | |
--to <value> | Transaction window end passed as query param to | |
--account-id <id> | Provider account id for balances and transactions | |
--include-raw | false | Store raw provider JSON as witness binary artifacts |
--redaction <default|none> | default | Hash provider account/transaction ids unless explicitly set to none |
--env <sandbox|production> | bank config | Environment label |
--base-url <url> | bank config | Capital One API base URL |
--token-url <url> | bank config | OAuth client-credentials token URL |
--access-token <token> | ARIES_CAPITALONE_ACCESS_TOKEN | Pre-issued bearer token; not persisted |
--client-id <id> | bank config | OAuth client id |
--client-secret <secret> | bank config | OAuth client secret |
--scope <scope> | bank config | Optional OAuth client-credentials scope |
--api-version <version> | 5 | Capital One products media-type version |
--operation <retrieve-products|retail-products|search> | search | Capital One products operation |
--product-id <id> | ~ for product-id operations | Capital One path product id |
--body <json> | {"isCollapseRate":true} for search; {} otherwise | JSON body for Capital One products POST operations |
--body-file <path> | JSON body file for Capital One products POST operations | |
--accounts-path <path> | bank config | Accounts endpoint path |
--balances-path <path> | bank config | Balances endpoint path; may include {accountId} |
--transactions-path <path> | bank config | Transactions endpoint path; may include {accountId} |
With --resource accounts, the bank witness returns one
network.xyo.bank.account-snapshot payload containing normalized accounts,
balances, and transactions. By default, provider account and transaction
identifiers are hashed.
With --resource products, the bank witness calls Capital One's documented
Retrieve Consumer Bank Products sandbox API and returns one
network.xyo.bank.product-catalog payload. This is product catalog data, not a
consumer account snapshot. The default product request follows Capital One's
published "Scenario 1a: All Products" example: POST /deposits/products/~/search
with {"isCollapseRate": true}.
If Capital One returns {"id":"200008","text":"no endpoint matched for request"}
from the product request after OAuth succeeds, the client credentials are valid
but Capital One's sandbox gateway did not match the product endpoint. Verify the
app is connected to DevExchange product 1359-5 in the sandbox and confirm the
active sandbox base path with Capital One.
aries witness pentair-intellichem| Option | Default | Description |
|---|---|---|
--history | false | Fetch IntelliChem controller history |
--from <date|age> | 24h | History start as ISO date or relative age like 30m, 6h, 7d |
--to <date|age> | now | History end as ISO date or relative age |
--save | false | Save normalized samples to the JSONL series file |
--series-file <path> | pentair config or ~/.aries/pentair/intellichem.jsonl | JSONL file used for saved samples and graphing |
--graph <path> | Write a standalone HTML graph | |
--graph-only | false | Render a graph from the series file without connecting to ScreenLogic |
--address <ip> | pentair config | Connect directly to a ScreenLogic adapter IP instead of UDP discovery |
--port <number> | pentair config or 80 | ScreenLogic adapter TCP port for direct connection |
--password <password> | pentair config or SCREENLOGIC_PASSWORD | ScreenLogic password for direct connection, if configured |
--system-name <name> | pentair config or Pentair ScreenLogic | ScreenLogic system name for direct connection |
--response-timeout <ms> | pentair config or 15000 | Milliseconds to wait for each ScreenLogic command response |
--search-timeout <ms> | pentair config or 5000 | Milliseconds to wait for each UDP discovery attempt |
--search-attempts <count> | pentair config or 3 | Number of UDP discovery attempts before failing |
Examples:
aries witness pentair-intellichem --save
aries witness pentair-intellichem --history --from 7d --save --graph intellichem.html
aries witness pentair-intellichem --graph-only --graph intellichem.html
aries witness pentair-schedules| Option | Default | Description |
|---|---|---|
--address <ip> | pentair config | Connect directly to a ScreenLogic adapter IP instead of UDP discovery |
--port <number> | pentair config or 80 | ScreenLogic adapter TCP port for direct connection |
--password <password> | pentair config or SCREENLOGIC_PASSWORD | ScreenLogic password for direct connection, if configured |
--system-name <name> | pentair config or Pentair ScreenLogic | ScreenLogic system name for direct connection |
--response-timeout <ms> | pentair config or 15000 | Milliseconds to wait for each ScreenLogic command response |
--search-timeout <ms> | pentair config or 5000 | Milliseconds to wait for each UDP discovery attempt |
--search-attempts <count> | pentair config or 3 | Number of UDP discovery attempts before failing |
Example:
aries witness pentair-schedules --json
aries witness app list| Option | Default | Description |
|---|---|---|
--scope <all|global|system|user> | all | Filter by install scope |
witness timestamp, witness system-info, and witness pentair take only the common flags.
aries xyo — XYO protocol utilitiesaries xyo rewards <sequence|mainnet> <view>Query finalized XL1 reward lifecycle activity (pool funding → step holders →
escrows → redemptions) through the SDK REST gateway and its multi-family block
rollup indexes (blocks/*).
aries xyo rewards sequence summary
aries xyo rewards mainnet steps --from-block 500000
aries xyo rewards sequence recipients --stage redeemed --limit 25
aries xyo rewards mainnet recipients --stage supplemental-funding --limit 25
aries xyo rewards sequence address <address> --json
aries xyo rewards sequence summary --from-block 510000 --explain
aries xyo rewards sequence index status
aries xyo rewards sequence index verify --concurrency 8
| View | Description |
|---|---|
summary | Direct and supplemental funding, allocation, payout, actual step-holder balance, unique-recipient, and reward-step totals |
steps | Per-step direct funding, supplemental funding, and allocation; optionally filter with --step-level |
recipients | Rank recipients at the funded, supplemental-funding, allocated, or redeemed stage |
address <address> | Reward lifecycle events involving an escrow, staker, or destination |
index status | Show the durable network-stake rewards-index head and its XL1/EVM source-watermark lag |
index verify | Recompute cumulative network-stake totals from every immutable reward-step record and verify the snapshot and source hashes |
Two different “rewards indexes”. Do not confuse them:
| Index | Path / command | What it is for | Used by summary / steps / recipients / address? |
|---|---|---|---|
| Multi-family blocks index | indexes.*.xyo.space blocks/{level}/{i}.json | Bulk block frames for history walks | Yes (via blocksByStep) |
| Local lifecycle cache | ~/.aries/xyo-rewards/<net>/lifecycle/v1/ | Client-side cumulative summary resume | Yes (summary only, from-block 0) |
| Durable network-stake rewards index | rewards/network-stake/v1/{policy}/… + xyo rewards … index | Stake-reward allocation math (XL1 ∩ EVM watermarks) | No — backfilling or verifying it does not speed lifecycle summary |
| Common option | Default | Description |
|---|---|---|
--from-block <n> | 0 | First finalized block to include (non-zero → range-delta lifecycle nets) |
--to-block <n> | finalized head | Last finalized block to include |
--recent-blocks <n> | Scan only the last N blocks (derived from --to-block/head; not with --from-block) | |
--skip-balance | false | Skip the step-holder balance batch (faster incremental scans; omits outstanding balance) |
--lifecycle-cache | true | Summary only: reuse/extend local cumulative cache under ~/.aries/xyo-rewards/<network>/lifecycle/v1/ |
--refresh-lifecycle-cache | false | Summary only: force a full cumulative rescan and rewrite the local cache |
--concurrency <n> | 8 | Indexed ranges read concurrently, from 1 to 16 |
--json | false | Stable machine-readable output; XL1 amounts include atto and decimal forms |
--explain | false | Show indexed frame use, direct reads, gateway setup/scan/balance requests, bytes, timing, and SDK budget warnings |
--no-progress | Suppress the default gateway and scan progress written to stderr |
Incremental / recent windows. Full-history mainnet scans are expensive because every finalized block’s transfers are decoded. Prefer a bounded window when you only need recent activity:
aries xyo rewards mainnet summary --recent-blocks 50000 --skip-balance
aries xyo rewards mainnet summary --from-block 900000 --to-block 950000 --skip-balance
With a non-zero start, funding/allocation/escrow nets are range deltas. Step-holder
balance (unless --skip-balance) remains the actual balance at --to-block.
Local lifecycle cache (summary). Cumulative summary runs (--from-block 0, no
--recent-blocks) persist accumulator state under
~/.aries/xyo-rewards/<network>/lifecycle/v1/head.json. The next run verifies the
cached block hash, hydrates unique sets and totals, and only live-scans the tip
above the cache watermark. Use --no-lifecycle-cache to disable, or
--refresh-lifecycle-cache to rebuild. Cache status appears in --explain and
stderr progress. This is a client-side acceleration cache — not the durable
network-stake rewards index under rewards/network-stake/....
The initial network-stake rewards-index backfill is an internal S3 mutation and
is intentionally excluded from the public aries binary. It builds stake-allocation
snapshots under rewards/network-stake/... and does not feed or accelerate
summary / steps / recipients / address. Operators run it through ariesi
only while the automatic indexer writer is stopped:
ariesi xyo rewards sequence index backfill --dry-run
ariesi xyo rewards sequence index backfill \
--bucket sequence-index \
--account-id "$CF_ACCOUNT" \
--confirm-writer-stopped
aries xyo rewards sequence index verify
backfill resumes from the published rewards head, advances only through the
intersection of the durable XL1 index watermark and finalized EVM event-index
watermark, and verifies the resulting immutable steps and snapshot directly from
S3 before reporting success. --confirm-writer-stopped confirms that the
automatic writer is stopped and authorizes writes; --dry-run requires no S3
credentials.
The reward lifecycle distinguishes direct funding (reward pool to step holder)
from supplemental funding (any other inbound transfer to a deterministic step
holder), followed by allocation (step holder to reward escrow) and redemption
(reward escrow to a final wallet). “Total Rewards Funded” is direct plus
supplemental funding. “Total Rewards Paid Out” means redeemed rewards. Exact
staker identity is visible when an escrow redeems, so
uniqueObservedStakers counts stakers seen in redemption context; it is not an
allocation-time staker count.
“Outstanding in Step Holders” is the actual sum of deterministic holder account
balances at --to-block, read in one SDK batch against the finalized range.
The separately reported step-holder lifecycle net is direct plus supplemental
funding, minus allocation and rounding returns. With a later --from-block,
that lifecycle value and the reward-escrow value are labeled range deltas,
while the step-holder balance remains the actual balance at --to-block.
--explain is intentionally part of the product rather than only a debugging
flag. It separates gateway startup work from the reward scan and makes direct
block fallbacks, payload volume, and repeated request patterns visible. It also
reports blocks-index lag (multi-family blocks/* watermark vs chain head):
when the blocks index trails the tip, the unfinished range falls back to
per-block GETs and full-history scans slow down sharply. Check overall index
health with ariesi xyo s3 index monitor mainnet. Those measurements also
identify reward-specific lifecycle indexes worth publishing through the XL1
indexing pipeline as full-history use grows.
Human-readable commands print gateway initialization and bounded scan progress
to stderr by default. JSON commands remain quiet so stdout stays
machine-readable; SDK diagnostics and the completion footer also stay on
stderr. Add --verbose to a JSON command to opt into progress.
Every aries and ariesi invocation writes a status-aware timing footer to
stderr after the command finishes: ✅ Succeeded in <milliseconds>ms. or
❌ Failed in <milliseconds>ms. This includes JSON commands without changing
their machine-readable stdout.
aries xyo tx validate [data]Validate one or more XL1 transactions. Reads from a file path, inline JSON, or stdin.
| Positional | Description | |
|---|---|---|
data | Path to a .json/.jsonl file, or an inline transaction JSON tuple [bw, payloads[]]. Omit to read from stdin. |
| Option | Default | Description |
|---|---|---|
-d, --detail | false | Print per-transaction error details (always shown for invalid transactions) |
Input modes (resolved in priority order):
| Mode | Example |
|---|---|
| File path | aries xyo tx validate ./tx.json |
| File path (JSONL batch) | aries xyo tx validate ./txs.jsonl |
| Inline JSON | aries xyo tx validate '[[...], [...]]' |
| Piped stdin | cat txs.jsonl | aries xyo tx validate |
Supported file formats:
.json — a single transaction tuple [boundWitness, payloads[]], or a JSON array of tuples.jsonl / .ndjson — one transaction tuple per lineOutput:
Total: 3
Valid: 2
Invalid: 1
[2] ./txs.jsonl:3
- TransactionGasValidator: insufficient gas
Exit codes: 0 = all valid, 1 = any invalid or parse error.
Aries configuration lives under ~/.aries/ (or $ARIES_HOME if set). Wallet data lives under ~/.xl1/wallet/cli (or $XL1_WALLET_HOME if set) and is encrypted at rest using your wallet password.
LGPL-3.0-only © XY Labs
FAQs
Aries Tools CLI - A suite of tools by Arie Trouw
We found that @ariestools/cli demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 3 open source maintainers collaborating on the project.

Security News
It has been one year since Shai-Hulud made its first appearance on npm.

Research
/Security News
Operators behind PolinRider used a compromised GitHub account to plant malware in four development versions of a Packagist package with 700,000+ downloads.

Security News
GitHub Actions now supports cache-mode, a least-privilege control on the Actions cache aimed at the cache poisoning technique behind recent compromises.