@capxul/cli 4.20.0-beta.6 → 4.20.0-beta.8
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 +212 -17
- package/dist/browser/signer.js +446 -26
- package/dist/browser/signer.js.map +1 -1
- package/dist/main.mjs +2457 -332
- package/dist/main.mjs.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# Capxul CLI
|
|
2
2
|
|
|
3
3
|
The CLI provides email OTP login, persistent first-party sessions, terminal-owned
|
|
4
|
-
signup, a bundled Openfort wallet page,
|
|
5
|
-
diagnostics, and one global collection
|
|
6
|
-
on macOS or Linux.
|
|
4
|
+
signup, personal and Organization contacts, a bundled Openfort wallet page,
|
|
5
|
+
backend profile and account reads, diagnostics, and one global collection
|
|
6
|
+
preference. It requires Node 24 or later on macOS or Linux.
|
|
7
7
|
|
|
8
8
|
```sh
|
|
9
9
|
capxul --help
|
|
@@ -24,6 +24,51 @@ machinery and collection controls send no observation records.
|
|
|
24
24
|
check uses the public Capxul SDK and verifies the backend response nonce.
|
|
25
25
|
It does not authenticate a person or submit a transaction.
|
|
26
26
|
|
|
27
|
+
## Contact commands
|
|
28
|
+
|
|
29
|
+
```sh
|
|
30
|
+
capxul contact list [--include-hidden]
|
|
31
|
+
capxul contact get --entry-id PARTY_ID
|
|
32
|
+
capxul contact add --input FILE|- [--confirm]
|
|
33
|
+
capxul contact label --entry-id PARTY_ID --label TEXT [--confirm]
|
|
34
|
+
capxul contact hide --entry-id PARTY_ID [--confirm]
|
|
35
|
+
capxul contact unhide --entry-id PARTY_ID [--confirm]
|
|
36
|
+
|
|
37
|
+
capxul org contact list --org ORGANIZATION_ID [--include-hidden]
|
|
38
|
+
capxul org contact get --org ORGANIZATION_ID --entry-id PARTY_ID
|
|
39
|
+
capxul org contact add --org ORGANIZATION_ID --input FILE|- [--confirm]
|
|
40
|
+
capxul org contact label --org ORGANIZATION_ID --entry-id PARTY_ID --label TEXT [--confirm]
|
|
41
|
+
capxul org contact hide --org ORGANIZATION_ID --entry-id PARTY_ID [--confirm]
|
|
42
|
+
capxul org contact unhide --org ORGANIZATION_ID --entry-id PARTY_ID [--confirm]
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Personal commands use the authenticated Account address book. Organization
|
|
46
|
+
commands require one explicit `--org` or `--org-id`; they never use the saved
|
|
47
|
+
Organization read default. `list` omits hidden entries unless
|
|
48
|
+
`--include-hidden` is present. `get`, `label`, `hide`, and `unhide` address one
|
|
49
|
+
stable Party with `--entry-id`.
|
|
50
|
+
|
|
51
|
+
`add --input` reads the existing `AddressBookAddInput` JSON shape. For example:
|
|
52
|
+
|
|
53
|
+
```json
|
|
54
|
+
{
|
|
55
|
+
"ref": { "kind": "email", "email": "supplier@example.test" },
|
|
56
|
+
"label": "New Supplier"
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Use `--input -` to read the same object from stdin. An interactive `add` can
|
|
61
|
+
collect the reference kind, value, and optional label instead. Interactive
|
|
62
|
+
writes show the actor and exact contact change, then ask a default-no question.
|
|
63
|
+
JSON, CI, and other noninteractive writes require `--confirm` before the CLI
|
|
64
|
+
creates a client. Contact writes do not start a browser signer.
|
|
65
|
+
|
|
66
|
+
Success data is the SDK value without a CLI wrapper: `list` returns
|
|
67
|
+
`AddressBookEntry[]`, `get` returns `AddressBookEntry | null`, and each mutation
|
|
68
|
+
returns `AddressBookEntry`. Human `get` prints `No contact found` for null and
|
|
69
|
+
exits successfully. Entries retain their stable PartyId, exact reference,
|
|
70
|
+
relationships, hidden state, and last activity time.
|
|
71
|
+
|
|
27
72
|
## Organization commands
|
|
28
73
|
|
|
29
74
|
```sh
|
|
@@ -44,6 +89,14 @@ These commands accept `--email`. Without it, they restore the protected current
|
|
|
44
89
|
session. Organization reads accept `--org` or its alias `--org-id`. Identical
|
|
45
90
|
repeated IDs are accepted. Different IDs are refused.
|
|
46
91
|
|
|
92
|
+
A read without `--org` resolves one exact Organization in this order: the saved
|
|
93
|
+
read default, then the recovery handle this machine recorded for the person's
|
|
94
|
+
Organization journey. A recovery handle can also name an Organization whose
|
|
95
|
+
setup lane still runs, which the own-access list does not carry yet; the read
|
|
96
|
+
reports that exact lane, and it applies the usual current-access rule again once
|
|
97
|
+
the Organization reports ready. The read refuses an Organization it cannot
|
|
98
|
+
reach, and it never substitutes another one.
|
|
99
|
+
|
|
47
100
|
`org use` requires an explicit Organization ID. It checks current access and
|
|
48
101
|
saves a protected per-person read default. The default never grants authority.
|
|
49
102
|
Each read checks current access again. Without an explicit ID or saved default,
|
|
@@ -60,12 +113,74 @@ No match returns exit 2. Duplicate matches return exit 1.
|
|
|
60
113
|
seconds and defaults to 120. Timeout returns exit 5; interruption returns 130.
|
|
61
114
|
A successful read can report a failed or pending domain state.
|
|
62
115
|
|
|
116
|
+
## Invitation commands
|
|
117
|
+
|
|
118
|
+
```sh
|
|
119
|
+
capxul org invite list [--mine] [--limit N] [--cursor C] [--phase PHASE ...] [--org O]
|
|
120
|
+
capxul org invite get --invitation-id I [--org O]
|
|
121
|
+
capxul org invite wait --invitation-id I [--org O] [--timeout-seconds N]
|
|
122
|
+
capxul org invite review --invitation-id I --org O [--timeout-seconds N]
|
|
123
|
+
capxul org invite accept --invitation-id I --offer-digest D --org O [--confirm] [--timeout-seconds N]
|
|
124
|
+
capxul org invite decline --invitation-id I --org O [--confirm]
|
|
125
|
+
capxul org invite cancel --invitation-id I --org O [--confirm]
|
|
126
|
+
capxul org invite resend --invitation-id I --org O [--confirm]
|
|
127
|
+
capxul org invite retry --invitation-id I --org O [--confirm]
|
|
128
|
+
capxul org member invite (--to-email E | --account-id ID) [--budget-id B ...] [--permission-id M ...] [--new-budget-name N --asset A (--limit Q | --unlimited) (--recipient-account ID ... | --any-recipient) --actions pay[,commitments]] --org O [--request-key K] [--preview] [--confirm]
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
`org invite list` returns your own offers. It accepts `--limit` (1--100),
|
|
132
|
+
`--cursor`, and repeated `--phase` values, and its result carries `invitations`,
|
|
133
|
+
`nextCursor`, and `observedAt`: pass `nextCursor` back as `--cursor`, and change
|
|
134
|
+
no other filter between the two calls. `--mine` names the own-offer projection,
|
|
135
|
+
which is already the default. With `--org O` the command returns that
|
|
136
|
+
Organization's invitations for a current Admin instead; the Organization list is
|
|
137
|
+
not filtered to you, so `--mine` together with `--org` refuses with exit 2. The
|
|
138
|
+
other invitation commands require an exact `--invitation-id`.
|
|
139
|
+
|
|
140
|
+
`org invite get` and `org invite wait` use `--org` when you name it. Without
|
|
141
|
+
`--org` they walk your own-offer pages, 100 rows per request, until they find
|
|
142
|
+
the invitation or the pages end. They never consult the saved read default, and
|
|
143
|
+
an offer you cannot see is refused. `--timeout-seconds` bounds the resolution
|
|
144
|
+
and the read together on both commands.
|
|
145
|
+
|
|
146
|
+
`org invite wait` only reads. It finishes when the offer settles or when the
|
|
147
|
+
recovery asks a person to act. It never retries, resends, or accepts.
|
|
148
|
+
|
|
149
|
+
`org invite review` requires `--org`, returns the current `InvitationView`
|
|
150
|
+
directly in `data`, and performs no write or signing.
|
|
151
|
+
|
|
152
|
+
The four transitions require `--org` in both modes, as `accept` does. They never
|
|
153
|
+
author a new offer. A noninteractive or JSON run requires `--confirm`. An
|
|
154
|
+
interactive run shows the resolved current offer and asks a default-no question.
|
|
155
|
+
|
|
156
|
+
`org member invite` authorizes one exact offer. `--preview` writes nothing and
|
|
157
|
+
needs neither a request key nor confirmation. A noninteractive write requires
|
|
158
|
+
`--request-key` and `--confirm`. An interactive run prints the request key it
|
|
159
|
+
used before it submits, so a lost response is recoverable with the same
|
|
160
|
+
identity. At most one `--new-budget-name` is accepted per command.
|
|
161
|
+
|
|
162
|
+
`org invite accept` is the exact grantee's consent commit. It takes the exact
|
|
163
|
+
digest the offer shows as `--offer-digest`: a noninteractive or JSON run must
|
|
164
|
+
supply it, and without it the command refuses with exit 2 before it creates a
|
|
165
|
+
client. An interactive run may omit it, and then reads the offer and fills the
|
|
166
|
+
digest from the value it displayed. A digest you state is never replaced by the
|
|
167
|
+
displayed one. `--expected-offer` remains a compatibility spelling, and both
|
|
168
|
+
spellings must match when supplied together. The command returns the
|
|
169
|
+
`InvitationView` directly in `data`. The grant is executed by the deployment's
|
|
170
|
+
technical executor, so the command needs no browser bridge and works in a
|
|
171
|
+
headless or CI session. A repeat with the stored digest returns the same
|
|
172
|
+
accepted result; a different digest refuses and cannot overwrite consent. The
|
|
173
|
+
returned view is the authorization-time view of the consent commit
|
|
174
|
+
(`pending_grant`); read the settled `active` state with `get` or `wait`.
|
|
175
|
+
|
|
63
176
|
## Organization writes
|
|
64
177
|
|
|
65
178
|
`org create` and `org retry` restore the protected current session and start the
|
|
66
179
|
existing command-scoped browser signer. They never read or write the saved read
|
|
67
|
-
default.
|
|
68
|
-
|
|
180
|
+
default. `org create` writes the person's Organization recovery handle. That
|
|
181
|
+
handle holds the exact business handle and the exact Organization ID, and it
|
|
182
|
+
holds nothing else. Local input checks run before any client, browser, or
|
|
183
|
+
backend work, and they include the confirmation gate:
|
|
69
184
|
|
|
70
185
|
- A noninteractive or JSON write requires `--confirm`. Without it the command
|
|
71
186
|
refuses with exit 2 before any client, browser, or mutation work.
|
|
@@ -106,6 +221,47 @@ failed lane still reports the Organization it is about. The command returns
|
|
|
106
221
|
success only after an exact `org(O).getLifecycle()` read reports `ready`. It
|
|
107
222
|
never saves a read default and never returns a different ready Organization.
|
|
108
223
|
|
|
224
|
+
`org create` continues the Organization journey this machine already prepared.
|
|
225
|
+
Before the first durable write it records the exact business handle as the safe
|
|
226
|
+
recovery handle. It adds the first committed Organization ID to that handle
|
|
227
|
+
before it forwards any founder authorization digest, and it keeps that handle
|
|
228
|
+
after a failure, an interruption, or a ready result. A later create therefore
|
|
229
|
+
resolves exactly one Organization:
|
|
230
|
+
|
|
231
|
+
- The same handle resumes the exact recorded Organization. It calls the SDK
|
|
232
|
+
recovery owner once per attempt and settles the same lifecycle. It never
|
|
233
|
+
submits a second bootstrap, and it never creates a second Organization or
|
|
234
|
+
treasury.
|
|
235
|
+
- A different handle refuses with exit 2 while the recorded Organization is not
|
|
236
|
+
ready. The refusal names the exact Organization.
|
|
237
|
+
- A different handle creates one Organization only after the recorded
|
|
238
|
+
Organization reaches ready.
|
|
239
|
+
- A recorded Organization that is already ready, and still in the person's
|
|
240
|
+
current access, returns unchanged, with no write and no signature. A ready
|
|
241
|
+
result the person can no longer reach refuses, and the committed recovery
|
|
242
|
+
handle stays recorded for exact recovery.
|
|
243
|
+
- A create that continues a recorded handle checks current access before it
|
|
244
|
+
reports success. The committed Organization ID becomes durable first, so a
|
|
245
|
+
refusal or an interruption keeps the exact recovery handle, and a ready
|
|
246
|
+
lifecycle line reaches stderr only after the check resolves.
|
|
247
|
+
- A terminal preview reads the recorded Organization's lifecycle only for the
|
|
248
|
+
handle that continues it. A different handle is a new creation, so an
|
|
249
|
+
unreachable recorded Organization never blocks it.
|
|
250
|
+
- A handle the backend refuses is refused before any Organization write. The
|
|
251
|
+
command releases the prepared handle, so the person can correct the handle and
|
|
252
|
+
create. Every other failure keeps the handle, because its Organization may
|
|
253
|
+
already exist.
|
|
254
|
+
|
|
255
|
+
The recovery line names the exact Organization and the safe handle. JSON mode
|
|
256
|
+
writes it as one newline-delimited progress object:
|
|
257
|
+
|
|
258
|
+
```json
|
|
259
|
+
{ "type": "organization.recovery", "organizationId": "O", "handle": "acme" }
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
`org retry` stays explicit: `--org` (or its alias `--org-id`) is the one write
|
|
263
|
+
scope, and no read default or recovery handle is consulted.
|
|
264
|
+
|
|
109
265
|
`org retry` requires an explicit `--org` (or `--org-id`). It validates the ID
|
|
110
266
|
with the public `toOrgId` constructor, reads that exact Organization's lifecycle
|
|
111
267
|
for its terminal preview, resumes that same durable setup lane, then settles the
|
|
@@ -162,7 +318,8 @@ unsafe permissions, symlinks, and corrupt state produce a storage failure.
|
|
|
162
318
|
|
|
163
319
|
## Output
|
|
164
320
|
|
|
165
|
-
`--json` writes one version 1 envelope to stdout. Success contains `data
|
|
321
|
+
`--json` writes one version 1 envelope to stdout. Success contains `data`, which
|
|
322
|
+
can be an object, array, or null according to the command's SDK result.
|
|
166
323
|
Failure contains `error.code` and CLI-owned `error.message`. Each envelope has
|
|
167
324
|
`command`, `invocationId`, and `outcome`. An invocation ID is null before a
|
|
168
325
|
command starts. Human errors go to stderr.
|
|
@@ -242,11 +399,21 @@ stored and tagged as `legacy-native-grant` in status. A profile read asks for an
|
|
|
242
399
|
explicit new login; it never exchanges the old grant for a broader session.
|
|
243
400
|
Logout forgets and attempts to revoke both credential types for the selected email.
|
|
244
401
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
code
|
|
248
|
-
|
|
249
|
-
|
|
402
|
+
`capxul auth login` and `capxul auth signup` stay separate commands. On a
|
|
403
|
+
terminal, each command is a wizard. `auth login` asks for the email and a masked
|
|
404
|
+
OTP. It accepts the code as a paste. It retries an invalid code at most three
|
|
405
|
+
times for one request. After sign-in, an incomplete account gets one offer to
|
|
406
|
+
continue setup in the same command. `auth signup` authenticates first, then asks
|
|
407
|
+
for the Profile fields: display name, two-letter country code, and handle. A
|
|
408
|
+
known value is the prompt default, so Enter keeps it.
|
|
409
|
+
|
|
410
|
+
The browser opens only when the shared Core onboarding journey needs Openfort
|
|
411
|
+
wallet readiness. It shows wallet status only. It has no email, OTP, Profile, or
|
|
412
|
+
approval form.
|
|
413
|
+
|
|
414
|
+
Ctrl+C or Ctrl+D at a wizard prompt cancels the command. The command prints no
|
|
415
|
+
success result and exits 130. A step that already finished keeps its result: a
|
|
416
|
+
completed sign-in keeps its session.
|
|
250
417
|
|
|
251
418
|
For an agent, send and verify in separate processes:
|
|
252
419
|
|
|
@@ -254,7 +421,6 @@ For an agent, send and verify in separate processes:
|
|
|
254
421
|
capxul auth send --email "$TEST_EMAIL" --json
|
|
255
422
|
# Supply the delivered six-digit OTP through stdin, not a command argument.
|
|
256
423
|
capxul auth verify --email "$TEST_EMAIL" --otp-stdin --json
|
|
257
|
-
capxul auth signup --email "$TEST_EMAIL" --display-name "Test Person" --country GH --handle test_person --json
|
|
258
424
|
capxul auth profile --email "$TEST_EMAIL" --json
|
|
259
425
|
# A later process uses the same protected CLI home; no new OTP is required.
|
|
260
426
|
capxul auth profile --email "$TEST_EMAIL" --json
|
|
@@ -262,12 +428,13 @@ capxul auth status --email "$TEST_EMAIL" --json
|
|
|
262
428
|
capxul auth logout --email "$TEST_EMAIL" --json
|
|
263
429
|
```
|
|
264
430
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
431
|
+
A machine run never prompts. `auth login` with `--otp-stdin` sends the OTP and
|
|
432
|
+
verifies one code from stdin. It returns the tagged result
|
|
433
|
+
`setupState: "setup-required"` when the account needs setup. It does not start
|
|
434
|
+
setup work, so sign-in never becomes signup.
|
|
269
435
|
|
|
270
|
-
A fresh
|
|
436
|
+
A fresh machine signup does verification and setup in one command. State every
|
|
437
|
+
Profile field; a missing field refuses with exit 2:
|
|
271
438
|
|
|
272
439
|
```sh
|
|
273
440
|
# Supply only the delivered OTP through stdin.
|
|
@@ -275,6 +442,11 @@ capxul auth signup --email "$TEST_EMAIL" --otp-stdin \
|
|
|
275
442
|
--display-name "Test Person" --country GH --handle test_person --json
|
|
276
443
|
```
|
|
277
444
|
|
|
445
|
+
`--otp-stdin` reads up to 64 bytes, ending at EOF. Pipe from a secret provider or
|
|
446
|
+
use input redirection from a protected file. An invalid value refuses with exit 2. A missing `--otp-stdin` refuses with exit 2 before the command starts client
|
|
447
|
+
work. OTPs are never accepted in argv, persisted in the continuation, or included
|
|
448
|
+
in output.
|
|
449
|
+
|
|
278
450
|
The local page binds to an OS-selected loopback port. A random launch capability
|
|
279
451
|
is redeemed once and removed from the URL before Openfort starts. The page receives
|
|
280
452
|
only the authenticated wallet token and encryption session in memory. Closing it
|
|
@@ -282,6 +454,29 @@ ends the current wallet attempt. Re-run `auth signup` with the same CLI home to
|
|
|
282
454
|
resume the same Profile and Account without another OTP while the backend session
|
|
283
455
|
remains valid.
|
|
284
456
|
|
|
457
|
+
`auth signup` returns only two readiness results. `setupState: "ready"` is a
|
|
458
|
+
personal Account that the Account readiness owner reads as ready and deployed,
|
|
459
|
+
and its data carries the public identifiers: the Profile, the public wallet
|
|
460
|
+
address (`smartAccount.signerAddress`), the personal Smart Account address
|
|
461
|
+
(`smartAccount.smartAccountAddress`), the Account ID
|
|
462
|
+
(`lifecycle.accountId`), and the ready status. Any other state returns the typed
|
|
463
|
+
recoverable result `setupState: "setup-required"`, with the lifecycle, its
|
|
464
|
+
failure code, and the command that resumes the journey. A ready Account starts
|
|
465
|
+
no wallet work, so a retry keeps the one Profile, wallet, Smart Account, and
|
|
466
|
+
Account. An interruption keeps the stored session and stores no code, so the
|
|
467
|
+
next command resumes the same setup.
|
|
468
|
+
|
|
469
|
+
A ready personal Account continues the same journey into Organization creation
|
|
470
|
+
with `capxul org create --name NAME --handle HANDLE --country CC`. The create
|
|
471
|
+
command records the safe recovery handle for that Organization, so an
|
|
472
|
+
interruption or a restart resumes the exact same Organization.
|
|
473
|
+
|
|
474
|
+
The CLI checks `--display-name`, `--country`, and `--handle` before it opens a
|
|
475
|
+
client, so a malformed value refuses with exit 2 and no code is sent. The handle
|
|
476
|
+
check covers the grammar only: a handle that another person holds, and a reserved
|
|
477
|
+
handle, refuse through the identity owner after sign-in. Both refusals name the
|
|
478
|
+
handle, and neither offers verification-code recovery for a Profile problem.
|
|
479
|
+
|
|
285
480
|
The version 2 `first-party-session` record stores the opaque provider credential
|
|
286
481
|
in the existing protected plaintext store. Its scope includes the application
|
|
287
482
|
key, issuer, environment, and email. Each process validates restoration with the
|