@bnbagent/studio-cli 0.0.6-alpha.5 → 0.0.6-alpha.6

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/bag.js CHANGED
@@ -2722,6 +2722,11 @@ function client(networkName) {
2722
2722
  const net2 = getNetwork(networkName);
2723
2723
  return createPublicClient({ transport: http(net2.rpcUrl) });
2724
2724
  }
2725
+ async function readChainIdAt(rpcUrl) {
2726
+ return createPublicClient({
2727
+ transport: http(rpcUrl, { retryCount: 0, timeout: 5e3 })
2728
+ }).getChainId();
2729
+ }
2725
2730
  async function readNativeBalanceRaw(address, networkName) {
2726
2731
  return client(networkName).getBalance({
2727
2732
  address: getAddress(address)
@@ -3192,44 +3197,6 @@ function relocateKeys(src, target, label) {
3192
3197
  return true;
3193
3198
  }
3194
3199
 
3195
- // src/cli/_twakContractTargets.ts
3196
- import { resolveNetwork } from "@bnbagent/sdk";
3197
- var CONTRACT_OVERRIDES = [
3198
- ["ERC8004_REGISTRY_ADDRESS", "registryContract"],
3199
- ["ERC8183_COMMERCE_ADDRESS", "commerceContract"],
3200
- ["ERC8183_ROUTER_ADDRESS", "routerContract"],
3201
- ["ERC8183_POLICY_ADDRESS", "policyContract"]
3202
- ];
3203
- function twakCustomContractOverrides(networkName, env = process.env) {
3204
- let network;
3205
- try {
3206
- network = resolveNetwork(networkName);
3207
- } catch {
3208
- return [];
3209
- }
3210
- const erc8183 = erc8183ContractOverrideState(env);
3211
- const out = [];
3212
- for (const [envKey, field] of CONTRACT_OVERRIDES) {
3213
- if (envKey.startsWith("ERC8183_") && erc8183.mode !== "custom") {
3214
- continue;
3215
- }
3216
- const configured = env[envKey]?.trim() ?? "";
3217
- if (!/^0x[0-9a-fA-F]{40}$/u.test(configured)) {
3218
- continue;
3219
- }
3220
- const canonical = network[field];
3221
- if (configured.toLowerCase() !== canonical.toLowerCase()) {
3222
- out.push({ envKey, configured, canonical });
3223
- }
3224
- }
3225
- return out;
3226
- }
3227
- function twakUnsupportedContractOverrides(networkName, env = process.env) {
3228
- return twakCustomContractOverrides(networkName, env).filter(
3229
- (item) => item.envKey.startsWith("ERC8183_")
3230
- );
3231
- }
3232
-
3233
3200
  // src/cli/init.ts
3234
3201
  import * as fs23 from "fs";
3235
3202
  import * as os4 from "os";
@@ -3498,6 +3465,46 @@ import * as fs15 from "fs";
3498
3465
  import * as path14 from "path";
3499
3466
  import { envLocalPath as envLocalPath7 } from "@bnbagent/studio-runtime/config";
3500
3467
  import { resolveTwakHome } from "@bnbagent/studio-runtime/wallet";
3468
+
3469
+ // src/cli/_twakContractTargets.ts
3470
+ import { resolveNetwork } from "@bnbagent/sdk";
3471
+ var CONTRACT_OVERRIDES = [
3472
+ ["ERC8004_REGISTRY_ADDRESS", "registryContract"],
3473
+ ["ERC8183_COMMERCE_ADDRESS", "commerceContract"],
3474
+ ["ERC8183_ROUTER_ADDRESS", "routerContract"],
3475
+ ["ERC8183_POLICY_ADDRESS", "policyContract"]
3476
+ ];
3477
+ function twakCustomContractOverrides(networkName, env = process.env) {
3478
+ let network;
3479
+ try {
3480
+ network = resolveNetwork(networkName);
3481
+ } catch {
3482
+ return [];
3483
+ }
3484
+ const erc8183 = erc8183ContractOverrideState(env);
3485
+ const out = [];
3486
+ for (const [envKey, field] of CONTRACT_OVERRIDES) {
3487
+ if (envKey.startsWith("ERC8183_") && erc8183.mode !== "custom") {
3488
+ continue;
3489
+ }
3490
+ const configured = env[envKey]?.trim() ?? "";
3491
+ if (!/^0x[0-9a-fA-F]{40}$/u.test(configured)) {
3492
+ continue;
3493
+ }
3494
+ const canonical = network[field];
3495
+ if (configured.toLowerCase() !== canonical.toLowerCase()) {
3496
+ out.push({ envKey, configured, canonical });
3497
+ }
3498
+ }
3499
+ return out;
3500
+ }
3501
+ function twakUnsupportedContractOverrides(networkName, env = process.env) {
3502
+ return twakCustomContractOverrides(networkName, env).filter(
3503
+ (item) => item.envKey.startsWith("ERC8183_")
3504
+ );
3505
+ }
3506
+
3507
+ // src/cli/_deploy/checks/twak.ts
3501
3508
  var AGENTCORE_DESCRIPTOR = path14.join("agentcore", "agentcore.json");
3502
3509
  function isTwak(data) {
3503
3510
  return tableOf2(data, "wallet").kind === "twak";
@@ -9858,6 +9865,57 @@ function isDir4(p) {
9858
9865
  }
9859
9866
  }
9860
9867
 
9868
+ // src/cli/_runtimeEnvKeys.ts
9869
+ function tableOf8(cfg, key) {
9870
+ const v = cfg[key];
9871
+ return v !== null && typeof v === "object" && !Array.isArray(v) ? v : {};
9872
+ }
9873
+ function runtimeEnvKeysCore(cfg, resolvable) {
9874
+ const walletKind2 = tableOf8(cfg, "wallet").kind ?? "evm-local";
9875
+ let keys;
9876
+ if (walletKind2 === "twak") {
9877
+ keys = ["TWAK_WALLET_PASSWORD"];
9878
+ for (const k of ["TWAK_ACCESS_ID", "TWAK_HMAC_SECRET"]) {
9879
+ if (resolvable(k)) {
9880
+ keys.push(k);
9881
+ }
9882
+ }
9883
+ } else if (walletKind2 === "altana") {
9884
+ keys = [];
9885
+ } else {
9886
+ keys = ["WALLET_PASSWORD"];
9887
+ }
9888
+ const provider = tableOf8(cfg, "llm").provider;
9889
+ const providerKey = typeof provider === "string" ? PROVIDER_KEY_ENV[provider] : null;
9890
+ if (providerKey) {
9891
+ keys.push(providerKey);
9892
+ }
9893
+ const storageKind2 = String(
9894
+ tableOf8(cfg, "storage").kind ?? "local"
9895
+ ).toLowerCase();
9896
+ if (storageKind2 === "ipfs") {
9897
+ keys.push("STORAGE_API_URL");
9898
+ if (resolvable("STORAGE_API_KEY")) {
9899
+ keys.push("STORAGE_API_KEY");
9900
+ }
9901
+ }
9902
+ if (resolvable("RPC_URL")) {
9903
+ keys.push("RPC_URL");
9904
+ }
9905
+ if (commerceRails(cfg).erc8183) {
9906
+ for (const key of ERC8183_ADDRESS_OVERRIDE_KEYS) {
9907
+ if (resolvable(key)) keys.push(key);
9908
+ }
9909
+ }
9910
+ const runtime = String(tableOf8(cfg, "stack").runtime ?? "agentcore");
9911
+ if (runtime === "agentcore" && x402SellerUsesB402(cfg)) {
9912
+ for (const key of B402_RUNTIME_KEYS) {
9913
+ if (resolvable(key)) keys.push(key);
9914
+ }
9915
+ }
9916
+ return keys;
9917
+ }
9918
+
9861
9919
  // src/cli/dev.ts
9862
9920
  var DEFAULT_AGENT_HOST = "127.0.0.1";
9863
9921
  var AGENTCORE_BIN = "agentcore";
@@ -9944,17 +10002,17 @@ function loadAgentToml2(workspaceRoot) {
9944
10002
  return {};
9945
10003
  }
9946
10004
  }
9947
- function tableOf8(data, key) {
10005
+ function tableOf9(data, key) {
9948
10006
  const v = data[key];
9949
10007
  return v !== null && typeof v === "object" && !Array.isArray(v) ? v : {};
9950
10008
  }
9951
10009
  function agentRuntime(workspaceRoot) {
9952
- const runtime = tableOf8(loadAgentToml2(workspaceRoot), "stack").runtime;
10010
+ const runtime = tableOf9(loadAgentToml2(workspaceRoot), "stack").runtime;
9953
10011
  return typeof runtime === "string" && runtime.trim() ? runtime.trim() : RUNTIME_AGENTCORE;
9954
10012
  }
9955
10013
  function agentFaces(workspaceRoot) {
9956
10014
  const cfg = loadAgentToml2(workspaceRoot);
9957
- return stackFaces(tableOf8(cfg, "stack"), tableOf8(cfg, "payments"));
10015
+ return stackFaces(tableOf9(cfg, "stack"), tableOf9(cfg, "payments"));
9958
10016
  }
9959
10017
  function localEntryFile(faces) {
9960
10018
  return `src/${entryStemOf(faces)}.ts`;
@@ -9969,7 +10027,7 @@ function storageKind(agentDir) {
9969
10027
  } catch {
9970
10028
  return "local";
9971
10029
  }
9972
- const kind = tableOf8(data, "storage").kind;
10030
+ const kind = tableOf9(data, "storage").kind;
9973
10031
  return typeof kind === "string" && kind.trim() ? kind.trim() : "local";
9974
10032
  }
9975
10033
  function networkNameOf(agentDir) {
@@ -9979,7 +10037,7 @@ function networkNameOf(agentDir) {
9979
10037
  } catch {
9980
10038
  return "bsc-testnet";
9981
10039
  }
9982
- const name = tableOf8(data, "network").default;
10040
+ const name = tableOf9(data, "network").default;
9983
10041
  return typeof name === "string" && name.trim() ? name.trim() : "bsc-testnet";
9984
10042
  }
9985
10043
  function walletKindOf(agentDir) {
@@ -9989,12 +10047,12 @@ function walletKindOf(agentDir) {
9989
10047
  } catch {
9990
10048
  return "evm-local";
9991
10049
  }
9992
- const kind = tableOf8(data, "wallet").kind;
10050
+ const kind = tableOf9(data, "wallet").kind;
9993
10051
  return typeof kind === "string" && kind.trim() ? kind.trim() : "evm-local";
9994
10052
  }
9995
10053
  function altanaSessionForRuntime(agentDir) {
9996
10054
  const cfg = loadStudioToml11(path23.join(agentDir, "studio.toml"));
9997
- const wallet = tableOf8(cfg, "wallet");
10055
+ const wallet = tableOf9(cfg, "wallet");
9998
10056
  const configured = String(
9999
10057
  wallet.session_file ?? ".studio/wallets/altana-session.json"
10000
10058
  );
@@ -10089,48 +10147,7 @@ function runtimeEnvKeys(agentDir) {
10089
10147
  } catch {
10090
10148
  cfg = {};
10091
10149
  }
10092
- const resolvable = (key) => Boolean(process.env[key]);
10093
- const kind = tableOf8(cfg, "wallet").kind;
10094
- let keys;
10095
- if (kind === "twak") {
10096
- keys = ["TWAK_WALLET_PASSWORD"];
10097
- for (const k of ["TWAK_ACCESS_ID", "TWAK_HMAC_SECRET"]) {
10098
- if (resolvable(k)) {
10099
- keys.push(k);
10100
- }
10101
- }
10102
- } else if (kind === "altana") {
10103
- keys = [];
10104
- } else {
10105
- keys = ["WALLET_PASSWORD"];
10106
- }
10107
- const provider = tableOf8(cfg, "llm").provider;
10108
- const providerKey = typeof provider === "string" ? PROVIDER_KEY_ENV[provider] : null;
10109
- if (providerKey) {
10110
- keys.push(providerKey);
10111
- }
10112
- const sk = String(tableOf8(cfg, "storage").kind ?? "local").toLowerCase();
10113
- if (sk === "ipfs") {
10114
- keys.push("STORAGE_API_URL");
10115
- if (resolvable("STORAGE_API_KEY")) {
10116
- keys.push("STORAGE_API_KEY");
10117
- }
10118
- }
10119
- if (resolvable("RPC_URL")) {
10120
- keys.push("RPC_URL");
10121
- }
10122
- if (commerceRails(cfg).erc8183) {
10123
- for (const key of ERC8183_ADDRESS_OVERRIDE_KEYS) {
10124
- if (resolvable(key)) keys.push(key);
10125
- }
10126
- }
10127
- const runtime = String(tableOf8(cfg, "stack").runtime ?? "agentcore");
10128
- if (runtime === "agentcore" && x402SellerUsesB402(cfg)) {
10129
- for (const key of B402_RUNTIME_KEYS) {
10130
- if (resolvable(key)) keys.push(key);
10131
- }
10132
- }
10133
- return keys;
10150
+ return runtimeEnvKeysCore(cfg, (key) => Boolean(process.env[key]));
10134
10151
  }
10135
10152
  function compactJson(text2) {
10136
10153
  try {
@@ -10142,7 +10159,7 @@ function compactJson(text2) {
10142
10159
  function readTwakFiles(agentDir) {
10143
10160
  let walletCfg = {};
10144
10161
  try {
10145
- walletCfg = tableOf8(
10162
+ walletCfg = tableOf9(
10146
10163
  loadStudioToml11(path23.join(agentDir, "studio.toml")),
10147
10164
  "wallet"
10148
10165
  );
@@ -10552,7 +10569,7 @@ function networkBanner(agentDir) {
10552
10569
  } catch {
10553
10570
  return null;
10554
10571
  }
10555
- const name = tableOf8(data, "network").default;
10572
+ const name = tableOf9(data, "network").default;
10556
10573
  if (typeof name !== "string" || !name.trim()) {
10557
10574
  return null;
10558
10575
  }
@@ -10605,49 +10622,7 @@ function runtimeEnvKeys2(agentRoot2) {
10605
10622
  cfg = {};
10606
10623
  }
10607
10624
  const resolvable = (key) => Boolean(process.env[key] || getEnvVar(envLocalPath11(agentRoot2), key));
10608
- const walletKind2 = tableOf2(cfg, "wallet").kind ?? "evm-local";
10609
- let keys;
10610
- if (walletKind2 === "twak") {
10611
- keys = ["TWAK_WALLET_PASSWORD"];
10612
- for (const k of ["TWAK_ACCESS_ID", "TWAK_HMAC_SECRET"]) {
10613
- if (resolvable(k)) {
10614
- keys.push(k);
10615
- }
10616
- }
10617
- } else if (walletKind2 === "altana") {
10618
- keys = [];
10619
- } else {
10620
- keys = ["WALLET_PASSWORD"];
10621
- }
10622
- const provider = tableOf2(cfg, "llm").provider;
10623
- const providerKey = typeof provider === "string" ? PROVIDER_KEY_ENV[provider] : null;
10624
- if (providerKey) {
10625
- keys.push(providerKey);
10626
- }
10627
- const storageKind2 = String(
10628
- tableOf2(cfg, "storage").kind ?? "local"
10629
- ).toLowerCase();
10630
- if (storageKind2 === "ipfs") {
10631
- keys.push("STORAGE_API_URL");
10632
- if (resolvable("STORAGE_API_KEY")) {
10633
- keys.push("STORAGE_API_KEY");
10634
- }
10635
- }
10636
- if (resolvable("RPC_URL")) {
10637
- keys.push("RPC_URL");
10638
- }
10639
- if (commerceRails(cfg).erc8183) {
10640
- for (const key of ERC8183_ADDRESS_OVERRIDE_KEYS) {
10641
- if (resolvable(key)) keys.push(key);
10642
- }
10643
- }
10644
- const runtime = String(tableOf2(cfg, "stack").runtime ?? "agentcore");
10645
- if (runtime === "agentcore" && x402SellerUsesB402(cfg)) {
10646
- for (const key of B402_RUNTIME_KEYS) {
10647
- if (resolvable(key)) keys.push(key);
10648
- }
10649
- }
10650
- return keys;
10625
+ return runtimeEnvKeysCore(cfg, resolvable);
10651
10626
  }
10652
10627
  var require2 = createRequire(import.meta.url);
10653
10628
  async function checkAgentcoreJsonPresent(root, target) {
@@ -11436,17 +11411,17 @@ function loadTomlOr(agentRoot2) {
11436
11411
  return {};
11437
11412
  }
11438
11413
  }
11439
- function tableOf9(cfg, key) {
11414
+ function tableOf10(cfg, key) {
11440
11415
  const v = cfg[key];
11441
11416
  return v !== null && typeof v === "object" && !Array.isArray(v) ? v : {};
11442
11417
  }
11443
11418
  function deployWalletKind(agentRoot2) {
11444
- const kind = tableOf9(loadTomlOr(agentRoot2), "wallet").kind;
11419
+ const kind = tableOf10(loadTomlOr(agentRoot2), "wallet").kind;
11445
11420
  return kind ? String(kind) : "evm-local";
11446
11421
  }
11447
11422
  function resolveKeystoreDir3(agentRoot2) {
11448
11423
  const rel = String(
11449
- tableOf9(loadTomlOr(agentRoot2), "wallet").keystore_dir ?? ".studio/wallets"
11424
+ tableOf10(loadTomlOr(agentRoot2), "wallet").keystore_dir ?? ".studio/wallets"
11450
11425
  );
11451
11426
  return path25.resolve(path25.isAbsolute(rel) ? rel : path25.join(agentRoot2, rel));
11452
11427
  }
@@ -11461,7 +11436,7 @@ function readKeystoreJson(agentRoot2) {
11461
11436
  if (names.length === 0) {
11462
11437
  return null;
11463
11438
  }
11464
- const address = tableOf9(loadTomlOr(agentRoot2), "wallet").address;
11439
+ const address = tableOf10(loadTomlOr(agentRoot2), "wallet").address;
11465
11440
  let chosen = null;
11466
11441
  if (typeof address === "string" && address) {
11467
11442
  for (const n of names) {
@@ -12503,7 +12478,7 @@ import * as fs33 from "fs";
12503
12478
  import * as path32 from "path";
12504
12479
  import { envLocalPath as envLocalPath14 } from "@bnbagent/studio-runtime/config";
12505
12480
  import { show } from "@bnbagent/studio-runtime/erc8004";
12506
- import { getNetwork as getNetwork8 } from "@bnbagent/studio-runtime/networks";
12481
+ import { DEFAULT_RPC, getNetwork as getNetwork8 } from "@bnbagent/studio-runtime/networks";
12507
12482
  import * as walletRt3 from "@bnbagent/studio-runtime/wallet";
12508
12483
  var TBNB_MIN_WEI = 7n * 10n ** 15n;
12509
12484
  function isFile13(p) {
@@ -12665,6 +12640,51 @@ async function checkRpcUrlSetForRuntime(root, _target) {
12665
12640
  }
12666
12641
  ];
12667
12642
  }
12643
+ async function checkRuntimeRpcReachable(root, _target) {
12644
+ const netName = tableOf2(loadAgentToml(root), "network").default;
12645
+ if (!netName || typeof netName !== "string") {
12646
+ return [];
12647
+ }
12648
+ const expected = getNetwork8(netName).chainId;
12649
+ const configured = process.env.RPC_URL || getEnvVar(envLocalPath14(root), "RPC_URL") || "";
12650
+ const rpcUrl = configured || DEFAULT_RPC[netName] || "";
12651
+ if (!rpcUrl) {
12652
+ return [];
12653
+ }
12654
+ const source = configured ? "RPC_URL" : "the runtime default";
12655
+ let actual;
12656
+ try {
12657
+ actual = await readChainIdAt(rpcUrl);
12658
+ } catch (exc) {
12659
+ return [
12660
+ {
12661
+ level: Level.WARNING,
12662
+ name: "runtime_rpc_reachable",
12663
+ message: `the RPC endpoint the deployed runtime will use (${rpcUrl}, from ${source}) did not answer eth_chainId (${exc instanceof Error ? exc.message.split("\n")[0] : String(exc)}). The seller's first chain read (e.g. notify_funded verification) will fail in the cloud until a working endpoint is set.`,
12664
+ fixCmd: "bag env set RPC_URL <working-endpoint>",
12665
+ details: { rpc_url: rpcUrl, source, network: netName }
12666
+ }
12667
+ ];
12668
+ }
12669
+ if (actual !== expected) {
12670
+ return [
12671
+ {
12672
+ level: Level.WARNING,
12673
+ name: "runtime_rpc_reachable",
12674
+ message: `the RPC endpoint the deployed runtime will use (${rpcUrl}, from ${source}) answered chain_id=${actual}; expected ${expected} for ${netName}.`,
12675
+ fixCmd: "bag env set RPC_URL <endpoint-on-the-right-chain>",
12676
+ details: {
12677
+ rpc_url: rpcUrl,
12678
+ source,
12679
+ network: netName,
12680
+ expected,
12681
+ actual
12682
+ }
12683
+ }
12684
+ ];
12685
+ }
12686
+ return [];
12687
+ }
12668
12688
  async function checkInstalledRecipesUnchanged(root, _target) {
12669
12689
  const manifest = path32.join(root, ".studio", "recipes", "manifest.json");
12670
12690
  let data;
@@ -12780,6 +12800,7 @@ var allChecks4 = [
12780
12800
  checkAgentUriDataUriOrHttps,
12781
12801
  checkNetworkMatchesChainId,
12782
12802
  checkRpcUrlSetForRuntime,
12803
+ checkRuntimeRpcReachable,
12783
12804
  checkInstalledRecipesUnchanged,
12784
12805
  checkCognitoAuthorizerConfigured,
12785
12806
  checkStorageLocalNotDeployable
@@ -12787,7 +12808,7 @@ var allChecks4 = [
12787
12808
 
12788
12809
  // src/cli/_deploy/checks/platform.ts
12789
12810
  var SLUG_RE = /^[a-z][a-z0-9-]{1,40}$/;
12790
- function tableOf10(data, key) {
12811
+ function tableOf11(data, key) {
12791
12812
  const value = data[key];
12792
12813
  return value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
12793
12814
  }
@@ -12802,16 +12823,16 @@ function loadAgent(root) {
12802
12823
  }
12803
12824
  }
12804
12825
  function platformArtifact(data) {
12805
- const walletKind2 = String(tableOf10(data, "wallet").kind ?? "evm-local").trim().toLowerCase();
12826
+ const walletKind2 = String(tableOf11(data, "wallet").kind ?? "evm-local").trim().toLowerCase();
12806
12827
  if (walletKind2 === "twak") return "container";
12807
- const deploy = tableOf10(data, "deploy");
12828
+ const deploy = tableOf11(data, "deploy");
12808
12829
  const explicit = String(deploy.platform_artifact ?? "").toLowerCase();
12809
12830
  if (explicit) return explicit;
12810
12831
  return String(deploy.packaging ?? "").toLowerCase() === "container" ? "container" : "zip";
12811
12832
  }
12812
12833
  var checkPlatformEntrypointPresent = async (root, _target) => {
12813
12834
  const data = loadAgent(root);
12814
- const faces = stackFaces(tableOf10(data, "stack"), tableOf10(data, "payments"));
12835
+ const faces = stackFaces(tableOf11(data, "stack"), tableOf11(data, "payments"));
12815
12836
  const stem2 = entryStemOf(faces);
12816
12837
  const filenames = [`${stem2}.ts`];
12817
12838
  if (stem2 === "dualMain") filenames.push("mcpMain.ts");
@@ -12831,7 +12852,7 @@ var checkPlatformEntrypointPresent = async (root, _target) => {
12831
12852
  };
12832
12853
  var checkPlatformKeystoreNotInArtifact = async (root, _target) => {
12833
12854
  const data = loadAgent(root);
12834
- const wallet = tableOf10(data, "wallet");
12855
+ const wallet = tableOf11(data, "wallet");
12835
12856
  if (String(wallet.kind ?? "evm-local") === "twak") return [];
12836
12857
  const agent = path33.resolve(agentRoot(root));
12837
12858
  const configured = String(wallet.keystore_dir ?? ".studio/wallets");
@@ -12855,7 +12876,7 @@ var checkPlatformKeystoreNotInArtifact = async (root, _target) => {
12855
12876
  ];
12856
12877
  };
12857
12878
  var checkPlatformTestnetOnly = async (root, _target) => {
12858
- const network = String(tableOf10(loadAgent(root), "network").default ?? "").trim().toLowerCase();
12879
+ const network = String(tableOf11(loadAgent(root), "network").default ?? "").trim().toLowerCase();
12859
12880
  if (!network || network === "bsc-testnet") return [];
12860
12881
  return [
12861
12882
  {
@@ -12868,7 +12889,7 @@ var checkPlatformTestnetOnly = async (root, _target) => {
12868
12889
  ];
12869
12890
  };
12870
12891
  var checkPlatformSlugValid = async (root, _target) => {
12871
- const platform = tableOf10(tableOf10(loadAgent(root), "deploy"), "platform");
12892
+ const platform = tableOf11(tableOf11(loadAgent(root), "deploy"), "platform");
12872
12893
  const slug = String(platform.slug ?? "").trim();
12873
12894
  if (!slug || SLUG_RE.test(slug)) return [];
12874
12895
  return [
@@ -12926,7 +12947,7 @@ var checkPlatformStorageEndpoint = async (root, _target) => {
12926
12947
  };
12927
12948
  var checkPlatformMcpSyncTimeout = async (root, _target) => {
12928
12949
  const data = loadAgent(root);
12929
- const faces = stackFaces(tableOf10(data, "stack"), tableOf10(data, "payments"));
12950
+ const faces = stackFaces(tableOf11(data, "stack"), tableOf11(data, "payments"));
12930
12951
  if (!hasMcpFace(faces)) return [];
12931
12952
  const dual = hasA2aFace(faces);
12932
12953
  return [
@@ -12939,8 +12960,8 @@ var checkPlatformMcpSyncTimeout = async (root, _target) => {
12939
12960
  ];
12940
12961
  };
12941
12962
  var checkPlatformX402MerchantsMainnet = async (root, _target) => {
12942
- const merchants = tableOf10(
12943
- tableOf10(tableOf10(loadAgent(root), "payments"), "x402"),
12963
+ const merchants = tableOf11(
12964
+ tableOf11(tableOf11(loadAgent(root), "payments"), "x402"),
12944
12965
  "merchants"
12945
12966
  );
12946
12967
  const names = Object.keys(merchants).sort();
@@ -13001,7 +13022,8 @@ var warningChecks = [
13001
13022
  checkPlatformX402MerchantsMainnet,
13002
13023
  checkWalletBalancesAllZero,
13003
13024
  checkWalletTbnbBalanceSufficient,
13004
- checkWalletUBalanceNonzero
13025
+ checkWalletUBalanceNonzero,
13026
+ checkRuntimeRpcReachable
13005
13027
  ];
13006
13028
  var infoChecks = [
13007
13029
  checkPlatformTrialStatus,
@@ -13273,15 +13295,15 @@ async function runVerify(opts) {
13273
13295
  exitCode: 1
13274
13296
  });
13275
13297
  }
13276
- const tableOf16 = (key) => {
13298
+ const tableOf17 = (key) => {
13277
13299
  const v = data[key];
13278
13300
  return v !== null && typeof v === "object" && !Array.isArray(v) ? v : {};
13279
13301
  };
13280
- const network = opts.network || String(tableOf16("network").default ?? "bsc-testnet");
13302
+ const network = opts.network || String(tableOf17("network").default ?? "bsc-testnet");
13281
13303
  const protocol = nativeProtocolOf(
13282
- stackFaces(tableOf16("stack"), tableOf16("payments"))
13304
+ stackFaces(tableOf17("stack"), tableOf17("payments"))
13283
13305
  );
13284
- const identity = tableOf16("identity");
13306
+ const identity = tableOf17("identity");
13285
13307
  const existingAgentId = identity.agent_id;
13286
13308
  const accessDescription = accessSummaryForAgentcore(root, { protocol });
13287
13309
  let agentId = null;
@@ -13436,10 +13458,16 @@ var WALLET_SECTION = "wallet";
13436
13458
  var KEYSTORE_JSON_ENV2 = "WALLET_KEYSTORE_JSON";
13437
13459
  var TWAK_WALLET_JSON_ENV2 = "TWAK_WALLET_JSON";
13438
13460
  var WALLET_MATERIAL_KEYS = [KEYSTORE_JSON_ENV2, TWAK_WALLET_JSON_ENV2];
13461
+ var RETIRED_AGENT_STATES = /* @__PURE__ */ new Set([
13462
+ "deleted",
13463
+ "retired",
13464
+ "removed",
13465
+ "reclaiming"
13466
+ ]);
13439
13467
  function isJsonObject(value) {
13440
13468
  return value !== null && typeof value === "object" && !Array.isArray(value);
13441
13469
  }
13442
- function tableOf11(cfg, key) {
13470
+ function tableOf12(cfg, key) {
13443
13471
  const value = cfg[key];
13444
13472
  return isJsonObject(value) ? value : {};
13445
13473
  }
@@ -13474,7 +13502,7 @@ function loadAgentCfg(root) {
13474
13502
  }
13475
13503
  }
13476
13504
  function platformCfg(root) {
13477
- return tableOf11(tableOf11(loadAgentCfg(root), "deploy"), "platform");
13505
+ return tableOf12(tableOf12(loadAgentCfg(root), "deploy"), "platform");
13478
13506
  }
13479
13507
  function patchTomlKv2(tomlPath, section, key, value) {
13480
13508
  let text2 = fs36.readFileSync(tomlPath, "utf-8");
@@ -13494,6 +13522,32 @@ function recordPlatformKv(root, key, value) {
13494
13522
  } catch {
13495
13523
  }
13496
13524
  }
13525
+ function retiredAgentReason(agent) {
13526
+ const candidates = [agent];
13527
+ for (const key of ["agent", "data"]) {
13528
+ const nested = agent[key];
13529
+ if (isJsonObject(nested)) {
13530
+ candidates.push(nested);
13531
+ }
13532
+ }
13533
+ for (const item of candidates) {
13534
+ for (const key of [
13535
+ "state",
13536
+ "status",
13537
+ "lifecycle_state",
13538
+ "lifecycleState"
13539
+ ]) {
13540
+ const value = item[key];
13541
+ if (typeof value === "string" && RETIRED_AGENT_STATES.has(value.toLowerCase())) {
13542
+ return value.toLowerCase();
13543
+ }
13544
+ }
13545
+ if (item.deleted_at || item.deletedAt) {
13546
+ return "deleted";
13547
+ }
13548
+ }
13549
+ return null;
13550
+ }
13497
13551
  function suggestNextSlug(slug) {
13498
13552
  const m = /(\d+)$/.exec(slug);
13499
13553
  let next;
@@ -13504,12 +13558,45 @@ function suggestNextSlug(slug) {
13504
13558
  }
13505
13559
  return next.slice(0, 41);
13506
13560
  }
13561
+ async function retiredSlugPreflight(slug, platformCmd) {
13562
+ let res;
13563
+ try {
13564
+ res = await platformCmd(["list"], {
13565
+ slug: "studio-platform",
13566
+ json: true,
13567
+ quiet: true
13568
+ });
13569
+ } catch {
13570
+ return null;
13571
+ }
13572
+ if (res.code !== 0 || !isJsonObject(res.data)) {
13573
+ return null;
13574
+ }
13575
+ const candidates = [res.data];
13576
+ for (const key of ["agents", "data", "items", "records"]) {
13577
+ const nested = res.data[key];
13578
+ if (Array.isArray(nested)) {
13579
+ candidates.push(...nested);
13580
+ }
13581
+ }
13582
+ for (const entry of candidates) {
13583
+ if (!isJsonObject(entry)) {
13584
+ continue;
13585
+ }
13586
+ const entrySlug = String(entry.slug ?? entry.name ?? "").toLowerCase();
13587
+ if (entrySlug !== slug.toLowerCase()) {
13588
+ continue;
13589
+ }
13590
+ return retiredAgentReason(entry);
13591
+ }
13592
+ return null;
13593
+ }
13507
13594
  function clearIdentityEndpointIfMatches(root, oldUrl) {
13508
13595
  if (!oldUrl) {
13509
13596
  return;
13510
13597
  }
13511
13598
  const cfg = loadAgentCfg(root);
13512
- if (String(tableOf11(cfg, "identity").endpoint ?? "") !== String(oldUrl)) {
13599
+ if (String(tableOf12(cfg, "identity").endpoint ?? "") !== String(oldUrl)) {
13513
13600
  return;
13514
13601
  }
13515
13602
  const tomlPath = agentTomlPath2(root);
@@ -13528,7 +13615,7 @@ function persistedPackaging2(agentRoot2) {
13528
13615
  }
13529
13616
  try {
13530
13617
  const cfg = loadStudioToml19(tomlPath);
13531
- const value = tableOf11(cfg, "deploy").packaging;
13618
+ const value = tableOf12(cfg, "deploy").packaging;
13532
13619
  return value ? String(value) : null;
13533
13620
  } catch {
13534
13621
  return null;
@@ -13539,7 +13626,7 @@ function resolvePlatformArtifact2(agentRoot2) {
13539
13626
  if (isFile14(tomlPath)) {
13540
13627
  try {
13541
13628
  const cfg = loadStudioToml19(tomlPath);
13542
- const explicit = tableOf11(cfg, "deploy").platform_artifact;
13629
+ const explicit = tableOf12(cfg, "deploy").platform_artifact;
13543
13630
  if (explicit) {
13544
13631
  return String(explicit);
13545
13632
  }
@@ -13551,7 +13638,7 @@ function resolvePlatformArtifact2(agentRoot2) {
13551
13638
  function platformPackaging(root) {
13552
13639
  const agentRoot2 = findSubProjectRoot15("agent", root);
13553
13640
  const platformArtifact2 = agentRoot2 !== null ? resolvePlatformArtifact2(agentRoot2) : "zip";
13554
- const walletKind2 = agentRoot2 !== null ? String(tableOf11(loadCfgAt(agentRoot2), "wallet").kind ?? "evm-local") : "evm-local";
13641
+ const walletKind2 = agentRoot2 !== null ? String(tableOf12(loadCfgAt(agentRoot2), "wallet").kind ?? "evm-local") : "evm-local";
13555
13642
  if (walletKind2 === "twak") {
13556
13643
  return "container";
13557
13644
  }
@@ -13569,7 +13656,7 @@ function recordExposedAddress(root, address) {
13569
13656
  if (tomlPath === null) {
13570
13657
  return;
13571
13658
  }
13572
- const existing = tableOf11(
13659
+ const existing = tableOf12(
13573
13660
  loadAgentCfg(root),
13574
13661
  WALLET_SECTION
13575
13662
  ).platform_exposed_addresses;
@@ -13589,7 +13676,7 @@ function utcStamp() {
13589
13676
  function buyerAccess(root) {
13590
13677
  const base = bnbPlatformApiUrl();
13591
13678
  const cfg = loadAgentCfg(root);
13592
- const faces = stackFaces(tableOf11(cfg, "stack"), tableOf11(cfg, "payments"));
13679
+ const faces = stackFaces(tableOf12(cfg, "stack"), tableOf12(cfg, "payments"));
13593
13680
  const protocol = nativeProtocolOf(faces);
13594
13681
  const rawAgentId = platformCfg(root).agent_id;
13595
13682
  const agentId = typeof rawAgentId === "string" && rawAgentId ? rawAgentId : null;
@@ -13633,7 +13720,7 @@ function resolveSlug(root) {
13633
13720
  if (typeof recorded === "string" && recorded) {
13634
13721
  return recorded;
13635
13722
  }
13636
- let name = String(tableOf11(loadAgentCfg(root), "project").name ?? "");
13723
+ let name = String(tableOf12(loadAgentCfg(root), "project").name ?? "");
13637
13724
  name = name.replace(/-(agent|service)$/, "");
13638
13725
  if (!name) {
13639
13726
  name = path36.basename(findWorkspaceRoot6(root) ?? root);
@@ -13713,6 +13800,11 @@ async function platformAgent(opts) {
13713
13800
  }
13714
13801
  const secrets = await (opts.collectRuntimeSecrets ?? collectRuntimeSecrets)(root);
13715
13802
  walletWarning(root, secrets);
13803
+ if (Object.keys(secrets).length > 0) {
13804
+ warn(
13805
+ `note: runtime secret keys handed to the platform: ${Object.keys(secrets).sort().join(", ")} (names only \u2014 values not printed).`
13806
+ );
13807
+ }
13716
13808
  if (!opts.skipPrepare && opts.runPrepareGate) {
13717
13809
  const rc = await opts.runPrepareGate(root, opts.force ?? false);
13718
13810
  if (rc !== null && rc !== 0) {
@@ -13723,6 +13815,18 @@ async function platformAgent(opts) {
13723
13815
  }
13724
13816
  }
13725
13817
  const slug = resolveSlug(root);
13818
+ {
13819
+ const reason = await retiredSlugPreflight(slug, platformCmd);
13820
+ if (reason !== null) {
13821
+ const next = suggestNextSlug(slug);
13822
+ warn(
13823
+ `error: the slug '${slug}' is ${reason} on the platform \u2014 deploys to it always fail (destroyed slugs are permanently retired). Pick a new slug:
13824
+ bag config set deploy.platform.slug ${next}
13825
+ then re-run the deploy.`
13826
+ );
13827
+ return 1;
13828
+ }
13829
+ }
13726
13830
  const agentDir = findSubProjectRoot15("agent", root);
13727
13831
  if (agentDir === null) {
13728
13832
  warn(
@@ -13731,7 +13835,7 @@ async function platformAgent(opts) {
13731
13835
  return 1;
13732
13836
  }
13733
13837
  const cfg = loadAgentCfg(root);
13734
- const faces = stackFaces(tableOf11(cfg, "stack"), tableOf11(cfg, "payments"));
13838
+ const faces = stackFaces(tableOf12(cfg, "stack"), tableOf12(cfg, "payments"));
13735
13839
  const protocol = nativeProtocolOf(faces);
13736
13840
  const runDeploy = opts.runDelegatedDeploy ?? (async (o) => withDeployFiles(
13737
13841
  o.root,
@@ -13845,8 +13949,8 @@ async function confirmPackagingDefault(root, packaging, deps) {
13845
13949
  return null;
13846
13950
  }
13847
13951
  const cfg = loadAgentCfg(root);
13848
- const walletKind2 = String(tableOf11(cfg, "wallet").kind ?? "evm-local");
13849
- const destination = String(tableOf11(cfg, "deploy").destination ?? "platform");
13952
+ const walletKind2 = String(tableOf12(cfg, "wallet").kind ?? "evm-local");
13953
+ const destination = String(tableOf12(cfg, "deploy").destination ?? "platform");
13850
13954
  const answer = await deps.promptUser(
13851
13955
  `This project will deploy as a ${packaging} package (wallet.kind=${walletKind2}, destination=${destination}). Continue? [Y/n] `
13852
13956
  );
@@ -13860,7 +13964,7 @@ function walletWarning(root, secrets) {
13860
13964
  if (!WALLET_MATERIAL_KEYS.some((k) => k in secrets)) {
13861
13965
  return;
13862
13966
  }
13863
- const address = tableOf11(loadAgentCfg(root), "wallet").address;
13967
+ const address = tableOf12(loadAgentCfg(root), "wallet").address;
13864
13968
  const who = typeof address === "string" && address ? `key (address ${address})` : "signing key";
13865
13969
  warn(
13866
13970
  `
@@ -13906,7 +14010,7 @@ function recordShippedWallet(root, secrets) {
13906
14010
  if (!WALLET_MATERIAL_KEYS.some((k) => k in secrets)) {
13907
14011
  return;
13908
14012
  }
13909
- const address = tableOf11(loadAgentCfg(root), "wallet").address;
14013
+ const address = tableOf12(loadAgentCfg(root), "wallet").address;
13910
14014
  if (typeof address === "string" && address) {
13911
14015
  recordExposedAddress(root, address);
13912
14016
  }
@@ -13938,7 +14042,7 @@ function printAccessNextSteps(root, _invokeUrl) {
13938
14042
  }
13939
14043
  if (!x402Only) {
13940
14044
  emit(
13941
- " mint buyer creds: bag platform invoke-client new (prints client_id + client_secret to POST to the client_credentials token endpoint above)"
14045
+ " mint buyer creds: bag platform invoke-client new (prints client_id + client_secret to POST to the client_credentials token endpoint above \u2014 credentials go in the form BODY; HTTP Basic auth is not accepted)"
13942
14046
  );
13943
14047
  } else {
13944
14048
  emit(" protocol discovery is suppressed for this X402-only deployment.");
@@ -13989,6 +14093,8 @@ function printAgentClientPrompt(root, invokeUrl, status) {
13989
14093
  const agentIdNote = agentId ?? "<not registered yet \u2014 run `bag platform invoke-client new` to get one>";
13990
14094
  const tokenSteps = ` 1) run \`bag platform invoke-client new\` -> client_id + client_secret (secret shown ONCE).
13991
14095
  2) POST client_credentials to ${tokenUrl} with scope \`${scope}\` -> access_token.
14096
+ Send client_id + client_secret in the application/x-www-form-urlencoded BODY \u2014
14097
+ this endpoint does NOT accept HTTP Basic auth (\`curl -u\` fails with oauth.invalid_request).
13992
14098
  3) send \`Authorization: Bearer <token>\`.`;
13993
14099
  const agentCfg = loadAgentCfg(agentRoot2);
13994
14100
  const rails = commerceRails(agentCfg);
@@ -13999,7 +14105,10 @@ function printAgentClientPrompt(root, invokeUrl, status) {
13999
14105
  if (hasA2aFace(faces)) {
14000
14106
  endpoints.push(
14001
14107
  ` [A2A] Agent card: ${cardUrl}
14002
- Invoke (JSON-RPC message/send): ${a2aInvokeUrl}`
14108
+ Invoke (JSON-RPC message/send): ${a2aInvokeUrl}
14109
+ When composing agent-card URLs in code, build them with \`new URL(base)\` +
14110
+ \`url.pathname = ... \` (keeps any querystring intact) \u2014 never string-concatenate
14111
+ \`\${base}/.well-known/agent-card.json\`; that breaks on URLs that carry a querystring.`
14003
14112
  );
14004
14113
  }
14005
14114
  if (hasMcpFace(faces)) {
@@ -14204,7 +14313,8 @@ async function platformDestroy(opts) {
14204
14313
  return 1;
14205
14314
  }
14206
14315
  const oldInvokeUrl = recorded.invoke_url;
14207
- recordPlatformKv(root, "slug", "");
14316
+ const nextSlug = suggestNextSlug(slug);
14317
+ recordPlatformKv(root, "slug", nextSlug);
14208
14318
  recordPlatformKv(root, "deployment_id", "");
14209
14319
  recordPlatformKv(root, "invoke_url", "");
14210
14320
  recordPlatformKv(root, "agent_id", "");
@@ -14215,11 +14325,10 @@ async function platformDestroy(opts) {
14215
14325
  );
14216
14326
  emit(`\u2713 deleted platform agent ${slug} (deployment + transmitted secret).`);
14217
14327
  emit(
14218
- "note: the on-chain ERC-8004 identity is unchanged; its endpoint will go stale. The platform slug was cleared locally because destroyed slugs are permanently retired. Your local keystore (.studio/wallets/) was left untouched."
14328
+ `note: the on-chain ERC-8004 identity is unchanged; its endpoint will go stale. Destroyed slugs are permanently retired, so the local slug was advanced to '${nextSlug}' \u2014 the next deploy uses it automatically. Your local keystore (.studio/wallets/) was left untouched.`
14219
14329
  );
14220
14330
  emit(
14221
- ` Redeploying THIS project needs a fresh slug (the old one is retired):
14222
- bag config set deploy.platform.slug ${suggestNextSlug(slug)}
14331
+ ` Redeploy THIS project (uses '${nextSlug}', or pick your own with \`bag config set deploy.platform.slug <name>\`):
14223
14332
  bag deploy --provider bnb`
14224
14333
  );
14225
14334
  return 0;
@@ -14267,7 +14376,7 @@ function isDir7(p) {
14267
14376
  function errMsg2(exc) {
14268
14377
  return exc instanceof Error ? exc.message : String(exc);
14269
14378
  }
14270
- function tableOf12(cfg, key) {
14379
+ function tableOf13(cfg, key) {
14271
14380
  const v = cfg[key];
14272
14381
  return v !== null && typeof v === "object" && !Array.isArray(v) ? v : {};
14273
14382
  }
@@ -14479,7 +14588,7 @@ function readStackRuntime(root) {
14479
14588
  if (cfg === null) {
14480
14589
  return null;
14481
14590
  }
14482
- const runtime = tableOf12(cfg, "stack").runtime;
14591
+ const runtime = tableOf13(cfg, "stack").runtime;
14483
14592
  return runtime ? String(runtime) : null;
14484
14593
  }
14485
14594
  function agentNetworkDefault(root) {
@@ -14487,14 +14596,14 @@ function agentNetworkDefault(root) {
14487
14596
  if (cfg === null) {
14488
14597
  return "";
14489
14598
  }
14490
- return String(tableOf12(cfg, "network").default ?? "").toLowerCase();
14599
+ return String(tableOf13(cfg, "network").default ?? "").toLowerCase();
14491
14600
  }
14492
14601
  function agentDeployDestination(root) {
14493
14602
  const cfg = loadAgentCfg2(root);
14494
14603
  if (cfg === null) {
14495
14604
  return "self";
14496
14605
  }
14497
- const dest = String(tableOf12(cfg, "deploy").destination ?? "").trim().toLowerCase();
14606
+ const dest = String(tableOf13(cfg, "deploy").destination ?? "").trim().toLowerCase();
14498
14607
  return dest || "self";
14499
14608
  }
14500
14609
  function resolveTarget(opts, root, destination = agentDeployDestination(root)) {
@@ -15246,13 +15355,13 @@ function recordedEndpoint(root) {
15246
15355
  if (cfg === null) {
15247
15356
  return null;
15248
15357
  }
15249
- const url = tableOf12(cfg, "identity").endpoint;
15358
+ const url = tableOf13(cfg, "identity").endpoint;
15250
15359
  return url ? String(url) : null;
15251
15360
  }
15252
15361
  function recordedAgentId(agentRoot2) {
15253
15362
  try {
15254
15363
  const cfg = loadStudioToml20(path37.join(agentRoot2, "studio.toml"));
15255
- const val = tableOf12(cfg, "identity").agent_id;
15364
+ const val = tableOf13(cfg, "identity").agent_id;
15256
15365
  return val !== void 0 && val !== null && val !== "" ? String(val) : null;
15257
15366
  } catch {
15258
15367
  return null;
@@ -15261,7 +15370,7 @@ function recordedAgentId(agentRoot2) {
15261
15370
  function recordedRuntimeArn(agentRoot2) {
15262
15371
  try {
15263
15372
  const cfg = loadStudioToml20(path37.join(agentRoot2, "studio.toml"));
15264
- const val = tableOf12(cfg, "deploy").runtime_arn;
15373
+ const val = tableOf13(cfg, "deploy").runtime_arn;
15265
15374
  return val ? String(val) : null;
15266
15375
  } catch {
15267
15376
  return null;
@@ -15270,7 +15379,7 @@ function recordedRuntimeArn(agentRoot2) {
15270
15379
  function recordedOauthClientId(agentRoot2) {
15271
15380
  try {
15272
15381
  const cfg = loadStudioToml20(path37.join(agentRoot2, "studio.toml"));
15273
- const val = tableOf12(cfg, "deploy").oauth_client_id;
15382
+ const val = tableOf13(cfg, "deploy").oauth_client_id;
15274
15383
  return val ? String(val) : null;
15275
15384
  } catch {
15276
15385
  return null;
@@ -15279,7 +15388,7 @@ function recordedOauthClientId(agentRoot2) {
15279
15388
  function agentFacesOf(agentRoot2) {
15280
15389
  try {
15281
15390
  const cfg = loadStudioToml20(path37.join(agentRoot2, "studio.toml"));
15282
- return stackFaces(tableOf12(cfg, "stack"), tableOf12(cfg, "payments"));
15391
+ return stackFaces(tableOf13(cfg, "stack"), tableOf13(cfg, "payments"));
15283
15392
  } catch {
15284
15393
  return ["A2A"];
15285
15394
  }
@@ -15372,7 +15481,10 @@ async function printAgentClientPrompt2(root, destination, opts = {}) {
15372
15481
  and POST it to the invoke URL above.` : ` [A2A] Invoke (JSON-RPC message/send, POST-only): ${a2aInvokeUrl}
15373
15482
  NOTE: this AgentCore endpoint is POST-only and serves NO
15374
15483
  GET-able agent card. Skip A2A discovery (do NOT fetch
15375
- /.well-known/agent-card.json) \u2014 ${a2aPayloadPhrase} straight to the invoke URL above.`;
15484
+ /.well-known/agent-card.json) \u2014 ${a2aPayloadPhrase} straight to the invoke URL above.
15485
+ The invoke URL carries a querystring (?qualifier=...): never
15486
+ string-concatenate extra path segments onto it \u2014 that produces
15487
+ an invalid URL and an HTTP 405.`;
15376
15488
  const lines = [
15377
15489
  "",
15378
15490
  CLIENT_PROMPT_RULE2,
@@ -15572,7 +15684,7 @@ function renderVerifyHuman(r, deployment, liveStatus) {
15572
15684
  }
15573
15685
  }
15574
15686
  function deployCliError(data) {
15575
- const error = tableOf12(data, "error");
15687
+ const error = tableOf13(data, "error");
15576
15688
  const message = String(error.message ?? "").trim();
15577
15689
  return message || null;
15578
15690
  }
@@ -15987,7 +16099,7 @@ var SECRET_ENV_KEYS = [
15987
16099
  "TWAK_ACCESS_ID",
15988
16100
  "TWAK_HMAC_SECRET"
15989
16101
  ];
15990
- function tableOf13(cfg, key) {
16102
+ function tableOf14(cfg, key) {
15991
16103
  const v = cfg[key];
15992
16104
  return v !== null && typeof v === "object" && !Array.isArray(v) ? v : {};
15993
16105
  }
@@ -16064,7 +16176,7 @@ async function cmdDoctor(opts) {
16064
16176
  checks.push(...await checkBalances(projectRoot, data, opts.network));
16065
16177
  checks.push(...await checkPieverseMainnetU(projectRoot, data));
16066
16178
  checks.push(...await check8004(projectRoot, data, opts.network));
16067
- const destination = String(tableOf13(data, "deploy").destination ?? "self").trim().toLowerCase();
16179
+ const destination = String(tableOf14(data, "deploy").destination ?? "self").trim().toLowerCase();
16068
16180
  checks.push(...await checkDeployTools(data, destination));
16069
16181
  checks.push(...checkAgentsMdSkillTrigger(projectRoot));
16070
16182
  printChecks(checks);
@@ -16147,13 +16259,13 @@ function checkAppMain(projectRootArg) {
16147
16259
  config = {};
16148
16260
  }
16149
16261
  }
16150
- const stack = tableOf13(config, "stack");
16262
+ const stack = tableOf14(config, "stack");
16151
16263
  const runtime = String(stack.runtime ?? "").toLowerCase();
16152
16264
  let entrypoint;
16153
16265
  if (runtime === "azure-foundry") {
16154
16266
  entrypoint = "src/foundryMain.ts";
16155
16267
  } else if (runtime === "agentcore") {
16156
- const faces = stackFaces(stack, tableOf13(config, "payments"));
16268
+ const faces = stackFaces(stack, tableOf14(config, "payments"));
16157
16269
  entrypoint = `src/${entryStemOf(faces)}.ts`;
16158
16270
  } else {
16159
16271
  entrypoint = "src/main.ts";
@@ -16224,7 +16336,7 @@ function anchoredKeystoreDir(projectRoot, walletCfg) {
16224
16336
  return path38.isAbsolute(rel) ? rel : path38.join(projectRoot, rel);
16225
16337
  }
16226
16338
  async function checkWallet(projectRoot, data) {
16227
- const walletCfg = tableOf13(data, "wallet");
16339
+ const walletCfg = tableOf14(data, "wallet");
16228
16340
  if (walletCfg.kind === "twak") {
16229
16341
  return checkWalletTwak(walletCfg, projectRoot, data);
16230
16342
  }
@@ -16396,7 +16508,7 @@ async function checkWalletTwak(walletCfg, projectRoot, data = {}) {
16396
16508
  detail: `not on PATH \u2014 npm install -g @trustwallet/cli@${TWAK_CLI_VERSION}`
16397
16509
  });
16398
16510
  }
16399
- const networkName = String(tableOf13(data, "network").default ?? "bsc-testnet");
16511
+ const networkName = String(tableOf14(data, "network").default ?? "bsc-testnet");
16400
16512
  const unsupportedTargets = twakUnsupportedContractOverrides(networkName);
16401
16513
  if (unsupportedTargets.length > 0) {
16402
16514
  out.push({
@@ -16442,7 +16554,7 @@ async function checkWalletTwak(walletCfg, projectRoot, data = {}) {
16442
16554
  return out;
16443
16555
  }
16444
16556
  function checkPassword(data) {
16445
- const walletKind2 = String(tableOf13(data, "wallet").kind ?? "evm-local");
16557
+ const walletKind2 = String(tableOf14(data, "wallet").kind ?? "evm-local");
16446
16558
  if (walletKind2 === "twak") {
16447
16559
  if (process.env.TWAK_WALLET_PASSWORD) {
16448
16560
  return [
@@ -16478,7 +16590,7 @@ function checkPassword(data) {
16478
16590
  ];
16479
16591
  }
16480
16592
  async function checkLlm(data, projectRoot) {
16481
- const llmCfg = tableOf13(data, "llm");
16593
+ const llmCfg = tableOf14(data, "llm");
16482
16594
  const provider = llmCfg.provider ? String(llmCfg.provider) : null;
16483
16595
  if (!provider) {
16484
16596
  return [{ name: "[llm] provider", status: WARN, detail: "not configured" }];
@@ -16523,8 +16635,8 @@ async function checkLlm(data, projectRoot) {
16523
16635
  return out;
16524
16636
  }
16525
16637
  async function checkPieverse(data, apiKey) {
16526
- const llmCfg = tableOf13(data, "llm");
16527
- const pvCfg = tableOf13(llmCfg, "pieverse");
16638
+ const llmCfg = tableOf14(data, "llm");
16639
+ const pvCfg = tableOf14(llmCfg, "pieverse");
16528
16640
  const keyHash = pvCfg.key_hash ? String(pvCfg.key_hash) : null;
16529
16641
  const hasEnv = Boolean(apiKey);
16530
16642
  const out = [];
@@ -16594,8 +16706,8 @@ async function checkPieverse(data, apiKey) {
16594
16706
  });
16595
16707
  }
16596
16708
  try {
16597
- const policy = pieversePolicyFromToml(tableOf13(llmCfg, "auto_renew"));
16598
- const budget = policyFromToml(tableOf13(data, "budget"));
16709
+ const policy = pieversePolicyFromToml(tableOf14(llmCfg, "auto_renew"));
16710
+ const budget = policyFromToml(tableOf14(data, "budget"));
16599
16711
  let detail;
16600
16712
  if (policy.enabled) {
16601
16713
  const allocateDetail = `enabled: allocates $${policy.topupChunkUsd.toFixed(2)} from Account Balance when key < $${policy.minBalanceUsd.toFixed(2)}.`;
@@ -16615,7 +16727,7 @@ async function checkPieverse(data, apiKey) {
16615
16727
  return out;
16616
16728
  }
16617
16729
  async function checkNetwork(data, networkOverride) {
16618
- const netName = networkOverride || tableOf13(data, "network").default;
16730
+ const netName = networkOverride || tableOf14(data, "network").default;
16619
16731
  if (!netName) {
16620
16732
  return [
16621
16733
  {
@@ -16660,7 +16772,7 @@ async function checkNetwork(data, networkOverride) {
16660
16772
  }
16661
16773
  }
16662
16774
  function checkCurrency(data) {
16663
- const payments = tableOf13(data, "payments");
16775
+ const payments = tableOf14(data, "payments");
16664
16776
  const pay = payments.erc8183;
16665
16777
  if (pay === null || typeof pay !== "object" || Array.isArray(pay)) {
16666
16778
  return [];
@@ -16678,7 +16790,7 @@ function checkCurrency(data) {
16678
16790
  return [];
16679
16791
  }
16680
16792
  function checkErc8183Pricing(data) {
16681
- const payValue = tableOf13(data, "payments").erc8183;
16793
+ const payValue = tableOf14(data, "payments").erc8183;
16682
16794
  if (payValue === null || typeof payValue !== "object" || Array.isArray(payValue)) {
16683
16795
  return [];
16684
16796
  }
@@ -16758,7 +16870,7 @@ function checkErc8183Pricing(data) {
16758
16870
  ];
16759
16871
  }
16760
16872
  function checkPriceBounds(data) {
16761
- const payValue = tableOf13(data, "payments").erc8183;
16873
+ const payValue = tableOf14(data, "payments").erc8183;
16762
16874
  if (payValue === null || typeof payValue !== "object" || Array.isArray(payValue)) {
16763
16875
  return [];
16764
16876
  }
@@ -16776,7 +16888,7 @@ function checkPriceBounds(data) {
16776
16888
  return [];
16777
16889
  }
16778
16890
  function checkX402Seller(data, agentRoot2) {
16779
- const payments = tableOf13(data, "payments");
16891
+ const payments = tableOf14(data, "payments");
16780
16892
  const sellerValue = payments.x402_seller;
16781
16893
  if (sellerValue === null || typeof sellerValue !== "object" || Array.isArray(sellerValue)) {
16782
16894
  return [];
@@ -16793,7 +16905,7 @@ function checkX402Seller(data, agentRoot2) {
16793
16905
  }
16794
16906
  ];
16795
16907
  }
16796
- const runtime = String(tableOf13(data, "stack").runtime ?? "agentcore");
16908
+ const runtime = String(tableOf14(data, "stack").runtime ?? "agentcore");
16797
16909
  const hasErc8183 = payments.erc8183 !== null && typeof payments.erc8183 === "object" && !Array.isArray(payments.erc8183);
16798
16910
  const fallbackStatus = hasErc8183 ? WARN : FAIL;
16799
16911
  if (pricing.kind === "free") {
@@ -16828,7 +16940,7 @@ function checkX402Seller(data, agentRoot2) {
16828
16940
  detail: `PAID \u2014 $${pricing.priceUsd} per request through B402.`
16829
16941
  }
16830
16942
  ];
16831
- const walletKind2 = String(tableOf13(data, "wallet").kind ?? "evm-local");
16943
+ const walletKind2 = String(tableOf14(data, "wallet").kind ?? "evm-local");
16832
16944
  if (!["evm-local", "twak"].includes(walletKind2)) {
16833
16945
  out.push({
16834
16946
  name: "x402 payout wallet",
@@ -16854,7 +16966,7 @@ function checkX402Seller(data, agentRoot2) {
16854
16966
  return out;
16855
16967
  }
16856
16968
  function checkStorage(data) {
16857
- const kind = String(tableOf13(data, "storage").kind ?? "local").toLowerCase();
16969
+ const kind = String(tableOf14(data, "storage").kind ?? "local").toLowerCase();
16858
16970
  if (kind === "ipfs") {
16859
16971
  if (!process.env.STORAGE_API_URL) {
16860
16972
  return [
@@ -16900,7 +17012,7 @@ function checkStorage(data) {
16900
17012
  ];
16901
17013
  }
16902
17014
  function balanceAddress(projectRoot, data) {
16903
- const walletCfg = tableOf13(data, "wallet");
17015
+ const walletCfg = tableOf14(data, "wallet");
16904
17016
  if (walletCfg.kind === "twak" || walletCfg.kind === "altana") {
16905
17017
  const addr = String(walletCfg.address ?? "").trim();
16906
17018
  return addr || null;
@@ -16922,7 +17034,7 @@ function balanceAddress(projectRoot, data) {
16922
17034
  return provider.address;
16923
17035
  }
16924
17036
  async function checkBalances(projectRoot, data, networkOverride) {
16925
- const netName = networkOverride || tableOf13(data, "network").default;
17037
+ const netName = networkOverride || tableOf14(data, "network").default;
16926
17038
  if (!netName) {
16927
17039
  return [];
16928
17040
  }
@@ -16999,11 +17111,11 @@ async function checkBalances(projectRoot, data, networkOverride) {
16999
17111
  }
17000
17112
  }
17001
17113
  async function checkPieverseMainnetU(projectRoot, data) {
17002
- const llmCfg = tableOf13(data, "llm");
17114
+ const llmCfg = tableOf14(data, "llm");
17003
17115
  if (llmCfg.provider !== "pieverse-llm") {
17004
17116
  return [];
17005
17117
  }
17006
- const pvCfg = tableOf13(llmCfg, "pieverse");
17118
+ const pvCfg = tableOf14(llmCfg, "pieverse");
17007
17119
  const pvNetwork = String(pvCfg.network ?? "bsc-mainnet");
17008
17120
  if (pvNetwork === "bsc-testnet") {
17009
17121
  return [
@@ -17016,7 +17128,7 @@ async function checkPieverseMainnetU(projectRoot, data) {
17016
17128
  }
17017
17129
  const modelName = String(llmCfg.model ?? "");
17018
17130
  const isFreeModel2 = modelName.includes("auto/free");
17019
- const budgetEnabled = tableOf13(data, "budget").enabled === true;
17131
+ const budgetEnabled = tableOf14(data, "budget").enabled === true;
17020
17132
  if (isFreeModel2 && !budgetEnabled) {
17021
17133
  return [
17022
17134
  {
@@ -17026,7 +17138,7 @@ async function checkPieverseMainnetU(projectRoot, data) {
17026
17138
  }
17027
17139
  ];
17028
17140
  }
17029
- const autoRenew = tableOf13(llmCfg, "auto_renew");
17141
+ const autoRenew = tableOf14(llmCfg, "auto_renew");
17030
17142
  const chunk = typeof autoRenew.topup_chunk_usd === "number" ? autoRenew.topup_chunk_usd : 1;
17031
17143
  const threshold = chunk * 2;
17032
17144
  try {
@@ -17071,7 +17183,7 @@ async function check8004(projectRoot, data, networkOverride) {
17071
17183
  if (!process.env.WALLET_PASSWORD) {
17072
17184
  return [];
17073
17185
  }
17074
- const walletCfg = tableOf13(data, "wallet");
17186
+ const walletCfg = tableOf14(data, "wallet");
17075
17187
  if (!isLocalEvmWallet(walletCfg)) {
17076
17188
  return [];
17077
17189
  }
@@ -17080,7 +17192,7 @@ async function check8004(projectRoot, data, networkOverride) {
17080
17192
  return [];
17081
17193
  }
17082
17194
  const network = String(
17083
- networkOverride || tableOf13(data, "network").default || "bsc-testnet"
17195
+ networkOverride || tableOf14(data, "network").default || "bsc-testnet"
17084
17196
  );
17085
17197
  try {
17086
17198
  const wallet = walletRt5.getWallet();
@@ -17113,11 +17225,11 @@ async function check8004(projectRoot, data, networkOverride) {
17113
17225
  }
17114
17226
  }
17115
17227
  function platformPackagingRequiresContainer(data) {
17116
- const walletKind2 = String(tableOf13(data, "wallet").kind ?? "evm-local").trim().toLowerCase();
17228
+ const walletKind2 = String(tableOf14(data, "wallet").kind ?? "evm-local").trim().toLowerCase();
17117
17229
  if (walletKind2 === "twak") {
17118
17230
  return true;
17119
17231
  }
17120
- const deployCfg = tableOf13(data, "deploy");
17232
+ const deployCfg = tableOf14(data, "deploy");
17121
17233
  let platformArtifact2 = String(deployCfg.platform_artifact ?? "").trim().toLowerCase();
17122
17234
  if (!platformArtifact2) {
17123
17235
  const packaging = String(deployCfg.packaging ?? "").trim().toLowerCase();
@@ -17153,7 +17265,7 @@ async function checkDeployTools(data, destination) {
17153
17265
  detail: "[deploy].platform_artifact='zip' uses the managed platform's ZIP runtime; local Docker is not required."
17154
17266
  });
17155
17267
  }
17156
- const walletKind2 = String(tableOf13(data, "wallet").kind ?? "").trim().toLowerCase();
17268
+ const walletKind2 = String(tableOf14(data, "wallet").kind ?? "").trim().toLowerCase();
17157
17269
  if (walletKind2 === "twak") {
17158
17270
  out.push(emit2(await checkTwak()));
17159
17271
  } else {
@@ -17437,7 +17549,7 @@ function registerErc8004(program) {
17437
17549
  )
17438
17550
  );
17439
17551
  }
17440
- function tableOf14(cfg, key) {
17552
+ function tableOf15(cfg, key) {
17441
17553
  const v = cfg[key];
17442
17554
  return v !== null && typeof v === "object" && !Array.isArray(v) ? v : {};
17443
17555
  }
@@ -17460,7 +17572,7 @@ function resolveNetwork2(override) {
17460
17572
  return override;
17461
17573
  }
17462
17574
  const cfg = loadAgentCfg3();
17463
- const net2 = cfg === null ? void 0 : tableOf14(cfg, "network").default;
17575
+ const net2 = cfg === null ? void 0 : tableOf15(cfg, "network").default;
17464
17576
  return net2 ? String(net2) : "bsc-testnet";
17465
17577
  }
17466
17578
  function resolveProtocol(override) {
@@ -17471,7 +17583,7 @@ function resolveProtocol(override) {
17471
17583
  if (cfg === null) {
17472
17584
  return "A2A";
17473
17585
  }
17474
- const faces = stackFaces(tableOf14(cfg, "stack"), tableOf14(cfg, "payments"));
17586
+ const faces = stackFaces(tableOf15(cfg, "stack"), tableOf15(cfg, "payments"));
17475
17587
  if (faces.length === 1 && hasX402Face(faces)) {
17476
17588
  printErr(
17477
17589
  "warning: this X402-only project has no public ERC-8004 protocol face; A2A is only the internal AgentCore protocol declaration."
@@ -17481,13 +17593,13 @@ function resolveProtocol(override) {
17481
17593
  }
17482
17594
  function recordedEndpoint2() {
17483
17595
  const cfg = loadAgentCfg3();
17484
- const endpoint = cfg === null ? void 0 : tableOf14(cfg, "identity").endpoint;
17596
+ const endpoint = cfg === null ? void 0 : tableOf15(cfg, "identity").endpoint;
17485
17597
  return endpoint ? String(endpoint) : null;
17486
17598
  }
17487
17599
  var REGISTER_MIN_BNB = 2e-3;
17488
17600
  function walletSelfPaysGas() {
17489
17601
  const cfg = loadAgentCfg3();
17490
- if (cfg !== null && tableOf14(cfg, "wallet").gasless) {
17602
+ if (cfg !== null && tableOf15(cfg, "wallet").gasless) {
17491
17603
  return false;
17492
17604
  }
17493
17605
  return true;
@@ -17527,7 +17639,7 @@ function syncAgentRegistry(agentId, op) {
17527
17639
  function loadIdentityBlock(agentRoot2) {
17528
17640
  try {
17529
17641
  return {
17530
- ...tableOf14(
17642
+ ...tableOf15(
17531
17643
  loadStudioToml22(path40.join(agentRoot2, "studio.toml")),
17532
17644
  "identity"
17533
17645
  )
@@ -17630,7 +17742,7 @@ function printPartialRegister(exc) {
17630
17742
  }
17631
17743
  async function cmdRegister2(opts) {
17632
17744
  const cfg = loadAgentCfg3();
17633
- const destination = cfg === null ? "" : String(tableOf14(cfg, "deploy").destination ?? "").trim().toLowerCase();
17745
+ const destination = cfg === null ? "" : String(tableOf15(cfg, "deploy").destination ?? "").trim().toLowerCase();
17634
17746
  if (destination === "platform") {
17635
17747
  printErr(
17636
17748
  "error: this is a platform-destination project \u2014 ERC-8004 registration is relayed GASLESSLY by the BNB Chain operator, not broadcast from your local wallet.\n Use: bag deploy verify --endpoint <your-invoke-url>\n(`bag erc8004 register` always self-pays gas from the local wallet, which fails on the zero-balance throwaway wallet the trial uses.)"
@@ -17934,7 +18046,12 @@ function registerErc8183(program) {
17934
18046
  "--agent-id <id>",
17935
18047
  "ERC-8004 agent_id (resolves provider + negotiates).",
17936
18048
  (v) => Number.parseInt(v, 10)
17937
- ).argument("[task]", "Task description (or use --task).").option("--task <text>", "Task description (alternative to positional).").option(
18049
+ ).argument("[task]", "Task description (or use --task).").option("--task <text>", "Task description (alternative to positional).").addOption(
18050
+ new Option6(
18051
+ "--quote-json <json|path>",
18052
+ "A seller's signed quote envelope (the negotiate response JSON, inline or a file path) to anchor on-chain. Use with --provider for sellers whose negotiate step ran out-of-band (e.g. an OAuth-gated AgentCore seller)."
18053
+ ).conflicts("agentId")
18054
+ ).option(
17938
18055
  "--budget-u <amount>",
17939
18056
  "Max U to spend (default: negotiated or policy)."
17940
18057
  ).option(
@@ -18061,6 +18178,35 @@ async function cmdList3(opts) {
18061
18178
  }
18062
18179
  return 0;
18063
18180
  }
18181
+ function parseQuoteEnvelope(raw) {
18182
+ const trimmed = raw.trim();
18183
+ let text2 = trimmed;
18184
+ if (!trimmed.startsWith("{")) {
18185
+ try {
18186
+ text2 = fs40.readFileSync(trimmed, "utf-8");
18187
+ } catch (exc) {
18188
+ throw new Error(
18189
+ `--quote-json is neither inline JSON nor a readable file: ${errMsg5(exc)}`
18190
+ );
18191
+ }
18192
+ }
18193
+ let parsed;
18194
+ try {
18195
+ parsed = JSON.parse(text2);
18196
+ } catch (exc) {
18197
+ throw new Error(`--quote-json is not valid JSON: ${errMsg5(exc)}`);
18198
+ }
18199
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
18200
+ throw new Error("--quote-json must decode to a JSON object.");
18201
+ }
18202
+ const envelope = parsed;
18203
+ if (!envelope.negotiation_hash || !envelope.provider_sig) {
18204
+ throw new Error(
18205
+ "--quote-json is not a signed quote envelope: it must carry `negotiation_hash` and `provider_sig` (the seller's negotiate response). Re-run the negotiate step and pass its full response body."
18206
+ );
18207
+ }
18208
+ return envelope;
18209
+ }
18064
18210
  async function cmdBuy(taskPositional, opts) {
18065
18211
  const rc = applyProjectRoot2(opts.projectRoot);
18066
18212
  if (rc !== null) {
@@ -18070,6 +18216,15 @@ async function cmdBuy(taskPositional, opts) {
18070
18216
  printErr("error: one of --provider / --agent-id is required");
18071
18217
  return 2;
18072
18218
  }
18219
+ let negotiationEnvelope = null;
18220
+ if (opts.quoteJson !== void 0) {
18221
+ try {
18222
+ negotiationEnvelope = parseQuoteEnvelope(opts.quoteJson);
18223
+ } catch (exc) {
18224
+ printErr(`error: ${errMsg5(exc)}`);
18225
+ return 2;
18226
+ }
18227
+ }
18073
18228
  if (taskPositional !== void 0 && opts.task !== void 0) {
18074
18229
  printErr(
18075
18230
  "error: pass the task once (either positional or --task, not both)"
@@ -18077,19 +18232,20 @@ async function cmdBuy(taskPositional, opts) {
18077
18232
  return 2;
18078
18233
  }
18079
18234
  const task = taskPositional ?? opts.task;
18080
- if (task === void 0) {
18081
- printErr("error: task is required");
18235
+ if (task === void 0 && negotiationEnvelope === null) {
18236
+ printErr("error: task is required (or pass --quote-json)");
18082
18237
  return 2;
18083
18238
  }
18084
18239
  let r;
18085
18240
  try {
18086
- r = await buyWorkflow(opts.provider ?? null, task, {
18241
+ r = await buyWorkflow(opts.provider ?? null, task ?? "", {
18087
18242
  agentId: opts.agentId ?? null,
18088
18243
  budgetU: opts.budgetU ?? null,
18089
18244
  deadlineMinutes: opts.deadlineMin,
18090
18245
  network: opts.network ?? null,
18091
18246
  negotiate: opts.negotiate,
18092
- protocol: opts.protocol
18247
+ protocol: opts.protocol,
18248
+ negotiationEnvelope
18093
18249
  });
18094
18250
  } catch (exc) {
18095
18251
  printErr(`error: ${errMsg5(exc)}`);
@@ -19328,6 +19484,9 @@ function registerX402(program) {
19328
19484
  ).option("--method <verb>", "HTTP verb to send (default: GET).", "GET").option(
19329
19485
  "--json <body>",
19330
19486
  "JSON body to send with the request (a string parsed as JSON)."
19487
+ ).option(
19488
+ "--local-dev",
19489
+ "DEV ONLY: skip the host allowlist for a localhost/127.0.0.1 target."
19331
19490
  ).action(
19332
19491
  act(
19333
19492
  (url, opts) => cmdQuote(url, opts)
@@ -19343,6 +19502,9 @@ function registerX402(program) {
19343
19502
  ).option("--method <verb>", "HTTP verb to send (default: GET).", "GET").option(
19344
19503
  "--json <body>",
19345
19504
  "JSON body to send with the request (a string parsed as JSON)."
19505
+ ).option(
19506
+ "--local-dev",
19507
+ "DEV ONLY: for a localhost/127.0.0.1 target, skip the host allowlist and accept the challenge's payTo as the recipient (printed loudly)."
19346
19508
  ).action(
19347
19509
  act(
19348
19510
  (url, opts) => cmdBuy2(url, opts)
@@ -19394,6 +19556,23 @@ function hostOf(url) {
19394
19556
  return "";
19395
19557
  }
19396
19558
  }
19559
+ function isLoopbackHost(host) {
19560
+ const h = host.toLowerCase().replace(/^\[|\]$/g, "");
19561
+ return h === "localhost" || h === "127.0.0.1" || h === "::1";
19562
+ }
19563
+ function printLocalDevHint(url) {
19564
+ printErr("hint: local dev seller detected. One command sets up everything:");
19565
+ printErr(` bag x402 trust ${url.split("?")[0]}`);
19566
+ printErr(
19567
+ " (adds the host to the allowlist AND pins the seller's payTo as the trusted recipient)"
19568
+ );
19569
+ printErr(
19570
+ "Or configure both by hand in studio.toml [payments.x402]: add the host to allowed_hosts and set expected_recipient."
19571
+ );
19572
+ printErr(
19573
+ "For a throwaway check you can also pass --local-dev to `bag x402 buy`/`quote` (loopback targets only)."
19574
+ );
19575
+ }
19397
19576
  function checkHostAllowed(url, allowedHosts) {
19398
19577
  const host = hostOf(url);
19399
19578
  const allowedLower = new Set(
@@ -19401,7 +19580,7 @@ function checkHostAllowed(url, allowedHosts) {
19401
19580
  );
19402
19581
  return allowedLower.has(host);
19403
19582
  }
19404
- function tableOf15(cfg, key) {
19583
+ function tableOf16(cfg, key) {
19405
19584
  const v = cfg[key];
19406
19585
  return v !== null && typeof v === "object" && !Array.isArray(v) ? v : {};
19407
19586
  }
@@ -19440,7 +19619,7 @@ function resolveNetwork3(cfg, override) {
19440
19619
  if (override) {
19441
19620
  return override;
19442
19621
  }
19443
- const net2 = tableOf15(cfg, "network").default;
19622
+ const net2 = tableOf16(cfg, "network").default;
19444
19623
  return net2 ? String(net2) : "bsc-mainnet";
19445
19624
  }
19446
19625
  function parseJsonBody(raw) {
@@ -19466,8 +19645,11 @@ function resolveWallet2() {
19466
19645
  return null;
19467
19646
  }
19468
19647
  }
19469
- function printScopeError(host) {
19648
+ function printScopeError(host, url) {
19470
19649
  printErr(`error: ${SCOPE_NOTE.replace("{host}", host)}`);
19650
+ if (url !== void 0 && isLoopbackHost(host)) {
19651
+ printLocalDevHint(url);
19652
+ }
19471
19653
  }
19472
19654
  async function cmdSellInit(priceFlag) {
19473
19655
  const loaded = loadSellerConfig();
@@ -19484,7 +19666,7 @@ async function cmdSellInit(priceFlag) {
19484
19666
  return 2;
19485
19667
  }
19486
19668
  const free = x402SellerPricingState({ price_usd: priceUsd }).kind === "free";
19487
- const walletKind2 = String(tableOf15(cfg, "wallet").kind ?? "evm-local");
19669
+ const walletKind2 = String(tableOf16(cfg, "wallet").kind ?? "evm-local");
19488
19670
  if (!free && !["evm-local", "twak"].includes(walletKind2)) {
19489
19671
  printErr(
19490
19672
  `error: the b402 seller rail supports wallet.kind evm-local or twak only; '${walletKind2}' cannot act as the b402 payout wallet.`
@@ -19644,8 +19826,12 @@ async function cmdQuote(url, opts) {
19644
19826
  printErr(`error: ${errMsg6(exc)}`);
19645
19827
  return 2;
19646
19828
  }
19647
- if (!checkHostAllowed(url, hosts)) {
19648
- printScopeError(hostOf(url) || url);
19829
+ if (opts.localDev && !isLoopbackHost(hostOf(url))) {
19830
+ printErr("error: --local-dev applies to localhost/127.0.0.1 targets only.");
19831
+ return 2;
19832
+ }
19833
+ if (!opts.localDev && !checkHostAllowed(url, hosts)) {
19834
+ printScopeError(hostOf(url) || url, url);
19649
19835
  return 1;
19650
19836
  }
19651
19837
  let body;
@@ -19653,7 +19839,7 @@ async function cmdQuote(url, opts) {
19653
19839
  body = await quoteUrl(url, {
19654
19840
  method: opts.method,
19655
19841
  jsonBody,
19656
- allowedHosts: hosts
19842
+ allowedHosts: opts.localDev ? null : hosts
19657
19843
  });
19658
19844
  } catch (exc) {
19659
19845
  printX402Error(exc);
@@ -19687,8 +19873,12 @@ async function cmdBuy2(url, opts) {
19687
19873
  return 1;
19688
19874
  }
19689
19875
  const [, cfg, hosts] = loaded;
19690
- if (!checkHostAllowed(url, hosts)) {
19691
- printScopeError(hostOf(url) || url);
19876
+ if (opts.localDev && !isLoopbackHost(hostOf(url))) {
19877
+ printErr("error: --local-dev applies to localhost/127.0.0.1 targets only.");
19878
+ return 2;
19879
+ }
19880
+ if (!opts.localDev && !checkHostAllowed(url, hosts)) {
19881
+ printScopeError(hostOf(url) || url, url);
19692
19882
  return 1;
19693
19883
  }
19694
19884
  let jsonBody;
@@ -19699,6 +19889,24 @@ async function cmdBuy2(url, opts) {
19699
19889
  return 2;
19700
19890
  }
19701
19891
  const networkName = resolveNetwork3(cfg, opts.network);
19892
+ let localDevExpectedTo = null;
19893
+ if (opts.localDev) {
19894
+ let challenge;
19895
+ try {
19896
+ challenge = await quoteUrl(url, { method: opts.method, jsonBody });
19897
+ } catch (exc) {
19898
+ printX402Error(exc);
19899
+ return 1;
19900
+ }
19901
+ const selected2 = selectPayable(challenge, networkName);
19902
+ if (selected2 === null) {
19903
+ return 1;
19904
+ }
19905
+ localDevExpectedTo = String(selected2[0].payTo);
19906
+ printOut(
19907
+ `\u26A0 DEV-ONLY --local-dev: accepting the challenge's payTo ${localDevExpectedTo} as the recipient without a configured pin. Never use this outside your own machine.`
19908
+ );
19909
+ }
19702
19910
  const wallet = resolveWallet2();
19703
19911
  if (wallet === null) {
19704
19912
  return 1;
@@ -19743,7 +19951,8 @@ async function cmdBuy2(url, opts) {
19743
19951
  networkName,
19744
19952
  method: opts.method,
19745
19953
  jsonBody,
19746
- allowedHosts: hosts
19954
+ allowedHosts: opts.localDev ? null : hosts,
19955
+ expectedTo: localDevExpectedTo
19747
19956
  });
19748
19957
  if (r.paidUsd !== null) {
19749
19958
  h.extraContext.paid_usd = r.paidUsd;
@@ -19756,6 +19965,9 @@ async function cmdBuy2(url, opts) {
19756
19965
  );
19757
19966
  } catch (exc) {
19758
19967
  printX402Error(exc);
19968
+ if (errName4(exc) === "X402RecipientRequiredError" && isLoopbackHost(hostOf(url))) {
19969
+ printLocalDevHint(url);
19970
+ }
19759
19971
  return 1;
19760
19972
  }
19761
19973
  const paidUsd = result.paidUsd ?? 0;
@@ -19869,10 +20081,19 @@ async function cmdTrust(merchant, opts) {
19869
20081
  if (merchant.includes("://")) {
19870
20082
  probeUrl = merchant;
19871
20083
  host = hostOf(probeUrl);
19872
- if (!probeUrl.toLowerCase().startsWith("https://") || !host) {
19873
- printErr("error: trust-by-URL needs an absolute https:// URL.");
20084
+ const plainHttp = probeUrl.toLowerCase().startsWith("http://");
20085
+ const localDevHttp = plainHttp && isLoopbackHost(host);
20086
+ if (!probeUrl.toLowerCase().startsWith("https://") && !localDevHttp || !host) {
20087
+ printErr(
20088
+ "error: trust-by-URL needs an absolute https:// URL (plain http:// is allowed only for localhost/127.0.0.1 dev sellers)."
20089
+ );
19874
20090
  return 1;
19875
20091
  }
20092
+ if (localDevHttp) {
20093
+ printOut(
20094
+ "\u26A0 DEV-ONLY: trusting a plain-http loopback seller. http:// carries no transport integrity \u2014 never trust it beyond your own machine."
20095
+ );
20096
+ }
19876
20097
  methodHint = null;
19877
20098
  } else {
19878
20099
  rec = RECOMMENDED_MERCHANTS[merchant.toLowerCase()] ?? null;
@@ -19952,7 +20173,7 @@ The merchant may have rotated its address (or the response was tampered with). U
19952
20173
  " \u26A0 MAINNET: calls spend real $U from the agent wallet. The cap above and [budget].max_per_day_usd bound the exposure."
19953
20174
  );
19954
20175
  }
19955
- const projectDefault = tableOf15(cfg, "network").default;
20176
+ const projectDefault = tableOf16(cfg, "network").default;
19956
20177
  if (projectDefault && String(projectDefault) !== networkName) {
19957
20178
  printOut(
19958
20179
  ` note: your project default is ${projectDefault}; this paid capability settles on ${networkName} independently of it.`
@@ -20033,7 +20254,7 @@ function buildProgram() {
20033
20254
  return program;
20034
20255
  }
20035
20256
  function cliVersion() {
20036
- return "0.0.6-alpha.5";
20257
+ return "0.0.6-alpha.6";
20037
20258
  }
20038
20259
 
20039
20260
  // src/cli/updateCheck.ts