@vapi-network/cli 0.2.2 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export declare const HELP = "vAPI Network\n\nUsage:\n vapi init [--networks <base,solana>] [--json]\n vapi fund [--amount <usd>] [--json]\n vapi accounts [--enable solana] [--json]\n vapi search [query] [--kind <kind>] [--network <caip2>] [--limit <n>] [--cursor <cursor>] [--json]\n vapi inspect <id> [--endpoint <name>] [--json]\n vapi pay <id-or-url> [--method <method>] [--endpoint <name>] [--body <json>] [--content-type <type>] [--network <caip2>] [--expected-pay-to <address>] [--max <amount>] [--json]\n vapi balance [--json]\n vapi receipts [--limit <n>] [--json]\n vapi receipts export --format <json|csv> [--range <24h|7d|30d>]\n vapi stats [--range <24h|7d|30d>] [--json]\n vapi sweep <address> [--network <caip2>] [--json]\n vapi report \"<what happened>\" [--include-addresses] [--send] [--json]\n vapi mcp [--json]\n vapi serve [--json]\n vapi version [--json]\n vapi publish [--json]\n\nWith no command, vapi shows this help. The MCP server starts only with `vapi mcp`.";
1
+ export declare const HELP = "vAPI Network\n\nUsage:\n vapi init [--networks <base,solana>] [--json]\n vapi fund [--amount <usd>] [--json]\n vapi accounts [--enable solana] [--json]\n vapi search [query] [--kind <kind>] [--network <caip2>] [--limit <n>] [--cursor <cursor>] [--json]\n vapi inspect <id> [--endpoint <name>] [--json]\n vapi pay <id-or-url> [--method <method>] [--endpoint <name>] [--body <json>] [--content-type <type>] [--network <caip2>] [--expected-pay-to <address>] [--max <amount>] [--json]\n vapi balance [--json]\n vapi receipts [--limit <n>] [--json]\n vapi receipts export --format <json|csv> [--range <24h|7d|30d>]\n vapi stats [--range <24h|7d|30d>] [--json]\n vapi sweep <address> [--network <caip2>] [--json]\n vapi export-key [--network <caip2>] [--json]\n vapi report \"<what happened>\" [--include-addresses] [--send] [--json]\n vapi mcp [--json]\n vapi serve [--json]\n vapi version [--json]\n vapi publish [--json]\n\nWith no command, vapi shows this help. The MCP server starts only with `vapi mcp`.";
2
2
  export type CliIo = {
3
3
  stdout(message: string): void;
4
4
  stderr(message: string): void;
package/dist/cli.js CHANGED
@@ -45333,8 +45333,8 @@ var DEFAULT_DISCOVERY_URL = `${DEFAULT_REGISTRY_URL}/api/call/services`;
45333
45333
  var DEFAULT_MARKETPLACE_DISCOVERY_URL = `${DEFAULT_REGISTRY_URL}/api/call/discovery`;
45334
45334
  var DEFAULT_REGISTRY_FALLBACKS = [
45335
45335
  {
45336
- discoveryUrl: "https://console.vapinetwork.ai/api/call/services",
45337
- marketplaceDiscoveryUrl: "https://console.vapinetwork.ai/api/call/discovery"
45336
+ discoveryUrl: DEFAULT_DISCOVERY_URL,
45337
+ marketplaceDiscoveryUrl: DEFAULT_MARKETPLACE_DISCOVERY_URL
45338
45338
  }
45339
45339
  ];
45340
45340
  var DEFAULT_SPEND_CAPS = {
@@ -45439,6 +45439,83 @@ async function migrateLegacyVapiHome(options = {}) {
45439
45439
  }
45440
45440
  return copied;
45441
45441
  }
45442
+ var LEGACY_REGISTRY_HOSTS = /* @__PURE__ */ new Map([
45443
+ ["console.vapinetwork.ai", "api.vapinetwork.ai"],
45444
+ ["console-staging.vapinetwork.ai", "api-staging.vapinetwork.ai"]
45445
+ ]);
45446
+ var LEGACY_REGISTRY_PATHS = /* @__PURE__ */ new Map([
45447
+ ["/api/network/services", "/api/call/services"],
45448
+ ["/api/marketplace/discovery", "/api/call/discovery"]
45449
+ ]);
45450
+ var REGISTRY_DOMAIN = "vapinetwork.ai";
45451
+ function rewriteLegacyRegistryUrl(value) {
45452
+ let url2;
45453
+ try {
45454
+ url2 = new URL(value);
45455
+ } catch {
45456
+ return value;
45457
+ }
45458
+ let rewritten = false;
45459
+ const host = LEGACY_REGISTRY_HOSTS.get(url2.hostname.toLowerCase());
45460
+ if (host) {
45461
+ url2.hostname = host;
45462
+ rewritten = true;
45463
+ }
45464
+ const hostname3 = url2.hostname.toLowerCase();
45465
+ if (hostname3 === REGISTRY_DOMAIN || hostname3.endsWith(`.${REGISTRY_DOMAIN}`)) {
45466
+ const path = LEGACY_REGISTRY_PATHS.get(url2.pathname.replace(/\/+$/, ""));
45467
+ if (path) {
45468
+ url2.pathname = path;
45469
+ rewritten = true;
45470
+ }
45471
+ }
45472
+ return rewritten ? url2.href : value;
45473
+ }
45474
+ function rewriteLegacyRegistryUrls(config2) {
45475
+ const changes = [];
45476
+ const rewrite = (field, from16) => {
45477
+ const to = rewriteLegacyRegistryUrl(from16);
45478
+ if (to !== from16) changes.push({ field, from: from16, to });
45479
+ return to;
45480
+ };
45481
+ const next = {
45482
+ ...config2,
45483
+ discoveryUrl: rewrite("discoveryUrl", config2.discoveryUrl),
45484
+ marketplaceDiscoveryUrl: rewrite("marketplaceDiscoveryUrl", config2.marketplaceDiscoveryUrl),
45485
+ ...config2.registryFallbacks ? {
45486
+ registryFallbacks: config2.registryFallbacks.map((fallback, index2) => ({
45487
+ discoveryUrl: rewrite(
45488
+ `registryFallbacks[${index2}].discoveryUrl`,
45489
+ fallback.discoveryUrl
45490
+ ),
45491
+ marketplaceDiscoveryUrl: rewrite(
45492
+ `registryFallbacks[${index2}].marketplaceDiscoveryUrl`,
45493
+ fallback.marketplaceDiscoveryUrl
45494
+ )
45495
+ }))
45496
+ } : {}
45497
+ };
45498
+ return changes.length === 0 ? { config: config2, changes } : { config: next, changes };
45499
+ }
45500
+ function formatLegacyRegistryRewrites(changes) {
45501
+ return [
45502
+ "Rewrote retired vAPI registry URLs in the local config:",
45503
+ ...changes.map((change) => ` ${change.field}: ${change.from} -> ${change.to}`)
45504
+ ].join("\n");
45505
+ }
45506
+ async function migrateLegacyRegistryConfig(path = getVapiPaths().config) {
45507
+ let raw;
45508
+ try {
45509
+ raw = await readFile(path, "utf8");
45510
+ } catch (error61) {
45511
+ if (isMissingFile(error61)) return [];
45512
+ throw error61;
45513
+ }
45514
+ const { config: config2, changes } = rewriteLegacyRegistryUrls(configSchema.parse(JSON.parse(raw)));
45515
+ if (changes.length === 0) return [];
45516
+ await writeConfigFile(path, config2);
45517
+ return changes;
45518
+ }
45442
45519
  function getDefaultConfig(source = process.env, options = {}) {
45443
45520
  const registry2 = registryEndpoints(source.VAPI_REGISTRY_URL?.trim() || DEFAULT_REGISTRY_URL);
45444
45521
  const requested = new Set(options.networks ?? ["base"]);
@@ -45477,7 +45554,7 @@ function getDefaultConfig(source = process.env, options = {}) {
45477
45554
  spendCaps: { ...DEFAULT_SPEND_CAPS }
45478
45555
  };
45479
45556
  }
45480
- async function loadConfig(path = getVapiPaths().config, source = process.env) {
45557
+ async function loadConfig(path = getVapiPaths().config, source = process.env, options = {}) {
45481
45558
  if (!process.env.VAPI_HOME?.trim() && path === getVapiPaths(join(homedir(), ".vapi")).config) {
45482
45559
  await migrateLegacyVapiHome({ targetDirectory: join(homedir(), ".vapi") });
45483
45560
  }
@@ -45488,8 +45565,16 @@ async function loadConfig(path = getVapiPaths().config, source = process.env) {
45488
45565
  if (isMissingFile(error61)) return getDefaultConfig(source);
45489
45566
  throw error61;
45490
45567
  }
45491
- const config2 = configSchema.parse(JSON.parse(raw));
45492
- config2.registryFallbacks ??= DEFAULT_REGISTRY_FALLBACKS.map((fallback) => ({ ...fallback }));
45568
+ const parsed = configSchema.parse(JSON.parse(raw));
45569
+ parsed.registryFallbacks ??= DEFAULT_REGISTRY_FALLBACKS.map((fallback) => ({ ...fallback }));
45570
+ const migrated = rewriteLegacyRegistryUrls(parsed);
45571
+ const config2 = migrated.config;
45572
+ if (migrated.changes.length > 0 && options.notice) {
45573
+ options.notice(
45574
+ `${formatLegacyRegistryRewrites(migrated.changes)}
45575
+ Run vapi init to write the new URLs to ${path}.`
45576
+ );
45577
+ }
45493
45578
  const baseRpcUrl = source.BASE_RPC_URL?.trim();
45494
45579
  const arcRpcUrl = source.ARC_TESTNET_RPC_URL?.trim();
45495
45580
  const solanaRpcUrl = source.SOLANA_RPC_URL?.trim();
@@ -45545,15 +45630,7 @@ async function writeDefaultConfig(path = getVapiPaths().config, source = process
45545
45630
  if (copied.includes(path)) return await loadConfig(path, source);
45546
45631
  }
45547
45632
  const config2 = getDefaultConfig(source, options);
45548
- await mkdir(dirname(path), { recursive: true, mode: 448 });
45549
- const temporaryPath = `${path}.${process.pid}.tmp`;
45550
- await writeFile(temporaryPath, `${JSON.stringify(config2, null, 2)}
45551
- `, {
45552
- encoding: "utf8",
45553
- mode: 384,
45554
- flag: "wx"
45555
- });
45556
- await rename(temporaryPath, path);
45633
+ await writeConfigFile(path, config2);
45557
45634
  return config2;
45558
45635
  }
45559
45636
  async function enableDefaultNetwork(network, path = getVapiPaths().config, source = process.env) {
@@ -45564,6 +45641,10 @@ async function enableDefaultNetwork(network, path = getVapiPaths().config, sourc
45564
45641
  usdc: NETWORKS[SOLANA_MAINNET_CAIP2].usdc
45565
45642
  };
45566
45643
  }
45644
+ await writeConfigFile(path, config2);
45645
+ return config2;
45646
+ }
45647
+ async function writeConfigFile(path, config2) {
45567
45648
  await mkdir(dirname(path), { recursive: true, mode: 448 });
45568
45649
  const temporaryPath = `${path}.${process.pid}.tmp`;
45569
45650
  await writeFile(temporaryPath, `${JSON.stringify(config2, null, 2)}
@@ -45573,7 +45654,6 @@ async function enableDefaultNetwork(network, path = getVapiPaths().config, sourc
45573
45654
  flag: "wx"
45574
45655
  });
45575
45656
  await rename(temporaryPath, path);
45576
- return config2;
45577
45657
  }
45578
45658
  async function pathExists(path) {
45579
45659
  try {
@@ -45994,6 +46074,49 @@ async function unlockKeystore(passphrase, path = getVapiPaths().keystore) {
45994
46074
  }
45995
46075
  return await paymentAccountFromKeys(keys);
45996
46076
  }
46077
+ async function readKeystoreAddress(path = getVapiPaths().keystore) {
46078
+ let raw;
46079
+ try {
46080
+ raw = await readFile3(path, "utf8");
46081
+ } catch {
46082
+ return void 0;
46083
+ }
46084
+ let parsed;
46085
+ try {
46086
+ parsed = JSON.parse(raw);
46087
+ } catch {
46088
+ return void 0;
46089
+ }
46090
+ const address2 = typeof parsed === "object" && parsed !== null ? Reflect.get(parsed, "address") : void 0;
46091
+ return typeof address2 === "string" ? address2 : void 0;
46092
+ }
46093
+ async function exportKeystoreKeys(passphrase, path = getVapiPaths().keystore) {
46094
+ let raw;
46095
+ try {
46096
+ raw = await readFile3(path, "utf8");
46097
+ } catch (error61) {
46098
+ if (isMissingFile(error61)) {
46099
+ throw new KeystoreError(`No vAPI keystore found at ${path}. Run vapi init.`);
46100
+ }
46101
+ throw error61;
46102
+ }
46103
+ const keys = await decryptKeys(parseAnyKeystore(JSON.parse(raw)), passphrase);
46104
+ const evmPrivateKey = keys.evm;
46105
+ const exported = {
46106
+ evm: { address: privateKeyToAccount(evmPrivateKey).address, privateKey: evmPrivateKey }
46107
+ };
46108
+ if (!keys.solana) return exported;
46109
+ const seed = Uint8Array.from(Buffer.from(keys.solana, "base64"));
46110
+ const signer = await createSolanaSigner(Uint8Array.from(seed));
46111
+ const publicKey = Uint8Array.from(getBase58Encoder().encode(signer.address));
46112
+ const secretKey = new Uint8Array(seed.length + publicKey.length);
46113
+ secretKey.set(seed);
46114
+ secretKey.set(publicKey, seed.length);
46115
+ const encoded = getBase58Decoder().decode(secretKey);
46116
+ seed.fill(0);
46117
+ secretKey.fill(0);
46118
+ return { ...exported, solana: { address: signer.address, secretKey: encoded } };
46119
+ }
45997
46120
  async function enableSolanaKey(passphrase, path = getVapiPaths().keystore) {
45998
46121
  let raw;
45999
46122
  try {
@@ -46673,7 +46796,7 @@ function csvCell(value) {
46673
46796
  import { mkdir as mkdir6, writeFile as writeFile4 } from "node:fs/promises";
46674
46797
  import { arch, platform, release } from "node:os";
46675
46798
  import { join as join2 } from "node:path";
46676
- var VAPI_CLIENT_VERSION = "0.2.2";
46799
+ var VAPI_CLIENT_VERSION = "0.2.3";
46677
46800
  async function createSupportReport(options) {
46678
46801
  const message = options.message.trim();
46679
46802
  if (!message) throw new Error("Support report message must not be empty.");
@@ -48966,7 +49089,7 @@ function rgbToAnsi256(red, green, blue) {
48966
49089
  }
48967
49090
 
48968
49091
  // src/version.ts
48969
- var CLI_VERSION = "0.2.2";
49092
+ var CLI_VERSION = "0.2.3";
48970
49093
 
48971
49094
  // src/cli.ts
48972
49095
  var HELP_HEADING = "vAPI Network";
@@ -48984,6 +49107,7 @@ Usage:
48984
49107
  vapi receipts export --format <json|csv> [--range <24h|7d|30d>]
48985
49108
  vapi stats [--range <24h|7d|30d>] [--json]
48986
49109
  vapi sweep <address> [--network <caip2>] [--json]
49110
+ vapi export-key [--network <caip2>] [--json]
48987
49111
  vapi report "<what happened>" [--include-addresses] [--send] [--json]
48988
49112
  vapi mcp [--json]
48989
49113
  vapi serve [--json]
@@ -49052,6 +49176,9 @@ async function runCli(argv = process.argv.slice(2), io = processIo, dependencies
49052
49176
  case "sweep":
49053
49177
  await sweepCommand(args.slice(1), json2, io);
49054
49178
  return 0;
49179
+ case "export-key":
49180
+ await exportKeyCommand(args.slice(1), json2, io);
49181
+ return 0;
49055
49182
  case "report":
49056
49183
  await reportCommand(args.slice(1), json2, io, dependencies);
49057
49184
  return 0;
@@ -49091,8 +49218,18 @@ async function initCommand(argv, json2, io, dependencies) {
49091
49218
  if (!process.env.VAPI_HOME?.trim()) {
49092
49219
  migrated = await migrateLegacyVapiHome({ targetDirectory: paths.directory, notice: io.stderr });
49093
49220
  }
49221
+ const adopted = migrated.includes(paths.keystore);
49222
+ if (!adopted && await fileExists(paths.keystore)) {
49223
+ const address2 = await readKeystoreAddress(paths.keystore);
49224
+ throw new Error(
49225
+ [
49226
+ `Keystore already exists at ${paths.keystore}. Refusing to replace the local payment key.`,
49227
+ ...address2 ? [`Address: ${address2}`] : []
49228
+ ].join("\n")
49229
+ );
49230
+ }
49094
49231
  const passphrase = await getKeystorePassphrase({ confirm: true });
49095
- let account = migrated.includes(paths.keystore) ? await unlockKeystore(passphrase, paths.keystore) : await createKeystore(passphrase, paths.keystore, { enableSolana });
49232
+ let account = adopted ? await unlockKeystore(passphrase, paths.keystore) : await createKeystore(passphrase, paths.keystore, { enableSolana });
49096
49233
  if (enableSolana && !account.solana) {
49097
49234
  account = await enableSolanaKey(passphrase, paths.keystore);
49098
49235
  }
@@ -49101,7 +49238,8 @@ async function initCommand(argv, json2, io, dependencies) {
49101
49238
  } else if (enableSolana) {
49102
49239
  await enableDefaultNetwork("solana", paths.config);
49103
49240
  }
49104
- const config2 = await loadConfig(paths.config);
49241
+ const configRewrites = await migrateLegacyRegistryConfig(paths.config);
49242
+ const config2 = await readConfig(paths.config, io);
49105
49243
  const accounts = await listAccounts({
49106
49244
  address: account.address,
49107
49245
  ...account.solana ? { solanaAddress: account.solana.address } : {},
@@ -49113,6 +49251,7 @@ async function initCommand(argv, json2, io, dependencies) {
49113
49251
  accounts,
49114
49252
  config: paths.config,
49115
49253
  keystore: paths.keystore,
49254
+ ...configRewrites.length > 0 ? { configRewrites } : {},
49116
49255
  message: "vAPI wallet created. Its encrypted key stays on this machine.",
49117
49256
  nextSteps: buildNextSteps(account.address)
49118
49257
  };
@@ -49120,6 +49259,7 @@ async function initCommand(argv, json2, io, dependencies) {
49120
49259
  io.stdout(JSON.stringify(result));
49121
49260
  return;
49122
49261
  }
49262
+ if (configRewrites.length > 0) io.stdout(formatLegacyRegistryRewrites(configRewrites));
49123
49263
  io.stdout(result.message);
49124
49264
  io.stdout(`Address: ${result.address}`);
49125
49265
  io.stdout(
@@ -49144,7 +49284,7 @@ async function fundCommand(argv, json2, io, dependencies) {
49144
49284
  });
49145
49285
  const fiatAmount = optionalUsdAmount(parsed.one("--amount"), "--amount");
49146
49286
  const paths = getVapiPaths();
49147
- const config2 = await loadConfig(paths.config);
49287
+ const config2 = await readConfig(paths.config, io);
49148
49288
  const account = await unlockKeystore(await getKeystorePassphrase(), paths.keystore);
49149
49289
  const session = await createOnrampSession({
49150
49290
  address: account.address,
@@ -49164,7 +49304,7 @@ async function searchCommand(argv, json2, io, dependencies) {
49164
49304
  maximumPositionals: 1
49165
49305
  });
49166
49306
  const limit = optionalPositiveInteger(parsed.one("--limit"), "--limit");
49167
- const config2 = await loadConfig(getVapiPaths().config);
49307
+ const config2 = await readConfig(getVapiPaths().config, io);
49168
49308
  const page = await searchMarketplace(
49169
49309
  {
49170
49310
  ...parsed.positionals[0] ? { query: parsed.positionals[0] } : {},
@@ -49188,7 +49328,7 @@ async function inspectCommand(argv, json2, io, dependencies) {
49188
49328
  parsed.positionals[0],
49189
49329
  "Usage: vapi inspect <id> [--endpoint <name>]"
49190
49330
  );
49191
- const config2 = await loadConfig(getVapiPaths().config);
49331
+ const config2 = await readConfig(getVapiPaths().config, io);
49192
49332
  const result = await inspectService(
49193
49333
  { id, ...parsed.one("--endpoint") ? { endpoint: parsed.one("--endpoint") } : {} },
49194
49334
  config2,
@@ -49212,7 +49352,7 @@ async function payCommand(argv, json2, io) {
49212
49352
  });
49213
49353
  const target = requiredPositional(parsed.positionals[0], "Usage: vapi pay <id-or-url> [options]");
49214
49354
  const paths = getVapiPaths();
49215
- const config2 = await loadConfig(paths.config);
49355
+ const config2 = await readConfig(paths.config, io);
49216
49356
  const account = await unlockKeystore(await getKeystorePassphrase(), paths.keystore);
49217
49357
  const bodyText = parsed.one("--body");
49218
49358
  const maxPriceUsd = aliasedOption(parsed, "--max", "--max-price-usd");
@@ -49238,7 +49378,7 @@ async function payCommand(argv, json2, io) {
49238
49378
  async function balanceCommand(argv, json2, io, dependencies) {
49239
49379
  requireNoArguments(argv, "balance");
49240
49380
  const paths = getVapiPaths();
49241
- const config2 = await loadConfig(paths.config);
49381
+ const config2 = await readConfig(paths.config, io);
49242
49382
  const account = await unlockKeystore(await getKeystorePassphrase(), paths.keystore);
49243
49383
  const wallet = await getWallet(account, config2, dependencies);
49244
49384
  output2(io, json2, wallet, formatWallet(wallet));
@@ -49256,7 +49396,7 @@ async function accountsCommand(argv, json2, io, dependencies) {
49256
49396
  const passphrase = await getKeystorePassphrase();
49257
49397
  const account = enable ? await enableSolanaKey(passphrase, paths.keystore) : await unlockKeystore(passphrase, paths.keystore);
49258
49398
  if (enable) await enableDefaultNetwork("solana", paths.config);
49259
- const config2 = await loadConfig(paths.config);
49399
+ const config2 = await readConfig(paths.config, io);
49260
49400
  const accounts = await listAccounts({
49261
49401
  address: account.address,
49262
49402
  ...account.solana ? { solanaAddress: account.solana.address } : {},
@@ -49325,7 +49465,7 @@ async function sweepCommand(argv, json2, io) {
49325
49465
  );
49326
49466
  const requestedNetwork = parsed.one("--network");
49327
49467
  const paths = getVapiPaths();
49328
- const config2 = await loadConfig(paths.config);
49468
+ const config2 = await readConfig(paths.config, io);
49329
49469
  const account = await unlockKeystore(await getKeystorePassphrase(), paths.keystore);
49330
49470
  if (requestedNetwork && !isNetworkConfigured(config2.networks, requestedNetwork)) {
49331
49471
  throw new Error(`Network ${requestedNetwork} is not configured.`);
@@ -49369,6 +49509,33 @@ async function reportCommand(argv, json2, io, dependencies) {
49369
49509
  });
49370
49510
  output2(io, json2, result, formatSupportReport(result));
49371
49511
  }
49512
+ var EXPORT_KEY_WARNING = "Anyone with this key can spend the wallet. Never paste it into a website or chat.";
49513
+ async function exportKeyCommand(argv, json2, io) {
49514
+ const parsed = parseArguments(argv, {
49515
+ valueOptions: /* @__PURE__ */ new Set(["--network"]),
49516
+ maximumPositionals: 0
49517
+ });
49518
+ const network = parsed.one("--network") ?? BASE_MAINNET_CAIP2;
49519
+ const solana = isSolanaNetwork(network);
49520
+ if (!solana && !network.startsWith("eip155:")) {
49521
+ throw new UsageError("--network must be an eip155:<chainId> or Solana network identifier.");
49522
+ }
49523
+ const paths = getVapiPaths();
49524
+ const keys = await exportKeystoreKeys(await getKeystorePassphrase(), paths.keystore);
49525
+ if (solana && !keys.solana) {
49526
+ throw new Error(
49527
+ `No Solana key is enabled in ${paths.keystore}. Run vapi accounts --enable solana first.`
49528
+ );
49529
+ }
49530
+ const selected = solana && keys.solana ? keys.solana : keys.evm;
49531
+ const result = {
49532
+ network,
49533
+ address: selected.address,
49534
+ privateKey: "secretKey" in selected ? selected.secretKey : selected.privateKey
49535
+ };
49536
+ io.stderr(EXPORT_KEY_WARNING);
49537
+ io.stdout(json2 ? JSON.stringify(result) : result.privateKey);
49538
+ }
49372
49539
  async function mcpCommand(argv) {
49373
49540
  requireNoArguments(argv, "mcp");
49374
49541
  const paths = getVapiPaths();
@@ -49382,6 +49549,9 @@ async function mcpCommand(argv) {
49382
49549
  searchesPath: paths.searches
49383
49550
  });
49384
49551
  }
49552
+ async function readConfig(path, io) {
49553
+ return await loadConfig(path, process.env, { notice: io.stderr });
49554
+ }
49385
49555
  function output2(io, json2, value, human) {
49386
49556
  io.stdout(json2 ? JSON.stringify(value) : human);
49387
49557
  }