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

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
@@ -1,5 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
+ B402_DEVELOPER_ACCOUNT_URL,
4
+ B402_PAID_ONBOARDING_GUIDANCE,
3
5
  B402_RUNTIME_KEYS,
4
6
  CliExit,
5
7
  DEFAULT_B402_PRICE_USD,
@@ -42,7 +44,7 @@ import {
42
44
  x402SellerIsFree,
43
45
  x402SellerPricingState,
44
46
  x402SellerUsesB402
45
- } from "./chunk-A7NAGZHR.js";
47
+ } from "./chunk-VEOOFDSF.js";
46
48
  import {
47
49
  TWAK_CLI_MIN_VERSION,
48
50
  TWAK_CLI_VERSION,
@@ -55,7 +57,7 @@ import {
55
57
  twakVersionBelowFloor,
56
58
  twakWalletFile,
57
59
  whichTwak
58
- } from "./chunk-7RAKL4AS.js";
60
+ } from "./chunk-RO726HJG.js";
59
61
  import {
60
62
  validateAgentcoreName
61
63
  } from "./chunk-U7IDQ3K5.js";
@@ -104,7 +106,7 @@ import {
104
106
  var CAMPAIGN_DOC_URL = "https://www.bnbchain.org/en/blog/bnb-agent-studio-is-live-on-bnb-chain-ai-agents-from-one-prompt";
105
107
  var CAMPAIGN_CHECK_TIMEOUT_MS = 6e3;
106
108
  async function fetchCampaignActive() {
107
- const { bnbPlatformApiUrl: bnbPlatformApiUrl2 } = await import("./deployCli-264UE6KB.js");
109
+ const { bnbPlatformApiUrl: bnbPlatformApiUrl2 } = await import("./deployCli-EEK75T67.js");
108
110
  const controller = new AbortController();
109
111
  const timer = setTimeout(() => controller.abort(), CAMPAIGN_CHECK_TIMEOUT_MS);
110
112
  try {
@@ -2552,7 +2554,7 @@ function cmdListKeys(projectRoot) {
2552
2554
  import * as fs37 from "fs";
2553
2555
  import * as path37 from "path";
2554
2556
  import {
2555
- envLocalPath as envLocalPath15,
2557
+ envLocalPath as envLocalPath16,
2556
2558
  findStudioWorkspaceRoot as findStudioWorkspaceRoot3,
2557
2559
  findSubProjectRoot as findSubProjectRoot16,
2558
2560
  loadStudioToml as loadStudioToml20
@@ -2987,24 +2989,24 @@ function hasIpfsEndpointFinding(result) {
2987
2989
  }
2988
2990
 
2989
2991
  // src/cli/_deploy/cognitoCdk.ts
2990
- import * as fs26 from "fs";
2991
- import * as path25 from "path";
2992
- import { envLocalPath as envLocalPath12 } from "@bnbagent/studio-runtime/config";
2992
+ import * as fs27 from "fs";
2993
+ import * as path26 from "path";
2994
+ import { envLocalPath as envLocalPath13 } from "@bnbagent/studio-runtime/config";
2993
2995
 
2994
2996
  // src/cli/_deploy/secrets.ts
2995
- import * as fs25 from "fs";
2996
- import * as path24 from "path";
2997
+ import * as fs26 from "fs";
2998
+ import * as path25 from "path";
2997
2999
  import {
2998
- envLocalPath as envLocalPath11,
2999
- findSubProjectRoot as findSubProjectRoot7,
3000
- loadStudioToml as loadStudioToml12
3000
+ envLocalPath as envLocalPath12,
3001
+ findSubProjectRoot as findSubProjectRoot8,
3002
+ loadStudioToml as loadStudioToml13
3001
3003
  } from "@bnbagent/studio-runtime/config";
3002
3004
 
3003
3005
  // src/cli/dev.ts
3004
- import * as fs23 from "fs";
3005
- import * as os4 from "os";
3006
- import * as path22 from "path";
3007
- import { loadStudioToml as loadStudioToml10 } from "@bnbagent/studio-runtime/config";
3006
+ import * as fs24 from "fs";
3007
+ import * as os5 from "os";
3008
+ import * as path23 from "path";
3009
+ import { loadStudioToml as loadStudioToml11 } from "@bnbagent/studio-runtime/config";
3008
3010
  import { getNetwork as getNetwork7 } from "@bnbagent/studio-runtime/networks";
3009
3011
  import { writePrivate as writePrivate2 } from "@bnbagent/studio-runtime/secretWrite";
3010
3012
  import { Option as Option3 } from "commander";
@@ -3078,6 +3080,20 @@ function migrateEnvLocal(start) {
3078
3080
  } catch {
3079
3081
  }
3080
3082
  }
3083
+ var KEYSTORE_WALLET_KINDS = /* @__PURE__ */ new Set(["evm-local", "altana"]);
3084
+ function readWalletKind(agentRoot2) {
3085
+ try {
3086
+ const wallet = loadStudioToml5(path11.join(agentRoot2, "studio.toml")).wallet;
3087
+ if (wallet !== null && typeof wallet === "object") {
3088
+ const kind = wallet.kind;
3089
+ if (typeof kind === "string" && kind.trim()) {
3090
+ return kind.trim();
3091
+ }
3092
+ }
3093
+ } catch {
3094
+ }
3095
+ return "evm-local";
3096
+ }
3081
3097
  function resolveKeystoreDir(agentRoot2) {
3082
3098
  let rel = ".studio/wallets";
3083
3099
  try {
@@ -3110,6 +3126,9 @@ function migrateKeystoreOutOfCodelocation(start) {
3110
3126
  }
3111
3127
  fs12.rmSync(stash, { recursive: true, force: true });
3112
3128
  }
3129
+ if (!KEYSTORE_WALLET_KINDS.has(readWalletKind(agentRoot2))) {
3130
+ return;
3131
+ }
3113
3132
  const src = resolveKeystoreDir(agentRoot2);
3114
3133
  const srcReal = realpathOr(src);
3115
3134
  const agentReal = realpathOr(agentRoot2);
@@ -3173,25 +3192,274 @@ function relocateKeys(src, target, label) {
3173
3192
  return true;
3174
3193
  }
3175
3194
 
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
+
3176
3233
  // src/cli/init.ts
3177
- import * as fs22 from "fs";
3178
- import * as os3 from "os";
3179
- import * as path21 from "path";
3234
+ import * as fs23 from "fs";
3235
+ import * as os4 from "os";
3236
+ import * as path22 from "path";
3180
3237
  import { getNetwork as getNetwork6 } from "@bnbagent/studio-runtime/networks";
3181
3238
  import { ensureTwakKeychain } from "@bnbagent/studio-runtime/wallet";
3182
3239
  import { Option as Option2 } from "commander";
3183
3240
  import { parse as parseToml } from "smol-toml";
3184
3241
 
3185
- // src/cli/_packageMetadata.ts
3242
+ // src/cli/_deploy/providers.ts
3186
3243
  import * as fs13 from "fs";
3187
3244
  import * as path12 from "path";
3245
+ import {
3246
+ findSubProjectRoot as findSubProjectRoot6,
3247
+ findWorkspaceRoot as findWorkspaceRoot4,
3248
+ loadStudioToml as loadStudioToml6
3249
+ } from "@bnbagent/studio-runtime/config";
3250
+ var PROVIDER_TARGETS = {
3251
+ bnb: "bnb/trial",
3252
+ aws: "aws/agentcore",
3253
+ azure: "azure/foundry"
3254
+ };
3255
+ var PROVIDER_LABELS = {
3256
+ bnb: "BNB Chain Trial",
3257
+ aws: "AWS AgentCore",
3258
+ azure: "Azure Foundry"
3259
+ };
3260
+ var PROVIDER_MENU_ORDER = [
3261
+ "bnb",
3262
+ "aws",
3263
+ "azure"
3264
+ ];
3265
+ var PROVIDER_SHORT_LABELS = {
3266
+ bnb: "BNB",
3267
+ aws: "AWS",
3268
+ azure: "Azure"
3269
+ };
3270
+ function providerDigit(provider) {
3271
+ return PROVIDER_MENU_ORDER.indexOf(provider) + 1;
3272
+ }
3273
+ var ADVERTISED_PROVIDERS = ["bnb", "aws"];
3274
+ var ADVERTISED_PROVIDERS_HELP = ADVERTISED_PROVIDERS.join("|");
3275
+ function tableOf3(data, key) {
3276
+ const value = data[key];
3277
+ return value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
3278
+ }
3279
+ function text(value) {
3280
+ if (typeof value !== "string") return null;
3281
+ const clean = value.trim();
3282
+ return clean || null;
3283
+ }
3284
+ function descriptorName(workspaceRoot) {
3285
+ try {
3286
+ const data = JSON.parse(
3287
+ fs13.readFileSync(
3288
+ path12.join(workspaceRoot, "agentcore", "agentcore.json"),
3289
+ "utf-8"
3290
+ )
3291
+ );
3292
+ return text(data.name);
3293
+ } catch {
3294
+ return null;
3295
+ }
3296
+ }
3297
+ function discoverRecordedDeployments(root) {
3298
+ const workspaceRoot = findWorkspaceRoot4(root) ?? path12.resolve(root);
3299
+ const agentRoot2 = findSubProjectRoot6("agent", workspaceRoot);
3300
+ if (agentRoot2 === null) return [];
3301
+ let config;
3302
+ try {
3303
+ config = loadStudioToml6(path12.join(agentRoot2, "studio.toml"));
3304
+ } catch {
3305
+ return [];
3306
+ }
3307
+ const projectName2 = descriptorName(workspaceRoot) ?? text(tableOf3(config, "project").name) ?? path12.basename(workspaceRoot);
3308
+ const deploy = tableOf3(config, "deploy");
3309
+ const platform = tableOf3(deploy, "platform");
3310
+ const azure = tableOf3(config, "azure");
3311
+ const runtime = text(tableOf3(config, "stack").runtime) ?? "agentcore";
3312
+ const found = [];
3313
+ const bnbId = text(platform.deployment_id);
3314
+ const bnbEndpoint = text(platform.invoke_url);
3315
+ if (bnbId || bnbEndpoint || text(platform.last_deploy_at)) {
3316
+ found.push({
3317
+ provider: "bnb",
3318
+ target: PROVIDER_TARGETS.bnb,
3319
+ name: text(platform.slug) ?? projectName2,
3320
+ deploymentId: bnbId,
3321
+ endpoint: bnbEndpoint,
3322
+ status: "active"
3323
+ });
3324
+ }
3325
+ const awsArn = text(deploy.runtime_arn);
3326
+ const awsEndpoint = text(deploy.invoke_url);
3327
+ const legacyAwsTimestamp = Boolean(text(deploy.last_deploy_at)) && runtime !== "azure-foundry" && text(deploy.destination) !== "platform";
3328
+ if (awsArn || awsEndpoint || text(deploy.provider) === "aws" || legacyAwsTimestamp) {
3329
+ found.push({
3330
+ provider: "aws",
3331
+ target: PROVIDER_TARGETS.aws,
3332
+ name: projectName2,
3333
+ deploymentId: awsArn,
3334
+ endpoint: awsEndpoint,
3335
+ status: "active"
3336
+ });
3337
+ }
3338
+ const azureEndpoint = text(azure.agent_endpoint);
3339
+ const azureDeploymentId = text(azure.deployment_id);
3340
+ if (azureEndpoint || azureDeploymentId || text(azure.last_deploy_at)) {
3341
+ found.push({
3342
+ provider: "azure",
3343
+ target: PROVIDER_TARGETS.azure,
3344
+ name: text(azure.agent_name) ?? projectName2,
3345
+ deploymentId: azureDeploymentId,
3346
+ endpoint: azureEndpoint,
3347
+ status: "active"
3348
+ });
3349
+ }
3350
+ return found;
3351
+ }
3352
+ function unavailableProvidersForProject(root) {
3353
+ const workspaceRoot = findWorkspaceRoot4(root) ?? path12.resolve(root);
3354
+ const agentRoot2 = findSubProjectRoot6("agent", workspaceRoot);
3355
+ if (agentRoot2 === null) return {};
3356
+ let runtime = "agentcore";
3357
+ let azureProtocolUnsupported = false;
3358
+ try {
3359
+ const cfg = loadStudioToml6(path12.join(agentRoot2, "studio.toml"));
3360
+ runtime = text(tableOf3(cfg, "stack").runtime) ?? "agentcore";
3361
+ const faces = stackFaces(tableOf3(cfg, "stack"), tableOf3(cfg, "payments"));
3362
+ azureProtocolUnsupported = !hasA2aFace(faces) || hasMcpFace(faces);
3363
+ } catch {
3364
+ return {};
3365
+ }
3366
+ if (runtime === "azure-foundry") {
3367
+ const reason = "this project uses a different container adapter; scaffold an agentcore project before selecting this provider";
3368
+ return {
3369
+ bnb: reason,
3370
+ aws: reason,
3371
+ ...azureProtocolUnsupported ? {
3372
+ azure: "Azure Foundry deploy currently supports A2A projects only; use an A2A azure-foundry scaffold or AgentCore for MCP"
3373
+ } : {}
3374
+ };
3375
+ }
3376
+ return {
3377
+ azure: "this project uses the agentcore adapter; scaffold with --runtime azure-foundry before selecting Azure"
3378
+ };
3379
+ }
3380
+ function selected(provider, deployments) {
3381
+ const active = deployments.filter((d) => d.status === "active");
3382
+ return {
3383
+ kind: "selected",
3384
+ provider,
3385
+ operation: active.some((d) => d.provider === provider) ? "update" : "create",
3386
+ hasOtherActive: active.some((d) => d.provider !== provider)
3387
+ };
3388
+ }
3389
+ function trialExpired(trial) {
3390
+ return trial.state.toLowerCase() === "expired";
3391
+ }
3392
+ function unavailableReason(opts, provider) {
3393
+ if (provider === "bnb" && trialExpired(opts.trial)) {
3394
+ return "the 48h trial has expired";
3395
+ }
3396
+ return opts.unavailable?.[provider] ?? null;
3397
+ }
3398
+ function providerPromptHint() {
3399
+ return PROVIDER_MENU_ORDER.filter((p) => ADVERTISED_PROVIDERS.includes(p)).map((p) => `${providerDigit(p)}=${PROVIDER_SHORT_LABELS[p]}`).join(", ");
3400
+ }
3401
+ async function promptProvider(opts) {
3402
+ for (; ; ) {
3403
+ const answer = (await opts.prompt(`Provider [${providerPromptHint()}]: `)).trim().toLowerCase();
3404
+ const provider = answer === "1" || answer === "bnb" ? "bnb" : answer === "2" || answer === "aws" ? "aws" : answer === "3" || answer === "azure" ? "azure" : null;
3405
+ if (provider === null) {
3406
+ if (answer === "" || answer === "q" || answer === "cancel") {
3407
+ return { kind: "cancelled", exitCode: 1 };
3408
+ }
3409
+ continue;
3410
+ }
3411
+ if (unavailableReason(opts, provider)) {
3412
+ continue;
3413
+ }
3414
+ return selected(provider, opts.deployments);
3415
+ }
3416
+ }
3417
+ async function selectDeployProvider(opts) {
3418
+ if (opts.requested) {
3419
+ const reason = unavailableReason(opts, opts.requested);
3420
+ if (reason) {
3421
+ return {
3422
+ kind: "unavailable",
3423
+ provider: opts.requested,
3424
+ reason,
3425
+ exitCode: 2
3426
+ };
3427
+ }
3428
+ return selected(opts.requested, opts.deployments);
3429
+ }
3430
+ if (!opts.interactive) {
3431
+ return { kind: "selection_required", exitCode: 2 };
3432
+ }
3433
+ const active = opts.deployments.filter((d) => d.status === "active");
3434
+ const activeDeployment = active[0];
3435
+ if (active.length === 1 && activeDeployment) {
3436
+ if (unavailableReason(opts, activeDeployment.provider)) {
3437
+ return promptProvider(opts);
3438
+ }
3439
+ const answer = (await opts.prompt(
3440
+ `Update the existing ${PROVIDER_LABELS[activeDeployment.provider]} deployment? [1=update, 2=another provider, 3=cancel]: `
3441
+ )).trim().toLowerCase();
3442
+ if (answer === "1" || answer === "update" || answer === "yes") {
3443
+ return selected(activeDeployment.provider, opts.deployments);
3444
+ }
3445
+ if (answer === "2" || answer === "another") {
3446
+ return promptProvider(opts);
3447
+ }
3448
+ return { kind: "cancelled", exitCode: 1 };
3449
+ }
3450
+ return promptProvider(opts);
3451
+ }
3452
+
3453
+ // src/cli/_packageMetadata.ts
3454
+ import * as fs14 from "fs";
3455
+ import * as path13 from "path";
3188
3456
  import { fileURLToPath as fileURLToPath2 } from "url";
3189
3457
  function packageRoot() {
3190
- let dir = path12.dirname(fileURLToPath2(import.meta.url));
3458
+ let dir = path13.dirname(fileURLToPath2(import.meta.url));
3191
3459
  for (; ; ) {
3192
- const packageJson = path12.join(dir, "package.json");
3193
- if (fs13.existsSync(packageJson)) return dir;
3194
- const parent = path12.dirname(dir);
3460
+ const packageJson = path13.join(dir, "package.json");
3461
+ if (fs14.existsSync(packageJson)) return dir;
3462
+ const parent = path13.dirname(dir);
3195
3463
  if (parent === dir) {
3196
3464
  throw new Error("cannot locate the studio-cli package root");
3197
3465
  }
@@ -3202,8 +3470,8 @@ function pnpmVersion() {
3202
3470
  if ("10.24.0") {
3203
3471
  return "10.24.0";
3204
3472
  }
3205
- const file = path12.join(packageRoot(), "package.json");
3206
- const pkg = JSON.parse(fs13.readFileSync(file, "utf-8"));
3473
+ const file = path13.join(packageRoot(), "package.json");
3474
+ const pkg = JSON.parse(fs14.readFileSync(file, "utf-8"));
3207
3475
  const value = String(pkg.packageManager ?? "");
3208
3476
  const match = /^pnpm@(.+)$/u.exec(value);
3209
3477
  if (!match?.[1]) {
@@ -3216,67 +3484,27 @@ function pnpmVersion() {
3216
3484
 
3217
3485
  // src/cli/_runtime/azureFoundry.ts
3218
3486
  import * as crypto2 from "crypto";
3219
- import * as fs16 from "fs";
3220
- import * as path15 from "path";
3487
+ import * as fs17 from "fs";
3488
+ import * as path16 from "path";
3221
3489
  import {
3222
3490
  findStudioWorkspaceRoot,
3223
- findSubProjectRoot as findSubProjectRoot6,
3224
- loadStudioToml as loadStudioToml6
3491
+ findSubProjectRoot as findSubProjectRoot7,
3492
+ loadStudioToml as loadStudioToml7
3225
3493
  } from "@bnbagent/studio-runtime/config";
3226
3494
  import { resolveProviderConfig } from "@bnbagent/studio-runtime/llm";
3227
3495
 
3228
3496
  // src/cli/_deploy/checks/twak.ts
3229
- import * as fs14 from "fs";
3230
- import * as path13 from "path";
3497
+ import * as fs15 from "fs";
3498
+ import * as path14 from "path";
3231
3499
  import { envLocalPath as envLocalPath7 } from "@bnbagent/studio-runtime/config";
3232
3500
  import { resolveTwakHome } from "@bnbagent/studio-runtime/wallet";
3233
-
3234
- // src/cli/_twakContractTargets.ts
3235
- import { resolveNetwork } from "@bnbagent/sdk";
3236
- var CONTRACT_OVERRIDES = [
3237
- ["ERC8004_REGISTRY_ADDRESS", "registryContract"],
3238
- ["ERC8183_COMMERCE_ADDRESS", "commerceContract"],
3239
- ["ERC8183_ROUTER_ADDRESS", "routerContract"],
3240
- ["ERC8183_POLICY_ADDRESS", "policyContract"]
3241
- ];
3242
- function twakCustomContractOverrides(networkName, env = process.env) {
3243
- let network;
3244
- try {
3245
- network = resolveNetwork(networkName);
3246
- } catch {
3247
- return [];
3248
- }
3249
- const erc8183 = erc8183ContractOverrideState(env);
3250
- const out = [];
3251
- for (const [envKey, field] of CONTRACT_OVERRIDES) {
3252
- if (envKey.startsWith("ERC8183_") && erc8183.mode !== "custom") {
3253
- continue;
3254
- }
3255
- const configured = env[envKey]?.trim() ?? "";
3256
- if (!/^0x[0-9a-fA-F]{40}$/u.test(configured)) {
3257
- continue;
3258
- }
3259
- const canonical = network[field];
3260
- if (configured.toLowerCase() !== canonical.toLowerCase()) {
3261
- out.push({ envKey, configured, canonical });
3262
- }
3263
- }
3264
- return out;
3265
- }
3266
- function twakUnsupportedContractOverrides(networkName, env = process.env) {
3267
- return twakCustomContractOverrides(networkName, env).filter(
3268
- (item) => item.envKey.startsWith("ERC8183_")
3269
- );
3270
- }
3271
-
3272
- // src/cli/_deploy/checks/twak.ts
3273
- var AGENTCORE_DESCRIPTOR = path13.join("agentcore", "agentcore.json");
3501
+ var AGENTCORE_DESCRIPTOR = path14.join("agentcore", "agentcore.json");
3274
3502
  function isTwak(data) {
3275
3503
  return tableOf2(data, "wallet").kind === "twak";
3276
3504
  }
3277
3505
  function isFile4(p) {
3278
3506
  try {
3279
- return fs14.statSync(p).isFile();
3507
+ return fs15.statSync(p).isFile();
3280
3508
  } catch {
3281
3509
  return false;
3282
3510
  }
@@ -3289,13 +3517,13 @@ async function checkTwakRequiresContainer(root, target) {
3289
3517
  if (!isTwak(data)) {
3290
3518
  return [];
3291
3519
  }
3292
- const descriptor = path13.join(root, AGENTCORE_DESCRIPTOR);
3520
+ const descriptor = path14.join(root, AGENTCORE_DESCRIPTOR);
3293
3521
  if (!isFile4(descriptor)) {
3294
3522
  return [];
3295
3523
  }
3296
3524
  let cfg;
3297
3525
  try {
3298
- cfg = JSON.parse(fs14.readFileSync(descriptor, "utf-8"));
3526
+ cfg = JSON.parse(fs15.readFileSync(descriptor, "utf-8"));
3299
3527
  } catch {
3300
3528
  return [];
3301
3529
  }
@@ -3318,7 +3546,7 @@ async function checkTwakRequiresContainer(root, target) {
3318
3546
  }
3319
3547
  ];
3320
3548
  }
3321
- const dockerfile = path13.join(agentRootOf(root), "Dockerfile");
3549
+ const dockerfile = path14.join(agentRootOf(root), "Dockerfile");
3322
3550
  if (!isFile4(dockerfile)) {
3323
3551
  return [
3324
3552
  {
@@ -3405,7 +3633,7 @@ async function checkTwakWalletExists(root, _target) {
3405
3633
  if (!isFile4(walletFile)) {
3406
3634
  let createCmd = "twak wallet create --password <pw> --no-keychain";
3407
3635
  if (walletCfg.twak_home) {
3408
- createCmd = `HOME=${path13.dirname(path13.dirname(walletFile))} ${createCmd}`;
3636
+ createCmd = `HOME=${path14.dirname(path14.dirname(walletFile))} ${createCmd}`;
3409
3637
  }
3410
3638
  return [
3411
3639
  {
@@ -3527,8 +3755,8 @@ async function checkTwakCredentialsAvailable(root, _target) {
3527
3755
  }
3528
3756
  const agentRoot2 = agentRootOf(root);
3529
3757
  const walletCfg = tableOf2(data, "wallet");
3530
- const credentialsFile = path13.join(
3531
- path13.dirname(twakWalletFile(walletCfg, agentRoot2)),
3758
+ const credentialsFile = path14.join(
3759
+ path14.dirname(twakWalletFile(walletCfg, agentRoot2)),
3532
3760
  "credentials.json"
3533
3761
  );
3534
3762
  const envLocal = envLocalPath7(agentRoot2);
@@ -3550,21 +3778,21 @@ async function checkTwakCredentialsAvailable(root, _target) {
3550
3778
  }
3551
3779
 
3552
3780
  // src/cli/_deploy/fixes.ts
3553
- import * as fs15 from "fs";
3554
- import * as path14 from "path";
3781
+ import * as fs16 from "fs";
3782
+ import * as path15 from "path";
3555
3783
  import { envLocalPath as envLocalPath8 } from "@bnbagent/studio-runtime/config";
3556
3784
  function fixGitignore(root) {
3557
- const ws = path14.dirname(path14.dirname(envLocalPath8(root)));
3558
- const gi = path14.join(ws, ".gitignore");
3785
+ const ws = path15.dirname(path15.dirname(envLocalPath8(root)));
3786
+ const gi = path15.join(ws, ".gitignore");
3559
3787
  const required = [".studio/"];
3560
3788
  let exists = false;
3561
3789
  try {
3562
- exists = fs15.statSync(gi).isFile();
3790
+ exists = fs16.statSync(gi).isFile();
3563
3791
  } catch {
3564
3792
  exists = false;
3565
3793
  }
3566
3794
  if (!exists) {
3567
- fs15.writeFileSync(gi, `${required.join("\n")}
3795
+ fs16.writeFileSync(gi, `${required.join("\n")}
3568
3796
  `, "utf-8");
3569
3797
  return {
3570
3798
  name: "fix-gitignore",
@@ -3572,7 +3800,7 @@ function fixGitignore(root) {
3572
3800
  message: `created .gitignore with ${required.length} entries`
3573
3801
  };
3574
3802
  }
3575
- let text2 = fs15.readFileSync(gi, "utf-8");
3803
+ let text2 = fs16.readFileSync(gi, "utf-8");
3576
3804
  const existing = new Set(text2.split(/\r?\n/).map((l) => l.trim()));
3577
3805
  const appended = required.filter((r) => !existing.has(r));
3578
3806
  if (appended.length === 0) {
@@ -3587,7 +3815,7 @@ function fixGitignore(root) {
3587
3815
  }
3588
3816
  text2 += `${appended.join("\n")}
3589
3817
  `;
3590
- fs15.writeFileSync(gi, text2, "utf-8");
3818
+ fs16.writeFileSync(gi, text2, "utf-8");
3591
3819
  return {
3592
3820
  name: "fix-gitignore",
3593
3821
  changed: true,
@@ -3595,10 +3823,10 @@ function fixGitignore(root) {
3595
3823
  };
3596
3824
  }
3597
3825
  function patchTomlKv(tomlPath, section, key, value) {
3598
- const text2 = fs15.readFileSync(tomlPath, "utf-8");
3826
+ const text2 = fs16.readFileSync(tomlPath, "utf-8");
3599
3827
  const updated = updateSection(text2, section, { [key]: value });
3600
3828
  if (updated !== text2) {
3601
- fs15.writeFileSync(tomlPath, updated, "utf-8");
3829
+ fs16.writeFileSync(tomlPath, updated, "utf-8");
3602
3830
  }
3603
3831
  }
3604
3832
 
@@ -3631,12 +3859,12 @@ var HOSTED_AGENT_REGIONS = /* @__PURE__ */ new Set([
3631
3859
  ]);
3632
3860
  function isFile5(p) {
3633
3861
  try {
3634
- return fs16.statSync(p).isFile();
3862
+ return fs17.statSync(p).isFile();
3635
3863
  } catch {
3636
3864
  return false;
3637
3865
  }
3638
3866
  }
3639
- function tableOf3(cfg, key) {
3867
+ function tableOf4(cfg, key) {
3640
3868
  const v = cfg[key];
3641
3869
  return v !== null && typeof v === "object" && !Array.isArray(v) ? v : {};
3642
3870
  }
@@ -3644,26 +3872,26 @@ function deployWorkspaceRoot(root) {
3644
3872
  return findStudioWorkspaceRoot(root) ?? root;
3645
3873
  }
3646
3874
  function loadStudioCfg(workspaceRoot) {
3647
- const agentRoot2 = findSubProjectRoot6("agent", workspaceRoot);
3875
+ const agentRoot2 = findSubProjectRoot7("agent", workspaceRoot);
3648
3876
  if (agentRoot2 === null) {
3649
3877
  return {};
3650
3878
  }
3651
- const tomlPath = path15.join(agentRoot2, "studio.toml");
3879
+ const tomlPath = path16.join(agentRoot2, "studio.toml");
3652
3880
  if (!isFile5(tomlPath)) {
3653
3881
  return {};
3654
3882
  }
3655
3883
  try {
3656
- return loadStudioToml6(tomlPath);
3884
+ return loadStudioToml7(tomlPath);
3657
3885
  } catch {
3658
3886
  return {};
3659
3887
  }
3660
3888
  }
3661
3889
  function recordAzureDeployment(root, data, endpoint) {
3662
- const agentRoot2 = findSubProjectRoot6("agent", deployWorkspaceRoot(root));
3890
+ const agentRoot2 = findSubProjectRoot7("agent", deployWorkspaceRoot(root));
3663
3891
  if (agentRoot2 === null) return;
3664
- const tomlPath = path15.join(agentRoot2, "studio.toml");
3892
+ const tomlPath = path16.join(agentRoot2, "studio.toml");
3665
3893
  try {
3666
- const name = String(data.id ?? tableOf3(data, "record").id ?? "").trim();
3894
+ const name = String(data.id ?? tableOf4(data, "record").id ?? "").trim();
3667
3895
  if (name) {
3668
3896
  patchTomlKv(tomlPath, "azure", "agent_name", name);
3669
3897
  patchTomlKv(tomlPath, "azure", "deployment_id", name);
@@ -3677,9 +3905,9 @@ function recordAzureDeployment(root, data, endpoint) {
3677
3905
  }
3678
3906
  }
3679
3907
  function clearAzureEndpoint(root) {
3680
- const agentRoot2 = findSubProjectRoot6("agent", deployWorkspaceRoot(root));
3908
+ const agentRoot2 = findSubProjectRoot7("agent", deployWorkspaceRoot(root));
3681
3909
  if (agentRoot2 === null) return;
3682
- const tomlPath = path15.join(agentRoot2, "studio.toml");
3910
+ const tomlPath = path16.join(agentRoot2, "studio.toml");
3683
3911
  try {
3684
3912
  for (const key of [
3685
3913
  "agent_endpoint",
@@ -3706,7 +3934,7 @@ function collectAzureSecretPayload(root) {
3706
3934
  const payload = collectRuntimeSecrets(root);
3707
3935
  try {
3708
3936
  const providerCfg = resolveProviderConfig(
3709
- tableOf3(loadStudioCfg(root), "llm")
3937
+ tableOf4(loadStudioCfg(root), "llm")
3710
3938
  );
3711
3939
  if (providerCfg.baseUrl) {
3712
3940
  payload[LLM_BASE_URL_ENV] = providerCfg.baseUrl;
@@ -3723,7 +3951,7 @@ function stripLeadingDdash(args) {
3723
3951
  return args[0] === "--" ? [...args.slice(1)] : [...args];
3724
3952
  }
3725
3953
  function recordOf(data) {
3726
- return tableOf3(data, "record");
3954
+ return tableOf4(data, "record");
3727
3955
  }
3728
3956
  async function deployAzureFoundry(opts) {
3729
3957
  const root = opts.projectRoot;
@@ -3798,7 +4026,7 @@ async function destroyAzureFoundry(opts) {
3798
4026
  const extra = opts.purge ? " --purge" : "";
3799
4027
  printOut("=== bag deploy destroy \u2014 teardown plan (dry-run) ===\n");
3800
4028
  printOut(
3801
- `project: ${path15.basename(workspaceRoot)} (runtime: azure-foundry)
4029
+ `project: ${path16.basename(workspaceRoot)} (runtime: azure-foundry)
3802
4030
  `
3803
4031
  );
3804
4032
  printOut("--- Agent (Foundry Hosted Agent) ---");
@@ -3837,11 +4065,11 @@ async function destroyAzureFoundry(opts) {
3837
4065
  }
3838
4066
  var OPENAI_COMPATIBLE_PROVIDERS = ["openai", "openrouter", "pieverse-llm"];
3839
4067
  function agentTomlPath(root) {
3840
- const agentRoot2 = findSubProjectRoot6("agent", root);
4068
+ const agentRoot2 = findSubProjectRoot7("agent", root);
3841
4069
  if (agentRoot2 === null) {
3842
4070
  return null;
3843
4071
  }
3844
- const tomlPath = path15.join(agentRoot2, "studio.toml");
4072
+ const tomlPath = path16.join(agentRoot2, "studio.toml");
3845
4073
  return isFile5(tomlPath) ? tomlPath : null;
3846
4074
  }
3847
4075
  function checkAzureBlock(root) {
@@ -3851,7 +4079,7 @@ function checkAzureBlock(root) {
3851
4079
  }
3852
4080
  let cfg;
3853
4081
  try {
3854
- cfg = loadStudioToml6(tomlPath);
4082
+ cfg = loadStudioToml7(tomlPath);
3855
4083
  } catch {
3856
4084
  return null;
3857
4085
  }
@@ -3865,7 +4093,7 @@ var checkStackRuntimeAzure = async (root, _target) => {
3865
4093
  }
3866
4094
  let cfg;
3867
4095
  try {
3868
- cfg = loadStudioToml6(tomlPath);
4096
+ cfg = loadStudioToml7(tomlPath);
3869
4097
  } catch (exc) {
3870
4098
  return [
3871
4099
  {
@@ -3875,7 +4103,7 @@ var checkStackRuntimeAzure = async (root, _target) => {
3875
4103
  }
3876
4104
  ];
3877
4105
  }
3878
- const runtime = String(tableOf3(cfg, "stack").runtime ?? "").trim();
4106
+ const runtime = String(tableOf4(cfg, "stack").runtime ?? "").trim();
3879
4107
  if (runtime !== "azure-foundry") {
3880
4108
  return [
3881
4109
  {
@@ -3957,13 +4185,13 @@ var checkAccountEqualsSubdomain = async (root, _target) => {
3957
4185
  return [];
3958
4186
  };
3959
4187
  var checkEntrypointAndDockerfile = async (root, _target) => {
3960
- const agentRoot2 = findSubProjectRoot6("agent", root);
4188
+ const agentRoot2 = findSubProjectRoot7("agent", root);
3961
4189
  if (agentRoot2 === null) {
3962
4190
  return [];
3963
4191
  }
3964
4192
  const findings = [];
3965
4193
  const cfg = loadStudioCfg(deployWorkspaceRoot(root));
3966
- const faces = stackFaces(tableOf3(cfg, "stack"), tableOf3(cfg, "payments"));
4194
+ const faces = stackFaces(tableOf4(cfg, "stack"), tableOf4(cfg, "payments"));
3967
4195
  if (!hasA2aFace(faces) || hasMcpFace(faces)) {
3968
4196
  return [
3969
4197
  {
@@ -3975,7 +4203,7 @@ var checkEntrypointAndDockerfile = async (root, _target) => {
3975
4203
  ];
3976
4204
  }
3977
4205
  const entry = "src/foundryMain.ts";
3978
- if (!isFile5(path15.join(agentRoot2, entry))) {
4206
+ if (!isFile5(path16.join(agentRoot2, entry))) {
3979
4207
  findings.push({
3980
4208
  level: "CRITICAL",
3981
4209
  name: "azure_agent_entrypoint",
@@ -3983,7 +4211,7 @@ var checkEntrypointAndDockerfile = async (root, _target) => {
3983
4211
  details: { entrypoint: entry }
3984
4212
  });
3985
4213
  }
3986
- if (!isFile5(path15.join(agentRoot2, "Dockerfile"))) {
4214
+ if (!isFile5(path16.join(agentRoot2, "Dockerfile"))) {
3987
4215
  findings.push({
3988
4216
  level: "CRITICAL",
3989
4217
  name: "azure_dockerfile_present",
@@ -3999,7 +4227,7 @@ var checkLlmExternalProviderReady = async (root, _target) => {
3999
4227
  }
4000
4228
  let cfg;
4001
4229
  try {
4002
- cfg = loadStudioToml6(tomlPath);
4230
+ cfg = loadStudioToml7(tomlPath);
4003
4231
  } catch {
4004
4232
  return [];
4005
4233
  }
@@ -4033,13 +4261,13 @@ var azureFoundryChecks = [
4033
4261
  ];
4034
4262
 
4035
4263
  // src/cli/llm.ts
4036
- import * as fs17 from "fs";
4037
- import * as path16 from "path";
4264
+ import * as fs18 from "fs";
4265
+ import * as path17 from "path";
4038
4266
  import { query as auditQuery, auditedOp } from "@bnbagent/studio-runtime/audit";
4039
4267
  import {
4040
4268
  envLocalPath as envLocalPath9,
4041
4269
  findProjectRoot as findProjectRoot2,
4042
- loadStudioToml as loadStudioToml7
4270
+ loadStudioToml as loadStudioToml8
4043
4271
  } from "@bnbagent/studio-runtime/config";
4044
4272
  import {
4045
4273
  pieverseKeyHash,
@@ -4076,12 +4304,12 @@ function isErrorNamed(exc, name) {
4076
4304
  function errMessage(exc) {
4077
4305
  return exc instanceof Error ? exc.message : String(exc);
4078
4306
  }
4079
- function tableOf4(cfg, key) {
4307
+ function tableOf5(cfg, key) {
4080
4308
  const v = cfg[key];
4081
4309
  return v !== null && typeof v === "object" && !Array.isArray(v) ? v : {};
4082
4310
  }
4083
4311
  function ensurePieverseProvider(cfg) {
4084
- const provider = tableOf4(cfg, "llm").provider;
4312
+ const provider = tableOf5(cfg, "llm").provider;
4085
4313
  if (provider !== "pieverse-llm") {
4086
4314
  const shown = provider === void 0 || provider === null ? "None" : `'${String(provider)}'`;
4087
4315
  throw new PieverseCliError(
@@ -4090,7 +4318,7 @@ function ensurePieverseProvider(cfg) {
4090
4318
  }
4091
4319
  }
4092
4320
  function loadPieverseConfig(cfg) {
4093
- return { ...tableOf4(tableOf4(cfg, "llm"), "pieverse") };
4321
+ return { ...tableOf5(tableOf5(cfg, "llm"), "pieverse") };
4094
4322
  }
4095
4323
  function resolvePieverseNetwork(cfg, networkOverride) {
4096
4324
  if (networkOverride) {
@@ -4100,7 +4328,7 @@ function resolvePieverseNetwork(cfg, networkOverride) {
4100
4328
  if (pvCfg.network) {
4101
4329
  return String(pvCfg.network);
4102
4330
  }
4103
- const projectDefault = tableOf4(cfg, "network").default;
4331
+ const projectDefault = tableOf5(cfg, "network").default;
4104
4332
  return projectDefault ? String(projectDefault) : "bsc-mainnet";
4105
4333
  }
4106
4334
  function printUBalanceShortfall(walletAddress, currentRaw, neededRaw, neededUsd, networkName) {
@@ -4149,7 +4377,7 @@ var API_KEY_ENV = {
4149
4377
  // uses AWS credentials chain, no single env var
4150
4378
  };
4151
4379
  var PIEVERSE_ENV_KEY = "PIEVERSE_LLM_API_KEY";
4152
- function tableOf5(cfg, key) {
4380
+ function tableOf6(cfg, key) {
4153
4381
  const v = cfg[key];
4154
4382
  return v !== null && typeof v === "object" && !Array.isArray(v) ? v : {};
4155
4383
  }
@@ -4238,8 +4466,8 @@ function registerLlm(program) {
4238
4466
  );
4239
4467
  }
4240
4468
  function loadLlmCfg(providerOverride) {
4241
- const cfg = loadStudioToml7();
4242
- const llmCfg = { ...tableOf5(cfg, "llm") };
4469
+ const cfg = loadStudioToml8();
4470
+ const llmCfg = { ...tableOf6(cfg, "llm") };
4243
4471
  if (providerOverride) {
4244
4472
  llmCfg.provider = providerOverride;
4245
4473
  }
@@ -4309,7 +4537,7 @@ function loadFullCfg() {
4309
4537
  }
4310
4538
  let cfg;
4311
4539
  try {
4312
- cfg = loadStudioToml7(path16.join(root, "studio.toml"));
4540
+ cfg = loadStudioToml8(path17.join(root, "studio.toml"));
4313
4541
  } catch (exc) {
4314
4542
  printErr(`error: failed to parse studio.toml: ${errMessage(exc)}`);
4315
4543
  return null;
@@ -4350,7 +4578,7 @@ function requirePieverse(cfg) {
4350
4578
  }
4351
4579
  function expectedRecipientOf(cfg) {
4352
4580
  return String(
4353
- tableOf5(tableOf5(cfg, "payments"), "x402").expected_recipient ?? ""
4581
+ tableOf6(tableOf6(cfg, "payments"), "x402").expected_recipient ?? ""
4354
4582
  ).trim();
4355
4583
  }
4356
4584
  function printAllocateDeferred(amountUsd, keyHash, exc) {
@@ -4392,7 +4620,8 @@ async function cmdActivate(opts) {
4392
4620
  }
4393
4621
  const pvCfg = loadPieverseConfig(cfg);
4394
4622
  let existingHash = pvCfg.key_hash ? String(pvCfg.key_hash) : null;
4395
- const existingEnv = getEnvVar(envLocalPath9(root), PIEVERSE_ENV_KEY) || process.env[PIEVERSE_ENV_KEY];
4623
+ const envFileValue = getEnvVar(envLocalPath9(root), PIEVERSE_ENV_KEY);
4624
+ const existingEnv = envFileValue || process.env[PIEVERSE_ENV_KEY];
4396
4625
  if (!existingHash && existingEnv) {
4397
4626
  const derivedHash = pieverseKeyHash(existingEnv);
4398
4627
  printOut(
@@ -4401,11 +4630,15 @@ async function cmdActivate(opts) {
4401
4630
  try {
4402
4631
  await withSiweRetry(wallet, (token) => inspectKey(token, derivedHash));
4403
4632
  } catch (exc) {
4633
+ const sources = [
4634
+ envFileValue ? `.studio/.env.local (a ${PIEVERSE_ENV_KEY}= line)` : "",
4635
+ process.env[PIEVERSE_ENV_KEY] ? "the shell environment" : ""
4636
+ ].filter(Boolean).join(" and ");
4404
4637
  printErr(
4405
4638
  `error: ${PIEVERSE_ENV_KEY} already exists but its derived key_hash could not be verified: ${errMessage(
4406
4639
  exc
4407
4640
  )}
4408
- The existing key was kept and no new key was created. Restore its key_hash or run \`bag llm rotate\` for an explicit replacement.`
4641
+ The existing key was kept and no new key was created. The key comes from ${sources}; \`bag\` reads both, so clear every source \u2014 remove the ${PIEVERSE_ENV_KEY}= line from .studio/.env.local AND \`unset ${PIEVERSE_ENV_KEY}\` in the shell \u2014 then re-run \`bag llm activate\` to mint a fresh key. (\`bag llm rotate\` replaces a key that is still valid in Pieverse; it cannot recover this one.)`
4409
4642
  );
4410
4643
  return 2;
4411
4644
  }
@@ -4646,9 +4879,9 @@ Retry: re-run \`bag llm activate\` \u2014 key_hash is saved so it will pick up w
4646
4879
  return 0;
4647
4880
  }
4648
4881
  function updateStudioTomlSection(root, section, updates) {
4649
- const tomlPath = path16.join(root, "studio.toml");
4650
- const text2 = fs17.readFileSync(tomlPath, "utf-8");
4651
- fs17.writeFileSync(tomlPath, updateSection(text2, section, updates), "utf-8");
4882
+ const tomlPath = path17.join(root, "studio.toml");
4883
+ const text2 = fs18.readFileSync(tomlPath, "utf-8");
4884
+ fs18.writeFileSync(tomlPath, updateSection(text2, section, updates), "utf-8");
4652
4885
  }
4653
4886
  function cumulativeTopupsUsd() {
4654
4887
  let total = 0;
@@ -4739,8 +4972,8 @@ async function cmdStatus(full) {
4739
4972
  const remainingRaw = info.remaining_usd;
4740
4973
  const remaining = remainingRaw === void 0 || remainingRaw === null ? null : Number(remainingRaw);
4741
4974
  const balanceStr = remaining === null ? "unknown (Pieverse inspect endpoint did not return balance field)" : `$${remaining.toFixed(4)}`;
4742
- const llmCfg = tableOf5(cfg, "llm");
4743
- const policy = pieversePolicyFromToml(tableOf5(llmCfg, "auto_renew"));
4975
+ const llmCfg = tableOf6(cfg, "llm");
4976
+ const policy = pieversePolicyFromToml(tableOf6(llmCfg, "auto_renew"));
4744
4977
  printOut("provider: pieverse-llm");
4745
4978
  const model = llmCfg.model ? String(llmCfg.model) : null;
4746
4979
  printOut(`model: ${model ?? "(unset \u2014 provider default)"}`);
@@ -4844,9 +5077,9 @@ function autoRenewStatus() {
4844
5077
  }
4845
5078
  const [cfg] = loaded;
4846
5079
  const llmPolicy = pieversePolicyFromToml(
4847
- tableOf5(tableOf5(cfg, "llm"), "auto_renew")
5080
+ tableOf6(tableOf6(cfg, "llm"), "auto_renew")
4848
5081
  );
4849
- const budgetPolicy = policyFromToml(tableOf5(cfg, "budget"));
5082
+ const budgetPolicy = policyFromToml(tableOf6(cfg, "budget"));
4850
5083
  printOut("auto-renew status (two independent tiers):");
4851
5084
  printOut("");
4852
5085
  printOut(
@@ -5197,8 +5430,8 @@ function normalizeNodeDeps(deps) {
5197
5430
  }
5198
5431
 
5199
5432
  // src/cli/recipes/loader.ts
5200
- import * as fs18 from "fs";
5201
- import * as path17 from "path";
5433
+ import * as fs19 from "fs";
5434
+ import * as path18 from "path";
5202
5435
  import { fileURLToPath as fileURLToPath3 } from "url";
5203
5436
  import { parse as parse5 } from "smol-toml";
5204
5437
  var PLACEHOLDER_RE = /\{\{\s*([A-Za-z_][A-Za-z0-9_]*)\s*\}\}/g;
@@ -5207,12 +5440,12 @@ function bundledRecipesRoot() {
5207
5440
  if (override) {
5208
5441
  return override;
5209
5442
  }
5210
- let dir = path17.dirname(fileURLToPath3(import.meta.url));
5443
+ let dir = path18.dirname(fileURLToPath3(import.meta.url));
5211
5444
  for (; ; ) {
5212
- if (fs18.existsSync(path17.join(dir, "package.json"))) {
5213
- return path17.join(dir, "recipes");
5445
+ if (fs19.existsSync(path18.join(dir, "package.json"))) {
5446
+ return path18.join(dir, "recipes");
5214
5447
  }
5215
- const parent = path17.dirname(dir);
5448
+ const parent = path18.dirname(dir);
5216
5449
  if (parent === dir) {
5217
5450
  throw new Error("cannot locate the studio-cli package root");
5218
5451
  }
@@ -5236,24 +5469,24 @@ function defaultMode(recipe) {
5236
5469
  }
5237
5470
  function listRecipes(root) {
5238
5471
  const base = root ?? bundledRecipesRoot();
5239
- if (!fs18.existsSync(base)) {
5472
+ if (!fs19.existsSync(base)) {
5240
5473
  return [];
5241
5474
  }
5242
- return fs18.readdirSync(base).filter(
5243
- (name) => !name.startsWith("_") && fs18.existsSync(path17.join(base, name, "recipe.toml")) && fs18.statSync(path17.join(base, name)).isDirectory()
5475
+ return fs19.readdirSync(base).filter(
5476
+ (name) => !name.startsWith("_") && fs19.existsSync(path18.join(base, name, "recipe.toml")) && fs19.statSync(path18.join(base, name)).isDirectory()
5244
5477
  ).sort();
5245
5478
  }
5246
5479
  var RecipeModeError = class extends Error {
5247
5480
  };
5248
5481
  function loadRecipe(name, opts = {}) {
5249
5482
  const base = opts.root ?? bundledRecipesRoot();
5250
- const recipeDir = path17.join(base, name);
5251
- const tomlPath = path17.join(recipeDir, "recipe.toml");
5252
- if (!fs18.existsSync(tomlPath) || !fs18.statSync(tomlPath).isFile()) {
5483
+ const recipeDir = path18.join(base, name);
5484
+ const tomlPath = path18.join(recipeDir, "recipe.toml");
5485
+ if (!fs19.existsSync(tomlPath) || !fs19.statSync(tomlPath).isFile()) {
5253
5486
  throw new Error(`Recipe '${name}' not found at ${tomlPath}`);
5254
5487
  }
5255
- const metadata = parse5(fs18.readFileSync(tomlPath, "utf-8"));
5256
- const allFiles = collectTemplateFiles(path17.join(recipeDir, "code"));
5488
+ const metadata = parse5(fs19.readFileSync(tomlPath, "utf-8"));
5489
+ const allFiles = collectTemplateFiles(path18.join(recipeDir, "code"));
5257
5490
  const modesMeta = metaTable(metadata, "modes");
5258
5491
  const mode = opts.mode ?? null;
5259
5492
  if (Object.keys(modesMeta).length === 0) {
@@ -5300,22 +5533,22 @@ function modeFiles(modesMeta, modeName) {
5300
5533
  return Array.isArray(files) ? files.filter((f) => typeof f === "string") : [];
5301
5534
  }
5302
5535
  function collectTemplateFiles(codeDir) {
5303
- if (!fs18.existsSync(codeDir) || !fs18.statSync(codeDir).isDirectory()) {
5536
+ if (!fs19.existsSync(codeDir) || !fs19.statSync(codeDir).isDirectory()) {
5304
5537
  return [];
5305
5538
  }
5306
5539
  const out = [];
5307
5540
  const walk = (dir) => {
5308
- for (const name of fs18.readdirSync(dir).sort()) {
5309
- const full = path17.join(dir, name);
5310
- if (fs18.statSync(full).isDirectory()) {
5541
+ for (const name of fs19.readdirSync(dir).sort()) {
5542
+ const full = path18.join(dir, name);
5543
+ if (fs19.statSync(full).isDirectory()) {
5311
5544
  walk(full);
5312
5545
  } else {
5313
- const rel = path17.relative(codeDir, full);
5546
+ const rel = path18.relative(codeDir, full);
5314
5547
  const target = rel.endsWith(".tmpl") ? rel.slice(0, -".tmpl".length) : rel;
5315
5548
  out.push({
5316
5549
  // Recipes use forward slashes regardless of host OS.
5317
- targetPath: target.split(path17.sep).join("/"),
5318
- content: fs18.readFileSync(full, "utf-8")
5550
+ targetPath: target.split(path18.sep).join("/"),
5551
+ content: fs19.readFileSync(full, "utf-8")
5319
5552
  });
5320
5553
  }
5321
5554
  }
@@ -5382,9 +5615,9 @@ function renderRecipe(recipe, opts = {}) {
5382
5615
 
5383
5616
  // src/cli/skillsInstaller.ts
5384
5617
  import * as crypto3 from "crypto";
5385
- import * as fs19 from "fs";
5618
+ import * as fs20 from "fs";
5386
5619
  import * as os2 from "os";
5387
- import * as path18 from "path";
5620
+ import * as path19 from "path";
5388
5621
  import { fileURLToPath as fileURLToPath4 } from "url";
5389
5622
  var SUPPORTED_TARGETS = ["claude-code", "cursor"];
5390
5623
  var SUPPORTED_SCOPES = ["user", "project"];
@@ -5431,14 +5664,14 @@ var HIDDEN_SKILL_NAMES = /* @__PURE__ */ new Set([
5431
5664
  ]);
5432
5665
  function isDir3(p) {
5433
5666
  try {
5434
- return fs19.statSync(p).isDirectory();
5667
+ return fs20.statSync(p).isDirectory();
5435
5668
  } catch {
5436
5669
  return false;
5437
5670
  }
5438
5671
  }
5439
5672
  function isFile6(p) {
5440
5673
  try {
5441
- return fs19.statSync(p).isFile();
5674
+ return fs20.statSync(p).isFile();
5442
5675
  } catch {
5443
5676
  return false;
5444
5677
  }
@@ -5448,15 +5681,15 @@ function sha256(text2) {
5448
5681
  }
5449
5682
  function resolveSkillsSource() {
5450
5683
  const pkgRoot = packageRoot2();
5451
- return pkgRoot !== null ? path18.join(pkgRoot, "skills") : path18.join(path18.dirname(fileURLToPath4(import.meta.url)), "skills");
5684
+ return pkgRoot !== null ? path19.join(pkgRoot, "skills") : path19.join(path19.dirname(fileURLToPath4(import.meta.url)), "skills");
5452
5685
  }
5453
5686
  function packageRoot2() {
5454
- let dir = path18.dirname(fileURLToPath4(import.meta.url));
5687
+ let dir = path19.dirname(fileURLToPath4(import.meta.url));
5455
5688
  for (; ; ) {
5456
- if (fs19.existsSync(path18.join(dir, "package.json"))) {
5689
+ if (fs20.existsSync(path19.join(dir, "package.json"))) {
5457
5690
  return dir;
5458
5691
  }
5459
- const parent = path18.dirname(dir);
5692
+ const parent = path19.dirname(dir);
5460
5693
  if (parent === dir) {
5461
5694
  return null;
5462
5695
  }
@@ -5468,18 +5701,18 @@ function listSourceSkills(source) {
5468
5701
  if (!isDir3(source)) {
5469
5702
  return [];
5470
5703
  }
5471
- return fs19.readdirSync(source).filter(
5472
- (name) => name.endsWith(".md") && !name.startsWith("_") && !HIDDEN_SKILL_NAMES.has(stem(name)) && isFile6(path18.join(source, name))
5473
- ).sort().map((name) => path18.join(source, name));
5704
+ return fs20.readdirSync(source).filter(
5705
+ (name) => name.endsWith(".md") && !name.startsWith("_") && !HIDDEN_SKILL_NAMES.has(stem(name)) && isFile6(path19.join(source, name))
5706
+ ).sort().map((name) => path19.join(source, name));
5474
5707
  }
5475
5708
  function listSourceReferences(source) {
5476
- const refs = path18.join(source, "references");
5709
+ const refs = path19.join(source, "references");
5477
5710
  if (!isDir3(refs)) {
5478
5711
  return [];
5479
5712
  }
5480
- return fs19.readdirSync(refs).filter(
5481
- (name) => name.endsWith(".md") && !name.startsWith("_") && !HIDDEN_SKILL_NAMES.has(stem(name)) && isFile6(path18.join(refs, name))
5482
- ).sort().map((name) => path18.join(refs, name));
5713
+ return fs20.readdirSync(refs).filter(
5714
+ (name) => name.endsWith(".md") && !name.startsWith("_") && !HIDDEN_SKILL_NAMES.has(stem(name)) && isFile6(path19.join(refs, name))
5715
+ ).sort().map((name) => path19.join(refs, name));
5483
5716
  }
5484
5717
  function stem(fileName) {
5485
5718
  return fileName.replace(/\.[^.]+$/, "");
@@ -5487,15 +5720,15 @@ function stem(fileName) {
5487
5720
  function whichSync(name) {
5488
5721
  const pathEnv = process.env.PATH ?? "";
5489
5722
  const exts = process.platform === "win32" ? ["", ".cmd", ".exe", ".bat"] : [""];
5490
- for (const dir of pathEnv.split(path18.delimiter)) {
5723
+ for (const dir of pathEnv.split(path19.delimiter)) {
5491
5724
  if (!dir) {
5492
5725
  continue;
5493
5726
  }
5494
5727
  for (const ext of exts) {
5495
- const candidate = path18.join(dir, name + ext);
5728
+ const candidate = path19.join(dir, name + ext);
5496
5729
  try {
5497
- fs19.accessSync(candidate, fs19.constants.X_OK);
5498
- if (fs19.statSync(candidate).isFile()) {
5730
+ fs20.accessSync(candidate, fs20.constants.X_OK);
5731
+ if (fs20.statSync(candidate).isFile()) {
5499
5732
  return candidate;
5500
5733
  }
5501
5734
  } catch {
@@ -5506,14 +5739,14 @@ function whichSync(name) {
5506
5739
  }
5507
5740
  function claudeCodeInstalled(opts = {}) {
5508
5741
  const home = opts.home ?? os2.homedir();
5509
- if (isDir3(path18.join(home, ".claude"))) {
5742
+ if (isDir3(path19.join(home, ".claude"))) {
5510
5743
  return true;
5511
5744
  }
5512
5745
  return (opts.which ?? whichSync)("claude") !== null;
5513
5746
  }
5514
5747
  function cursorInstalled(opts = {}) {
5515
5748
  const home = opts.home ?? os2.homedir();
5516
- if (isDir3(path18.join(home, ".cursor"))) {
5749
+ if (isDir3(path19.join(home, ".cursor"))) {
5517
5750
  return true;
5518
5751
  }
5519
5752
  return (opts.which ?? whichSync)("cursor") !== null;
@@ -5536,9 +5769,9 @@ function anySkillsInstalled(opts = {}) {
5536
5769
  for (const target of detectTargets(opts)) {
5537
5770
  const tdir = resolveTargetDir({ target, scope: "user", home: opts.home });
5538
5771
  for (const skill of sources) {
5539
- const name = stem(path18.basename(skill));
5540
- const rel = target === "claude-code" ? path18.join(name, "SKILL.md") : `${name}.mdc`;
5541
- if (isFile6(path18.join(tdir, rel))) {
5772
+ const name = stem(path19.basename(skill));
5773
+ const rel = target === "claude-code" ? path19.join(name, "SKILL.md") : `${name}.mdc`;
5774
+ if (isFile6(path19.join(tdir, rel))) {
5542
5775
  return true;
5543
5776
  }
5544
5777
  }
@@ -5563,7 +5796,7 @@ function resolveTargetDir(opts) {
5563
5796
  }
5564
5797
  const base = scope === "user" ? opts.home ?? os2.homedir() : opts.projectRoot ?? process.cwd();
5565
5798
  const [d1, d2] = TARGET_SUBDIR[target];
5566
- return path18.join(base, d1, d2);
5799
+ return path19.join(base, d1, d2);
5567
5800
  }
5568
5801
  function splitFrontmatter(text2) {
5569
5802
  const lines = text2.split("\n");
@@ -5621,16 +5854,16 @@ function iterRenderedPayloads(src, target) {
5621
5854
  for (const skill of listSourceSkills(src)) {
5622
5855
  payloads.push(
5623
5856
  renderSkillPayload(
5624
- fs19.readFileSync(skill, "utf-8"),
5625
- stem(path18.basename(skill)),
5857
+ fs20.readFileSync(skill, "utf-8"),
5858
+ stem(path19.basename(skill)),
5626
5859
  target
5627
5860
  )
5628
5861
  );
5629
5862
  }
5630
5863
  for (const ref of listSourceReferences(src)) {
5631
5864
  payloads.push([
5632
- `${ROUTER_SKILL_NAME}/references/${path18.basename(ref)}`,
5633
- fs19.readFileSync(ref, "utf-8")
5865
+ `${ROUTER_SKILL_NAME}/references/${path19.basename(ref)}`,
5866
+ fs20.readFileSync(ref, "utf-8")
5634
5867
  ]);
5635
5868
  }
5636
5869
  return payloads;
@@ -5642,7 +5875,7 @@ function packageVersion() {
5642
5875
  return "unknown";
5643
5876
  }
5644
5877
  const pkg = JSON.parse(
5645
- fs19.readFileSync(path18.join(root, "package.json"), "utf-8")
5878
+ fs20.readFileSync(path19.join(root, "package.json"), "utf-8")
5646
5879
  );
5647
5880
  return typeof pkg.version === "string" ? pkg.version : "unknown";
5648
5881
  } catch {
@@ -5661,11 +5894,11 @@ function contentKey(payloads) {
5661
5894
  return h.digest("hex");
5662
5895
  }
5663
5896
  function metaPath(tdir) {
5664
- return path18.join(tdir, ROUTER_SKILL_NAME, META_FILENAME);
5897
+ return path19.join(tdir, ROUTER_SKILL_NAME, META_FILENAME);
5665
5898
  }
5666
5899
  function loadMeta(tdir) {
5667
5900
  try {
5668
- const data = JSON.parse(fs19.readFileSync(metaPath(tdir), "utf-8"));
5901
+ const data = JSON.parse(fs20.readFileSync(metaPath(tdir), "utf-8"));
5669
5902
  return data !== null && typeof data === "object" && !Array.isArray(data) ? data : null;
5670
5903
  } catch {
5671
5904
  return null;
@@ -5682,15 +5915,15 @@ function writeMeta(tdir, payloads) {
5682
5915
  package_version: packageVersion()
5683
5916
  };
5684
5917
  const p = metaPath(tdir);
5685
- fs19.mkdirSync(path18.dirname(p), { recursive: true });
5686
- fs19.writeFileSync(p, `${JSON.stringify(meta, null, 2)}
5918
+ fs20.mkdirSync(path19.dirname(p), { recursive: true });
5919
+ fs20.writeFileSync(p, `${JSON.stringify(meta, null, 2)}
5687
5920
  `);
5688
5921
  }
5689
5922
  function installedMarker(tdir, target) {
5690
5923
  if (target === "cursor") {
5691
- return path18.join(tdir, `${ROUTER_SKILL_NAME}.mdc`);
5924
+ return path19.join(tdir, `${ROUTER_SKILL_NAME}.mdc`);
5692
5925
  }
5693
- return path18.join(tdir, ROUTER_SKILL_NAME, "SKILL.md");
5926
+ return path19.join(tdir, ROUTER_SKILL_NAME, "SKILL.md");
5694
5927
  }
5695
5928
  function syncInstalledSkills(opts = {}) {
5696
5929
  const src = opts.source ?? SKILLS_SOURCE;
@@ -5727,15 +5960,15 @@ function syncOneDir(tdir, payloads) {
5727
5960
  const wrote = [];
5728
5961
  const keptEdited = [];
5729
5962
  for (const [rel, content] of payloads) {
5730
- const dest = path18.join(tdir, rel);
5963
+ const dest = path19.join(tdir, rel);
5731
5964
  const newHash = sha256(content);
5732
- const cur = isFile6(dest) ? sha256(fs19.readFileSync(dest, "utf-8")) : null;
5965
+ const cur = isFile6(dest) ? sha256(fs20.readFileSync(dest, "utf-8")) : null;
5733
5966
  if (cur === newHash) {
5734
5967
  continue;
5735
5968
  }
5736
5969
  if (cur === null || cur === recordedFiles[rel]) {
5737
- fs19.mkdirSync(path18.dirname(dest), { recursive: true });
5738
- fs19.writeFileSync(dest, content);
5970
+ fs20.mkdirSync(path19.dirname(dest), { recursive: true });
5971
+ fs20.writeFileSync(dest, content);
5739
5972
  wrote.push(rel);
5740
5973
  } else {
5741
5974
  keptEdited.push(rel);
@@ -5746,15 +5979,15 @@ function syncOneDir(tdir, payloads) {
5746
5979
  if (shipped.has(rel)) {
5747
5980
  continue;
5748
5981
  }
5749
- const dest = path18.join(tdir, rel);
5982
+ const dest = path19.join(tdir, rel);
5750
5983
  try {
5751
- if (isFile6(dest) && sha256(fs19.readFileSync(dest, "utf-8")) === recorded) {
5752
- fs19.unlinkSync(dest);
5984
+ if (isFile6(dest) && sha256(fs20.readFileSync(dest, "utf-8")) === recorded) {
5985
+ fs20.unlinkSync(dest);
5753
5986
  wrote.push(`removed ${rel}`);
5754
- let parent = path18.dirname(dest);
5755
- while (parent !== tdir && isDir3(parent) && fs19.readdirSync(parent).length === 0) {
5756
- fs19.rmdirSync(parent);
5757
- parent = path18.dirname(parent);
5987
+ let parent = path19.dirname(dest);
5988
+ while (parent !== tdir && isDir3(parent) && fs20.readdirSync(parent).length === 0) {
5989
+ fs20.rmdirSync(parent);
5990
+ parent = path19.dirname(parent);
5758
5991
  }
5759
5992
  }
5760
5993
  } catch {
@@ -5784,45 +6017,45 @@ function installSkills(opts) {
5784
6017
  projectRoot: opts.projectRoot,
5785
6018
  home: opts.home
5786
6019
  });
5787
- fs19.mkdirSync(tdir, { recursive: true });
6020
+ fs20.mkdirSync(tdir, { recursive: true });
5788
6021
  const installed = [];
5789
6022
  const skipped = [];
5790
6023
  for (const skill of skillFiles) {
5791
- const skillName = stem(path18.basename(skill));
5792
- const srcText = fs19.readFileSync(skill, "utf-8");
6024
+ const skillName = stem(path19.basename(skill));
6025
+ const srcText = fs20.readFileSync(skill, "utf-8");
5793
6026
  const [relPath, content] = renderSkillPayload(srcText, skillName, target);
5794
- const dest = path18.join(tdir, relPath);
5795
- fs19.mkdirSync(path18.dirname(dest), { recursive: true });
5796
- if (isFile6(dest) && sha256(fs19.readFileSync(dest, "utf-8")) === sha256(content)) {
6027
+ const dest = path19.join(tdir, relPath);
6028
+ fs20.mkdirSync(path19.dirname(dest), { recursive: true });
6029
+ if (isFile6(dest) && sha256(fs20.readFileSync(dest, "utf-8")) === sha256(content)) {
5797
6030
  skipped.push(skillName);
5798
6031
  } else {
5799
- fs19.writeFileSync(dest, content);
6032
+ fs20.writeFileSync(dest, content);
5800
6033
  installed.push(skillName);
5801
6034
  }
5802
6035
  if (target === "claude-code") {
5803
- const legacyFlat = path18.join(tdir, path18.basename(skill));
6036
+ const legacyFlat = path19.join(tdir, path19.basename(skill));
5804
6037
  if (isFile6(legacyFlat)) {
5805
- fs19.unlinkSync(legacyFlat);
6038
+ fs20.unlinkSync(legacyFlat);
5806
6039
  }
5807
6040
  }
5808
6041
  }
5809
6042
  for (const ref of listSourceReferences(src)) {
5810
- const rel = `${ROUTER_SKILL_NAME}/references/${path18.basename(ref)}`;
5811
- const dest = path18.join(tdir, rel);
5812
- fs19.mkdirSync(path18.dirname(dest), { recursive: true });
5813
- const content = fs19.readFileSync(ref, "utf-8");
5814
- if (isFile6(dest) && sha256(fs19.readFileSync(dest, "utf-8")) === sha256(content)) {
6043
+ const rel = `${ROUTER_SKILL_NAME}/references/${path19.basename(ref)}`;
6044
+ const dest = path19.join(tdir, rel);
6045
+ fs20.mkdirSync(path19.dirname(dest), { recursive: true });
6046
+ const content = fs20.readFileSync(ref, "utf-8");
6047
+ if (isFile6(dest) && sha256(fs20.readFileSync(dest, "utf-8")) === sha256(content)) {
5815
6048
  skipped.push(rel);
5816
6049
  } else {
5817
- fs19.writeFileSync(dest, content);
6050
+ fs20.writeFileSync(dest, content);
5818
6051
  installed.push(rel);
5819
6052
  }
5820
6053
  }
5821
- if (isDir3(path18.join(tdir, ROUTER_SKILL_NAME))) {
6054
+ if (isDir3(path19.join(tdir, ROUTER_SKILL_NAME))) {
5822
6055
  writeMeta(tdir, iterRenderedPayloads(src, target));
5823
6056
  }
5824
- const legacy = target === "claude-code" ? LEGACY_SKILL_NAMES.filter((name) => isDir3(path18.join(tdir, name))) : LEGACY_SKILL_NAMES.filter(
5825
- (name) => isFile6(path18.join(tdir, `${name}.mdc`))
6057
+ const legacy = target === "claude-code" ? LEGACY_SKILL_NAMES.filter((name) => isDir3(path19.join(tdir, name))) : LEGACY_SKILL_NAMES.filter(
6058
+ (name) => isFile6(path19.join(tdir, `${name}.mdc`))
5826
6059
  );
5827
6060
  return {
5828
6061
  target,
@@ -5848,18 +6081,20 @@ function acceptChoices(option, accepted, advertised) {
5848
6081
  }
5849
6082
 
5850
6083
  // src/cli/wallet.ts
5851
- import * as fs21 from "fs";
5852
- import * as path20 from "path";
6084
+ import * as fs22 from "fs";
6085
+ import * as os3 from "os";
6086
+ import * as path21 from "path";
5853
6087
  import { EVMWalletProvider, SigningPolicy } from "@bnbagent/sdk";
5854
6088
  import {
6089
+ envLocalPath as envLocalPath10,
5855
6090
  findProjectRoot as findProjectRoot3,
5856
- loadStudioToml as loadStudioToml9
6091
+ loadStudioToml as loadStudioToml10
5857
6092
  } from "@bnbagent/studio-runtime/config";
5858
6093
  import { buildPolicy, buildWallet } from "@bnbagent/studio-runtime/wallet";
5859
6094
 
5860
6095
  // src/cli/walletSession.ts
5861
- import * as fs20 from "fs";
5862
- import * as path19 from "path";
6096
+ import * as fs21 from "fs";
6097
+ import * as path20 from "path";
5863
6098
  import { AltanaWalletProvider } from "@bnbagent/sdk";
5864
6099
  import { getAddress as deployedAddresses } from "@bnbagent/sdk/networks";
5865
6100
  import {
@@ -5868,7 +6103,7 @@ import {
5868
6103
  serializeSession
5869
6104
  } from "@bnbagent/sdk/wallets";
5870
6105
  import { auditedOp as auditedOp2 } from "@bnbagent/studio-runtime/audit";
5871
- import { loadStudioToml as loadStudioToml8 } from "@bnbagent/studio-runtime/config";
6106
+ import { loadStudioToml as loadStudioToml9 } from "@bnbagent/studio-runtime/config";
5872
6107
  import { getNetwork as getNetwork5, toRaw as toRaw2 } from "@bnbagent/studio-runtime/networks";
5873
6108
  import { writePrivate } from "@bnbagent/studio-runtime/secretWrite";
5874
6109
  import {
@@ -5878,18 +6113,18 @@ import {
5878
6113
  var defaultAdminFactory = (opts) => AltanaWalletProvider.adminFromKeystore(opts);
5879
6114
  var adminFactory = defaultAdminFactory;
5880
6115
  var sessionDeserializer = deserializeSession;
5881
- function tableOf6(value) {
6116
+ function tableOf7(value) {
5882
6117
  return value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
5883
6118
  }
5884
6119
  function loadContext(projectRoot) {
5885
- const cfg = loadStudioToml8(path19.join(projectRoot, "studio.toml"));
5886
- const walletCfg = tableOf6(cfg.wallet);
6120
+ const cfg = loadStudioToml9(path20.join(projectRoot, "studio.toml"));
6121
+ const walletCfg = tableOf7(cfg.wallet);
5887
6122
  if (String(walletCfg.kind ?? "evm-local") !== "altana") {
5888
6123
  throw new Error(
5889
6124
  `wallet session commands require [wallet].kind='altana' (got ${JSON.stringify(walletCfg.kind ?? "evm-local")}).`
5890
6125
  );
5891
6126
  }
5892
- const networkName = String(tableOf6(cfg.network).default ?? "bsc-testnet");
6127
+ const networkName = String(tableOf7(cfg.network).default ?? "bsc-testnet");
5893
6128
  const altanaNetwork = ALTANA_NETWORK_BY_STUDIO[networkName];
5894
6129
  if (altanaNetwork === void 0) {
5895
6130
  throw new Error(
@@ -5904,7 +6139,7 @@ function loadContext(projectRoot) {
5904
6139
  }
5905
6140
  const resolvePath = (value, fallback) => {
5906
6141
  const configured = String(value ?? fallback);
5907
- return path19.isAbsolute(configured) ? configured : path19.join(projectRoot, configured);
6142
+ return path20.isAbsolute(configured) ? configured : path20.join(projectRoot, configured);
5908
6143
  };
5909
6144
  return {
5910
6145
  projectRoot,
@@ -5952,8 +6187,8 @@ function parseSessionEnvelope(serialized) {
5952
6187
  `invalid Altana session JSON: ${error instanceof Error ? error.message : String(error)}`
5953
6188
  );
5954
6189
  }
5955
- const record = tableOf6(parsed);
5956
- if (record.version !== 1 || typeof record.walletAddress !== "string" || typeof record.publicKey !== "string" || !record.publicKey.startsWith("0x") || typeof record.expiry !== "number" || Object.keys(tableOf6(record.permissions)).length === 0) {
6190
+ const record = tableOf7(parsed);
6191
+ if (record.version !== 1 || typeof record.walletAddress !== "string" || typeof record.publicKey !== "string" || !record.publicKey.startsWith("0x") || typeof record.expiry !== "number" || Object.keys(tableOf7(record.permissions)).length === 0) {
5957
6192
  throw new Error(
5958
6193
  "invalid Altana session envelope (expected version/walletAddress/publicKey/expiry/permissions)."
5959
6194
  );
@@ -5962,13 +6197,13 @@ function parseSessionEnvelope(serialized) {
5962
6197
  walletAddress: record.walletAddress,
5963
6198
  publicKey: record.publicKey,
5964
6199
  expiry: record.expiry,
5965
- permissions: tableOf6(record.permissions)
6200
+ permissions: tableOf7(record.permissions)
5966
6201
  };
5967
6202
  }
5968
6203
  function readSession(ctx) {
5969
6204
  let serialized;
5970
6205
  try {
5971
- serialized = fs20.readFileSync(ctx.sessionFile, "utf8");
6206
+ serialized = fs21.readFileSync(ctx.sessionFile, "utf8");
5972
6207
  } catch {
5973
6208
  throw new Error(
5974
6209
  `no Altana session file at ${ctx.sessionFile} \u2014 run \`bag wallet session grant\`.`
@@ -5977,8 +6212,8 @@ function readSession(ctx) {
5977
6212
  return { serialized, envelope: parseSessionEnvelope(serialized) };
5978
6213
  }
5979
6214
  function writeSession(ctx, session) {
5980
- fs20.mkdirSync(path19.dirname(ctx.sessionFile), { recursive: true, mode: 448 });
5981
- fs20.chmodSync(path19.dirname(ctx.sessionFile), 448);
6215
+ fs21.mkdirSync(path20.dirname(ctx.sessionFile), { recursive: true, mode: 448 });
6216
+ fs21.chmodSync(path20.dirname(ctx.sessionFile), 448);
5982
6217
  writePrivate(ctx.sessionFile, serializeSession(session));
5983
6218
  }
5984
6219
  function sessionKeyFingerprint(publicKey) {
@@ -6089,7 +6324,7 @@ async function cmdSessionGrant(opts) {
6089
6324
  "--budget-u"
6090
6325
  );
6091
6326
  let existing = null;
6092
- if (fs20.existsSync(ctx.sessionFile)) {
6327
+ if (fs21.existsSync(ctx.sessionFile)) {
6093
6328
  existing = readSession(ctx).envelope;
6094
6329
  if (!opts.force) {
6095
6330
  throw new Error(
@@ -6171,8 +6406,8 @@ function cmdSessionStatus(projectRootArg) {
6171
6406
  const spend = envelope.permissions.spend;
6172
6407
  if (Array.isArray(spend)) {
6173
6408
  for (const [index, cap] of spend.entries()) {
6174
- const record = tableOf6(cap);
6175
- const encoded = tableOf6(record.limit).$bigint;
6409
+ const record = tableOf7(cap);
6410
+ const encoded = tableOf7(record.limit).$bigint;
6176
6411
  const limit = typeof encoded === "string" ? encoded : String(record.limit);
6177
6412
  printOut(
6178
6413
  `spend[${index}]: limit=${limit} period=${String(record.period ?? "day")} token=${String(record.token ?? "native")}`
@@ -6207,7 +6442,7 @@ async function cmdSessionRevoke(opts) {
6207
6442
  await admin.revokeSession(envelope.publicKey);
6208
6443
  }
6209
6444
  );
6210
- fs20.unlinkSync(ctx.sessionFile);
6445
+ fs21.unlinkSync(ctx.sessionFile);
6211
6446
  printErr(`\u2713 Altana session revoked and removed: ${ctx.sessionFile}`);
6212
6447
  return 0;
6213
6448
  }
@@ -6331,8 +6566,8 @@ var ProjectRootNotFound = class extends Error {
6331
6566
  };
6332
6567
  function resolveWalletProjectRoot(argRoot) {
6333
6568
  if (argRoot != null) {
6334
- const root2 = path20.resolve(argRoot);
6335
- if (!isFile7(path20.join(root2, "studio.toml"))) {
6569
+ const root2 = path21.resolve(argRoot);
6570
+ if (!isFile7(path21.join(root2, "studio.toml"))) {
6336
6571
  throw new ProjectRootNotFound(
6337
6572
  `No studio.toml found under --project-root ${root2}`
6338
6573
  );
@@ -6349,13 +6584,13 @@ function resolveWalletProjectRoot(argRoot) {
6349
6584
  }
6350
6585
  function isFile7(p) {
6351
6586
  try {
6352
- return fs21.statSync(p).isFile();
6587
+ return fs22.statSync(p).isFile();
6353
6588
  } catch {
6354
6589
  return false;
6355
6590
  }
6356
6591
  }
6357
6592
  function loadWalletCfg(projectRoot) {
6358
- const data = loadStudioToml9(path20.join(projectRoot, "studio.toml"));
6593
+ const data = loadStudioToml10(path21.join(projectRoot, "studio.toml"));
6359
6594
  const wallet = data.wallet;
6360
6595
  return wallet !== null && typeof wallet === "object" && !Array.isArray(wallet) ? wallet : {};
6361
6596
  }
@@ -6365,7 +6600,7 @@ function walletKind(walletCfg) {
6365
6600
  function projectNetwork(projectRoot) {
6366
6601
  let data;
6367
6602
  try {
6368
- data = loadStudioToml9(path20.join(projectRoot, "studio.toml"));
6603
+ data = loadStudioToml10(path21.join(projectRoot, "studio.toml"));
6369
6604
  } catch {
6370
6605
  return "bsc-testnet";
6371
6606
  }
@@ -6387,13 +6622,29 @@ function requirePassword2() {
6387
6622
  }
6388
6623
  return pw;
6389
6624
  }
6625
+ function requireDurablePassword(projectRoot) {
6626
+ const password = requirePassword2();
6627
+ const envPath = envLocalPath10(projectRoot);
6628
+ const persisted = getEnvVar(envPath, PASSWORD_ENV2);
6629
+ if (!persisted) {
6630
+ throw new Error(
6631
+ `refusing to create a keystore with an unpersisted ${PASSWORD_ENV2}. Edit ${envPath}, set ${PASSWORD_ENV2} there, and retry; do not pass wallet passwords on the command line.`
6632
+ );
6633
+ }
6634
+ if (persisted !== password) {
6635
+ throw new Error(
6636
+ `refusing to create a keystore because the active ${PASSWORD_ENV2} does not match ${envPath}. Make the durable file value authoritative before retrying.`
6637
+ );
6638
+ }
6639
+ return password;
6640
+ }
6390
6641
  function persistAddress(projectRoot, address) {
6391
- const tomlPath = path20.join(projectRoot, "studio.toml");
6642
+ const tomlPath = path21.join(projectRoot, "studio.toml");
6392
6643
  if (!isFile7(tomlPath)) {
6393
6644
  return;
6394
6645
  }
6395
- const text2 = fs21.readFileSync(tomlPath, "utf-8");
6396
- fs21.writeFileSync(
6646
+ const text2 = fs22.readFileSync(tomlPath, "utf-8");
6647
+ fs22.writeFileSync(
6397
6648
  tomlPath,
6398
6649
  updateSection(text2, "wallet", { address }),
6399
6650
  "utf-8"
@@ -6409,7 +6660,7 @@ function resolveKeystoreDir2(projectRoot, cliOverride, walletCfg) {
6409
6660
  } else {
6410
6661
  d = ".studio/wallets";
6411
6662
  }
6412
- return path20.isAbsolute(d) ? d : path20.join(projectRoot, d);
6663
+ return path21.isAbsolute(d) ? d : path21.join(projectRoot, d);
6413
6664
  }
6414
6665
  async function resolvePrivateKeyArg(raw) {
6415
6666
  if (raw === void 0 || raw === false) {
@@ -6442,7 +6693,7 @@ function registerWallet(program) {
6442
6693
  )
6443
6694
  );
6444
6695
  p.command("twak-init").description(
6445
- "Create the project's twak wallet WITHOUT putting the password on argv (wallet.kind=twak): wraps `twak wallet create --no-keychain` reading the password from stdin / a 0600 file / a hidden prompt, then adopts the address like `bag wallet new`."
6696
+ "Create the project's twak wallet without YOU typing the password on a command line (wallet.kind=twak): wraps `twak wallet create --no-keychain` reading the password from stdin / a 0600 file / a hidden prompt, seeds the NaaS credentials, then adopts the address like `bag wallet new`. twak requires --password on its own argv, so the value does reach that short-lived child process."
6446
6697
  ).option(
6447
6698
  "--password-stdin",
6448
6699
  'Read the wallet password from stdin (CI: `printf %s "$PW" | bag wallet twak-init --password-stdin`).'
@@ -6524,7 +6775,7 @@ async function cmdNew(opts) {
6524
6775
  projectRoot = process.cwd();
6525
6776
  }
6526
6777
  let walletCfg = {};
6527
- if (isFile7(path20.join(projectRoot, "studio.toml"))) {
6778
+ if (isFile7(path21.join(projectRoot, "studio.toml"))) {
6528
6779
  walletCfg = loadWalletCfg(projectRoot);
6529
6780
  }
6530
6781
  const kind = walletKind(walletCfg);
@@ -6532,13 +6783,13 @@ async function cmdNew(opts) {
6532
6783
  return cmdNewTwak(projectRoot, walletCfg);
6533
6784
  }
6534
6785
  const privateKey = await resolvePrivateKeyArg(opts.privateKey);
6535
- const password = requirePassword2();
6786
+ const password = requireDurablePassword(projectRoot);
6536
6787
  const keystoreDir = resolveKeystoreDir2(
6537
6788
  projectRoot,
6538
6789
  opts.keystoreDir,
6539
6790
  walletCfg
6540
6791
  );
6541
- fs21.mkdirSync(keystoreDir, { recursive: true });
6792
+ fs22.mkdirSync(keystoreDir, { recursive: true });
6542
6793
  const provider = new EVMWalletProvider({
6543
6794
  password,
6544
6795
  ...privateKey !== null ? { privateKey } : {},
@@ -6566,7 +6817,7 @@ Install it (Node >=22): npm install -g @trustwallet/cli@${TWAK_CLI_VERSION}`
6566
6817
  let createCmd = "twak wallet create --password <your-password> --no-keychain";
6567
6818
  let setupCmd = "twak setup";
6568
6819
  if (walletCfg.twak_home) {
6569
- const home = path20.dirname(path20.dirname(walletFile));
6820
+ const home = path21.dirname(path21.dirname(walletFile));
6570
6821
  createCmd = `HOME=${home} ${createCmd}`;
6571
6822
  setupCmd = `HOME=${home} ${setupCmd}`;
6572
6823
  }
@@ -6591,16 +6842,39 @@ Install it (Node >=22): npm install -g @trustwallet/cli@${TWAK_CLI_VERSION}`
6591
6842
  persistAddress(projectRoot, address);
6592
6843
  return 0;
6593
6844
  }
6845
+ function ensureTwakCredentials(walletFile, homeDir) {
6846
+ const twakDir = path21.dirname(walletFile);
6847
+ const target = path21.join(twakDir, "credentials.json");
6848
+ if (isFile7(target)) {
6849
+ return true;
6850
+ }
6851
+ const machine = path21.join(os3.homedir(), ".twak", "credentials.json");
6852
+ if (path21.resolve(machine) === path21.resolve(target) || !isFile7(machine)) {
6853
+ printErr(
6854
+ `error: no Trust Wallet NaaS credentials for this wallet home \u2014 ${target} is missing. Get an Access ID + HMAC secret from https://portal.trustwallet.com/dashboard/apps, run \`HOME=${homeDir} twak setup\` once, then re-run this command.`
6855
+ );
6856
+ return false;
6857
+ }
6858
+ fs22.mkdirSync(twakDir, { recursive: true });
6859
+ fs22.writeFileSync(target, fs22.readFileSync(machine, "utf-8"), { mode: 384 });
6860
+ try {
6861
+ fs22.chmodSync(twakDir, 448);
6862
+ fs22.chmodSync(target, 384);
6863
+ } catch {
6864
+ }
6865
+ printErr(`note: copied NaaS credentials from ${machine} into ${twakDir}.`);
6866
+ return true;
6867
+ }
6594
6868
  async function resolveTwakInitPassword(opts) {
6595
6869
  if (opts.passwordStdin && opts.passwordFile) {
6596
6870
  printErr("error: pass exactly one of --password-stdin or --password-file.");
6597
6871
  throw new CliExit(2);
6598
6872
  }
6599
6873
  if (opts.passwordFile) {
6600
- const file = path20.resolve(opts.passwordFile);
6874
+ const file = path21.resolve(opts.passwordFile);
6601
6875
  let mode;
6602
6876
  try {
6603
- mode = fs21.statSync(file).mode;
6877
+ mode = fs22.statSync(file).mode;
6604
6878
  } catch {
6605
6879
  printErr(`error: cannot read --password-file ${file}.`);
6606
6880
  throw new CliExit(2);
@@ -6611,7 +6885,7 @@ async function resolveTwakInitPassword(opts) {
6611
6885
  );
6612
6886
  throw new CliExit(2);
6613
6887
  }
6614
- const password = (fs21.readFileSync(file, "utf-8").split(/\r?\n/)[0] ?? "").trim();
6888
+ const password = (fs22.readFileSync(file, "utf-8").split(/\r?\n/)[0] ?? "").trim();
6615
6889
  if (!password) {
6616
6890
  printErr(`error: --password-file ${file} is empty.`);
6617
6891
  throw new CliExit(2);
@@ -6671,11 +6945,14 @@ Install it (Node >=22): npm install -g @trustwallet/cli@${TWAK_CLI_VERSION}`
6671
6945
  return 1;
6672
6946
  }
6673
6947
  const password = await resolveTwakInitPassword(opts);
6674
- const homeDir = path20.dirname(path20.dirname(walletFile));
6675
- fs21.mkdirSync(homeDir, { recursive: true });
6948
+ const homeDir = path21.dirname(path21.dirname(walletFile));
6949
+ fs22.mkdirSync(homeDir, { recursive: true });
6950
+ if (!ensureTwakCredentials(walletFile, homeDir)) {
6951
+ return 1;
6952
+ }
6676
6953
  const create = await runCapture(
6677
6954
  "twak",
6678
- ["wallet", "create", "--no-keychain"],
6955
+ ["wallet", "create", "--password", password, "--no-keychain"],
6679
6956
  {
6680
6957
  env: {
6681
6958
  ...process.env,
@@ -6683,8 +6960,8 @@ Install it (Node >=22): npm install -g @trustwallet/cli@${TWAK_CLI_VERSION}`
6683
6960
  TWAK_WALLET_PASSWORD: password,
6684
6961
  TWAK_NONINTERACTIVE: "1"
6685
6962
  },
6686
- // A prompting twak build reads these lines; an env-reading one
6687
- // ignores them. Either way the password never touches argv.
6963
+ // A prompting twak build reads these lines; an env-reading one ignores
6964
+ // them. Both channels are kept alongside the required argv flag.
6688
6965
  input: `${password}
6689
6966
  ${password}
6690
6967
  `,
@@ -6695,8 +6972,8 @@ ${password}
6695
6972
  const detail = `${create.stderr}
6696
6973
  ${create.stdout}`.trim();
6697
6974
  printErr(
6698
- `error: \`twak wallet create --no-keychain\` did not produce ${walletFile}${detail ? `:
6699
- ${detail}` : "."}`
6975
+ detail ? `error: \`twak wallet create --no-keychain\` failed:
6976
+ ${detail}` : `error: \`twak wallet create --no-keychain\` did not produce ${walletFile}.`
6700
6977
  );
6701
6978
  if (/no api credentials/i.test(detail)) {
6702
6979
  printErr(
@@ -6706,14 +6983,14 @@ ${detail}` : "."}`
6706
6983
  return 1;
6707
6984
  }
6708
6985
  try {
6709
- fs21.chmodSync(walletFile, 384);
6986
+ fs22.chmodSync(walletFile, 384);
6710
6987
  } catch {
6711
6988
  }
6712
6989
  if (!process.env.TWAK_WALLET_PASSWORD) {
6713
6990
  process.env.TWAK_WALLET_PASSWORD = password;
6714
6991
  }
6715
6992
  printErr(
6716
- `\u2713 twak wallet created under ${path20.dirname(walletFile)} (no keychain)`
6993
+ `\u2713 twak wallet created under ${path21.dirname(walletFile)} (no keychain)`
6717
6994
  );
6718
6995
  printErr(
6719
6996
  "next: persist TWAK_WALLET_PASSWORD in .studio/.env.local so deploys and non-interactive signing can unlock it."
@@ -6750,7 +7027,7 @@ function cmdShow5(projectRootArg) {
6750
7027
  ...walletCfg.address ? { address: String(walletCfg.address) } : {}
6751
7028
  });
6752
7029
  const address = provider.address;
6753
- const keystorePath = path20.join(keystoreDir, `${address}.json`);
7030
+ const keystorePath = path21.join(keystoreDir, `${address}.json`);
6754
7031
  printOut(`address: ${address}`);
6755
7032
  printOut(`source: ${kind}`);
6756
7033
  printOut(`keystore_dir: ${keystoreDir}`);
@@ -6759,14 +7036,14 @@ function cmdShow5(projectRootArg) {
6759
7036
  const configured = String(
6760
7037
  walletCfg.session_file ?? ".studio/wallets/altana-session.json"
6761
7038
  );
6762
- const sessionFile = path20.isAbsolute(configured) ? configured : path20.join(projectRoot, configured);
7039
+ const sessionFile = path21.isAbsolute(configured) ? configured : path21.join(projectRoot, configured);
6763
7040
  printOut(`session_file: ${sessionFile}`);
6764
7041
  if (!isFile7(sessionFile)) {
6765
7042
  printOut("session_status: missing (run `bag wallet session grant`)");
6766
7043
  } else {
6767
7044
  let envelope;
6768
7045
  try {
6769
- envelope = JSON.parse(fs21.readFileSync(sessionFile, "utf8"));
7046
+ envelope = JSON.parse(fs22.readFileSync(sessionFile, "utf8"));
6770
7047
  } catch {
6771
7048
  throw new Error(`invalid Altana session JSON at ${sessionFile}`);
6772
7049
  }
@@ -6792,7 +7069,7 @@ function cmdList2(projectRootArg) {
6792
7069
  const keystoreDir = resolveKeystoreDir2(projectRoot, null, walletCfg);
6793
7070
  let entries;
6794
7071
  try {
6795
- entries = fs21.readdirSync(keystoreDir).sort();
7072
+ entries = fs22.readdirSync(keystoreDir).sort();
6796
7073
  } catch {
6797
7074
  return 0;
6798
7075
  }
@@ -6804,7 +7081,7 @@ function cmdList2(projectRootArg) {
6804
7081
  let data;
6805
7082
  try {
6806
7083
  data = JSON.parse(
6807
- fs21.readFileSync(path20.join(keystoreDir, child), "utf-8")
7084
+ fs22.readFileSync(path21.join(keystoreDir, child), "utf-8")
6808
7085
  );
6809
7086
  } catch {
6810
7087
  continue;
@@ -6855,7 +7132,7 @@ async function cmdSign(msg, projectRootArg) {
6855
7132
  }
6856
7133
  async function cmdBalance(opts) {
6857
7134
  const projectRoot = resolveWalletProjectRoot(opts.projectRoot);
6858
- const data = loadStudioToml9(path20.join(projectRoot, "studio.toml"));
7135
+ const data = loadStudioToml10(path21.join(projectRoot, "studio.toml"));
6859
7136
  const walletCfg = data.wallet !== null && typeof data.wallet === "object" ? data.wallet : {};
6860
7137
  let address;
6861
7138
  const kind = walletKind(walletCfg);
@@ -6982,10 +7259,10 @@ var PROVIDER_KEY_ENV = {
6982
7259
  "pieverse-llm": "PIEVERSE_LLM_API_KEY"
6983
7260
  };
6984
7261
  function renderAgentcoreProject(target, name) {
6985
- const acDir = path21.join(target, "agentcore");
6986
- fs22.mkdirSync(acDir, { recursive: true });
6987
- fs22.writeFileSync(
6988
- path21.join(acDir, "agentcore.json"),
7262
+ const acDir = path22.join(target, "agentcore");
7263
+ fs23.mkdirSync(acDir, { recursive: true });
7264
+ fs23.writeFileSync(
7265
+ path22.join(acDir, "agentcore.json"),
6989
7266
  `${JSON.stringify(
6990
7267
  {
6991
7268
  $schema: "https://schema.agentcore.aws.dev/v1/agentcore.json",
@@ -6999,7 +7276,7 @@ function renderAgentcoreProject(target, name) {
6999
7276
  )}
7000
7277
  `
7001
7278
  );
7002
- fs22.writeFileSync(path21.join(acDir, "aws-targets.json"), "[]\n");
7279
+ fs23.writeFileSync(path22.join(acDir, "aws-targets.json"), "[]\n");
7003
7280
  }
7004
7281
  var AGENTS_MD_MARKER = "# bnbagent-studio additions (ERC-8183 seller)";
7005
7282
  var AGENTS_MD_STUDIO_SECTION = `
@@ -7023,17 +7300,16 @@ every intent to the right playbook via its references.
7023
7300
  under a deploy codeLocation). It lives at the workspace root precisely so
7024
7301
  that no packaging path can bundle it into an artifact. Never print, log,
7025
7302
  or export private key material.
7026
- 2. **Never commit secrets.** The \`.env.local\` file (API keys, plus
7027
- TWAK_WALLET_PASSWORD for twak projects) is gitignored \u2014 keep it that way;
7028
- never echo its values into code, logs, or chat. For evm-local projects,
7029
- WALLET_PASSWORD is read from the shell environment and is never written to
7030
- disk.
7303
+ 2. **Never commit secrets.** The \`.env.local\` file (API keys and wallet
7304
+ unlock passwords) is gitignored \u2014 keep it that way; never echo its values
7305
+ into code, logs, argv, or chat. For evm-local and Altana projects, set
7306
+ WALLET_PASSWORD in that owner-only file before creating the keystore.
7031
7307
  3. **Signing is fixed entrypoint code.** Never expose wallet signing as an
7032
7308
  LLM-callable tool, and keep MCP tools read-only. All on-chain signing
7033
7309
  lives in \`src/signing.ts\`.
7034
7310
  4. **The quote path is deterministic** (fixed list price, clamp + sign).
7035
7311
  Never put an LLM in the quote path.
7036
- 5. **Deploy with \`bag deploy --provider bnb|aws\`.** Every deploy or
7312
+ 5. **Deploy with \`bag deploy --provider ${ADVERTISED_PROVIDERS_HELP}\`.** Every deploy or
7037
7313
  redeploy requires a visible provider choice. Studio runs its local business
7038
7314
  gates, then delegates cloud credentials, secrets, packaging and lifecycle
7039
7315
  calls to the pinned bnbagent-deploy CLI. Do not bypass this boundary with
@@ -7044,30 +7320,30 @@ every intent to the right playbook via its references.
7044
7320
  and state the tradeoff.
7045
7321
  `;
7046
7322
  function appendAgentsMdStudioSection(target) {
7047
- const agentsMd = path21.join(target, "AGENTS.md");
7323
+ const agentsMd = path22.join(target, "AGENTS.md");
7048
7324
  let existing = "";
7049
7325
  try {
7050
- existing = fs22.readFileSync(agentsMd, "utf-8");
7326
+ existing = fs23.readFileSync(agentsMd, "utf-8");
7051
7327
  } catch {
7052
7328
  existing = "";
7053
7329
  }
7054
7330
  if (existing.includes(AGENTS_MD_MARKER)) {
7055
7331
  return;
7056
7332
  }
7057
- fs22.writeFileSync(
7333
+ fs23.writeFileSync(
7058
7334
  agentsMd,
7059
7335
  `${existing.replace(/\n+$/, "")}
7060
7336
  ${AGENTS_MD_STUDIO_SECTION}`
7061
7337
  );
7062
7338
  }
7063
7339
  function seedAwsTargets(target) {
7064
- const p = path21.join(target, "agentcore", "aws-targets.json");
7340
+ const p = path22.join(target, "agentcore", "aws-targets.json");
7065
7341
  if (!isFile8(p)) {
7066
7342
  return;
7067
7343
  }
7068
7344
  let data;
7069
7345
  try {
7070
- data = JSON.parse(fs22.readFileSync(p, "utf-8"));
7346
+ data = JSON.parse(fs23.readFileSync(p, "utf-8"));
7071
7347
  } catch {
7072
7348
  return;
7073
7349
  }
@@ -7078,7 +7354,7 @@ function seedAwsTargets(target) {
7078
7354
  { name: "default", account: AWS_ACCOUNT_PLACEHOLDER, region: "us-east-1" }
7079
7355
  ];
7080
7356
  try {
7081
- fs22.writeFileSync(p, `${JSON.stringify(skeleton, null, 2)}
7357
+ fs23.writeFileSync(p, `${JSON.stringify(skeleton, null, 2)}
7082
7358
  `);
7083
7359
  } catch {
7084
7360
  return;
@@ -7101,13 +7377,13 @@ function registerAgentcoreRuntime(target, name, opts = {}) {
7101
7377
  const protocol = nativeProtocolOf(faces);
7102
7378
  const stem2 = entryStemOf(faces);
7103
7379
  const isContainer = opts.packaging === "container" || walletKind2 === "twak";
7104
- const cfgPath = path21.join(target, "agentcore", "agentcore.json");
7380
+ const cfgPath = path22.join(target, "agentcore", "agentcore.json");
7105
7381
  if (!isFile8(cfgPath)) {
7106
7382
  return;
7107
7383
  }
7108
7384
  let cfg;
7109
7385
  try {
7110
- const parsed = JSON.parse(fs22.readFileSync(cfgPath, "utf-8"));
7386
+ const parsed = JSON.parse(fs23.readFileSync(cfgPath, "utf-8"));
7111
7387
  if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
7112
7388
  return;
7113
7389
  }
@@ -7146,7 +7422,7 @@ function registerAgentcoreRuntime(target, name, opts = {}) {
7146
7422
  runtimes.push(runtime);
7147
7423
  cfg.runtimes = runtimes;
7148
7424
  try {
7149
- fs22.writeFileSync(cfgPath, `${JSON.stringify(cfg, null, 2)}
7425
+ fs23.writeFileSync(cfgPath, `${JSON.stringify(cfg, null, 2)}
7150
7426
  `);
7151
7427
  } catch {
7152
7428
  return;
@@ -7283,12 +7559,12 @@ function registerInit(program) {
7283
7559
  );
7284
7560
  }
7285
7561
  function enclosingProjectRoot(start) {
7286
- let current = path21.resolve(start);
7562
+ let current = path22.resolve(start);
7287
7563
  for (; ; ) {
7288
- if (isFile8(path21.join(current, APP_DIR, AGENT_PKG, "studio.toml"))) {
7564
+ if (isFile8(path22.join(current, APP_DIR, AGENT_PKG, "studio.toml"))) {
7289
7565
  return current;
7290
7566
  }
7291
- const parent = path21.dirname(current);
7567
+ const parent = path22.dirname(current);
7292
7568
  if (parent === current) {
7293
7569
  return null;
7294
7570
  }
@@ -7296,8 +7572,8 @@ function enclosingProjectRoot(start) {
7296
7572
  }
7297
7573
  }
7298
7574
  async function cmdInit(nameArg, opts) {
7299
- const target = path21.resolve(process.cwd(), nameArg);
7300
- let projectName2 = path21.basename(target);
7575
+ const target = path22.resolve(process.cwd(), nameArg);
7576
+ let projectName2 = path22.basename(target);
7301
7577
  if (!projectName2) {
7302
7578
  printErr(
7303
7579
  `error: cannot derive a project name from '${nameArg}' (path has no basename).`
@@ -7382,15 +7658,15 @@ async function cmdInit(nameArg, opts) {
7382
7658
  return 2;
7383
7659
  }
7384
7660
  }
7385
- const enclosing = enclosingProjectRoot(path21.dirname(target));
7661
+ const enclosing = enclosingProjectRoot(path22.dirname(target));
7386
7662
  if (enclosing !== null) {
7387
7663
  printErr(
7388
- `error: ${path21.dirname(target)} is inside an existing bag project (${enclosing}).
7389
- \`bag init\` resolves the new project relative to the current directory, so running it here would nest a second scaffold inside ${path21.basename(enclosing)}/. cd to a directory OUTSIDE any project and retry.`
7664
+ `error: ${path22.dirname(target)} is inside an existing bag project (${enclosing}).
7665
+ \`bag init\` resolves the new project relative to the current directory, so running it here would nest a second scaffold inside ${path22.basename(enclosing)}/. cd to a directory OUTSIDE any project and retry.`
7390
7666
  );
7391
7667
  return 2;
7392
7668
  }
7393
- if (fs22.existsSync(target) && !opts.force) {
7669
+ if (fs23.existsSync(target) && !opts.force) {
7394
7670
  printErr(`error: ${target} already exists. Use --force to overwrite.`);
7395
7671
  return 2;
7396
7672
  }
@@ -7421,8 +7697,8 @@ async function cmdInit(nameArg, opts) {
7421
7697
  );
7422
7698
  return 2;
7423
7699
  }
7424
- if (fs22.existsSync(target)) {
7425
- fs22.rmSync(target, { recursive: true, force: true });
7700
+ if (fs23.existsSync(target)) {
7701
+ fs23.rmSync(target, { recursive: true, force: true });
7426
7702
  }
7427
7703
  if (destination === "platform") {
7428
7704
  printCampaignIntro();
@@ -7467,7 +7743,7 @@ async function cmdInit(nameArg, opts) {
7467
7743
  }
7468
7744
  }
7469
7745
  try {
7470
- fs22.mkdirSync(target, { recursive: true });
7746
+ fs23.mkdirSync(target, { recursive: true });
7471
7747
  if (runtime === "agentcore") {
7472
7748
  renderAgentcoreProject(target, projectName2);
7473
7749
  }
@@ -7483,7 +7759,7 @@ async function cmdInit(nameArg, opts) {
7483
7759
  printErr(
7484
7760
  `error: the b402 seller rail supports wallet.kind evm-local or twak only; '${walletKind2}' cannot act as the b402 payout wallet. Re-run with --rails 8183 or a supported --wallet-kind.`
7485
7761
  );
7486
- fs22.rmSync(target, { recursive: true, force: true });
7762
+ fs23.rmSync(target, { recursive: true, force: true });
7487
7763
  return 2;
7488
7764
  }
7489
7765
  const ides = resolveEmitIdes(opts.ide);
@@ -7526,9 +7802,9 @@ async function cmdInit(nameArg, opts) {
7526
7802
  });
7527
7803
  seedAwsTargets(target);
7528
7804
  }
7529
- const agentDir = path21.join(target, APP_DIR, AGENT_PKG);
7530
- fs22.mkdirSync(path21.join(agentDir, "vendor"), { recursive: true });
7531
- fs22.writeFileSync(path21.join(agentDir, "vendor", ".gitkeep"), "");
7805
+ const agentDir = path22.join(target, APP_DIR, AGENT_PKG);
7806
+ fs23.mkdirSync(path22.join(agentDir, "vendor"), { recursive: true });
7807
+ fs23.writeFileSync(path22.join(agentDir, "vendor", ".gitkeep"), "");
7532
7808
  const skipInstall = opts.install === false || opts.venv === false;
7533
7809
  let provisioned = false;
7534
7810
  let installFailed = false;
@@ -7657,64 +7933,64 @@ function derivePackaging(walletKind2, destination, platformArtifact2 = "zip", ru
7657
7933
  }
7658
7934
  function scaffold(target, name, o) {
7659
7935
  const packageManagerVersion = pnpmVersion();
7660
- fs22.writeFileSync(
7661
- path21.join(target, "package.json"),
7936
+ fs23.writeFileSync(
7937
+ path22.join(target, "package.json"),
7662
7938
  renderWorkspacePackageJson(name, packageManagerVersion)
7663
7939
  );
7664
- fs22.writeFileSync(
7665
- path21.join(target, "pnpm-workspace.yaml"),
7940
+ fs23.writeFileSync(
7941
+ path22.join(target, "pnpm-workspace.yaml"),
7666
7942
  renderPnpmWorkspaceYaml()
7667
7943
  );
7668
- fs22.writeFileSync(path21.join(target, ".gitignore"), renderWorkspaceGitignore());
7669
- if (!isFile8(path21.join(target, "README.md"))) {
7670
- fs22.writeFileSync(
7671
- path21.join(target, "README.md"),
7944
+ fs23.writeFileSync(path22.join(target, ".gitignore"), renderWorkspaceGitignore());
7945
+ if (!isFile8(path22.join(target, "README.md"))) {
7946
+ fs23.writeFileSync(
7947
+ path22.join(target, "README.md"),
7672
7948
  renderWorkspaceReadme(name, o.destination)
7673
7949
  );
7674
7950
  }
7675
7951
  appendAgentsMdStudioSection(target);
7676
- const appRoot = path21.join(target, APP_DIR);
7677
- fs22.mkdirSync(appRoot, { recursive: true });
7678
- const agentRoot2 = path21.join(appRoot, AGENT_PKG);
7679
- fs22.mkdirSync(agentRoot2, { recursive: true });
7680
- fs22.writeFileSync(
7681
- path21.join(agentRoot2, "pnpm-workspace.yaml"),
7952
+ const appRoot = path22.join(target, APP_DIR);
7953
+ fs23.mkdirSync(appRoot, { recursive: true });
7954
+ const agentRoot2 = path22.join(appRoot, AGENT_PKG);
7955
+ fs23.mkdirSync(agentRoot2, { recursive: true });
7956
+ fs23.writeFileSync(
7957
+ path22.join(agentRoot2, "pnpm-workspace.yaml"),
7682
7958
  renderAgentPnpmWorkspaceYaml()
7683
7959
  );
7684
7960
  if (o.walletKind === "evm-local" || o.walletKind === "altana") {
7685
- fs22.mkdirSync(path21.join(target, ".studio", "wallets"), { recursive: true });
7961
+ fs23.mkdirSync(path22.join(target, ".studio", "wallets"), { recursive: true });
7686
7962
  } else if (o.walletKind === "twak") {
7687
7963
  let homeDir;
7688
7964
  let label;
7689
7965
  if (o.twakHome === void 0 || o.twakHome === DEDICATED_TWAK_HOME_REL) {
7690
- homeDir = path21.join(target, ".studio", "twak");
7966
+ homeDir = path22.join(target, ".studio", "twak");
7691
7967
  label = ".studio/twak";
7692
7968
  } else {
7693
- homeDir = path21.isAbsolute(o.twakHome) ? o.twakHome : path21.resolve(agentRoot2, o.twakHome);
7969
+ homeDir = path22.isAbsolute(o.twakHome) ? o.twakHome : path22.resolve(agentRoot2, o.twakHome);
7694
7970
  label = o.twakHome;
7695
7971
  }
7696
- fs22.mkdirSync(homeDir, { recursive: true });
7972
+ fs23.mkdirSync(homeDir, { recursive: true });
7697
7973
  if (ensureTwakKeychain(homeDir)) {
7698
7974
  printOut(
7699
7975
  `\u2713 isolated twak keychain ready under ${label} (macOS) \u2014 no manual \`security\` setup needed`
7700
7976
  );
7701
7977
  }
7702
7978
  }
7703
- fs22.writeFileSync(
7704
- path21.join(agentRoot2, "package.json"),
7979
+ fs23.writeFileSync(
7980
+ path22.join(agentRoot2, "package.json"),
7705
7981
  renderAgentPackageJson(name, o.runtime, o.provider, o.faces, o.walletKind)
7706
7982
  );
7707
- fs22.writeFileSync(
7708
- path21.join(agentRoot2, "tsconfig.json"),
7983
+ fs23.writeFileSync(
7984
+ path22.join(agentRoot2, "tsconfig.json"),
7709
7985
  renderAgentTsconfig()
7710
7986
  );
7711
- fs22.writeFileSync(
7712
- path21.join(agentRoot2, "studio.toml"),
7987
+ fs23.writeFileSync(
7988
+ path22.join(agentRoot2, "studio.toml"),
7713
7989
  renderAgentStudioToml(name, o)
7714
7990
  );
7715
- const envLocal = path21.join(target, ".studio", ".env.local");
7716
- fs22.mkdirSync(path21.dirname(envLocal), { recursive: true });
7717
- fs22.writeFileSync(
7991
+ const envLocal = path22.join(target, ".studio", ".env.local");
7992
+ fs23.mkdirSync(path22.dirname(envLocal), { recursive: true });
7993
+ fs23.writeFileSync(
7718
7994
  envLocal,
7719
7995
  renderAgentEnvLocal(
7720
7996
  o.provider,
@@ -7725,9 +8001,9 @@ function scaffold(target, name, o) {
7725
8001
  o.network
7726
8002
  )
7727
8003
  );
7728
- fs22.writeFileSync(path21.join(agentRoot2, ".gitignore"), renderAgentGitignore());
7729
- fs22.writeFileSync(
7730
- path21.join(agentRoot2, "README.md"),
8004
+ fs23.writeFileSync(path22.join(agentRoot2, ".gitignore"), renderAgentGitignore());
8005
+ fs23.writeFileSync(
8006
+ path22.join(agentRoot2, "README.md"),
7731
8007
  renderAgentReadme(name, o.faces, o.destination)
7732
8008
  );
7733
8009
  const packaging = derivePackaging(
@@ -7763,18 +8039,18 @@ function emitRecipe(base, name, opts = {}) {
7763
8039
  const recipe = loadRecipe(name, { mode: opts.mode ?? null });
7764
8040
  for (const rf of recipe.files) {
7765
8041
  const targetPath = substitutePlaceholders(rf.targetPath, opts.context);
7766
- const basename16 = path21.posix.basename(targetPath);
7767
- const dst = basename16 === "Dockerfile" || basename16 === ".dockerignore" ? path21.join(base, basename16) : path21.join(base, targetPath);
7768
- fs22.mkdirSync(path21.dirname(dst), { recursive: true });
7769
- fs22.writeFileSync(dst, substitutePlaceholders(rf.content, opts.context));
8042
+ const basename16 = path22.posix.basename(targetPath);
8043
+ const dst = basename16 === "Dockerfile" || basename16 === ".dockerignore" ? path22.join(base, basename16) : path22.join(base, targetPath);
8044
+ fs23.mkdirSync(path22.dirname(dst), { recursive: true });
8045
+ fs23.writeFileSync(dst, substitutePlaceholders(rf.content, opts.context));
7770
8046
  }
7771
8047
  }
7772
8048
  function readRecipeNodeDeps(recipeName, group) {
7773
- const tomlPath = path21.join(bundledRecipesRoot(), recipeName, "recipe.toml");
8049
+ const tomlPath = path22.join(bundledRecipesRoot(), recipeName, "recipe.toml");
7774
8050
  if (!isFile8(tomlPath)) {
7775
8051
  return [];
7776
8052
  }
7777
- const meta = parseToml(fs22.readFileSync(tomlPath, "utf-8"));
8053
+ const meta = parseToml(fs23.readFileSync(tomlPath, "utf-8"));
7778
8054
  const depsSection = meta.dependencies !== null && typeof meta.dependencies === "object" ? meta.dependencies : {};
7779
8055
  const collect = (v) => Array.isArray(v) ? v.filter((d) => typeof d === "string") : [];
7780
8056
  const deps = collect(depsSection.node);
@@ -8223,7 +8499,13 @@ function renderAgentEnvLocal(provider, storageProvider, walletKind2, rails, b402
8223
8499
  lines.push(
8224
8500
  "",
8225
8501
  "# B402 merchant credentials (issued per environment after manual approval).",
8226
- free ? "# FREE price 0 does not use these credentials; leave them empty until switching to PAID." : "# PAID requires all four; all absent = dormant, partial = boot error.",
8502
+ free ? "# FREE price 0 does not use these credentials; leave them empty until switching to PAID." : "# PAID: create the agent wallet first, then apply for a separate merchant",
8503
+ ...free ? [] : [
8504
+ "# for that exact wallet and environment. Never reuse merchant credentials",
8505
+ "# across wallets.",
8506
+ `# Apply: ${B402_DEVELOPER_ACCOUNT_URL}`,
8507
+ "# PAID requires all four; all absent = dormant, partial = boot error."
8508
+ ],
8227
8509
  `B402_BASE_URL=${baseUrl}`,
8228
8510
  "B402_CLIENT_ID=",
8229
8511
  "B402_ACCESS_TOKEN=",
@@ -8301,7 +8583,7 @@ It auto-loads \`.studio/.env.local\` \u2014 no need to \`source\` it.
8301
8583
  ## Deploy (managed platform \u2014 48h testnet trial)
8302
8584
 
8303
8585
  \`\`\`bash
8304
- bag platform login # GitHub device flow (~/.bag/session.json)
8586
+ bag platform login # GitHub device flow (~/.bnbagent-deploy/bnb/session.json)
8305
8587
  # From the workspace root:
8306
8588
  bag deploy --provider bnb # explicit 48h trial provider
8307
8589
  \`\`\`
@@ -8353,7 +8635,7 @@ bag deploy --provider aws
8353
8635
  `;
8354
8636
  }
8355
8637
  function emitProviderSkills(target, provider, ides) {
8356
- const skillDir = path21.join(
8638
+ const skillDir = path22.join(
8357
8639
  bundledRecipesRoot(),
8358
8640
  "providers",
8359
8641
  provider,
@@ -8363,34 +8645,34 @@ function emitProviderSkills(target, provider, ides) {
8363
8645
  return;
8364
8646
  }
8365
8647
  let emittedCursor = false;
8366
- for (const md of fs22.readdirSync(skillDir).filter((n) => n.endsWith(".md")).sort()) {
8367
- const srcText = fs22.readFileSync(path21.join(skillDir, md), "utf-8");
8648
+ for (const md of fs23.readdirSync(skillDir).filter((n) => n.endsWith(".md")).sort()) {
8649
+ const srcText = fs23.readFileSync(path22.join(skillDir, md), "utf-8");
8368
8650
  const stem2 = md.replace(/\.md$/, "");
8369
8651
  for (const ide of ides) {
8370
8652
  const [relPath, content] = renderSkillPayload(srcText, stem2, ide);
8371
- const base = ide === "claude-code" ? path21.join(target, ".claude", "skills") : path21.join(target, ".cursor", "rules");
8372
- const dst = path21.join(base, relPath);
8373
- fs22.mkdirSync(path21.dirname(dst), { recursive: true });
8374
- fs22.writeFileSync(dst, content);
8653
+ const base = ide === "claude-code" ? path22.join(target, ".claude", "skills") : path22.join(target, ".cursor", "rules");
8654
+ const dst = path22.join(base, relPath);
8655
+ fs23.mkdirSync(path22.dirname(dst), { recursive: true });
8656
+ fs23.writeFileSync(dst, content);
8375
8657
  if (ide === "cursor") {
8376
8658
  emittedCursor = true;
8377
8659
  }
8378
8660
  }
8379
8661
  }
8380
8662
  if (emittedCursor) {
8381
- ensureCursorGitignore(path21.join(target, ".gitignore"));
8663
+ ensureCursorGitignore(path22.join(target, ".gitignore"));
8382
8664
  }
8383
8665
  }
8384
8666
  function ensureCursorGitignore(gitignore) {
8385
8667
  if (!isFile8(gitignore)) {
8386
8668
  return;
8387
8669
  }
8388
- const text2 = fs22.readFileSync(gitignore, "utf-8");
8670
+ const text2 = fs23.readFileSync(gitignore, "utf-8");
8389
8671
  if (text2.includes(".cursor/rules/")) {
8390
8672
  return;
8391
8673
  }
8392
8674
  const addition = "\n# Cursor rules emitted at init (regeneratable via `bag skills install --target cursor`).\n.cursor/rules/\n";
8393
- fs22.writeFileSync(gitignore, `${text2.replace(/\n+$/, "")}
8675
+ fs23.writeFileSync(gitignore, `${text2.replace(/\n+$/, "")}
8394
8676
  ${addition}`);
8395
8677
  }
8396
8678
  async function resolveWalletKind(flagValue, isTty) {
@@ -8572,7 +8854,7 @@ function readWalletAddress(studioToml) {
8572
8854
  return null;
8573
8855
  }
8574
8856
  try {
8575
- const data = parseToml(fs22.readFileSync(studioToml, "utf-8"));
8857
+ const data = parseToml(fs23.readFileSync(studioToml, "utf-8"));
8576
8858
  const wallet = data.wallet;
8577
8859
  if (wallet !== null && typeof wallet === "object") {
8578
8860
  const addr = wallet.address;
@@ -8675,7 +8957,9 @@ async function runOnboarding(o) {
8675
8957
  if (password === null) {
8676
8958
  return false;
8677
8959
  }
8678
- const agentRoot2 = path21.join(o.workspaceRoot, APP_DIR, AGENT_PKG);
8960
+ const agentRoot2 = path22.join(o.workspaceRoot, APP_DIR, AGENT_PKG);
8961
+ const { envLocalPath: envLocalPath19 } = await import("@bnbagent/studio-runtime/config");
8962
+ setEnvVar(envLocalPath19(agentRoot2), "WALLET_PASSWORD", password);
8679
8963
  const savedCwd = process.cwd();
8680
8964
  const savedPw = process.env.WALLET_PASSWORD;
8681
8965
  let address = null;
@@ -8701,7 +8985,7 @@ async function runOnboarding(o) {
8701
8985
  );
8702
8986
  return false;
8703
8987
  }
8704
- address = readWalletAddress(path21.join(agentRoot2, "studio.toml"));
8988
+ address = readWalletAddress(path22.join(agentRoot2, "studio.toml"));
8705
8989
  if (o.walletKind !== "altana" || o.provider !== "pieverse-llm") {
8706
8990
  await onboardProviderActivation(agentRoot2, o.provider, o.model);
8707
8991
  }
@@ -8714,8 +8998,7 @@ async function runOnboarding(o) {
8714
8998
  }
8715
8999
  }
8716
9000
  if (o.storageProvider !== "local") {
8717
- const { envLocalPath: envLocalPath18 } = await import("@bnbagent/studio-runtime/config");
8718
- await onboardIpfsKey(envLocalPath18(agentRoot2), o.ipfsKey);
9001
+ await onboardIpfsKey(envLocalPath19(agentRoot2), o.ipfsKey);
8719
9002
  }
8720
9003
  if (address) {
8721
9004
  await printFaucetHint(o.network, address);
@@ -8731,9 +9014,9 @@ async function onboardProviderActivation(agentRoot2, provider, model) {
8731
9014
  if (provider === "pieverse-llm") {
8732
9015
  const chosenModel = model ?? await promptPieverseModel();
8733
9016
  if (model === void 0) {
8734
- const tomlPath = path21.join(agentRoot2, "studio.toml");
8735
- const text2 = fs22.readFileSync(tomlPath, "utf-8");
8736
- fs22.writeFileSync(
9017
+ const tomlPath = path22.join(agentRoot2, "studio.toml");
9018
+ const text2 = fs23.readFileSync(tomlPath, "utf-8");
9019
+ fs23.writeFileSync(
8737
9020
  tomlPath,
8738
9021
  updateSection(text2, "llm", { model: chosenModel })
8739
9022
  );
@@ -8769,45 +9052,50 @@ set ${keyEnv}= in .studio/.env.local before running \`bag dev\`.`
8769
9052
  }
8770
9053
  }
8771
9054
  async function runOnboardingTwak(o) {
8772
- const agentRoot2 = path21.join(o.workspaceRoot, APP_DIR, AGENT_PKG);
8773
- const studioToml = path21.join(agentRoot2, "studio.toml");
9055
+ const agentRoot2 = path22.join(o.workspaceRoot, APP_DIR, AGENT_PKG);
9056
+ const studioToml = path22.join(agentRoot2, "studio.toml");
8774
9057
  if (await whichTwak() === null) {
8775
9058
  printErr(
8776
9059
  `
8777
9060
  wallet.kind = 'twak' but the \`twak\` CLI is not on PATH. Install it (Node >=22):
8778
9061
  npm install -g @trustwallet/cli@${TWAK_CLI_VERSION}
8779
- then create the project-dedicated wallet and finish onboarding:
8780
- HOME=$PWD/.studio/twak twak wallet create --password <your-password> --no-keychain
8781
- cd app/agent && bag wallet new && bag llm activate`
9062
+ then set up NaaS credentials once and create the project-dedicated wallet
9063
+ (\`bag wallet twak-init\` runs \`twak wallet create --password \u2026 --no-keychain\` for
9064
+ you, so you never type the password on a command line, and adopts the address):
9065
+ HOME=$PWD/.studio/twak twak setup
9066
+ cd app/agent && bag wallet twak-init && bag llm activate`
8782
9067
  );
8783
9068
  return false;
8784
9069
  }
8785
9070
  let walletCfg = {};
8786
9071
  try {
8787
- const data = parseToml(fs22.readFileSync(studioToml, "utf-8"));
9072
+ const data = parseToml(fs23.readFileSync(studioToml, "utf-8"));
8788
9073
  if (data.wallet !== null && typeof data.wallet === "object") {
8789
9074
  walletCfg = data.wallet;
8790
9075
  }
8791
9076
  } catch {
8792
9077
  walletCfg = {};
8793
9078
  }
8794
- const { twakWalletFile: twakWalletFile2 } = await import("./_twak-5XQMOFUC.js");
9079
+ const { twakWalletFile: twakWalletFile2 } = await import("./_twak-4XF4H5PL.js");
8795
9080
  let projectWallet = twakWalletFile2(walletCfg, agentRoot2);
8796
- const machineWallet = path21.join(os3.homedir(), ".twak", "wallet.json");
9081
+ const machineWallet = path22.join(os4.homedir(), ".twak", "wallet.json");
8797
9082
  if (!o.twakHomePinned && isFile8(machineWallet) && realpathIfExists(projectWallet) !== realpathIfExists(machineWallet)) {
8798
9083
  if (await promptUseMachineTwakWallet(machineWallet)) {
8799
9084
  projectWallet = adoptMachineTwakWallet(machineWallet, o.workspaceRoot);
8800
9085
  }
8801
9086
  }
8802
9087
  if (!isFile8(projectWallet)) {
8803
- const homeDir = path21.dirname(path21.dirname(projectWallet));
9088
+ const homeDir = path22.dirname(path22.dirname(projectWallet));
8804
9089
  try {
8805
- fs22.mkdirSync(homeDir, { recursive: true });
9090
+ fs23.mkdirSync(homeDir, { recursive: true });
8806
9091
  } catch {
8807
9092
  }
8808
9093
  printErr(
8809
9094
  `
8810
- No twak wallet at this project's dedicated home yet. Create it ONCE yourself (you type the password \u2014 studio never puts it on a command line; upstream S-8):
9095
+ No twak wallet at this project's dedicated home yet. Create it ONCE \u2014 let studio source the password so you never type it on a command line:
9096
+ cd app/agent && bag wallet twak-init # hidden prompt (CI: --password-stdin / --password-file)
9097
+ or do it yourself:
9098
+ HOME=${homeDir} twak setup
8811
9099
  HOME=${homeDir} twak wallet create --password <your-password> --no-keychain
8812
9100
  then finish onboarding:
8813
9101
  cd app/agent && bag wallet new && bag llm activate
@@ -8844,8 +9132,8 @@ Guide: the bnbagent-studio-using-twak-wallet.md reference (installed by \`bag sk
8844
9132
  process.chdir(savedCwd);
8845
9133
  }
8846
9134
  if (o.storageProvider !== "local") {
8847
- const { envLocalPath: envLocalPath18 } = await import("@bnbagent/studio-runtime/config");
8848
- await onboardIpfsKey(envLocalPath18(agentRoot2), o.ipfsKey);
9135
+ const { envLocalPath: envLocalPath19 } = await import("@bnbagent/studio-runtime/config");
9136
+ await onboardIpfsKey(envLocalPath19(agentRoot2), o.ipfsKey);
8849
9137
  }
8850
9138
  if (address) {
8851
9139
  await printFaucetHint(o.network, address);
@@ -8854,9 +9142,9 @@ Guide: the bnbagent-studio-using-twak-wallet.md reference (installed by \`bag sk
8854
9142
  }
8855
9143
  function realpathIfExists(p) {
8856
9144
  try {
8857
- return fs22.realpathSync(p);
9145
+ return fs23.realpathSync(p);
8858
9146
  } catch {
8859
- return path21.resolve(p);
9147
+ return path22.resolve(p);
8860
9148
  }
8861
9149
  }
8862
9150
  async function promptUseMachineTwakWallet(machineWallet) {
@@ -8869,39 +9157,39 @@ Found an existing twak wallet: ${machineWallet}`);
8869
9157
  return answer === "y" || answer === "yes";
8870
9158
  }
8871
9159
  function adoptMachineTwakWallet(machineWallet, workspaceRoot) {
8872
- const homeDir = path21.join(workspaceRoot, ".studio", "twak");
8873
- const twakDir = path21.join(homeDir, ".twak");
8874
- fs22.mkdirSync(twakDir, { recursive: true });
9160
+ const homeDir = path22.join(workspaceRoot, ".studio", "twak");
9161
+ const twakDir = path22.join(homeDir, ".twak");
9162
+ fs23.mkdirSync(twakDir, { recursive: true });
8875
9163
  try {
8876
- fs22.chmodSync(homeDir, 448);
8877
- fs22.chmodSync(twakDir, 448);
9164
+ fs23.chmodSync(homeDir, 448);
9165
+ fs23.chmodSync(twakDir, 448);
8878
9166
  } catch {
8879
9167
  }
8880
9168
  for (const name of ["wallet.json", "credentials.json"]) {
8881
- const src = path21.join(path21.dirname(machineWallet), name);
9169
+ const src = path22.join(path22.dirname(machineWallet), name);
8882
9170
  if (isFile8(src)) {
8883
- const dst = path21.join(twakDir, name);
8884
- fs22.writeFileSync(dst, fs22.readFileSync(src, "utf-8"), { mode: 384 });
8885
- fs22.chmodSync(dst, 384);
9171
+ const dst = path22.join(twakDir, name);
9172
+ fs23.writeFileSync(dst, fs23.readFileSync(src, "utf-8"), { mode: 384 });
9173
+ fs23.chmodSync(dst, 384);
8886
9174
  }
8887
9175
  }
8888
- return path21.join(twakDir, "wallet.json");
9176
+ return path22.join(twakDir, "wallet.json");
8889
9177
  }
8890
9178
  function normalizeTwakHome(raw) {
8891
- const expanded = raw.startsWith("~") ? path21.join(os3.homedir(), raw.slice(1)) : raw;
8892
- if (!path21.isAbsolute(expanded)) {
9179
+ const expanded = raw.startsWith("~") ? path22.join(os4.homedir(), raw.slice(1)) : raw;
9180
+ if (!path22.isAbsolute(expanded)) {
8893
9181
  return { home: raw };
8894
9182
  }
8895
9183
  const isFile19 = (p) => {
8896
9184
  try {
8897
- return fs22.statSync(p).isFile();
9185
+ return fs23.statSync(p).isFile();
8898
9186
  } catch {
8899
9187
  return false;
8900
9188
  }
8901
9189
  };
8902
- if (path21.basename(expanded) === ".twak") {
8903
- const parent = path21.dirname(expanded);
8904
- if (isFile19(path21.join(expanded, "wallet.json"))) {
9190
+ if (path22.basename(expanded) === ".twak") {
9191
+ const parent = path22.dirname(expanded);
9192
+ if (isFile19(path22.join(expanded, "wallet.json"))) {
8905
9193
  return {
8906
9194
  home: parent,
8907
9195
  note: `note: --twak-home points at the .twak wallet directory itself; using its parent '${parent}' as the wallet home (the runtime resolves <twak_home>/.twak/wallet.json).`
@@ -8911,15 +9199,15 @@ function normalizeTwakHome(raw) {
8911
9199
  error: `error: --twak-home must name the HOME-STYLE PARENT directory (the one that contains .twak/wallet.json), not a .twak directory itself. '${raw}' holds no wallet.json, so it cannot be auto-corrected \u2014 pass '${parent}' to adopt an existing wallet, or omit --twak-home to use the project-dedicated .studio/twak.`
8912
9200
  };
8913
9201
  }
8914
- if (isFile19(path21.join(expanded, "wallet.json")) && !isFile19(path21.join(expanded, ".twak", "wallet.json"))) {
9202
+ if (isFile19(path22.join(expanded, "wallet.json")) && !isFile19(path22.join(expanded, ".twak", "wallet.json"))) {
8915
9203
  return {
8916
- error: `error: --twak-home '${raw}' looks like a twak WALLET directory (it contains wallet.json directly). Pass its parent '${path21.dirname(expanded)}' instead \u2014 the runtime resolves <twak_home>/.twak/wallet.json.`
9204
+ error: `error: --twak-home '${raw}' looks like a twak WALLET directory (it contains wallet.json directly). Pass its parent '${path22.dirname(expanded)}' instead \u2014 the runtime resolves <twak_home>/.twak/wallet.json.`
8917
9205
  };
8918
9206
  }
8919
- if (!isFile19(path21.join(expanded, ".twak", "wallet.json"))) {
9207
+ if (!isFile19(path22.join(expanded, ".twak", "wallet.json"))) {
8920
9208
  return {
8921
9209
  home: raw,
8922
- note: `note: no wallet found at ${path21.join(raw, ".twak", "wallet.json")} \u2014 treating --twak-home as a NEW project wallet home; \`bag wallet new\` will guide wallet creation.`
9210
+ note: `note: no wallet found at ${path22.join(raw, ".twak", "wallet.json")} \u2014 treating --twak-home as a NEW project wallet home; \`bag wallet new\` will guide wallet creation.`
8923
9211
  };
8924
9212
  }
8925
9213
  return { home: raw };
@@ -8929,8 +9217,8 @@ function twakHomeIsMainHome(twakHome) {
8929
9217
  return false;
8930
9218
  }
8931
9219
  try {
8932
- const expanded = twakHome.startsWith("~") ? path21.join(os3.homedir(), twakHome.slice(1)) : twakHome;
8933
- return realpathIfExists(expanded) === realpathIfExists(os3.homedir());
9220
+ const expanded = twakHome.startsWith("~") ? path22.join(os4.homedir(), twakHome.slice(1)) : twakHome;
9221
+ return realpathIfExists(expanded) === realpathIfExists(os4.homedir());
8934
9222
  } catch {
8935
9223
  return false;
8936
9224
  }
@@ -8990,9 +9278,10 @@ function printTwakNotice(destination = "self") {
8990
9278
  NOTE \u2014 wallet.kind = "twak" (Trust Wallet Agent Kit, CLI >= ${TWAK_CLI_VERSION}):
8991
9279
  \xB7 GAS: x402 payments (e.g. Pieverse topup) are GASLESS on both networks, and
8992
9280
  ERC-8004 registry writes (register / update) are gas-sponsored on both.
8993
- ERC-8183 fund / settle are gas-sponsored on TESTNET (zero tBNB needed) but
8994
- SELF-PAY on MAINNET \u2014 keep a little BNB there. Fund only a few days of U
8995
- spend: hot wallet.
9281
+ ERC-8183 fund / settle are gas-sponsored on TESTNET for the canonical
9282
+ contracts (custom contract sponsorship depends on the paymaster policy \u2014
9283
+ keep fallback tBNB) but SELF-PAY on MAINNET \u2014 keep a little BNB there.
9284
+ Fund only a few days of U spend: hot wallet.
8996
9285
  ${deployLine}
8997
9286
  Prefer the default local keystore instead? re-run with --wallet-kind evm-local.`
8998
9287
  );
@@ -9078,11 +9367,11 @@ function entrypointHint(faces) {
9078
9367
  return "app/agent/src/main.ts + executor.ts = A2A entrypoint (build your value here)";
9079
9368
  }
9080
9369
  function hasVendoredTarballs(agentDir) {
9081
- const vendor = path21.join(agentDir, "vendor");
9370
+ const vendor = path22.join(agentDir, "vendor");
9082
9371
  if (!isDir4(vendor)) {
9083
9372
  return false;
9084
9373
  }
9085
- return fs22.readdirSync(vendor).some((n) => n.endsWith(".tgz"));
9374
+ return fs23.readdirSync(vendor).some((n) => n.endsWith(".tgz"));
9086
9375
  }
9087
9376
  function printCompactNextSteps(name, o = {}) {
9088
9377
  const faces = o.faces ?? normalizeProtocolFaces(o.protocol ?? "A2A");
@@ -9105,7 +9394,7 @@ function printCompactNextSteps(name, o = {}) {
9105
9394
  );
9106
9395
  } else {
9107
9396
  printOut(
9108
- " export WALLET_PASSWORD=\u2026 # your wallet password lives only in the shell \u2014 studio never writes it to disk"
9397
+ " # WALLET_PASSWORD is stored in .studio/.env.local (0600); never pass it on argv"
9109
9398
  );
9110
9399
  }
9111
9400
  if (walletKind2 === "altana") {
@@ -9229,9 +9518,9 @@ function printNextSteps(name, provider, o = {}) {
9229
9518
  );
9230
9519
  } else if (walletKind2 === "altana") {
9231
9520
  printOut(
9232
- " # 1. create the encrypted Altana admin keystore (password stays in your shell)"
9521
+ " # 1. set WALLET_PASSWORD in .studio/.env.local (0600), then create the encrypted Altana admin keystore"
9233
9522
  );
9234
- printOut(" export WALLET_PASSWORD=<your-password>");
9523
+ printOut(" # bag auto-loads it; never pass it on argv");
9235
9524
  printOut(" (cd app/agent && bag wallet new)");
9236
9525
  printOut(
9237
9526
  " # 2. fund the printed address with ~0.6 tBNB for bootstrap/registration + U, then grant one bounded runtime session"
@@ -9242,11 +9531,10 @@ function printNextSteps(name, provider, o = {}) {
9242
9531
  );
9243
9532
  } else {
9244
9533
  printOut(
9245
- " # 1. set a wallet password (encrypts the keystore + signs all on-chain ops)"
9534
+ " # 1. edit .studio/.env.local and set WALLET_PASSWORD (encrypts the keystore + signs all on-chain ops)"
9246
9535
  );
9247
- printOut(" export WALLET_PASSWORD=<your-password>");
9248
9536
  printOut(
9249
- " # bag reads WALLET_PASSWORD from your shell; studio never writes it to disk"
9537
+ " # bag auto-loads it from the owner-only file; never pass it on argv"
9250
9538
  );
9251
9539
  printOut("");
9252
9540
  printOut(" # 2. generate the agent's EOA wallet (the SOLE signer key)");
@@ -9337,7 +9625,7 @@ function loadTomlSafe(p) {
9337
9625
  return {};
9338
9626
  }
9339
9627
  try {
9340
- return parseToml(fs22.readFileSync(p, "utf-8"));
9628
+ return parseToml(fs23.readFileSync(p, "utf-8"));
9341
9629
  } catch {
9342
9630
  return {};
9343
9631
  }
@@ -9357,7 +9645,7 @@ function weiToU(raw) {
9357
9645
  }
9358
9646
  }
9359
9647
  function printConfigSummary(agentRoot2) {
9360
- const agent = loadTomlSafe(path21.join(agentRoot2, "studio.toml"));
9648
+ const agent = loadTomlSafe(path22.join(agentRoot2, "studio.toml"));
9361
9649
  if (Object.keys(agent).length === 0) {
9362
9650
  return;
9363
9651
  }
@@ -9537,8 +9825,9 @@ function printConfigSummary(agentRoot2) {
9537
9825
  );
9538
9826
  }
9539
9827
  if (hasX402Seller && !isFreeX402) {
9828
+ todo.push(`PAID /x402 onboarding \u2014 ${B402_PAID_ONBOARDING_GUIDANCE}`);
9540
9829
  todo.push(
9541
- "B402_BASE_URL / CLIENT_ID / ACCESS_TOKEN / private key \u2014 required for PAID /x402"
9830
+ "then set B402_BASE_URL / CLIENT_ID / ACCESS_TOKEN / private key"
9542
9831
  );
9543
9832
  }
9544
9833
  if (storageKind2 === "local") {
@@ -9556,14 +9845,14 @@ function printConfigSummary(agentRoot2) {
9556
9845
  }
9557
9846
  function isFile8(p) {
9558
9847
  try {
9559
- return fs22.statSync(p).isFile();
9848
+ return fs23.statSync(p).isFile();
9560
9849
  } catch {
9561
9850
  return false;
9562
9851
  }
9563
9852
  }
9564
9853
  function isDir4(p) {
9565
9854
  try {
9566
- return fs22.statSync(p).isDirectory();
9855
+ return fs23.statSync(p).isDirectory();
9567
9856
  } catch {
9568
9857
  return false;
9569
9858
  }
@@ -9573,11 +9862,12 @@ function isDir4(p) {
9573
9862
  var DEFAULT_AGENT_HOST = "127.0.0.1";
9574
9863
  var AGENTCORE_BIN = "agentcore";
9575
9864
  var RUNTIME_AGENTCORE = "agentcore";
9865
+ var RUNTIME_AZURE_FOUNDRY = "azure-foundry";
9576
9866
  var MIN_NODE_MAJOR = 22;
9577
9867
  var CONTAINER_RUNTIMES = ["docker", "podman", "finch"];
9578
9868
  function isFile9(p) {
9579
9869
  try {
9580
- return fs23.statSync(p).isFile();
9870
+ return fs24.statSync(p).isFile();
9581
9871
  } catch {
9582
9872
  return false;
9583
9873
  }
@@ -9609,8 +9899,8 @@ async function nodeMajor() {
9609
9899
  return /^\d+$/.test(head) ? Number.parseInt(head, 10) : null;
9610
9900
  }
9611
9901
  function workspaceBase(root) {
9612
- for (const base of [path22.join(root, "app"), root]) {
9613
- if (isFile9(path22.join(base, "agent", "studio.toml"))) {
9902
+ for (const base of [path23.join(root, "app"), root]) {
9903
+ if (isFile9(path23.join(base, "agent", "studio.toml"))) {
9614
9904
  return base;
9615
9905
  }
9616
9906
  }
@@ -9618,7 +9908,7 @@ function workspaceBase(root) {
9618
9908
  }
9619
9909
  function resolveWorkspaceRoot(argRoot) {
9620
9910
  if (argRoot !== null) {
9621
- const root = path22.resolve(argRoot);
9911
+ const root = path23.resolve(argRoot);
9622
9912
  const base = workspaceBase(root);
9623
9913
  if (base === null) {
9624
9914
  printErr(
@@ -9628,13 +9918,13 @@ function resolveWorkspaceRoot(argRoot) {
9628
9918
  }
9629
9919
  return base;
9630
9920
  }
9631
- let current = path22.resolve(process.cwd());
9921
+ let current = path23.resolve(process.cwd());
9632
9922
  for (; ; ) {
9633
9923
  const base = workspaceBase(current);
9634
9924
  if (base !== null) {
9635
9925
  return base;
9636
9926
  }
9637
- const parent = path22.dirname(current);
9927
+ const parent = path23.dirname(current);
9638
9928
  if (parent === current) {
9639
9929
  break;
9640
9930
  }
@@ -9647,24 +9937,24 @@ function resolveWorkspaceRoot(argRoot) {
9647
9937
  }
9648
9938
  function loadAgentToml2(workspaceRoot) {
9649
9939
  try {
9650
- return loadStudioToml10(
9651
- path22.join(workspaceRoot, "agent", "studio.toml")
9940
+ return loadStudioToml11(
9941
+ path23.join(workspaceRoot, "agent", "studio.toml")
9652
9942
  );
9653
9943
  } catch {
9654
9944
  return {};
9655
9945
  }
9656
9946
  }
9657
- function tableOf7(data, key) {
9947
+ function tableOf8(data, key) {
9658
9948
  const v = data[key];
9659
9949
  return v !== null && typeof v === "object" && !Array.isArray(v) ? v : {};
9660
9950
  }
9661
9951
  function agentRuntime(workspaceRoot) {
9662
- const runtime = tableOf7(loadAgentToml2(workspaceRoot), "stack").runtime;
9952
+ const runtime = tableOf8(loadAgentToml2(workspaceRoot), "stack").runtime;
9663
9953
  return typeof runtime === "string" && runtime.trim() ? runtime.trim() : RUNTIME_AGENTCORE;
9664
9954
  }
9665
9955
  function agentFaces(workspaceRoot) {
9666
9956
  const cfg = loadAgentToml2(workspaceRoot);
9667
- return stackFaces(tableOf7(cfg, "stack"), tableOf7(cfg, "payments"));
9957
+ return stackFaces(tableOf8(cfg, "stack"), tableOf8(cfg, "payments"));
9668
9958
  }
9669
9959
  function localEntryFile(faces) {
9670
9960
  return `src/${entryStemOf(faces)}.ts`;
@@ -9675,36 +9965,46 @@ function defaultAgentPort(faces) {
9675
9965
  function storageKind(agentDir) {
9676
9966
  let data;
9677
9967
  try {
9678
- data = loadStudioToml10(path22.join(agentDir, "studio.toml"));
9968
+ data = loadStudioToml11(path23.join(agentDir, "studio.toml"));
9679
9969
  } catch {
9680
9970
  return "local";
9681
9971
  }
9682
- const kind = tableOf7(data, "storage").kind;
9972
+ const kind = tableOf8(data, "storage").kind;
9683
9973
  return typeof kind === "string" && kind.trim() ? kind.trim() : "local";
9684
9974
  }
9975
+ function networkNameOf(agentDir) {
9976
+ let data;
9977
+ try {
9978
+ data = loadStudioToml11(path23.join(agentDir, "studio.toml"));
9979
+ } catch {
9980
+ return "bsc-testnet";
9981
+ }
9982
+ const name = tableOf8(data, "network").default;
9983
+ return typeof name === "string" && name.trim() ? name.trim() : "bsc-testnet";
9984
+ }
9685
9985
  function walletKindOf(agentDir) {
9686
9986
  let data;
9687
9987
  try {
9688
- data = loadStudioToml10(path22.join(agentDir, "studio.toml"));
9988
+ data = loadStudioToml11(path23.join(agentDir, "studio.toml"));
9689
9989
  } catch {
9690
9990
  return "evm-local";
9691
9991
  }
9692
- const kind = tableOf7(data, "wallet").kind;
9992
+ const kind = tableOf8(data, "wallet").kind;
9693
9993
  return typeof kind === "string" && kind.trim() ? kind.trim() : "evm-local";
9694
9994
  }
9695
9995
  function altanaSessionForRuntime(agentDir) {
9696
- const cfg = loadStudioToml10(path22.join(agentDir, "studio.toml"));
9697
- const wallet = tableOf7(cfg, "wallet");
9996
+ const cfg = loadStudioToml11(path23.join(agentDir, "studio.toml"));
9997
+ const wallet = tableOf8(cfg, "wallet");
9698
9998
  const configured = String(
9699
9999
  wallet.session_file ?? ".studio/wallets/altana-session.json"
9700
10000
  );
9701
- const sessionFile = path22.isAbsolute(configured) ? configured : path22.join(agentDir, configured);
10001
+ const sessionFile = path23.isAbsolute(configured) ? configured : path23.join(agentDir, configured);
9702
10002
  if (!isFile9(sessionFile)) {
9703
10003
  throw new Error(
9704
10004
  `no Altana session at ${sessionFile} \u2014 run \`bag wallet session grant\` first.`
9705
10005
  );
9706
10006
  }
9707
- const serialized = fs23.readFileSync(sessionFile, "utf8");
10007
+ const serialized = fs24.readFileSync(sessionFile, "utf8");
9708
10008
  let envelope;
9709
10009
  try {
9710
10010
  envelope = JSON.parse(serialized);
@@ -9736,7 +10036,7 @@ function loadEnvFileForDev(p) {
9736
10036
  if (!isFile9(p)) {
9737
10037
  return;
9738
10038
  }
9739
- for (const line of fs23.readFileSync(p, "utf-8").split(/\r?\n/)) {
10039
+ for (const line of fs24.readFileSync(p, "utf-8").split(/\r?\n/)) {
9740
10040
  if (!line || line.trimStart().startsWith("#")) {
9741
10041
  continue;
9742
10042
  }
@@ -9757,20 +10057,20 @@ function ensureStoragePath(projectRoot) {
9757
10057
  const raw = process.env.STORAGE_LOCAL_PATH;
9758
10058
  let resolved;
9759
10059
  if (raw) {
9760
- resolved = path22.resolve(
9761
- raw.startsWith("~") ? path22.join(os4.homedir(), raw.slice(1)) : raw
10060
+ resolved = path23.resolve(
10061
+ raw.startsWith("~") ? path23.join(os5.homedir(), raw.slice(1)) : raw
9762
10062
  );
9763
10063
  } else {
9764
- resolved = path22.resolve(
9765
- path22.join(
9766
- os4.homedir(),
10064
+ resolved = path23.resolve(
10065
+ path23.join(
10066
+ os5.homedir(),
9767
10067
  ".bag",
9768
10068
  "deliverables",
9769
- path22.basename(projectRoot)
10069
+ path23.basename(projectRoot)
9770
10070
  )
9771
10071
  );
9772
10072
  }
9773
- fs23.mkdirSync(resolved, { recursive: true });
10073
+ fs24.mkdirSync(resolved, { recursive: true });
9774
10074
  process.env.STORAGE_LOCAL_PATH = resolved;
9775
10075
  }
9776
10076
  function ipfsPreflight(agentDir) {
@@ -9785,12 +10085,12 @@ function ipfsPreflight(agentDir) {
9785
10085
  function runtimeEnvKeys(agentDir) {
9786
10086
  let cfg = {};
9787
10087
  try {
9788
- cfg = loadStudioToml10(path22.join(agentDir, "studio.toml"));
10088
+ cfg = loadStudioToml11(path23.join(agentDir, "studio.toml"));
9789
10089
  } catch {
9790
10090
  cfg = {};
9791
10091
  }
9792
10092
  const resolvable = (key) => Boolean(process.env[key]);
9793
- const kind = tableOf7(cfg, "wallet").kind;
10093
+ const kind = tableOf8(cfg, "wallet").kind;
9794
10094
  let keys;
9795
10095
  if (kind === "twak") {
9796
10096
  keys = ["TWAK_WALLET_PASSWORD"];
@@ -9804,12 +10104,12 @@ function runtimeEnvKeys(agentDir) {
9804
10104
  } else {
9805
10105
  keys = ["WALLET_PASSWORD"];
9806
10106
  }
9807
- const provider = tableOf7(cfg, "llm").provider;
10107
+ const provider = tableOf8(cfg, "llm").provider;
9808
10108
  const providerKey = typeof provider === "string" ? PROVIDER_KEY_ENV[provider] : null;
9809
10109
  if (providerKey) {
9810
10110
  keys.push(providerKey);
9811
10111
  }
9812
- const sk = String(tableOf7(cfg, "storage").kind ?? "local").toLowerCase();
10112
+ const sk = String(tableOf8(cfg, "storage").kind ?? "local").toLowerCase();
9813
10113
  if (sk === "ipfs") {
9814
10114
  keys.push("STORAGE_API_URL");
9815
10115
  if (resolvable("STORAGE_API_KEY")) {
@@ -9824,7 +10124,7 @@ function runtimeEnvKeys(agentDir) {
9824
10124
  if (resolvable(key)) keys.push(key);
9825
10125
  }
9826
10126
  }
9827
- const runtime = String(tableOf7(cfg, "stack").runtime ?? "agentcore");
10127
+ const runtime = String(tableOf8(cfg, "stack").runtime ?? "agentcore");
9828
10128
  if (runtime === "agentcore" && x402SellerUsesB402(cfg)) {
9829
10129
  for (const key of B402_RUNTIME_KEYS) {
9830
10130
  if (resolvable(key)) keys.push(key);
@@ -9842,8 +10142,8 @@ function compactJson(text2) {
9842
10142
  function readTwakFiles(agentDir) {
9843
10143
  let walletCfg = {};
9844
10144
  try {
9845
- walletCfg = tableOf7(
9846
- loadStudioToml10(path22.join(agentDir, "studio.toml")),
10145
+ walletCfg = tableOf8(
10146
+ loadStudioToml11(path23.join(agentDir, "studio.toml")),
9847
10147
  "wallet"
9848
10148
  );
9849
10149
  } catch {
@@ -9851,9 +10151,9 @@ function readTwakFiles(agentDir) {
9851
10151
  }
9852
10152
  const twakDir = twakHomeDir(walletCfg, agentDir);
9853
10153
  const read = (name) => {
9854
- const p = path22.join(twakDir, name);
10154
+ const p = path23.join(twakDir, name);
9855
10155
  try {
9856
- return fs23.readFileSync(p, "utf-8");
10156
+ return fs24.readFileSync(p, "utf-8");
9857
10157
  } catch {
9858
10158
  return null;
9859
10159
  }
@@ -9861,19 +10161,19 @@ function readTwakFiles(agentDir) {
9861
10161
  return [read("wallet.json"), read("credentials.json")];
9862
10162
  }
9863
10163
  function ensureAgentcoreEnvGitignored(agentcoreDir) {
9864
- const gi = path22.join(agentcoreDir, ".gitignore");
10164
+ const gi = path23.join(agentcoreDir, ".gitignore");
9865
10165
  const entry = ".env.local";
9866
10166
  if (isFile9(gi)) {
9867
- const text2 = fs23.readFileSync(gi, "utf-8");
10167
+ const text2 = fs24.readFileSync(gi, "utf-8");
9868
10168
  const lines = new Set(text2.split("\n").map((l) => l.trim()));
9869
10169
  if (lines.has(entry)) {
9870
10170
  return;
9871
10171
  }
9872
10172
  const sep6 = text2.endsWith("\n") || text2 === "" ? "" : "\n";
9873
- fs23.writeFileSync(gi, `${text2}${sep6}${entry}
10173
+ fs24.writeFileSync(gi, `${text2}${sep6}${entry}
9874
10174
  `);
9875
10175
  } else {
9876
- fs23.writeFileSync(gi, `${entry}
10176
+ fs24.writeFileSync(gi, `${entry}
9877
10177
  `);
9878
10178
  }
9879
10179
  }
@@ -9896,8 +10196,8 @@ function writeAgentcoreEnvLocal(agentcoreRoot, agentDir) {
9896
10196
  } else if (walletKindOf(agentDir) === "altana") {
9897
10197
  bundle.ALTANA_SESSION = altanaSessionForRuntime(agentDir);
9898
10198
  }
9899
- const envPath = path22.join(agentcoreRoot, "agentcore", ".env.local");
9900
- const prior = isFile9(envPath) ? fs23.readFileSync(envPath, "utf-8") : "";
10199
+ const envPath = path23.join(agentcoreRoot, "agentcore", ".env.local");
10200
+ const prior = isFile9(envPath) ? fs24.readFileSync(envPath, "utf-8") : "";
9901
10201
  const merged = {};
9902
10202
  for (const line of prior.split("\n")) {
9903
10203
  if (!line || line.trimStart().startsWith("#")) {
@@ -9912,14 +10212,14 @@ function writeAgentcoreEnvLocal(agentcoreRoot, agentDir) {
9912
10212
  Object.assign(merged, bundle);
9913
10213
  const content = Object.entries(merged).map(([k, v]) => `${k}=${v}
9914
10214
  `).join("");
9915
- fs23.mkdirSync(path22.dirname(envPath), { recursive: true });
9916
- ensureAgentcoreEnvGitignored(path22.dirname(envPath));
10215
+ fs24.mkdirSync(path23.dirname(envPath), { recursive: true });
10216
+ ensureAgentcoreEnvGitignored(path23.dirname(envPath));
9917
10217
  writePrivate2(envPath, content);
9918
10218
  return [envPath, content !== prior];
9919
10219
  }
9920
10220
  function agentcoreProjectRoot2(workspaceRoot) {
9921
- for (const candidate of [path22.dirname(workspaceRoot), workspaceRoot]) {
9922
- if (isFile9(path22.join(candidate, "agentcore", "agentcore.json"))) {
10221
+ for (const candidate of [path23.dirname(workspaceRoot), workspaceRoot]) {
10222
+ if (isFile9(path23.join(candidate, "agentcore", "agentcore.json"))) {
9923
10223
  return candidate;
9924
10224
  }
9925
10225
  }
@@ -9928,8 +10228,8 @@ function agentcoreProjectRoot2(workspaceRoot) {
9928
10228
  function loadAgentcoreConfig(projectRoot) {
9929
10229
  try {
9930
10230
  const cfg = JSON.parse(
9931
- fs23.readFileSync(
9932
- path22.join(projectRoot, "agentcore", "agentcore.json"),
10231
+ fs24.readFileSync(
10232
+ path23.join(projectRoot, "agentcore", "agentcore.json"),
9933
10233
  "utf-8"
9934
10234
  )
9935
10235
  );
@@ -10019,11 +10319,11 @@ async function cmdDev(opts) {
10019
10319
  if (workspaceRoot === null) {
10020
10320
  return 2;
10021
10321
  }
10022
- const agentDir = path22.join(workspaceRoot, "agent");
10322
+ const agentDir = path23.join(workspaceRoot, "agent");
10023
10323
  migrateEnvLocal(agentDir);
10024
10324
  migrateKeystoreOutOfCodelocation(agentDir);
10025
- const { envLocalPath: envLocalPath18 } = await import("@bnbagent/studio-runtime/config");
10026
- loadEnvFileForDev(envLocalPath18(agentDir));
10325
+ const { envLocalPath: envLocalPath19 } = await import("@bnbagent/studio-runtime/config");
10326
+ loadEnvFileForDev(envLocalPath19(agentDir));
10027
10327
  ensureStoragePath(workspaceRoot);
10028
10328
  const ipfsErr = ipfsPreflight(agentDir);
10029
10329
  if (ipfsErr !== null) {
@@ -10055,7 +10355,7 @@ async function cmdDev(opts) {
10055
10355
  const runtime = agentRuntime(workspaceRoot);
10056
10356
  const container = Boolean(opts.container);
10057
10357
  const entryFile = localEntryFile(faces);
10058
- const agentFile = path22.join(agentDir, entryFile);
10358
+ const agentFile = path23.join(agentDir, entryFile);
10059
10359
  if (!isFile9(agentFile)) {
10060
10360
  printErr(
10061
10361
  `error: Agent entrypoint file ${agentFile} does not exist. [stack] faces = [${faces.join(", ")}], so the entrypoint is ${entryFile} (A2A/X402-only \u2192 src/main.ts, MCP \u2192 src/mcpMain.ts, A2A+MCP \u2192 src/dualMain.ts). Run \`bag init\` to scaffold the workspace.`
@@ -10069,6 +10369,17 @@ async function cmdDev(opts) {
10069
10369
  );
10070
10370
  return 2;
10071
10371
  }
10372
+ if (walletKind2 === "twak") {
10373
+ const unsupported = twakUnsupportedContractOverrides(
10374
+ networkNameOf(agentDir)
10375
+ );
10376
+ if (unsupported.length > 0) {
10377
+ const keys = unsupported.map((item) => item.envKey).join(", ");
10378
+ printErr(
10379
+ `warning: wallet.kind='twak' cannot use the selected custom ERC-8183 targets (${keys}): twak v0.20.0 has no Commerce/Router/Policy address option, so on-chain 8183 writes (submit/fund/settle) will fail against this stack. Use wallet.kind='evm-local' for custom ERC-8183 contracts, or remove the overrides and use the canonical stack. ERC8004_REGISTRY_ADDRESS is supported.`
10380
+ );
10381
+ }
10382
+ }
10072
10383
  if (await devPortInUse(agentPort)) {
10073
10384
  printErr(
10074
10385
  `error: port ${agentPort} is already in use on 127.0.0.1 (another \`bag dev\`?). Stop it or pass --port <other>.`
@@ -10123,7 +10434,7 @@ Switch to Node \u226522 so it wins on PATH, then reopen the shell and retry. Ver
10123
10434
  }
10124
10435
  let launch;
10125
10436
  if (runtime === RUNTIME_AGENTCORE && container) {
10126
- const root = path22.resolve(agentcoreRoot);
10437
+ const root = path23.resolve(agentcoreRoot);
10127
10438
  try {
10128
10439
  const vendored = await vendorLocalTarballs(agentDir);
10129
10440
  if (vendored.length > 0) {
@@ -10138,7 +10449,7 @@ Switch to Node \u226522 so it wins on PATH, then reopen the shell and retry. Ver
10138
10449
  }
10139
10450
  const [envPath, changed] = writeAgentcoreEnvLocal(root, agentDir);
10140
10451
  printOut(
10141
- `bag dev: wrote ${path22.relative(root, envPath)} (runtime secrets + materialized wallet for the container).`
10452
+ `bag dev: wrote ${path23.relative(root, envPath)} (runtime secrets + materialized wallet for the container).`
10142
10453
  );
10143
10454
  if (changed && process.env.BAG_DEV_ENV_WARNED !== "1") {
10144
10455
  printErr(
@@ -10186,6 +10497,11 @@ Switch to Node \u226522 so it wins on PATH, then reopen the shell and retry. Ver
10186
10497
  printOut(
10187
10498
  `bag dev: starting Agent in-process (\`tsx ${args.join(" ")}\` on :${agentPort}, no Docker \u2014 the entrypoint self-serves; cwd=${agentDir}, runner=${runner2})`
10188
10499
  );
10500
+ if (runtime === RUNTIME_AZURE_FOUNDRY) {
10501
+ printOut(
10502
+ "bag dev: azure-foundry serves this local A2A/MCP entrypoint in-process; src/foundryMain.ts is the deploy-only Foundry host (the entrypoint `bag doctor` reports) and never runs here."
10503
+ );
10504
+ }
10189
10505
  launch = () => runStream(runner2, args, { cwd: agentDir, env });
10190
10506
  }
10191
10507
  const banner = networkBanner(agentDir);
@@ -10210,7 +10526,7 @@ Switch to Node \u226522 so it wins on PATH, then reopen the shell and retry. Ver
10210
10526
  }
10211
10527
  if (hasX402Face(faces)) {
10212
10528
  const free = x402SellerIsFree(
10213
- loadStudioToml10(path22.join(agentDir, "studio.toml"))
10529
+ loadStudioToml11(path23.join(agentDir, "studio.toml"))
10214
10530
  );
10215
10531
  printOut(
10216
10532
  free ? `bag dev: x402 seller at http://localhost:${agentPort}/x402 (FREE \u2014 anonymous passthrough; B402 bypassed)` : `bag dev: x402 seller at http://localhost:${agentPort}/x402 (PAID \u2014 active when B402 credentials are configured)`
@@ -10221,8 +10537,8 @@ Switch to Node \u226522 so it wins on PATH, then reopen the shell and retry. Ver
10221
10537
  }
10222
10538
  function tsxRunner(agentDir, workspaceBaseDir) {
10223
10539
  const bin = process.platform === "win32" ? "tsx.cmd" : "tsx";
10224
- for (const dir of [agentDir, path22.dirname(workspaceBaseDir)]) {
10225
- const candidate = path22.join(dir, "node_modules", ".bin", bin);
10540
+ for (const dir of [agentDir, path23.dirname(workspaceBaseDir)]) {
10541
+ const candidate = path23.join(dir, "node_modules", ".bin", bin);
10226
10542
  if (isFile9(candidate)) {
10227
10543
  return candidate;
10228
10544
  }
@@ -10232,11 +10548,11 @@ function tsxRunner(agentDir, workspaceBaseDir) {
10232
10548
  function networkBanner(agentDir) {
10233
10549
  let data;
10234
10550
  try {
10235
- data = loadStudioToml10(path22.join(agentDir, "studio.toml"));
10551
+ data = loadStudioToml11(path23.join(agentDir, "studio.toml"));
10236
10552
  } catch {
10237
10553
  return null;
10238
10554
  }
10239
- const name = tableOf7(data, "network").default;
10555
+ const name = tableOf8(data, "network").default;
10240
10556
  if (typeof name !== "string" || !name.trim()) {
10241
10557
  return null;
10242
10558
  }
@@ -10249,34 +10565,34 @@ function networkBanner(agentDir) {
10249
10565
  }
10250
10566
 
10251
10567
  // src/cli/_deploy/checks/critical.ts
10252
- import * as fs24 from "fs";
10568
+ import * as fs25 from "fs";
10253
10569
  import { createRequire } from "module";
10254
- import * as path23 from "path";
10255
- import { envLocalPath as envLocalPath10, loadStudioToml as loadStudioToml11 } from "@bnbagent/studio-runtime/config";
10570
+ import * as path24 from "path";
10571
+ import { envLocalPath as envLocalPath11, loadStudioToml as loadStudioToml12 } from "@bnbagent/studio-runtime/config";
10256
10572
  import { pieverseKeyHash as pieverseKeyHash2 } from "@bnbagent/studio-runtime/llm";
10257
10573
  var AGENTCORE_DESCRIPTOR2 = "agentcore/agentcore.json";
10258
10574
  function isFile10(p) {
10259
10575
  try {
10260
- return fs24.statSync(p).isFile();
10576
+ return fs25.statSync(p).isFile();
10261
10577
  } catch {
10262
10578
  return false;
10263
10579
  }
10264
10580
  }
10265
10581
  function isDir5(p) {
10266
10582
  try {
10267
- return fs24.statSync(p).isDirectory();
10583
+ return fs25.statSync(p).isDirectory();
10268
10584
  } catch {
10269
10585
  return false;
10270
10586
  }
10271
10587
  }
10272
10588
  function keystoreDirOf(root, data) {
10273
10589
  const rel = String(tableOf2(data, "wallet").keystore_dir ?? ".studio/wallets");
10274
- const dir = path23.isAbsolute(rel) ? rel : path23.join(agentRootOf(root), rel);
10275
- return path23.resolve(dir);
10590
+ const dir = path24.isAbsolute(rel) ? rel : path24.join(agentRootOf(root), rel);
10591
+ return path24.resolve(dir);
10276
10592
  }
10277
10593
  function keystoreJsonFiles2(dir) {
10278
10594
  try {
10279
- return fs24.readdirSync(dir).filter((n) => n.endsWith(".json")).sort();
10595
+ return fs25.readdirSync(dir).filter((n) => n.endsWith(".json")).sort();
10280
10596
  } catch {
10281
10597
  return [];
10282
10598
  }
@@ -10284,11 +10600,11 @@ function keystoreJsonFiles2(dir) {
10284
10600
  function runtimeEnvKeys2(agentRoot2) {
10285
10601
  let cfg = {};
10286
10602
  try {
10287
- cfg = loadStudioToml11(path23.join(agentRoot2, "studio.toml"));
10603
+ cfg = loadStudioToml12(path24.join(agentRoot2, "studio.toml"));
10288
10604
  } catch {
10289
10605
  cfg = {};
10290
10606
  }
10291
- const resolvable = (key) => Boolean(process.env[key] || getEnvVar(envLocalPath10(agentRoot2), key));
10607
+ const resolvable = (key) => Boolean(process.env[key] || getEnvVar(envLocalPath11(agentRoot2), key));
10292
10608
  const walletKind2 = tableOf2(cfg, "wallet").kind ?? "evm-local";
10293
10609
  let keys;
10294
10610
  if (walletKind2 === "twak") {
@@ -10338,7 +10654,7 @@ async function checkAgentcoreJsonPresent(root, target) {
10338
10654
  if (target !== "agentcore") {
10339
10655
  return [];
10340
10656
  }
10341
- const descriptor = path23.join(root, AGENTCORE_DESCRIPTOR2);
10657
+ const descriptor = path24.join(root, AGENTCORE_DESCRIPTOR2);
10342
10658
  if (isFile10(descriptor)) {
10343
10659
  return [];
10344
10660
  }
@@ -10355,10 +10671,10 @@ async function checkAgentcoreAuthorizerKeyLegacy(root, target) {
10355
10671
  if (target !== "agentcore") {
10356
10672
  return [];
10357
10673
  }
10358
- const descriptor = path23.join(root, AGENTCORE_DESCRIPTOR2);
10674
+ const descriptor = path24.join(root, AGENTCORE_DESCRIPTOR2);
10359
10675
  let data;
10360
10676
  try {
10361
- data = JSON.parse(fs24.readFileSync(descriptor, "utf-8"));
10677
+ data = JSON.parse(fs25.readFileSync(descriptor, "utf-8"));
10362
10678
  } catch {
10363
10679
  return [];
10364
10680
  }
@@ -10398,10 +10714,10 @@ async function checkAgentPackagePresent(root, target) {
10398
10714
  sourceEntries.push("src/mcpMain.ts");
10399
10715
  }
10400
10716
  const missingSource = sourceEntries.find(
10401
- (entry) => !isFile10(path23.join(agentRoot2, entry))
10717
+ (entry) => !isFile10(path24.join(agentRoot2, entry))
10402
10718
  );
10403
10719
  if (missingSource !== void 0) {
10404
- const epPath = path23.join(agentRoot2, missingSource);
10720
+ const epPath = path24.join(agentRoot2, missingSource);
10405
10721
  return [
10406
10722
  {
10407
10723
  level: Level.CRITICAL,
@@ -10416,10 +10732,10 @@ async function checkAgentPackagePresent(root, target) {
10416
10732
  distEntries.push("dist/mcpMain.js");
10417
10733
  }
10418
10734
  const missingDist = distEntries.find(
10419
- (entry) => !isFile10(path23.join(agentRoot2, entry))
10735
+ (entry) => !isFile10(path24.join(agentRoot2, entry))
10420
10736
  );
10421
10737
  if (missingDist !== void 0) {
10422
- const distPath = path23.join(agentRoot2, missingDist);
10738
+ const distPath = path24.join(agentRoot2, missingDist);
10423
10739
  return [
10424
10740
  {
10425
10741
  level: Level.WARNING,
@@ -10444,8 +10760,8 @@ async function checkKeystoreNotInsideAgent(root, target) {
10444
10760
  if (!isDir5(keystoreDir) || keystoreJsonFiles2(keystoreDir).length === 0) {
10445
10761
  return [];
10446
10762
  }
10447
- const agentDir = path23.resolve(agentRootOf(root));
10448
- const inside2 = keystoreDir === agentDir || keystoreDir.startsWith(agentDir + path23.sep);
10763
+ const agentDir = path24.resolve(agentRootOf(root));
10764
+ const inside2 = keystoreDir === agentDir || keystoreDir.startsWith(agentDir + path24.sep);
10449
10765
  if (!inside2) {
10450
10766
  return [];
10451
10767
  }
@@ -10453,7 +10769,7 @@ async function checkKeystoreNotInsideAgent(root, target) {
10453
10769
  {
10454
10770
  level: Level.WARNING,
10455
10771
  name: "keystore_not_inside_agent",
10456
- message: `keystore dir ${keystoreDir} is INSIDE the deploy codeLocation (${agentDir}) \u2014 a legacy layout. \`bag deploy --provider aws\` and \`bag doctor\` auto-migrate it to <workspace>/.studio/wallets (and repoint [wallet].keystore_dir). Fix: run \`bag doctor\` or move it manually and set [wallet].keystore_dir = "../../.studio/wallets".`,
10772
+ message: `keystore dir ${keystoreDir} is INSIDE the deploy codeLocation (${agentDir}) \u2014 a legacy layout. \`bag dev\` and \`bag deploy\` auto-migrate it to <workspace>/.studio/wallets (and repoint [wallet].keystore_dir). Fix: run \`bag dev\` once, or move it manually and set [wallet].keystore_dir = "../../.studio/wallets".`,
10457
10773
  details: { keystore_dir: keystoreDir, agent_dir: agentDir }
10458
10774
  }
10459
10775
  ];
@@ -10521,18 +10837,18 @@ async function checkLlmProviderKeySet(root, _target) {
10521
10837
  function gitignoreLines(p) {
10522
10838
  try {
10523
10839
  return new Set(
10524
- fs24.readFileSync(p, "utf-8").split(/\r?\n/).map((l) => l.trim())
10840
+ fs25.readFileSync(p, "utf-8").split(/\r?\n/).map((l) => l.trim())
10525
10841
  );
10526
10842
  } catch {
10527
10843
  return null;
10528
10844
  }
10529
10845
  }
10530
10846
  function agentcoreEnvLocalIgnored(ws) {
10531
- const wsLines = gitignoreLines(path23.join(ws, ".gitignore"));
10847
+ const wsLines = gitignoreLines(path24.join(ws, ".gitignore"));
10532
10848
  if (wsLines?.has("agentcore/.env.local")) {
10533
10849
  return true;
10534
10850
  }
10535
- const acLines = gitignoreLines(path23.join(ws, "agentcore", ".gitignore"));
10851
+ const acLines = gitignoreLines(path24.join(ws, "agentcore", ".gitignore"));
10536
10852
  return acLines?.has(".env.local") ?? false;
10537
10853
  }
10538
10854
  function studioIgnored(lines) {
@@ -10543,8 +10859,8 @@ function studioIgnored(lines) {
10543
10859
  }
10544
10860
  async function checkGitignoreExcludesSecrets(root, _target) {
10545
10861
  const out = [];
10546
- const ws = path23.dirname(path23.dirname(envLocalPath10(root)));
10547
- const gi = path23.join(ws, ".gitignore");
10862
+ const ws = path24.dirname(path24.dirname(envLocalPath11(root)));
10863
+ const gi = path24.join(ws, ".gitignore");
10548
10864
  const lines = gitignoreLines(gi);
10549
10865
  if (lines === null) {
10550
10866
  return [
@@ -10566,7 +10882,7 @@ async function checkGitignoreExcludesSecrets(root, _target) {
10566
10882
  details: { missing: [".studio/"] }
10567
10883
  });
10568
10884
  }
10569
- if (isDir5(path23.join(ws, "agentcore")) && !agentcoreEnvLocalIgnored(ws)) {
10885
+ if (isDir5(path24.join(ws, "agentcore")) && !agentcoreEnvLocalIgnored(ws)) {
10570
10886
  out.push({
10571
10887
  level: Level.CRITICAL,
10572
10888
  name: "gitignore_excludes_secrets",
@@ -10583,16 +10899,16 @@ function installedRuntimeVersion() {
10583
10899
  }
10584
10900
  try {
10585
10901
  const entry = require2.resolve("@bnbagent/studio-runtime");
10586
- let dir = path23.dirname(entry);
10902
+ let dir = path24.dirname(entry);
10587
10903
  for (let i = 0; i < 10; i++) {
10588
- const pkgPath = path23.join(dir, "package.json");
10904
+ const pkgPath = path24.join(dir, "package.json");
10589
10905
  if (isFile10(pkgPath)) {
10590
- const pkg = JSON.parse(fs24.readFileSync(pkgPath, "utf-8"));
10906
+ const pkg = JSON.parse(fs25.readFileSync(pkgPath, "utf-8"));
10591
10907
  if (pkg.name === "@bnbagent/studio-runtime") {
10592
10908
  return typeof pkg.version === "string" ? pkg.version : null;
10593
10909
  }
10594
10910
  }
10595
- const parent = path23.dirname(dir);
10911
+ const parent = path24.dirname(dir);
10596
10912
  if (parent === dir) {
10597
10913
  break;
10598
10914
  }
@@ -10649,7 +10965,7 @@ async function checkPieverseKeyHash(root, _target) {
10649
10965
  ];
10650
10966
  }
10651
10967
  const agentRoot2 = agentRootOf(root);
10652
- const apiKey = getEnvVar(envLocalPath10(agentRoot2), "PIEVERSE_LLM_API_KEY") || process.env.PIEVERSE_LLM_API_KEY;
10968
+ const apiKey = getEnvVar(envLocalPath11(agentRoot2), "PIEVERSE_LLM_API_KEY") || process.env.PIEVERSE_LLM_API_KEY;
10653
10969
  if (!apiKey) return [];
10654
10970
  const configured = String(pvCfg.key_hash).trim().toLowerCase().replace(/^0x/u, "");
10655
10971
  const actual = pieverseKeyHash2(apiKey);
@@ -10822,7 +11138,7 @@ function x402SellerRailChecks(agentRoot2, cfg, target) {
10822
11138
  out.push({
10823
11139
  level: Level.CRITICAL,
10824
11140
  name: "x402_credentials_partial",
10825
- message: "B402 credentials are only partially configured. Set BASE_URL, CLIENT_ID, ACCESS_TOKEN, and exactly one private-key form before deploy.",
11141
+ message: `B402 credentials are only partially configured. Set BASE_URL, CLIENT_ID, ACCESS_TOKEN, and exactly one private-key form before deploy. Confirm they were issued for this exact agent wallet and environment; never reuse them across wallets. Apply: ${B402_DEVELOPER_ACCOUNT_URL}`,
10826
11142
  details: { present: credentials.presentKeys }
10827
11143
  });
10828
11144
  }
@@ -10838,7 +11154,7 @@ function x402SellerRailChecks(agentRoot2, cfg, target) {
10838
11154
  out.push({
10839
11155
  level: rails.erc8183 ? Level.WARNING : Level.CRITICAL,
10840
11156
  name: "x402_credentials_missing",
10841
- message: "The x402 seller rail is enabled but all B402 credentials are absent, so it will start dormant.",
11157
+ message: `The x402 seller rail is enabled but all B402 credentials are absent, so it will start dormant. ${B402_PAID_ONBOARDING_GUIDANCE}`,
10842
11158
  details: {}
10843
11159
  });
10844
11160
  }
@@ -10876,9 +11192,9 @@ function x402SellerRailChecks(agentRoot2, cfg, target) {
10876
11192
  details: { destination, target, stackRuntime: stackRuntime2 }
10877
11193
  });
10878
11194
  }
10879
- const dockerfile = path23.join(agentRoot2, "Dockerfile");
11195
+ const dockerfile = path24.join(agentRoot2, "Dockerfile");
10880
11196
  if (rails.x402 && isFile10(dockerfile)) {
10881
- const source = fs24.readFileSync(dockerfile, "utf8");
11197
+ const source = fs25.readFileSync(dockerfile, "utf8");
10882
11198
  if (!/^\s*FROM\s+node:22(?:[.-]|\s|$)/im.test(source)) {
10883
11199
  out.push({
10884
11200
  level: Level.WARNING,
@@ -10951,10 +11267,10 @@ async function checkDeployCliRunnable(_root, target) {
10951
11267
  ];
10952
11268
  }
10953
11269
  function agentcoreEnvVars(root) {
10954
- const descriptor = path23.join(root, AGENTCORE_DESCRIPTOR2);
11270
+ const descriptor = path24.join(root, AGENTCORE_DESCRIPTOR2);
10955
11271
  let data;
10956
11272
  try {
10957
- data = JSON.parse(fs24.readFileSync(descriptor, "utf-8"));
11273
+ data = JSON.parse(fs25.readFileSync(descriptor, "utf-8"));
10958
11274
  } catch {
10959
11275
  return [];
10960
11276
  }
@@ -10999,7 +11315,7 @@ async function checkRuntimeSecretsInjected(root, target) {
10999
11315
  }
11000
11316
  const missing = needed.filter((k) => !present[k]);
11001
11317
  if (missing.length > 0) {
11002
- const envLocal = envLocalPath10(root);
11318
+ const envLocal = envLocalPath11(root);
11003
11319
  const recoverable = missing.filter(
11004
11320
  (k) => Boolean(process.env[k] || getEnvVar(envLocal, k))
11005
11321
  );
@@ -11036,7 +11352,7 @@ async function checkRuntimeSecretsInjected(root, target) {
11036
11352
  }
11037
11353
  ];
11038
11354
  }
11039
- const lines = gitignoreLines(path23.join(root, ".gitignore"));
11355
+ const lines = gitignoreLines(path24.join(root, ".gitignore"));
11040
11356
  let tracked = true;
11041
11357
  if (lines !== null) {
11042
11358
  for (const p of ["agentcore/agentcore.json", "agentcore/", "/agentcore/"]) {
@@ -11061,7 +11377,7 @@ async function checkAwsTargetsPopulated(root, target) {
11061
11377
  if (target !== "agentcore") {
11062
11378
  return [];
11063
11379
  }
11064
- const p = path23.join(root, "agentcore", "aws-targets.json");
11380
+ const p = path24.join(root, "agentcore", "aws-targets.json");
11065
11381
  const [account, region] = readAwsTarget(root);
11066
11382
  if (account && region) {
11067
11383
  return [];
@@ -11108,44 +11424,44 @@ var TWAK_WALLET_JSON_ENV = "TWAK_WALLET_JSON";
11108
11424
  var TWAK_CREDENTIALS_JSON_ENV = "TWAK_CREDENTIALS_JSON";
11109
11425
  function isFile11(p) {
11110
11426
  try {
11111
- return fs25.statSync(p).isFile();
11427
+ return fs26.statSync(p).isFile();
11112
11428
  } catch {
11113
11429
  return false;
11114
11430
  }
11115
11431
  }
11116
11432
  function loadTomlOr(agentRoot2) {
11117
11433
  try {
11118
- return loadStudioToml12(path24.join(agentRoot2, "studio.toml"));
11434
+ return loadStudioToml13(path25.join(agentRoot2, "studio.toml"));
11119
11435
  } catch {
11120
11436
  return {};
11121
11437
  }
11122
11438
  }
11123
- function tableOf8(cfg, key) {
11439
+ function tableOf9(cfg, key) {
11124
11440
  const v = cfg[key];
11125
11441
  return v !== null && typeof v === "object" && !Array.isArray(v) ? v : {};
11126
11442
  }
11127
11443
  function deployWalletKind(agentRoot2) {
11128
- const kind = tableOf8(loadTomlOr(agentRoot2), "wallet").kind;
11444
+ const kind = tableOf9(loadTomlOr(agentRoot2), "wallet").kind;
11129
11445
  return kind ? String(kind) : "evm-local";
11130
11446
  }
11131
11447
  function resolveKeystoreDir3(agentRoot2) {
11132
11448
  const rel = String(
11133
- tableOf8(loadTomlOr(agentRoot2), "wallet").keystore_dir ?? ".studio/wallets"
11449
+ tableOf9(loadTomlOr(agentRoot2), "wallet").keystore_dir ?? ".studio/wallets"
11134
11450
  );
11135
- return path24.resolve(path24.isAbsolute(rel) ? rel : path24.join(agentRoot2, rel));
11451
+ return path25.resolve(path25.isAbsolute(rel) ? rel : path25.join(agentRoot2, rel));
11136
11452
  }
11137
11453
  function readKeystoreJson(agentRoot2) {
11138
11454
  const keystoreDir = resolveKeystoreDir3(agentRoot2);
11139
11455
  let names;
11140
11456
  try {
11141
- names = fs25.readdirSync(keystoreDir).filter((n) => n.endsWith(".json")).sort();
11457
+ names = fs26.readdirSync(keystoreDir).filter((n) => n.endsWith(".json")).sort();
11142
11458
  } catch {
11143
11459
  return null;
11144
11460
  }
11145
11461
  if (names.length === 0) {
11146
11462
  return null;
11147
11463
  }
11148
- const address = tableOf8(loadTomlOr(agentRoot2), "wallet").address;
11464
+ const address = tableOf9(loadTomlOr(agentRoot2), "wallet").address;
11149
11465
  let chosen = null;
11150
11466
  if (typeof address === "string" && address) {
11151
11467
  for (const n of names) {
@@ -11160,9 +11476,9 @@ function readKeystoreJson(agentRoot2) {
11160
11476
  );
11161
11477
  }
11162
11478
  }
11163
- const file = path24.join(keystoreDir, chosen ?? names[0]);
11479
+ const file = path25.join(keystoreDir, chosen ?? names[0]);
11164
11480
  try {
11165
- return fs25.readFileSync(file, "utf-8");
11481
+ return fs26.readFileSync(file, "utf-8");
11166
11482
  } catch {
11167
11483
  return null;
11168
11484
  }
@@ -11170,11 +11486,11 @@ function readKeystoreJson(agentRoot2) {
11170
11486
  function readEnvLocal(agentRoot2) {
11171
11487
  const values = {};
11172
11488
  try {
11173
- const file = envLocalPath11(agentRoot2);
11489
+ const file = envLocalPath12(agentRoot2);
11174
11490
  if (!isFile11(file)) {
11175
11491
  return values;
11176
11492
  }
11177
- for (const rawLine of fs25.readFileSync(file, "utf-8").split(/\r?\n/)) {
11493
+ for (const rawLine of fs26.readFileSync(file, "utf-8").split(/\r?\n/)) {
11178
11494
  const line = rawLine.trim();
11179
11495
  if (!line || line.startsWith("#")) {
11180
11496
  continue;
@@ -11195,7 +11511,7 @@ function readEnvLocal(agentRoot2) {
11195
11511
  return values;
11196
11512
  }
11197
11513
  function collectRuntimeSecretsDetailed(root) {
11198
- const agentRoot2 = findSubProjectRoot7("agent", root) ?? root;
11514
+ const agentRoot2 = findSubProjectRoot8("agent", root) ?? root;
11199
11515
  if (deployWalletKind(agentRoot2) === "altana") {
11200
11516
  throw new Error(
11201
11517
  "Altana deployment is deferred: refusing to collect either the admin keystore or runtime session for a deploy target."
@@ -11262,12 +11578,12 @@ var SCOPE_NAME = "invoke";
11262
11578
  var SCOPE = `${RESOURCE_SERVER_ID}/${SCOPE_NAME}`;
11263
11579
  var COGNITO_OUTPUTS_FILE = "agentcore/cognito/cdk-outputs.json";
11264
11580
  function emitNextSteps(result) {
11265
- return `\u2713 wrote Cognito CDK app to ${path25.dirname(result.appPath)}
11266
- - ${path25.basename(result.appPath)} (CognitoStack: user pool + resource server + M2M client)
11267
- - ${path25.basename(result.readmePath)} (deploy + wiring instructions)
11581
+ return `\u2713 wrote Cognito CDK app to ${path26.dirname(result.appPath)}
11582
+ - ${path26.basename(result.appPath)} (CognitoStack: user pool + resource server + M2M client)
11583
+ - ${path26.basename(result.readmePath)} (deploy + wiring instructions)
11268
11584
 
11269
11585
  Next steps:
11270
- 1. cd ${path25.dirname(result.appPath)}
11586
+ 1. cd ${path26.dirname(result.appPath)}
11271
11587
  2. npm install # aws-cdk-lib + constructs + the cdk CLI (local)
11272
11588
  3. npx cdk deploy --outputs-file cdk-outputs.json # YOU run this (the only AWS step)
11273
11589
  4. bag deploy provision-cognito --wire # studio reads cdk-outputs.json \u2192
@@ -11458,26 +11774,26 @@ function emitCognitoCdk(workspaceRoot, opts = {}) {
11458
11774
  regionHint = null;
11459
11775
  }
11460
11776
  }
11461
- const outDir = path25.join(workspaceRoot, COGNITO_DIR);
11462
- fs26.mkdirSync(outDir, { recursive: true });
11463
- const appPath = path25.join(outDir, "app.ts");
11464
- const readmePath = path25.join(outDir, "README.md");
11465
- fs26.writeFileSync(appPath, appTs(regionHint), "utf-8");
11466
- fs26.writeFileSync(path25.join(outDir, "cdk.json"), cdkJson(), "utf-8");
11467
- fs26.writeFileSync(
11468
- path25.join(outDir, "package.json"),
11777
+ const outDir = path26.join(workspaceRoot, COGNITO_DIR);
11778
+ fs27.mkdirSync(outDir, { recursive: true });
11779
+ const appPath = path26.join(outDir, "app.ts");
11780
+ const readmePath = path26.join(outDir, "README.md");
11781
+ fs27.writeFileSync(appPath, appTs(regionHint), "utf-8");
11782
+ fs27.writeFileSync(path26.join(outDir, "cdk.json"), cdkJson(), "utf-8");
11783
+ fs27.writeFileSync(
11784
+ path26.join(outDir, "package.json"),
11469
11785
  cognitoPackageJson(),
11470
11786
  "utf-8"
11471
11787
  );
11472
- fs26.writeFileSync(readmePath, readme(), "utf-8");
11788
+ fs27.writeFileSync(readmePath, readme(), "utf-8");
11473
11789
  return { appPath, readmePath };
11474
11790
  }
11475
11791
  function wireSummary(r) {
11476
11792
  return `\u2713 wired Cognito authorizer from the CDK outputs (no AWS call \u2014 read a local file):
11477
- - ${path25.basename(r.agentcoreJson)}: authorizerConfiguration.customJwtAuthorizer
11793
+ - ${path26.basename(r.agentcoreJson)}: authorizerConfiguration.customJwtAuthorizer
11478
11794
  discoveryUrl = ${r.discoveryUrl}
11479
11795
  allowedClients = [${r.clientId}]
11480
- - ${path25.basename(r.agentcoreJson)}: envVars[] OAUTH_TOKEN_URL + OAUTH_SCOPE (reach the runtime so the agent card advertises oauth2)
11796
+ - ${path26.basename(r.agentcoreJson)}: envVars[] OAUTH_TOKEN_URL + OAUTH_SCOPE (reach the runtime so the agent card advertises oauth2)
11481
11797
  - ${r.envLocal}: same pair, for local \`bag dev\`
11482
11798
  \u2192 \`bag deploy prepare\` W9 will now pass; deploy when ready.`;
11483
11799
  }
@@ -11510,8 +11826,8 @@ function upsertDescriptorEnvvars(cfg, values) {
11510
11826
  function upsertEnv(envLocal, values) {
11511
11827
  let lines = [];
11512
11828
  try {
11513
- if (fs26.statSync(envLocal).isFile()) {
11514
- lines = fs26.readFileSync(envLocal, "utf-8").split(/\r?\n/);
11829
+ if (fs27.statSync(envLocal).isFile()) {
11830
+ lines = fs27.readFileSync(envLocal, "utf-8").split(/\r?\n/);
11515
11831
  if (lines.length > 0 && lines[lines.length - 1] === "") {
11516
11832
  lines.pop();
11517
11833
  }
@@ -11530,19 +11846,19 @@ function upsertEnv(envLocal, values) {
11530
11846
  lines.push(repl);
11531
11847
  }
11532
11848
  }
11533
- fs26.mkdirSync(path25.dirname(envLocal), { recursive: true });
11534
- fs26.writeFileSync(envLocal, `${lines.join("\n")}
11849
+ fs27.mkdirSync(path26.dirname(envLocal), { recursive: true });
11850
+ fs27.writeFileSync(envLocal, `${lines.join("\n")}
11535
11851
  `, {
11536
11852
  encoding: "utf-8",
11537
11853
  mode: 384
11538
11854
  });
11539
- fs26.chmodSync(envLocal, 384);
11855
+ fs27.chmodSync(envLocal, 384);
11540
11856
  }
11541
11857
  function wireCognitoOutputs(workspaceRoot, outputsFile = null) {
11542
- const outPath = outputsFile ?? path25.join(workspaceRoot, COGNITO_OUTPUTS_FILE);
11858
+ const outPath = outputsFile ?? path26.join(workspaceRoot, COGNITO_OUTPUTS_FILE);
11543
11859
  let exists = false;
11544
11860
  try {
11545
- exists = fs26.statSync(outPath).isFile();
11861
+ exists = fs27.statSync(outPath).isFile();
11546
11862
  } catch {
11547
11863
  exists = false;
11548
11864
  }
@@ -11552,7 +11868,7 @@ function wireCognitoOutputs(workspaceRoot, outputsFile = null) {
11552
11868
  );
11553
11869
  }
11554
11870
  const outs = flattenCdkOutputs(
11555
- JSON.parse(fs26.readFileSync(outPath, "utf-8"))
11871
+ JSON.parse(fs27.readFileSync(outPath, "utf-8"))
11556
11872
  );
11557
11873
  for (const key of ["DiscoveryUrl", "AppClientId", "TokenUrl", "Scope"]) {
11558
11874
  if (outs[key] === void 0) {
@@ -11565,8 +11881,8 @@ function wireCognitoOutputs(workspaceRoot, outputsFile = null) {
11565
11881
  const clientId = String(outs.AppClientId);
11566
11882
  const tokenUrl = String(outs.TokenUrl);
11567
11883
  const scope = String(outs.Scope);
11568
- const acj = path25.join(workspaceRoot, "agentcore", "agentcore.json");
11569
- const cfg = JSON.parse(fs26.readFileSync(acj, "utf-8"));
11884
+ const acj = path26.join(workspaceRoot, "agentcore", "agentcore.json");
11885
+ const cfg = JSON.parse(fs27.readFileSync(acj, "utf-8"));
11570
11886
  const runtimes = cfg.runtimes;
11571
11887
  if (!Array.isArray(runtimes) || runtimes.length === 0) {
11572
11888
  throw new Error(
@@ -11589,9 +11905,9 @@ function wireCognitoOutputs(workspaceRoot, outputsFile = null) {
11589
11905
  OAUTH_TOKEN_URL: tokenUrl,
11590
11906
  OAUTH_SCOPE: scope
11591
11907
  });
11592
- fs26.writeFileSync(acj, `${JSON.stringify(cfg, null, 2)}
11908
+ fs27.writeFileSync(acj, `${JSON.stringify(cfg, null, 2)}
11593
11909
  `, "utf-8");
11594
- const envLocal = envLocalPath12(workspaceRoot);
11910
+ const envLocal = envLocalPath13(workspaceRoot);
11595
11911
  upsertEnv(envLocal, { OAUTH_TOKEN_URL: tokenUrl, OAUTH_SCOPE: scope });
11596
11912
  return {
11597
11913
  discoveryUrl: discovery,
@@ -11604,41 +11920,41 @@ function wireCognitoOutputs(workspaceRoot, outputsFile = null) {
11604
11920
  }
11605
11921
 
11606
11922
  // src/cli/_deploy/destroy.ts
11607
- import * as fs28 from "fs";
11608
- import * as path27 from "path";
11609
- import { findSubProjectRoot as findSubProjectRoot9 } from "@bnbagent/studio-runtime/config";
11923
+ import * as fs29 from "fs";
11924
+ import * as path28 from "path";
11925
+ import { findSubProjectRoot as findSubProjectRoot10 } from "@bnbagent/studio-runtime/config";
11610
11926
 
11611
11927
  // src/cli/_deploy/status.ts
11612
- import * as fs27 from "fs";
11613
- import * as path26 from "path";
11928
+ import * as fs28 from "fs";
11929
+ import * as path27 from "path";
11614
11930
  import {
11615
11931
  APP_DIR as APP_DIR2,
11616
- findSubProjectRoot as findSubProjectRoot8,
11617
- findWorkspaceRoot as findWorkspaceRoot4,
11618
- loadStudioToml as loadStudioToml13
11932
+ findSubProjectRoot as findSubProjectRoot9,
11933
+ findWorkspaceRoot as findWorkspaceRoot5,
11934
+ loadStudioToml as loadStudioToml14
11619
11935
  } from "@bnbagent/studio-runtime/config";
11620
11936
  function loadToml(p) {
11621
11937
  try {
11622
- return loadStudioToml13(p);
11938
+ return loadStudioToml14(p);
11623
11939
  } catch {
11624
11940
  return {};
11625
11941
  }
11626
11942
  }
11627
11943
  function projectName(workspaceRoot) {
11628
- const descriptor = path26.join(workspaceRoot, "agentcore", "agentcore.json");
11944
+ const descriptor = path27.join(workspaceRoot, "agentcore", "agentcore.json");
11629
11945
  try {
11630
- const data = JSON.parse(fs27.readFileSync(descriptor, "utf-8"));
11946
+ const data = JSON.parse(fs28.readFileSync(descriptor, "utf-8"));
11631
11947
  if (data !== null && typeof data === "object" && data.name) {
11632
11948
  return String(data.name);
11633
11949
  }
11634
11950
  } catch {
11635
11951
  }
11636
- return path26.basename(workspaceRoot);
11952
+ return path27.basename(workspaceRoot);
11637
11953
  }
11638
11954
  async function runStatus(opts = {}) {
11639
- const start = opts.projectRoot ? path26.resolve(opts.projectRoot) : void 0;
11640
- const agentRoot2 = findSubProjectRoot8("agent", start);
11641
- const agentData = agentRoot2 !== null ? loadToml(path26.join(agentRoot2, "studio.toml")) : {};
11955
+ const start = opts.projectRoot ? path27.resolve(opts.projectRoot) : void 0;
11956
+ const agentRoot2 = findSubProjectRoot9("agent", start);
11957
+ const agentData = agentRoot2 !== null ? loadToml(path27.join(agentRoot2, "studio.toml")) : {};
11642
11958
  const deployRaw = agentData.deploy;
11643
11959
  const deploy = deployRaw !== null && typeof deployRaw === "object" && !Array.isArray(deployRaw) ? { ...deployRaw } : {};
11644
11960
  const runtimeArn = deploy.runtime_arn ? String(deploy.runtime_arn) : null;
@@ -11651,8 +11967,8 @@ async function runStatus(opts = {}) {
11651
11967
  }
11652
11968
  const onchainEndpoint = identity.endpoint ? String(identity.endpoint) : null;
11653
11969
  const agentReachable = null;
11654
- const workspaceBase2 = findWorkspaceRoot4(start) ?? (agentRoot2 !== null ? path26.dirname(agentRoot2) : null);
11655
- const workspaceRoot = workspaceBase2 !== null && path26.basename(workspaceBase2) === APP_DIR2 ? path26.dirname(workspaceBase2) : workspaceBase2;
11970
+ const workspaceBase2 = findWorkspaceRoot5(start) ?? (agentRoot2 !== null ? path27.dirname(agentRoot2) : null);
11971
+ const workspaceRoot = workspaceBase2 !== null && path27.basename(workspaceBase2) === APP_DIR2 ? path27.dirname(workspaceBase2) : workspaceBase2;
11656
11972
  let region = null;
11657
11973
  let account = null;
11658
11974
  let secretId = null;
@@ -11716,13 +12032,13 @@ function printInvariants() {
11716
12032
  );
11717
12033
  }
11718
12034
  function nullRecordedState(workspaceRoot) {
11719
- const agentRoot2 = findSubProjectRoot9("agent", workspaceRoot);
12035
+ const agentRoot2 = findSubProjectRoot10("agent", workspaceRoot);
11720
12036
  if (agentRoot2 === null) {
11721
12037
  return;
11722
12038
  }
11723
- const ap = path27.join(agentRoot2, "studio.toml");
12039
+ const ap = path28.join(agentRoot2, "studio.toml");
11724
12040
  try {
11725
- if (!fs28.statSync(ap).isFile()) {
12041
+ if (!fs29.statSync(ap).isFile()) {
11726
12042
  return;
11727
12043
  }
11728
12044
  } catch {
@@ -11786,19 +12102,19 @@ async function runDestroy(opts) {
11786
12102
  }
11787
12103
 
11788
12104
  // src/cli/_deploy/packaging.ts
11789
- import * as fs29 from "fs";
11790
- import * as path28 from "path";
12105
+ import * as fs30 from "fs";
12106
+ import * as path29 from "path";
11791
12107
  import {
11792
- findSubProjectRoot as findSubProjectRoot10,
11793
- loadStudioToml as loadStudioToml14
12108
+ findSubProjectRoot as findSubProjectRoot11,
12109
+ loadStudioToml as loadStudioToml15
11794
12110
  } from "@bnbagent/studio-runtime/config";
11795
12111
  function agentRootOf2(root) {
11796
- return findSubProjectRoot10("agent", root);
12112
+ return findSubProjectRoot11("agent", root);
11797
12113
  }
11798
12114
  function agentTable(agentRoot2, key) {
11799
- const tomlPath = path28.join(agentRoot2, "studio.toml");
12115
+ const tomlPath = path29.join(agentRoot2, "studio.toml");
11800
12116
  try {
11801
- if (!fs29.statSync(tomlPath).isFile()) {
12117
+ if (!fs30.statSync(tomlPath).isFile()) {
11802
12118
  return {};
11803
12119
  }
11804
12120
  } catch {
@@ -11806,7 +12122,7 @@ function agentTable(agentRoot2, key) {
11806
12122
  }
11807
12123
  let cfg;
11808
12124
  try {
11809
- cfg = loadStudioToml14(tomlPath);
12125
+ cfg = loadStudioToml15(tomlPath);
11810
12126
  } catch {
11811
12127
  return {};
11812
12128
  }
@@ -11865,10 +12181,10 @@ function checkPackagingDrift(root, destination, walletKind2, force) {
11865
12181
  );
11866
12182
  return 1;
11867
12183
  }
11868
- const dockerfile = path28.join(agentRoot2, "Dockerfile");
12184
+ const dockerfile = path29.join(agentRoot2, "Dockerfile");
11869
12185
  let dockerfilePresent = false;
11870
12186
  try {
11871
- dockerfilePresent = fs29.statSync(dockerfile).isFile();
12187
+ dockerfilePresent = fs30.statSync(dockerfile).isFile();
11872
12188
  } catch {
11873
12189
  dockerfilePresent = false;
11874
12190
  }
@@ -11909,7 +12225,7 @@ function deployWalletKindSafe(root) {
11909
12225
  }
11910
12226
  let cfg;
11911
12227
  try {
11912
- cfg = loadStudioToml14(path28.join(agentRoot2, "studio.toml"));
12228
+ cfg = loadStudioToml15(path29.join(agentRoot2, "studio.toml"));
11913
12229
  } catch {
11914
12230
  return "evm-local";
11915
12231
  }
@@ -11922,22 +12238,22 @@ function deployWalletKindSafe(root) {
11922
12238
  import { findStudioWorkspaceRoot as findStudioWorkspaceRoot2 } from "@bnbagent/studio-runtime/config";
11923
12239
 
11924
12240
  // src/cli/_deploy/checks/blocked.ts
11925
- import * as fs30 from "fs";
11926
- import * as path29 from "path";
12241
+ import * as fs31 from "fs";
12242
+ import * as path30 from "path";
11927
12243
  import {
11928
- findSubProjectRoot as findSubProjectRoot11,
11929
- loadStudioToml as loadStudioToml15
12244
+ findSubProjectRoot as findSubProjectRoot12,
12245
+ loadStudioToml as loadStudioToml16
11930
12246
  } from "@bnbagent/studio-runtime/config";
11931
12247
  function isFile12(p) {
11932
12248
  try {
11933
- return fs30.statSync(p).isFile();
12249
+ return fs31.statSync(p).isFile();
11934
12250
  } catch {
11935
12251
  return false;
11936
12252
  }
11937
12253
  }
11938
12254
  function isDir6(p) {
11939
12255
  try {
11940
- return fs30.statSync(p).isDirectory();
12256
+ return fs31.statSync(p).isDirectory();
11941
12257
  } catch {
11942
12258
  return false;
11943
12259
  }
@@ -11945,10 +12261,10 @@ function isDir6(p) {
11945
12261
  async function checkStudioTomlPresent(root, _target) {
11946
12262
  const out = [];
11947
12263
  const layers = {
11948
- agent: findSubProjectRoot11("agent", root)
12264
+ agent: findSubProjectRoot12("agent", root)
11949
12265
  };
11950
12266
  for (const [side, subRoot] of Object.entries(layers)) {
11951
- const tomlPath = subRoot === null ? null : path29.join(subRoot, "studio.toml");
12267
+ const tomlPath = subRoot === null ? null : path30.join(subRoot, "studio.toml");
11952
12268
  if (tomlPath === null || !isFile12(tomlPath)) {
11953
12269
  out.push({
11954
12270
  level: Level.BLOCKED,
@@ -11959,7 +12275,7 @@ async function checkStudioTomlPresent(root, _target) {
11959
12275
  continue;
11960
12276
  }
11961
12277
  try {
11962
- loadStudioToml15(tomlPath);
12278
+ loadStudioToml16(tomlPath);
11963
12279
  } catch (exc) {
11964
12280
  const msg = exc instanceof Error ? exc.message : String(exc);
11965
12281
  out.push({
@@ -11973,8 +12289,8 @@ async function checkStudioTomlPresent(root, _target) {
11973
12289
  return out;
11974
12290
  }
11975
12291
  async function checkCwdIsProjectRoot(root, _target) {
11976
- const cwd = path29.resolve(process.cwd());
11977
- const rr = path29.resolve(root);
12292
+ const cwd = path30.resolve(process.cwd());
12293
+ const rr = path30.resolve(root);
11978
12294
  if (cwd !== rr) {
11979
12295
  return [
11980
12296
  {
@@ -11988,7 +12304,7 @@ async function checkCwdIsProjectRoot(root, _target) {
11988
12304
  return [];
11989
12305
  }
11990
12306
  async function checkNoSecretInGitHistory(root, _target) {
11991
- if (!isDir6(path29.join(root, ".git"))) {
12307
+ if (!isDir6(path30.join(root, ".git"))) {
11992
12308
  return [];
11993
12309
  }
11994
12310
  const needles = [".env.local", "WALLET_PASSWORD"];
@@ -12026,8 +12342,8 @@ var allChecks2 = [
12026
12342
  ];
12027
12343
 
12028
12344
  // src/cli/_deploy/checks/info.ts
12029
- import * as fs31 from "fs";
12030
- import * as path30 from "path";
12345
+ import * as fs32 from "fs";
12346
+ import * as path31 from "path";
12031
12347
  async function checkPreviousDeployStatus(root, _target) {
12032
12348
  const deploy = tableOf2(loadAgentToml(root), "deploy");
12033
12349
  const last = deploy.last_deploy_at;
@@ -12051,10 +12367,10 @@ async function checkPreviousDeployStatus(root, _target) {
12051
12367
  ];
12052
12368
  }
12053
12369
  async function checkInstalledRecipesList(root, _target) {
12054
- const manifest = path30.join(root, ".studio", "recipes", "manifest.json");
12370
+ const manifest = path31.join(root, ".studio", "recipes", "manifest.json");
12055
12371
  let exists = false;
12056
12372
  try {
12057
- exists = fs31.statSync(manifest).isFile();
12373
+ exists = fs32.statSync(manifest).isFile();
12058
12374
  } catch {
12059
12375
  exists = false;
12060
12376
  }
@@ -12070,7 +12386,7 @@ async function checkInstalledRecipesList(root, _target) {
12070
12386
  }
12071
12387
  let data;
12072
12388
  try {
12073
- data = JSON.parse(fs31.readFileSync(manifest, "utf-8"));
12389
+ data = JSON.parse(fs32.readFileSync(manifest, "utf-8"));
12074
12390
  } catch {
12075
12391
  return [
12076
12392
  {
@@ -12173,26 +12489,26 @@ var allChecks3 = [
12173
12489
  ];
12174
12490
 
12175
12491
  // src/cli/_deploy/checks/platform.ts
12176
- import * as fs33 from "fs";
12177
- import * as path32 from "path";
12492
+ import * as fs34 from "fs";
12493
+ import * as path33 from "path";
12178
12494
  import {
12179
- findSubProjectRoot as findSubProjectRoot12,
12180
- loadStudioToml as loadStudioToml16
12495
+ findSubProjectRoot as findSubProjectRoot13,
12496
+ loadStudioToml as loadStudioToml17
12181
12497
  } from "@bnbagent/studio-runtime/config";
12182
12498
  import { BSC_TESTNET_FAUCET_URLS } from "@bnbagent/studio-runtime/networks";
12183
12499
 
12184
12500
  // src/cli/_deploy/checks/warning.ts
12185
12501
  import * as crypto4 from "crypto";
12186
- import * as fs32 from "fs";
12187
- import * as path31 from "path";
12188
- import { envLocalPath as envLocalPath13 } from "@bnbagent/studio-runtime/config";
12502
+ import * as fs33 from "fs";
12503
+ import * as path32 from "path";
12504
+ import { envLocalPath as envLocalPath14 } from "@bnbagent/studio-runtime/config";
12189
12505
  import { show } from "@bnbagent/studio-runtime/erc8004";
12190
12506
  import { getNetwork as getNetwork8 } from "@bnbagent/studio-runtime/networks";
12191
12507
  import * as walletRt3 from "@bnbagent/studio-runtime/wallet";
12192
12508
  var TBNB_MIN_WEI = 7n * 10n ** 15n;
12193
12509
  function isFile13(p) {
12194
12510
  try {
12195
- return fs32.statSync(p).isFile();
12511
+ return fs33.statSync(p).isFile();
12196
12512
  } catch {
12197
12513
  return false;
12198
12514
  }
@@ -12330,7 +12646,7 @@ async function checkNetworkMatchesChainId(root, _target) {
12330
12646
  return [];
12331
12647
  }
12332
12648
  async function checkRpcUrlSetForRuntime(root, _target) {
12333
- const envLocal = envLocalPath13(root);
12649
+ const envLocal = envLocalPath14(root);
12334
12650
  if (getEnvVar(envLocal, "RPC_URL")) {
12335
12651
  return [];
12336
12652
  }
@@ -12350,10 +12666,10 @@ async function checkRpcUrlSetForRuntime(root, _target) {
12350
12666
  ];
12351
12667
  }
12352
12668
  async function checkInstalledRecipesUnchanged(root, _target) {
12353
- const manifest = path31.join(root, ".studio", "recipes", "manifest.json");
12669
+ const manifest = path32.join(root, ".studio", "recipes", "manifest.json");
12354
12670
  let data;
12355
12671
  try {
12356
- data = JSON.parse(fs32.readFileSync(manifest, "utf-8"));
12672
+ data = JSON.parse(fs33.readFileSync(manifest, "utf-8"));
12357
12673
  } catch {
12358
12674
  return [];
12359
12675
  }
@@ -12368,11 +12684,11 @@ async function checkInstalledRecipesUnchanged(root, _target) {
12368
12684
  if (!rel || !expected || typeof rel !== "string") {
12369
12685
  continue;
12370
12686
  }
12371
- const p = path31.join(root, rel);
12687
+ const p = path32.join(root, rel);
12372
12688
  if (!isFile13(p)) {
12373
12689
  continue;
12374
12690
  }
12375
- const actual = crypto4.createHash("sha256").update(fs32.readFileSync(p)).digest("hex");
12691
+ const actual = crypto4.createHash("sha256").update(fs33.readFileSync(p)).digest("hex");
12376
12692
  if (actual !== expected) {
12377
12693
  stale.push(rel);
12378
12694
  }
@@ -12390,10 +12706,10 @@ async function checkInstalledRecipesUnchanged(root, _target) {
12390
12706
  return [];
12391
12707
  }
12392
12708
  function agentcoreAuthorizer(root) {
12393
- const descriptor = path31.join(root, "agentcore", "agentcore.json");
12709
+ const descriptor = path32.join(root, "agentcore", "agentcore.json");
12394
12710
  let data;
12395
12711
  try {
12396
- data = JSON.parse(fs32.readFileSync(descriptor, "utf-8"));
12712
+ data = JSON.parse(fs33.readFileSync(descriptor, "utf-8"));
12397
12713
  } catch {
12398
12714
  return null;
12399
12715
  }
@@ -12471,39 +12787,39 @@ var allChecks4 = [
12471
12787
 
12472
12788
  // src/cli/_deploy/checks/platform.ts
12473
12789
  var SLUG_RE = /^[a-z][a-z0-9-]{1,40}$/;
12474
- function tableOf9(data, key) {
12790
+ function tableOf10(data, key) {
12475
12791
  const value = data[key];
12476
12792
  return value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
12477
12793
  }
12478
12794
  function agentRoot(root) {
12479
- return findSubProjectRoot12("agent", root) ?? path32.join(root, "app", "agent");
12795
+ return findSubProjectRoot13("agent", root) ?? path33.join(root, "app", "agent");
12480
12796
  }
12481
12797
  function loadAgent(root) {
12482
12798
  try {
12483
- return loadStudioToml16(path32.join(agentRoot(root), "studio.toml"));
12799
+ return loadStudioToml17(path33.join(agentRoot(root), "studio.toml"));
12484
12800
  } catch {
12485
12801
  return {};
12486
12802
  }
12487
12803
  }
12488
12804
  function platformArtifact(data) {
12489
- const walletKind2 = String(tableOf9(data, "wallet").kind ?? "evm-local").trim().toLowerCase();
12805
+ const walletKind2 = String(tableOf10(data, "wallet").kind ?? "evm-local").trim().toLowerCase();
12490
12806
  if (walletKind2 === "twak") return "container";
12491
- const deploy = tableOf9(data, "deploy");
12807
+ const deploy = tableOf10(data, "deploy");
12492
12808
  const explicit = String(deploy.platform_artifact ?? "").toLowerCase();
12493
12809
  if (explicit) return explicit;
12494
12810
  return String(deploy.packaging ?? "").toLowerCase() === "container" ? "container" : "zip";
12495
12811
  }
12496
12812
  var checkPlatformEntrypointPresent = async (root, _target) => {
12497
12813
  const data = loadAgent(root);
12498
- const faces = stackFaces(tableOf9(data, "stack"), tableOf9(data, "payments"));
12814
+ const faces = stackFaces(tableOf10(data, "stack"), tableOf10(data, "payments"));
12499
12815
  const stem2 = entryStemOf(faces);
12500
12816
  const filenames = [`${stem2}.ts`];
12501
12817
  if (stem2 === "dualMain") filenames.push("mcpMain.ts");
12502
12818
  const filename = filenames.find(
12503
- (candidate) => !fs33.existsSync(path32.join(agentRoot(root), "src", candidate))
12819
+ (candidate) => !fs34.existsSync(path33.join(agentRoot(root), "src", candidate))
12504
12820
  );
12505
12821
  if (filename === void 0) return [];
12506
- const expected = path32.join(agentRoot(root), "src", filename);
12822
+ const expected = path33.join(agentRoot(root), "src", filename);
12507
12823
  return [
12508
12824
  {
12509
12825
  level: Level.CRITICAL,
@@ -12515,20 +12831,20 @@ var checkPlatformEntrypointPresent = async (root, _target) => {
12515
12831
  };
12516
12832
  var checkPlatformKeystoreNotInArtifact = async (root, _target) => {
12517
12833
  const data = loadAgent(root);
12518
- const wallet = tableOf9(data, "wallet");
12834
+ const wallet = tableOf10(data, "wallet");
12519
12835
  if (String(wallet.kind ?? "evm-local") === "twak") return [];
12520
- const agent = path32.resolve(agentRoot(root));
12836
+ const agent = path33.resolve(agentRoot(root));
12521
12837
  const configured = String(wallet.keystore_dir ?? ".studio/wallets");
12522
- const keystore = path32.resolve(agent, configured);
12838
+ const keystore = path33.resolve(agent, configured);
12523
12839
  let jsonFiles;
12524
12840
  try {
12525
- jsonFiles = fs33.readdirSync(keystore).filter((name) => name.endsWith(".json"));
12841
+ jsonFiles = fs34.readdirSync(keystore).filter((name) => name.endsWith(".json"));
12526
12842
  } catch {
12527
12843
  return [];
12528
12844
  }
12529
12845
  if (jsonFiles.length === 0) return [];
12530
- const rel = path32.relative(agent, keystore);
12531
- if (rel.startsWith("..") || path32.isAbsolute(rel)) return [];
12846
+ const rel = path33.relative(agent, keystore);
12847
+ if (rel.startsWith("..") || path33.isAbsolute(rel)) return [];
12532
12848
  return [
12533
12849
  {
12534
12850
  level: Level.CRITICAL,
@@ -12539,7 +12855,7 @@ var checkPlatformKeystoreNotInArtifact = async (root, _target) => {
12539
12855
  ];
12540
12856
  };
12541
12857
  var checkPlatformTestnetOnly = async (root, _target) => {
12542
- const network = String(tableOf9(loadAgent(root), "network").default ?? "").trim().toLowerCase();
12858
+ const network = String(tableOf10(loadAgent(root), "network").default ?? "").trim().toLowerCase();
12543
12859
  if (!network || network === "bsc-testnet") return [];
12544
12860
  return [
12545
12861
  {
@@ -12552,7 +12868,7 @@ var checkPlatformTestnetOnly = async (root, _target) => {
12552
12868
  ];
12553
12869
  };
12554
12870
  var checkPlatformSlugValid = async (root, _target) => {
12555
- const platform = tableOf9(tableOf9(loadAgent(root), "deploy"), "platform");
12871
+ const platform = tableOf10(tableOf10(loadAgent(root), "deploy"), "platform");
12556
12872
  const slug = String(platform.slug ?? "").trim();
12557
12873
  if (!slug || SLUG_RE.test(slug)) return [];
12558
12874
  return [
@@ -12610,7 +12926,7 @@ var checkPlatformStorageEndpoint = async (root, _target) => {
12610
12926
  };
12611
12927
  var checkPlatformMcpSyncTimeout = async (root, _target) => {
12612
12928
  const data = loadAgent(root);
12613
- const faces = stackFaces(tableOf9(data, "stack"), tableOf9(data, "payments"));
12929
+ const faces = stackFaces(tableOf10(data, "stack"), tableOf10(data, "payments"));
12614
12930
  if (!hasMcpFace(faces)) return [];
12615
12931
  const dual = hasA2aFace(faces);
12616
12932
  return [
@@ -12623,8 +12939,8 @@ var checkPlatformMcpSyncTimeout = async (root, _target) => {
12623
12939
  ];
12624
12940
  };
12625
12941
  var checkPlatformX402MerchantsMainnet = async (root, _target) => {
12626
- const merchants = tableOf9(
12627
- tableOf9(tableOf9(loadAgent(root), "payments"), "x402"),
12942
+ const merchants = tableOf10(
12943
+ tableOf10(tableOf10(loadAgent(root), "payments"), "x402"),
12628
12944
  "merchants"
12629
12945
  );
12630
12946
  const names = Object.keys(merchants).sort();
@@ -12753,217 +13069,6 @@ async function runProducers(producers, root, target) {
12753
13069
  return out;
12754
13070
  }
12755
13071
 
12756
- // src/cli/_deploy/providers.ts
12757
- import * as fs34 from "fs";
12758
- import * as path33 from "path";
12759
- import {
12760
- findSubProjectRoot as findSubProjectRoot13,
12761
- findWorkspaceRoot as findWorkspaceRoot5,
12762
- loadStudioToml as loadStudioToml17
12763
- } from "@bnbagent/studio-runtime/config";
12764
- var PROVIDER_TARGETS = {
12765
- bnb: "bnb/trial",
12766
- aws: "aws/agentcore",
12767
- azure: "azure/foundry"
12768
- };
12769
- var PROVIDER_LABELS = {
12770
- bnb: "BNB Chain Trial",
12771
- aws: "AWS AgentCore",
12772
- azure: "Azure Foundry"
12773
- };
12774
- var PROVIDER_MENU_ORDER = [
12775
- "bnb",
12776
- "aws",
12777
- "azure"
12778
- ];
12779
- var PROVIDER_SHORT_LABELS = {
12780
- bnb: "BNB",
12781
- aws: "AWS",
12782
- azure: "Azure"
12783
- };
12784
- function providerDigit(provider) {
12785
- return PROVIDER_MENU_ORDER.indexOf(provider) + 1;
12786
- }
12787
- var ADVERTISED_PROVIDERS = ["bnb", "aws"];
12788
- var ADVERTISED_PROVIDERS_HELP = ADVERTISED_PROVIDERS.join("|");
12789
- function tableOf10(data, key) {
12790
- const value = data[key];
12791
- return value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
12792
- }
12793
- function text(value) {
12794
- if (typeof value !== "string") return null;
12795
- const clean = value.trim();
12796
- return clean || null;
12797
- }
12798
- function descriptorName(workspaceRoot) {
12799
- try {
12800
- const data = JSON.parse(
12801
- fs34.readFileSync(
12802
- path33.join(workspaceRoot, "agentcore", "agentcore.json"),
12803
- "utf-8"
12804
- )
12805
- );
12806
- return text(data.name);
12807
- } catch {
12808
- return null;
12809
- }
12810
- }
12811
- function discoverRecordedDeployments(root) {
12812
- const workspaceRoot = findWorkspaceRoot5(root) ?? path33.resolve(root);
12813
- const agentRoot2 = findSubProjectRoot13("agent", workspaceRoot);
12814
- if (agentRoot2 === null) return [];
12815
- let config;
12816
- try {
12817
- config = loadStudioToml17(path33.join(agentRoot2, "studio.toml"));
12818
- } catch {
12819
- return [];
12820
- }
12821
- const projectName2 = descriptorName(workspaceRoot) ?? text(tableOf10(config, "project").name) ?? path33.basename(workspaceRoot);
12822
- const deploy = tableOf10(config, "deploy");
12823
- const platform = tableOf10(deploy, "platform");
12824
- const azure = tableOf10(config, "azure");
12825
- const runtime = text(tableOf10(config, "stack").runtime) ?? "agentcore";
12826
- const found = [];
12827
- const bnbId = text(platform.deployment_id);
12828
- const bnbEndpoint = text(platform.invoke_url);
12829
- if (bnbId || bnbEndpoint || text(platform.last_deploy_at)) {
12830
- found.push({
12831
- provider: "bnb",
12832
- target: PROVIDER_TARGETS.bnb,
12833
- name: text(platform.slug) ?? projectName2,
12834
- deploymentId: bnbId,
12835
- endpoint: bnbEndpoint,
12836
- status: "active"
12837
- });
12838
- }
12839
- const awsArn = text(deploy.runtime_arn);
12840
- const awsEndpoint = text(deploy.invoke_url);
12841
- const legacyAwsTimestamp = Boolean(text(deploy.last_deploy_at)) && runtime !== "azure-foundry" && text(deploy.destination) !== "platform";
12842
- if (awsArn || awsEndpoint || text(deploy.provider) === "aws" || legacyAwsTimestamp) {
12843
- found.push({
12844
- provider: "aws",
12845
- target: PROVIDER_TARGETS.aws,
12846
- name: projectName2,
12847
- deploymentId: awsArn,
12848
- endpoint: awsEndpoint,
12849
- status: "active"
12850
- });
12851
- }
12852
- const azureEndpoint = text(azure.agent_endpoint);
12853
- const azureDeploymentId = text(azure.deployment_id);
12854
- if (azureEndpoint || azureDeploymentId || text(azure.last_deploy_at)) {
12855
- found.push({
12856
- provider: "azure",
12857
- target: PROVIDER_TARGETS.azure,
12858
- name: text(azure.agent_name) ?? projectName2,
12859
- deploymentId: azureDeploymentId,
12860
- endpoint: azureEndpoint,
12861
- status: "active"
12862
- });
12863
- }
12864
- return found;
12865
- }
12866
- function unavailableProvidersForProject(root) {
12867
- const workspaceRoot = findWorkspaceRoot5(root) ?? path33.resolve(root);
12868
- const agentRoot2 = findSubProjectRoot13("agent", workspaceRoot);
12869
- if (agentRoot2 === null) return {};
12870
- let runtime = "agentcore";
12871
- let azureProtocolUnsupported = false;
12872
- try {
12873
- const cfg = loadStudioToml17(path33.join(agentRoot2, "studio.toml"));
12874
- runtime = text(tableOf10(cfg, "stack").runtime) ?? "agentcore";
12875
- const faces = stackFaces(tableOf10(cfg, "stack"), tableOf10(cfg, "payments"));
12876
- azureProtocolUnsupported = !hasA2aFace(faces) || hasMcpFace(faces);
12877
- } catch {
12878
- return {};
12879
- }
12880
- if (runtime === "azure-foundry") {
12881
- const reason = "this project uses a different container adapter; scaffold an agentcore project before selecting BNB or AWS";
12882
- return {
12883
- bnb: reason,
12884
- aws: reason,
12885
- ...azureProtocolUnsupported ? {
12886
- azure: "Azure Foundry deploy currently supports A2A projects only; use an A2A azure-foundry scaffold or AgentCore for MCP"
12887
- } : {}
12888
- };
12889
- }
12890
- return {
12891
- azure: "this project uses the agentcore adapter; scaffold with --runtime azure-foundry before selecting Azure"
12892
- };
12893
- }
12894
- function selected(provider, deployments) {
12895
- const active = deployments.filter((d) => d.status === "active");
12896
- return {
12897
- kind: "selected",
12898
- provider,
12899
- operation: active.some((d) => d.provider === provider) ? "update" : "create",
12900
- hasOtherActive: active.some((d) => d.provider !== provider)
12901
- };
12902
- }
12903
- function trialExpired(trial) {
12904
- return trial.state.toLowerCase() === "expired";
12905
- }
12906
- function unavailableReason(opts, provider) {
12907
- if (provider === "bnb" && trialExpired(opts.trial)) {
12908
- return "the 48h trial has expired";
12909
- }
12910
- return opts.unavailable?.[provider] ?? null;
12911
- }
12912
- function providerPromptHint() {
12913
- return PROVIDER_MENU_ORDER.filter((p) => ADVERTISED_PROVIDERS.includes(p)).map((p) => `${providerDigit(p)}=${PROVIDER_SHORT_LABELS[p]}`).join(", ");
12914
- }
12915
- async function promptProvider(opts) {
12916
- for (; ; ) {
12917
- const answer = (await opts.prompt(`Provider [${providerPromptHint()}]: `)).trim().toLowerCase();
12918
- const provider = answer === "1" || answer === "bnb" ? "bnb" : answer === "2" || answer === "aws" ? "aws" : answer === "3" || answer === "azure" ? "azure" : null;
12919
- if (provider === null) {
12920
- if (answer === "" || answer === "q" || answer === "cancel") {
12921
- return { kind: "cancelled", exitCode: 1 };
12922
- }
12923
- continue;
12924
- }
12925
- if (unavailableReason(opts, provider)) {
12926
- continue;
12927
- }
12928
- return selected(provider, opts.deployments);
12929
- }
12930
- }
12931
- async function selectDeployProvider(opts) {
12932
- if (opts.requested) {
12933
- const reason = unavailableReason(opts, opts.requested);
12934
- if (reason) {
12935
- return {
12936
- kind: "unavailable",
12937
- provider: opts.requested,
12938
- reason,
12939
- exitCode: 2
12940
- };
12941
- }
12942
- return selected(opts.requested, opts.deployments);
12943
- }
12944
- if (!opts.interactive) {
12945
- return { kind: "selection_required", exitCode: 2 };
12946
- }
12947
- const active = opts.deployments.filter((d) => d.status === "active");
12948
- const activeDeployment = active[0];
12949
- if (active.length === 1 && activeDeployment) {
12950
- if (unavailableReason(opts, activeDeployment.provider)) {
12951
- return promptProvider(opts);
12952
- }
12953
- const answer = (await opts.prompt(
12954
- `Update the existing ${PROVIDER_LABELS[activeDeployment.provider]} deployment? [1=update, 2=another provider, 3=cancel]: `
12955
- )).trim().toLowerCase();
12956
- if (answer === "1" || answer === "update" || answer === "yes") {
12957
- return selected(activeDeployment.provider, opts.deployments);
12958
- }
12959
- if (answer === "2" || answer === "another") {
12960
- return promptProvider(opts);
12961
- }
12962
- return { kind: "cancelled", exitCode: 1 };
12963
- }
12964
- return promptProvider(opts);
12965
- }
12966
-
12967
13072
  // src/cli/_deploy/verify.ts
12968
13073
  import * as path35 from "path";
12969
13074
  import {
@@ -13321,7 +13426,7 @@ async function runVerify(opts) {
13321
13426
  import * as fs36 from "fs";
13322
13427
  import * as path36 from "path";
13323
13428
  import {
13324
- envLocalPath as envLocalPath14,
13429
+ envLocalPath as envLocalPath15,
13325
13430
  findSubProjectRoot as findSubProjectRoot15,
13326
13431
  findWorkspaceRoot as findWorkspaceRoot6,
13327
13432
  loadStudioToml as loadStudioToml19
@@ -13971,7 +14076,7 @@ function persistDeploySummary(root, text2) {
13971
14076
  return null;
13972
14077
  }
13973
14078
  const p = path36.join(
13974
- path36.dirname(envLocalPath14(root)),
14079
+ path36.dirname(envLocalPath15(root)),
13975
14080
  "last-deploy-summary.txt"
13976
14081
  );
13977
14082
  fs36.mkdirSync(path36.dirname(p), { recursive: true });
@@ -14184,7 +14289,7 @@ function loadAgentCfg2(root) {
14184
14289
  function registerDeploy(program) {
14185
14290
  program.enablePositionalOptions();
14186
14291
  const p = program.command("deploy").description(
14187
- "Deploy the agent after explicitly selecting BNB or AWS; lifecycle subcommands inspect recorded deployments."
14292
+ `Deploy the agent after explicitly selecting a provider (${ADVERTISED_PROVIDERS_HELP}); lifecycle subcommands inspect recorded deployments.`
14188
14293
  );
14189
14294
  const runtimeOption = () => acceptChoices(
14190
14295
  new Option4(
@@ -14205,7 +14310,7 @@ function registerDeploy(program) {
14205
14310
  const providerOption = () => acceptChoices(
14206
14311
  new Option4(
14207
14312
  "--provider <provider>",
14208
- "Provider: bnb or aws. Required for non-interactive deploy; lifecycle commands need it only when multiple records exist."
14313
+ `Provider: ${ADVERTISED_PROVIDERS_HELP}. Required for non-interactive deploy; lifecycle commands need it only when multiple records exist.`
14209
14314
  ),
14210
14315
  // Unadvertised providers stay parseable (see ADVERTISED_PROVIDERS).
14211
14316
  PROVIDER_MENU_ORDER,
@@ -14363,7 +14468,8 @@ function applyProjectRoot(projectRoot, requireToml = true) {
14363
14468
  return null;
14364
14469
  }
14365
14470
  function resolveProjectRoot2(_projectRoot) {
14366
- return path37.resolve(process.cwd());
14471
+ const cwd = path37.resolve(process.cwd());
14472
+ return findStudioWorkspaceRoot3(cwd) ?? cwd;
14367
14473
  }
14368
14474
  function deployWorkspaceRoot2(root) {
14369
14475
  return findStudioWorkspaceRoot3(root) ?? root;
@@ -14600,10 +14706,10 @@ function writeAgentDeployState(workspaceRoot, arn, record = {}, destination = "s
14600
14706
  patchTomlKv(tomlPath, "deploy", "oauth_discovery_url", discoveryUrl);
14601
14707
  }
14602
14708
  if (tokenUrl) {
14603
- setEnvVar(envLocalPath15(agentRoot2), "OAUTH_TOKEN_URL", tokenUrl);
14709
+ setEnvVar(envLocalPath16(agentRoot2), "OAUTH_TOKEN_URL", tokenUrl);
14604
14710
  }
14605
14711
  if (scope) {
14606
- setEnvVar(envLocalPath15(agentRoot2), "OAUTH_SCOPE", scope);
14712
+ setEnvVar(envLocalPath16(agentRoot2), "OAUTH_SCOPE", scope);
14607
14713
  }
14608
14714
  if (persistedPackaging(agentRoot2) === null) {
14609
14715
  patchTomlKv(
@@ -15325,7 +15431,7 @@ function persistDeploySummary2(root, text2) {
15325
15431
  return null;
15326
15432
  }
15327
15433
  const p = path37.join(
15328
- path37.dirname(envLocalPath15(root)),
15434
+ path37.dirname(envLocalPath16(root)),
15329
15435
  "last-deploy-summary.txt"
15330
15436
  );
15331
15437
  fs37.mkdirSync(path37.dirname(p), { recursive: true });
@@ -15842,7 +15948,7 @@ import * as fs38 from "fs";
15842
15948
  import * as path38 from "path";
15843
15949
  import { EVMWalletProvider as EVMWalletProvider2 } from "@bnbagent/sdk";
15844
15950
  import {
15845
- envLocalPath as envLocalPath16,
15951
+ envLocalPath as envLocalPath17,
15846
15952
  findProjectRoot as findProjectRoot4,
15847
15953
  findStudioWorkspaceRoot as findStudioWorkspaceRoot4,
15848
15954
  loadStudioToml as loadStudioToml21
@@ -15982,7 +16088,7 @@ function resolveProjectRoot3(argRoot) {
15982
16088
  }
15983
16089
  function runCheckEnv(projectRoot) {
15984
16090
  const agentDir = workspaceLayers(projectRoot) ?? path38.join(projectRoot, "agent");
15985
- const envPath = envLocalPath16(agentDir);
16091
+ const envPath = envLocalPath17(agentDir);
15986
16092
  printOut(`bag doctor --check-env: ${envPath}`);
15987
16093
  if (!isFile16(envPath)) {
15988
16094
  printOut(` (no ${path38.basename(envPath)} found \u2014 nothing to report)`);
@@ -16062,7 +16168,8 @@ function checkAppMain(projectRootArg) {
16062
16168
  }
16063
16169
  ];
16064
16170
  }
16065
- return [{ name: "agent entrypoint", status: PASS, detail: entrypoint }];
16171
+ const detail = runtime === "azure-foundry" ? `${entrypoint} (deploy entrypoint; \`bag dev\` serves src/main.ts or src/mcpMain.ts locally)` : entrypoint;
16172
+ return [{ name: "agent entrypoint", status: PASS, detail }];
16066
16173
  }
16067
16174
  function checkAgentcoreName(projectRoot) {
16068
16175
  let cfgPath = null;
@@ -16395,7 +16502,7 @@ async function checkLlm(data, projectRoot) {
16395
16502
  }
16396
16503
  ];
16397
16504
  }
16398
- const keyValue = getEnvVar(envLocalPath16(projectRoot), keyEnv) || process.env[keyEnv];
16505
+ const keyValue = getEnvVar(envLocalPath17(projectRoot), keyEnv) || process.env[keyEnv];
16399
16506
  const out = [];
16400
16507
  if (keyValue) {
16401
16508
  out.push({
@@ -16734,7 +16841,7 @@ function checkX402Seller(data, agentRoot2) {
16734
16841
  out.push({
16735
16842
  name: "x402 credentials",
16736
16843
  status: credentials.any ? FAIL : fallbackStatus,
16737
- detail: credentials.any ? "B402 credentials are partial; set BASE_URL, CLIENT_ID, ACCESS_TOKEN, and exactly one private-key form." : "PAID mode needs the four B402 merchant credentials; without them the rail starts dormant."
16844
+ detail: credentials.any ? `B402 credentials are partial; set BASE_URL, CLIENT_ID, ACCESS_TOKEN, and exactly one private-key form. Confirm they were issued for this exact agent wallet and environment; never reuse them across wallets. Apply: ${B402_DEVELOPER_ACCOUNT_URL}` : `PAID mode needs the four B402 merchant credentials; without them the rail starts dormant. ${B402_PAID_ONBOARDING_GUIDANCE}`
16738
16845
  });
16739
16846
  }
16740
16847
  if (runtime !== "agentcore") {
@@ -18101,7 +18208,7 @@ async function cmdSettle(jobId, opts) {
18101
18208
 
18102
18209
  // src/cli/skills.ts
18103
18210
  import * as fs41 from "fs";
18104
- import * as os5 from "os";
18211
+ import * as os6 from "os";
18105
18212
  import * as path42 from "path";
18106
18213
  import { Option as Option7 } from "commander";
18107
18214
  function registerSkills(program) {
@@ -18421,7 +18528,7 @@ function isFile17(p) {
18421
18528
  }
18422
18529
  function findInstalledSkills(knownNames) {
18423
18530
  const found = [];
18424
- const home = os5.homedir();
18531
+ const home = os6.homedir();
18425
18532
  const cwd = process.cwd();
18426
18533
  const roots = [];
18427
18534
  const addRoot = (root) => {
@@ -19141,7 +19248,7 @@ import * as fs44 from "fs";
19141
19248
  import * as path46 from "path";
19142
19249
  import { auditedOp as auditedOp4 } from "@bnbagent/studio-runtime/audit";
19143
19250
  import {
19144
- envLocalPath as envLocalPath17,
19251
+ envLocalPath as envLocalPath18,
19145
19252
  findProjectRoot as findProjectRoot6,
19146
19253
  loadStudioToml as loadStudioToml24
19147
19254
  } from "@bnbagent/studio-runtime/config";
@@ -19405,7 +19512,7 @@ async function cmdSellInit(priceFlag) {
19405
19512
  "utf8"
19406
19513
  );
19407
19514
  }
19408
- const envPath = envLocalPath17(root);
19515
+ const envPath = envLocalPath18(root);
19409
19516
  for (const key of B402_ENV_KEYS) {
19410
19517
  const existing = getEnvVar(envPath, key);
19411
19518
  if (key === "B402_BASE_URL" && !free && resolveNetwork3(cfg).toLowerCase() === "bsc-testnet" && !process.env.B402_BASE_URL && !existing) {
@@ -19417,6 +19524,9 @@ async function cmdSellInit(priceFlag) {
19417
19524
  printOut(
19418
19525
  free ? "\u2713 x402 seller config is ready in FREE mode; B402 credentials are not required." : "\u2713 x402 seller config and B402 placeholders are ready for PAID mode."
19419
19526
  );
19527
+ if (!free) {
19528
+ printOut(`Next: ${B402_PAID_ONBOARDING_GUIDANCE}`);
19529
+ }
19420
19530
  if (free) {
19421
19531
  printErr(
19422
19532
  "warning: /x402 is an anonymous FREE endpoint; B402 verify/settle and payment audit are bypassed."
@@ -19479,6 +19589,9 @@ async function cmdSellStatus(probe) {
19479
19589
  for (const [key, isSet] of Object.entries(presence)) {
19480
19590
  printOut(` ${key}: ${isSet ? "set" : "absent"}`);
19481
19591
  }
19592
+ if (policy.enabled && !free && !credentialsComplete) {
19593
+ printOut(`Onboarding: ${B402_PAID_ONBOARDING_GUIDANCE}`);
19594
+ }
19482
19595
  if (!probe) {
19483
19596
  printOut("B402 probe: skipped (--no-probe)");
19484
19597
  return 0;
@@ -19920,12 +20033,12 @@ function buildProgram() {
19920
20033
  return program;
19921
20034
  }
19922
20035
  function cliVersion() {
19923
- return "0.0.6-alpha.4";
20036
+ return "0.0.6-alpha.5";
19924
20037
  }
19925
20038
 
19926
20039
  // src/cli/updateCheck.ts
19927
20040
  import * as fs45 from "fs";
19928
- import * as os6 from "os";
20041
+ import * as os7 from "os";
19929
20042
  import * as path47 from "path";
19930
20043
  var PACKAGE = "@bnbagent/studio-cli";
19931
20044
  var REGISTRY_LATEST_URL = `https://registry.npmjs.org/${PACKAGE}/latest`;
@@ -19989,7 +20102,7 @@ async function maybePrintUpdateNudge(opts = {}) {
19989
20102
  if (!isTty()) {
19990
20103
  return;
19991
20104
  }
19992
- const home = opts.home ?? os6.homedir();
20105
+ const home = opts.home ?? os7.homedir();
19993
20106
  const state = loadCache(home);
19994
20107
  const now = Date.now() / 1e3;
19995
20108
  if (now - Number(state.checked_at ?? 0) < CHECK_INTERVAL_SECONDS) {