@agenzo/token-cli 0.3.4 → 0.5.0

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/dist/index.js CHANGED
@@ -18,6 +18,9 @@ var CODE_NUM = {
18
18
  AUTH_INVITE_CODE_INVALID: 1004,
19
19
  KEY_INVALID: 1101,
20
20
  KEY_SCOPE_DENIED: 1102,
21
+ PAYMENT_METHOD_NOT_FOUND: 1401,
22
+ PAYMENT_METHOD_DISABLED: 1402,
23
+ INVALID_PAYMENT_METHOD: 1403,
21
24
  RESOURCE_NOT_FOUND: 2001,
22
25
  RESOURCE_CONFLICT: 2002,
23
26
  RESOURCE_STATE_INVALID: 2003,
@@ -38,6 +41,23 @@ var CODE_NUM = {
38
41
  QUOTE_EXPIRED: 4202,
39
42
  BOOKING_FAILED: 4203,
40
43
  CANCELLATION_NOT_ALLOWED: 4204,
44
+ PRICE_MISMATCH: 4205,
45
+ VEHICLE_CLASS_MISMATCH: 4206,
46
+ PAYMENT_METHOD_REQUIRED: 4207,
47
+ QUOTE_CACHE_UNAVAILABLE: 4208,
48
+ ARREARS_OUTSTANDING: 4209,
49
+ CONTACT_REQUIRED: 4210,
50
+ INVALID_PHONE: 4211,
51
+ SEAT_LIMIT_EXCEEDED: 4213,
52
+ RIDE_NOT_FOUND: 4212,
53
+ NO_AVAILABILITY: 4301,
54
+ PRICE_CHANGED: 4302,
55
+ NAME_FORMAT_INVALID: 4303,
56
+ HOTEL_ORDER_NOT_FOUND: 4304,
57
+ ALREADY_CANCELLED: 4305,
58
+ CHECKOUT_NOT_ALLOWED: 4306,
59
+ CHECKOUT_TASK_NOT_FOUND: 4307,
60
+ PAY_PER_CALL_NOT_AVAILABLE: 4308,
41
61
  RATE_LIMITED: 5001,
42
62
  UPSTREAM_ERROR: 5101,
43
63
  INTERNAL_ERROR: 5201,
@@ -55,23 +75,29 @@ function codeNum(code) {
55
75
  return CODE_NUM[code];
56
76
  }
57
77
  var CliError = class _CliError extends Error {
58
- constructor(code, message, statusCode, requestId, upstream) {
78
+ constructor(code, message, statusCode, requestId, upstream, backendMessage) {
59
79
  super(message);
60
80
  this.code = code;
61
81
  this.statusCode = statusCode;
62
82
  this.requestId = requestId;
63
83
  this.upstream = upstream;
84
+ this.backendMessage = backendMessage;
64
85
  this.name = "CliError";
65
86
  }
66
87
  code;
67
88
  statusCode;
68
89
  requestId;
69
90
  upstream;
91
+ backendMessage;
70
92
  /**
71
93
  * Map a backend ApiError to a CLI-facing code (§8.5 transitional mapping).
72
- * Backend numeric codes / HTTP status are translated to §8.4 string codes;
73
- * the raw backend message is NOT passed through (§8.1 principle 4) — a
74
- * stable, fixed message per code is used instead.
94
+ * Backend numeric codes / HTTP status are translated to §8.4 string codes.
95
+ * The top-level `message` is always the stable, catalog-owned text for the
96
+ * resolved code (§8.1 principle 4 never let raw backend text become the
97
+ * primary/stable message). The backend's own message is NOT discarded,
98
+ * though: it is preserved on `backendMessage` and surfaced in the envelope
99
+ * as `backend_message` so the caller can see the real reason (e.g. which
100
+ * field failed validation) alongside the stable code/message.
75
101
  *
76
102
  * The optional `opts.auth` selects the auth semantics for the 401 mapping:
77
103
  * - `'bearer'` (default, admin-cli Bearer Token): 401 → `AUTH_SESSION_EXPIRED`.
@@ -95,7 +121,8 @@ var CliError = class _CliError extends Error {
95
121
  STABLE_MESSAGE[error.code] ?? "Request failed. Please check your input and retry.",
96
122
  error.statusCode,
97
123
  error.requestId,
98
- error.upstream
124
+ error.upstream,
125
+ error.errorMessage
99
126
  );
100
127
  }
101
128
  const status = error.statusCode;
@@ -112,7 +139,8 @@ var CliError = class _CliError extends Error {
112
139
  STABLE_MESSAGE[code] ?? "Request failed. Please check your input and retry.",
113
140
  status,
114
141
  error.requestId,
115
- error.upstream
142
+ error.upstream,
143
+ error.errorMessage
116
144
  );
117
145
  }
118
146
  };
@@ -167,6 +195,9 @@ var STABLE_MESSAGE = {
167
195
  AUTH_INVITE_CODE_INVALID: "The invitation code is invalid.",
168
196
  KEY_INVALID: "The API key is invalid or has been revoked. Please check your --api-key and retry.",
169
197
  KEY_SCOPE_DENIED: "This API key does not have the required scope for this command.",
198
+ PAYMENT_METHOD_NOT_FOUND: "Payment method not found.",
199
+ PAYMENT_METHOD_DISABLED: "This payment method has been disabled.",
200
+ INVALID_PAYMENT_METHOD: "The payment method is not available for this operation.",
170
201
  RESOURCE_NOT_FOUND: "The resource was not found or does not belong to the current organization.",
171
202
  RESOURCE_CONFLICT: "A resource with the same unique value already exists.",
172
203
  RESOURCE_STATE_INVALID: "The resource is in a state that does not permit this operation.",
@@ -188,18 +219,38 @@ var STABLE_MESSAGE = {
188
219
  VEHICLE_UNAVAILABLE: "No vehicle is available for the requested trip. Please try a different time or class.",
189
220
  QUOTE_EXPIRED: "The quote has expired. Please request a new quote and retry.",
190
221
  BOOKING_FAILED: "The booking could not be completed. Please retry.",
222
+ PRICE_MISMATCH: "The price does not match the quote. Re-quote and use the exact amount from the quote response.",
223
+ VEHICLE_CLASS_MISMATCH: "The vehicle class does not match the quote. Use the vehicle class from the quote response.",
224
+ PAYMENT_METHOD_REQUIRED: "Pay-per-call billing requires an active payment method. Please add a card first.",
225
+ QUOTE_CACHE_UNAVAILABLE: "Quote cache is temporarily unavailable. Please request a new quote and retry.",
226
+ ARREARS_OUTSTANDING: "You have outstanding arrears. Please settle your balance before booking a new ride.",
227
+ CONTACT_REQUIRED: "Passenger contact information is required. Please provide a passenger name and phone number.",
228
+ INVALID_PHONE: "The passenger phone number is not valid. Please provide a valid international number.",
229
+ SEAT_LIMIT_EXCEEDED: "The number of child/infant/toddler seats exceeds the vehicle capacity. Reduce seats or choose a larger vehicle.",
230
+ RIDE_NOT_FOUND: "The ride order was not found or does not belong to you.",
191
231
  CANCELLATION_NOT_ALLOWED: "This order cannot be cancelled in its current state.",
232
+ NO_AVAILABILITY: "No rooms available for the selected hotel and dates.",
233
+ PRICE_CHANGED: "The price changed since the quote. Re-quote and confirm.",
234
+ NAME_FORMAT_INVALID: "The guest name format is not accepted; use Latin letters.",
235
+ HOTEL_ORDER_NOT_FOUND: "Hotel order not found.",
236
+ ALREADY_CANCELLED: "This hotel order is already cancelled.",
237
+ CHECKOUT_NOT_ALLOWED: "A partial check-out is not allowed in the current state.",
238
+ CHECKOUT_TASK_NOT_FOUND: "Check-out application not found.",
239
+ PAY_PER_CALL_NOT_AVAILABLE: "Pay-per-call billing is not available; use monthly_settlement.",
192
240
  NOT_IMPLEMENTED: "This operation is not implemented yet."
193
241
  };
194
242
  function toErrorEnvelope(error) {
195
243
  if (error instanceof CliError) {
244
+ const stableMessage = error.message || "Unknown error";
245
+ const backendMessage = error.backendMessage && error.backendMessage !== stableMessage ? error.backendMessage : void 0;
196
246
  return {
197
247
  error: {
198
248
  code: error.code,
199
249
  code_num: codeNum(error.code),
200
- message: error.message || "Unknown error",
250
+ message: stableMessage,
201
251
  ...error.requestId ? { request_id: error.requestId } : {},
202
- ...error.upstream ? { upstream: error.upstream } : {}
252
+ ...error.upstream ? { upstream: error.upstream } : {},
253
+ ...backendMessage ? { backend_message: backendMessage } : {}
203
254
  }
204
255
  };
205
256
  }
@@ -262,13 +313,27 @@ function isBelow(current, minimum) {
262
313
  var ApiClient = class {
263
314
  baseUrl;
264
315
  timeout;
316
+ /**
317
+ * Correlation id for this CLI invocation. Generated once per `ApiClient`
318
+ * instance (i.e. once per command execution — each `apps/*` entrypoint
319
+ * constructs exactly one `ApiClient` per process run) and sent as
320
+ * `X-Request-Id` on every request this client makes. The backend's
321
+ * `RequestIdMiddleware` adopts a client-supplied `X-Request-Id` verbatim as
322
+ * both `trace_id` and `request_id` (only generating its own when the header
323
+ * is absent), so every HTTP call belonging to one CLI operation — including
324
+ * multi-step flows like `payment-methods add`'s create + poll + get — shares
325
+ * a single trace_id server-side and can be followed as one chain in logs.
326
+ */
327
+ requestId;
265
328
  constructor(config) {
266
329
  this.baseUrl = config.baseUrl.replace(/\/+$/, "");
267
330
  this.timeout = config.timeout ?? 6e4;
331
+ this.requestId = crypto.randomUUID();
268
332
  }
269
333
  buildHeaders(auth) {
270
334
  const headers = {
271
- "User-Agent": `agenzo-admin-cli/${getCurrentVersion()}`
335
+ "User-Agent": `agenzo-admin-cli/${getCurrentVersion()}`,
336
+ "X-Request-Id": this.requestId
272
337
  };
273
338
  if (auth.type === "bearer") {
274
339
  headers["Authorization"] = `Bearer ${auth.token}`;
@@ -743,6 +808,265 @@ async function collectPaymentMethodParams(type, flags) {
743
808
  return params;
744
809
  }
745
810
 
811
+ // src/verb-schema.ts
812
+ var CLI_NAME = "agenzo-token-cli";
813
+ var PAYMENT_METHODS_NOUN = "payment-methods";
814
+ var PAYMENT_TOKENS_NOUN = "payment-tokens";
815
+ function wantsJsonSchema(argv = process.argv) {
816
+ for (let i = 0; i < argv.length; i++) {
817
+ const a = argv[i];
818
+ if (a === "--format=json") return true;
819
+ if (a === "--format" && argv[i + 1] === "json") return true;
820
+ }
821
+ return false;
822
+ }
823
+ function emitSchema(schema) {
824
+ console.log(JSON.stringify(schema, null, 2));
825
+ }
826
+ function attachSchemaHelp(cmd, schema) {
827
+ const baseHelp = cmd.helpInformation.bind(cmd);
828
+ cmd.helpInformation = (context) => {
829
+ if (!wantsJsonSchema()) return baseHelp(context);
830
+ emitSchema(schema);
831
+ return "";
832
+ };
833
+ return cmd;
834
+ }
835
+ var pmAddSchema = {
836
+ cli: CLI_NAME,
837
+ noun: PAYMENT_METHODS_NOUN,
838
+ verb: "add",
839
+ description: "Add a payment method (manual 3DS or Drop-in session)",
840
+ flags: {
841
+ type: { type: "string", required: false, default: "card", description: "Payment method type" },
842
+ mode: {
843
+ type: "string",
844
+ required: false,
845
+ default: "manual",
846
+ description: 'Add mode: "manual" (CLI collects card details and polls 3DS) or "dropin" (mint a Drop-in session; the app opens the Drop-in SDK for the user to enter card details securely \u2014 use this mode when the user wants to bind/add a card from chat)',
847
+ constraints: "manual | dropin"
848
+ },
849
+ email: {
850
+ type: "string",
851
+ required: "conditional",
852
+ description: "Manual mode: email for 3DS verification. Dropin mode: email used as the Drop-in session reference. Use the user's login profile email \u2014 never ask in chat."
853
+ },
854
+ "idempotency-key": {
855
+ type: "string",
856
+ required: false,
857
+ description: "Idempotency key forwarded verbatim as the Idempotency-Key header (manual mode only)"
858
+ },
859
+ "no-poll": {
860
+ type: "bool",
861
+ required: false,
862
+ default: false,
863
+ description: "Dropin mode: mint the session, print it, and exit immediately without polling verification status (for server/SDK-driven flows where the front-end completes the binding). Agents integrating with a UI card flow should set this."
864
+ }
865
+ },
866
+ response: {
867
+ id: { type: "string", description: "Payment method id" },
868
+ session_id: { type: "string|absent", description: "Drop-in session id (dropin mode only) \u2014 pass to the front-end Drop-in SDK, never read aloud to the user" },
869
+ status: { type: "string", description: "PENDING | ACTIVE | FAILED | EXPIRED" },
870
+ brand: { type: "string|absent", description: "Card brand, once known" },
871
+ last4: { type: "string|absent", description: "Card last 4 digits, once known" }
872
+ },
873
+ example: {
874
+ command: "agenzo-token-cli payment-methods add --mode dropin --email user@example.com --no-poll",
875
+ output_summary: "Dropin mode returns { id, session_id }. Never read card numbers/CVV/expiry to or from the user (PCI) \u2014 the Drop-in SDK collects them securely."
876
+ },
877
+ error_recovery: {
878
+ PARAM_INVALID: 'Fix the offending flag (mode must be "manual" or "dropin"), then retry.'
879
+ }
880
+ };
881
+ var pmListSchema = {
882
+ cli: CLI_NAME,
883
+ noun: PAYMENT_METHODS_NOUN,
884
+ verb: "list",
885
+ description: "List payment methods",
886
+ flags: {
887
+ member: { type: "string", required: false, description: "Filter by member ID" }
888
+ },
889
+ response: {
890
+ payment_methods: {
891
+ type: "array",
892
+ description: "Payment methods for the developer (optionally scoped to --member)",
893
+ items: {
894
+ id: { type: "string", description: "Payment method id" },
895
+ type: { type: "string", description: "Payment method type (e.g. card)" },
896
+ status: { type: "string", description: "PENDING | ACTIVE | FAILED | DISABLED | EXPIRED" },
897
+ brand: { type: "string|null", description: "Card brand" },
898
+ first6: { type: "string|null", description: "Card first 6 digits" },
899
+ last4: { type: "string|null", description: "Card last 4 digits" }
900
+ }
901
+ }
902
+ },
903
+ example: {
904
+ command: "agenzo-token-cli payment-methods list",
905
+ output_summary: "Returns payment_methods[]. Check for status=ACTIVE before assuming the user has a usable card."
906
+ }
907
+ };
908
+ var pmGetSchema = {
909
+ cli: CLI_NAME,
910
+ noun: PAYMENT_METHODS_NOUN,
911
+ verb: "get",
912
+ description: "Get a payment method by ID",
913
+ flags: {
914
+ pm_id: { type: "string", required: true, description: "Payment method id (positional argument)" }
915
+ },
916
+ response: {
917
+ id: { type: "string", description: "Payment method id" },
918
+ type: { type: "string", description: "Payment method type" },
919
+ status: { type: "string", description: "PENDING | ACTIVE | FAILED | DISABLED | EXPIRED" },
920
+ brand: { type: "string|null", description: "Card brand" },
921
+ first6: { type: "string|null", description: "Card first 6 digits" },
922
+ last4: { type: "string|null", description: "Card last 4 digits" },
923
+ created_at: { type: "string", description: "Creation time" }
924
+ },
925
+ example: {
926
+ command: "agenzo-token-cli payment-methods get pm_01H...",
927
+ output_summary: "Returns the payment method detail including status."
928
+ }
929
+ };
930
+ var pmDisableSchema = {
931
+ cli: CLI_NAME,
932
+ noun: PAYMENT_METHODS_NOUN,
933
+ verb: "disable",
934
+ description: "Disable a payment method",
935
+ flags: {
936
+ pm_id: { type: "string", required: true, description: "Payment method id (positional argument)" },
937
+ "idempotency-key": {
938
+ type: "string",
939
+ required: true,
940
+ description: "Idempotency key forwarded verbatim as the Idempotency-Key header"
941
+ }
942
+ },
943
+ response: {
944
+ status: { type: "string", description: "Status after disabling (typically DISABLED)" },
945
+ revoked_tokens_count: { type: "int", description: "Number of payment tokens revoked as a side effect" }
946
+ },
947
+ example: {
948
+ command: "agenzo-token-cli payment-methods disable pm_01H... --idempotency-key disable-123",
949
+ output_summary: "Disables the card and revokes any payment tokens issued against it. Only use when the user explicitly requests it."
950
+ },
951
+ error_recovery: {
952
+ PARAM_IDEMPOTENCY_KEY_REQUIRED: "Supply --idempotency-key (1-128 chars [A-Za-z0-9_-]); the CLI never generates one under --yes."
953
+ }
954
+ };
955
+ var ptCreateSchema = {
956
+ cli: CLI_NAME,
957
+ noun: PAYMENT_TOKENS_NOUN,
958
+ verb: "create",
959
+ description: "Create a payment token (VCN / Network Token / X402)",
960
+ flags: {
961
+ type: { type: "string", required: true, description: "Token type", constraints: "vcn | network-token | x402" },
962
+ "payment-method-id": { type: "string", required: "conditional", description: "Payment method ID to use (or resolved via --card / auto-select from ACTIVE cards)" },
963
+ card: { type: "string", required: false, description: "Match payment method by last 4 digits" },
964
+ member: { type: "string", required: false, description: "Member ID" },
965
+ amount: { type: "string", required: "conditional", description: "Amount in USD (vcn) or USDC (x402)" },
966
+ currency: { type: "string", required: false, description: "Currency (vcn only; server default applies if omitted)" },
967
+ "pay-to": { type: "string", required: "conditional", description: "Pay-to address (x402 only)" },
968
+ nonce: { type: "string", required: "conditional", description: "Nonce (x402 only)" },
969
+ network: { type: "string", required: "conditional", description: "Network (x402 only)" },
970
+ deadline: { type: "string", required: "conditional", description: "Deadline as a Unix timestamp in seconds (x402 only)" },
971
+ "external-tx-id": { type: "string", required: false, description: "External transaction ID" },
972
+ "idempotency-key": {
973
+ type: "string",
974
+ required: true,
975
+ description: "Idempotency key forwarded verbatim as the Idempotency-Key header"
976
+ }
977
+ },
978
+ response: {
979
+ id: { type: "string", description: "Payment token id" },
980
+ type: { type: "string", description: "vcn | network_token | x402" },
981
+ status: { type: "string", description: "Token status" }
982
+ },
983
+ example: {
984
+ command: "agenzo-token-cli payment-tokens create --type vcn --card 1234 --amount 25.00 --idempotency-key tok-123",
985
+ output_summary: "Creates a token; response shape varies by type (nested under vcn / network_token / x402)."
986
+ },
987
+ error_recovery: {
988
+ TOKEN_FEATURE_DISABLED: "This token type is not enabled yet. Tell the user and suggest an alternative type if applicable.",
989
+ CLIENT_NO_PAYMENT_METHOD: "The user has no ACTIVE payment method. Guide them to add one first (payment-methods add --mode dropin).",
990
+ CLIENT_CARD_NOT_MATCHED: "The --card last-4 did not match any ACTIVE card. Call payment-methods list to see available cards."
991
+ }
992
+ };
993
+ var ptListSchema = {
994
+ cli: CLI_NAME,
995
+ noun: PAYMENT_TOKENS_NOUN,
996
+ verb: "list",
997
+ description: "List payment tokens",
998
+ flags: {
999
+ type: { type: "string", required: false, description: "Filter by token type" },
1000
+ member: { type: "string", required: false, description: "Filter by member ID" }
1001
+ },
1002
+ response: {
1003
+ payment_tokens: {
1004
+ type: "array",
1005
+ description: "Payment tokens for the developer (optionally filtered)",
1006
+ items: {
1007
+ id: { type: "string", description: "Token id" },
1008
+ type: { type: "string", description: "vcn | network_token | x402" },
1009
+ status: { type: "string", description: "Token status" }
1010
+ }
1011
+ }
1012
+ },
1013
+ example: {
1014
+ command: "agenzo-token-cli payment-tokens list --type vcn",
1015
+ output_summary: "Returns payment_tokens[]."
1016
+ }
1017
+ };
1018
+ var ptGetSchema = {
1019
+ cli: CLI_NAME,
1020
+ noun: PAYMENT_TOKENS_NOUN,
1021
+ verb: "get",
1022
+ description: "Get a payment token by ID",
1023
+ flags: {
1024
+ payment_token_id: { type: "string", required: true, description: "Payment token id (positional argument)" },
1025
+ reveal: {
1026
+ type: "bool",
1027
+ required: false,
1028
+ default: false,
1029
+ description: "Reveal full VCN card number and CVC in the output. NEVER pass this or read revealed card data aloud to the user (PCI) unless explicitly required by a payment flow."
1030
+ }
1031
+ },
1032
+ response: {
1033
+ id: { type: "string", description: "Token id" },
1034
+ type: { type: "string", description: "vcn | network_token | x402" },
1035
+ status: { type: "string", description: "Token status" }
1036
+ },
1037
+ example: {
1038
+ command: "agenzo-token-cli payment-tokens get pt_01H...",
1039
+ output_summary: "Returns the token detail. VCN PAN/CVC are masked unless --reveal is set."
1040
+ }
1041
+ };
1042
+ var ptRevokeSchema = {
1043
+ cli: CLI_NAME,
1044
+ noun: PAYMENT_TOKENS_NOUN,
1045
+ verb: "revoke",
1046
+ description: "Revoke a payment token",
1047
+ flags: {
1048
+ payment_token_id: { type: "string", required: true, description: "Payment token id (positional argument)" },
1049
+ "idempotency-key": {
1050
+ type: "string",
1051
+ required: true,
1052
+ description: "Idempotency key forwarded verbatim as the Idempotency-Key header"
1053
+ }
1054
+ },
1055
+ response: {
1056
+ id: { type: "string", description: "Token id" },
1057
+ status: { type: "string", description: "Status after revocation" },
1058
+ revoked_at: { type: "string|absent", description: "Revocation time (immediate revoke)" },
1059
+ expires_at: { type: "string|absent", description: "Expiry time (delayed revoke \u2014 x402 cryptogram auto-expires)" }
1060
+ },
1061
+ example: {
1062
+ command: "agenzo-token-cli payment-tokens revoke pt_01H... --idempotency-key revoke-123",
1063
+ output_summary: "Revokes the token immediately, or schedules a delayed revoke for x402 (status stays ACTIVE until expires_at)."
1064
+ },
1065
+ error_recovery: {
1066
+ PARAM_IDEMPOTENCY_KEY_REQUIRED: "Supply --idempotency-key (1-128 chars [A-Za-z0-9_-]); the CLI never generates one under --yes."
1067
+ }
1068
+ };
1069
+
746
1070
  // src/payment-methods/add.ts
747
1071
  var MANUAL_POLL_INTERVAL_MS = 3e3;
748
1072
  var MANUAL_POLL_TIMEOUT_MS = 15 * 60 * 1e3;
@@ -764,6 +1088,7 @@ function registerAddCommand(parent, deps) {
764
1088
  "--no-poll",
765
1089
  "Dropin mode: mint the session, print it, and exit immediately without polling verification status (for server/SDK-driven flows where the front-end completes the binding)"
766
1090
  );
1091
+ attachSchemaHelp(cmd, pmAddSchema);
767
1092
  cmd.action(async () => {
768
1093
  const opts = cmd.optsWithGlobals();
769
1094
  const format = resolveFormat(opts.format);
@@ -1014,6 +1339,7 @@ function sleep(ms) {
1014
1339
  // src/payment-methods/list.ts
1015
1340
  function registerListCommand(parent, deps) {
1016
1341
  const cmd = parent.command("list").description("List payment methods").option("--api-key <key>", "API Key for authentication").option("--member <member_id>", "Filter by member ID");
1342
+ attachSchemaHelp(cmd, pmListSchema);
1017
1343
  cmd.action(async () => {
1018
1344
  const opts = cmd.optsWithGlobals();
1019
1345
  const format = resolveFormat(opts.format);
@@ -1060,6 +1386,7 @@ function registerListCommand(parent, deps) {
1060
1386
  // src/payment-methods/get.ts
1061
1387
  function registerGetCommand(parent, deps) {
1062
1388
  const cmd = parent.command("get <pm_id>").description("Get a payment method by ID").option("--api-key <key>", "API key for authentication");
1389
+ attachSchemaHelp(cmd, pmGetSchema);
1063
1390
  cmd.action(async (pmId) => {
1064
1391
  const opts = cmd.optsWithGlobals();
1065
1392
  const format = resolveFormat(opts.format);
@@ -1105,6 +1432,7 @@ function registerDisableCommand(parent, deps) {
1105
1432
  "--idempotency-key <key>",
1106
1433
  "Idempotency key forwarded verbatim as the Idempotency-Key header"
1107
1434
  );
1435
+ attachSchemaHelp(cmd, pmDisableSchema);
1108
1436
  cmd.action(async (pmId) => {
1109
1437
  const opts = cmd.optsWithGlobals();
1110
1438
  const format = resolveFormat(opts.format);
@@ -1232,7 +1560,7 @@ function registerDropinStatusCommand(parent, deps) {
1232
1560
 
1233
1561
  // src/payment-tokens/create.ts
1234
1562
  import { confirm, select as select2 } from "@inquirer/prompts";
1235
- var DEFAULT_NT_FEE_CENTS = 500;
1563
+ var DEFAULT_NT_FEE_CENTS = 50;
1236
1564
  var USDC_UNIT = 1e6;
1237
1565
  function mapTokenType(cliType) {
1238
1566
  if (cliType === "network-token") return "network_token";
@@ -1343,6 +1671,7 @@ function registerCreateCommand(parent, deps) {
1343
1671
  "--idempotency-key <key>",
1344
1672
  "Idempotency key forwarded verbatim as the Idempotency-Key header"
1345
1673
  );
1674
+ attachSchemaHelp(cmd, ptCreateSchema);
1346
1675
  cmd.action(async () => {
1347
1676
  const opts = cmd.optsWithGlobals();
1348
1677
  const format = resolveFormat(opts.format);
@@ -1574,6 +1903,7 @@ function getSummary(token) {
1574
1903
  }
1575
1904
  function registerListCommand2(parent, deps) {
1576
1905
  const cmd = parent.command("list").description("List payment tokens").option("--api-key <key>", "API Key for authentication").option("--type <type>", "Filter by token type").option("--member <member_id>", "Filter by member ID");
1906
+ attachSchemaHelp(cmd, ptListSchema);
1577
1907
  cmd.action(async () => {
1578
1908
  const opts = cmd.optsWithGlobals();
1579
1909
  const format = resolveFormat(opts.format);
@@ -1710,6 +2040,7 @@ function formatCentsPlain(cents) {
1710
2040
  }
1711
2041
  function registerGetCommand2(parent, deps) {
1712
2042
  const cmd = parent.command("get <payment_token_id>").description("Get a payment token by ID").option("--api-key <key>", "API key for authentication").option("--reveal", "Reveal full VCN card number and CVC in the output");
2043
+ attachSchemaHelp(cmd, ptGetSchema);
1713
2044
  cmd.action(async (paymentTokenId) => {
1714
2045
  const opts = cmd.optsWithGlobals();
1715
2046
  const format = resolveFormat(opts.format);
@@ -1741,6 +2072,7 @@ function registerRevokeCommand(parent, deps) {
1741
2072
  "--idempotency-key <key>",
1742
2073
  "Idempotency key forwarded verbatim as the Idempotency-Key header"
1743
2074
  );
2075
+ attachSchemaHelp(cmd, ptRevokeSchema);
1744
2076
  cmd.action(async (paymentTokenId) => {
1745
2077
  const opts = cmd.optsWithGlobals();
1746
2078
  const format = resolveFormat(opts.format);
@@ -1851,6 +2183,9 @@ function reportError(error) {
1851
2183
  console.error(
1852
2184
  Formatter.status("error", `[${envelope.error.code_num}] ${envelope.error.message}`)
1853
2185
  );
2186
+ if (envelope.error.upstream) {
2187
+ console.error(` \u21B3 [${envelope.error.upstream.code}] ${envelope.error.upstream.message}`);
2188
+ }
1854
2189
  if (!(error instanceof CliError) && process.argv.includes("--verbose")) {
1855
2190
  console.error(error);
1856
2191
  }