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

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
@@ -44,7 +44,7 @@ import {
44
44
  x402SellerIsFree,
45
45
  x402SellerPricingState,
46
46
  x402SellerUsesB402
47
- } from "./chunk-VEOOFDSF.js";
47
+ } from "./chunk-JZAW6HMV.js";
48
48
  import {
49
49
  TWAK_CLI_MIN_VERSION,
50
50
  TWAK_CLI_VERSION,
@@ -106,7 +106,7 @@ import {
106
106
  var CAMPAIGN_DOC_URL = "https://www.bnbchain.org/en/blog/bnb-agent-studio-is-live-on-bnb-chain-ai-agents-from-one-prompt";
107
107
  var CAMPAIGN_CHECK_TIMEOUT_MS = 6e3;
108
108
  async function fetchCampaignActive() {
109
- const { bnbPlatformApiUrl: bnbPlatformApiUrl2 } = await import("./deployCli-EEK75T67.js");
109
+ const { bnbPlatformApiUrl: bnbPlatformApiUrl2 } = await import("./deployCli-AJ25A4VK.js");
110
110
  const controller = new AbortController();
111
111
  const timer = setTimeout(() => controller.abort(), CAMPAIGN_CHECK_TIMEOUT_MS);
112
112
  try {
@@ -2090,11 +2090,11 @@ async function devAgentResponding(port = 9e3, timeoutMs = 500) {
2090
2090
  }
2091
2091
  }
2092
2092
  function devPortInUse(port = 9e3, timeoutMs = 250) {
2093
- return new Promise((resolve23) => {
2093
+ return new Promise((resolve24) => {
2094
2094
  const socket = new net.Socket();
2095
2095
  const done = (result) => {
2096
2096
  socket.destroy();
2097
- resolve23(result);
2097
+ resolve24(result);
2098
2098
  };
2099
2099
  socket.setTimeout(timeoutMs);
2100
2100
  socket.once("connect", () => done(true));
@@ -2551,8 +2551,8 @@ function cmdListKeys(projectRoot) {
2551
2551
  }
2552
2552
 
2553
2553
  // src/cli/deploy.ts
2554
- import * as fs37 from "fs";
2555
- import * as path37 from "path";
2554
+ import * as fs38 from "fs";
2555
+ import * as path38 from "path";
2556
2556
  import {
2557
2557
  envLocalPath as envLocalPath16,
2558
2558
  findStudioWorkspaceRoot as findStudioWorkspaceRoot3,
@@ -2994,23 +2994,24 @@ function hasIpfsEndpointFinding(result) {
2994
2994
  }
2995
2995
 
2996
2996
  // src/cli/_deploy/cognitoCdk.ts
2997
- import * as fs27 from "fs";
2998
- import * as path26 from "path";
2997
+ import * as fs28 from "fs";
2998
+ import * as path27 from "path";
2999
2999
  import { envLocalPath as envLocalPath13 } from "@bnbagent/studio-runtime/config";
3000
3000
 
3001
3001
  // src/cli/_deploy/secrets.ts
3002
- import * as fs26 from "fs";
3003
- import * as path25 from "path";
3002
+ import * as fs27 from "fs";
3003
+ import * as path26 from "path";
3004
3004
  import {
3005
3005
  envLocalPath as envLocalPath12,
3006
3006
  findSubProjectRoot as findSubProjectRoot8,
3007
3007
  loadStudioToml as loadStudioToml13
3008
3008
  } from "@bnbagent/studio-runtime/config";
3009
+ import { ALTANA_SESSION_ENV } from "@bnbagent/studio-runtime/wallet";
3009
3010
 
3010
3011
  // src/cli/dev.ts
3011
- import * as fs24 from "fs";
3012
+ import * as fs25 from "fs";
3012
3013
  import * as os5 from "os";
3013
- import * as path23 from "path";
3014
+ import * as path24 from "path";
3014
3015
  import { loadStudioToml as loadStudioToml11 } from "@bnbagent/studio-runtime/config";
3015
3016
  import { getNetwork as getNetwork7 } from "@bnbagent/studio-runtime/networks";
3016
3017
  import { writePrivate as writePrivate2 } from "@bnbagent/studio-runtime/secretWrite";
@@ -3198,9 +3199,9 @@ function relocateKeys(src, target, label) {
3198
3199
  }
3199
3200
 
3200
3201
  // src/cli/init.ts
3201
- import * as fs23 from "fs";
3202
+ import * as fs24 from "fs";
3202
3203
  import * as os4 from "os";
3203
- import * as path22 from "path";
3204
+ import * as path23 from "path";
3204
3205
  import { getNetwork as getNetwork6 } from "@bnbagent/studio-runtime/networks";
3205
3206
  import { ensureTwakKeychain } from "@bnbagent/studio-runtime/wallet";
3206
3207
  import { Option as Option2 } from "commander";
@@ -3451,8 +3452,8 @@ function pnpmVersion() {
3451
3452
 
3452
3453
  // src/cli/_runtime/azureFoundry.ts
3453
3454
  import * as crypto2 from "crypto";
3454
- import * as fs17 from "fs";
3455
- import * as path16 from "path";
3455
+ import * as fs18 from "fs";
3456
+ import * as path17 from "path";
3456
3457
  import {
3457
3458
  findStudioWorkspaceRoot,
3458
3459
  findSubProjectRoot as findSubProjectRoot7,
@@ -3460,9 +3461,177 @@ import {
3460
3461
  } from "@bnbagent/studio-runtime/config";
3461
3462
  import { resolveProviderConfig } from "@bnbagent/studio-runtime/llm";
3462
3463
 
3463
- // src/cli/_deploy/checks/twak.ts
3464
+ // src/cli/_deploy/checks/altana.ts
3464
3465
  import * as fs15 from "fs";
3465
3466
  import * as path14 from "path";
3467
+ import { resolveProjectAltanaSdkEntry } from "@bnbagent/studio-runtime/wallet";
3468
+ var EXPIRY_WARN_SECONDS = 7 * 24 * 60 * 60;
3469
+ function isAltana(data) {
3470
+ return tableOf2(data, "wallet").kind === "altana";
3471
+ }
3472
+ function isFile4(p) {
3473
+ try {
3474
+ return fs15.statSync(p).isFile();
3475
+ } catch {
3476
+ return false;
3477
+ }
3478
+ }
3479
+ function sessionFileOf(root, walletCfg) {
3480
+ const configured = String(
3481
+ walletCfg.session_file ?? ".studio/wallets/altana-session.json"
3482
+ );
3483
+ return path14.isAbsolute(configured) ? configured : path14.join(agentRootOf(root), configured);
3484
+ }
3485
+ function checkAltanaSessionReady(root, _target) {
3486
+ const data = loadAgentToml(root);
3487
+ if (!isAltana(data)) {
3488
+ return [];
3489
+ }
3490
+ const walletCfg = tableOf2(data, "wallet");
3491
+ const sessionFile = sessionFileOf(root, walletCfg);
3492
+ if (!isFile4(sessionFile)) {
3493
+ return [
3494
+ {
3495
+ level: Level.CRITICAL,
3496
+ name: "altana_session_exists",
3497
+ message: `no Altana session at ${sessionFile} (wallet.kind='altana') \u2014 the deployed runtime receives ONLY the bounded session (never the admin keystore) and cannot sign without one.`,
3498
+ fixCmd: "bag wallet session grant",
3499
+ details: { session_file: sessionFile }
3500
+ }
3501
+ ];
3502
+ }
3503
+ let envelope;
3504
+ try {
3505
+ envelope = JSON.parse(fs15.readFileSync(sessionFile, "utf8"));
3506
+ } catch {
3507
+ return [
3508
+ {
3509
+ level: Level.CRITICAL,
3510
+ name: "altana_session_valid",
3511
+ message: `invalid Altana session JSON at ${sessionFile} \u2014 revoke and grant a fresh session.`,
3512
+ fixCmd: "bag wallet session grant --force",
3513
+ details: { session_file: sessionFile }
3514
+ }
3515
+ ];
3516
+ }
3517
+ const anchored = String(walletCfg.address ?? "").trim();
3518
+ if (!anchored) {
3519
+ return [
3520
+ {
3521
+ level: Level.CRITICAL,
3522
+ name: "altana_session_valid",
3523
+ message: "no [wallet].address anchored in app/agent/studio.toml \u2014 the session cannot be verified against the project identity; deploy refuses identity drift.",
3524
+ details: { session_file: sessionFile }
3525
+ }
3526
+ ];
3527
+ }
3528
+ const sessionAddress = String(envelope.walletAddress ?? "");
3529
+ if (envelope.version !== 1 || typeof envelope.publicKey !== "string" || !envelope.publicKey.startsWith("0x") || typeof envelope.expiry !== "number") {
3530
+ return [
3531
+ {
3532
+ level: Level.CRITICAL,
3533
+ name: "altana_session_valid",
3534
+ message: `invalid Altana session envelope at ${sessionFile} \u2014 revoke and grant a fresh session.`,
3535
+ fixCmd: "bag wallet session grant --force",
3536
+ details: { session_file: sessionFile }
3537
+ }
3538
+ ];
3539
+ }
3540
+ if (sessionAddress.toLowerCase() !== anchored.toLowerCase()) {
3541
+ return [
3542
+ {
3543
+ level: Level.CRITICAL,
3544
+ name: "altana_session_valid",
3545
+ message: `the Altana session at ${sessionFile} was granted for ${sessionAddress}, but studio.toml anchors [wallet].address = ${anchored} \u2014 deploying would ship a DIFFERENT identity than the one registered on-chain. Restore the right session or re-anchor, then re-grant.`,
3546
+ details: { anchored, session_address: sessionAddress }
3547
+ }
3548
+ ];
3549
+ }
3550
+ const out = [];
3551
+ const remaining = envelope.expiry - Math.floor(Date.now() / 1e3);
3552
+ if (remaining <= 0) {
3553
+ out.push({
3554
+ level: Level.CRITICAL,
3555
+ name: "altana_session_expiry",
3556
+ message: `the Altana session expired at ${new Date(envelope.expiry * 1e3).toISOString()} \u2014 the deployed runtime would refuse to load it at cold start. Re-grant with \`bag wallet session grant --force\`, then redeploy.`,
3557
+ fixCmd: "bag wallet session grant --force",
3558
+ details: { expiry: envelope.expiry }
3559
+ });
3560
+ } else if (remaining < EXPIRY_WARN_SECONDS) {
3561
+ out.push({
3562
+ level: Level.WARNING,
3563
+ name: "altana_session_expiry",
3564
+ message: `the Altana session expires ${new Date(envelope.expiry * 1e3).toISOString()} (< 7 days). When it lapses the DEPLOYED agent dies at cold start and recovery needs a re-grant AND a redeploy (\`bag wallet session grant --force\`, then \`bag deploy\`). Consider re-granting now.`,
3565
+ details: { expiry: envelope.expiry, remaining_seconds: remaining }
3566
+ });
3567
+ }
3568
+ try {
3569
+ if (process.platform !== "win32" && (fs15.statSync(sessionFile).mode & 63) !== 0) {
3570
+ out.push({
3571
+ level: Level.WARNING,
3572
+ name: "altana_session_permissions",
3573
+ message: `${sessionFile} is readable by group/others and contains the raw session private key; run chmod 600.`,
3574
+ details: { session_file: sessionFile }
3575
+ });
3576
+ }
3577
+ } catch {
3578
+ }
3579
+ return out;
3580
+ }
3581
+ function checkAltanaSdkResolvable(root, _target) {
3582
+ const data = loadAgentToml(root);
3583
+ if (!isAltana(data)) {
3584
+ return [];
3585
+ }
3586
+ const agentRoot2 = agentRootOf(root);
3587
+ let entry = null;
3588
+ let failure = null;
3589
+ try {
3590
+ entry = resolveProjectAltanaSdkEntry(agentRoot2);
3591
+ } catch (error) {
3592
+ failure = error instanceof Error ? error.message : String(error);
3593
+ }
3594
+ if (entry !== null) {
3595
+ return [];
3596
+ }
3597
+ return [
3598
+ {
3599
+ level: Level.CRITICAL,
3600
+ name: "altana_sdk_resolvable",
3601
+ message: `@altananetwork/sdk is not resolvable from the agent project${failure ? ` (${failure})` : ""} \u2014 the deployed runtime cannot build the Altana session wallet at cold start.`,
3602
+ fixCmd: "pnpm add @altananetwork/sdk@0.5.1",
3603
+ details: failure ? { error: failure } : {}
3604
+ }
3605
+ ];
3606
+ }
3607
+ function checkAltanaSessionNotInsideAgent(root, _target) {
3608
+ const data = loadAgentToml(root);
3609
+ if (!isAltana(data)) {
3610
+ return [];
3611
+ }
3612
+ const sessionFile = path14.resolve(
3613
+ sessionFileOf(root, tableOf2(data, "wallet"))
3614
+ );
3615
+ if (!isFile4(sessionFile)) {
3616
+ return [];
3617
+ }
3618
+ const agentDir = path14.resolve(agentRootOf(root));
3619
+ if (!sessionFile.startsWith(agentDir + path14.sep)) {
3620
+ return [];
3621
+ }
3622
+ return [
3623
+ {
3624
+ level: Level.CRITICAL,
3625
+ name: "altana_session_not_inside_agent",
3626
+ message: `the Altana session file ${sessionFile} is INSIDE the deploy artifact root (${agentDir}) \u2014 it contains the raw session private key and would ship in the artifact. Move it to <workspace>/.studio/wallets and set [wallet].session_file = "../../.studio/wallets/altana-session.json" (deploy injects it as the ALTANA_SESSION secret instead).`,
3627
+ details: { session_file: sessionFile, agent_dir: agentDir }
3628
+ }
3629
+ ];
3630
+ }
3631
+
3632
+ // src/cli/_deploy/checks/twak.ts
3633
+ import * as fs16 from "fs";
3634
+ import * as path15 from "path";
3466
3635
  import { envLocalPath as envLocalPath7 } from "@bnbagent/studio-runtime/config";
3467
3636
  import { resolveTwakHome } from "@bnbagent/studio-runtime/wallet";
3468
3637
 
@@ -3505,13 +3674,13 @@ function twakUnsupportedContractOverrides(networkName, env = process.env) {
3505
3674
  }
3506
3675
 
3507
3676
  // src/cli/_deploy/checks/twak.ts
3508
- var AGENTCORE_DESCRIPTOR = path14.join("agentcore", "agentcore.json");
3677
+ var AGENTCORE_DESCRIPTOR = path15.join("agentcore", "agentcore.json");
3509
3678
  function isTwak(data) {
3510
3679
  return tableOf2(data, "wallet").kind === "twak";
3511
3680
  }
3512
- function isFile4(p) {
3681
+ function isFile5(p) {
3513
3682
  try {
3514
- return fs15.statSync(p).isFile();
3683
+ return fs16.statSync(p).isFile();
3515
3684
  } catch {
3516
3685
  return false;
3517
3686
  }
@@ -3524,13 +3693,13 @@ async function checkTwakRequiresContainer(root, target) {
3524
3693
  if (!isTwak(data)) {
3525
3694
  return [];
3526
3695
  }
3527
- const descriptor = path14.join(root, AGENTCORE_DESCRIPTOR);
3528
- if (!isFile4(descriptor)) {
3696
+ const descriptor = path15.join(root, AGENTCORE_DESCRIPTOR);
3697
+ if (!isFile5(descriptor)) {
3529
3698
  return [];
3530
3699
  }
3531
3700
  let cfg;
3532
3701
  try {
3533
- cfg = JSON.parse(fs15.readFileSync(descriptor, "utf-8"));
3702
+ cfg = JSON.parse(fs16.readFileSync(descriptor, "utf-8"));
3534
3703
  } catch {
3535
3704
  return [];
3536
3705
  }
@@ -3553,8 +3722,8 @@ async function checkTwakRequiresContainer(root, target) {
3553
3722
  }
3554
3723
  ];
3555
3724
  }
3556
- const dockerfile = path14.join(agentRootOf(root), "Dockerfile");
3557
- if (!isFile4(dockerfile)) {
3725
+ const dockerfile = path15.join(agentRootOf(root), "Dockerfile");
3726
+ if (!isFile5(dockerfile)) {
3558
3727
  return [
3559
3728
  {
3560
3729
  level: Level.BLOCKED,
@@ -3637,10 +3806,10 @@ async function checkTwakWalletExists(root, _target) {
3637
3806
  const agentRoot2 = agentRootOf(root);
3638
3807
  const walletCfg = tableOf2(data, "wallet");
3639
3808
  const walletFile = twakWalletFile(walletCfg, agentRoot2);
3640
- if (!isFile4(walletFile)) {
3809
+ if (!isFile5(walletFile)) {
3641
3810
  let createCmd = "twak wallet create --password <pw> --no-keychain";
3642
3811
  if (walletCfg.twak_home) {
3643
- createCmd = `HOME=${path14.dirname(path14.dirname(walletFile))} ${createCmd}`;
3812
+ createCmd = `HOME=${path15.dirname(path15.dirname(walletFile))} ${createCmd}`;
3644
3813
  }
3645
3814
  return [
3646
3815
  {
@@ -3762,13 +3931,13 @@ async function checkTwakCredentialsAvailable(root, _target) {
3762
3931
  }
3763
3932
  const agentRoot2 = agentRootOf(root);
3764
3933
  const walletCfg = tableOf2(data, "wallet");
3765
- const credentialsFile = path14.join(
3766
- path14.dirname(twakWalletFile(walletCfg, agentRoot2)),
3934
+ const credentialsFile = path15.join(
3935
+ path15.dirname(twakWalletFile(walletCfg, agentRoot2)),
3767
3936
  "credentials.json"
3768
3937
  );
3769
3938
  const envLocal = envLocalPath7(agentRoot2);
3770
3939
  const resolvable = (key) => Boolean(process.env[key] || getEnvVar(envLocal, key));
3771
- if (isFile4(credentialsFile)) {
3940
+ if (isFile5(credentialsFile)) {
3772
3941
  return [];
3773
3942
  }
3774
3943
  if (resolvable("TWAK_ACCESS_ID") && resolvable("TWAK_HMAC_SECRET")) {
@@ -3785,21 +3954,21 @@ async function checkTwakCredentialsAvailable(root, _target) {
3785
3954
  }
3786
3955
 
3787
3956
  // src/cli/_deploy/fixes.ts
3788
- import * as fs16 from "fs";
3789
- import * as path15 from "path";
3957
+ import * as fs17 from "fs";
3958
+ import * as path16 from "path";
3790
3959
  import { envLocalPath as envLocalPath8 } from "@bnbagent/studio-runtime/config";
3791
3960
  function fixGitignore(root) {
3792
- const ws = path15.dirname(path15.dirname(envLocalPath8(root)));
3793
- const gi = path15.join(ws, ".gitignore");
3961
+ const ws = path16.dirname(path16.dirname(envLocalPath8(root)));
3962
+ const gi = path16.join(ws, ".gitignore");
3794
3963
  const required = [".studio/"];
3795
3964
  let exists = false;
3796
3965
  try {
3797
- exists = fs16.statSync(gi).isFile();
3966
+ exists = fs17.statSync(gi).isFile();
3798
3967
  } catch {
3799
3968
  exists = false;
3800
3969
  }
3801
3970
  if (!exists) {
3802
- fs16.writeFileSync(gi, `${required.join("\n")}
3971
+ fs17.writeFileSync(gi, `${required.join("\n")}
3803
3972
  `, "utf-8");
3804
3973
  return {
3805
3974
  name: "fix-gitignore",
@@ -3807,7 +3976,7 @@ function fixGitignore(root) {
3807
3976
  message: `created .gitignore with ${required.length} entries`
3808
3977
  };
3809
3978
  }
3810
- let text2 = fs16.readFileSync(gi, "utf-8");
3979
+ let text2 = fs17.readFileSync(gi, "utf-8");
3811
3980
  const existing = new Set(text2.split(/\r?\n/).map((l) => l.trim()));
3812
3981
  const appended = required.filter((r) => !existing.has(r));
3813
3982
  if (appended.length === 0) {
@@ -3822,7 +3991,7 @@ function fixGitignore(root) {
3822
3991
  }
3823
3992
  text2 += `${appended.join("\n")}
3824
3993
  `;
3825
- fs16.writeFileSync(gi, text2, "utf-8");
3994
+ fs17.writeFileSync(gi, text2, "utf-8");
3826
3995
  return {
3827
3996
  name: "fix-gitignore",
3828
3997
  changed: true,
@@ -3830,10 +3999,10 @@ function fixGitignore(root) {
3830
3999
  };
3831
4000
  }
3832
4001
  function patchTomlKv(tomlPath, section, key, value) {
3833
- const text2 = fs16.readFileSync(tomlPath, "utf-8");
4002
+ const text2 = fs17.readFileSync(tomlPath, "utf-8");
3834
4003
  const updated = updateSection(text2, section, { [key]: value });
3835
4004
  if (updated !== text2) {
3836
- fs16.writeFileSync(tomlPath, updated, "utf-8");
4005
+ fs17.writeFileSync(tomlPath, updated, "utf-8");
3837
4006
  }
3838
4007
  }
3839
4008
 
@@ -3864,9 +4033,9 @@ var HOSTED_AGENT_REGIONS = /* @__PURE__ */ new Set([
3864
4033
  "spaincentral",
3865
4034
  "australiaeast"
3866
4035
  ]);
3867
- function isFile5(p) {
4036
+ function isFile6(p) {
3868
4037
  try {
3869
- return fs17.statSync(p).isFile();
4038
+ return fs18.statSync(p).isFile();
3870
4039
  } catch {
3871
4040
  return false;
3872
4041
  }
@@ -3883,8 +4052,8 @@ function loadStudioCfg(workspaceRoot) {
3883
4052
  if (agentRoot2 === null) {
3884
4053
  return {};
3885
4054
  }
3886
- const tomlPath = path16.join(agentRoot2, "studio.toml");
3887
- if (!isFile5(tomlPath)) {
4055
+ const tomlPath = path17.join(agentRoot2, "studio.toml");
4056
+ if (!isFile6(tomlPath)) {
3888
4057
  return {};
3889
4058
  }
3890
4059
  try {
@@ -3896,7 +4065,7 @@ function loadStudioCfg(workspaceRoot) {
3896
4065
  function recordAzureDeployment(root, data, endpoint) {
3897
4066
  const agentRoot2 = findSubProjectRoot7("agent", deployWorkspaceRoot(root));
3898
4067
  if (agentRoot2 === null) return;
3899
- const tomlPath = path16.join(agentRoot2, "studio.toml");
4068
+ const tomlPath = path17.join(agentRoot2, "studio.toml");
3900
4069
  try {
3901
4070
  const name = String(data.id ?? tableOf4(data, "record").id ?? "").trim();
3902
4071
  if (name) {
@@ -3914,7 +4083,7 @@ function recordAzureDeployment(root, data, endpoint) {
3914
4083
  function clearAzureEndpoint(root) {
3915
4084
  const agentRoot2 = findSubProjectRoot7("agent", deployWorkspaceRoot(root));
3916
4085
  if (agentRoot2 === null) return;
3917
- const tomlPath = path16.join(agentRoot2, "studio.toml");
4086
+ const tomlPath = path17.join(agentRoot2, "studio.toml");
3918
4087
  try {
3919
4088
  for (const key of [
3920
4089
  "agent_endpoint",
@@ -4033,7 +4202,7 @@ async function destroyAzureFoundry(opts) {
4033
4202
  const extra = opts.purge ? " --purge" : "";
4034
4203
  printOut("=== bag deploy destroy \u2014 teardown plan (dry-run) ===\n");
4035
4204
  printOut(
4036
- `project: ${path16.basename(workspaceRoot)} (runtime: azure-foundry)
4205
+ `project: ${path17.basename(workspaceRoot)} (runtime: azure-foundry)
4037
4206
  `
4038
4207
  );
4039
4208
  printOut("--- Agent (Foundry Hosted Agent) ---");
@@ -4076,8 +4245,8 @@ function agentTomlPath(root) {
4076
4245
  if (agentRoot2 === null) {
4077
4246
  return null;
4078
4247
  }
4079
- const tomlPath = path16.join(agentRoot2, "studio.toml");
4080
- return isFile5(tomlPath) ? tomlPath : null;
4248
+ const tomlPath = path17.join(agentRoot2, "studio.toml");
4249
+ return isFile6(tomlPath) ? tomlPath : null;
4081
4250
  }
4082
4251
  function checkAzureBlock(root) {
4083
4252
  const tomlPath = agentTomlPath(root);
@@ -4210,7 +4379,7 @@ var checkEntrypointAndDockerfile = async (root, _target) => {
4210
4379
  ];
4211
4380
  }
4212
4381
  const entry = "src/foundryMain.ts";
4213
- if (!isFile5(path16.join(agentRoot2, entry))) {
4382
+ if (!isFile6(path17.join(agentRoot2, entry))) {
4214
4383
  findings.push({
4215
4384
  level: "CRITICAL",
4216
4385
  name: "azure_agent_entrypoint",
@@ -4218,7 +4387,7 @@ var checkEntrypointAndDockerfile = async (root, _target) => {
4218
4387
  details: { entrypoint: entry }
4219
4388
  });
4220
4389
  }
4221
- if (!isFile5(path16.join(agentRoot2, "Dockerfile"))) {
4390
+ if (!isFile6(path17.join(agentRoot2, "Dockerfile"))) {
4222
4391
  findings.push({
4223
4392
  level: "CRITICAL",
4224
4393
  name: "azure_dockerfile_present",
@@ -4264,12 +4433,15 @@ var azureFoundryChecks = [
4264
4433
  checkEntrypointAndDockerfile,
4265
4434
  checkLlmExternalProviderReady,
4266
4435
  checkTwakPasswordEnvSet,
4267
- checkTwakCredentialsAvailable
4436
+ checkTwakCredentialsAvailable,
4437
+ checkAltanaSessionReady,
4438
+ checkAltanaSdkResolvable,
4439
+ checkAltanaSessionNotInsideAgent
4268
4440
  ];
4269
4441
 
4270
4442
  // src/cli/llm.ts
4271
- import * as fs18 from "fs";
4272
- import * as path17 from "path";
4443
+ import * as fs19 from "fs";
4444
+ import * as path18 from "path";
4273
4445
  import { query as auditQuery, auditedOp } from "@bnbagent/studio-runtime/audit";
4274
4446
  import {
4275
4447
  envLocalPath as envLocalPath9,
@@ -4284,6 +4456,7 @@ import {
4284
4456
  import { getNetwork as getNetwork4 } from "@bnbagent/studio-runtime/networks";
4285
4457
  import * as pieverseRt from "@bnbagent/studio-runtime/pieverse";
4286
4458
  import {
4459
+ PieverseKeyNotFoundError,
4287
4460
  PieversePolicy,
4288
4461
  RetryPolicy,
4289
4462
  allocateWithSettleRetry,
@@ -4417,7 +4590,10 @@ function registerLlm(program) {
4417
4590
  ).option(
4418
4591
  "--network <name>",
4419
4592
  "Override [llm.pieverse].network (e.g. bsc-mainnet, bsc-testnet)."
4420
- ).option("--name <name>", "Key name (default: bnbagent-studio-default).").action(
4593
+ ).option("--name <name>", "Key name (default: bnbagent-studio-default).").option(
4594
+ "--replace",
4595
+ "Ignore any existing key and mint a fresh one, overwriting PIEVERSE_LLM_API_KEY in .studio/.env.local. Use when the key you inherited (e.g. from a shared env file) no longer exists in Pieverse. The old key is left untouched on the Pieverse side."
4596
+ ).action(
4421
4597
  act(
4422
4598
  (opts) => cmdActivate(opts)
4423
4599
  )
@@ -4544,7 +4720,7 @@ function loadFullCfg() {
4544
4720
  }
4545
4721
  let cfg;
4546
4722
  try {
4547
- cfg = loadStudioToml8(path17.join(root, "studio.toml"));
4723
+ cfg = loadStudioToml8(path18.join(root, "studio.toml"));
4548
4724
  } catch (exc) {
4549
4725
  printErr(`error: failed to parse studio.toml: ${errMessage(exc)}`);
4550
4726
  return null;
@@ -4626,9 +4802,20 @@ async function cmdActivate(opts) {
4626
4802
  return 2;
4627
4803
  }
4628
4804
  const pvCfg = loadPieverseConfig(cfg);
4629
- let existingHash = pvCfg.key_hash ? String(pvCfg.key_hash) : null;
4630
- const envFileValue = getEnvVar(envLocalPath9(root), PIEVERSE_ENV_KEY);
4631
- const existingEnv = envFileValue || process.env[PIEVERSE_ENV_KEY];
4805
+ const replace = opts.replace === true;
4806
+ let existingHash = !replace && pvCfg.key_hash ? String(pvCfg.key_hash) : null;
4807
+ const envFileValue = replace ? null : getEnvVar(envLocalPath9(root), PIEVERSE_ENV_KEY);
4808
+ const existingEnv = replace ? null : envFileValue || process.env[PIEVERSE_ENV_KEY];
4809
+ if (replace) {
4810
+ printOut(
4811
+ `\u2192 --replace: ignoring any existing ${PIEVERSE_ENV_KEY} and minting a fresh key\u2026`
4812
+ );
4813
+ if (process.env[PIEVERSE_ENV_KEY]) {
4814
+ printErr(
4815
+ `warning: ${PIEVERSE_ENV_KEY} is also exported in this shell. The new key goes to .studio/.env.local, which \`bag\` prefers, but \`unset ${PIEVERSE_ENV_KEY}\` to keep the two from diverging.`
4816
+ );
4817
+ }
4818
+ }
4632
4819
  if (!existingHash && existingEnv) {
4633
4820
  const derivedHash = pieverseKeyHash(existingEnv);
4634
4821
  printOut(
@@ -4637,15 +4824,24 @@ async function cmdActivate(opts) {
4637
4824
  try {
4638
4825
  await withSiweRetry(wallet, (token) => inspectKey(token, derivedHash));
4639
4826
  } catch (exc) {
4827
+ if (!(exc instanceof PieverseKeyNotFoundError)) {
4828
+ printErr(
4829
+ `error: could not verify the existing ${PIEVERSE_ENV_KEY} against Pieverse: ${errMessage(
4830
+ exc
4831
+ )}
4832
+ The existing key was kept and no new key was created. This looks like a transport or login failure rather than a missing key \u2014 retry \`bag llm activate\` once Pieverse is reachable.`
4833
+ );
4834
+ return 2;
4835
+ }
4640
4836
  const sources = [
4641
4837
  envFileValue ? `.studio/.env.local (a ${PIEVERSE_ENV_KEY}= line)` : "",
4642
4838
  process.env[PIEVERSE_ENV_KEY] ? "the shell environment" : ""
4643
4839
  ].filter(Boolean).join(" and ");
4644
4840
  printErr(
4645
- `error: ${PIEVERSE_ENV_KEY} already exists but its derived key_hash could not be verified: ${errMessage(
4841
+ `error: ${PIEVERSE_ENV_KEY} already exists but Pieverse does not know its key_hash: ${errMessage(
4646
4842
  exc
4647
4843
  )}
4648
- 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.)`
4844
+ The existing key was kept and no new key was created. The key comes from ${sources}. Re-run \`bag llm activate --replace\` to mint a fresh key and overwrite .studio/.env.local (then \`unset ${PIEVERSE_ENV_KEY}\` if you also exported it in this shell). (\`bag llm rotate\` replaces a key that is still valid in Pieverse; it cannot recover this one.)`
4649
4845
  );
4650
4846
  return 2;
4651
4847
  }
@@ -4886,9 +5082,9 @@ Retry: re-run \`bag llm activate\` \u2014 key_hash is saved so it will pick up w
4886
5082
  return 0;
4887
5083
  }
4888
5084
  function updateStudioTomlSection(root, section, updates) {
4889
- const tomlPath = path17.join(root, "studio.toml");
4890
- const text2 = fs18.readFileSync(tomlPath, "utf-8");
4891
- fs18.writeFileSync(tomlPath, updateSection(text2, section, updates), "utf-8");
5085
+ const tomlPath = path18.join(root, "studio.toml");
5086
+ const text2 = fs19.readFileSync(tomlPath, "utf-8");
5087
+ fs19.writeFileSync(tomlPath, updateSection(text2, section, updates), "utf-8");
4892
5088
  }
4893
5089
  function cumulativeTopupsUsd() {
4894
5090
  let total = 0;
@@ -5437,8 +5633,8 @@ function normalizeNodeDeps(deps) {
5437
5633
  }
5438
5634
 
5439
5635
  // src/cli/recipes/loader.ts
5440
- import * as fs19 from "fs";
5441
- import * as path18 from "path";
5636
+ import * as fs20 from "fs";
5637
+ import * as path19 from "path";
5442
5638
  import { fileURLToPath as fileURLToPath3 } from "url";
5443
5639
  import { parse as parse5 } from "smol-toml";
5444
5640
  var PLACEHOLDER_RE = /\{\{\s*([A-Za-z_][A-Za-z0-9_]*)\s*\}\}/g;
@@ -5447,12 +5643,12 @@ function bundledRecipesRoot() {
5447
5643
  if (override) {
5448
5644
  return override;
5449
5645
  }
5450
- let dir = path18.dirname(fileURLToPath3(import.meta.url));
5646
+ let dir = path19.dirname(fileURLToPath3(import.meta.url));
5451
5647
  for (; ; ) {
5452
- if (fs19.existsSync(path18.join(dir, "package.json"))) {
5453
- return path18.join(dir, "recipes");
5648
+ if (fs20.existsSync(path19.join(dir, "package.json"))) {
5649
+ return path19.join(dir, "recipes");
5454
5650
  }
5455
- const parent = path18.dirname(dir);
5651
+ const parent = path19.dirname(dir);
5456
5652
  if (parent === dir) {
5457
5653
  throw new Error("cannot locate the studio-cli package root");
5458
5654
  }
@@ -5476,24 +5672,24 @@ function defaultMode(recipe) {
5476
5672
  }
5477
5673
  function listRecipes(root) {
5478
5674
  const base = root ?? bundledRecipesRoot();
5479
- if (!fs19.existsSync(base)) {
5675
+ if (!fs20.existsSync(base)) {
5480
5676
  return [];
5481
5677
  }
5482
- return fs19.readdirSync(base).filter(
5483
- (name) => !name.startsWith("_") && fs19.existsSync(path18.join(base, name, "recipe.toml")) && fs19.statSync(path18.join(base, name)).isDirectory()
5678
+ return fs20.readdirSync(base).filter(
5679
+ (name) => !name.startsWith("_") && fs20.existsSync(path19.join(base, name, "recipe.toml")) && fs20.statSync(path19.join(base, name)).isDirectory()
5484
5680
  ).sort();
5485
5681
  }
5486
5682
  var RecipeModeError = class extends Error {
5487
5683
  };
5488
5684
  function loadRecipe(name, opts = {}) {
5489
5685
  const base = opts.root ?? bundledRecipesRoot();
5490
- const recipeDir = path18.join(base, name);
5491
- const tomlPath = path18.join(recipeDir, "recipe.toml");
5492
- if (!fs19.existsSync(tomlPath) || !fs19.statSync(tomlPath).isFile()) {
5686
+ const recipeDir = path19.join(base, name);
5687
+ const tomlPath = path19.join(recipeDir, "recipe.toml");
5688
+ if (!fs20.existsSync(tomlPath) || !fs20.statSync(tomlPath).isFile()) {
5493
5689
  throw new Error(`Recipe '${name}' not found at ${tomlPath}`);
5494
5690
  }
5495
- const metadata = parse5(fs19.readFileSync(tomlPath, "utf-8"));
5496
- const allFiles = collectTemplateFiles(path18.join(recipeDir, "code"));
5691
+ const metadata = parse5(fs20.readFileSync(tomlPath, "utf-8"));
5692
+ const allFiles = collectTemplateFiles(path19.join(recipeDir, "code"));
5497
5693
  const modesMeta = metaTable(metadata, "modes");
5498
5694
  const mode = opts.mode ?? null;
5499
5695
  if (Object.keys(modesMeta).length === 0) {
@@ -5540,22 +5736,22 @@ function modeFiles(modesMeta, modeName) {
5540
5736
  return Array.isArray(files) ? files.filter((f) => typeof f === "string") : [];
5541
5737
  }
5542
5738
  function collectTemplateFiles(codeDir) {
5543
- if (!fs19.existsSync(codeDir) || !fs19.statSync(codeDir).isDirectory()) {
5739
+ if (!fs20.existsSync(codeDir) || !fs20.statSync(codeDir).isDirectory()) {
5544
5740
  return [];
5545
5741
  }
5546
5742
  const out = [];
5547
5743
  const walk = (dir) => {
5548
- for (const name of fs19.readdirSync(dir).sort()) {
5549
- const full = path18.join(dir, name);
5550
- if (fs19.statSync(full).isDirectory()) {
5744
+ for (const name of fs20.readdirSync(dir).sort()) {
5745
+ const full = path19.join(dir, name);
5746
+ if (fs20.statSync(full).isDirectory()) {
5551
5747
  walk(full);
5552
5748
  } else {
5553
- const rel = path18.relative(codeDir, full);
5749
+ const rel = path19.relative(codeDir, full);
5554
5750
  const target = rel.endsWith(".tmpl") ? rel.slice(0, -".tmpl".length) : rel;
5555
5751
  out.push({
5556
5752
  // Recipes use forward slashes regardless of host OS.
5557
- targetPath: target.split(path18.sep).join("/"),
5558
- content: fs19.readFileSync(full, "utf-8")
5753
+ targetPath: target.split(path19.sep).join("/"),
5754
+ content: fs20.readFileSync(full, "utf-8")
5559
5755
  });
5560
5756
  }
5561
5757
  }
@@ -5622,9 +5818,9 @@ function renderRecipe(recipe, opts = {}) {
5622
5818
 
5623
5819
  // src/cli/skillsInstaller.ts
5624
5820
  import * as crypto3 from "crypto";
5625
- import * as fs20 from "fs";
5821
+ import * as fs21 from "fs";
5626
5822
  import * as os2 from "os";
5627
- import * as path19 from "path";
5823
+ import * as path20 from "path";
5628
5824
  import { fileURLToPath as fileURLToPath4 } from "url";
5629
5825
  var SUPPORTED_TARGETS = ["claude-code", "cursor"];
5630
5826
  var SUPPORTED_SCOPES = ["user", "project"];
@@ -5671,14 +5867,14 @@ var HIDDEN_SKILL_NAMES = /* @__PURE__ */ new Set([
5671
5867
  ]);
5672
5868
  function isDir3(p) {
5673
5869
  try {
5674
- return fs20.statSync(p).isDirectory();
5870
+ return fs21.statSync(p).isDirectory();
5675
5871
  } catch {
5676
5872
  return false;
5677
5873
  }
5678
5874
  }
5679
- function isFile6(p) {
5875
+ function isFile7(p) {
5680
5876
  try {
5681
- return fs20.statSync(p).isFile();
5877
+ return fs21.statSync(p).isFile();
5682
5878
  } catch {
5683
5879
  return false;
5684
5880
  }
@@ -5688,15 +5884,15 @@ function sha256(text2) {
5688
5884
  }
5689
5885
  function resolveSkillsSource() {
5690
5886
  const pkgRoot = packageRoot2();
5691
- return pkgRoot !== null ? path19.join(pkgRoot, "skills") : path19.join(path19.dirname(fileURLToPath4(import.meta.url)), "skills");
5887
+ return pkgRoot !== null ? path20.join(pkgRoot, "skills") : path20.join(path20.dirname(fileURLToPath4(import.meta.url)), "skills");
5692
5888
  }
5693
5889
  function packageRoot2() {
5694
- let dir = path19.dirname(fileURLToPath4(import.meta.url));
5890
+ let dir = path20.dirname(fileURLToPath4(import.meta.url));
5695
5891
  for (; ; ) {
5696
- if (fs20.existsSync(path19.join(dir, "package.json"))) {
5892
+ if (fs21.existsSync(path20.join(dir, "package.json"))) {
5697
5893
  return dir;
5698
5894
  }
5699
- const parent = path19.dirname(dir);
5895
+ const parent = path20.dirname(dir);
5700
5896
  if (parent === dir) {
5701
5897
  return null;
5702
5898
  }
@@ -5708,18 +5904,18 @@ function listSourceSkills(source) {
5708
5904
  if (!isDir3(source)) {
5709
5905
  return [];
5710
5906
  }
5711
- return fs20.readdirSync(source).filter(
5712
- (name) => name.endsWith(".md") && !name.startsWith("_") && !HIDDEN_SKILL_NAMES.has(stem(name)) && isFile6(path19.join(source, name))
5713
- ).sort().map((name) => path19.join(source, name));
5907
+ return fs21.readdirSync(source).filter(
5908
+ (name) => name.endsWith(".md") && !name.startsWith("_") && !HIDDEN_SKILL_NAMES.has(stem(name)) && isFile7(path20.join(source, name))
5909
+ ).sort().map((name) => path20.join(source, name));
5714
5910
  }
5715
5911
  function listSourceReferences(source) {
5716
- const refs = path19.join(source, "references");
5912
+ const refs = path20.join(source, "references");
5717
5913
  if (!isDir3(refs)) {
5718
5914
  return [];
5719
5915
  }
5720
- return fs20.readdirSync(refs).filter(
5721
- (name) => name.endsWith(".md") && !name.startsWith("_") && !HIDDEN_SKILL_NAMES.has(stem(name)) && isFile6(path19.join(refs, name))
5722
- ).sort().map((name) => path19.join(refs, name));
5916
+ return fs21.readdirSync(refs).filter(
5917
+ (name) => name.endsWith(".md") && !name.startsWith("_") && !HIDDEN_SKILL_NAMES.has(stem(name)) && isFile7(path20.join(refs, name))
5918
+ ).sort().map((name) => path20.join(refs, name));
5723
5919
  }
5724
5920
  function stem(fileName) {
5725
5921
  return fileName.replace(/\.[^.]+$/, "");
@@ -5727,15 +5923,15 @@ function stem(fileName) {
5727
5923
  function whichSync(name) {
5728
5924
  const pathEnv = process.env.PATH ?? "";
5729
5925
  const exts = process.platform === "win32" ? ["", ".cmd", ".exe", ".bat"] : [""];
5730
- for (const dir of pathEnv.split(path19.delimiter)) {
5926
+ for (const dir of pathEnv.split(path20.delimiter)) {
5731
5927
  if (!dir) {
5732
5928
  continue;
5733
5929
  }
5734
5930
  for (const ext of exts) {
5735
- const candidate = path19.join(dir, name + ext);
5931
+ const candidate = path20.join(dir, name + ext);
5736
5932
  try {
5737
- fs20.accessSync(candidate, fs20.constants.X_OK);
5738
- if (fs20.statSync(candidate).isFile()) {
5933
+ fs21.accessSync(candidate, fs21.constants.X_OK);
5934
+ if (fs21.statSync(candidate).isFile()) {
5739
5935
  return candidate;
5740
5936
  }
5741
5937
  } catch {
@@ -5746,14 +5942,14 @@ function whichSync(name) {
5746
5942
  }
5747
5943
  function claudeCodeInstalled(opts = {}) {
5748
5944
  const home = opts.home ?? os2.homedir();
5749
- if (isDir3(path19.join(home, ".claude"))) {
5945
+ if (isDir3(path20.join(home, ".claude"))) {
5750
5946
  return true;
5751
5947
  }
5752
5948
  return (opts.which ?? whichSync)("claude") !== null;
5753
5949
  }
5754
5950
  function cursorInstalled(opts = {}) {
5755
5951
  const home = opts.home ?? os2.homedir();
5756
- if (isDir3(path19.join(home, ".cursor"))) {
5952
+ if (isDir3(path20.join(home, ".cursor"))) {
5757
5953
  return true;
5758
5954
  }
5759
5955
  return (opts.which ?? whichSync)("cursor") !== null;
@@ -5776,9 +5972,9 @@ function anySkillsInstalled(opts = {}) {
5776
5972
  for (const target of detectTargets(opts)) {
5777
5973
  const tdir = resolveTargetDir({ target, scope: "user", home: opts.home });
5778
5974
  for (const skill of sources) {
5779
- const name = stem(path19.basename(skill));
5780
- const rel = target === "claude-code" ? path19.join(name, "SKILL.md") : `${name}.mdc`;
5781
- if (isFile6(path19.join(tdir, rel))) {
5975
+ const name = stem(path20.basename(skill));
5976
+ const rel = target === "claude-code" ? path20.join(name, "SKILL.md") : `${name}.mdc`;
5977
+ if (isFile7(path20.join(tdir, rel))) {
5782
5978
  return true;
5783
5979
  }
5784
5980
  }
@@ -5803,7 +5999,7 @@ function resolveTargetDir(opts) {
5803
5999
  }
5804
6000
  const base = scope === "user" ? opts.home ?? os2.homedir() : opts.projectRoot ?? process.cwd();
5805
6001
  const [d1, d2] = TARGET_SUBDIR[target];
5806
- return path19.join(base, d1, d2);
6002
+ return path20.join(base, d1, d2);
5807
6003
  }
5808
6004
  function splitFrontmatter(text2) {
5809
6005
  const lines = text2.split("\n");
@@ -5861,16 +6057,16 @@ function iterRenderedPayloads(src, target) {
5861
6057
  for (const skill of listSourceSkills(src)) {
5862
6058
  payloads.push(
5863
6059
  renderSkillPayload(
5864
- fs20.readFileSync(skill, "utf-8"),
5865
- stem(path19.basename(skill)),
6060
+ fs21.readFileSync(skill, "utf-8"),
6061
+ stem(path20.basename(skill)),
5866
6062
  target
5867
6063
  )
5868
6064
  );
5869
6065
  }
5870
6066
  for (const ref of listSourceReferences(src)) {
5871
6067
  payloads.push([
5872
- `${ROUTER_SKILL_NAME}/references/${path19.basename(ref)}`,
5873
- fs20.readFileSync(ref, "utf-8")
6068
+ `${ROUTER_SKILL_NAME}/references/${path20.basename(ref)}`,
6069
+ fs21.readFileSync(ref, "utf-8")
5874
6070
  ]);
5875
6071
  }
5876
6072
  return payloads;
@@ -5882,7 +6078,7 @@ function packageVersion() {
5882
6078
  return "unknown";
5883
6079
  }
5884
6080
  const pkg = JSON.parse(
5885
- fs20.readFileSync(path19.join(root, "package.json"), "utf-8")
6081
+ fs21.readFileSync(path20.join(root, "package.json"), "utf-8")
5886
6082
  );
5887
6083
  return typeof pkg.version === "string" ? pkg.version : "unknown";
5888
6084
  } catch {
@@ -5901,11 +6097,11 @@ function contentKey(payloads) {
5901
6097
  return h.digest("hex");
5902
6098
  }
5903
6099
  function metaPath(tdir) {
5904
- return path19.join(tdir, ROUTER_SKILL_NAME, META_FILENAME);
6100
+ return path20.join(tdir, ROUTER_SKILL_NAME, META_FILENAME);
5905
6101
  }
5906
6102
  function loadMeta(tdir) {
5907
6103
  try {
5908
- const data = JSON.parse(fs20.readFileSync(metaPath(tdir), "utf-8"));
6104
+ const data = JSON.parse(fs21.readFileSync(metaPath(tdir), "utf-8"));
5909
6105
  return data !== null && typeof data === "object" && !Array.isArray(data) ? data : null;
5910
6106
  } catch {
5911
6107
  return null;
@@ -5922,15 +6118,15 @@ function writeMeta(tdir, payloads) {
5922
6118
  package_version: packageVersion()
5923
6119
  };
5924
6120
  const p = metaPath(tdir);
5925
- fs20.mkdirSync(path19.dirname(p), { recursive: true });
5926
- fs20.writeFileSync(p, `${JSON.stringify(meta, null, 2)}
6121
+ fs21.mkdirSync(path20.dirname(p), { recursive: true });
6122
+ fs21.writeFileSync(p, `${JSON.stringify(meta, null, 2)}
5927
6123
  `);
5928
6124
  }
5929
6125
  function installedMarker(tdir, target) {
5930
6126
  if (target === "cursor") {
5931
- return path19.join(tdir, `${ROUTER_SKILL_NAME}.mdc`);
6127
+ return path20.join(tdir, `${ROUTER_SKILL_NAME}.mdc`);
5932
6128
  }
5933
- return path19.join(tdir, ROUTER_SKILL_NAME, "SKILL.md");
6129
+ return path20.join(tdir, ROUTER_SKILL_NAME, "SKILL.md");
5934
6130
  }
5935
6131
  function syncInstalledSkills(opts = {}) {
5936
6132
  const src = opts.source ?? SKILLS_SOURCE;
@@ -5944,7 +6140,7 @@ function syncInstalledSkills(opts = {}) {
5944
6140
  home: opts.home,
5945
6141
  projectRoot: opts.projectRoot
5946
6142
  });
5947
- if (!isFile6(installedMarker(tdir, target))) {
6143
+ if (!isFile7(installedMarker(tdir, target))) {
5948
6144
  continue;
5949
6145
  }
5950
6146
  if (payloads === null) {
@@ -5967,15 +6163,15 @@ function syncOneDir(tdir, payloads) {
5967
6163
  const wrote = [];
5968
6164
  const keptEdited = [];
5969
6165
  for (const [rel, content] of payloads) {
5970
- const dest = path19.join(tdir, rel);
6166
+ const dest = path20.join(tdir, rel);
5971
6167
  const newHash = sha256(content);
5972
- const cur = isFile6(dest) ? sha256(fs20.readFileSync(dest, "utf-8")) : null;
6168
+ const cur = isFile7(dest) ? sha256(fs21.readFileSync(dest, "utf-8")) : null;
5973
6169
  if (cur === newHash) {
5974
6170
  continue;
5975
6171
  }
5976
6172
  if (cur === null || cur === recordedFiles[rel]) {
5977
- fs20.mkdirSync(path19.dirname(dest), { recursive: true });
5978
- fs20.writeFileSync(dest, content);
6173
+ fs21.mkdirSync(path20.dirname(dest), { recursive: true });
6174
+ fs21.writeFileSync(dest, content);
5979
6175
  wrote.push(rel);
5980
6176
  } else {
5981
6177
  keptEdited.push(rel);
@@ -5986,15 +6182,15 @@ function syncOneDir(tdir, payloads) {
5986
6182
  if (shipped.has(rel)) {
5987
6183
  continue;
5988
6184
  }
5989
- const dest = path19.join(tdir, rel);
6185
+ const dest = path20.join(tdir, rel);
5990
6186
  try {
5991
- if (isFile6(dest) && sha256(fs20.readFileSync(dest, "utf-8")) === recorded) {
5992
- fs20.unlinkSync(dest);
6187
+ if (isFile7(dest) && sha256(fs21.readFileSync(dest, "utf-8")) === recorded) {
6188
+ fs21.unlinkSync(dest);
5993
6189
  wrote.push(`removed ${rel}`);
5994
- let parent = path19.dirname(dest);
5995
- while (parent !== tdir && isDir3(parent) && fs20.readdirSync(parent).length === 0) {
5996
- fs20.rmdirSync(parent);
5997
- parent = path19.dirname(parent);
6190
+ let parent = path20.dirname(dest);
6191
+ while (parent !== tdir && isDir3(parent) && fs21.readdirSync(parent).length === 0) {
6192
+ fs21.rmdirSync(parent);
6193
+ parent = path20.dirname(parent);
5998
6194
  }
5999
6195
  }
6000
6196
  } catch {
@@ -6024,45 +6220,45 @@ function installSkills(opts) {
6024
6220
  projectRoot: opts.projectRoot,
6025
6221
  home: opts.home
6026
6222
  });
6027
- fs20.mkdirSync(tdir, { recursive: true });
6223
+ fs21.mkdirSync(tdir, { recursive: true });
6028
6224
  const installed = [];
6029
6225
  const skipped = [];
6030
6226
  for (const skill of skillFiles) {
6031
- const skillName = stem(path19.basename(skill));
6032
- const srcText = fs20.readFileSync(skill, "utf-8");
6227
+ const skillName = stem(path20.basename(skill));
6228
+ const srcText = fs21.readFileSync(skill, "utf-8");
6033
6229
  const [relPath, content] = renderSkillPayload(srcText, skillName, target);
6034
- const dest = path19.join(tdir, relPath);
6035
- fs20.mkdirSync(path19.dirname(dest), { recursive: true });
6036
- if (isFile6(dest) && sha256(fs20.readFileSync(dest, "utf-8")) === sha256(content)) {
6230
+ const dest = path20.join(tdir, relPath);
6231
+ fs21.mkdirSync(path20.dirname(dest), { recursive: true });
6232
+ if (isFile7(dest) && sha256(fs21.readFileSync(dest, "utf-8")) === sha256(content)) {
6037
6233
  skipped.push(skillName);
6038
6234
  } else {
6039
- fs20.writeFileSync(dest, content);
6235
+ fs21.writeFileSync(dest, content);
6040
6236
  installed.push(skillName);
6041
6237
  }
6042
6238
  if (target === "claude-code") {
6043
- const legacyFlat = path19.join(tdir, path19.basename(skill));
6044
- if (isFile6(legacyFlat)) {
6045
- fs20.unlinkSync(legacyFlat);
6239
+ const legacyFlat = path20.join(tdir, path20.basename(skill));
6240
+ if (isFile7(legacyFlat)) {
6241
+ fs21.unlinkSync(legacyFlat);
6046
6242
  }
6047
6243
  }
6048
6244
  }
6049
6245
  for (const ref of listSourceReferences(src)) {
6050
- const rel = `${ROUTER_SKILL_NAME}/references/${path19.basename(ref)}`;
6051
- const dest = path19.join(tdir, rel);
6052
- fs20.mkdirSync(path19.dirname(dest), { recursive: true });
6053
- const content = fs20.readFileSync(ref, "utf-8");
6054
- if (isFile6(dest) && sha256(fs20.readFileSync(dest, "utf-8")) === sha256(content)) {
6246
+ const rel = `${ROUTER_SKILL_NAME}/references/${path20.basename(ref)}`;
6247
+ const dest = path20.join(tdir, rel);
6248
+ fs21.mkdirSync(path20.dirname(dest), { recursive: true });
6249
+ const content = fs21.readFileSync(ref, "utf-8");
6250
+ if (isFile7(dest) && sha256(fs21.readFileSync(dest, "utf-8")) === sha256(content)) {
6055
6251
  skipped.push(rel);
6056
6252
  } else {
6057
- fs20.writeFileSync(dest, content);
6253
+ fs21.writeFileSync(dest, content);
6058
6254
  installed.push(rel);
6059
6255
  }
6060
6256
  }
6061
- if (isDir3(path19.join(tdir, ROUTER_SKILL_NAME))) {
6257
+ if (isDir3(path20.join(tdir, ROUTER_SKILL_NAME))) {
6062
6258
  writeMeta(tdir, iterRenderedPayloads(src, target));
6063
6259
  }
6064
- const legacy = target === "claude-code" ? LEGACY_SKILL_NAMES.filter((name) => isDir3(path19.join(tdir, name))) : LEGACY_SKILL_NAMES.filter(
6065
- (name) => isFile6(path19.join(tdir, `${name}.mdc`))
6260
+ const legacy = target === "claude-code" ? LEGACY_SKILL_NAMES.filter((name) => isDir3(path20.join(tdir, name))) : LEGACY_SKILL_NAMES.filter(
6261
+ (name) => isFile7(path20.join(tdir, `${name}.mdc`))
6066
6262
  );
6067
6263
  return {
6068
6264
  target,
@@ -6088,9 +6284,9 @@ function acceptChoices(option, accepted, advertised) {
6088
6284
  }
6089
6285
 
6090
6286
  // src/cli/wallet.ts
6091
- import * as fs22 from "fs";
6287
+ import * as fs23 from "fs";
6092
6288
  import * as os3 from "os";
6093
- import * as path21 from "path";
6289
+ import * as path22 from "path";
6094
6290
  import { EVMWalletProvider, SigningPolicy } from "@bnbagent/sdk";
6095
6291
  import {
6096
6292
  envLocalPath as envLocalPath10,
@@ -6100,14 +6296,16 @@ import {
6100
6296
  import { buildPolicy, buildWallet } from "@bnbagent/studio-runtime/wallet";
6101
6297
 
6102
6298
  // src/cli/walletSession.ts
6103
- import * as fs21 from "fs";
6104
- import * as path20 from "path";
6299
+ import * as fs22 from "fs";
6300
+ import * as path21 from "path";
6301
+ import { pathToFileURL } from "url";
6105
6302
  import { AltanaWalletProvider } from "@bnbagent/sdk";
6106
6303
  import { getAddress as deployedAddresses } from "@bnbagent/sdk/networks";
6107
6304
  import {
6108
6305
  defaultAgentPermissions,
6109
6306
  deserializeSession,
6110
- serializeSession
6307
+ serializeSession,
6308
+ setAltanaSdkImporter
6111
6309
  } from "@bnbagent/sdk/wallets";
6112
6310
  import { auditedOp as auditedOp2 } from "@bnbagent/studio-runtime/audit";
6113
6311
  import { loadStudioToml as loadStudioToml9 } from "@bnbagent/studio-runtime/config";
@@ -6115,7 +6313,8 @@ import { getNetwork as getNetwork5, toRaw as toRaw2 } from "@bnbagent/studio-run
6115
6313
  import { writePrivate } from "@bnbagent/studio-runtime/secretWrite";
6116
6314
  import {
6117
6315
  ALTANA_NETWORK_BY_STUDIO,
6118
- PASSWORD_ENV
6316
+ PASSWORD_ENV,
6317
+ resolveProjectAltanaSdkEntry as resolveProjectAltanaSdkEntry2
6119
6318
  } from "@bnbagent/studio-runtime/wallet";
6120
6319
  var defaultAdminFactory = (opts) => AltanaWalletProvider.adminFromKeystore(opts);
6121
6320
  var adminFactory = defaultAdminFactory;
@@ -6124,13 +6323,17 @@ function tableOf7(value) {
6124
6323
  return value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
6125
6324
  }
6126
6325
  function loadContext(projectRoot) {
6127
- const cfg = loadStudioToml9(path20.join(projectRoot, "studio.toml"));
6326
+ const cfg = loadStudioToml9(path21.join(projectRoot, "studio.toml"));
6128
6327
  const walletCfg = tableOf7(cfg.wallet);
6129
6328
  if (String(walletCfg.kind ?? "evm-local") !== "altana") {
6130
6329
  throw new Error(
6131
6330
  `wallet session commands require [wallet].kind='altana' (got ${JSON.stringify(walletCfg.kind ?? "evm-local")}).`
6132
6331
  );
6133
6332
  }
6333
+ const sdkEntry = resolveProjectAltanaSdkEntry2(projectRoot);
6334
+ setAltanaSdkImporter(
6335
+ sdkEntry === null ? null : () => import(pathToFileURL(sdkEntry).href)
6336
+ );
6134
6337
  const networkName = String(tableOf7(cfg.network).default ?? "bsc-testnet");
6135
6338
  const altanaNetwork = ALTANA_NETWORK_BY_STUDIO[networkName];
6136
6339
  if (altanaNetwork === void 0) {
@@ -6146,7 +6349,7 @@ function loadContext(projectRoot) {
6146
6349
  }
6147
6350
  const resolvePath = (value, fallback) => {
6148
6351
  const configured = String(value ?? fallback);
6149
- return path20.isAbsolute(configured) ? configured : path20.join(projectRoot, configured);
6352
+ return path21.isAbsolute(configured) ? configured : path21.join(projectRoot, configured);
6150
6353
  };
6151
6354
  return {
6152
6355
  projectRoot,
@@ -6210,7 +6413,7 @@ function parseSessionEnvelope(serialized) {
6210
6413
  function readSession(ctx) {
6211
6414
  let serialized;
6212
6415
  try {
6213
- serialized = fs21.readFileSync(ctx.sessionFile, "utf8");
6416
+ serialized = fs22.readFileSync(ctx.sessionFile, "utf8");
6214
6417
  } catch {
6215
6418
  throw new Error(
6216
6419
  `no Altana session file at ${ctx.sessionFile} \u2014 run \`bag wallet session grant\`.`
@@ -6219,8 +6422,8 @@ function readSession(ctx) {
6219
6422
  return { serialized, envelope: parseSessionEnvelope(serialized) };
6220
6423
  }
6221
6424
  function writeSession(ctx, session) {
6222
- fs21.mkdirSync(path20.dirname(ctx.sessionFile), { recursive: true, mode: 448 });
6223
- fs21.chmodSync(path20.dirname(ctx.sessionFile), 448);
6425
+ fs22.mkdirSync(path21.dirname(ctx.sessionFile), { recursive: true, mode: 448 });
6426
+ fs22.chmodSync(path21.dirname(ctx.sessionFile), 448);
6224
6427
  writePrivate(ctx.sessionFile, serializeSession(session));
6225
6428
  }
6226
6429
  function sessionKeyFingerprint(publicKey) {
@@ -6331,7 +6534,7 @@ async function cmdSessionGrant(opts) {
6331
6534
  "--budget-u"
6332
6535
  );
6333
6536
  let existing = null;
6334
- if (fs21.existsSync(ctx.sessionFile)) {
6537
+ if (fs22.existsSync(ctx.sessionFile)) {
6335
6538
  existing = readSession(ctx).envelope;
6336
6539
  if (!opts.force) {
6337
6540
  throw new Error(
@@ -6449,7 +6652,7 @@ async function cmdSessionRevoke(opts) {
6449
6652
  await admin.revokeSession(envelope.publicKey);
6450
6653
  }
6451
6654
  );
6452
- fs21.unlinkSync(ctx.sessionFile);
6655
+ fs22.unlinkSync(ctx.sessionFile);
6453
6656
  printErr(`\u2713 Altana session revoked and removed: ${ctx.sessionFile}`);
6454
6657
  return 0;
6455
6658
  }
@@ -6573,8 +6776,8 @@ var ProjectRootNotFound = class extends Error {
6573
6776
  };
6574
6777
  function resolveWalletProjectRoot(argRoot) {
6575
6778
  if (argRoot != null) {
6576
- const root2 = path21.resolve(argRoot);
6577
- if (!isFile7(path21.join(root2, "studio.toml"))) {
6779
+ const root2 = path22.resolve(argRoot);
6780
+ if (!isFile8(path22.join(root2, "studio.toml"))) {
6578
6781
  throw new ProjectRootNotFound(
6579
6782
  `No studio.toml found under --project-root ${root2}`
6580
6783
  );
@@ -6589,15 +6792,15 @@ function resolveWalletProjectRoot(argRoot) {
6589
6792
  }
6590
6793
  return root;
6591
6794
  }
6592
- function isFile7(p) {
6795
+ function isFile8(p) {
6593
6796
  try {
6594
- return fs22.statSync(p).isFile();
6797
+ return fs23.statSync(p).isFile();
6595
6798
  } catch {
6596
6799
  return false;
6597
6800
  }
6598
6801
  }
6599
6802
  function loadWalletCfg(projectRoot) {
6600
- const data = loadStudioToml10(path21.join(projectRoot, "studio.toml"));
6803
+ const data = loadStudioToml10(path22.join(projectRoot, "studio.toml"));
6601
6804
  const wallet = data.wallet;
6602
6805
  return wallet !== null && typeof wallet === "object" && !Array.isArray(wallet) ? wallet : {};
6603
6806
  }
@@ -6607,7 +6810,7 @@ function walletKind(walletCfg) {
6607
6810
  function projectNetwork(projectRoot) {
6608
6811
  let data;
6609
6812
  try {
6610
- data = loadStudioToml10(path21.join(projectRoot, "studio.toml"));
6813
+ data = loadStudioToml10(path22.join(projectRoot, "studio.toml"));
6611
6814
  } catch {
6612
6815
  return "bsc-testnet";
6613
6816
  }
@@ -6646,12 +6849,12 @@ function requireDurablePassword(projectRoot) {
6646
6849
  return password;
6647
6850
  }
6648
6851
  function persistAddress(projectRoot, address) {
6649
- const tomlPath = path21.join(projectRoot, "studio.toml");
6650
- if (!isFile7(tomlPath)) {
6852
+ const tomlPath = path22.join(projectRoot, "studio.toml");
6853
+ if (!isFile8(tomlPath)) {
6651
6854
  return;
6652
6855
  }
6653
- const text2 = fs22.readFileSync(tomlPath, "utf-8");
6654
- fs22.writeFileSync(
6856
+ const text2 = fs23.readFileSync(tomlPath, "utf-8");
6857
+ fs23.writeFileSync(
6655
6858
  tomlPath,
6656
6859
  updateSection(text2, "wallet", { address }),
6657
6860
  "utf-8"
@@ -6667,7 +6870,7 @@ function resolveKeystoreDir2(projectRoot, cliOverride, walletCfg) {
6667
6870
  } else {
6668
6871
  d = ".studio/wallets";
6669
6872
  }
6670
- return path21.isAbsolute(d) ? d : path21.join(projectRoot, d);
6873
+ return path22.isAbsolute(d) ? d : path22.join(projectRoot, d);
6671
6874
  }
6672
6875
  async function resolvePrivateKeyArg(raw) {
6673
6876
  if (raw === void 0 || raw === false) {
@@ -6782,7 +6985,7 @@ async function cmdNew(opts) {
6782
6985
  projectRoot = process.cwd();
6783
6986
  }
6784
6987
  let walletCfg = {};
6785
- if (isFile7(path21.join(projectRoot, "studio.toml"))) {
6988
+ if (isFile8(path22.join(projectRoot, "studio.toml"))) {
6786
6989
  walletCfg = loadWalletCfg(projectRoot);
6787
6990
  }
6788
6991
  const kind = walletKind(walletCfg);
@@ -6796,7 +6999,7 @@ async function cmdNew(opts) {
6796
6999
  opts.keystoreDir,
6797
7000
  walletCfg
6798
7001
  );
6799
- fs22.mkdirSync(keystoreDir, { recursive: true });
7002
+ fs23.mkdirSync(keystoreDir, { recursive: true });
6800
7003
  const provider = new EVMWalletProvider({
6801
7004
  password,
6802
7005
  ...privateKey !== null ? { privateKey } : {},
@@ -6806,7 +7009,7 @@ async function cmdNew(opts) {
6806
7009
  persistAddress(projectRoot, provider.address);
6807
7010
  if (kind === "altana") {
6808
7011
  printErr(
6809
- "Altana admin keystore created. Fund this address with about 0.6 tBNB for testnet bootstrap/registration, then run `bag wallet session grant` to create the bounded runtime session."
7012
+ "Altana admin keystore created. Fund this address with about 0.05 tBNB for testnet bootstrap/registration, then run `bag wallet session grant` to create the bounded runtime session."
6810
7013
  );
6811
7014
  }
6812
7015
  return 0;
@@ -6820,11 +7023,11 @@ Install it (Node >=22): npm install -g @trustwallet/cli@${TWAK_CLI_VERSION}`
6820
7023
  return 1;
6821
7024
  }
6822
7025
  const walletFile = twakWalletFile(walletCfg, projectRoot);
6823
- if (!isFile7(walletFile)) {
7026
+ if (!isFile8(walletFile)) {
6824
7027
  let createCmd = "twak wallet create --password <your-password> --no-keychain";
6825
7028
  let setupCmd = "twak setup";
6826
7029
  if (walletCfg.twak_home) {
6827
- const home = path21.dirname(path21.dirname(walletFile));
7030
+ const home = path22.dirname(path22.dirname(walletFile));
6828
7031
  createCmd = `HOME=${home} ${createCmd}`;
6829
7032
  setupCmd = `HOME=${home} ${setupCmd}`;
6830
7033
  }
@@ -6850,23 +7053,23 @@ Install it (Node >=22): npm install -g @trustwallet/cli@${TWAK_CLI_VERSION}`
6850
7053
  return 0;
6851
7054
  }
6852
7055
  function ensureTwakCredentials(walletFile, homeDir) {
6853
- const twakDir = path21.dirname(walletFile);
6854
- const target = path21.join(twakDir, "credentials.json");
6855
- if (isFile7(target)) {
7056
+ const twakDir = path22.dirname(walletFile);
7057
+ const target = path22.join(twakDir, "credentials.json");
7058
+ if (isFile8(target)) {
6856
7059
  return true;
6857
7060
  }
6858
- const machine = path21.join(os3.homedir(), ".twak", "credentials.json");
6859
- if (path21.resolve(machine) === path21.resolve(target) || !isFile7(machine)) {
7061
+ const machine = path22.join(os3.homedir(), ".twak", "credentials.json");
7062
+ if (path22.resolve(machine) === path22.resolve(target) || !isFile8(machine)) {
6860
7063
  printErr(
6861
7064
  `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.`
6862
7065
  );
6863
7066
  return false;
6864
7067
  }
6865
- fs22.mkdirSync(twakDir, { recursive: true });
6866
- fs22.writeFileSync(target, fs22.readFileSync(machine, "utf-8"), { mode: 384 });
7068
+ fs23.mkdirSync(twakDir, { recursive: true });
7069
+ fs23.writeFileSync(target, fs23.readFileSync(machine, "utf-8"), { mode: 384 });
6867
7070
  try {
6868
- fs22.chmodSync(twakDir, 448);
6869
- fs22.chmodSync(target, 384);
7071
+ fs23.chmodSync(twakDir, 448);
7072
+ fs23.chmodSync(target, 384);
6870
7073
  } catch {
6871
7074
  }
6872
7075
  printErr(`note: copied NaaS credentials from ${machine} into ${twakDir}.`);
@@ -6878,10 +7081,10 @@ async function resolveTwakInitPassword(opts) {
6878
7081
  throw new CliExit(2);
6879
7082
  }
6880
7083
  if (opts.passwordFile) {
6881
- const file = path21.resolve(opts.passwordFile);
7084
+ const file = path22.resolve(opts.passwordFile);
6882
7085
  let mode;
6883
7086
  try {
6884
- mode = fs22.statSync(file).mode;
7087
+ mode = fs23.statSync(file).mode;
6885
7088
  } catch {
6886
7089
  printErr(`error: cannot read --password-file ${file}.`);
6887
7090
  throw new CliExit(2);
@@ -6892,7 +7095,7 @@ async function resolveTwakInitPassword(opts) {
6892
7095
  );
6893
7096
  throw new CliExit(2);
6894
7097
  }
6895
- const password = (fs22.readFileSync(file, "utf-8").split(/\r?\n/)[0] ?? "").trim();
7098
+ const password = (fs23.readFileSync(file, "utf-8").split(/\r?\n/)[0] ?? "").trim();
6896
7099
  if (!password) {
6897
7100
  printErr(`error: --password-file ${file} is empty.`);
6898
7101
  throw new CliExit(2);
@@ -6945,15 +7148,15 @@ Install it (Node >=22): npm install -g @trustwallet/cli@${TWAK_CLI_VERSION}`
6945
7148
  return 1;
6946
7149
  }
6947
7150
  const walletFile = twakWalletFile(walletCfg, projectRoot);
6948
- if (isFile7(walletFile)) {
7151
+ if (isFile8(walletFile)) {
6949
7152
  printErr(
6950
7153
  `error: a twak wallet already exists at ${walletFile} \u2014 nothing to create. Run \`bag wallet new\` to adopt its address into studio.toml.`
6951
7154
  );
6952
7155
  return 1;
6953
7156
  }
6954
7157
  const password = await resolveTwakInitPassword(opts);
6955
- const homeDir = path21.dirname(path21.dirname(walletFile));
6956
- fs22.mkdirSync(homeDir, { recursive: true });
7158
+ const homeDir = path22.dirname(path22.dirname(walletFile));
7159
+ fs23.mkdirSync(homeDir, { recursive: true });
6957
7160
  if (!ensureTwakCredentials(walletFile, homeDir)) {
6958
7161
  return 1;
6959
7162
  }
@@ -6975,7 +7178,7 @@ ${password}
6975
7178
  timeoutMs: 12e4
6976
7179
  }
6977
7180
  );
6978
- if (create.code !== 0 || !isFile7(walletFile)) {
7181
+ if (create.code !== 0 || !isFile8(walletFile)) {
6979
7182
  const detail = `${create.stderr}
6980
7183
  ${create.stdout}`.trim();
6981
7184
  printErr(
@@ -6990,14 +7193,14 @@ ${detail}` : `error: \`twak wallet create --no-keychain\` did not produce ${wall
6990
7193
  return 1;
6991
7194
  }
6992
7195
  try {
6993
- fs22.chmodSync(walletFile, 384);
7196
+ fs23.chmodSync(walletFile, 384);
6994
7197
  } catch {
6995
7198
  }
6996
7199
  if (!process.env.TWAK_WALLET_PASSWORD) {
6997
7200
  process.env.TWAK_WALLET_PASSWORD = password;
6998
7201
  }
6999
7202
  printErr(
7000
- `\u2713 twak wallet created under ${path21.dirname(walletFile)} (no keychain)`
7203
+ `\u2713 twak wallet created under ${path22.dirname(walletFile)} (no keychain)`
7001
7204
  );
7002
7205
  printErr(
7003
7206
  "next: persist TWAK_WALLET_PASSWORD in .studio/.env.local so deploys and non-interactive signing can unlock it."
@@ -7034,7 +7237,7 @@ function cmdShow5(projectRootArg) {
7034
7237
  ...walletCfg.address ? { address: String(walletCfg.address) } : {}
7035
7238
  });
7036
7239
  const address = provider.address;
7037
- const keystorePath = path21.join(keystoreDir, `${address}.json`);
7240
+ const keystorePath = path22.join(keystoreDir, `${address}.json`);
7038
7241
  printOut(`address: ${address}`);
7039
7242
  printOut(`source: ${kind}`);
7040
7243
  printOut(`keystore_dir: ${keystoreDir}`);
@@ -7043,14 +7246,14 @@ function cmdShow5(projectRootArg) {
7043
7246
  const configured = String(
7044
7247
  walletCfg.session_file ?? ".studio/wallets/altana-session.json"
7045
7248
  );
7046
- const sessionFile = path21.isAbsolute(configured) ? configured : path21.join(projectRoot, configured);
7249
+ const sessionFile = path22.isAbsolute(configured) ? configured : path22.join(projectRoot, configured);
7047
7250
  printOut(`session_file: ${sessionFile}`);
7048
- if (!isFile7(sessionFile)) {
7251
+ if (!isFile8(sessionFile)) {
7049
7252
  printOut("session_status: missing (run `bag wallet session grant`)");
7050
7253
  } else {
7051
7254
  let envelope;
7052
7255
  try {
7053
- envelope = JSON.parse(fs22.readFileSync(sessionFile, "utf8"));
7256
+ envelope = JSON.parse(fs23.readFileSync(sessionFile, "utf8"));
7054
7257
  } catch {
7055
7258
  throw new Error(`invalid Altana session JSON at ${sessionFile}`);
7056
7259
  }
@@ -7076,7 +7279,7 @@ function cmdList2(projectRootArg) {
7076
7279
  const keystoreDir = resolveKeystoreDir2(projectRoot, null, walletCfg);
7077
7280
  let entries;
7078
7281
  try {
7079
- entries = fs22.readdirSync(keystoreDir).sort();
7282
+ entries = fs23.readdirSync(keystoreDir).sort();
7080
7283
  } catch {
7081
7284
  return 0;
7082
7285
  }
@@ -7088,7 +7291,7 @@ function cmdList2(projectRootArg) {
7088
7291
  let data;
7089
7292
  try {
7090
7293
  data = JSON.parse(
7091
- fs22.readFileSync(path21.join(keystoreDir, child), "utf-8")
7294
+ fs23.readFileSync(path22.join(keystoreDir, child), "utf-8")
7092
7295
  );
7093
7296
  } catch {
7094
7297
  continue;
@@ -7139,7 +7342,7 @@ async function cmdSign(msg, projectRootArg) {
7139
7342
  }
7140
7343
  async function cmdBalance(opts) {
7141
7344
  const projectRoot = resolveWalletProjectRoot(opts.projectRoot);
7142
- const data = loadStudioToml10(path21.join(projectRoot, "studio.toml"));
7345
+ const data = loadStudioToml10(path22.join(projectRoot, "studio.toml"));
7143
7346
  const walletCfg = data.wallet !== null && typeof data.wallet === "object" ? data.wallet : {};
7144
7347
  let address;
7145
7348
  const kind = walletKind(walletCfg);
@@ -7266,10 +7469,10 @@ var PROVIDER_KEY_ENV = {
7266
7469
  "pieverse-llm": "PIEVERSE_LLM_API_KEY"
7267
7470
  };
7268
7471
  function renderAgentcoreProject(target, name) {
7269
- const acDir = path22.join(target, "agentcore");
7270
- fs23.mkdirSync(acDir, { recursive: true });
7271
- fs23.writeFileSync(
7272
- path22.join(acDir, "agentcore.json"),
7472
+ const acDir = path23.join(target, "agentcore");
7473
+ fs24.mkdirSync(acDir, { recursive: true });
7474
+ fs24.writeFileSync(
7475
+ path23.join(acDir, "agentcore.json"),
7273
7476
  `${JSON.stringify(
7274
7477
  {
7275
7478
  $schema: "https://schema.agentcore.aws.dev/v1/agentcore.json",
@@ -7283,7 +7486,7 @@ function renderAgentcoreProject(target, name) {
7283
7486
  )}
7284
7487
  `
7285
7488
  );
7286
- fs23.writeFileSync(path22.join(acDir, "aws-targets.json"), "[]\n");
7489
+ fs24.writeFileSync(path23.join(acDir, "aws-targets.json"), "[]\n");
7287
7490
  }
7288
7491
  var AGENTS_MD_MARKER = "# bnbagent-studio additions (ERC-8183 seller)";
7289
7492
  var AGENTS_MD_STUDIO_SECTION = `
@@ -7327,30 +7530,30 @@ every intent to the right playbook via its references.
7327
7530
  and state the tradeoff.
7328
7531
  `;
7329
7532
  function appendAgentsMdStudioSection(target) {
7330
- const agentsMd = path22.join(target, "AGENTS.md");
7533
+ const agentsMd = path23.join(target, "AGENTS.md");
7331
7534
  let existing = "";
7332
7535
  try {
7333
- existing = fs23.readFileSync(agentsMd, "utf-8");
7536
+ existing = fs24.readFileSync(agentsMd, "utf-8");
7334
7537
  } catch {
7335
7538
  existing = "";
7336
7539
  }
7337
7540
  if (existing.includes(AGENTS_MD_MARKER)) {
7338
7541
  return;
7339
7542
  }
7340
- fs23.writeFileSync(
7543
+ fs24.writeFileSync(
7341
7544
  agentsMd,
7342
7545
  `${existing.replace(/\n+$/, "")}
7343
7546
  ${AGENTS_MD_STUDIO_SECTION}`
7344
7547
  );
7345
7548
  }
7346
7549
  function seedAwsTargets(target) {
7347
- const p = path22.join(target, "agentcore", "aws-targets.json");
7348
- if (!isFile8(p)) {
7550
+ const p = path23.join(target, "agentcore", "aws-targets.json");
7551
+ if (!isFile9(p)) {
7349
7552
  return;
7350
7553
  }
7351
7554
  let data;
7352
7555
  try {
7353
- data = JSON.parse(fs23.readFileSync(p, "utf-8"));
7556
+ data = JSON.parse(fs24.readFileSync(p, "utf-8"));
7354
7557
  } catch {
7355
7558
  return;
7356
7559
  }
@@ -7361,7 +7564,7 @@ function seedAwsTargets(target) {
7361
7564
  { name: "default", account: AWS_ACCOUNT_PLACEHOLDER, region: "us-east-1" }
7362
7565
  ];
7363
7566
  try {
7364
- fs23.writeFileSync(p, `${JSON.stringify(skeleton, null, 2)}
7567
+ fs24.writeFileSync(p, `${JSON.stringify(skeleton, null, 2)}
7365
7568
  `);
7366
7569
  } catch {
7367
7570
  return;
@@ -7384,13 +7587,13 @@ function registerAgentcoreRuntime(target, name, opts = {}) {
7384
7587
  const protocol = nativeProtocolOf(faces);
7385
7588
  const stem2 = entryStemOf(faces);
7386
7589
  const isContainer = opts.packaging === "container" || walletKind2 === "twak";
7387
- const cfgPath = path22.join(target, "agentcore", "agentcore.json");
7388
- if (!isFile8(cfgPath)) {
7590
+ const cfgPath = path23.join(target, "agentcore", "agentcore.json");
7591
+ if (!isFile9(cfgPath)) {
7389
7592
  return;
7390
7593
  }
7391
7594
  let cfg;
7392
7595
  try {
7393
- const parsed = JSON.parse(fs23.readFileSync(cfgPath, "utf-8"));
7596
+ const parsed = JSON.parse(fs24.readFileSync(cfgPath, "utf-8"));
7394
7597
  if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
7395
7598
  return;
7396
7599
  }
@@ -7429,7 +7632,7 @@ function registerAgentcoreRuntime(target, name, opts = {}) {
7429
7632
  runtimes.push(runtime);
7430
7633
  cfg.runtimes = runtimes;
7431
7634
  try {
7432
- fs23.writeFileSync(cfgPath, `${JSON.stringify(cfg, null, 2)}
7635
+ fs24.writeFileSync(cfgPath, `${JSON.stringify(cfg, null, 2)}
7433
7636
  `);
7434
7637
  } catch {
7435
7638
  return;
@@ -7566,12 +7769,12 @@ function registerInit(program) {
7566
7769
  );
7567
7770
  }
7568
7771
  function enclosingProjectRoot(start) {
7569
- let current = path22.resolve(start);
7772
+ let current = path23.resolve(start);
7570
7773
  for (; ; ) {
7571
- if (isFile8(path22.join(current, APP_DIR, AGENT_PKG, "studio.toml"))) {
7774
+ if (isFile9(path23.join(current, APP_DIR, AGENT_PKG, "studio.toml"))) {
7572
7775
  return current;
7573
7776
  }
7574
- const parent = path22.dirname(current);
7777
+ const parent = path23.dirname(current);
7575
7778
  if (parent === current) {
7576
7779
  return null;
7577
7780
  }
@@ -7579,8 +7782,8 @@ function enclosingProjectRoot(start) {
7579
7782
  }
7580
7783
  }
7581
7784
  async function cmdInit(nameArg, opts) {
7582
- const target = path22.resolve(process.cwd(), nameArg);
7583
- let projectName2 = path22.basename(target);
7785
+ const target = path23.resolve(process.cwd(), nameArg);
7786
+ let projectName2 = path23.basename(target);
7584
7787
  if (!projectName2) {
7585
7788
  printErr(
7586
7789
  `error: cannot derive a project name from '${nameArg}' (path has no basename).`
@@ -7665,15 +7868,15 @@ async function cmdInit(nameArg, opts) {
7665
7868
  return 2;
7666
7869
  }
7667
7870
  }
7668
- const enclosing = enclosingProjectRoot(path22.dirname(target));
7871
+ const enclosing = enclosingProjectRoot(path23.dirname(target));
7669
7872
  if (enclosing !== null) {
7670
7873
  printErr(
7671
- `error: ${path22.dirname(target)} is inside an existing bag project (${enclosing}).
7672
- \`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.`
7874
+ `error: ${path23.dirname(target)} is inside an existing bag project (${enclosing}).
7875
+ \`bag init\` resolves the new project relative to the current directory, so running it here would nest a second scaffold inside ${path23.basename(enclosing)}/. cd to a directory OUTSIDE any project and retry.`
7673
7876
  );
7674
7877
  return 2;
7675
7878
  }
7676
- if (fs23.existsSync(target) && !opts.force) {
7879
+ if (fs24.existsSync(target) && !opts.force) {
7677
7880
  printErr(`error: ${target} already exists. Use --force to overwrite.`);
7678
7881
  return 2;
7679
7882
  }
@@ -7692,20 +7895,14 @@ async function cmdInit(nameArg, opts) {
7692
7895
  destination = "self";
7693
7896
  runtime = "agentcore";
7694
7897
  }
7695
- if (destination === "platform" && walletKind2 === "altana") {
7696
- printErr(
7697
- "error: Altana (wallet.kind='altana') is not supported by the managed platform; the runtime needs a bounded local session, never the admin key. Use --destination self."
7698
- );
7699
- return 2;
7700
- }
7701
7898
  if (destination === "self" && runtime === "azure-foundry" && (!hasA2aFace(faces) || hasMcpFace(faces))) {
7702
7899
  printErr(
7703
7900
  "error: azure-foundry supports protocol A2A only as its native face (X402 is optional) and does not support an MCP face. Foundry is delegated through its invocations container contract (:8088, /readiness, /invocations), not the native MCP /mcp transport. Use --protocols A2A (optionally with X402), or use --runtime agentcore for MCP."
7704
7901
  );
7705
7902
  return 2;
7706
7903
  }
7707
- if (fs23.existsSync(target)) {
7708
- fs23.rmSync(target, { recursive: true, force: true });
7904
+ if (fs24.existsSync(target)) {
7905
+ fs24.rmSync(target, { recursive: true, force: true });
7709
7906
  }
7710
7907
  if (destination === "platform") {
7711
7908
  printCampaignIntro();
@@ -7750,7 +7947,7 @@ async function cmdInit(nameArg, opts) {
7750
7947
  }
7751
7948
  }
7752
7949
  try {
7753
- fs23.mkdirSync(target, { recursive: true });
7950
+ fs24.mkdirSync(target, { recursive: true });
7754
7951
  if (runtime === "agentcore") {
7755
7952
  renderAgentcoreProject(target, projectName2);
7756
7953
  }
@@ -7766,7 +7963,7 @@ async function cmdInit(nameArg, opts) {
7766
7963
  printErr(
7767
7964
  `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.`
7768
7965
  );
7769
- fs23.rmSync(target, { recursive: true, force: true });
7966
+ fs24.rmSync(target, { recursive: true, force: true });
7770
7967
  return 2;
7771
7968
  }
7772
7969
  const ides = resolveEmitIdes(opts.ide);
@@ -7809,9 +8006,9 @@ async function cmdInit(nameArg, opts) {
7809
8006
  });
7810
8007
  seedAwsTargets(target);
7811
8008
  }
7812
- const agentDir = path22.join(target, APP_DIR, AGENT_PKG);
7813
- fs23.mkdirSync(path22.join(agentDir, "vendor"), { recursive: true });
7814
- fs23.writeFileSync(path22.join(agentDir, "vendor", ".gitkeep"), "");
8009
+ const agentDir = path23.join(target, APP_DIR, AGENT_PKG);
8010
+ fs24.mkdirSync(path23.join(agentDir, "vendor"), { recursive: true });
8011
+ fs24.writeFileSync(path23.join(agentDir, "vendor", ".gitkeep"), "");
7815
8012
  const skipInstall = opts.install === false || opts.venv === false;
7816
8013
  let provisioned = false;
7817
8014
  let installFailed = false;
@@ -7940,64 +8137,64 @@ function derivePackaging(walletKind2, destination, platformArtifact2 = "zip", ru
7940
8137
  }
7941
8138
  function scaffold(target, name, o) {
7942
8139
  const packageManagerVersion = pnpmVersion();
7943
- fs23.writeFileSync(
7944
- path22.join(target, "package.json"),
8140
+ fs24.writeFileSync(
8141
+ path23.join(target, "package.json"),
7945
8142
  renderWorkspacePackageJson(name, packageManagerVersion)
7946
8143
  );
7947
- fs23.writeFileSync(
7948
- path22.join(target, "pnpm-workspace.yaml"),
8144
+ fs24.writeFileSync(
8145
+ path23.join(target, "pnpm-workspace.yaml"),
7949
8146
  renderPnpmWorkspaceYaml()
7950
8147
  );
7951
- fs23.writeFileSync(path22.join(target, ".gitignore"), renderWorkspaceGitignore());
7952
- if (!isFile8(path22.join(target, "README.md"))) {
7953
- fs23.writeFileSync(
7954
- path22.join(target, "README.md"),
8148
+ fs24.writeFileSync(path23.join(target, ".gitignore"), renderWorkspaceGitignore());
8149
+ if (!isFile9(path23.join(target, "README.md"))) {
8150
+ fs24.writeFileSync(
8151
+ path23.join(target, "README.md"),
7955
8152
  renderWorkspaceReadme(name, o.destination)
7956
8153
  );
7957
8154
  }
7958
8155
  appendAgentsMdStudioSection(target);
7959
- const appRoot = path22.join(target, APP_DIR);
7960
- fs23.mkdirSync(appRoot, { recursive: true });
7961
- const agentRoot2 = path22.join(appRoot, AGENT_PKG);
7962
- fs23.mkdirSync(agentRoot2, { recursive: true });
7963
- fs23.writeFileSync(
7964
- path22.join(agentRoot2, "pnpm-workspace.yaml"),
8156
+ const appRoot = path23.join(target, APP_DIR);
8157
+ fs24.mkdirSync(appRoot, { recursive: true });
8158
+ const agentRoot2 = path23.join(appRoot, AGENT_PKG);
8159
+ fs24.mkdirSync(agentRoot2, { recursive: true });
8160
+ fs24.writeFileSync(
8161
+ path23.join(agentRoot2, "pnpm-workspace.yaml"),
7965
8162
  renderAgentPnpmWorkspaceYaml()
7966
8163
  );
7967
8164
  if (o.walletKind === "evm-local" || o.walletKind === "altana") {
7968
- fs23.mkdirSync(path22.join(target, ".studio", "wallets"), { recursive: true });
8165
+ fs24.mkdirSync(path23.join(target, ".studio", "wallets"), { recursive: true });
7969
8166
  } else if (o.walletKind === "twak") {
7970
8167
  let homeDir;
7971
8168
  let label;
7972
8169
  if (o.twakHome === void 0 || o.twakHome === DEDICATED_TWAK_HOME_REL) {
7973
- homeDir = path22.join(target, ".studio", "twak");
8170
+ homeDir = path23.join(target, ".studio", "twak");
7974
8171
  label = ".studio/twak";
7975
8172
  } else {
7976
- homeDir = path22.isAbsolute(o.twakHome) ? o.twakHome : path22.resolve(agentRoot2, o.twakHome);
8173
+ homeDir = path23.isAbsolute(o.twakHome) ? o.twakHome : path23.resolve(agentRoot2, o.twakHome);
7977
8174
  label = o.twakHome;
7978
8175
  }
7979
- fs23.mkdirSync(homeDir, { recursive: true });
8176
+ fs24.mkdirSync(homeDir, { recursive: true });
7980
8177
  if (ensureTwakKeychain(homeDir)) {
7981
8178
  printOut(
7982
8179
  `\u2713 isolated twak keychain ready under ${label} (macOS) \u2014 no manual \`security\` setup needed`
7983
8180
  );
7984
8181
  }
7985
8182
  }
7986
- fs23.writeFileSync(
7987
- path22.join(agentRoot2, "package.json"),
8183
+ fs24.writeFileSync(
8184
+ path23.join(agentRoot2, "package.json"),
7988
8185
  renderAgentPackageJson(name, o.runtime, o.provider, o.faces, o.walletKind)
7989
8186
  );
7990
- fs23.writeFileSync(
7991
- path22.join(agentRoot2, "tsconfig.json"),
8187
+ fs24.writeFileSync(
8188
+ path23.join(agentRoot2, "tsconfig.json"),
7992
8189
  renderAgentTsconfig()
7993
8190
  );
7994
- fs23.writeFileSync(
7995
- path22.join(agentRoot2, "studio.toml"),
8191
+ fs24.writeFileSync(
8192
+ path23.join(agentRoot2, "studio.toml"),
7996
8193
  renderAgentStudioToml(name, o)
7997
8194
  );
7998
- const envLocal = path22.join(target, ".studio", ".env.local");
7999
- fs23.mkdirSync(path22.dirname(envLocal), { recursive: true });
8000
- fs23.writeFileSync(
8195
+ const envLocal = path23.join(target, ".studio", ".env.local");
8196
+ fs24.mkdirSync(path23.dirname(envLocal), { recursive: true });
8197
+ fs24.writeFileSync(
8001
8198
  envLocal,
8002
8199
  renderAgentEnvLocal(
8003
8200
  o.provider,
@@ -8008,9 +8205,9 @@ function scaffold(target, name, o) {
8008
8205
  o.network
8009
8206
  )
8010
8207
  );
8011
- fs23.writeFileSync(path22.join(agentRoot2, ".gitignore"), renderAgentGitignore());
8012
- fs23.writeFileSync(
8013
- path22.join(agentRoot2, "README.md"),
8208
+ fs24.writeFileSync(path23.join(agentRoot2, ".gitignore"), renderAgentGitignore());
8209
+ fs24.writeFileSync(
8210
+ path23.join(agentRoot2, "README.md"),
8014
8211
  renderAgentReadme(name, o.faces, o.destination)
8015
8212
  );
8016
8213
  const packaging = derivePackaging(
@@ -8046,18 +8243,18 @@ function emitRecipe(base, name, opts = {}) {
8046
8243
  const recipe = loadRecipe(name, { mode: opts.mode ?? null });
8047
8244
  for (const rf of recipe.files) {
8048
8245
  const targetPath = substitutePlaceholders(rf.targetPath, opts.context);
8049
- const basename16 = path22.posix.basename(targetPath);
8050
- const dst = basename16 === "Dockerfile" || basename16 === ".dockerignore" ? path22.join(base, basename16) : path22.join(base, targetPath);
8051
- fs23.mkdirSync(path22.dirname(dst), { recursive: true });
8052
- fs23.writeFileSync(dst, substitutePlaceholders(rf.content, opts.context));
8246
+ const basename16 = path23.posix.basename(targetPath);
8247
+ const dst = basename16 === "Dockerfile" || basename16 === ".dockerignore" ? path23.join(base, basename16) : path23.join(base, targetPath);
8248
+ fs24.mkdirSync(path23.dirname(dst), { recursive: true });
8249
+ fs24.writeFileSync(dst, substitutePlaceholders(rf.content, opts.context));
8053
8250
  }
8054
8251
  }
8055
8252
  function readRecipeNodeDeps(recipeName, group) {
8056
- const tomlPath = path22.join(bundledRecipesRoot(), recipeName, "recipe.toml");
8057
- if (!isFile8(tomlPath)) {
8253
+ const tomlPath = path23.join(bundledRecipesRoot(), recipeName, "recipe.toml");
8254
+ if (!isFile9(tomlPath)) {
8058
8255
  return [];
8059
8256
  }
8060
- const meta = parseToml(fs23.readFileSync(tomlPath, "utf-8"));
8257
+ const meta = parseToml(fs24.readFileSync(tomlPath, "utf-8"));
8061
8258
  const depsSection = meta.dependencies !== null && typeof meta.dependencies === "object" ? meta.dependencies : {};
8062
8259
  const collect = (v) => Array.isArray(v) ? v.filter((d) => typeof d === "string") : [];
8063
8260
  const deps = collect(depsSection.node);
@@ -8642,7 +8839,7 @@ bag deploy --provider aws
8642
8839
  `;
8643
8840
  }
8644
8841
  function emitProviderSkills(target, provider, ides) {
8645
- const skillDir = path22.join(
8842
+ const skillDir = path23.join(
8646
8843
  bundledRecipesRoot(),
8647
8844
  "providers",
8648
8845
  provider,
@@ -8652,34 +8849,34 @@ function emitProviderSkills(target, provider, ides) {
8652
8849
  return;
8653
8850
  }
8654
8851
  let emittedCursor = false;
8655
- for (const md of fs23.readdirSync(skillDir).filter((n) => n.endsWith(".md")).sort()) {
8656
- const srcText = fs23.readFileSync(path22.join(skillDir, md), "utf-8");
8852
+ for (const md of fs24.readdirSync(skillDir).filter((n) => n.endsWith(".md")).sort()) {
8853
+ const srcText = fs24.readFileSync(path23.join(skillDir, md), "utf-8");
8657
8854
  const stem2 = md.replace(/\.md$/, "");
8658
8855
  for (const ide of ides) {
8659
8856
  const [relPath, content] = renderSkillPayload(srcText, stem2, ide);
8660
- const base = ide === "claude-code" ? path22.join(target, ".claude", "skills") : path22.join(target, ".cursor", "rules");
8661
- const dst = path22.join(base, relPath);
8662
- fs23.mkdirSync(path22.dirname(dst), { recursive: true });
8663
- fs23.writeFileSync(dst, content);
8857
+ const base = ide === "claude-code" ? path23.join(target, ".claude", "skills") : path23.join(target, ".cursor", "rules");
8858
+ const dst = path23.join(base, relPath);
8859
+ fs24.mkdirSync(path23.dirname(dst), { recursive: true });
8860
+ fs24.writeFileSync(dst, content);
8664
8861
  if (ide === "cursor") {
8665
8862
  emittedCursor = true;
8666
8863
  }
8667
8864
  }
8668
8865
  }
8669
8866
  if (emittedCursor) {
8670
- ensureCursorGitignore(path22.join(target, ".gitignore"));
8867
+ ensureCursorGitignore(path23.join(target, ".gitignore"));
8671
8868
  }
8672
8869
  }
8673
8870
  function ensureCursorGitignore(gitignore) {
8674
- if (!isFile8(gitignore)) {
8871
+ if (!isFile9(gitignore)) {
8675
8872
  return;
8676
8873
  }
8677
- const text2 = fs23.readFileSync(gitignore, "utf-8");
8874
+ const text2 = fs24.readFileSync(gitignore, "utf-8");
8678
8875
  if (text2.includes(".cursor/rules/")) {
8679
8876
  return;
8680
8877
  }
8681
8878
  const addition = "\n# Cursor rules emitted at init (regeneratable via `bag skills install --target cursor`).\n.cursor/rules/\n";
8682
- fs23.writeFileSync(gitignore, `${text2.replace(/\n+$/, "")}
8879
+ fs24.writeFileSync(gitignore, `${text2.replace(/\n+$/, "")}
8683
8880
  ${addition}`);
8684
8881
  }
8685
8882
  async function resolveWalletKind(flagValue, isTty) {
@@ -8857,11 +9054,11 @@ async function promptPassword() {
8857
9054
  return first;
8858
9055
  }
8859
9056
  function readWalletAddress(studioToml) {
8860
- if (!isFile8(studioToml)) {
9057
+ if (!isFile9(studioToml)) {
8861
9058
  return null;
8862
9059
  }
8863
9060
  try {
8864
- const data = parseToml(fs23.readFileSync(studioToml, "utf-8"));
9061
+ const data = parseToml(fs24.readFileSync(studioToml, "utf-8"));
8865
9062
  const wallet = data.wallet;
8866
9063
  if (wallet !== null && typeof wallet === "object") {
8867
9064
  const addr = wallet.address;
@@ -8964,7 +9161,7 @@ async function runOnboarding(o) {
8964
9161
  if (password === null) {
8965
9162
  return false;
8966
9163
  }
8967
- const agentRoot2 = path22.join(o.workspaceRoot, APP_DIR, AGENT_PKG);
9164
+ const agentRoot2 = path23.join(o.workspaceRoot, APP_DIR, AGENT_PKG);
8968
9165
  const { envLocalPath: envLocalPath19 } = await import("@bnbagent/studio-runtime/config");
8969
9166
  setEnvVar(envLocalPath19(agentRoot2), "WALLET_PASSWORD", password);
8970
9167
  const savedCwd = process.cwd();
@@ -8992,7 +9189,7 @@ async function runOnboarding(o) {
8992
9189
  );
8993
9190
  return false;
8994
9191
  }
8995
- address = readWalletAddress(path22.join(agentRoot2, "studio.toml"));
9192
+ address = readWalletAddress(path23.join(agentRoot2, "studio.toml"));
8996
9193
  if (o.walletKind !== "altana" || o.provider !== "pieverse-llm") {
8997
9194
  await onboardProviderActivation(agentRoot2, o.provider, o.model);
8998
9195
  }
@@ -9011,7 +9208,7 @@ async function runOnboarding(o) {
9011
9208
  await printFaucetHint(o.network, address);
9012
9209
  if (o.walletKind === "altana") {
9013
9210
  printOut(
9014
- "Altana next step: fund about 0.6 tBNB for bootstrap/registration, then run `bag wallet session grant`."
9211
+ "Altana next step: fund about 0.05 tBNB for bootstrap/registration, then run `bag wallet session grant`."
9015
9212
  );
9016
9213
  }
9017
9214
  }
@@ -9021,9 +9218,9 @@ async function onboardProviderActivation(agentRoot2, provider, model) {
9021
9218
  if (provider === "pieverse-llm") {
9022
9219
  const chosenModel = model ?? await promptPieverseModel();
9023
9220
  if (model === void 0) {
9024
- const tomlPath = path22.join(agentRoot2, "studio.toml");
9025
- const text2 = fs23.readFileSync(tomlPath, "utf-8");
9026
- fs23.writeFileSync(
9221
+ const tomlPath = path23.join(agentRoot2, "studio.toml");
9222
+ const text2 = fs24.readFileSync(tomlPath, "utf-8");
9223
+ fs24.writeFileSync(
9027
9224
  tomlPath,
9028
9225
  updateSection(text2, "llm", { model: chosenModel })
9029
9226
  );
@@ -9059,8 +9256,8 @@ set ${keyEnv}= in .studio/.env.local before running \`bag dev\`.`
9059
9256
  }
9060
9257
  }
9061
9258
  async function runOnboardingTwak(o) {
9062
- const agentRoot2 = path22.join(o.workspaceRoot, APP_DIR, AGENT_PKG);
9063
- const studioToml = path22.join(agentRoot2, "studio.toml");
9259
+ const agentRoot2 = path23.join(o.workspaceRoot, APP_DIR, AGENT_PKG);
9260
+ const studioToml = path23.join(agentRoot2, "studio.toml");
9064
9261
  if (await whichTwak() === null) {
9065
9262
  printErr(
9066
9263
  `
@@ -9076,7 +9273,7 @@ you, so you never type the password on a command line, and adopts the address):
9076
9273
  }
9077
9274
  let walletCfg = {};
9078
9275
  try {
9079
- const data = parseToml(fs23.readFileSync(studioToml, "utf-8"));
9276
+ const data = parseToml(fs24.readFileSync(studioToml, "utf-8"));
9080
9277
  if (data.wallet !== null && typeof data.wallet === "object") {
9081
9278
  walletCfg = data.wallet;
9082
9279
  }
@@ -9085,16 +9282,16 @@ you, so you never type the password on a command line, and adopts the address):
9085
9282
  }
9086
9283
  const { twakWalletFile: twakWalletFile2 } = await import("./_twak-4XF4H5PL.js");
9087
9284
  let projectWallet = twakWalletFile2(walletCfg, agentRoot2);
9088
- const machineWallet = path22.join(os4.homedir(), ".twak", "wallet.json");
9089
- if (!o.twakHomePinned && isFile8(machineWallet) && realpathIfExists(projectWallet) !== realpathIfExists(machineWallet)) {
9285
+ const machineWallet = path23.join(os4.homedir(), ".twak", "wallet.json");
9286
+ if (!o.twakHomePinned && isFile9(machineWallet) && realpathIfExists(projectWallet) !== realpathIfExists(machineWallet)) {
9090
9287
  if (await promptUseMachineTwakWallet(machineWallet)) {
9091
9288
  projectWallet = adoptMachineTwakWallet(machineWallet, o.workspaceRoot);
9092
9289
  }
9093
9290
  }
9094
- if (!isFile8(projectWallet)) {
9095
- const homeDir = path22.dirname(path22.dirname(projectWallet));
9291
+ if (!isFile9(projectWallet)) {
9292
+ const homeDir = path23.dirname(path23.dirname(projectWallet));
9096
9293
  try {
9097
- fs23.mkdirSync(homeDir, { recursive: true });
9294
+ fs24.mkdirSync(homeDir, { recursive: true });
9098
9295
  } catch {
9099
9296
  }
9100
9297
  printErr(
@@ -9149,9 +9346,9 @@ Guide: the bnbagent-studio-using-twak-wallet.md reference (installed by \`bag sk
9149
9346
  }
9150
9347
  function realpathIfExists(p) {
9151
9348
  try {
9152
- return fs23.realpathSync(p);
9349
+ return fs24.realpathSync(p);
9153
9350
  } catch {
9154
- return path22.resolve(p);
9351
+ return path23.resolve(p);
9155
9352
  }
9156
9353
  }
9157
9354
  async function promptUseMachineTwakWallet(machineWallet) {
@@ -9164,39 +9361,39 @@ Found an existing twak wallet: ${machineWallet}`);
9164
9361
  return answer === "y" || answer === "yes";
9165
9362
  }
9166
9363
  function adoptMachineTwakWallet(machineWallet, workspaceRoot) {
9167
- const homeDir = path22.join(workspaceRoot, ".studio", "twak");
9168
- const twakDir = path22.join(homeDir, ".twak");
9169
- fs23.mkdirSync(twakDir, { recursive: true });
9364
+ const homeDir = path23.join(workspaceRoot, ".studio", "twak");
9365
+ const twakDir = path23.join(homeDir, ".twak");
9366
+ fs24.mkdirSync(twakDir, { recursive: true });
9170
9367
  try {
9171
- fs23.chmodSync(homeDir, 448);
9172
- fs23.chmodSync(twakDir, 448);
9368
+ fs24.chmodSync(homeDir, 448);
9369
+ fs24.chmodSync(twakDir, 448);
9173
9370
  } catch {
9174
9371
  }
9175
9372
  for (const name of ["wallet.json", "credentials.json"]) {
9176
- const src = path22.join(path22.dirname(machineWallet), name);
9177
- if (isFile8(src)) {
9178
- const dst = path22.join(twakDir, name);
9179
- fs23.writeFileSync(dst, fs23.readFileSync(src, "utf-8"), { mode: 384 });
9180
- fs23.chmodSync(dst, 384);
9373
+ const src = path23.join(path23.dirname(machineWallet), name);
9374
+ if (isFile9(src)) {
9375
+ const dst = path23.join(twakDir, name);
9376
+ fs24.writeFileSync(dst, fs24.readFileSync(src, "utf-8"), { mode: 384 });
9377
+ fs24.chmodSync(dst, 384);
9181
9378
  }
9182
9379
  }
9183
- return path22.join(twakDir, "wallet.json");
9380
+ return path23.join(twakDir, "wallet.json");
9184
9381
  }
9185
9382
  function normalizeTwakHome(raw) {
9186
- const expanded = raw.startsWith("~") ? path22.join(os4.homedir(), raw.slice(1)) : raw;
9187
- if (!path22.isAbsolute(expanded)) {
9383
+ const expanded = raw.startsWith("~") ? path23.join(os4.homedir(), raw.slice(1)) : raw;
9384
+ if (!path23.isAbsolute(expanded)) {
9188
9385
  return { home: raw };
9189
9386
  }
9190
- const isFile19 = (p) => {
9387
+ const isFile20 = (p) => {
9191
9388
  try {
9192
- return fs23.statSync(p).isFile();
9389
+ return fs24.statSync(p).isFile();
9193
9390
  } catch {
9194
9391
  return false;
9195
9392
  }
9196
9393
  };
9197
- if (path22.basename(expanded) === ".twak") {
9198
- const parent = path22.dirname(expanded);
9199
- if (isFile19(path22.join(expanded, "wallet.json"))) {
9394
+ if (path23.basename(expanded) === ".twak") {
9395
+ const parent = path23.dirname(expanded);
9396
+ if (isFile20(path23.join(expanded, "wallet.json"))) {
9200
9397
  return {
9201
9398
  home: parent,
9202
9399
  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).`
@@ -9206,15 +9403,15 @@ function normalizeTwakHome(raw) {
9206
9403
  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.`
9207
9404
  };
9208
9405
  }
9209
- if (isFile19(path22.join(expanded, "wallet.json")) && !isFile19(path22.join(expanded, ".twak", "wallet.json"))) {
9406
+ if (isFile20(path23.join(expanded, "wallet.json")) && !isFile20(path23.join(expanded, ".twak", "wallet.json"))) {
9210
9407
  return {
9211
- 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.`
9408
+ error: `error: --twak-home '${raw}' looks like a twak WALLET directory (it contains wallet.json directly). Pass its parent '${path23.dirname(expanded)}' instead \u2014 the runtime resolves <twak_home>/.twak/wallet.json.`
9212
9409
  };
9213
9410
  }
9214
- if (!isFile19(path22.join(expanded, ".twak", "wallet.json"))) {
9411
+ if (!isFile20(path23.join(expanded, ".twak", "wallet.json"))) {
9215
9412
  return {
9216
9413
  home: raw,
9217
- 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.`
9414
+ note: `note: no wallet found at ${path23.join(raw, ".twak", "wallet.json")} \u2014 treating --twak-home as a NEW project wallet home; \`bag wallet new\` will guide wallet creation.`
9218
9415
  };
9219
9416
  }
9220
9417
  return { home: raw };
@@ -9224,7 +9421,7 @@ function twakHomeIsMainHome(twakHome) {
9224
9421
  return false;
9225
9422
  }
9226
9423
  try {
9227
- const expanded = twakHome.startsWith("~") ? path22.join(os4.homedir(), twakHome.slice(1)) : twakHome;
9424
+ const expanded = twakHome.startsWith("~") ? path23.join(os4.homedir(), twakHome.slice(1)) : twakHome;
9228
9425
  return realpathIfExists(expanded) === realpathIfExists(os4.homedir());
9229
9426
  } catch {
9230
9427
  return false;
@@ -9315,8 +9512,10 @@ NOTE \u2014 wallet.kind = "altana" (bounded runtime session):
9315
9512
  .studio/wallets/. WALLET_PASSWORD is used only by wallet/session commands.
9316
9513
  \xB7 RUNTIME: fund the admin address, then run \`bag wallet session grant\`.
9317
9514
  The Agent receives only .studio/wallets/altana-session.json.
9318
- \xB7 DEPLOY: deployment is deferred in this release. \`bag deploy --provider <provider>\` is
9319
- rejected before packaging or external calls; local \`bag dev\` is supported.`
9515
+ \xB7 DEPLOY: \`bag deploy\` ships ONLY the bounded session (as the
9516
+ ALTANA_SESSION runtime secret) \u2014 the admin keystore and WALLET_PASSWORD
9517
+ never leave this machine. When the session expires, re-grant with
9518
+ \`bag wallet session grant --force\` and redeploy.`
9320
9519
  );
9321
9520
  }
9322
9521
  function printPlatformWalletSuggestion() {
@@ -9374,11 +9573,11 @@ function entrypointHint(faces) {
9374
9573
  return "app/agent/src/main.ts + executor.ts = A2A entrypoint (build your value here)";
9375
9574
  }
9376
9575
  function hasVendoredTarballs(agentDir) {
9377
- const vendor = path22.join(agentDir, "vendor");
9576
+ const vendor = path23.join(agentDir, "vendor");
9378
9577
  if (!isDir4(vendor)) {
9379
9578
  return false;
9380
9579
  }
9381
- return fs23.readdirSync(vendor).some((n) => n.endsWith(".tgz"));
9580
+ return fs24.readdirSync(vendor).some((n) => n.endsWith(".tgz"));
9382
9581
  }
9383
9582
  function printCompactNextSteps(name, o = {}) {
9384
9583
  const faces = o.faces ?? normalizeProtocolFaces(o.protocol ?? "A2A");
@@ -9406,7 +9605,7 @@ function printCompactNextSteps(name, o = {}) {
9406
9605
  }
9407
9606
  if (walletKind2 === "altana") {
9408
9607
  printOut(
9409
- " bag wallet session grant # after funding ~0.6 tBNB: create the bounded runtime session"
9608
+ " bag wallet session grant # after funding ~0.05 tBNB: create the bounded runtime session"
9410
9609
  );
9411
9610
  if (o.provider === "pieverse-llm") {
9412
9611
  printOut(
@@ -9530,7 +9729,7 @@ function printNextSteps(name, provider, o = {}) {
9530
9729
  printOut(" # bag auto-loads it; never pass it on argv");
9531
9730
  printOut(" (cd app/agent && bag wallet new)");
9532
9731
  printOut(
9533
- " # 2. fund the printed address with ~0.6 tBNB for bootstrap/registration + U, then grant one bounded runtime session"
9732
+ " # 2. fund the printed address with ~0.05 tBNB for bootstrap/registration + U, then grant one bounded runtime session"
9534
9733
  );
9535
9734
  printOut(" (cd app/agent && bag wallet session grant)");
9536
9735
  printOut(
@@ -9628,11 +9827,11 @@ function printNextSteps(name, provider, o = {}) {
9628
9827
  );
9629
9828
  }
9630
9829
  function loadTomlSafe(p) {
9631
- if (!isFile8(p)) {
9830
+ if (!isFile9(p)) {
9632
9831
  return {};
9633
9832
  }
9634
9833
  try {
9635
- return parseToml(fs23.readFileSync(p, "utf-8"));
9834
+ return parseToml(fs24.readFileSync(p, "utf-8"));
9636
9835
  } catch {
9637
9836
  return {};
9638
9837
  }
@@ -9652,7 +9851,7 @@ function weiToU(raw) {
9652
9851
  }
9653
9852
  }
9654
9853
  function printConfigSummary(agentRoot2) {
9655
- const agent = loadTomlSafe(path22.join(agentRoot2, "studio.toml"));
9854
+ const agent = loadTomlSafe(path23.join(agentRoot2, "studio.toml"));
9656
9855
  if (Object.keys(agent).length === 0) {
9657
9856
  return;
9658
9857
  }
@@ -9850,16 +10049,16 @@ function printConfigSummary(agentRoot2) {
9850
10049
  printOut("");
9851
10050
  }
9852
10051
  }
9853
- function isFile8(p) {
10052
+ function isFile9(p) {
9854
10053
  try {
9855
- return fs23.statSync(p).isFile();
10054
+ return fs24.statSync(p).isFile();
9856
10055
  } catch {
9857
10056
  return false;
9858
10057
  }
9859
10058
  }
9860
10059
  function isDir4(p) {
9861
10060
  try {
9862
- return fs23.statSync(p).isDirectory();
10061
+ return fs24.statSync(p).isDirectory();
9863
10062
  } catch {
9864
10063
  return false;
9865
10064
  }
@@ -9923,9 +10122,9 @@ var RUNTIME_AGENTCORE = "agentcore";
9923
10122
  var RUNTIME_AZURE_FOUNDRY = "azure-foundry";
9924
10123
  var MIN_NODE_MAJOR = 22;
9925
10124
  var CONTAINER_RUNTIMES = ["docker", "podman", "finch"];
9926
- function isFile9(p) {
10125
+ function isFile10(p) {
9927
10126
  try {
9928
- return fs24.statSync(p).isFile();
10127
+ return fs25.statSync(p).isFile();
9929
10128
  } catch {
9930
10129
  return false;
9931
10130
  }
@@ -9957,8 +10156,8 @@ async function nodeMajor() {
9957
10156
  return /^\d+$/.test(head) ? Number.parseInt(head, 10) : null;
9958
10157
  }
9959
10158
  function workspaceBase(root) {
9960
- for (const base of [path23.join(root, "app"), root]) {
9961
- if (isFile9(path23.join(base, "agent", "studio.toml"))) {
10159
+ for (const base of [path24.join(root, "app"), root]) {
10160
+ if (isFile10(path24.join(base, "agent", "studio.toml"))) {
9962
10161
  return base;
9963
10162
  }
9964
10163
  }
@@ -9966,7 +10165,7 @@ function workspaceBase(root) {
9966
10165
  }
9967
10166
  function resolveWorkspaceRoot(argRoot) {
9968
10167
  if (argRoot !== null) {
9969
- const root = path23.resolve(argRoot);
10168
+ const root = path24.resolve(argRoot);
9970
10169
  const base = workspaceBase(root);
9971
10170
  if (base === null) {
9972
10171
  printErr(
@@ -9976,13 +10175,13 @@ function resolveWorkspaceRoot(argRoot) {
9976
10175
  }
9977
10176
  return base;
9978
10177
  }
9979
- let current = path23.resolve(process.cwd());
10178
+ let current = path24.resolve(process.cwd());
9980
10179
  for (; ; ) {
9981
10180
  const base = workspaceBase(current);
9982
10181
  if (base !== null) {
9983
10182
  return base;
9984
10183
  }
9985
- const parent = path23.dirname(current);
10184
+ const parent = path24.dirname(current);
9986
10185
  if (parent === current) {
9987
10186
  break;
9988
10187
  }
@@ -9996,7 +10195,7 @@ function resolveWorkspaceRoot(argRoot) {
9996
10195
  function loadAgentToml2(workspaceRoot) {
9997
10196
  try {
9998
10197
  return loadStudioToml11(
9999
- path23.join(workspaceRoot, "agent", "studio.toml")
10198
+ path24.join(workspaceRoot, "agent", "studio.toml")
10000
10199
  );
10001
10200
  } catch {
10002
10201
  return {};
@@ -10023,7 +10222,7 @@ function defaultAgentPort(faces) {
10023
10222
  function storageKind(agentDir) {
10024
10223
  let data;
10025
10224
  try {
10026
- data = loadStudioToml11(path23.join(agentDir, "studio.toml"));
10225
+ data = loadStudioToml11(path24.join(agentDir, "studio.toml"));
10027
10226
  } catch {
10028
10227
  return "local";
10029
10228
  }
@@ -10033,7 +10232,7 @@ function storageKind(agentDir) {
10033
10232
  function networkNameOf(agentDir) {
10034
10233
  let data;
10035
10234
  try {
10036
- data = loadStudioToml11(path23.join(agentDir, "studio.toml"));
10235
+ data = loadStudioToml11(path24.join(agentDir, "studio.toml"));
10037
10236
  } catch {
10038
10237
  return "bsc-testnet";
10039
10238
  }
@@ -10043,7 +10242,7 @@ function networkNameOf(agentDir) {
10043
10242
  function walletKindOf(agentDir) {
10044
10243
  let data;
10045
10244
  try {
10046
- data = loadStudioToml11(path23.join(agentDir, "studio.toml"));
10245
+ data = loadStudioToml11(path24.join(agentDir, "studio.toml"));
10047
10246
  } catch {
10048
10247
  return "evm-local";
10049
10248
  }
@@ -10051,18 +10250,18 @@ function walletKindOf(agentDir) {
10051
10250
  return typeof kind === "string" && kind.trim() ? kind.trim() : "evm-local";
10052
10251
  }
10053
10252
  function altanaSessionForRuntime(agentDir) {
10054
- const cfg = loadStudioToml11(path23.join(agentDir, "studio.toml"));
10253
+ const cfg = loadStudioToml11(path24.join(agentDir, "studio.toml"));
10055
10254
  const wallet = tableOf9(cfg, "wallet");
10056
10255
  const configured = String(
10057
10256
  wallet.session_file ?? ".studio/wallets/altana-session.json"
10058
10257
  );
10059
- const sessionFile = path23.isAbsolute(configured) ? configured : path23.join(agentDir, configured);
10060
- if (!isFile9(sessionFile)) {
10258
+ const sessionFile = path24.isAbsolute(configured) ? configured : path24.join(agentDir, configured);
10259
+ if (!isFile10(sessionFile)) {
10061
10260
  throw new Error(
10062
10261
  `no Altana session at ${sessionFile} \u2014 run \`bag wallet session grant\` first.`
10063
10262
  );
10064
10263
  }
10065
- const serialized = fs24.readFileSync(sessionFile, "utf8");
10264
+ const serialized = fs25.readFileSync(sessionFile, "utf8");
10066
10265
  let envelope;
10067
10266
  try {
10068
10267
  envelope = JSON.parse(serialized);
@@ -10091,10 +10290,10 @@ function altanaSessionForRuntime(agentDir) {
10091
10290
  }
10092
10291
  var KEY_LINE_RE = /^\s*([A-Za-z_][A-Za-z0-9_]*)\s*=/;
10093
10292
  function loadEnvFileForDev(p) {
10094
- if (!isFile9(p)) {
10293
+ if (!isFile10(p)) {
10095
10294
  return;
10096
10295
  }
10097
- for (const line of fs24.readFileSync(p, "utf-8").split(/\r?\n/)) {
10296
+ for (const line of fs25.readFileSync(p, "utf-8").split(/\r?\n/)) {
10098
10297
  if (!line || line.trimStart().startsWith("#")) {
10099
10298
  continue;
10100
10299
  }
@@ -10115,20 +10314,20 @@ function ensureStoragePath(projectRoot) {
10115
10314
  const raw = process.env.STORAGE_LOCAL_PATH;
10116
10315
  let resolved;
10117
10316
  if (raw) {
10118
- resolved = path23.resolve(
10119
- raw.startsWith("~") ? path23.join(os5.homedir(), raw.slice(1)) : raw
10317
+ resolved = path24.resolve(
10318
+ raw.startsWith("~") ? path24.join(os5.homedir(), raw.slice(1)) : raw
10120
10319
  );
10121
10320
  } else {
10122
- resolved = path23.resolve(
10123
- path23.join(
10321
+ resolved = path24.resolve(
10322
+ path24.join(
10124
10323
  os5.homedir(),
10125
10324
  ".bag",
10126
10325
  "deliverables",
10127
- path23.basename(projectRoot)
10326
+ path24.basename(projectRoot)
10128
10327
  )
10129
10328
  );
10130
10329
  }
10131
- fs24.mkdirSync(resolved, { recursive: true });
10330
+ fs25.mkdirSync(resolved, { recursive: true });
10132
10331
  process.env.STORAGE_LOCAL_PATH = resolved;
10133
10332
  }
10134
10333
  function ipfsPreflight(agentDir) {
@@ -10143,7 +10342,7 @@ function ipfsPreflight(agentDir) {
10143
10342
  function runtimeEnvKeys(agentDir) {
10144
10343
  let cfg = {};
10145
10344
  try {
10146
- cfg = loadStudioToml11(path23.join(agentDir, "studio.toml"));
10345
+ cfg = loadStudioToml11(path24.join(agentDir, "studio.toml"));
10147
10346
  } catch {
10148
10347
  cfg = {};
10149
10348
  }
@@ -10160,7 +10359,7 @@ function readTwakFiles(agentDir) {
10160
10359
  let walletCfg = {};
10161
10360
  try {
10162
10361
  walletCfg = tableOf9(
10163
- loadStudioToml11(path23.join(agentDir, "studio.toml")),
10362
+ loadStudioToml11(path24.join(agentDir, "studio.toml")),
10164
10363
  "wallet"
10165
10364
  );
10166
10365
  } catch {
@@ -10168,9 +10367,9 @@ function readTwakFiles(agentDir) {
10168
10367
  }
10169
10368
  const twakDir = twakHomeDir(walletCfg, agentDir);
10170
10369
  const read = (name) => {
10171
- const p = path23.join(twakDir, name);
10370
+ const p = path24.join(twakDir, name);
10172
10371
  try {
10173
- return fs24.readFileSync(p, "utf-8");
10372
+ return fs25.readFileSync(p, "utf-8");
10174
10373
  } catch {
10175
10374
  return null;
10176
10375
  }
@@ -10178,19 +10377,19 @@ function readTwakFiles(agentDir) {
10178
10377
  return [read("wallet.json"), read("credentials.json")];
10179
10378
  }
10180
10379
  function ensureAgentcoreEnvGitignored(agentcoreDir) {
10181
- const gi = path23.join(agentcoreDir, ".gitignore");
10380
+ const gi = path24.join(agentcoreDir, ".gitignore");
10182
10381
  const entry = ".env.local";
10183
- if (isFile9(gi)) {
10184
- const text2 = fs24.readFileSync(gi, "utf-8");
10382
+ if (isFile10(gi)) {
10383
+ const text2 = fs25.readFileSync(gi, "utf-8");
10185
10384
  const lines = new Set(text2.split("\n").map((l) => l.trim()));
10186
10385
  if (lines.has(entry)) {
10187
10386
  return;
10188
10387
  }
10189
- const sep6 = text2.endsWith("\n") || text2 === "" ? "" : "\n";
10190
- fs24.writeFileSync(gi, `${text2}${sep6}${entry}
10388
+ const sep7 = text2.endsWith("\n") || text2 === "" ? "" : "\n";
10389
+ fs25.writeFileSync(gi, `${text2}${sep7}${entry}
10191
10390
  `);
10192
10391
  } else {
10193
- fs24.writeFileSync(gi, `${entry}
10392
+ fs25.writeFileSync(gi, `${entry}
10194
10393
  `);
10195
10394
  }
10196
10395
  }
@@ -10213,8 +10412,8 @@ function writeAgentcoreEnvLocal(agentcoreRoot, agentDir) {
10213
10412
  } else if (walletKindOf(agentDir) === "altana") {
10214
10413
  bundle.ALTANA_SESSION = altanaSessionForRuntime(agentDir);
10215
10414
  }
10216
- const envPath = path23.join(agentcoreRoot, "agentcore", ".env.local");
10217
- const prior = isFile9(envPath) ? fs24.readFileSync(envPath, "utf-8") : "";
10415
+ const envPath = path24.join(agentcoreRoot, "agentcore", ".env.local");
10416
+ const prior = isFile10(envPath) ? fs25.readFileSync(envPath, "utf-8") : "";
10218
10417
  const merged = {};
10219
10418
  for (const line of prior.split("\n")) {
10220
10419
  if (!line || line.trimStart().startsWith("#")) {
@@ -10229,14 +10428,14 @@ function writeAgentcoreEnvLocal(agentcoreRoot, agentDir) {
10229
10428
  Object.assign(merged, bundle);
10230
10429
  const content = Object.entries(merged).map(([k, v]) => `${k}=${v}
10231
10430
  `).join("");
10232
- fs24.mkdirSync(path23.dirname(envPath), { recursive: true });
10233
- ensureAgentcoreEnvGitignored(path23.dirname(envPath));
10431
+ fs25.mkdirSync(path24.dirname(envPath), { recursive: true });
10432
+ ensureAgentcoreEnvGitignored(path24.dirname(envPath));
10234
10433
  writePrivate2(envPath, content);
10235
10434
  return [envPath, content !== prior];
10236
10435
  }
10237
10436
  function agentcoreProjectRoot2(workspaceRoot) {
10238
- for (const candidate of [path23.dirname(workspaceRoot), workspaceRoot]) {
10239
- if (isFile9(path23.join(candidate, "agentcore", "agentcore.json"))) {
10437
+ for (const candidate of [path24.dirname(workspaceRoot), workspaceRoot]) {
10438
+ if (isFile10(path24.join(candidate, "agentcore", "agentcore.json"))) {
10240
10439
  return candidate;
10241
10440
  }
10242
10441
  }
@@ -10245,8 +10444,8 @@ function agentcoreProjectRoot2(workspaceRoot) {
10245
10444
  function loadAgentcoreConfig(projectRoot) {
10246
10445
  try {
10247
10446
  const cfg = JSON.parse(
10248
- fs24.readFileSync(
10249
- path23.join(projectRoot, "agentcore", "agentcore.json"),
10447
+ fs25.readFileSync(
10448
+ path24.join(projectRoot, "agentcore", "agentcore.json"),
10250
10449
  "utf-8"
10251
10450
  )
10252
10451
  );
@@ -10336,7 +10535,7 @@ async function cmdDev(opts) {
10336
10535
  if (workspaceRoot === null) {
10337
10536
  return 2;
10338
10537
  }
10339
- const agentDir = path23.join(workspaceRoot, "agent");
10538
+ const agentDir = path24.join(workspaceRoot, "agent");
10340
10539
  migrateEnvLocal(agentDir);
10341
10540
  migrateKeystoreOutOfCodelocation(agentDir);
10342
10541
  const { envLocalPath: envLocalPath19 } = await import("@bnbagent/studio-runtime/config");
@@ -10372,8 +10571,8 @@ async function cmdDev(opts) {
10372
10571
  const runtime = agentRuntime(workspaceRoot);
10373
10572
  const container = Boolean(opts.container);
10374
10573
  const entryFile = localEntryFile(faces);
10375
- const agentFile = path23.join(agentDir, entryFile);
10376
- if (!isFile9(agentFile)) {
10574
+ const agentFile = path24.join(agentDir, entryFile);
10575
+ if (!isFile10(agentFile)) {
10377
10576
  printErr(
10378
10577
  `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.`
10379
10578
  );
@@ -10451,7 +10650,7 @@ Switch to Node \u226522 so it wins on PATH, then reopen the shell and retry. Ver
10451
10650
  }
10452
10651
  let launch;
10453
10652
  if (runtime === RUNTIME_AGENTCORE && container) {
10454
- const root = path23.resolve(agentcoreRoot);
10653
+ const root = path24.resolve(agentcoreRoot);
10455
10654
  try {
10456
10655
  const vendored = await vendorLocalTarballs(agentDir);
10457
10656
  if (vendored.length > 0) {
@@ -10466,7 +10665,7 @@ Switch to Node \u226522 so it wins on PATH, then reopen the shell and retry. Ver
10466
10665
  }
10467
10666
  const [envPath, changed] = writeAgentcoreEnvLocal(root, agentDir);
10468
10667
  printOut(
10469
- `bag dev: wrote ${path23.relative(root, envPath)} (runtime secrets + materialized wallet for the container).`
10668
+ `bag dev: wrote ${path24.relative(root, envPath)} (runtime secrets + materialized wallet for the container).`
10470
10669
  );
10471
10670
  if (changed && process.env.BAG_DEV_ENV_WARNED !== "1") {
10472
10671
  printErr(
@@ -10543,7 +10742,7 @@ Switch to Node \u226522 so it wins on PATH, then reopen the shell and retry. Ver
10543
10742
  }
10544
10743
  if (hasX402Face(faces)) {
10545
10744
  const free = x402SellerIsFree(
10546
- loadStudioToml11(path23.join(agentDir, "studio.toml"))
10745
+ loadStudioToml11(path24.join(agentDir, "studio.toml"))
10547
10746
  );
10548
10747
  printOut(
10549
10748
  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)`
@@ -10554,9 +10753,9 @@ Switch to Node \u226522 so it wins on PATH, then reopen the shell and retry. Ver
10554
10753
  }
10555
10754
  function tsxRunner(agentDir, workspaceBaseDir) {
10556
10755
  const bin = process.platform === "win32" ? "tsx.cmd" : "tsx";
10557
- for (const dir of [agentDir, path23.dirname(workspaceBaseDir)]) {
10558
- const candidate = path23.join(dir, "node_modules", ".bin", bin);
10559
- if (isFile9(candidate)) {
10756
+ for (const dir of [agentDir, path24.dirname(workspaceBaseDir)]) {
10757
+ const candidate = path24.join(dir, "node_modules", ".bin", bin);
10758
+ if (isFile10(candidate)) {
10560
10759
  return candidate;
10561
10760
  }
10562
10761
  }
@@ -10565,7 +10764,7 @@ function tsxRunner(agentDir, workspaceBaseDir) {
10565
10764
  function networkBanner(agentDir) {
10566
10765
  let data;
10567
10766
  try {
10568
- data = loadStudioToml11(path23.join(agentDir, "studio.toml"));
10767
+ data = loadStudioToml11(path24.join(agentDir, "studio.toml"));
10569
10768
  } catch {
10570
10769
  return null;
10571
10770
  }
@@ -10582,34 +10781,34 @@ function networkBanner(agentDir) {
10582
10781
  }
10583
10782
 
10584
10783
  // src/cli/_deploy/checks/critical.ts
10585
- import * as fs25 from "fs";
10784
+ import * as fs26 from "fs";
10586
10785
  import { createRequire } from "module";
10587
- import * as path24 from "path";
10786
+ import * as path25 from "path";
10588
10787
  import { envLocalPath as envLocalPath11, loadStudioToml as loadStudioToml12 } from "@bnbagent/studio-runtime/config";
10589
10788
  import { pieverseKeyHash as pieverseKeyHash2 } from "@bnbagent/studio-runtime/llm";
10590
10789
  var AGENTCORE_DESCRIPTOR2 = "agentcore/agentcore.json";
10591
- function isFile10(p) {
10790
+ function isFile11(p) {
10592
10791
  try {
10593
- return fs25.statSync(p).isFile();
10792
+ return fs26.statSync(p).isFile();
10594
10793
  } catch {
10595
10794
  return false;
10596
10795
  }
10597
10796
  }
10598
10797
  function isDir5(p) {
10599
10798
  try {
10600
- return fs25.statSync(p).isDirectory();
10799
+ return fs26.statSync(p).isDirectory();
10601
10800
  } catch {
10602
10801
  return false;
10603
10802
  }
10604
10803
  }
10605
10804
  function keystoreDirOf(root, data) {
10606
10805
  const rel = String(tableOf2(data, "wallet").keystore_dir ?? ".studio/wallets");
10607
- const dir = path24.isAbsolute(rel) ? rel : path24.join(agentRootOf(root), rel);
10608
- return path24.resolve(dir);
10806
+ const dir = path25.isAbsolute(rel) ? rel : path25.join(agentRootOf(root), rel);
10807
+ return path25.resolve(dir);
10609
10808
  }
10610
10809
  function keystoreJsonFiles2(dir) {
10611
10810
  try {
10612
- return fs25.readdirSync(dir).filter((n) => n.endsWith(".json")).sort();
10811
+ return fs26.readdirSync(dir).filter((n) => n.endsWith(".json")).sort();
10613
10812
  } catch {
10614
10813
  return [];
10615
10814
  }
@@ -10617,7 +10816,7 @@ function keystoreJsonFiles2(dir) {
10617
10816
  function runtimeEnvKeys2(agentRoot2) {
10618
10817
  let cfg = {};
10619
10818
  try {
10620
- cfg = loadStudioToml12(path24.join(agentRoot2, "studio.toml"));
10819
+ cfg = loadStudioToml12(path25.join(agentRoot2, "studio.toml"));
10621
10820
  } catch {
10622
10821
  cfg = {};
10623
10822
  }
@@ -10629,8 +10828,8 @@ async function checkAgentcoreJsonPresent(root, target) {
10629
10828
  if (target !== "agentcore") {
10630
10829
  return [];
10631
10830
  }
10632
- const descriptor = path24.join(root, AGENTCORE_DESCRIPTOR2);
10633
- if (isFile10(descriptor)) {
10831
+ const descriptor = path25.join(root, AGENTCORE_DESCRIPTOR2);
10832
+ if (isFile11(descriptor)) {
10634
10833
  return [];
10635
10834
  }
10636
10835
  return [
@@ -10646,10 +10845,10 @@ async function checkAgentcoreAuthorizerKeyLegacy(root, target) {
10646
10845
  if (target !== "agentcore") {
10647
10846
  return [];
10648
10847
  }
10649
- const descriptor = path24.join(root, AGENTCORE_DESCRIPTOR2);
10848
+ const descriptor = path25.join(root, AGENTCORE_DESCRIPTOR2);
10650
10849
  let data;
10651
10850
  try {
10652
- data = JSON.parse(fs25.readFileSync(descriptor, "utf-8"));
10851
+ data = JSON.parse(fs26.readFileSync(descriptor, "utf-8"));
10653
10852
  } catch {
10654
10853
  return [];
10655
10854
  }
@@ -10689,10 +10888,10 @@ async function checkAgentPackagePresent(root, target) {
10689
10888
  sourceEntries.push("src/mcpMain.ts");
10690
10889
  }
10691
10890
  const missingSource = sourceEntries.find(
10692
- (entry) => !isFile10(path24.join(agentRoot2, entry))
10891
+ (entry) => !isFile11(path25.join(agentRoot2, entry))
10693
10892
  );
10694
10893
  if (missingSource !== void 0) {
10695
- const epPath = path24.join(agentRoot2, missingSource);
10894
+ const epPath = path25.join(agentRoot2, missingSource);
10696
10895
  return [
10697
10896
  {
10698
10897
  level: Level.CRITICAL,
@@ -10707,10 +10906,10 @@ async function checkAgentPackagePresent(root, target) {
10707
10906
  distEntries.push("dist/mcpMain.js");
10708
10907
  }
10709
10908
  const missingDist = distEntries.find(
10710
- (entry) => !isFile10(path24.join(agentRoot2, entry))
10909
+ (entry) => !isFile11(path25.join(agentRoot2, entry))
10711
10910
  );
10712
10911
  if (missingDist !== void 0) {
10713
- const distPath = path24.join(agentRoot2, missingDist);
10912
+ const distPath = path25.join(agentRoot2, missingDist);
10714
10913
  return [
10715
10914
  {
10716
10915
  level: Level.WARNING,
@@ -10735,8 +10934,8 @@ async function checkKeystoreNotInsideAgent(root, target) {
10735
10934
  if (!isDir5(keystoreDir) || keystoreJsonFiles2(keystoreDir).length === 0) {
10736
10935
  return [];
10737
10936
  }
10738
- const agentDir = path24.resolve(agentRootOf(root));
10739
- const inside2 = keystoreDir === agentDir || keystoreDir.startsWith(agentDir + path24.sep);
10937
+ const agentDir = path25.resolve(agentRootOf(root));
10938
+ const inside2 = keystoreDir === agentDir || keystoreDir.startsWith(agentDir + path25.sep);
10740
10939
  if (!inside2) {
10741
10940
  return [];
10742
10941
  }
@@ -10755,6 +10954,9 @@ async function checkLocalKeystoreExists(root, _target) {
10755
10954
  if (walletCfg.kind === "twak") {
10756
10955
  return [];
10757
10956
  }
10957
+ if (walletCfg.kind === "altana") {
10958
+ return [];
10959
+ }
10758
10960
  const signer = walletCfg.signer ?? "local";
10759
10961
  if (signer !== "local") {
10760
10962
  return [];
@@ -10773,7 +10975,11 @@ async function checkLocalKeystoreExists(root, _target) {
10773
10975
  ];
10774
10976
  }
10775
10977
  async function checkWalletPasswordEnvSet(root, _target) {
10776
- if (tableOf2(loadAgentToml(root), "wallet").kind === "twak") {
10978
+ const kind = tableOf2(loadAgentToml(root), "wallet").kind;
10979
+ if (kind === "twak") {
10980
+ return [];
10981
+ }
10982
+ if (kind === "altana") {
10777
10983
  return [];
10778
10984
  }
10779
10985
  if (process.env.WALLET_PASSWORD) {
@@ -10812,18 +11018,18 @@ async function checkLlmProviderKeySet(root, _target) {
10812
11018
  function gitignoreLines(p) {
10813
11019
  try {
10814
11020
  return new Set(
10815
- fs25.readFileSync(p, "utf-8").split(/\r?\n/).map((l) => l.trim())
11021
+ fs26.readFileSync(p, "utf-8").split(/\r?\n/).map((l) => l.trim())
10816
11022
  );
10817
11023
  } catch {
10818
11024
  return null;
10819
11025
  }
10820
11026
  }
10821
11027
  function agentcoreEnvLocalIgnored(ws) {
10822
- const wsLines = gitignoreLines(path24.join(ws, ".gitignore"));
11028
+ const wsLines = gitignoreLines(path25.join(ws, ".gitignore"));
10823
11029
  if (wsLines?.has("agentcore/.env.local")) {
10824
11030
  return true;
10825
11031
  }
10826
- const acLines = gitignoreLines(path24.join(ws, "agentcore", ".gitignore"));
11032
+ const acLines = gitignoreLines(path25.join(ws, "agentcore", ".gitignore"));
10827
11033
  return acLines?.has(".env.local") ?? false;
10828
11034
  }
10829
11035
  function studioIgnored(lines) {
@@ -10834,8 +11040,8 @@ function studioIgnored(lines) {
10834
11040
  }
10835
11041
  async function checkGitignoreExcludesSecrets(root, _target) {
10836
11042
  const out = [];
10837
- const ws = path24.dirname(path24.dirname(envLocalPath11(root)));
10838
- const gi = path24.join(ws, ".gitignore");
11043
+ const ws = path25.dirname(path25.dirname(envLocalPath11(root)));
11044
+ const gi = path25.join(ws, ".gitignore");
10839
11045
  const lines = gitignoreLines(gi);
10840
11046
  if (lines === null) {
10841
11047
  return [
@@ -10857,7 +11063,7 @@ async function checkGitignoreExcludesSecrets(root, _target) {
10857
11063
  details: { missing: [".studio/"] }
10858
11064
  });
10859
11065
  }
10860
- if (isDir5(path24.join(ws, "agentcore")) && !agentcoreEnvLocalIgnored(ws)) {
11066
+ if (isDir5(path25.join(ws, "agentcore")) && !agentcoreEnvLocalIgnored(ws)) {
10861
11067
  out.push({
10862
11068
  level: Level.CRITICAL,
10863
11069
  name: "gitignore_excludes_secrets",
@@ -10874,16 +11080,16 @@ function installedRuntimeVersion() {
10874
11080
  }
10875
11081
  try {
10876
11082
  const entry = require2.resolve("@bnbagent/studio-runtime");
10877
- let dir = path24.dirname(entry);
11083
+ let dir = path25.dirname(entry);
10878
11084
  for (let i = 0; i < 10; i++) {
10879
- const pkgPath = path24.join(dir, "package.json");
10880
- if (isFile10(pkgPath)) {
10881
- const pkg = JSON.parse(fs25.readFileSync(pkgPath, "utf-8"));
11085
+ const pkgPath = path25.join(dir, "package.json");
11086
+ if (isFile11(pkgPath)) {
11087
+ const pkg = JSON.parse(fs26.readFileSync(pkgPath, "utf-8"));
10882
11088
  if (pkg.name === "@bnbagent/studio-runtime") {
10883
11089
  return typeof pkg.version === "string" ? pkg.version : null;
10884
11090
  }
10885
11091
  }
10886
- const parent = path24.dirname(dir);
11092
+ const parent = path25.dirname(dir);
10887
11093
  if (parent === dir) {
10888
11094
  break;
10889
11095
  }
@@ -11167,9 +11373,9 @@ function x402SellerRailChecks(agentRoot2, cfg, target) {
11167
11373
  details: { destination, target, stackRuntime: stackRuntime2 }
11168
11374
  });
11169
11375
  }
11170
- const dockerfile = path24.join(agentRoot2, "Dockerfile");
11171
- if (rails.x402 && isFile10(dockerfile)) {
11172
- const source = fs25.readFileSync(dockerfile, "utf8");
11376
+ const dockerfile = path25.join(agentRoot2, "Dockerfile");
11377
+ if (rails.x402 && isFile11(dockerfile)) {
11378
+ const source = fs26.readFileSync(dockerfile, "utf8");
11173
11379
  if (!/^\s*FROM\s+node:22(?:[.-]|\s|$)/im.test(source)) {
11174
11380
  out.push({
11175
11381
  level: Level.WARNING,
@@ -11242,10 +11448,10 @@ async function checkDeployCliRunnable(_root, target) {
11242
11448
  ];
11243
11449
  }
11244
11450
  function agentcoreEnvVars(root) {
11245
- const descriptor = path24.join(root, AGENTCORE_DESCRIPTOR2);
11451
+ const descriptor = path25.join(root, AGENTCORE_DESCRIPTOR2);
11246
11452
  let data;
11247
11453
  try {
11248
- data = JSON.parse(fs25.readFileSync(descriptor, "utf-8"));
11454
+ data = JSON.parse(fs26.readFileSync(descriptor, "utf-8"));
11249
11455
  } catch {
11250
11456
  return [];
11251
11457
  }
@@ -11327,7 +11533,7 @@ async function checkRuntimeSecretsInjected(root, target) {
11327
11533
  }
11328
11534
  ];
11329
11535
  }
11330
- const lines = gitignoreLines(path24.join(root, ".gitignore"));
11536
+ const lines = gitignoreLines(path25.join(root, ".gitignore"));
11331
11537
  let tracked = true;
11332
11538
  if (lines !== null) {
11333
11539
  for (const p of ["agentcore/agentcore.json", "agentcore/", "/agentcore/"]) {
@@ -11352,7 +11558,7 @@ async function checkAwsTargetsPopulated(root, target) {
11352
11558
  if (target !== "agentcore") {
11353
11559
  return [];
11354
11560
  }
11355
- const p = path24.join(root, "agentcore", "aws-targets.json");
11561
+ const p = path25.join(root, "agentcore", "aws-targets.json");
11356
11562
  const [account, region] = readAwsTarget(root);
11357
11563
  if (account && region) {
11358
11564
  return [];
@@ -11366,6 +11572,84 @@ async function checkAwsTargetsPopulated(root, target) {
11366
11572
  }
11367
11573
  ];
11368
11574
  }
11575
+ var AGENTCORE_AGENT_QUOTA_CODE = "L-F4575653";
11576
+ function awsJson(stdout) {
11577
+ try {
11578
+ const parsed = JSON.parse(stdout);
11579
+ return parsed !== null && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
11580
+ } catch {
11581
+ return null;
11582
+ }
11583
+ }
11584
+ async function checkAgentcoreQuotaHeadroom(root, target) {
11585
+ if (target !== "agentcore") {
11586
+ return [];
11587
+ }
11588
+ const [, region] = readAwsTarget(root);
11589
+ if (!region || !await whichBin("aws")) {
11590
+ return [];
11591
+ }
11592
+ const quotaRes = await runCapture("aws", [
11593
+ "service-quotas",
11594
+ "get-service-quota",
11595
+ "--service-code",
11596
+ "bedrock-agentcore",
11597
+ "--quota-code",
11598
+ AGENTCORE_AGENT_QUOTA_CODE,
11599
+ "--region",
11600
+ region,
11601
+ "--output",
11602
+ "json"
11603
+ ]);
11604
+ if (quotaRes.code !== 0) {
11605
+ return [];
11606
+ }
11607
+ const quota = awsJson(quotaRes.stdout)?.Quota;
11608
+ const limit = typeof quota?.Value === "number" ? quota.Value : null;
11609
+ if (limit === null) {
11610
+ return [];
11611
+ }
11612
+ const listRes = await runCapture("aws", [
11613
+ "bedrock-agentcore-control",
11614
+ "list-agent-runtimes",
11615
+ "--region",
11616
+ region,
11617
+ "--output",
11618
+ "json"
11619
+ ]);
11620
+ if (listRes.code !== 0) {
11621
+ return [];
11622
+ }
11623
+ const runtimes = awsJson(listRes.stdout)?.agentRuntimes;
11624
+ if (!Array.isArray(runtimes)) {
11625
+ return [];
11626
+ }
11627
+ const used = runtimes.length;
11628
+ const details = {
11629
+ used,
11630
+ limit,
11631
+ region,
11632
+ quota_code: AGENTCORE_AGENT_QUOTA_CODE
11633
+ };
11634
+ if (used < limit) {
11635
+ return [
11636
+ {
11637
+ level: Level.INFO,
11638
+ name: "agentcore_quota_headroom",
11639
+ message: `AgentCore runtimes: ${used}/${limit} used in ${region}.`,
11640
+ details
11641
+ }
11642
+ ];
11643
+ }
11644
+ return [
11645
+ {
11646
+ level: Level.CRITICAL,
11647
+ name: "agentcore_quota_headroom",
11648
+ message: `AgentCore runtimes: ${used}/${limit} used in ${region} \u2014 no slots left, so the deploy would fail with \`maxAgents limit exceeded\` AFTER pushing the image and creating the secret, M2M client, and execution role (all orphans). Delete a runtime you no longer need (\`bag deploy destroy\` in its workspace) or request a quota increase for ${AGENTCORE_AGENT_QUOTA_CODE} ("Total Agents per Account") in the Service Quotas console.`,
11649
+ details
11650
+ }
11651
+ ];
11652
+ }
11369
11653
  var allChecks = [
11370
11654
  checkAgentcoreJsonPresent,
11371
11655
  checkAgentcoreAuthorizerKeyLegacy,
@@ -11383,6 +11667,10 @@ var allChecks = [
11383
11667
  checkTwakPasswordEnvSet,
11384
11668
  checkTwakCredentialsAvailable,
11385
11669
  checkTwakDockerAvailable,
11670
+ // altana-kind checks (every one early-returns for other kinds).
11671
+ checkAltanaSessionReady,
11672
+ checkAltanaSdkResolvable,
11673
+ checkAltanaSessionNotInsideAgent,
11386
11674
  checkLlmProviderKeySet,
11387
11675
  checkGitignoreExcludesSecrets,
11388
11676
  checkInstalledBnbagentStudioMatches,
@@ -11390,23 +11678,24 @@ var allChecks = [
11390
11678
  checkCommerceReady,
11391
11679
  checkDeployCliRunnable,
11392
11680
  checkRuntimeSecretsInjected,
11393
- checkAwsTargetsPopulated
11681
+ checkAwsTargetsPopulated,
11682
+ checkAgentcoreQuotaHeadroom
11394
11683
  ];
11395
11684
 
11396
11685
  // src/cli/_deploy/secrets.ts
11397
11686
  var KEYSTORE_JSON_ENV = "WALLET_KEYSTORE_JSON";
11398
11687
  var TWAK_WALLET_JSON_ENV = "TWAK_WALLET_JSON";
11399
11688
  var TWAK_CREDENTIALS_JSON_ENV = "TWAK_CREDENTIALS_JSON";
11400
- function isFile11(p) {
11689
+ function isFile12(p) {
11401
11690
  try {
11402
- return fs26.statSync(p).isFile();
11691
+ return fs27.statSync(p).isFile();
11403
11692
  } catch {
11404
11693
  return false;
11405
11694
  }
11406
11695
  }
11407
11696
  function loadTomlOr(agentRoot2) {
11408
11697
  try {
11409
- return loadStudioToml13(path25.join(agentRoot2, "studio.toml"));
11698
+ return loadStudioToml13(path26.join(agentRoot2, "studio.toml"));
11410
11699
  } catch {
11411
11700
  return {};
11412
11701
  }
@@ -11423,13 +11712,13 @@ function resolveKeystoreDir3(agentRoot2) {
11423
11712
  const rel = String(
11424
11713
  tableOf10(loadTomlOr(agentRoot2), "wallet").keystore_dir ?? ".studio/wallets"
11425
11714
  );
11426
- return path25.resolve(path25.isAbsolute(rel) ? rel : path25.join(agentRoot2, rel));
11715
+ return path26.resolve(path26.isAbsolute(rel) ? rel : path26.join(agentRoot2, rel));
11427
11716
  }
11428
11717
  function readKeystoreJson(agentRoot2) {
11429
11718
  const keystoreDir = resolveKeystoreDir3(agentRoot2);
11430
11719
  let names;
11431
11720
  try {
11432
- names = fs26.readdirSync(keystoreDir).filter((n) => n.endsWith(".json")).sort();
11721
+ names = fs27.readdirSync(keystoreDir).filter((n) => n.endsWith(".json")).sort();
11433
11722
  } catch {
11434
11723
  return null;
11435
11724
  }
@@ -11451,9 +11740,9 @@ function readKeystoreJson(agentRoot2) {
11451
11740
  );
11452
11741
  }
11453
11742
  }
11454
- const file = path25.join(keystoreDir, chosen ?? names[0]);
11743
+ const file = path26.join(keystoreDir, chosen ?? names[0]);
11455
11744
  try {
11456
- return fs26.readFileSync(file, "utf-8");
11745
+ return fs27.readFileSync(file, "utf-8");
11457
11746
  } catch {
11458
11747
  return null;
11459
11748
  }
@@ -11462,10 +11751,10 @@ function readEnvLocal(agentRoot2) {
11462
11751
  const values = {};
11463
11752
  try {
11464
11753
  const file = envLocalPath12(agentRoot2);
11465
- if (!isFile11(file)) {
11754
+ if (!isFile12(file)) {
11466
11755
  return values;
11467
11756
  }
11468
- for (const rawLine of fs26.readFileSync(file, "utf-8").split(/\r?\n/)) {
11757
+ for (const rawLine of fs27.readFileSync(file, "utf-8").split(/\r?\n/)) {
11469
11758
  const line = rawLine.trim();
11470
11759
  if (!line || line.startsWith("#")) {
11471
11760
  continue;
@@ -11487,11 +11776,6 @@ function readEnvLocal(agentRoot2) {
11487
11776
  }
11488
11777
  function collectRuntimeSecretsDetailed(root) {
11489
11778
  const agentRoot2 = findSubProjectRoot8("agent", root) ?? root;
11490
- if (deployWalletKind(agentRoot2) === "altana") {
11491
- throw new Error(
11492
- "Altana deployment is deferred: refusing to collect either the admin keystore or runtime session for a deploy target."
11493
- );
11494
- }
11495
11779
  const secretKeys = runtimeEnvKeys2(agentRoot2);
11496
11780
  const fileValues = readEnvLocal(agentRoot2);
11497
11781
  const payload = {};
@@ -11504,7 +11788,8 @@ function collectRuntimeSecretsDetailed(root) {
11504
11788
  sources[k] = fromFile ? ".studio/.env.local" : "process.env";
11505
11789
  }
11506
11790
  }
11507
- if (deployWalletKind(agentRoot2) === "twak") {
11791
+ const walletKind2 = deployWalletKind(agentRoot2);
11792
+ if (walletKind2 === "twak") {
11508
11793
  const [walletJson, credentialsJson] = readTwakFiles(agentRoot2);
11509
11794
  if (walletJson) {
11510
11795
  payload[TWAK_WALLET_JSON_ENV] = walletJson;
@@ -11514,6 +11799,9 @@ function collectRuntimeSecretsDetailed(root) {
11514
11799
  payload[TWAK_CREDENTIALS_JSON_ENV] = credentialsJson;
11515
11800
  sources[TWAK_CREDENTIALS_JSON_ENV] = "wallet-file";
11516
11801
  }
11802
+ } else if (walletKind2 === "altana") {
11803
+ payload[ALTANA_SESSION_ENV] = altanaSessionForRuntime(agentRoot2);
11804
+ sources[ALTANA_SESSION_ENV] = "wallet-file";
11517
11805
  } else {
11518
11806
  const keystoreJson = readKeystoreJson(agentRoot2);
11519
11807
  if (keystoreJson) {
@@ -11521,7 +11809,7 @@ function collectRuntimeSecretsDetailed(root) {
11521
11809
  sources[KEYSTORE_JSON_ENV] = "wallet-file";
11522
11810
  }
11523
11811
  }
11524
- if (!(KEYSTORE_JSON_ENV in payload) && !(TWAK_WALLET_JSON_ENV in payload)) {
11812
+ if (walletKind2 !== "altana" && !(KEYSTORE_JSON_ENV in payload) && !(TWAK_WALLET_JSON_ENV in payload)) {
11525
11813
  printErr(
11526
11814
  `WARNING: no wallet signing material found (${KEYSTORE_JSON_ENV} for evm-local / ${TWAK_WALLET_JSON_ENV} for twak). The deployed runtime won't be able to sign quotes or deliveries. Create/adopt a wallet first (e.g. \`bag wallet new\`) and redeploy.`
11527
11815
  );
@@ -11553,12 +11841,12 @@ var SCOPE_NAME = "invoke";
11553
11841
  var SCOPE = `${RESOURCE_SERVER_ID}/${SCOPE_NAME}`;
11554
11842
  var COGNITO_OUTPUTS_FILE = "agentcore/cognito/cdk-outputs.json";
11555
11843
  function emitNextSteps(result) {
11556
- return `\u2713 wrote Cognito CDK app to ${path26.dirname(result.appPath)}
11557
- - ${path26.basename(result.appPath)} (CognitoStack: user pool + resource server + M2M client)
11558
- - ${path26.basename(result.readmePath)} (deploy + wiring instructions)
11844
+ return `\u2713 wrote Cognito CDK app to ${path27.dirname(result.appPath)}
11845
+ - ${path27.basename(result.appPath)} (CognitoStack: user pool + resource server + M2M client)
11846
+ - ${path27.basename(result.readmePath)} (deploy + wiring instructions)
11559
11847
 
11560
11848
  Next steps:
11561
- 1. cd ${path26.dirname(result.appPath)}
11849
+ 1. cd ${path27.dirname(result.appPath)}
11562
11850
  2. npm install # aws-cdk-lib + constructs + the cdk CLI (local)
11563
11851
  3. npx cdk deploy --outputs-file cdk-outputs.json # YOU run this (the only AWS step)
11564
11852
  4. bag deploy provision-cognito --wire # studio reads cdk-outputs.json \u2192
@@ -11674,6 +11962,12 @@ function cognitoPackageJson() {
11674
11962
  function readme() {
11675
11963
  return `# Cognito M2M client for the AgentCore A2A inbound OAuth2 authorizer
11676
11964
 
11965
+ > **DEPRECATED.** \`bag deploy --provider aws\` now provisions its own user pool
11966
+ > and M2M client, and overwrites the values wired from this stack. Deploying
11967
+ > this app leaves a second, unused pool behind that you have to clean up
11968
+ > yourself. Keep it only if you need to own the pool out of band; otherwise run
11969
+ > \`bag deploy --provider aws\` and hand buyers the credentials it prints.
11970
+
11677
11971
  AgentCore A2A endpoints REQUIRE inbound auth (there is no anonymous mode). This
11678
11972
  seller uses **OAuth2 via Cognito** \u2014 NOT SigV4, because external buyers cannot
11679
11973
  obtain your AWS IAM credentials. Cognito has no public machine-to-machine
@@ -11714,12 +12008,11 @@ This reads the local \`cdk-outputs.json\` and patches:
11714
12008
  | \`Scope\` | \`agentcore.json\` \u2192 \`envVars[] OAUTH_SCOPE\` (+ \`.studio/.env.local\` for local dev) |
11715
12009
 
11716
12010
  \`OAUTH_TOKEN_URL\` / \`OAUTH_SCOPE\` are read by the emitted agent card from
11717
- the environment, so the published A2A agent card advertises the OAuth2 security
11718
- scheme buyers must use. They go into \`agentcore.json\` \`envVars[]\` (non-secret)
11719
- because \`.studio/.env.local\` lives outside the deploy CodeZip \u2014 so envVars[]
11720
- is the channel that actually reaches the runtime; the \`.env.local\` copy only
11721
- serves local \`bag dev\`. (\`bag deploy provision-cognito --wire <file>\` accepts a
11722
- custom outputs path.)
12011
+ the environment, so the agent card advertises the OAuth2 security scheme buyers
12012
+ must use. **A \`bag deploy\` run replaces both values (and the authorizer) with
12013
+ the pool it provisions itself**, so this wiring only takes effect for local
12014
+ \`bag dev\`. (\`bag deploy provision-cognito --wire <file>\` accepts a custom
12015
+ outputs path.)
11723
12016
 
11724
12017
  ## Issue buyer credentials
11725
12018
 
@@ -11749,28 +12042,29 @@ function emitCognitoCdk(workspaceRoot, opts = {}) {
11749
12042
  regionHint = null;
11750
12043
  }
11751
12044
  }
11752
- const outDir = path26.join(workspaceRoot, COGNITO_DIR);
11753
- fs27.mkdirSync(outDir, { recursive: true });
11754
- const appPath = path26.join(outDir, "app.ts");
11755
- const readmePath = path26.join(outDir, "README.md");
11756
- fs27.writeFileSync(appPath, appTs(regionHint), "utf-8");
11757
- fs27.writeFileSync(path26.join(outDir, "cdk.json"), cdkJson(), "utf-8");
11758
- fs27.writeFileSync(
11759
- path26.join(outDir, "package.json"),
12045
+ const outDir = path27.join(workspaceRoot, COGNITO_DIR);
12046
+ fs28.mkdirSync(outDir, { recursive: true });
12047
+ const appPath = path27.join(outDir, "app.ts");
12048
+ const readmePath = path27.join(outDir, "README.md");
12049
+ fs28.writeFileSync(appPath, appTs(regionHint), "utf-8");
12050
+ fs28.writeFileSync(path27.join(outDir, "cdk.json"), cdkJson(), "utf-8");
12051
+ fs28.writeFileSync(
12052
+ path27.join(outDir, "package.json"),
11760
12053
  cognitoPackageJson(),
11761
12054
  "utf-8"
11762
12055
  );
11763
- fs27.writeFileSync(readmePath, readme(), "utf-8");
12056
+ fs28.writeFileSync(readmePath, readme(), "utf-8");
11764
12057
  return { appPath, readmePath };
11765
12058
  }
11766
12059
  function wireSummary(r) {
11767
12060
  return `\u2713 wired Cognito authorizer from the CDK outputs (no AWS call \u2014 read a local file):
11768
- - ${path26.basename(r.agentcoreJson)}: authorizerConfiguration.customJwtAuthorizer
12061
+ - ${path27.basename(r.agentcoreJson)}: authorizerConfiguration.customJwtAuthorizer
11769
12062
  discoveryUrl = ${r.discoveryUrl}
11770
12063
  allowedClients = [${r.clientId}]
11771
- - ${path26.basename(r.agentcoreJson)}: envVars[] OAUTH_TOKEN_URL + OAUTH_SCOPE (reach the runtime so the agent card advertises oauth2)
12064
+ - ${path27.basename(r.agentcoreJson)}: envVars[] OAUTH_TOKEN_URL + OAUTH_SCOPE (reach the runtime so the agent card advertises oauth2)
11772
12065
  - ${r.envLocal}: same pair, for local \`bag dev\`
11773
- \u2192 \`bag deploy prepare\` W9 will now pass; deploy when ready.`;
12066
+ \u2192 NOTE: a \`bag deploy\` run provisions its own pool and overwrites these
12067
+ values with the ones it issued. This wiring only feeds local \`bag dev\`.`;
11774
12068
  }
11775
12069
  function flattenCdkOutputs(raw) {
11776
12070
  const flat = {};
@@ -11798,11 +12092,54 @@ function upsertDescriptorEnvvars(cfg, values) {
11798
12092
  }
11799
12093
  }
11800
12094
  }
12095
+ function syncDescriptorOauthFacts(workspaceRoot, facts) {
12096
+ const acj = path27.join(workspaceRoot, "agentcore", "agentcore.json");
12097
+ let cfg;
12098
+ try {
12099
+ cfg = JSON.parse(fs28.readFileSync(acj, "utf-8"));
12100
+ } catch {
12101
+ return;
12102
+ }
12103
+ const envValues = {};
12104
+ if (facts.tokenUrl) {
12105
+ envValues.OAUTH_TOKEN_URL = facts.tokenUrl;
12106
+ }
12107
+ if (facts.scope) {
12108
+ envValues.OAUTH_SCOPE = facts.scope;
12109
+ }
12110
+ const authorizer = facts.discoveryUrl && facts.clientId ? {
12111
+ customJwtAuthorizer: {
12112
+ discoveryUrl: facts.discoveryUrl,
12113
+ allowedClients: [facts.clientId]
12114
+ }
12115
+ } : null;
12116
+ if (Object.keys(envValues).length === 0 && authorizer === null) {
12117
+ return;
12118
+ }
12119
+ if (Object.keys(envValues).length > 0) {
12120
+ upsertDescriptorEnvvars(cfg, envValues);
12121
+ }
12122
+ if (authorizer !== null && Array.isArray(cfg.runtimes)) {
12123
+ for (const rt of cfg.runtimes) {
12124
+ if (rt !== null && typeof rt === "object") {
12125
+ const r = rt;
12126
+ r.authorizerType = "CUSTOM_JWT";
12127
+ r.authorizerConfiguration = authorizer;
12128
+ }
12129
+ }
12130
+ }
12131
+ try {
12132
+ fs28.writeFileSync(acj, `${JSON.stringify(cfg, null, 2)}
12133
+ `, "utf-8");
12134
+ } catch {
12135
+ return;
12136
+ }
12137
+ }
11801
12138
  function upsertEnv(envLocal, values) {
11802
12139
  let lines = [];
11803
12140
  try {
11804
- if (fs27.statSync(envLocal).isFile()) {
11805
- lines = fs27.readFileSync(envLocal, "utf-8").split(/\r?\n/);
12141
+ if (fs28.statSync(envLocal).isFile()) {
12142
+ lines = fs28.readFileSync(envLocal, "utf-8").split(/\r?\n/);
11806
12143
  if (lines.length > 0 && lines[lines.length - 1] === "") {
11807
12144
  lines.pop();
11808
12145
  }
@@ -11821,19 +12158,19 @@ function upsertEnv(envLocal, values) {
11821
12158
  lines.push(repl);
11822
12159
  }
11823
12160
  }
11824
- fs27.mkdirSync(path26.dirname(envLocal), { recursive: true });
11825
- fs27.writeFileSync(envLocal, `${lines.join("\n")}
12161
+ fs28.mkdirSync(path27.dirname(envLocal), { recursive: true });
12162
+ fs28.writeFileSync(envLocal, `${lines.join("\n")}
11826
12163
  `, {
11827
12164
  encoding: "utf-8",
11828
12165
  mode: 384
11829
12166
  });
11830
- fs27.chmodSync(envLocal, 384);
12167
+ fs28.chmodSync(envLocal, 384);
11831
12168
  }
11832
12169
  function wireCognitoOutputs(workspaceRoot, outputsFile = null) {
11833
- const outPath = outputsFile ?? path26.join(workspaceRoot, COGNITO_OUTPUTS_FILE);
12170
+ const outPath = outputsFile ?? path27.join(workspaceRoot, COGNITO_OUTPUTS_FILE);
11834
12171
  let exists = false;
11835
12172
  try {
11836
- exists = fs27.statSync(outPath).isFile();
12173
+ exists = fs28.statSync(outPath).isFile();
11837
12174
  } catch {
11838
12175
  exists = false;
11839
12176
  }
@@ -11843,7 +12180,7 @@ function wireCognitoOutputs(workspaceRoot, outputsFile = null) {
11843
12180
  );
11844
12181
  }
11845
12182
  const outs = flattenCdkOutputs(
11846
- JSON.parse(fs27.readFileSync(outPath, "utf-8"))
12183
+ JSON.parse(fs28.readFileSync(outPath, "utf-8"))
11847
12184
  );
11848
12185
  for (const key of ["DiscoveryUrl", "AppClientId", "TokenUrl", "Scope"]) {
11849
12186
  if (outs[key] === void 0) {
@@ -11856,8 +12193,8 @@ function wireCognitoOutputs(workspaceRoot, outputsFile = null) {
11856
12193
  const clientId = String(outs.AppClientId);
11857
12194
  const tokenUrl = String(outs.TokenUrl);
11858
12195
  const scope = String(outs.Scope);
11859
- const acj = path26.join(workspaceRoot, "agentcore", "agentcore.json");
11860
- const cfg = JSON.parse(fs27.readFileSync(acj, "utf-8"));
12196
+ const acj = path27.join(workspaceRoot, "agentcore", "agentcore.json");
12197
+ const cfg = JSON.parse(fs28.readFileSync(acj, "utf-8"));
11861
12198
  const runtimes = cfg.runtimes;
11862
12199
  if (!Array.isArray(runtimes) || runtimes.length === 0) {
11863
12200
  throw new Error(
@@ -11880,7 +12217,7 @@ function wireCognitoOutputs(workspaceRoot, outputsFile = null) {
11880
12217
  OAUTH_TOKEN_URL: tokenUrl,
11881
12218
  OAUTH_SCOPE: scope
11882
12219
  });
11883
- fs27.writeFileSync(acj, `${JSON.stringify(cfg, null, 2)}
12220
+ fs28.writeFileSync(acj, `${JSON.stringify(cfg, null, 2)}
11884
12221
  `, "utf-8");
11885
12222
  const envLocal = envLocalPath13(workspaceRoot);
11886
12223
  upsertEnv(envLocal, { OAUTH_TOKEN_URL: tokenUrl, OAUTH_SCOPE: scope });
@@ -11895,13 +12232,13 @@ function wireCognitoOutputs(workspaceRoot, outputsFile = null) {
11895
12232
  }
11896
12233
 
11897
12234
  // src/cli/_deploy/destroy.ts
11898
- import * as fs29 from "fs";
11899
- import * as path28 from "path";
12235
+ import * as fs30 from "fs";
12236
+ import * as path29 from "path";
11900
12237
  import { findSubProjectRoot as findSubProjectRoot10 } from "@bnbagent/studio-runtime/config";
11901
12238
 
11902
12239
  // src/cli/_deploy/status.ts
11903
- import * as fs28 from "fs";
11904
- import * as path27 from "path";
12240
+ import * as fs29 from "fs";
12241
+ import * as path28 from "path";
11905
12242
  import {
11906
12243
  APP_DIR as APP_DIR2,
11907
12244
  findSubProjectRoot as findSubProjectRoot9,
@@ -11916,20 +12253,20 @@ function loadToml(p) {
11916
12253
  }
11917
12254
  }
11918
12255
  function projectName(workspaceRoot) {
11919
- const descriptor = path27.join(workspaceRoot, "agentcore", "agentcore.json");
12256
+ const descriptor = path28.join(workspaceRoot, "agentcore", "agentcore.json");
11920
12257
  try {
11921
- const data = JSON.parse(fs28.readFileSync(descriptor, "utf-8"));
12258
+ const data = JSON.parse(fs29.readFileSync(descriptor, "utf-8"));
11922
12259
  if (data !== null && typeof data === "object" && data.name) {
11923
12260
  return String(data.name);
11924
12261
  }
11925
12262
  } catch {
11926
12263
  }
11927
- return path27.basename(workspaceRoot);
12264
+ return path28.basename(workspaceRoot);
11928
12265
  }
11929
12266
  async function runStatus(opts = {}) {
11930
- const start = opts.projectRoot ? path27.resolve(opts.projectRoot) : void 0;
12267
+ const start = opts.projectRoot ? path28.resolve(opts.projectRoot) : void 0;
11931
12268
  const agentRoot2 = findSubProjectRoot9("agent", start);
11932
- const agentData = agentRoot2 !== null ? loadToml(path27.join(agentRoot2, "studio.toml")) : {};
12269
+ const agentData = agentRoot2 !== null ? loadToml(path28.join(agentRoot2, "studio.toml")) : {};
11933
12270
  const deployRaw = agentData.deploy;
11934
12271
  const deploy = deployRaw !== null && typeof deployRaw === "object" && !Array.isArray(deployRaw) ? { ...deployRaw } : {};
11935
12272
  const runtimeArn = deploy.runtime_arn ? String(deploy.runtime_arn) : null;
@@ -11942,8 +12279,8 @@ async function runStatus(opts = {}) {
11942
12279
  }
11943
12280
  const onchainEndpoint = identity.endpoint ? String(identity.endpoint) : null;
11944
12281
  const agentReachable = null;
11945
- const workspaceBase2 = findWorkspaceRoot5(start) ?? (agentRoot2 !== null ? path27.dirname(agentRoot2) : null);
11946
- const workspaceRoot = workspaceBase2 !== null && path27.basename(workspaceBase2) === APP_DIR2 ? path27.dirname(workspaceBase2) : workspaceBase2;
12282
+ const workspaceBase2 = findWorkspaceRoot5(start) ?? (agentRoot2 !== null ? path28.dirname(agentRoot2) : null);
12283
+ const workspaceRoot = workspaceBase2 !== null && path28.basename(workspaceBase2) === APP_DIR2 ? path28.dirname(workspaceBase2) : workspaceBase2;
11947
12284
  let region = null;
11948
12285
  let account = null;
11949
12286
  let secretId = null;
@@ -12011,9 +12348,9 @@ function nullRecordedState(workspaceRoot) {
12011
12348
  if (agentRoot2 === null) {
12012
12349
  return;
12013
12350
  }
12014
- const ap = path28.join(agentRoot2, "studio.toml");
12351
+ const ap = path29.join(agentRoot2, "studio.toml");
12015
12352
  try {
12016
- if (!fs29.statSync(ap).isFile()) {
12353
+ if (!fs30.statSync(ap).isFile()) {
12017
12354
  return;
12018
12355
  }
12019
12356
  } catch {
@@ -12077,8 +12414,8 @@ async function runDestroy(opts) {
12077
12414
  }
12078
12415
 
12079
12416
  // src/cli/_deploy/packaging.ts
12080
- import * as fs30 from "fs";
12081
- import * as path29 from "path";
12417
+ import * as fs31 from "fs";
12418
+ import * as path30 from "path";
12082
12419
  import {
12083
12420
  findSubProjectRoot as findSubProjectRoot11,
12084
12421
  loadStudioToml as loadStudioToml15
@@ -12087,9 +12424,9 @@ function agentRootOf2(root) {
12087
12424
  return findSubProjectRoot11("agent", root);
12088
12425
  }
12089
12426
  function agentTable(agentRoot2, key) {
12090
- const tomlPath = path29.join(agentRoot2, "studio.toml");
12427
+ const tomlPath = path30.join(agentRoot2, "studio.toml");
12091
12428
  try {
12092
- if (!fs30.statSync(tomlPath).isFile()) {
12429
+ if (!fs31.statSync(tomlPath).isFile()) {
12093
12430
  return {};
12094
12431
  }
12095
12432
  } catch {
@@ -12156,10 +12493,10 @@ function checkPackagingDrift(root, destination, walletKind2, force) {
12156
12493
  );
12157
12494
  return 1;
12158
12495
  }
12159
- const dockerfile = path29.join(agentRoot2, "Dockerfile");
12496
+ const dockerfile = path30.join(agentRoot2, "Dockerfile");
12160
12497
  let dockerfilePresent = false;
12161
12498
  try {
12162
- dockerfilePresent = fs30.statSync(dockerfile).isFile();
12499
+ dockerfilePresent = fs31.statSync(dockerfile).isFile();
12163
12500
  } catch {
12164
12501
  dockerfilePresent = false;
12165
12502
  }
@@ -12200,7 +12537,7 @@ function deployWalletKindSafe(root) {
12200
12537
  }
12201
12538
  let cfg;
12202
12539
  try {
12203
- cfg = loadStudioToml15(path29.join(agentRoot2, "studio.toml"));
12540
+ cfg = loadStudioToml15(path30.join(agentRoot2, "studio.toml"));
12204
12541
  } catch {
12205
12542
  return "evm-local";
12206
12543
  }
@@ -12213,22 +12550,22 @@ function deployWalletKindSafe(root) {
12213
12550
  import { findStudioWorkspaceRoot as findStudioWorkspaceRoot2 } from "@bnbagent/studio-runtime/config";
12214
12551
 
12215
12552
  // src/cli/_deploy/checks/blocked.ts
12216
- import * as fs31 from "fs";
12217
- import * as path30 from "path";
12553
+ import * as fs32 from "fs";
12554
+ import * as path31 from "path";
12218
12555
  import {
12219
12556
  findSubProjectRoot as findSubProjectRoot12,
12220
12557
  loadStudioToml as loadStudioToml16
12221
12558
  } from "@bnbagent/studio-runtime/config";
12222
- function isFile12(p) {
12559
+ function isFile13(p) {
12223
12560
  try {
12224
- return fs31.statSync(p).isFile();
12561
+ return fs32.statSync(p).isFile();
12225
12562
  } catch {
12226
12563
  return false;
12227
12564
  }
12228
12565
  }
12229
12566
  function isDir6(p) {
12230
12567
  try {
12231
- return fs31.statSync(p).isDirectory();
12568
+ return fs32.statSync(p).isDirectory();
12232
12569
  } catch {
12233
12570
  return false;
12234
12571
  }
@@ -12239,8 +12576,8 @@ async function checkStudioTomlPresent(root, _target) {
12239
12576
  agent: findSubProjectRoot12("agent", root)
12240
12577
  };
12241
12578
  for (const [side, subRoot] of Object.entries(layers)) {
12242
- const tomlPath = subRoot === null ? null : path30.join(subRoot, "studio.toml");
12243
- if (tomlPath === null || !isFile12(tomlPath)) {
12579
+ const tomlPath = subRoot === null ? null : path31.join(subRoot, "studio.toml");
12580
+ if (tomlPath === null || !isFile13(tomlPath)) {
12244
12581
  out.push({
12245
12582
  level: Level.BLOCKED,
12246
12583
  name: "studio_toml_present",
@@ -12264,8 +12601,8 @@ async function checkStudioTomlPresent(root, _target) {
12264
12601
  return out;
12265
12602
  }
12266
12603
  async function checkCwdIsProjectRoot(root, _target) {
12267
- const cwd = path30.resolve(process.cwd());
12268
- const rr = path30.resolve(root);
12604
+ const cwd = path31.resolve(process.cwd());
12605
+ const rr = path31.resolve(root);
12269
12606
  if (cwd !== rr) {
12270
12607
  return [
12271
12608
  {
@@ -12279,7 +12616,7 @@ async function checkCwdIsProjectRoot(root, _target) {
12279
12616
  return [];
12280
12617
  }
12281
12618
  async function checkNoSecretInGitHistory(root, _target) {
12282
- if (!isDir6(path30.join(root, ".git"))) {
12619
+ if (!isDir6(path31.join(root, ".git"))) {
12283
12620
  return [];
12284
12621
  }
12285
12622
  const needles = [".env.local", "WALLET_PASSWORD"];
@@ -12317,8 +12654,8 @@ var allChecks2 = [
12317
12654
  ];
12318
12655
 
12319
12656
  // src/cli/_deploy/checks/info.ts
12320
- import * as fs32 from "fs";
12321
- import * as path31 from "path";
12657
+ import * as fs33 from "fs";
12658
+ import * as path32 from "path";
12322
12659
  async function checkPreviousDeployStatus(root, _target) {
12323
12660
  const deploy = tableOf2(loadAgentToml(root), "deploy");
12324
12661
  const last = deploy.last_deploy_at;
@@ -12342,10 +12679,10 @@ async function checkPreviousDeployStatus(root, _target) {
12342
12679
  ];
12343
12680
  }
12344
12681
  async function checkInstalledRecipesList(root, _target) {
12345
- const manifest = path31.join(root, ".studio", "recipes", "manifest.json");
12682
+ const manifest = path32.join(root, ".studio", "recipes", "manifest.json");
12346
12683
  let exists = false;
12347
12684
  try {
12348
- exists = fs32.statSync(manifest).isFile();
12685
+ exists = fs33.statSync(manifest).isFile();
12349
12686
  } catch {
12350
12687
  exists = false;
12351
12688
  }
@@ -12361,7 +12698,7 @@ async function checkInstalledRecipesList(root, _target) {
12361
12698
  }
12362
12699
  let data;
12363
12700
  try {
12364
- data = JSON.parse(fs32.readFileSync(manifest, "utf-8"));
12701
+ data = JSON.parse(fs33.readFileSync(manifest, "utf-8"));
12365
12702
  } catch {
12366
12703
  return [
12367
12704
  {
@@ -12464,8 +12801,8 @@ var allChecks3 = [
12464
12801
  ];
12465
12802
 
12466
12803
  // src/cli/_deploy/checks/platform.ts
12467
- import * as fs34 from "fs";
12468
- import * as path33 from "path";
12804
+ import * as fs35 from "fs";
12805
+ import * as path34 from "path";
12469
12806
  import {
12470
12807
  findSubProjectRoot as findSubProjectRoot13,
12471
12808
  loadStudioToml as loadStudioToml17
@@ -12474,16 +12811,16 @@ import { BSC_TESTNET_FAUCET_URLS } from "@bnbagent/studio-runtime/networks";
12474
12811
 
12475
12812
  // src/cli/_deploy/checks/warning.ts
12476
12813
  import * as crypto4 from "crypto";
12477
- import * as fs33 from "fs";
12478
- import * as path32 from "path";
12814
+ import * as fs34 from "fs";
12815
+ import * as path33 from "path";
12479
12816
  import { envLocalPath as envLocalPath14 } from "@bnbagent/studio-runtime/config";
12480
12817
  import { show } from "@bnbagent/studio-runtime/erc8004";
12481
12818
  import { DEFAULT_RPC, getNetwork as getNetwork8 } from "@bnbagent/studio-runtime/networks";
12482
12819
  import * as walletRt3 from "@bnbagent/studio-runtime/wallet";
12483
12820
  var TBNB_MIN_WEI = 7n * 10n ** 15n;
12484
- function isFile13(p) {
12821
+ function isFile14(p) {
12485
12822
  try {
12486
- return fs33.statSync(p).isFile();
12823
+ return fs34.statSync(p).isFile();
12487
12824
  } catch {
12488
12825
  return false;
12489
12826
  }
@@ -12686,10 +13023,10 @@ async function checkRuntimeRpcReachable(root, _target) {
12686
13023
  return [];
12687
13024
  }
12688
13025
  async function checkInstalledRecipesUnchanged(root, _target) {
12689
- const manifest = path32.join(root, ".studio", "recipes", "manifest.json");
13026
+ const manifest = path33.join(root, ".studio", "recipes", "manifest.json");
12690
13027
  let data;
12691
13028
  try {
12692
- data = JSON.parse(fs33.readFileSync(manifest, "utf-8"));
13029
+ data = JSON.parse(fs34.readFileSync(manifest, "utf-8"));
12693
13030
  } catch {
12694
13031
  return [];
12695
13032
  }
@@ -12704,11 +13041,11 @@ async function checkInstalledRecipesUnchanged(root, _target) {
12704
13041
  if (!rel || !expected || typeof rel !== "string") {
12705
13042
  continue;
12706
13043
  }
12707
- const p = path32.join(root, rel);
12708
- if (!isFile13(p)) {
13044
+ const p = path33.join(root, rel);
13045
+ if (!isFile14(p)) {
12709
13046
  continue;
12710
13047
  }
12711
- const actual = crypto4.createHash("sha256").update(fs33.readFileSync(p)).digest("hex");
13048
+ const actual = crypto4.createHash("sha256").update(fs34.readFileSync(p)).digest("hex");
12712
13049
  if (actual !== expected) {
12713
13050
  stale.push(rel);
12714
13051
  }
@@ -12725,59 +13062,6 @@ async function checkInstalledRecipesUnchanged(root, _target) {
12725
13062
  }
12726
13063
  return [];
12727
13064
  }
12728
- function agentcoreAuthorizer(root) {
12729
- const descriptor = path32.join(root, "agentcore", "agentcore.json");
12730
- let data;
12731
- try {
12732
- data = JSON.parse(fs33.readFileSync(descriptor, "utf-8"));
12733
- } catch {
12734
- return null;
12735
- }
12736
- if (data === null || typeof data !== "object" || Array.isArray(data)) {
12737
- return null;
12738
- }
12739
- const runtimes = data.runtimes;
12740
- if (!Array.isArray(runtimes)) {
12741
- return null;
12742
- }
12743
- for (const rt of runtimes) {
12744
- if (rt === null || typeof rt !== "object") {
12745
- continue;
12746
- }
12747
- const auth = rt.authorizerConfiguration;
12748
- if (auth !== null && typeof auth === "object" && !Array.isArray(auth)) {
12749
- const jwt = auth.customJwtAuthorizer ?? auth.customJWTAuthorizer;
12750
- if (jwt !== null && typeof jwt === "object" && !Array.isArray(jwt)) {
12751
- return jwt;
12752
- }
12753
- }
12754
- }
12755
- return null;
12756
- }
12757
- async function checkCognitoAuthorizerConfigured(root, target) {
12758
- if (target !== "agentcore") {
12759
- return [];
12760
- }
12761
- const jwt = agentcoreAuthorizer(root);
12762
- const discovery = jwt?.discoveryUrl;
12763
- const clients = jwt?.allowedClients;
12764
- const configured = Boolean(discovery) && Array.isArray(clients) && clients.length > 0;
12765
- if (configured) {
12766
- return [];
12767
- }
12768
- return [
12769
- {
12770
- level: Level.WARNING,
12771
- name: "cognito_authorizer_configured",
12772
- message: "no Cognito authorizer configured in agentcore.json (authorizerConfiguration.customJwtAuthorizer.discoveryUrl/allowedClients) \u2192 the A2A endpoint will require SigV4/AWS creds; external buyers can't reach it. Run `bag deploy provision-cognito`, then paste the CDK outputs into the authorizer.",
12773
- fixCmd: "bag deploy provision-cognito",
12774
- details: {
12775
- discovery_url_set: Boolean(discovery),
12776
- allowed_clients: Array.isArray(clients) ? clients : []
12777
- }
12778
- }
12779
- ];
12780
- }
12781
13065
  async function checkStorageLocalNotDeployable(root, _target) {
12782
13066
  const storage = loadAgentToml(root).storage;
12783
13067
  if (storage === null || typeof storage !== "object" || Array.isArray(storage) || String(storage.kind ?? "").toLowerCase() !== "local") {
@@ -12802,7 +13086,6 @@ var allChecks4 = [
12802
13086
  checkRpcUrlSetForRuntime,
12803
13087
  checkRuntimeRpcReachable,
12804
13088
  checkInstalledRecipesUnchanged,
12805
- checkCognitoAuthorizerConfigured,
12806
13089
  checkStorageLocalNotDeployable
12807
13090
  ];
12808
13091
 
@@ -12813,11 +13096,11 @@ function tableOf11(data, key) {
12813
13096
  return value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
12814
13097
  }
12815
13098
  function agentRoot(root) {
12816
- return findSubProjectRoot13("agent", root) ?? path33.join(root, "app", "agent");
13099
+ return findSubProjectRoot13("agent", root) ?? path34.join(root, "app", "agent");
12817
13100
  }
12818
13101
  function loadAgent(root) {
12819
13102
  try {
12820
- return loadStudioToml17(path33.join(agentRoot(root), "studio.toml"));
13103
+ return loadStudioToml17(path34.join(agentRoot(root), "studio.toml"));
12821
13104
  } catch {
12822
13105
  return {};
12823
13106
  }
@@ -12837,10 +13120,10 @@ var checkPlatformEntrypointPresent = async (root, _target) => {
12837
13120
  const filenames = [`${stem2}.ts`];
12838
13121
  if (stem2 === "dualMain") filenames.push("mcpMain.ts");
12839
13122
  const filename = filenames.find(
12840
- (candidate) => !fs34.existsSync(path33.join(agentRoot(root), "src", candidate))
13123
+ (candidate) => !fs35.existsSync(path34.join(agentRoot(root), "src", candidate))
12841
13124
  );
12842
13125
  if (filename === void 0) return [];
12843
- const expected = path33.join(agentRoot(root), "src", filename);
13126
+ const expected = path34.join(agentRoot(root), "src", filename);
12844
13127
  return [
12845
13128
  {
12846
13129
  level: Level.CRITICAL,
@@ -12854,18 +13137,18 @@ var checkPlatformKeystoreNotInArtifact = async (root, _target) => {
12854
13137
  const data = loadAgent(root);
12855
13138
  const wallet = tableOf11(data, "wallet");
12856
13139
  if (String(wallet.kind ?? "evm-local") === "twak") return [];
12857
- const agent = path33.resolve(agentRoot(root));
13140
+ const agent = path34.resolve(agentRoot(root));
12858
13141
  const configured = String(wallet.keystore_dir ?? ".studio/wallets");
12859
- const keystore = path33.resolve(agent, configured);
13142
+ const keystore = path34.resolve(agent, configured);
12860
13143
  let jsonFiles;
12861
13144
  try {
12862
- jsonFiles = fs34.readdirSync(keystore).filter((name) => name.endsWith(".json"));
13145
+ jsonFiles = fs35.readdirSync(keystore).filter((name) => name.endsWith(".json"));
12863
13146
  } catch {
12864
13147
  return [];
12865
13148
  }
12866
13149
  if (jsonFiles.length === 0) return [];
12867
- const rel = path33.relative(agent, keystore);
12868
- if (rel.startsWith("..") || path33.isAbsolute(rel)) return [];
13150
+ const rel = path34.relative(agent, keystore);
13151
+ if (rel.startsWith("..") || path34.isAbsolute(rel)) return [];
12869
13152
  return [
12870
13153
  {
12871
13154
  level: Level.CRITICAL,
@@ -13092,7 +13375,7 @@ async function runProducers(producers, root, target) {
13092
13375
  }
13093
13376
 
13094
13377
  // src/cli/_deploy/verify.ts
13095
- import * as path35 from "path";
13378
+ import * as path36 from "path";
13096
13379
  import {
13097
13380
  findSubProjectRoot as findSubProjectRoot14,
13098
13381
  loadStudioToml as loadStudioToml18
@@ -13105,11 +13388,11 @@ import {
13105
13388
  import * as walletRt4 from "@bnbagent/studio-runtime/wallet";
13106
13389
 
13107
13390
  // src/cli/_identity.ts
13108
- import * as fs35 from "fs";
13109
- import * as path34 from "path";
13391
+ import * as fs36 from "fs";
13392
+ import * as path35 from "path";
13110
13393
  function writeIdentityBlock(root, identity) {
13111
- const p = path34.join(root, "studio.toml");
13112
- const text2 = fs35.readFileSync(p, "utf-8");
13394
+ const p = path35.join(root, "studio.toml");
13395
+ const text2 = fs36.readFileSync(p, "utf-8");
13113
13396
  const lines = text2.split(/\r?\n/);
13114
13397
  if (lines.length > 0 && lines[lines.length - 1] === "") {
13115
13398
  lines.pop();
@@ -13148,7 +13431,7 @@ function writeIdentityBlock(root, identity) {
13148
13431
  }
13149
13432
  }
13150
13433
  out.push("");
13151
- fs35.writeFileSync(p, out.join("\n"), "utf-8");
13434
+ fs36.writeFileSync(p, out.join("\n"), "utf-8");
13152
13435
  }
13153
13436
 
13154
13437
  // src/cli/_deploy/verify.ts
@@ -13256,6 +13539,7 @@ function baseResult(endpoint, runtime, overrides) {
13256
13539
  studioTomlUpdated: false,
13257
13540
  runtime,
13258
13541
  note: null,
13542
+ warning: null,
13259
13543
  error: null,
13260
13544
  exitCode: 0,
13261
13545
  ...overrides
@@ -13265,7 +13549,7 @@ async function runVerify(opts) {
13265
13549
  const endpoint = opts.endpoint;
13266
13550
  const runtime = opts.runtime ?? "agentcore";
13267
13551
  const skipRegister = opts.skipRegister ?? false;
13268
- const start = opts.projectRoot ? path35.resolve(opts.projectRoot) : void 0;
13552
+ const start = opts.projectRoot ? path36.resolve(opts.projectRoot) : void 0;
13269
13553
  const root = findSubProjectRoot14("agent", start);
13270
13554
  if (root === null) {
13271
13555
  return baseResult(endpoint, runtime, {
@@ -13285,7 +13569,7 @@ async function runVerify(opts) {
13285
13569
  }
13286
13570
  let data;
13287
13571
  try {
13288
- data = loadStudioToml18(path35.join(root, "studio.toml"));
13572
+ data = loadStudioToml18(path36.join(root, "studio.toml"));
13289
13573
  } catch (exc) {
13290
13574
  return baseResult(endpoint, runtime, {
13291
13575
  awsAccount,
@@ -13311,6 +13595,7 @@ async function runVerify(opts) {
13311
13595
  let action = "none";
13312
13596
  let registerError = null;
13313
13597
  let postWriteError = null;
13598
+ let postWriteWarning = null;
13314
13599
  let registerNote = null;
13315
13600
  let identityPendingReason = null;
13316
13601
  let registerExitCode = 0;
@@ -13343,9 +13628,8 @@ async function runVerify(opts) {
13343
13628
  const cause = e.cause !== null && typeof e.cause === "object" ? e.cause : null;
13344
13629
  const relayTxHash = typeof cause?.txHash === "string" ? cause.txHash : e.txHash;
13345
13630
  action = "register_partial";
13346
- postWriteError = relayTxHash ? `ERC-8004 register created agent_id=${e.agentId}, but setAgentURI relay tx_hash=${relayTxHash} was not observed by the chain RPC. Run \`bag erc8004 clear-pending\` to reconcile, then retry \`bag erc8004 update-endpoint\`.` : `ERC-8004 register created agent_id=${e.agentId}, but the setAgentURI relay submission was not observed by the chain RPC. Run \`bag erc8004 clear-pending\` to reconcile, then retry \`bag erc8004 update-endpoint\`.`;
13631
+ postWriteWarning = relayTxHash ? `ERC-8004 register created agent_id=${e.agentId}, but setAgentURI relay tx_hash=${relayTxHash} was not observed by the chain RPC. Run \`bag erc8004 clear-pending\` to reconcile, then retry \`bag erc8004 update-endpoint\`.` : `ERC-8004 register created agent_id=${e.agentId}, but the setAgentURI relay submission was not observed by the chain RPC. Run \`bag erc8004 clear-pending\` to reconcile, then retry \`bag erc8004 update-endpoint\`.`;
13347
13632
  identityPendingReason = "setAgentURI relay submission unverified; run bag erc8004 clear-pending before retrying";
13348
- registerExitCode = 1;
13349
13633
  } else if (e.txHash) {
13350
13634
  action = "register_pending";
13351
13635
  registerNote = `ERC-8004 register created agent_id=${e.agentId}; setAgentURI tx pending (${e.txHash}). Check the tx before retrying \`bag erc8004 update-endpoint\`.`;
@@ -13439,14 +13723,15 @@ async function runVerify(opts) {
13439
13723
  action,
13440
13724
  studioTomlUpdated,
13441
13725
  note: notes.length > 0 ? notes.join(" | ") : null,
13726
+ warning: postWriteWarning,
13442
13727
  error: postWriteError,
13443
13728
  exitCode: registerExitCode
13444
13729
  });
13445
13730
  }
13446
13731
 
13447
13732
  // src/cli/_hosted/deployOps.ts
13448
- import * as fs36 from "fs";
13449
- import * as path36 from "path";
13733
+ import * as fs37 from "fs";
13734
+ import * as path37 from "path";
13450
13735
  import {
13451
13736
  envLocalPath as envLocalPath15,
13452
13737
  findSubProjectRoot as findSubProjectRoot15,
@@ -13457,7 +13742,12 @@ var PLATFORM_SECTION = "deploy.platform";
13457
13742
  var WALLET_SECTION = "wallet";
13458
13743
  var KEYSTORE_JSON_ENV2 = "WALLET_KEYSTORE_JSON";
13459
13744
  var TWAK_WALLET_JSON_ENV2 = "TWAK_WALLET_JSON";
13460
- var WALLET_MATERIAL_KEYS = [KEYSTORE_JSON_ENV2, TWAK_WALLET_JSON_ENV2];
13745
+ var ALTANA_SESSION_ENV2 = "ALTANA_SESSION";
13746
+ var WALLET_MATERIAL_KEYS = [
13747
+ KEYSTORE_JSON_ENV2,
13748
+ TWAK_WALLET_JSON_ENV2,
13749
+ ALTANA_SESSION_ENV2
13750
+ ];
13461
13751
  var RETIRED_AGENT_STATES = /* @__PURE__ */ new Set([
13462
13752
  "deleted",
13463
13753
  "retired",
@@ -13487,8 +13777,8 @@ function agentTomlPath2(root) {
13487
13777
  if (agentRoot2 === null) {
13488
13778
  return null;
13489
13779
  }
13490
- const tomlPath = path36.join(agentRoot2, "studio.toml");
13491
- return isFile14(tomlPath) ? tomlPath : null;
13780
+ const tomlPath = path37.join(agentRoot2, "studio.toml");
13781
+ return isFile15(tomlPath) ? tomlPath : null;
13492
13782
  }
13493
13783
  function loadAgentCfg(root) {
13494
13784
  const tomlPath = agentTomlPath2(root);
@@ -13505,12 +13795,12 @@ function platformCfg(root) {
13505
13795
  return tableOf12(tableOf12(loadAgentCfg(root), "deploy"), "platform");
13506
13796
  }
13507
13797
  function patchTomlKv2(tomlPath, section, key, value) {
13508
- let text2 = fs36.readFileSync(tomlPath, "utf-8");
13798
+ let text2 = fs37.readFileSync(tomlPath, "utf-8");
13509
13799
  if (!hasSection(text2, section)) {
13510
13800
  text2 = addSection(text2, section);
13511
13801
  }
13512
13802
  text2 = hasKey(text2, section, key) ? setExistingKey(text2, section, key, value) : addKeyToSection(text2, section, key, value);
13513
- fs36.writeFileSync(tomlPath, text2);
13803
+ fs37.writeFileSync(tomlPath, text2);
13514
13804
  }
13515
13805
  function recordPlatformKv(root, key, value) {
13516
13806
  const tomlPath = agentTomlPath2(root);
@@ -13609,8 +13899,8 @@ function clearIdentityEndpointIfMatches(root, oldUrl) {
13609
13899
  }
13610
13900
  }
13611
13901
  function persistedPackaging2(agentRoot2) {
13612
- const tomlPath = path36.join(agentRoot2, "studio.toml");
13613
- if (!isFile14(tomlPath)) {
13902
+ const tomlPath = path37.join(agentRoot2, "studio.toml");
13903
+ if (!isFile15(tomlPath)) {
13614
13904
  return null;
13615
13905
  }
13616
13906
  try {
@@ -13622,8 +13912,8 @@ function persistedPackaging2(agentRoot2) {
13622
13912
  }
13623
13913
  }
13624
13914
  function resolvePlatformArtifact2(agentRoot2) {
13625
- const tomlPath = path36.join(agentRoot2, "studio.toml");
13626
- if (isFile14(tomlPath)) {
13915
+ const tomlPath = path37.join(agentRoot2, "studio.toml");
13916
+ if (isFile15(tomlPath)) {
13627
13917
  try {
13628
13918
  const cfg = loadStudioToml19(tomlPath);
13629
13919
  const explicit = tableOf12(cfg, "deploy").platform_artifact;
@@ -13646,7 +13936,7 @@ function platformPackaging(root) {
13646
13936
  }
13647
13937
  function loadCfgAt(agentRoot2) {
13648
13938
  try {
13649
- return loadStudioToml19(path36.join(agentRoot2, "studio.toml"));
13939
+ return loadStudioToml19(path37.join(agentRoot2, "studio.toml"));
13650
13940
  } catch {
13651
13941
  return {};
13652
13942
  }
@@ -13723,7 +14013,7 @@ function resolveSlug(root) {
13723
14013
  let name = String(tableOf12(loadAgentCfg(root), "project").name ?? "");
13724
14014
  name = name.replace(/-(agent|service)$/, "");
13725
14015
  if (!name) {
13726
- name = path36.basename(findWorkspaceRoot6(root) ?? root);
14016
+ name = path37.basename(findWorkspaceRoot6(root) ?? root);
13727
14017
  }
13728
14018
  let base = name.toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-+|-+$/g, "");
13729
14019
  base = base || "agent";
@@ -13965,6 +14255,19 @@ function walletWarning(root, secrets) {
13965
14255
  return;
13966
14256
  }
13967
14257
  const address = tableOf12(loadAgentCfg(root), "wallet").address;
14258
+ if (ALTANA_SESSION_ENV2 in secrets) {
14259
+ const who2 = typeof address === "string" && address ? ` (wallet ${address})` : "";
14260
+ warn(
14261
+ `
14262
+ !!! session exposure (platform trial) !!!
14263
+ This project's bounded Altana session${who2} will be transmitted to the BNB Chain operator's Secrets Manager so the trial runtime can sign on testnet. The session is budget-limited, expiring, and revocable \u2014 the admin keystore and WALLET_PASSWORD never ship.
14264
+ If the current budget or expiry is wider than you want an operator-held key to carry, stop and grant a tighter one first:
14265
+ bag wallet session grant --force --budget-u <small> --expiry-days <short>
14266
+ You can revoke it on-chain at any time with \`bag wallet session revoke\`.
14267
+ `
14268
+ );
14269
+ return;
14270
+ }
13968
14271
  const who = typeof address === "string" && address ? `key (address ${address})` : "signing key";
13969
14272
  warn(
13970
14273
  `
@@ -14181,15 +14484,15 @@ function printAgentClientPrompt(root, invokeUrl, status) {
14181
14484
  }
14182
14485
  function persistDeploySummary(root, text2) {
14183
14486
  try {
14184
- if (!fs36.statSync(path36.resolve(root)).isDirectory()) {
14487
+ if (!fs37.statSync(path37.resolve(root)).isDirectory()) {
14185
14488
  return null;
14186
14489
  }
14187
- const p = path36.join(
14188
- path36.dirname(envLocalPath15(root)),
14490
+ const p = path37.join(
14491
+ path37.dirname(envLocalPath15(root)),
14189
14492
  "last-deploy-summary.txt"
14190
14493
  );
14191
- fs36.mkdirSync(path36.dirname(p), { recursive: true });
14192
- fs36.writeFileSync(p, `${text2}
14494
+ fs37.mkdirSync(path37.dirname(p), { recursive: true });
14495
+ fs37.writeFileSync(p, `${text2}
14193
14496
  `);
14194
14497
  return p;
14195
14498
  } catch {
@@ -14344,9 +14647,9 @@ async function deletePlatformAgent(slug, deps = {}) {
14344
14647
  }
14345
14648
  return 0;
14346
14649
  }
14347
- function isFile14(p) {
14650
+ function isFile15(p) {
14348
14651
  try {
14349
- return fs36.statSync(p).isFile();
14652
+ return fs37.statSync(p).isFile();
14350
14653
  } catch {
14351
14654
  return false;
14352
14655
  }
@@ -14359,16 +14662,16 @@ var ADVERTISED_DEPLOY_RUNTIME_TARGETS = ["agentcore"];
14359
14662
  // src/cli/deploy.ts
14360
14663
  var TARGET_CHOICES = [...DEPLOY_RUNTIME_TARGETS];
14361
14664
  var ADVERTISED_TARGET_CHOICES = [...ADVERTISED_DEPLOY_RUNTIME_TARGETS];
14362
- function isFile15(p) {
14665
+ function isFile16(p) {
14363
14666
  try {
14364
- return fs37.statSync(p).isFile();
14667
+ return fs38.statSync(p).isFile();
14365
14668
  } catch {
14366
14669
  return false;
14367
14670
  }
14368
14671
  }
14369
14672
  function isDir7(p) {
14370
14673
  try {
14371
- return fs37.statSync(p).isDirectory();
14674
+ return fs38.statSync(p).isDirectory();
14372
14675
  } catch {
14373
14676
  return false;
14374
14677
  }
@@ -14385,8 +14688,8 @@ function loadAgentCfg2(root) {
14385
14688
  if (agentRoot2 === null) {
14386
14689
  return null;
14387
14690
  }
14388
- const tomlPath = path37.join(agentRoot2, "studio.toml");
14389
- if (!isFile15(tomlPath)) {
14691
+ const tomlPath = path38.join(agentRoot2, "studio.toml");
14692
+ if (!isFile16(tomlPath)) {
14390
14693
  return null;
14391
14694
  }
14392
14695
  try {
@@ -14548,8 +14851,8 @@ function registerDeploy(program) {
14548
14851
  p.command("fix-gitignore").description(
14549
14852
  "Ensure the workspace .gitignore excludes .studio/ (the agent's .env.local + keystore)."
14550
14853
  ).option("--project-root <path>", "Override project root.").action(act((opts) => cmdFixGitignore(opts)));
14551
- p.command("provision-cognito").description(
14552
- "Emit an AWS CDK app under agentcore/cognito/ that provisions a Cognito M2M client for the AgentCore A2A inbound OAuth2 authorizer (studio writes IaC + prints steps; you run `cdk deploy`)."
14854
+ p.command("provision-cognito", { hidden: true }).description(
14855
+ "DEPRECATED \u2014 `bag deploy` provisions inbound OAuth by itself. Emit an AWS CDK app under agentcore/cognito/ that provisions a Cognito M2M client for the AgentCore inbound OAuth2 authorizer (studio writes IaC + prints steps; you run `cdk deploy`)."
14553
14856
  ).option("--project-root <path>", "Override project root.").option(
14554
14857
  "--wire [outputsFile]",
14555
14858
  "After you `cdk deploy --outputs-file <file>`, wire those outputs into agentcore.json + .studio/.env.local (default file: agentcore/cognito/cdk-outputs.json). Pure local file I/O \u2014 studio never calls AWS."
@@ -14563,9 +14866,9 @@ function applyProjectRoot(projectRoot, requireToml = true) {
14563
14866
  if (projectRoot === void 0) {
14564
14867
  return null;
14565
14868
  }
14566
- const p = path37.resolve(projectRoot);
14869
+ const p = path38.resolve(projectRoot);
14567
14870
  const agentRoot2 = findSubProjectRoot16("agent", p);
14568
- if (requireToml && !isFile15(path37.join(p, "studio.toml")) && (agentRoot2 === null || !isFile15(path37.join(agentRoot2, "studio.toml")))) {
14871
+ if (requireToml && !isFile16(path38.join(p, "studio.toml")) && (agentRoot2 === null || !isFile16(path38.join(agentRoot2, "studio.toml")))) {
14569
14872
  printErr(`error: no studio.toml under --project-root ${p}`);
14570
14873
  return 2;
14571
14874
  }
@@ -14577,7 +14880,7 @@ function applyProjectRoot(projectRoot, requireToml = true) {
14577
14880
  return null;
14578
14881
  }
14579
14882
  function resolveProjectRoot2(_projectRoot) {
14580
- const cwd = path37.resolve(process.cwd());
14883
+ const cwd = path38.resolve(process.cwd());
14581
14884
  return findStudioWorkspaceRoot3(cwd) ?? cwd;
14582
14885
  }
14583
14886
  function deployWorkspaceRoot2(root) {
@@ -14608,12 +14911,17 @@ function agentDeployDestination(root) {
14608
14911
  }
14609
14912
  function resolveTarget(opts, root, destination = agentDeployDestination(root)) {
14610
14913
  const explicit = opts.runtime ?? opts.target;
14611
- if (explicit) {
14612
- return explicit;
14613
- }
14614
14914
  if (destination === "platform") {
14915
+ if (explicit && explicit !== "platform") {
14916
+ printErr(
14917
+ `warning: --runtime=${explicit} ignored \u2014 studio.toml has [deploy].destination = 'platform', which selects the managed deploy path and its own checks. Use --provider bnb|aws to pick where this agent deploys.`
14918
+ );
14919
+ }
14615
14920
  return "platform";
14616
14921
  }
14922
+ if (explicit) {
14923
+ return explicit;
14924
+ }
14617
14925
  return readStackRuntime(root) ?? "agentcore";
14618
14926
  }
14619
14927
  function validateRuntimeAgainstStack(target, force, root) {
@@ -14638,7 +14946,7 @@ function validateRuntimeAgainstStack(target, force, root) {
14638
14946
  async function cmdPrepare(opts) {
14639
14947
  let root;
14640
14948
  if (opts.projectRoot !== void 0) {
14641
- const p = path37.resolve(opts.projectRoot);
14949
+ const p = path38.resolve(opts.projectRoot);
14642
14950
  if (!isDir7(p)) {
14643
14951
  printErr(`error: --project-root ${p} is not a directory`);
14644
14952
  return 2;
@@ -14646,7 +14954,7 @@ async function cmdPrepare(opts) {
14646
14954
  process.chdir(p);
14647
14955
  root = findStudioWorkspaceRoot3(p) ?? p;
14648
14956
  } else {
14649
- const cwd = path37.resolve(process.cwd());
14957
+ const cwd = path38.resolve(process.cwd());
14650
14958
  root = findStudioWorkspaceRoot3(cwd) ?? cwd;
14651
14959
  }
14652
14960
  const target = resolveTarget(opts, root);
@@ -14788,8 +15096,8 @@ function writeAgentDeployState(workspaceRoot, arn, record = {}, destination = "s
14788
15096
  if (agentRoot2 === null) {
14789
15097
  return;
14790
15098
  }
14791
- const tomlPath = path37.join(agentRoot2, "studio.toml");
14792
- if (!isFile15(tomlPath)) {
15099
+ const tomlPath = path38.join(agentRoot2, "studio.toml");
15100
+ if (!isFile16(tomlPath)) {
14793
15101
  return;
14794
15102
  }
14795
15103
  try {
@@ -14820,6 +15128,12 @@ function writeAgentDeployState(workspaceRoot, arn, record = {}, destination = "s
14820
15128
  if (scope) {
14821
15129
  setEnvVar(envLocalPath16(agentRoot2), "OAUTH_SCOPE", scope);
14822
15130
  }
15131
+ syncDescriptorOauthFacts(workspaceRoot, {
15132
+ tokenUrl,
15133
+ scope,
15134
+ discoveryUrl,
15135
+ clientId
15136
+ });
14823
15137
  if (persistedPackaging(agentRoot2) === null) {
14824
15138
  patchTomlKv(
14825
15139
  tomlPath,
@@ -14861,10 +15175,10 @@ package and at the repo root).
14861
15175
  `;
14862
15176
  function iamNoticeTomlPath(root) {
14863
15177
  const agentRoot2 = findSubProjectRoot16("agent", root) ?? root;
14864
- return path37.join(agentRoot2, "studio.toml");
15178
+ return path38.join(agentRoot2, "studio.toml");
14865
15179
  }
14866
15180
  function iamNoticeAccepted(tomlPath) {
14867
- if (!isFile15(tomlPath)) {
15181
+ if (!isFile16(tomlPath)) {
14868
15182
  return false;
14869
15183
  }
14870
15184
  let data;
@@ -14915,7 +15229,7 @@ async function iamNoticeGate(root, acceptRisk) {
14915
15229
  return 1;
14916
15230
  }
14917
15231
  async function buildAgentProject(agentRoot2, packaging) {
14918
- if (!isFile15(path37.join(agentRoot2, "package.json"))) {
15232
+ if (!isFile16(path38.join(agentRoot2, "package.json"))) {
14919
15233
  printErr(
14920
15234
  `warning: no package.json under ${agentRoot2} \u2014 skipping the agent \`pnpm build\`; bnbagent-deploy will package whatever dist/ holds.`
14921
15235
  );
@@ -15085,6 +15399,17 @@ async function refreshLocalDeployDependencies(root) {
15085
15399
  return 1;
15086
15400
  }
15087
15401
  }
15402
+ function partialDeployCleanupNote(workspaceRoot) {
15403
+ const project = projectName(workspaceRoot);
15404
+ return [
15405
+ "note: a deploy that fails partway can leave these behind (they are reused by a successful retry, so clean up only if you are giving up):",
15406
+ ` - ECR image bnbagent/${project}`,
15407
+ ` - Secrets Manager bnbagent/${project}/runtime`,
15408
+ ` - Cognito M2M client bnbagent-${project}`,
15409
+ ` - IAM role bnbagent-${project}-runtime`,
15410
+ " `bag deploy destroy --provider aws --execute` removes the runtime, secret, and M2M client; add --purge for the ECR repository and log groups. The IAM role is deleted with the runtime it was created for."
15411
+ ].join("\n");
15412
+ }
15088
15413
  async function cmdAgent(opts, agentcoreArgs) {
15089
15414
  let rc = applyProjectRoot(opts.projectRoot);
15090
15415
  if (rc !== null) {
@@ -15095,12 +15420,6 @@ async function cmdAgent(opts, agentcoreArgs) {
15095
15420
  const packagingDestination = opts.to ?? opts.destination ?? agentDeployDestination(root);
15096
15421
  const driftAgentRoot = findSubProjectRoot16("agent", root) ?? root;
15097
15422
  const driftKind = deployWalletKind(driftAgentRoot);
15098
- if (driftKind === "altana") {
15099
- printErr(
15100
- "error: Altana deployment is deferred in this release. `bag dev` uses the bounded session locally, but no deploy adapter may receive the admin key or an unreviewed session transport. No packaging or external deploy calls were started."
15101
- );
15102
- return 2;
15103
- }
15104
15423
  rc = checkPackagingDrift(
15105
15424
  root,
15106
15425
  packagingDestination,
@@ -15243,7 +15562,7 @@ async function cmdAgent(opts, agentcoreArgs) {
15243
15562
  packagingDestination,
15244
15563
  resolvePlatformArtifact(agentRoot2)
15245
15564
  ) === "container" ? "container" : "zip";
15246
- const walletBlurb = walletKind2 === "twak" ? "the encrypted twak wallet as TWAK_WALLET_JSON" : "the encrypted keystore as WALLET_KEYSTORE_JSON";
15565
+ const walletBlurb = walletKind2 === "twak" ? "the encrypted twak wallet as TWAK_WALLET_JSON" : walletKind2 === "altana" ? "the bounded Altana session as ALTANA_SESSION \u2014 the admin keystore and WALLET_PASSWORD never ship" : "the encrypted keystore as WALLET_KEYSTORE_JSON";
15247
15566
  if (secretsMode === "envvars") {
15248
15567
  printErr(
15249
15568
  `note: --secrets-mode envvars inlines the runtime secrets (incl. ${walletBlurb}) as PLAINTEXT runtime env vars in the deploy spec \u2014 testnet only, refused on mainnet.`
@@ -15296,6 +15615,7 @@ async function cmdAgent(opts, agentcoreArgs) {
15296
15615
  printErr(
15297
15616
  "note: the pinned bnbagent-deploy adapter automatically restores an owned runtime secret that is inside its recovery window. If AWS denies that operation, update the deployer policy to include secretsmanager:RestoreSecret."
15298
15617
  );
15618
+ printErr(partialDeployCleanupNote(workspaceRoot));
15299
15619
  return code;
15300
15620
  }
15301
15621
  const record = recordOf2(data);
@@ -15360,7 +15680,7 @@ function recordedEndpoint(root) {
15360
15680
  }
15361
15681
  function recordedAgentId(agentRoot2) {
15362
15682
  try {
15363
- const cfg = loadStudioToml20(path37.join(agentRoot2, "studio.toml"));
15683
+ const cfg = loadStudioToml20(path38.join(agentRoot2, "studio.toml"));
15364
15684
  const val = tableOf13(cfg, "identity").agent_id;
15365
15685
  return val !== void 0 && val !== null && val !== "" ? String(val) : null;
15366
15686
  } catch {
@@ -15369,7 +15689,7 @@ function recordedAgentId(agentRoot2) {
15369
15689
  }
15370
15690
  function recordedRuntimeArn(agentRoot2) {
15371
15691
  try {
15372
- const cfg = loadStudioToml20(path37.join(agentRoot2, "studio.toml"));
15692
+ const cfg = loadStudioToml20(path38.join(agentRoot2, "studio.toml"));
15373
15693
  const val = tableOf13(cfg, "deploy").runtime_arn;
15374
15694
  return val ? String(val) : null;
15375
15695
  } catch {
@@ -15378,7 +15698,7 @@ function recordedRuntimeArn(agentRoot2) {
15378
15698
  }
15379
15699
  function recordedOauthClientId(agentRoot2) {
15380
15700
  try {
15381
- const cfg = loadStudioToml20(path37.join(agentRoot2, "studio.toml"));
15701
+ const cfg = loadStudioToml20(path38.join(agentRoot2, "studio.toml"));
15382
15702
  const val = tableOf13(cfg, "deploy").oauth_client_id;
15383
15703
  return val ? String(val) : null;
15384
15704
  } catch {
@@ -15387,7 +15707,7 @@ function recordedOauthClientId(agentRoot2) {
15387
15707
  }
15388
15708
  function agentFacesOf(agentRoot2) {
15389
15709
  try {
15390
- const cfg = loadStudioToml20(path37.join(agentRoot2, "studio.toml"));
15710
+ const cfg = loadStudioToml20(path38.join(agentRoot2, "studio.toml"));
15391
15711
  return stackFaces(tableOf13(cfg, "stack"), tableOf13(cfg, "payments"));
15392
15712
  } catch {
15393
15713
  return ["A2A"];
@@ -15539,15 +15859,15 @@ async function printAgentClientPrompt2(root, destination, opts = {}) {
15539
15859
  }
15540
15860
  function persistDeploySummary2(root, text2) {
15541
15861
  try {
15542
- if (!fs37.statSync(path37.resolve(root)).isDirectory()) {
15862
+ if (!fs38.statSync(path38.resolve(root)).isDirectory()) {
15543
15863
  return null;
15544
15864
  }
15545
- const p = path37.join(
15546
- path37.dirname(envLocalPath16(root)),
15865
+ const p = path38.join(
15866
+ path38.dirname(envLocalPath16(root)),
15547
15867
  "last-deploy-summary.txt"
15548
15868
  );
15549
- fs37.mkdirSync(path37.dirname(p), { recursive: true });
15550
- fs37.writeFileSync(p, `${text2}
15869
+ fs38.mkdirSync(path38.dirname(p), { recursive: true });
15870
+ fs38.writeFileSync(p, `${text2}
15551
15871
  `, "utf-8");
15552
15872
  return p;
15553
15873
  } catch {
@@ -15638,6 +15958,7 @@ function verifyToJson(r) {
15638
15958
  studio_toml_updated: r.studioTomlUpdated,
15639
15959
  runtime: r.runtime,
15640
15960
  note: r.note,
15961
+ warning: r.warning,
15641
15962
  error: r.error,
15642
15963
  exit_code: r.exitCode
15643
15964
  };
@@ -15679,6 +16000,9 @@ function renderVerifyHuman(r, deployment, liveStatus) {
15679
16000
  if (r.note) {
15680
16001
  printOut(`note: ${r.note}`);
15681
16002
  }
16003
+ if (r.warning) {
16004
+ printOut(`warning: ${r.warning}`);
16005
+ }
15682
16006
  if (r.error) {
15683
16007
  printOut(`error: ${r.error}`);
15684
16008
  }
@@ -15940,9 +16264,9 @@ async function cmdDestroy(opts) {
15940
16264
  return 2;
15941
16265
  }
15942
16266
  const answer = await promptUser(
15943
- `This delegates the teardown of "${path37.basename(workspaceRoot)}" (Foundry hosted agent + the resources its deploy record tracks) to bnbagent-deploy. Type the project name to proceed: `
16267
+ `This delegates the teardown of "${path38.basename(workspaceRoot)}" (Foundry hosted agent + the resources its deploy record tracks) to bnbagent-deploy. Type the project name to proceed: `
15944
16268
  );
15945
- if (answer.trim() !== path37.basename(workspaceRoot)) {
16269
+ if (answer.trim() !== path38.basename(workspaceRoot)) {
15946
16270
  printErr(
15947
16271
  "error: confirmation did not match the project name; aborting."
15948
16272
  );
@@ -16026,6 +16350,7 @@ async function cmdFixGitignore(opts) {
16026
16350
  printOut(`${marker} ${result.name}: ${result.message}`);
16027
16351
  return 0;
16028
16352
  }
16353
+ var PROVISION_COGNITO_DEPRECATION = "warning: `bag deploy provision-cognito` is deprecated and will be removed.\n `bag deploy` provisions the inbound OAuth user pool and M2M client on its\n own; the pool this CDK app stands up is never used by a deploy, and both\n the stack and its client are billable orphans you have to clean up.\n Run `bag deploy --provider aws` directly instead.";
16029
16354
  async function cmdProvisionCognito(opts) {
16030
16355
  const rc = applyProjectRoot(opts.projectRoot, false);
16031
16356
  if (rc !== null) {
@@ -16033,6 +16358,7 @@ async function cmdProvisionCognito(opts) {
16033
16358
  }
16034
16359
  const root = resolveProjectRoot2(opts.projectRoot);
16035
16360
  const workspaceRoot = deployWorkspaceRoot2(root);
16361
+ printOut(PROVISION_COGNITO_DEPRECATION);
16036
16362
  if (opts.wire !== void 0 && opts.wire !== false) {
16037
16363
  const outputsFile = typeof opts.wire === "string" && opts.wire ? opts.wire : null;
16038
16364
  try {
@@ -16056,8 +16382,8 @@ async function cmdProvisionCognito(opts) {
16056
16382
 
16057
16383
  // src/cli/doctor.ts
16058
16384
  import * as crypto5 from "crypto";
16059
- import * as fs38 from "fs";
16060
- import * as path38 from "path";
16385
+ import * as fs39 from "fs";
16386
+ import * as path39 from "path";
16061
16387
  import { EVMWalletProvider as EVMWalletProvider2 } from "@bnbagent/sdk";
16062
16388
  import {
16063
16389
  envLocalPath as envLocalPath17,
@@ -16103,23 +16429,23 @@ function tableOf14(cfg, key) {
16103
16429
  const v = cfg[key];
16104
16430
  return v !== null && typeof v === "object" && !Array.isArray(v) ? v : {};
16105
16431
  }
16106
- function isFile16(p) {
16432
+ function isFile17(p) {
16107
16433
  try {
16108
- return fs38.statSync(p).isFile();
16434
+ return fs39.statSync(p).isFile();
16109
16435
  } catch {
16110
16436
  return false;
16111
16437
  }
16112
16438
  }
16113
16439
  function isDir8(p) {
16114
16440
  try {
16115
- return fs38.statSync(p).isDirectory();
16441
+ return fs39.statSync(p).isDirectory();
16116
16442
  } catch {
16117
16443
  return false;
16118
16444
  }
16119
16445
  }
16120
16446
  function keystoreJsons(dir) {
16121
16447
  try {
16122
- return fs38.readdirSync(dir).filter((f) => f.endsWith(".json")).sort();
16448
+ return fs39.readdirSync(dir).filter((f) => f.endsWith(".json")).sort();
16123
16449
  } catch {
16124
16450
  return [];
16125
16451
  }
@@ -16148,7 +16474,7 @@ async function cmdDoctor(opts) {
16148
16474
  if (opts.checkEnv) {
16149
16475
  return runCheckEnv(projectRoot);
16150
16476
  }
16151
- const tomlPath = path38.join(projectRoot, "studio.toml");
16477
+ const tomlPath = path39.join(projectRoot, "studio.toml");
16152
16478
  let data;
16153
16479
  try {
16154
16480
  data = loadStudioToml21(tomlPath);
@@ -16184,8 +16510,8 @@ async function cmdDoctor(opts) {
16184
16510
  }
16185
16511
  function resolveProjectRoot3(argRoot) {
16186
16512
  if (argRoot !== void 0) {
16187
- const root2 = path38.resolve(argRoot);
16188
- if (!isFile16(path38.join(root2, "studio.toml"))) {
16513
+ const root2 = path39.resolve(argRoot);
16514
+ if (!isFile17(path39.join(root2, "studio.toml"))) {
16189
16515
  printErr(`error: no studio.toml under --project-root ${root2}`);
16190
16516
  return null;
16191
16517
  }
@@ -16199,15 +16525,15 @@ function resolveProjectRoot3(argRoot) {
16199
16525
  return root;
16200
16526
  }
16201
16527
  function runCheckEnv(projectRoot) {
16202
- const agentDir = workspaceLayers(projectRoot) ?? path38.join(projectRoot, "agent");
16528
+ const agentDir = workspaceLayers(projectRoot) ?? path39.join(projectRoot, "agent");
16203
16529
  const envPath = envLocalPath17(agentDir);
16204
16530
  printOut(`bag doctor --check-env: ${envPath}`);
16205
- if (!isFile16(envPath)) {
16206
- printOut(` (no ${path38.basename(envPath)} found \u2014 nothing to report)`);
16531
+ if (!isFile17(envPath)) {
16532
+ printOut(` (no ${path39.basename(envPath)} found \u2014 nothing to report)`);
16207
16533
  return 0;
16208
16534
  }
16209
16535
  const values = {};
16210
- for (const rawLine of fs38.readFileSync(envPath, "utf-8").split(/\r?\n/)) {
16536
+ for (const rawLine of fs39.readFileSync(envPath, "utf-8").split(/\r?\n/)) {
16211
16537
  const line = rawLine.trim();
16212
16538
  if (!line || line.startsWith("#") || !line.includes("=")) {
16213
16539
  continue;
@@ -16234,25 +16560,25 @@ function runCheckEnv(projectRoot) {
16234
16560
  return 0;
16235
16561
  }
16236
16562
  function workspaceLayers(projectRoot) {
16237
- const parent = path38.dirname(projectRoot);
16238
- if (isFile16(path38.join(parent, "agent", "studio.toml"))) {
16239
- return path38.join(parent, "agent");
16563
+ const parent = path39.dirname(projectRoot);
16564
+ if (isFile17(path39.join(parent, "agent", "studio.toml"))) {
16565
+ return path39.join(parent, "agent");
16240
16566
  }
16241
- if (isFile16(path38.join(projectRoot, "agent", "studio.toml"))) {
16242
- return path38.join(projectRoot, "agent");
16567
+ if (isFile17(path39.join(projectRoot, "agent", "studio.toml"))) {
16568
+ return path39.join(projectRoot, "agent");
16243
16569
  }
16244
16570
  return null;
16245
16571
  }
16246
16572
  function checkAppMain(projectRootArg) {
16247
16573
  let projectRoot = projectRootArg;
16248
- const parent = path38.dirname(projectRoot);
16249
- if (isFile16(path38.join(parent, "agent", "studio.toml"))) {
16574
+ const parent = path39.dirname(projectRoot);
16575
+ if (isFile17(path39.join(parent, "agent", "studio.toml"))) {
16250
16576
  projectRoot = parent;
16251
16577
  }
16252
- const agentDir = path38.join(projectRoot, "agent");
16578
+ const agentDir = path39.join(projectRoot, "agent");
16253
16579
  let config = {};
16254
- const tomlPath = path38.join(agentDir, "studio.toml");
16255
- if (isFile16(tomlPath)) {
16580
+ const tomlPath = path39.join(agentDir, "studio.toml");
16581
+ if (isFile17(tomlPath)) {
16256
16582
  try {
16257
16583
  config = loadStudioToml21(tomlPath);
16258
16584
  } catch {
@@ -16270,8 +16596,8 @@ function checkAppMain(projectRootArg) {
16270
16596
  } else {
16271
16597
  entrypoint = "src/main.ts";
16272
16598
  }
16273
- const entryFile = path38.join(agentDir, entrypoint);
16274
- if (!isFile16(entryFile)) {
16599
+ const entryFile = path39.join(agentDir, entrypoint);
16600
+ if (!isFile17(entryFile)) {
16275
16601
  return [
16276
16602
  {
16277
16603
  name: "agent entrypoint",
@@ -16286,12 +16612,12 @@ function checkAppMain(projectRootArg) {
16286
16612
  function checkAgentcoreName(projectRoot) {
16287
16613
  let cfgPath = null;
16288
16614
  for (const candidate of [
16289
- path38.dirname(path38.dirname(projectRoot)),
16290
- path38.dirname(projectRoot),
16615
+ path39.dirname(path39.dirname(projectRoot)),
16616
+ path39.dirname(projectRoot),
16291
16617
  projectRoot
16292
16618
  ]) {
16293
- const p = path38.join(candidate, "agentcore", "agentcore.json");
16294
- if (isFile16(p)) {
16619
+ const p = path39.join(candidate, "agentcore", "agentcore.json");
16620
+ if (isFile17(p)) {
16295
16621
  cfgPath = p;
16296
16622
  break;
16297
16623
  }
@@ -16301,7 +16627,7 @@ function checkAgentcoreName(projectRoot) {
16301
16627
  }
16302
16628
  let cfg;
16303
16629
  try {
16304
- cfg = JSON.parse(fs38.readFileSync(cfgPath, "utf-8"));
16630
+ cfg = JSON.parse(fs39.readFileSync(cfgPath, "utf-8"));
16305
16631
  } catch {
16306
16632
  return [];
16307
16633
  }
@@ -16333,7 +16659,7 @@ function isLocalEvmWallet(walletCfg) {
16333
16659
  }
16334
16660
  function anchoredKeystoreDir(projectRoot, walletCfg) {
16335
16661
  const rel = String(walletCfg.keystore_dir ?? ".studio/wallets");
16336
- return path38.isAbsolute(rel) ? rel : path38.join(projectRoot, rel);
16662
+ return path39.isAbsolute(rel) ? rel : path39.join(projectRoot, rel);
16337
16663
  }
16338
16664
  async function checkWallet(projectRoot, data) {
16339
16665
  const walletCfg = tableOf14(data, "wallet");
@@ -16379,8 +16705,8 @@ async function checkWallet(projectRoot, data) {
16379
16705
  }
16380
16706
  const address = String(walletCfg.address ?? "").trim();
16381
16707
  if (address) {
16382
- const expected = path38.join(keystoreDir, `${address}.json`);
16383
- if (!isFile16(expected)) {
16708
+ const expected = path39.join(keystoreDir, `${address}.json`);
16709
+ if (!isFile17(expected)) {
16384
16710
  out.push({
16385
16711
  name: "[wallet] address \u2194 keystore",
16386
16712
  status: FAIL,
@@ -16390,7 +16716,7 @@ async function checkWallet(projectRoot, data) {
16390
16716
  out.push({
16391
16717
  name: "[wallet] address \u2194 keystore",
16392
16718
  status: PASS,
16393
- detail: `${address} matches ${path38.basename(expected)}`
16719
+ detail: `${address} matches ${path39.basename(expected)}`
16394
16720
  });
16395
16721
  }
16396
16722
  }
@@ -16407,9 +16733,9 @@ function checkWalletAltana(walletCfg, projectRoot) {
16407
16733
  detail: "no [wallet].address \u2014 run `bag wallet new` first"
16408
16734
  });
16409
16735
  } else {
16410
- const expected = path38.join(keystoreDir, `${address}.json`);
16736
+ const expected = path39.join(keystoreDir, `${address}.json`);
16411
16737
  out.push(
16412
- isFile16(expected) ? {
16738
+ isFile17(expected) ? {
16413
16739
  name: "[wallet] Altana admin",
16414
16740
  status: PASS,
16415
16741
  detail: `${address} matches ${expected}`
@@ -16423,8 +16749,8 @@ function checkWalletAltana(walletCfg, projectRoot) {
16423
16749
  const configured = String(
16424
16750
  walletCfg.session_file ?? ".studio/wallets/altana-session.json"
16425
16751
  );
16426
- const sessionFile = path38.isAbsolute(configured) ? configured : path38.join(projectRoot, configured);
16427
- if (!isFile16(sessionFile)) {
16752
+ const sessionFile = path39.isAbsolute(configured) ? configured : path39.join(projectRoot, configured);
16753
+ if (!isFile17(sessionFile)) {
16428
16754
  out.push({
16429
16755
  name: "[wallet] Altana session",
16430
16756
  status: FAIL,
@@ -16434,7 +16760,7 @@ function checkWalletAltana(walletCfg, projectRoot) {
16434
16760
  }
16435
16761
  let envelope;
16436
16762
  try {
16437
- envelope = JSON.parse(fs38.readFileSync(sessionFile, "utf8"));
16763
+ envelope = JSON.parse(fs39.readFileSync(sessionFile, "utf8"));
16438
16764
  } catch {
16439
16765
  out.push({
16440
16766
  name: "[wallet] Altana session",
@@ -16460,7 +16786,7 @@ function checkWalletAltana(walletCfg, projectRoot) {
16460
16786
  status: remaining <= 0 ? FAIL : remaining < 3 * 24 * 60 * 60 ? WARN : PASS,
16461
16787
  detail: remaining > 0 ? `${String(envelope.publicKey)} active until ${new Date(expiry * 1e3).toISOString()}` : `expired at ${new Date(expiry * 1e3).toISOString()} \u2014 run \`bag wallet session grant --force\``
16462
16788
  });
16463
- if ((fs38.statSync(sessionFile).mode & 63) !== 0) {
16789
+ if ((fs39.statSync(sessionFile).mode & 63) !== 0) {
16464
16790
  out.push({
16465
16791
  name: "[wallet] Altana session permissions",
16466
16792
  status: WARN,
@@ -16518,7 +16844,7 @@ async function checkWalletTwak(walletCfg, projectRoot, data = {}) {
16518
16844
  });
16519
16845
  }
16520
16846
  const walletFile = twakWalletFile(walletCfg, projectRoot);
16521
- if (isFile16(walletFile)) {
16847
+ if (isFile17(walletFile)) {
16522
16848
  out.push({
16523
16849
  name: "[wallet] twak wallet",
16524
16850
  status: PASS,
@@ -16528,7 +16854,7 @@ async function checkWalletTwak(walletCfg, projectRoot, data = {}) {
16528
16854
  let createCmd = "twak wallet create --password <pw> --no-keychain";
16529
16855
  let setupCmd = "twak setup";
16530
16856
  if (walletCfg.twak_home) {
16531
- const home = path38.dirname(path38.dirname(walletFile));
16857
+ const home = path39.dirname(path39.dirname(walletFile));
16532
16858
  createCmd = `HOME=${home} ${createCmd}`;
16533
16859
  setupCmd = `HOME=${home} ${setupCmd}`;
16534
16860
  }
@@ -17284,11 +17610,11 @@ function checkAgentsMdSkillTrigger(projectRoot) {
17284
17610
  if (ws === null) {
17285
17611
  return [];
17286
17612
  }
17287
- const agentsMd = path38.join(ws, "AGENTS.md");
17613
+ const agentsMd = path39.join(ws, "AGENTS.md");
17288
17614
  const line = "For any bnbagent-studio task (deploy, sell, operate, debug), load the `/bnbagent-studio` skill first.";
17289
17615
  let text2;
17290
17616
  try {
17291
- text2 = isFile16(agentsMd) ? fs38.readFileSync(agentsMd, "utf-8") : null;
17617
+ text2 = isFile17(agentsMd) ? fs39.readFileSync(agentsMd, "utf-8") : null;
17292
17618
  } catch {
17293
17619
  return [];
17294
17620
  }
@@ -17325,8 +17651,8 @@ function printChecks(checks) {
17325
17651
  }
17326
17652
 
17327
17653
  // src/cli/env.ts
17328
- import * as fs39 from "fs";
17329
- import * as path39 from "path";
17654
+ import * as fs40 from "fs";
17655
+ import * as path40 from "path";
17330
17656
  var SECRET_KEY_PARTS = ["PASSWORD", "SECRET", "TOKEN", "API_KEY"];
17331
17657
  var WALLET_PASSWORD_KEYS = /* @__PURE__ */ new Set([
17332
17658
  "WALLET_PASSWORD",
@@ -17372,8 +17698,8 @@ function resolveEnvPath(fileArg, rootArg) {
17372
17698
  return [fileArg, null];
17373
17699
  }
17374
17700
  if (rootArg !== void 0) {
17375
- const root2 = path39.resolve(rootArg);
17376
- if (!fs39.existsSync(path39.join(root2, "studio.toml"))) {
17701
+ const root2 = path40.resolve(rootArg);
17702
+ if (!fs40.existsSync(path40.join(root2, "studio.toml"))) {
17377
17703
  return [null, `error: no studio.toml under --project-root ${root2}`];
17378
17704
  }
17379
17705
  return [envLocalPath(root2), null];
@@ -17384,7 +17710,7 @@ function resolveEnvPath(fileArg, rootArg) {
17384
17710
  }
17385
17711
  const target = envLocalPath(root);
17386
17712
  let note = null;
17387
- if (path39.dirname(path39.dirname(target)) !== path39.resolve(process.cwd())) {
17713
+ if (path40.dirname(path40.dirname(target)) !== path40.resolve(process.cwd())) {
17388
17714
  note = `\u2192 writing to ${target} (workspace .studio/, where \`bag dev\` reads)`;
17389
17715
  }
17390
17716
  return [target, note];
@@ -17441,7 +17767,7 @@ function cmdGet2(key, fileArg, rootArg) {
17441
17767
  }
17442
17768
 
17443
17769
  // src/cli/erc8004.ts
17444
- import * as path40 from "path";
17770
+ import * as path41 from "path";
17445
17771
  import { auditedOp as auditedOp3 } from "@bnbagent/studio-runtime/audit";
17446
17772
  import {
17447
17773
  findProjectRoot as findProjectRoot5,
@@ -17451,7 +17777,7 @@ import {
17451
17777
  import {
17452
17778
  getMetadata,
17453
17779
  register as register2,
17454
- resolve as resolve20,
17780
+ resolve as resolve21,
17455
17781
  setMetadata,
17456
17782
  show as show2,
17457
17783
  updateServiceEndpoint as updateServiceEndpoint2
@@ -17562,7 +17888,7 @@ function loadAgentCfg3() {
17562
17888
  return null;
17563
17889
  }
17564
17890
  try {
17565
- return loadStudioToml22(path40.join(root, "studio.toml"));
17891
+ return loadStudioToml22(path41.join(root, "studio.toml"));
17566
17892
  } catch {
17567
17893
  return null;
17568
17894
  }
@@ -17640,7 +17966,7 @@ function loadIdentityBlock(agentRoot2) {
17640
17966
  try {
17641
17967
  return {
17642
17968
  ...tableOf15(
17643
- loadStudioToml22(path40.join(agentRoot2, "studio.toml")),
17969
+ loadStudioToml22(path41.join(agentRoot2, "studio.toml")),
17644
17970
  "identity"
17645
17971
  )
17646
17972
  };
@@ -17979,7 +18305,7 @@ async function cmdResolve(agentId, networkArg) {
17979
18305
  const wallet = walletRt6.getWallet();
17980
18306
  let uri;
17981
18307
  try {
17982
- uri = await resolve20(agentId, {
18308
+ uri = await resolve21(agentId, {
17983
18309
  wallet,
17984
18310
  network: resolveNetwork2(networkArg)
17985
18311
  });
@@ -17992,8 +18318,8 @@ async function cmdResolve(agentId, networkArg) {
17992
18318
  }
17993
18319
 
17994
18320
  // src/cli/erc8183.ts
17995
- import * as fs40 from "fs";
17996
- import * as path41 from "path";
18321
+ import * as fs41 from "fs";
18322
+ import * as path42 from "path";
17997
18323
  import { JobStatus } from "@bnbagent/sdk";
17998
18324
  import {
17999
18325
  buyWorkflow,
@@ -18097,8 +18423,8 @@ function applyProjectRoot2(root) {
18097
18423
  if (root === void 0) {
18098
18424
  return null;
18099
18425
  }
18100
- const p = path41.resolve(root);
18101
- if (!fs40.existsSync(path41.join(p, "studio.toml"))) {
18426
+ const p = path42.resolve(root);
18427
+ if (!fs41.existsSync(path42.join(p, "studio.toml"))) {
18102
18428
  printErr(`error: no studio.toml under --project-root ${p}`);
18103
18429
  return 2;
18104
18430
  }
@@ -18183,7 +18509,7 @@ function parseQuoteEnvelope(raw) {
18183
18509
  let text2 = trimmed;
18184
18510
  if (!trimmed.startsWith("{")) {
18185
18511
  try {
18186
- text2 = fs40.readFileSync(trimmed, "utf-8");
18512
+ text2 = fs41.readFileSync(trimmed, "utf-8");
18187
18513
  } catch (exc) {
18188
18514
  throw new Error(
18189
18515
  `--quote-json is neither inline JSON nor a readable file: ${errMsg5(exc)}`
@@ -18363,9 +18689,9 @@ async function cmdSettle(jobId, opts) {
18363
18689
  }
18364
18690
 
18365
18691
  // src/cli/skills.ts
18366
- import * as fs41 from "fs";
18692
+ import * as fs42 from "fs";
18367
18693
  import * as os6 from "os";
18368
- import * as path42 from "path";
18694
+ import * as path43 from "path";
18369
18695
  import { Option as Option7 } from "commander";
18370
18696
  function registerSkills(program) {
18371
18697
  const skills = program.command("skills").description("Install Claude Code skills into the host IDE.").action(
@@ -18411,7 +18737,7 @@ function cmdList4() {
18411
18737
  for (const p of listSourceSkills(
18412
18738
  SKILLS_SOURCE
18413
18739
  )) {
18414
- printOut(path42.basename(p));
18740
+ printOut(path43.basename(p));
18415
18741
  }
18416
18742
  const refs = listSourceReferences(
18417
18743
  SKILLS_SOURCE
@@ -18422,7 +18748,7 @@ function cmdList4() {
18422
18748
  references (installed under ${ROUTER_SKILL_NAME}/references/, loaded on demand by the skills above):`
18423
18749
  );
18424
18750
  for (const p of refs) {
18425
- printOut(` ${path42.basename(p)}`);
18751
+ printOut(` ${path43.basename(p)}`);
18426
18752
  }
18427
18753
  }
18428
18754
  return 0;
@@ -18634,7 +18960,7 @@ function installTargets(targets, scope) {
18634
18960
  );
18635
18961
  for (const name of result.legacyPresent) {
18636
18962
  const leaf = result.target === "cursor" ? `${name}.mdc` : name;
18637
- printErr(` - ${path42.join(result.targetDir, leaf)}`);
18963
+ printErr(` - ${path43.join(result.targetDir, leaf)}`);
18638
18964
  }
18639
18965
  printErr(
18640
18966
  "\nThese are NOT auto-deleted (studio never touches user resources).\nRemove with `rm -rf <path>` once you confirm none of them are\ncarrying local edits you want to keep."
@@ -18647,19 +18973,19 @@ function studioSkillNames() {
18647
18973
  for (const p of listSourceSkills(
18648
18974
  SKILLS_SOURCE
18649
18975
  )) {
18650
- names.add(path42.basename(p).replace(/\.md$/, ""));
18976
+ names.add(path43.basename(p).replace(/\.md$/, ""));
18651
18977
  }
18652
18978
  for (const name of LEGACY_SKILL_NAMES) {
18653
18979
  names.add(name);
18654
18980
  }
18655
- const providersRoot = path42.join(bundledRecipesRoot(), "providers");
18981
+ const providersRoot = path43.join(bundledRecipesRoot(), "providers");
18656
18982
  if (isDir9(providersRoot)) {
18657
- for (const provider of fs41.readdirSync(providersRoot)) {
18658
- const skillDir = path42.join(providersRoot, provider, "skills");
18983
+ for (const provider of fs42.readdirSync(providersRoot)) {
18984
+ const skillDir = path43.join(providersRoot, provider, "skills");
18659
18985
  if (!isDir9(skillDir)) {
18660
18986
  continue;
18661
18987
  }
18662
- for (const md of fs41.readdirSync(skillDir)) {
18988
+ for (const md of fs42.readdirSync(skillDir)) {
18663
18989
  if (md.endsWith(".md")) {
18664
18990
  names.add(md.replace(/\.md$/, ""));
18665
18991
  }
@@ -18670,14 +18996,14 @@ function studioSkillNames() {
18670
18996
  }
18671
18997
  function isDir9(p) {
18672
18998
  try {
18673
- return fs41.statSync(p).isDirectory();
18999
+ return fs42.statSync(p).isDirectory();
18674
19000
  } catch {
18675
19001
  return false;
18676
19002
  }
18677
19003
  }
18678
- function isFile17(p) {
19004
+ function isFile18(p) {
18679
19005
  try {
18680
- return fs41.statSync(p).isFile();
19006
+ return fs42.statSync(p).isFile();
18681
19007
  } catch {
18682
19008
  return false;
18683
19009
  }
@@ -18691,26 +19017,26 @@ function findInstalledSkills(knownNames) {
18691
19017
  if (!isDir9(root)) {
18692
19018
  return;
18693
19019
  }
18694
- const resolved = fs41.realpathSync(root);
18695
- if (!roots.some((r) => fs41.realpathSync(r) === resolved)) {
19020
+ const resolved = fs42.realpathSync(root);
19021
+ if (!roots.some((r) => fs42.realpathSync(r) === resolved)) {
18696
19022
  roots.push(root);
18697
19023
  }
18698
19024
  };
18699
- addRoot(path42.join(home, ".claude", "skills"));
18700
- addRoot(path42.join(home, ".cursor", "rules"));
18701
- addRoot(path42.join(cwd, ".claude", "skills"));
18702
- addRoot(path42.join(cwd, ".cursor", "rules"));
19025
+ addRoot(path43.join(home, ".claude", "skills"));
19026
+ addRoot(path43.join(home, ".cursor", "rules"));
19027
+ addRoot(path43.join(cwd, ".claude", "skills"));
19028
+ addRoot(path43.join(cwd, ".cursor", "rules"));
18703
19029
  for (const root of roots) {
18704
- const isCursor = path42.basename(root) === "rules" && path42.basename(path42.dirname(root)) === ".cursor";
19030
+ const isCursor = path43.basename(root) === "rules" && path43.basename(path43.dirname(root)) === ".cursor";
18705
19031
  for (const name of [...knownNames].sort()) {
18706
- const target = path42.join(root, isCursor ? `${name}.mdc` : name);
18707
- if (isCursor && isFile17(target)) {
19032
+ const target = path43.join(root, isCursor ? `${name}.mdc` : name);
19033
+ if (isCursor && isFile18(target)) {
18708
19034
  found.push(target);
18709
19035
  } else if (!isCursor && isDir9(target)) {
18710
19036
  found.push(target);
18711
19037
  }
18712
- if (isCursor && isDir9(path42.join(root, name))) {
18713
- found.push(path42.join(root, name));
19038
+ if (isCursor && isDir9(path43.join(root, name))) {
19039
+ found.push(path43.join(root, name));
18714
19040
  }
18715
19041
  }
18716
19042
  }
@@ -18738,7 +19064,7 @@ async function cmdUninstall(flags) {
18738
19064
  }
18739
19065
  }
18740
19066
  for (const p of installed) {
18741
- fs41.rmSync(p, { recursive: true, force: true });
19067
+ fs42.rmSync(p, { recursive: true, force: true });
18742
19068
  printOut(` removed: ${p}`);
18743
19069
  }
18744
19070
  }
@@ -18777,7 +19103,7 @@ function registerUninstall(program) {
18777
19103
  }
18778
19104
 
18779
19105
  // src/cli/platform.ts
18780
- import * as path43 from "path";
19106
+ import * as path44 from "path";
18781
19107
  import {
18782
19108
  STUDIO_TOML as STUDIO_TOML2,
18783
19109
  findSubProjectRoot as findSubProjectRoot18,
@@ -18980,7 +19306,7 @@ function localPlatformCfg() {
18980
19306
  if (agentRoot2 === null) {
18981
19307
  return [null, {}];
18982
19308
  }
18983
- const tomlPath = path43.join(agentRoot2, STUDIO_TOML2);
19309
+ const tomlPath = path44.join(agentRoot2, STUDIO_TOML2);
18984
19310
  let cfg;
18985
19311
  try {
18986
19312
  cfg = loadStudioToml23(tomlPath);
@@ -19053,8 +19379,8 @@ function formatRemaining(seconds) {
19053
19379
  }
19054
19380
 
19055
19381
  // src/cli/recipe.ts
19056
- import * as fs42 from "fs";
19057
- import * as path44 from "path";
19382
+ import * as fs43 from "fs";
19383
+ import * as path45 from "path";
19058
19384
  import { parse as parse6 } from "smol-toml";
19059
19385
  function registerRecipe(program) {
19060
19386
  const p = program.command("recipe").description("Print recipe code/files (agent / wallet / 8004).");
@@ -19184,7 +19510,7 @@ function resolvePkgContext(explicit) {
19184
19510
  let data;
19185
19511
  try {
19186
19512
  data = parse6(
19187
- fs42.readFileSync(path44.join(projectRoot, "studio.toml"), "utf-8")
19513
+ fs43.readFileSync(path45.join(projectRoot, "studio.toml"), "utf-8")
19188
19514
  );
19189
19515
  } catch {
19190
19516
  return [null, null];
@@ -19202,8 +19528,8 @@ function resolvePkgContext(explicit) {
19202
19528
  }
19203
19529
 
19204
19530
  // src/cli/scan.ts
19205
- import * as fs43 from "fs";
19206
- import * as path45 from "path";
19531
+ import * as fs44 from "fs";
19532
+ import * as path46 from "path";
19207
19533
  import { Option as Option8 } from "commander";
19208
19534
  import { parse as parse7 } from "smol-toml";
19209
19535
  function registerScan(program) {
@@ -19220,7 +19546,7 @@ function registerScan(program) {
19220
19546
  "note: `--json` is deprecated (JSON is the default output); ignoring."
19221
19547
  );
19222
19548
  }
19223
- const root = path45.resolve(opts.path ?? process.cwd());
19549
+ const root = path46.resolve(opts.path ?? process.cwd());
19224
19550
  const report = scanProject(root);
19225
19551
  if (opts.text) {
19226
19552
  process.stdout.write(formatText(report));
@@ -19232,26 +19558,26 @@ function registerScan(program) {
19232
19558
  })
19233
19559
  );
19234
19560
  }
19235
- function isFile18(p) {
19561
+ function isFile19(p) {
19236
19562
  try {
19237
- return fs43.statSync(p).isFile();
19563
+ return fs44.statSync(p).isFile();
19238
19564
  } catch {
19239
19565
  return false;
19240
19566
  }
19241
19567
  }
19242
19568
  function isDir10(p) {
19243
19569
  try {
19244
- return fs43.statSync(p).isDirectory();
19570
+ return fs44.statSync(p).isDirectory();
19245
19571
  } catch {
19246
19572
  return false;
19247
19573
  }
19248
19574
  }
19249
19575
  function layerBase(root) {
19250
- return isDir10(path45.join(root, "app", "agent")) ? path45.join(root, "app") : root;
19576
+ return isDir10(path46.join(root, "app", "agent")) ? path46.join(root, "app") : root;
19251
19577
  }
19252
19578
  function safeReadJson(p) {
19253
19579
  try {
19254
- const data = JSON.parse(fs43.readFileSync(p, "utf-8"));
19580
+ const data = JSON.parse(fs44.readFileSync(p, "utf-8"));
19255
19581
  return data !== null && typeof data === "object" && !Array.isArray(data) ? data : null;
19256
19582
  } catch {
19257
19583
  return null;
@@ -19259,7 +19585,7 @@ function safeReadJson(p) {
19259
19585
  }
19260
19586
  function safeReadToml(p) {
19261
19587
  try {
19262
- return parse7(fs43.readFileSync(p, "utf-8"));
19588
+ return parse7(fs44.readFileSync(p, "utf-8"));
19263
19589
  } catch {
19264
19590
  return null;
19265
19591
  }
@@ -19289,33 +19615,33 @@ function resolvePackageName(projectName2, root) {
19289
19615
  if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(candidate)) {
19290
19616
  return null;
19291
19617
  }
19292
- if (!isDir10(path45.join(root, candidate))) {
19618
+ if (!isDir10(path46.join(root, candidate))) {
19293
19619
  return null;
19294
19620
  }
19295
19621
  return candidate;
19296
19622
  }
19297
19623
  function inferLayout(root) {
19298
- const agentDir = path45.join(layerBase(root), "agent");
19299
- const hasAgent = isFile18(path45.join(agentDir, "main.ts")) || isFile18(path45.join(agentDir, "main.py"));
19624
+ const agentDir = path46.join(layerBase(root), "agent");
19625
+ const hasAgent = isFile19(path46.join(agentDir, "main.ts")) || isFile19(path46.join(agentDir, "main.py"));
19300
19626
  return {
19301
19627
  has_agent: hasAgent,
19302
- has_agent_descriptor: isFile18(
19303
- path45.join(root, "agentcore", "agentcore.json")
19628
+ has_agent_descriptor: isFile19(
19629
+ path46.join(root, "agentcore", "agentcore.json")
19304
19630
  ),
19305
19631
  role: hasAgent ? "agent" : "none"
19306
19632
  };
19307
19633
  }
19308
19634
  function inferPackageManager(root, hasPackageJson) {
19309
- if (isFile18(path45.join(root, "pnpm-lock.yaml"))) {
19635
+ if (isFile19(path46.join(root, "pnpm-lock.yaml"))) {
19310
19636
  return "pnpm";
19311
19637
  }
19312
- if (isFile18(path45.join(root, "yarn.lock"))) {
19638
+ if (isFile19(path46.join(root, "yarn.lock"))) {
19313
19639
  return "yarn";
19314
19640
  }
19315
- if (isFile18(path45.join(root, "bun.lockb"))) {
19641
+ if (isFile19(path46.join(root, "bun.lockb"))) {
19316
19642
  return "bun";
19317
19643
  }
19318
- if (isFile18(path45.join(root, "package-lock.json"))) {
19644
+ if (isFile19(path46.join(root, "package-lock.json"))) {
19319
19645
  return "npm";
19320
19646
  }
19321
19647
  if (hasPackageJson) {
@@ -19328,7 +19654,7 @@ function inferRecipes(root, studioData, layout) {
19328
19654
  if (layout.has_agent) {
19329
19655
  recipes.push("agent");
19330
19656
  }
19331
- const walletsDir = path45.join(root, ".studio", "wallets");
19657
+ const walletsDir = path46.join(root, ".studio", "wallets");
19332
19658
  const walletSection = studioData?.wallet;
19333
19659
  const hasWalletSection = walletSection !== null && typeof walletSection === "object" && !Array.isArray(walletSection);
19334
19660
  if (isDir10(walletsDir) && hasWalletSection) {
@@ -19337,13 +19663,13 @@ function inferRecipes(root, studioData, layout) {
19337
19663
  return recipes;
19338
19664
  }
19339
19665
  function scanProject(root) {
19340
- const studioToml = path45.join(root, "studio.toml");
19341
- const packageJson = path45.join(root, "package.json");
19342
- const agentcoreJson = path45.join(root, "agentcore", "agentcore.json");
19343
- const hasStudioToml = isFile18(studioToml);
19344
- const hasPackageJson = isFile18(packageJson);
19345
- const hasAgentcoreJson = isFile18(agentcoreJson);
19346
- const hasDotStudioDir = isDir10(path45.join(root, ".studio"));
19666
+ const studioToml = path46.join(root, "studio.toml");
19667
+ const packageJson = path46.join(root, "package.json");
19668
+ const agentcoreJson = path46.join(root, "agentcore", "agentcore.json");
19669
+ const hasStudioToml = isFile19(studioToml);
19670
+ const hasPackageJson = isFile19(packageJson);
19671
+ const hasAgentcoreJson = isFile19(agentcoreJson);
19672
+ const hasDotStudioDir = isDir10(path46.join(root, ".studio"));
19347
19673
  const pkgData = hasPackageJson ? safeReadJson(packageJson) : null;
19348
19674
  const studioData = hasStudioToml ? safeReadToml(studioToml) : null;
19349
19675
  const rawName = pkgData?.name;
@@ -19400,8 +19726,8 @@ function formatText(report) {
19400
19726
  }
19401
19727
 
19402
19728
  // src/cli/x402.ts
19403
- import * as fs44 from "fs";
19404
- import * as path46 from "path";
19729
+ import * as fs45 from "fs";
19730
+ import * as path47 from "path";
19405
19731
  import { auditedOp as auditedOp4 } from "@bnbagent/studio-runtime/audit";
19406
19732
  import {
19407
19733
  envLocalPath as envLocalPath18,
@@ -19595,7 +19921,7 @@ function loadX402Policy() {
19595
19921
  }
19596
19922
  let cfg;
19597
19923
  try {
19598
- cfg = loadStudioToml24(path46.join(root, "studio.toml"));
19924
+ cfg = loadStudioToml24(path47.join(root, "studio.toml"));
19599
19925
  } catch (exc) {
19600
19926
  printErr(`error: failed to parse studio.toml: ${errMsg6(exc)}`);
19601
19927
  return null;
@@ -19609,7 +19935,7 @@ function loadSellerConfig() {
19609
19935
  return null;
19610
19936
  }
19611
19937
  try {
19612
- return [root, loadStudioToml24(path46.join(root, "studio.toml"))];
19938
+ return [root, loadStudioToml24(path47.join(root, "studio.toml"))];
19613
19939
  } catch (exc) {
19614
19940
  printErr(`error: failed to parse studio.toml: ${errMsg6(exc)}`);
19615
19941
  return null;
@@ -19655,8 +19981,8 @@ async function cmdSellInit(priceFlag) {
19655
19981
  const loaded = loadSellerConfig();
19656
19982
  if (loaded === null) return 1;
19657
19983
  const [root, cfg] = loaded;
19658
- const tomlPath = path46.join(root, "studio.toml");
19659
- const original = fs44.readFileSync(tomlPath, "utf8");
19984
+ const tomlPath = path47.join(root, "studio.toml");
19985
+ const original = fs45.readFileSync(tomlPath, "utf8");
19660
19986
  const sellerExists = hasSection(original, "payments.x402_seller");
19661
19987
  let priceUsd;
19662
19988
  try {
@@ -19674,7 +20000,7 @@ async function cmdSellInit(priceFlag) {
19674
20000
  return 1;
19675
20001
  }
19676
20002
  if (!sellerExists) {
19677
- fs44.writeFileSync(
20003
+ fs45.writeFileSync(
19678
20004
  tomlPath,
19679
20005
  updateSection(original, "payments.x402_seller", {
19680
20006
  enabled: true,
@@ -19686,7 +20012,7 @@ async function cmdSellInit(priceFlag) {
19686
20012
  "utf8"
19687
20013
  );
19688
20014
  } else if (priceFlag !== void 0) {
19689
- fs44.writeFileSync(
20015
+ fs45.writeFileSync(
19690
20016
  tomlPath,
19691
20017
  updateSection(original, "payments.x402_seller", {
19692
20018
  price_usd: priceUsd
@@ -20055,14 +20381,14 @@ async function confirmOrAbort(prompt, assumeYes) {
20055
20381
  return answer === "y" || answer === "yes";
20056
20382
  }
20057
20383
  function writeMerchantEntry(tomlPath, fields) {
20058
- const text2 = fs44.readFileSync(tomlPath, "utf-8");
20384
+ const text2 = fs45.readFileSync(tomlPath, "utf-8");
20059
20385
  const entries = {
20060
20386
  domain: fields.domain,
20061
20387
  pay_to: fields.payTo,
20062
20388
  per_call_cap_usd: fields.capUsd,
20063
20389
  verified: fields.verified
20064
20390
  };
20065
- fs44.writeFileSync(
20391
+ fs45.writeFileSync(
20066
20392
  tomlPath,
20067
20393
  updateSection(text2, `payments.x402.merchants.${fields.key}`, entries),
20068
20394
  "utf-8"
@@ -20191,7 +20517,7 @@ The merchant may have rotated its address (or the response was tampered with). U
20191
20517
  printOut("aborted \u2014 nothing written.");
20192
20518
  return 1;
20193
20519
  }
20194
- const tomlPath = path46.join(root, "studio.toml");
20520
+ const tomlPath = path47.join(root, "studio.toml");
20195
20521
  try {
20196
20522
  writeMerchantEntry(tomlPath, {
20197
20523
  key,
@@ -20254,23 +20580,23 @@ function buildProgram() {
20254
20580
  return program;
20255
20581
  }
20256
20582
  function cliVersion() {
20257
- return "0.0.6-alpha.6";
20583
+ return "0.0.6-alpha.8";
20258
20584
  }
20259
20585
 
20260
20586
  // src/cli/updateCheck.ts
20261
- import * as fs45 from "fs";
20587
+ import * as fs46 from "fs";
20262
20588
  import * as os7 from "os";
20263
- import * as path47 from "path";
20589
+ import * as path48 from "path";
20264
20590
  var PACKAGE = "@bnbagent/studio-cli";
20265
20591
  var REGISTRY_LATEST_URL = `https://registry.npmjs.org/${PACKAGE}/latest`;
20266
20592
  var CHECK_INTERVAL_SECONDS = 24 * 3600;
20267
20593
  var TIMEOUT_MS = 2e3;
20268
20594
  function cachePath(home) {
20269
- return path47.join(home, ".bag", "update-check.json");
20595
+ return path48.join(home, ".bag", "update-check.json");
20270
20596
  }
20271
20597
  function loadCache(home) {
20272
20598
  try {
20273
- const data = JSON.parse(fs45.readFileSync(cachePath(home), "utf-8"));
20599
+ const data = JSON.parse(fs46.readFileSync(cachePath(home), "utf-8"));
20274
20600
  return data !== null && typeof data === "object" && !Array.isArray(data) ? data : {};
20275
20601
  } catch {
20276
20602
  return {};
@@ -20279,8 +20605,8 @@ function loadCache(home) {
20279
20605
  function saveCache(state, home) {
20280
20606
  try {
20281
20607
  const p = cachePath(home);
20282
- fs45.mkdirSync(path47.dirname(p), { recursive: true });
20283
- fs45.writeFileSync(p, `${JSON.stringify(state, null, 2)}
20608
+ fs46.mkdirSync(path48.dirname(p), { recursive: true });
20609
+ fs46.writeFileSync(p, `${JSON.stringify(state, null, 2)}
20284
20610
  `);
20285
20611
  } catch {
20286
20612
  }