@airwallex/airi-cli 0.1.0-beta.1 → 0.1.0-beta.3
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 +97 -10
- package/checksums.json +4 -4
- package/package.json +1 -1
- package/scripts/postinstall.mjs +40 -23
package/README.md
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
# airi-cli
|
|
2
2
|
|
|
3
|
-

|
|
4
4
|
|
|
5
5
|
Command-line tool for the Airi wallet. Authenticate with OAuth, inspect your
|
|
6
6
|
session, and drive an **agentic checkout** — list payment methods, create a
|
|
7
|
-
payment mandate, fetch the single-use checkout credential,
|
|
8
|
-
|
|
7
|
+
payment mandate, fetch the single-use checkout credential, report the result,
|
|
8
|
+
and cancel a mandate — or browse mandates already in the wallet, from your
|
|
9
|
+
terminal or an AI agent.
|
|
9
10
|
|
|
10
11
|
Results are printed to stdout as JSON, so they are easy to consume from scripts
|
|
11
12
|
and agents.
|
|
@@ -13,7 +14,8 @@ and agents.
|
|
|
13
14
|
## Installation
|
|
14
15
|
|
|
15
16
|
airi-cli is available for macOS and Linux as a single self-contained binary.
|
|
16
|
-
|
|
17
|
+
|
|
18
|
+
### npm
|
|
17
19
|
|
|
18
20
|
```bash
|
|
19
21
|
npm install -g @airwallex/airi-cli@beta
|
|
@@ -23,17 +25,68 @@ This installs the `@airwallex/airi-cli` package, which downloads the prebuilt
|
|
|
23
25
|
binary for your platform, verifies its SHA256 checksum, and puts `airi-cli` on
|
|
24
26
|
your `PATH`.
|
|
25
27
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
+
To run it once without installing globally, use npx:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npx @airwallex/airi-cli@beta
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
#### Switching from a `curl | sh` install
|
|
35
|
+
|
|
36
|
+
If you previously installed with the `install.sh` script (via `curl`), remove
|
|
37
|
+
that copy first — otherwise it may stay ahead of the npm one on your `PATH` and
|
|
38
|
+
keep shadowing it, so `airi-cli` keeps running the old binary.
|
|
39
|
+
|
|
40
|
+
Check for more than one `airi-cli` on your `PATH`:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
which -a airi-cli
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
If an entry under `~/.local/bin` (the `install.sh` default) shows up alongside
|
|
47
|
+
the npm one, remove the old install:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
curl -fsSL https://raw.githubusercontent.com/airwallex/airi-cli/master/install.sh | sh -s -- uninstall
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Then reopen your shell and re-check with `which -a airi-cli`.
|
|
54
|
+
|
|
55
|
+
### install.sh (fallback)
|
|
56
|
+
|
|
57
|
+
If npm is not available, install the binary directly with the install script:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
curl -fsSL https://raw.githubusercontent.com/airwallex/airi-cli/master/install.sh | sh
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
To uninstall (removes the binary):
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
curl -fsSL https://raw.githubusercontent.com/airwallex/airi-cli/master/install.sh | sh -s -- uninstall
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Install-time environment variables
|
|
28
70
|
|
|
29
|
-
|
|
71
|
+
Both install methods honour the same variables and behave identically, except
|
|
72
|
+
where noted:
|
|
30
73
|
|
|
31
74
|
| Variable | Description |
|
|
32
75
|
|----------|-------------|
|
|
33
|
-
| `AIRI_CLI_VERSION` |
|
|
34
|
-
| `
|
|
76
|
+
| `AIRI_CLI_VERSION` | Install a specific release tag (e.g. `v0.1.0`) instead of the default. With npm the pinned checksum only matches the package's own version, so overriding it there also requires `AIRI_CLI_SKIP_CHECKSUM=1`. |
|
|
77
|
+
| `AIRI_CLI_INSTALL_DIR` | install.sh only: where to install (default: `$HOME/.local/bin`). npm always installs inside the package and ignores this. |
|
|
35
78
|
| `AIRI_CLI_SKIP_CHECKSUM` | **Local development only.** Set to `1` to bypass SHA256 verification. Never use this in production or CI. |
|
|
36
|
-
| `
|
|
79
|
+
| `AIRI_CLI_SKIP_SKILLS` | Set to `1` to skip deploying the bundled agent skills. |
|
|
80
|
+
|
|
81
|
+
Both methods deploy the bundled agent skills at install time. You can also
|
|
82
|
+
deploy them to a specific project with:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
npx skills add airwallex/airi-cli
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
or re-run deployment any time with `airi-cli skills install` (see
|
|
89
|
+
[Skills](#skills)).
|
|
37
90
|
|
|
38
91
|
### Checking for updates
|
|
39
92
|
|
|
@@ -151,6 +204,22 @@ after `auth login`, is:
|
|
|
151
204
|
|
|
152
205
|
4. **Report the result** — after submitting the checkout, always report the
|
|
153
206
|
outcome with `airi-cli mandate result --mandate-id <id> --result <SUCCEEDED|CANCELLED|DECLINED>`.
|
|
207
|
+
5. **Cancel a mandate** — when the user asks to cancel, run
|
|
208
|
+
`airi-cli mandate cancel --mandate-id <id>`. The id is a flag, not a
|
|
209
|
+
positional argument. A cancelled mandate's status becomes `DENIED`. An
|
|
210
|
+
agent should cancel only when the user requests it.
|
|
211
|
+
|
|
212
|
+
## Browsing mandates
|
|
213
|
+
|
|
214
|
+
`airi-cli mandate list` returns the user's mandates, most recent first. Page
|
|
215
|
+
with `--page` (0-based) and `--size` when `hasMore` is true. Filter with
|
|
216
|
+
repeatable `--status` (`CREATED`, `AUTHENTICATED`, `READY`, `COMPLETED`,
|
|
217
|
+
`FAILED`, `DENIED`) and `--created-from` / `--created-to` (full ISO-8601
|
|
218
|
+
timestamps, for example `2026-10-01T00:00:00Z`).
|
|
219
|
+
|
|
220
|
+
```bash
|
|
221
|
+
airi-cli mandate list --status READY --size 10 --pretty
|
|
222
|
+
```
|
|
154
223
|
|
|
155
224
|
## Commands
|
|
156
225
|
|
|
@@ -161,7 +230,9 @@ after `auth login`, is:
|
|
|
161
230
|
| `airi-cli auth whoami` | Print the current sign-in status. |
|
|
162
231
|
| `airi-cli auth logout` | Sign out by removing the stored session (local only). |
|
|
163
232
|
| `airi-cli payment-methods list` | List payment methods available for agentic checkout. |
|
|
233
|
+
| `airi-cli mandate list` | List payment mandates, most recent first. |
|
|
164
234
|
| `airi-cli mandate create` | Create a payment mandate for a checkout. |
|
|
235
|
+
| `airi-cli mandate cancel` | Cancel a payment mandate (`status` becomes `DENIED`). |
|
|
165
236
|
| `airi-cli mandate get-credential` | Poll for and fetch the single-use checkout credential. |
|
|
166
237
|
| `airi-cli mandate result` | Report the transaction outcome for a mandate. |
|
|
167
238
|
| `airi-cli skills install` | Deploy the bundled agent skills into local AI-agent skill directories. |
|
|
@@ -186,6 +257,22 @@ Flags for `airi-cli auth whoami`:
|
|
|
186
257
|
| --- | --- | --- |
|
|
187
258
|
| `--verbose` | `false` | Include device details (name, platform, device id). |
|
|
188
259
|
|
|
260
|
+
Flags for `airi-cli mandate list`:
|
|
261
|
+
|
|
262
|
+
| Flag | Default | Description |
|
|
263
|
+
| --- | --- | --- |
|
|
264
|
+
| `--status` | — | Filter by mandate status (repeatable): `CREATED`, `AUTHENTICATED`, `READY`, `COMPLETED`, `FAILED`, `DENIED`. |
|
|
265
|
+
| `--created-from` | — | Include mandates created at or after this ISO-8601 time. |
|
|
266
|
+
| `--created-to` | — | Include mandates created at or before this ISO-8601 time. |
|
|
267
|
+
| `--page` | `0` | Zero-based page number. |
|
|
268
|
+
| `--size` | `10` | Mandates per page (1–100). |
|
|
269
|
+
|
|
270
|
+
Flags for `airi-cli mandate cancel`:
|
|
271
|
+
|
|
272
|
+
| Flag | Description |
|
|
273
|
+
| --- | --- |
|
|
274
|
+
| `--mandate-id` | Mandate ID (required). |
|
|
275
|
+
|
|
189
276
|
Flags for `airi-cli mandate create` (all required):
|
|
190
277
|
|
|
191
278
|
| Flag | Description |
|
package/checksums.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"checksums": {
|
|
3
|
-
"linux_amd64": "
|
|
4
|
-
"linux_arm64": "
|
|
5
|
-
"macos_x86_64": "
|
|
6
|
-
"macos_arm64": "
|
|
3
|
+
"linux_amd64": "c928039f16658358e493b27ab09710ef8d768552d4b55ffdc2a32375d7b8ce2d",
|
|
4
|
+
"linux_arm64": "267acceccdbecf8de21aabbdc654dc2552aa7f22da8d060a09cd33143bd5096a",
|
|
5
|
+
"macos_x86_64": "2fb413d8c48b0639f548e5a250bce69b95bcc0cd1267ba1758a16472e3bfda91",
|
|
6
|
+
"macos_arm64": "6e617b33e087a12e57e0c601d223aa55e809acbc211abbfa2f9c2ecd4510f25d"
|
|
7
7
|
}
|
|
8
8
|
}
|
package/package.json
CHANGED
package/scripts/postinstall.mjs
CHANGED
|
@@ -17,23 +17,22 @@
|
|
|
17
17
|
//
|
|
18
18
|
// Environment variables:
|
|
19
19
|
// AIRI_CLI_VERSION download this release tag instead of the package's
|
|
20
|
-
// own version
|
|
21
|
-
//
|
|
22
|
-
//
|
|
23
|
-
// AIRI_CLI_SKIP_DOWNLOAD set to "1" to skip the download entirely. Useful
|
|
24
|
-
// for offline CI that provides the binary another
|
|
25
|
-
// way; the CLI won't run until it is present.
|
|
20
|
+
// own version. The pinned digest only matches the
|
|
21
|
+
// package's own version, so an override also requires
|
|
22
|
+
// AIRI_CLI_SKIP_CHECKSUM.
|
|
26
23
|
// AIRI_CLI_SKIP_CHECKSUM set to "1" to skip SHA256 verification (local-dev
|
|
27
24
|
// only — never in production or CI).
|
|
28
|
-
//
|
|
25
|
+
// AIRI_CLI_SKIP_SKILLS set to "1" to skip deploying the bundled agent skills.
|
|
26
|
+
// AIRI_CLI_BASE_URL (internal, undocumented) override the release host.
|
|
27
|
+
// The e2e tests point it at a local server; kept out
|
|
28
|
+
// of the README so it isn't a supported user knob.
|
|
29
29
|
//
|
|
30
|
-
//
|
|
31
|
-
//
|
|
32
|
-
//
|
|
33
|
-
// re-reports a missing binary with the same remediation if the CLI is run.
|
|
30
|
+
// A download or verification failure warns but does NOT hard-fail: a transient
|
|
31
|
+
// network issue must not abort a larger `npm install`. The launcher re-reports
|
|
32
|
+
// a missing binary with the same remediation if the CLI is run.
|
|
34
33
|
|
|
35
34
|
import { createWriteStream, existsSync } from 'node:fs'
|
|
36
|
-
import { mkdir, mkdtemp, readFile, rm, chmod, rename } from 'node:fs/promises'
|
|
35
|
+
import { mkdir, mkdtemp, readFile, rm, chmod, rename, copyFile } from 'node:fs/promises'
|
|
37
36
|
import { createHash } from 'node:crypto'
|
|
38
37
|
import { tmpdir } from 'node:os'
|
|
39
38
|
import path from 'node:path'
|
|
@@ -157,12 +156,29 @@ function extract(tarball, destDir) {
|
|
|
157
156
|
if (res.status !== 0) throw new Error(`tar exited ${res.status}`)
|
|
158
157
|
}
|
|
159
158
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
159
|
+
// Deploy the agent skills bundled in the binary, mirroring install.sh: invoke
|
|
160
|
+
// the freshly installed binary's `skills install`, honouring AIRI_CLI_SKIP_SKILLS.
|
|
161
|
+
// Best-effort — a failure warns but never fails the install (the user can
|
|
162
|
+
// re-run `airi-cli skills install`).
|
|
163
|
+
function deploySkills(bin) {
|
|
164
|
+
if (process.env.AIRI_CLI_SKIP_SKILLS === '1') {
|
|
165
|
+
warn('AIRI_CLI_SKIP_SKILLS=1 — skipping skill deployment.')
|
|
163
166
|
return
|
|
164
167
|
}
|
|
168
|
+
log('deploying agent skills')
|
|
169
|
+
// stdio inherited so the CLI's own output — including the target directories
|
|
170
|
+
// it installed into — flows through to the npm install log.
|
|
171
|
+
const res = spawnSync(
|
|
172
|
+
bin,
|
|
173
|
+
['--no-telemetry', '-o', 'text', 'skills', 'install'],
|
|
174
|
+
{ stdio: 'inherit' }
|
|
175
|
+
)
|
|
176
|
+
if (res.error || res.status !== 0) {
|
|
177
|
+
warn(`skill deployment failed; retry later with: ${BIN_NAME} skills install`)
|
|
178
|
+
}
|
|
179
|
+
}
|
|
165
180
|
|
|
181
|
+
async function main() {
|
|
166
182
|
let platform
|
|
167
183
|
try {
|
|
168
184
|
platform = detectPlatform()
|
|
@@ -230,18 +246,19 @@ async function main() {
|
|
|
230
246
|
throw new Error(`archive did not contain expected '${BIN_NAME}' binary`)
|
|
231
247
|
}
|
|
232
248
|
const finalPath = binPath()
|
|
233
|
-
//
|
|
234
|
-
//
|
|
235
|
-
//
|
|
236
|
-
// hit) — and because the staged copy is fully in place and executable
|
|
237
|
-
// before the swap, a failure never leaves the old working binary deleted
|
|
238
|
-
// with no replacement.
|
|
249
|
+
// copyFile (not rename) crosses devices without EXDEV; staging inside the
|
|
250
|
+
// vendor dir keeps the final swap a same-device atomic rename, so a failure
|
|
251
|
+
// never leaves the old working binary deleted with no replacement.
|
|
239
252
|
const staged = path.join(dir, `.${BIN_NAME}.new`)
|
|
240
253
|
await rm(staged, { force: true })
|
|
241
|
-
await
|
|
254
|
+
await copyFile(extracted, staged)
|
|
242
255
|
await chmod(staged, 0o755)
|
|
243
256
|
await rename(staged, finalPath)
|
|
244
|
-
log(`installed
|
|
257
|
+
log(`installed ${BIN_NAME} ${tag}`)
|
|
258
|
+
|
|
259
|
+
// Only after the binary is verified and in place, so skills are never
|
|
260
|
+
// deployed from a half-installed or unverified CLI.
|
|
261
|
+
deploySkills(finalPath)
|
|
245
262
|
} catch (err) {
|
|
246
263
|
warn(`failed to download the airi-cli binary: ${err.message}`)
|
|
247
264
|
warn(
|