@visa/cli 4.1.0-rc.27 → 4.1.0-rc.270
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +202 -46
- package/dist/checkout-engine/adapters/generic.d.ts +69 -0
- package/dist/checkout-engine/adapters/generic.js +383 -58
- package/dist/checkout-engine/adapters/index.d.ts +4 -1
- package/dist/checkout-engine/adapters/index.js +10 -3
- package/dist/checkout-engine/adapters/shopify.d.ts +98 -0
- package/dist/checkout-engine/adapters/shopify.js +744 -0
- package/dist/checkout-engine/amount.d.ts +17 -0
- package/dist/checkout-engine/amount.js +72 -0
- package/dist/checkout-engine/browser-launch.d.ts +9 -4
- package/dist/checkout-engine/browser-launch.js +19 -4
- package/dist/checkout-engine/browserbase-browser.d.ts +24 -0
- package/dist/checkout-engine/browserbase-browser.js +186 -0
- package/dist/checkout-engine/cli-engine.d.ts +247 -32
- package/dist/checkout-engine/cli-engine.js +960 -222
- package/dist/checkout-engine/confirmed-merchants.d.ts +31 -0
- package/dist/checkout-engine/confirmed-merchants.js +165 -0
- package/dist/checkout-engine/detect.d.ts +1 -1
- package/dist/checkout-engine/detect.js +6 -0
- package/dist/checkout-engine/evidence.d.ts +1 -1
- package/dist/checkout-engine/executor.d.ts +92 -4
- package/dist/checkout-engine/executor.js +688 -157
- package/dist/checkout-engine/hosted-approval.d.ts +69 -9
- package/dist/checkout-engine/hosted-approval.js +211 -21
- package/dist/checkout-engine/index.d.ts +9 -3
- package/dist/checkout-engine/index.js +7 -2
- package/dist/checkout-engine/instrument.d.ts +6 -0
- package/dist/checkout-engine/known-merchants.d.ts +10 -0
- package/dist/checkout-engine/known-merchants.js +38 -0
- package/dist/checkout-engine/live-fill-approval.d.ts +5 -11
- package/dist/checkout-engine/live-fill-approval.js +20 -34
- package/dist/checkout-engine/mandate/card-mandate.d.ts +6 -2
- package/dist/checkout-engine/mandate/card-mandate.js +10 -5
- package/dist/checkout-engine/mandate/mandate-ledger.d.ts +63 -23
- package/dist/checkout-engine/mandate/mandate-ledger.js +124 -17
- package/dist/checkout-engine/mandate.d.ts +8 -0
- package/dist/checkout-engine/mandate.js +44 -9
- package/dist/checkout-engine/receipt-dir.d.ts +6 -0
- package/dist/checkout-engine/receipt-dir.js +8 -0
- package/dist/checkout-engine/receipt.d.ts +56 -2
- package/dist/checkout-engine/receipt.js +55 -16
- package/dist/checkout-engine/shopify-primary-domain.d.ts +25 -0
- package/dist/checkout-engine/shopify-primary-domain.js +96 -0
- package/dist/checkout-engine/trace-handles.d.ts +8 -0
- package/dist/checkout-engine/trace-handles.js +12 -0
- package/dist/checkout-engine/types.d.ts +15 -2
- package/dist/checkout-engine/unresolved-charges.d.ts +34 -0
- package/dist/checkout-engine/unresolved-charges.js +134 -0
- package/dist/checkout-engine/vgs-gateway/server-mint-client.d.ts +63 -7
- package/dist/checkout-engine/vgs-gateway/server-mint-client.js +181 -27
- package/dist/checkout-engine/vgs-live-instrument.d.ts +11 -35
- package/dist/checkout-engine/vgs-live-instrument.js +14 -74
- package/dist/checkout-engine/vic-confirmation.d.ts +18 -0
- package/dist/checkout-engine/vic-confirmation.js +9 -3
- package/dist/checkout-engine/web-bot-auth.d.ts +98 -0
- package/dist/checkout-engine/web-bot-auth.js +218 -0
- package/dist/cli.js +904 -391
- package/dist/mcp-apps/ucp-checkout.html +280 -0
- package/dist/mcp-server/index.js +729 -257
- package/dist/merchant-ucp-mcp/index.js +6 -0
- package/dist/skills/pair-visa-agent/RUNTIMES.md +122 -79
- package/dist/skills/pair-visa-agent/SKILL.md +433 -318
- package/dist/skills/pair-visa-agent/scripts/__tests__/setup.test.mjs +407 -0
- package/dist/skills/pair-visa-agent/scripts/setup.mjs +310 -30
- package/dist/skills/visa-shopify-checkout/SKILL.md +122 -0
- package/dist/skills/visa-shopify-checkout/references/evidence-and-states.md +37 -0
- package/dist/skills/visa-ucp-shopping/SKILL.md +86 -0
- package/dist/subway-direct.mjs +1 -0
- package/install.ps1 +7 -6
- package/install.sh +3 -3
- package/native/bin/win32-x64/visa-keychain-win.exe +0 -0
- package/package.json +31 -28
- package/server.json +4 -4
- package/dist/checkout-engine/inline-target.d.ts +0 -13
- package/dist/checkout-engine/inline-target.js +0 -37
- package/dist/checkout-engine/pay-args.d.ts +0 -14
- package/dist/checkout-engine/pay-args.js +0 -44
- package/dist/checkout-engine/pay.d.ts +0 -1
- package/dist/checkout-engine/pay.js +0 -13
- package/dist/checkout-engine/repo-env.d.ts +0 -11
- package/dist/checkout-engine/repo-env.js +0 -23
- package/dist/checkout-engine/run-live-fill.d.ts +0 -1
- package/dist/checkout-engine/run-live-fill.js +0 -493
- package/dist/checkout-engine/vgs-gateway/fetch-credential.d.mts +0 -74
- package/dist/checkout-engine/vgs-gateway/fetch-credential.mjs +0 -248
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { type Browser } from 'playwright-core';
|
|
2
|
-
import { prepareCheckout as realPrepareCheckout, submitApprovedCheckout as realSubmitApprovedCheckout, type PreparedCheckoutSessionStore } from './executor.js';
|
|
3
|
-
import {
|
|
2
|
+
import { prepareCheckout as realPrepareCheckout, submitApprovedCheckout as realSubmitApprovedCheckout, type CheckoutMode, type CheckoutOutcome, type CheckoutFailureCode, type CheckoutResult, type PreparedCheckoutSessionStore } from './executor.js';
|
|
3
|
+
import type { MandateRefusalCode } from './mandate.js';
|
|
4
|
+
import { claimMandatePickup as realClaimMandatePickup, runHostedApproval as realRunHostedApproval } from './hosted-approval.js';
|
|
4
5
|
import { type VgsCheckoutTarget } from './vgs-live-instrument.js';
|
|
5
|
-
import { serverFetchCryptogram } from './vgs-gateway/server-mint-client.js';
|
|
6
|
+
import { ServerIntentError, serverFetchCryptogram, serverPostConfirmation } from './vgs-gateway/server-mint-client.js';
|
|
6
7
|
import { type CardMandateFacts } from './mandate/card-mandate.js';
|
|
7
8
|
import { MandateLedger } from './mandate/mandate-ledger.js';
|
|
8
9
|
import { writeReceipt as realWriteReceipt } from './receipt.js';
|
|
9
10
|
import { reportVicOutcome as realReportVicOutcome, type VicConfirmationReport } from './vic-confirmation.js';
|
|
10
|
-
import type { Contact } from './types.js';
|
|
11
|
+
import type { Contact, OtpResolver } from './types.js';
|
|
11
12
|
/**
|
|
12
13
|
* A card-mandate draw failed transiently (retryable) rather than definitively.
|
|
13
14
|
* Gateway 5xx, "server cryptogram not completed / try again", and network
|
|
@@ -16,15 +17,45 @@ import type { Contact } from './types.js';
|
|
|
16
17
|
* is classified by its underlying gateway error. Exported for tests.
|
|
17
18
|
*/
|
|
18
19
|
export declare function isTransientDrawFailure(err: unknown): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* A verdict refusal may be wrapped by drawFromMandate after its local
|
|
22
|
+
* reservation is released. Walk the cause chain so the original auth status +
|
|
23
|
+
* reasons still decide whether the mandate is permanently disabled.
|
|
24
|
+
*/
|
|
25
|
+
export declare function classifyCardDrawVerdictFailure(err: unknown): {
|
|
26
|
+
transient: boolean;
|
|
27
|
+
grantCapacity: boolean;
|
|
28
|
+
reasons: string[];
|
|
29
|
+
} | null;
|
|
19
30
|
export type CliReviewInput = {
|
|
20
31
|
url: string;
|
|
32
|
+
checkoutRoute: 'guest-card';
|
|
21
33
|
amount: string;
|
|
22
34
|
currency: string;
|
|
23
35
|
credentialPath: string;
|
|
36
|
+
/** See {@link CardInstrumentSource}. */
|
|
37
|
+
cardTokenId?: string;
|
|
38
|
+
/** Exact request-key identity selected by the caller. */
|
|
39
|
+
agentJkt?: string;
|
|
40
|
+
/** Owner-facing selected-agent label for the compact local receipt. */
|
|
41
|
+
agentName?: string;
|
|
42
|
+
/** Safe display suffix derived from the selected card grant label. */
|
|
43
|
+
cardLast4?: string;
|
|
24
44
|
contact: Contact;
|
|
25
45
|
approvalBaseUrl: string;
|
|
46
|
+
/**
|
|
47
|
+
* #8047: agent-authored purchase narrative captured at review time and
|
|
48
|
+
* replayed into the card draw's Transaction Intent Journal at pay time.
|
|
49
|
+
*/
|
|
50
|
+
intentNarrative?: CardIntentNarrative;
|
|
26
51
|
merchantName?: string;
|
|
27
52
|
merchantCountryCode?: string;
|
|
53
|
+
trustedMerchantIdentity?: Readonly<{
|
|
54
|
+
handoffId: string;
|
|
55
|
+
checkoutId: string;
|
|
56
|
+
allowedOrigins: readonly string[];
|
|
57
|
+
expiresAt: string;
|
|
58
|
+
}>;
|
|
28
59
|
};
|
|
29
60
|
export type CliReviewFacts = {
|
|
30
61
|
reviewId: string;
|
|
@@ -34,41 +65,77 @@ export type CliReviewFacts = {
|
|
|
34
65
|
submitTargetFingerprint: string;
|
|
35
66
|
detectedRoles: string[];
|
|
36
67
|
};
|
|
68
|
+
/**
|
|
69
|
+
* A checkout was inspected successfully but cannot be reviewed safely.
|
|
70
|
+
*
|
|
71
|
+
* The explicit fields survive the CLI's copied-engine boundary structurally,
|
|
72
|
+
* so MCP callers do not have to parse the human-readable message.
|
|
73
|
+
*/
|
|
74
|
+
export declare class CheckoutReviewRefusedError extends Error {
|
|
75
|
+
readonly code = "CHECKOUT_REVIEW_REFUSED";
|
|
76
|
+
readonly checkoutOutcome: CheckoutOutcome;
|
|
77
|
+
readonly failureCode?: CheckoutFailureCode;
|
|
78
|
+
/** Bounded mandate/trusted-identity reason (#8669); absent for other outcomes. */
|
|
79
|
+
readonly refusalCode?: MandateRefusalCode;
|
|
80
|
+
readonly requiresAdapter: string[];
|
|
81
|
+
readonly detectedRoles: string[];
|
|
82
|
+
readonly receiptWrite: ReceiptWriteObservation;
|
|
83
|
+
readonly detail?: string;
|
|
84
|
+
constructor(result: CheckoutResult, receiptWrite: ReceiptWriteObservation);
|
|
85
|
+
}
|
|
37
86
|
export type CliPayInput = CliReviewInput & {
|
|
38
87
|
reviewId: string;
|
|
39
88
|
submit: boolean;
|
|
89
|
+
/**
|
|
90
|
+
* Headless handoff for this payment attempt. The MCP layer uses it to return
|
|
91
|
+
* the hosted passkey URL to a messaging surface while the engine continues
|
|
92
|
+
* waiting in-process.
|
|
93
|
+
*/
|
|
94
|
+
onApprovalUrl?: (url: string) => void;
|
|
40
95
|
};
|
|
41
96
|
export type CliReceiptFacts = {
|
|
42
|
-
outcome:
|
|
97
|
+
outcome: CheckoutOutcome;
|
|
43
98
|
confirmationRef: string | null;
|
|
44
99
|
receiptPath: string | null;
|
|
45
100
|
detail: string | null;
|
|
46
101
|
vicConfirmation: VicConfirmationReport | null;
|
|
47
102
|
/**
|
|
48
103
|
* Which credential path actually ran: `mandate` = tap-free draw against an
|
|
49
|
-
* existing card mandate; `
|
|
50
|
-
*
|
|
51
|
-
*
|
|
104
|
+
* existing card mandate; `null` = none ran (a pre-flight refusal, e.g. no
|
|
105
|
+
* prepared review or no covering mandate). Transparency, never magic — the
|
|
106
|
+
* caller can always see whether a passkey was skipped.
|
|
52
107
|
*/
|
|
53
|
-
source: 'mandate' |
|
|
108
|
+
source: 'mandate' | null;
|
|
54
109
|
/** Remaining mandate budget (minor units) after a mandate draw; else null. */
|
|
55
110
|
remainingMinor: number | null;
|
|
111
|
+
/**
|
|
112
|
+
* Immutable VIC/VGS intent used for server-side receipt correlation. This is
|
|
113
|
+
* an opaque non-credential identifier; it never carries the mint/verdict
|
|
114
|
+
* bearer that authorizes a cryptogram or confirmation. Present only after a
|
|
115
|
+
* card confirmation target exists.
|
|
116
|
+
*/
|
|
117
|
+
processorIntentId?: string | null;
|
|
118
|
+
/** True only when the checkout engine recorded a credential-minted step. */
|
|
119
|
+
credentialIssued: boolean;
|
|
120
|
+
/** True only when at least one payment field was successfully filled. */
|
|
121
|
+
credentialDisclosed: boolean;
|
|
122
|
+
/** Privacy-safe local receipt persistence outcome for centralized correlation. */
|
|
123
|
+
receiptWrite?: ReceiptWriteObservation;
|
|
124
|
+
};
|
|
125
|
+
type PayAttempt = {
|
|
126
|
+
fingerprint: string;
|
|
127
|
+
promise: Promise<CliReceiptFacts>;
|
|
56
128
|
};
|
|
57
129
|
export type CliStartMandateInput = {
|
|
58
|
-
/**
|
|
59
|
-
|
|
60
|
-
url?: string;
|
|
130
|
+
/** Optional local card-capability selector (legacy name or exact request-key JKT). */
|
|
131
|
+
agentRef?: string;
|
|
61
132
|
ceiling: string;
|
|
62
133
|
currency: string;
|
|
63
134
|
credentialPath: string;
|
|
135
|
+
/** See {@link CardInstrumentSource}. */
|
|
136
|
+
cardTokenId?: string;
|
|
64
137
|
contact: Contact;
|
|
65
138
|
approvalBaseUrl: string;
|
|
66
|
-
merchantName?: string;
|
|
67
|
-
merchantCountryCode?: string;
|
|
68
|
-
/** ISO 8601 mandate expiry; defaults to now + 24h. */
|
|
69
|
-
expiresAt?: string;
|
|
70
|
-
/** Max draws the ceiling intent may fulfil. */
|
|
71
|
-
maxDraws?: number;
|
|
72
139
|
/**
|
|
73
140
|
* Per-purchase cap (decimal string, > 0 and <= ceiling). Registered with the
|
|
74
141
|
* approval context so the operator reads it as a worst-case term, and carried
|
|
@@ -81,11 +148,33 @@ export type CliStartMandateInput = {
|
|
|
81
148
|
*/
|
|
82
149
|
intent?: string;
|
|
83
150
|
/**
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
151
|
+
* Per-call relay of the hosted-approval URL, the moment it is known and
|
|
152
|
+
* BEFORE the (up-to-timeout) wait. Takes precedence over the engine-level
|
|
153
|
+
* `deps.onApprovalUrl`.
|
|
154
|
+
*
|
|
155
|
+
* The engine seam was deps-only, and the MCP surface builds its engine once
|
|
156
|
+
* per process without it — so `start_card_mandate` produced an approval URL,
|
|
157
|
+
* printed it to stderr, and blocked the agent's turn for minutes with no way
|
|
158
|
+
* to tell the human what to open. A per-call hook lets one caller relay the
|
|
159
|
+
* URL without every caller sharing one engine-wide callback.
|
|
87
160
|
*/
|
|
88
|
-
|
|
161
|
+
onApprovalUrl?: (url: string) => void;
|
|
162
|
+
};
|
|
163
|
+
export type CliClaimMandateInput = {
|
|
164
|
+
/** Optional local card-capability selector (legacy name or exact request-key JKT). */
|
|
165
|
+
agentRef?: string;
|
|
166
|
+
/** Single-use pickup code the owner handed over from the panel. */
|
|
167
|
+
pickupCode: string;
|
|
168
|
+
/**
|
|
169
|
+
* The agent handoff this runtime just redeemed, when the pickup code rode
|
|
170
|
+
* inside its claim code. A dialog-minted budget pins that handoff instead of
|
|
171
|
+
* a key — there was no key yet — so this is what the pin is checked against.
|
|
172
|
+
*/
|
|
173
|
+
expectedHandoffId?: string;
|
|
174
|
+
credentialPath: string;
|
|
175
|
+
/** See {@link CardInstrumentSource}. */
|
|
176
|
+
cardTokenId?: string;
|
|
177
|
+
approvalBaseUrl: string;
|
|
89
178
|
};
|
|
90
179
|
export type CliMandateFacts = CardMandateFacts & {
|
|
91
180
|
merchantHost: string;
|
|
@@ -93,19 +182,86 @@ export type CliMandateFacts = CardMandateFacts & {
|
|
|
93
182
|
* True when the mandate minted its ceiling intent but the #5942 register
|
|
94
183
|
* handshake failed, so `findCovering` will SKIP it and no tap-free draw is
|
|
95
184
|
* possible. The mandate exists but is not usable — the caller must surface
|
|
96
|
-
* this (not report a plain success). Absent/false
|
|
97
|
-
*
|
|
185
|
+
* this (not report a plain success). Absent/false means registration succeeded;
|
|
186
|
+
* mandate-start now refuses before approval when no capability can register.
|
|
98
187
|
*/
|
|
99
188
|
registerFailed?: boolean;
|
|
189
|
+
/**
|
|
190
|
+
* The server's refusal reason when {@link registerFailed} is true, verbatim.
|
|
191
|
+
* Carried out so the CLI can distinguish causes that need DIFFERENT operator
|
|
192
|
+
* actions — notably `token_mismatch`, which means the on-device grant record's
|
|
193
|
+
* cached token no longer matches the owner's live agentic token (they
|
|
194
|
+
* re-enrolled a card after the grant) and is fixed by re-running `grant-card`,
|
|
195
|
+
* not by retrying `mandate start`. Without the reason every failure reads as
|
|
196
|
+
* "the auth server was unreachable", which sends the operator in a loop.
|
|
197
|
+
*/
|
|
198
|
+
registerFailureReason?: string;
|
|
199
|
+
};
|
|
200
|
+
/**
|
|
201
|
+
* The owner approved a budget but the intent bootstrap did not complete
|
|
202
|
+
* (#8470). `resumable` means the same approval can be resumed without a second
|
|
203
|
+
* passkey ceremony: the server's bootstrap state is at-most-once per signed
|
|
204
|
+
* token, so a resume can only recover an intent that already exists or
|
|
205
|
+
* dispatch once when nothing was ever dispatched — never create a sibling.
|
|
206
|
+
*/
|
|
207
|
+
export type CardMandateActivationFacts = {
|
|
208
|
+
phase: 'intent';
|
|
209
|
+
/** `uncertain`: the provider may have created the intent. `not_created`: proven not. */
|
|
210
|
+
outcome: 'uncertain' | 'not_created';
|
|
211
|
+
resumable: boolean;
|
|
212
|
+
status: number | null;
|
|
213
|
+
errorCode: string | null;
|
|
214
|
+
requestId: string | null;
|
|
215
|
+
bootstrapState: string;
|
|
216
|
+
/** Opaque, process-bound handle for {@link CliCheckoutEngine.resumeCardMandate}. */
|
|
217
|
+
resumeToken?: string;
|
|
218
|
+
/** When the approval's bootstrap credential stops being usable. */
|
|
219
|
+
resumeExpiresAt?: string;
|
|
220
|
+
};
|
|
221
|
+
export declare class CardMandateActivationError extends Error {
|
|
222
|
+
readonly facts: CardMandateActivationFacts;
|
|
223
|
+
readonly code = "CARD_MANDATE_ACTIVATION_INCOMPLETE";
|
|
224
|
+
constructor(message: string, facts: CardMandateActivationFacts);
|
|
225
|
+
}
|
|
226
|
+
export type CliResumeMandateInput = {
|
|
227
|
+
resumeToken: string;
|
|
228
|
+
};
|
|
229
|
+
/**
|
|
230
|
+
* Sort a budget-intent route failure into resume semantics. Exported for the
|
|
231
|
+
* regression net; the truth table is the product contract of #8470.
|
|
232
|
+
*/
|
|
233
|
+
export declare function classifyServerIntentFailure(err: ServerIntentError): {
|
|
234
|
+
outcome: 'uncertain' | 'not_created';
|
|
235
|
+
resumable: boolean;
|
|
100
236
|
};
|
|
101
237
|
type Session = {
|
|
102
238
|
browser: Browser;
|
|
239
|
+
/** Exact caller URL repeated at pay time; may contain a UCP capability. */
|
|
240
|
+
requestUrl: string;
|
|
241
|
+
checkoutRoute: 'guest-card';
|
|
103
242
|
target: VgsCheckoutTarget;
|
|
104
243
|
amountMinor: number;
|
|
105
244
|
currency: string;
|
|
106
245
|
contact: Contact;
|
|
246
|
+
agentJkt?: string;
|
|
247
|
+
/** #8047: narrative for this review's journal, carried review -> pay. */
|
|
248
|
+
intentNarrative?: CardIntentNarrative;
|
|
107
249
|
cleanupTimer: ReturnType<typeof setTimeout>;
|
|
108
250
|
};
|
|
251
|
+
/**
|
|
252
|
+
* #8047 Transaction Intent Journal narrative — the agent-authored half of the
|
|
253
|
+
* journal. Structural mirror of the CLI card client's `CardIntentNarrative`;
|
|
254
|
+
* the engine only threads it through and never interprets it.
|
|
255
|
+
*/
|
|
256
|
+
export interface CardIntentNarrative {
|
|
257
|
+
userRequest: string;
|
|
258
|
+
product: string;
|
|
259
|
+
purpose?: string;
|
|
260
|
+
quantity?: number;
|
|
261
|
+
expectedResult?: string;
|
|
262
|
+
recurring?: boolean;
|
|
263
|
+
userIntentSalt?: string;
|
|
264
|
+
}
|
|
109
265
|
export interface CardDrawVerdictDraw {
|
|
110
266
|
tokenId: string;
|
|
111
267
|
amount: string;
|
|
@@ -117,32 +273,39 @@ export interface CardDrawVerdictDraw {
|
|
|
117
273
|
export interface CardDrawVerdictCapability {
|
|
118
274
|
/** Opaque to the engine — passed straight back to {@link CardDrawVerdictSeam.fetchVerdict}. */
|
|
119
275
|
agentKey: unknown;
|
|
276
|
+
/** Root-signed delegation for a short-lived device key. */
|
|
277
|
+
runtimeCertificate?: string;
|
|
120
278
|
agentJkt: string;
|
|
121
279
|
/** Auth origin that minted the binding and hosts the /v4/card/draw* routes. */
|
|
122
280
|
authBaseUrl: string;
|
|
123
281
|
}
|
|
124
282
|
export interface CardDrawVerdictSeam {
|
|
125
|
-
loadCapability: () => CardDrawVerdictCapability | null;
|
|
283
|
+
loadCapability: (agentRef?: string) => CardDrawVerdictCapability | null;
|
|
126
284
|
fetchVerdict: (input: {
|
|
127
285
|
authBaseUrl: string;
|
|
128
286
|
agentKey: unknown;
|
|
287
|
+
runtimeCertificate?: string;
|
|
129
288
|
mandateId: string;
|
|
130
289
|
drawId: string;
|
|
131
290
|
draw: CardDrawVerdictDraw;
|
|
291
|
+
/** #8047: narrative the client turns into the draw's journal sidecar. */
|
|
292
|
+
intentNarrative?: CardIntentNarrative;
|
|
132
293
|
}) => Promise<{
|
|
133
294
|
verdict: string;
|
|
134
295
|
remainingCents: number;
|
|
135
296
|
}>;
|
|
136
297
|
}
|
|
137
298
|
export interface CardMandateRegisterSeam {
|
|
138
|
-
loadCapability: () => {
|
|
299
|
+
loadCapability: (agentRef?: string) => {
|
|
139
300
|
agentKey: unknown;
|
|
301
|
+
runtimeCertificate?: string;
|
|
140
302
|
agentJkt: string;
|
|
141
303
|
authBaseUrl: string;
|
|
142
304
|
} | null;
|
|
143
305
|
register: (input: {
|
|
144
306
|
authBaseUrl: string;
|
|
145
307
|
agentKey: unknown;
|
|
308
|
+
runtimeCertificate?: string;
|
|
146
309
|
mandateId: string;
|
|
147
310
|
mintToken: string;
|
|
148
311
|
ceiling: string;
|
|
@@ -150,6 +313,12 @@ export interface CardMandateRegisterSeam {
|
|
|
150
313
|
}) => Promise<{
|
|
151
314
|
ok: boolean;
|
|
152
315
|
reason?: string;
|
|
316
|
+
/**
|
|
317
|
+
* The ceiling the server committed — `min(requested, the owner's live card
|
|
318
|
+
* grant cap)`. Omitted by an older auth that does not report it, in which
|
|
319
|
+
* case the requested ceiling stands.
|
|
320
|
+
*/
|
|
321
|
+
approvedCeilingMinor?: number;
|
|
153
322
|
}>;
|
|
154
323
|
}
|
|
155
324
|
export type CliEngineDeps = {
|
|
@@ -157,6 +326,8 @@ export type CliEngineDeps = {
|
|
|
157
326
|
prepareCheckout?: typeof realPrepareCheckout;
|
|
158
327
|
submitApprovedCheckout?: typeof realSubmitApprovedCheckout;
|
|
159
328
|
runHostedApproval?: typeof realRunHostedApproval;
|
|
329
|
+
/** Injectable pickup-code redeem for claimCardMandate — tests pass a fake. */
|
|
330
|
+
claimMandatePickup?: typeof realClaimMandatePickup;
|
|
160
331
|
/**
|
|
161
332
|
* Relay the hosted-approval URL to the caller as DATA the moment it is known,
|
|
162
333
|
* before the (up-to-timeout) poll wait. A headless agent surface wires this to
|
|
@@ -166,8 +337,18 @@ export type CliEngineDeps = {
|
|
|
166
337
|
onApprovalUrl?: (url: string) => void;
|
|
167
338
|
reportVicOutcome?: typeof realReportVicOutcome;
|
|
168
339
|
writeReceipt?: typeof realWriteReceipt;
|
|
340
|
+
/**
|
|
341
|
+
* Privacy-safe receipt persistence lifecycle signal. The event deliberately
|
|
342
|
+
* excludes the receipt body, checkout URL, filesystem path, and raw error.
|
|
343
|
+
* Observer failures are swallowed so logging can never alter checkout state.
|
|
344
|
+
*/
|
|
345
|
+
onReceiptWrite?: (event: ReceiptWriteObservation) => void | Promise<void>;
|
|
346
|
+
/** Injectable privacy-safe id source for terminal observations before reviewId exists. */
|
|
347
|
+
createObservationId?: () => string;
|
|
169
348
|
store?: PreparedCheckoutSessionStore;
|
|
170
349
|
sessions?: Map<string, Session>;
|
|
350
|
+
/** Exact-review singleflight registry; tests inject a fresh map for isolation. */
|
|
351
|
+
payAttempts?: Map<string, PayAttempt>;
|
|
171
352
|
ttlMs?: number;
|
|
172
353
|
/** Owner-only card-mandate ledger — defaults to the ~/.visa-mcp singleton. */
|
|
173
354
|
ledger?: MandateLedger;
|
|
@@ -179,24 +360,58 @@ export type CliEngineDeps = {
|
|
|
179
360
|
* markUnhonored path with no network.
|
|
180
361
|
*/
|
|
181
362
|
serverFetchCryptogram?: typeof serverFetchCryptogram;
|
|
363
|
+
/** Injectable confirmation transport; defaults to verify-web. */
|
|
364
|
+
serverPostConfirmation?: typeof serverPostConfirmation;
|
|
182
365
|
/**
|
|
183
366
|
* #5923 delegated card-draw verdict seam (see {@link CardDrawVerdictSeam}).
|
|
184
|
-
* Injected by the CLI when the
|
|
185
|
-
*
|
|
186
|
-
* shipped #5917 flow, unchanged).
|
|
367
|
+
* Injected by the CLI when the runtime holds separately provisioned card
|
|
368
|
+
* authority. When absent, a covering-mandate draw fails before cryptogram mint.
|
|
187
369
|
*/
|
|
188
370
|
cardDrawVerdict?: CardDrawVerdictSeam;
|
|
189
371
|
/**
|
|
190
372
|
* #5942 delegated card-mandate register seam (see {@link CardMandateRegisterSeam}).
|
|
191
|
-
*
|
|
192
|
-
*
|
|
193
|
-
* still works, only the delegated draw needs the register row).
|
|
373
|
+
* Required by mandate-start. When absent, the ceremony is refused before
|
|
374
|
+
* passkey approval because a budget token cannot act as draw authority.
|
|
194
375
|
*/
|
|
195
376
|
cardMandateRegister?: CardMandateRegisterSeam;
|
|
377
|
+
/**
|
|
378
|
+
* Canonical mailbox OTP reader supplied by the runtime. The checkout engine
|
|
379
|
+
* owns no mailbox credential and never imports an email provider package.
|
|
380
|
+
*/
|
|
381
|
+
resolveEmailOtp?: OtpResolver;
|
|
382
|
+
};
|
|
383
|
+
export type ReceiptWriteObservation = {
|
|
384
|
+
event: 'checkout_receipt_write';
|
|
385
|
+
status: 'written' | 'failed';
|
|
386
|
+
mode: CheckoutMode;
|
|
387
|
+
checkoutOutcome: CheckoutOutcome;
|
|
388
|
+
merchantHost: string;
|
|
389
|
+
observationId: string;
|
|
390
|
+
failureCode: string | null;
|
|
391
|
+
errorCode: string | null;
|
|
392
|
+
panRedactions: number | null;
|
|
196
393
|
};
|
|
197
394
|
export declare function createCliCheckoutEngine(deps?: CliEngineDeps): {
|
|
198
395
|
startCardMandate(input: CliStartMandateInput): Promise<CliMandateFacts>;
|
|
396
|
+
resumeCardMandate(input: CliResumeMandateInput): Promise<CliMandateFacts>;
|
|
397
|
+
claimCardMandate(input: CliClaimMandateInput): Promise<CliMandateFacts>;
|
|
199
398
|
review(input: CliReviewInput): Promise<CliReviewFacts>;
|
|
399
|
+
/**
|
|
400
|
+
* Give up a prepared review without paying it (#7100).
|
|
401
|
+
*
|
|
402
|
+
* The retained browser is what lets a same-process MCP `review` → `pay`
|
|
403
|
+
* draw against the checkout it already inspected. A TERMINAL review-only
|
|
404
|
+
* run has no such second call — that process tells the operator to re-RUN
|
|
405
|
+
* with `--submit`, and the new process cannot reach this one's in-memory
|
|
406
|
+
* session. So the browser sat open for the full TTL, and because a live
|
|
407
|
+
* browser connection keeps the event loop alive, a command that had already
|
|
408
|
+
* succeeded looked hung until Ctrl-C.
|
|
409
|
+
*
|
|
410
|
+
* Idempotent and non-throwing: an unknown or already-released id is a
|
|
411
|
+
* no-op, so it is safe on an error path that may not have prepared anything
|
|
412
|
+
* and safe to call twice.
|
|
413
|
+
*/
|
|
414
|
+
releaseReview(reviewId: string): Promise<void>;
|
|
200
415
|
pay(input: CliPayInput): Promise<CliReceiptFacts>;
|
|
201
416
|
};
|
|
202
417
|
export {};
|