@capxul/cli 4.20.0-beta.2 → 4.20.0-beta.20

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 CHANGED
@@ -1,7 +1,9 @@
1
1
  # Capxul CLI
2
2
 
3
- The CLI provides local diagnostics, an online backend check, and one global
4
- collection preference. It requires Node 24 or later on macOS or Linux.
3
+ The CLI provides email OTP login, persistent first-party sessions, terminal-owned
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.
5
7
 
6
8
  ```sh
7
9
  capxul --help
@@ -14,27 +16,727 @@ capxul telemetry enable --json
14
16
  capxul doctor --online --timeout-ms 30000 --json
15
17
  ```
16
18
 
17
- Help, version, and completion do not read configuration or contact a server.
19
+ Help and version do not require application credentials or a working backend.
20
+ With no arguments, `capxul` shows the same generated help as `capxul --help`.
21
+ They use the same observation policy as ordinary commands. Shell completion
22
+ machinery and collection controls send no observation records.
18
23
  `doctor` checks local configuration unless `--online` is present. An online
19
24
  check uses the public Capxul SDK and verifies the backend response nonce.
20
25
  It does not authenticate a person or submit a transaction.
21
26
 
27
+ ## Guided terminal input
28
+
29
+ In a human terminal, these commands collect missing required fields one step at
30
+ a time:
31
+
32
+ ```sh
33
+ capxul org permission change
34
+ capxul org member invite
35
+ capxul org payment get
36
+ capxul document get
37
+ ```
38
+
39
+ Supplied valid values remain in the command. Preview and confirmation still
40
+ apply to writes. `--wizard` provides an explicit entry to the same native input
41
+ flow. Ctrl+C or Ctrl+D cancels with exit 130. Bare groups show help. JSON, CI,
42
+ and noninteractive runs require their declared input and do not prompt.
43
+
44
+ ## Waiting output
45
+
46
+ Pending setup and observation commands show a waiting message. Human terminals
47
+ also show an activity indicator. The indicator stops before a prompt or final
48
+ result. Noninteractive human output uses text without animation.
49
+
50
+ Payment, Payroll, Permission, Organization, and Invitation waits print observed
51
+ state changes on stderr. JSON mode uses declared progress objects on stderr and
52
+ one final version 1 result on stdout. Account setup reports public signer states.
53
+ Activity shows that the CLI is waiting. It does not prove settlement or a healthy
54
+ connection. A deadline stops observation; it does not cancel a submitted operation.
55
+
56
+ ## Status overview
57
+
58
+ ```sh
59
+ capxul status
60
+ capxul status --email EMAIL --json
61
+ capxul status --org ORGANIZATION_ID
62
+ ```
63
+
64
+ `status` reads the current personal Account unless one explicit Organization
65
+ is selected with `--org`. It shows the saved session identity, selected actor
66
+ profile and readiness, separate asset balances, received and issued requests,
67
+ pending or active Payments, and five recent Activity rows. It gives scoped
68
+ commands to inspect requests and Activity. A saved Organization default does
69
+ not change the overview's personal scope.
70
+
71
+ Each source read retains its own state. An unavailable balance or Inbox is
72
+ not an empty balance or Inbox. Indexed Activity fallback is marked incomplete.
73
+ JSON returns `state: "partial"` when a read fails or Activity is incomplete.
74
+ Document counts include known references from available request and Payment
75
+ reads. Activity detail can have additional documents. The overview does not
76
+ render or download PDFs and does not prepare or submit Payments. Showing an
77
+ existing scheduled or streaming Payment does not add recurring billing.
78
+
79
+ ## Personal Payments
80
+
81
+ ```sh
82
+ capxul payment send --input payment.json --request-key REQUEST_KEY --confirm --json
83
+ capxul payment send --resume REQUEST_KEY --confirm --json
84
+ capxul payment retry --payment-id PAYMENT_ID --confirm --json
85
+ capxul payment list --json
86
+ capxul payment get --payment-id PAYMENT_ID --json
87
+ capxul payment wait --payment-id PAYMENT_ID --timeout-seconds 120 --json
88
+ ```
89
+
90
+ These commands use the current authenticated session. Add `--email EMAIL` to
91
+ select a saved session. In a terminal, omit the required Payment ID to enter it.
92
+ `list` returns `{ payments }`. `get` returns `{ payment }` and refuses when the
93
+ Payment is absent or unavailable to the session. Human output shows the full ID,
94
+ status, amount, counterparty and available receipt.
95
+
96
+ `wait` observes the exact Payment until it reaches a terminal state or needs an
97
+ action. A failed Payment can be a completed observation. The timeout accepts
98
+ 1–3600 seconds and includes session restoration. A timeout or unavailable read
99
+ prints exact get/wait commands. Waiting never resubmits a Payment.
100
+
101
+ `send` accepts a bounded JSON file or `--input -` for stdin. An interactive
102
+ send can collect the recipient, asset, amount and document options. It validates
103
+ these fields, resolves the recipient, and previews the exact target before
104
+ confirmation. A scripted send requires `--request-key` and `--confirm`. A human
105
+ send generates a key when none was supplied. Signing starts after confirmation.
106
+
107
+ The CLI saves the exact input in protected local state before preparation. It
108
+ prints the request key and resume command, then prints prepared Payment IDs
109
+ before signing. `--resume` uses that saved input and key; it refuses input or key
110
+ overrides. Keep the same CLI home and authenticated person for recovery.
111
+ A different input cannot replace the saved input for the same key.
112
+
113
+ Send returns `{ payment, requestKey }` with the observed Payment state. Retry
114
+ returns `{ payments }` and addresses the existing Payment command. It never
115
+ creates a replacement send. Uncertain results keep exact read/wait or same-key
116
+ resume guidance. A submitted result does not prove settlement.
117
+
118
+ For an external address, JSON input must include
119
+ `"externalAddressAcknowledged": true`. `--confirm` alone does not acknowledge
120
+ the address. Human input shows the exact address and an unverified-recipient
121
+ warning before one default-No confirmation. Known Capxul Parties resolved from
122
+ addresses remain supported. Resume keeps the saved reference and acknowledgement.
123
+ A saved key cannot gain new acknowledgement; use fresh input and a fresh key.
124
+
125
+ ## Activity
126
+
127
+ ```sh
128
+ capxul activity list --limit 25 --json
129
+ capxul activity get --kind payment --id PAYMENT_ID --json
130
+ capxul activity get --kind movement --id MOVEMENT_ID --json
131
+ capxul activity summary --from 1790553600000 --to 1790639999999 --json
132
+ capxul activity annotate --input annotation.json --confirm --json
133
+ ```
134
+
135
+ Add explicit `--org ORGANIZATION_ID` for Organization scope. The saved
136
+ Organization read default does not select this scope. List supports kind,
137
+ direction, status and inclusive epoch-millisecond bounds. Reuse a cursor with
138
+ the same filters and actor. An unavailable indexer produces a visible incomplete
139
+ activity warning. Movement rows remain Movements.
140
+
141
+ Summary keeps exact per-asset raw-unit totals. Get returns exact detail and
142
+ refuses a missing or unavailable reference. Annotation accepts only `reference`,
143
+ `accountingCategory` and `memo`; it cannot alter settlement or documents. Human
144
+ writes require preview and confirmation. Scripted writes require `--confirm`.
145
+ In a terminal, omit required fields for guided flags and annotation input.
146
+
147
+ ## Issued requests and received Inbox
148
+
149
+ ```sh
150
+ capxul request list
151
+ capxul request issue --input invoice.json --confirm
152
+ capxul request get --request-id REQUEST_ID
153
+ capxul request cancel --request-id REQUEST_ID --confirm
154
+ capxul inbox list
155
+ capxul inbox get --request-id REQUEST_ID
156
+ capxul inbox pay --request-id REQUEST_ID --confirm
157
+ capxul inbox decline --request-id REQUEST_ID --confirm
158
+ capxul org request list --org ORGANIZATION_ID
159
+ capxul org request issue --org ORGANIZATION_ID --input invoice.json --confirm
160
+ capxul org request get --org ORGANIZATION_ID --request-id REQUEST_ID
161
+ capxul org request cancel --org ORGANIZATION_ID --request-id REQUEST_ID --confirm
162
+ capxul org inbox list --org ORGANIZATION_ID
163
+ capxul org inbox get --org ORGANIZATION_ID --request-id REQUEST_ID
164
+ capxul org inbox pay --org ORGANIZATION_ID --request-id REQUEST_ID --permission-id PERMISSION_ID --confirm
165
+ capxul org inbox decline --org ORGANIZATION_ID --request-id REQUEST_ID --confirm
166
+ ```
167
+
168
+ `request` reads the selected actor's issued Invoice and payment requests.
169
+ `inbox` reads payment requests addressed to that actor. Organization reads
170
+ require one explicit Organization ID. Add `--email EMAIL` to select a saved
171
+ session. No signer is required for these reads.
172
+
173
+ For human reads, start with `capxul request --help` or `capxul inbox --help`.
174
+ Run `request list` for requests you issued. Run `inbox list` for requests you
175
+ received. Copy the full request ID from the list into the matching `get` command.
176
+ In a terminal, omit required fields to start guided input. Ctrl+C or Ctrl+D
177
+ cancels with exit 130. The wizard can ask about optional email selection before
178
+ required fields. Provide `--email EMAIL` when you need one saved session.
179
+
180
+ For agent reads, supply all required flags and add `--json`. Capture stdout,
181
+ stderr, and the process exit code separately. A refusal is still a version 1
182
+ result on stdout. Inspect `outcome` and `error.code`; do not infer success from
183
+ valid JSON. Missing required input exits 2. A missing authenticated session exits 3. Noninteractive human refusals use stderr. These runs do not prompt.
184
+
185
+ A missing `--org` refuses an Organization request or Inbox read before session
186
+ restoration. Supply that selector on every Organization command. Do not assume
187
+ that `org use` selects request or Inbox scope.
188
+
189
+ The [installed beta18 audit](../../docs/planning/checkout-cli/request-read-contract.md#installed-beta18-local-audit-c06)
190
+ records local help, refusal, and cancellation checks. Authenticated request
191
+ reads, document output, issuance, and payment remain separate journey checks.
192
+
193
+ Human output shows request ID, reference, amount, status, counterparty
194
+ reference, and document references. An unpaid Invoice can have a document
195
+ before any Payment exists. The document guidance preserves the selected
196
+ session. Run that explicit command to save a PDF. Request and Inbox reads do
197
+ not render or download PDFs. JSON output preserves scope, direction, and the
198
+ SDK item or list. Unavailable reads remain failures, not empty lists.
199
+
200
+ Cancel changes an issued request. Decline changes a received request. Both
201
+ commands read the exact request in the selected scope before the write.
202
+ Terminal writes show a preview and ask for confirmation. Scripted writes
203
+ require `--confirm` before session restoration. A lost write reply gives an
204
+ exact readback command in the same scope and session. It never repeats the
205
+ write. These commands start no signer and move no funds.
206
+
207
+ Issue accepts an Invoice request JSON object from `--input FILE` or `--input -`.
208
+ It saves the issued Invoice PDF in the common document directory by default.
209
+ Human and JSON output include `checkoutUrl` for an Invoice instruction with a link token.
210
+ Memo requests do not receive an Invoice checkout URL.
211
+ The PDF includes the checkout link from the authorized backend render context.
212
+ For a custom deployment, set `CAPXUL_CHECKOUT_FRONTEND_ORIGIN` in both the CLI
213
+ and backend environments. Use the same frontend origin for both.
214
+ Offer create, get, list, revise, and deactivate output also include `checkoutUrl`.
215
+ The checkout page reads current terms and status when the link opens.
216
+ Use `--output-dir DIRECTORY` to change that location. A PDF failure retains the
217
+ issued request and its document references. Do not issue it again to retry PDF
218
+ output; use the printed document render command.
219
+
220
+ ```json
221
+ {
222
+ "payer": { "kind": "email", "email": "bob@example.com" },
223
+ "amount": { "asset": "<admitted asset ID>", "value": "9" },
224
+ "invoice": {
225
+ "kind": "invoice",
226
+ "invoiceNumber": "INV-002",
227
+ "payerRef": "Bob",
228
+ "payeeRef": "Alice",
229
+ "dueAt": 1900000000000,
230
+ "note": "Thank you",
231
+ "discountMinor": "1000000",
232
+ "lineItems": [{ "description": "Consulting", "quantity": 1, "unitMinor": "10000000" }]
233
+ }
234
+ }
235
+ ```
236
+
237
+ Supply your Invoice number. The request reference defaults to that number;
238
+ optional `reference` changes the request reference only. `dueAt` uses epoch
239
+ milliseconds, as the shared Invoice document and frontend do. Set it to zero
240
+ for no due date. Optional `expiresAt` also uses epoch milliseconds. `discountMinor` and
241
+ `unitMinor` use the asset's exact minor units. The example is 10 USDC less
242
+ 1 USDC for a six-decimal USDC asset. The backend checks the Invoice total,
243
+ registered payer, and issuer authority before creation. Optional `memo` is a
244
+ request memo; `invoice.note` is the document note. Unknown fields refuse.
245
+
246
+ Earlier CLI guidance incorrectly named Unix seconds for `dueAt`. Convert those
247
+ values to milliseconds for new drafts. Rendering does not change the dates in
248
+ an issued document. Inspect an incorrect Invoice before cancelling it and
249
+ issuing a corrected request.
250
+
251
+ A lost issuance reply provides issued-list readback in the same scope and
252
+ session. Issuance has no automatic resend.
253
+
254
+ Inbox pay reads and confirms exact backend-owned request terms. It uses the existing
255
+ CLI signer and the SDK fulfillment API. Organization payment requires the
256
+ selected Permission; the backend checks Budget and spending authority. The
257
+ command publishes prepared Payment IDs before signing. A submitted Payment
258
+ is not a settled Payment. Use the printed get/wait commands to inspect its state.
259
+ Returned documents use the same default PDF directory.
260
+
261
+ A lost reply or timeout gives exact readback in the same session and scope.
262
+ Pay refuses an already prepared Invoice unless you explicitly use `--resume`
263
+ after readback. Resumption must retain its linked Payment ID and original
264
+ Invoice terms. It does not create another request or Payment. Use
265
+ `--timeout-seconds N` to change the bounded signing wait (default 120).
266
+ An Invoice retains its issued instruction. A generic request uses a deterministic
267
+ Memo instruction. Reading terms creates no Payment or document. Fulfillment
268
+ checks those terms again and stores the Memo with the original request birth.
269
+
270
+ ## Payment documents
271
+
272
+ ```sh
273
+ capxul document get --document-hash H --content-hash C --json
274
+ capxul document verify --document-hash H --content-hash C --json
275
+ capxul document render --document-hash H --content-hash C
276
+ capxul document render --document-hash H --content-hash C --output-dir ./documents --json
277
+ capxul document export --document-hash H --content-hash C --out original.bin
278
+ ```
279
+
280
+ Each command uses the current authenticated session. Add `--email EMAIL` to
281
+ select a saved session. In a terminal, omit required fields to enter them.
282
+ `get` returns document metadata and saves a PDF. It does not print source bytes.
283
+ `verify` reports `ok: false` when verification fails. `render` saves a PDF and its
284
+ self-contained HTML source in the `documents` directory next to CLI settings.
285
+ Use `--output-dir` to change this directory. Human and JSON output contain
286
+ file metadata. Each render uses a new private directory and preserves earlier
287
+ files. `export` writes the original bytes to a new file.
288
+ It refuses an existing output file.
289
+
290
+ Personal and Organization Payment `send`, `get`, `wait`, `retry`, and `list`
291
+ also save available documents as PDFs. Activity detail and Payroll results
292
+ save available documents in the same directory. Their results include
293
+ document output metadata.
294
+ Pending or unavailable documents retain that state. A document failure does
295
+ not change the Payment result or start another Payment.
296
+
297
+ ## Contact commands
298
+
299
+ ```sh
300
+ capxul contact list [--include-hidden]
301
+ capxul contact get --entry-id PARTY_ID
302
+ capxul contact add --input FILE|- [--confirm]
303
+ capxul contact label --entry-id PARTY_ID --label TEXT [--confirm]
304
+ capxul contact hide --entry-id PARTY_ID [--confirm]
305
+ capxul contact unhide --entry-id PARTY_ID [--confirm]
306
+
307
+ capxul org contact list --org ORGANIZATION_ID [--include-hidden]
308
+ capxul org contact get --org ORGANIZATION_ID --entry-id PARTY_ID
309
+ capxul org contact add --org ORGANIZATION_ID --input FILE|- [--confirm]
310
+ capxul org contact label --org ORGANIZATION_ID --entry-id PARTY_ID --label TEXT [--confirm]
311
+ capxul org contact hide --org ORGANIZATION_ID --entry-id PARTY_ID [--confirm]
312
+ capxul org contact unhide --org ORGANIZATION_ID --entry-id PARTY_ID [--confirm]
313
+ ```
314
+
315
+ Personal commands use the authenticated Account address book. Organization
316
+ commands require one explicit `--org` or `--org-id`; they never use the saved
317
+ Organization read default. `list` omits hidden entries unless
318
+ `--include-hidden` is present. `get`, `label`, `hide`, and `unhide` address one
319
+ stable Party with `--entry-id`.
320
+
321
+ `add --input` reads the existing `AddressBookAddInput` JSON shape. For example:
322
+
323
+ ```json
324
+ {
325
+ "ref": { "kind": "email", "email": "supplier@example.test" },
326
+ "label": "New Supplier"
327
+ }
328
+ ```
329
+
330
+ Use `--input -` to read the same object from stdin. An interactive `add` can
331
+ collect the reference kind, value, and optional label instead. Interactive
332
+ writes show the actor and exact contact change, then ask a default-no question.
333
+ JSON, CI, and other noninteractive writes require `--confirm` before the CLI
334
+ creates a client. Contact writes do not start a browser signer.
335
+
336
+ Success data is the SDK value without a CLI wrapper: `list` returns
337
+ `AddressBookEntry[]`, `get` returns `AddressBookEntry | null`, and each mutation
338
+ returns `AddressBookEntry`. Human `get` prints `No contact found` for null and
339
+ exits successfully. Entries retain their stable PartyId, exact reference,
340
+ relationships, hidden state, and last activity time.
341
+
342
+ ## Personal Account reads
343
+
344
+ ```bash
345
+ capxul account status --email person@example.com
346
+ capxul account balance --json
347
+ capxul account deposit --wizard
348
+ ```
349
+
350
+ These commands reuse your verified current session unless you provide an email.
351
+ They do not start setup or open a signer. Status shows lifecycle and transaction
352
+ readiness; a failed lifecycle exposes its stage and error code. Balance shows
353
+ exact asset quantities and available fiat valuations. An unavailable valuation
354
+ or failed read is not zero. Deposit uses the SDK's address and network.
355
+
356
+ ## Organization commands
357
+
358
+ ```sh
359
+ capxul org list --json
360
+ capxul org use --org ORGANIZATION_ID
361
+ capxul org status --org ORGANIZATION_ID --json
362
+ capxul org get --json
363
+ capxul org me --json
364
+ capxul org members --json
365
+ capxul org member list --json
366
+ capxul org member get --account-id ACCOUNT_ID --json
367
+ capxul org wait --timeout-seconds 120 --json
368
+ capxul org create --name NAME --handle HANDLE --country CC [--bio TEXT] [--size TEXT] [--confirm]
369
+ capxul org retry --org ORGANIZATION_ID [--confirm]
370
+ ```
371
+
372
+ These commands accept `--email`. Without it, they restore the protected current
373
+ session. Organization reads accept `--org` or its alias `--org-id`. Identical
374
+ repeated IDs are accepted. Different IDs are refused.
375
+
376
+ A read without --org uses the saved read default, then this machine's
377
+ recovery ID, then the one unfinished setup returned by the backend. org list
378
+ includes unfinished founder setups. This works from a clean authenticated home.
379
+ Interactive status/wait offers a choice when several unfinished setups exist.
380
+ Scripted and JSON reads require an exact --org in that case. A ready
381
+ Organization must still appear in current access.
382
+
383
+ Human output shows Organization identity and setup, with a separate unfinished
384
+ setup section and explicit empty results. Members without an Account ID remain
385
+ visible. `org me` shows backend capabilities and exact per-payment Budget caps;
386
+ these caps are not available balances. `--json` keeps the structured SDK data.
387
+
388
+ org use saves a protected per-person read default. Without --org, an interactive
389
+ use command offers current accessible Organizations and ignores the old default.
390
+ A scripted use requires --org. The default grants no
391
+ authority. Member lookup uses an exact AccountId. In a human terminal, omit
392
+ --account-id to select an attached Account from the authorized member list.
393
+ Members without an Account ID cannot be selected. Scripted and JSON lookup
394
+ requires --account-id. Reads do not sign or change
395
+ setup state.
396
+
397
+ org wait opens one exact setup subscription. It continues when needsAttention
398
+ has a scheduled next check. It stops at ready, failed, awaitingAuthorization,
399
+ or attention without a next check. It does not request a check or poll. The
400
+ timeout accepts 1 to 3600 seconds and defaults to 120. A deadline returns
401
+ CLI_DEADLINE at exit 5; Ctrl-C returns CANCELLED at exit 130.
402
+
403
+ ## Organization Payment send
404
+
405
+ ```sh
406
+ capxul org payment send --org O --input payment.json --request-key K --confirm --json
407
+ capxul org payment send --org O --resume K --confirm --json
408
+ capxul org payment send
409
+ ```
410
+
411
+ The Organization input adds its exact Budget ID as `permissionId`. It supports
412
+ the same recipient, amount, and document fields as Personal send. It rejects
413
+ `timing` and payload actor, Organization, key, and lineage overrides. Scripted
414
+ calls require an explicit Organization, request identity, and `--confirm`.
415
+ A human terminal collects missing input and previews the selected actor, exact
416
+ Organization, Budget, treasury asset position, recipient, and document summary.
417
+ A saved read default does not select this write.
418
+
419
+ One default-No confirmation precedes signing. The protected input binds actor,
420
+ Organization, and key. Resume uses that input and forbids source/key overrides.
421
+ Prepared IDs reach stderr before the next signature. Send reports submission;
422
+ exact scoped get/wait establishes later state. JSON preview includes safe
423
+ summary fields and omits document bytes. External recipients use the same
424
+ literal-true input field and human warning as Personal send. Resume preserves
425
+ the saved reference even when the current lookup resolves to a Party.
426
+
427
+ ## Organization Payment reads
428
+
429
+ ```sh
430
+ capxul org payment list --org O [--json]
431
+ capxul org payment get --org O --payment-id P [--json]
432
+ capxul org payment wait --org O --payment-id P [--timeout-seconds N] [--json]
433
+ ```
434
+
435
+ These commands require an explicit Organization. They do not use the saved
436
+ read default. The backend checks current Organization participation and returns
437
+ only that Organization's outgoing, incoming, and self Payments. Get refuses
438
+ a missing or mismatched Payment ID. Reads do not need a signer.
439
+
440
+ Wait observes the exact Organization and Payment through the SDK subscription.
441
+ It stops on a terminal state, required action, or required retry. The timeout
442
+ accepts 1 to 3600 seconds and defaults to 120. It covers session restoration
443
+ and observation. Deadline exit 5 and interruption exit 130 retain read/wait
444
+ instructions with both Organization and Payment IDs.
445
+
446
+ ## Organization Payment retry
447
+
448
+ ```sh
449
+ capxul org payment retry --org O --payment-id P --confirm --json
450
+ capxul org payment retry
451
+ ```
452
+
453
+ Retry addresses the original command and every Payment in that command. It
454
+ creates no replacement send or request key. A terminal can collect the Payment
455
+ ID and select a currently accessible Organization. A saved read default does
456
+ not choose the write target. JSON and scripted runs require both IDs and
457
+ `--confirm`.
458
+
459
+ Before signing, the preview shows every original Payment, recipient, exact
460
+ asset and quantity, timing, and state. It also shows the original command and
461
+ stored Budget. A human terminal asks one default-no question, including when
462
+ `--confirm` is supplied. The signer starts after this step. A changed prepared cohort
463
+ or actor refuses before signature.
464
+
465
+ The result is `{ payments }` in the SDK's original order. Submitted Payments
466
+ can still be pending. A failure, timeout, or interruption retains the selected
467
+ Organization, Payment, and verified sibling IDs with same-scope get/wait
468
+ commands. Retry does not claim settlement from a submission hash.
469
+
470
+ ## Permissions
471
+
472
+ ```sh
473
+ capxul org permission list [--org O] [--json]
474
+ capxul org permission get --permission-id B [--org O] [--json]
475
+ capxul org permission create --org O --input budget.json --request-key K --confirm [--json]
476
+ capxul org permission change --org O --permission-id B --input budget.json --request-key K --confirm [--json]
477
+ ```
478
+
479
+ These commands use the explicit Organization, then the protected read default.
480
+ A human terminal can select an accessible Organization when neither exists.
481
+ Each read checks current Organization access. `get` requires an exact Permission
482
+ ID and refuses a missing or mismatched result. Reads do not need a signer.
483
+
484
+ Human output shows Permission and assignment IDs, revisions, and states.
485
+ Budget output labels the exact per-payment cap or no cap. It does not show a
486
+ remaining balance. JSON preserves the public SDK result.
487
+
488
+ Every Budget write supplies the complete policy:
489
+
490
+ ```json
491
+ {
492
+ "type": "budget",
493
+ "asset": "A",
494
+ "limit": { "asset": "A", "value": "500" },
495
+ "scope": {
496
+ "recipients": { "type": "allowlist", "accounts": ["account_alice"] },
497
+ "actions": ["pay"]
498
+ }
499
+ }
500
+ ```
501
+
502
+ Use an exact admitted AssetId for `A`. The cap must be positive and finite.
503
+ Recipients are `anyone` or 1 to 32 unique Account IDs. Actions are `pay`,
504
+ `commitments`, or both. `pay` covers single and batch Payments. Missing scope,
505
+ duplicate recipients/actions, unknown fields, and an asset mismatch refuse.
506
+ A Budget change keeps its asset. Management input is `{"type":"managePeople"}`.
507
+ Use `--input -` for stdin. Input is limited to 64 KiB.
508
+
509
+ A human terminal can guide policy input. Change prefills the exact active
510
+ revision's complete stored policy. The preview shows all before/after rights
511
+ and any allowance reset before one default-no confirmation. The CLI then records
512
+ verified prepared IDs and compares the frozen policy with that confirmation.
513
+ If it changed, the CLI refuses before signing. A missing human key is generated
514
+ and printed before the first write. Scripted runs require `--request-key` and
515
+ `--confirm`.
516
+
517
+ Success means submitted and pending application. It does not prove active
518
+ rights. After an interruption or uncertain result, retain the original input,
519
+ Organization ID, key, command ID, and execution ID. The key alone cannot restore
520
+ wizard/stdin input.
521
+
522
+ `org permission replace --org O --request-key K --confirm` replaces the current
523
+ Roles module and carries its active Permissions, assignments, and admitted
524
+ Invitation rights. Human mode guides missing scope and shows the full frozen
525
+ before/after snapshot before one default-no approval. Machine mode requires
526
+ scope, key, and confirmation. A changed snapshot refuses before staging or
527
+ signature. Unfinished Invitation configuration must complete or cancel first.
528
+ Submission remains pending application. Use exact command get/wait after an
529
+ uncertain result; the command does not promise unconditional replacement replay.
530
+
531
+ ## Payroll runs, rosters, and reads
532
+
533
+ ```sh
534
+ capxul org payroll groups list --org O [--json]
535
+ capxul org payroll groups save --org O --input group.json --confirm [--json]
536
+ capxul org payroll groups remove --org O --group-id G --confirm [--json]
537
+ capxul org payroll terms --org O [--json]
538
+ capxul org payroll list --org O [--json]
539
+ capxul org payroll run --org O --input run.json --request-key K --confirm [--json]
540
+ capxul org payroll run --org O --resume K --confirm [--json]
541
+ capxul org payroll get --org O --run-id R [--json]
542
+ capxul org payroll wait --org O --run-id R --timeout-seconds 120 [--json]
543
+ ```
544
+
545
+ Group input contains `name`, `tone`, and `members`. Each member supplies a
546
+ canonical `partyId`, draft `amount` text, and `currency`. An optional `id`
547
+ updates that exact group. These commands do not sign or transfer money.
548
+ Group amounts stay unchanged, including unfinished draft text. They do not
549
+ supply payout quantities or currency conversion. A lost create response must
550
+ be reconciled with the same scoped group list before another create.
551
+
552
+ Terms retain raw rates, decimals, units, and effective dates. Run listing
553
+ retains the backend `settledThisMonth` aggregate. The CLI does not sum a partial
554
+ run page or compute earned pay.
555
+
556
+ Run input contains `permissionId`, `asset`, `period`, and ordered `items`.
557
+ Each item supplies a recipient Ref, asserted `partyId`, settlement `amount`,
558
+ raw-unit `gross` and `net`, and signed `adjustments`. Net must equal the exact
559
+ settlement quantity and gross plus adjustments. Keep Organization, actor, signer,
560
+ and request-key routing outside the JSON. `--input -` reads bounded stdin.
561
+ The current Payroll producer accepts email and Party Refs. Other Ref kinds
562
+ refuse before client work.
563
+
564
+ In a human terminal, `capxul org payroll run` guides the current Organization,
565
+ Budget, settlement asset, date, roster or known Parties, and actual payout
566
+ quantities. Roster amounts and terms are reference data. The complete preview
567
+ shows each recipient and Safe, quantity, raw units, and adjustment. One
568
+ default-no approval precedes signing, including when `--confirm` is supplied.
569
+ Machine runs require exact scope, input, key, and `--confirm`.
570
+
571
+ The command saves the exact input in protected storage under the verified actor,
572
+ Organization, and key before execution. `--resume K` restores that snapshot.
573
+ It requires the same explicit Organization and cannot combine fresh input or
574
+ another key. Payroll accepts email and Party references. Raw external addresses
575
+ are outside the current run contract.
576
+ Success returns `{ run, requestKey }`; submission does not prove settlement.
577
+
578
+ Get returns the full authorized run detail, command, ordered items, and recorded
579
+ times. Wait observes the exact run without polling or submitting. It keeps
580
+ waiting through partial settlement and ends when all Payments settle, a failure
581
+ is recorded, or action is required. Timeout exits 5. Cancellation exits 130.
582
+ Recovery retains exact Organization, run, and any observed request key.
583
+
584
+ ## Invitation commands
585
+
586
+ ```sh
587
+ capxul org invite list [--mine] [--limit N] [--cursor C] [--phase PHASE ...] [--org O]
588
+ capxul org invite get --invitation-id I [--org O]
589
+ capxul org invite wait --invitation-id I [--org O] [--timeout-seconds N]
590
+ capxul org invite review --invitation-id I --org O [--timeout-seconds N]
591
+ capxul org invite accept --invitation-id I --offer-digest D --org O [--confirm] [--timeout-seconds N]
592
+ capxul org invite decline --invitation-id I --org O [--confirm]
593
+ capxul org invite cancel --invitation-id I --org O [--confirm]
594
+ capxul org invite resend --invitation-id I --org O [--confirm]
595
+ capxul org invite retry --invitation-id I --org O [--confirm]
596
+ 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]
597
+ ```
598
+
599
+ `org invite list` returns your own offers. It accepts `--limit` (1--100),
600
+ `--cursor`, and repeated `--phase` values, and its result carries `invitations`,
601
+ `nextCursor`, and `observedAt`: pass `nextCursor` back as `--cursor`, and change
602
+ no other filter between the two calls. `--mine` names the own-offer projection,
603
+ which is already the default. With `--org O` the command returns that
604
+ Organization's invitations for a current Admin instead; the Organization list is
605
+ not filtered to you, so `--mine` together with `--org` refuses with exit 2. The
606
+ other invitation commands require an exact `--invitation-id`.
607
+
608
+ `org invite get` and `org invite wait` use `--org` when you name it. Without
609
+ `--org` they walk your own-offer pages, 100 rows per request, until they find
610
+ the invitation or the pages end. They never consult the saved read default, and
611
+ an offer you cannot see is refused. `--timeout-seconds` bounds the resolution
612
+ and the read together on both commands.
613
+
614
+ Invitation lists label own-offer or Organization Admin scope and the verified
615
+ actor. They show an explicit empty page, next cursor, or end of results. Page
616
+ filters and cursor values stay in their selected scope.
617
+
618
+ Invitation human output shows the authoritative phase, delivery, expiry, and
619
+ offered policies. An offer does not prove active membership. Manual resend/retry commands come only
620
+ from the backend action projection, with exact scope/session and earliest time.
621
+ Older responses without that projection show read-back guidance. Lifecycle
622
+ recovery remains separate from manual options. Member-invite
623
+ previews show exact per-payment caps and allowed recipients/actions; expiry is
624
+ unavailable before authoring. The native authoring wizard asks for Organization,
625
+ recipient, grants and policy before session email. New-Budget labels identify
626
+ policy inputs; skip them for existing grants. Wizard answers use the same request
627
+ validation as flags. Every authoring write prints its request key
628
+ before submission. JSON result data stays unchanged.
629
+
630
+ Uncertain decline/cancel/resend/retry failures and transition deadlines print an
631
+ exact `org invite get` command with the resolved session. Read the current offer
632
+ before another transition; a lost response does not authorize replay.
633
+
634
+ `org invite wait` uses one exact SDK subscription after resolving scope. It
635
+ finishes when the offer settles or lifecycle recovery asks a person to act.
636
+ Manual recovery options do not stop the wait. It never polls, retries, resends,
637
+ or accepts. The deadline covers resolution and observation; completion, failure
638
+ and interruption release the subscription, including a handle that arrives late.
639
+
640
+ Native invitation target prompts ask Organization and invitation IDs before
641
+ session email. Transition confirmation shows the verified actor and the current
642
+ resolved offer, including grants and expiry, before the default-No question.
643
+
644
+ `org invite review` requires `--org`, returns the current `InvitationView`
645
+ directly in `data`, and performs no write or signing.
646
+
647
+ The four transitions require `--org` in both modes, as `accept` does. They never
648
+ author a new offer. A noninteractive or JSON run requires `--confirm`. An
649
+ interactive run shows the resolved current offer and asks a default-no question.
650
+
651
+ `org member invite` authorizes one exact offer. `--preview` writes nothing and
652
+ needs neither a request key nor confirmation. A noninteractive write requires
653
+ `--request-key` and `--confirm`. An interactive run prints the request key it
654
+ used before it submits, so a lost response is recoverable with the same
655
+ identity. At most one `--new-budget-name` is accepted per command.
656
+
657
+ `org invite accept` is the exact grantee's consent commit. It takes the exact
658
+ digest the offer shows as `--offer-digest`: a noninteractive or JSON run must
659
+ supply it, and without it the command refuses with exit 2 before it creates a
660
+ client. An interactive run may omit it, and then reads the offer and fills the
661
+ digest from the value it displayed. A digest you state is never replaced by the
662
+ displayed one. `--expected-offer` remains a compatibility spelling, and both
663
+ spellings must match when supplied together. The command returns the
664
+ `InvitationView` directly in `data`. The grant is executed by the deployment's
665
+ technical executor, so the command needs no browser bridge and works in a
666
+ headless or CI session. A repeat with the stored digest returns the same
667
+ accepted result; a different digest refuses and cannot overwrite consent. The
668
+ returned view is the authorization-time view of the consent commit
669
+ (`pending_grant`); read the settled `active` state with `get` or `wait`.
670
+
671
+ ## Organization writes
672
+
673
+ org create and org retry use the protected current session unless --email names
674
+ one. A JSON or noninteractive write requires --confirm. A terminal write shows
675
+ the current Organization and recovery information, then asks a default-no
676
+ question. The signer starts after confirmation.
677
+
678
+ `org create --wizard` guides name, handle, country, optional bio and size, then
679
+ session email. Supplied flags remain in the generated command. The final write
680
+ preview names the verified actor and starts with No selected.
681
+ `org retry --wizard` collects the exact Organization ID before session email.
682
+ Its final preview shows the verified actor and current lifecycle. Saved read
683
+ defaults and creation recovery records cannot change that retry ID.
684
+
685
+ org create validates name, handle, and country before client work. It calls
686
+ onboarding.beginOrganization, saves and prints the exact Organization ID,
687
+ authorizes only an awaitingAuthorization setup, then subscribes to setup
688
+ changes. It reports success only after ready and current access. JSON progress
689
+ uses one line per state:
690
+
691
+ { "type": "organization.lifecycle", "organizationId": "O", "status": "processing" }
692
+
693
+ org retry requires one exact --org. It authorizes only awaitingAuthorization.
694
+ For an accepted setup it asks the backend to check the same operation hash
695
+ through setup.resume, then subscribes. Neither command replaces a submitted
696
+ operation. The local recovery record keeps a safe handle and Organization ID
697
+ for convenience; the backend unfinished list supports recovery without it.
698
+
699
+ --timeout-seconds sets one 1-to-3600-second deadline for the command. A
700
+ deadline stops local work and returns exit 5. If the last observed setup has
701
+ another automatic check scheduled, the message is "Stopped waiting.
702
+ Organization setup continues in the background." Before acceptance or without
703
+ a scheduled check, the message is "Stopped waiting. Read the Organization
704
+ setup status." The error details include the safe Organization ID when known,
705
+ last observed setup state, setup reason, and bounded provider diagnostics.
706
+ Ctrl-C stops local work at exit 130. Neither stop writes a backend failure.
707
+
22
708
  ## Configuration
23
709
 
24
- | Variable | Use |
25
- | ------------------------------ | ------------------------------------------------------------------------------------------------------------ |
26
- | `CAPXUL_CLI_HOME` | Directory for global CLI settings. Defaults to `$XDG_CONFIG_HOME/capxul/cli`, or `$HOME/.config/capxul/cli`. |
27
- | `CAPXUL_PUBLISHABLE_KEY` | Application publishable key, required for an online check. |
28
- | `CAPXUL_BOOTSTRAP_URL` | Bootstrap origin. Defaults to `https://api.staging.capxul.com`. Convex Cloud origins are rejected. |
29
- | `CAPXUL_POSTHOG_HOST` | PostHog ingestion origin. |
30
- | `CAPXUL_POSTHOG_PROJECT_TOKEN` | Project ingestion token. Both PostHog variables are required for export. |
31
- | `CAPXUL_TELEMETRY_DISABLED` | Set to `true` to disable remote observation regardless of the saved preference. |
710
+ | Variable | Use |
711
+ | --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
712
+ | `CAPXUL_CLI_HOME` | Directory for global CLI settings. Defaults to `$XDG_CONFIG_HOME/capxul/cli`, or `$HOME/.config/capxul/cli`. |
713
+ | `CAPXUL_PUBLISHABLE_KEY` | Optional developer override for the bundled first-party staging key. |
714
+ | `CAPXUL_BOOTSTRAP_URL` | Bootstrap origin. Defaults to `https://api.staging.capxul.com`. Convex Cloud origins are rejected. |
715
+ | `CAPXUL_CHECKOUT_FRONTEND_ORIGIN` | Checkout frontend origin. Staging uses `https://app.staging.capxul.com`. Devnet at `http://127.0.0.1:3211` uses `http://127.0.0.1:3002`. Custom bootstrap origins require this value. |
716
+ | `CAPXUL_POSTHOG_HOST` | Optional development override for the built-in public PostHog ingestion origin. |
717
+ | `CAPXUL_POSTHOG_PROJECT_TOKEN` | Optional development override for the built-in public project ingestion token. |
718
+ | `CAPXUL_TELEMETRY_DISABLED` | Set to `true` to disable remote observation regardless of the saved preference. |
32
719
 
33
- Collection defaults to enabled. Local commands send no remote signals.
720
+ The published CLI includes the verified first-party staging application key and
721
+ Capxul-owned public ingestion configuration. You do not need key or PostHog
722
+ environment variables. A different bootstrap origin requires an explicit key. Collection defaults to enabled for
723
+ ordinary local and online commands, help, version, and safely attributed argument
724
+ refusals. Parser refusals produce a completion without a start. Early native
725
+ global errors with no resolved command route send nothing, because the CLI
726
+ cannot determine whether they belong to a silent collection control.
34
727
  `telemetry disable` saves one preference for the OS user and sends no final
35
728
  remote event. Already running CLI processes check the current preference before
36
729
  each export. Requests already sent cannot be recalled. `telemetry status`
37
730
  reports the stored preference, effective policy, configuration, and reason.
731
+ `--log-level` controls normal diagnostic output, not collection. An eligible
732
+ invocation still produces its remote completion unless collection is disabled.
733
+
734
+ Eligible commands reuse a random anonymous identifier stored in the protected
735
+ CLI directory. Invocation and trace identifiers remain separate. A first-use
736
+ marker records the first eligible observed use, not a download or a verified
737
+ person. If this state cannot be accessed safely, observation stops and the
738
+ command retains its normal result. Delivery is bounded and best-effort; the CLI
739
+ does not keep a persistent activity queue.
38
740
 
39
741
  Settings use a versioned JSON file in a directory with mode `0700`. The file has
40
742
  mode `0600`. Writes are atomic and serialize between processes. A later writer
@@ -43,8 +745,22 @@ unsafe permissions, symlinks, and corrupt state produce a storage failure.
43
745
 
44
746
  ## Output
45
747
 
46
- `--json` writes one version 1 envelope to stdout. Success contains `data`.
47
- Failure contains `error.code` and CLI-owned `error.message`. Each envelope has
748
+ Organization setup failures include a copyable command with the exact ID and
749
+ selected email. When state is uncertain, read status first. A supported retry
750
+ includes `--confirm`; terminal runs still ask for confirmation. If no ID is
751
+ known, the command lists your Organizations instead of guessing one.
752
+ JSON errors can include `error.details.recovery` with `kind` (`read` or `retry`)
753
+ and an `argv` array for that primary action. These arguments preserve the same
754
+ scope as the human command; they do not grant authority or bypass current checks.
755
+
756
+ `--json` writes one version 1 envelope to stdout. Success contains `data`, which
757
+ can be an object, array, or null according to the command's SDK result.
758
+ Failure contains `error.code` and CLI-owned `error.message`. A wallet failure
759
+ also includes its known `error.mode` and allowed `error.details`: wallet stage,
760
+ operation, provider, provider code, and HTTP status. An unknown browser failure
761
+ uses mode `unknown`. No provider message, token, signature, or native cause enters
762
+ the result. These fields remain available when collection is off or
763
+ `--log-level none` is set. Each envelope has
48
764
  `command`, `invocationId`, and `outcome`. An invocation ID is null before a
49
765
  command starts. Human errors go to stderr.
50
766
 
@@ -93,11 +809,21 @@ compinit
93
809
  Use `npm update -g @capxul/cli` or `brew upgrade xelmar-tech/tap/capxul` to update.
94
810
  Use one installer for the `capxul` executable to avoid conflicting PATH entries.
95
811
 
812
+ After a successful human command, help, or version request, the CLI can show an
813
+ update notice on terminal stderr. It checks the public npm `latest` tag at most
814
+ once per 24 hours. It shows only the command for the verified running npm-global
815
+ or Homebrew installation. It does not execute that command. Unknown installations,
816
+ development versions, JSON output, redirected stderr, CI, shell completion, and
817
+ all `telemetry` commands receive no notice. The optional check has one 500 ms
818
+ budget. Safe failed attempts are cached. Storage or network failures remain
819
+ silent and do not change the command result. This check sends no telemetry.
820
+
96
821
  ## Development commands
97
822
 
98
823
  ```sh
99
824
  vp test run apps/cli
100
825
  vp run --filter @capxul/cli check-types
826
+ vp run --filter @capxul/cli lint
101
827
  vp run --filter @capxul/cli build
102
828
  vp exec node --test --test-name-pattern='@capxul/cli' scripts/__tests__/pack-install-smoke.test.mjs
103
829
  ```
@@ -105,3 +831,211 @@ vp exec node --test --test-name-pattern='@capxul/cli' scripts/__tests__/pack-ins
105
831
  The last command installs the tarball outside the workspace and exercises the
106
832
  installed executable with isolated settings and a local HTTP server. The CI
107
833
  `CLI / Linux / Node 24.0.0` job runs this proof at the declared minimum version.
834
+
835
+ ## Email login and session restoration
836
+
837
+ This CLI establishes a first-party BetterAuth session. An older native
838
+ `account:read` grant does not count as sign-in and cannot read the profile.
839
+ Logout clears the selected email's session and attempts to revoke any native
840
+ grant that was stored before the first-party flow replaced it.
841
+
842
+ `capxul auth login` and `capxul auth signup` stay separate commands. On a
843
+ terminal, each command is a wizard. `auth login` asks for the email and a masked
844
+ OTP. It accepts the code as a paste. It retries an invalid code at most three
845
+ times for one request. After sign-in, an incomplete account gets one offer to
846
+ continue setup in the same command. `auth signup` authenticates first, then asks
847
+ for the Profile fields: display name, two-letter country code, and handle. A
848
+ known value is the prompt default, so Enter keeps it.
849
+
850
+ The browser opens only when the shared Core onboarding journey needs Openfort
851
+ wallet readiness. It shows wallet status only. It has no email, OTP, Profile, or
852
+ approval form.
853
+
854
+ Ctrl+C or Ctrl+D at a wizard prompt cancels the command. The command prints no
855
+ success result and exits 130. A step that already finished keeps its result: a
856
+ completed sign-in keeps its session.
857
+
858
+ For an agent, send and verify in separate processes:
859
+
860
+ ```sh
861
+ capxul auth send --email "$TEST_EMAIL" --json
862
+ # Supply the delivered six-digit OTP through stdin, not a command argument.
863
+ capxul auth verify --email "$TEST_EMAIL" --otp-stdin --json
864
+ capxul auth profile --email "$TEST_EMAIL" --json
865
+ # A later process uses the same protected CLI home; no new OTP is required.
866
+ capxul auth profile --email "$TEST_EMAIL" --json
867
+ capxul auth status --email "$TEST_EMAIL" --json
868
+ capxul auth logout --email "$TEST_EMAIL" --json
869
+ ```
870
+
871
+ After sending a code, human output includes the exact verification command with
872
+ your email safely quoted. If verification has no pending code, the error gives
873
+ the exact command to request one. Neither command includes the OTP itself.
874
+
875
+ If account setup or its final read fails recoverably, the CLI prints an exact
876
+ `auth signup` continuation with your email and Profile fields. Run it with the
877
+ same protected CLI home to resume the saved session. Explicit access/input
878
+ refusals and non-retryable failures require their stated correction first.
879
+
880
+ Human profile/status output labels your Profile fields and available Account,
881
+ wallet and Smart Account identifiers. Failed setup includes its stage and error
882
+ code. These reads do not open the wallet browser. `--json` retains the structured
883
+ result, including the same Profile and lifecycle values.
884
+
885
+ A machine run never prompts. `auth login` with `--otp-stdin` sends the OTP and
886
+ verifies one code from stdin. It returns the tagged result
887
+ `setupState: "setup-required"` when the account needs setup. It does not start
888
+ setup work, so sign-in never becomes signup.
889
+
890
+ A fresh machine signup does verification and setup in one command. State every
891
+ Profile field; a missing field refuses with exit 2:
892
+
893
+ ```sh
894
+ # Supply only the delivered OTP through stdin.
895
+ capxul auth signup --email "$TEST_EMAIL" --otp-stdin \
896
+ --display-name "Test Person" --country GH --handle test_person --json
897
+ ```
898
+
899
+ `--otp-stdin` reads up to 64 bytes, ending at EOF. Pipe from a secret provider or
900
+ 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
901
+ work. OTPs are never accepted in argv, persisted in the continuation, or included
902
+ in output.
903
+
904
+ The local page binds to an OS-selected loopback port. A random launch capability
905
+ is redeemed once and removed from the URL before Openfort starts. The page receives
906
+ only the authenticated wallet token and encryption session in memory. Closing it
907
+ ends the current wallet attempt. Re-run `auth signup` with the same CLI home to
908
+ resume the same Profile and Account without another OTP while the backend session
909
+ remains valid.
910
+
911
+ `auth signup` returns only two readiness results. `setupState: "ready"` is a
912
+ personal Account that the Account readiness owner reads as ready and deployed,
913
+ and its data carries the public identifiers: the Profile, the public wallet
914
+ address (`smartAccount.signerAddress`), the personal Smart Account address
915
+ (`smartAccount.smartAccountAddress`), the Account ID
916
+ (`lifecycle.accountId`), and the ready status. Any other state returns the typed
917
+ recoverable result `setupState: "setup-required"`, with the lifecycle, its
918
+ failure code, and the command that resumes the journey. A ready Account starts
919
+ no wallet work, so a retry keeps the one Profile, wallet, Smart Account, and
920
+ Account. An interruption keeps the stored session and stores no code, so the
921
+ next command resumes the same setup.
922
+
923
+ A ready personal Account continues the same journey into Organization creation
924
+ with `capxul org create --name NAME --handle HANDLE --country CC`. The create
925
+ command records the safe recovery handle for that Organization, so an
926
+ interruption or a restart resumes the exact same Organization.
927
+
928
+ The CLI checks `--display-name`, `--country`, and `--handle` before it opens a
929
+ client, so a malformed value refuses with exit 2 and no code is sent. The handle
930
+ check covers the grammar only: a handle that another person holds, and a reserved
931
+ handle, refuse through the identity owner after sign-in. Both refusals name the
932
+ handle, and neither offers verification-code recovery for a Profile problem.
933
+
934
+ The version 2 `first-party-session` record stores the opaque provider credential
935
+ in the existing protected plaintext store. Its scope includes the application
936
+ key, issuer, environment, and email. Each process validates restoration with the
937
+ backend; cached session data is not authority. Conditional replacement prevents
938
+ a concurrent logout from being undone by a delayed credential save. The backend
939
+ owns expiry and revocation. A failed remote logout is reported as `unconfirmed`;
940
+ local sign-out remains in effect.
941
+
942
+ `auth profile` returns a backend-read Profile and account lifecycle without opening
943
+ the browser. Successful email authentication can return `setupState: "setup-required"`.
944
+ `auth signup` returns `setupState: "ready"` only after Core reads a ready Account.
945
+ After logout, profile reads refuse with `NOT_AUTHENTICATED` and exit 3. An invalid
946
+ or expired OTP refuses with exit 2.
947
+
948
+ Resume an existing personal Account after incomplete setup:
949
+
950
+ ```sh
951
+ capxul account retry --email you@example.com --confirm --timeout-seconds 120
952
+ capxul account retry --email you@example.com --wizard
953
+ ```
954
+
955
+ The terminal shows the verified session, Account ID and current lifecycle before
956
+ confirmation. A ready Account starts no wallet work. Missing Account or Profile
957
+ state directs to `auth signup`. A deadline stops waiting; check `account status`
958
+ for the same session before retrying.
959
+
960
+ Read an Organization treasury or deposit target:
961
+
962
+ ```sh
963
+ capxul org balance --org org_example --email you@example.com
964
+ capxul org deposit --org org_example --email you@example.com
965
+ capxul org balance --wizard
966
+ ```
967
+
968
+ These commands use the existing Organization read selection. Balances require
969
+ backend treasury access. Deposit instructions use the public SDK's own-access
970
+ projection. Neither command starts a signer or changes Organization setup.
971
+
972
+ Contact reads show the selected scope, label, full Party ID, reference,
973
+ relationships and hidden state. JSON keeps the existing array, entry or null.
974
+
975
+ ```sh
976
+ capxul contact list --include-hidden
977
+ capxul contact get --entry-id party_example
978
+ capxul org contact get --org org_example --wizard
979
+ ```
980
+
981
+ In a terminal, omit `--entry-id` to select a contact, including hidden contacts.
982
+ In a script, provide the exact Party ID. Organization contacts always require
983
+ an explicit `--org`; they never use the personal book as a fallback.
984
+
985
+ Contact add shows the reference and optional label before terminal confirmation.
986
+ Without an input file, the wizard asks for these values. On an uncertain response,
987
+ use the printed list command to check the same address book before adding again.
988
+ Adding an existing contact can unhide it or change its label.
989
+
990
+ Change a contact label with `contact label --entry-id party_example --label
991
+ "New label" --confirm`. In a terminal, omit the Party ID to select from the
992
+ same book, including hidden contacts. Organization labels require `--org`.
993
+ After an uncertain response, use the exact get command printed by the CLI.
994
+
995
+ `contact hide` can select a contact in a terminal when `--entry-id` is omitted.
996
+ It confirms the hidden state, then prints the exact `contact unhide` command for
997
+ the same Party, session and scope. The contact's history remains available.
998
+
999
+ `contact unhide` uses the same scoped selector, including hidden contacts, when
1000
+ a terminal omits `--entry-id`. It confirms the change and shows the visible
1001
+ contact. Scripts provide the exact Party ID and `--confirm`.
1002
+
1003
+ ## Fixed offers
1004
+
1005
+ Manage fixed service offers in your personal Account or an explicit Organization.
1006
+ These commands do not sign payments or create checkout purchases.
1007
+
1008
+ ```sh
1009
+ capxul offer create --input offer.json --request-key consulting-001 --confirm
1010
+ capxul offer list
1011
+ capxul offer get --offer-id OFFER_ID
1012
+ capxul offer revise --offer-id OFFER_ID --expected-revision 1 --input offer.json --confirm
1013
+ capxul offer deactivate --offer-id OFFER_ID --expected-revision 2 --confirm
1014
+ capxul org offer list --org ORG_ID
1015
+ ```
1016
+
1017
+ Use `org offer` and `--org ORG_ID` for each Organization command. Use `--email`
1018
+ to select a saved session. Scripts must supply `--confirm` for each write.
1019
+ A terminal shows the proposed change and asks for confirmation. Use `--json`
1020
+ for structured output. Lists and reads create no PDF.
1021
+
1022
+ The input file contains the complete offer terms. Use `--input -` to read stdin.
1023
+ The input limit is 64 KiB. Supply an admitted Base Sepolia asset ID from the
1024
+ existing asset catalog. Amounts use exact decimal strings. Quantity limits use
1025
+ positive whole numbers.
1026
+
1027
+ ```json
1028
+ {
1029
+ "title": "Consulting",
1030
+ "description": "One hour of consulting",
1031
+ "unitLabel": "hour",
1032
+ "unitAmount": { "asset": "ASSET_ID", "value": "12" },
1033
+ "quantity": { "min": 1, "max": 8 }
1034
+ }
1035
+ ```
1036
+
1037
+ Creation requires an explicit replay key. Keep the key and identical terms when
1038
+ recovering an uncertain result. Read the offer list before another write. Revision
1039
+ and deactivation require the revision you observed. A conflict requires a fresh
1040
+ read. The CLI does not retry a write automatically. Checkout links are not emitted
1041
+ until the checkout route works.