New:Microsoft Teams Notifications Are Now Available in Socket.Learn more
Get Started

@ariestools/cli

Package Overview
Dependencies
Maintainers
3
Versions
17
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@ariestools/cli

Aries Tools CLI - A suite of tools by Arie Trouw

latest
npmnpm
Version
0.1.23
Version published
Maintainers
3
Created
Source

@ariestools/cli

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.

Installation

npm install -g @ariestools/cli
# or
pnpm add -g @ariestools/cli

Quick start

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

Local datalake (standalone install)

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

Programmatic client (no shell-out per request)

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.

Top-level commands

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

Global options

Available on every command:

OptionDescription
-v, --verboseEnable verbose output
--help-aiPrint static AI-oriented help for a registered command path
--versionShow version number
--helpShow help

aries secrets — Secrets foundation and the human-only vault path

The 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.

The refusal contract

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.

Storage layout under ~/.aries/secrets

ARIES_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.

PathContents
config/bastions.jsonThe bastion profile envelope: realms, bastions, endpoints, provider entries, and the active selection. Non-secret. ARIES_SECRETS_BASTIONS redirects it (absolute path).
vaults/<providerId>/vault.jsonThe 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.jsonThe password verifier: the PBKDF2 salt and a SHA-256 hash of the derived key. Never the password.
vaults/<providerId>/records.jsonEvery secret, as ciphertext with its authenticated metadata. The display name lives inside the encrypted body.
realms/<realmId>/secrets-index.jsonThe routing index: secret ID → { providerId, digest }, and nothing else.
realms/<realmId>/denies.jsonDeny records, consulted before every secret-touching operation. Nothing in this milestone writes it.
audit/human-attested.jsonlThe hash-chained, append-only human-attested audit log: one event per line, no secret value and no grant evidence.
inventory.jsonThe 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 visibility

aries 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 profiles

aries 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 entries

aries 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 creation

aries 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:

  • standard input and standard output must both be interactive terminals; a piped, redirected, or captured channel fails with HUMAN_CHANNEL_REQUIRED (exit 2) on stderr and writes nothing to stdout;
  • a detected AI agent host (Claude Code, Codex, Cursor, Aider, and the other documented signals, or an agent binary in the process ancestry) is refused, and an ambiguous probe fails closed;
  • there is no --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;
  • the command is not mirrored as an MCP tool and is reachable over no IPC, socket, or remote transport;
  • every run, refusal, and failure appends a human-attested, unbrokered event to <secretsRoot>/audit/human-attested.jsonl; an event that cannot be written refuses the operation (AUDIT_UNAVAILABLE);
  • the realm's deny records are consulted before a secret-touching operation (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;
  • on 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 storage

aries 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.

The secret index

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 terminal

aries 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 replace

aries 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 generation

aries 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:

KindStored as--lengthDefaultRange
random-bytesapplication/octet-stream, raw bytesbytes328–1024
base64url-tokentext/plaincharacters328–512
passwordtext/plaincharacters328–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 delete

aries 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 listing

aries 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 secret

aries 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.

OptionDefaultDescription
--port <number>8791Listener port
--host <address>127.0.0.1Bind address; auto TLS requires the default
--ssl off|autooffEnable macOS automatic local HTTPS setup
--backing memorymemoryEphemeral storage, wiped on shutdown
--timeout <seconds>10Startup 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 settings

ariesi 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.

Capital One config keys

KeyEnv varDefaultDescription
envARIES_CAPITALONE_ENVsandboxEnvironment label: sandbox or production
base-urlARIES_CAPITALONE_BASE_URLCapital One API base URL
token-urlARIES_CAPITALONE_TOKEN_URLOAuth client-credentials token URL
client-idARIES_CAPITALONE_CLIENT_IDOAuth client id
client-secretARIES_CAPITALONE_CLIENT_SECRETOAuth client secret
scopeARIES_CAPITALONE_SCOPEOptional OAuth scope
accounts-pathARIES_CAPITALONE_ACCOUNTS_PATHAccounts endpoint path
balances-pathARIES_CAPITALONE_BALANCES_PATHBalances endpoint path; may include {accountId}
transactions-pathARIES_CAPITALONE_TRANSACTIONS_PATHTransactions 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 systems

