@visa/cli 4.1.0-rc.24 → 4.1.0-rc.240

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.
Files changed (86) hide show
  1. package/README.md +262 -227
  2. package/dist/checkout-engine/adapters/generic.d.ts +69 -0
  3. package/dist/checkout-engine/adapters/generic.js +383 -58
  4. package/dist/checkout-engine/adapters/index.d.ts +4 -1
  5. package/dist/checkout-engine/adapters/index.js +10 -3
  6. package/dist/checkout-engine/adapters/shopify.d.ts +80 -0
  7. package/dist/checkout-engine/adapters/shopify.js +688 -0
  8. package/dist/checkout-engine/amount.d.ts +15 -0
  9. package/dist/checkout-engine/amount.js +72 -0
  10. package/dist/checkout-engine/browser-launch.d.ts +9 -4
  11. package/dist/checkout-engine/browser-launch.js +19 -4
  12. package/dist/checkout-engine/browserbase-browser.d.ts +24 -0
  13. package/dist/checkout-engine/browserbase-browser.js +186 -0
  14. package/dist/checkout-engine/cli-engine.d.ts +297 -4
  15. package/dist/checkout-engine/cli-engine.js +942 -48
  16. package/dist/checkout-engine/confirmed-merchants.d.ts +31 -0
  17. package/dist/checkout-engine/confirmed-merchants.js +165 -0
  18. package/dist/checkout-engine/detect.d.ts +1 -1
  19. package/dist/checkout-engine/detect.js +26 -0
  20. package/dist/checkout-engine/evidence.d.ts +4 -1
  21. package/dist/checkout-engine/evidence.js +51 -6
  22. package/dist/checkout-engine/executor.d.ts +64 -4
  23. package/dist/checkout-engine/executor.js +604 -145
  24. package/dist/checkout-engine/hosted-approval.d.ts +124 -7
  25. package/dist/checkout-engine/hosted-approval.js +384 -54
  26. package/dist/checkout-engine/index.d.ts +9 -2
  27. package/dist/checkout-engine/index.js +8 -1
  28. package/dist/checkout-engine/instrument.d.ts +7 -0
  29. package/dist/checkout-engine/instrument.js +4 -0
  30. package/dist/checkout-engine/known-merchants.d.ts +10 -0
  31. package/dist/checkout-engine/known-merchants.js +38 -0
  32. package/dist/checkout-engine/live-fill-approval.d.ts +5 -20
  33. package/dist/checkout-engine/live-fill-approval.js +20 -51
  34. package/dist/checkout-engine/mandate/card-mandate.d.ts +121 -0
  35. package/dist/checkout-engine/mandate/card-mandate.js +226 -0
  36. package/dist/checkout-engine/mandate/mandate-ledger.d.ts +174 -0
  37. package/dist/checkout-engine/mandate/mandate-ledger.js +410 -0
  38. package/dist/checkout-engine/outcome.d.ts +2 -2
  39. package/dist/checkout-engine/outcome.js +36 -1
  40. package/dist/checkout-engine/owner-only-file.d.ts +9 -0
  41. package/dist/checkout-engine/owner-only-file.js +20 -1
  42. package/dist/checkout-engine/receipt-dir.d.ts +6 -0
  43. package/dist/checkout-engine/receipt-dir.js +8 -0
  44. package/dist/checkout-engine/receipt.d.ts +56 -2
  45. package/dist/checkout-engine/receipt.js +55 -16
  46. package/dist/checkout-engine/trace-handles.d.ts +8 -0
  47. package/dist/checkout-engine/trace-handles.js +12 -0
  48. package/dist/checkout-engine/types.d.ts +28 -2
  49. package/dist/checkout-engine/unresolved-charges.d.ts +34 -0
  50. package/dist/checkout-engine/unresolved-charges.js +134 -0
  51. package/dist/checkout-engine/vgs-gateway/server-mint-client.d.ts +53 -1
  52. package/dist/checkout-engine/vgs-gateway/server-mint-client.js +78 -10
  53. package/dist/checkout-engine/vgs-live-instrument.d.ts +38 -35
  54. package/dist/checkout-engine/vgs-live-instrument.js +51 -74
  55. package/dist/checkout-engine/vic-confirmation.d.ts +18 -0
  56. package/dist/checkout-engine/vic-confirmation.js +9 -3
  57. package/dist/checkout-engine/web-bot-auth.d.ts +98 -0
  58. package/dist/checkout-engine/web-bot-auth.js +218 -0
  59. package/dist/cli.js +968 -505
  60. package/dist/mcp-apps/ucp-checkout.html +280 -0
  61. package/dist/mcp-server/index.js +807 -175
  62. package/dist/skills/pair-visa-agent/RUNTIMES.md +122 -79
  63. package/dist/skills/pair-visa-agent/SKILL.md +436 -248
  64. package/dist/skills/pair-visa-agent/scripts/__tests__/setup.test.mjs +407 -0
  65. package/dist/skills/pair-visa-agent/scripts/setup.mjs +310 -30
  66. package/dist/skills/visa-shopify-checkout/SKILL.md +122 -0
  67. package/dist/skills/visa-shopify-checkout/references/evidence-and-states.md +37 -0
  68. package/dist/skills/visa-ucp-shopping/SKILL.md +84 -0
  69. package/dist/subway-direct.mjs +1 -0
  70. package/install.ps1 +9 -46
  71. package/install.sh +5 -37
  72. package/native/bin/win32-x64/visa-keychain-win.exe +0 -0
  73. package/package.json +32 -28
  74. package/server.json +4 -4
  75. package/dist/checkout-engine/inline-target.d.ts +0 -13
  76. package/dist/checkout-engine/inline-target.js +0 -37
  77. package/dist/checkout-engine/pay-args.d.ts +0 -14
  78. package/dist/checkout-engine/pay-args.js +0 -44
  79. package/dist/checkout-engine/pay.d.ts +0 -1
  80. package/dist/checkout-engine/pay.js +0 -13
  81. package/dist/checkout-engine/repo-env.d.ts +0 -11
  82. package/dist/checkout-engine/repo-env.js +0 -23
  83. package/dist/checkout-engine/run-live-fill.d.ts +0 -1
  84. package/dist/checkout-engine/run-live-fill.js +0 -443
  85. package/dist/checkout-engine/vgs-gateway/fetch-credential.d.mts +0 -74
  86. package/dist/checkout-engine/vgs-gateway/fetch-credential.mjs +0 -248
