@devlab.group/agent-commerce 2.4.1 → 2.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/README.md +115 -15
- package/dist/ap2.d.ts +24 -12
- package/dist/ap2.js +31 -13
- package/dist/ap2.js.map +1 -1
- package/dist/{chunk-DTKU3Z2M.js → chunk-3OTCFFFT.js} +37 -4
- package/dist/chunk-3OTCFFFT.js.map +1 -0
- package/dist/{chunk-QPV3EGJO.js → chunk-4K7FIBJM.js} +25 -4
- package/dist/chunk-4K7FIBJM.js.map +1 -0
- package/dist/{chunk-CXWC5LWM.js → chunk-FKQK5XZA.js} +652 -68
- package/dist/chunk-FKQK5XZA.js.map +1 -0
- package/dist/chunk-GA3O2A7R.js +92 -0
- package/dist/chunk-GA3O2A7R.js.map +1 -0
- package/dist/{chunk-WZW5ORZH.js → chunk-VUCMBGUR.js} +3 -3
- package/dist/{chunk-WZW5ORZH.js.map → chunk-VUCMBGUR.js.map} +1 -1
- package/dist/cli/{ap2-GWSP4LYY.js → ap2-YAPLERSC.js} +34 -15
- package/dist/cli/ap2-YAPLERSC.js.map +1 -0
- package/dist/cli/{chunk-G2JEY7MB.js → chunk-2J2IQQ4X.js} +8 -7
- package/dist/cli/chunk-2J2IQQ4X.js.map +1 -0
- package/dist/cli/chunk-2UPPX3FJ.js +311 -0
- package/dist/cli/chunk-2UPPX3FJ.js.map +1 -0
- package/dist/cli/{chunk-WYOGIANL.js → chunk-4H2QLHQI.js} +4 -4
- package/dist/cli/{chunk-WYOGIANL.js.map → chunk-4H2QLHQI.js.map} +1 -1
- package/dist/cli/{chunk-OZ4LAWBK.js → chunk-5R7DM5LM.js} +25 -4
- package/dist/cli/chunk-5R7DM5LM.js.map +1 -0
- package/dist/cli/chunk-663ALDZA.js +92 -0
- package/dist/cli/chunk-663ALDZA.js.map +1 -0
- package/dist/cli/{chunk-QQ3WY5L3.js → chunk-IDY2735M.js} +36 -104
- package/dist/cli/chunk-IDY2735M.js.map +1 -0
- package/dist/cli/chunk-JFVRG2HH.js +107 -0
- package/dist/cli/chunk-JFVRG2HH.js.map +1 -0
- package/dist/cli/chunk-M7NXVRU5.js +8 -0
- package/dist/cli/{chunk-ITWNSS2B.js.map → chunk-M7NXVRU5.js.map} +1 -1
- package/dist/cli/chunk-NIU5EMSB.js +119 -0
- package/dist/cli/chunk-NIU5EMSB.js.map +1 -0
- package/dist/cli/{chunk-TNMLDPUO.js → chunk-QA2OPHBF.js} +655 -70
- package/dist/cli/chunk-QA2OPHBF.js.map +1 -0
- package/dist/cli/{chunk-GJIMDMYT.js → chunk-QLUCNPRT.js} +404 -161
- package/dist/cli/chunk-QLUCNPRT.js.map +1 -0
- package/dist/cli/chunk-SYQLJXIU.js +105 -0
- package/dist/cli/chunk-SYQLJXIU.js.map +1 -0
- package/dist/cli/{chunk-3MGAJ5FX.js → chunk-VJ4EO4LE.js} +3 -3
- package/dist/cli/{chunk-3MGAJ5FX.js.map → chunk-VJ4EO4LE.js.map} +1 -1
- package/dist/cli/{chunk-PIMFPCNZ.js → chunk-Z34UMZBB.js} +234 -85
- package/dist/cli/chunk-Z34UMZBB.js.map +1 -0
- package/dist/cli/config-BWFMN2ZB.js +12 -0
- package/dist/cli/{config-UI4EDG4L.js.map → config-BWFMN2ZB.js.map} +1 -1
- package/dist/cli/index.js +258 -11
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/{mcp-PGBRWZVA.js → mcp-KZEMXLHR.js} +5 -4
- package/dist/cli/mcp-KZEMXLHR.js.map +1 -0
- package/dist/cli/{near-5AY3HWYF.js → near-U6365VFX.js} +15 -4
- package/dist/cli/near-U6365VFX.js.map +1 -0
- package/dist/cli/payment-providers-SZL36H3Y.js +6 -0
- package/dist/cli/payment-providers-SZL36H3Y.js.map +1 -0
- package/dist/cli/{provider-I2ESL6RS.js → provider-6TKB5ADJ.js} +26 -15
- package/dist/cli/provider-6TKB5ADJ.js.map +1 -0
- package/dist/cli/receipts-ZGLJWMQG.js +8 -0
- package/dist/cli/receipts-ZGLJWMQG.js.map +1 -0
- package/dist/cli/reconcile-IC22MJD5.js +4 -0
- package/dist/cli/reconcile-IC22MJD5.js.map +1 -0
- package/dist/cli/{run-JK4ERPJV.js → run-ZTYPQI4D.js} +151 -115
- package/dist/cli/run-ZTYPQI4D.js.map +1 -0
- package/dist/cli/svm-KDSPDFJG.js +48 -0
- package/dist/cli/svm-KDSPDFJG.js.map +1 -0
- package/dist/cli/{x402-7WBFZQXV.js → x402-WLYBLODI.js} +10 -9
- package/dist/cli/x402-WLYBLODI.js.map +1 -0
- package/dist/index.d.ts +112 -12
- package/dist/index.js +948 -157
- package/dist/index.js.map +1 -1
- package/dist/mcp.d.ts +1 -2
- package/dist/mcp.js +1 -1
- package/dist/mpp.js +20 -10
- package/dist/mpp.js.map +1 -1
- package/dist/{near-D6C42VPE.js → near-FH7HPZV3.js} +15 -4
- package/dist/near-FH7HPZV3.js.map +1 -0
- package/dist/{protocol-adapter-C9odYl6l.d.ts → protocol-adapter-DEXpdp8m.d.ts} +102 -48
- package/dist/{runtime-Cl_BLVZV.d.ts → runtime-Dz2fSO-P.d.ts} +220 -2
- package/dist/svm-KNC3PHMS.js +48 -0
- package/dist/svm-KNC3PHMS.js.map +1 -0
- package/dist/x402.js +5 -5
- package/package.json +1 -1
- package/dist/authorization-DjAecwuW.d.ts +0 -115
- package/dist/chunk-CXWC5LWM.js.map +0 -1
- package/dist/chunk-DTKU3Z2M.js.map +0 -1
- package/dist/chunk-KA2AX5FH.js +0 -44
- package/dist/chunk-KA2AX5FH.js.map +0 -1
- package/dist/chunk-QPV3EGJO.js.map +0 -1
- package/dist/cli/ap2-GWSP4LYY.js.map +0 -1
- package/dist/cli/chunk-G2JEY7MB.js.map +0 -1
- package/dist/cli/chunk-GJIMDMYT.js.map +0 -1
- package/dist/cli/chunk-ITWNSS2B.js +0 -8
- package/dist/cli/chunk-OSTCU6ZK.js +0 -44
- package/dist/cli/chunk-OSTCU6ZK.js.map +0 -1
- package/dist/cli/chunk-OZ4LAWBK.js.map +0 -1
- package/dist/cli/chunk-PIMFPCNZ.js.map +0 -1
- package/dist/cli/chunk-QQ3WY5L3.js.map +0 -1
- package/dist/cli/chunk-TNMLDPUO.js.map +0 -1
- package/dist/cli/config-UI4EDG4L.js +0 -11
- package/dist/cli/mcp-PGBRWZVA.js.map +0 -1
- package/dist/cli/near-5AY3HWYF.js.map +0 -1
- package/dist/cli/provider-I2ESL6RS.js.map +0 -1
- package/dist/cli/run-JK4ERPJV.js.map +0 -1
- package/dist/cli/svm-3MMYFPC7.js +0 -33
- package/dist/cli/svm-3MMYFPC7.js.map +0 -1
- package/dist/cli/x402-7WBFZQXV.js.map +0 -1
- package/dist/near-D6C42VPE.js.map +0 -1
- package/dist/svm-QEUAUNPQ.js +0 -33
- package/dist/svm-QEUAUNPQ.js.map +0 -1
package/dist/cli/index.js
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { createSqliteReceiptStore, A2A_SPEC_VERSION, A2A_PROTOCOL_VERSION, A2A_PROTOCOL_BINDING, A2A_AGENT_CARD_PATH, A2A_UNSUPPORTED, ACP_UNSUPPORTED } from './chunk-GJIMDMYT.js';
|
|
3
|
-
import { DEFAULT_CONFIG_FILENAME, extractPathParameterNames, ACP_SPEC_VERSION, ACP_API_VERSION, ACP_WELL_KNOWN_PATH, findUnparsedBraceToken } from './chunk-PIMFPCNZ.js';
|
|
4
|
-
import { MPP_PROFILE, MPP_SPEC_DRAFTS, MPPX_VERSION, MPP_SPEC_COMMIT, MPP_DEFAULT_PAYMENT_FLOW } from './chunk-AA3FIEAR.js';
|
|
5
|
-
import { ANVIL_WELL_KNOWN_ACCOUNTS, describeDeploymentMode, X402_DEFAULT_PAYMENT_FLOW, findX402Network, isEvmAddress, LOCAL_CHAIN_ID, resolveDeploymentMode, sameAddress } from './chunk-OZ4LAWBK.js';
|
|
6
2
|
import { AP2_UNSUPPORTED } from './chunk-3EQBCFZY.js';
|
|
7
|
-
import './chunk-
|
|
3
|
+
import { A2A_SPEC_VERSION, A2A_PROTOCOL_VERSION, A2A_PROTOCOL_BINDING, A2A_AGENT_CARD_PATH, A2A_UNSUPPORTED, ACP_UNSUPPORTED } from './chunk-NIU5EMSB.js';
|
|
4
|
+
import { createSqliteReceiptStore } from './chunk-QLUCNPRT.js';
|
|
5
|
+
import './chunk-VJ4EO4LE.js';
|
|
6
|
+
import { DEFAULT_CONFIG_FILENAME, extractPathParameterNames, ACP_SPEC_VERSION, ACP_API_VERSION, ACP_WELL_KNOWN_PATH, findUnparsedBraceToken } from './chunk-Z34UMZBB.js';
|
|
8
7
|
import { AP2_SPEC_VERSION, AP2_CHECKOUT_MANDATE_VCT, AP2_CHECKOUT_PROFILE } from './chunk-FHCFR2GS.js';
|
|
9
8
|
import { MCP_TOOL_NAME_MAX_LENGTH, MCP_TOOL_NAME_CHARS } from './chunk-TPC4EJLT.js';
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
9
|
+
import { MPP_PROFILE, MPP_SPEC_DRAFTS, MPPX_VERSION, MPP_SPEC_COMMIT, MPP_DEFAULT_PAYMENT_FLOW } from './chunk-AA3FIEAR.js';
|
|
10
|
+
import { PACKAGE_VERSION } from './chunk-M7NXVRU5.js';
|
|
11
|
+
import { ANVIL_WELL_KNOWN_ACCOUNTS, describeDeploymentMode, X402_DEFAULT_PAYMENT_FLOW, findX402Network, isEvmAddress, LOCAL_CHAIN_ID, resolveDeploymentMode, sameAddress } from './chunk-5R7DM5LM.js';
|
|
12
|
+
import { PROTOCOL_NAMES, systemClock, NOOP_LOGGER } from './chunk-IDY2735M.js';
|
|
13
|
+
import { isCommerceError, redactedErrorText, CommerceError } from './chunk-SYQLJXIU.js';
|
|
12
14
|
import { isRecord } from './chunk-3M6U7ILB.js';
|
|
13
15
|
import { CommanderError, Command } from 'commander';
|
|
14
16
|
import { existsSync, mkdirSync, readFileSync, accessSync, constants } from 'fs';
|
|
@@ -20,6 +22,7 @@ import { writeFile, stat, mkdir, rename, rm, open } from 'fs/promises';
|
|
|
20
22
|
import { isDeepStrictEqual } from 'util';
|
|
21
23
|
import { validate } from '@scalar/openapi-parser';
|
|
22
24
|
import * as clack from '@clack/prompts';
|
|
25
|
+
import { userInfo } from 'os';
|
|
23
26
|
|
|
24
27
|
// src/cli/commands/demo.ts
|
|
25
28
|
function defaultDemoSteps() {
|
|
@@ -78,7 +81,7 @@ async function execCommand(command, args) {
|
|
|
78
81
|
// src/cli/lib/config-client.ts
|
|
79
82
|
async function importConfig() {
|
|
80
83
|
try {
|
|
81
|
-
return await import('./config-
|
|
84
|
+
return await import('./config-BWFMN2ZB.js');
|
|
82
85
|
} catch (err) {
|
|
83
86
|
throw new CommerceError(
|
|
84
87
|
"INTERNAL_ERROR",
|
|
@@ -345,7 +348,7 @@ async function storageChecks(config, createStore) {
|
|
|
345
348
|
}
|
|
346
349
|
const status = storeHealth.status === "pass" ? "PASS" : storeHealth.status === "warn" ? "WARN" : "FAIL";
|
|
347
350
|
const receiptsSuffix = receiptCount !== void 0 ? `; receipts=${receiptCount}${undeliveredCount !== void 0 && undeliveredCount > 0 ? ` (${undeliveredCount} undelivered)` : ""}` : "";
|
|
348
|
-
const uncertainSuffix = uncertainCount !== void 0 && uncertainCount > 0 ? `; ${uncertainCount} payment(s) with unknown settlement outcome, see GET /api/
|
|
351
|
+
const uncertainSuffix = uncertainCount !== void 0 && uncertainCount > 0 ? `; ${uncertainCount} payment(s) with unknown settlement outcome, see GET /api/transactions?unresolved=true or run agent-commerce reconcile` : "";
|
|
349
352
|
checks.push({
|
|
350
353
|
name: "Storage",
|
|
351
354
|
status,
|
|
@@ -2476,6 +2479,206 @@ async function runInit(options, io, deps = {}) {
|
|
|
2476
2479
|
io.stdout(" docker compose up # or the whole local demo stack, from a repo clone");
|
|
2477
2480
|
return 0;
|
|
2478
2481
|
}
|
|
2482
|
+
var DURATION = /^(\d{1,9})(s|m|h|d)$/;
|
|
2483
|
+
var UNIT_MS = { s: 1e3, m: 6e4, h: 36e5, d: 864e5 };
|
|
2484
|
+
async function runReconcileCommand(options, io, deps = {}) {
|
|
2485
|
+
const minAgeMs = options.minAge !== void 0 ? parseDuration(options.minAge) : void 0;
|
|
2486
|
+
if (minAgeMs === null) {
|
|
2487
|
+
io.stderr(`FAIL --min-age must be a duration such as 30s, 15m or 2h, got "${options.minAge}"`);
|
|
2488
|
+
return 1;
|
|
2489
|
+
}
|
|
2490
|
+
const limit = options.limit !== void 0 ? Number(options.limit) : void 0;
|
|
2491
|
+
if (limit !== void 0 && (!Number.isSafeInteger(limit) || limit < 1)) {
|
|
2492
|
+
io.stderr(`FAIL --limit must be a positive integer, got "${options.limit}"`);
|
|
2493
|
+
return 1;
|
|
2494
|
+
}
|
|
2495
|
+
const actor = options.actor ?? osUser();
|
|
2496
|
+
if (actor.trim() === "") {
|
|
2497
|
+
io.stderr("FAIL --actor must not be empty");
|
|
2498
|
+
return 1;
|
|
2499
|
+
}
|
|
2500
|
+
let config;
|
|
2501
|
+
try {
|
|
2502
|
+
config = await (deps.loadConfig ?? loadConfigDynamic)(
|
|
2503
|
+
options.configPath !== void 0 ? { path: options.configPath } : {}
|
|
2504
|
+
);
|
|
2505
|
+
} catch (error) {
|
|
2506
|
+
io.stderr(formatConfigError(error, false, false));
|
|
2507
|
+
return 1;
|
|
2508
|
+
}
|
|
2509
|
+
try {
|
|
2510
|
+
const logger = stderrLogger(io);
|
|
2511
|
+
const { runReconcile } = await import('./reconcile-IC22MJD5.js');
|
|
2512
|
+
const providers = await (await import('./payment-providers-SZL36H3Y.js')).createConfiguredPaymentProviders(config.payments, logger);
|
|
2513
|
+
await withJournal(config, logger, async (store, authorizationProviders) => {
|
|
2514
|
+
const report = await runReconcile({
|
|
2515
|
+
store,
|
|
2516
|
+
providers,
|
|
2517
|
+
authorizationProviders,
|
|
2518
|
+
clock: systemClock,
|
|
2519
|
+
actor,
|
|
2520
|
+
dryRun: options.dryRun === true,
|
|
2521
|
+
...minAgeMs !== void 0 ? { minAgeMs } : {},
|
|
2522
|
+
...limit !== void 0 ? { limit } : {},
|
|
2523
|
+
logger
|
|
2524
|
+
});
|
|
2525
|
+
printReport(report, io, options.json === true);
|
|
2526
|
+
});
|
|
2527
|
+
return 0;
|
|
2528
|
+
} catch (error) {
|
|
2529
|
+
io.stderr(`FAIL reconcile could not run: ${redactedErrorText(error)}`);
|
|
2530
|
+
return 1;
|
|
2531
|
+
}
|
|
2532
|
+
}
|
|
2533
|
+
async function withJournal(config, logger, fn) {
|
|
2534
|
+
const [{ createConfiguredAuthorizationProviders }, { createSqliteReceiptStore: createSqliteReceiptStore2 }] = await Promise.all([
|
|
2535
|
+
import('./payment-providers-SZL36H3Y.js'),
|
|
2536
|
+
import('./receipts-ZGLJWMQG.js')
|
|
2537
|
+
]);
|
|
2538
|
+
const authorizationProviders = await createConfiguredAuthorizationProviders(
|
|
2539
|
+
config.authorization,
|
|
2540
|
+
logger
|
|
2541
|
+
);
|
|
2542
|
+
try {
|
|
2543
|
+
const store = createSqliteReceiptStore2({ path: config.storage.receipts.path, logger });
|
|
2544
|
+
try {
|
|
2545
|
+
await store.init();
|
|
2546
|
+
await fn(store, authorizationProviders);
|
|
2547
|
+
} finally {
|
|
2548
|
+
await store.close();
|
|
2549
|
+
}
|
|
2550
|
+
} finally {
|
|
2551
|
+
for (const provider of authorizationProviders) provider.close();
|
|
2552
|
+
}
|
|
2553
|
+
}
|
|
2554
|
+
function parseDuration(value) {
|
|
2555
|
+
if (value === "0") return 0;
|
|
2556
|
+
const match = DURATION.exec(value);
|
|
2557
|
+
return match ? Number(match[1]) * UNIT_MS[match[2]] : null;
|
|
2558
|
+
}
|
|
2559
|
+
function printReport(report, io, json) {
|
|
2560
|
+
const count = (outcome) => report.entries.filter((e) => e.outcome === outcome).length;
|
|
2561
|
+
const counts = {
|
|
2562
|
+
candidates: report.entries.length,
|
|
2563
|
+
settled: count("settled"),
|
|
2564
|
+
notSettled: count("not-settled"),
|
|
2565
|
+
unknown: count("unknown"),
|
|
2566
|
+
resolved: report.entries.filter((e) => e.written).length,
|
|
2567
|
+
holdsAligned: report.holds.filter((h) => h.written).length
|
|
2568
|
+
};
|
|
2569
|
+
if (json) {
|
|
2570
|
+
io.stdout(
|
|
2571
|
+
JSON.stringify(
|
|
2572
|
+
{ dryRun: report.dryRun, counts, entries: report.entries, holds: report.holds },
|
|
2573
|
+
null,
|
|
2574
|
+
2
|
|
2575
|
+
)
|
|
2576
|
+
);
|
|
2577
|
+
return;
|
|
2578
|
+
}
|
|
2579
|
+
io.stdout(
|
|
2580
|
+
`reconcile${report.dryRun ? " (dry run, no resolutions written)" : ""}: ${counts.candidates} candidates, ${counts.settled} settled, ${counts.notSettled} not settled, ${counts.unknown} unknown, ${counts.resolved} resolved` + (report.holds.length > 0 ? `, ${counts.holdsAligned} of ${report.holds.length} holds aligned` : "")
|
|
2581
|
+
);
|
|
2582
|
+
for (const entry of report.entries) {
|
|
2583
|
+
io.stdout(
|
|
2584
|
+
[
|
|
2585
|
+
entry.outcome.toUpperCase().padEnd(11),
|
|
2586
|
+
entry.attemptId,
|
|
2587
|
+
`request=${entry.requestId}`,
|
|
2588
|
+
`provider=${entry.provider}`,
|
|
2589
|
+
`status=${entry.status}`,
|
|
2590
|
+
`reason=${entry.reason}`,
|
|
2591
|
+
...entry.externalReference !== void 0 ? [`reference=${entry.externalReference}`] : [],
|
|
2592
|
+
...entry.retryAfter !== void 0 ? [`retryAfter=${entry.retryAfter}`] : [],
|
|
2593
|
+
...entry.error !== void 0 ? [`error=${entry.error}`] : [],
|
|
2594
|
+
...entry.written ? ["resolved"] : []
|
|
2595
|
+
].join(" ")
|
|
2596
|
+
);
|
|
2597
|
+
}
|
|
2598
|
+
for (const hold of report.holds) {
|
|
2599
|
+
io.stdout(
|
|
2600
|
+
[
|
|
2601
|
+
"HOLD".padEnd(11),
|
|
2602
|
+
hold.transactionId,
|
|
2603
|
+
`attempt=${hold.attemptId}`,
|
|
2604
|
+
`method=${hold.method}`,
|
|
2605
|
+
`hold=${hold.hold}`,
|
|
2606
|
+
...hold.reason !== void 0 ? [`reason=${hold.reason}`] : [],
|
|
2607
|
+
...hold.written ? ["aligned"] : []
|
|
2608
|
+
].join(" ")
|
|
2609
|
+
);
|
|
2610
|
+
}
|
|
2611
|
+
}
|
|
2612
|
+
function osUser() {
|
|
2613
|
+
try {
|
|
2614
|
+
return userInfo().username;
|
|
2615
|
+
} catch {
|
|
2616
|
+
return "unknown";
|
|
2617
|
+
}
|
|
2618
|
+
}
|
|
2619
|
+
function stderrLogger(io) {
|
|
2620
|
+
const write = (level) => (obj, msg) => io.stderr(`${level} ${msg ?? ""} ${JSON.stringify(obj)}`.trimEnd());
|
|
2621
|
+
return {
|
|
2622
|
+
...NOOP_LOGGER,
|
|
2623
|
+
warn: write("WARN"),
|
|
2624
|
+
error: write("ERROR"),
|
|
2625
|
+
child: () => stderrLogger(io)
|
|
2626
|
+
};
|
|
2627
|
+
}
|
|
2628
|
+
|
|
2629
|
+
// src/cli/commands/resolve.ts
|
|
2630
|
+
var OPERATOR_ERRORS = /* @__PURE__ */ new Set(["INPUT_INVALID", "RESOURCE_NOT_FOUND"]);
|
|
2631
|
+
async function runResolveCommand(attemptId, options, io, deps = {}) {
|
|
2632
|
+
let config;
|
|
2633
|
+
try {
|
|
2634
|
+
config = await (deps.loadConfig ?? loadConfigDynamic)(
|
|
2635
|
+
options.configPath !== void 0 ? { path: options.configPath } : {}
|
|
2636
|
+
);
|
|
2637
|
+
} catch (error) {
|
|
2638
|
+
io.stderr(formatConfigError(error, false, false));
|
|
2639
|
+
return 1;
|
|
2640
|
+
}
|
|
2641
|
+
try {
|
|
2642
|
+
const { resolveManually } = await import('./reconcile-IC22MJD5.js');
|
|
2643
|
+
const logger = stderrLogger(io);
|
|
2644
|
+
let code = 1;
|
|
2645
|
+
await withJournal(config, logger, async (store, authorizationProviders) => {
|
|
2646
|
+
const result = await resolveManually({
|
|
2647
|
+
store,
|
|
2648
|
+
authorizationProviders,
|
|
2649
|
+
clock: systemClock,
|
|
2650
|
+
logger,
|
|
2651
|
+
attemptId,
|
|
2652
|
+
status: options.status,
|
|
2653
|
+
actor: options.actor ?? osUser(),
|
|
2654
|
+
reason: options.reason,
|
|
2655
|
+
...options.reference !== void 0 ? { externalReference: options.reference } : {},
|
|
2656
|
+
...options.confirmExpired === true ? { confirmExpired: true } : {}
|
|
2657
|
+
});
|
|
2658
|
+
if (!result.resolved) {
|
|
2659
|
+
const hint = result.refusal === "expiry_unknown" ? " (pass --confirm-expired)" : "";
|
|
2660
|
+
io.stderr(
|
|
2661
|
+
`FAIL ${attemptId} not resolved: ${result.message}${hint} [${result.refusal}, status=${result.attempt.status}]`
|
|
2662
|
+
);
|
|
2663
|
+
return;
|
|
2664
|
+
}
|
|
2665
|
+
io.stdout(`RESOLVED ${attemptId} status=${result.attempt.status}`);
|
|
2666
|
+
const { hold } = result;
|
|
2667
|
+
if (hold !== void 0) {
|
|
2668
|
+
io.stdout(
|
|
2669
|
+
hold.written ? `HOLD ${hold.method} ${hold.hold}` : `WARN ${hold.method} hold not ${hold.hold} (${hold.reason}); agent-commerce reconcile aligns it once the provider is available`
|
|
2670
|
+
);
|
|
2671
|
+
}
|
|
2672
|
+
code = 0;
|
|
2673
|
+
});
|
|
2674
|
+
return code;
|
|
2675
|
+
} catch (error) {
|
|
2676
|
+
io.stderr(
|
|
2677
|
+
isCommerceError(error) && OPERATOR_ERRORS.has(error.code) ? `FAIL ${error.code}: ${error.message}` : `FAIL resolve could not run: ${redactedErrorText(error)}`
|
|
2678
|
+
);
|
|
2679
|
+
return 1;
|
|
2680
|
+
}
|
|
2681
|
+
}
|
|
2479
2682
|
|
|
2480
2683
|
// src/cli/commands/version.ts
|
|
2481
2684
|
function runVersion(io, deps = {}) {
|
|
@@ -2508,7 +2711,9 @@ var processIo = {
|
|
|
2508
2711
|
var ENV_FILE_HELP = "load environment variables from this file; variables already set win";
|
|
2509
2712
|
function buildProgram(io = processIo) {
|
|
2510
2713
|
const program = new Command();
|
|
2511
|
-
program.name("agent-commerce").description(
|
|
2714
|
+
program.name("agent-commerce").description(
|
|
2715
|
+
"CLI for the Agent Commerce Gateway: init, import, validate, start, doctor, reconcile, demo."
|
|
2716
|
+
).version(readVersionReport().cliVersion, "-v, --version", "Print the CLI version.").exitOverride().configureOutput({
|
|
2512
2717
|
writeOut: (str) => io.stdout(str.replace(/\n+$/, "")),
|
|
2513
2718
|
writeErr: (str) => io.stderr(str.replace(/\n+$/, ""))
|
|
2514
2719
|
}).hook("preAction", (_program, command) => {
|
|
@@ -2536,7 +2741,7 @@ function buildProgram(io = processIo) {
|
|
|
2536
2741
|
`Start the gateway from ${DEFAULT_CONFIG_FILENAME} and serve until SIGTERM or SIGINT.`
|
|
2537
2742
|
).option("--config <path>", `path to ${DEFAULT_CONFIG_FILENAME}`).option("--env-file <path>", ENV_FILE_HELP).action(async (opts) => {
|
|
2538
2743
|
try {
|
|
2539
|
-
const { runGateway } = await import('./run-
|
|
2744
|
+
const { runGateway } = await import('./run-ZTYPQI4D.js');
|
|
2540
2745
|
await runGateway(opts.config !== void 0 ? { configPath: opts.config } : {});
|
|
2541
2746
|
} catch (error) {
|
|
2542
2747
|
io.stderr(formatConfigError(error, false, false));
|
|
@@ -2554,6 +2759,48 @@ function buildProgram(io = processIo) {
|
|
|
2554
2759
|
printDoctorReport(report, io, opts.json === true);
|
|
2555
2760
|
process.exitCode = report.exitCode;
|
|
2556
2761
|
});
|
|
2762
|
+
program.command("reconcile").description(
|
|
2763
|
+
"Resolve uncertain payment attempts using chain evidence. Never settles or refunds."
|
|
2764
|
+
).option("--config <path>", `path to ${DEFAULT_CONFIG_FILENAME}`).option("--env-file <path>", ENV_FILE_HELP).option("--dry-run", "read evidence and report without recording resolutions", false).option("--json", "emit machine-readable JSON instead of a formatted report", false).option("--actor <name>", "who ran it, stored with each resolution (default: the OS user)").option(
|
|
2765
|
+
"--min-age <duration>",
|
|
2766
|
+
"skip reserved attempts younger than this, such as 30s, 15m or 2h (default: 15m)"
|
|
2767
|
+
).option("--limit <n>", "check at most this many attempts, and update at most this many holds").action(
|
|
2768
|
+
async (opts) => {
|
|
2769
|
+
process.exitCode = await runReconcileCommand(
|
|
2770
|
+
{
|
|
2771
|
+
...opts.config !== void 0 ? { configPath: opts.config } : {},
|
|
2772
|
+
dryRun: opts.dryRun,
|
|
2773
|
+
json: opts.json,
|
|
2774
|
+
...opts.actor !== void 0 ? { actor: opts.actor } : {},
|
|
2775
|
+
...opts.minAge !== void 0 ? { minAge: opts.minAge } : {},
|
|
2776
|
+
...opts.limit !== void 0 ? { limit: opts.limit } : {}
|
|
2777
|
+
},
|
|
2778
|
+
io
|
|
2779
|
+
);
|
|
2780
|
+
}
|
|
2781
|
+
);
|
|
2782
|
+
program.command("resolve <attemptId>").description(
|
|
2783
|
+
"Record a verdict on one unresolved payment attempt and align its hold. Never settles or refunds."
|
|
2784
|
+
).requiredOption("--status <status>", "settled or rejected").requiredOption("--reason <text>", "why, stored with the resolution").option("--reference <ref>", "transaction reference, stored as your unchecked claim").option("--actor <name>", "who resolved it, stored with the resolution (default: the OS user)").option(
|
|
2785
|
+
"--confirm-expired",
|
|
2786
|
+
"confirm that an authorization with no recorded expiry can no longer land",
|
|
2787
|
+
false
|
|
2788
|
+
).option("--config <path>", `path to ${DEFAULT_CONFIG_FILENAME}`).option("--env-file <path>", ENV_FILE_HELP).action(
|
|
2789
|
+
async (attemptId, opts) => {
|
|
2790
|
+
process.exitCode = await runResolveCommand(
|
|
2791
|
+
attemptId,
|
|
2792
|
+
{
|
|
2793
|
+
...opts.config !== void 0 ? { configPath: opts.config } : {},
|
|
2794
|
+
status: opts.status,
|
|
2795
|
+
reason: opts.reason,
|
|
2796
|
+
...opts.reference !== void 0 ? { reference: opts.reference } : {},
|
|
2797
|
+
...opts.actor !== void 0 ? { actor: opts.actor } : {},
|
|
2798
|
+
confirmExpired: opts.confirmExpired
|
|
2799
|
+
},
|
|
2800
|
+
io
|
|
2801
|
+
);
|
|
2802
|
+
}
|
|
2803
|
+
);
|
|
2557
2804
|
program.command("init").description(`Interactively generate ${DEFAULT_CONFIG_FILENAME}.`).option("--output <path>", "output path", DEFAULT_CONFIG_FILENAME).option("--force", "overwrite an existing file", false).option("--yes", "use non-interactive defaults (required for scripting/tests)", false).action(async (opts) => {
|
|
2558
2805
|
const code = await runInit({ outputPath: opts.output, force: opts.force, yes: opts.yes }, io);
|
|
2559
2806
|
process.exitCode = code;
|