ariesi 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.

Config keys

KeyDefaultDescription
addressScreenLogic adapter IP for direct connection; omit to use UDP discovery
port80ScreenLogic adapter TCP port for direct connection
passwordSCREENLOGIC_PASSWORDScreenLogic password for direct connection
system-namePentair ScreenLogicScreenLogic system name for direct connection
response-timeout15000Milliseconds to wait for each ScreenLogic command response
search-timeout5000Milliseconds to wait for each UDP discovery attempt
search-attempts3Number of UDP discovery attempts before failing
series-file~/.aries/pentair/intellichem.jsonlJSONL file used for saved IntelliChem samples and graphing

config get redacts password; pass --show-secrets to print it.

ariesi pentair circuit runtime set

Set the ScreenLogic circuit egg timer. Runtime values are sent to ScreenLogic as minutes; --hours 24 becomes 1440.

OptionDescription
--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
--onTurn the circuit on after setting the runtime
--jsonOutput 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 tools

The Plex command is available from the internal ariesi build with license.tier=internal.

ariesi plex libraries

List 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.

OptionDefaultDescription
--url <url>PLEX_URL or http://127.0.0.1:32400Plex server URL
--token <token>env/local Preferences.xmlPlex auth token
--preferences <path>auto-detectPlex Preferences.xml path for token discovery
--database <path>auto-detectPlex library database path for local fallback
--no-fallbackDisable fallback to Plex Media Scanner --list when the API is unavailable
--jsonfalseOutput 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.

OptionDefaultDescription
-l, --library <name-or-id>all librariesPlex library name or ID, e.g. Movies or 9
--database <path>auto-detectPlex library database path
--jsonfalseOutput 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.

OptionDefaultDescription
-l, --library <name-or-id>requiredPlex library name or ID, e.g. Movies or 9
--database <path>auto-detectPlex library database path
--fields <list>media,optimizationsComma-separated details: media, optimizations, files, all
--limit <n>Maximum number of items to inspect
--jsonfalseOutput 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.

OptionDefaultDescription
-l, --library <name-or-id>requiredPlex library name or ID, e.g. Movies or 9
--tvrequiredOptimize missing items for Plex's TV profile
--dry-runfalseShow what would be queued without changing Plex
--url <url>PLEX_URL or http://127.0.0.1:32400Plex server URL
--token <token>env/local token discoveryPlex auth token
--preferences <path>auto-detectPlex Preferences.xml path for token discovery
--database <path>auto-detectPlex library database path
--limit <n>Maximum number of missing optimizations to queue
--inspect-limit <n>Maximum number of library items to inspect
--jsonfalseOutput 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.

OptionDefaultDescription
-l, --library <name-or-id>all librariesPlex library name or ID, e.g. Movies or 9
--url <url>PLEX_URL or http://127.0.0.1:32400Plex server URL
--token <token>env/local token discoveryPlex auth token
--preferences <path>auto-detectPlex Preferences.xml path for token discovery
--database <path>auto-detectPlex library database path for library names
--jsonfalseOutput as JSON

ariesi gate — Gate exchange API

The 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:

OptionDefaultDescription
--base-url <url>ARIES_GATE_API_URL, GATE_API_URL, or https://api.gateio.ws/api/v4Gate API v4 base URL
--jsonfalseOutput 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.

OptionDefaultDescription
--side any|base|quoteanyMatch the symbol only as the base or only as the quote currency
--allfalseInclude 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 tools

aries ai detect

Scan for installed AI clients.

OptionDefaultDescription
--jsonfalseOutput as JSON

aries ai lint [path]

Check Claude Code and Codex AI configuration drift. The folder defaults to the current directory.

OptionDefaultDescription
--scope <all|project|home>allCheck project config, shared/custom home config, or both
--jsonfalseOutput 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.

OptionDefaultDescription
--jsonfalseOutput 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 datalakes

Authentication

aries datalake login

OptionDefaultDescription
--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.

Lifecycle

aries datalake create <name>

PositionalDescription
namerequiredHuman-friendly name (unique per owner)
OptionDefaultDescription
-t, --tier <small|medium|large|archive>smallService 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 defaultRetention in days
--verify-hashesfalseReject 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]