package/install.ps1 CHANGED
@@ -108,8 +108,8 @@ try {
108
108
  }
109
109
 
110
110
  $major = [int]$nodeMatch.Groups['major'].Value
111
- if ($major -lt 18) {
112
- Write-Host " Node.js $nodeVersion is too old. Version 18+ required." -ForegroundColor Red
111
+ if ($major -lt 20) {
112
+ Write-Host " Node.js $nodeVersion is too old. Version 20+ required." -ForegroundColor Red
113
113
  Write-Host " Install from https://nodejs.org/ and try again." -ForegroundColor Yellow
114
114
  Wait-BeforeExit
115
115
  exit 1
@@ -137,8 +137,9 @@ try {
137
137
  }
138
138
 
139
139
  # Install via npm
140
- Write-Host " Running: npm install -g @visa/cli" -ForegroundColor Gray
141
- $npmOutput = & npm install -g @visa/cli 2>&1
140
+ $Package = '@visa/cli@rc'
141
+ Write-Host " Running: npm install -g $Package" -ForegroundColor Gray
142
+ $npmOutput = & npm install -g $Package 2>&1
142
143
  $npmExitCode = $LASTEXITCODE
143
144
  $npmText = ($npmOutput | Out-String)
144
145
  $npmOutput | Out-Host
@@ -158,7 +159,7 @@ if ($npmExitCode -ne 0) {
158
159
  Write-Host " Do not disable TLS verification globally." -ForegroundColor Yellow
159
160
  } else {
160
161
  Write-Host " Run manually for the full error, then retry:" -ForegroundColor Yellow
161
- Write-Host " npm install -g @visa/cli" -ForegroundColor Yellow
162
+ Write-Host " npm install -g $Package" -ForegroundColor Yellow
162
163
  }
163
164
 
164
165
  Wait-BeforeExit
@@ -168,7 +169,6 @@ if ($npmExitCode -ne 0) {
168
169
  # Verify
169
170
  $cliCommandNames = Get-InstalledCliCommands
170
171
  $verifiedCommand = $null
171
- $verifiedCommandPath = $null
172
172
  $visaVersion = $null
173
173
 
174
174
  foreach ($commandName in $cliCommandNames) {
@@ -177,12 +177,9 @@ foreach ($commandName in $cliCommandNames) {
177
177
  continue
178
178
  }
179
179
 
180
- # Capture the resolved executable path so the setup hand-off below runs
181
- # exactly the binary verified here, not a fresh PATH lookup.
182
180
  $versionOutput = (& $commandInfo.Source --version 2>$null | Select-Object -First 1)
183
181
  if ($LASTEXITCODE -eq 0 -and $versionOutput) {
184
182
  $verifiedCommand = $commandName
185
- $verifiedCommandPath = $commandInfo.Source
186
183
  $visaVersion = $versionOutput.Trim()
187
184
  break
188
185
  }
@@ -191,46 +188,12 @@ foreach ($commandName in $cliCommandNames) {
191
188
  Write-Host ""
192
189
  if ($verifiedCommand) {
193
190
  Write-Host " Visa CLI $visaVersion installed." -ForegroundColor Green
194
-
195
- # Hand off straight into setup so install -> setup -> signed-in is one
196
- # uninterrupted flow. Hardening:
197
- # * Auto-launch only on an interactive console with input/output/error
198
- # all attached - setup must prompt and open a browser. Redirected
199
- # streams and CI fall back to printing the next step.
200
- # * Invoke $verifiedCommandPath (the path verified just above), not a
201
- # bare command name re-resolved through PATH.
202
- # * Pass only the literal "setup" argument - nothing caller-controlled.
203
- if ($Host.Name -eq 'ConsoleHost' -and -not [Console]::IsInputRedirected -and -not [Console]::IsOutputRedirected -and -not [Console]::IsErrorRedirected -and -not $env:CI) {
204
- Write-Host ""
205
- Write-Host " Continuing to setup..." -ForegroundColor Cyan
206
- Write-Host ""
207
- try {
208
- $setupProcess = Start-Process -FilePath $verifiedCommandPath -ArgumentList @('setup') -Wait -NoNewWindow -PassThru -ErrorAction Stop
209
- } catch {
210
- Write-Host ""
211
- Write-Host " Setup could not start. Visa CLI is installed." -ForegroundColor Yellow
212
- Write-Host " PowerShell error: $($_.Exception.Message)" -ForegroundColor Yellow
213
- Write-Host " run '$verifiedCommand setup' when you're ready to finish." -ForegroundColor Yellow
214
- Wait-BeforeExit
215
- exit 1
216
- }
217
- if ($setupProcess.ExitCode -ne 0) {
218
- Write-Host ""
219
- Write-Host " Setup exited before completion. Visa CLI is installed." -ForegroundColor Yellow
220
- Write-Host " run '$verifiedCommand setup' when you're ready to finish." -ForegroundColor Yellow
221
- Wait-BeforeExit
222
- exit 1
223
- }
224
- exit 0
225
- } else {
226
- Write-Host " Run '$verifiedCommand setup' to get started." -ForegroundColor Cyan
227
- Write-Host " After setup, run /mcp inside Claude Code, not PowerShell, if Claude Code was already open." -ForegroundColor Cyan
228
- }
191
+ Write-Host " Connect an AI client with: $verifiedCommand connect <client>" -ForegroundColor Cyan
192
+ Write-Host " Then ask your agent to call setup_start." -ForegroundColor Cyan
229
193
  Write-Host ""
230
194
  } else {
231
195
  $primaryCommand = $cliCommandNames | Select-Object -First 1
232
196
  Write-Host " Installed but '$primaryCommand' was not runnable from PATH yet." -ForegroundColor Yellow
233
- Write-Host " Close and reopen PowerShell, then run: $primaryCommand setup" -ForegroundColor Yellow
234
- Write-Host " Run /mcp inside Claude Code after setup if you need to reconnect the MCP server." -ForegroundColor Yellow
197
+ Write-Host " Close and reopen PowerShell, then run: $primaryCommand connect <client>" -ForegroundColor Yellow
235
198
  Write-Host ""
236
199
  }
package/install.sh CHANGED
@@ -10,8 +10,8 @@
10
10
  _visa_install() {
11
11
  set -euo pipefail
12
12
 
13
- REQUIRED_NODE_MAJOR=18
14
- PACKAGE="@visa/cli"
13
+ REQUIRED_NODE_MAJOR=20
14
+ PACKAGE="@visa/cli@rc"
15
15
 
16
16
  # ── colours (disabled when piped) ─────────────────────────────────────────────
17
17
  if [ -t 1 ]; then
@@ -99,9 +99,6 @@ fi
99
99
  echo "$NPM_OUTPUT"
100
100
 
101
101
  # ── verify ────────────────────────────────────────────────────────────────────
102
- # Capture the absolute path resolved here so the setup hand-off below invokes
103
- # exactly the binary we just verified, instead of re-resolving "visa-cli"
104
- # through $PATH a second time.
105
102
  VISA_BIN=""
106
103
  VISA_VERSION=""
107
104
  if VISA_BIN="$(command -v visa-cli 2>/dev/null)"; then
@@ -111,40 +108,11 @@ fi
111
108
  echo ""
112
109
  if [ -n "$VISA_VERSION" ]; then
113
110
  ok "Visa CLI ${VISA_VERSION} installed."
114
- # Hand off straight into setup so install -> setup -> signed-in is one
115
- # uninterrupted flow. Hardening:
116
- # * Auto-launch only when output streams are real terminals and setup can
117
- # read from either stdin or /dev/tty. That keeps `curl ... | bash` usable:
118
- # the script arrives on stdin, while setup prompts still read from the
119
- # user's terminal. CI and redirected output print the next step instead.
120
- # * Invoke "$VISA_BIN" (the path verified just above), never a bare
121
- # "visa-cli" re-resolved through $PATH at call time.
122
- # * Pass only the literal "setup" argument — "$@" is never forwarded — so
123
- # nothing the script's caller controls reaches the installed binary.
124
- if [ -t 1 ] && [ -t 2 ] && { [ -t 0 ] || [ -r /dev/tty ]; }; then
125
- echo ""
126
- info "Continuing to setup..."
127
- echo ""
128
- SETUP_EXIT=0
129
- if [ -t 0 ]; then
130
- "$VISA_BIN" setup || SETUP_EXIT=$?
131
- else
132
- "$VISA_BIN" setup </dev/tty || SETUP_EXIT=$?
133
- fi
134
- if [ "$SETUP_EXIT" -ne 0 ]; then
135
- echo ""
136
- warn "Setup exited before completion. Visa CLI is installed."
137
- warn "run 'visa-cli setup' when you're ready to finish."
138
- exit 1
139
- fi
140
- exit 0
141
- else
142
- info "Run 'visa-cli setup' to get started."
143
- info "After setup, run /mcp inside Claude Code, not Terminal, if Claude Code was already open."
144
- fi
111
+ info "Connect an AI client with: visa-cli connect <client>"
112
+ info "Then ask your agent to call setup_start."
145
113
  else
146
114
  warn "Installed, but 'visa-cli' was not found on PATH."
147
- warn "You may need to restart your shell, then run: visa-cli setup"
115
+ warn "Restart your shell, then run: visa-cli connect <client>"
148
116
  fi
149
117
  echo ""
150
118
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@visa/cli",
3
- "version": "4.1.0-rc.24",
4
- "description": "AI-powered payments for Claude Code",
3
+ "version": "4.1.0-rc.240",
4
+ "description": "Visa CLI runtime for stable agent identity and separately authorized payment capabilities",
5
5
  "bin": {
6
6
  "visa-cli": "./bin/visa-cli.js",
7
7
  "visa": "./bin/visa-cli.js"
@@ -9,7 +9,7 @@
9
9
  "scripts": {
10
10
  "sync:server-json": "node scripts/sync-server-json.mjs",
11
11
  "check:server-json": "node scripts/sync-server-json.mjs --check",
12
- "prebuild": "node scripts/sync-server-json.mjs && pnpm --filter @visa/money build && pnpm --filter @visa/crypto build && pnpm --filter subway-sdk build && pnpm --filter @visa-cli/tools build && pnpm --filter @visa/identity build && pnpm --filter @visa/wallet build && pnpm --filter @visa/wallet-tools build && pnpm --filter @visa/checkout-engine build",
12
+ "prebuild": "node scripts/sync-server-json.mjs && pnpm --filter @visa/shared build && pnpm --filter @visa/observability build && pnpm --filter @visa/money build && pnpm --filter @visa/crypto build && pnpm --filter subway-sdk build && pnpm --filter @visa-cli/tools build && pnpm --filter @visa/identity build && pnpm --filter @visa/wallet build && pnpm --filter @visa/agent-mail build && pnpm --filter @visa/wallet-tools build && pnpm --filter @visa/checkout-engine build",
13
13
  "build": "tsc --noEmit && node esbuild.config.js",
14
14
  "prepack": "node scripts/sync-server-json.mjs --check",
15
15
  "dev": "tsc --watch",
@@ -20,9 +20,9 @@
20
20
  "test:unit:watch": "jest --config jest.config.js --watch",
21
21
  "test:unit:coverage": "jest --config jest.config.js --coverage",
22
22
  "test:smoke": "VISA_AUTH_URL=https://auth.visacli.sh jest --config jest.smoke.config.js",
23
+ "test:packed": "node scripts/packed-cli-smoke.mjs",
23
24
  "test:integration": "jest --config jest.integration.config.js",
24
25
  "test:e2e": "jest --config jest.e2e.config.js",
25
- "test:catalog-e2e": "jest --config jest.catalog-e2e.config.js",
26
26
  "test:all": "npm run test:unit && npm run test:integration && npm run test:e2e",
27
27
  "prepublishOnly": "npm run build && npm test",
28
28
  "lint": "eslint src/**/*.ts",
@@ -42,47 +42,52 @@
42
42
  "author": "Visa Crypto Labs",
43
43
  "license": "SEE LICENSE IN LICENSE",
44
44
  "dependencies": {
45
- "@modelcontextprotocol/sdk": "^1.0.0",
45
+ "@modelcontextprotocol/ext-apps": "1.7.5",
46
+ "@modelcontextprotocol/server": "2.0.0",
47
+ "@ucp-js/sdk": "0.4.4",
46
48
  "commander": "^12.1.0",
47
- "zod": "^3.23.0"
49
+ "punycode": "^2.3.1",
50
+ "toml": "^4.3.0",
51
+ "yaml": "^2.9.0",
52
+ "zod": "^3.25.76"
48
53
  },
49
54
  "optionalDependencies": {
50
- "libp2p": "^3.3.4",
51
- "@libp2p/tcp": "^11.0.22",
52
- "@libp2p/crypto": "^5.1.20",
53
55
  "@chainsafe/libp2p-noise": "^17.0.0",
54
56
  "@chainsafe/libp2p-yamux": "^8.0.1",
57
+ "@libp2p/crypto": "^5.1.23",
58
+ "@libp2p/tcp": "^11.0.26",
55
59
  "@multiformats/multiaddr": "^13.0.3",
56
- "uint8arrays": "^6.1.1",
57
- "playwright-core": "^1.48.2"
60
+ "libp2p": "^3.3.9",
61
+ "playwright-core": "^1.62.1",
62
+ "uint8arrays": "^6.1.1"
58
63
  },
59
64
  "devDependencies": {
65
+ "@types/express": "^5.0.0",
66
+ "@types/jest": "^30.0.0",
67
+ "@types/node": "^26.1.0",
68
+ "@typescript-eslint/eslint-plugin": "^8.68.0",
69
+ "@typescript-eslint/parser": "^8.68.0",
70
+ "@visa-cli/tools": "workspace:*",
71
+ "@visa/agent-mail": "workspace:*",
60
72
  "@visa/checkout-engine": "workspace:*",
61
73
  "@visa/crypto": "workspace:*",
62
- "subway-sdk": "workspace:*",
74
+ "@visa/identity": "workspace:*",
63
75
  "@visa/money": "workspace:*",
76
+ "@visa/observability": "workspace:*",
77
+ "@visa/shared": "workspace:*",
64
78
  "@visa/wallet": "workspace:*",
65
79
  "@visa/wallet-tools": "workspace:*",
66
- "@visa/observability": "workspace:*",
67
- "@visa-cli/tools": "workspace:*",
68
- "@changesets/changelog-git": "^0.2.1",
69
- "@changesets/cli": "^2.31.0",
70
- "@types/jest": "^30.0.0",
71
- "@types/node": "^26.1.0",
72
- "@typescript-eslint/eslint-plugin": "^8.63.0",
73
- "@typescript-eslint/parser": "^8.63.0",
74
- "@types/express": "^5.0.0",
75
80
  "esbuild": "^0.28.1",
76
- "express": "^4.21.0",
77
81
  "eslint": "^10.0.2",
78
- "eslint-config-prettier": "^10.1.8",
82
+ "express": "^4.21.0",
79
83
  "jest": "^29.7.0",
80
- "prettier": "^3.9.4",
81
- "ts-jest": "^29.4.11",
84
+ "prettier": "^3.9.6",
85
+ "subway-sdk": "workspace:*",
86
+ "ts-jest": "^29.4.12",
82
87
  "typescript": "^5.7.0"
83
88
  },
84
89
  "engines": {
85
- "node": ">=18.0.0"
90
+ "node": ">=20.0.0"
86
91
  },
87
92
  "mcpName": "io.github.visa-crypto-labs/visa-cli",
88
93
  "files": [
@@ -95,7 +100,6 @@
95
100
  "native/build-win.bat",
96
101
  "native/bin/win32-x64/visa-keychain-win.exe",
97
102
  "server.json",
98
- "README.md",
99
- "LICENSE"
103
+ "README.md"
100
104
  ]
101
105
  }
package/server.json CHANGED
@@ -1,15 +1,15 @@
1
1
  {
2
- "$schema": "https://static.modelcontextprotocol.io/schemas/2025-10-17/server.schema.json",
2
+ "$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
3
3
  "name": "io.github.visa-crypto-labs/visa-cli",
4
- "version": "4.1.0-rc.24",
4
+ "version": "4.1.0-rc.240",
5
5
  "title": "Visa CLI",
6
- "description": "AI-powered payments and creative tools for coding agents. Generate images, music, video, query crypto prices, and make purchases all from your AI coding assistant.",
6
+ "description": "Pair a human-approved agent identity, configure payment capabilities separately, and discover and pay x402 services from your AI coding assistant.",
7
7
  "websiteUrl": "https://github.com/Visa-Crypto-Labs/Visa-mono/tree/main/packages/cli#readme",
8
8
  "packages": [
9
9
  {
10
10
  "registryType": "npm",
11
11
  "identifier": "@visa/cli",
12
- "version": "4.1.0-rc.24",
12
+ "version": "4.1.0-rc.240",
13
13
  "transport": {
14
14
  "type": "stdio"
15
15
  },
@@ -1,13 +0,0 @@
1
- import type { VgsCheckoutTarget } from './vgs-live-instrument.js';
2
- /**
3
- * Build a checkout target from inline CLI flags (`--merchant-url` +
4
- * `--amount`, with optional `--merchant-name` / `--country` / `--currency`)
5
- * so any merchant can be paid without authoring a checkout JSON file first.
6
- *
7
- * Returns null when neither driving flag is present (file mode). Shape-only:
8
- * the returned target flows through run-live-fill's existing validation block
9
- * (positive-decimal amount, ISO codes, HTTPS), which stays the single source
10
- * of truth — nothing is double-validated here except the URL parse, which
11
- * must happen early because the merchant-name default derives from it.
12
- */
13
- export declare function inlineTargetFromFlags(input: Map<string, string>): VgsCheckoutTarget | null;
@@ -1,37 +0,0 @@
1
- /**
2
- * Build a checkout target from inline CLI flags (`--merchant-url` +
3
- * `--amount`, with optional `--merchant-name` / `--country` / `--currency`)
4
- * so any merchant can be paid without authoring a checkout JSON file first.
5
- *
6
- * Returns null when neither driving flag is present (file mode). Shape-only:
7
- * the returned target flows through run-live-fill's existing validation block
8
- * (positive-decimal amount, ISO codes, HTTPS), which stays the single source
9
- * of truth — nothing is double-validated here except the URL parse, which
10
- * must happen early because the merchant-name default derives from it.
11
- */
12
- export function inlineTargetFromFlags(input) {
13
- const merchantUrl = input.get('--merchant-url');
14
- const amount = input.get('--amount');
15
- if (merchantUrl === undefined && amount === undefined)
16
- return null;
17
- if (!merchantUrl || !amount) {
18
- throw new Error('inline checkout needs both --merchant-url and --amount');
19
- }
20
- let host;
21
- try {
22
- host = new URL(merchantUrl).hostname;
23
- }
24
- catch {
25
- throw new Error('--merchant-url must be a valid URL');
26
- }
27
- if (!host) {
28
- throw new Error('--merchant-url must have a hostname');
29
- }
30
- return {
31
- merchantName: input.get('--merchant-name') ?? host,
32
- merchantUrl,
33
- merchantCountryCode: input.get('--country') ?? 'US',
34
- transactionAmount: amount,
35
- transactionCurrencyCode: input.get('--currency') ?? 'USD',
36
- };
37
- }
@@ -1,14 +0,0 @@
1
- /**
2
- * Argv rewriter for the `pnpm pay` positional entry point, extracted pure so
3
- * it is unit-testable (the pay.ts script executes on import). Maps
4
- * `<checkout-url> <amount> [flags]` onto run-live-fill's inline flags.
5
- *
6
- * Strict by design — this drives a real-money run:
7
- * - `--merchant-url`/`--amount` are REJECTED as passthrough flags: the
8
- * runner's arg map lets a later flag win, so a stray duplicate would
9
- * silently retarget the purchase away from the typed positionals.
10
- * - Every flag must carry a value (same grammar as run-live-fill's args()),
11
- * so a trailing bare flag fails HERE with pay's usage, not downstream with
12
- * fill:live's.
13
- */
14
- export declare function rewritePayArgs(argv: string[]): string[];
@@ -1,44 +0,0 @@
1
- /**
2
- * Argv rewriter for the `pnpm pay` positional entry point, extracted pure so
3
- * it is unit-testable (the pay.ts script executes on import). Maps
4
- * `<checkout-url> <amount> [flags]` onto run-live-fill's inline flags.
5
- *
6
- * Strict by design — this drives a real-money run:
7
- * - `--merchant-url`/`--amount` are REJECTED as passthrough flags: the
8
- * runner's arg map lets a later flag win, so a stray duplicate would
9
- * silently retarget the purchase away from the typed positionals.
10
- * - Every flag must carry a value (same grammar as run-live-fill's args()),
11
- * so a trailing bare flag fails HERE with pay's usage, not downstream with
12
- * fill:live's.
13
- */
14
- const USAGE = 'usage: pnpm pay -- <checkout-url> <amount> [--merchant-name <name>] ' +
15
- '[--country <CC>] [--currency <ISO>] [--mode dry-run|submit] [--contact-file <path>] ' +
16
- '[--agent-credential-file <path>] [--approval-base-url <url>]';
17
- const RESERVED_FLAGS = ['--merchant-url', '--amount'];
18
- export function rewritePayArgs(argv) {
19
- // pnpm forwards the literal `--` separator; drop it like run-live-fill does.
20
- const tokens = argv.filter((a) => a !== '--');
21
- const positionals = [];
22
- const flags = [];
23
- for (let i = 0; i < tokens.length; i++) {
24
- const token = tokens[i];
25
- if (token.startsWith('--')) {
26
- if (RESERVED_FLAGS.includes(token)) {
27
- throw new Error(`${token} is derived from the positionals — pass the url and amount ` +
28
- `positionally instead of as flags\n${USAGE}`);
29
- }
30
- const value = tokens[i + 1];
31
- if (value === undefined || value.startsWith('--')) {
32
- throw new Error(`flag ${token} needs a value\n${USAGE}`);
33
- }
34
- flags.push(token, value);
35
- i++;
36
- }
37
- else {
38
- positionals.push(token);
39
- }
40
- }
41
- if (positionals.length !== 2)
42
- throw new Error(USAGE);
43
- return ['--merchant-url', positionals[0], '--amount', positionals[1], ...flags];
44
- }
@@ -1 +0,0 @@
1
- export {};
@@ -1,13 +0,0 @@
1
- /**
2
- * Positional sugar over run-live-fill's inline any-merchant mode:
3
- *
4
- * pnpm pay -- <checkout-url> <amount> [--mode submit] [--merchant-name "X"] [...]
5
- *
6
- * Rewrites the two positionals into --merchant-url/--amount (pay-args.ts,
7
- * strict) and re-enters the runner, so every guardrail (typed PAY approval,
8
- * CHECKOUT_AGENT_ALLOW_SUBMIT, hosted/loopback ceremony, receipts) is exactly
9
- * the fill:live path — this file must never grow logic of its own.
10
- */
11
- import { rewritePayArgs } from './pay-args.js';
12
- process.argv = [process.argv[0], process.argv[1], ...rewritePayArgs(process.argv.slice(2))];
13
- await import('./run-live-fill.js');
@@ -1,11 +0,0 @@
1
- /**
2
- * Load the monorepo root `.env` as DEFAULTS for the runner, so stable
3
- * per-machine config (VGS credentials, CHECKOUT_APPROVAL_BASE_URL,
4
- * CHECKOUT_AGENT_ALLOW_SUBMIT, CHECKOUT_AGENT_MODE) is set once instead of
5
- * retyped on every invocation. `process.loadEnvFile` never overrides
6
- * variables already present in the environment (verified: shell always wins),
7
- * so an explicit `FOO=x pnpm pay …` still beats the file. A missing file is
8
- * fine — the runner then relies on the ambient environment exactly as before.
9
- */
10
- export declare function defaultRepoEnvPath(): string;
11
- export declare function loadRepoEnvDefaults(path?: string, log?: (line: string) => void): boolean;
@@ -1,23 +0,0 @@
1
- import { fileURLToPath } from 'node:url';
2
- /**
3
- * Load the monorepo root `.env` as DEFAULTS for the runner, so stable
4
- * per-machine config (VGS credentials, CHECKOUT_APPROVAL_BASE_URL,
5
- * CHECKOUT_AGENT_ALLOW_SUBMIT, CHECKOUT_AGENT_MODE) is set once instead of
6
- * retyped on every invocation. `process.loadEnvFile` never overrides
7
- * variables already present in the environment (verified: shell always wins),
8
- * so an explicit `FOO=x pnpm pay …` still beats the file. A missing file is
9
- * fine — the runner then relies on the ambient environment exactly as before.
10
- */
11
- export function defaultRepoEnvPath() {
12
- return fileURLToPath(new URL('../../../.env', import.meta.url));
13
- }
14
- export function loadRepoEnvDefaults(path = defaultRepoEnvPath(), log = (line) => process.stdout.write(`${line}\n`)) {
15
- try {
16
- process.loadEnvFile(path);
17
- }
18
- catch {
19
- return false;
20
- }
21
- log(`loaded env defaults from ${path} (already-set variables win)`);
22
- return true;
23
- }
@@ -1 +0,0 @@
1
- export {};