@ariestools/cli 0.1.19 → 0.1.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +678 -91
- package/dist/bin/aries.mjs +216102 -148159
- package/dist/bin/daemons/chain-server.mjs +3079 -1363
- package/dist/bin/daemons/dapp-server.mjs +21 -20
- package/dist/bin/daemons/datalake-dev.mjs +3767 -1750
- package/dist/node/datalake.d.ts +48 -9
- package/dist/node/datalake.mjs +1511 -29
- package/package.json +25 -24
- package/dist/plugins/xy-readme/.claude-plugin/plugin.json +0 -5
- package/dist/plugins/xy-readme/skills/readme-audit/SKILL.md +0 -187
- package/dist/plugins/xy-readme/skills/readme-author/SKILL.md +0 -293
- package/dist/plugins/xy-readme/skills/readme-init/SKILL.md +0 -243
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @ariestools/cli
|
|
2
2
|
|
|
3
|
-
Aries Tools CLI — a suite by Arie Trouw for AI-client tooling,
|
|
3
|
+
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.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -15,8 +15,10 @@ pnpm add -g @ariestools/cli
|
|
|
15
15
|
```sh
|
|
16
16
|
aries --help
|
|
17
17
|
aries info
|
|
18
|
-
aries
|
|
18
|
+
aries secrets status
|
|
19
|
+
ariesi hash --algorithm pdq ./photo.jpg
|
|
19
20
|
ariesi plex libraries
|
|
21
|
+
ariesi gate pair ticker BTC_USDT
|
|
20
22
|
aries wallet create
|
|
21
23
|
aries witness url --url https://example.com
|
|
22
24
|
aries datalake list
|
|
@@ -32,9 +34,9 @@ private monorepo packages (`aries-datalake-plane`, etc.) installed.
|
|
|
32
34
|
export ARIES_HOME=/tmp/aries-test-$$
|
|
33
35
|
|
|
34
36
|
# Free ports by default (or pass --control-port / --plane-port)
|
|
35
|
-
aries datalake
|
|
37
|
+
aries datalake up
|
|
36
38
|
aries datalake list
|
|
37
|
-
aries datalake
|
|
39
|
+
aries datalake down
|
|
38
40
|
```
|
|
39
41
|
|
|
40
42
|
### Programmatic client (no shell-out per request)
|
|
@@ -45,7 +47,7 @@ import {
|
|
|
45
47
|
RestPayloadsClient,
|
|
46
48
|
} from '@ariestools/cli/datalake'
|
|
47
49
|
|
|
48
|
-
// After `aries datalake
|
|
50
|
+
// After `aries datalake up` (or with baseUrl + authToken options)
|
|
49
51
|
const control = createDatalakeClient()
|
|
50
52
|
const lakes = await control.list()
|
|
51
53
|
// …
|
|
@@ -56,17 +58,22 @@ Private workspace packages stay private; runtime daemons ship under
|
|
|
56
58
|
|
|
57
59
|
## Top-level commands
|
|
58
60
|
|
|
61
|
+
The reference includes public `aries` commands and internal `ariesi` commands.
|
|
62
|
+
Internal commands require the private CLI build and an internal license tier;
|
|
63
|
+
the public installation cannot run them.
|
|
64
|
+
|
|
59
65
|
```text
|
|
60
66
|
aries ai AI client tools
|
|
61
|
-
|
|
67
|
+
ariesi bank Manage bank witness settings
|
|
62
68
|
aries chain Run a local published-chain S3/REST server
|
|
63
|
-
aries clamp Run commands inside a permission-controlled sandbox
|
|
64
69
|
aries datalake Provision and manage on-demand XL1 datalakes
|
|
65
|
-
|
|
70
|
+
ariesi gate Query the Gate exchange API (internal build)
|
|
71
|
+
ariesi hash [file] Generate a hash (sha256, xyo, fuzzy, perceptual)
|
|
66
72
|
aries info Display version and environment info
|
|
67
|
-
|
|
68
|
-
|
|
73
|
+
ariesi npmjs Inspect and lint npmjs org packages
|
|
74
|
+
ariesi pentair Manage Pentair ScreenLogic systems
|
|
69
75
|
ariesi plex Inspect and manage Plex Media Server (internal build)
|
|
76
|
+
aries secrets Secrets foundation, static AI instructions, and the human-only vault path
|
|
70
77
|
aries wallet XL1 wallet — seed phrases, accounts, transactions, contacts
|
|
71
78
|
aries witness Observe data and produce XYO-compliant payloads
|
|
72
79
|
aries xyo XYO protocol utilities
|
|
@@ -79,11 +86,561 @@ Available on every command:
|
|
|
79
86
|
| Option | Description |
|
|
80
87
|
|---|---|
|
|
81
88
|
| `-v, --verbose` | Enable verbose output |
|
|
89
|
+
| `--help-ai` | Print static AI-oriented help for a registered command path |
|
|
82
90
|
| `--version` | Show version number |
|
|
83
91
|
| `--help` | Show help |
|
|
84
92
|
|
|
85
93
|
---
|
|
86
94
|
|
|
95
|
+
## `aries secrets` — Secrets foundation and the human-only vault path
|
|
96
|
+
|
|
97
|
+
The current implementation provides versioned, static discovery and status,
|
|
98
|
+
the read-only inventory listing, local bastion profile and provider
|
|
99
|
+
configuration, and eight human-only commands, `init`, `create`, `reveal`,
|
|
100
|
+
`set`, `generate`, `delete`, `list`, and `describe`, each documented in the
|
|
101
|
+
next sections:
|
|
102
|
+
|
|
103
|
+
```sh
|
|
104
|
+
aries secrets status
|
|
105
|
+
aries secrets status --json
|
|
106
|
+
aries secrets --help-ai
|
|
107
|
+
aries secrets --help-ai --json
|
|
108
|
+
aries secrets init # human-only; no --json form
|
|
109
|
+
aries secrets create --name "Deploy token" --input-fd 3 3<file # human-only; value from fd 3, else the prompt
|
|
110
|
+
aries secrets reveal --secret-id sec_… # human-only; the value, once, to the terminal
|
|
111
|
+
aries secrets set --secret-id sec_… --expected-version <v> --input-fd 3 3<file # human-only; compare-and-swap replace
|
|
112
|
+
aries secrets generate --name "Signing key" --kind random-bytes --length 64 # human-only; drawn in-process, never printed
|
|
113
|
+
aries secrets delete --secret-id sec_… --expected-version <v> # human-only; compare-and-swap delete, not recoverable
|
|
114
|
+
aries secrets list # human-only; metadata only
|
|
115
|
+
aries secrets describe --secret-id sec_… # human-only; metadata only
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
`status` reports the implementation phase (`human-only-storage`) plus three
|
|
119
|
+
live observations: `bastionConfigured` is true when the bastion profile store
|
|
120
|
+
holds at least one profile and `data.bastionStore` names the store path and
|
|
121
|
+
its state (`configured`, `empty`, or `unreadable` — a refused or corrupt store
|
|
122
|
+
is reported, never thrown); `data.providers` carries the negotiated state of
|
|
123
|
+
every provider entry on the selected profile; and `data.humanOnlyPath` states
|
|
124
|
+
whether the human-only path is available on this platform. `data.state` is
|
|
125
|
+
`not-initialized` until a vault exists on the selected profile and
|
|
126
|
+
`human-only-storage` once one does. There is no `initialized` state and no
|
|
127
|
+
authenticated operator: `init` performs no operator or recovery bootstrap, so
|
|
128
|
+
the realm stays provisional and nothing accepts a grant.
|
|
129
|
+
|
|
130
|
+
`aries --help-ai [--json]` discovers registered AI-help subtrees. AI help is
|
|
131
|
+
embedded package content and runs before `.env`, settings, licensing, provider,
|
|
132
|
+
or broker initialization. Its manifest marks future commands as `planned`, the
|
|
133
|
+
human-only commands as `human-only` (risk `human-only`, no `--json` option),
|
|
134
|
+
and carries a `humanOnlyPath` block: `brokered: false`, `humanAttested:
|
|
135
|
+
true`, the eight conditions every human-only command enforces, the platforms
|
|
136
|
+
on which they can be satisfied (`darwin`, `linux`), `unlock:
|
|
137
|
+
'per-invocation'`, and `lease: 'not-available'`.
|
|
138
|
+
|
|
139
|
+
Agent-operational secret access is not implemented. This foundation cannot
|
|
140
|
+
connect to a bastion, create AI identities, authenticate with JWTs, manage
|
|
141
|
+
grants or approvals, or broker a secret to any program. The inventory listing
|
|
142
|
+
below observes presence metadata only: it initializes no provider and reads no
|
|
143
|
+
secret value. The bastion profile and provider commands record non-secret
|
|
144
|
+
configuration only: they contact no bastion and create no socket or vault.
|
|
145
|
+
The one path that touches a vault is human-only and unbrokered, described
|
|
146
|
+
under `aries secrets init`, `aries secrets create`, `aries secrets reveal`,
|
|
147
|
+
and the `set`, `generate`, `delete`, `list`, and `describe` sections below.
|
|
148
|
+
|
|
149
|
+
### The refusal contract
|
|
150
|
+
|
|
151
|
+
All eight human-only commands — `init`, `create`, `reveal`, `set`,
|
|
152
|
+
`generate`, `delete`, `list`, and `describe` — refuse unless standard input
|
|
153
|
+
and standard output are both interactive terminals, the platform provides
|
|
154
|
+
`/dev/tty`, `stty`, and a process-ancestry probe (an allow-list, so `win32`
|
|
155
|
+
and any unknown platform are refused outright), no AI agent host is detected
|
|
156
|
+
through a documented environment signal or an agent binary in the process
|
|
157
|
+
ancestry (an ambiguous probe fails closed), and argv carries no
|
|
158
|
+
structured-output option (`--json`, `--no-json`) and no delivery option
|
|
159
|
+
(`--delivery`, `--destination`, `--output`, `--out`, `--out-file`, `--fd`,
|
|
160
|
+
`--env`, `--clipboard`, `--temp-file`, `--to`) anywhere — including before
|
|
161
|
+
the `secrets` word. A secret value still has two ways in, both of them input
|
|
162
|
+
channels rather than delivery: the masked prompt on the attached terminal,
|
|
163
|
+
and `--input-fd <fd>` on `create` and `set`, which reads the value from a
|
|
164
|
+
descriptor the caller opened. Every refusal is `HUMAN_CHANNEL_REQUIRED`
|
|
165
|
+
(exit 2) with a fixed message on standard error that never reflects an argv
|
|
166
|
+
value and nothing at all on standard output, and the two kinds differ in
|
|
167
|
+
what they record: a refusal by the channel gate — a pipe, a non-terminal, an
|
|
168
|
+
unsupported platform, a detected or ambiguous agent host — is recorded as a
|
|
169
|
+
human-attested `refused` audit event, while an argv refusal is caught by the
|
|
170
|
+
preflight before any store is opened and writes no audit event at all. The
|
|
171
|
+
gate conditions are evaluated in the order above, so a piped or captured
|
|
172
|
+
caller is refused before any `ps` probe runs. Passing the gate refuses the
|
|
173
|
+
non-interactive case; it is not proof of a human, because a pseudo-terminal
|
|
174
|
+
remains agent-drivable.
|
|
175
|
+
|
|
176
|
+
No MCP tool and no GUI reaches this path. The `aries mcp` servers register no
|
|
177
|
+
tool that names a secret and import nothing from the secrets action tree; the
|
|
178
|
+
Electron shell and the dashboard import nothing from that tree either — not
|
|
179
|
+
the human-only modules, not the barrel that re-exports them, not the provider
|
|
180
|
+
seam, and not the encrypted-file vault package — and neither declares
|
|
181
|
+
`@ariestools/cli-lib` as a dependency (the dashboard reads only
|
|
182
|
+
`secrets inventory list --json` by running the packed CLI, which reads no
|
|
183
|
+
value). The vault package itself is not a GUI or IPC API: the only consumers
|
|
184
|
+
of its unlock, create, re-key, and record primitives are the human-only
|
|
185
|
+
command modules that handle plaintext and the provider seam they load it
|
|
186
|
+
through. There is no socket, no daemon, and no lease — a command unlocks the
|
|
187
|
+
vault for that invocation and locks it again before it returns.
|
|
188
|
+
|
|
189
|
+
### Storage layout under `~/.aries/secrets`
|
|
190
|
+
|
|
191
|
+
`ARIES_HOME` relocates `~/.aries` in full. Everything the CLI writes below it
|
|
192
|
+
is created `0600` inside `0700` directories. The three stores it owns —
|
|
193
|
+
`config/bastions.json`, `realms/<realmId>/secrets-index.json`, and
|
|
194
|
+
`audit/human-attested.jsonl` — are also checked when they are read: a group
|
|
195
|
+
or other permission bit, a foreign owner, a symlink, a non-regular file, or
|
|
196
|
+
an oversized one fails the command and names the `chmod` or `chown` fix
|
|
197
|
+
rather than repairing it. The vault files are written the same way and are
|
|
198
|
+
refused on a symlink, a non-regular file, or an oversized one, and their
|
|
199
|
+
directory is created `0700`. Two rows below are operator-authored and are
|
|
200
|
+
never written, moved, or permission-checked by the CLI: `inventory.json`,
|
|
201
|
+
read as declarations only, and `realms/<realmId>/denies.json`, which refuses
|
|
202
|
+
every secret-touching operation in this milestone by existing at all.
|
|
203
|
+
|
|
204
|
+
| Path | Contents |
|
|
205
|
+
| --- | --- |
|
|
206
|
+
| `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). |
|
|
207
|
+
| `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. |
|
|
208
|
+
| `vaults/<providerId>/vault-password.json` | The password verifier: the PBKDF2 salt and a SHA-256 hash of the derived key. Never the password. |
|
|
209
|
+
| `vaults/<providerId>/records.json` | Every secret, as ciphertext with its authenticated metadata. The display name lives inside the encrypted body. |
|
|
210
|
+
| `realms/<realmId>/secrets-index.json` | The routing index: secret ID → `{ providerId, digest }`, and nothing else. |
|
|
211
|
+
| `realms/<realmId>/denies.json` | Deny records, consulted before every secret-touching operation. Nothing in this milestone writes it. |
|
|
212
|
+
| `audit/human-attested.jsonl` | The hash-chained, append-only human-attested audit log: one event per line, no secret value and no grant evidence. |
|
|
213
|
+
| `inventory.json` | The machine-wide managed-secret declarations, written by the operator and only read here. Presence metadata only. `ARIES_SECRETS_INVENTORY` redirects it. |
|
|
214
|
+
|
|
215
|
+
`broker.sock` is recorded on a local profile as the endpoint the future broker
|
|
216
|
+
would use; no socket is created, bound, or connected to in this build.
|
|
217
|
+
|
|
218
|
+
## `aries secrets inventory` — Managed secrets visibility
|
|
219
|
+
|
|
220
|
+
```sh
|
|
221
|
+
aries secrets inventory list
|
|
222
|
+
aries secrets inventory list --repo owner/myapp
|
|
223
|
+
aries secrets inventory list --source env --env-file ./deploy/.env --json
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
`secrets` is always registered at the free tier, so every example works
|
|
227
|
+
unchanged in the internal `ariesi` build.
|
|
228
|
+
|
|
229
|
+
Managed secrets are declared in one schema at two scopes, each a JSON file
|
|
230
|
+
with a root-level `inventory` list:
|
|
231
|
+
|
|
232
|
+
- `~/.aries/secrets/inventory.json` (override with `ARIES_SECRETS_INVENTORY`;
|
|
233
|
+
`ARIES_HOME` relocates `~/.aries`) — machine-wide entries, each optionally
|
|
234
|
+
naming its `repos`. The legacy `~/.config/aries/secrets.json` is still read
|
|
235
|
+
when the new file is absent, with a notice on stderr and
|
|
236
|
+
`data.legacyInventoryPath` under `--json`; move it to the new path.
|
|
237
|
+
- `<repo>/.config/aries/secrets.json` — entries needed by that repository's
|
|
238
|
+
agents. These files are safe to commit: the closed entry shape
|
|
239
|
+
(`service`, `account`, optional `label`, `env`, and — global only — `repos`)
|
|
240
|
+
structurally rejects value-bearing fields, so a committed file can never
|
|
241
|
+
become a secret store.
|
|
242
|
+
|
|
243
|
+
```json
|
|
244
|
+
{
|
|
245
|
+
"version": 1,
|
|
246
|
+
"inventory": [
|
|
247
|
+
{
|
|
248
|
+
"account": "ci-token",
|
|
249
|
+
"env": "GITHUB_TOKEN",
|
|
250
|
+
"label": "GitHub token",
|
|
251
|
+
"service": "github"
|
|
252
|
+
}
|
|
253
|
+
]
|
|
254
|
+
}
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
Presence is metadata only and never returns a value: on macOS the default
|
|
258
|
+
`auto` source probes the Keychain by `(service, account)` existence without
|
|
259
|
+
requesting the password; elsewhere (or with `--source env`) presence means the
|
|
260
|
+
mapped `env` variable is set and non-empty after `.env` loading. Repositories
|
|
261
|
+
are discovered below `ARIES_CODE_ROOT` (default `~/GitHub`). The `--json`
|
|
262
|
+
envelope follows the secrets result schema and contains identifiers and
|
|
263
|
+
presence booleans only — suitable as the dashboard panel's data source.
|
|
264
|
+
|
|
265
|
+
## `aries secrets bastion` — Bastion profiles
|
|
266
|
+
|
|
267
|
+
```sh
|
|
268
|
+
aries secrets bastion add --name "Laptop bastion"
|
|
269
|
+
aries secrets bastion list
|
|
270
|
+
aries secrets bastion show # active or sole profile
|
|
271
|
+
aries secrets bastion show "Laptop bastion" # by display name
|
|
272
|
+
aries secrets bastion show --bastion bpf_… # by profile ID
|
|
273
|
+
aries secrets bastion use "Laptop bastion"
|
|
274
|
+
aries secrets bastion remove "Laptop bastion"
|
|
275
|
+
aries secrets bastion list --json
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
A bastion profile is a closed, versioned, non-secret record naming a realm,
|
|
279
|
+
a bastion, its endpoint, and its providers; it holds no password, token, or
|
|
280
|
+
key material. Profiles live in one envelope at
|
|
281
|
+
`~/.aries/secrets/config/bastions.json` (`ARIES_HOME` relocates `~/.aries`;
|
|
282
|
+
`ARIES_SECRETS_BASTIONS` redirects the file for tests and must be absolute),
|
|
283
|
+
written `0600` inside a `0700` directory. A file or directory with group or
|
|
284
|
+
other permission bits, a foreign owner, a file over 256 KiB, or an unparseable
|
|
285
|
+
file fails every command with `BASTION_CONFIGURATION_INVALID` (exit 9), naming
|
|
286
|
+
only the path and the fix. A redirected store is disclosed on stderr in human
|
|
287
|
+
output and as `data.bastionStore` under `--json`.
|
|
288
|
+
|
|
289
|
+
- `add --name <displayName> [--kind local-ipc]` mints the profile, realm, and
|
|
290
|
+
bastion identifiers, derives the audience, and records the inert socket path
|
|
291
|
+
`<secretsRoot>/broker.sock` without touching the filesystem. The first
|
|
292
|
+
profile written to an empty store becomes the active selection. Every new
|
|
293
|
+
profile starts with one `encrypted-file` provider entry (`encrypted-local`,
|
|
294
|
+
vault directory `<secretsRoot>/vaults/encrypted-local`); no vault is created.
|
|
295
|
+
`--kind remote` is refused with `CAPABILITY_UNSUPPORTED` until Phase 9. A
|
|
296
|
+
display name that collides with an existing profile ID or display name is an
|
|
297
|
+
error, never an overwrite.
|
|
298
|
+
- `list` reads the store only: it never contacts a bastion or starts a broker,
|
|
299
|
+
succeeds on a missing store with an empty table, and marks a `remote`
|
|
300
|
+
profile `unusable in this build`.
|
|
301
|
+
- `show [<profile>] [--bastion <profile>]` resolves by profile ID first, then
|
|
302
|
+
display name, else the active profile, else the sole profile; the result
|
|
303
|
+
names which namespace matched. With nothing selectable it fails with
|
|
304
|
+
`BASTION_NOT_SELECTED`. The endpoint is labeled `not used in this build`.
|
|
305
|
+
- `use <profile>` writes `activeProfileId` and nothing else. Selection is not
|
|
306
|
+
authorization; a `remote` profile is refused.
|
|
307
|
+
- `remove <profile>` deletes the local record and clears an active selection
|
|
308
|
+
that pointed at it. It revokes nothing: grants, delegations, and enrollments
|
|
309
|
+
at the removed realm remain in force and must be revoked at the bastion
|
|
310
|
+
separately, which the result states in both output forms.
|
|
311
|
+
|
|
312
|
+
`add`, `use`, and `remove` are mutating: they print the store path on stderr
|
|
313
|
+
for every write, and an agent must not run them without explicit operator
|
|
314
|
+
instruction (the AI-help manifest carries that rule). Every command takes
|
|
315
|
+
`--json`; the envelope follows the secrets result schema and typed failures
|
|
316
|
+
map to the secrets exit codes.
|
|
317
|
+
|
|
318
|
+
---
|
|
319
|
+
|
|
320
|
+
## `aries secrets provider` — Provider entries
|
|
321
|
+
|
|
322
|
+
```sh
|
|
323
|
+
aries secrets provider list
|
|
324
|
+
aries secrets provider show # active or sole provider
|
|
325
|
+
aries secrets provider show backup # by provider ID
|
|
326
|
+
aries secrets provider add --id backup --kind encrypted-file
|
|
327
|
+
aries secrets provider add --id backup --kind encrypted-file --vault-path /srv/vaults/backup
|
|
328
|
+
aries secrets provider configure backup --vault-path /srv/vaults/backup
|
|
329
|
+
aries secrets provider use backup
|
|
330
|
+
aries secrets provider remove backup
|
|
331
|
+
aries secrets provider test # active or sole provider
|
|
332
|
+
aries secrets provider test backup --json
|
|
333
|
+
aries secrets provider list --bastion "Laptop bastion" --json
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
A provider entry is the non-secret placement record on a bastion profile:
|
|
337
|
+
`providerId`, `kind`, and `configurationRef` (for `encrypted-file`, the
|
|
338
|
+
absolute vault directory, default `<secretsRoot>/vaults/<providerId>`). It
|
|
339
|
+
holds no password and no key material; the vault's own files hold those.
|
|
340
|
+
Every command takes the inherited `--bastion <profile>` (profile ID first,
|
|
341
|
+
then display name; omitted means the active profile, else the sole profile,
|
|
342
|
+
else `BASTION_NOT_SELECTED`) and `--json`, discloses the store as
|
|
343
|
+
`data.bastionStore`, and refuses a `remote` profile with
|
|
344
|
+
`CAPABILITY_UNSUPPORTED`.
|
|
345
|
+
|
|
346
|
+
- `add --id <providerId> --kind encrypted-file [--vault-path <dir>]` appends
|
|
347
|
+
one entry. The kind union is closed at the option table and again at the
|
|
348
|
+
record parser, so `memory` and `macos-keychain` are refused by both. A
|
|
349
|
+
duplicate ID is an error, never an overwrite. No vault and no directory is
|
|
350
|
+
created: initialization needs a password and is human-only.
|
|
351
|
+
- `list` prints every entry with `initialized` — whether `vault.json` exists
|
|
352
|
+
at `configurationRef`, a stat only, with no unlock and no header parse —
|
|
353
|
+
and marks the active provider.
|
|
354
|
+
- `show [<providerId>]` resolves by ID, else the active provider (set by
|
|
355
|
+
`use`), else the sole provider, and carries two fixed notes: unlock is
|
|
356
|
+
per-invocation with no lease, and compare-and-swap is cooperative (it holds
|
|
357
|
+
only among writers honoring the vault store lock).
|
|
358
|
+
- `configure <providerId> --vault-path <dir>` replaces `configurationRef`
|
|
359
|
+
only; the kind is immutable and nothing is created, moved, or unlocked.
|
|
360
|
+
- `remove <providerId>` deletes the entry and clears an active provider
|
|
361
|
+
selection that pointed at it. The vault directory is not deleted, which the
|
|
362
|
+
result states in both output forms. The last provider of a profile cannot
|
|
363
|
+
be removed; remove the profile instead.
|
|
364
|
+
- `use <providerId>` records `activeProviderId`, which satisfies `--provider`
|
|
365
|
+
on management commands only. Placement on `create` and `generate` still
|
|
366
|
+
requires `--provider` whenever the profile lists more than one provider;
|
|
367
|
+
there is no default provider.
|
|
368
|
+
- `test [<providerId>]` resolves like `show` and reports the adapter's
|
|
369
|
+
declared capabilities, `maximumSecretBytes`, a bounded health check, the
|
|
370
|
+
per-invocation unlock mode, and the cooperative compare-and-swap caveat.
|
|
371
|
+
It never prompts, unlocks, lists, or reads: the adapter is built around a
|
|
372
|
+
locked placeholder session, and a locked vault — the designed steady state
|
|
373
|
+
— succeeds with health `locked` and exit 0. Only an unavailable provider
|
|
374
|
+
fails (`PROVIDER_UNAVAILABLE`, exit 7): not initialized (`next.command`
|
|
375
|
+
names the human-only `init`), a corrupt header (reported with a redacted
|
|
376
|
+
diagnostic, never a path), or a health check that misses its deadline
|
|
377
|
+
(retryable). `status` runs the same negotiation for every provider entry
|
|
378
|
+
on the selected profile and reports `providerCount` and per-provider rows
|
|
379
|
+
under the same ok-when-locked rule; it still succeeds when every provider
|
|
380
|
+
is unavailable.
|
|
381
|
+
|
|
382
|
+
`--vault-path` must be absolute and is refused when equal to or inside the
|
|
383
|
+
resolved XL1 wallet root, or inside the directory named by `XL1_WALLET_HOME`
|
|
384
|
+
or `ARIES_WALLET_HOME` when either is set, so a vault never shares a
|
|
385
|
+
directory with a wallet store; the refusal names the rule, never the path.
|
|
386
|
+
`add`, `configure`, `remove`, and `use` are mutating: they print the store
|
|
387
|
+
path on stderr for every write, and an agent must not run them without
|
|
388
|
+
explicit operator instruction.
|
|
389
|
+
|
|
390
|
+
## `aries secrets init` — Human-only vault creation
|
|
391
|
+
|
|
392
|
+
```sh
|
|
393
|
+
aries secrets init # mints "Local bastion" when no profile exists
|
|
394
|
+
aries secrets init --name "Laptop bastion" # display name for the minted profile
|
|
395
|
+
aries secrets init --bastion "Laptop bastion" # an existing profile
|
|
396
|
+
aries secrets init --provider-id backup # another entry; added to the profile when absent
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
`init` is the first human-only, unbrokered command. From an interactive
|
|
400
|
+
terminal it resolves the bastion profile (or mints a local one when none
|
|
401
|
+
exists), ensures an `encrypted-file` provider entry for `--provider-id`
|
|
402
|
+
(default `encrypted-local`, vault directory
|
|
403
|
+
`<secretsRoot>/vaults/<providerId>`), refuses an existing vault at that
|
|
404
|
+
entry's location (`VERSION_CONFLICT`, exit 8; the refusal names the rule,
|
|
405
|
+
never the path), prompts for the vault password twice on `/dev/tty` with
|
|
406
|
+
the vault's 12-character minimum, creates the vault, opens it once to confirm
|
|
407
|
+
it answers under that password, locks it again, and prints the profile,
|
|
408
|
+
provider, and vault summary. Unlock is per-invocation: no lease, session
|
|
409
|
+
file, or key survives the command. The password is read from the terminal
|
|
410
|
+
alone — never from an environment variable or a command-line argument.
|
|
411
|
+
|
|
412
|
+
`init` initializes one vault and one local profile only. It performs no
|
|
413
|
+
operator or recovery bootstrap: the realm stays provisional in the plan's
|
|
414
|
+
sense, nothing accepts a grant, and neither `status` nor `--help-ai`
|
|
415
|
+
describes the operator as authenticated.
|
|
416
|
+
|
|
417
|
+
Every human-only command enforces these rules, each covered by a test:
|
|
418
|
+
|
|
419
|
+
- standard input and standard output must both be interactive terminals; a
|
|
420
|
+
piped, redirected, or captured channel fails with `HUMAN_CHANNEL_REQUIRED`
|
|
421
|
+
(exit 2) on stderr and writes nothing to stdout;
|
|
422
|
+
- a detected AI agent host (Claude Code, Codex, Cursor, Aider, and the other
|
|
423
|
+
documented signals, or an agent binary in the process ancestry) is refused,
|
|
424
|
+
and an ambiguous probe fails closed;
|
|
425
|
+
- there is no `--json` and no delivery option; `--json`, `--no-json`,
|
|
426
|
+
`--delivery`, `--destination`, `--output`, `--fd`, `--env`, `--clipboard`,
|
|
427
|
+
`--temp-file`, or `--to` anywhere in argv — including before the `secrets`
|
|
428
|
+
word — is refused with a fixed message before yargs runs, and the refused
|
|
429
|
+
value is never reflected;
|
|
430
|
+
- the command is not mirrored as an MCP tool and is reachable over no IPC,
|
|
431
|
+
socket, or remote transport;
|
|
432
|
+
- every run, refusal, and failure appends a human-attested, unbrokered event
|
|
433
|
+
to `<secretsRoot>/audit/human-attested.jsonl`; an event that cannot be
|
|
434
|
+
written refuses the operation (`AUDIT_UNAVAILABLE`);
|
|
435
|
+
- the realm's deny records are consulted before a secret-touching operation
|
|
436
|
+
(`init` alone is exempt, because no realm exists before it mints one);
|
|
437
|
+
`create`, `reveal`, `set`, `generate`, `delete`, `list`, and `describe`
|
|
438
|
+
refuse with `POLICY_INVALID` (exit 5) when the deny set cannot be read,
|
|
439
|
+
which in this milestone includes any existing
|
|
440
|
+
`<secretsRoot>/realms/<realmId>/denies.json`, since nothing writes one yet;
|
|
441
|
+
- on `win32` every human-only command fails with `HUMAN_CHANNEL_REQUIRED` and
|
|
442
|
+
reason `platform-unsupported`, which `status` and the manifest state.
|
|
443
|
+
|
|
444
|
+
Agents must not invoke a human-only command, wrap it, or treat it as agent
|
|
445
|
+
access: it identifies no principal, evaluates no grant, and confers nothing
|
|
446
|
+
on any agent principal.
|
|
447
|
+
|
|
448
|
+
## `aries secrets create` — Human-only secret storage
|
|
449
|
+
|
|
450
|
+
```sh
|
|
451
|
+
aries secrets create --name "Deploy token" --input-fd 3 3<./token.txt # value from descriptor 3
|
|
452
|
+
aries secrets create --name "Deploy token" # masked prompt, typed twice
|
|
453
|
+
aries secrets create --name "API key" --provider backup # placement on a named entry
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
`create` stores one secret in the operator's own vault. From an interactive
|
|
457
|
+
terminal it resolves the bastion profile (`--bastion`, else the active
|
|
458
|
+
profile, else the sole profile — it never mints one), places the secret on
|
|
459
|
+
`--provider` (required when the profile lists more than one provider,
|
|
460
|
+
implied when it lists exactly one; the active provider never satisfies
|
|
461
|
+
placement), consults the realm's deny records, appends the `intent` audit
|
|
462
|
+
event, prompts for the vault password on `/dev/tty`, collects the value,
|
|
463
|
+
writes the record, indexes it, locks the vault, and prints the secret ID
|
|
464
|
+
and version — never the value.
|
|
465
|
+
|
|
466
|
+
The value comes from exactly one of two sources. `--input-fd <n>` reads a
|
|
467
|
+
trusted producer's descriptor, which must be numbered 3 or higher, open,
|
|
468
|
+
and not a terminal: standard input is never accepted, because it may be
|
|
469
|
+
model-composed or captured in a transcript. The read is bounded at 65536
|
|
470
|
+
bytes and exactly one trailing newline is removed. Without `--input-fd`
|
|
471
|
+
the value is typed on the terminal, masked, and confirmed. In both cases
|
|
472
|
+
the record is stored as `text/plain`, and the descriptor is read before
|
|
473
|
+
the password prompt so a closed or reserved descriptor is refused early.
|
|
474
|
+
The display name (`--name`, at most 256 bytes, no control characters) is
|
|
475
|
+
stored inside the encrypted record body, where the vault's associated data
|
|
476
|
+
authenticates it.
|
|
477
|
+
|
|
478
|
+
The write spans two stores under two leases and is not atomic, so its order
|
|
479
|
+
is fixed: the provider record is created first, then the index entry. If
|
|
480
|
+
the index write fails, the record is deleted again under the same session
|
|
481
|
+
and the command reports the index failure with provider effect none; if
|
|
482
|
+
that deletion cannot be proven, the command reports
|
|
483
|
+
`PROVIDER_OUTCOME_UNKNOWN` (exit 7) naming the record's opaque ID, which
|
|
484
|
+
may then remain in the vault unindexed until it is reconciled.
|
|
485
|
+
|
|
486
|
+
### The secret index
|
|
487
|
+
|
|
488
|
+
Each realm has one routing index at
|
|
489
|
+
`<secretsRoot>/realms/<realmId>/secrets-index.json`, written `0600` inside
|
|
490
|
+
a `0700` realm directory through the same journaled, atomic store that
|
|
491
|
+
holds the bastion profiles. It maps a secret ID to `{ providerId, digest }`
|
|
492
|
+
and nothing else: no display name, content type, byte length, or timestamp
|
|
493
|
+
ever lands in it, so the file discloses routing alone. The `digest` is
|
|
494
|
+
SHA-256 over the canonical JSON of `{ secretId, providerId, opaqueId }`,
|
|
495
|
+
computed at create and re-verified on every resolve; `opaqueId` equals the
|
|
496
|
+
secret ID by construction, because the human path mints a canonical
|
|
497
|
+
22-character `sec_` token that the encrypted-file vault stores verbatim.
|
|
498
|
+
The digest is unkeyed: it detects an accidental edit or a truncated write,
|
|
499
|
+
and nothing more — any party with write access to the file can recompute
|
|
500
|
+
it. Phase 3 replaces it with a broker-held keyed MAC. Do not delete the
|
|
501
|
+
index: every secret it routes becomes unreachable by ID.
|
|
502
|
+
|
|
503
|
+
## `aries secrets reveal` — Human-only reveal to the terminal
|
|
504
|
+
|
|
505
|
+
```sh
|
|
506
|
+
aries secrets reveal --secret-id sec_… # the value, once, then a newline
|
|
507
|
+
aries secrets reveal --secret-id sec_… --bastion "Laptop" # an explicit profile
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
`reveal` resolves `--secret-id` through the realm's secret index alone. A
|
|
511
|
+
missing entry is `INVALID_ARGUMENT` (exit 2); an entry naming a provider
|
|
512
|
+
the profile no longer lists, or one whose digest no longer verifies, is
|
|
513
|
+
`BASTION_CONFIGURATION_INVALID` (exit 9) — each fails closed, and no
|
|
514
|
+
provider is ever opened or searched to find a matching record. `--provider`
|
|
515
|
+
is refused with `INVALID_ARGUMENT` for the same reason: the index is the
|
|
516
|
+
only routing input, so a reference can never be redirected from the
|
|
517
|
+
command line. The command then consults the deny records, appends the
|
|
518
|
+
`intent` event, prompts for the vault password, reads the record, locks the
|
|
519
|
+
vault, appends the `completed` event, and writes the value exactly once to
|
|
520
|
+
standard output followed by one newline — nothing else is written there.
|
|
521
|
+
There is no other delivery: no destination, file, descriptor, environment,
|
|
522
|
+
clipboard, or temporary file, and no structured output. The value never
|
|
523
|
+
appears in an audit line or on standard error.
|
|
524
|
+
|
|
525
|
+
## `aries secrets set` — Human-only compare-and-swap replace
|
|
526
|
+
|
|
527
|
+
```sh
|
|
528
|
+
aries secrets set --secret-id sec_… --expected-version <v> --input-fd 3 3<./new.txt # value from descriptor 3
|
|
529
|
+
aries secrets set --secret-id sec_… --expected-version <v> # masked prompt, typed twice
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
`set` replaces one secret's value in the operator's own vault. It resolves
|
|
533
|
+
`--secret-id` through the realm's secret index alone, exactly as `reveal`
|
|
534
|
+
does (`--provider` is refused with `INVALID_ARGUMENT`), consults the deny
|
|
535
|
+
records, appends the `intent` event, prompts for the vault password, collects
|
|
536
|
+
the new value from `--input-fd` (3 or higher; read before the password prompt)
|
|
537
|
+
or the masked terminal prompt with confirmation, and performs one
|
|
538
|
+
compare-and-swap replace: `--expected-version` must equal the record's
|
|
539
|
+
current version token exactly as the last `create`, `generate`, `set`, or
|
|
540
|
+
`describe` printed it, or the command fails with `VERSION_CONFLICT` (exit 8)
|
|
541
|
+
and nothing changes. The display name and content type are preserved from
|
|
542
|
+
the record. The reference does not change, so the index is untouched; the
|
|
543
|
+
command prints the new version and the superseded one, never the value. A
|
|
544
|
+
replace whose effect the provider cannot prove is `PROVIDER_OUTCOME_UNKNOWN`
|
|
545
|
+
(exit 7), naming the record and stating that the index still routes it.
|
|
546
|
+
|
|
547
|
+
## `aries secrets generate` — Human-only in-process generation
|
|
548
|
+
|
|
549
|
+
```sh
|
|
550
|
+
aries secrets generate --name "Signing key" --kind random-bytes --length 64
|
|
551
|
+
aries secrets generate --name "Webhook token" --kind base64url-token
|
|
552
|
+
aries secrets generate --name "Database password" --kind password --length 24 --provider backup
|
|
553
|
+
```
|
|
554
|
+
|
|
555
|
+
`generate` draws a value in the operator's own process from Web Crypto and
|
|
556
|
+
stores it exactly as `create` would: placement on `--provider` (or the sole
|
|
557
|
+
provider), the deny consultation, the `intent` event, the password prompt,
|
|
558
|
+
the provider record first with the display name inside the encrypted body,
|
|
559
|
+
then the routing entry in the realm's index, with the same rollback when the
|
|
560
|
+
index write fails. It prints the secret ID, kind, size, and version — the
|
|
561
|
+
value is never printed, logged, audited, or returned, and exists only in the
|
|
562
|
+
record's ciphertext; read it back with `reveal`. `--kind` is a closed list
|
|
563
|
+
and `--length` counts the kind's unit inside an inclusive range:
|
|
564
|
+
|
|
565
|
+
| Kind | Stored as | `--length` | Default | Range |
|
|
566
|
+
| --- | --- | --- | --- | --- |
|
|
567
|
+
| `random-bytes` | `application/octet-stream`, raw bytes | bytes | 32 | 8–1024 |
|
|
568
|
+
| `base64url-token` | `text/plain` | characters | 32 | 8–512 |
|
|
569
|
+
| `password` | `text/plain` | characters | 32 | 8–256 |
|
|
570
|
+
|
|
571
|
+
`password` uses a fixed 70-symbol printable alphabet with the ambiguous
|
|
572
|
+
`0 O 1 l I` removed and no space, quote, backslash, `$`, backtick, or
|
|
573
|
+
redirection character; `base64url-token` uses the 64 base64url symbols. Both
|
|
574
|
+
are uniform: a byte that would bias the draw is rejected, never reduced. An
|
|
575
|
+
unlisted kind or an out-of-range length is `INVALID_ARGUMENT` (exit 2) before
|
|
576
|
+
anything runs.
|
|
577
|
+
|
|
578
|
+
## `aries secrets delete` — Human-only compare-and-swap delete
|
|
579
|
+
|
|
580
|
+
```sh
|
|
581
|
+
aries secrets delete --secret-id sec_… --expected-version <v>
|
|
582
|
+
```
|
|
583
|
+
|
|
584
|
+
`delete` resolves `--secret-id` through the index alone, consults the deny
|
|
585
|
+
records, appends the `intent` event, prompts for the vault password, and
|
|
586
|
+
deletes the record under the `--expected-version` guard; a stale guard is
|
|
587
|
+
`VERSION_CONFLICT` (exit 8) and nothing changes. It then removes the routing
|
|
588
|
+
entry from the realm's index: the tombstone is the removal itself, so the ID
|
|
589
|
+
no longer resolves through any command and a later `describe` or `reveal`
|
|
590
|
+
stops at the index with `INVALID_ARGUMENT`. **The vault record is gone and is
|
|
591
|
+
not recoverable through aries**: the encrypted-file provider discards the
|
|
592
|
+
ciphertext and keeps no tombstone, which the receipt reports as
|
|
593
|
+
`unrecoverable`. The audit line records the secret ID and the fresh tombstone
|
|
594
|
+
version only. If the record is deleted but the index cannot be updated, the
|
|
595
|
+
command reports `PROVIDER_OUTCOME_UNKNOWN` (exit 7) naming both facts — the
|
|
596
|
+
record is gone, the index may still route the ID. Until you reconcile,
|
|
597
|
+
`describe` on that ID fails either at the vault with `RESOURCE_UNAVAILABLE`,
|
|
598
|
+
with `list` showing it as `missing`, or at the index with `INVALID_ARGUMENT`
|
|
599
|
+
if the entry did go after all.
|
|
600
|
+
|
|
601
|
+
## `aries secrets list` — Human-only metadata listing
|
|
602
|
+
|
|
603
|
+
```sh
|
|
604
|
+
aries secrets list # the active provider, or the sole provider
|
|
605
|
+
aries secrets list --provider backup # one provider entry
|
|
606
|
+
```
|
|
607
|
+
|
|
608
|
+
`list` resolves the provider entry (`--provider`, else the active provider,
|
|
609
|
+
else the sole one), consults the deny records for the realm's catalog,
|
|
610
|
+
prompts for the vault password, and prints metadata alone: for every index
|
|
611
|
+
entry routed to that provider, the secret ID, version, incarnation, content
|
|
612
|
+
type, byte length, display name, and created and updated timestamps, read
|
|
613
|
+
from the vault's own description; an entry whose record the provider no
|
|
614
|
+
longer holds is shown as `missing`, one whose index digest does not verify
|
|
615
|
+
as `integrity-failed` (the vault is not consulted for it), and one whose
|
|
616
|
+
record the vault holds but will not describe as `undescribable` with the
|
|
617
|
+
failure code — a single unreadable record never hides the rest of the
|
|
618
|
+
catalog. Entries routed to other providers on the profile are counted, not
|
|
619
|
+
listed. The
|
|
620
|
+
command also enumerates the provider's own records and reports every record
|
|
621
|
+
the index does not route to that provider as `unindexed`, with its opaque
|
|
622
|
+
ID, version, byte length, and timestamps — never its value or display name.
|
|
623
|
+
An unindexed record is reachable by no aries command until it is reconciled,
|
|
624
|
+
because the index is the only routing input. No value is ever printed.
|
|
625
|
+
|
|
626
|
+
## `aries secrets describe` — Human-only metadata for one secret
|
|
627
|
+
|
|
628
|
+
```sh
|
|
629
|
+
aries secrets describe --secret-id sec_…
|
|
630
|
+
```
|
|
631
|
+
|
|
632
|
+
`describe` resolves `--secret-id` through the index alone (`--provider` is
|
|
633
|
+
refused), consults the deny records, prompts for the vault password, and
|
|
634
|
+
prints the record's current version, incarnation, created and updated
|
|
635
|
+
timestamps, content type, byte length, and display name — never the value,
|
|
636
|
+
which is decrypted only to measure it and wiped inside the library. A
|
|
637
|
+
record the vault does not hold is `RESOURCE_UNAVAILABLE` (exit 7); an ID the
|
|
638
|
+
index does not route is `INVALID_ARGUMENT` (exit 2) before any vault is
|
|
639
|
+
opened. The printed version is the `--expected-version` for the next `set`
|
|
640
|
+
or `delete`.
|
|
641
|
+
|
|
642
|
+
---
|
|
643
|
+
|
|
87
644
|
## `aries chain` — Local published-chain server
|
|
88
645
|
|
|
89
646
|
```sh
|
|
@@ -118,17 +675,17 @@ CA file for another HTTPS S3-compatible endpoint.
|
|
|
118
675
|
|
|
119
676
|
---
|
|
120
677
|
|
|
121
|
-
## `
|
|
678
|
+
## `ariesi bank` — Manage bank witness settings
|
|
122
679
|
|
|
123
680
|
```sh
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
681
|
+
ariesi bank capitalone config get
|
|
682
|
+
ariesi bank capitalone config set base-url https://api-sandbox.capitalone.com
|
|
683
|
+
ariesi bank capitalone config set token-url https://api-sandbox.capitalone.com/oauth2/token
|
|
684
|
+
ariesi bank capitalone config set client-id "$CAPITALONE_CLIENT_ID"
|
|
685
|
+
ariesi bank capitalone config set client-secret "$CAPITALONE_CLIENT_SECRET"
|
|
686
|
+
ariesi bank capitalone config set accounts-path /accounts
|
|
687
|
+
ariesi bank capitalone config set balances-path '/accounts/{accountId}/balances'
|
|
688
|
+
ariesi bank capitalone config set transactions-path '/accounts/{accountId}/transactions'
|
|
132
689
|
```
|
|
133
690
|
|
|
134
691
|
Capital One config is stored in `~/.aries/bank/capitalone.json` with restricted
|
|
@@ -163,15 +720,15 @@ for one run.
|
|
|
163
720
|
|
|
164
721
|
---
|
|
165
722
|
|
|
166
|
-
## `
|
|
723
|
+
## `ariesi pentair` — Manage Pentair ScreenLogic systems
|
|
167
724
|
|
|
168
725
|
```sh
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
726
|
+
ariesi pentair config get
|
|
727
|
+
ariesi pentair config get address
|
|
728
|
+
ariesi pentair config set address 192.0.2.10
|
|
729
|
+
ariesi pentair config set port 80
|
|
730
|
+
ariesi pentair config set system-name "Pentair ScreenLogic"
|
|
731
|
+
ariesi pentair circuit runtime set --circuit-id 6 --hours 24 --on
|
|
175
732
|
```
|
|
176
733
|
|
|
177
734
|
Pentair config is stored in `~/.aries/pentair/config.json` and is used by the
|
|
@@ -192,7 +749,7 @@ Pentair witness and circuit commands. `ARIES_HOME` overrides the `~/.aries` root
|
|
|
192
749
|
|
|
193
750
|
`config get` redacts `password`; pass `--show-secrets` to print it.
|
|
194
751
|
|
|
195
|
-
### `
|
|
752
|
+
### `ariesi pentair circuit runtime set`
|
|
196
753
|
|
|
197
754
|
Set the ScreenLogic circuit egg timer. Runtime values are sent to ScreenLogic as
|
|
198
755
|
minutes; `--hours 24` becomes `1440`.
|
|
@@ -283,64 +840,93 @@ List items currently in Plex's optimizer queue. When `--library` is omitted, Ari
|
|
|
283
840
|
|
|
284
841
|
---
|
|
285
842
|
|
|
286
|
-
## `
|
|
843
|
+
## `ariesi gate` — Gate exchange API
|
|
287
844
|
|
|
288
|
-
|
|
845
|
+
The Gate command is available from the internal `ariesi` build with
|
|
846
|
+
`license.tier=internal`.
|
|
289
847
|
|
|
290
|
-
|
|
848
|
+
A read-only client for the [Gate](https://www.gate.com) exchange REST API (v4). It calls only
|
|
849
|
+
unauthenticated public spot endpoints — no API key is read, and nothing is ever traded.
|
|
850
|
+
|
|
851
|
+
These options are available on every `gate` subcommand:
|
|
291
852
|
|
|
292
853
|
| Option | Default | Description |
|
|
293
854
|
|---|---|---|
|
|
855
|
+
| `--base-url <url>` | `ARIES_GATE_API_URL`, `GATE_API_URL`, or `https://api.gateio.ws/api/v4` | Gate API v4 base URL |
|
|
294
856
|
| `--json` | `false` | Output as JSON |
|
|
295
857
|
|
|
296
|
-
### `
|
|
858
|
+
### `ariesi gate pair list <symbol>`
|
|
297
859
|
|
|
298
|
-
|
|
860
|
+
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.
|
|
299
861
|
|
|
300
862
|
| Option | Default | Description |
|
|
301
863
|
|---|---|---|
|
|
302
|
-
| `--
|
|
864
|
+
| `--side any\|base\|quote` | `any` | Match the symbol only as the base or only as the quote currency |
|
|
865
|
+
| `--all` | `false` | Include pairs whose trade status is not `tradable` |
|
|
303
866
|
|
|
304
|
-
|
|
867
|
+
```sh
|
|
868
|
+
ariesi gate pair list XYO
|
|
869
|
+
```
|
|
305
870
|
|
|
306
|
-
|
|
871
|
+
```text
|
|
872
|
+
XYO_ETH XYO Network / Ethereum fee 0.2%
|
|
873
|
+
XYO_USDT XYO Network / Tether fee 0.2%
|
|
874
|
+
2 pair(s) for XYO
|
|
875
|
+
```
|
|
307
876
|
|
|
308
|
-
|
|
309
|
-
|---|---|---|
|
|
310
|
-
| `--scope <all\|project\|home>` | `all` | Check project config, shared/custom home config, or both |
|
|
311
|
-
| `--json` | `false` | Output as JSON |
|
|
877
|
+
### `ariesi gate pair ticker <pair>`
|
|
312
878
|
|
|
313
|
-
|
|
879
|
+
Show the 24-hour spot ticker for a single pair — last price, change, bid/ask, high/low, and base + quote volume.
|
|
314
880
|
|
|
315
|
-
|
|
881
|
+
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`).
|
|
316
882
|
|
|
317
883
|
```sh
|
|
318
|
-
|
|
319
|
-
aries clamp policy list # List available clamp policies
|
|
320
|
-
aries clamp policy show <name> # Show a clamp policy
|
|
321
|
-
aries clamp policy init # Create a starter .aries-clamp.json
|
|
884
|
+
ariesi gate pair ticker BTC_USDT
|
|
322
885
|
```
|
|
323
886
|
|
|
324
|
-
|
|
887
|
+
```text
|
|
888
|
+
BTC_USDT
|
|
889
|
+
last 78862
|
|
890
|
+
change 24h +0.04%
|
|
891
|
+
bid / ask 78861.9 / 78862
|
|
892
|
+
high / low 79235.9 / 77638.6
|
|
893
|
+
base volume 4902.5960069814 BTC
|
|
894
|
+
quote volume 384979909.02896446684 USDT
|
|
895
|
+
```
|
|
325
896
|
|
|
326
|
-
|
|
327
|
-
|
|
897
|
+
---
|
|
898
|
+
|
|
899
|
+
## `aries ai` — AI client tools
|
|
900
|
+
|
|
901
|
+
### `aries ai detect`
|
|
902
|
+
|
|
903
|
+
Scan for installed AI clients.
|
|
904
|
+
|
|
905
|
+
| Option | Default | Description |
|
|
328
906
|
|---|---|---|
|
|
329
|
-
| `
|
|
330
|
-
|
|
907
|
+
| `--json` | `false` | Output as JSON |
|
|
908
|
+
|
|
909
|
+
### `aries ai lint [path]`
|
|
910
|
+
|
|
911
|
+
Check Claude Code and Codex AI configuration drift. The folder defaults to the current directory.
|
|
331
912
|
|
|
332
913
|
| Option | Default | Description |
|
|
333
914
|
|---|---|---|
|
|
334
|
-
|
|
|
335
|
-
| `--
|
|
336
|
-
| `--dry-run` | `false` | Show what would be sandboxed without running |
|
|
915
|
+
| `--scope <all\|project\|home>` | `all` | Check project config, shared/custom home config, or both |
|
|
916
|
+
| `--json` | `false` | Output as JSON |
|
|
337
917
|
|
|
338
|
-
|
|
339
|
-
|
|
918
|
+
### `aries ai skills list [tool]`
|
|
919
|
+
|
|
920
|
+
List installed skills discovered for Claude Code, Codex, and Cursor. The optional
|
|
921
|
+
`tool` positional accepts `claude`, `codex`, or `cursor`; omit it to inspect all
|
|
922
|
+
three. Cursor currently reports no skills. Detection and listing do not modify client configuration.
|
|
923
|
+
|
|
924
|
+
| Option | Default | Description |
|
|
340
925
|
|---|---|---|
|
|
341
|
-
| `
|
|
926
|
+
| `--json` | `false` | Output as JSON |
|
|
342
927
|
|
|
343
|
-
|
|
928
|
+
AI lint also inspects shared/custom home plugin manifests and skill files for
|
|
929
|
+
drift without changing them.
|
|
344
930
|
|
|
345
931
|
---
|
|
346
932
|
|
|
@@ -486,14 +1072,17 @@ aries datalake audit purge # Delete rotated audit files older than --max-age-
|
|
|
486
1072
|
### Local development
|
|
487
1073
|
|
|
488
1074
|
```sh
|
|
489
|
-
aries datalake
|
|
490
|
-
aries datalake
|
|
491
|
-
aries datalake
|
|
492
|
-
aries datalake
|
|
493
|
-
aries datalake
|
|
1075
|
+
aries datalake up # Start the local control + data plane dev server
|
|
1076
|
+
aries datalake down # Stop it (clears credentials)
|
|
1077
|
+
aries datalake status # Report whether the local dev server is running and healthy
|
|
1078
|
+
aries datalake logs # Print recent dev server log output
|
|
1079
|
+
aries datalake reset # Stop the dev server and wipe all local state
|
|
494
1080
|
```
|
|
495
1081
|
|
|
496
|
-
|
|
1082
|
+
The original `aries datalake dev up|down|status|logs|reset` spellings remain
|
|
1083
|
+
available for compatibility.
|
|
1084
|
+
|
|
1085
|
+
#### `aries datalake up`
|
|
497
1086
|
| Option | Default | Description |
|
|
498
1087
|
|---|---|---|
|
|
499
1088
|
| `--control-port <n>` | free loopback port | Control-plane port |
|
|
@@ -506,7 +1095,7 @@ aries datalake dev reset # Stop the dev server and wipe all local state
|
|
|
506
1095
|
| `--audit-rotate` | `false` | Rotate the audit log daily (writes to `<home>/dev/audit/`) |
|
|
507
1096
|
| `--audit-keep-days <n>` | | Prune rotated audit files older than this many days |
|
|
508
1097
|
|
|
509
|
-
#### `aries datalake
|
|
1098
|
+
#### `aries datalake logs`
|
|
510
1099
|
| Option | Default | Description |
|
|
511
1100
|
|---|---|---|
|
|
512
1101
|
| `-f, --follow` | `false` | Stream new lines as they arrive |
|
|
@@ -580,14 +1169,14 @@ preserving the hydrated transaction tuple and all existing signatures.
|
|
|
580
1169
|
|
|
581
1170
|
---
|
|
582
1171
|
|
|
583
|
-
## `
|
|
1172
|
+
## `ariesi hash [file]` — content hashing
|
|
584
1173
|
|
|
585
1174
|
```text
|
|
586
|
-
|
|
587
|
-
|
|
1175
|
+
ariesi hash [file] [options]
|
|
1176
|
+
ariesi hash compare <hashA> <hashB> --algorithm <name> [--json]
|
|
588
1177
|
```
|
|
589
1178
|
|
|
590
|
-
Reads input from `[file]` (positional), `--string`, or piped stdin (priority order). Dispatches to one of
|
|
1179
|
+
Reads input from `[file]` (positional), `--string`, or piped stdin (priority order). Dispatches to one of 10 algorithms.
|
|
591
1180
|
|
|
592
1181
|
### Options
|
|
593
1182
|
|
|
@@ -606,7 +1195,6 @@ Reads input from `[file]` (positional), `--string`, or piped stdin (priority ord
|
|
|
606
1195
|
|---|---|---|---|---|---|
|
|
607
1196
|
| `sha256` | strict | bytes | 64-char hex | — | `exact-match` |
|
|
608
1197
|
| `xyo` | strict | JSON | 64-char hex | — | `exact-match` |
|
|
609
|
-
| `tlsh` | fuzzy-byte | ≥50 bytes | 70-char hex | — | `tlsh-bit-hamming` ⚠ |
|
|
610
1198
|
| `nilsimsa` | fuzzy-byte | bytes | 64-char hex | — | `nilsimsa-score` |
|
|
611
1199
|
| `ssdeep` | fuzzy-byte | bytes | `bs:h1:h2` | `ssdeep` | `ssdeep-levenshtein` ⚠ |
|
|
612
1200
|
| `phash` | perceptual-image | image | 16-char hex (64-bit) | — | `hamming-64` |
|
|
@@ -617,7 +1205,6 @@ Reads input from `[file]` (positional), `--string`, or piped stdin (priority ord
|
|
|
617
1205
|
| `video-frames` | video | video file | JSON `{fps, frames:[{t,hash}]}` | `ffmpeg` | `frame-sequence-<algo>@<fps>fps` |
|
|
618
1206
|
|
|
619
1207
|
⚠ — Approximations, not the canonical reference scores:
|
|
620
|
-
- `tlsh-bit-hamming` — the upstream `tlsh` npm package only exposes hashing, not the canonical TLSH-diff algorithm. We use bit-level Hamming over the hash body as a proxy.
|
|
621
1208
|
- `ssdeep-levenshtein` — block-size-aware Levenshtein, without the canonical block-size attenuation curve.
|
|
622
1209
|
|
|
623
1210
|
### External binary install
|
|
@@ -639,29 +1226,29 @@ Each algorithm probes its binary at hash time and prints clear install instructi
|
|
|
639
1226
|
|
|
640
1227
|
```sh
|
|
641
1228
|
# Strict
|
|
642
|
-
|
|
643
|
-
|
|
1229
|
+
ariesi hash --string "hello"
|
|
1230
|
+
ariesi hash ./payload.json --algorithm xyo
|
|
644
1231
|
|
|
645
1232
|
# Byte-fuzzy
|
|
646
|
-
|
|
647
|
-
|
|
1233
|
+
ariesi hash --algorithm nilsimsa ./binary.exe
|
|
1234
|
+
ariesi hash compare <hashA> <hashB> --algorithm nilsimsa
|
|
648
1235
|
|
|
649
1236
|
# Perceptual image
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
1237
|
+
ariesi hash --algorithm phash ./photo.jpg
|
|
1238
|
+
ariesi hash --algorithm pdq ./photo.jpg
|
|
1239
|
+
ariesi hash compare <hashA> <hashB> --algorithm pdq
|
|
653
1240
|
|
|
654
1241
|
# Audio
|
|
655
|
-
|
|
656
|
-
|
|
1242
|
+
ariesi hash --algorithm chromaprint ./song.mp3 > song.fp.json
|
|
1243
|
+
ariesi hash compare "$(cat a.fp.json)" "$(cat b.fp.json)" --algorithm chromaprint --json
|
|
657
1244
|
|
|
658
1245
|
# Video
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
1246
|
+
ariesi hash --algorithm video-frames --fps 1 ./movie.mkv > movie.fp.json
|
|
1247
|
+
ariesi hash --algorithm video-frames --fps 1 --frame-algorithm pdq ./movie.mkv > movie-pdq.fp.json
|
|
1248
|
+
ariesi hash compare "$(cat a.fp.json)" "$(cat b.fp.json)" --algorithm video-frames
|
|
662
1249
|
```
|
|
663
1250
|
|
|
664
|
-
### `
|
|
1251
|
+
### `ariesi hash compare <hashA> <hashB>`
|
|
665
1252
|
|
|
666
1253
|
| Positional | | Description |
|
|
667
1254
|
|---|---|---|
|
|
@@ -679,18 +1266,18 @@ The compare command needs only the two hash strings — works against hashes gen
|
|
|
679
1266
|
|
|
680
1267
|
---
|
|
681
1268
|
|
|
682
|
-
## `
|
|
1269
|
+
## `ariesi npmjs` — npmjs org package checks
|
|
683
1270
|
|
|
684
1271
|
```sh
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
1272
|
+
ariesi npmjs list --org=xylabs
|
|
1273
|
+
ariesi npmjs lint --org=xylabs
|
|
1274
|
+
ariesi npmjs lint --org=xylabs --fix
|
|
1275
|
+
ariesi npmjs lint # all auth-visible org packages
|
|
689
1276
|
```
|
|
690
1277
|
|
|
691
|
-
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`, `
|
|
1278
|
+
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.
|
|
692
1279
|
|
|
693
|
-
### `
|
|
1280
|
+
### `ariesi npmjs list`
|
|
694
1281
|
|
|
695
1282
|
| Option | Default | Description |
|
|
696
1283
|
|---|---|---|
|
|
@@ -698,7 +1285,7 @@ By default, package discovery uses your current npm CLI authentication via `npm
|
|
|
698
1285
|
| `--public-only` | `false` | List only public packages without using `npm access` |
|
|
699
1286
|
| `--json` | `false` | Output as JSON |
|
|
700
1287
|
|
|
701
|
-
### `
|
|
1288
|
+
### `ariesi npmjs lint`
|
|
702
1289
|
|
|
703
1290
|
Find packages that are not marked deprecated but probably should be. V1 reports warning-only findings and exits `0` unless an operational error occurs.
|
|
704
1291
|
|