PositionalDescription
nameactive defaultDatalake name or id

destroy adds:

OptionDefaultDescription
-f, --forcefalseRequired confirmation flag

aries datalake use [name]

Sets the default datalake for subsequent commands. Omit the name to clear.

Access control

aries datalake grant <name> <principal>

PositionalDescription
namerequiredDatalake name or id
principalrequiredUser id, or the literal public
OptionDefaultDescription
-r, --role <viewer|runner>viewerRole to grant
--confirm-publicfalseRequired to grant public runner (anonymous writes)

aries datalake revoke <name> <principal>

Same positionals; no command-specific options.

aries datalake token [name]

PositionalDescription
nameactive defaultDatalake name or id
OptionDefaultDescription
-r, --role <viewer|runner>viewerRole encoded in the token
--ttl <seconds>server-cappedLifetime in seconds

Data plane

aries datalake push <file> [name]

PositionalDescription
filerequiredPath to a .json (array) or .jsonl (one payload/line) file
nameactive defaultTarget datalake
OptionDefaultDescription
--batch-size <n>500Max payloads per HTTP request
--verifyfalseVerify each payload's $hash against content locally before pushing
--xl1-sdkfalseUse the real @xyo-network/xl1-protocol-sdk RestDataLakeRunner

aries datalake fetch <hash> [name]

PositionalDescription
hashrequiredContent hash of the payload
nameactive defaultTarget datalake
OptionDefaultDescription
--rawfalsePrint only the raw JSON payload (no header)
--xl1-sdkfalseUse the real @xyo-network/xl1-protocol-sdk RestDataLakeViewer

aries datalake tail [name]

PositionalDescription
nameactive defaultDatalake name or id
OptionDefaultDescription
-f, --followfalseKeep polling for new payloads after draining the backlog
-n, --limit <n>50Max payloads per page
--cursor <hash>Resume after this hash (exclusive)
--schemas <csv>Comma-separated list of schemas to include
--poll-interval <ms>1000Poll interval in ms when following

Audit (data-plane log inspection)

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

OptionDefaultDescription
-f, --followfalseStream new rows as they arrive (tails the most recent file)
-n, --lines <n>50Tail 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

OptionDefaultDescription
--max-age-days <n>requiredRetention window; files older than this are deleted
--directory <path><ARIES_HOME>/dev/auditRotation directory
--dry-runfalseReport what would be deleted without removing anything

Local development

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

OptionDefaultDescription
--control-port <n>free loopback portControl-plane port
--plane-port <n>free loopback portData-plane port
--control-audience <aud>aries-datalake-controlExact JWT audience accepted by the control plane
--cors-origin <origin>disabledExact browser origin to allow; repeat for multiple origins
--timeout <s>10Seconds to wait for health
--persistfalsePersist store state to disk so it survives restarts
--auditfalseWrite a JSONL audit log of every data-plane request
--audit-rotatefalseRotate 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

OptionDefaultDescription
-f, --followfalseStream new lines as they arrive
-n, --lines <n>50Number of tail lines to show

down, status, reset take no command-specific options.

ariesi signing-pool — XL1 gas-sponsored transaction signing

Signing 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.

Local development

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

OptionDefaultDescription
--port <n>8790Control-plane port
--timeout <s>10Seconds to wait for health
--persistfalsePersist pool state under <ARIES_HOME>/signing-pool-dev/store
--audience <aud>aries-signing-poolJWT audience accepted by the dev control plane
--master-mnemonic <phrase>generatedOverride the dev mnemonic used to derive pool signing accounts
--xl1-node-rpc-url <url>$XL1_NODE_RPC_URLXL1 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.

Upstream builder follow-up

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 hashing

ariesi 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.

Options

OptionDefaultDescription
-a, --algorithm <name>sha256Algorithm — see the matrix below
-s, --string <text>Hash this string instead of a file/stdin
-x, --xyofalseShortcut for --algorithm xyo (input must be JSON)
--base64falseRe-encode hex output as base64 (only for hex-output algorithms)
--fps <n>1Frames-per-second sample rate (video-frames only)
--frame-algorithm <phash|pdq>phashPer-frame hash for video-frames

Algorithm reference

