@visa/cli 4.1.0-rc.156 → 4.1.0-rc.158
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/checkout-engine/cli-engine.d.ts +16 -1
- package/dist/checkout-engine/cli-engine.js +26 -2
- package/dist/checkout-engine/executor.d.ts +3 -0
- package/dist/checkout-engine/executor.js +9 -2
- package/dist/checkout-engine/index.d.ts +2 -2
- package/dist/checkout-engine/index.js +1 -1
- package/dist/cli.js +346 -346
- package/dist/mcp-server/index.js +259 -259
- package/dist/skills/pair-visa-agent/SKILL.md +68 -9
- package/native/bin/win32-x64/visa-keychain-win.exe +0 -0
- package/package.json +2 -3
- package/server.json +2 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type Browser } from 'playwright-core';
|
|
2
|
-
import { prepareCheckout as realPrepareCheckout, submitApprovedCheckout as realSubmitApprovedCheckout, type CheckoutOutcome, type PreparedCheckoutSessionStore } from './executor.js';
|
|
2
|
+
import { prepareCheckout as realPrepareCheckout, submitApprovedCheckout as realSubmitApprovedCheckout, type CheckoutOutcome, type CheckoutFailureCode, type CheckoutResult, type PreparedCheckoutSessionStore } from './executor.js';
|
|
3
3
|
import { claimMandatePickup as realClaimMandatePickup, runHostedApproval as realRunHostedApproval } from './hosted-approval.js';
|
|
4
4
|
import { type VgsCheckoutTarget } from './vgs-live-instrument.js';
|
|
5
5
|
import { serverFetchCryptogram, serverPostConfirmation } from './vgs-gateway/server-mint-client.js';
|
|
@@ -51,6 +51,21 @@ export type CliReviewFacts = {
|
|
|
51
51
|
submitTargetFingerprint: string;
|
|
52
52
|
detectedRoles: string[];
|
|
53
53
|
};
|
|
54
|
+
/**
|
|
55
|
+
* A checkout was inspected successfully but cannot be reviewed safely.
|
|
56
|
+
*
|
|
57
|
+
* The explicit fields survive the CLI's copied-engine boundary structurally,
|
|
58
|
+
* so MCP callers do not have to parse the human-readable message.
|
|
59
|
+
*/
|
|
60
|
+
export declare class CheckoutReviewRefusedError extends Error {
|
|
61
|
+
readonly code = "CHECKOUT_REVIEW_REFUSED";
|
|
62
|
+
readonly checkoutOutcome: CheckoutOutcome;
|
|
63
|
+
readonly failureCode?: CheckoutFailureCode;
|
|
64
|
+
readonly requiresAdapter: string[];
|
|
65
|
+
readonly detectedRoles: string[];
|
|
66
|
+
readonly detail?: string;
|
|
67
|
+
constructor(result: CheckoutResult);
|
|
68
|
+
}
|
|
54
69
|
export type CliPayInput = CliReviewInput & {
|
|
55
70
|
reviewId: string;
|
|
56
71
|
submit: boolean;
|
|
@@ -118,6 +118,31 @@ async function resolveCardInstrument(input) {
|
|
|
118
118
|
'`visa agent grant-card <agent-id> --ceiling <usd> --per-transaction <usd> --wait` to ' +
|
|
119
119
|
'attach one, or use a pre-provisioned VIC runtime.', readError instanceof Error ? { cause: readError } : undefined);
|
|
120
120
|
}
|
|
121
|
+
/**
|
|
122
|
+
* A checkout was inspected successfully but cannot be reviewed safely.
|
|
123
|
+
*
|
|
124
|
+
* The explicit fields survive the CLI's copied-engine boundary structurally,
|
|
125
|
+
* so MCP callers do not have to parse the human-readable message.
|
|
126
|
+
*/
|
|
127
|
+
export class CheckoutReviewRefusedError extends Error {
|
|
128
|
+
code = 'CHECKOUT_REVIEW_REFUSED';
|
|
129
|
+
checkoutOutcome;
|
|
130
|
+
failureCode;
|
|
131
|
+
requiresAdapter;
|
|
132
|
+
detectedRoles;
|
|
133
|
+
detail;
|
|
134
|
+
constructor(result) {
|
|
135
|
+
super(result.detail
|
|
136
|
+
? `review refused: ${result.outcome} — ${result.detail}`
|
|
137
|
+
: `review refused: ${result.outcome}`);
|
|
138
|
+
this.name = 'CheckoutReviewRefusedError';
|
|
139
|
+
this.checkoutOutcome = result.outcome;
|
|
140
|
+
this.failureCode = result.failureCode;
|
|
141
|
+
this.requiresAdapter = [...result.requiresAdapter];
|
|
142
|
+
this.detectedRoles = Object.keys(result.fields);
|
|
143
|
+
this.detail = result.detail;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
121
146
|
function payAttemptFingerprint(input) {
|
|
122
147
|
return JSON.stringify([
|
|
123
148
|
input.url,
|
|
@@ -488,8 +513,7 @@ export function createCliCheckoutEngine(deps = {}) {
|
|
|
488
513
|
contact: input.contact,
|
|
489
514
|
}, store);
|
|
490
515
|
if (prep.status !== 'ready') {
|
|
491
|
-
|
|
492
|
-
throw new Error(`review refused: ${prep.result.outcome} — ${prep.result.detail ?? ''}`);
|
|
516
|
+
throw new CheckoutReviewRefusedError(prep.result);
|
|
493
517
|
}
|
|
494
518
|
const r = prep.checkout.review;
|
|
495
519
|
// Expire the companion session on the SAME schedule as the store entry
|
|
@@ -11,6 +11,8 @@ export type CheckoutMode = 'dry-run' | 'submit';
|
|
|
11
11
|
export type CheckoutOutcome = 'reviewed-dry-run'
|
|
12
12
|
/** Historical receipt value from the credential-disclosing dry-run. */
|
|
13
13
|
| 'filled-dry-run' | 'partial-fill' | 'adapter-required' | 'confirmed' | 'declined' | 'action-required' | 'cancelled' | 'blocked-by-mandate' | 'failed';
|
|
14
|
+
/** Stable machine-readable cause for an expected terminal checkout result. */
|
|
15
|
+
export type CheckoutFailureCode = 'card-number-field-unavailable' | 'human-action-required' | 'mandate-blocked';
|
|
14
16
|
export type CredentialLifecycle = 'not-requested' | 'minted-not-exposed' | 'partially-exposed' | 'fully-filled';
|
|
15
17
|
export type CredentialTiming = {
|
|
16
18
|
approvedAt?: string;
|
|
@@ -26,6 +28,7 @@ export type CheckoutResult = {
|
|
|
26
28
|
requiresAdapter: string[];
|
|
27
29
|
credentialLifecycle: CredentialLifecycle;
|
|
28
30
|
credentialTiming: CredentialTiming;
|
|
31
|
+
failureCode?: CheckoutFailureCode;
|
|
29
32
|
detail?: string;
|
|
30
33
|
};
|
|
31
34
|
export type PrepareCheckoutOptions = {
|
|
@@ -341,7 +341,7 @@ function unknownPreparedCheckoutResult(reviewId) {
|
|
|
341
341
|
evidence.step('approval', { approved: false, reviewId, reason: detail });
|
|
342
342
|
return makeResult('failed', {}, evidence, [], detail);
|
|
343
343
|
}
|
|
344
|
-
function makeResult(outcome, fields, evidence, requiresAdapter, detail, confirmationRef) {
|
|
344
|
+
function makeResult(outcome, fields, evidence, requiresAdapter, detail, confirmationRef, failureCode) {
|
|
345
345
|
const steps = evidence.getSteps();
|
|
346
346
|
const approved = steps.find((step) => step.type === 'approval' && step.data.approved === true);
|
|
347
347
|
const minted = steps.find((step) => step.type === 'credential-minted');
|
|
@@ -359,6 +359,12 @@ function makeResult(outcome, fields, evidence, requiresAdapter, detail, confirma
|
|
|
359
359
|
: filledRoles.has('number') || filledRoles.has('cvc')
|
|
360
360
|
? 'partially-exposed'
|
|
361
361
|
: 'minted-not-exposed';
|
|
362
|
+
const terminalFailureCode = failureCode ??
|
|
363
|
+
(outcome === 'action-required'
|
|
364
|
+
? 'human-action-required'
|
|
365
|
+
: outcome === 'blocked-by-mandate'
|
|
366
|
+
? 'mandate-blocked'
|
|
367
|
+
: undefined);
|
|
362
368
|
return {
|
|
363
369
|
outcome,
|
|
364
370
|
fields,
|
|
@@ -373,6 +379,7 @@ function makeResult(outcome, fields, evidence, requiresAdapter, detail, confirma
|
|
|
373
379
|
: {}),
|
|
374
380
|
...(completed ? { fillCompletedAt: completed.ts } : {}),
|
|
375
381
|
},
|
|
382
|
+
...(terminalFailureCode ? { failureCode: terminalFailureCode } : {}),
|
|
376
383
|
...(detail ? { detail } : {}),
|
|
377
384
|
...(confirmationRef ? { confirmationRef } : {}),
|
|
378
385
|
};
|
|
@@ -844,7 +851,7 @@ export async function prepareCheckout(opts, store = defaultPreparedCheckoutStore
|
|
|
844
851
|
evidence.setSnapshotSummary(await snapshotSummary(page));
|
|
845
852
|
return {
|
|
846
853
|
status: 'finished',
|
|
847
|
-
result: makeResult('failed', fields, evidence, requiresAdapter, reason),
|
|
854
|
+
result: makeResult('failed', fields, evidence, requiresAdapter, reason, undefined, 'card-number-field-unavailable'),
|
|
848
855
|
};
|
|
849
856
|
}
|
|
850
857
|
const facts = await readTransactionFacts(page, options, 'review');
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { createCliCheckoutEngine, type CliReviewInput, type CliReviewFacts, type CliPayInput, type CliReceiptFacts, type CliStartMandateInput, type CliMandateFacts, type CliEngineDeps, } from './cli-engine.js';
|
|
1
|
+
export { createCliCheckoutEngine, type CliReviewInput, type CliReviewFacts, type CliPayInput, type CliReceiptFacts, type CliStartMandateInput, type CliMandateFacts, type CliEngineDeps, CheckoutReviewRefusedError, } from './cli-engine.js';
|
|
2
2
|
export { prepareCheckout, submitApprovedCheckout, runCheckout, InMemoryPreparedCheckoutStore, } from './executor.js';
|
|
3
|
-
export type { CheckoutResult, CheckoutReview, CheckoutOutcome } from './executor.js';
|
|
3
|
+
export type { CheckoutResult, CheckoutReview, CheckoutOutcome, CheckoutFailureCode, } from './executor.js';
|
|
4
4
|
export { readConfirmedMerchants, type ConfirmedMerchant, type ConfirmedCharge, } from './confirmed-merchants.js';
|
|
5
5
|
export { KNOWN_MERCHANT_IDENTITIES, type MerchantIdentity } from './known-merchants.js';
|
|
6
6
|
export { RECEIPT_DIR } from './receipt-dir.js';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Public API of @visa/checkout-engine. The pay_merchant tool in @visa/cli
|
|
2
2
|
// consumes createCliCheckoutEngine() through a structural seam; the core engine
|
|
3
3
|
// primitives are re-exported for direct/embedded use.
|
|
4
|
-
export { createCliCheckoutEngine, } from './cli-engine.js';
|
|
4
|
+
export { createCliCheckoutEngine, CheckoutReviewRefusedError, } from './cli-engine.js';
|
|
5
5
|
export { prepareCheckout, submitApprovedCheckout, runCheckout, InMemoryPreparedCheckoutStore, } from './executor.js';
|
|
6
6
|
export { readConfirmedMerchants, } from './confirmed-merchants.js';
|
|
7
7
|
export { KNOWN_MERCHANT_IDENTITIES } from './known-merchants.js';
|