@devlab.group/agent-commerce 2.4.0 → 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.
Files changed (108) hide show
  1. package/README.md +115 -15
  2. package/dist/ap2.d.ts +24 -12
  3. package/dist/ap2.js +31 -13
  4. package/dist/ap2.js.map +1 -1
  5. package/dist/{chunk-AITMDXKW.js → chunk-3OTCFFFT.js} +37 -4
  6. package/dist/chunk-3OTCFFFT.js.map +1 -0
  7. package/dist/{chunk-4OEXK3YG.js → chunk-4K7FIBJM.js} +25 -4
  8. package/dist/chunk-4K7FIBJM.js.map +1 -0
  9. package/dist/{chunk-WUIAUAA7.js → chunk-FKQK5XZA.js} +652 -68
  10. package/dist/chunk-FKQK5XZA.js.map +1 -0
  11. package/dist/chunk-GA3O2A7R.js +92 -0
  12. package/dist/chunk-GA3O2A7R.js.map +1 -0
  13. package/dist/{chunk-6WACRJVT.js → chunk-VUCMBGUR.js} +3 -3
  14. package/dist/{chunk-6WACRJVT.js.map → chunk-VUCMBGUR.js.map} +1 -1
  15. package/dist/cli/{ap2-QDHPRSTF.js → ap2-YAPLERSC.js} +34 -15
  16. package/dist/cli/ap2-YAPLERSC.js.map +1 -0
  17. package/dist/cli/{chunk-G2JEY7MB.js → chunk-2J2IQQ4X.js} +8 -7
  18. package/dist/cli/chunk-2J2IQQ4X.js.map +1 -0
  19. package/dist/cli/chunk-2UPPX3FJ.js +311 -0
  20. package/dist/cli/chunk-2UPPX3FJ.js.map +1 -0
  21. package/dist/cli/{chunk-WYOGIANL.js → chunk-4H2QLHQI.js} +4 -4
  22. package/dist/cli/{chunk-WYOGIANL.js.map → chunk-4H2QLHQI.js.map} +1 -1
  23. package/dist/cli/{chunk-OZ4LAWBK.js → chunk-5R7DM5LM.js} +25 -4
  24. package/dist/cli/chunk-5R7DM5LM.js.map +1 -0
  25. package/dist/cli/chunk-663ALDZA.js +92 -0
  26. package/dist/cli/chunk-663ALDZA.js.map +1 -0
  27. package/dist/cli/{chunk-QQ3WY5L3.js → chunk-IDY2735M.js} +36 -104
  28. package/dist/cli/chunk-IDY2735M.js.map +1 -0
  29. package/dist/cli/chunk-JFVRG2HH.js +107 -0
  30. package/dist/cli/chunk-JFVRG2HH.js.map +1 -0
  31. package/dist/cli/chunk-M7NXVRU5.js +8 -0
  32. package/dist/cli/{chunk-UXB65XCS.js.map → chunk-M7NXVRU5.js.map} +1 -1
  33. package/dist/cli/chunk-NIU5EMSB.js +119 -0
  34. package/dist/cli/chunk-NIU5EMSB.js.map +1 -0
  35. package/dist/cli/{chunk-AZDWFVDW.js → chunk-QA2OPHBF.js} +655 -70
  36. package/dist/cli/chunk-QA2OPHBF.js.map +1 -0
  37. package/dist/cli/{chunk-DCMW67JM.js → chunk-QLUCNPRT.js} +404 -161
  38. package/dist/cli/chunk-QLUCNPRT.js.map +1 -0
  39. package/dist/cli/chunk-SYQLJXIU.js +105 -0
  40. package/dist/cli/chunk-SYQLJXIU.js.map +1 -0
  41. package/dist/cli/{chunk-3MGAJ5FX.js → chunk-VJ4EO4LE.js} +3 -3
  42. package/dist/cli/{chunk-3MGAJ5FX.js.map → chunk-VJ4EO4LE.js.map} +1 -1
  43. package/dist/cli/{chunk-PIMFPCNZ.js → chunk-Z34UMZBB.js} +234 -85
  44. package/dist/cli/chunk-Z34UMZBB.js.map +1 -0
  45. package/dist/cli/config-BWFMN2ZB.js +12 -0
  46. package/dist/cli/{config-UI4EDG4L.js.map → config-BWFMN2ZB.js.map} +1 -1
  47. package/dist/cli/index.js +258 -11
  48. package/dist/cli/index.js.map +1 -1
  49. package/dist/cli/{mcp-26LJMN4N.js → mcp-KZEMXLHR.js} +5 -4
  50. package/dist/cli/mcp-KZEMXLHR.js.map +1 -0
  51. package/dist/cli/{near-5AY3HWYF.js → near-U6365VFX.js} +15 -4
  52. package/dist/cli/near-U6365VFX.js.map +1 -0
  53. package/dist/cli/payment-providers-SZL36H3Y.js +6 -0
  54. package/dist/cli/payment-providers-SZL36H3Y.js.map +1 -0
  55. package/dist/cli/{provider-Z4OJNAYI.js → provider-6TKB5ADJ.js} +30 -16
  56. package/dist/cli/provider-6TKB5ADJ.js.map +1 -0
  57. package/dist/cli/receipts-ZGLJWMQG.js +8 -0
  58. package/dist/cli/receipts-ZGLJWMQG.js.map +1 -0
  59. package/dist/cli/reconcile-IC22MJD5.js +4 -0
  60. package/dist/cli/reconcile-IC22MJD5.js.map +1 -0
  61. package/dist/cli/{run-TEPYJUHG.js → run-ZTYPQI4D.js} +151 -115
  62. package/dist/cli/run-ZTYPQI4D.js.map +1 -0
  63. package/dist/cli/svm-KDSPDFJG.js +48 -0
  64. package/dist/cli/svm-KDSPDFJG.js.map +1 -0
  65. package/dist/cli/{x402-BMVONZKA.js → x402-WLYBLODI.js} +10 -9
  66. package/dist/cli/x402-WLYBLODI.js.map +1 -0
  67. package/dist/index.d.ts +112 -12
  68. package/dist/index.js +948 -157
  69. package/dist/index.js.map +1 -1
  70. package/dist/mcp.d.ts +1 -2
  71. package/dist/mcp.js +1 -1
  72. package/dist/mpp.js +24 -11
  73. package/dist/mpp.js.map +1 -1
  74. package/dist/{near-D6C42VPE.js → near-FH7HPZV3.js} +15 -4
  75. package/dist/near-FH7HPZV3.js.map +1 -0
  76. package/dist/{protocol-adapter-C9odYl6l.d.ts → protocol-adapter-DEXpdp8m.d.ts} +102 -48
  77. package/dist/{runtime-Cl_BLVZV.d.ts → runtime-Dz2fSO-P.d.ts} +220 -2
  78. package/dist/svm-KNC3PHMS.js +48 -0
  79. package/dist/svm-KNC3PHMS.js.map +1 -0
  80. package/dist/x402.js +5 -5
  81. package/package.json +1 -1
  82. package/dist/authorization-DjAecwuW.d.ts +0 -115
  83. package/dist/chunk-4OEXK3YG.js.map +0 -1
  84. package/dist/chunk-AITMDXKW.js.map +0 -1
  85. package/dist/chunk-KA2AX5FH.js +0 -44
  86. package/dist/chunk-KA2AX5FH.js.map +0 -1
  87. package/dist/chunk-WUIAUAA7.js.map +0 -1
  88. package/dist/cli/ap2-QDHPRSTF.js.map +0 -1
  89. package/dist/cli/chunk-AZDWFVDW.js.map +0 -1
  90. package/dist/cli/chunk-DCMW67JM.js.map +0 -1
  91. package/dist/cli/chunk-G2JEY7MB.js.map +0 -1
  92. package/dist/cli/chunk-OSTCU6ZK.js +0 -44
  93. package/dist/cli/chunk-OSTCU6ZK.js.map +0 -1
  94. package/dist/cli/chunk-OZ4LAWBK.js.map +0 -1
  95. package/dist/cli/chunk-PIMFPCNZ.js.map +0 -1
  96. package/dist/cli/chunk-QQ3WY5L3.js.map +0 -1
  97. package/dist/cli/chunk-UXB65XCS.js +0 -8
  98. package/dist/cli/config-UI4EDG4L.js +0 -11
  99. package/dist/cli/mcp-26LJMN4N.js.map +0 -1
  100. package/dist/cli/near-5AY3HWYF.js.map +0 -1
  101. package/dist/cli/provider-Z4OJNAYI.js.map +0 -1
  102. package/dist/cli/run-TEPYJUHG.js.map +0 -1
  103. package/dist/cli/svm-3MMYFPC7.js +0 -33
  104. package/dist/cli/svm-3MMYFPC7.js.map +0 -1
  105. package/dist/cli/x402-BMVONZKA.js.map +0 -1
  106. package/dist/near-D6C42VPE.js.map +0 -1
  107. package/dist/svm-QEUAUNPQ.js +0 -33
  108. 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-DCMW67JM.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-3MGAJ5FX.js';
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 { PACKAGE_VERSION } from './chunk-UXB65XCS.js';
11
- import { PROTOCOL_NAMES, isCommerceError, CommerceError } from './chunk-QQ3WY5L3.js';
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-UI4EDG4L.js');
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/payment-attempts?uncertain=true` : "";
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("CLI for the Agent Commerce Gateway: init, import, validate, start, doctor, demo.").version(readVersionReport().cliVersion, "-v, --version", "Print the CLI version.").exitOverride().configureOutput({
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-TEPYJUHG.js');
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;