AlgorithmFamilyInputOutputExternal binaryCompare metric
sha256strictbytes64-char hexexact-match
xyostrictJSON64-char hexexact-match
nilsimsafuzzy-bytebytes64-char hexnilsimsa-score
ssdeepfuzzy-bytebytesbs:h1:h2ssdeepssdeep-levenshtein
phashperceptual-imageimage16-char hex (64-bit)hamming-64
dhashperceptual-imageimage16-char hex (64-bit)hamming-64
blockhashperceptual-imageimage16-char hex (64-bit)hamming-64
pdqperceptual-imageimage64-char hex (256-bit) — Meta PDQ via WASMhamming-256
chromaprintaudioaudio fileJSON {duration, fingerprint[]}fpcalcchromaprint-windowed-hamming
video-framesvideovideo fileJSON {fps, frames:[{t,hash}]}ffmpegframe-sequence-<algo>@<fps>fps

⚠ — Approximations, not the canonical reference scores:

  • ssdeep-levenshtein — block-size-aware Levenshtein, without the canonical block-size attenuation curve.

External binary install

# 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.

Examples

# 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>

PositionalDescription
hashArequiredFirst hash
hashBrequiredSecond hash
OptionDefaultDescription
-a, --algorithm <name>requiredAlgorithm that produced the hashes
--jsonfalsePrint 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 checks

ariesi 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

OptionDefaultDescription
--org <scope>npm org scope, with or without @; omit for all auth-visible org packages
--public-onlyfalseList only public packages without using npm access
--jsonfalseOutput as JSON

ariesi npmjs lint

Find packages that are not marked deprecated but probably should be. V1 reports warning-only findings and exits 0 unless an operational error occurs.

OptionDefaultDescription
--org <scope>npm org scope, with or without @; omit for all auth-visible org packages
--public-onlyfalseLint only public packages without using npm access
--abandoned-days <n>365Warn when latest publish is at least this many days old
--unused-downloads <n>100Warn when weekly downloads are below this threshold
--new-days <n>30Do not warn for low downloads until a package is at least this many days old
--fixfalseInteractively choose lint findings to deprecate with npm deprecate
--deprecation-message <text>Message to pass to npm deprecate for selected packages
--jsonfalseOutput 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 info

Display ariestools version and environment info. No command-specific options.

aries wallet — XL1 wallet

Wallet 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).

Wallet management

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

OptionDefaultDescription
-l, --label <text>first available wallet#Friendly label for the wallet
--algorithm <secp256k1|ml-dsa-65>secp256k1Wallet signing algorithm

aries wallet import

OptionDefaultDescription
-l, --label <text>importedFriendly label
-p, --phrase <words>Recovery phrase (skips interactive prompt)
--algorithm <secp256k1|ml-dsa-65>secp256k1Wallet 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

OptionDefaultDescription
--id <wallet-id>activeWallet id or label

aries wallet use <id> / aries wallet remove <id>

PositionalDescription
idrequiredWallet id or label

aries wallet rename <id> <label>

PositionalDescription
idrequiredWallet id or current label
labelrequiredNew label

Session

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

OptionDefaultDescription
--ttl <seconds>900Session lifetime in seconds (default 15 min)

lock and password change take no command-specific options.

Reset (lost password recovery)

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:

  • Type the literal word RESET (uppercase, exactly).
  • Answer 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.

Accounts

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>

OptionDefaultDescription
-l, --label <text>Friendly label for the account

Balance & signing

aries wallet balance [offset]

PositionalDescription
offset0HD path offset

aries wallet sign <file>

PositionalDescription
filerequiredPath to a JSON payload file
OptionDefaultDescription
-o, --offset <n>0HD path offset of the signer
-O, --output <path>Write output to file instead of stdout

Produces a BoundWitness.

Self-signed JWT

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

OptionDefaultDescription
-a, --audience <domain>requiredAudience — becomes the aud claim (e.g. xyo.network)
--ttl <seconds>3600Lifetime in seconds (mutually exclusive with --exp)
--exp <unix-seconds>Absolute expiration; alternative to --ttl
--schema <schema>network.xyo.auth.signinXYO 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>0HD path offset of the signer
-O, --output <path>Write the token to a file instead of stdout

