@agenzo/token-cli 0.4.0 → 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 +268 -359
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../../../packages/cli-core/errors/error-catalog.ts","../../../packages/cli-core/errors/errors.ts","../../../packages/cli-core/version/version.ts","../../../packages/cli-core/api-client/client.ts","../../../packages/cli-core/credential-store/credential-store.ts","../../../packages/cli-core/key-store/key-store.ts","../../../packages/cli-core/config/config-manager.ts","../../../packages/cli-core/exit/exit.ts","../../../packages/cli-core/formatter/formatter.ts","../../../packages/cli-core/formatter/output.ts","../../../packages/cli-core/formatter/render-context.ts","../../../packages/cli-core/prompt-engine/prompt-engine.ts","../src/payment-methods/prompts.ts","../src/verb-schema.ts","../src/payment-methods/add.ts","../src/payment-methods/list.ts","../src/payment-methods/get.ts","../src/payment-methods/disable.ts","../src/payment-methods/dropin-create.ts","../src/payment-methods/dropin-status.ts","../src/payment-tokens/create.ts","../src/payment-tokens/list.ts","../src/payment-tokens/get.ts","../src/payment-tokens/revoke.ts"],"sourcesContent":["import { Command } from 'commander';\nimport {\n ApiClient,\n ConfigManager,\n Formatter,\n CliError,\n UserCancelError,\n toErrorEnvelope,\n resolveFormat,\n type OutputFormat,\n exitCodeFor,\n getCurrentVersion,\n} from '@agenzo/cli-core';\n\n// payment-methods commands\nimport { registerAddCommand } from './payment-methods/add.js';\nimport { registerListCommand as registerPmListCommand } from './payment-methods/list.js';\nimport { registerGetCommand as registerPmGetCommand } from './payment-methods/get.js';\nimport { registerDisableCommand as registerPmDisableCommand } from './payment-methods/disable.js';\nimport { registerDropinCreateCommand } from './payment-methods/dropin-create.js';\nimport { registerDropinStatusCommand } from './payment-methods/dropin-status.js';\n\n// payment-tokens commands\nimport { registerCreateCommand } from './payment-tokens/create.js';\nimport { registerListCommand as registerPtListCommand } from './payment-tokens/list.js';\nimport { registerGetCommand as registerPtGetCommand } from './payment-tokens/get.js';\nimport { registerRevokeCommand } from './payment-tokens/revoke.js';\n\n// Holds the parsed program so the top-level error handler can read the\n// resolved `--format` global flag. Assigned inside `main()` once the program\n// is constructed; may be undefined if an error is thrown before then.\nlet programRef: Command | undefined;\n\nasync function main() {\n // Instantiate shared infrastructure. token-cli authenticates per-command via\n // `--api-key` (X-Api-Key); there is no Bearer session / AuthService / keystore.\n const configManager = new ConfigManager(undefined, '/api/token/v1');\n await configManager.ensureDirectories();\n\n const apiBaseUrl = await configManager.getApiBaseUrl();\n const apiClient = new ApiClient({ baseUrl: apiBaseUrl });\n\n // Shared deps object — API Key is supplied per-command, so commands only\n // need the HTTP client.\n const deps = { apiClient };\n\n // Create program\n const program = new Command();\n programRef = program;\n program\n .name('agenzo-token-cli')\n .version(getCurrentVersion())\n .description(\n 'Agenzo token plane: payment methods (add payment method + 3DS) and payment tokens (VCN / Network Token / X402)',\n )\n .option('--verbose', 'Show verbose logs')\n .option('--yes', 'Skip confirmation prompts (for automation/AI Agents)')\n .option(\n '--format <format>',\n 'Output format: json | table (default: table; or set AGENZO_FORMAT)',\n );\n\n // Mirror the resolved global --format into AGENZO_FORMAT before any action\n // runs, so code paths without direct format access can resolve the active\n // format and stay silent in json mode.\n program.hook('preAction', (thisCommand) => {\n const flag = thisCommand.opts().format as string | undefined;\n process.env.AGENZO_FORMAT = resolveFormat(flag);\n });\n\n // payment-methods command group\n const pmCmd = program.command('payment-methods').description('Payment method management');\n registerAddCommand(pmCmd, deps);\n registerPmListCommand(pmCmd, deps);\n registerPmGetCommand(pmCmd, deps);\n registerPmDisableCommand(pmCmd, deps);\n // Drop-in non-blocking commands (programmatic callers; not in SKILL/README).\n registerDropinCreateCommand(pmCmd, deps);\n registerDropinStatusCommand(pmCmd, deps);\n\n // payment-tokens command group\n const ptCmd = program.command('payment-tokens').description('Payment token management');\n registerCreateCommand(ptCmd, deps);\n registerPtListCommand(ptCmd, deps);\n registerPtGetCommand(ptCmd, deps);\n registerRevokeCommand(ptCmd, deps);\n\n // Parse and execute\n await program.parseAsync(process.argv);\n}\n\n/**\n * Resolve the active output format for error reporting. Prefers the parsed\n * global `--format` flag (available on `programRef` once the program is\n * constructed); if an error was thrown before parsing, falls back to\n * `resolveFormat(undefined)` (which consults `AGENZO_FORMAT`, else `table`).\n */\nfunction resolveActiveFormat(): OutputFormat {\n const flag = programRef?.opts().format as string | undefined;\n return resolveFormat(flag);\n}\n\n/**\n * Top-level failure path. Writes the error envelope to stderr in the resolved\n * format and exits with the mapped code (1–5). stdout is left untouched so a\n * partial machine payload is never emitted on failure.\n *\n * - `json`: a single `{ error: { code, code_num, message, request_id? } }` envelope (§8.2).\n * - `table`: `✗ [<code_num>] <message>`.\n */\nfunction reportError(error: unknown): never {\n const envelope = toErrorEnvelope(error);\n const format = resolveActiveFormat();\n\n if (format === 'json') {\n console.error(JSON.stringify(envelope));\n } else {\n console.error(\n Formatter.status('error', `[${envelope.error.code_num}] ${envelope.error.message}`),\n );\n // Unknown (non-CliError) failures keep the --verbose raw-dump affordance.\n if (!(error instanceof CliError) && process.argv.includes('--verbose')) {\n console.error(error);\n }\n }\n\n // exitCodeFor owns the error-class → exit-code matrix, including\n // UpgradeRequiredError → 2 and UserCancelError → 5.\n process.exit(exitCodeFor(error));\n}\n\n// Ctrl+C / SIGINT maps to a user-cancel (exit 5) via the same envelope path.\nprocess.on('SIGINT', () => {\n reportError(new UserCancelError());\n});\n\n// Global error handler. Normal completion exits 0 naturally (the mapper is\n// never consulted on success).\nmain().catch(reportError);\n","/**\n * Unified outward-facing CLI error-code catalog (cli-design §8, single source of truth).\n *\n * Every outward code has both a string code (the preferred routing key) and a\n * numeric code (compact, convenient for log aggregation). The two map 1:1, bound\n * by {@link CODE_NUM}. String codes are grouped by domain prefix; numeric codes\n * are segmented by the same domains (§8.3).\n *\n * Note: `UPGRADE_REQUIRED` (CLI too old) and `CLIENT_ABORTED` (user-initiated\n * cancel) are non-business codes detected locally by the CLI. They are not part\n * of the §8.4 business dictionary and are allocated at the tail of the CLIENT range.\n */\nexport type ErrorCode =\n // AUTH_* (1000-1099)\n | 'AUTH_SESSION_EXPIRED'\n | 'AUTH_MAGIC_LINK_EXPIRED'\n | 'AUTH_INVITE_CODE_REQUIRED'\n | 'AUTH_INVITE_CODE_INVALID'\n // KEY_* (1100-1199)\n | 'KEY_INVALID'\n | 'KEY_SCOPE_DENIED'\n // RESOURCE_* (2000-2099)\n | 'RESOURCE_NOT_FOUND'\n | 'RESOURCE_CONFLICT'\n | 'RESOURCE_STATE_INVALID'\n // PARAM_* (2100-2199)\n | 'PARAM_INVALID'\n | 'PARAM_IDEMPOTENCY_KEY_REQUIRED'\n | 'PARAM_IDEMPOTENCY_KEY_CONFLICT'\n // BILLING_* (3000-3099)\n | 'BILLING_MODE_MISMATCH'\n // ACCOUNT_* (3100-3199)\n | 'ACCOUNT_NOT_FOUND'\n | 'ACCOUNT_SUSPENDED'\n | 'ACCOUNT_INSUFFICIENT_BALANCE'\n // PAYMENT_ORDER_* (3200-3299)\n | 'PAYMENT_ORDER_NOT_FOUND'\n | 'PAYMENT_ORDER_NOT_PAID'\n | 'PAYMENT_ORDER_MISMATCH'\n | 'PAYMENT_ORDER_ALREADY_CONSUMED'\n // TOKEN_* (4000-4099)\n | 'TOKEN_FEATURE_DISABLED'\n // SERVICE_* (4100-4199)\n | 'SERVICE_NOT_FOUND'\n // ride business codes (4200-4299)\n | 'VEHICLE_UNAVAILABLE'\n | 'QUOTE_EXPIRED'\n | 'BOOKING_FAILED'\n | 'CANCELLATION_NOT_ALLOWED'\n // RATE_* (5000-5099)\n | 'RATE_LIMITED'\n // UPSTREAM_* (5100-5199)\n | 'UPSTREAM_ERROR'\n // INTERNAL_* (5200-5299)\n | 'INTERNAL_ERROR'\n // NOT_IMPLEMENTED (5300)\n | 'NOT_IMPLEMENTED'\n // CLIENT_* (9000-9099) — produced locally by the CLI\n | 'CLIENT_NOT_SIGNED_IN'\n | 'CLIENT_LOGIN_TIMEOUT'\n | 'CLIENT_ORG_NOT_LOCAL'\n | 'CLIENT_ORG_WRONG_ENV'\n | 'CLIENT_NO_PAYMENT_METHOD'\n | 'CLIENT_CARD_NOT_MATCHED'\n | 'CLIENT_ABORTED'\n // Non-business code (detected locally by the CLI)\n | 'UPGRADE_REQUIRED';\n\n/**\n * String code → numeric code (§8.4). Each outward code's numeric value is\n * uniquely bound by this table; once published it is append-only (never changed).\n */\nexport const CODE_NUM: Record<ErrorCode, number> = {\n AUTH_SESSION_EXPIRED: 1001,\n AUTH_MAGIC_LINK_EXPIRED: 1002,\n AUTH_INVITE_CODE_REQUIRED: 1003,\n AUTH_INVITE_CODE_INVALID: 1004,\n KEY_INVALID: 1101,\n KEY_SCOPE_DENIED: 1102,\n RESOURCE_NOT_FOUND: 2001,\n RESOURCE_CONFLICT: 2002,\n RESOURCE_STATE_INVALID: 2003,\n PARAM_INVALID: 2101,\n PARAM_IDEMPOTENCY_KEY_REQUIRED: 2102,\n PARAM_IDEMPOTENCY_KEY_CONFLICT: 2103,\n BILLING_MODE_MISMATCH: 3001,\n ACCOUNT_NOT_FOUND: 3101,\n ACCOUNT_SUSPENDED: 3102,\n ACCOUNT_INSUFFICIENT_BALANCE: 3103,\n PAYMENT_ORDER_NOT_FOUND: 3201,\n PAYMENT_ORDER_NOT_PAID: 3202,\n PAYMENT_ORDER_MISMATCH: 3203,\n PAYMENT_ORDER_ALREADY_CONSUMED: 3204,\n TOKEN_FEATURE_DISABLED: 4001,\n SERVICE_NOT_FOUND: 4101,\n VEHICLE_UNAVAILABLE: 4201,\n QUOTE_EXPIRED: 4202,\n BOOKING_FAILED: 4203,\n CANCELLATION_NOT_ALLOWED: 4204,\n RATE_LIMITED: 5001,\n UPSTREAM_ERROR: 5101,\n INTERNAL_ERROR: 5201,\n NOT_IMPLEMENTED: 5300,\n CLIENT_NOT_SIGNED_IN: 9001,\n CLIENT_LOGIN_TIMEOUT: 9002,\n CLIENT_ORG_NOT_LOCAL: 9003,\n CLIENT_ORG_WRONG_ENV: 9004,\n CLIENT_NO_PAYMENT_METHOD: 9005,\n CLIENT_CARD_NOT_MATCHED: 9006,\n CLIENT_ABORTED: 9007,\n UPGRADE_REQUIRED: 9008,\n};\n\n/** Look up the numeric code for a string error code. */\nexport function codeNum(code: ErrorCode): number {\n return CODE_NUM[code];\n}\n","import { type ErrorCode, CODE_NUM, codeNum } from './error-catalog.js';\nimport type { ApiError, UpstreamError } from '../api-client/client.js';\n\n/** Base class for all CLI errors. Carries the CLI-facing error code (§8.4). */\nexport class CliError extends Error {\n constructor(\n public readonly code: ErrorCode,\n message: string,\n public readonly statusCode?: number,\n public readonly requestId?: string,\n public readonly upstream?: UpstreamError,\n ) {\n super(message);\n this.name = 'CliError';\n }\n\n /**\n * Map a backend ApiError to a CLI-facing code (§8.5 transitional mapping).\n * Backend numeric codes / HTTP status are translated to §8.4 string codes;\n * the raw backend message is NOT passed through (§8.1 principle 4) — a\n * stable, fixed message per code is used instead.\n *\n * The optional `opts.auth` selects the auth semantics for the 401 mapping:\n * - `'bearer'` (default, admin-cli Bearer Token): 401 → `AUTH_SESSION_EXPIRED`.\n * - `'api-key'` (token-cli `X-Api-Key`): 401 → `KEY_INVALID`.\n * 403 maps to `KEY_SCOPE_DENIED` under both auth modes. Omitting `opts`\n * preserves the original Bearer behavior exactly (§8.5 / requirement 6.4).\n *\n * Domain string-code routing (D3 / requirement 5.4): when the backend\n * supplies a string `error.code` in the v3 envelope that is a known §8 code\n * (present in {@link CODE_NUM}), it is used verbatim as the CLI-facing code\n * so ride/merchant-specific codes (`QUOTE_EXPIRED`, `VEHICLE_UNAVAILABLE`,\n * `BILLING_MODE_MISMATCH`, `PAYMENT_ORDER_*`, …) survive intact. Otherwise —\n * including when no string code is provided, as is the case for admin/token\n * today — mapping falls back to the HTTP-status table below, leaving the\n * existing Bearer/api-key behavior unchanged.\n */\n static fromApi(error: ApiError, opts?: { auth?: 'bearer' | 'api-key' }): CliError {\n // D3: prefer the backend's string code when it is a known §8 catalog code.\n if (error.code && isKnownErrorCode(error.code)) {\n return new CliError(\n error.code,\n STABLE_MESSAGE[error.code] ?? 'Request failed. Please check your input and retry.',\n error.statusCode,\n error.requestId,\n error.upstream,\n );\n }\n\n const status = error.statusCode;\n let code: ErrorCode;\n\n if (status === 401) code = opts?.auth === 'api-key' ? 'KEY_INVALID' : 'AUTH_SESSION_EXPIRED';\n else if (status === 403) code = 'KEY_SCOPE_DENIED';\n else if (status === 404) code = 'RESOURCE_NOT_FOUND';\n else if (status === 409) code = 'RESOURCE_CONFLICT';\n else if (status === 429) code = 'RATE_LIMITED';\n else if (status >= 500) code = 'INTERNAL_ERROR';\n else code = 'PARAM_INVALID'; // other 4xx (incl. 400/422)\n\n return new CliError(\n code,\n STABLE_MESSAGE[code] ?? 'Request failed. Please check your input and retry.',\n status,\n error.requestId,\n error.upstream,\n );\n }\n}\n\n/** Network / connectivity failure → UPSTREAM_ERROR. Never leak the internal URL/path. */\nexport class NetworkError extends CliError {\n constructor(_url: string, timeout?: number, _cause?: Error) {\n super(\n 'UPSTREAM_ERROR',\n timeout\n ? 'The request timed out. The service may be temporarily unavailable — please retry.'\n : 'Connection failed. The service may be temporarily unavailable — please retry.',\n );\n }\n}\n\n/** Auth / session failures. Code chosen by message intent (§8.4 AUTH_* / CLIENT_*). */\nexport class AuthError extends CliError {\n constructor(message: string, public readonly suggestion: string) {\n const m = message.toLowerCase();\n const code: ErrorCode = m.includes('not signed in')\n ? 'CLIENT_NOT_SIGNED_IN'\n : m.includes('time')\n ? 'CLIENT_LOGIN_TIMEOUT'\n : m.includes('magic link')\n ? 'AUTH_MAGIC_LINK_EXPIRED'\n : 'AUTH_SESSION_EXPIRED';\n super(code, message || 'Unknown error');\n }\n}\n\nexport class ConfigError extends CliError {\n constructor(message: string, public readonly filePath: string) {\n super('INTERNAL_ERROR', message || 'Unknown error');\n }\n}\n\nexport class ValidationError extends CliError {\n constructor(message: string) {\n super('PARAM_INVALID', message || 'Unknown error');\n }\n}\n\nexport class IdempotencyKeyRequiredError extends CliError {\n constructor(commandPath: string) {\n super(\n 'PARAM_IDEMPOTENCY_KEY_REQUIRED',\n `\\`${commandPath}\\` requires --idempotency-key <key>. Supply a unique key so the write can be safely retried.`,\n );\n }\n}\n\nexport class UpgradeRequiredError extends CliError {\n constructor(currentVersion: string, minVersion: string, upgradeCommand: string) {\n super(\n 'UPGRADE_REQUIRED',\n `agenzo-admin-cli ${currentVersion} is out of date — the server requires ${minVersion} or newer. To upgrade, run: ${upgradeCommand}`,\n );\n }\n}\n\nexport class UserCancelError extends CliError {\n constructor(message = 'Operation cancelled by user') {\n super('CLIENT_ABORTED', message || 'Unknown error');\n }\n}\n\n/** Type guard: is `value` a known §8 string error code (present in CODE_NUM)? */\nfunction isKnownErrorCode(value: string): value is ErrorCode {\n return Object.prototype.hasOwnProperty.call(CODE_NUM, value);\n}\n\n/**\n * Stable, CLI-owned message per code used when mapping opaque backend errors\n * (§8.1 principle 4: never surface raw backend detail).\n */\nconst STABLE_MESSAGE: Partial<Record<ErrorCode, string>> = {\n AUTH_SESSION_EXPIRED: 'Your session has expired. Please run `agenzo-admin-cli auth login` again.',\n AUTH_MAGIC_LINK_EXPIRED: 'Verification link is invalid or has expired. Please request a new one.',\n AUTH_INVITE_CODE_REQUIRED: 'An invitation code is required to register.',\n AUTH_INVITE_CODE_INVALID: 'The invitation code is invalid.',\n KEY_INVALID: 'The API key is invalid or has been revoked. Please check your --api-key and retry.',\n KEY_SCOPE_DENIED: 'This API key does not have the required scope for this command.',\n RESOURCE_NOT_FOUND: 'The resource was not found or does not belong to the current organization.',\n RESOURCE_CONFLICT: 'A resource with the same unique value already exists.',\n RESOURCE_STATE_INVALID: 'The resource is in a state that does not permit this operation.',\n RATE_LIMITED: 'Too many requests. Please back off and retry.',\n UPSTREAM_ERROR: 'A third-party service is temporarily unavailable. Please try again later.',\n INTERNAL_ERROR: 'Something went wrong on the server. Please retry and note the request_id.',\n PARAM_INVALID: 'One or more parameters are invalid. Please check your input and retry.',\n PARAM_IDEMPOTENCY_KEY_CONFLICT: 'A request with this idempotency key was already processed with different parameters.',\n TOKEN_FEATURE_DISABLED: 'VCN creation is not supported yet. Coming soon.',\n BILLING_MODE_MISMATCH: 'The billing mode does not match this operation. Please verify your account billing configuration.',\n ACCOUNT_NOT_FOUND: 'The settlement account was not found.',\n ACCOUNT_SUSPENDED: 'The settlement account is suspended. Please contact support.',\n ACCOUNT_INSUFFICIENT_BALANCE: 'The settlement account has insufficient balance for this operation.',\n PAYMENT_ORDER_NOT_FOUND: 'The payment order was not found.',\n PAYMENT_ORDER_NOT_PAID: 'The payment order has not been paid. Please complete payment and retry.',\n PAYMENT_ORDER_MISMATCH: 'The payment order does not match this order. Please check the --payment-order-id.',\n PAYMENT_ORDER_ALREADY_CONSUMED: 'The payment order has already been consumed by another booking.',\n SERVICE_NOT_FOUND: 'The requested service was not found.',\n VEHICLE_UNAVAILABLE: 'No vehicle is available for the requested trip. Please try a different time or class.',\n QUOTE_EXPIRED: 'The quote has expired. Please request a new quote and retry.',\n BOOKING_FAILED: 'The booking could not be completed. Please retry.',\n CANCELLATION_NOT_ALLOWED: 'This order cannot be cancelled in its current state.',\n NOT_IMPLEMENTED: 'This operation is not implemented yet.',\n};\n\n/** §8.2 error envelope: `{ error: { code, code_num, message, request_id?, upstream? } }`. */\nexport interface ErrorEnvelope {\n error: {\n code: ErrorCode;\n code_num: number;\n message: string;\n request_id?: string;\n upstream?: UpstreamError;\n };\n}\n\nexport function toErrorEnvelope(error: unknown): ErrorEnvelope {\n if (error instanceof CliError) {\n return {\n error: {\n code: error.code,\n code_num: codeNum(error.code),\n message: error.message || 'Unknown error',\n ...(error.requestId ? { request_id: error.requestId } : {}),\n ...(error.upstream ? { upstream: error.upstream } : {}),\n },\n };\n }\n\n const message =\n error instanceof Error\n ? error.message\n : typeof error === 'string'\n ? error\n : 'Unexpected error';\n return {\n error: {\n code: 'INTERNAL_ERROR',\n code_num: codeNum('INTERNAL_ERROR'),\n message: message || 'Unknown error',\n },\n };\n}\n","/**\n * CLI version + min-version comparator.\n *\n * The CLI's current version is read from `package.json` at runtime. This is\n * the single source of truth — bumping `package.json` automatically updates\n * what the CLI reports and what it compares against the server-advertised\n * minimum (`X-CLI-Min-Version` response header, driven by\n * `AGENT_PAY_CLI_MIN_VERSION` on the server).\n *\n * Only numeric major.minor.patch segments are compared; pre-release and build\n * metadata suffixes are stripped. This matches our versioning scheme and\n * avoids pulling in `semver` for a single `<` check.\n */\n\nimport { readFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\n/** Command the user should run to pick up the latest CLI. */\nexport const UPGRADE_COMMAND = 'npm install -g agenzo-admin-cli@latest';\n\n/**\n * Hard-coded fallback used only when `package.json` cannot be read at runtime\n * (unusual packaging/bundling edge cases). Keep this in sync with\n * `package.json`'s `version` on every release so the reported version and\n * the User-Agent stay accurate even in the degraded path.\n */\nexport const FALLBACK_VERSION = '0.1.1';\n\nlet cachedVersion: string | null = null;\n\nexport function getCurrentVersion(): string {\n if (cachedVersion !== null) return cachedVersion;\n // Walk up from the compiled file (dist/index.js) or source layout to find\n // package.json. Both `dist/..` and `src/utils/../..` resolve to the project\n // root, which is where package.json lives in a published npm install.\n const here = dirname(fileURLToPath(import.meta.url));\n const candidates = [\n join(here, '..', 'package.json'), // dist/ → project root\n join(here, '..', '..', 'package.json'), // src/utils/ → project root\n ];\n for (const p of candidates) {\n try {\n const pkg = JSON.parse(readFileSync(p, 'utf-8')) as { version?: string };\n if (typeof pkg.version === 'string') {\n cachedVersion = pkg.version;\n return cachedVersion;\n }\n } catch {\n // try next candidate\n }\n }\n // Degrade gracefully instead of crashing the CLI: if we can't locate\n // package.json at runtime, report the hard-coded fallback. The User-Agent\n // and any min-version comparison will still behave sensibly. We write a\n // one-line warning to stderr so packaging regressions remain visible.\n cachedVersion = FALLBACK_VERSION;\n // eslint-disable-next-line no-console\n console.warn(\n `[agenzo-admin-cli] package.json not found; using fallback version ${FALLBACK_VERSION}`,\n );\n return cachedVersion;\n}\n\n/**\n * Returns negative / zero / positive like `Array.sort`, comparing `a` against `b`.\n * Non-numeric segments and suffixes are treated as zero.\n */\nexport function compareVersions(a: string, b: string): number {\n const parse = (v: string): [number, number, number] => {\n const clean = v.trim().replace(/^v/, '').split(/[-+]/)[0];\n const parts = clean.split('.');\n return [\n parseInt(parts[0] ?? '0', 10) || 0,\n parseInt(parts[1] ?? '0', 10) || 0,\n parseInt(parts[2] ?? '0', 10) || 0,\n ];\n };\n const [a1, a2, a3] = parse(a);\n const [b1, b2, b3] = parse(b);\n if (a1 !== b1) return a1 - b1;\n if (a2 !== b2) return a2 - b2;\n return a3 - b3;\n}\n\nexport function isBelow(current: string, minimum: string): boolean {\n return compareVersions(current, minimum) < 0;\n}\n","import { NetworkError, UpgradeRequiredError } from '../errors/errors.js';\nimport { getCurrentVersion, isBelow, UPGRADE_COMMAND } from '../version/version.js';\n\nexport interface ApiClientConfig {\n baseUrl: string;\n timeout?: number; // Default 30000ms\n}\n\nexport interface ApiResponse<T> {\n success: true;\n data: T;\n /** Server-provided message from the unified response envelope. */\n message?: string;\n}\n\n/** Upstream error details (diagnostic only, not stable). */\nexport interface UpstreamError {\n /** Upstream-specific error code (stringified). */\n code: string;\n /** Upstream-specific error message. */\n message: string;\n}\n\nexport interface ApiError {\n success: false;\n errorCode: number;\n errorMessage: string;\n statusCode: number;\n /**\n * Raw string code from the v3 response envelope (`{ code, message, data }`),\n * surfaced verbatim so {@link CliError.fromApi} can route domain-specific\n * §8 codes (e.g. `QUOTE_EXPIRED`, `VEHICLE_UNAVAILABLE`) by string code\n * before falling back to HTTP-status mapping. Absent when the backend does\n * not provide a string code (e.g. non-JSON error responses).\n */\n code?: string;\n /** Server-provided request correlation id, surfaced in the error envelope. */\n requestId?: string;\n /** Upstream error details for diagnostic transparency. */\n upstream?: UpstreamError;\n}\n\nexport type ApiResult<T> = ApiResponse<T> | ApiError;\n\nexport type AuthMode =\n | { type: 'bearer'; token: string }\n | { type: 'api-key'; key: string }\n | { type: 'none' };\n\nexport class ApiClient {\n private readonly baseUrl: string;\n private readonly timeout: number;\n\n constructor(config: ApiClientConfig) {\n this.baseUrl = config.baseUrl.replace(/\\/+$/, '');\n this.timeout = config.timeout ?? 60000;\n }\n\n private buildHeaders(auth: AuthMode): Record<string, string> {\n const headers: Record<string, string> = {\n 'User-Agent': `agenzo-admin-cli/${getCurrentVersion()}`,\n };\n if (auth.type === 'bearer') {\n headers['Authorization'] = `Bearer ${auth.token}`;\n } else if (auth.type === 'api-key') {\n headers['X-Api-Key'] = auth.key;\n }\n return headers;\n }\n\n async get<T>(\n path: string,\n auth: AuthMode,\n params?: Record<string, string>,\n ): Promise<ApiResult<T>> {\n let url = `${this.baseUrl}${path}`;\n if (params && Object.keys(params).length > 0) {\n const searchParams = new URLSearchParams(params);\n url += `?${searchParams.toString()}`;\n }\n return this.request<T>(url, {\n method: 'GET',\n headers: this.buildHeaders(auth),\n });\n }\n\n async post<T>(\n path: string,\n auth: AuthMode,\n body?: Record<string, unknown>,\n extraHeaders?: Record<string, string>,\n ): Promise<ApiResult<T>> {\n const url = `${this.baseUrl}${path}`;\n const headers = this.buildHeaders(auth);\n headers['Content-Type'] = 'application/json';\n if (extraHeaders) {\n Object.assign(headers, extraHeaders);\n }\n return this.request<T>(url, {\n method: 'POST',\n headers,\n body: body ? JSON.stringify(body) : undefined,\n });\n }\n\n private async request<T>(url: string, init: RequestInit): Promise<ApiResult<T>> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(url, {\n ...init,\n signal: controller.signal,\n });\n\n // Enforce server-advertised CLI version floor before doing any work\n // on the response. Throws UpgradeRequiredError which is rendered and\n // exits at the top level (src/index.ts).\n this.enforceMinVersion(response.headers.get('x-cli-min-version'));\n\n // Handle non-JSON responses (e.g. 500 Internal Server Error returns plain text)\n const contentType = response.headers.get('content-type') ?? '';\n let responseBody: Record<string, unknown>;\n if (contentType.includes('application/json')) {\n responseBody = await response.json() as Record<string, unknown>;\n } else {\n const text = await response.text();\n if (!response.ok) {\n const statusMsg = this.friendlyStatusMessage(response.status);\n return {\n success: false,\n errorCode: 0,\n errorMessage: statusMsg,\n statusCode: response.status,\n };\n }\n // Try parsing as JSON anyway (some servers don't set content-type)\n try {\n responseBody = JSON.parse(text) as Record<string, unknown>;\n } catch {\n return {\n success: false,\n errorCode: 0,\n errorMessage: `Unexpected response from server (${response.status})`,\n statusCode: response.status,\n };\n }\n }\n\n // Server uses unified format: { code: \"0000\", message: \"...\", data: {...} }\n const code = responseBody.code as string | undefined;\n const message = responseBody.message as string | undefined;\n\n // Success: HTTP 2xx AND code is \"0000\" (or no code field for raw responses)\n if (response.ok && (!code || code === '0000')) {\n // If the server wraps the payload in a \"data\" field, unwrap it —\n // including when `data` is explicitly null (a valid empty payload,\n // e.g. GET /accounts for a developer without a settlement account).\n // We must distinguish \"no data field\" (raw response → use the whole\n // body) from \"data field present but null\" (→ return null), since\n // `data ?? responseBody` would wrongly fall back to the envelope and\n // surface { code, message, data: null } as the payload.\n const hasDataField = Object.prototype.hasOwnProperty.call(responseBody, 'data');\n const payload = hasDataField ? responseBody.data : responseBody;\n return { success: true, data: payload as T, message };\n }\n\n // Error: either HTTP non-2xx or code !== \"0000\"\n const errorCode = code ? parseInt(code, 10) : 0;\n // Handle FastAPI 422 validation errors where detail is an array\n let errorMsg = message ?? response.statusText;\n if (!errorMsg || errorMsg === response.statusText) {\n const detail = responseBody.detail;\n if (Array.isArray(detail)) {\n errorMsg = detail.map((d: Record<string, unknown>) => {\n const loc = (d.loc as string[])?.slice(1).join('.') ?? '';\n return loc ? `${loc}: ${d.msg}` : String(d.msg);\n }).join('; ');\n } else if (typeof detail === 'string') {\n errorMsg = detail;\n }\n }\n\n // Prefer string error_code (CLI D3 routing) over numeric code string\n const errorCodeStr = responseBody.error_code as string | undefined;\n\n // Extract upstream error details from data.upstream\n const rawData = responseBody.data as Record<string, unknown> | undefined;\n const upstream = (rawData?.upstream && typeof rawData.upstream === 'object')\n ? rawData.upstream as UpstreamError\n : undefined;\n\n return {\n success: false,\n errorCode: isNaN(errorCode) ? 0 : errorCode,\n errorMessage: errorMsg,\n statusCode: response.status,\n ...(errorCodeStr ? { code: errorCodeStr } : (typeof code === 'string' && code ? { code } : {})),\n requestId: (responseBody.request_id ?? responseBody.requestId) as string | undefined,\n ...(upstream ? { upstream } : {}),\n };\n } catch (error) {\n // UpgradeRequiredError is a CliError and must propagate untouched to the\n // top-level handler; don't rewrap it as a NetworkError.\n if (error instanceof UpgradeRequiredError) {\n throw error;\n }\n if (error instanceof DOMException && error.name === 'AbortError') {\n throw new NetworkError(url, this.timeout);\n }\n throw new NetworkError(url, undefined, error instanceof Error ? error : undefined);\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n /**\n * Validate that the running CLI meets the server-advertised minimum.\n * Missing or empty header → skip (backward compat with servers that don't\n * advertise yet, and clients hitting legacy proxies).\n */\n private enforceMinVersion(headerValue: string | null): void {\n const minVersion = headerValue?.trim();\n if (!minVersion) return;\n const current = getCurrentVersion();\n if (isBelow(current, minVersion)) {\n throw new UpgradeRequiredError(current, minVersion, UPGRADE_COMMAND);\n }\n }\n\n private friendlyStatusMessage(status: number): string {\n const messages: Record<number, string> = {\n 400: 'Invalid request. Please check your input.',\n 401: 'Authentication failed. Please check your API key or login again.',\n 403: 'Access denied. You do not have permission for this operation.',\n 404: 'Resource not found. Please check the ID.',\n 409: 'Conflict. This resource may already exist.',\n 422: 'Invalid input. Please check the request parameters.',\n 429: 'Too many requests. Please wait and try again.',\n 500: 'Something went wrong on the server. Please try again later.',\n 502: 'Service is temporarily unavailable. Please try again in a moment.',\n 503: 'Service is temporarily unavailable. Please try again in a moment.',\n 504: 'The request took too long. Please try again.',\n };\n return messages[status] ?? `Something went wrong (${status}). Please try again later.`;\n }\n}\n","import { readFile, writeFile, readdir, unlink, access, mkdir, chmod } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { homedir } from 'node:os';\nimport { OrgCredential } from '../types/config.js';\n\nexport class CredentialStore {\n private readonly basePath: string;\n\n constructor(basePath?: string) {\n this.basePath = basePath ?? join(homedir(), '.agenzo-admin-cli', 'credentials');\n }\n\n private filePath(orgId: string): string {\n return join(this.basePath, `${orgId}.json`);\n }\n\n private async ensureDir(): Promise<void> {\n // Credentials hold long-lived Bearer tokens — dir must be owner-only (0700).\n // mkdir mode is subject to umask, so chmod afterwards to enforce it on\n // both freshly created and pre-existing directories.\n await mkdir(this.basePath, { recursive: true, mode: 0o700 });\n await chmod(this.basePath, 0o700);\n }\n\n async get(orgId: string): Promise<OrgCredential | null> {\n try {\n const content = await readFile(this.filePath(orgId), 'utf-8');\n return JSON.parse(content) as OrgCredential;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return null;\n }\n throw error;\n }\n }\n\n async save(credential: OrgCredential): Promise<void> {\n await this.ensureDir();\n const path = this.filePath(credential.org_id);\n // Owner read/write only (0600); chmod after write so pre-existing files\n // created before this safeguard also get tightened.\n await writeFile(path, JSON.stringify(credential, null, 2), {\n encoding: 'utf-8',\n mode: 0o600,\n });\n await chmod(path, 0o600);\n }\n\n async delete(orgId: string): Promise<void> {\n try {\n await unlink(this.filePath(orgId));\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return;\n }\n throw error;\n }\n }\n\n async listAll(): Promise<OrgCredential[]> {\n try {\n const files = await readdir(this.basePath);\n const jsonFiles = files.filter((f) => f.endsWith('.json'));\n const credentials: OrgCredential[] = [];\n for (const file of jsonFiles) {\n try {\n const content = await readFile(join(this.basePath, file), 'utf-8');\n credentials.push(JSON.parse(content) as OrgCredential);\n } catch {\n // Skip corrupted files\n }\n }\n return credentials;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return [];\n }\n throw error;\n }\n }\n\n async exists(orgId: string): Promise<boolean> {\n try {\n await access(this.filePath(orgId));\n return true;\n } catch {\n return false;\n }\n }\n}\n","import { readFile, writeFile, mkdir, chmod } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport { homedir } from 'node:os';\nimport { StoredApiKey } from '../types/config.js';\n\nexport class KeyStore {\n private readonly basePath: string;\n\n constructor(basePath?: string) {\n // API keys are shared across runtime-plane CLIs (token/merchant/payment).\n // Stored under the legacy path for backward compatibility; will migrate to\n // ~/.agenzo/keys/ in a future release.\n this.basePath = basePath ?? join(homedir(), '.agenzo-token-cli', 'api-keys');\n }\n\n private filePath(orgId: string): string {\n return join(this.basePath, `${orgId}.json`);\n }\n\n private async loadData(orgId: string): Promise<StoredApiKey[]> {\n try {\n const content = await readFile(this.filePath(orgId), 'utf-8');\n return JSON.parse(content) as StoredApiKey[];\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return [];\n }\n throw error;\n }\n }\n\n private async saveData(orgId: string, data: StoredApiKey[]): Promise<void> {\n // Stored API keys are plaintext secrets — dir 0700, file 0600.\n await mkdir(this.basePath, { recursive: true, mode: 0o700 });\n await chmod(this.basePath, 0o700);\n const path = this.filePath(orgId);\n await writeFile(path, JSON.stringify(data, null, 2), {\n encoding: 'utf-8',\n mode: 0o600,\n });\n await chmod(path, 0o600);\n }\n\n async add(orgId: string, key: StoredApiKey): Promise<void> {\n const data = await this.loadData(orgId);\n data.push(key);\n await this.saveData(orgId, data);\n }\n\n async update(orgId: string, keyId: string, newKeyValue: string): Promise<void> {\n const data = await this.loadData(orgId);\n const key = data.find((k) => k.key_id === keyId);\n if (key) {\n key.key_value = newKeyValue;\n await this.saveData(orgId, data);\n }\n }\n\n async list(orgId: string): Promise<StoredApiKey[]> {\n return this.loadData(orgId);\n }\n\n async get(orgId: string, keyId: string): Promise<StoredApiKey | null> {\n const data = await this.loadData(orgId);\n return data.find((k) => k.key_id === keyId) ?? null;\n }\n}\n","import { readFile, writeFile, mkdir, chmod } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { homedir } from 'node:os';\nimport { AppConfig } from '../types/config.js';\nimport { ConfigError, ValidationError } from '../errors/errors.js';\n\n// §6 target routing: each product line is served under its own prefix\n// (/api/{line}/v1). The prefix is a per-binary constant injected into\n// ConfigManager (see constructor `apiPath`), NOT a single shared value — the\n// four CLIs hit different product lines under one shared api_host.\n// This default is the admin control-plane prefix; other CLIs override it.\nconst DEFAULT_API_PATH = '/api/admin/v1';\n\nconst DEFAULT_CONFIG: AppConfig = {\n active_org: null,\n active_developer_id: null,\n api_host: 'https://agent.everonet.com',\n api_path: DEFAULT_API_PATH,\n};\n\nexport const BUILTIN_PROFILES: Record<string, string> = {\n production: 'https://agent.everonet.com',\n testing: 'https://agent-test.everonet.com',\n};\n\n/**\n * Resolve a user-supplied host argument (a built-in profile name or an\n * explicit URL) to the concrete API host URL that gets persisted.\n * Pure (no I/O) so callers can compute the resolved value before/without a\n * config write — e.g. `config set-host` needs it to match stored credentials\n * by their resolved `api_host` rather than the raw profile name.\n * Throws `ValidationError` for unknown profiles / malformed URLs.\n */\nexport function resolveApiHost(host: string): string {\n if (BUILTIN_PROFILES[host]) {\n return BUILTIN_PROFILES[host];\n }\n\n let url: URL;\n try {\n url = new URL(host);\n } catch {\n throw new ValidationError(`Unknown profile or invalid URL: ${host}`);\n }\n\n if (url.protocol === 'https:') {\n return host;\n }\n\n if (\n url.protocol === 'http:'\n && (url.hostname === 'localhost' || url.hostname === '127.0.0.1')\n ) {\n return host;\n }\n\n // Allow HTTP for Docker internal container-to-container traffic (gated by env var)\n if (url.protocol === 'http:' && process.env.AGENZO_ALLOW_INSECURE_HOST === '1') {\n return host;\n }\n\n throw new ValidationError(\n `Insecure API host is not allowed: ${host}. Use HTTPS, except for localhost or 127.0.0.1.`,\n );\n}\n\nexport class ConfigManager {\n private readonly basePath: string;\n private readonly configPath: string;\n /**\n * Product-line API prefix this CLI targets (e.g. /api/admin/v1,\n * /api/token/v1). Injected per binary so the four CLIs share one api_host\n * but route to different product lines. Overrides any persisted api_path.\n */\n private readonly apiPath: string;\n\n constructor(basePath?: string, apiPath?: string) {\n this.basePath = basePath ?? join(homedir(), '.agenzo-admin-cli');\n this.configPath = join(this.basePath, 'config.json');\n this.apiPath = apiPath ?? DEFAULT_API_PATH;\n }\n\n /** The resolved product-line API prefix for this CLI (per-binary constant). */\n getApiPath(): string {\n return this.apiPath;\n }\n\n async ensureDirectories(): Promise<void> {\n // Base dir contains the credentials/ subtree → owner-only (0700).\n await mkdir(this.basePath, { recursive: true, mode: 0o700 });\n await chmod(this.basePath, 0o700);\n const credDir = join(this.basePath, 'credentials');\n await mkdir(credDir, { recursive: true, mode: 0o700 });\n await chmod(credDir, 0o700);\n }\n\n async load(): Promise<AppConfig> {\n try {\n const content = await readFile(this.configPath, 'utf-8');\n try {\n const raw = JSON.parse(content) as Record<string, unknown>;\n // Migrate old api_base_url format\n if (raw.api_base_url && !raw.api_host) {\n const url = String(raw.api_base_url);\n const pathIndex = url.indexOf('/api/');\n raw.api_host = pathIndex > 0 ? url.slice(0, pathIndex) : url;\n raw.api_path = pathIndex > 0 ? url.slice(pathIndex) : DEFAULT_CONFIG.api_path;\n delete raw.api_base_url;\n }\n return {\n active_org: (raw.active_org as string) ?? null,\n active_developer_id: (raw.active_developer_id as string) ?? null,\n api_host: (raw.api_host as string) ?? DEFAULT_CONFIG.api_host,\n api_path: (raw.api_path as string) ?? DEFAULT_CONFIG.api_path,\n };\n } catch {\n throw new ConfigError(\n `Invalid config file: ${this.configPath}`,\n this.configPath,\n );\n }\n } catch (error) {\n if (error instanceof ConfigError) throw error;\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return { ...DEFAULT_CONFIG };\n }\n throw error;\n }\n }\n\n async save(config: AppConfig): Promise<void> {\n await this.ensureDirectories();\n await writeFile(this.configPath, JSON.stringify(config, null, 2), {\n encoding: 'utf-8',\n mode: 0o600,\n });\n await chmod(this.configPath, 0o600);\n }\n\n async getActiveOrg(): Promise<string | null> {\n const config = await this.load();\n return config.active_org;\n }\n\n async setActiveOrg(orgId: string): Promise<void> {\n const config = await this.load();\n config.active_org = orgId;\n await this.save(config);\n }\n\n async getApiBaseUrl(): Promise<string> {\n const config = await this.load();\n const host = resolveApiHost(config.api_host).replace(/\\/+$/, '');\n // Use the per-binary product-line prefix, not the persisted api_path —\n // the latter is shared across all CLIs and would route every binary to the\n // same product line. The injected prefix overrides any stale stored value.\n const path = this.apiPath.startsWith('/') ? this.apiPath : `/${this.apiPath}`;\n return `${host}${path}`;\n }\n\n async setApiHost(host: string): Promise<void> {\n const config = await this.load();\n config.api_host = resolveApiHost(host);\n await this.save(config);\n }\n\n async getApiHost(): Promise<string> {\n const config = await this.load();\n return resolveApiHost(config.api_host);\n }\n}\n","import { CliError } from '../errors/errors.js';\n\n/**\n * Exit-code mapper (cli-design §8.6 / cli-standard §5.4).\n *\n * Maps any thrown error reaching the top-level handler to one of the CLI's\n * non-zero exit codes. Normal completion implies `0` and never consults this.\n *\n * 1 — business / param: PARAM_* / RESOURCE_* / BILLING_* / ACCOUNT_* /\n * PAYMENT_ORDER_* / TOKEN_* / SERVICE_* / ride codes / CLIENT_* /\n * NOT_IMPLEMENTED, and unknown errors\n * 2 — upgrade required: UPGRADE_REQUIRED\n * 3 — auth-fail / invalid-key: AUTH_* / KEY_*\n * 4 — network / 5xx: UPSTREAM_ERROR / INTERNAL_ERROR / RATE_LIMITED\n * 5 — user-cancel: CLIENT_ABORTED\n */\nexport function exitCodeFor(error: unknown): 1 | 2 | 3 | 4 | 5 {\n if (!(error instanceof CliError)) {\n return 1;\n }\n\n const code = error.code;\n\n if (code === 'UPGRADE_REQUIRED') {\n return 2;\n }\n\n if (code === 'CLIENT_ABORTED') {\n return 5;\n }\n\n if (code.startsWith('AUTH_') || code.startsWith('KEY_')) {\n return 3;\n }\n\n if (\n code === 'UPSTREAM_ERROR' ||\n code === 'INTERNAL_ERROR' ||\n code === 'RATE_LIMITED'\n ) {\n return 4;\n }\n\n return 1;\n}\n","export type StatusPrefix = 'success' | 'error' | 'info' | 'warning' | 'loading';\n\nconst STATUS_ICONS: Record<StatusPrefix, string> = {\n success: '✓',\n error: '✗',\n info: 'ℹ',\n warning: '⚠',\n loading: '⠋',\n};\n\nconst SPINNER_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];\n\nexport interface Spinner {\n /** Update the spinner message while it's running */\n update(message: string): void;\n /** Stop the spinner and show a final status line */\n stop(type?: StatusPrefix, finalMessage?: string): void;\n}\n\n/**\n * Creates an animated terminal spinner that cycles through braille frames.\n * Call `spinner.stop()` when the async work is done.\n */\nexport function createSpinner(message: string, intervalMs = 60): Spinner {\n let frameIdx = 0;\n let currentMessage = message;\n\n const render = () => {\n process.stdout.write(`\\r\\x1b[K${SPINNER_FRAMES[frameIdx]} ${currentMessage}`);\n frameIdx = (frameIdx + 1) % SPINNER_FRAMES.length;\n };\n\n render();\n const timer = setInterval(render, intervalMs);\n\n return {\n update(msg: string) {\n currentMessage = msg;\n },\n stop(type?: StatusPrefix, finalMessage?: string) {\n clearInterval(timer);\n process.stdout.write('\\r\\x1b[K');\n if (type && finalMessage) {\n console.log(Formatter.status(type, finalMessage));\n }\n },\n };\n}\n\nexport class Formatter {\n /** Get display width of a string (CJK characters count as 2) */\n private static displayWidth(str: string): number {\n let width = 0;\n for (const char of str) {\n const code = char.codePointAt(0)!;\n // CJK Unified Ideographs and common fullwidth ranges\n if (\n (code >= 0x4e00 && code <= 0x9fff) || // CJK Unified\n (code >= 0x3000 && code <= 0x303f) || // CJK Punctuation\n (code >= 0x3400 && code <= 0x4dbf) || // CJK Extension A\n (code >= 0xff00 && code <= 0xffef) || // Fullwidth Forms\n (code >= 0xf900 && code <= 0xfaff) || // CJK Compatibility\n (code >= 0x20000 && code <= 0x2a6df) // CJK Extension B\n ) {\n width += 2;\n } else {\n width += 1;\n }\n }\n return width;\n }\n\n /** Pad string to target display width (right-pad with spaces) */\n private static padEndDisplay(str: string, targetWidth: number): string {\n const currentWidth = Formatter.displayWidth(str);\n const padding = Math.max(0, targetWidth - currentWidth);\n return str + ' '.repeat(padding);\n }\n\n /** Pad string to target display width (left-pad with spaces) */\n private static padStartDisplay(str: string, targetWidth: number): string {\n const currentWidth = Formatter.displayWidth(str);\n const padding = Math.max(0, targetWidth - currentWidth);\n return ' '.repeat(padding) + str;\n }\n\n /** Table output for list commands — columns aligned by max width */\n static table(headers: string[], rows: string[][]): string {\n const colWidths = headers.map((h, i) => {\n const cellWidths = rows.map((r) => Formatter.displayWidth(r[i] ?? ''));\n return Math.max(Formatter.displayWidth(h), ...cellWidths);\n });\n\n const sep = ' ';\n\n const headerLine = headers.map((h, i) => Formatter.padEndDisplay(h, colWidths[i])).join(sep);\n const divider = colWidths.map((w) => '-'.repeat(w)).join(sep);\n const dataLines = rows.map((row) =>\n row.map((cell, i) => Formatter.padEndDisplay(cell ?? '', colWidths[i])).join(sep),\n );\n\n return [headerLine, divider, ...dataLines].join('\\n');\n }\n\n /** Key-value output for detail commands — keys left-aligned */\n static keyValue(entries: [string, string][]): string {\n const maxKeyWidth = Math.max(...entries.map(([k]) => Formatter.displayWidth(k)));\n return entries\n .map(([key, value]) => `${Formatter.padEndDisplay(key, maxKeyWidth)} ${value}`)\n .join('\\n');\n }\n\n /** Status-prefixed message */\n static status(type: StatusPrefix, message: string): string {\n return `${STATUS_ICONS[type]} ${message}`;\n }\n\n /** Mask sensitive info, keeping only the prefix */\n static maskKey(key: string, prefixLength = 8): string {\n if (key.length <= prefixLength) {\n return key;\n }\n return key.slice(0, prefixLength) + '*'.repeat(key.length - prefixLength);\n }\n\n /**\n * Format ISO 8601 timestamp to local timezone display.\n * Automatically uses the user's system timezone.\n * e.g. \"2026-05-07T03:24:53+00:00\" → \"2026-05-07 11:24:53\" (in CST)\n * \"2026-05-07T03:24:53+00:00\" → \"2026-05-06 20:24:53\" (in PDT)\n * Returns the original string if parsing fails or input is empty.\n */\n static formatTime(iso: string | null | undefined): string {\n if (!iso) return '';\n const date = new Date(iso);\n if (isNaN(date.getTime())) return iso;\n const pad = (n: number) => String(n).padStart(2, '0');\n const y = date.getFullYear();\n const m = pad(date.getMonth() + 1);\n const d = pad(date.getDate());\n const h = pad(date.getHours());\n const min = pad(date.getMinutes());\n const s = pad(date.getSeconds());\n const offsetMin = -date.getTimezoneOffset();\n const sign = offsetMin >= 0 ? '+' : '-';\n const absOffset = Math.abs(offsetMin);\n const tzH = pad(Math.floor(absOffset / 60));\n const tzM = pad(absOffset % 60);\n return `${y}-${m}-${d} ${h}:${min}:${s} (UTC${sign}${tzH}:${tzM})`;\n }\n}\n","import type { CommandResult } from '../types/commands.js';\nimport { Formatter, type StatusPrefix } from './formatter.js';\n\n/**\n * Central output renderer.\n *\n * Single choke point that turns a {@link CommandResult} into stdout bytes,\n * switching between machine-readable JSON and a human-readable table view.\n * This is what lets command handlers stop calling `console.log` directly:\n * they build a `CommandResult` and hand it here.\n *\n * Contract (cli-standard §5.1/§5.2):\n * - stdout carries ONLY the business payload — a single JSON value\n * (`--format json`) or human-readable text (`--format table`).\n * - logs, spinners, prompts, hints and progress lines belong on stderr and\n * are NEVER written here.\n *\n * Recorded deviation from cli-standard §5.1: the default format is `table`\n * (not `json`), and the flag values are `json | table` (not `json | text`).\n */\n\n/** The two supported output formats. */\nexport type OutputFormat = 'json' | 'table';\n\n/** Options consumed by {@link render}. */\nexport interface RenderOptions {\n format: OutputFormat;\n}\n\n/** The default format used when nothing valid is supplied (deliberate deviation: `table`). */\nconst DEFAULT_FORMAT: OutputFormat = 'table';\n\n/** Narrow an arbitrary string to a known {@link OutputFormat}. */\nfunction isOutputFormat(value: string): value is OutputFormat {\n return value === 'json' || value === 'table';\n}\n\n/**\n * Resolve the active output format.\n *\n * Precedence: `--format` flag > `AGENZO_FORMAT` env var > default `table`.\n * Any invalid value falls back to the default. The result is always one of\n * `'json' | 'table'`.\n *\n * The `--format` flag is authoritative when provided: a provided-but-invalid\n * flag falls back to the default rather than deferring to the environment.\n */\nexport function resolveFormat(\n flag?: string,\n env: string | undefined = process.env.AGENZO_FORMAT,\n): OutputFormat {\n // 1. --format flag is authoritative when provided.\n if (flag !== undefined) {\n return isOutputFormat(flag) ? flag : DEFAULT_FORMAT;\n }\n // 2. AGENZO_FORMAT environment value, when set to a valid format.\n if (env !== undefined && isOutputFormat(env)) {\n return env;\n }\n // 3. Default.\n return DEFAULT_FORMAT;\n}\n\n/**\n * Emit a successful command result to stdout in the chosen format.\n *\n * - `json`: writes `JSON.stringify(result.data, null, 2)` (the machine payload\n * only — never the text-mode chrome).\n * - `table`: writes the lazy human presenter `result.text()`.\n *\n * Only the payload reaches stdout; status/progress lines must go to stderr by\n * the caller. A trailing newline is appended so the output pipes cleanly into\n * tools like `jq`.\n */\nexport function render<T>(result: CommandResult<T>, opts: RenderOptions): void {\n if (opts.format === 'json') {\n process.stdout.write(`${JSON.stringify(result.data, null, 2)}\\n`);\n return;\n }\n process.stdout.write(`${result.text()}\\n`);\n}\n\n/**\n * Emit a human-facing status line (✓ / ℹ / ⚠) to stderr — but ONLY in `table`\n * mode. In `json` mode the output is consumed by other agents/scripts, so any\n * decorative status text (even on stderr) is noise that can confuse parsing;\n * `json` mode therefore stays completely silent here. Errors are NOT routed\n * through this helper — they are owned by the top-level handler in index.ts.\n *\n * This is the single choke point for command success/progress notices, so the\n * `json`-silence rule is enforced in one place rather than scattered across\n * every handler.\n */\nexport function notify(\n format: OutputFormat,\n type: StatusPrefix,\n message: string,\n): void {\n if (format === 'json') {\n return;\n }\n console.error(Formatter.status(type, message));\n}\n","/**\n * Shared JSON envelope renderer (cli-design §7.7.2 BACK-011).\n *\n * In `--format json` mode, every command's payload is prefixed with two\n * client-assembled context fields:\n * - `profile`: the active environment name (production / testing / custom),\n * derived by reverse-looking-up the api_host in BUILTIN_PROFILES.\n * - `endpoint`: the api **host only** (e.g. https://agent.everonet.com) —\n * NEVER the internal API path (/api/admin/v1), so internal\n * routing is not leaked to agent consumers.\n *\n * `result.data` is expected to be an object (single-resource payloads are flat\n * field maps; list payloads are `{ <namedKey>: [...], page: {...} }`). The two\n * context fields are spread in front of it.\n *\n * In `--format table` mode this is a passthrough to the standard `render`.\n *\n * This lives in `@agenzo/cli-core` (BACK-011) so every CLI shares one\n * implementation rather than copying it per app.\n */\nimport type { CommandResult } from '../types/commands.js';\nimport { type RenderOptions, render } from './output.js';\nimport { ConfigManager, BUILTIN_PROFILES } from '../config/config-manager.js';\n\nexport async function renderWithContext<T>(\n result: CommandResult<T>,\n opts: RenderOptions,\n configManager: ConfigManager,\n): Promise<void> {\n if (opts.format !== 'json') {\n render(result, opts);\n return;\n }\n\n const config = await configManager.load();\n const host = config.api_host.replace(/\\/+$/, '');\n const profile =\n Object.entries(BUILTIN_PROFILES).find(([, v]) => v === host)?.[0] ?? 'custom';\n\n const dataObj =\n result.data && typeof result.data === 'object'\n ? (result.data as Record<string, unknown>)\n : { value: result.data };\n\n const payload = {\n profile,\n endpoint: host,\n ...dataObj,\n };\n\n render({ ...result, data: payload } as CommandResult<typeof payload>, opts);\n}\n","import { input, password, select } from '@inquirer/prompts';\n\ninterface PromptConfig {\n message: string;\n type?: 'input' | 'password' | 'select';\n choices?: { name: string; value: string }[];\n validate?: (input: string) => boolean | string;\n}\n\nexport class PromptEngine {\n /** Return flagValue directly if provided, otherwise prompt interactively */\n static async resolveInput(\n flagValue: string | undefined,\n config: PromptConfig,\n ): Promise<string> {\n if (flagValue !== undefined) {\n return flagValue;\n }\n\n if (config.type === 'password') {\n return password({ message: config.message, mask: '*' });\n }\n\n if (config.type === 'select' && config.choices) {\n return select({\n message: config.message,\n choices: config.choices,\n });\n }\n\n return input({\n message: config.message,\n validate: config.validate,\n });\n }\n}\n","import { password } from '@inquirer/prompts';\nimport { PromptEngine } from '@agenzo/cli-core';\n\n// ============================================================\n// Payment-method interactive prompts (token-cli domain)\n// ============================================================\n//\n// These were relocated out of @agenzo/cli-core's PromptEngine: collecting card\n// number / expiry / CVV is token-cli payment-method business, not a generic\n// interactive fallback. cli-core keeps only the general `PromptEngine.resolveInput`.\n\n/** Always collect CVV interactively with masked display. */\nexport async function collectCvv(): Promise<string> {\n return password({\n message: 'CVV:',\n mask: '*',\n });\n}\n\n/** Collect payment method params based on type. */\nexport async function collectPaymentMethodParams(\n type: string,\n flags: Record<string, string | undefined>,\n): Promise<Record<string, string>> {\n const params: Record<string, string> = { type };\n\n const email = await PromptEngine.resolveInput(flags.cardEmail ?? flags.email, {\n message: 'Email (for 3DS verification):',\n });\n params.email = email;\n\n if (type === 'card') {\n params.card_number = await PromptEngine.resolveInput(flags.cardNumber, {\n message: 'Card number:',\n });\n params.expiry_date = await PromptEngine.resolveInput(flags.expiry, {\n message: 'Expiry (MMYY):',\n });\n // CVV: use flag if provided, otherwise collect interactively\n if (flags.cvv) {\n params.cvv = flags.cvv;\n } else {\n params.cvv = await collectCvv();\n }\n }\n\n return params;\n}\n","/**\n * `--help --format json` verb-level schema (§4.4.1.3) — token domain.\n *\n * Every payment-methods / payment-tokens verb supports `--help --format json`,\n * emitting a machine-readable JSON object describing the verb. This is the\n * standard way an Agent (orchestrator) discovers flags, response shape, and\n * error-recovery guidance locally, without a network round-trip.\n *\n * Mechanism: identical to merchant-cli — `attachSchemaHelp` overrides a\n * command's `helpInformation`. Only an explicit `--format json` in argv\n * switches to JSON schema output; bare `--help` keeps commander text.\n */\nimport type { Command } from 'commander';\n\nconst CLI_NAME = 'agenzo-token-cli';\n\n// ============================================================\n// Schema shape (reusable interfaces)\n// ============================================================\n\nexport interface FlagSchema {\n type: string;\n required: boolean | 'conditional';\n default?: unknown;\n description: string;\n constraints?: string;\n /** Hint for orchestrator: where this value comes from. */\n source?: 'user' | 'from_previous_step' | 'agent_generated' | 'config';\n /** When source=from_previous_step, which field to take from. */\n from?: string;\n}\n\nexport interface ExampleSchema {\n command: string;\n output_summary: string;\n}\n\nexport interface VerbSchema {\n cli: string;\n noun: string;\n verb: string;\n description: string;\n flags: Record<string, FlagSchema>;\n response: Record<string, unknown>;\n example: ExampleSchema;\n error_recovery?: Record<string, string>;\n}\n\n// ============================================================\n// Emit + attach mechanism (identical to merchant-cli)\n// ============================================================\n\nexport function wantsJsonSchema(argv: string[] = process.argv): boolean {\n for (let i = 0; i < argv.length; i++) {\n const a = argv[i];\n if (a === '--format=json') return true;\n if (a === '--format' && argv[i + 1] === 'json') return true;\n }\n return false;\n}\n\nexport function emitSchema(schema: VerbSchema): void {\n console.log(JSON.stringify(schema, null, 2));\n}\n\nexport function attachSchemaHelp(cmd: Command, schema: VerbSchema): Command {\n const baseHelp = cmd.helpInformation.bind(cmd);\n cmd.helpInformation = (context) => {\n if (!wantsJsonSchema()) return baseHelp(context);\n emitSchema(schema);\n return '';\n };\n return cmd;\n}\n\n// ============================================================\n// payment-methods verb schemas\n// ============================================================\n\nexport const pmAddSchema: VerbSchema = {\n cli: CLI_NAME,\n noun: 'payment-methods',\n verb: 'add',\n description:\n 'Add a payment method. --payment-brand evo (default): card binding + 3DS via Drop-in session. ' +\n '--payment-brand unionpay: UPI Agent Pay enrollment (requires --member); returns enroll_url, ' +\n 'result arrives asynchronously via webhook.',\n flags: {\n 'payment-brand': {\n type: 'string',\n required: false,\n default: 'evo',\n description:\n 'Payment brand: \"evo\" (default; 3DS/Drop-in binding) or \"unionpay\" (UPI Agent Pay enrollment)',\n constraints: 'evo | unionpay',\n },\n member: {\n type: 'string',\n required: 'conditional',\n description:\n 'End-user member id (required when --payment-brand unionpay; identifies which user this card belongs to). ' +\n 'Ignored for evo payment brand.',\n source: 'from_previous_step',\n from: 'user.member_id or auth context',\n },\n mode: {\n type: 'string',\n required: false,\n default: 'dropin',\n description:\n 'Add mode (evo payment brand only): \"manual\" (CLI collects card details) or \"dropin\" (mint a Drop-in session)',\n constraints: 'manual | dropin',\n },\n email: {\n type: 'string',\n required: false,\n description: 'Email for 3DS verification (evo/manual) or Drop-in session reference (evo/dropin)',\n },\n 'no-poll': {\n type: 'bool',\n required: false,\n default: false,\n description:\n 'Dropin mode: mint session and exit immediately without polling verification status',\n },\n },\n response: {\n id: { type: 'string', description: 'Payment method id' },\n status: {\n type: 'string',\n description: 'PENDING (awaiting enrollment/3DS) / ACTIVE / FAILED / DISABLED',\n },\n 'payment-brand': { type: 'string', description: 'evo or unionpay' },\n session_id: {\n type: 'string|absent',\n description: 'Drop-in session id (evo/dropin mode only)',\n },\n enroll_url: {\n type: 'string|absent',\n description: 'UnionPay enrollment URL (unionpay payment brand only) — user opens this to bind card',\n },\n correlation_id: {\n type: 'string|absent',\n description: 'src_correlation_id for tracking enrollment result (unionpay payment brand only)',\n },\n },\n example: {\n command:\n 'agenzo-token-cli payment-methods add --payment-brand unionpay --member usr_abc123 --format json',\n output_summary:\n 'Returns enroll_url. User opens the URL in a browser to complete card binding. ' +\n 'Result arrives async via webhook; poll with `payment-methods list` or `payment-methods get`.',\n },\n error_recovery: {\n PARAM_INVALID:\n 'Fix the offending flag (--payment-brand must be evo|unionpay; --member required for unionpay).',\n UPSTREAM_ERROR:\n 'UPI enrollment initiation failed. Retry after a short delay (may be transient network).',\n MEMBER_REQUIRED:\n 'UnionPay payment brand requires --member <id>. Supply the end-user member identifier.',\n },\n};\n\nexport const pmListSchema: VerbSchema = {\n cli: CLI_NAME,\n noun: 'payment-methods',\n verb: 'list',\n description: 'List all payment methods for the authenticated developer',\n flags: {},\n response: {\n payment_methods: {\n type: 'array',\n description: 'List of payment methods',\n items: {\n id: { type: 'string', description: 'Payment method id' },\n status: { type: 'string', description: 'PENDING / ACTIVE / FAILED / DISABLED' },\n payment_brand: { type: 'string', description: 'evo or unionpay' },\n brand: { type: 'string|null', description: 'Card brand (Visa, Mastercard, UnionPay, etc.)' },\n last4: { type: 'string|null', description: 'Last 4 digits of card' },\n exp_month: { type: 'int|null', description: 'Expiry month' },\n exp_year: { type: 'int|null', description: 'Expiry year' },\n },\n },\n },\n example: {\n command: 'agenzo-token-cli payment-methods list --format json',\n output_summary: 'Returns array of payment methods with status and card info.',\n },\n};\n\nexport const pmGetSchema: VerbSchema = {\n cli: CLI_NAME,\n noun: 'payment-methods',\n verb: 'get',\n description: 'Get a payment method by ID',\n flags: {\n id: { type: 'string', required: true, description: 'Payment method id', source: 'from_previous_step', from: 'payment_methods[].id' },\n },\n response: {\n id: { type: 'string', description: 'Payment method id' },\n status: { type: 'string', description: 'PENDING / ACTIVE / FAILED / DISABLED' },\n payment_brand: { type: 'string', description: 'evo or unionpay' },\n brand: { type: 'string|null', description: 'Card brand' },\n last4: { type: 'string|null', description: 'Last 4 digits' },\n exp_month: { type: 'int|null', description: 'Expiry month' },\n exp_year: { type: 'int|null', description: 'Expiry year' },\n },\n example: {\n command: 'agenzo-token-cli payment-methods get --id pm_abc123 --format json',\n output_summary: 'Returns full payment method details including card info and status.',\n },\n};\n\nexport const pmDisableSchema: VerbSchema = {\n cli: CLI_NAME,\n noun: 'payment-methods',\n verb: 'disable',\n description: 'Disable a payment method (cascades revoke on active tokens)',\n flags: {\n id: { type: 'string', required: true, description: 'Payment method id to disable', source: 'from_previous_step', from: 'payment_methods[].id' },\n },\n response: {\n id: { type: 'string', description: 'Payment method id' },\n status: { type: 'string', description: 'DISABLED' },\n },\n example: {\n command: 'agenzo-token-cli payment-methods disable --id pm_abc123 --format json',\n output_summary: 'Disables the payment method and revokes any active tokens.',\n },\n error_recovery: {\n NOT_FOUND: 'Payment method id does not exist. Check the id with `payment-methods list`.',\n ALREADY_DISABLED: 'Card is already disabled. No action needed.',\n },\n};\n","import { Command } from 'commander';\nimport {\n ApiClient,\n ConfigManager,\n PromptEngine,\n Formatter,\n createSpinner,\n resolveFormat,\n notify,\n CliError,\n IdempotencyKeyRequiredError,\n renderWithContext,\n} from '@agenzo/cli-core';\nimport type { CommandResult, OutputFormat } from '@agenzo/cli-core';\nimport type { DropinCreateResponse, PaymentMethod } from '../types/api.js';\nimport { collectPaymentMethodParams } from './prompts.js';\nimport { attachSchemaHelp, pmAddSchema } from '../verb-schema.js';\n\n// ============================================================\n// Constants\n// ============================================================\n\n// Manual mode (3DS via email): the user clicks the magic link in their\n// inbox, so polling is short and tight.\nconst MANUAL_POLL_INTERVAL_MS = 3000;\nconst MANUAL_POLL_TIMEOUT_MS = 15 * 60 * 1000; // 15 minutes\n\n// Drop-in mode (v3): the add-payment-method form is rendered by the Drop-in\n// SDK inside the developer's own front-end, so the operator may need longer\n// to finish in the browser. The backend flips the PM to EXPIRED if the user\n// does not complete in time.\nconst DROPIN_POLL_INTERVAL_MS = 5000;\nconst DROPIN_POLL_TIMEOUT_MS = 30 * 60 * 1000; // 30 minutes\n\n// Backend writes one of these into PaymentMethod.status when the verification\n// flow reaches a final state. We stop polling on any of them. EXPIRED only\n// ever applies to dropin PMs (manual PMs never expire server-side).\nconst TERMINAL_STATUSES = new Set(['ACTIVE', 'FAILED', 'EXPIRED']);\n\ntype AddDeps = { apiClient: ApiClient };\n\n// ============================================================\n// Command registration\n// ============================================================\n\n/**\n * `payment-methods add` — add a payment method (§3.4.0.1).\n *\n * Two modes, selected via `--mode`:\n *\n * - `manual` (default): the CLI collects card details (--email / --card-number\n * / --expiry / --cvv), POSTs /payment-methods/create, then polls 3DS\n * verification until ACTIVE / FAILED / 15-minute timeout.\n * - `dropin`: the CLI mints a Drop-in session (POST /payment-methods/dropin/create\n * with the developer email), prints the session id so the caller can render\n * the add-payment UI in their own front-end via the Drop-in SDK, then polls\n * the same verification/status endpoint until ACTIVE / FAILED / EXPIRED /\n * 30-minute timeout. No card details / idempotency key are needed.\n *\n * Orthogonal to `--mode` is `--payment-brand`, selecting the payment brand:\n *\n * - `evo` (default): the existing Evo 3DS binding flow above, fully unchanged.\n * - `unionpay`: dispatches to UPI Agent Pay enrollment. Requires `--member <id>`\n * (the end-user identity the card is bound to). POSTs /payment-methods/create\n * with `payment_brand=unionpay`, prints the returned `enroll_url` for the user to open\n * in a browser to complete card binding, then exits immediately — the CLI\n * does not poll for unionpay (the async result arrives via webhook; polling\n * for terminal state is done by the orchestrator, not the CLI).\n */\nexport function registerAddCommand(parent: Command, deps: AddDeps): void {\n const cmd = parent\n .command('add')\n .description('Add a payment method (manual 3DS or Drop-in session)')\n .option('--api-key <key>', 'API Key for authentication')\n .option('--type <type>', 'Payment method type (default: card)', 'card')\n .option(\n '--payment-brand <brand>',\n 'Payment brand: \"evo\" (default; existing 3DS/Drop-in binding) or \"unionpay\" (UPI Agent Pay enrollment)',\n 'evo',\n )\n .option(\n '--member <id>',\n 'End-user member id (required when --payment-brand unionpay; identifies which end-user this card belongs to)',\n )\n .option(\n '--mode <mode>',\n 'Add mode: \"manual\" (default; CLI collects card details and polls 3DS) or \"dropin\" (mint a Drop-in session and poll until the user finishes adding the payment method in the browser)',\n 'manual',\n )\n .option(\n '--email <email>',\n 'Manual mode: email for 3DS verification. Dropin mode: email used as the Drop-in session reference.',\n )\n .option('--card-number <number>', 'Card number (manual mode only)')\n .option('--expiry <mmyy>', 'Expiry date (MMYY format) (manual mode only)')\n .option('--cvv <cvv>', 'Card CVV (manual mode only)')\n .option(\n '--idempotency-key <key>',\n 'Idempotency key forwarded verbatim as the Idempotency-Key header (manual mode only)',\n )\n .option(\n '--no-poll',\n '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)',\n );\n\n attachSchemaHelp(cmd, pmAddSchema);\n\n cmd.action(async () => {\n const opts = cmd.optsWithGlobals();\n const format = resolveFormat(opts.format as string | undefined);\n const isYes = Boolean(opts.yes);\n\n const paymentBrand = String(opts.paymentBrand ?? 'evo').toLowerCase();\n if (paymentBrand !== 'evo' && paymentBrand !== 'unionpay') {\n throw new CliError(\n 'PARAM_INVALID',\n `Unknown --payment-brand \"${opts.paymentBrand}\". Expected \"evo\" or \"unionpay\".`,\n );\n }\n\n if (paymentBrand === 'unionpay') {\n await handleUnionpayPaymentBrand(deps, opts, format);\n return;\n }\n\n const mode = String(opts.mode ?? 'manual').toLowerCase();\n if (mode !== 'manual' && mode !== 'dropin') {\n throw new CliError(\n 'PARAM_INVALID',\n `Unknown --mode \"${opts.mode}\". Expected \"manual\" or \"dropin\".`,\n );\n }\n\n if (mode === 'dropin') {\n await handleDropinMode(deps, opts, format);\n return;\n }\n\n await handleManualMode(deps, opts, format, isYes);\n });\n}\n\n// ============================================================\n// Manual mode (collect card details + 3DS polling)\n// ============================================================\n\n/**\n * Manual mode: collect card details, POST /payment-methods/create, then poll\n * 3DS verification status until ACTIVE / FAILED / 15-minute timeout.\n */\nasync function handleManualMode(\n deps: AddDeps,\n opts: Record<string, unknown>,\n format: OutputFormat,\n isYes: boolean,\n): Promise<void> {\n // --- Resolve API key ---\n const apiKey = await PromptEngine.resolveInput(opts.apiKey as string | undefined, {\n message: 'API Key:',\n type: 'password',\n });\n\n // --- Resolve payment method type ---\n const type = (opts.type as string) || 'card';\n\n // --- Collect card params via PromptEngine ---\n const flags: Record<string, string | undefined> = {\n email: opts.email as string | undefined,\n cardNumber: opts.cardNumber as string | undefined,\n expiry: opts.expiry as string | undefined,\n cvv: opts.cvv as string | undefined,\n };\n const params = await collectPaymentMethodParams(type, flags);\n\n // --- Idempotency key (required for write, Requirement 6.3) ---\n let idempotencyKey = opts.idempotencyKey as string | undefined;\n if (!idempotencyKey) {\n if (isYes) {\n throw new IdempotencyKeyRequiredError('payment-methods add');\n }\n idempotencyKey = await PromptEngine.resolveInput(undefined, {\n message: 'Idempotency key (unique per write, for safe retry):',\n validate: (v) => v.trim().length > 0 || 'Idempotency key is required',\n });\n }\n\n const extraHeaders: Record<string, string> = {\n 'Idempotency-Key': idempotencyKey,\n };\n\n // --- POST /payment-methods/create ---\n const result = await deps.apiClient.post<PaymentMethod>(\n '/payment-methods/create',\n { type: 'api-key', key: apiKey },\n params,\n extraHeaders,\n );\n\n if (!result.success) {\n throw CliError.fromApi(result, { auth: 'api-key' });\n }\n\n const pm = result.data;\n\n // --- Output: created state ---\n notify(format, 'success', 'Payment method created');\n\n const createdResult: CommandResult<PaymentMethod> = {\n data: pm,\n text: () => {\n const lines: [string, string][] = [\n ['ID', pm.id],\n ['Type', pm.type],\n ['Status', pm.status],\n ];\n if (pm.brand) lines.push(['Brand', pm.brand]);\n if (pm.first6) lines.push(['First 6', pm.first6]);\n if (pm.last4) lines.push(['Last 4', pm.last4]);\n return Formatter.keyValue(lines);\n },\n };\n\n const configManager = new ConfigManager();\n await renderWithContext(createdResult, { format }, configManager);\n\n // Hint about 3DS (after keyValue output)\n notify(format, 'info', 'Complete 3DS verification via email to activate');\n\n // --- 3DS polling (only for type=card and PENDING status) ---\n if (type === 'card' && pm.status === 'PENDING') {\n const finalStatus = await poll3dsVerification(deps.apiClient, apiKey, pm.id, format);\n\n if (finalStatus === 'ACTIVE') {\n // Fetch the updated payment method for full details\n const getResult = await deps.apiClient.get<PaymentMethod>(\n `/payment-methods/${pm.id}`,\n { type: 'api-key', key: apiKey },\n );\n\n if (getResult.success) {\n const activatedPm = getResult.data;\n notify(format, 'success', 'Payment method activated');\n\n const activatedResult: CommandResult<PaymentMethod> = {\n data: activatedPm,\n text: () => {\n const lines: [string, string][] = [\n ['ID', activatedPm.id],\n ['Type', activatedPm.type],\n ['Status', activatedPm.status],\n ];\n if (activatedPm.brand) lines.push(['Brand', activatedPm.brand]);\n if (activatedPm.first6) lines.push(['First 6', activatedPm.first6]);\n if (activatedPm.last4) lines.push(['Last 4', activatedPm.last4]);\n return Formatter.keyValue(lines);\n },\n };\n\n await renderWithContext(activatedResult, { format }, configManager);\n } else {\n // 3DS already reported ACTIVE, but the follow-up detail GET failed.\n // Emit a degraded terminal state from what we already know (the\n // create response + known-ACTIVE status) rather than exiting silently.\n notify(format, 'success', 'Payment method activated');\n\n const degraded: PaymentMethod = { ...pm, status: 'ACTIVE' };\n const degradedResult: CommandResult<PaymentMethod> = {\n data: degraded,\n text: () => {\n const lines: [string, string][] = [\n ['ID', degraded.id],\n ['Type', degraded.type],\n ['Status', degraded.status],\n ];\n if (degraded.brand) lines.push(['Brand', degraded.brand]);\n if (degraded.first6) lines.push(['First 6', degraded.first6]);\n if (degraded.last4) lines.push(['Last 4', degraded.last4]);\n return Formatter.keyValue(lines);\n },\n };\n\n await renderWithContext(degradedResult, { format }, configManager);\n }\n } else if (finalStatus === 'FAILED') {\n notify(format, 'error', '3DS verification failed');\n } else if (finalStatus === 'TIMEOUT') {\n notify(\n format,\n 'info',\n `Verification timed out (15 min). Check status with: agenzo-token-cli payment-methods get ${pm.id} --api-key <your_key>`,\n );\n }\n }\n}\n\n// ============================================================\n// UnionPay payment brand (enrollment: POST create(payment_brand=unionpay) + print enroll_url)\n// ============================================================\n\n/**\n * UnionPay payment brand: POST /payment-methods/create with `payment_brand=unionpay` +\n * `member_id`, print the returned `enroll_url` for the user to open in a\n * browser to complete card binding, then return immediately.\n *\n * No idempotency key is needed (unlike evo manual mode) — unionpay binding is\n * a UPI-side enrollment, not a card charge/verification attempt. No polling\n * happens here: the enrollment result arrives asynchronously via webhook, and\n * terminal-state polling (if any) is done by the orchestrator via\n * `payment-methods list`/`get`, not the CLI.\n */\nasync function handleUnionpayPaymentBrand(\n deps: AddDeps,\n opts: Record<string, unknown>,\n format: OutputFormat,\n): Promise<void> {\n const isYes = Boolean(opts.yes);\n\n // In --yes (non-interactive) mode, --member is required as a flag.\n let member: string;\n if (opts.member) {\n member = String(opts.member);\n } else if (isYes) {\n throw new CliError(\n 'PARAM_INVALID',\n 'Missing required --member <id> for --payment-brand unionpay (required in --yes mode)',\n );\n } else {\n member = await PromptEngine.resolveInput(undefined, {\n message: 'Member ID (end-user identity this card belongs to):',\n validate: (v) => v.trim().length > 0 || 'Member ID is required for --payment-brand unionpay',\n });\n }\n\n const apiKey = await PromptEngine.resolveInput(opts.apiKey as string | undefined, {\n message: 'API Key:',\n type: 'password',\n });\n\n const email = await PromptEngine.resolveInput(opts.email as string | undefined, {\n message: 'Email:',\n });\n\n const result = await deps.apiClient.post<PaymentMethod>(\n '/payment-methods/create',\n { type: 'api-key', key: apiKey },\n { type: 'card', payment_brand: 'unionpay', member_id: member, email },\n );\n\n if (!result.success) {\n throw CliError.fromApi(result, { auth: 'api-key' });\n }\n\n const pm = result.data;\n\n notify(format, 'success', 'Card binding initiated');\n\n const createdResult: CommandResult<PaymentMethod> = {\n data: pm,\n text: () =>\n Formatter.keyValue([\n ['ID', pm.id],\n ['Status', pm.status],\n ['Enroll URL', pm.enroll_url ?? '-'],\n ['Correlation ID', pm.correlation_id ?? '-'],\n ]),\n };\n\n const configManager = new ConfigManager();\n await renderWithContext(createdResult, { format }, configManager);\n\n notify(\n format,\n 'info',\n 'Open the Enroll URL in a browser to complete card binding. Waiting for result...',\n );\n\n // Poll GET /payment-methods/{id} every 5s, up to 60s, waiting for ACTIVE/FAILED.\n const UNIONPAY_POLL_INTERVAL_MS = 5000;\n const UNIONPAY_POLL_TIMEOUT_MS = 60_000;\n const startTime = Date.now();\n\n const spinner = format !== 'json' ? createSpinner('Waiting for card binding result...') : null;\n\n while (Date.now() - startTime < UNIONPAY_POLL_TIMEOUT_MS) {\n await sleep(UNIONPAY_POLL_INTERVAL_MS);\n\n const pollResult = await deps.apiClient.get<PaymentMethod>(\n `/payment-methods/${pm.id}`,\n { type: 'api-key', key: apiKey },\n );\n\n if (pollResult.success) {\n const status = pollResult.data.status;\n if (status === 'ACTIVE') {\n spinner?.stop();\n notify(format, 'success', 'Payment method activated');\n const activatedPm = pollResult.data;\n const activatedResult: CommandResult<PaymentMethod> = {\n data: activatedPm,\n text: () => {\n const lines: [string, string][] = [\n ['ID', activatedPm.id],\n ['Type', activatedPm.type ?? 'card'],\n ['Status', activatedPm.status],\n ];\n if (activatedPm.brand) lines.push(['Brand', activatedPm.brand]);\n if (activatedPm.first6) lines.push(['First 6', activatedPm.first6]);\n if (activatedPm.last4) lines.push(['Last 4', activatedPm.last4]);\n return Formatter.keyValue(lines);\n },\n };\n await renderWithContext(activatedResult, { format }, configManager);\n return;\n }\n if (status === 'FAILED') {\n spinner?.stop('error', 'Card binding failed.');\n return;\n }\n }\n // Still PENDING — continue polling\n }\n\n spinner?.stop('info', 'Timed out waiting for card binding result. Check status later with: payment-methods get ' + pm.id);\n}\n\n// ============================================================\n// Drop-in mode (mint Drop-in session + poll)\n// ============================================================\n\n/**\n * Drop-in mode: mint a Drop-in session and hand the add-payment-method UI off\n * to the developer's own front-end (which embeds the Drop-in SDK using the\n * session id). The CLI then polls the same verification/status endpoint manual\n * mode uses until the PM reaches a terminal status or the 30-minute timeout.\n */\nasync function handleDropinMode(\n deps: AddDeps,\n opts: Record<string, unknown>,\n format: OutputFormat,\n): Promise<void> {\n const apiKey = await PromptEngine.resolveInput(opts.apiKey as string | undefined, {\n message: 'API Key:',\n type: 'password',\n });\n\n const email = await PromptEngine.resolveInput(opts.email as string | undefined, {\n message: 'Email:',\n });\n\n const configManager = new ConfigManager();\n\n // 1) Create the Drop-in session (API Key auth). The backend creates a\n // PENDING PM keyed by pm_id and mints the session for the front-end SDK.\n const sessionResult = await deps.apiClient.post<DropinCreateResponse>(\n '/payment-methods/dropin/create',\n { type: 'api-key', key: apiKey },\n { email },\n );\n\n if (!sessionResult.success) {\n throw CliError.fromApi(sessionResult, { auth: 'api-key' });\n }\n\n const session = sessionResult.data;\n const pmId = session.id;\n\n // 2) Print the session id so the caller can initialise the front-end SDK.\n notify(format, 'success', 'Drop-in session created');\n\n const createdResult: CommandResult<DropinCreateResponse> = {\n data: session,\n text: () => Formatter.keyValue([['Session ID', session.session_id || '-']]),\n };\n await renderWithContext(createdResult, { format }, configManager);\n\n notify(\n format,\n 'info',\n 'Use the Session ID to add the payment method in the browser via the Drop-in SDK',\n );\n\n // --no-poll: server/SDK-driven flows finish the binding in the front-end, so\n // the CLI mints + prints the session and exits immediately. The session id is\n // already on stdout (clean JSON in --format json), so the caller can parse it.\n if (opts.poll === false) {\n return;\n }\n\n // 3) Poll verification/status (same endpoint manual mode uses) until the PM\n // reaches a terminal status or we time out at 30 minutes.\n const finalPm = await pollVerificationStatus(deps.apiClient, apiKey, pmId, {\n intervalMs: DROPIN_POLL_INTERVAL_MS,\n timeoutMs: DROPIN_POLL_TIMEOUT_MS,\n });\n\n if (finalPm.status === 'ACTIVE') {\n notify(format, 'success', 'Payment method activated');\n const activated: CommandResult<PaymentMethod> = {\n data: finalPm,\n text: () =>\n Formatter.keyValue([\n ['PM ID', finalPm.id],\n ['Brand', finalPm.brand ?? '-'],\n ['First 6', finalPm.first6 ?? '-'],\n ['Last 4', finalPm.last4 ?? '-'],\n ['Status', finalPm.status],\n ]),\n };\n await renderWithContext(activated, { format }, configManager);\n return;\n }\n\n if (finalPm.status === 'FAILED') {\n notify(format, 'error', 'Failed to add payment method');\n await renderPmId(finalPm.id, format, configManager);\n process.exitCode = 1;\n return;\n }\n\n if (finalPm.status === 'EXPIRED') {\n notify(format, 'error', 'Session expired before the payment method was added');\n await renderPmId(finalPm.id, format, configManager);\n process.exitCode = 1;\n return;\n }\n\n // Timed out without reaching a terminal status — PM is still PENDING\n // server-side. The operator can re-run with the same email to resume\n // (PENDING dropin PMs are overwritten/reused).\n notify(\n format,\n 'error',\n 'Adding payment method did not complete within 30 minutes. Re-run with the same email to resume.',\n );\n await renderPmId(pmId, format, configManager);\n process.exitCode = 1;\n}\n\n/** Render `{ id }` as the terminal payload (PM ID line in table, JSON in json). */\nasync function renderPmId(\n id: string,\n format: OutputFormat,\n configManager: ConfigManager,\n): Promise<void> {\n const result: CommandResult<{ id: string }> = {\n data: { id },\n text: () => Formatter.keyValue([['PM ID', id]]),\n };\n await renderWithContext(result, { format }, configManager);\n}\n\n// ============================================================\n// Polling helpers\n// ============================================================\n\n/**\n * Poll GET /payment-methods/verification/status?payment_method_id=<id> every\n * 3000ms until ACTIVE, FAILED, or 15-minute timeout (manual / 3DS mode).\n *\n * Returns the terminal status: 'ACTIVE' | 'FAILED' | 'TIMEOUT'.\n */\nasync function poll3dsVerification(\n apiClient: ApiClient,\n apiKey: string,\n paymentMethodId: string,\n format: OutputFormat,\n): Promise<'ACTIVE' | 'FAILED' | 'TIMEOUT'> {\n const startTime = Date.now();\n\n notify(format, 'info', 'Waiting for 3DS verification...');\n\n while (Date.now() - startTime < MANUAL_POLL_TIMEOUT_MS) {\n await sleep(MANUAL_POLL_INTERVAL_MS);\n\n const result = await apiClient.get<{ status: string }>(\n '/payment-methods/verification/status',\n { type: 'api-key', key: apiKey },\n { payment_method_id: paymentMethodId },\n );\n\n if (result.success) {\n const status = result.data.status;\n if (status === 'ACTIVE') {\n return 'ACTIVE';\n }\n if (status === 'FAILED') {\n return 'FAILED';\n }\n // Still PENDING — continue polling\n }\n // On API error during polling, continue trying (transient failures)\n }\n\n return 'TIMEOUT';\n}\n\ninterface PollOptions {\n intervalMs: number;\n timeoutMs: number;\n}\n\n/**\n * Poll GET /payment-methods/verification/status?payment_method_id=<id> at\n * `intervalMs` until the PM reaches a terminal status (ACTIVE / FAILED /\n * EXPIRED) or `timeoutMs` elapses (dropin mode).\n *\n * Returns the final PaymentMethod on a terminal status, or\n * `{ id, status: 'PENDING' }` on timeout so callers can branch on the final\n * status uniformly. Transient poll errors are ignored (next tick retries).\n */\nasync function pollVerificationStatus(\n apiClient: ApiClient,\n apiKey: string,\n pmId: string,\n options: PollOptions,\n): Promise<PaymentMethod> {\n const startTime = Date.now();\n\n while (Date.now() - startTime < options.timeoutMs) {\n const result = await apiClient.get<PaymentMethod>(\n '/payment-methods/verification/status',\n { type: 'api-key', key: apiKey },\n { payment_method_id: pmId },\n );\n\n if (result.success && TERMINAL_STATUSES.has(result.data.status)) {\n return result.data;\n }\n\n await sleep(options.intervalMs);\n }\n\n return { id: pmId, status: 'PENDING' } as PaymentMethod;\n}\n\n/** Simple async sleep utility. */\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","import { Command } from 'commander';\nimport {\n ApiClient,\n ConfigManager,\n PromptEngine,\n Formatter,\n resolveFormat,\n CliError,\n renderWithContext,\n} from '@agenzo/cli-core';\nimport type { CommandResult } from '@agenzo/cli-core';\nimport type { PaymentMethod } from '../types/api.js';\nimport { attachSchemaHelp, pmListSchema } from '../verb-schema.js';\n\n/**\n * `payment-methods list` — list payment methods (§3.4.0.2).\n *\n * GET /payment-methods with X-Api-Key header.\n * Optional --member flag maps to ?member_id= query param.\n * Table headers: ID / Type / Brand / First 6 / Last 4 / Status.\n * Empty list → info message (no table). Missing brand/first6/last4 → `-`.\n */\nexport function registerListCommand(parent: Command, deps: { apiClient: ApiClient }): void {\n const cmd = parent\n .command('list')\n .description('List payment methods')\n .option('--api-key <key>', 'API Key for authentication')\n .option('--member <member_id>', 'Filter by member ID');\n\n attachSchemaHelp(cmd, pmListSchema);\n\n cmd.action(async () => {\n const opts = cmd.optsWithGlobals();\n const format = resolveFormat(opts.format as string | undefined);\n\n const apiKey = await PromptEngine.resolveInput(opts.apiKey as string | undefined, {\n message: 'API Key:',\n type: 'password',\n });\n\n // Build query params\n const params: Record<string, string> = {};\n if (opts.member) {\n params.member_id = opts.member as string;\n }\n\n const result = await deps.apiClient.get<PaymentMethod[]>(\n '/payment-methods',\n { type: 'api-key', key: apiKey },\n Object.keys(params).length > 0 ? params : undefined,\n );\n\n if (!result.success) {\n throw CliError.fromApi(result, { auth: 'api-key' });\n }\n\n const methods = result.data;\n\n const configManager = new ConfigManager();\n const commandResult: CommandResult<{ payment_methods: PaymentMethod[] }> = {\n data: { payment_methods: methods },\n text: () => {\n if (methods.length === 0) {\n return Formatter.status('info', 'No payment methods found');\n }\n const headers = ['ID', 'Type', 'Brand', 'First 6', 'Last 4', 'Status'];\n const rows = methods.map((m) => [\n m.id,\n m.type,\n m.brand || '-',\n m.first6 || '-',\n m.last4 || '-',\n m.status,\n ]);\n return Formatter.table(headers, rows);\n },\n };\n\n await renderWithContext(commandResult, { format }, configManager);\n });\n}\n","import { Command } from 'commander';\nimport {\n ApiClient,\n ConfigManager,\n Formatter,\n PromptEngine,\n resolveFormat,\n CliError,\n renderWithContext,\n} from '@agenzo/cli-core';\nimport type { CommandResult } from '@agenzo/cli-core';\nimport type { PaymentMethod } from '../types/api.js';\nimport { attachSchemaHelp, pmGetSchema } from '../verb-schema.js';\n\n/**\n * `payment-methods get <pm_id>` — show a single payment method (§3.4.0.3).\n *\n * Reads: GET /payment-methods/<pm_id> (X-Api-Key).\n * Output: keyValue. Brand / First 6 / Last 4 appear only when their\n * corresponding fields are non-empty/non-null (conditional inclusion).\n */\nexport function registerGetCommand(parent: Command, deps: { apiClient: ApiClient }): void {\n const cmd = parent\n .command('get <pm_id>')\n .description('Get a payment method by ID')\n .option('--api-key <key>', 'API key for authentication');\n\n attachSchemaHelp(cmd, pmGetSchema);\n\n cmd.action(async (pmId: string) => {\n const opts = cmd.optsWithGlobals();\n const format = resolveFormat(opts.format as string | undefined);\n\n // Resolve API key — prompt interactively if not provided via flag\n const apiKey = await PromptEngine.resolveInput(opts.apiKey as string | undefined, {\n message: 'API Key:',\n type: 'password',\n });\n\n // GET /payment-methods/<pm_id>\n const result = await deps.apiClient.get<PaymentMethod>(\n `/payment-methods/${pmId}`,\n { type: 'api-key', key: apiKey },\n );\n\n if (!result.success) {\n throw CliError.fromApi(result, { auth: 'api-key' });\n }\n\n const pm = result.data;\n\n // Build keyValue entries — Brand/First 6/Last 4 only when non-empty\n const entries: [string, string][] = [\n ['ID', pm.id],\n ['Type', pm.type],\n ];\n\n if (pm.brand) {\n entries.push(['Brand', pm.brand]);\n }\n if (pm.first6) {\n entries.push(['First 6', pm.first6]);\n }\n if (pm.last4) {\n entries.push(['Last 4', pm.last4]);\n }\n\n entries.push(['Status', pm.status]);\n entries.push(['Created', Formatter.formatTime(pm.created_at)]);\n\n const configManager = new ConfigManager();\n const cmdResult: CommandResult<PaymentMethod> = {\n data: pm,\n text: () => Formatter.keyValue(entries),\n };\n\n await renderWithContext(cmdResult, { format }, configManager);\n });\n}\n","import { renderWithContext } from '@agenzo/cli-core';\nimport { Command } from 'commander';\nimport {\n ApiClient,\n ConfigManager,\n PromptEngine,\n Formatter,\n resolveFormat,\n notify,\n CliError,\n IdempotencyKeyRequiredError,\n} from '@agenzo/cli-core';\nimport type { CommandResult, DisableResult } from '@agenzo/cli-core';\nimport { attachSchemaHelp, pmDisableSchema } from '../verb-schema.js';\n\n/**\n * `payment-methods disable <pm_id>` — disable a payment method (§3.4.0.4).\n *\n * POST /payment-methods/<pm_id>/disable (no body).\n * Output: `✓ Payment method <id> disabled` + Status + Revoked tokens.\n * Idempotency: --idempotency-key required in --yes mode (Requirement 6.3).\n */\nexport function registerDisableCommand(parent: Command, deps: { apiClient: ApiClient }): void {\n const cmd = parent\n .command('disable <pm_id>')\n .description('Disable a payment method')\n .option('--api-key <key>', 'API key for authentication')\n .option(\n '--idempotency-key <key>',\n 'Idempotency key forwarded verbatim as the Idempotency-Key header',\n );\n\n attachSchemaHelp(cmd, pmDisableSchema);\n\n cmd.action(async (pmId: string) => {\n const opts = cmd.optsWithGlobals();\n const format = resolveFormat(opts.format as string | undefined);\n\n const apiKey = await PromptEngine.resolveInput(opts.apiKey as string | undefined, {\n message: 'API Key:',\n type: 'password',\n });\n\n // Idempotency key handling (Requirement 6.3):\n // In --yes mode, --idempotency-key is mandatory — never auto-generate, never send request.\n // In interactive mode, prompt if not provided.\n let idempotencyKey = opts.idempotencyKey as string | undefined;\n if (!idempotencyKey) {\n if (opts.yes) {\n throw new IdempotencyKeyRequiredError('payment-methods disable');\n }\n idempotencyKey = await PromptEngine.resolveInput(undefined, {\n message: 'Idempotency key (unique per write, for safe retry):',\n validate: (v) => v.trim().length > 0 || 'Idempotency key is required',\n });\n }\n\n const extraHeaders: Record<string, string> = {\n 'Idempotency-Key': idempotencyKey,\n };\n\n const result = await deps.apiClient.post<DisableResult>(\n `/payment-methods/${pmId}/disable`,\n { type: 'api-key', key: apiKey },\n undefined,\n extraHeaders,\n );\n\n if (!result.success) {\n throw CliError.fromApi(result, { auth: 'api-key' });\n }\n\n const data = result.data;\n\n // Status line → stderr (json mode stays silent per §5)\n notify(format, 'success', `Payment method ${pmId} disabled`);\n\n const cmdResult: CommandResult<DisableResult> = {\n data,\n text: () =>\n Formatter.keyValue([\n ['Status', data.status],\n ['Revoked tokens', String(data.revoked_tokens_count ?? 0)],\n ]),\n };\n\n const configManager = new ConfigManager();\n await renderWithContext(cmdResult, { format }, configManager);\n });\n}\n","import { Command } from 'commander';\nimport {\n ApiClient,\n ConfigManager,\n PromptEngine,\n Formatter,\n resolveFormat,\n notify,\n CliError,\n renderWithContext,\n} from '@agenzo/cli-core';\nimport type { CommandResult } from '@agenzo/cli-core';\nimport type { DropinCreateResponse } from '../types/api.js';\n\n/**\n * `payment-methods dropin-create` — mint a Drop-in session and return\n * immediately (no polling).\n *\n * This is the non-blocking half of `payment-methods add --mode dropin`: it\n * POSTs /payment-methods/dropin/create with the developer email, prints the\n * minted `session_id` (+ pm id) so the caller can initialise the Drop-in SDK\n * in their own front-end, then exits. Unlike `add --mode dropin`, it does NOT\n * poll verification/status — callers poll separately via\n * `payment-methods dropin-status <pm_id>` once the user finishes in the browser.\n *\n * Intended for programmatic callers (e.g. the agent orchestrator) that need the\n * session id synchronously to render an add-card card, rather than a CLI\n * operator who waits at the terminal. Not advertised in the SKILL/README.\n */\nexport function registerDropinCreateCommand(\n parent: Command,\n deps: { apiClient: ApiClient },\n): void {\n const cmd = parent\n .command('dropin-create')\n .description('Mint a Drop-in session and return the session id (no polling)')\n .option('--api-key <key>', 'API Key for authentication')\n .option('--email <email>', 'Email used as the Drop-in session reference');\n\n cmd.action(async () => {\n const opts = cmd.optsWithGlobals();\n const format = resolveFormat(opts.format as string | undefined);\n\n const apiKey = await PromptEngine.resolveInput(opts.apiKey as string | undefined, {\n message: 'API Key:',\n type: 'password',\n });\n\n const email = await PromptEngine.resolveInput(opts.email as string | undefined, {\n message: 'Email:',\n });\n\n // POST /payment-methods/dropin/create — backend creates a PENDING PM and\n // mints the Drop-in session for the front-end SDK. Returns synchronously.\n const sessionResult = await deps.apiClient.post<DropinCreateResponse>(\n '/payment-methods/dropin/create',\n { type: 'api-key', key: apiKey },\n { email },\n );\n\n if (!sessionResult.success) {\n throw CliError.fromApi(sessionResult, { auth: 'api-key' });\n }\n\n const session = sessionResult.data;\n\n notify(format, 'success', 'Drop-in session created');\n\n const configManager = new ConfigManager();\n const result: CommandResult<DropinCreateResponse> = {\n data: session,\n text: () =>\n Formatter.keyValue([\n ['PM ID', session.id],\n ['Session ID', session.session_id || '-'],\n ['Merchant Trans ID', session.merchant_trans_id || '-'],\n ['Status', session.status],\n ]),\n };\n\n await renderWithContext(result, { format }, configManager);\n\n notify(\n format,\n 'info',\n 'Use the Session ID to add the payment method via the Drop-in SDK, then poll: agenzo-token-cli payment-methods dropin-status <pm_id> --api-key <your_key>',\n );\n });\n}\n","import { Command } from 'commander';\nimport {\n ApiClient,\n ConfigManager,\n Formatter,\n PromptEngine,\n resolveFormat,\n CliError,\n renderWithContext,\n} from '@agenzo/cli-core';\nimport type { CommandResult } from '@agenzo/cli-core';\nimport type { PaymentMethod } from '../types/api.js';\n\n/**\n * `payment-methods dropin-status [pm_id]` — query the current Drop-in binding\n * status for a payment method, once (no polling).\n *\n * This is the status-check half of `payment-methods add --mode dropin`: it\n * reads GET /payment-methods/verification/status?payment_method_id=<pm_id>\n * and prints the current status, then exits. Callers (e.g. the agent\n * orchestrator) poll this on their own cadence after minting a session with\n * `payment-methods dropin-create`, instead of letting the CLI block for 30\n * minutes.\n *\n * The payment method id may be supplied either as the positional `<pm_id>`\n * (CLI operators) or via `--payment-method-id <id>`. The flag form exists for\n * programmatic callers like the agent orchestrator, whose CLI gateway only\n * passes `--flag value` pairs and cannot send positional arguments.\n *\n * Status enum: PENDING | ACTIVE | FAILED | DISABLED | EXPIRED.\n * Not advertised in the SKILL/README.\n */\nexport function registerDropinStatusCommand(\n parent: Command,\n deps: { apiClient: ApiClient },\n): void {\n const cmd = parent\n .command('dropin-status [pm_id]')\n .description('Query the current Drop-in binding status for a payment method (single check)')\n .option('--api-key <key>', 'API Key for authentication')\n .option(\n '--payment-method-id <id>',\n 'Payment method id to query (alternative to the positional <pm_id>, for programmatic callers that pass flags only)',\n );\n\n cmd.action(async (pmIdArg: string | undefined) => {\n const opts = cmd.optsWithGlobals();\n const format = resolveFormat(opts.format as string | undefined);\n\n // Accept the pm id from the positional arg or the --payment-method-id flag\n // (the orchestrator gateway can only pass flags), else prompt interactively.\n const pmId = await PromptEngine.resolveInput(\n pmIdArg ?? (opts.paymentMethodId as string | undefined),\n { message: 'Payment method id:' },\n );\n\n const apiKey = await PromptEngine.resolveInput(opts.apiKey as string | undefined, {\n message: 'API Key:',\n type: 'password',\n });\n\n // GET /payment-methods/verification/status?payment_method_id=<pm_id>\n const result = await deps.apiClient.get<PaymentMethod>(\n '/payment-methods/verification/status',\n { type: 'api-key', key: apiKey },\n { payment_method_id: pmId },\n );\n\n if (!result.success) {\n throw CliError.fromApi(result, { auth: 'api-key' });\n }\n\n const pm = result.data;\n\n const entries: [string, string][] = [['ID', pm.id ?? pmId]];\n if (pm.brand) entries.push(['Brand', pm.brand]);\n if (pm.first6) entries.push(['First 6', pm.first6]);\n if (pm.last4) entries.push(['Last 4', pm.last4]);\n entries.push(['Status', pm.status]);\n\n const configManager = new ConfigManager();\n const cmdResult: CommandResult<PaymentMethod> = {\n data: pm,\n text: () => Formatter.keyValue(entries),\n };\n\n await renderWithContext(cmdResult, { format }, configManager);\n });\n}\n","import { Command } from 'commander';\nimport { confirm, select } from '@inquirer/prompts';\nimport {\n ApiClient,\n ConfigManager,\n PromptEngine,\n Formatter,\n createSpinner,\n resolveFormat,\n notify,\n CliError,\n IdempotencyKeyRequiredError,\n renderWithContext,\n} from '@agenzo/cli-core';\nimport type { CommandResult, OutputFormat } from '@agenzo/cli-core';\nimport type { PaymentMethod } from '../types/api.js';\n\n// ============================================================\n// Constants\n// ============================================================\n\n/** Default network-token fee in cents when /config/network-token-fee is unreachable. */\nconst DEFAULT_NT_FEE_CENTS = 500;\n\n/** Smallest USDC unit (1 USDC = 1_000_000 micro-units). */\nconst USDC_UNIT = 1_000_000;\n\n/**\n * Decimal-amount format used by the `unionpay_amount` intent field.\n * Server expects a plain positive decimal string (e.g. \"174.58\") — NOT\n * cents. No conversion happens for this field, only format validation.\n */\nconst DECIMAL_AMOUNT_RE = /^\\d+(\\.\\d+)?$/;\n\n// ============================================================\n// Helpers (token-domain-specific — stays in app per requirement 5.5)\n// ============================================================\n\n/**\n * Map CLI `--type` flag value to the server-side `type` field.\n * `network-token` → `network_token`; unknown values pass through unchanged.\n */\nexport function mapTokenType(cliType: string): string {\n if (cliType === 'network-token') return 'network_token';\n return cliType;\n}\n\n/**\n * Convert a USD amount string (e.g. \"12.50\") to integer cents using\n * string-based parsing to avoid floating-point drift.\n *\n * Accepts formats: \"12\", \"12.5\", \"12.50\", \".50\", \"0.01\".\n * Throws PARAM_INVALID on non-numeric / out-of-range.\n */\nexport function usdToCents(amountStr: string): number {\n const trimmed = amountStr.trim();\n\n // Validate format: optional digits, optional decimal point with up to 2 fractional digits\n if (!/^\\d*\\.?\\d{0,2}$/.test(trimmed) || trimmed === '' || trimmed === '.') {\n throw new CliError('PARAM_INVALID', `Invalid amount format: \"${amountStr}\". Expected a decimal like \"12.50\".`);\n }\n\n const parts = trimmed.split('.');\n const integerPart = parts[0] || '0';\n let fractionalPart = parts[1] || '0';\n\n // Pad fractional to exactly 2 digits\n fractionalPart = fractionalPart.padEnd(2, '0');\n\n const integerCents = parseInt(integerPart, 10) * 100;\n const fractionalCents = parseInt(fractionalPart, 10);\n return integerCents + fractionalCents;\n}\n\n/**\n * Resolve the payment method to use, following 4-level priority:\n * 1. --payment-method-id (explicit)\n * 2. --card (match last4 against ACTIVE cards)\n * 3. Single ACTIVE card → auto-select\n * 4. Multiple ACTIVE cards → interactive select\n *\n * Throws CLIENT_NO_PAYMENT_METHOD when no ACTIVE cards exist.\n * Throws CLIENT_CARD_NOT_MATCHED when --card doesn't match any ACTIVE card.\n */\nexport async function resolvePaymentMethod(\n apiClient: ApiClient,\n apiKey: string,\n opts: {\n paymentMethodId?: string;\n card?: string;\n yes?: boolean;\n },\n): Promise<string> {\n // Priority 1: explicit --payment-method-id\n if (opts.paymentMethodId) {\n return opts.paymentMethodId;\n }\n\n // Need to fetch ACTIVE cards for priorities 2–4\n const result = await apiClient.get<PaymentMethod[]>(\n '/payment-methods',\n { type: 'api-key', key: apiKey },\n );\n\n if (!result.success) {\n throw CliError.fromApi(result, { auth: 'api-key' });\n }\n\n const activeCards = result.data.filter((m) => m.status === 'ACTIVE');\n\n if (activeCards.length === 0) {\n throw new CliError(\n 'CLIENT_NO_PAYMENT_METHOD',\n 'No active payment methods found. Add one with: agenzo-token-cli payment-methods add --api-key <your_key>',\n );\n }\n\n // Priority 2: --card (match last4)\n if (opts.card) {\n const matched = activeCards.find((m) => m.last4 === opts.card);\n if (!matched) {\n throw new CliError(\n 'CLIENT_CARD_NOT_MATCHED',\n `No active card ending in ${opts.card}. Available: ${activeCards.map((m) => m.last4 || '????').join(', ')}`,\n );\n }\n return matched.id;\n }\n\n // Priority 3: single card → auto-select\n if (activeCards.length === 1) {\n return activeCards[0].id;\n }\n\n // Priority 4: multiple cards → interactive select\n if (opts.yes) {\n // In --yes mode we cannot prompt; if there's ambiguity, we cannot proceed\n throw new CliError(\n 'PARAM_INVALID',\n 'Multiple active payment methods found. Specify --payment-method-id or --card to disambiguate.',\n );\n }\n\n const selected = await select({\n message: 'Select a payment method:',\n choices: activeCards.map((m) => ({\n name: `${m.id} (${m.brand || m.type} ****${m.last4 || '????'})`,\n value: m.id,\n })),\n });\n\n return selected;\n}\n\n/**\n * Format a payment token for human-readable output (§3.4.1 create output).\n * Renders differently per type: VCN / Network Token / X402.\n *\n * NOTE: The server response wraps type-specific data under `data.vcn`,\n * `data.network_token`, or `data.x402` (nested). This formatter reads\n * from that nested structure directly.\n */\nexport function formatPaymentToken(data: Record<string, unknown>): string {\n const type = data.type as string;\n const lines: [string, string][] = [];\n\n if (type === 'vcn') {\n const vcn = data.vcn as Record<string, unknown> | undefined ?? data;\n lines.push(['Payment Token ID', String(data.id || vcn.id || '')]);\n lines.push(['Type', 'VCN']);\n lines.push(['Card Number', String(vcn.card_number || '')]);\n lines.push(['Expiry', String(vcn.expiry || '')]);\n lines.push(['CVC', String(vcn.cvc || '')]);\n lines.push(['Limit', `$${formatCentsToUsd(vcn.amount_limit as number)}`]);\n lines.push(['Currency', String(vcn.currency || 'USD')]);\n lines.push(['Status', String(vcn.status || data.status || '')]);\n } else if (type === 'network_token') {\n if (data.status === 'PENDING' && data.checkout_url) {\n // UnionPay async PENDING response is flat (no `network_token` sub-object,\n // no cryptogram yet — that arrives later via checkout webhook).\n lines.push(['Payment Token ID', String(data.id || '')]);\n lines.push(['Type', 'Network Token']);\n lines.push(['Status', 'PENDING']);\n lines.push(['Checkout URL', String(data.checkout_url || '')]);\n lines.push(['Correlation ID', String(data.correlation_id || '')]);\n } else {\n const nt = data.network_token as Record<string, unknown> | undefined ?? data;\n lines.push(['Payment Token ID', String(data.id || nt.id || '')]);\n lines.push(['Type', 'Network Token']);\n lines.push(['Brand', String(nt.payment_brand || nt.brand || '')]);\n const eci = nt.eci || '';\n if (eci) lines.push(['ECI', String(eci)]);\n lines.push(['Cryptogram', String(nt.token_cryptogram || nt.cryptogram || '')]);\n lines.push(['Expiry', String(nt.expiry_date || nt.expiry || '')]);\n lines.push(['Token Number', String(nt.value || '')]);\n }\n } else if (type === 'x402') {\n const x402 = data.x402 as Record<string, unknown> | undefined ?? data;\n lines.push(['Payment Token ID', String(data.id || x402.id || '')]);\n lines.push(['Type', 'X402']);\n lines.push(['Signature Value', String(x402.signature_value || '')]);\n lines.push(['Status', String(x402.status || data.status || '')]);\n } else {\n // Unknown type: best-effort\n lines.push(['Payment Token ID', String(data.id || '')]);\n lines.push(['Type', String(type || 'unknown')]);\n lines.push(['Status', String(data.status || '')]);\n }\n\n return Formatter.keyValue(lines);\n}\n\n/** Format cents back to USD string (e.g. 1250 → \"12.50\"). */\nfunction formatCentsToUsd(cents: number | undefined): string {\n if (cents === undefined || cents === null) return '0.00';\n const dollars = Math.floor(cents / 100);\n const remainder = cents % 100;\n return `${dollars}.${String(remainder).padStart(2, '0')}`;\n}\n\n/**\n * Validate the `unionpay_amount` intent field: a positive decimal string\n * (e.g. \"174.58\"). No cents conversion — the server expects the decimal\n * string verbatim.\n */\nfunction isValidUnionpayAmount(amountStr: string): boolean {\n const trimmed = amountStr.trim();\n if (!DECIMAL_AMOUNT_RE.test(trimmed)) return false;\n return parseFloat(trimmed) > 0;\n}\n\n// ============================================================\n// Command registration\n// ============================================================\n\n/**\n * `payment-tokens create` — generate a VCN / Network Token / X402 credential\n * (§3.4.1).\n */\nexport function registerCreateCommand(parent: Command, deps: { apiClient: ApiClient }): void {\n const cmd = parent\n .command('create')\n .description('Create a payment token (VCN / Network Token / X402)')\n .option('--api-key <key>', 'API Key for authentication')\n .option('--type <type>', 'Token type: vcn | network-token | x402')\n .option('--payment-method-id <id>', 'Payment method ID to use')\n .option('--card <last4>', 'Match payment method by last 4 digits')\n .option('--member <member_id>', 'Member ID')\n .option('--amount <amount>', 'Amount in USD (VCN / X402)')\n .option('--currency <currency>', 'Currency (default: USD)')\n .option('--pay-to <address>', 'Pay-to address (X402)')\n .option('--nonce <nonce>', 'Nonce (X402)')\n .option('--network <network>', 'Network (X402)')\n .option('--deadline <deadline>', 'Deadline (X402)')\n .option('--external-tx-id <id>', 'External transaction ID')\n .option('--recipient-first-name <name>', 'UnionPay network token: recipient first name (order delivery details)')\n .option('--recipient-last-name <name>', 'UnionPay network token: recipient last name (order delivery details)')\n .option('--recipient-email <email>', 'UnionPay network token: recipient email (recipient-email or recipient-phone required)')\n .option('--recipient-phone <phone>', 'UnionPay network token: recipient phone (recipient-email or recipient-phone required)')\n .option('--unionpay-amount <amount>', 'UnionPay network token: intent amount as a decimal string, e.g. \"174.58\"')\n .option(\n '--idempotency-key <key>',\n 'Idempotency key forwarded verbatim as the Idempotency-Key header',\n );\n\n cmd.action(async () => {\n const opts = cmd.optsWithGlobals();\n const format = resolveFormat(opts.format as string | undefined);\n const isYes = Boolean(opts.yes);\n\n // --- Resolve API key ---\n const apiKey = await PromptEngine.resolveInput(opts.apiKey as string | undefined, {\n message: 'API Key:',\n type: 'password',\n });\n\n // --- Resolve token type ---\n const cliType = await PromptEngine.resolveInput(opts.type as string | undefined, {\n message: 'Token type:',\n type: 'select',\n choices: [\n { name: 'VCN (Virtual Card Number)', value: 'vcn' },\n { name: 'Network Token', value: 'network-token' },\n { name: 'X402 (USDC on-chain)', value: 'x402' },\n ],\n });\n const serverType = mapTokenType(cliType);\n\n // --- Resolve payment method (4-level priority) ---\n const paymentMethodId = await resolvePaymentMethod(deps.apiClient, apiKey, {\n paymentMethodId: opts.paymentMethodId as string | undefined,\n card: opts.card as string | undefined,\n yes: isYes,\n });\n\n // --- For network tokens, fetch the selected PM's `payment_brand` up front ---\n // (needed to branch evo vs. unionpay below, and to enforce that unionpay\n // cards may only be selected via --payment-method-id, never --card).\n let selectedPmPaymentBrand: string | undefined;\n if (serverType === 'network_token') {\n const pmResult = await deps.apiClient.get<PaymentMethod>(\n `/payment-methods/${paymentMethodId}`,\n { type: 'api-key', key: apiKey },\n );\n if (!pmResult.success) {\n throw CliError.fromApi(pmResult, { auth: 'api-key' });\n }\n selectedPmPaymentBrand = pmResult.data.payment_brand;\n\n if (selectedPmPaymentBrand === 'unionpay' && opts.card && !opts.paymentMethodId) {\n throw new CliError(\n 'PARAM_INVALID',\n 'UnionPay cards must be selected via --payment-method-id; --card (last4 matching) is not supported for unionpay payment brand.',\n );\n }\n }\n const isUnionpayNetworkToken = serverType === 'network_token' && selectedPmPaymentBrand === 'unionpay';\n\n // --- Resolve member ---\n let member: string | undefined = opts.member as string | undefined;\n if (!member && !isYes) {\n // In interactive mode, prompt for member (optional — allow empty)\n const memberInput = await PromptEngine.resolveInput(undefined, {\n message: 'Member ID (optional, press Enter to skip):',\n validate: () => true, // always valid (optional)\n });\n if (memberInput.trim()) {\n member = memberInput.trim();\n }\n }\n // In --yes mode, if --member not provided, omit it (don't prompt).\n\n // --- Type-specific branch logic ---\n let freezeAmountCents: number | undefined;\n let feeCents: number | undefined;\n let feeDisplay: string | undefined;\n let freezeDisplay: string | undefined;\n // Body fields that vary by type\n const typeBody: Record<string, unknown> = {};\n\n if (serverType === 'vcn') {\n // VCN branch: feature gate + amount + fee\n await checkVcnFeatureEnabled(deps.apiClient, apiKey);\n\n const amountStr = await PromptEngine.resolveInput(opts.amount as string | undefined, {\n message: 'Amount (USD, e.g. 25.00):',\n validate: (v) => {\n try {\n const cents = usdToCents(v);\n if (cents < 1 || cents > 50000) {\n return 'Amount must be between $0.01 and $500.00';\n }\n return true;\n } catch {\n return 'Invalid amount format. Use a decimal like \"25.00\"';\n }\n },\n });\n\n const cents = usdToCents(amountStr);\n if (cents < 1 || cents > 50000) {\n throw new CliError(\n 'PARAM_INVALID',\n 'Amount must be between $0.01 and $500.00',\n );\n }\n\n feeCents = Math.max(1, Math.round(cents * 0.05));\n freezeAmountCents = cents + feeCents;\n feeDisplay = `$${formatCentsToUsd(feeCents)}`;\n freezeDisplay = `$${formatCentsToUsd(freezeAmountCents)}`;\n\n typeBody.amount = cents;\n // §3.4.1: --currency omitted → do NOT send; server applies its default.\n if (opts.currency) {\n typeBody.currency = opts.currency as string;\n }\n } else if (serverType === 'network_token') {\n if (isUnionpayNetworkToken) {\n // UnionPay branch: no fee/freeze concept here (fee bypass is a\n // server-side concern — see task 15.3). Skip fee lookup entirely.\n // Collect intent fields instead: recipient info + unionpay_amount.\n const unionpayAmountStr = await PromptEngine.resolveInput(\n opts.unionpayAmount as string | undefined,\n {\n message: 'UnionPay intent amount (USD, e.g. 174.58):',\n validate: (v) => isValidUnionpayAmount(v) || 'Amount must be a positive decimal, e.g. \"174.58\"',\n },\n );\n if (!isValidUnionpayAmount(unionpayAmountStr)) {\n throw new CliError(\n 'PARAM_INVALID',\n `Invalid --unionpay-amount \"${unionpayAmountStr}\". Expected a positive decimal string, e.g. \"174.58\".`,\n );\n }\n typeBody.unionpay_amount = unionpayAmountStr.trim();\n\n typeBody.recipient_first_name = await PromptEngine.resolveInput(\n opts.recipientFirstName as string | undefined,\n {\n message: 'Recipient first name:',\n validate: (v) => v.trim().length > 0 || 'Recipient first name is required',\n },\n );\n typeBody.recipient_last_name = await PromptEngine.resolveInput(\n opts.recipientLastName as string | undefined,\n {\n message: 'Recipient last name:',\n validate: (v) => v.trim().length > 0 || 'Recipient last name is required',\n },\n );\n\n let recipientEmail = opts.recipientEmail as string | undefined;\n let recipientPhone = opts.recipientPhone as string | undefined;\n if (!recipientEmail && !recipientPhone) {\n if (isYes) {\n throw new CliError(\n 'PARAM_INVALID',\n '--recipient-email or --recipient-phone is required for unionpay network tokens.',\n );\n }\n const emailInput = await PromptEngine.resolveInput(undefined, {\n message: 'Recipient email (optional, press Enter to skip and enter phone instead):',\n validate: () => true,\n });\n if (emailInput.trim()) {\n recipientEmail = emailInput.trim();\n } else {\n const phoneInput = await PromptEngine.resolveInput(undefined, {\n message: 'Recipient phone (required, since no email was given):',\n validate: (v) => v.trim().length > 0 || 'Recipient email or phone is required',\n });\n recipientPhone = phoneInput.trim();\n }\n }\n if (recipientEmail) typeBody.recipient_email = recipientEmail;\n if (recipientPhone) typeBody.recipient_phone = recipientPhone;\n } else {\n // Evo branch (default): fetch fee config (fallback to default)\n feeCents = await fetchNetworkTokenFee(deps.apiClient, apiKey);\n freezeAmountCents = feeCents;\n feeDisplay = `$${formatCentsToUsd(feeCents)}`;\n freezeDisplay = feeDisplay;\n }\n } else if (serverType === 'x402') {\n // X402 branch: USDC amount + fee\n const amountStr = await PromptEngine.resolveInput(opts.amount as string | undefined, {\n message: 'Amount (USDC):',\n validate: (v) => {\n const n = parseFloat(v);\n if (isNaN(n) || n <= 0) return 'Amount must be a positive number';\n return true;\n },\n });\n\n const amountUsdc = parseFloat(amountStr);\n const amountUnits = Math.round(amountUsdc * USDC_UNIT);\n // Fee = max(0.01 USDC units, amount * 5%)\n const minFeeUnits = Math.round(0.01 * USDC_UNIT); // 10000 units = $0.01\n const percentFeeUnits = Math.round(amountUnits * 0.05);\n const feeUnits = Math.max(minFeeUnits, percentFeeUnits);\n const freezeUnits = amountUnits + feeUnits;\n\n feeDisplay = `${(feeUnits / USDC_UNIT).toFixed(6)} USDC`;\n freezeDisplay = `${(freezeUnits / USDC_UNIT).toFixed(6)} USDC`;\n\n typeBody.amount = amountUnits;\n typeBody.pay_to = await PromptEngine.resolveInput(opts.payTo as string | undefined, {\n message: 'Pay-to address:',\n });\n typeBody.nonce = await PromptEngine.resolveInput(opts.nonce as string | undefined, {\n message: 'Nonce:',\n });\n typeBody.network = await PromptEngine.resolveInput(opts.network as string | undefined, {\n message: 'Network:',\n });\n const deadlineStr = await PromptEngine.resolveInput(opts.deadline as string | undefined, {\n message: 'Deadline (Unix timestamp):',\n validate: (v) =>\n /^\\d+$/.test(v.trim()) || 'Deadline must be a Unix timestamp (integer seconds)',\n });\n // §3.4.1 request body requires `deadline: <number>` — coerce and validate\n // (covers both the --deadline flag path and the interactive path).\n const deadlineNum = Number(deadlineStr.trim());\n if (!Number.isInteger(deadlineNum) || deadlineNum <= 0) {\n throw new CliError(\n 'PARAM_INVALID',\n `Invalid deadline: \"${deadlineStr}\". Expected a Unix timestamp (integer seconds).`,\n );\n }\n typeBody.deadline = deadlineNum;\n }\n\n // --- Confirmation (unless --yes) ---\n if (!isYes) {\n if (freezeDisplay !== undefined && feeDisplay !== undefined) {\n const warningLines = [`Freeze: ${freezeDisplay}`, `Fee: ${feeDisplay}`];\n notify(format, 'warning', warningLines.join(' | '));\n } else if (isUnionpayNetworkToken) {\n notify(format, 'info', 'UnionPay: no fee (clearing network not yet enabled)');\n }\n\n const confirmMessage = isUnionpayNetworkToken\n ? 'Proceed with UnionPay network token request?'\n : 'Proceed with token creation?';\n const confirmed = await confirm({\n message: confirmMessage,\n default: true,\n });\n if (!confirmed) {\n throw new CliError('CLIENT_ABORTED', 'Token creation cancelled by user');\n }\n }\n\n // --- Idempotency key (required for write) ---\n let idempotencyKey = opts.idempotencyKey as string | undefined;\n if (!idempotencyKey) {\n if (isYes) {\n throw new IdempotencyKeyRequiredError('payment-tokens create');\n }\n idempotencyKey = await PromptEngine.resolveInput(undefined, {\n message: 'Idempotency key (unique per write, for safe retry):',\n validate: (v) => v.trim().length > 0 || 'Idempotency key is required',\n });\n }\n\n // --- Build request body ---\n const body: Record<string, unknown> = {\n type: serverType,\n payment_method_id: paymentMethodId,\n ...typeBody,\n };\n if (member) {\n body.member_id = member;\n }\n if (opts.externalTxId) {\n body.external_tx_id = opts.externalTxId as string;\n }\n\n const extraHeaders: Record<string, string> = {\n 'Idempotency-Key': idempotencyKey,\n };\n\n // --- POST /payment-tokens/create ---\n const result = await deps.apiClient.post<Record<string, unknown>>(\n '/payment-tokens/create',\n { type: 'api-key', key: apiKey },\n body,\n extraHeaders,\n );\n\n if (!result.success) {\n throw CliError.fromApi(result, { auth: 'api-key' });\n }\n\n const tokenData = result.data;\n // Ensure type is on the top-level data for formatPaymentToken\n if (!tokenData.type) {\n tokenData.type = serverType;\n }\n\n // --- Output ---\n notify(format, 'success', 'Payment token created');\n\n const configManager = new ConfigManager();\n const commandResult: CommandResult<Record<string, unknown>> = {\n data: tokenData,\n text: () => {\n let output = formatPaymentToken(tokenData);\n // X402: append info message about X-PAYMENT header\n if (serverType === 'x402') {\n output += '\\n' + Formatter.status('info', 'Use the Signature Value in the X-PAYMENT request header');\n }\n return output;\n },\n };\n\n await renderWithContext(commandResult, { format }, configManager);\n\n // UnionPay network tokens are async (PENDING at this point) — poll\n // GET /payment-tokens/{id} every 5s up to 60s waiting for ACTIVE/FAILED.\n if (isUnionpayNetworkToken) {\n notify(\n format,\n 'info',\n 'Open the Checkout URL to complete the UnionPay payment verification. Waiting for result...',\n );\n\n const UNIONPAY_TOKEN_POLL_INTERVAL_MS = 5000;\n const UNIONPAY_TOKEN_POLL_TIMEOUT_MS = 60_000;\n const pollStart = Date.now();\n const tokenId = tokenData.id as string;\n\n while (Date.now() - pollStart < UNIONPAY_TOKEN_POLL_TIMEOUT_MS) {\n await new Promise((resolve) => setTimeout(resolve, UNIONPAY_TOKEN_POLL_INTERVAL_MS));\n\n const pollResult = await deps.apiClient.get<Record<string, unknown>>(\n `/payment-tokens/${tokenId}`,\n { type: 'api-key', key: apiKey },\n );\n\n if (pollResult.success) {\n const status = pollResult.data.status as string;\n if (status === 'ACTIVE') {\n notify(format, 'success', 'UnionPay network token activated!');\n if (!pollResult.data.type) pollResult.data.type = serverType;\n const activatedResult: CommandResult<Record<string, unknown>> = {\n data: pollResult.data,\n text: () => formatPaymentToken(pollResult.data),\n };\n await renderWithContext(activatedResult, { format }, configManager);\n return;\n }\n if (status === 'FAILED') {\n notify(format, 'error', 'UnionPay network token failed.');\n return;\n }\n }\n // Still PENDING — continue polling\n }\n\n notify(format, 'info', `Timed out waiting for token activation. Check status later with: payment-tokens get ${tokenId}`);\n }\n });\n}\n\n// ============================================================\n// Type-branch helpers\n// ============================================================\n\n/**\n * VCN feature gate: GET /features/vcn — if disabled, throw TOKEN_FEATURE_DISABLED.\n */\nasync function checkVcnFeatureEnabled(apiClient: ApiClient, apiKey: string): Promise<void> {\n const result = await apiClient.get<{ enabled: boolean }>(\n '/features/vcn',\n { type: 'api-key', key: apiKey },\n );\n\n if (!result.success) {\n // If the endpoint fails, treat as feature disabled (conservative)\n throw CliError.fromApi(result, { auth: 'api-key' });\n }\n\n if (!result.data.enabled) {\n throw new CliError(\n 'TOKEN_FEATURE_DISABLED',\n 'VCN creation is not supported yet. Coming soon.',\n );\n }\n}\n\n/**\n * Fetch network-token fee from /config/network-token-fee.\n * Falls back to DEFAULT_NT_FEE_CENTS (500) if unreachable.\n */\nasync function fetchNetworkTokenFee(apiClient: ApiClient, apiKey: string): Promise<number> {\n try {\n const result = await apiClient.get<{ fee_cents: number }>(\n '/config/network-token-fee',\n { type: 'api-key', key: apiKey },\n );\n\n if (result.success && typeof result.data.fee_cents === 'number') {\n return result.data.fee_cents;\n }\n // Unreachable / unexpected shape → fallback\n return DEFAULT_NT_FEE_CENTS;\n } catch {\n // Network error / timeout → fallback\n return DEFAULT_NT_FEE_CENTS;\n }\n}\n","import { Command } from 'commander';\nimport {\n ApiClient,\n ConfigManager,\n PromptEngine,\n Formatter,\n resolveFormat,\n CliError,\n renderWithContext,\n} from '@agenzo/cli-core';\nimport type { CommandResult } from '@agenzo/cli-core';\n\n// ============================================================\n// getSummary — per-type summary for table rendering (§3.4.2)\n// ============================================================\n\n/**\n * Render a one-line summary for a payment token in the list table.\n *\n * - vcn: `<first6>****<last4> $<limit/100>` (e.g. \"411111****1234 $25.00\")\n * - network_token: `<brand>` (e.g. \"Visa\")\n * - x402: `<amount> <network>` (e.g. \"1000000 Base\")\n */\nfunction getSummary(token: Record<string, unknown>): string {\n const type = token.type as string;\n\n if (type === 'vcn') {\n const first6 = String(token.first6 || token.first_six || '');\n const last4 = String(token.last4 || token.last_four || '');\n const limit = token.amount_limit as number | undefined ?? token.limit as number | undefined;\n const limitDisplay = limit !== undefined && limit !== null\n ? `$${(limit / 100).toFixed(2)}`\n : '';\n return `${first6}****${last4} ${limitDisplay}`.trim();\n }\n\n if (type === 'network_token') {\n const nt = token.network_token as Record<string, unknown> | undefined;\n return String(nt?.payment_brand || token.brand || '');\n }\n\n if (type === 'x402') {\n const amount = String(token.amount ?? '');\n const network = String(token.network || '');\n return `${amount} ${network}`.trim();\n }\n\n return '';\n}\n\n// ============================================================\n// Command registration\n// ============================================================\n\n/**\n * `payment-tokens list` — list payment tokens (§3.4.2).\n *\n * GET /payment-tokens with X-Api-Key header.\n * Optional --type flag maps to ?type= query param.\n * Optional --member flag maps to ?member_id= query param.\n * Table headers: Token ID / Type / Status / Summary.\n * Empty list → `ℹ No payment tokens found` (no table).\n */\nexport function registerListCommand(parent: Command, deps: { apiClient: ApiClient }): void {\n const cmd = parent\n .command('list')\n .description('List payment tokens')\n .option('--api-key <key>', 'API Key for authentication')\n .option('--type <type>', 'Filter by token type')\n .option('--member <member_id>', 'Filter by member ID');\n\n cmd.action(async () => {\n const opts = cmd.optsWithGlobals();\n const format = resolveFormat(opts.format as string | undefined);\n\n const apiKey = await PromptEngine.resolveInput(opts.apiKey as string | undefined, {\n message: 'API Key:',\n type: 'password',\n });\n\n // Build query params\n const params: Record<string, string> = {};\n if (opts.type) {\n params.type = opts.type as string;\n }\n if (opts.member) {\n params.member_id = opts.member as string;\n }\n\n const result = await deps.apiClient.get<Record<string, unknown>[]>(\n '/payment-tokens',\n { type: 'api-key', key: apiKey },\n Object.keys(params).length > 0 ? params : undefined,\n );\n\n if (!result.success) {\n throw CliError.fromApi(result, { auth: 'api-key' });\n }\n\n const tokens = result.data;\n\n const configManager = new ConfigManager();\n const commandResult: CommandResult<{ payment_tokens: Record<string, unknown>[] }> = {\n data: { payment_tokens: tokens },\n text: () => {\n if (tokens.length === 0) {\n return Formatter.status('info', 'No payment tokens found');\n }\n const headers = ['Token ID', 'Type', 'Status', 'Summary'];\n const rows = tokens.map((t) => [\n String(t.id || ''),\n String(t.type || ''),\n String(t.status || ''),\n getSummary(t),\n ]);\n return Formatter.table(headers, rows);\n },\n };\n\n await renderWithContext(commandResult, { format }, configManager);\n });\n}\n","import { Command } from 'commander';\nimport {\n ApiClient,\n ConfigManager,\n Formatter,\n PromptEngine,\n resolveFormat,\n CliError,\n renderWithContext,\n} from '@agenzo/cli-core';\nimport type { CommandResult } from '@agenzo/cli-core';\n\n// ============================================================\n// Formatter — SEPARATE from create's `formatPaymentToken` (Property 7)\n// ============================================================\n\ninterface FormatPaymentTokenGetOptions {\n revealSensitive?: boolean;\n}\n\nfunction asString(value: unknown): string {\n return typeof value === 'string' ? value : '';\n}\n\nfunction maskPan(value: string, lastFour?: string): string {\n const suffix = lastFour || value.slice(-4);\n if (!suffix) return '';\n const maskedLength = Math.max(value.length - suffix.length, 4);\n return `${'*'.repeat(maskedLength)}${suffix}`;\n}\n\nfunction maskCvc(value: string): string {\n return value ? '***' : '';\n}\n\nfunction maskVcnFields(vcn: Record<string, unknown>): Record<string, unknown> {\n const masked = { ...vcn };\n const lastFour = asString(masked.last_four ?? masked.last4);\n\n if (typeof masked.card_number === 'string') {\n masked.card_number = maskPan(masked.card_number, lastFour);\n }\n if (typeof masked.pan === 'string') {\n masked.pan = maskPan(masked.pan, lastFour);\n }\n if (typeof masked.cvc === 'string') {\n masked.cvc = maskCvc(masked.cvc);\n }\n if (typeof masked.cvv === 'string') {\n masked.cvv = maskCvc(masked.cvv);\n }\n\n return masked;\n}\n\n/** Build the JSON payload for `payment-tokens get`, masking VCN secrets by default. */\nexport function buildPaymentTokenGetPayload(\n data: Record<string, unknown>,\n opts: FormatPaymentTokenGetOptions = {},\n): Record<string, unknown> {\n if (opts.revealSensitive || data.type !== 'vcn') {\n return data;\n }\n\n const payload = { ...data };\n if (payload.vcn && typeof payload.vcn === 'object') {\n payload.vcn = maskVcnFields(payload.vcn as Record<string, unknown>);\n return payload;\n }\n\n return maskVcnFields(payload);\n}\n\n/**\n * Format a payment token for the `get` command output (§3.4.3).\n *\n * CRITICAL: This MUST remain a standalone formatter — do NOT converge\n * with `formatPaymentToken` in create.ts. The differences are intentional\n * per design Property 7:\n *\n * - Top key: `Token ID` (create uses `Payment Token ID`)\n * - VCN: includes a `Last 4` line (create does not)\n * - VCN `Limit` / `Balance`: numeric values WITHOUT `$` prefix\n * (create uses `$` prefix for `Limit`)\n *\n * By default VCN PAN/CVC are masked. Use `--reveal` to intentionally print\n * full VCN credentials for a payment flow that needs to use them.\n */\nexport function formatPaymentTokenGet(\n data: Record<string, unknown>,\n opts: FormatPaymentTokenGetOptions = {},\n): string {\n const type = data.type as string;\n const lines: [string, string][] = [];\n\n if (type === 'vcn') {\n const vcn = (data.vcn as Record<string, unknown> | undefined) ?? data;\n const lastFour = asString(vcn.last_four ?? vcn.last4);\n const cardNumber = asString(vcn.card_number ?? vcn.pan);\n const cvc = asString(vcn.cvc ?? vcn.cvv);\n lines.push(['Token ID', String(data.id || vcn.id || '')]);\n lines.push(['Type', 'VCN']);\n lines.push([\n 'Card Number',\n opts.revealSensitive ? cardNumber : maskPan(cardNumber, lastFour),\n ]);\n lines.push(['Last 4', lastFour]);\n lines.push(['Expiry', String(vcn.expiry || '')]);\n lines.push(['CVC', opts.revealSensitive ? cvc : maskCvc(cvc)]);\n // Limit and Balance: numeric cents → USD string, NO `$` prefix\n lines.push(['Limit', formatCentsPlain(vcn.amount_limit as number)]);\n lines.push(['Balance', formatCentsPlain(vcn.balance as number)]);\n lines.push(['Currency', String(vcn.currency || 'USD')]);\n lines.push(['Status', String(vcn.status || data.status || '')]);\n } else if (type === 'network_token') {\n const nt = (data.network_token as Record<string, unknown> | undefined) ?? data;\n lines.push(['Token ID', String(data.id || nt.id || '')]);\n lines.push(['Type', 'Network Token']);\n lines.push(['Brand', String(nt.payment_brand || nt.brand || '')]);\n lines.push(['ECI', String(nt.eci || '')]);\n lines.push(['Cryptogram', String(nt.token_cryptogram || nt.cryptogram || '')]);\n lines.push(['Expiry', String(nt.expiry_date || nt.expiry || '')]);\n lines.push(['Value', String(nt.value || '')]);\n } else if (type === 'x402') {\n const x402 = (data.x402 as Record<string, unknown> | undefined) ?? data;\n lines.push(['Token ID', String(data.id || x402.id || '')]);\n lines.push(['Type', 'X402']);\n lines.push(['Signature Value', String(x402.signature_value || '')]);\n lines.push(['Status', String(x402.status || data.status || '')]);\n } else {\n // Unknown type: best-effort\n lines.push(['Token ID', String(data.id || '')]);\n lines.push(['Type', String(type || 'unknown')]);\n lines.push(['Status', String(data.status || '')]);\n }\n\n return Formatter.keyValue(lines);\n}\n\n/**\n * Format cents as plain USD string without `$` prefix (e.g. 1250 → \"12.50\").\n * This is the key difference from create's `formatCentsToUsd` which is used\n * with a `$` prefix in `Limit`.\n */\nfunction formatCentsPlain(cents: number | undefined | null): string {\n if (cents === undefined || cents === null) return '0.00';\n const dollars = Math.floor(cents / 100);\n const remainder = cents % 100;\n return `${dollars}.${String(remainder).padStart(2, '0')}`;\n}\n\n// ============================================================\n// Command registration\n// ============================================================\n\n/**\n * `payment-tokens get <payment_token_id>` — show a payment token (§3.4.3).\n *\n * Reads: GET /payment-tokens/<id> (X-Api-Key).\n * Output: keyValue with formatting that DIFFERS from create output (Property 7).\n */\nexport function registerGetCommand(parent: Command, deps: { apiClient: ApiClient }): void {\n const cmd = parent\n .command('get <payment_token_id>')\n .description('Get a payment token by ID')\n .option('--api-key <key>', 'API key for authentication')\n .option('--reveal', 'Reveal full VCN card number and CVC in the output');\n\n cmd.action(async (paymentTokenId: string) => {\n const opts = cmd.optsWithGlobals();\n const format = resolveFormat(opts.format as string | undefined);\n\n // Resolve API key — prompt interactively if not provided via flag\n const apiKey = await PromptEngine.resolveInput(opts.apiKey as string | undefined, {\n message: 'API Key:',\n type: 'password',\n });\n\n // GET /payment-tokens/<id>\n const result = await deps.apiClient.get<Record<string, unknown>>(\n `/payment-tokens/${paymentTokenId}`,\n { type: 'api-key', key: apiKey },\n );\n\n if (!result.success) {\n throw CliError.fromApi(result, { auth: 'api-key' });\n }\n\n const revealSensitive = Boolean(opts.reveal);\n const tokenData = buildPaymentTokenGetPayload(result.data, { revealSensitive });\n\n const configManager = new ConfigManager();\n const commandResult: CommandResult<Record<string, unknown>> = {\n data: tokenData,\n text: () => formatPaymentTokenGet(result.data, { revealSensitive }),\n };\n\n await renderWithContext(commandResult, { format }, configManager);\n });\n}\n","import { Command } from 'commander';\nimport {\n ApiClient,\n ConfigManager,\n PromptEngine,\n Formatter,\n resolveFormat,\n notify,\n CliError,\n IdempotencyKeyRequiredError,\n renderWithContext,\n} from '@agenzo/cli-core';\nimport type { CommandResult } from '@agenzo/cli-core';\nimport type { RevokeResult } from '../types/api.js';\n\n/**\n * `payment-tokens revoke <payment_token_id>` — revoke a payment token (§3.4.4).\n *\n * POST /payment-tokens/<id>/revoke (no body).\n * Two output states:\n * 1. Immediate revoke: `✓ Payment token revoked` + Token ID / Status / Revoked At\n * 2. Delayed revoke (X402, status==='ACTIVE' && expires_at non-null):\n * `✓ Revoke scheduled (cryptogram will auto-expire)` + Token ID / Status / Expires At (+message)\n *\n * Idempotency: --idempotency-key required in --yes mode (Requirement 6.3).\n */\nexport function registerRevokeCommand(parent: Command, deps: { apiClient: ApiClient }): void {\n const cmd = parent\n .command('revoke <payment_token_id>')\n .description('Revoke a payment token')\n .option('--api-key <key>', 'API key for authentication')\n .option(\n '--idempotency-key <key>',\n 'Idempotency key forwarded verbatim as the Idempotency-Key header',\n );\n\n cmd.action(async (paymentTokenId: string) => {\n const opts = cmd.optsWithGlobals();\n const format = resolveFormat(opts.format as string | undefined);\n\n const apiKey = await PromptEngine.resolveInput(opts.apiKey as string | undefined, {\n message: 'API Key:',\n type: 'password',\n });\n\n // Idempotency key handling (Requirement 6.3):\n // In --yes mode, --idempotency-key is mandatory — never auto-generate, never send request.\n // In interactive mode, prompt if not provided.\n let idempotencyKey = opts.idempotencyKey as string | undefined;\n if (!idempotencyKey) {\n if (opts.yes) {\n throw new IdempotencyKeyRequiredError('payment-tokens revoke');\n }\n idempotencyKey = await PromptEngine.resolveInput(undefined, {\n message: 'Idempotency key (unique per write, for safe retry):',\n validate: (v) => v.trim().length > 0 || 'Idempotency key is required',\n });\n }\n\n const extraHeaders: Record<string, string> = {\n 'Idempotency-Key': idempotencyKey,\n };\n\n const result = await deps.apiClient.post<RevokeResult>(\n `/payment-tokens/${paymentTokenId}/revoke`,\n { type: 'api-key', key: apiKey },\n undefined,\n extraHeaders,\n );\n\n if (!result.success) {\n throw CliError.fromApi(result, { auth: 'api-key' });\n }\n\n const data = result.data;\n\n // Determine output state:\n // Delayed revoke (X402): status is still ACTIVE and expires_at is present\n // Immediate revoke: all other cases\n const isDelayedRevoke = data.status === 'ACTIVE' && data.expires_at != null;\n\n if (isDelayedRevoke) {\n // Delayed revoke (X402 cryptogram will auto-expire)\n notify(format, 'success', 'Revoke scheduled (cryptogram will auto-expire)');\n\n const kvPairs: [string, string][] = [\n ['Token ID', data.id],\n ['Status', data.status],\n ['Expires At', Formatter.formatTime(data.expires_at)],\n ];\n if (data.message) {\n kvPairs.push(['Message', data.message]);\n }\n\n const cmdResult: CommandResult<RevokeResult> = {\n data,\n text: () => Formatter.keyValue(kvPairs),\n };\n\n const configManager = new ConfigManager();\n await renderWithContext(cmdResult, { format }, configManager);\n } else {\n // Immediate revoke\n notify(format, 'success', 'Payment token revoked');\n\n const cmdResult: CommandResult<RevokeResult> = {\n data,\n text: () =>\n Formatter.keyValue([\n ['Token ID', data.id],\n ['Status', data.status],\n ['Revoked At', Formatter.formatTime(data.revoked_at)],\n ]),\n };\n\n const configManager = new ConfigManager();\n await renderWithContext(cmdResult, { format }, configManager);\n }\n });\n}\n"],"mappings":"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","names":["readFile","writeFile","mkdir","chmod","join","homedir","join","homedir","mkdir","chmod","readFile","writeFile","render","password","password","select","select","cents","registerListCommand","registerGetCommand","registerListCommand","registerGetCommand"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../../../packages/cli-core/errors/error-catalog.ts","../../../packages/cli-core/errors/errors.ts","../../../packages/cli-core/version/version.ts","../../../packages/cli-core/api-client/client.ts","../../../packages/cli-core/credential-store/credential-store.ts","../../../packages/cli-core/key-store/key-store.ts","../../../packages/cli-core/config/config-manager.ts","../../../packages/cli-core/exit/exit.ts","../../../packages/cli-core/formatter/formatter.ts","../../../packages/cli-core/formatter/output.ts","../../../packages/cli-core/formatter/render-context.ts","../../../packages/cli-core/prompt-engine/prompt-engine.ts","../src/payment-methods/prompts.ts","../src/verb-schema.ts","../src/payment-methods/add.ts","../src/payment-methods/list.ts","../src/payment-methods/get.ts","../src/payment-methods/disable.ts","../src/payment-methods/dropin-create.ts","../src/payment-methods/dropin-status.ts","../src/payment-tokens/create.ts","../src/payment-tokens/list.ts","../src/payment-tokens/get.ts","../src/payment-tokens/revoke.ts"],"sourcesContent":["import { Command } from 'commander';\nimport {\n ApiClient,\n ConfigManager,\n Formatter,\n CliError,\n UserCancelError,\n toErrorEnvelope,\n resolveFormat,\n type OutputFormat,\n exitCodeFor,\n getCurrentVersion,\n} from '@agenzo/cli-core';\n\n// payment-methods commands\nimport { registerAddCommand } from './payment-methods/add.js';\nimport { registerListCommand as registerPmListCommand } from './payment-methods/list.js';\nimport { registerGetCommand as registerPmGetCommand } from './payment-methods/get.js';\nimport { registerDisableCommand as registerPmDisableCommand } from './payment-methods/disable.js';\nimport { registerDropinCreateCommand } from './payment-methods/dropin-create.js';\nimport { registerDropinStatusCommand } from './payment-methods/dropin-status.js';\n\n// payment-tokens commands\nimport { registerCreateCommand } from './payment-tokens/create.js';\nimport { registerListCommand as registerPtListCommand } from './payment-tokens/list.js';\nimport { registerGetCommand as registerPtGetCommand } from './payment-tokens/get.js';\nimport { registerRevokeCommand } from './payment-tokens/revoke.js';\n\n// Holds the parsed program so the top-level error handler can read the\n// resolved `--format` global flag. Assigned inside `main()` once the program\n// is constructed; may be undefined if an error is thrown before then.\nlet programRef: Command | undefined;\n\nasync function main() {\n // Instantiate shared infrastructure. token-cli authenticates per-command via\n // `--api-key` (X-Api-Key); there is no Bearer session / AuthService / keystore.\n const configManager = new ConfigManager(undefined, '/api/token/v1');\n await configManager.ensureDirectories();\n\n const apiBaseUrl = await configManager.getApiBaseUrl();\n const apiClient = new ApiClient({ baseUrl: apiBaseUrl });\n\n // Shared deps object — API Key is supplied per-command, so commands only\n // need the HTTP client.\n const deps = { apiClient };\n\n // Create program\n const program = new Command();\n programRef = program;\n program\n .name('agenzo-token-cli')\n .version(getCurrentVersion())\n .description(\n 'Agenzo token plane: payment methods (add payment method + 3DS) and payment tokens (VCN / Network Token / X402)',\n )\n .option('--verbose', 'Show verbose logs')\n .option('--yes', 'Skip confirmation prompts (for automation/AI Agents)')\n .option(\n '--format <format>',\n 'Output format: json | table (default: table; or set AGENZO_FORMAT)',\n );\n\n // Mirror the resolved global --format into AGENZO_FORMAT before any action\n // runs, so code paths without direct format access can resolve the active\n // format and stay silent in json mode.\n program.hook('preAction', (thisCommand) => {\n const flag = thisCommand.opts().format as string | undefined;\n process.env.AGENZO_FORMAT = resolveFormat(flag);\n });\n\n // payment-methods command group\n const pmCmd = program.command('payment-methods').description('Payment method management');\n registerAddCommand(pmCmd, deps);\n registerPmListCommand(pmCmd, deps);\n registerPmGetCommand(pmCmd, deps);\n registerPmDisableCommand(pmCmd, deps);\n // Drop-in non-blocking commands (programmatic callers; not in SKILL/README).\n registerDropinCreateCommand(pmCmd, deps);\n registerDropinStatusCommand(pmCmd, deps);\n\n // payment-tokens command group\n const ptCmd = program.command('payment-tokens').description('Payment token management');\n registerCreateCommand(ptCmd, deps);\n registerPtListCommand(ptCmd, deps);\n registerPtGetCommand(ptCmd, deps);\n registerRevokeCommand(ptCmd, deps);\n\n // Parse and execute\n await program.parseAsync(process.argv);\n}\n\n/**\n * Resolve the active output format for error reporting. Prefers the parsed\n * global `--format` flag (available on `programRef` once the program is\n * constructed); if an error was thrown before parsing, falls back to\n * `resolveFormat(undefined)` (which consults `AGENZO_FORMAT`, else `table`).\n */\nfunction resolveActiveFormat(): OutputFormat {\n const flag = programRef?.opts().format as string | undefined;\n return resolveFormat(flag);\n}\n\n/**\n * Top-level failure path. Writes the error envelope to stderr in the resolved\n * format and exits with the mapped code (1–5). stdout is left untouched so a\n * partial machine payload is never emitted on failure.\n *\n * - `json`: a single `{ error: { code, code_num, message, request_id?, upstream? } }` envelope (§8.2).\n * - `table`: `✗ [<code_num>] <message>`, plus a ` ↳ [<upstream.code>] <upstream.message>`\n * line when this failure originated from a third-party upstream (e.g. EVO card/network-\n * token binding) the platform calls out to.\n */\nfunction reportError(error: unknown): never {\n const envelope = toErrorEnvelope(error);\n const format = resolveActiveFormat();\n\n if (format === 'json') {\n console.error(JSON.stringify(envelope));\n } else {\n console.error(\n Formatter.status('error', `[${envelope.error.code_num}] ${envelope.error.message}`),\n );\n if (envelope.error.upstream) {\n console.error(` ↳ [${envelope.error.upstream.code}] ${envelope.error.upstream.message}`);\n }\n // Unknown (non-CliError) failures keep the --verbose raw-dump affordance.\n if (!(error instanceof CliError) && process.argv.includes('--verbose')) {\n console.error(error);\n }\n }\n\n // exitCodeFor owns the error-class → exit-code matrix, including\n // UpgradeRequiredError → 2 and UserCancelError → 5.\n process.exit(exitCodeFor(error));\n}\n\n// Ctrl+C / SIGINT maps to a user-cancel (exit 5) via the same envelope path.\nprocess.on('SIGINT', () => {\n reportError(new UserCancelError());\n});\n\n// Global error handler. Normal completion exits 0 naturally (the mapper is\n// never consulted on success).\nmain().catch(reportError);\n","/**\n * Unified outward-facing CLI error-code catalog (cli-design §8, single source of truth).\n *\n * Every outward code has both a string code (the preferred routing key) and a\n * numeric code (compact, convenient for log aggregation). The two map 1:1, bound\n * by {@link CODE_NUM}. String codes are grouped by domain prefix; numeric codes\n * are segmented by the same domains (§8.3).\n *\n * Note: `UPGRADE_REQUIRED` (CLI too old) and `CLIENT_ABORTED` (user-initiated\n * cancel) are non-business codes detected locally by the CLI. They are not part\n * of the §8.4 business dictionary and are allocated at the tail of the CLIENT range.\n */\nexport type ErrorCode =\n // AUTH_* (1000-1099)\n | 'AUTH_SESSION_EXPIRED'\n | 'AUTH_MAGIC_LINK_EXPIRED'\n | 'AUTH_INVITE_CODE_REQUIRED'\n | 'AUTH_INVITE_CODE_INVALID'\n // KEY_* (1100-1199)\n | 'KEY_INVALID'\n | 'KEY_SCOPE_DENIED'\n // PAYMENT_METHOD_* (1400-1499)\n | 'PAYMENT_METHOD_NOT_FOUND'\n | 'PAYMENT_METHOD_DISABLED'\n | 'INVALID_PAYMENT_METHOD'\n // RESOURCE_* (2000-2099)\n | 'RESOURCE_NOT_FOUND'\n | 'RESOURCE_CONFLICT'\n | 'RESOURCE_STATE_INVALID'\n // PARAM_* (2100-2199)\n | 'PARAM_INVALID'\n | 'PARAM_IDEMPOTENCY_KEY_REQUIRED'\n | 'PARAM_IDEMPOTENCY_KEY_CONFLICT'\n // BILLING_* (3000-3099)\n | 'BILLING_MODE_MISMATCH'\n // ACCOUNT_* (3100-3199)\n | 'ACCOUNT_NOT_FOUND'\n | 'ACCOUNT_SUSPENDED'\n | 'ACCOUNT_INSUFFICIENT_BALANCE'\n // PAYMENT_ORDER_* (3200-3299)\n | 'PAYMENT_ORDER_NOT_FOUND'\n | 'PAYMENT_ORDER_NOT_PAID'\n | 'PAYMENT_ORDER_MISMATCH'\n | 'PAYMENT_ORDER_ALREADY_CONSUMED'\n // TOKEN_* (4000-4099)\n | 'TOKEN_FEATURE_DISABLED'\n // SERVICE_* (4100-4199)\n | 'SERVICE_NOT_FOUND'\n // ride business codes (4200-4299)\n | 'VEHICLE_UNAVAILABLE'\n | 'QUOTE_EXPIRED'\n | 'BOOKING_FAILED'\n | 'CANCELLATION_NOT_ALLOWED'\n | 'PRICE_MISMATCH'\n | 'VEHICLE_CLASS_MISMATCH'\n | 'PAYMENT_METHOD_REQUIRED'\n | 'QUOTE_CACHE_UNAVAILABLE'\n | 'ARREARS_OUTSTANDING'\n | 'CONTACT_REQUIRED'\n | 'INVALID_PHONE'\n | 'SEAT_LIMIT_EXCEEDED'\n | 'RIDE_NOT_FOUND'\n // hotel business codes (4300-4399)\n | 'NO_AVAILABILITY'\n | 'PRICE_CHANGED'\n | 'NAME_FORMAT_INVALID'\n | 'HOTEL_ORDER_NOT_FOUND'\n | 'ALREADY_CANCELLED'\n | 'CHECKOUT_NOT_ALLOWED'\n | 'CHECKOUT_TASK_NOT_FOUND'\n | 'PAY_PER_CALL_NOT_AVAILABLE'\n // RATE_* (5000-5099)\n | 'RATE_LIMITED'\n // UPSTREAM_* (5100-5199)\n | 'UPSTREAM_ERROR'\n // INTERNAL_* (5200-5299)\n | 'INTERNAL_ERROR'\n // NOT_IMPLEMENTED (5300)\n | 'NOT_IMPLEMENTED'\n // CLIENT_* (9000-9099) — produced locally by the CLI\n | 'CLIENT_NOT_SIGNED_IN'\n | 'CLIENT_LOGIN_TIMEOUT'\n | 'CLIENT_ORG_NOT_LOCAL'\n | 'CLIENT_ORG_WRONG_ENV'\n | 'CLIENT_NO_PAYMENT_METHOD'\n | 'CLIENT_CARD_NOT_MATCHED'\n | 'CLIENT_ABORTED'\n // Non-business code (detected locally by the CLI)\n | 'UPGRADE_REQUIRED';\n\n/**\n * String code → numeric code (§8.4). Each outward code's numeric value is\n * uniquely bound by this table; once published it is append-only (never changed).\n */\nexport const CODE_NUM: Record<ErrorCode, number> = {\n AUTH_SESSION_EXPIRED: 1001,\n AUTH_MAGIC_LINK_EXPIRED: 1002,\n AUTH_INVITE_CODE_REQUIRED: 1003,\n AUTH_INVITE_CODE_INVALID: 1004,\n KEY_INVALID: 1101,\n KEY_SCOPE_DENIED: 1102,\n PAYMENT_METHOD_NOT_FOUND: 1401,\n PAYMENT_METHOD_DISABLED: 1402,\n INVALID_PAYMENT_METHOD: 1403,\n RESOURCE_NOT_FOUND: 2001,\n RESOURCE_CONFLICT: 2002,\n RESOURCE_STATE_INVALID: 2003,\n PARAM_INVALID: 2101,\n PARAM_IDEMPOTENCY_KEY_REQUIRED: 2102,\n PARAM_IDEMPOTENCY_KEY_CONFLICT: 2103,\n BILLING_MODE_MISMATCH: 3001,\n ACCOUNT_NOT_FOUND: 3101,\n ACCOUNT_SUSPENDED: 3102,\n ACCOUNT_INSUFFICIENT_BALANCE: 3103,\n PAYMENT_ORDER_NOT_FOUND: 3201,\n PAYMENT_ORDER_NOT_PAID: 3202,\n PAYMENT_ORDER_MISMATCH: 3203,\n PAYMENT_ORDER_ALREADY_CONSUMED: 3204,\n TOKEN_FEATURE_DISABLED: 4001,\n SERVICE_NOT_FOUND: 4101,\n VEHICLE_UNAVAILABLE: 4201,\n QUOTE_EXPIRED: 4202,\n BOOKING_FAILED: 4203,\n CANCELLATION_NOT_ALLOWED: 4204,\n PRICE_MISMATCH: 4205,\n VEHICLE_CLASS_MISMATCH: 4206,\n PAYMENT_METHOD_REQUIRED: 4207,\n QUOTE_CACHE_UNAVAILABLE: 4208,\n ARREARS_OUTSTANDING: 4209,\n CONTACT_REQUIRED: 4210,\n INVALID_PHONE: 4211,\n SEAT_LIMIT_EXCEEDED: 4213,\n RIDE_NOT_FOUND: 4212,\n NO_AVAILABILITY: 4301,\n PRICE_CHANGED: 4302,\n NAME_FORMAT_INVALID: 4303,\n HOTEL_ORDER_NOT_FOUND: 4304,\n ALREADY_CANCELLED: 4305,\n CHECKOUT_NOT_ALLOWED: 4306,\n CHECKOUT_TASK_NOT_FOUND: 4307,\n PAY_PER_CALL_NOT_AVAILABLE: 4308,\n RATE_LIMITED: 5001,\n UPSTREAM_ERROR: 5101,\n INTERNAL_ERROR: 5201,\n NOT_IMPLEMENTED: 5300,\n CLIENT_NOT_SIGNED_IN: 9001,\n CLIENT_LOGIN_TIMEOUT: 9002,\n CLIENT_ORG_NOT_LOCAL: 9003,\n CLIENT_ORG_WRONG_ENV: 9004,\n CLIENT_NO_PAYMENT_METHOD: 9005,\n CLIENT_CARD_NOT_MATCHED: 9006,\n CLIENT_ABORTED: 9007,\n UPGRADE_REQUIRED: 9008,\n};\n\n/** Look up the numeric code for a string error code. */\nexport function codeNum(code: ErrorCode): number {\n return CODE_NUM[code];\n}\n","import { type ErrorCode, CODE_NUM, codeNum } from './error-catalog.js';\nimport type { ApiError, UpstreamError } from '../api-client/client.js';\n\n/** Base class for all CLI errors. Carries the CLI-facing error code (§8.4). */\nexport class CliError extends Error {\n constructor(\n public readonly code: ErrorCode,\n message: string,\n public readonly statusCode?: number,\n public readonly requestId?: string,\n public readonly upstream?: UpstreamError,\n /**\n * The backend's own raw message for this error (e.g. a Pydantic\n * validation detail such as \"child_seat_count: must be between 0 and 5\",\n * or a provider adapter's `user_hint`). Kept SEPARATE from `message`\n * (the stable, catalog-owned text for `code`) so callers always get a\n * predictable top-level message while still being able to see exactly\n * what the backend said. Surfaced in the envelope as `backend_message`\n * when present and different from the stable message.\n */\n public readonly backendMessage?: string,\n ) {\n super(message);\n this.name = 'CliError';\n }\n\n /**\n * Map a backend ApiError to a CLI-facing code (§8.5 transitional mapping).\n * Backend numeric codes / HTTP status are translated to §8.4 string codes.\n * The top-level `message` is always the stable, catalog-owned text for the\n * resolved code (§8.1 principle 4 — never let raw backend text become the\n * primary/stable message). The backend's own message is NOT discarded,\n * though: it is preserved on `backendMessage` and surfaced in the envelope\n * as `backend_message` so the caller can see the real reason (e.g. which\n * field failed validation) alongside the stable code/message.\n *\n * The optional `opts.auth` selects the auth semantics for the 401 mapping:\n * - `'bearer'` (default, admin-cli Bearer Token): 401 → `AUTH_SESSION_EXPIRED`.\n * - `'api-key'` (token-cli `X-Api-Key`): 401 → `KEY_INVALID`.\n * 403 maps to `KEY_SCOPE_DENIED` under both auth modes. Omitting `opts`\n * preserves the original Bearer behavior exactly (§8.5 / requirement 6.4).\n *\n * Domain string-code routing (D3 / requirement 5.4): when the backend\n * supplies a string `error.code` in the v3 envelope that is a known §8 code\n * (present in {@link CODE_NUM}), it is used verbatim as the CLI-facing code\n * so ride/merchant-specific codes (`QUOTE_EXPIRED`, `VEHICLE_UNAVAILABLE`,\n * `BILLING_MODE_MISMATCH`, `PAYMENT_ORDER_*`, …) survive intact. Otherwise —\n * including when no string code is provided, as is the case for admin/token\n * today — mapping falls back to the HTTP-status table below, leaving the\n * existing Bearer/api-key behavior unchanged.\n */\n static fromApi(error: ApiError, opts?: { auth?: 'bearer' | 'api-key' }): CliError {\n // D3: prefer the backend's string code when it is a known §8 catalog code.\n if (error.code && isKnownErrorCode(error.code)) {\n return new CliError(\n error.code,\n STABLE_MESSAGE[error.code] ?? 'Request failed. Please check your input and retry.',\n error.statusCode,\n error.requestId,\n error.upstream,\n error.errorMessage,\n );\n }\n\n const status = error.statusCode;\n let code: ErrorCode;\n\n if (status === 401) code = opts?.auth === 'api-key' ? 'KEY_INVALID' : 'AUTH_SESSION_EXPIRED';\n else if (status === 403) code = 'KEY_SCOPE_DENIED';\n else if (status === 404) code = 'RESOURCE_NOT_FOUND';\n else if (status === 409) code = 'RESOURCE_CONFLICT';\n else if (status === 429) code = 'RATE_LIMITED';\n else if (status >= 500) code = 'INTERNAL_ERROR';\n else code = 'PARAM_INVALID'; // other 4xx (incl. 400/422)\n\n return new CliError(\n code,\n STABLE_MESSAGE[code] ?? 'Request failed. Please check your input and retry.',\n status,\n error.requestId,\n error.upstream,\n error.errorMessage,\n );\n }\n}\n\n/** Network / connectivity failure → UPSTREAM_ERROR. Never leak the internal URL/path. */\nexport class NetworkError extends CliError {\n constructor(_url: string, timeout?: number, _cause?: Error) {\n super(\n 'UPSTREAM_ERROR',\n timeout\n ? 'The request timed out. The service may be temporarily unavailable — please retry.'\n : 'Connection failed. The service may be temporarily unavailable — please retry.',\n );\n }\n}\n\n/** Auth / session failures. Code chosen by message intent (§8.4 AUTH_* / CLIENT_*). */\nexport class AuthError extends CliError {\n constructor(message: string, public readonly suggestion: string) {\n const m = message.toLowerCase();\n const code: ErrorCode = m.includes('not signed in')\n ? 'CLIENT_NOT_SIGNED_IN'\n : m.includes('time')\n ? 'CLIENT_LOGIN_TIMEOUT'\n : m.includes('magic link')\n ? 'AUTH_MAGIC_LINK_EXPIRED'\n : 'AUTH_SESSION_EXPIRED';\n super(code, message || 'Unknown error');\n }\n}\n\nexport class ConfigError extends CliError {\n constructor(message: string, public readonly filePath: string) {\n super('INTERNAL_ERROR', message || 'Unknown error');\n }\n}\n\nexport class ValidationError extends CliError {\n constructor(message: string) {\n super('PARAM_INVALID', message || 'Unknown error');\n }\n}\n\nexport class IdempotencyKeyRequiredError extends CliError {\n constructor(commandPath: string) {\n super(\n 'PARAM_IDEMPOTENCY_KEY_REQUIRED',\n `\\`${commandPath}\\` requires --idempotency-key <key>. Supply a unique key so the write can be safely retried.`,\n );\n }\n}\n\nexport class UpgradeRequiredError extends CliError {\n constructor(currentVersion: string, minVersion: string, upgradeCommand: string) {\n super(\n 'UPGRADE_REQUIRED',\n `agenzo-admin-cli ${currentVersion} is out of date — the server requires ${minVersion} or newer. To upgrade, run: ${upgradeCommand}`,\n );\n }\n}\n\nexport class UserCancelError extends CliError {\n constructor(message = 'Operation cancelled by user') {\n super('CLIENT_ABORTED', message || 'Unknown error');\n }\n}\n\n/** Type guard: is `value` a known §8 string error code (present in CODE_NUM)? */\nfunction isKnownErrorCode(value: string): value is ErrorCode {\n return Object.prototype.hasOwnProperty.call(CODE_NUM, value);\n}\n\n/**\n * Stable, CLI-owned message per code used when mapping opaque backend errors\n * (§8.1 principle 4: never surface raw backend detail).\n */\nconst STABLE_MESSAGE: Partial<Record<ErrorCode, string>> = {\n AUTH_SESSION_EXPIRED: 'Your session has expired. Please run `agenzo-admin-cli auth login` again.',\n AUTH_MAGIC_LINK_EXPIRED: 'Verification link is invalid or has expired. Please request a new one.',\n AUTH_INVITE_CODE_REQUIRED: 'An invitation code is required to register.',\n AUTH_INVITE_CODE_INVALID: 'The invitation code is invalid.',\n KEY_INVALID: 'The API key is invalid or has been revoked. Please check your --api-key and retry.',\n KEY_SCOPE_DENIED: 'This API key does not have the required scope for this command.',\n PAYMENT_METHOD_NOT_FOUND: 'Payment method not found.',\n PAYMENT_METHOD_DISABLED: 'This payment method has been disabled.',\n INVALID_PAYMENT_METHOD: 'The payment method is not available for this operation.',\n RESOURCE_NOT_FOUND: 'The resource was not found or does not belong to the current organization.',\n RESOURCE_CONFLICT: 'A resource with the same unique value already exists.',\n RESOURCE_STATE_INVALID: 'The resource is in a state that does not permit this operation.',\n RATE_LIMITED: 'Too many requests. Please back off and retry.',\n UPSTREAM_ERROR: 'A third-party service is temporarily unavailable. Please try again later.',\n INTERNAL_ERROR: 'Something went wrong on the server. Please retry and note the request_id.',\n PARAM_INVALID: 'One or more parameters are invalid. Please check your input and retry.',\n PARAM_IDEMPOTENCY_KEY_CONFLICT: 'A request with this idempotency key was already processed with different parameters.',\n TOKEN_FEATURE_DISABLED: 'VCN creation is not supported yet. Coming soon.',\n BILLING_MODE_MISMATCH: 'The billing mode does not match this operation. Please verify your account billing configuration.',\n ACCOUNT_NOT_FOUND: 'The settlement account was not found.',\n ACCOUNT_SUSPENDED: 'The settlement account is suspended. Please contact support.',\n ACCOUNT_INSUFFICIENT_BALANCE: 'The settlement account has insufficient balance for this operation.',\n PAYMENT_ORDER_NOT_FOUND: 'The payment order was not found.',\n PAYMENT_ORDER_NOT_PAID: 'The payment order has not been paid. Please complete payment and retry.',\n PAYMENT_ORDER_MISMATCH: 'The payment order does not match this order. Please check the --payment-order-id.',\n PAYMENT_ORDER_ALREADY_CONSUMED: 'The payment order has already been consumed by another booking.',\n SERVICE_NOT_FOUND: 'The requested service was not found.',\n VEHICLE_UNAVAILABLE: 'No vehicle is available for the requested trip. Please try a different time or class.',\n QUOTE_EXPIRED: 'The quote has expired. Please request a new quote and retry.',\n BOOKING_FAILED: 'The booking could not be completed. Please retry.',\n PRICE_MISMATCH: 'The price does not match the quote. Re-quote and use the exact amount from the quote response.',\n VEHICLE_CLASS_MISMATCH: 'The vehicle class does not match the quote. Use the vehicle class from the quote response.',\n PAYMENT_METHOD_REQUIRED: 'Pay-per-call billing requires an active payment method. Please add a card first.',\n QUOTE_CACHE_UNAVAILABLE: 'Quote cache is temporarily unavailable. Please request a new quote and retry.',\n ARREARS_OUTSTANDING: 'You have outstanding arrears. Please settle your balance before booking a new ride.',\n CONTACT_REQUIRED: 'Passenger contact information is required. Please provide a passenger name and phone number.',\n INVALID_PHONE: 'The passenger phone number is not valid. Please provide a valid international number.',\n SEAT_LIMIT_EXCEEDED: 'The number of child/infant/toddler seats exceeds the vehicle capacity. Reduce seats or choose a larger vehicle.',\n RIDE_NOT_FOUND: 'The ride order was not found or does not belong to you.',\n CANCELLATION_NOT_ALLOWED: 'This order cannot be cancelled in its current state.',\n NO_AVAILABILITY: 'No rooms available for the selected hotel and dates.',\n PRICE_CHANGED: 'The price changed since the quote. Re-quote and confirm.',\n NAME_FORMAT_INVALID: 'The guest name format is not accepted; use Latin letters.',\n HOTEL_ORDER_NOT_FOUND: 'Hotel order not found.',\n ALREADY_CANCELLED: 'This hotel order is already cancelled.',\n CHECKOUT_NOT_ALLOWED: 'A partial check-out is not allowed in the current state.',\n CHECKOUT_TASK_NOT_FOUND: 'Check-out application not found.',\n PAY_PER_CALL_NOT_AVAILABLE: 'Pay-per-call billing is not available; use monthly_settlement.',\n NOT_IMPLEMENTED: 'This operation is not implemented yet.',\n};\n\n/**\n * §8.2 error envelope: `{ error: { code, code_num, message, request_id?, upstream?, backend_message? } }`.\n *\n * `message` is always the stable, catalog-owned text for `code` — safe to\n * match on and never changes shape. `backend_message` (when present) is the\n * backend's own raw text for this specific failure (e.g. which field failed\n * validation, or a provider's real rejection reason) — diagnostic, not a\n * stable contract, but no longer discarded.\n */\nexport interface ErrorEnvelope {\n error: {\n code: ErrorCode;\n code_num: number;\n message: string;\n request_id?: string;\n upstream?: UpstreamError;\n backend_message?: string;\n };\n}\n\nexport function toErrorEnvelope(error: unknown): ErrorEnvelope {\n if (error instanceof CliError) {\n const stableMessage = error.message || 'Unknown error';\n // Only surface backend_message when it adds information beyond the\n // stable message (avoid noisy duplication when they already match).\n const backendMessage =\n error.backendMessage && error.backendMessage !== stableMessage\n ? error.backendMessage\n : undefined;\n return {\n error: {\n code: error.code,\n code_num: codeNum(error.code),\n message: stableMessage,\n ...(error.requestId ? { request_id: error.requestId } : {}),\n ...(error.upstream ? { upstream: error.upstream } : {}),\n ...(backendMessage ? { backend_message: backendMessage } : {}),\n },\n };\n }\n\n const message =\n error instanceof Error\n ? error.message\n : typeof error === 'string'\n ? error\n : 'Unexpected error';\n return {\n error: {\n code: 'INTERNAL_ERROR',\n code_num: codeNum('INTERNAL_ERROR'),\n message: message || 'Unknown error',\n },\n };\n}\n","/**\n * CLI version + min-version comparator.\n *\n * The CLI's current version is read from `package.json` at runtime. This is\n * the single source of truth — bumping `package.json` automatically updates\n * what the CLI reports and what it compares against the server-advertised\n * minimum (`X-CLI-Min-Version` response header, driven by\n * `AGENT_PAY_CLI_MIN_VERSION` on the server).\n *\n * Only numeric major.minor.patch segments are compared; pre-release and build\n * metadata suffixes are stripped. This matches our versioning scheme and\n * avoids pulling in `semver` for a single `<` check.\n */\n\nimport { readFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\n/** Command the user should run to pick up the latest CLI. */\nexport const UPGRADE_COMMAND = 'npm install -g agenzo-admin-cli@latest';\n\n/**\n * Hard-coded fallback used only when `package.json` cannot be read at runtime\n * (unusual packaging/bundling edge cases). Keep this in sync with\n * `package.json`'s `version` on every release so the reported version and\n * the User-Agent stay accurate even in the degraded path.\n */\nexport const FALLBACK_VERSION = '0.1.1';\n\nlet cachedVersion: string | null = null;\n\nexport function getCurrentVersion(): string {\n if (cachedVersion !== null) return cachedVersion;\n // Walk up from the compiled file (dist/index.js) or source layout to find\n // package.json. Both `dist/..` and `src/utils/../..` resolve to the project\n // root, which is where package.json lives in a published npm install.\n const here = dirname(fileURLToPath(import.meta.url));\n const candidates = [\n join(here, '..', 'package.json'), // dist/ → project root\n join(here, '..', '..', 'package.json'), // src/utils/ → project root\n ];\n for (const p of candidates) {\n try {\n const pkg = JSON.parse(readFileSync(p, 'utf-8')) as { version?: string };\n if (typeof pkg.version === 'string') {\n cachedVersion = pkg.version;\n return cachedVersion;\n }\n } catch {\n // try next candidate\n }\n }\n // Degrade gracefully instead of crashing the CLI: if we can't locate\n // package.json at runtime, report the hard-coded fallback. The User-Agent\n // and any min-version comparison will still behave sensibly. We write a\n // one-line warning to stderr so packaging regressions remain visible.\n cachedVersion = FALLBACK_VERSION;\n // eslint-disable-next-line no-console\n console.warn(\n `[agenzo-admin-cli] package.json not found; using fallback version ${FALLBACK_VERSION}`,\n );\n return cachedVersion;\n}\n\n/**\n * Returns negative / zero / positive like `Array.sort`, comparing `a` against `b`.\n * Non-numeric segments and suffixes are treated as zero.\n */\nexport function compareVersions(a: string, b: string): number {\n const parse = (v: string): [number, number, number] => {\n const clean = v.trim().replace(/^v/, '').split(/[-+]/)[0];\n const parts = clean.split('.');\n return [\n parseInt(parts[0] ?? '0', 10) || 0,\n parseInt(parts[1] ?? '0', 10) || 0,\n parseInt(parts[2] ?? '0', 10) || 0,\n ];\n };\n const [a1, a2, a3] = parse(a);\n const [b1, b2, b3] = parse(b);\n if (a1 !== b1) return a1 - b1;\n if (a2 !== b2) return a2 - b2;\n return a3 - b3;\n}\n\nexport function isBelow(current: string, minimum: string): boolean {\n return compareVersions(current, minimum) < 0;\n}\n","import { NetworkError, UpgradeRequiredError } from '../errors/errors.js';\nimport { getCurrentVersion, isBelow, UPGRADE_COMMAND } from '../version/version.js';\n\nexport interface ApiClientConfig {\n baseUrl: string;\n timeout?: number; // Default 30000ms\n}\n\nexport interface ApiResponse<T> {\n success: true;\n data: T;\n /** Server-provided message from the unified response envelope. */\n message?: string;\n}\n\n/** Upstream error details (diagnostic only, not stable). */\nexport interface UpstreamError {\n /** Upstream-specific error code (stringified). */\n code: string;\n /** Upstream-specific error message. */\n message: string;\n}\n\nexport interface ApiError {\n success: false;\n errorCode: number;\n errorMessage: string;\n statusCode: number;\n /**\n * Raw string code from the v3 response envelope (`{ code, message, data }`),\n * surfaced verbatim so {@link CliError.fromApi} can route domain-specific\n * §8 codes (e.g. `QUOTE_EXPIRED`, `VEHICLE_UNAVAILABLE`) by string code\n * before falling back to HTTP-status mapping. Absent when the backend does\n * not provide a string code (e.g. non-JSON error responses).\n */\n code?: string;\n /** Server-provided request correlation id, surfaced in the error envelope. */\n requestId?: string;\n /** Upstream error details for diagnostic transparency. */\n upstream?: UpstreamError;\n}\n\nexport type ApiResult<T> = ApiResponse<T> | ApiError;\n\nexport type AuthMode =\n | { type: 'bearer'; token: string }\n | { type: 'api-key'; key: string }\n | { type: 'none' };\n\nexport class ApiClient {\n private readonly baseUrl: string;\n private readonly timeout: number;\n /**\n * Correlation id for this CLI invocation. Generated once per `ApiClient`\n * instance (i.e. once per command execution — each `apps/*` entrypoint\n * constructs exactly one `ApiClient` per process run) and sent as\n * `X-Request-Id` on every request this client makes. The backend's\n * `RequestIdMiddleware` adopts a client-supplied `X-Request-Id` verbatim as\n * both `trace_id` and `request_id` (only generating its own when the header\n * is absent), so every HTTP call belonging to one CLI operation — including\n * multi-step flows like `payment-methods add`'s create + poll + get — shares\n * a single trace_id server-side and can be followed as one chain in logs.\n */\n private readonly requestId: string;\n\n constructor(config: ApiClientConfig) {\n this.baseUrl = config.baseUrl.replace(/\\/+$/, '');\n this.timeout = config.timeout ?? 60000;\n this.requestId = crypto.randomUUID();\n }\n\n private buildHeaders(auth: AuthMode): Record<string, string> {\n const headers: Record<string, string> = {\n 'User-Agent': `agenzo-admin-cli/${getCurrentVersion()}`,\n 'X-Request-Id': this.requestId,\n };\n if (auth.type === 'bearer') {\n headers['Authorization'] = `Bearer ${auth.token}`;\n } else if (auth.type === 'api-key') {\n headers['X-Api-Key'] = auth.key;\n }\n return headers;\n }\n\n async get<T>(\n path: string,\n auth: AuthMode,\n params?: Record<string, string>,\n ): Promise<ApiResult<T>> {\n let url = `${this.baseUrl}${path}`;\n if (params && Object.keys(params).length > 0) {\n const searchParams = new URLSearchParams(params);\n url += `?${searchParams.toString()}`;\n }\n return this.request<T>(url, {\n method: 'GET',\n headers: this.buildHeaders(auth),\n });\n }\n\n async post<T>(\n path: string,\n auth: AuthMode,\n body?: Record<string, unknown>,\n extraHeaders?: Record<string, string>,\n ): Promise<ApiResult<T>> {\n const url = `${this.baseUrl}${path}`;\n const headers = this.buildHeaders(auth);\n headers['Content-Type'] = 'application/json';\n if (extraHeaders) {\n Object.assign(headers, extraHeaders);\n }\n return this.request<T>(url, {\n method: 'POST',\n headers,\n body: body ? JSON.stringify(body) : undefined,\n });\n }\n\n private async request<T>(url: string, init: RequestInit): Promise<ApiResult<T>> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(url, {\n ...init,\n signal: controller.signal,\n });\n\n // Enforce server-advertised CLI version floor before doing any work\n // on the response. Throws UpgradeRequiredError which is rendered and\n // exits at the top level (src/index.ts).\n this.enforceMinVersion(response.headers.get('x-cli-min-version'));\n\n // Handle non-JSON responses (e.g. 500 Internal Server Error returns plain text)\n const contentType = response.headers.get('content-type') ?? '';\n let responseBody: Record<string, unknown>;\n if (contentType.includes('application/json')) {\n responseBody = await response.json() as Record<string, unknown>;\n } else {\n const text = await response.text();\n if (!response.ok) {\n const statusMsg = this.friendlyStatusMessage(response.status);\n return {\n success: false,\n errorCode: 0,\n errorMessage: statusMsg,\n statusCode: response.status,\n };\n }\n // Try parsing as JSON anyway (some servers don't set content-type)\n try {\n responseBody = JSON.parse(text) as Record<string, unknown>;\n } catch {\n return {\n success: false,\n errorCode: 0,\n errorMessage: `Unexpected response from server (${response.status})`,\n statusCode: response.status,\n };\n }\n }\n\n // Server uses unified format: { code: \"0000\", message: \"...\", data: {...} }\n const code = responseBody.code as string | undefined;\n const message = responseBody.message as string | undefined;\n\n // Success: HTTP 2xx AND code is \"0000\" (or no code field for raw responses)\n if (response.ok && (!code || code === '0000')) {\n // If the server wraps the payload in a \"data\" field, unwrap it —\n // including when `data` is explicitly null (a valid empty payload,\n // e.g. GET /accounts for a developer without a settlement account).\n // We must distinguish \"no data field\" (raw response → use the whole\n // body) from \"data field present but null\" (→ return null), since\n // `data ?? responseBody` would wrongly fall back to the envelope and\n // surface { code, message, data: null } as the payload.\n const hasDataField = Object.prototype.hasOwnProperty.call(responseBody, 'data');\n const payload = hasDataField ? responseBody.data : responseBody;\n return { success: true, data: payload as T, message };\n }\n\n // Error: either HTTP non-2xx or code !== \"0000\"\n const errorCode = code ? parseInt(code, 10) : 0;\n // Handle FastAPI 422 validation errors where detail is an array\n let errorMsg = message ?? response.statusText;\n if (!errorMsg || errorMsg === response.statusText) {\n const detail = responseBody.detail;\n if (Array.isArray(detail)) {\n errorMsg = detail.map((d: Record<string, unknown>) => {\n const loc = (d.loc as string[])?.slice(1).join('.') ?? '';\n return loc ? `${loc}: ${d.msg}` : String(d.msg);\n }).join('; ');\n } else if (typeof detail === 'string') {\n errorMsg = detail;\n }\n }\n\n // Prefer string error_code (CLI D3 routing) over numeric code string\n const errorCodeStr = responseBody.error_code as string | undefined;\n\n // Extract upstream error details from data.upstream\n const rawData = responseBody.data as Record<string, unknown> | undefined;\n const upstream = (rawData?.upstream && typeof rawData.upstream === 'object')\n ? rawData.upstream as UpstreamError\n : undefined;\n\n return {\n success: false,\n errorCode: isNaN(errorCode) ? 0 : errorCode,\n errorMessage: errorMsg,\n statusCode: response.status,\n ...(errorCodeStr ? { code: errorCodeStr } : (typeof code === 'string' && code ? { code } : {})),\n requestId: (responseBody.request_id ?? responseBody.requestId) as string | undefined,\n ...(upstream ? { upstream } : {}),\n };\n } catch (error) {\n // UpgradeRequiredError is a CliError and must propagate untouched to the\n // top-level handler; don't rewrap it as a NetworkError.\n if (error instanceof UpgradeRequiredError) {\n throw error;\n }\n if (error instanceof DOMException && error.name === 'AbortError') {\n throw new NetworkError(url, this.timeout);\n }\n throw new NetworkError(url, undefined, error instanceof Error ? error : undefined);\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n /**\n * Validate that the running CLI meets the server-advertised minimum.\n * Missing or empty header → skip (backward compat with servers that don't\n * advertise yet, and clients hitting legacy proxies).\n */\n private enforceMinVersion(headerValue: string | null): void {\n const minVersion = headerValue?.trim();\n if (!minVersion) return;\n const current = getCurrentVersion();\n if (isBelow(current, minVersion)) {\n throw new UpgradeRequiredError(current, minVersion, UPGRADE_COMMAND);\n }\n }\n\n private friendlyStatusMessage(status: number): string {\n const messages: Record<number, string> = {\n 400: 'Invalid request. Please check your input.',\n 401: 'Authentication failed. Please check your API key or login again.',\n 403: 'Access denied. You do not have permission for this operation.',\n 404: 'Resource not found. Please check the ID.',\n 409: 'Conflict. This resource may already exist.',\n 422: 'Invalid input. Please check the request parameters.',\n 429: 'Too many requests. Please wait and try again.',\n 500: 'Something went wrong on the server. Please try again later.',\n 502: 'Service is temporarily unavailable. Please try again in a moment.',\n 503: 'Service is temporarily unavailable. Please try again in a moment.',\n 504: 'The request took too long. Please try again.',\n };\n return messages[status] ?? `Something went wrong (${status}). Please try again later.`;\n }\n}\n","import { readFile, writeFile, readdir, unlink, access, mkdir, chmod } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { homedir } from 'node:os';\nimport { OrgCredential } from '../types/config.js';\n\nexport class CredentialStore {\n private readonly basePath: string;\n\n constructor(basePath?: string) {\n this.basePath = basePath ?? join(homedir(), '.agenzo-admin-cli', 'credentials');\n }\n\n private filePath(orgId: string): string {\n return join(this.basePath, `${orgId}.json`);\n }\n\n private async ensureDir(): Promise<void> {\n // Credentials hold long-lived Bearer tokens — dir must be owner-only (0700).\n // mkdir mode is subject to umask, so chmod afterwards to enforce it on\n // both freshly created and pre-existing directories.\n await mkdir(this.basePath, { recursive: true, mode: 0o700 });\n await chmod(this.basePath, 0o700);\n }\n\n async get(orgId: string): Promise<OrgCredential | null> {\n try {\n const content = await readFile(this.filePath(orgId), 'utf-8');\n return JSON.parse(content) as OrgCredential;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return null;\n }\n throw error;\n }\n }\n\n async save(credential: OrgCredential): Promise<void> {\n await this.ensureDir();\n const path = this.filePath(credential.org_id);\n // Owner read/write only (0600); chmod after write so pre-existing files\n // created before this safeguard also get tightened.\n await writeFile(path, JSON.stringify(credential, null, 2), {\n encoding: 'utf-8',\n mode: 0o600,\n });\n await chmod(path, 0o600);\n }\n\n async delete(orgId: string): Promise<void> {\n try {\n await unlink(this.filePath(orgId));\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return;\n }\n throw error;\n }\n }\n\n async listAll(): Promise<OrgCredential[]> {\n try {\n const files = await readdir(this.basePath);\n const jsonFiles = files.filter((f) => f.endsWith('.json'));\n const credentials: OrgCredential[] = [];\n for (const file of jsonFiles) {\n try {\n const content = await readFile(join(this.basePath, file), 'utf-8');\n credentials.push(JSON.parse(content) as OrgCredential);\n } catch {\n // Skip corrupted files\n }\n }\n return credentials;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return [];\n }\n throw error;\n }\n }\n\n async exists(orgId: string): Promise<boolean> {\n try {\n await access(this.filePath(orgId));\n return true;\n } catch {\n return false;\n }\n }\n}\n","import { readFile, writeFile, mkdir, chmod } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport { homedir } from 'node:os';\nimport { StoredApiKey } from '../types/config.js';\n\nexport class KeyStore {\n private readonly basePath: string;\n\n constructor(basePath?: string) {\n // API keys are shared across runtime-plane CLIs (token/merchant/payment).\n // Stored under the legacy path for backward compatibility; will migrate to\n // ~/.agenzo/keys/ in a future release.\n this.basePath = basePath ?? join(homedir(), '.agenzo-token-cli', 'api-keys');\n }\n\n private filePath(orgId: string): string {\n return join(this.basePath, `${orgId}.json`);\n }\n\n private async loadData(orgId: string): Promise<StoredApiKey[]> {\n try {\n const content = await readFile(this.filePath(orgId), 'utf-8');\n return JSON.parse(content) as StoredApiKey[];\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return [];\n }\n throw error;\n }\n }\n\n private async saveData(orgId: string, data: StoredApiKey[]): Promise<void> {\n // Stored API keys are plaintext secrets — dir 0700, file 0600.\n await mkdir(this.basePath, { recursive: true, mode: 0o700 });\n await chmod(this.basePath, 0o700);\n const path = this.filePath(orgId);\n await writeFile(path, JSON.stringify(data, null, 2), {\n encoding: 'utf-8',\n mode: 0o600,\n });\n await chmod(path, 0o600);\n }\n\n async add(orgId: string, key: StoredApiKey): Promise<void> {\n const data = await this.loadData(orgId);\n data.push(key);\n await this.saveData(orgId, data);\n }\n\n async update(orgId: string, keyId: string, newKeyValue: string): Promise<void> {\n const data = await this.loadData(orgId);\n const key = data.find((k) => k.key_id === keyId);\n if (key) {\n key.key_value = newKeyValue;\n await this.saveData(orgId, data);\n }\n }\n\n async list(orgId: string): Promise<StoredApiKey[]> {\n return this.loadData(orgId);\n }\n\n async get(orgId: string, keyId: string): Promise<StoredApiKey | null> {\n const data = await this.loadData(orgId);\n return data.find((k) => k.key_id === keyId) ?? null;\n }\n}\n","import { readFile, writeFile, mkdir, chmod } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { homedir } from 'node:os';\nimport { AppConfig } from '../types/config.js';\nimport { ConfigError, ValidationError } from '../errors/errors.js';\n\n// §6 target routing: each product line is served under its own prefix\n// (/api/{line}/v1). The prefix is a per-binary constant injected into\n// ConfigManager (see constructor `apiPath`), NOT a single shared value — the\n// four CLIs hit different product lines under one shared api_host.\n// This default is the admin control-plane prefix; other CLIs override it.\nconst DEFAULT_API_PATH = '/api/admin/v1';\n\nconst DEFAULT_CONFIG: AppConfig = {\n active_org: null,\n active_developer_id: null,\n api_host: 'https://agent.everonet.com',\n api_path: DEFAULT_API_PATH,\n};\n\nexport const BUILTIN_PROFILES: Record<string, string> = {\n production: 'https://agent.everonet.com',\n testing: 'https://agent-test.everonet.com',\n};\n\n/**\n * Resolve a user-supplied host argument (a built-in profile name or an\n * explicit URL) to the concrete API host URL that gets persisted.\n * Pure (no I/O) so callers can compute the resolved value before/without a\n * config write — e.g. `config set-host` needs it to match stored credentials\n * by their resolved `api_host` rather than the raw profile name.\n * Throws `ValidationError` for unknown profiles / malformed URLs.\n */\nexport function resolveApiHost(host: string): string {\n if (BUILTIN_PROFILES[host]) {\n return BUILTIN_PROFILES[host];\n }\n\n let url: URL;\n try {\n url = new URL(host);\n } catch {\n throw new ValidationError(`Unknown profile or invalid URL: ${host}`);\n }\n\n if (url.protocol === 'https:') {\n return host;\n }\n\n if (\n url.protocol === 'http:'\n && (url.hostname === 'localhost' || url.hostname === '127.0.0.1')\n ) {\n return host;\n }\n\n // Allow HTTP for Docker internal container-to-container traffic (gated by env var)\n if (url.protocol === 'http:' && process.env.AGENZO_ALLOW_INSECURE_HOST === '1') {\n return host;\n }\n\n throw new ValidationError(\n `Insecure API host is not allowed: ${host}. Use HTTPS, except for localhost or 127.0.0.1.`,\n );\n}\n\nexport class ConfigManager {\n private readonly basePath: string;\n private readonly configPath: string;\n /**\n * Product-line API prefix this CLI targets (e.g. /api/admin/v1,\n * /api/token/v1). Injected per binary so the four CLIs share one api_host\n * but route to different product lines. Overrides any persisted api_path.\n */\n private readonly apiPath: string;\n\n constructor(basePath?: string, apiPath?: string) {\n this.basePath = basePath ?? join(homedir(), '.agenzo-admin-cli');\n this.configPath = join(this.basePath, 'config.json');\n this.apiPath = apiPath ?? DEFAULT_API_PATH;\n }\n\n /** The resolved product-line API prefix for this CLI (per-binary constant). */\n getApiPath(): string {\n return this.apiPath;\n }\n\n async ensureDirectories(): Promise<void> {\n // Base dir contains the credentials/ subtree → owner-only (0700).\n await mkdir(this.basePath, { recursive: true, mode: 0o700 });\n await chmod(this.basePath, 0o700);\n const credDir = join(this.basePath, 'credentials');\n await mkdir(credDir, { recursive: true, mode: 0o700 });\n await chmod(credDir, 0o700);\n }\n\n async load(): Promise<AppConfig> {\n try {\n const content = await readFile(this.configPath, 'utf-8');\n try {\n const raw = JSON.parse(content) as Record<string, unknown>;\n // Migrate old api_base_url format\n if (raw.api_base_url && !raw.api_host) {\n const url = String(raw.api_base_url);\n const pathIndex = url.indexOf('/api/');\n raw.api_host = pathIndex > 0 ? url.slice(0, pathIndex) : url;\n raw.api_path = pathIndex > 0 ? url.slice(pathIndex) : DEFAULT_CONFIG.api_path;\n delete raw.api_base_url;\n }\n return {\n active_org: (raw.active_org as string) ?? null,\n active_developer_id: (raw.active_developer_id as string) ?? null,\n api_host: (raw.api_host as string) ?? DEFAULT_CONFIG.api_host,\n api_path: (raw.api_path as string) ?? DEFAULT_CONFIG.api_path,\n };\n } catch {\n throw new ConfigError(\n `Invalid config file: ${this.configPath}`,\n this.configPath,\n );\n }\n } catch (error) {\n if (error instanceof ConfigError) throw error;\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return { ...DEFAULT_CONFIG };\n }\n throw error;\n }\n }\n\n async save(config: AppConfig): Promise<void> {\n await this.ensureDirectories();\n await writeFile(this.configPath, JSON.stringify(config, null, 2), {\n encoding: 'utf-8',\n mode: 0o600,\n });\n await chmod(this.configPath, 0o600);\n }\n\n async getActiveOrg(): Promise<string | null> {\n const config = await this.load();\n return config.active_org;\n }\n\n async setActiveOrg(orgId: string): Promise<void> {\n const config = await this.load();\n config.active_org = orgId;\n await this.save(config);\n }\n\n async getApiBaseUrl(): Promise<string> {\n const config = await this.load();\n const host = resolveApiHost(config.api_host).replace(/\\/+$/, '');\n // Use the per-binary product-line prefix, not the persisted api_path —\n // the latter is shared across all CLIs and would route every binary to the\n // same product line. The injected prefix overrides any stale stored value.\n const path = this.apiPath.startsWith('/') ? this.apiPath : `/${this.apiPath}`;\n return `${host}${path}`;\n }\n\n async setApiHost(host: string): Promise<void> {\n const config = await this.load();\n config.api_host = resolveApiHost(host);\n await this.save(config);\n }\n\n async getApiHost(): Promise<string> {\n const config = await this.load();\n return resolveApiHost(config.api_host);\n }\n}\n","import { CliError } from '../errors/errors.js';\n\n/**\n * Exit-code mapper (cli-design §8.6 / cli-standard §5.4).\n *\n * Maps any thrown error reaching the top-level handler to one of the CLI's\n * non-zero exit codes. Normal completion implies `0` and never consults this.\n *\n * 1 — business / param: PARAM_* / RESOURCE_* / BILLING_* / ACCOUNT_* /\n * PAYMENT_ORDER_* / TOKEN_* / SERVICE_* / ride codes / CLIENT_* /\n * NOT_IMPLEMENTED, and unknown errors\n * 2 — upgrade required: UPGRADE_REQUIRED\n * 3 — auth-fail / invalid-key: AUTH_* / KEY_*\n * 4 — network / 5xx: UPSTREAM_ERROR / INTERNAL_ERROR / RATE_LIMITED\n * 5 — user-cancel: CLIENT_ABORTED\n */\nexport function exitCodeFor(error: unknown): 1 | 2 | 3 | 4 | 5 {\n if (!(error instanceof CliError)) {\n return 1;\n }\n\n const code = error.code;\n\n if (code === 'UPGRADE_REQUIRED') {\n return 2;\n }\n\n if (code === 'CLIENT_ABORTED') {\n return 5;\n }\n\n if (code.startsWith('AUTH_') || code.startsWith('KEY_')) {\n return 3;\n }\n\n if (\n code === 'UPSTREAM_ERROR' ||\n code === 'INTERNAL_ERROR' ||\n code === 'RATE_LIMITED'\n ) {\n return 4;\n }\n\n return 1;\n}\n","export type StatusPrefix = 'success' | 'error' | 'info' | 'warning' | 'loading';\n\nconst STATUS_ICONS: Record<StatusPrefix, string> = {\n success: '✓',\n error: '✗',\n info: 'ℹ',\n warning: '⚠',\n loading: '⠋',\n};\n\nconst SPINNER_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];\n\nexport interface Spinner {\n /** Update the spinner message while it's running */\n update(message: string): void;\n /** Stop the spinner and show a final status line */\n stop(type?: StatusPrefix, finalMessage?: string): void;\n}\n\n/**\n * Creates an animated terminal spinner that cycles through braille frames.\n * Call `spinner.stop()` when the async work is done.\n */\nexport function createSpinner(message: string, intervalMs = 60): Spinner {\n let frameIdx = 0;\n let currentMessage = message;\n\n const render = () => {\n process.stdout.write(`\\r\\x1b[K${SPINNER_FRAMES[frameIdx]} ${currentMessage}`);\n frameIdx = (frameIdx + 1) % SPINNER_FRAMES.length;\n };\n\n render();\n const timer = setInterval(render, intervalMs);\n\n return {\n update(msg: string) {\n currentMessage = msg;\n },\n stop(type?: StatusPrefix, finalMessage?: string) {\n clearInterval(timer);\n process.stdout.write('\\r\\x1b[K');\n if (type && finalMessage) {\n console.log(Formatter.status(type, finalMessage));\n }\n },\n };\n}\n\nexport class Formatter {\n /** Get display width of a string (CJK characters count as 2) */\n private static displayWidth(str: string): number {\n let width = 0;\n for (const char of str) {\n const code = char.codePointAt(0)!;\n // CJK Unified Ideographs and common fullwidth ranges\n if (\n (code >= 0x4e00 && code <= 0x9fff) || // CJK Unified\n (code >= 0x3000 && code <= 0x303f) || // CJK Punctuation\n (code >= 0x3400 && code <= 0x4dbf) || // CJK Extension A\n (code >= 0xff00 && code <= 0xffef) || // Fullwidth Forms\n (code >= 0xf900 && code <= 0xfaff) || // CJK Compatibility\n (code >= 0x20000 && code <= 0x2a6df) // CJK Extension B\n ) {\n width += 2;\n } else {\n width += 1;\n }\n }\n return width;\n }\n\n /** Pad string to target display width (right-pad with spaces) */\n private static padEndDisplay(str: string, targetWidth: number): string {\n const currentWidth = Formatter.displayWidth(str);\n const padding = Math.max(0, targetWidth - currentWidth);\n return str + ' '.repeat(padding);\n }\n\n /** Pad string to target display width (left-pad with spaces) */\n private static padStartDisplay(str: string, targetWidth: number): string {\n const currentWidth = Formatter.displayWidth(str);\n const padding = Math.max(0, targetWidth - currentWidth);\n return ' '.repeat(padding) + str;\n }\n\n /** Table output for list commands — columns aligned by max width */\n static table(headers: string[], rows: string[][]): string {\n const colWidths = headers.map((h, i) => {\n const cellWidths = rows.map((r) => Formatter.displayWidth(r[i] ?? ''));\n return Math.max(Formatter.displayWidth(h), ...cellWidths);\n });\n\n const sep = ' ';\n\n const headerLine = headers.map((h, i) => Formatter.padEndDisplay(h, colWidths[i])).join(sep);\n const divider = colWidths.map((w) => '-'.repeat(w)).join(sep);\n const dataLines = rows.map((row) =>\n row.map((cell, i) => Formatter.padEndDisplay(cell ?? '', colWidths[i])).join(sep),\n );\n\n return [headerLine, divider, ...dataLines].join('\\n');\n }\n\n /** Key-value output for detail commands — keys left-aligned */\n static keyValue(entries: [string, string][]): string {\n const maxKeyWidth = Math.max(...entries.map(([k]) => Formatter.displayWidth(k)));\n return entries\n .map(([key, value]) => `${Formatter.padEndDisplay(key, maxKeyWidth)} ${value}`)\n .join('\\n');\n }\n\n /** Status-prefixed message */\n static status(type: StatusPrefix, message: string): string {\n return `${STATUS_ICONS[type]} ${message}`;\n }\n\n /** Mask sensitive info, keeping only the prefix */\n static maskKey(key: string, prefixLength = 8): string {\n if (key.length <= prefixLength) {\n return key;\n }\n return key.slice(0, prefixLength) + '*'.repeat(key.length - prefixLength);\n }\n\n /**\n * Format ISO 8601 timestamp to local timezone display.\n * Automatically uses the user's system timezone.\n * e.g. \"2026-05-07T03:24:53+00:00\" → \"2026-05-07 11:24:53\" (in CST)\n * \"2026-05-07T03:24:53+00:00\" → \"2026-05-06 20:24:53\" (in PDT)\n * Returns the original string if parsing fails or input is empty.\n */\n static formatTime(iso: string | null | undefined): string {\n if (!iso) return '';\n const date = new Date(iso);\n if (isNaN(date.getTime())) return iso;\n const pad = (n: number) => String(n).padStart(2, '0');\n const y = date.getFullYear();\n const m = pad(date.getMonth() + 1);\n const d = pad(date.getDate());\n const h = pad(date.getHours());\n const min = pad(date.getMinutes());\n const s = pad(date.getSeconds());\n const offsetMin = -date.getTimezoneOffset();\n const sign = offsetMin >= 0 ? '+' : '-';\n const absOffset = Math.abs(offsetMin);\n const tzH = pad(Math.floor(absOffset / 60));\n const tzM = pad(absOffset % 60);\n return `${y}-${m}-${d} ${h}:${min}:${s} (UTC${sign}${tzH}:${tzM})`;\n }\n}\n","import type { CommandResult } from '../types/commands.js';\nimport { Formatter, type StatusPrefix } from './formatter.js';\n\n/**\n * Central output renderer.\n *\n * Single choke point that turns a {@link CommandResult} into stdout bytes,\n * switching between machine-readable JSON and a human-readable table view.\n * This is what lets command handlers stop calling `console.log` directly:\n * they build a `CommandResult` and hand it here.\n *\n * Contract (cli-standard §5.1/§5.2):\n * - stdout carries ONLY the business payload — a single JSON value\n * (`--format json`) or human-readable text (`--format table`).\n * - logs, spinners, prompts, hints and progress lines belong on stderr and\n * are NEVER written here.\n *\n * Recorded deviation from cli-standard §5.1: the default format is `table`\n * (not `json`), and the flag values are `json | table` (not `json | text`).\n */\n\n/** The two supported output formats. */\nexport type OutputFormat = 'json' | 'table';\n\n/** Options consumed by {@link render}. */\nexport interface RenderOptions {\n format: OutputFormat;\n}\n\n/** The default format used when nothing valid is supplied (deliberate deviation: `table`). */\nconst DEFAULT_FORMAT: OutputFormat = 'table';\n\n/** Narrow an arbitrary string to a known {@link OutputFormat}. */\nfunction isOutputFormat(value: string): value is OutputFormat {\n return value === 'json' || value === 'table';\n}\n\n/**\n * Resolve the active output format.\n *\n * Precedence: `--format` flag > `AGENZO_FORMAT` env var > default `table`.\n * Any invalid value falls back to the default. The result is always one of\n * `'json' | 'table'`.\n *\n * The `--format` flag is authoritative when provided: a provided-but-invalid\n * flag falls back to the default rather than deferring to the environment.\n */\nexport function resolveFormat(\n flag?: string,\n env: string | undefined = process.env.AGENZO_FORMAT,\n): OutputFormat {\n // 1. --format flag is authoritative when provided.\n if (flag !== undefined) {\n return isOutputFormat(flag) ? flag : DEFAULT_FORMAT;\n }\n // 2. AGENZO_FORMAT environment value, when set to a valid format.\n if (env !== undefined && isOutputFormat(env)) {\n return env;\n }\n // 3. Default.\n return DEFAULT_FORMAT;\n}\n\n/**\n * Emit a successful command result to stdout in the chosen format.\n *\n * - `json`: writes `JSON.stringify(result.data, null, 2)` (the machine payload\n * only — never the text-mode chrome).\n * - `table`: writes the lazy human presenter `result.text()`.\n *\n * Only the payload reaches stdout; status/progress lines must go to stderr by\n * the caller. A trailing newline is appended so the output pipes cleanly into\n * tools like `jq`.\n */\nexport function render<T>(result: CommandResult<T>, opts: RenderOptions): void {\n if (opts.format === 'json') {\n process.stdout.write(`${JSON.stringify(result.data, null, 2)}\\n`);\n return;\n }\n process.stdout.write(`${result.text()}\\n`);\n}\n\n/**\n * Emit a human-facing status line (✓ / ℹ / ⚠) to stderr — but ONLY in `table`\n * mode. In `json` mode the output is consumed by other agents/scripts, so any\n * decorative status text (even on stderr) is noise that can confuse parsing;\n * `json` mode therefore stays completely silent here. Errors are NOT routed\n * through this helper — they are owned by the top-level handler in index.ts.\n *\n * This is the single choke point for command success/progress notices, so the\n * `json`-silence rule is enforced in one place rather than scattered across\n * every handler.\n */\nexport function notify(\n format: OutputFormat,\n type: StatusPrefix,\n message: string,\n): void {\n if (format === 'json') {\n return;\n }\n console.error(Formatter.status(type, message));\n}\n","/**\n * Shared JSON envelope renderer (cli-design §7.7.2 BACK-011).\n *\n * In `--format json` mode, every command's payload is prefixed with two\n * client-assembled context fields:\n * - `profile`: the active environment name (production / testing / custom),\n * derived by reverse-looking-up the api_host in BUILTIN_PROFILES.\n * - `endpoint`: the api **host only** (e.g. https://agent.everonet.com) —\n * NEVER the internal API path (/api/admin/v1), so internal\n * routing is not leaked to agent consumers.\n *\n * `result.data` is expected to be an object (single-resource payloads are flat\n * field maps; list payloads are `{ <namedKey>: [...], page: {...} }`). The two\n * context fields are spread in front of it.\n *\n * In `--format table` mode this is a passthrough to the standard `render`.\n *\n * This lives in `@agenzo/cli-core` (BACK-011) so every CLI shares one\n * implementation rather than copying it per app.\n */\nimport type { CommandResult } from '../types/commands.js';\nimport { type RenderOptions, render } from './output.js';\nimport { ConfigManager, BUILTIN_PROFILES } from '../config/config-manager.js';\n\nexport async function renderWithContext<T>(\n result: CommandResult<T>,\n opts: RenderOptions,\n configManager: ConfigManager,\n): Promise<void> {\n if (opts.format !== 'json') {\n render(result, opts);\n return;\n }\n\n const config = await configManager.load();\n const host = config.api_host.replace(/\\/+$/, '');\n const profile =\n Object.entries(BUILTIN_PROFILES).find(([, v]) => v === host)?.[0] ?? 'custom';\n\n const dataObj =\n result.data && typeof result.data === 'object'\n ? (result.data as Record<string, unknown>)\n : { value: result.data };\n\n const payload = {\n profile,\n endpoint: host,\n ...dataObj,\n };\n\n render({ ...result, data: payload } as CommandResult<typeof payload>, opts);\n}\n","import { input, password, select } from '@inquirer/prompts';\n\ninterface PromptConfig {\n message: string;\n type?: 'input' | 'password' | 'select';\n choices?: { name: string; value: string }[];\n validate?: (input: string) => boolean | string;\n}\n\nexport class PromptEngine {\n /** Return flagValue directly if provided, otherwise prompt interactively */\n static async resolveInput(\n flagValue: string | undefined,\n config: PromptConfig,\n ): Promise<string> {\n if (flagValue !== undefined) {\n return flagValue;\n }\n\n if (config.type === 'password') {\n return password({ message: config.message, mask: '*' });\n }\n\n if (config.type === 'select' && config.choices) {\n return select({\n message: config.message,\n choices: config.choices,\n });\n }\n\n return input({\n message: config.message,\n validate: config.validate,\n });\n }\n}\n","import { password } from '@inquirer/prompts';\nimport { PromptEngine } from '@agenzo/cli-core';\n\n// ============================================================\n// Payment-method interactive prompts (token-cli domain)\n// ============================================================\n//\n// These were relocated out of @agenzo/cli-core's PromptEngine: collecting card\n// number / expiry / CVV is token-cli payment-method business, not a generic\n// interactive fallback. cli-core keeps only the general `PromptEngine.resolveInput`.\n\n/** Always collect CVV interactively with masked display. */\nexport async function collectCvv(): Promise<string> {\n return password({\n message: 'CVV:',\n mask: '*',\n });\n}\n\n/** Collect payment method params based on type. */\nexport async function collectPaymentMethodParams(\n type: string,\n flags: Record<string, string | undefined>,\n): Promise<Record<string, string>> {\n const params: Record<string, string> = { type };\n\n const email = await PromptEngine.resolveInput(flags.cardEmail ?? flags.email, {\n message: 'Email (for 3DS verification):',\n });\n params.email = email;\n\n if (type === 'card') {\n params.card_number = await PromptEngine.resolveInput(flags.cardNumber, {\n message: 'Card number:',\n });\n params.expiry_date = await PromptEngine.resolveInput(flags.expiry, {\n message: 'Expiry (MMYY):',\n });\n // CVV: use flag if provided, otherwise collect interactively\n if (flags.cvv) {\n params.cvv = flags.cvv;\n } else {\n params.cvv = await collectCvv();\n }\n }\n\n return params;\n}\n","/**\n * `--help --format json` verb-level schema (§4.4.1.3 pattern) — token domain.\n *\n * Mirrors `apps/merchant-cli/src/verb-schema.ts`: every payment-methods /\n * payment-tokens verb supports `--help --format json`, which prints a single\n * machine-readable JSON object describing the verb instead of commander's\n * default text help. This is how an Agent discovers a verb's flags, response\n * shape, and example invocation locally, without a network round-trip.\n *\n * Before this file existed, token-cli's `--help` always rendered commander's\n * default TEXT help regardless of `--format json` — the orchestrator's tool\n * discovery (`agenzo-agent-orchestrator/app/providers/cli_provider.py`) could\n * not parse it as JSON, so every payment-methods / payment-tokens verb was\n * silently dropped from the LLM's tool list (`cli_provider.verb_schema_skip`).\n * A user typing \"bind card\" / \"add a card\" in chat would hit an LLM with NO\n * card-binding tool available — even though the underlying CLI command works\n * fine when invoked directly, and the deterministic \"Add card\" button UI\n * (dropin-session flow) bypasses tool discovery entirely and was never\n * affected. This file closes that gap for the LLM tool-discovery path only.\n *\n * Mechanism (commander v14): `attachSchemaHelp` overrides a command's\n * `helpInformation`. Commander resolves `--help` BEFORE later argv tokens are\n * applied to options, so the parsed `--format` value is not yet available when\n * help renders — we therefore read it straight from `process.argv`. Only an\n * explicit `--format json` switches to the JSON schema; bare `--help` and\n * `--help --format table` keep commander's default text help.\n */\nimport type { Command } from 'commander';\n\nconst CLI_NAME = 'agenzo-token-cli';\nexport const PAYMENT_METHODS_NOUN = 'payment-methods';\nexport const PAYMENT_TOKENS_NOUN = 'payment-tokens';\n\n// ============================================================\n// Schema shape (kept identical to merchant-cli's VerbSchema)\n// ============================================================\n\n/** One flag descriptor: type / required / optional default / description / constraints. */\nexport interface FlagSchema {\n type: string;\n /** `true` / `false`, or the literal `'conditional'` for mode-dependent flags. */\n required: boolean | 'conditional';\n default?: unknown;\n description: string;\n constraints?: string;\n}\n\n/** A complete, copy-pasteable example invocation plus what to read from the output. */\nexport interface ExampleSchema {\n command: string;\n output_summary: string;\n}\n\n/**\n * The verb-level schema object emitted by `--help --format json`:\n * `{ cli, noun, verb, description, flags, response, example, [error_recovery] }`.\n */\nexport interface VerbSchema {\n cli: string;\n noun: string;\n verb: string;\n description: string;\n flags: Record<string, FlagSchema>;\n response: Record<string, unknown>;\n example: ExampleSchema;\n error_recovery?: Record<string, string>;\n}\n\n// ============================================================\n// Emit + attach mechanism (identical to merchant-cli)\n// ============================================================\n\nexport function wantsJsonSchema(argv: string[] = process.argv): boolean {\n for (let i = 0; i < argv.length; i++) {\n const a = argv[i];\n if (a === '--format=json') return true;\n if (a === '--format' && argv[i + 1] === 'json') return true;\n }\n return false;\n}\n\n/** Print a verb schema as a single pretty-printed JSON object to stdout. */\nexport function emitSchema(schema: VerbSchema): void {\n console.log(JSON.stringify(schema, null, 2));\n}\n\n/**\n * Attach `--help --format json` schema output to a command. When help is\n * requested with an explicit `--format json`, the schema is printed to stdout\n * and an empty string is returned so commander prints nothing further and exits\n * cleanly. Otherwise the original (text) help is rendered unchanged.\n */\nexport function attachSchemaHelp(cmd: Command, schema: VerbSchema): Command {\n const baseHelp = cmd.helpInformation.bind(cmd);\n cmd.helpInformation = (context) => {\n if (!wantsJsonSchema()) return baseHelp(context);\n emitSchema(schema);\n return '';\n };\n return cmd;\n}\n\n// ============================================================\n// payment-methods verb schemas\n// ============================================================\n\n/** `payment-methods add` schema. Write op (W/Y in manual mode; dropin mode is non-blocking). */\nexport const pmAddSchema: VerbSchema = {\n cli: CLI_NAME,\n noun: PAYMENT_METHODS_NOUN,\n verb: 'add',\n description: 'Add a payment method (manual 3DS or Drop-in session)',\n flags: {\n type: { type: 'string', required: false, default: 'card', description: 'Payment method type' },\n mode: {\n type: 'string',\n required: false,\n default: 'manual',\n description:\n '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 — use this mode when the user wants to bind/add a card from chat)',\n constraints: 'manual | dropin',\n },\n email: {\n type: 'string',\n required: 'conditional',\n description:\n \"Manual mode: email for 3DS verification. Dropin mode: email used as the Drop-in session reference. Use the user's login profile email — never ask in chat.\",\n },\n 'idempotency-key': {\n type: 'string',\n required: false,\n description: 'Idempotency key forwarded verbatim as the Idempotency-Key header (manual mode only)',\n },\n 'no-poll': {\n type: 'bool',\n required: false,\n default: false,\n description:\n '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.',\n },\n },\n response: {\n id: { type: 'string', description: 'Payment method id' },\n session_id: { type: 'string|absent', description: 'Drop-in session id (dropin mode only) — pass to the front-end Drop-in SDK, never read aloud to the user' },\n status: { type: 'string', description: 'PENDING | ACTIVE | FAILED | EXPIRED' },\n brand: { type: 'string|absent', description: 'Card brand, once known' },\n last4: { type: 'string|absent', description: 'Card last 4 digits, once known' },\n },\n example: {\n command: 'agenzo-token-cli payment-methods add --mode dropin --email user@example.com --no-poll',\n output_summary:\n 'Dropin mode returns { id, session_id }. Never read card numbers/CVV/expiry to or from the user (PCI) — the Drop-in SDK collects them securely.',\n },\n error_recovery: {\n PARAM_INVALID: 'Fix the offending flag (mode must be \"manual\" or \"dropin\"), then retry.',\n },\n};\n\n/** `payment-methods list` schema. Read-only. */\nexport const pmListSchema: VerbSchema = {\n cli: CLI_NAME,\n noun: PAYMENT_METHODS_NOUN,\n verb: 'list',\n description: 'List payment methods',\n flags: {\n member: { type: 'string', required: false, description: 'Filter by member ID' },\n },\n response: {\n payment_methods: {\n type: 'array',\n description: 'Payment methods for the developer (optionally scoped to --member)',\n items: {\n id: { type: 'string', description: 'Payment method id' },\n type: { type: 'string', description: 'Payment method type (e.g. card)' },\n status: { type: 'string', description: 'PENDING | ACTIVE | FAILED | DISABLED | EXPIRED' },\n brand: { type: 'string|null', description: 'Card brand' },\n first6: { type: 'string|null', description: 'Card first 6 digits' },\n last4: { type: 'string|null', description: 'Card last 4 digits' },\n },\n },\n },\n example: {\n command: 'agenzo-token-cli payment-methods list',\n output_summary: 'Returns payment_methods[]. Check for status=ACTIVE before assuming the user has a usable card.',\n },\n};\n\n/** `payment-methods get <pm_id>` schema. Read-only. */\nexport const pmGetSchema: VerbSchema = {\n cli: CLI_NAME,\n noun: PAYMENT_METHODS_NOUN,\n verb: 'get',\n description: 'Get a payment method by ID',\n flags: {\n pm_id: { type: 'string', required: true, description: 'Payment method id (positional argument)' },\n },\n response: {\n id: { type: 'string', description: 'Payment method id' },\n type: { type: 'string', description: 'Payment method type' },\n status: { type: 'string', description: 'PENDING | ACTIVE | FAILED | DISABLED | EXPIRED' },\n brand: { type: 'string|null', description: 'Card brand' },\n first6: { type: 'string|null', description: 'Card first 6 digits' },\n last4: { type: 'string|null', description: 'Card last 4 digits' },\n created_at: { type: 'string', description: 'Creation time' },\n },\n example: {\n command: 'agenzo-token-cli payment-methods get pm_01H...',\n output_summary: 'Returns the payment method detail including status.',\n },\n};\n\n/** `payment-methods disable <pm_id>` schema. Write op (W/Y). */\nexport const pmDisableSchema: VerbSchema = {\n cli: CLI_NAME,\n noun: PAYMENT_METHODS_NOUN,\n verb: 'disable',\n description: 'Disable a payment method',\n flags: {\n pm_id: { type: 'string', required: true, description: 'Payment method id (positional argument)' },\n 'idempotency-key': {\n type: 'string',\n required: true,\n description: 'Idempotency key forwarded verbatim as the Idempotency-Key header',\n },\n },\n response: {\n status: { type: 'string', description: 'Status after disabling (typically DISABLED)' },\n revoked_tokens_count: { type: 'int', description: 'Number of payment tokens revoked as a side effect' },\n },\n example: {\n command: 'agenzo-token-cli payment-methods disable pm_01H... --idempotency-key disable-123',\n output_summary: 'Disables the card and revokes any payment tokens issued against it. Only use when the user explicitly requests it.',\n },\n error_recovery: {\n PARAM_IDEMPOTENCY_KEY_REQUIRED: 'Supply --idempotency-key (1-128 chars [A-Za-z0-9_-]); the CLI never generates one under --yes.',\n },\n};\n\n// ============================================================\n// payment-tokens verb schemas\n// ============================================================\n\n/** `payment-tokens create` schema. Write op (W/Y). */\nexport const ptCreateSchema: VerbSchema = {\n cli: CLI_NAME,\n noun: PAYMENT_TOKENS_NOUN,\n verb: 'create',\n description: 'Create a payment token (VCN / Network Token / X402)',\n flags: {\n type: { type: 'string', required: true, description: 'Token type', constraints: 'vcn | network-token | x402' },\n 'payment-method-id': { type: 'string', required: 'conditional', description: 'Payment method ID to use (or resolved via --card / auto-select from ACTIVE cards)' },\n card: { type: 'string', required: false, description: 'Match payment method by last 4 digits' },\n member: { type: 'string', required: false, description: 'Member ID' },\n amount: { type: 'string', required: 'conditional', description: 'Amount in USD (vcn) or USDC (x402)' },\n currency: { type: 'string', required: false, description: 'Currency (vcn only; server default applies if omitted)' },\n 'pay-to': { type: 'string', required: 'conditional', description: 'Pay-to address (x402 only)' },\n nonce: { type: 'string', required: 'conditional', description: 'Nonce (x402 only)' },\n network: { type: 'string', required: 'conditional', description: 'Network (x402 only)' },\n deadline: { type: 'string', required: 'conditional', description: 'Deadline as a Unix timestamp in seconds (x402 only)' },\n 'external-tx-id': { type: 'string', required: false, description: 'External transaction ID' },\n 'idempotency-key': {\n type: 'string',\n required: true,\n description: 'Idempotency key forwarded verbatim as the Idempotency-Key header',\n },\n },\n response: {\n id: { type: 'string', description: 'Payment token id' },\n type: { type: 'string', description: 'vcn | network_token | x402' },\n status: { type: 'string', description: 'Token status' },\n },\n example: {\n command: 'agenzo-token-cli payment-tokens create --type vcn --card 1234 --amount 25.00 --idempotency-key tok-123',\n output_summary: 'Creates a token; response shape varies by type (nested under vcn / network_token / x402).',\n },\n error_recovery: {\n TOKEN_FEATURE_DISABLED: 'This token type is not enabled yet. Tell the user and suggest an alternative type if applicable.',\n CLIENT_NO_PAYMENT_METHOD: 'The user has no ACTIVE payment method. Guide them to add one first (payment-methods add --mode dropin).',\n CLIENT_CARD_NOT_MATCHED: 'The --card last-4 did not match any ACTIVE card. Call payment-methods list to see available cards.',\n },\n};\n\n/** `payment-tokens list` schema. Read-only. */\nexport const ptListSchema: VerbSchema = {\n cli: CLI_NAME,\n noun: PAYMENT_TOKENS_NOUN,\n verb: 'list',\n description: 'List payment tokens',\n flags: {\n type: { type: 'string', required: false, description: 'Filter by token type' },\n member: { type: 'string', required: false, description: 'Filter by member ID' },\n },\n response: {\n payment_tokens: {\n type: 'array',\n description: 'Payment tokens for the developer (optionally filtered)',\n items: {\n id: { type: 'string', description: 'Token id' },\n type: { type: 'string', description: 'vcn | network_token | x402' },\n status: { type: 'string', description: 'Token status' },\n },\n },\n },\n example: {\n command: 'agenzo-token-cli payment-tokens list --type vcn',\n output_summary: 'Returns payment_tokens[].',\n },\n};\n\n/** `payment-tokens get <payment_token_id>` schema. Read-only. */\nexport const ptGetSchema: VerbSchema = {\n cli: CLI_NAME,\n noun: PAYMENT_TOKENS_NOUN,\n verb: 'get',\n description: 'Get a payment token by ID',\n flags: {\n payment_token_id: { type: 'string', required: true, description: 'Payment token id (positional argument)' },\n reveal: {\n type: 'bool',\n required: false,\n default: false,\n 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.',\n },\n },\n response: {\n id: { type: 'string', description: 'Token id' },\n type: { type: 'string', description: 'vcn | network_token | x402' },\n status: { type: 'string', description: 'Token status' },\n },\n example: {\n command: 'agenzo-token-cli payment-tokens get pt_01H...',\n output_summary: 'Returns the token detail. VCN PAN/CVC are masked unless --reveal is set.',\n },\n};\n\n/** `payment-tokens revoke <payment_token_id>` schema. Write op (W/Y). */\nexport const ptRevokeSchema: VerbSchema = {\n cli: CLI_NAME,\n noun: PAYMENT_TOKENS_NOUN,\n verb: 'revoke',\n description: 'Revoke a payment token',\n flags: {\n payment_token_id: { type: 'string', required: true, description: 'Payment token id (positional argument)' },\n 'idempotency-key': {\n type: 'string',\n required: true,\n description: 'Idempotency key forwarded verbatim as the Idempotency-Key header',\n },\n },\n response: {\n id: { type: 'string', description: 'Token id' },\n status: { type: 'string', description: 'Status after revocation' },\n revoked_at: { type: 'string|absent', description: 'Revocation time (immediate revoke)' },\n expires_at: { type: 'string|absent', description: 'Expiry time (delayed revoke — x402 cryptogram auto-expires)' },\n },\n example: {\n command: 'agenzo-token-cli payment-tokens revoke pt_01H... --idempotency-key revoke-123',\n output_summary: 'Revokes the token immediately, or schedules a delayed revoke for x402 (status stays ACTIVE until expires_at).',\n },\n error_recovery: {\n PARAM_IDEMPOTENCY_KEY_REQUIRED: 'Supply --idempotency-key (1-128 chars [A-Za-z0-9_-]); the CLI never generates one under --yes.',\n },\n};\n","import { Command } from 'commander';\nimport {\n ApiClient,\n ConfigManager,\n PromptEngine,\n Formatter,\n resolveFormat,\n notify,\n CliError,\n IdempotencyKeyRequiredError,\n renderWithContext,\n} from '@agenzo/cli-core';\nimport type { CommandResult, OutputFormat } from '@agenzo/cli-core';\nimport type { DropinCreateResponse, PaymentMethod } from '../types/api.js';\nimport { collectPaymentMethodParams } from './prompts.js';\nimport { attachSchemaHelp, pmAddSchema } from '../verb-schema.js';\n\n// ============================================================\n// Constants\n// ============================================================\n\n// Manual mode (3DS via email): the user clicks the magic link in their\n// inbox, so polling is short and tight.\nconst MANUAL_POLL_INTERVAL_MS = 3000;\nconst MANUAL_POLL_TIMEOUT_MS = 15 * 60 * 1000; // 15 minutes\n\n// Drop-in mode (v3): the add-payment-method form is rendered by the Drop-in\n// SDK inside the developer's own front-end, so the operator may need longer\n// to finish in the browser. The backend flips the PM to EXPIRED if the user\n// does not complete in time.\nconst DROPIN_POLL_INTERVAL_MS = 5000;\nconst DROPIN_POLL_TIMEOUT_MS = 30 * 60 * 1000; // 30 minutes\n\n// Backend writes one of these into PaymentMethod.status when the verification\n// flow reaches a final state. We stop polling on any of them. EXPIRED only\n// ever applies to dropin PMs (manual PMs never expire server-side).\nconst TERMINAL_STATUSES = new Set(['ACTIVE', 'FAILED', 'EXPIRED']);\n\ntype AddDeps = { apiClient: ApiClient };\n\n// ============================================================\n// Command registration\n// ============================================================\n\n/**\n * `payment-methods add` — add a payment method (§3.4.0.1).\n *\n * Two modes, selected via `--mode`:\n *\n * - `manual` (default): the CLI collects card details (--email / --card-number\n * / --expiry / --cvv), POSTs /payment-methods/create, then polls 3DS\n * verification until ACTIVE / FAILED / 15-minute timeout.\n * - `dropin`: the CLI mints a Drop-in session (POST /payment-methods/dropin/create\n * with the developer email), prints the session id so the caller can render\n * the add-payment UI in their own front-end via the Drop-in SDK, then polls\n * the same verification/status endpoint until ACTIVE / FAILED / EXPIRED /\n * 30-minute timeout. No card details / idempotency key are needed.\n */\nexport function registerAddCommand(parent: Command, deps: AddDeps): void {\n const cmd = parent\n .command('add')\n .description('Add a payment method (manual 3DS or Drop-in session)')\n .option('--api-key <key>', 'API Key for authentication')\n .option('--type <type>', 'Payment method type (default: card)', 'card')\n .option(\n '--mode <mode>',\n 'Add mode: \"manual\" (default; CLI collects card details and polls 3DS) or \"dropin\" (mint a Drop-in session and poll until the user finishes adding the payment method in the browser)',\n 'manual',\n )\n .option(\n '--email <email>',\n 'Manual mode: email for 3DS verification. Dropin mode: email used as the Drop-in session reference.',\n )\n .option('--card-number <number>', 'Card number (manual mode only)')\n .option('--expiry <mmyy>', 'Expiry date (MMYY format) (manual mode only)')\n .option('--cvv <cvv>', 'Card CVV (manual mode only)')\n .option(\n '--idempotency-key <key>',\n 'Idempotency key forwarded verbatim as the Idempotency-Key header (manual mode only)',\n )\n .option(\n '--no-poll',\n '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)',\n );\n\n attachSchemaHelp(cmd, pmAddSchema);\n\n cmd.action(async () => {\n const opts = cmd.optsWithGlobals();\n const format = resolveFormat(opts.format as string | undefined);\n const isYes = Boolean(opts.yes);\n\n const mode = String(opts.mode ?? 'manual').toLowerCase();\n if (mode !== 'manual' && mode !== 'dropin') {\n throw new CliError(\n 'PARAM_INVALID',\n `Unknown --mode \"${opts.mode}\". Expected \"manual\" or \"dropin\".`,\n );\n }\n\n if (mode === 'dropin') {\n await handleDropinMode(deps, opts, format);\n return;\n }\n\n await handleManualMode(deps, opts, format, isYes);\n });\n}\n\n// ============================================================\n// Manual mode (collect card details + 3DS polling)\n// ============================================================\n\n/**\n * Manual mode: collect card details, POST /payment-methods/create, then poll\n * 3DS verification status until ACTIVE / FAILED / 15-minute timeout.\n */\nasync function handleManualMode(\n deps: AddDeps,\n opts: Record<string, unknown>,\n format: OutputFormat,\n isYes: boolean,\n): Promise<void> {\n // --- Resolve API key ---\n const apiKey = await PromptEngine.resolveInput(opts.apiKey as string | undefined, {\n message: 'API Key:',\n type: 'password',\n });\n\n // --- Resolve payment method type ---\n const type = (opts.type as string) || 'card';\n\n // --- Collect card params via PromptEngine ---\n const flags: Record<string, string | undefined> = {\n email: opts.email as string | undefined,\n cardNumber: opts.cardNumber as string | undefined,\n expiry: opts.expiry as string | undefined,\n cvv: opts.cvv as string | undefined,\n };\n const params = await collectPaymentMethodParams(type, flags);\n\n // --- Idempotency key (required for write, Requirement 6.3) ---\n let idempotencyKey = opts.idempotencyKey as string | undefined;\n if (!idempotencyKey) {\n if (isYes) {\n throw new IdempotencyKeyRequiredError('payment-methods add');\n }\n idempotencyKey = await PromptEngine.resolveInput(undefined, {\n message: 'Idempotency key (unique per write, for safe retry):',\n validate: (v) => v.trim().length > 0 || 'Idempotency key is required',\n });\n }\n\n const extraHeaders: Record<string, string> = {\n 'Idempotency-Key': idempotencyKey,\n };\n\n // --- POST /payment-methods/create ---\n const result = await deps.apiClient.post<PaymentMethod>(\n '/payment-methods/create',\n { type: 'api-key', key: apiKey },\n params,\n extraHeaders,\n );\n\n if (!result.success) {\n throw CliError.fromApi(result, { auth: 'api-key' });\n }\n\n const pm = result.data;\n\n // --- Output: created state ---\n notify(format, 'success', 'Payment method created');\n\n const createdResult: CommandResult<PaymentMethod> = {\n data: pm,\n text: () => {\n const lines: [string, string][] = [\n ['ID', pm.id],\n ['Type', pm.type],\n ['Status', pm.status],\n ];\n if (pm.brand) lines.push(['Brand', pm.brand]);\n if (pm.first6) lines.push(['First 6', pm.first6]);\n if (pm.last4) lines.push(['Last 4', pm.last4]);\n return Formatter.keyValue(lines);\n },\n };\n\n const configManager = new ConfigManager();\n await renderWithContext(createdResult, { format }, configManager);\n\n // Hint about 3DS (after keyValue output)\n notify(format, 'info', 'Complete 3DS verification via email to activate');\n\n // --- 3DS polling (only for type=card and PENDING status) ---\n if (type === 'card' && pm.status === 'PENDING') {\n const finalStatus = await poll3dsVerification(deps.apiClient, apiKey, pm.id, format);\n\n if (finalStatus === 'ACTIVE') {\n // Fetch the updated payment method for full details\n const getResult = await deps.apiClient.get<PaymentMethod>(\n `/payment-methods/${pm.id}`,\n { type: 'api-key', key: apiKey },\n );\n\n if (getResult.success) {\n const activatedPm = getResult.data;\n notify(format, 'success', 'Payment method activated');\n\n const activatedResult: CommandResult<PaymentMethod> = {\n data: activatedPm,\n text: () => {\n const lines: [string, string][] = [\n ['ID', activatedPm.id],\n ['Type', activatedPm.type],\n ['Status', activatedPm.status],\n ];\n if (activatedPm.brand) lines.push(['Brand', activatedPm.brand]);\n if (activatedPm.first6) lines.push(['First 6', activatedPm.first6]);\n if (activatedPm.last4) lines.push(['Last 4', activatedPm.last4]);\n return Formatter.keyValue(lines);\n },\n };\n\n await renderWithContext(activatedResult, { format }, configManager);\n } else {\n // 3DS already reported ACTIVE, but the follow-up detail GET failed.\n // Emit a degraded terminal state from what we already know (the\n // create response + known-ACTIVE status) rather than exiting silently.\n notify(format, 'success', 'Payment method activated');\n\n const degraded: PaymentMethod = { ...pm, status: 'ACTIVE' };\n const degradedResult: CommandResult<PaymentMethod> = {\n data: degraded,\n text: () => {\n const lines: [string, string][] = [\n ['ID', degraded.id],\n ['Type', degraded.type],\n ['Status', degraded.status],\n ];\n if (degraded.brand) lines.push(['Brand', degraded.brand]);\n if (degraded.first6) lines.push(['First 6', degraded.first6]);\n if (degraded.last4) lines.push(['Last 4', degraded.last4]);\n return Formatter.keyValue(lines);\n },\n };\n\n await renderWithContext(degradedResult, { format }, configManager);\n }\n } else if (finalStatus === 'FAILED') {\n notify(format, 'error', '3DS verification failed');\n } else if (finalStatus === 'TIMEOUT') {\n notify(\n format,\n 'info',\n `Verification timed out (15 min). Check status with: agenzo-token-cli payment-methods get ${pm.id} --api-key <your_key>`,\n );\n }\n }\n}\n\n// ============================================================\n// Drop-in mode (mint Drop-in session + poll)\n// ============================================================\n\n/**\n * Drop-in mode: mint a Drop-in session and hand the add-payment-method UI off\n * to the developer's own front-end (which embeds the Drop-in SDK using the\n * session id). The CLI then polls the same verification/status endpoint manual\n * mode uses until the PM reaches a terminal status or the 30-minute timeout.\n */\nasync function handleDropinMode(\n deps: AddDeps,\n opts: Record<string, unknown>,\n format: OutputFormat,\n): Promise<void> {\n const apiKey = await PromptEngine.resolveInput(opts.apiKey as string | undefined, {\n message: 'API Key:',\n type: 'password',\n });\n\n const email = await PromptEngine.resolveInput(opts.email as string | undefined, {\n message: 'Email:',\n });\n\n const configManager = new ConfigManager();\n\n // 1) Create the Drop-in session (API Key auth). The backend creates a\n // PENDING PM keyed by pm_id and mints the session for the front-end SDK.\n const sessionResult = await deps.apiClient.post<DropinCreateResponse>(\n '/payment-methods/dropin/create',\n { type: 'api-key', key: apiKey },\n { email },\n );\n\n if (!sessionResult.success) {\n throw CliError.fromApi(sessionResult, { auth: 'api-key' });\n }\n\n const session = sessionResult.data;\n const pmId = session.id;\n\n // 2) Print the session id so the caller can initialise the front-end SDK.\n notify(format, 'success', 'Drop-in session created');\n\n const createdResult: CommandResult<DropinCreateResponse> = {\n data: session,\n text: () => Formatter.keyValue([['Session ID', session.session_id || '-']]),\n };\n await renderWithContext(createdResult, { format }, configManager);\n\n notify(\n format,\n 'info',\n 'Use the Session ID to add the payment method in the browser via the Drop-in SDK',\n );\n\n // --no-poll: server/SDK-driven flows finish the binding in the front-end, so\n // the CLI mints + prints the session and exits immediately. The session id is\n // already on stdout (clean JSON in --format json), so the caller can parse it.\n if (opts.poll === false) {\n return;\n }\n\n // 3) Poll verification/status (same endpoint manual mode uses) until the PM\n // reaches a terminal status or we time out at 30 minutes.\n const finalPm = await pollVerificationStatus(deps.apiClient, apiKey, pmId, {\n intervalMs: DROPIN_POLL_INTERVAL_MS,\n timeoutMs: DROPIN_POLL_TIMEOUT_MS,\n });\n\n if (finalPm.status === 'ACTIVE') {\n notify(format, 'success', 'Payment method activated');\n const activated: CommandResult<PaymentMethod> = {\n data: finalPm,\n text: () =>\n Formatter.keyValue([\n ['PM ID', finalPm.id],\n ['Brand', finalPm.brand ?? '-'],\n ['First 6', finalPm.first6 ?? '-'],\n ['Last 4', finalPm.last4 ?? '-'],\n ['Status', finalPm.status],\n ]),\n };\n await renderWithContext(activated, { format }, configManager);\n return;\n }\n\n if (finalPm.status === 'FAILED') {\n notify(format, 'error', 'Failed to add payment method');\n await renderPmId(finalPm.id, format, configManager);\n process.exitCode = 1;\n return;\n }\n\n if (finalPm.status === 'EXPIRED') {\n notify(format, 'error', 'Session expired before the payment method was added');\n await renderPmId(finalPm.id, format, configManager);\n process.exitCode = 1;\n return;\n }\n\n // Timed out without reaching a terminal status — PM is still PENDING\n // server-side. The operator can re-run with the same email to resume\n // (PENDING dropin PMs are overwritten/reused).\n notify(\n format,\n 'error',\n 'Adding payment method did not complete within 30 minutes. Re-run with the same email to resume.',\n );\n await renderPmId(pmId, format, configManager);\n process.exitCode = 1;\n}\n\n/** Render `{ id }` as the terminal payload (PM ID line in table, JSON in json). */\nasync function renderPmId(\n id: string,\n format: OutputFormat,\n configManager: ConfigManager,\n): Promise<void> {\n const result: CommandResult<{ id: string }> = {\n data: { id },\n text: () => Formatter.keyValue([['PM ID', id]]),\n };\n await renderWithContext(result, { format }, configManager);\n}\n\n// ============================================================\n// Polling helpers\n// ============================================================\n\n/**\n * Poll GET /payment-methods/verification/status?payment_method_id=<id> every\n * 3000ms until ACTIVE, FAILED, or 15-minute timeout (manual / 3DS mode).\n *\n * Returns the terminal status: 'ACTIVE' | 'FAILED' | 'TIMEOUT'.\n */\nasync function poll3dsVerification(\n apiClient: ApiClient,\n apiKey: string,\n paymentMethodId: string,\n format: OutputFormat,\n): Promise<'ACTIVE' | 'FAILED' | 'TIMEOUT'> {\n const startTime = Date.now();\n\n notify(format, 'info', 'Waiting for 3DS verification...');\n\n while (Date.now() - startTime < MANUAL_POLL_TIMEOUT_MS) {\n await sleep(MANUAL_POLL_INTERVAL_MS);\n\n const result = await apiClient.get<{ status: string }>(\n '/payment-methods/verification/status',\n { type: 'api-key', key: apiKey },\n { payment_method_id: paymentMethodId },\n );\n\n if (result.success) {\n const status = result.data.status;\n if (status === 'ACTIVE') {\n return 'ACTIVE';\n }\n if (status === 'FAILED') {\n return 'FAILED';\n }\n // Still PENDING — continue polling\n }\n // On API error during polling, continue trying (transient failures)\n }\n\n return 'TIMEOUT';\n}\n\ninterface PollOptions {\n intervalMs: number;\n timeoutMs: number;\n}\n\n/**\n * Poll GET /payment-methods/verification/status?payment_method_id=<id> at\n * `intervalMs` until the PM reaches a terminal status (ACTIVE / FAILED /\n * EXPIRED) or `timeoutMs` elapses (dropin mode).\n *\n * Returns the final PaymentMethod on a terminal status, or\n * `{ id, status: 'PENDING' }` on timeout so callers can branch on the final\n * status uniformly. Transient poll errors are ignored (next tick retries).\n */\nasync function pollVerificationStatus(\n apiClient: ApiClient,\n apiKey: string,\n pmId: string,\n options: PollOptions,\n): Promise<PaymentMethod> {\n const startTime = Date.now();\n\n while (Date.now() - startTime < options.timeoutMs) {\n const result = await apiClient.get<PaymentMethod>(\n '/payment-methods/verification/status',\n { type: 'api-key', key: apiKey },\n { payment_method_id: pmId },\n );\n\n if (result.success && TERMINAL_STATUSES.has(result.data.status)) {\n return result.data;\n }\n\n await sleep(options.intervalMs);\n }\n\n return { id: pmId, status: 'PENDING' } as PaymentMethod;\n}\n\n/** Simple async sleep utility. */\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","import { Command } from 'commander';\nimport {\n ApiClient,\n ConfigManager,\n PromptEngine,\n Formatter,\n resolveFormat,\n CliError,\n renderWithContext,\n} from '@agenzo/cli-core';\nimport type { CommandResult } from '@agenzo/cli-core';\nimport type { PaymentMethod } from '../types/api.js';\nimport { attachSchemaHelp, pmListSchema } from '../verb-schema.js';\n\n/**\n * `payment-methods list` — list payment methods (§3.4.0.2).\n *\n * GET /payment-methods with X-Api-Key header.\n * Optional --member flag maps to ?member_id= query param.\n * Table headers: ID / Type / Brand / First 6 / Last 4 / Status.\n * Empty list → info message (no table). Missing brand/first6/last4 → `-`.\n */\nexport function registerListCommand(parent: Command, deps: { apiClient: ApiClient }): void {\n const cmd = parent\n .command('list')\n .description('List payment methods')\n .option('--api-key <key>', 'API Key for authentication')\n .option('--member <member_id>', 'Filter by member ID');\n\n attachSchemaHelp(cmd, pmListSchema);\n\n cmd.action(async () => {\n const opts = cmd.optsWithGlobals();\n const format = resolveFormat(opts.format as string | undefined);\n\n const apiKey = await PromptEngine.resolveInput(opts.apiKey as string | undefined, {\n message: 'API Key:',\n type: 'password',\n });\n\n // Build query params\n const params: Record<string, string> = {};\n if (opts.member) {\n params.member_id = opts.member as string;\n }\n\n const result = await deps.apiClient.get<PaymentMethod[]>(\n '/payment-methods',\n { type: 'api-key', key: apiKey },\n Object.keys(params).length > 0 ? params : undefined,\n );\n\n if (!result.success) {\n throw CliError.fromApi(result, { auth: 'api-key' });\n }\n\n const methods = result.data;\n\n const configManager = new ConfigManager();\n const commandResult: CommandResult<{ payment_methods: PaymentMethod[] }> = {\n data: { payment_methods: methods },\n text: () => {\n if (methods.length === 0) {\n return Formatter.status('info', 'No payment methods found');\n }\n const headers = ['ID', 'Type', 'Brand', 'First 6', 'Last 4', 'Status'];\n const rows = methods.map((m) => [\n m.id,\n m.type,\n m.brand || '-',\n m.first6 || '-',\n m.last4 || '-',\n m.status,\n ]);\n return Formatter.table(headers, rows);\n },\n };\n\n await renderWithContext(commandResult, { format }, configManager);\n });\n}\n","import { Command } from 'commander';\nimport {\n ApiClient,\n ConfigManager,\n Formatter,\n PromptEngine,\n resolveFormat,\n CliError,\n renderWithContext,\n} from '@agenzo/cli-core';\nimport type { CommandResult } from '@agenzo/cli-core';\nimport type { PaymentMethod } from '../types/api.js';\nimport { attachSchemaHelp, pmGetSchema } from '../verb-schema.js';\n\n/**\n * `payment-methods get <pm_id>` — show a single payment method (§3.4.0.3).\n *\n * Reads: GET /payment-methods/<pm_id> (X-Api-Key).\n * Output: keyValue. Brand / First 6 / Last 4 appear only when their\n * corresponding fields are non-empty/non-null (conditional inclusion).\n */\nexport function registerGetCommand(parent: Command, deps: { apiClient: ApiClient }): void {\n const cmd = parent\n .command('get <pm_id>')\n .description('Get a payment method by ID')\n .option('--api-key <key>', 'API key for authentication');\n\n attachSchemaHelp(cmd, pmGetSchema);\n\n cmd.action(async (pmId: string) => {\n const opts = cmd.optsWithGlobals();\n const format = resolveFormat(opts.format as string | undefined);\n\n // Resolve API key — prompt interactively if not provided via flag\n const apiKey = await PromptEngine.resolveInput(opts.apiKey as string | undefined, {\n message: 'API Key:',\n type: 'password',\n });\n\n // GET /payment-methods/<pm_id>\n const result = await deps.apiClient.get<PaymentMethod>(\n `/payment-methods/${pmId}`,\n { type: 'api-key', key: apiKey },\n );\n\n if (!result.success) {\n throw CliError.fromApi(result, { auth: 'api-key' });\n }\n\n const pm = result.data;\n\n // Build keyValue entries — Brand/First 6/Last 4 only when non-empty\n const entries: [string, string][] = [\n ['ID', pm.id],\n ['Type', pm.type],\n ];\n\n if (pm.brand) {\n entries.push(['Brand', pm.brand]);\n }\n if (pm.first6) {\n entries.push(['First 6', pm.first6]);\n }\n if (pm.last4) {\n entries.push(['Last 4', pm.last4]);\n }\n\n entries.push(['Status', pm.status]);\n entries.push(['Created', Formatter.formatTime(pm.created_at)]);\n\n const configManager = new ConfigManager();\n const cmdResult: CommandResult<PaymentMethod> = {\n data: pm,\n text: () => Formatter.keyValue(entries),\n };\n\n await renderWithContext(cmdResult, { format }, configManager);\n });\n}\n","import { renderWithContext } from '@agenzo/cli-core';\nimport { Command } from 'commander';\nimport {\n ApiClient,\n ConfigManager,\n PromptEngine,\n Formatter,\n resolveFormat,\n notify,\n CliError,\n IdempotencyKeyRequiredError,\n} from '@agenzo/cli-core';\nimport type { CommandResult, DisableResult } from '@agenzo/cli-core';\nimport { attachSchemaHelp, pmDisableSchema } from '../verb-schema.js';\n\n/**\n * `payment-methods disable <pm_id>` — disable a payment method (§3.4.0.4).\n *\n * POST /payment-methods/<pm_id>/disable (no body).\n * Output: `✓ Payment method <id> disabled` + Status + Revoked tokens.\n * Idempotency: --idempotency-key required in --yes mode (Requirement 6.3).\n */\nexport function registerDisableCommand(parent: Command, deps: { apiClient: ApiClient }): void {\n const cmd = parent\n .command('disable <pm_id>')\n .description('Disable a payment method')\n .option('--api-key <key>', 'API key for authentication')\n .option(\n '--idempotency-key <key>',\n 'Idempotency key forwarded verbatim as the Idempotency-Key header',\n );\n\n attachSchemaHelp(cmd, pmDisableSchema);\n\n cmd.action(async (pmId: string) => {\n const opts = cmd.optsWithGlobals();\n const format = resolveFormat(opts.format as string | undefined);\n\n const apiKey = await PromptEngine.resolveInput(opts.apiKey as string | undefined, {\n message: 'API Key:',\n type: 'password',\n });\n\n // Idempotency key handling (Requirement 6.3):\n // In --yes mode, --idempotency-key is mandatory — never auto-generate, never send request.\n // In interactive mode, prompt if not provided.\n let idempotencyKey = opts.idempotencyKey as string | undefined;\n if (!idempotencyKey) {\n if (opts.yes) {\n throw new IdempotencyKeyRequiredError('payment-methods disable');\n }\n idempotencyKey = await PromptEngine.resolveInput(undefined, {\n message: 'Idempotency key (unique per write, for safe retry):',\n validate: (v) => v.trim().length > 0 || 'Idempotency key is required',\n });\n }\n\n const extraHeaders: Record<string, string> = {\n 'Idempotency-Key': idempotencyKey,\n };\n\n const result = await deps.apiClient.post<DisableResult>(\n `/payment-methods/${pmId}/disable`,\n { type: 'api-key', key: apiKey },\n undefined,\n extraHeaders,\n );\n\n if (!result.success) {\n throw CliError.fromApi(result, { auth: 'api-key' });\n }\n\n const data = result.data;\n\n // Status line → stderr (json mode stays silent per §5)\n notify(format, 'success', `Payment method ${pmId} disabled`);\n\n const cmdResult: CommandResult<DisableResult> = {\n data,\n text: () =>\n Formatter.keyValue([\n ['Status', data.status],\n ['Revoked tokens', String(data.revoked_tokens_count ?? 0)],\n ]),\n };\n\n const configManager = new ConfigManager();\n await renderWithContext(cmdResult, { format }, configManager);\n });\n}\n","import { Command } from 'commander';\nimport {\n ApiClient,\n ConfigManager,\n PromptEngine,\n Formatter,\n resolveFormat,\n notify,\n CliError,\n renderWithContext,\n} from '@agenzo/cli-core';\nimport type { CommandResult } from '@agenzo/cli-core';\nimport type { DropinCreateResponse } from '../types/api.js';\n\n/**\n * `payment-methods dropin-create` — mint a Drop-in session and return\n * immediately (no polling).\n *\n * This is the non-blocking half of `payment-methods add --mode dropin`: it\n * POSTs /payment-methods/dropin/create with the developer email, prints the\n * minted `session_id` (+ pm id) so the caller can initialise the Drop-in SDK\n * in their own front-end, then exits. Unlike `add --mode dropin`, it does NOT\n * poll verification/status — callers poll separately via\n * `payment-methods dropin-status <pm_id>` once the user finishes in the browser.\n *\n * Intended for programmatic callers (e.g. the agent orchestrator) that need the\n * session id synchronously to render an add-card card, rather than a CLI\n * operator who waits at the terminal. Not advertised in the SKILL/README.\n */\nexport function registerDropinCreateCommand(\n parent: Command,\n deps: { apiClient: ApiClient },\n): void {\n const cmd = parent\n .command('dropin-create')\n .description('Mint a Drop-in session and return the session id (no polling)')\n .option('--api-key <key>', 'API Key for authentication')\n .option('--email <email>', 'Email used as the Drop-in session reference');\n\n cmd.action(async () => {\n const opts = cmd.optsWithGlobals();\n const format = resolveFormat(opts.format as string | undefined);\n\n const apiKey = await PromptEngine.resolveInput(opts.apiKey as string | undefined, {\n message: 'API Key:',\n type: 'password',\n });\n\n const email = await PromptEngine.resolveInput(opts.email as string | undefined, {\n message: 'Email:',\n });\n\n // POST /payment-methods/dropin/create — backend creates a PENDING PM and\n // mints the Drop-in session for the front-end SDK. Returns synchronously.\n const sessionResult = await deps.apiClient.post<DropinCreateResponse>(\n '/payment-methods/dropin/create',\n { type: 'api-key', key: apiKey },\n { email },\n );\n\n if (!sessionResult.success) {\n throw CliError.fromApi(sessionResult, { auth: 'api-key' });\n }\n\n const session = sessionResult.data;\n\n notify(format, 'success', 'Drop-in session created');\n\n const configManager = new ConfigManager();\n const result: CommandResult<DropinCreateResponse> = {\n data: session,\n text: () =>\n Formatter.keyValue([\n ['PM ID', session.id],\n ['Session ID', session.session_id || '-'],\n ['Merchant Trans ID', session.merchant_trans_id || '-'],\n ['Status', session.status],\n ]),\n };\n\n await renderWithContext(result, { format }, configManager);\n\n notify(\n format,\n 'info',\n 'Use the Session ID to add the payment method via the Drop-in SDK, then poll: agenzo-token-cli payment-methods dropin-status <pm_id> --api-key <your_key>',\n );\n });\n}\n","import { Command } from 'commander';\nimport {\n ApiClient,\n ConfigManager,\n Formatter,\n PromptEngine,\n resolveFormat,\n CliError,\n renderWithContext,\n} from '@agenzo/cli-core';\nimport type { CommandResult } from '@agenzo/cli-core';\nimport type { PaymentMethod } from '../types/api.js';\n\n/**\n * `payment-methods dropin-status [pm_id]` — query the current Drop-in binding\n * status for a payment method, once (no polling).\n *\n * This is the status-check half of `payment-methods add --mode dropin`: it\n * reads GET /payment-methods/verification/status?payment_method_id=<pm_id>\n * and prints the current status, then exits. Callers (e.g. the agent\n * orchestrator) poll this on their own cadence after minting a session with\n * `payment-methods dropin-create`, instead of letting the CLI block for 30\n * minutes.\n *\n * The payment method id may be supplied either as the positional `<pm_id>`\n * (CLI operators) or via `--payment-method-id <id>`. The flag form exists for\n * programmatic callers like the agent orchestrator, whose CLI gateway only\n * passes `--flag value` pairs and cannot send positional arguments.\n *\n * Status enum: PENDING | ACTIVE | FAILED | DISABLED | EXPIRED.\n * Not advertised in the SKILL/README.\n */\nexport function registerDropinStatusCommand(\n parent: Command,\n deps: { apiClient: ApiClient },\n): void {\n const cmd = parent\n .command('dropin-status [pm_id]')\n .description('Query the current Drop-in binding status for a payment method (single check)')\n .option('--api-key <key>', 'API Key for authentication')\n .option(\n '--payment-method-id <id>',\n 'Payment method id to query (alternative to the positional <pm_id>, for programmatic callers that pass flags only)',\n );\n\n cmd.action(async (pmIdArg: string | undefined) => {\n const opts = cmd.optsWithGlobals();\n const format = resolveFormat(opts.format as string | undefined);\n\n // Accept the pm id from the positional arg or the --payment-method-id flag\n // (the orchestrator gateway can only pass flags), else prompt interactively.\n const pmId = await PromptEngine.resolveInput(\n pmIdArg ?? (opts.paymentMethodId as string | undefined),\n { message: 'Payment method id:' },\n );\n\n const apiKey = await PromptEngine.resolveInput(opts.apiKey as string | undefined, {\n message: 'API Key:',\n type: 'password',\n });\n\n // GET /payment-methods/verification/status?payment_method_id=<pm_id>\n const result = await deps.apiClient.get<PaymentMethod>(\n '/payment-methods/verification/status',\n { type: 'api-key', key: apiKey },\n { payment_method_id: pmId },\n );\n\n if (!result.success) {\n throw CliError.fromApi(result, { auth: 'api-key' });\n }\n\n const pm = result.data;\n\n const entries: [string, string][] = [['ID', pm.id ?? pmId]];\n if (pm.brand) entries.push(['Brand', pm.brand]);\n if (pm.first6) entries.push(['First 6', pm.first6]);\n if (pm.last4) entries.push(['Last 4', pm.last4]);\n entries.push(['Status', pm.status]);\n\n const configManager = new ConfigManager();\n const cmdResult: CommandResult<PaymentMethod> = {\n data: pm,\n text: () => Formatter.keyValue(entries),\n };\n\n await renderWithContext(cmdResult, { format }, configManager);\n });\n}\n","import { Command } from 'commander';\nimport { confirm, select } from '@inquirer/prompts';\nimport {\n ApiClient,\n ConfigManager,\n PromptEngine,\n Formatter,\n resolveFormat,\n notify,\n CliError,\n IdempotencyKeyRequiredError,\n renderWithContext,\n} from '@agenzo/cli-core';\nimport type { CommandResult, OutputFormat } from '@agenzo/cli-core';\nimport type { PaymentMethod } from '../types/api.js';\nimport { attachSchemaHelp, ptCreateSchema } from '../verb-schema.js';\n\n// ============================================================\n// Constants\n// ============================================================\n\n/** Default network-token fee in cents when /config/network-token-fee is unreachable. */\nconst DEFAULT_NT_FEE_CENTS = 50;\n\n/** Smallest USDC unit (1 USDC = 1_000_000 micro-units). */\nconst USDC_UNIT = 1_000_000;\n\n// ============================================================\n// Helpers (token-domain-specific — stays in app per requirement 5.5)\n// ============================================================\n\n/**\n * Map CLI `--type` flag value to the server-side `type` field.\n * `network-token` → `network_token`; unknown values pass through unchanged.\n */\nexport function mapTokenType(cliType: string): string {\n if (cliType === 'network-token') return 'network_token';\n return cliType;\n}\n\n/**\n * Convert a USD amount string (e.g. \"12.50\") to integer cents using\n * string-based parsing to avoid floating-point drift.\n *\n * Accepts formats: \"12\", \"12.5\", \"12.50\", \".50\", \"0.01\".\n * Throws PARAM_INVALID on non-numeric / out-of-range.\n */\nexport function usdToCents(amountStr: string): number {\n const trimmed = amountStr.trim();\n\n // Validate format: optional digits, optional decimal point with up to 2 fractional digits\n if (!/^\\d*\\.?\\d{0,2}$/.test(trimmed) || trimmed === '' || trimmed === '.') {\n throw new CliError('PARAM_INVALID', `Invalid amount format: \"${amountStr}\". Expected a decimal like \"12.50\".`);\n }\n\n const parts = trimmed.split('.');\n const integerPart = parts[0] || '0';\n let fractionalPart = parts[1] || '0';\n\n // Pad fractional to exactly 2 digits\n fractionalPart = fractionalPart.padEnd(2, '0');\n\n const integerCents = parseInt(integerPart, 10) * 100;\n const fractionalCents = parseInt(fractionalPart, 10);\n return integerCents + fractionalCents;\n}\n\n/**\n * Resolve the payment method to use, following 4-level priority:\n * 1. --payment-method-id (explicit)\n * 2. --card (match last4 against ACTIVE cards)\n * 3. Single ACTIVE card → auto-select\n * 4. Multiple ACTIVE cards → interactive select\n *\n * Throws CLIENT_NO_PAYMENT_METHOD when no ACTIVE cards exist.\n * Throws CLIENT_CARD_NOT_MATCHED when --card doesn't match any ACTIVE card.\n */\nexport async function resolvePaymentMethod(\n apiClient: ApiClient,\n apiKey: string,\n opts: {\n paymentMethodId?: string;\n card?: string;\n yes?: boolean;\n },\n): Promise<string> {\n // Priority 1: explicit --payment-method-id\n if (opts.paymentMethodId) {\n return opts.paymentMethodId;\n }\n\n // Need to fetch ACTIVE cards for priorities 2–4\n const result = await apiClient.get<PaymentMethod[]>(\n '/payment-methods',\n { type: 'api-key', key: apiKey },\n );\n\n if (!result.success) {\n throw CliError.fromApi(result, { auth: 'api-key' });\n }\n\n const activeCards = result.data.filter((m) => m.status === 'ACTIVE');\n\n if (activeCards.length === 0) {\n throw new CliError(\n 'CLIENT_NO_PAYMENT_METHOD',\n 'No active payment methods found. Add one with: agenzo-token-cli payment-methods add --api-key <your_key>',\n );\n }\n\n // Priority 2: --card (match last4)\n if (opts.card) {\n const matched = activeCards.find((m) => m.last4 === opts.card);\n if (!matched) {\n throw new CliError(\n 'CLIENT_CARD_NOT_MATCHED',\n `No active card ending in ${opts.card}. Available: ${activeCards.map((m) => m.last4 || '????').join(', ')}`,\n );\n }\n return matched.id;\n }\n\n // Priority 3: single card → auto-select\n if (activeCards.length === 1) {\n return activeCards[0].id;\n }\n\n // Priority 4: multiple cards → interactive select\n if (opts.yes) {\n // In --yes mode we cannot prompt; if there's ambiguity, we cannot proceed\n throw new CliError(\n 'PARAM_INVALID',\n 'Multiple active payment methods found. Specify --payment-method-id or --card to disambiguate.',\n );\n }\n\n const selected = await select({\n message: 'Select a payment method:',\n choices: activeCards.map((m) => ({\n name: `${m.id} (${m.brand || m.type} ****${m.last4 || '????'})`,\n value: m.id,\n })),\n });\n\n return selected;\n}\n\n/**\n * Format a payment token for human-readable output (§3.4.1 create output).\n * Renders differently per type: VCN / Network Token / X402.\n *\n * NOTE: The server response wraps type-specific data under `data.vcn`,\n * `data.network_token`, or `data.x402` (nested). This formatter reads\n * from that nested structure directly.\n */\nexport function formatPaymentToken(data: Record<string, unknown>): string {\n const type = data.type as string;\n const lines: [string, string][] = [];\n\n if (type === 'vcn') {\n const vcn = data.vcn as Record<string, unknown> | undefined ?? data;\n lines.push(['Payment Token ID', String(data.id || vcn.id || '')]);\n lines.push(['Type', 'VCN']);\n lines.push(['Card Number', String(vcn.card_number || '')]);\n lines.push(['Expiry', String(vcn.expiry || '')]);\n lines.push(['CVC', String(vcn.cvc || '')]);\n lines.push(['Limit', `$${formatCentsToUsd(vcn.amount_limit as number)}`]);\n lines.push(['Currency', String(vcn.currency || 'USD')]);\n lines.push(['Status', String(vcn.status || data.status || '')]);\n } else if (type === 'network_token') {\n const nt = data.network_token as Record<string, unknown> | undefined ?? data;\n lines.push(['Payment Token ID', String(data.id || nt.id || '')]);\n lines.push(['Type', 'Network Token']);\n lines.push(['Brand', String(nt.payment_brand || nt.brand || '')]);\n lines.push(['ECI', String(nt.eci || '')]);\n lines.push(['Cryptogram', String(nt.token_cryptogram || nt.cryptogram || '')]);\n lines.push(['Expiry', String(nt.expiry_date || nt.expiry || '')]);\n lines.push(['Value', String(nt.value || '')]);\n } else if (type === 'x402') {\n const x402 = data.x402 as Record<string, unknown> | undefined ?? data;\n lines.push(['Payment Token ID', String(data.id || x402.id || '')]);\n lines.push(['Type', 'X402']);\n lines.push(['Signature Value', String(x402.signature_value || '')]);\n lines.push(['Status', String(x402.status || data.status || '')]);\n } else {\n // Unknown type: best-effort\n lines.push(['Payment Token ID', String(data.id || '')]);\n lines.push(['Type', String(type || 'unknown')]);\n lines.push(['Status', String(data.status || '')]);\n }\n\n return Formatter.keyValue(lines);\n}\n\n/** Format cents back to USD string (e.g. 1250 → \"12.50\"). */\nfunction formatCentsToUsd(cents: number | undefined): string {\n if (cents === undefined || cents === null) return '0.00';\n const dollars = Math.floor(cents / 100);\n const remainder = cents % 100;\n return `${dollars}.${String(remainder).padStart(2, '0')}`;\n}\n\n// ============================================================\n// Command registration\n// ============================================================\n\n/**\n * `payment-tokens create` — generate a VCN / Network Token / X402 credential\n * (§3.4.1).\n */\nexport function registerCreateCommand(parent: Command, deps: { apiClient: ApiClient }): void {\n const cmd = parent\n .command('create')\n .description('Create a payment token (VCN / Network Token / X402)')\n .option('--api-key <key>', 'API Key for authentication')\n .option('--type <type>', 'Token type: vcn | network-token | x402')\n .option('--payment-method-id <id>', 'Payment method ID to use')\n .option('--card <last4>', 'Match payment method by last 4 digits')\n .option('--member <member_id>', 'Member ID')\n .option('--amount <amount>', 'Amount in USD (VCN / X402)')\n .option('--currency <currency>', 'Currency (default: USD)')\n .option('--pay-to <address>', 'Pay-to address (X402)')\n .option('--nonce <nonce>', 'Nonce (X402)')\n .option('--network <network>', 'Network (X402)')\n .option('--deadline <deadline>', 'Deadline (X402)')\n .option('--external-tx-id <id>', 'External transaction ID')\n .option(\n '--idempotency-key <key>',\n 'Idempotency key forwarded verbatim as the Idempotency-Key header',\n );\n\n attachSchemaHelp(cmd, ptCreateSchema);\n\n cmd.action(async () => {\n const opts = cmd.optsWithGlobals();\n const format = resolveFormat(opts.format as string | undefined);\n const isYes = Boolean(opts.yes);\n\n // --- Resolve API key ---\n const apiKey = await PromptEngine.resolveInput(opts.apiKey as string | undefined, {\n message: 'API Key:',\n type: 'password',\n });\n\n // --- Resolve token type ---\n const cliType = await PromptEngine.resolveInput(opts.type as string | undefined, {\n message: 'Token type:',\n type: 'select',\n choices: [\n { name: 'VCN (Virtual Card Number)', value: 'vcn' },\n { name: 'Network Token', value: 'network-token' },\n { name: 'X402 (USDC on-chain)', value: 'x402' },\n ],\n });\n const serverType = mapTokenType(cliType);\n\n // --- Resolve payment method (4-level priority) ---\n const paymentMethodId = await resolvePaymentMethod(deps.apiClient, apiKey, {\n paymentMethodId: opts.paymentMethodId as string | undefined,\n card: opts.card as string | undefined,\n yes: isYes,\n });\n\n // --- Resolve member ---\n let member: string | undefined = opts.member as string | undefined;\n if (!member && !isYes) {\n // In interactive mode, prompt for member (optional — allow empty)\n const memberInput = await PromptEngine.resolveInput(undefined, {\n message: 'Member ID (optional, press Enter to skip):',\n validate: () => true, // always valid (optional)\n });\n if (memberInput.trim()) {\n member = memberInput.trim();\n }\n }\n // In --yes mode, if --member not provided, omit it (don't prompt).\n\n // --- Type-specific branch logic ---\n let freezeAmountCents: number | undefined;\n let feeCents: number | undefined;\n let feeDisplay: string | undefined;\n let freezeDisplay: string | undefined;\n // Body fields that vary by type\n const typeBody: Record<string, unknown> = {};\n\n if (serverType === 'vcn') {\n // VCN branch: feature gate + amount + fee\n await checkVcnFeatureEnabled(deps.apiClient, apiKey);\n\n const amountStr = await PromptEngine.resolveInput(opts.amount as string | undefined, {\n message: 'Amount (USD, e.g. 25.00):',\n validate: (v) => {\n try {\n const cents = usdToCents(v);\n if (cents < 1 || cents > 50000) {\n return 'Amount must be between $0.01 and $500.00';\n }\n return true;\n } catch {\n return 'Invalid amount format. Use a decimal like \"25.00\"';\n }\n },\n });\n\n const cents = usdToCents(amountStr);\n if (cents < 1 || cents > 50000) {\n throw new CliError(\n 'PARAM_INVALID',\n 'Amount must be between $0.01 and $500.00',\n );\n }\n\n feeCents = Math.max(1, Math.round(cents * 0.05));\n freezeAmountCents = cents + feeCents;\n feeDisplay = `$${formatCentsToUsd(feeCents)}`;\n freezeDisplay = `$${formatCentsToUsd(freezeAmountCents)}`;\n\n typeBody.amount = cents;\n // §3.4.1: --currency omitted → do NOT send; server applies its default.\n if (opts.currency) {\n typeBody.currency = opts.currency as string;\n }\n } else if (serverType === 'network_token') {\n // Network-token branch: fetch fee config (fallback to default)\n feeCents = await fetchNetworkTokenFee(deps.apiClient, apiKey);\n freezeAmountCents = feeCents;\n feeDisplay = `$${formatCentsToUsd(feeCents)}`;\n freezeDisplay = feeDisplay;\n } else if (serverType === 'x402') {\n // X402 branch: USDC amount + fee\n const amountStr = await PromptEngine.resolveInput(opts.amount as string | undefined, {\n message: 'Amount (USDC):',\n validate: (v) => {\n const n = parseFloat(v);\n if (isNaN(n) || n <= 0) return 'Amount must be a positive number';\n return true;\n },\n });\n\n const amountUsdc = parseFloat(amountStr);\n const amountUnits = Math.round(amountUsdc * USDC_UNIT);\n // Fee = max(0.01 USDC units, amount * 5%)\n const minFeeUnits = Math.round(0.01 * USDC_UNIT); // 10000 units = $0.01\n const percentFeeUnits = Math.round(amountUnits * 0.05);\n const feeUnits = Math.max(minFeeUnits, percentFeeUnits);\n const freezeUnits = amountUnits + feeUnits;\n\n feeDisplay = `${(feeUnits / USDC_UNIT).toFixed(6)} USDC`;\n freezeDisplay = `${(freezeUnits / USDC_UNIT).toFixed(6)} USDC`;\n\n typeBody.amount = amountUnits;\n typeBody.pay_to = await PromptEngine.resolveInput(opts.payTo as string | undefined, {\n message: 'Pay-to address:',\n });\n typeBody.nonce = await PromptEngine.resolveInput(opts.nonce as string | undefined, {\n message: 'Nonce:',\n });\n typeBody.network = await PromptEngine.resolveInput(opts.network as string | undefined, {\n message: 'Network:',\n });\n const deadlineStr = await PromptEngine.resolveInput(opts.deadline as string | undefined, {\n message: 'Deadline (Unix timestamp):',\n validate: (v) =>\n /^\\d+$/.test(v.trim()) || 'Deadline must be a Unix timestamp (integer seconds)',\n });\n // §3.4.1 request body requires `deadline: <number>` — coerce and validate\n // (covers both the --deadline flag path and the interactive path).\n const deadlineNum = Number(deadlineStr.trim());\n if (!Number.isInteger(deadlineNum) || deadlineNum <= 0) {\n throw new CliError(\n 'PARAM_INVALID',\n `Invalid deadline: \"${deadlineStr}\". Expected a Unix timestamp (integer seconds).`,\n );\n }\n typeBody.deadline = deadlineNum;\n }\n\n // --- Confirmation (unless --yes) ---\n if (!isYes) {\n const warningLines = [`Freeze: ${freezeDisplay}`, `Fee: ${feeDisplay}`];\n notify(format, 'warning', warningLines.join(' | '));\n\n const confirmed = await confirm({\n message: 'Proceed with token creation?',\n default: true,\n });\n if (!confirmed) {\n throw new CliError('CLIENT_ABORTED', 'Token creation cancelled by user');\n }\n }\n\n // --- Idempotency key (required for write) ---\n let idempotencyKey = opts.idempotencyKey as string | undefined;\n if (!idempotencyKey) {\n if (isYes) {\n throw new IdempotencyKeyRequiredError('payment-tokens create');\n }\n idempotencyKey = await PromptEngine.resolveInput(undefined, {\n message: 'Idempotency key (unique per write, for safe retry):',\n validate: (v) => v.trim().length > 0 || 'Idempotency key is required',\n });\n }\n\n // --- Build request body ---\n const body: Record<string, unknown> = {\n type: serverType,\n payment_method_id: paymentMethodId,\n ...typeBody,\n };\n if (member) {\n body.member_id = member;\n }\n if (opts.externalTxId) {\n body.external_tx_id = opts.externalTxId as string;\n }\n\n const extraHeaders: Record<string, string> = {\n 'Idempotency-Key': idempotencyKey,\n };\n\n // --- POST /payment-tokens/create ---\n const result = await deps.apiClient.post<Record<string, unknown>>(\n '/payment-tokens/create',\n { type: 'api-key', key: apiKey },\n body,\n extraHeaders,\n );\n\n if (!result.success) {\n throw CliError.fromApi(result, { auth: 'api-key' });\n }\n\n const tokenData = result.data;\n // Ensure type is on the top-level data for formatPaymentToken\n if (!tokenData.type) {\n tokenData.type = serverType;\n }\n\n // --- Output ---\n notify(format, 'success', 'Payment token created');\n\n const configManager = new ConfigManager();\n const commandResult: CommandResult<Record<string, unknown>> = {\n data: tokenData,\n text: () => {\n let output = formatPaymentToken(tokenData);\n // X402: append info message about X-PAYMENT header\n if (serverType === 'x402') {\n output += '\\n' + Formatter.status('info', 'Use the Signature Value in the X-PAYMENT request header');\n }\n return output;\n },\n };\n\n await renderWithContext(commandResult, { format }, configManager);\n });\n}\n\n// ============================================================\n// Type-branch helpers\n// ============================================================\n\n/**\n * VCN feature gate: GET /features/vcn — if disabled, throw TOKEN_FEATURE_DISABLED.\n */\nasync function checkVcnFeatureEnabled(apiClient: ApiClient, apiKey: string): Promise<void> {\n const result = await apiClient.get<{ enabled: boolean }>(\n '/features/vcn',\n { type: 'api-key', key: apiKey },\n );\n\n if (!result.success) {\n // If the endpoint fails, treat as feature disabled (conservative)\n throw CliError.fromApi(result, { auth: 'api-key' });\n }\n\n if (!result.data.enabled) {\n throw new CliError(\n 'TOKEN_FEATURE_DISABLED',\n 'VCN creation is not supported yet. Coming soon.',\n );\n }\n}\n\n/**\n * Fetch network-token fee from /config/network-token-fee.\n * Falls back to DEFAULT_NT_FEE_CENTS (50) if unreachable.\n */\nasync function fetchNetworkTokenFee(apiClient: ApiClient, apiKey: string): Promise<number> {\n try {\n const result = await apiClient.get<{ fee_cents: number }>(\n '/config/network-token-fee',\n { type: 'api-key', key: apiKey },\n );\n\n if (result.success && typeof result.data.fee_cents === 'number') {\n return result.data.fee_cents;\n }\n // Unreachable / unexpected shape → fallback\n return DEFAULT_NT_FEE_CENTS;\n } catch {\n // Network error / timeout → fallback\n return DEFAULT_NT_FEE_CENTS;\n }\n}\n","import { Command } from 'commander';\nimport {\n ApiClient,\n ConfigManager,\n PromptEngine,\n Formatter,\n resolveFormat,\n CliError,\n renderWithContext,\n} from '@agenzo/cli-core';\nimport type { CommandResult } from '@agenzo/cli-core';\nimport { attachSchemaHelp, ptListSchema } from '../verb-schema.js';\n\n// ============================================================\n// getSummary — per-type summary for table rendering (§3.4.2)\n// ============================================================\n\n/**\n * Render a one-line summary for a payment token in the list table.\n *\n * - vcn: `<first6>****<last4> $<limit/100>` (e.g. \"411111****1234 $25.00\")\n * - network_token: `<brand>` (e.g. \"Visa\")\n * - x402: `<amount> <network>` (e.g. \"1000000 Base\")\n */\nfunction getSummary(token: Record<string, unknown>): string {\n const type = token.type as string;\n\n if (type === 'vcn') {\n const first6 = String(token.first6 || token.first_six || '');\n const last4 = String(token.last4 || token.last_four || '');\n const limit = token.amount_limit as number | undefined ?? token.limit as number | undefined;\n const limitDisplay = limit !== undefined && limit !== null\n ? `$${(limit / 100).toFixed(2)}`\n : '';\n return `${first6}****${last4} ${limitDisplay}`.trim();\n }\n\n if (type === 'network_token') {\n const nt = token.network_token as Record<string, unknown> | undefined;\n return String(nt?.payment_brand || token.brand || '');\n }\n\n if (type === 'x402') {\n const amount = String(token.amount ?? '');\n const network = String(token.network || '');\n return `${amount} ${network}`.trim();\n }\n\n return '';\n}\n\n// ============================================================\n// Command registration\n// ============================================================\n\n/**\n * `payment-tokens list` — list payment tokens (§3.4.2).\n *\n * GET /payment-tokens with X-Api-Key header.\n * Optional --type flag maps to ?type= query param.\n * Optional --member flag maps to ?member_id= query param.\n * Table headers: Token ID / Type / Status / Summary.\n * Empty list → `ℹ No payment tokens found` (no table).\n */\nexport function registerListCommand(parent: Command, deps: { apiClient: ApiClient }): void {\n const cmd = parent\n .command('list')\n .description('List payment tokens')\n .option('--api-key <key>', 'API Key for authentication')\n .option('--type <type>', 'Filter by token type')\n .option('--member <member_id>', 'Filter by member ID');\n\n attachSchemaHelp(cmd, ptListSchema);\n\n cmd.action(async () => {\n const opts = cmd.optsWithGlobals();\n const format = resolveFormat(opts.format as string | undefined);\n\n const apiKey = await PromptEngine.resolveInput(opts.apiKey as string | undefined, {\n message: 'API Key:',\n type: 'password',\n });\n\n // Build query params\n const params: Record<string, string> = {};\n if (opts.type) {\n params.type = opts.type as string;\n }\n if (opts.member) {\n params.member_id = opts.member as string;\n }\n\n const result = await deps.apiClient.get<Record<string, unknown>[]>(\n '/payment-tokens',\n { type: 'api-key', key: apiKey },\n Object.keys(params).length > 0 ? params : undefined,\n );\n\n if (!result.success) {\n throw CliError.fromApi(result, { auth: 'api-key' });\n }\n\n const tokens = result.data;\n\n const configManager = new ConfigManager();\n const commandResult: CommandResult<{ payment_tokens: Record<string, unknown>[] }> = {\n data: { payment_tokens: tokens },\n text: () => {\n if (tokens.length === 0) {\n return Formatter.status('info', 'No payment tokens found');\n }\n const headers = ['Token ID', 'Type', 'Status', 'Summary'];\n const rows = tokens.map((t) => [\n String(t.id || ''),\n String(t.type || ''),\n String(t.status || ''),\n getSummary(t),\n ]);\n return Formatter.table(headers, rows);\n },\n };\n\n await renderWithContext(commandResult, { format }, configManager);\n });\n}\n","import { Command } from 'commander';\nimport {\n ApiClient,\n ConfigManager,\n Formatter,\n PromptEngine,\n resolveFormat,\n CliError,\n renderWithContext,\n} from '@agenzo/cli-core';\nimport type { CommandResult } from '@agenzo/cli-core';\nimport { attachSchemaHelp, ptGetSchema } from '../verb-schema.js';\n\n// ============================================================\n// Formatter — SEPARATE from create's `formatPaymentToken` (Property 7)\n// ============================================================\n\ninterface FormatPaymentTokenGetOptions {\n revealSensitive?: boolean;\n}\n\nfunction asString(value: unknown): string {\n return typeof value === 'string' ? value : '';\n}\n\nfunction maskPan(value: string, lastFour?: string): string {\n const suffix = lastFour || value.slice(-4);\n if (!suffix) return '';\n const maskedLength = Math.max(value.length - suffix.length, 4);\n return `${'*'.repeat(maskedLength)}${suffix}`;\n}\n\nfunction maskCvc(value: string): string {\n return value ? '***' : '';\n}\n\nfunction maskVcnFields(vcn: Record<string, unknown>): Record<string, unknown> {\n const masked = { ...vcn };\n const lastFour = asString(masked.last_four ?? masked.last4);\n\n if (typeof masked.card_number === 'string') {\n masked.card_number = maskPan(masked.card_number, lastFour);\n }\n if (typeof masked.pan === 'string') {\n masked.pan = maskPan(masked.pan, lastFour);\n }\n if (typeof masked.cvc === 'string') {\n masked.cvc = maskCvc(masked.cvc);\n }\n if (typeof masked.cvv === 'string') {\n masked.cvv = maskCvc(masked.cvv);\n }\n\n return masked;\n}\n\n/** Build the JSON payload for `payment-tokens get`, masking VCN secrets by default. */\nexport function buildPaymentTokenGetPayload(\n data: Record<string, unknown>,\n opts: FormatPaymentTokenGetOptions = {},\n): Record<string, unknown> {\n if (opts.revealSensitive || data.type !== 'vcn') {\n return data;\n }\n\n const payload = { ...data };\n if (payload.vcn && typeof payload.vcn === 'object') {\n payload.vcn = maskVcnFields(payload.vcn as Record<string, unknown>);\n return payload;\n }\n\n return maskVcnFields(payload);\n}\n\n/**\n * Format a payment token for the `get` command output (§3.4.3).\n *\n * CRITICAL: This MUST remain a standalone formatter — do NOT converge\n * with `formatPaymentToken` in create.ts. The differences are intentional\n * per design Property 7:\n *\n * - Top key: `Token ID` (create uses `Payment Token ID`)\n * - VCN: includes a `Last 4` line (create does not)\n * - VCN `Limit` / `Balance`: numeric values WITHOUT `$` prefix\n * (create uses `$` prefix for `Limit`)\n *\n * By default VCN PAN/CVC are masked. Use `--reveal` to intentionally print\n * full VCN credentials for a payment flow that needs to use them.\n */\nexport function formatPaymentTokenGet(\n data: Record<string, unknown>,\n opts: FormatPaymentTokenGetOptions = {},\n): string {\n const type = data.type as string;\n const lines: [string, string][] = [];\n\n if (type === 'vcn') {\n const vcn = (data.vcn as Record<string, unknown> | undefined) ?? data;\n const lastFour = asString(vcn.last_four ?? vcn.last4);\n const cardNumber = asString(vcn.card_number ?? vcn.pan);\n const cvc = asString(vcn.cvc ?? vcn.cvv);\n lines.push(['Token ID', String(data.id || vcn.id || '')]);\n lines.push(['Type', 'VCN']);\n lines.push([\n 'Card Number',\n opts.revealSensitive ? cardNumber : maskPan(cardNumber, lastFour),\n ]);\n lines.push(['Last 4', lastFour]);\n lines.push(['Expiry', String(vcn.expiry || '')]);\n lines.push(['CVC', opts.revealSensitive ? cvc : maskCvc(cvc)]);\n // Limit and Balance: numeric cents → USD string, NO `$` prefix\n lines.push(['Limit', formatCentsPlain(vcn.amount_limit as number)]);\n lines.push(['Balance', formatCentsPlain(vcn.balance as number)]);\n lines.push(['Currency', String(vcn.currency || 'USD')]);\n lines.push(['Status', String(vcn.status || data.status || '')]);\n } else if (type === 'network_token') {\n const nt = (data.network_token as Record<string, unknown> | undefined) ?? data;\n lines.push(['Token ID', String(data.id || nt.id || '')]);\n lines.push(['Type', 'Network Token']);\n lines.push(['Brand', String(nt.payment_brand || nt.brand || '')]);\n lines.push(['ECI', String(nt.eci || '')]);\n lines.push(['Cryptogram', String(nt.token_cryptogram || nt.cryptogram || '')]);\n lines.push(['Expiry', String(nt.expiry_date || nt.expiry || '')]);\n lines.push(['Value', String(nt.value || '')]);\n } else if (type === 'x402') {\n const x402 = (data.x402 as Record<string, unknown> | undefined) ?? data;\n lines.push(['Token ID', String(data.id || x402.id || '')]);\n lines.push(['Type', 'X402']);\n lines.push(['Signature Value', String(x402.signature_value || '')]);\n lines.push(['Status', String(x402.status || data.status || '')]);\n } else {\n // Unknown type: best-effort\n lines.push(['Token ID', String(data.id || '')]);\n lines.push(['Type', String(type || 'unknown')]);\n lines.push(['Status', String(data.status || '')]);\n }\n\n return Formatter.keyValue(lines);\n}\n\n/**\n * Format cents as plain USD string without `$` prefix (e.g. 1250 → \"12.50\").\n * This is the key difference from create's `formatCentsToUsd` which is used\n * with a `$` prefix in `Limit`.\n */\nfunction formatCentsPlain(cents: number | undefined | null): string {\n if (cents === undefined || cents === null) return '0.00';\n const dollars = Math.floor(cents / 100);\n const remainder = cents % 100;\n return `${dollars}.${String(remainder).padStart(2, '0')}`;\n}\n\n// ============================================================\n// Command registration\n// ============================================================\n\n/**\n * `payment-tokens get <payment_token_id>` — show a payment token (§3.4.3).\n *\n * Reads: GET /payment-tokens/<id> (X-Api-Key).\n * Output: keyValue with formatting that DIFFERS from create output (Property 7).\n */\nexport function registerGetCommand(parent: Command, deps: { apiClient: ApiClient }): void {\n const cmd = parent\n .command('get <payment_token_id>')\n .description('Get a payment token by ID')\n .option('--api-key <key>', 'API key for authentication')\n .option('--reveal', 'Reveal full VCN card number and CVC in the output');\n\n attachSchemaHelp(cmd, ptGetSchema);\n\n cmd.action(async (paymentTokenId: string) => {\n const opts = cmd.optsWithGlobals();\n const format = resolveFormat(opts.format as string | undefined);\n\n // Resolve API key — prompt interactively if not provided via flag\n const apiKey = await PromptEngine.resolveInput(opts.apiKey as string | undefined, {\n message: 'API Key:',\n type: 'password',\n });\n\n // GET /payment-tokens/<id>\n const result = await deps.apiClient.get<Record<string, unknown>>(\n `/payment-tokens/${paymentTokenId}`,\n { type: 'api-key', key: apiKey },\n );\n\n if (!result.success) {\n throw CliError.fromApi(result, { auth: 'api-key' });\n }\n\n const revealSensitive = Boolean(opts.reveal);\n const tokenData = buildPaymentTokenGetPayload(result.data, { revealSensitive });\n\n const configManager = new ConfigManager();\n const commandResult: CommandResult<Record<string, unknown>> = {\n data: tokenData,\n text: () => formatPaymentTokenGet(result.data, { revealSensitive }),\n };\n\n await renderWithContext(commandResult, { format }, configManager);\n });\n}\n","import { Command } from 'commander';\nimport {\n ApiClient,\n ConfigManager,\n PromptEngine,\n Formatter,\n resolveFormat,\n notify,\n CliError,\n IdempotencyKeyRequiredError,\n renderWithContext,\n} from '@agenzo/cli-core';\nimport type { CommandResult } from '@agenzo/cli-core';\nimport type { RevokeResult } from '../types/api.js';\nimport { attachSchemaHelp, ptRevokeSchema } from '../verb-schema.js';\n\n/**\n * `payment-tokens revoke <payment_token_id>` — revoke a payment token (§3.4.4).\n *\n * POST /payment-tokens/<id>/revoke (no body).\n * Two output states:\n * 1. Immediate revoke: `✓ Payment token revoked` + Token ID / Status / Revoked At\n * 2. Delayed revoke (X402, status==='ACTIVE' && expires_at non-null):\n * `✓ Revoke scheduled (cryptogram will auto-expire)` + Token ID / Status / Expires At (+message)\n *\n * Idempotency: --idempotency-key required in --yes mode (Requirement 6.3).\n */\nexport function registerRevokeCommand(parent: Command, deps: { apiClient: ApiClient }): void {\n const cmd = parent\n .command('revoke <payment_token_id>')\n .description('Revoke a payment token')\n .option('--api-key <key>', 'API key for authentication')\n .option(\n '--idempotency-key <key>',\n 'Idempotency key forwarded verbatim as the Idempotency-Key header',\n );\n\n attachSchemaHelp(cmd, ptRevokeSchema);\n\n cmd.action(async (paymentTokenId: string) => {\n const opts = cmd.optsWithGlobals();\n const format = resolveFormat(opts.format as string | undefined);\n\n const apiKey = await PromptEngine.resolveInput(opts.apiKey as string | undefined, {\n message: 'API Key:',\n type: 'password',\n });\n\n // Idempotency key handling (Requirement 6.3):\n // In --yes mode, --idempotency-key is mandatory — never auto-generate, never send request.\n // In interactive mode, prompt if not provided.\n let idempotencyKey = opts.idempotencyKey as string | undefined;\n if (!idempotencyKey) {\n if (opts.yes) {\n throw new IdempotencyKeyRequiredError('payment-tokens revoke');\n }\n idempotencyKey = await PromptEngine.resolveInput(undefined, {\n message: 'Idempotency key (unique per write, for safe retry):',\n validate: (v) => v.trim().length > 0 || 'Idempotency key is required',\n });\n }\n\n const extraHeaders: Record<string, string> = {\n 'Idempotency-Key': idempotencyKey,\n };\n\n const result = await deps.apiClient.post<RevokeResult>(\n `/payment-tokens/${paymentTokenId}/revoke`,\n { type: 'api-key', key: apiKey },\n undefined,\n extraHeaders,\n );\n\n if (!result.success) {\n throw CliError.fromApi(result, { auth: 'api-key' });\n }\n\n const data = result.data;\n\n // Determine output state:\n // Delayed revoke (X402): status is still ACTIVE and expires_at is present\n // Immediate revoke: all other cases\n const isDelayedRevoke = data.status === 'ACTIVE' && data.expires_at != null;\n\n if (isDelayedRevoke) {\n // Delayed revoke (X402 cryptogram will auto-expire)\n notify(format, 'success', 'Revoke scheduled (cryptogram will auto-expire)');\n\n const kvPairs: [string, string][] = [\n ['Token ID', data.id],\n ['Status', data.status],\n ['Expires At', Formatter.formatTime(data.expires_at)],\n ];\n if (data.message) {\n kvPairs.push(['Message', data.message]);\n }\n\n const cmdResult: CommandResult<RevokeResult> = {\n data,\n text: () => Formatter.keyValue(kvPairs),\n };\n\n const configManager = new ConfigManager();\n await renderWithContext(cmdResult, { format }, configManager);\n } else {\n // Immediate revoke\n notify(format, 'success', 'Payment token revoked');\n\n const cmdResult: CommandResult<RevokeResult> = {\n data,\n text: () =>\n Formatter.keyValue([\n ['Token ID', data.id],\n ['Status', data.status],\n ['Revoked At', Formatter.formatTime(data.revoked_at)],\n ]),\n };\n\n const configManager = new ConfigManager();\n await renderWithContext(cmdResult, { format }, configManager);\n }\n });\n}\n"],"mappings":"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","names":["readFile","writeFile","mkdir","chmod","join","homedir","join","homedir","mkdir","chmod","readFile","writeFile","password","password","select","select","cents","registerListCommand","registerGetCommand","registerListCommand","registerGetCommand"]}
|