aries wallet jwt verify [token]

PositionalDescription
tokenJWT to verify (omit to read from --input or stdin)
OptionDefaultDescription
-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.

Transactions

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>

PositionalDescription
recipientrequiredRecipient address (0x…)
amountrequiredAmount in the selected unit (XL1 by default)
OptionDefaultDescription
-o, --offset <n>0HD path offset of the sender
--xl1Interpret amount as XL1 (default)
--milliInterpret amount as milli XL1
--microInterpret amount as micro XL1
--nanoInterpret amount as nano XL1
--picoInterpret amount as pico XL1
--femtoInterpret amount as femto XL1
--attoInterpret amount as atto XL1; must be a whole number
--dry-runfalseBuild and sign the transfer without submitting it
--jsonfalseEmit machine-readable JSON output
--attempts <n>30Confirmation polling attempts
--delay <ms>2000Delay between confirmation attempts

aries wallet tx sign <file>

PositionalDescription
filerequiredPath to unsigned transaction JSON
OptionDefaultDescription
-o, --offset <n>0HD path offset of the signer
-O, --output <path>Write signed tx to file instead of stdout

aries wallet tx broadcast <file>

PositionalDescription
filerequiredPath to signed transaction JSON
OptionDefaultDescription
-o, --offset <n>0HD path offset for client connection

Networks

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>

PositionalDescription
idrequiredNetwork id (unique)
rpcUrlrequiredGateway RPC URL
OptionDefaultDescription
-l, --label <text>Friendly label
--chain-id <hex>Chain id (hex)

use and remove take a network id positional only.

Contacts

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.

Backup

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 payloads

aries 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

Common witness flags

These flags are available on every witness leaf:

OptionDefaultDescription
--jsonfalseOutput raw JSON
-o, --output <path>Write output to file
--prettytruePretty-print JSON output
--bound-witnessfalseWrap payloads in a BoundWitness
--binary-dir <path>~/.aries/binaries/Directory for binary artifacts

Per-command additions

aries witness url

OptionDefaultDescription
--url <url>requiredThe URL to fetch

aries witness bank

aries 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
OptionDefaultDescription
--provider <capitalone>capitaloneBank provider
--resource <accounts|products>accountsaccounts 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-rawfalseStore raw provider JSON as witness binary artifacts
--redaction <default|none>defaultHash provider account/transaction ids unless explicitly set to none
--env <sandbox|production>bank configEnvironment label
--base-url <url>bank configCapital One API base URL
--token-url <url>bank configOAuth client-credentials token URL
--access-token <token>ARIES_CAPITALONE_ACCESS_TOKENPre-issued bearer token; not persisted
--client-id <id>bank configOAuth client id
--client-secret <secret>bank configOAuth client secret
--scope <scope>bank configOptional OAuth client-credentials scope
--api-version <version>5Capital One products media-type version
--operation <retrieve-products|retail-products|search>searchCapital One products operation
--product-id <id>~ for product-id operationsCapital One path product id
--body <json>{"isCollapseRate":true} for search; {} otherwiseJSON body for Capital One products POST operations
--body-file <path>JSON body file for Capital One products POST operations
--accounts-path <path>bank configAccounts endpoint path
--balances-path <path>bank configBalances endpoint path; may include {accountId}
--transactions-path <path>bank configTransactions 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

OptionDefaultDescription
--historyfalseFetch IntelliChem controller history
--from <date|age>24hHistory start as ISO date or relative age like 30m, 6h, 7d
--to <date|age>nowHistory end as ISO date or relative age
--savefalseSave normalized samples to the JSONL series file
--series-file <path>pentair config or ~/.aries/pentair/intellichem.jsonlJSONL file used for saved samples and graphing
--graph <path>Write a standalone HTML graph
--graph-onlyfalseRender a graph from the series file without connecting to ScreenLogic
--address <ip>pentair configConnect directly to a ScreenLogic adapter IP instead of UDP discovery
--port <number>pentair config or 80ScreenLogic adapter TCP port for direct connection
--password <password>pentair config or SCREENLOGIC_PASSWORDScreenLogic password for direct connection, if configured
--system-name <name>pentair config or Pentair ScreenLogicScreenLogic system name for direct connection
--response-timeout <ms>pentair config or 15000Milliseconds to wait for each ScreenLogic command response
--search-timeout <ms>pentair config or 5000Milliseconds to wait for each UDP discovery attempt
--search-attempts <count>pentair config or 3Number 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

OptionDefaultDescription
--address <ip>pentair configConnect directly to a ScreenLogic adapter IP instead of UDP discovery
--port <number>pentair config or 80ScreenLogic adapter TCP port for direct connection
--password <password>pentair config or SCREENLOGIC_PASSWORDScreenLogic password for direct connection, if configured
--system-name <name>pentair config or Pentair ScreenLogicScreenLogic system name for direct connection
--response-timeout <ms>pentair config or 15000Milliseconds to wait for each ScreenLogic command response
--search-timeout <ms>pentair config or 5000Milliseconds to wait for each UDP discovery attempt
--search-attempts <count>pentair config or 3Number of UDP discovery attempts before failing

Example:

aries witness pentair-schedules --json

aries witness app list

OptionDefaultDescription
--scope <all|global|system|user>allFilter by install scope

witness timestamp, witness system-info, and witness pentair take only the common flags.

aries xyo — XYO protocol utilities

aries 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
ViewDescription
summaryDirect and supplemental funding, allocation, payout, actual step-holder balance, unique-recipient, and reward-step totals
stepsPer-step direct funding, supplemental funding, and allocation; optionally filter with --step-level
recipientsRank recipients at the funded, supplemental-funding, allocated, or redeemed stage
address <address>Reward lifecycle events involving an escrow, staker, or destination
index statusShow the durable network-stake rewards-index head and its XL1/EVM source-watermark lag
index verifyRecompute 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:

IndexPath / commandWhat it is forUsed by summary / steps / recipients / address?
Multi-family blocks indexindexes.*.xyo.space blocks/{level}/{i}.jsonBulk block frames for history walksYes (via blocksByStep)
Local lifecycle cache~/.aries/xyo-rewards/<net>/lifecycle/v1/Client-side cumulative summary resumeYes (summary only, from-block 0)
Durable network-stake rewards indexrewards/network-stake/v1/{policy}/… + xyo rewards … indexStake-reward allocation math (XL1 ∩ EVM watermarks)No — backfilling or verifying it does not speed lifecycle summary
Common optionDefaultDescription
--from-block <n>0First finalized block to include (non-zero → range-delta lifecycle nets)
--to-block <n>finalized headLast finalized block to include
--recent-blocks <n>Scan only the last N blocks (derived from --to-block/head; not with --from-block)
--skip-balancefalseSkip the step-holder balance batch (faster incremental scans; omits outstanding balance)
--lifecycle-cachetrueSummary only: reuse/extend local cumulative cache under ~/.aries/xyo-rewards/<network>/lifecycle/v1/
--refresh-lifecycle-cachefalseSummary only: force a full cumulative rescan and rewrite the local cache
--concurrency <n>8Indexed ranges read concurrently, from 1 to 16
--jsonfalseStable machine-readable output; XL1 amounts include atto and decimal forms
--explainfalseShow indexed frame use, direct reads, gateway setup/scan/balance requests, bytes, timing, and SDK budget warnings
--no-progressSuppress 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.

PositionalDescription
dataPath to a .json/.jsonl file, or an inline transaction JSON tuple [bw, payloads[]]. Omit to read from stdin.
OptionDefaultDescription
-d, --detailfalsePrint per-transaction error details (always shown for invalid transactions)

Input modes (resolved in priority order):

ModeExample
File patharies xyo tx validate ./tx.json
File path (JSONL batch)aries xyo tx validate ./txs.jsonl
Inline JSONaries xyo tx validate '[[...], [...]]'
Piped stdincat 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 line

Output:

Total:   3
Valid:   2
Invalid: 1

[2] ./txs.jsonl:3
  - TransactionGasValidator: insufficient gas

Exit codes: 0 = all valid, 1 = any invalid or parse error.

Configuration

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.

License

LGPL-3.0-only © XY Labs

Credits

Made with 🔥 and ❄️ by AriesTools

Keywords

ariestools

FAQs

Package last updated on 13 Sep 2026

Related posts