@bnbagent/studio-cli 0.0.6-alpha.7 → 0.0.6-alpha.9

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,
@@ -4361,7 +4533,17 @@ function printUBalanceShortfall(walletAddress, currentRaw, neededRaw, neededUsd,
4361
4533
  function writeEnvLocal(key, value, envPath = ".env.local") {
4362
4534
  return setEnvVar(envPath, key, value);
4363
4535
  }
4536
+ function ensureSiweCapable(wallet) {
4537
+ const probe = wallet.supports;
4538
+ if (typeof probe !== "function") return;
4539
+ if (probe.call(wallet, "sign.message")) return;
4540
+ const kind = wallet.kind;
4541
+ throw new PieverseCliError(
4542
+ `the ${kind ? `'${kind}' ` : ""}wallet cannot log in to Pieverse: SIWE requires an EIP-191 personal-sign ('sign.message'), which this wallet kind never supports. Pieverse LLM is not usable with this wallet \u2014 set [llm].provider in studio.toml to 'openrouter', 'openai', or 'anthropic' (with the matching API key in .studio/.env.local), or use an 'evm-local' or 'twak' wallet.`
4543
+ );
4544
+ }
4364
4545
  async function withSiweRetry(wallet, call, opts = {}) {
4546
+ ensureSiweCapable(wallet);
4365
4547
  let token = opts.sessionToken ?? await siweLogin(wallet);
4366
4548
  try {
4367
4549
  return await call(token);
@@ -4548,7 +4730,7 @@ function loadFullCfg() {
4548
4730
  }
4549
4731
  let cfg;
4550
4732
  try {
4551
- cfg = loadStudioToml8(path17.join(root, "studio.toml"));
4733
+ cfg = loadStudioToml8(path18.join(root, "studio.toml"));
4552
4734
  } catch (exc) {
4553
4735
  printErr(`error: failed to parse studio.toml: ${errMessage(exc)}`);
4554
4736
  return null;
@@ -4629,6 +4811,15 @@ async function cmdActivate(opts) {
4629
4811
  if (wallet === null) {
4630
4812
  return 2;
4631
4813
  }
4814
+ try {
4815
+ ensureSiweCapable(wallet);
4816
+ } catch (exc) {
4817
+ if (exc instanceof PieverseCliError) {
4818
+ printErr(`error: ${exc.message}`);
4819
+ return 2;
4820
+ }
4821
+ throw exc;
4822
+ }
4632
4823
  const pvCfg = loadPieverseConfig(cfg);
4633
4824
  const replace = opts.replace === true;
4634
4825
  let existingHash = !replace && pvCfg.key_hash ? String(pvCfg.key_hash) : null;
@@ -4652,6 +4843,10 @@ async function cmdActivate(opts) {
4652
4843
  try {
4653
4844
  await withSiweRetry(wallet, (token) => inspectKey(token, derivedHash));
4654
4845
  } catch (exc) {
4846
+ if (exc instanceof PieverseCliError) {
4847
+ printErr(`error: ${exc.message}`);
4848
+ return 2;
4849
+ }
4655
4850
  if (!(exc instanceof PieverseKeyNotFoundError)) {
4656
4851
  printErr(
4657
4852
  `error: could not verify the existing ${PIEVERSE_ENV_KEY} against Pieverse: ${errMessage(
@@ -4910,9 +5105,9 @@ Retry: re-run \`bag llm activate\` \u2014 key_hash is saved so it will pick up w
4910
5105
  return 0;
4911
5106
  }
4912
5107
  function updateStudioTomlSection(root, section, updates) {
4913
- const tomlPath = path17.join(root, "studio.toml");
4914
- const text2 = fs18.readFileSync(tomlPath, "utf-8");
4915
- fs18.writeFileSync(tomlPath, updateSection(text2, section, updates), "utf-8");
5108
+ const tomlPath = path18.join(root, "studio.toml");
5109
+ const text2 = fs19.readFileSync(tomlPath, "utf-8");
5110
+ fs19.writeFileSync(tomlPath, updateSection(text2, section, updates), "utf-8");
4916
5111
  }
4917
5112
  function cumulativeTopupsUsd() {
4918
5113
  let total = 0;
@@ -5461,8 +5656,8 @@ function normalizeNodeDeps(deps) {
5461
5656
  }
5462
5657
 
5463
5658
  // src/cli/recipes/loader.ts
5464
- import * as fs19 from "fs";
5465
- import * as path18 from "path";
5659
+ import * as fs20 from "fs";
5660
+ import * as path19 from "path";
5466
5661
  import { fileURLToPath as fileURLToPath3 } from "url";
5467
5662
  import { parse as parse5 } from "smol-toml";
5468
5663
  var PLACEHOLDER_RE = /\{\{\s*([A-Za-z_][A-Za-z0-9_]*)\s*\}\}/g;
@@ -5471,12 +5666,12 @@ function bundledRecipesRoot() {
5471
5666
  if (override) {
5472
5667
  return override;
5473
5668
  }
5474
- let dir = path18.dirname(fileURLToPath3(import.meta.url));
5669
+ let dir = path19.dirname(fileURLToPath3(import.meta.url));
5475
5670
  for (; ; ) {
5476
- if (fs19.existsSync(path18.join(dir, "package.json"))) {
5477
- return path18.join(dir, "recipes");
5671
+ if (fs20.existsSync(path19.join(dir, "package.json"))) {
5672
+ return path19.join(dir, "recipes");
5478
5673
  }
5479
- const parent = path18.dirname(dir);
5674
+ const parent = path19.dirname(dir);
5480
5675
  if (parent === dir) {
5481
5676
  throw new Error("cannot locate the studio-cli package root");
5482
5677
  }
@@ -5500,24 +5695,24 @@ function defaultMode(recipe) {
5500
5695
  }
5501
5696
  function listRecipes(root) {
5502
5697
  const base = root ?? bundledRecipesRoot();
5503
- if (!fs19.existsSync(base)) {
5698
+ if (!fs20.existsSync(base)) {
5504
5699
  return [];
5505
5700
  }
5506
- return fs19.readdirSync(base).filter(
5507
- (name) => !name.startsWith("_") && fs19.existsSync(path18.join(base, name, "recipe.toml")) && fs19.statSync(path18.join(base, name)).isDirectory()
5701
+ return fs20.readdirSync(base).filter(
5702
+ (name) => !name.startsWith("_") && fs20.existsSync(path19.join(base, name, "recipe.toml")) && fs20.statSync(path19.join(base, name)).isDirectory()
5508
5703
  ).sort();
5509
5704
  }
5510
5705
  var RecipeModeError = class extends Error {
5511
5706
  };
5512
5707
  function loadRecipe(name, opts = {}) {
5513
5708
  const base = opts.root ?? bundledRecipesRoot();
5514
- const recipeDir = path18.join(base, name);
5515
- const tomlPath = path18.join(recipeDir, "recipe.toml");
5516
- if (!fs19.existsSync(tomlPath) || !fs19.statSync(tomlPath).isFile()) {
5709
+ const recipeDir = path19.join(base, name);
5710
+ const tomlPath = path19.join(recipeDir, "recipe.toml");
5711
+ if (!fs20.existsSync(tomlPath) || !fs20.statSync(tomlPath).isFile()) {
5517
5712
  throw new Error(`Recipe '${name}' not found at ${tomlPath}`);
5518
5713
  }
5519
- const metadata = parse5(fs19.readFileSync(tomlPath, "utf-8"));
5520
- const allFiles = collectTemplateFiles(path18.join(recipeDir, "code"));
5714
+ const metadata = parse5(fs20.readFileSync(tomlPath, "utf-8"));
5715
+ const allFiles = collectTemplateFiles(path19.join(recipeDir, "code"));
5521
5716
  const modesMeta = metaTable(metadata, "modes");
5522
5717
  const mode = opts.mode ?? null;
5523
5718
  if (Object.keys(modesMeta).length === 0) {
@@ -5564,22 +5759,22 @@ function modeFiles(modesMeta, modeName) {
5564
5759
  return Array.isArray(files) ? files.filter((f) => typeof f === "string") : [];
5565
5760
  }
5566
5761
  function collectTemplateFiles(codeDir) {
5567
- if (!fs19.existsSync(codeDir) || !fs19.statSync(codeDir).isDirectory()) {
5762
+ if (!fs20.existsSync(codeDir) || !fs20.statSync(codeDir).isDirectory()) {
5568
5763
  return [];
5569
5764
  }
5570
5765
  const out = [];
5571
5766
  const walk = (dir) => {
5572
- for (const name of fs19.readdirSync(dir).sort()) {
5573
- const full = path18.join(dir, name);
5574
- if (fs19.statSync(full).isDirectory()) {
5767
+ for (const name of fs20.readdirSync(dir).sort()) {
5768
+ const full = path19.join(dir, name);
5769
+ if (fs20.statSync(full).isDirectory()) {
5575
5770
  walk(full);
5576
5771
  } else {
5577
- const rel = path18.relative(codeDir, full);
5772
+ const rel = path19.relative(codeDir, full);
5578
5773
  const target = rel.endsWith(".tmpl") ? rel.slice(0, -".tmpl".length) : rel;
5579
5774
  out.push({
5580
5775
  // Recipes use forward slashes regardless of host OS.
5581
- targetPath: target.split(path18.sep).join("/"),
5582
- content: fs19.readFileSync(full, "utf-8")
5776
+ targetPath: target.split(path19.sep).join("/"),
5777
+ content: fs20.readFileSync(full, "utf-8")
5583
5778
  });
5584
5779
  }
5585
5780
  }
@@ -5646,9 +5841,9 @@ function renderRecipe(recipe, opts = {}) {
5646
5841
 
5647
5842
  // src/cli/skillsInstaller.ts
5648
5843
  import * as crypto3 from "crypto";
5649
- import * as fs20 from "fs";
5844
+ import * as fs21 from "fs";
5650
5845
  import * as os2 from "os";
5651
- import * as path19 from "path";
5846
+ import * as path20 from "path";
5652
5847
  import { fileURLToPath as fileURLToPath4 } from "url";
5653
5848
  var SUPPORTED_TARGETS = ["claude-code", "cursor"];
5654
5849
  var SUPPORTED_SCOPES = ["user", "project"];
@@ -5695,14 +5890,14 @@ var HIDDEN_SKILL_NAMES = /* @__PURE__ */ new Set([
5695
5890
  ]);
5696
5891
  function isDir3(p) {
5697
5892
  try {
5698
- return fs20.statSync(p).isDirectory();
5893
+ return fs21.statSync(p).isDirectory();
5699
5894
  } catch {
5700
5895
  return false;
5701
5896
  }
5702
5897
  }
5703
- function isFile6(p) {
5898
+ function isFile7(p) {
5704
5899
  try {
5705
- return fs20.statSync(p).isFile();
5900
+ return fs21.statSync(p).isFile();
5706
5901
  } catch {
5707
5902
  return false;
5708
5903
  }
@@ -5712,15 +5907,15 @@ function sha256(text2) {
5712
5907
  }
5713
5908
  function resolveSkillsSource() {
5714
5909
  const pkgRoot = packageRoot2();
5715
- return pkgRoot !== null ? path19.join(pkgRoot, "skills") : path19.join(path19.dirname(fileURLToPath4(import.meta.url)), "skills");
5910
+ return pkgRoot !== null ? path20.join(pkgRoot, "skills") : path20.join(path20.dirname(fileURLToPath4(import.meta.url)), "skills");
5716
5911
  }
5717
5912
  function packageRoot2() {
5718
- let dir = path19.dirname(fileURLToPath4(import.meta.url));
5913
+ let dir = path20.dirname(fileURLToPath4(import.meta.url));
5719
5914
  for (; ; ) {
5720
- if (fs20.existsSync(path19.join(dir, "package.json"))) {
5915
+ if (fs21.existsSync(path20.join(dir, "package.json"))) {
5721
5916
  return dir;
5722
5917
  }
5723
- const parent = path19.dirname(dir);
5918
+ const parent = path20.dirname(dir);
5724
5919
  if (parent === dir) {
5725
5920
  return null;
5726
5921
  }
@@ -5732,18 +5927,18 @@ function listSourceSkills(source) {
5732
5927
  if (!isDir3(source)) {
5733
5928
  return [];
5734
5929
  }
5735
- return fs20.readdirSync(source).filter(
5736
- (name) => name.endsWith(".md") && !name.startsWith("_") && !HIDDEN_SKILL_NAMES.has(stem(name)) && isFile6(path19.join(source, name))
5737
- ).sort().map((name) => path19.join(source, name));
5930
+ return fs21.readdirSync(source).filter(
5931
+ (name) => name.endsWith(".md") && !name.startsWith("_") && !HIDDEN_SKILL_NAMES.has(stem(name)) && isFile7(path20.join(source, name))
5932
+ ).sort().map((name) => path20.join(source, name));
5738
5933
  }
5739
5934
  function listSourceReferences(source) {
5740
- const refs = path19.join(source, "references");
5935
+ const refs = path20.join(source, "references");
5741
5936
  if (!isDir3(refs)) {
5742
5937
  return [];
5743
5938
  }
5744
- return fs20.readdirSync(refs).filter(
5745
- (name) => name.endsWith(".md") && !name.startsWith("_") && !HIDDEN_SKILL_NAMES.has(stem(name)) && isFile6(path19.join(refs, name))
5746
- ).sort().map((name) => path19.join(refs, name));
5939
+ return fs21.readdirSync(refs).filter(
5940
+ (name) => name.endsWith(".md") && !name.startsWith("_") && !HIDDEN_SKILL_NAMES.has(stem(name)) && isFile7(path20.join(refs, name))
5941
+ ).sort().map((name) => path20.join(refs, name));
5747
5942
  }
5748
5943
  function stem(fileName) {
5749
5944
  return fileName.replace(/\.[^.]+$/, "");
@@ -5751,15 +5946,15 @@ function stem(fileName) {
5751
5946
  function whichSync(name) {
5752
5947
  const pathEnv = process.env.PATH ?? "";
5753
5948
  const exts = process.platform === "win32" ? ["", ".cmd", ".exe", ".bat"] : [""];
5754
- for (const dir of pathEnv.split(path19.delimiter)) {
5949
+ for (const dir of pathEnv.split(path20.delimiter)) {
5755
5950
  if (!dir) {
5756
5951
  continue;
5757
5952
  }
5758
5953
  for (const ext of exts) {
5759
- const candidate = path19.join(dir, name + ext);
5954
+ const candidate = path20.join(dir, name + ext);
5760
5955
  try {
5761
- fs20.accessSync(candidate, fs20.constants.X_OK);
5762
- if (fs20.statSync(candidate).isFile()) {
5956
+ fs21.accessSync(candidate, fs21.constants.X_OK);
5957
+ if (fs21.statSync(candidate).isFile()) {
5763
5958
  return candidate;
5764
5959
  }
5765
5960
  } catch {
@@ -5770,14 +5965,14 @@ function whichSync(name) {
5770
5965
  }
5771
5966
  function claudeCodeInstalled(opts = {}) {
5772
5967
  const home = opts.home ?? os2.homedir();
5773
- if (isDir3(path19.join(home, ".claude"))) {
5968
+ if (isDir3(path20.join(home, ".claude"))) {
5774
5969
  return true;
5775
5970
  }
5776
5971
  return (opts.which ?? whichSync)("claude") !== null;
5777
5972
  }
5778
5973
  function cursorInstalled(opts = {}) {
5779
5974
  const home = opts.home ?? os2.homedir();
5780
- if (isDir3(path19.join(home, ".cursor"))) {
5975
+ if (isDir3(path20.join(home, ".cursor"))) {
5781
5976
  return true;
5782
5977
  }
5783
5978
  return (opts.which ?? whichSync)("cursor") !== null;
@@ -5800,9 +5995,9 @@ function anySkillsInstalled(opts = {}) {
5800
5995
  for (const target of detectTargets(opts)) {
5801
5996
  const tdir = resolveTargetDir({ target, scope: "user", home: opts.home });
5802
5997
  for (const skill of sources) {
5803
- const name = stem(path19.basename(skill));
5804
- const rel = target === "claude-code" ? path19.join(name, "SKILL.md") : `${name}.mdc`;
5805
- if (isFile6(path19.join(tdir, rel))) {
5998
+ const name = stem(path20.basename(skill));
5999
+ const rel = target === "claude-code" ? path20.join(name, "SKILL.md") : `${name}.mdc`;
6000
+ if (isFile7(path20.join(tdir, rel))) {
5806
6001
  return true;
5807
6002
  }
5808
6003
  }
@@ -5827,7 +6022,7 @@ function resolveTargetDir(opts) {
5827
6022
  }
5828
6023
  const base = scope === "user" ? opts.home ?? os2.homedir() : opts.projectRoot ?? process.cwd();
5829
6024
  const [d1, d2] = TARGET_SUBDIR[target];
5830
- return path19.join(base, d1, d2);
6025
+ return path20.join(base, d1, d2);
5831
6026
  }
5832
6027
  function splitFrontmatter(text2) {
5833
6028
  const lines = text2.split("\n");
@@ -5885,16 +6080,16 @@ function iterRenderedPayloads(src, target) {
5885
6080
  for (const skill of listSourceSkills(src)) {
5886
6081
  payloads.push(
5887
6082
  renderSkillPayload(
5888
- fs20.readFileSync(skill, "utf-8"),
5889
- stem(path19.basename(skill)),
6083
+ fs21.readFileSync(skill, "utf-8"),
6084
+ stem(path20.basename(skill)),
5890
6085
  target
5891
6086
  )
5892
6087
  );
5893
6088
  }
5894
6089
  for (const ref of listSourceReferences(src)) {
5895
6090
  payloads.push([
5896
- `${ROUTER_SKILL_NAME}/references/${path19.basename(ref)}`,
5897
- fs20.readFileSync(ref, "utf-8")
6091
+ `${ROUTER_SKILL_NAME}/references/${path20.basename(ref)}`,
6092
+ fs21.readFileSync(ref, "utf-8")
5898
6093
  ]);
5899
6094
  }
5900
6095
  return payloads;
@@ -5906,7 +6101,7 @@ function packageVersion() {
5906
6101
  return "unknown";
5907
6102
  }
5908
6103
  const pkg = JSON.parse(
5909
- fs20.readFileSync(path19.join(root, "package.json"), "utf-8")
6104
+ fs21.readFileSync(path20.join(root, "package.json"), "utf-8")
5910
6105
  );
5911
6106
  return typeof pkg.version === "string" ? pkg.version : "unknown";
5912
6107
  } catch {
@@ -5925,11 +6120,11 @@ function contentKey(payloads) {
5925
6120
  return h.digest("hex");
5926
6121
  }
5927
6122
  function metaPath(tdir) {
5928
- return path19.join(tdir, ROUTER_SKILL_NAME, META_FILENAME);
6123
+ return path20.join(tdir, ROUTER_SKILL_NAME, META_FILENAME);
5929
6124
  }
5930
6125
  function loadMeta(tdir) {
5931
6126
  try {
5932
- const data = JSON.parse(fs20.readFileSync(metaPath(tdir), "utf-8"));
6127
+ const data = JSON.parse(fs21.readFileSync(metaPath(tdir), "utf-8"));
5933
6128
  return data !== null && typeof data === "object" && !Array.isArray(data) ? data : null;
5934
6129
  } catch {
5935
6130
  return null;
@@ -5946,15 +6141,15 @@ function writeMeta(tdir, payloads) {
5946
6141
  package_version: packageVersion()
5947
6142
  };
5948
6143
  const p = metaPath(tdir);
5949
- fs20.mkdirSync(path19.dirname(p), { recursive: true });
5950
- fs20.writeFileSync(p, `${JSON.stringify(meta, null, 2)}
6144
+ fs21.mkdirSync(path20.dirname(p), { recursive: true });
6145
+ fs21.writeFileSync(p, `${JSON.stringify(meta, null, 2)}
5951
6146
  `);
5952
6147
  }
5953
6148
  function installedMarker(tdir, target) {
5954
6149
  if (target === "cursor") {
5955
- return path19.join(tdir, `${ROUTER_SKILL_NAME}.mdc`);
6150
+ return path20.join(tdir, `${ROUTER_SKILL_NAME}.mdc`);
5956
6151
  }
5957
- return path19.join(tdir, ROUTER_SKILL_NAME, "SKILL.md");
6152
+ return path20.join(tdir, ROUTER_SKILL_NAME, "SKILL.md");
5958
6153
  }
5959
6154
  function syncInstalledSkills(opts = {}) {
5960
6155
  const src = opts.source ?? SKILLS_SOURCE;
@@ -5968,7 +6163,7 @@ function syncInstalledSkills(opts = {}) {
5968
6163
  home: opts.home,
5969
6164
  projectRoot: opts.projectRoot
5970
6165
  });
5971
- if (!isFile6(installedMarker(tdir, target))) {
6166
+ if (!isFile7(installedMarker(tdir, target))) {
5972
6167
  continue;
5973
6168
  }
5974
6169
  if (payloads === null) {
@@ -5991,15 +6186,15 @@ function syncOneDir(tdir, payloads) {
5991
6186
  const wrote = [];
5992
6187
  const keptEdited = [];
5993
6188
  for (const [rel, content] of payloads) {
5994
- const dest = path19.join(tdir, rel);
6189
+ const dest = path20.join(tdir, rel);
5995
6190
  const newHash = sha256(content);
5996
- const cur = isFile6(dest) ? sha256(fs20.readFileSync(dest, "utf-8")) : null;
6191
+ const cur = isFile7(dest) ? sha256(fs21.readFileSync(dest, "utf-8")) : null;
5997
6192
  if (cur === newHash) {
5998
6193
  continue;
5999
6194
  }
6000
6195
  if (cur === null || cur === recordedFiles[rel]) {
6001
- fs20.mkdirSync(path19.dirname(dest), { recursive: true });
6002
- fs20.writeFileSync(dest, content);
6196
+ fs21.mkdirSync(path20.dirname(dest), { recursive: true });
6197
+ fs21.writeFileSync(dest, content);
6003
6198
  wrote.push(rel);
6004
6199
  } else {
6005
6200
  keptEdited.push(rel);
@@ -6010,15 +6205,15 @@ function syncOneDir(tdir, payloads) {
6010
6205
  if (shipped.has(rel)) {
6011
6206
  continue;
6012
6207
  }
6013
- const dest = path19.join(tdir, rel);
6208
+ const dest = path20.join(tdir, rel);
6014
6209
  try {
6015
- if (isFile6(dest) && sha256(fs20.readFileSync(dest, "utf-8")) === recorded) {
6016
- fs20.unlinkSync(dest);
6210
+ if (isFile7(dest) && sha256(fs21.readFileSync(dest, "utf-8")) === recorded) {
6211
+ fs21.unlinkSync(dest);
6017
6212
  wrote.push(`removed ${rel}`);
6018
- let parent = path19.dirname(dest);
6019
- while (parent !== tdir && isDir3(parent) && fs20.readdirSync(parent).length === 0) {
6020
- fs20.rmdirSync(parent);
6021
- parent = path19.dirname(parent);
6213
+ let parent = path20.dirname(dest);
6214
+ while (parent !== tdir && isDir3(parent) && fs21.readdirSync(parent).length === 0) {
6215
+ fs21.rmdirSync(parent);
6216
+ parent = path20.dirname(parent);
6022
6217
  }
6023
6218
  }
6024
6219
  } catch {
@@ -6048,45 +6243,45 @@ function installSkills(opts) {
6048
6243
  projectRoot: opts.projectRoot,
6049
6244
  home: opts.home
6050
6245
  });
6051
- fs20.mkdirSync(tdir, { recursive: true });
6246
+ fs21.mkdirSync(tdir, { recursive: true });
6052
6247
  const installed = [];
6053
6248
  const skipped = [];
6054
6249
  for (const skill of skillFiles) {
6055
- const skillName = stem(path19.basename(skill));
6056
- const srcText = fs20.readFileSync(skill, "utf-8");
6250
+ const skillName = stem(path20.basename(skill));
6251
+ const srcText = fs21.readFileSync(skill, "utf-8");
6057
6252
  const [relPath, content] = renderSkillPayload(srcText, skillName, target);
6058
- const dest = path19.join(tdir, relPath);
6059
- fs20.mkdirSync(path19.dirname(dest), { recursive: true });
6060
- if (isFile6(dest) && sha256(fs20.readFileSync(dest, "utf-8")) === sha256(content)) {
6253
+ const dest = path20.join(tdir, relPath);
6254
+ fs21.mkdirSync(path20.dirname(dest), { recursive: true });
6255
+ if (isFile7(dest) && sha256(fs21.readFileSync(dest, "utf-8")) === sha256(content)) {
6061
6256
  skipped.push(skillName);
6062
6257
  } else {
6063
- fs20.writeFileSync(dest, content);
6258
+ fs21.writeFileSync(dest, content);
6064
6259
  installed.push(skillName);
6065
6260
  }
6066
6261
  if (target === "claude-code") {
6067
- const legacyFlat = path19.join(tdir, path19.basename(skill));
6068
- if (isFile6(legacyFlat)) {
6069
- fs20.unlinkSync(legacyFlat);
6262
+ const legacyFlat = path20.join(tdir, path20.basename(skill));
6263
+ if (isFile7(legacyFlat)) {
6264
+ fs21.unlinkSync(legacyFlat);
6070
6265
  }
6071
6266
  }
6072
6267
  }
6073
6268
  for (const ref of listSourceReferences(src)) {
6074
- const rel = `${ROUTER_SKILL_NAME}/references/${path19.basename(ref)}`;
6075
- const dest = path19.join(tdir, rel);
6076
- fs20.mkdirSync(path19.dirname(dest), { recursive: true });
6077
- const content = fs20.readFileSync(ref, "utf-8");
6078
- if (isFile6(dest) && sha256(fs20.readFileSync(dest, "utf-8")) === sha256(content)) {
6269
+ const rel = `${ROUTER_SKILL_NAME}/references/${path20.basename(ref)}`;
6270
+ const dest = path20.join(tdir, rel);
6271
+ fs21.mkdirSync(path20.dirname(dest), { recursive: true });
6272
+ const content = fs21.readFileSync(ref, "utf-8");
6273
+ if (isFile7(dest) && sha256(fs21.readFileSync(dest, "utf-8")) === sha256(content)) {
6079
6274
  skipped.push(rel);
6080
6275
  } else {
6081
- fs20.writeFileSync(dest, content);
6276
+ fs21.writeFileSync(dest, content);
6082
6277
  installed.push(rel);
6083
6278
  }
6084
6279
  }
6085
- if (isDir3(path19.join(tdir, ROUTER_SKILL_NAME))) {
6280
+ if (isDir3(path20.join(tdir, ROUTER_SKILL_NAME))) {
6086
6281
  writeMeta(tdir, iterRenderedPayloads(src, target));
6087
6282
  }
6088
- const legacy = target === "claude-code" ? LEGACY_SKILL_NAMES.filter((name) => isDir3(path19.join(tdir, name))) : LEGACY_SKILL_NAMES.filter(
6089
- (name) => isFile6(path19.join(tdir, `${name}.mdc`))
6283
+ const legacy = target === "claude-code" ? LEGACY_SKILL_NAMES.filter((name) => isDir3(path20.join(tdir, name))) : LEGACY_SKILL_NAMES.filter(
6284
+ (name) => isFile7(path20.join(tdir, `${name}.mdc`))
6090
6285
  );
6091
6286
  return {
6092
6287
  target,
@@ -6112,9 +6307,9 @@ function acceptChoices(option, accepted, advertised) {
6112
6307
  }
6113
6308
 
6114
6309
  // src/cli/wallet.ts
6115
- import * as fs22 from "fs";
6310
+ import * as fs23 from "fs";
6116
6311
  import * as os3 from "os";
6117
- import * as path21 from "path";
6312
+ import * as path22 from "path";
6118
6313
  import { EVMWalletProvider, SigningPolicy } from "@bnbagent/sdk";
6119
6314
  import {
6120
6315
  envLocalPath as envLocalPath10,
@@ -6124,14 +6319,16 @@ import {
6124
6319
  import { buildPolicy, buildWallet } from "@bnbagent/studio-runtime/wallet";
6125
6320
 
6126
6321
  // src/cli/walletSession.ts
6127
- import * as fs21 from "fs";
6128
- import * as path20 from "path";
6322
+ import * as fs22 from "fs";
6323
+ import * as path21 from "path";
6324
+ import { pathToFileURL } from "url";
6129
6325
  import { AltanaWalletProvider } from "@bnbagent/sdk";
6130
6326
  import { getAddress as deployedAddresses } from "@bnbagent/sdk/networks";
6131
6327
  import {
6132
6328
  defaultAgentPermissions,
6133
6329
  deserializeSession,
6134
- serializeSession
6330
+ serializeSession,
6331
+ setAltanaSdkImporter
6135
6332
  } from "@bnbagent/sdk/wallets";
6136
6333
  import { auditedOp as auditedOp2 } from "@bnbagent/studio-runtime/audit";
6137
6334
  import { loadStudioToml as loadStudioToml9 } from "@bnbagent/studio-runtime/config";
@@ -6139,7 +6336,8 @@ import { getNetwork as getNetwork5, toRaw as toRaw2 } from "@bnbagent/studio-run
6139
6336
  import { writePrivate } from "@bnbagent/studio-runtime/secretWrite";
6140
6337
  import {
6141
6338
  ALTANA_NETWORK_BY_STUDIO,
6142
- PASSWORD_ENV
6339
+ PASSWORD_ENV,
6340
+ resolveProjectAltanaSdkEntry as resolveProjectAltanaSdkEntry2
6143
6341
  } from "@bnbagent/studio-runtime/wallet";
6144
6342
  var defaultAdminFactory = (opts) => AltanaWalletProvider.adminFromKeystore(opts);
6145
6343
  var adminFactory = defaultAdminFactory;
@@ -6148,13 +6346,17 @@ function tableOf7(value) {
6148
6346
  return value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
6149
6347
  }
6150
6348
  function loadContext(projectRoot) {
6151
- const cfg = loadStudioToml9(path20.join(projectRoot, "studio.toml"));
6349
+ const cfg = loadStudioToml9(path21.join(projectRoot, "studio.toml"));
6152
6350
  const walletCfg = tableOf7(cfg.wallet);
6153
6351
  if (String(walletCfg.kind ?? "evm-local") !== "altana") {
6154
6352
  throw new Error(
6155
6353
  `wallet session commands require [wallet].kind='altana' (got ${JSON.stringify(walletCfg.kind ?? "evm-local")}).`
6156
6354
  );
6157
6355
  }
6356
+ const sdkEntry = resolveProjectAltanaSdkEntry2(projectRoot);
6357
+ setAltanaSdkImporter(
6358
+ sdkEntry === null ? null : () => import(pathToFileURL(sdkEntry).href)
6359
+ );
6158
6360
  const networkName = String(tableOf7(cfg.network).default ?? "bsc-testnet");
6159
6361
  const altanaNetwork = ALTANA_NETWORK_BY_STUDIO[networkName];
6160
6362
  if (altanaNetwork === void 0) {
@@ -6170,7 +6372,7 @@ function loadContext(projectRoot) {
6170
6372
  }
6171
6373
  const resolvePath = (value, fallback) => {
6172
6374
  const configured = String(value ?? fallback);
6173
- return path20.isAbsolute(configured) ? configured : path20.join(projectRoot, configured);
6375
+ return path21.isAbsolute(configured) ? configured : path21.join(projectRoot, configured);
6174
6376
  };
6175
6377
  return {
6176
6378
  projectRoot,
@@ -6234,7 +6436,7 @@ function parseSessionEnvelope(serialized) {
6234
6436
  function readSession(ctx) {
6235
6437
  let serialized;
6236
6438
  try {
6237
- serialized = fs21.readFileSync(ctx.sessionFile, "utf8");
6439
+ serialized = fs22.readFileSync(ctx.sessionFile, "utf8");
6238
6440
  } catch {
6239
6441
  throw new Error(
6240
6442
  `no Altana session file at ${ctx.sessionFile} \u2014 run \`bag wallet session grant\`.`
@@ -6243,8 +6445,8 @@ function readSession(ctx) {
6243
6445
  return { serialized, envelope: parseSessionEnvelope(serialized) };
6244
6446
  }
6245
6447
  function writeSession(ctx, session) {
6246
- fs21.mkdirSync(path20.dirname(ctx.sessionFile), { recursive: true, mode: 448 });
6247
- fs21.chmodSync(path20.dirname(ctx.sessionFile), 448);
6448
+ fs22.mkdirSync(path21.dirname(ctx.sessionFile), { recursive: true, mode: 448 });
6449
+ fs22.chmodSync(path21.dirname(ctx.sessionFile), 448);
6248
6450
  writePrivate(ctx.sessionFile, serializeSession(session));
6249
6451
  }
6250
6452
  function sessionKeyFingerprint(publicKey) {
@@ -6355,7 +6557,7 @@ async function cmdSessionGrant(opts) {
6355
6557
  "--budget-u"
6356
6558
  );
6357
6559
  let existing = null;
6358
- if (fs21.existsSync(ctx.sessionFile)) {
6560
+ if (fs22.existsSync(ctx.sessionFile)) {
6359
6561
  existing = readSession(ctx).envelope;
6360
6562
  if (!opts.force) {
6361
6563
  throw new Error(
@@ -6473,7 +6675,7 @@ async function cmdSessionRevoke(opts) {
6473
6675
  await admin.revokeSession(envelope.publicKey);
6474
6676
  }
6475
6677
  );
6476
- fs21.unlinkSync(ctx.sessionFile);
6678
+ fs22.unlinkSync(ctx.sessionFile);
6477
6679
  printErr(`\u2713 Altana session revoked and removed: ${ctx.sessionFile}`);
6478
6680
  return 0;
6479
6681
  }
@@ -6597,8 +6799,8 @@ var ProjectRootNotFound = class extends Error {
6597
6799
  };
6598
6800
  function resolveWalletProjectRoot(argRoot) {
6599
6801
  if (argRoot != null) {
6600
- const root2 = path21.resolve(argRoot);
6601
- if (!isFile7(path21.join(root2, "studio.toml"))) {
6802
+ const root2 = path22.resolve(argRoot);
6803
+ if (!isFile8(path22.join(root2, "studio.toml"))) {
6602
6804
  throw new ProjectRootNotFound(
6603
6805
  `No studio.toml found under --project-root ${root2}`
6604
6806
  );
@@ -6613,15 +6815,15 @@ function resolveWalletProjectRoot(argRoot) {
6613
6815
  }
6614
6816
  return root;
6615
6817
  }
6616
- function isFile7(p) {
6818
+ function isFile8(p) {
6617
6819
  try {
6618
- return fs22.statSync(p).isFile();
6820
+ return fs23.statSync(p).isFile();
6619
6821
  } catch {
6620
6822
  return false;
6621
6823
  }
6622
6824
  }
6623
6825
  function loadWalletCfg(projectRoot) {
6624
- const data = loadStudioToml10(path21.join(projectRoot, "studio.toml"));
6826
+ const data = loadStudioToml10(path22.join(projectRoot, "studio.toml"));
6625
6827
  const wallet = data.wallet;
6626
6828
  return wallet !== null && typeof wallet === "object" && !Array.isArray(wallet) ? wallet : {};
6627
6829
  }
@@ -6631,7 +6833,7 @@ function walletKind(walletCfg) {
6631
6833
  function projectNetwork(projectRoot) {
6632
6834
  let data;
6633
6835
  try {
6634
- data = loadStudioToml10(path21.join(projectRoot, "studio.toml"));
6836
+ data = loadStudioToml10(path22.join(projectRoot, "studio.toml"));
6635
6837
  } catch {
6636
6838
  return "bsc-testnet";
6637
6839
  }
@@ -6670,12 +6872,12 @@ function requireDurablePassword(projectRoot) {
6670
6872
  return password;
6671
6873
  }
6672
6874
  function persistAddress(projectRoot, address) {
6673
- const tomlPath = path21.join(projectRoot, "studio.toml");
6674
- if (!isFile7(tomlPath)) {
6875
+ const tomlPath = path22.join(projectRoot, "studio.toml");
6876
+ if (!isFile8(tomlPath)) {
6675
6877
  return;
6676
6878
  }
6677
- const text2 = fs22.readFileSync(tomlPath, "utf-8");
6678
- fs22.writeFileSync(
6879
+ const text2 = fs23.readFileSync(tomlPath, "utf-8");
6880
+ fs23.writeFileSync(
6679
6881
  tomlPath,
6680
6882
  updateSection(text2, "wallet", { address }),
6681
6883
  "utf-8"
@@ -6691,7 +6893,7 @@ function resolveKeystoreDir2(projectRoot, cliOverride, walletCfg) {
6691
6893
  } else {
6692
6894
  d = ".studio/wallets";
6693
6895
  }
6694
- return path21.isAbsolute(d) ? d : path21.join(projectRoot, d);
6896
+ return path22.isAbsolute(d) ? d : path22.join(projectRoot, d);
6695
6897
  }
6696
6898
  async function resolvePrivateKeyArg(raw) {
6697
6899
  if (raw === void 0 || raw === false) {
@@ -6806,7 +7008,7 @@ async function cmdNew(opts) {
6806
7008
  projectRoot = process.cwd();
6807
7009
  }
6808
7010
  let walletCfg = {};
6809
- if (isFile7(path21.join(projectRoot, "studio.toml"))) {
7011
+ if (isFile8(path22.join(projectRoot, "studio.toml"))) {
6810
7012
  walletCfg = loadWalletCfg(projectRoot);
6811
7013
  }
6812
7014
  const kind = walletKind(walletCfg);
@@ -6820,7 +7022,7 @@ async function cmdNew(opts) {
6820
7022
  opts.keystoreDir,
6821
7023
  walletCfg
6822
7024
  );
6823
- fs22.mkdirSync(keystoreDir, { recursive: true });
7025
+ fs23.mkdirSync(keystoreDir, { recursive: true });
6824
7026
  const provider = new EVMWalletProvider({
6825
7027
  password,
6826
7028
  ...privateKey !== null ? { privateKey } : {},
@@ -6830,7 +7032,7 @@ async function cmdNew(opts) {
6830
7032
  persistAddress(projectRoot, provider.address);
6831
7033
  if (kind === "altana") {
6832
7034
  printErr(
6833
- "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."
7035
+ "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."
6834
7036
  );
6835
7037
  }
6836
7038
  return 0;
@@ -6844,11 +7046,11 @@ Install it (Node >=22): npm install -g @trustwallet/cli@${TWAK_CLI_VERSION}`
6844
7046
  return 1;
6845
7047
  }
6846
7048
  const walletFile = twakWalletFile(walletCfg, projectRoot);
6847
- if (!isFile7(walletFile)) {
7049
+ if (!isFile8(walletFile)) {
6848
7050
  let createCmd = "twak wallet create --password <your-password> --no-keychain";
6849
7051
  let setupCmd = "twak setup";
6850
7052
  if (walletCfg.twak_home) {
6851
- const home = path21.dirname(path21.dirname(walletFile));
7053
+ const home = path22.dirname(path22.dirname(walletFile));
6852
7054
  createCmd = `HOME=${home} ${createCmd}`;
6853
7055
  setupCmd = `HOME=${home} ${setupCmd}`;
6854
7056
  }
@@ -6874,23 +7076,23 @@ Install it (Node >=22): npm install -g @trustwallet/cli@${TWAK_CLI_VERSION}`
6874
7076
  return 0;
6875
7077
  }
6876
7078
  function ensureTwakCredentials(walletFile, homeDir) {
6877
- const twakDir = path21.dirname(walletFile);
6878
- const target = path21.join(twakDir, "credentials.json");
6879
- if (isFile7(target)) {
7079
+ const twakDir = path22.dirname(walletFile);
7080
+ const target = path22.join(twakDir, "credentials.json");
7081
+ if (isFile8(target)) {
6880
7082
  return true;
6881
7083
  }
6882
- const machine = path21.join(os3.homedir(), ".twak", "credentials.json");
6883
- if (path21.resolve(machine) === path21.resolve(target) || !isFile7(machine)) {
7084
+ const machine = path22.join(os3.homedir(), ".twak", "credentials.json");
7085
+ if (path22.resolve(machine) === path22.resolve(target) || !isFile8(machine)) {
6884
7086
  printErr(
6885
7087
  `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.`
6886
7088
  );
6887
7089
  return false;
6888
7090
  }
6889
- fs22.mkdirSync(twakDir, { recursive: true });
6890
- fs22.writeFileSync(target, fs22.readFileSync(machine, "utf-8"), { mode: 384 });
7091
+ fs23.mkdirSync(twakDir, { recursive: true });
7092
+ fs23.writeFileSync(target, fs23.readFileSync(machine, "utf-8"), { mode: 384 });
6891
7093
  try {
6892
- fs22.chmodSync(twakDir, 448);
6893
- fs22.chmodSync(target, 384);
7094
+ fs23.chmodSync(twakDir, 448);
7095
+ fs23.chmodSync(target, 384);
6894
7096
  } catch {
6895
7097
  }
6896
7098
  printErr(`note: copied NaaS credentials from ${machine} into ${twakDir}.`);
@@ -6902,10 +7104,10 @@ async function resolveTwakInitPassword(opts) {
6902
7104
  throw new CliExit(2);
6903
7105
  }
6904
7106
  if (opts.passwordFile) {
6905
- const file = path21.resolve(opts.passwordFile);
7107
+ const file = path22.resolve(opts.passwordFile);
6906
7108
  let mode;
6907
7109
  try {
6908
- mode = fs22.statSync(file).mode;
7110
+ mode = fs23.statSync(file).mode;
6909
7111
  } catch {
6910
7112
  printErr(`error: cannot read --password-file ${file}.`);
6911
7113
  throw new CliExit(2);
@@ -6916,7 +7118,7 @@ async function resolveTwakInitPassword(opts) {
6916
7118
  );
6917
7119
  throw new CliExit(2);
6918
7120
  }
6919
- const password = (fs22.readFileSync(file, "utf-8").split(/\r?\n/)[0] ?? "").trim();
7121
+ const password = (fs23.readFileSync(file, "utf-8").split(/\r?\n/)[0] ?? "").trim();
6920
7122
  if (!password) {
6921
7123
  printErr(`error: --password-file ${file} is empty.`);
6922
7124
  throw new CliExit(2);
@@ -6969,15 +7171,15 @@ Install it (Node >=22): npm install -g @trustwallet/cli@${TWAK_CLI_VERSION}`
6969
7171
  return 1;
6970
7172
  }
6971
7173
  const walletFile = twakWalletFile(walletCfg, projectRoot);
6972
- if (isFile7(walletFile)) {
7174
+ if (isFile8(walletFile)) {
6973
7175
  printErr(
6974
7176
  `error: a twak wallet already exists at ${walletFile} \u2014 nothing to create. Run \`bag wallet new\` to adopt its address into studio.toml.`
6975
7177
  );
6976
7178
  return 1;
6977
7179
  }
6978
7180
  const password = await resolveTwakInitPassword(opts);
6979
- const homeDir = path21.dirname(path21.dirname(walletFile));
6980
- fs22.mkdirSync(homeDir, { recursive: true });
7181
+ const homeDir = path22.dirname(path22.dirname(walletFile));
7182
+ fs23.mkdirSync(homeDir, { recursive: true });
6981
7183
  if (!ensureTwakCredentials(walletFile, homeDir)) {
6982
7184
  return 1;
6983
7185
  }
@@ -6999,7 +7201,7 @@ ${password}
6999
7201
  timeoutMs: 12e4
7000
7202
  }
7001
7203
  );
7002
- if (create.code !== 0 || !isFile7(walletFile)) {
7204
+ if (create.code !== 0 || !isFile8(walletFile)) {
7003
7205
  const detail = `${create.stderr}
7004
7206
  ${create.stdout}`.trim();
7005
7207
  printErr(
@@ -7014,14 +7216,14 @@ ${detail}` : `error: \`twak wallet create --no-keychain\` did not produce ${wall
7014
7216
  return 1;
7015
7217
  }
7016
7218
  try {
7017
- fs22.chmodSync(walletFile, 384);
7219
+ fs23.chmodSync(walletFile, 384);
7018
7220
  } catch {
7019
7221
  }
7020
7222
  if (!process.env.TWAK_WALLET_PASSWORD) {
7021
7223
  process.env.TWAK_WALLET_PASSWORD = password;
7022
7224
  }
7023
7225
  printErr(
7024
- `\u2713 twak wallet created under ${path21.dirname(walletFile)} (no keychain)`
7226
+ `\u2713 twak wallet created under ${path22.dirname(walletFile)} (no keychain)`
7025
7227
  );
7026
7228
  printErr(
7027
7229
  "next: persist TWAK_WALLET_PASSWORD in .studio/.env.local so deploys and non-interactive signing can unlock it."
@@ -7058,7 +7260,7 @@ function cmdShow5(projectRootArg) {
7058
7260
  ...walletCfg.address ? { address: String(walletCfg.address) } : {}
7059
7261
  });
7060
7262
  const address = provider.address;
7061
- const keystorePath = path21.join(keystoreDir, `${address}.json`);
7263
+ const keystorePath = path22.join(keystoreDir, `${address}.json`);
7062
7264
  printOut(`address: ${address}`);
7063
7265
  printOut(`source: ${kind}`);
7064
7266
  printOut(`keystore_dir: ${keystoreDir}`);
@@ -7067,14 +7269,14 @@ function cmdShow5(projectRootArg) {
7067
7269
  const configured = String(
7068
7270
  walletCfg.session_file ?? ".studio/wallets/altana-session.json"
7069
7271
  );
7070
- const sessionFile = path21.isAbsolute(configured) ? configured : path21.join(projectRoot, configured);
7272
+ const sessionFile = path22.isAbsolute(configured) ? configured : path22.join(projectRoot, configured);
7071
7273
  printOut(`session_file: ${sessionFile}`);
7072
- if (!isFile7(sessionFile)) {
7274
+ if (!isFile8(sessionFile)) {
7073
7275
  printOut("session_status: missing (run `bag wallet session grant`)");
7074
7276
  } else {
7075
7277
  let envelope;
7076
7278
  try {
7077
- envelope = JSON.parse(fs22.readFileSync(sessionFile, "utf8"));
7279
+ envelope = JSON.parse(fs23.readFileSync(sessionFile, "utf8"));
7078
7280
  } catch {
7079
7281
  throw new Error(`invalid Altana session JSON at ${sessionFile}`);
7080
7282
  }
@@ -7100,7 +7302,7 @@ function cmdList2(projectRootArg) {
7100
7302
  const keystoreDir = resolveKeystoreDir2(projectRoot, null, walletCfg);
7101
7303
  let entries;
7102
7304
  try {
7103
- entries = fs22.readdirSync(keystoreDir).sort();
7305
+ entries = fs23.readdirSync(keystoreDir).sort();
7104
7306
  } catch {
7105
7307
  return 0;
7106
7308
  }
@@ -7112,7 +7314,7 @@ function cmdList2(projectRootArg) {
7112
7314
  let data;
7113
7315
  try {
7114
7316
  data = JSON.parse(
7115
- fs22.readFileSync(path21.join(keystoreDir, child), "utf-8")
7317
+ fs23.readFileSync(path22.join(keystoreDir, child), "utf-8")
7116
7318
  );
7117
7319
  } catch {
7118
7320
  continue;
@@ -7163,7 +7365,7 @@ async function cmdSign(msg, projectRootArg) {
7163
7365
  }
7164
7366
  async function cmdBalance(opts) {
7165
7367
  const projectRoot = resolveWalletProjectRoot(opts.projectRoot);
7166
- const data = loadStudioToml10(path21.join(projectRoot, "studio.toml"));
7368
+ const data = loadStudioToml10(path22.join(projectRoot, "studio.toml"));
7167
7369
  const walletCfg = data.wallet !== null && typeof data.wallet === "object" ? data.wallet : {};
7168
7370
  let address;
7169
7371
  const kind = walletKind(walletCfg);
@@ -7290,10 +7492,10 @@ var PROVIDER_KEY_ENV = {
7290
7492
  "pieverse-llm": "PIEVERSE_LLM_API_KEY"
7291
7493
  };
7292
7494
  function renderAgentcoreProject(target, name) {
7293
- const acDir = path22.join(target, "agentcore");
7294
- fs23.mkdirSync(acDir, { recursive: true });
7295
- fs23.writeFileSync(
7296
- path22.join(acDir, "agentcore.json"),
7495
+ const acDir = path23.join(target, "agentcore");
7496
+ fs24.mkdirSync(acDir, { recursive: true });
7497
+ fs24.writeFileSync(
7498
+ path23.join(acDir, "agentcore.json"),
7297
7499
  `${JSON.stringify(
7298
7500
  {
7299
7501
  $schema: "https://schema.agentcore.aws.dev/v1/agentcore.json",
@@ -7307,7 +7509,7 @@ function renderAgentcoreProject(target, name) {
7307
7509
  )}
7308
7510
  `
7309
7511
  );
7310
- fs23.writeFileSync(path22.join(acDir, "aws-targets.json"), "[]\n");
7512
+ fs24.writeFileSync(path23.join(acDir, "aws-targets.json"), "[]\n");
7311
7513
  }
7312
7514
  var AGENTS_MD_MARKER = "# bnbagent-studio additions (ERC-8183 seller)";
7313
7515
  var AGENTS_MD_STUDIO_SECTION = `
@@ -7351,30 +7553,30 @@ every intent to the right playbook via its references.
7351
7553
  and state the tradeoff.
7352
7554
  `;
7353
7555
  function appendAgentsMdStudioSection(target) {
7354
- const agentsMd = path22.join(target, "AGENTS.md");
7556
+ const agentsMd = path23.join(target, "AGENTS.md");
7355
7557
  let existing = "";
7356
7558
  try {
7357
- existing = fs23.readFileSync(agentsMd, "utf-8");
7559
+ existing = fs24.readFileSync(agentsMd, "utf-8");
7358
7560
  } catch {
7359
7561
  existing = "";
7360
7562
  }
7361
7563
  if (existing.includes(AGENTS_MD_MARKER)) {
7362
7564
  return;
7363
7565
  }
7364
- fs23.writeFileSync(
7566
+ fs24.writeFileSync(
7365
7567
  agentsMd,
7366
7568
  `${existing.replace(/\n+$/, "")}
7367
7569
  ${AGENTS_MD_STUDIO_SECTION}`
7368
7570
  );
7369
7571
  }
7370
7572
  function seedAwsTargets(target) {
7371
- const p = path22.join(target, "agentcore", "aws-targets.json");
7372
- if (!isFile8(p)) {
7573
+ const p = path23.join(target, "agentcore", "aws-targets.json");
7574
+ if (!isFile9(p)) {
7373
7575
  return;
7374
7576
  }
7375
7577
  let data;
7376
7578
  try {
7377
- data = JSON.parse(fs23.readFileSync(p, "utf-8"));
7579
+ data = JSON.parse(fs24.readFileSync(p, "utf-8"));
7378
7580
  } catch {
7379
7581
  return;
7380
7582
  }
@@ -7385,7 +7587,7 @@ function seedAwsTargets(target) {
7385
7587
  { name: "default", account: AWS_ACCOUNT_PLACEHOLDER, region: "us-east-1" }
7386
7588
  ];
7387
7589
  try {
7388
- fs23.writeFileSync(p, `${JSON.stringify(skeleton, null, 2)}
7590
+ fs24.writeFileSync(p, `${JSON.stringify(skeleton, null, 2)}
7389
7591
  `);
7390
7592
  } catch {
7391
7593
  return;
@@ -7408,13 +7610,13 @@ function registerAgentcoreRuntime(target, name, opts = {}) {
7408
7610
  const protocol = nativeProtocolOf(faces);
7409
7611
  const stem2 = entryStemOf(faces);
7410
7612
  const isContainer = opts.packaging === "container" || walletKind2 === "twak";
7411
- const cfgPath = path22.join(target, "agentcore", "agentcore.json");
7412
- if (!isFile8(cfgPath)) {
7613
+ const cfgPath = path23.join(target, "agentcore", "agentcore.json");
7614
+ if (!isFile9(cfgPath)) {
7413
7615
  return;
7414
7616
  }
7415
7617
  let cfg;
7416
7618
  try {
7417
- const parsed = JSON.parse(fs23.readFileSync(cfgPath, "utf-8"));
7619
+ const parsed = JSON.parse(fs24.readFileSync(cfgPath, "utf-8"));
7418
7620
  if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
7419
7621
  return;
7420
7622
  }
@@ -7453,7 +7655,7 @@ function registerAgentcoreRuntime(target, name, opts = {}) {
7453
7655
  runtimes.push(runtime);
7454
7656
  cfg.runtimes = runtimes;
7455
7657
  try {
7456
- fs23.writeFileSync(cfgPath, `${JSON.stringify(cfg, null, 2)}
7658
+ fs24.writeFileSync(cfgPath, `${JSON.stringify(cfg, null, 2)}
7457
7659
  `);
7458
7660
  } catch {
7459
7661
  return;
@@ -7590,12 +7792,12 @@ function registerInit(program) {
7590
7792
  );
7591
7793
  }
7592
7794
  function enclosingProjectRoot(start) {
7593
- let current = path22.resolve(start);
7795
+ let current = path23.resolve(start);
7594
7796
  for (; ; ) {
7595
- if (isFile8(path22.join(current, APP_DIR, AGENT_PKG, "studio.toml"))) {
7797
+ if (isFile9(path23.join(current, APP_DIR, AGENT_PKG, "studio.toml"))) {
7596
7798
  return current;
7597
7799
  }
7598
- const parent = path22.dirname(current);
7800
+ const parent = path23.dirname(current);
7599
7801
  if (parent === current) {
7600
7802
  return null;
7601
7803
  }
@@ -7603,8 +7805,8 @@ function enclosingProjectRoot(start) {
7603
7805
  }
7604
7806
  }
7605
7807
  async function cmdInit(nameArg, opts) {
7606
- const target = path22.resolve(process.cwd(), nameArg);
7607
- let projectName2 = path22.basename(target);
7808
+ const target = path23.resolve(process.cwd(), nameArg);
7809
+ let projectName2 = path23.basename(target);
7608
7810
  if (!projectName2) {
7609
7811
  printErr(
7610
7812
  `error: cannot derive a project name from '${nameArg}' (path has no basename).`
@@ -7650,6 +7852,9 @@ async function cmdInit(nameArg, opts) {
7650
7852
  opts.llmProviderSource,
7651
7853
  isTty
7652
7854
  );
7855
+ if (llmProvider === null) {
7856
+ return 2;
7857
+ }
7653
7858
  let rails = await resolveRails(opts.rails, isTty);
7654
7859
  if (hasX402Face(faces) && rails === "8183") {
7655
7860
  rails = "both";
@@ -7689,15 +7894,15 @@ async function cmdInit(nameArg, opts) {
7689
7894
  return 2;
7690
7895
  }
7691
7896
  }
7692
- const enclosing = enclosingProjectRoot(path22.dirname(target));
7897
+ const enclosing = enclosingProjectRoot(path23.dirname(target));
7693
7898
  if (enclosing !== null) {
7694
7899
  printErr(
7695
- `error: ${path22.dirname(target)} is inside an existing bag project (${enclosing}).
7696
- \`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.`
7900
+ `error: ${path23.dirname(target)} is inside an existing bag project (${enclosing}).
7901
+ \`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.`
7697
7902
  );
7698
7903
  return 2;
7699
7904
  }
7700
- if (fs23.existsSync(target) && !opts.force) {
7905
+ if (fs24.existsSync(target) && !opts.force) {
7701
7906
  printErr(`error: ${target} already exists. Use --force to overwrite.`);
7702
7907
  return 2;
7703
7908
  }
@@ -7716,20 +7921,14 @@ async function cmdInit(nameArg, opts) {
7716
7921
  destination = "self";
7717
7922
  runtime = "agentcore";
7718
7923
  }
7719
- if (destination === "platform" && walletKind2 === "altana") {
7720
- printErr(
7721
- "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."
7722
- );
7723
- return 2;
7724
- }
7725
7924
  if (destination === "self" && runtime === "azure-foundry" && (!hasA2aFace(faces) || hasMcpFace(faces))) {
7726
7925
  printErr(
7727
7926
  "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."
7728
7927
  );
7729
7928
  return 2;
7730
7929
  }
7731
- if (fs23.existsSync(target)) {
7732
- fs23.rmSync(target, { recursive: true, force: true });
7930
+ if (fs24.existsSync(target)) {
7931
+ fs24.rmSync(target, { recursive: true, force: true });
7733
7932
  }
7734
7933
  if (destination === "platform") {
7735
7934
  printCampaignIntro();
@@ -7774,7 +7973,7 @@ async function cmdInit(nameArg, opts) {
7774
7973
  }
7775
7974
  }
7776
7975
  try {
7777
- fs23.mkdirSync(target, { recursive: true });
7976
+ fs24.mkdirSync(target, { recursive: true });
7778
7977
  if (runtime === "agentcore") {
7779
7978
  renderAgentcoreProject(target, projectName2);
7780
7979
  }
@@ -7790,7 +7989,7 @@ async function cmdInit(nameArg, opts) {
7790
7989
  printErr(
7791
7990
  `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.`
7792
7991
  );
7793
- fs23.rmSync(target, { recursive: true, force: true });
7992
+ fs24.rmSync(target, { recursive: true, force: true });
7794
7993
  return 2;
7795
7994
  }
7796
7995
  const ides = resolveEmitIdes(opts.ide);
@@ -7833,9 +8032,9 @@ async function cmdInit(nameArg, opts) {
7833
8032
  });
7834
8033
  seedAwsTargets(target);
7835
8034
  }
7836
- const agentDir = path22.join(target, APP_DIR, AGENT_PKG);
7837
- fs23.mkdirSync(path22.join(agentDir, "vendor"), { recursive: true });
7838
- fs23.writeFileSync(path22.join(agentDir, "vendor", ".gitkeep"), "");
8035
+ const agentDir = path23.join(target, APP_DIR, AGENT_PKG);
8036
+ fs24.mkdirSync(path23.join(agentDir, "vendor"), { recursive: true });
8037
+ fs24.writeFileSync(path23.join(agentDir, "vendor", ".gitkeep"), "");
7839
8038
  const skipInstall = opts.install === false || opts.venv === false;
7840
8039
  let provisioned = false;
7841
8040
  let installFailed = false;
@@ -7964,64 +8163,64 @@ function derivePackaging(walletKind2, destination, platformArtifact2 = "zip", ru
7964
8163
  }
7965
8164
  function scaffold(target, name, o) {
7966
8165
  const packageManagerVersion = pnpmVersion();
7967
- fs23.writeFileSync(
7968
- path22.join(target, "package.json"),
8166
+ fs24.writeFileSync(
8167
+ path23.join(target, "package.json"),
7969
8168
  renderWorkspacePackageJson(name, packageManagerVersion)
7970
8169
  );
7971
- fs23.writeFileSync(
7972
- path22.join(target, "pnpm-workspace.yaml"),
8170
+ fs24.writeFileSync(
8171
+ path23.join(target, "pnpm-workspace.yaml"),
7973
8172
  renderPnpmWorkspaceYaml()
7974
8173
  );
7975
- fs23.writeFileSync(path22.join(target, ".gitignore"), renderWorkspaceGitignore());
7976
- if (!isFile8(path22.join(target, "README.md"))) {
7977
- fs23.writeFileSync(
7978
- path22.join(target, "README.md"),
8174
+ fs24.writeFileSync(path23.join(target, ".gitignore"), renderWorkspaceGitignore());
8175
+ if (!isFile9(path23.join(target, "README.md"))) {
8176
+ fs24.writeFileSync(
8177
+ path23.join(target, "README.md"),
7979
8178
  renderWorkspaceReadme(name, o.destination)
7980
8179
  );
7981
8180
  }
7982
8181
  appendAgentsMdStudioSection(target);
7983
- const appRoot = path22.join(target, APP_DIR);
7984
- fs23.mkdirSync(appRoot, { recursive: true });
7985
- const agentRoot2 = path22.join(appRoot, AGENT_PKG);
7986
- fs23.mkdirSync(agentRoot2, { recursive: true });
7987
- fs23.writeFileSync(
7988
- path22.join(agentRoot2, "pnpm-workspace.yaml"),
8182
+ const appRoot = path23.join(target, APP_DIR);
8183
+ fs24.mkdirSync(appRoot, { recursive: true });
8184
+ const agentRoot2 = path23.join(appRoot, AGENT_PKG);
8185
+ fs24.mkdirSync(agentRoot2, { recursive: true });
8186
+ fs24.writeFileSync(
8187
+ path23.join(agentRoot2, "pnpm-workspace.yaml"),
7989
8188
  renderAgentPnpmWorkspaceYaml()
7990
8189
  );
7991
8190
  if (o.walletKind === "evm-local" || o.walletKind === "altana") {
7992
- fs23.mkdirSync(path22.join(target, ".studio", "wallets"), { recursive: true });
8191
+ fs24.mkdirSync(path23.join(target, ".studio", "wallets"), { recursive: true });
7993
8192
  } else if (o.walletKind === "twak") {
7994
8193
  let homeDir;
7995
8194
  let label;
7996
8195
  if (o.twakHome === void 0 || o.twakHome === DEDICATED_TWAK_HOME_REL) {
7997
- homeDir = path22.join(target, ".studio", "twak");
8196
+ homeDir = path23.join(target, ".studio", "twak");
7998
8197
  label = ".studio/twak";
7999
8198
  } else {
8000
- homeDir = path22.isAbsolute(o.twakHome) ? o.twakHome : path22.resolve(agentRoot2, o.twakHome);
8199
+ homeDir = path23.isAbsolute(o.twakHome) ? o.twakHome : path23.resolve(agentRoot2, o.twakHome);
8001
8200
  label = o.twakHome;
8002
8201
  }
8003
- fs23.mkdirSync(homeDir, { recursive: true });
8202
+ fs24.mkdirSync(homeDir, { recursive: true });
8004
8203
  if (ensureTwakKeychain(homeDir)) {
8005
8204
  printOut(
8006
8205
  `\u2713 isolated twak keychain ready under ${label} (macOS) \u2014 no manual \`security\` setup needed`
8007
8206
  );
8008
8207
  }
8009
8208
  }
8010
- fs23.writeFileSync(
8011
- path22.join(agentRoot2, "package.json"),
8209
+ fs24.writeFileSync(
8210
+ path23.join(agentRoot2, "package.json"),
8012
8211
  renderAgentPackageJson(name, o.runtime, o.provider, o.faces, o.walletKind)
8013
8212
  );
8014
- fs23.writeFileSync(
8015
- path22.join(agentRoot2, "tsconfig.json"),
8213
+ fs24.writeFileSync(
8214
+ path23.join(agentRoot2, "tsconfig.json"),
8016
8215
  renderAgentTsconfig()
8017
8216
  );
8018
- fs23.writeFileSync(
8019
- path22.join(agentRoot2, "studio.toml"),
8217
+ fs24.writeFileSync(
8218
+ path23.join(agentRoot2, "studio.toml"),
8020
8219
  renderAgentStudioToml(name, o)
8021
8220
  );
8022
- const envLocal = path22.join(target, ".studio", ".env.local");
8023
- fs23.mkdirSync(path22.dirname(envLocal), { recursive: true });
8024
- fs23.writeFileSync(
8221
+ const envLocal = path23.join(target, ".studio", ".env.local");
8222
+ fs24.mkdirSync(path23.dirname(envLocal), { recursive: true });
8223
+ fs24.writeFileSync(
8025
8224
  envLocal,
8026
8225
  renderAgentEnvLocal(
8027
8226
  o.provider,
@@ -8032,9 +8231,9 @@ function scaffold(target, name, o) {
8032
8231
  o.network
8033
8232
  )
8034
8233
  );
8035
- fs23.writeFileSync(path22.join(agentRoot2, ".gitignore"), renderAgentGitignore());
8036
- fs23.writeFileSync(
8037
- path22.join(agentRoot2, "README.md"),
8234
+ fs24.writeFileSync(path23.join(agentRoot2, ".gitignore"), renderAgentGitignore());
8235
+ fs24.writeFileSync(
8236
+ path23.join(agentRoot2, "README.md"),
8038
8237
  renderAgentReadme(name, o.faces, o.destination)
8039
8238
  );
8040
8239
  const packaging = derivePackaging(
@@ -8070,18 +8269,18 @@ function emitRecipe(base, name, opts = {}) {
8070
8269
  const recipe = loadRecipe(name, { mode: opts.mode ?? null });
8071
8270
  for (const rf of recipe.files) {
8072
8271
  const targetPath = substitutePlaceholders(rf.targetPath, opts.context);
8073
- const basename16 = path22.posix.basename(targetPath);
8074
- const dst = basename16 === "Dockerfile" || basename16 === ".dockerignore" ? path22.join(base, basename16) : path22.join(base, targetPath);
8075
- fs23.mkdirSync(path22.dirname(dst), { recursive: true });
8076
- fs23.writeFileSync(dst, substitutePlaceholders(rf.content, opts.context));
8272
+ const basename16 = path23.posix.basename(targetPath);
8273
+ const dst = basename16 === "Dockerfile" || basename16 === ".dockerignore" ? path23.join(base, basename16) : path23.join(base, targetPath);
8274
+ fs24.mkdirSync(path23.dirname(dst), { recursive: true });
8275
+ fs24.writeFileSync(dst, substitutePlaceholders(rf.content, opts.context));
8077
8276
  }
8078
8277
  }
8079
8278
  function readRecipeNodeDeps(recipeName, group) {
8080
- const tomlPath = path22.join(bundledRecipesRoot(), recipeName, "recipe.toml");
8081
- if (!isFile8(tomlPath)) {
8279
+ const tomlPath = path23.join(bundledRecipesRoot(), recipeName, "recipe.toml");
8280
+ if (!isFile9(tomlPath)) {
8082
8281
  return [];
8083
8282
  }
8084
- const meta = parseToml(fs23.readFileSync(tomlPath, "utf-8"));
8283
+ const meta = parseToml(fs24.readFileSync(tomlPath, "utf-8"));
8085
8284
  const depsSection = meta.dependencies !== null && typeof meta.dependencies === "object" ? meta.dependencies : {};
8086
8285
  const collect = (v) => Array.isArray(v) ? v.filter((d) => typeof d === "string") : [];
8087
8286
  const deps = collect(depsSection.node);
@@ -8666,7 +8865,7 @@ bag deploy --provider aws
8666
8865
  `;
8667
8866
  }
8668
8867
  function emitProviderSkills(target, provider, ides) {
8669
- const skillDir = path22.join(
8868
+ const skillDir = path23.join(
8670
8869
  bundledRecipesRoot(),
8671
8870
  "providers",
8672
8871
  provider,
@@ -8676,34 +8875,34 @@ function emitProviderSkills(target, provider, ides) {
8676
8875
  return;
8677
8876
  }
8678
8877
  let emittedCursor = false;
8679
- for (const md of fs23.readdirSync(skillDir).filter((n) => n.endsWith(".md")).sort()) {
8680
- const srcText = fs23.readFileSync(path22.join(skillDir, md), "utf-8");
8878
+ for (const md of fs24.readdirSync(skillDir).filter((n) => n.endsWith(".md")).sort()) {
8879
+ const srcText = fs24.readFileSync(path23.join(skillDir, md), "utf-8");
8681
8880
  const stem2 = md.replace(/\.md$/, "");
8682
8881
  for (const ide of ides) {
8683
8882
  const [relPath, content] = renderSkillPayload(srcText, stem2, ide);
8684
- const base = ide === "claude-code" ? path22.join(target, ".claude", "skills") : path22.join(target, ".cursor", "rules");
8685
- const dst = path22.join(base, relPath);
8686
- fs23.mkdirSync(path22.dirname(dst), { recursive: true });
8687
- fs23.writeFileSync(dst, content);
8883
+ const base = ide === "claude-code" ? path23.join(target, ".claude", "skills") : path23.join(target, ".cursor", "rules");
8884
+ const dst = path23.join(base, relPath);
8885
+ fs24.mkdirSync(path23.dirname(dst), { recursive: true });
8886
+ fs24.writeFileSync(dst, content);
8688
8887
  if (ide === "cursor") {
8689
8888
  emittedCursor = true;
8690
8889
  }
8691
8890
  }
8692
8891
  }
8693
8892
  if (emittedCursor) {
8694
- ensureCursorGitignore(path22.join(target, ".gitignore"));
8893
+ ensureCursorGitignore(path23.join(target, ".gitignore"));
8695
8894
  }
8696
8895
  }
8697
8896
  function ensureCursorGitignore(gitignore) {
8698
- if (!isFile8(gitignore)) {
8897
+ if (!isFile9(gitignore)) {
8699
8898
  return;
8700
8899
  }
8701
- const text2 = fs23.readFileSync(gitignore, "utf-8");
8900
+ const text2 = fs24.readFileSync(gitignore, "utf-8");
8702
8901
  if (text2.includes(".cursor/rules/")) {
8703
8902
  return;
8704
8903
  }
8705
8904
  const addition = "\n# Cursor rules emitted at init (regeneratable via `bag skills install --target cursor`).\n.cursor/rules/\n";
8706
- fs23.writeFileSync(gitignore, `${text2.replace(/\n+$/, "")}
8905
+ fs24.writeFileSync(gitignore, `${text2.replace(/\n+$/, "")}
8707
8906
  ${addition}`);
8708
8907
  }
8709
8908
  async function resolveWalletKind(flagValue, isTty) {
@@ -8729,8 +8928,9 @@ async function resolveLlmProviderForWallet(walletKind2, configuredProvider, valu
8729
8928
  if (explicitlyConfigured) {
8730
8929
  if (configuredProvider === "pieverse-llm") {
8731
8930
  printErr(
8732
- "warning: Altana + pieverse-llm has limited compatibility: `bag llm activate` and paid-model runtime credit renewal both require SIWE message signing, which Altana intentionally does not expose. An existing Pieverse API key is usable only with the free `auto/free` model; use openrouter, openai, or anthropic for paid models."
8931
+ "error: --wallet-kind altana cannot be combined with --llm-provider pieverse-llm: `bag llm activate` and paid-model runtime credit renewal both require SIWE message signing, which Altana intentionally does not expose \u2014 activation can never succeed. Use --llm-provider openrouter, openai, or anthropic (each needs only an API key)."
8733
8932
  );
8933
+ return null;
8734
8934
  }
8735
8935
  return configuredProvider;
8736
8936
  }
@@ -8881,11 +9081,11 @@ async function promptPassword() {
8881
9081
  return first;
8882
9082
  }
8883
9083
  function readWalletAddress(studioToml) {
8884
- if (!isFile8(studioToml)) {
9084
+ if (!isFile9(studioToml)) {
8885
9085
  return null;
8886
9086
  }
8887
9087
  try {
8888
- const data = parseToml(fs23.readFileSync(studioToml, "utf-8"));
9088
+ const data = parseToml(fs24.readFileSync(studioToml, "utf-8"));
8889
9089
  const wallet = data.wallet;
8890
9090
  if (wallet !== null && typeof wallet === "object") {
8891
9091
  const addr = wallet.address;
@@ -8988,7 +9188,7 @@ async function runOnboarding(o) {
8988
9188
  if (password === null) {
8989
9189
  return false;
8990
9190
  }
8991
- const agentRoot2 = path22.join(o.workspaceRoot, APP_DIR, AGENT_PKG);
9191
+ const agentRoot2 = path23.join(o.workspaceRoot, APP_DIR, AGENT_PKG);
8992
9192
  const { envLocalPath: envLocalPath19 } = await import("@bnbagent/studio-runtime/config");
8993
9193
  setEnvVar(envLocalPath19(agentRoot2), "WALLET_PASSWORD", password);
8994
9194
  const savedCwd = process.cwd();
@@ -9016,7 +9216,7 @@ async function runOnboarding(o) {
9016
9216
  );
9017
9217
  return false;
9018
9218
  }
9019
- address = readWalletAddress(path22.join(agentRoot2, "studio.toml"));
9219
+ address = readWalletAddress(path23.join(agentRoot2, "studio.toml"));
9020
9220
  if (o.walletKind !== "altana" || o.provider !== "pieverse-llm") {
9021
9221
  await onboardProviderActivation(agentRoot2, o.provider, o.model);
9022
9222
  }
@@ -9035,7 +9235,7 @@ async function runOnboarding(o) {
9035
9235
  await printFaucetHint(o.network, address);
9036
9236
  if (o.walletKind === "altana") {
9037
9237
  printOut(
9038
- "Altana next step: fund about 0.6 tBNB for bootstrap/registration, then run `bag wallet session grant`."
9238
+ "Altana next step: fund about 0.05 tBNB for bootstrap/registration, then run `bag wallet session grant`."
9039
9239
  );
9040
9240
  }
9041
9241
  }
@@ -9045,9 +9245,9 @@ async function onboardProviderActivation(agentRoot2, provider, model) {
9045
9245
  if (provider === "pieverse-llm") {
9046
9246
  const chosenModel = model ?? await promptPieverseModel();
9047
9247
  if (model === void 0) {
9048
- const tomlPath = path22.join(agentRoot2, "studio.toml");
9049
- const text2 = fs23.readFileSync(tomlPath, "utf-8");
9050
- fs23.writeFileSync(
9248
+ const tomlPath = path23.join(agentRoot2, "studio.toml");
9249
+ const text2 = fs24.readFileSync(tomlPath, "utf-8");
9250
+ fs24.writeFileSync(
9051
9251
  tomlPath,
9052
9252
  updateSection(text2, "llm", { model: chosenModel })
9053
9253
  );
@@ -9083,8 +9283,8 @@ set ${keyEnv}= in .studio/.env.local before running \`bag dev\`.`
9083
9283
  }
9084
9284
  }
9085
9285
  async function runOnboardingTwak(o) {
9086
- const agentRoot2 = path22.join(o.workspaceRoot, APP_DIR, AGENT_PKG);
9087
- const studioToml = path22.join(agentRoot2, "studio.toml");
9286
+ const agentRoot2 = path23.join(o.workspaceRoot, APP_DIR, AGENT_PKG);
9287
+ const studioToml = path23.join(agentRoot2, "studio.toml");
9088
9288
  if (await whichTwak() === null) {
9089
9289
  printErr(
9090
9290
  `
@@ -9100,7 +9300,7 @@ you, so you never type the password on a command line, and adopts the address):
9100
9300
  }
9101
9301
  let walletCfg = {};
9102
9302
  try {
9103
- const data = parseToml(fs23.readFileSync(studioToml, "utf-8"));
9303
+ const data = parseToml(fs24.readFileSync(studioToml, "utf-8"));
9104
9304
  if (data.wallet !== null && typeof data.wallet === "object") {
9105
9305
  walletCfg = data.wallet;
9106
9306
  }
@@ -9109,16 +9309,16 @@ you, so you never type the password on a command line, and adopts the address):
9109
9309
  }
9110
9310
  const { twakWalletFile: twakWalletFile2 } = await import("./_twak-4XF4H5PL.js");
9111
9311
  let projectWallet = twakWalletFile2(walletCfg, agentRoot2);
9112
- const machineWallet = path22.join(os4.homedir(), ".twak", "wallet.json");
9113
- if (!o.twakHomePinned && isFile8(machineWallet) && realpathIfExists(projectWallet) !== realpathIfExists(machineWallet)) {
9312
+ const machineWallet = path23.join(os4.homedir(), ".twak", "wallet.json");
9313
+ if (!o.twakHomePinned && isFile9(machineWallet) && realpathIfExists(projectWallet) !== realpathIfExists(machineWallet)) {
9114
9314
  if (await promptUseMachineTwakWallet(machineWallet)) {
9115
9315
  projectWallet = adoptMachineTwakWallet(machineWallet, o.workspaceRoot);
9116
9316
  }
9117
9317
  }
9118
- if (!isFile8(projectWallet)) {
9119
- const homeDir = path22.dirname(path22.dirname(projectWallet));
9318
+ if (!isFile9(projectWallet)) {
9319
+ const homeDir = path23.dirname(path23.dirname(projectWallet));
9120
9320
  try {
9121
- fs23.mkdirSync(homeDir, { recursive: true });
9321
+ fs24.mkdirSync(homeDir, { recursive: true });
9122
9322
  } catch {
9123
9323
  }
9124
9324
  printErr(
@@ -9173,9 +9373,9 @@ Guide: the bnbagent-studio-using-twak-wallet.md reference (installed by \`bag sk
9173
9373
  }
9174
9374
  function realpathIfExists(p) {
9175
9375
  try {
9176
- return fs23.realpathSync(p);
9376
+ return fs24.realpathSync(p);
9177
9377
  } catch {
9178
- return path22.resolve(p);
9378
+ return path23.resolve(p);
9179
9379
  }
9180
9380
  }
9181
9381
  async function promptUseMachineTwakWallet(machineWallet) {
@@ -9188,39 +9388,39 @@ Found an existing twak wallet: ${machineWallet}`);
9188
9388
  return answer === "y" || answer === "yes";
9189
9389
  }
9190
9390
  function adoptMachineTwakWallet(machineWallet, workspaceRoot) {
9191
- const homeDir = path22.join(workspaceRoot, ".studio", "twak");
9192
- const twakDir = path22.join(homeDir, ".twak");
9193
- fs23.mkdirSync(twakDir, { recursive: true });
9391
+ const homeDir = path23.join(workspaceRoot, ".studio", "twak");
9392
+ const twakDir = path23.join(homeDir, ".twak");
9393
+ fs24.mkdirSync(twakDir, { recursive: true });
9194
9394
  try {
9195
- fs23.chmodSync(homeDir, 448);
9196
- fs23.chmodSync(twakDir, 448);
9395
+ fs24.chmodSync(homeDir, 448);
9396
+ fs24.chmodSync(twakDir, 448);
9197
9397
  } catch {
9198
9398
  }
9199
9399
  for (const name of ["wallet.json", "credentials.json"]) {
9200
- const src = path22.join(path22.dirname(machineWallet), name);
9201
- if (isFile8(src)) {
9202
- const dst = path22.join(twakDir, name);
9203
- fs23.writeFileSync(dst, fs23.readFileSync(src, "utf-8"), { mode: 384 });
9204
- fs23.chmodSync(dst, 384);
9400
+ const src = path23.join(path23.dirname(machineWallet), name);
9401
+ if (isFile9(src)) {
9402
+ const dst = path23.join(twakDir, name);
9403
+ fs24.writeFileSync(dst, fs24.readFileSync(src, "utf-8"), { mode: 384 });
9404
+ fs24.chmodSync(dst, 384);
9205
9405
  }
9206
9406
  }
9207
- return path22.join(twakDir, "wallet.json");
9407
+ return path23.join(twakDir, "wallet.json");
9208
9408
  }
9209
9409
  function normalizeTwakHome(raw) {
9210
- const expanded = raw.startsWith("~") ? path22.join(os4.homedir(), raw.slice(1)) : raw;
9211
- if (!path22.isAbsolute(expanded)) {
9410
+ const expanded = raw.startsWith("~") ? path23.join(os4.homedir(), raw.slice(1)) : raw;
9411
+ if (!path23.isAbsolute(expanded)) {
9212
9412
  return { home: raw };
9213
9413
  }
9214
- const isFile19 = (p) => {
9414
+ const isFile20 = (p) => {
9215
9415
  try {
9216
- return fs23.statSync(p).isFile();
9416
+ return fs24.statSync(p).isFile();
9217
9417
  } catch {
9218
9418
  return false;
9219
9419
  }
9220
9420
  };
9221
- if (path22.basename(expanded) === ".twak") {
9222
- const parent = path22.dirname(expanded);
9223
- if (isFile19(path22.join(expanded, "wallet.json"))) {
9421
+ if (path23.basename(expanded) === ".twak") {
9422
+ const parent = path23.dirname(expanded);
9423
+ if (isFile20(path23.join(expanded, "wallet.json"))) {
9224
9424
  return {
9225
9425
  home: parent,
9226
9426
  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).`
@@ -9230,15 +9430,15 @@ function normalizeTwakHome(raw) {
9230
9430
  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.`
9231
9431
  };
9232
9432
  }
9233
- if (isFile19(path22.join(expanded, "wallet.json")) && !isFile19(path22.join(expanded, ".twak", "wallet.json"))) {
9433
+ if (isFile20(path23.join(expanded, "wallet.json")) && !isFile20(path23.join(expanded, ".twak", "wallet.json"))) {
9234
9434
  return {
9235
- 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.`
9435
+ 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.`
9236
9436
  };
9237
9437
  }
9238
- if (!isFile19(path22.join(expanded, ".twak", "wallet.json"))) {
9438
+ if (!isFile20(path23.join(expanded, ".twak", "wallet.json"))) {
9239
9439
  return {
9240
9440
  home: raw,
9241
- 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.`
9441
+ 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.`
9242
9442
  };
9243
9443
  }
9244
9444
  return { home: raw };
@@ -9248,7 +9448,7 @@ function twakHomeIsMainHome(twakHome) {
9248
9448
  return false;
9249
9449
  }
9250
9450
  try {
9251
- const expanded = twakHome.startsWith("~") ? path22.join(os4.homedir(), twakHome.slice(1)) : twakHome;
9451
+ const expanded = twakHome.startsWith("~") ? path23.join(os4.homedir(), twakHome.slice(1)) : twakHome;
9252
9452
  return realpathIfExists(expanded) === realpathIfExists(os4.homedir());
9253
9453
  } catch {
9254
9454
  return false;
@@ -9339,8 +9539,10 @@ NOTE \u2014 wallet.kind = "altana" (bounded runtime session):
9339
9539
  .studio/wallets/. WALLET_PASSWORD is used only by wallet/session commands.
9340
9540
  \xB7 RUNTIME: fund the admin address, then run \`bag wallet session grant\`.
9341
9541
  The Agent receives only .studio/wallets/altana-session.json.
9342
- \xB7 DEPLOY: deployment is deferred in this release. \`bag deploy --provider <provider>\` is
9343
- rejected before packaging or external calls; local \`bag dev\` is supported.`
9542
+ \xB7 DEPLOY: \`bag deploy\` ships ONLY the bounded session (as the
9543
+ ALTANA_SESSION runtime secret) \u2014 the admin keystore and WALLET_PASSWORD
9544
+ never leave this machine. When the session expires, re-grant with
9545
+ \`bag wallet session grant --force\` and redeploy.`
9344
9546
  );
9345
9547
  }
9346
9548
  function printPlatformWalletSuggestion() {
@@ -9398,11 +9600,11 @@ function entrypointHint(faces) {
9398
9600
  return "app/agent/src/main.ts + executor.ts = A2A entrypoint (build your value here)";
9399
9601
  }
9400
9602
  function hasVendoredTarballs(agentDir) {
9401
- const vendor = path22.join(agentDir, "vendor");
9603
+ const vendor = path23.join(agentDir, "vendor");
9402
9604
  if (!isDir4(vendor)) {
9403
9605
  return false;
9404
9606
  }
9405
- return fs23.readdirSync(vendor).some((n) => n.endsWith(".tgz"));
9607
+ return fs24.readdirSync(vendor).some((n) => n.endsWith(".tgz"));
9406
9608
  }
9407
9609
  function printCompactNextSteps(name, o = {}) {
9408
9610
  const faces = o.faces ?? normalizeProtocolFaces(o.protocol ?? "A2A");
@@ -9430,7 +9632,7 @@ function printCompactNextSteps(name, o = {}) {
9430
9632
  }
9431
9633
  if (walletKind2 === "altana") {
9432
9634
  printOut(
9433
- " bag wallet session grant # after funding ~0.6 tBNB: create the bounded runtime session"
9635
+ " bag wallet session grant # after funding ~0.05 tBNB: create the bounded runtime session"
9434
9636
  );
9435
9637
  if (o.provider === "pieverse-llm") {
9436
9638
  printOut(
@@ -9554,7 +9756,7 @@ function printNextSteps(name, provider, o = {}) {
9554
9756
  printOut(" # bag auto-loads it; never pass it on argv");
9555
9757
  printOut(" (cd app/agent && bag wallet new)");
9556
9758
  printOut(
9557
- " # 2. fund the printed address with ~0.6 tBNB for bootstrap/registration + U, then grant one bounded runtime session"
9759
+ " # 2. fund the printed address with ~0.05 tBNB for bootstrap/registration + U, then grant one bounded runtime session"
9558
9760
  );
9559
9761
  printOut(" (cd app/agent && bag wallet session grant)");
9560
9762
  printOut(
@@ -9576,20 +9778,7 @@ function printNextSteps(name, provider, o = {}) {
9576
9778
  }
9577
9779
  printOut("");
9578
9780
  let nextStep;
9579
- if (provider === "pieverse-llm" && walletKind2 === "altana") {
9580
- printOut(
9581
- " # Pieverse `bag llm activate` needs generic SIWE message signing, which"
9582
- );
9583
- printOut(
9584
- " # Altana intentionally does not expose. Runtime paid-model credit renewal"
9585
- );
9586
- printOut(
9587
- " # needs the same SIWE flow, so an existing key works only with auto/free."
9588
- );
9589
- printOut(" # Use openrouter/openai/anthropic for paid models.");
9590
- printOut("");
9591
- nextStep = 3;
9592
- } else if (provider === "pieverse-llm") {
9781
+ if (provider === "pieverse-llm") {
9593
9782
  printOut(" # 3. activate Pieverse LLM (zero-deposit by default)");
9594
9783
  printOut(
9595
9784
  " # SIWE login + create API key with $0 allocation. Default model"
@@ -9652,11 +9841,11 @@ function printNextSteps(name, provider, o = {}) {
9652
9841
  );
9653
9842
  }
9654
9843
  function loadTomlSafe(p) {
9655
- if (!isFile8(p)) {
9844
+ if (!isFile9(p)) {
9656
9845
  return {};
9657
9846
  }
9658
9847
  try {
9659
- return parseToml(fs23.readFileSync(p, "utf-8"));
9848
+ return parseToml(fs24.readFileSync(p, "utf-8"));
9660
9849
  } catch {
9661
9850
  return {};
9662
9851
  }
@@ -9676,7 +9865,7 @@ function weiToU(raw) {
9676
9865
  }
9677
9866
  }
9678
9867
  function printConfigSummary(agentRoot2) {
9679
- const agent = loadTomlSafe(path22.join(agentRoot2, "studio.toml"));
9868
+ const agent = loadTomlSafe(path23.join(agentRoot2, "studio.toml"));
9680
9869
  if (Object.keys(agent).length === 0) {
9681
9870
  return;
9682
9871
  }
@@ -9874,16 +10063,16 @@ function printConfigSummary(agentRoot2) {
9874
10063
  printOut("");
9875
10064
  }
9876
10065
  }
9877
- function isFile8(p) {
10066
+ function isFile9(p) {
9878
10067
  try {
9879
- return fs23.statSync(p).isFile();
10068
+ return fs24.statSync(p).isFile();
9880
10069
  } catch {
9881
10070
  return false;
9882
10071
  }
9883
10072
  }
9884
10073
  function isDir4(p) {
9885
10074
  try {
9886
- return fs23.statSync(p).isDirectory();
10075
+ return fs24.statSync(p).isDirectory();
9887
10076
  } catch {
9888
10077
  return false;
9889
10078
  }
@@ -9947,9 +10136,9 @@ var RUNTIME_AGENTCORE = "agentcore";
9947
10136
  var RUNTIME_AZURE_FOUNDRY = "azure-foundry";
9948
10137
  var MIN_NODE_MAJOR = 22;
9949
10138
  var CONTAINER_RUNTIMES = ["docker", "podman", "finch"];
9950
- function isFile9(p) {
10139
+ function isFile10(p) {
9951
10140
  try {
9952
- return fs24.statSync(p).isFile();
10141
+ return fs25.statSync(p).isFile();
9953
10142
  } catch {
9954
10143
  return false;
9955
10144
  }
@@ -9981,8 +10170,8 @@ async function nodeMajor() {
9981
10170
  return /^\d+$/.test(head) ? Number.parseInt(head, 10) : null;
9982
10171
  }
9983
10172
  function workspaceBase(root) {
9984
- for (const base of [path23.join(root, "app"), root]) {
9985
- if (isFile9(path23.join(base, "agent", "studio.toml"))) {
10173
+ for (const base of [path24.join(root, "app"), root]) {
10174
+ if (isFile10(path24.join(base, "agent", "studio.toml"))) {
9986
10175
  return base;
9987
10176
  }
9988
10177
  }
@@ -9990,7 +10179,7 @@ function workspaceBase(root) {
9990
10179
  }
9991
10180
  function resolveWorkspaceRoot(argRoot) {
9992
10181
  if (argRoot !== null) {
9993
- const root = path23.resolve(argRoot);
10182
+ const root = path24.resolve(argRoot);
9994
10183
  const base = workspaceBase(root);
9995
10184
  if (base === null) {
9996
10185
  printErr(
@@ -10000,13 +10189,13 @@ function resolveWorkspaceRoot(argRoot) {
10000
10189
  }
10001
10190
  return base;
10002
10191
  }
10003
- let current = path23.resolve(process.cwd());
10192
+ let current = path24.resolve(process.cwd());
10004
10193
  for (; ; ) {
10005
10194
  const base = workspaceBase(current);
10006
10195
  if (base !== null) {
10007
10196
  return base;
10008
10197
  }
10009
- const parent = path23.dirname(current);
10198
+ const parent = path24.dirname(current);
10010
10199
  if (parent === current) {
10011
10200
  break;
10012
10201
  }
@@ -10020,7 +10209,7 @@ function resolveWorkspaceRoot(argRoot) {
10020
10209
  function loadAgentToml2(workspaceRoot) {
10021
10210
  try {
10022
10211
  return loadStudioToml11(
10023
- path23.join(workspaceRoot, "agent", "studio.toml")
10212
+ path24.join(workspaceRoot, "agent", "studio.toml")
10024
10213
  );
10025
10214
  } catch {
10026
10215
  return {};
@@ -10047,7 +10236,7 @@ function defaultAgentPort(faces) {
10047
10236
  function storageKind(agentDir) {
10048
10237
  let data;
10049
10238
  try {
10050
- data = loadStudioToml11(path23.join(agentDir, "studio.toml"));
10239
+ data = loadStudioToml11(path24.join(agentDir, "studio.toml"));
10051
10240
  } catch {
10052
10241
  return "local";
10053
10242
  }
@@ -10057,7 +10246,7 @@ function storageKind(agentDir) {
10057
10246
  function networkNameOf(agentDir) {
10058
10247
  let data;
10059
10248
  try {
10060
- data = loadStudioToml11(path23.join(agentDir, "studio.toml"));
10249
+ data = loadStudioToml11(path24.join(agentDir, "studio.toml"));
10061
10250
  } catch {
10062
10251
  return "bsc-testnet";
10063
10252
  }
@@ -10067,7 +10256,7 @@ function networkNameOf(agentDir) {
10067
10256
  function walletKindOf(agentDir) {
10068
10257
  let data;
10069
10258
  try {
10070
- data = loadStudioToml11(path23.join(agentDir, "studio.toml"));
10259
+ data = loadStudioToml11(path24.join(agentDir, "studio.toml"));
10071
10260
  } catch {
10072
10261
  return "evm-local";
10073
10262
  }
@@ -10075,18 +10264,18 @@ function walletKindOf(agentDir) {
10075
10264
  return typeof kind === "string" && kind.trim() ? kind.trim() : "evm-local";
10076
10265
  }
10077
10266
  function altanaSessionForRuntime(agentDir) {
10078
- const cfg = loadStudioToml11(path23.join(agentDir, "studio.toml"));
10267
+ const cfg = loadStudioToml11(path24.join(agentDir, "studio.toml"));
10079
10268
  const wallet = tableOf9(cfg, "wallet");
10080
10269
  const configured = String(
10081
10270
  wallet.session_file ?? ".studio/wallets/altana-session.json"
10082
10271
  );
10083
- const sessionFile = path23.isAbsolute(configured) ? configured : path23.join(agentDir, configured);
10084
- if (!isFile9(sessionFile)) {
10272
+ const sessionFile = path24.isAbsolute(configured) ? configured : path24.join(agentDir, configured);
10273
+ if (!isFile10(sessionFile)) {
10085
10274
  throw new Error(
10086
10275
  `no Altana session at ${sessionFile} \u2014 run \`bag wallet session grant\` first.`
10087
10276
  );
10088
10277
  }
10089
- const serialized = fs24.readFileSync(sessionFile, "utf8");
10278
+ const serialized = fs25.readFileSync(sessionFile, "utf8");
10090
10279
  let envelope;
10091
10280
  try {
10092
10281
  envelope = JSON.parse(serialized);
@@ -10115,10 +10304,10 @@ function altanaSessionForRuntime(agentDir) {
10115
10304
  }
10116
10305
  var KEY_LINE_RE = /^\s*([A-Za-z_][A-Za-z0-9_]*)\s*=/;
10117
10306
  function loadEnvFileForDev(p) {
10118
- if (!isFile9(p)) {
10307
+ if (!isFile10(p)) {
10119
10308
  return;
10120
10309
  }
10121
- for (const line of fs24.readFileSync(p, "utf-8").split(/\r?\n/)) {
10310
+ for (const line of fs25.readFileSync(p, "utf-8").split(/\r?\n/)) {
10122
10311
  if (!line || line.trimStart().startsWith("#")) {
10123
10312
  continue;
10124
10313
  }
@@ -10139,20 +10328,20 @@ function ensureStoragePath(projectRoot) {
10139
10328
  const raw = process.env.STORAGE_LOCAL_PATH;
10140
10329
  let resolved;
10141
10330
  if (raw) {
10142
- resolved = path23.resolve(
10143
- raw.startsWith("~") ? path23.join(os5.homedir(), raw.slice(1)) : raw
10331
+ resolved = path24.resolve(
10332
+ raw.startsWith("~") ? path24.join(os5.homedir(), raw.slice(1)) : raw
10144
10333
  );
10145
10334
  } else {
10146
- resolved = path23.resolve(
10147
- path23.join(
10335
+ resolved = path24.resolve(
10336
+ path24.join(
10148
10337
  os5.homedir(),
10149
10338
  ".bag",
10150
10339
  "deliverables",
10151
- path23.basename(projectRoot)
10340
+ path24.basename(projectRoot)
10152
10341
  )
10153
10342
  );
10154
10343
  }
10155
- fs24.mkdirSync(resolved, { recursive: true });
10344
+ fs25.mkdirSync(resolved, { recursive: true });
10156
10345
  process.env.STORAGE_LOCAL_PATH = resolved;
10157
10346
  }
10158
10347
  function ipfsPreflight(agentDir) {
@@ -10167,7 +10356,7 @@ function ipfsPreflight(agentDir) {
10167
10356
  function runtimeEnvKeys(agentDir) {
10168
10357
  let cfg = {};
10169
10358
  try {
10170
- cfg = loadStudioToml11(path23.join(agentDir, "studio.toml"));
10359
+ cfg = loadStudioToml11(path24.join(agentDir, "studio.toml"));
10171
10360
  } catch {
10172
10361
  cfg = {};
10173
10362
  }
@@ -10184,7 +10373,7 @@ function readTwakFiles(agentDir) {
10184
10373
  let walletCfg = {};
10185
10374
  try {
10186
10375
  walletCfg = tableOf9(
10187
- loadStudioToml11(path23.join(agentDir, "studio.toml")),
10376
+ loadStudioToml11(path24.join(agentDir, "studio.toml")),
10188
10377
  "wallet"
10189
10378
  );
10190
10379
  } catch {
@@ -10192,9 +10381,9 @@ function readTwakFiles(agentDir) {
10192
10381
  }
10193
10382
  const twakDir = twakHomeDir(walletCfg, agentDir);
10194
10383
  const read = (name) => {
10195
- const p = path23.join(twakDir, name);
10384
+ const p = path24.join(twakDir, name);
10196
10385
  try {
10197
- return fs24.readFileSync(p, "utf-8");
10386
+ return fs25.readFileSync(p, "utf-8");
10198
10387
  } catch {
10199
10388
  return null;
10200
10389
  }
@@ -10202,19 +10391,19 @@ function readTwakFiles(agentDir) {
10202
10391
  return [read("wallet.json"), read("credentials.json")];
10203
10392
  }
10204
10393
  function ensureAgentcoreEnvGitignored(agentcoreDir) {
10205
- const gi = path23.join(agentcoreDir, ".gitignore");
10394
+ const gi = path24.join(agentcoreDir, ".gitignore");
10206
10395
  const entry = ".env.local";
10207
- if (isFile9(gi)) {
10208
- const text2 = fs24.readFileSync(gi, "utf-8");
10396
+ if (isFile10(gi)) {
10397
+ const text2 = fs25.readFileSync(gi, "utf-8");
10209
10398
  const lines = new Set(text2.split("\n").map((l) => l.trim()));
10210
10399
  if (lines.has(entry)) {
10211
10400
  return;
10212
10401
  }
10213
- const sep6 = text2.endsWith("\n") || text2 === "" ? "" : "\n";
10214
- fs24.writeFileSync(gi, `${text2}${sep6}${entry}
10402
+ const sep7 = text2.endsWith("\n") || text2 === "" ? "" : "\n";
10403
+ fs25.writeFileSync(gi, `${text2}${sep7}${entry}
10215
10404
  `);
10216
10405
  } else {
10217
- fs24.writeFileSync(gi, `${entry}
10406
+ fs25.writeFileSync(gi, `${entry}
10218
10407
  `);
10219
10408
  }
10220
10409
  }
@@ -10237,8 +10426,8 @@ function writeAgentcoreEnvLocal(agentcoreRoot, agentDir) {
10237
10426
  } else if (walletKindOf(agentDir) === "altana") {
10238
10427
  bundle.ALTANA_SESSION = altanaSessionForRuntime(agentDir);
10239
10428
  }
10240
- const envPath = path23.join(agentcoreRoot, "agentcore", ".env.local");
10241
- const prior = isFile9(envPath) ? fs24.readFileSync(envPath, "utf-8") : "";
10429
+ const envPath = path24.join(agentcoreRoot, "agentcore", ".env.local");
10430
+ const prior = isFile10(envPath) ? fs25.readFileSync(envPath, "utf-8") : "";
10242
10431
  const merged = {};
10243
10432
  for (const line of prior.split("\n")) {
10244
10433
  if (!line || line.trimStart().startsWith("#")) {
@@ -10253,14 +10442,14 @@ function writeAgentcoreEnvLocal(agentcoreRoot, agentDir) {
10253
10442
  Object.assign(merged, bundle);
10254
10443
  const content = Object.entries(merged).map(([k, v]) => `${k}=${v}
10255
10444
  `).join("");
10256
- fs24.mkdirSync(path23.dirname(envPath), { recursive: true });
10257
- ensureAgentcoreEnvGitignored(path23.dirname(envPath));
10445
+ fs25.mkdirSync(path24.dirname(envPath), { recursive: true });
10446
+ ensureAgentcoreEnvGitignored(path24.dirname(envPath));
10258
10447
  writePrivate2(envPath, content);
10259
10448
  return [envPath, content !== prior];
10260
10449
  }
10261
10450
  function agentcoreProjectRoot2(workspaceRoot) {
10262
- for (const candidate of [path23.dirname(workspaceRoot), workspaceRoot]) {
10263
- if (isFile9(path23.join(candidate, "agentcore", "agentcore.json"))) {
10451
+ for (const candidate of [path24.dirname(workspaceRoot), workspaceRoot]) {
10452
+ if (isFile10(path24.join(candidate, "agentcore", "agentcore.json"))) {
10264
10453
  return candidate;
10265
10454
  }
10266
10455
  }
@@ -10269,8 +10458,8 @@ function agentcoreProjectRoot2(workspaceRoot) {
10269
10458
  function loadAgentcoreConfig(projectRoot) {
10270
10459
  try {
10271
10460
  const cfg = JSON.parse(
10272
- fs24.readFileSync(
10273
- path23.join(projectRoot, "agentcore", "agentcore.json"),
10461
+ fs25.readFileSync(
10462
+ path24.join(projectRoot, "agentcore", "agentcore.json"),
10274
10463
  "utf-8"
10275
10464
  )
10276
10465
  );
@@ -10360,7 +10549,7 @@ async function cmdDev(opts) {
10360
10549
  if (workspaceRoot === null) {
10361
10550
  return 2;
10362
10551
  }
10363
- const agentDir = path23.join(workspaceRoot, "agent");
10552
+ const agentDir = path24.join(workspaceRoot, "agent");
10364
10553
  migrateEnvLocal(agentDir);
10365
10554
  migrateKeystoreOutOfCodelocation(agentDir);
10366
10555
  const { envLocalPath: envLocalPath19 } = await import("@bnbagent/studio-runtime/config");
@@ -10396,8 +10585,8 @@ async function cmdDev(opts) {
10396
10585
  const runtime = agentRuntime(workspaceRoot);
10397
10586
  const container = Boolean(opts.container);
10398
10587
  const entryFile = localEntryFile(faces);
10399
- const agentFile = path23.join(agentDir, entryFile);
10400
- if (!isFile9(agentFile)) {
10588
+ const agentFile = path24.join(agentDir, entryFile);
10589
+ if (!isFile10(agentFile)) {
10401
10590
  printErr(
10402
10591
  `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.`
10403
10592
  );
@@ -10475,7 +10664,7 @@ Switch to Node \u226522 so it wins on PATH, then reopen the shell and retry. Ver
10475
10664
  }
10476
10665
  let launch;
10477
10666
  if (runtime === RUNTIME_AGENTCORE && container) {
10478
- const root = path23.resolve(agentcoreRoot);
10667
+ const root = path24.resolve(agentcoreRoot);
10479
10668
  try {
10480
10669
  const vendored = await vendorLocalTarballs(agentDir);
10481
10670
  if (vendored.length > 0) {
@@ -10490,7 +10679,7 @@ Switch to Node \u226522 so it wins on PATH, then reopen the shell and retry. Ver
10490
10679
  }
10491
10680
  const [envPath, changed] = writeAgentcoreEnvLocal(root, agentDir);
10492
10681
  printOut(
10493
- `bag dev: wrote ${path23.relative(root, envPath)} (runtime secrets + materialized wallet for the container).`
10682
+ `bag dev: wrote ${path24.relative(root, envPath)} (runtime secrets + materialized wallet for the container).`
10494
10683
  );
10495
10684
  if (changed && process.env.BAG_DEV_ENV_WARNED !== "1") {
10496
10685
  printErr(
@@ -10567,7 +10756,7 @@ Switch to Node \u226522 so it wins on PATH, then reopen the shell and retry. Ver
10567
10756
  }
10568
10757
  if (hasX402Face(faces)) {
10569
10758
  const free = x402SellerIsFree(
10570
- loadStudioToml11(path23.join(agentDir, "studio.toml"))
10759
+ loadStudioToml11(path24.join(agentDir, "studio.toml"))
10571
10760
  );
10572
10761
  printOut(
10573
10762
  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)`
@@ -10578,9 +10767,9 @@ Switch to Node \u226522 so it wins on PATH, then reopen the shell and retry. Ver
10578
10767
  }
10579
10768
  function tsxRunner(agentDir, workspaceBaseDir) {
10580
10769
  const bin = process.platform === "win32" ? "tsx.cmd" : "tsx";
10581
- for (const dir of [agentDir, path23.dirname(workspaceBaseDir)]) {
10582
- const candidate = path23.join(dir, "node_modules", ".bin", bin);
10583
- if (isFile9(candidate)) {
10770
+ for (const dir of [agentDir, path24.dirname(workspaceBaseDir)]) {
10771
+ const candidate = path24.join(dir, "node_modules", ".bin", bin);
10772
+ if (isFile10(candidate)) {
10584
10773
  return candidate;
10585
10774
  }
10586
10775
  }
@@ -10589,7 +10778,7 @@ function tsxRunner(agentDir, workspaceBaseDir) {
10589
10778
  function networkBanner(agentDir) {
10590
10779
  let data;
10591
10780
  try {
10592
- data = loadStudioToml11(path23.join(agentDir, "studio.toml"));
10781
+ data = loadStudioToml11(path24.join(agentDir, "studio.toml"));
10593
10782
  } catch {
10594
10783
  return null;
10595
10784
  }
@@ -10606,34 +10795,34 @@ function networkBanner(agentDir) {
10606
10795
  }
10607
10796
 
10608
10797
  // src/cli/_deploy/checks/critical.ts
10609
- import * as fs25 from "fs";
10798
+ import * as fs26 from "fs";
10610
10799
  import { createRequire } from "module";
10611
- import * as path24 from "path";
10800
+ import * as path25 from "path";
10612
10801
  import { envLocalPath as envLocalPath11, loadStudioToml as loadStudioToml12 } from "@bnbagent/studio-runtime/config";
10613
10802
  import { pieverseKeyHash as pieverseKeyHash2 } from "@bnbagent/studio-runtime/llm";
10614
10803
  var AGENTCORE_DESCRIPTOR2 = "agentcore/agentcore.json";
10615
- function isFile10(p) {
10804
+ function isFile11(p) {
10616
10805
  try {
10617
- return fs25.statSync(p).isFile();
10806
+ return fs26.statSync(p).isFile();
10618
10807
  } catch {
10619
10808
  return false;
10620
10809
  }
10621
10810
  }
10622
10811
  function isDir5(p) {
10623
10812
  try {
10624
- return fs25.statSync(p).isDirectory();
10813
+ return fs26.statSync(p).isDirectory();
10625
10814
  } catch {
10626
10815
  return false;
10627
10816
  }
10628
10817
  }
10629
10818
  function keystoreDirOf(root, data) {
10630
10819
  const rel = String(tableOf2(data, "wallet").keystore_dir ?? ".studio/wallets");
10631
- const dir = path24.isAbsolute(rel) ? rel : path24.join(agentRootOf(root), rel);
10632
- return path24.resolve(dir);
10820
+ const dir = path25.isAbsolute(rel) ? rel : path25.join(agentRootOf(root), rel);
10821
+ return path25.resolve(dir);
10633
10822
  }
10634
10823
  function keystoreJsonFiles2(dir) {
10635
10824
  try {
10636
- return fs25.readdirSync(dir).filter((n) => n.endsWith(".json")).sort();
10825
+ return fs26.readdirSync(dir).filter((n) => n.endsWith(".json")).sort();
10637
10826
  } catch {
10638
10827
  return [];
10639
10828
  }
@@ -10641,7 +10830,7 @@ function keystoreJsonFiles2(dir) {
10641
10830
  function runtimeEnvKeys2(agentRoot2) {
10642
10831
  let cfg = {};
10643
10832
  try {
10644
- cfg = loadStudioToml12(path24.join(agentRoot2, "studio.toml"));
10833
+ cfg = loadStudioToml12(path25.join(agentRoot2, "studio.toml"));
10645
10834
  } catch {
10646
10835
  cfg = {};
10647
10836
  }
@@ -10653,8 +10842,8 @@ async function checkAgentcoreJsonPresent(root, target) {
10653
10842
  if (target !== "agentcore") {
10654
10843
  return [];
10655
10844
  }
10656
- const descriptor = path24.join(root, AGENTCORE_DESCRIPTOR2);
10657
- if (isFile10(descriptor)) {
10845
+ const descriptor = path25.join(root, AGENTCORE_DESCRIPTOR2);
10846
+ if (isFile11(descriptor)) {
10658
10847
  return [];
10659
10848
  }
10660
10849
  return [
@@ -10670,10 +10859,10 @@ async function checkAgentcoreAuthorizerKeyLegacy(root, target) {
10670
10859
  if (target !== "agentcore") {
10671
10860
  return [];
10672
10861
  }
10673
- const descriptor = path24.join(root, AGENTCORE_DESCRIPTOR2);
10862
+ const descriptor = path25.join(root, AGENTCORE_DESCRIPTOR2);
10674
10863
  let data;
10675
10864
  try {
10676
- data = JSON.parse(fs25.readFileSync(descriptor, "utf-8"));
10865
+ data = JSON.parse(fs26.readFileSync(descriptor, "utf-8"));
10677
10866
  } catch {
10678
10867
  return [];
10679
10868
  }
@@ -10713,10 +10902,10 @@ async function checkAgentPackagePresent(root, target) {
10713
10902
  sourceEntries.push("src/mcpMain.ts");
10714
10903
  }
10715
10904
  const missingSource = sourceEntries.find(
10716
- (entry) => !isFile10(path24.join(agentRoot2, entry))
10905
+ (entry) => !isFile11(path25.join(agentRoot2, entry))
10717
10906
  );
10718
10907
  if (missingSource !== void 0) {
10719
- const epPath = path24.join(agentRoot2, missingSource);
10908
+ const epPath = path25.join(agentRoot2, missingSource);
10720
10909
  return [
10721
10910
  {
10722
10911
  level: Level.CRITICAL,
@@ -10731,10 +10920,10 @@ async function checkAgentPackagePresent(root, target) {
10731
10920
  distEntries.push("dist/mcpMain.js");
10732
10921
  }
10733
10922
  const missingDist = distEntries.find(
10734
- (entry) => !isFile10(path24.join(agentRoot2, entry))
10923
+ (entry) => !isFile11(path25.join(agentRoot2, entry))
10735
10924
  );
10736
10925
  if (missingDist !== void 0) {
10737
- const distPath = path24.join(agentRoot2, missingDist);
10926
+ const distPath = path25.join(agentRoot2, missingDist);
10738
10927
  return [
10739
10928
  {
10740
10929
  level: Level.WARNING,
@@ -10759,8 +10948,8 @@ async function checkKeystoreNotInsideAgent(root, target) {
10759
10948
  if (!isDir5(keystoreDir) || keystoreJsonFiles2(keystoreDir).length === 0) {
10760
10949
  return [];
10761
10950
  }
10762
- const agentDir = path24.resolve(agentRootOf(root));
10763
- const inside2 = keystoreDir === agentDir || keystoreDir.startsWith(agentDir + path24.sep);
10951
+ const agentDir = path25.resolve(agentRootOf(root));
10952
+ const inside2 = keystoreDir === agentDir || keystoreDir.startsWith(agentDir + path25.sep);
10764
10953
  if (!inside2) {
10765
10954
  return [];
10766
10955
  }
@@ -10779,6 +10968,9 @@ async function checkLocalKeystoreExists(root, _target) {
10779
10968
  if (walletCfg.kind === "twak") {
10780
10969
  return [];
10781
10970
  }
10971
+ if (walletCfg.kind === "altana") {
10972
+ return [];
10973
+ }
10782
10974
  const signer = walletCfg.signer ?? "local";
10783
10975
  if (signer !== "local") {
10784
10976
  return [];
@@ -10797,7 +10989,11 @@ async function checkLocalKeystoreExists(root, _target) {
10797
10989
  ];
10798
10990
  }
10799
10991
  async function checkWalletPasswordEnvSet(root, _target) {
10800
- if (tableOf2(loadAgentToml(root), "wallet").kind === "twak") {
10992
+ const kind = tableOf2(loadAgentToml(root), "wallet").kind;
10993
+ if (kind === "twak") {
10994
+ return [];
10995
+ }
10996
+ if (kind === "altana") {
10801
10997
  return [];
10802
10998
  }
10803
10999
  if (process.env.WALLET_PASSWORD) {
@@ -10836,18 +11032,18 @@ async function checkLlmProviderKeySet(root, _target) {
10836
11032
  function gitignoreLines(p) {
10837
11033
  try {
10838
11034
  return new Set(
10839
- fs25.readFileSync(p, "utf-8").split(/\r?\n/).map((l) => l.trim())
11035
+ fs26.readFileSync(p, "utf-8").split(/\r?\n/).map((l) => l.trim())
10840
11036
  );
10841
11037
  } catch {
10842
11038
  return null;
10843
11039
  }
10844
11040
  }
10845
11041
  function agentcoreEnvLocalIgnored(ws) {
10846
- const wsLines = gitignoreLines(path24.join(ws, ".gitignore"));
11042
+ const wsLines = gitignoreLines(path25.join(ws, ".gitignore"));
10847
11043
  if (wsLines?.has("agentcore/.env.local")) {
10848
11044
  return true;
10849
11045
  }
10850
- const acLines = gitignoreLines(path24.join(ws, "agentcore", ".gitignore"));
11046
+ const acLines = gitignoreLines(path25.join(ws, "agentcore", ".gitignore"));
10851
11047
  return acLines?.has(".env.local") ?? false;
10852
11048
  }
10853
11049
  function studioIgnored(lines) {
@@ -10858,8 +11054,8 @@ function studioIgnored(lines) {
10858
11054
  }
10859
11055
  async function checkGitignoreExcludesSecrets(root, _target) {
10860
11056
  const out = [];
10861
- const ws = path24.dirname(path24.dirname(envLocalPath11(root)));
10862
- const gi = path24.join(ws, ".gitignore");
11057
+ const ws = path25.dirname(path25.dirname(envLocalPath11(root)));
11058
+ const gi = path25.join(ws, ".gitignore");
10863
11059
  const lines = gitignoreLines(gi);
10864
11060
  if (lines === null) {
10865
11061
  return [
@@ -10881,7 +11077,7 @@ async function checkGitignoreExcludesSecrets(root, _target) {
10881
11077
  details: { missing: [".studio/"] }
10882
11078
  });
10883
11079
  }
10884
- if (isDir5(path24.join(ws, "agentcore")) && !agentcoreEnvLocalIgnored(ws)) {
11080
+ if (isDir5(path25.join(ws, "agentcore")) && !agentcoreEnvLocalIgnored(ws)) {
10885
11081
  out.push({
10886
11082
  level: Level.CRITICAL,
10887
11083
  name: "gitignore_excludes_secrets",
@@ -10898,16 +11094,16 @@ function installedRuntimeVersion() {
10898
11094
  }
10899
11095
  try {
10900
11096
  const entry = require2.resolve("@bnbagent/studio-runtime");
10901
- let dir = path24.dirname(entry);
11097
+ let dir = path25.dirname(entry);
10902
11098
  for (let i = 0; i < 10; i++) {
10903
- const pkgPath = path24.join(dir, "package.json");
10904
- if (isFile10(pkgPath)) {
10905
- const pkg = JSON.parse(fs25.readFileSync(pkgPath, "utf-8"));
11099
+ const pkgPath = path25.join(dir, "package.json");
11100
+ if (isFile11(pkgPath)) {
11101
+ const pkg = JSON.parse(fs26.readFileSync(pkgPath, "utf-8"));
10906
11102
  if (pkg.name === "@bnbagent/studio-runtime") {
10907
11103
  return typeof pkg.version === "string" ? pkg.version : null;
10908
11104
  }
10909
11105
  }
10910
- const parent = path24.dirname(dir);
11106
+ const parent = path25.dirname(dir);
10911
11107
  if (parent === dir) {
10912
11108
  break;
10913
11109
  }
@@ -11191,9 +11387,9 @@ function x402SellerRailChecks(agentRoot2, cfg, target) {
11191
11387
  details: { destination, target, stackRuntime: stackRuntime2 }
11192
11388
  });
11193
11389
  }
11194
- const dockerfile = path24.join(agentRoot2, "Dockerfile");
11195
- if (rails.x402 && isFile10(dockerfile)) {
11196
- const source = fs25.readFileSync(dockerfile, "utf8");
11390
+ const dockerfile = path25.join(agentRoot2, "Dockerfile");
11391
+ if (rails.x402 && isFile11(dockerfile)) {
11392
+ const source = fs26.readFileSync(dockerfile, "utf8");
11197
11393
  if (!/^\s*FROM\s+node:22(?:[.-]|\s|$)/im.test(source)) {
11198
11394
  out.push({
11199
11395
  level: Level.WARNING,
@@ -11266,10 +11462,10 @@ async function checkDeployCliRunnable(_root, target) {
11266
11462
  ];
11267
11463
  }
11268
11464
  function agentcoreEnvVars(root) {
11269
- const descriptor = path24.join(root, AGENTCORE_DESCRIPTOR2);
11465
+ const descriptor = path25.join(root, AGENTCORE_DESCRIPTOR2);
11270
11466
  let data;
11271
11467
  try {
11272
- data = JSON.parse(fs25.readFileSync(descriptor, "utf-8"));
11468
+ data = JSON.parse(fs26.readFileSync(descriptor, "utf-8"));
11273
11469
  } catch {
11274
11470
  return [];
11275
11471
  }
@@ -11351,7 +11547,7 @@ async function checkRuntimeSecretsInjected(root, target) {
11351
11547
  }
11352
11548
  ];
11353
11549
  }
11354
- const lines = gitignoreLines(path24.join(root, ".gitignore"));
11550
+ const lines = gitignoreLines(path25.join(root, ".gitignore"));
11355
11551
  let tracked = true;
11356
11552
  if (lines !== null) {
11357
11553
  for (const p of ["agentcore/agentcore.json", "agentcore/", "/agentcore/"]) {
@@ -11376,7 +11572,7 @@ async function checkAwsTargetsPopulated(root, target) {
11376
11572
  if (target !== "agentcore") {
11377
11573
  return [];
11378
11574
  }
11379
- const p = path24.join(root, "agentcore", "aws-targets.json");
11575
+ const p = path25.join(root, "agentcore", "aws-targets.json");
11380
11576
  const [account, region] = readAwsTarget(root);
11381
11577
  if (account && region) {
11382
11578
  return [];
@@ -11459,12 +11655,18 @@ async function checkAgentcoreQuotaHeadroom(root, target) {
11459
11655
  }
11460
11656
  ];
11461
11657
  }
11658
+ const quotaRunbook = `Raising ${AGENTCORE_AGENT_QUOTA_CODE} ("Total Agents per Account") is a manual AWS step \u2014 \`bag\` cannot request it for you:
11659
+ 1. Open the AWS Service Quotas console (service "Amazon Bedrock AgentCore", region ${region}) and request an increase; low requests may need an AWS support case, and a first request can be rejected.
11660
+ 2. Check where an earlier request stands: aws service-quotas list-requested-service-quota-change-history --service-code bedrock-agentcore --region ${region}
11661
+ 3. While the increase is pending, deploy to the managed platform instead: bag deploy --provider bnb`;
11662
+ const message = limit <= 0 ? `AgentCore quota is 0 in ${region} (new accounts can start at zero), so ANY deploy would fail with \`maxAgents limit exceeded\` AFTER pushing the image and creating the secret, M2M client, and execution role (all orphans). ${quotaRunbook}` : `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 raise the quota. ${quotaRunbook}`;
11462
11663
  return [
11463
11664
  {
11464
11665
  level: Level.CRITICAL,
11465
11666
  name: "agentcore_quota_headroom",
11466
- 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.`,
11467
- details
11667
+ message,
11668
+ details,
11669
+ fixCmd: `# raise ${AGENTCORE_AGENT_QUOTA_CODE} in the AWS Service Quotas console (manual), or deploy with: bag deploy --provider bnb`
11468
11670
  }
11469
11671
  ];
11470
11672
  }
@@ -11485,6 +11687,10 @@ var allChecks = [
11485
11687
  checkTwakPasswordEnvSet,
11486
11688
  checkTwakCredentialsAvailable,
11487
11689
  checkTwakDockerAvailable,
11690
+ // altana-kind checks (every one early-returns for other kinds).
11691
+ checkAltanaSessionReady,
11692
+ checkAltanaSdkResolvable,
11693
+ checkAltanaSessionNotInsideAgent,
11488
11694
  checkLlmProviderKeySet,
11489
11695
  checkGitignoreExcludesSecrets,
11490
11696
  checkInstalledBnbagentStudioMatches,
@@ -11500,16 +11706,16 @@ var allChecks = [
11500
11706
  var KEYSTORE_JSON_ENV = "WALLET_KEYSTORE_JSON";
11501
11707
  var TWAK_WALLET_JSON_ENV = "TWAK_WALLET_JSON";
11502
11708
  var TWAK_CREDENTIALS_JSON_ENV = "TWAK_CREDENTIALS_JSON";
11503
- function isFile11(p) {
11709
+ function isFile12(p) {
11504
11710
  try {
11505
- return fs26.statSync(p).isFile();
11711
+ return fs27.statSync(p).isFile();
11506
11712
  } catch {
11507
11713
  return false;
11508
11714
  }
11509
11715
  }
11510
11716
  function loadTomlOr(agentRoot2) {
11511
11717
  try {
11512
- return loadStudioToml13(path25.join(agentRoot2, "studio.toml"));
11718
+ return loadStudioToml13(path26.join(agentRoot2, "studio.toml"));
11513
11719
  } catch {
11514
11720
  return {};
11515
11721
  }
@@ -11526,13 +11732,13 @@ function resolveKeystoreDir3(agentRoot2) {
11526
11732
  const rel = String(
11527
11733
  tableOf10(loadTomlOr(agentRoot2), "wallet").keystore_dir ?? ".studio/wallets"
11528
11734
  );
11529
- return path25.resolve(path25.isAbsolute(rel) ? rel : path25.join(agentRoot2, rel));
11735
+ return path26.resolve(path26.isAbsolute(rel) ? rel : path26.join(agentRoot2, rel));
11530
11736
  }
11531
11737
  function readKeystoreJson(agentRoot2) {
11532
11738
  const keystoreDir = resolveKeystoreDir3(agentRoot2);
11533
11739
  let names;
11534
11740
  try {
11535
- names = fs26.readdirSync(keystoreDir).filter((n) => n.endsWith(".json")).sort();
11741
+ names = fs27.readdirSync(keystoreDir).filter((n) => n.endsWith(".json")).sort();
11536
11742
  } catch {
11537
11743
  return null;
11538
11744
  }
@@ -11554,9 +11760,9 @@ function readKeystoreJson(agentRoot2) {
11554
11760
  );
11555
11761
  }
11556
11762
  }
11557
- const file = path25.join(keystoreDir, chosen ?? names[0]);
11763
+ const file = path26.join(keystoreDir, chosen ?? names[0]);
11558
11764
  try {
11559
- return fs26.readFileSync(file, "utf-8");
11765
+ return fs27.readFileSync(file, "utf-8");
11560
11766
  } catch {
11561
11767
  return null;
11562
11768
  }
@@ -11565,10 +11771,10 @@ function readEnvLocal(agentRoot2) {
11565
11771
  const values = {};
11566
11772
  try {
11567
11773
  const file = envLocalPath12(agentRoot2);
11568
- if (!isFile11(file)) {
11774
+ if (!isFile12(file)) {
11569
11775
  return values;
11570
11776
  }
11571
- for (const rawLine of fs26.readFileSync(file, "utf-8").split(/\r?\n/)) {
11777
+ for (const rawLine of fs27.readFileSync(file, "utf-8").split(/\r?\n/)) {
11572
11778
  const line = rawLine.trim();
11573
11779
  if (!line || line.startsWith("#")) {
11574
11780
  continue;
@@ -11590,11 +11796,6 @@ function readEnvLocal(agentRoot2) {
11590
11796
  }
11591
11797
  function collectRuntimeSecretsDetailed(root) {
11592
11798
  const agentRoot2 = findSubProjectRoot8("agent", root) ?? root;
11593
- if (deployWalletKind(agentRoot2) === "altana") {
11594
- throw new Error(
11595
- "Altana deployment is deferred: refusing to collect either the admin keystore or runtime session for a deploy target."
11596
- );
11597
- }
11598
11799
  const secretKeys = runtimeEnvKeys2(agentRoot2);
11599
11800
  const fileValues = readEnvLocal(agentRoot2);
11600
11801
  const payload = {};
@@ -11607,7 +11808,8 @@ function collectRuntimeSecretsDetailed(root) {
11607
11808
  sources[k] = fromFile ? ".studio/.env.local" : "process.env";
11608
11809
  }
11609
11810
  }
11610
- if (deployWalletKind(agentRoot2) === "twak") {
11811
+ const walletKind2 = deployWalletKind(agentRoot2);
11812
+ if (walletKind2 === "twak") {
11611
11813
  const [walletJson, credentialsJson] = readTwakFiles(agentRoot2);
11612
11814
  if (walletJson) {
11613
11815
  payload[TWAK_WALLET_JSON_ENV] = walletJson;
@@ -11617,6 +11819,9 @@ function collectRuntimeSecretsDetailed(root) {
11617
11819
  payload[TWAK_CREDENTIALS_JSON_ENV] = credentialsJson;
11618
11820
  sources[TWAK_CREDENTIALS_JSON_ENV] = "wallet-file";
11619
11821
  }
11822
+ } else if (walletKind2 === "altana") {
11823
+ payload[ALTANA_SESSION_ENV] = altanaSessionForRuntime(agentRoot2);
11824
+ sources[ALTANA_SESSION_ENV] = "wallet-file";
11620
11825
  } else {
11621
11826
  const keystoreJson = readKeystoreJson(agentRoot2);
11622
11827
  if (keystoreJson) {
@@ -11624,7 +11829,7 @@ function collectRuntimeSecretsDetailed(root) {
11624
11829
  sources[KEYSTORE_JSON_ENV] = "wallet-file";
11625
11830
  }
11626
11831
  }
11627
- if (!(KEYSTORE_JSON_ENV in payload) && !(TWAK_WALLET_JSON_ENV in payload)) {
11832
+ if (walletKind2 !== "altana" && !(KEYSTORE_JSON_ENV in payload) && !(TWAK_WALLET_JSON_ENV in payload)) {
11628
11833
  printErr(
11629
11834
  `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.`
11630
11835
  );
@@ -11656,12 +11861,12 @@ var SCOPE_NAME = "invoke";
11656
11861
  var SCOPE = `${RESOURCE_SERVER_ID}/${SCOPE_NAME}`;
11657
11862
  var COGNITO_OUTPUTS_FILE = "agentcore/cognito/cdk-outputs.json";
11658
11863
  function emitNextSteps(result) {
11659
- return `\u2713 wrote Cognito CDK app to ${path26.dirname(result.appPath)}
11660
- - ${path26.basename(result.appPath)} (CognitoStack: user pool + resource server + M2M client)
11661
- - ${path26.basename(result.readmePath)} (deploy + wiring instructions)
11864
+ return `\u2713 wrote Cognito CDK app to ${path27.dirname(result.appPath)}
11865
+ - ${path27.basename(result.appPath)} (CognitoStack: user pool + resource server + M2M client)
11866
+ - ${path27.basename(result.readmePath)} (deploy + wiring instructions)
11662
11867
 
11663
11868
  Next steps:
11664
- 1. cd ${path26.dirname(result.appPath)}
11869
+ 1. cd ${path27.dirname(result.appPath)}
11665
11870
  2. npm install # aws-cdk-lib + constructs + the cdk CLI (local)
11666
11871
  3. npx cdk deploy --outputs-file cdk-outputs.json # YOU run this (the only AWS step)
11667
11872
  4. bag deploy provision-cognito --wire # studio reads cdk-outputs.json \u2192
@@ -11857,26 +12062,26 @@ function emitCognitoCdk(workspaceRoot, opts = {}) {
11857
12062
  regionHint = null;
11858
12063
  }
11859
12064
  }
11860
- const outDir = path26.join(workspaceRoot, COGNITO_DIR);
11861
- fs27.mkdirSync(outDir, { recursive: true });
11862
- const appPath = path26.join(outDir, "app.ts");
11863
- const readmePath = path26.join(outDir, "README.md");
11864
- fs27.writeFileSync(appPath, appTs(regionHint), "utf-8");
11865
- fs27.writeFileSync(path26.join(outDir, "cdk.json"), cdkJson(), "utf-8");
11866
- fs27.writeFileSync(
11867
- path26.join(outDir, "package.json"),
12065
+ const outDir = path27.join(workspaceRoot, COGNITO_DIR);
12066
+ fs28.mkdirSync(outDir, { recursive: true });
12067
+ const appPath = path27.join(outDir, "app.ts");
12068
+ const readmePath = path27.join(outDir, "README.md");
12069
+ fs28.writeFileSync(appPath, appTs(regionHint), "utf-8");
12070
+ fs28.writeFileSync(path27.join(outDir, "cdk.json"), cdkJson(), "utf-8");
12071
+ fs28.writeFileSync(
12072
+ path27.join(outDir, "package.json"),
11868
12073
  cognitoPackageJson(),
11869
12074
  "utf-8"
11870
12075
  );
11871
- fs27.writeFileSync(readmePath, readme(), "utf-8");
12076
+ fs28.writeFileSync(readmePath, readme(), "utf-8");
11872
12077
  return { appPath, readmePath };
11873
12078
  }
11874
12079
  function wireSummary(r) {
11875
12080
  return `\u2713 wired Cognito authorizer from the CDK outputs (no AWS call \u2014 read a local file):
11876
- - ${path26.basename(r.agentcoreJson)}: authorizerConfiguration.customJwtAuthorizer
12081
+ - ${path27.basename(r.agentcoreJson)}: authorizerConfiguration.customJwtAuthorizer
11877
12082
  discoveryUrl = ${r.discoveryUrl}
11878
12083
  allowedClients = [${r.clientId}]
11879
- - ${path26.basename(r.agentcoreJson)}: envVars[] OAUTH_TOKEN_URL + OAUTH_SCOPE (reach the runtime so the agent card advertises oauth2)
12084
+ - ${path27.basename(r.agentcoreJson)}: envVars[] OAUTH_TOKEN_URL + OAUTH_SCOPE (reach the runtime so the agent card advertises oauth2)
11880
12085
  - ${r.envLocal}: same pair, for local \`bag dev\`
11881
12086
  \u2192 NOTE: a \`bag deploy\` run provisions its own pool and overwrites these
11882
12087
  values with the ones it issued. This wiring only feeds local \`bag dev\`.`;
@@ -11908,10 +12113,10 @@ function upsertDescriptorEnvvars(cfg, values) {
11908
12113
  }
11909
12114
  }
11910
12115
  function syncDescriptorOauthFacts(workspaceRoot, facts) {
11911
- const acj = path26.join(workspaceRoot, "agentcore", "agentcore.json");
12116
+ const acj = path27.join(workspaceRoot, "agentcore", "agentcore.json");
11912
12117
  let cfg;
11913
12118
  try {
11914
- cfg = JSON.parse(fs27.readFileSync(acj, "utf-8"));
12119
+ cfg = JSON.parse(fs28.readFileSync(acj, "utf-8"));
11915
12120
  } catch {
11916
12121
  return;
11917
12122
  }
@@ -11944,7 +12149,7 @@ function syncDescriptorOauthFacts(workspaceRoot, facts) {
11944
12149
  }
11945
12150
  }
11946
12151
  try {
11947
- fs27.writeFileSync(acj, `${JSON.stringify(cfg, null, 2)}
12152
+ fs28.writeFileSync(acj, `${JSON.stringify(cfg, null, 2)}
11948
12153
  `, "utf-8");
11949
12154
  } catch {
11950
12155
  return;
@@ -11953,8 +12158,8 @@ function syncDescriptorOauthFacts(workspaceRoot, facts) {
11953
12158
  function upsertEnv(envLocal, values) {
11954
12159
  let lines = [];
11955
12160
  try {
11956
- if (fs27.statSync(envLocal).isFile()) {
11957
- lines = fs27.readFileSync(envLocal, "utf-8").split(/\r?\n/);
12161
+ if (fs28.statSync(envLocal).isFile()) {
12162
+ lines = fs28.readFileSync(envLocal, "utf-8").split(/\r?\n/);
11958
12163
  if (lines.length > 0 && lines[lines.length - 1] === "") {
11959
12164
  lines.pop();
11960
12165
  }
@@ -11973,19 +12178,19 @@ function upsertEnv(envLocal, values) {
11973
12178
  lines.push(repl);
11974
12179
  }
11975
12180
  }
11976
- fs27.mkdirSync(path26.dirname(envLocal), { recursive: true });
11977
- fs27.writeFileSync(envLocal, `${lines.join("\n")}
12181
+ fs28.mkdirSync(path27.dirname(envLocal), { recursive: true });
12182
+ fs28.writeFileSync(envLocal, `${lines.join("\n")}
11978
12183
  `, {
11979
12184
  encoding: "utf-8",
11980
12185
  mode: 384
11981
12186
  });
11982
- fs27.chmodSync(envLocal, 384);
12187
+ fs28.chmodSync(envLocal, 384);
11983
12188
  }
11984
12189
  function wireCognitoOutputs(workspaceRoot, outputsFile = null) {
11985
- const outPath = outputsFile ?? path26.join(workspaceRoot, COGNITO_OUTPUTS_FILE);
12190
+ const outPath = outputsFile ?? path27.join(workspaceRoot, COGNITO_OUTPUTS_FILE);
11986
12191
  let exists = false;
11987
12192
  try {
11988
- exists = fs27.statSync(outPath).isFile();
12193
+ exists = fs28.statSync(outPath).isFile();
11989
12194
  } catch {
11990
12195
  exists = false;
11991
12196
  }
@@ -11995,7 +12200,7 @@ function wireCognitoOutputs(workspaceRoot, outputsFile = null) {
11995
12200
  );
11996
12201
  }
11997
12202
  const outs = flattenCdkOutputs(
11998
- JSON.parse(fs27.readFileSync(outPath, "utf-8"))
12203
+ JSON.parse(fs28.readFileSync(outPath, "utf-8"))
11999
12204
  );
12000
12205
  for (const key of ["DiscoveryUrl", "AppClientId", "TokenUrl", "Scope"]) {
12001
12206
  if (outs[key] === void 0) {
@@ -12008,8 +12213,8 @@ function wireCognitoOutputs(workspaceRoot, outputsFile = null) {
12008
12213
  const clientId = String(outs.AppClientId);
12009
12214
  const tokenUrl = String(outs.TokenUrl);
12010
12215
  const scope = String(outs.Scope);
12011
- const acj = path26.join(workspaceRoot, "agentcore", "agentcore.json");
12012
- const cfg = JSON.parse(fs27.readFileSync(acj, "utf-8"));
12216
+ const acj = path27.join(workspaceRoot, "agentcore", "agentcore.json");
12217
+ const cfg = JSON.parse(fs28.readFileSync(acj, "utf-8"));
12013
12218
  const runtimes = cfg.runtimes;
12014
12219
  if (!Array.isArray(runtimes) || runtimes.length === 0) {
12015
12220
  throw new Error(
@@ -12032,7 +12237,7 @@ function wireCognitoOutputs(workspaceRoot, outputsFile = null) {
12032
12237
  OAUTH_TOKEN_URL: tokenUrl,
12033
12238
  OAUTH_SCOPE: scope
12034
12239
  });
12035
- fs27.writeFileSync(acj, `${JSON.stringify(cfg, null, 2)}
12240
+ fs28.writeFileSync(acj, `${JSON.stringify(cfg, null, 2)}
12036
12241
  `, "utf-8");
12037
12242
  const envLocal = envLocalPath13(workspaceRoot);
12038
12243
  upsertEnv(envLocal, { OAUTH_TOKEN_URL: tokenUrl, OAUTH_SCOPE: scope });
@@ -12047,13 +12252,13 @@ function wireCognitoOutputs(workspaceRoot, outputsFile = null) {
12047
12252
  }
12048
12253
 
12049
12254
  // src/cli/_deploy/destroy.ts
12050
- import * as fs29 from "fs";
12051
- import * as path28 from "path";
12255
+ import * as fs30 from "fs";
12256
+ import * as path29 from "path";
12052
12257
  import { findSubProjectRoot as findSubProjectRoot10 } from "@bnbagent/studio-runtime/config";
12053
12258
 
12054
12259
  // src/cli/_deploy/status.ts
12055
- import * as fs28 from "fs";
12056
- import * as path27 from "path";
12260
+ import * as fs29 from "fs";
12261
+ import * as path28 from "path";
12057
12262
  import {
12058
12263
  APP_DIR as APP_DIR2,
12059
12264
  findSubProjectRoot as findSubProjectRoot9,
@@ -12068,20 +12273,20 @@ function loadToml(p) {
12068
12273
  }
12069
12274
  }
12070
12275
  function projectName(workspaceRoot) {
12071
- const descriptor = path27.join(workspaceRoot, "agentcore", "agentcore.json");
12276
+ const descriptor = path28.join(workspaceRoot, "agentcore", "agentcore.json");
12072
12277
  try {
12073
- const data = JSON.parse(fs28.readFileSync(descriptor, "utf-8"));
12278
+ const data = JSON.parse(fs29.readFileSync(descriptor, "utf-8"));
12074
12279
  if (data !== null && typeof data === "object" && data.name) {
12075
12280
  return String(data.name);
12076
12281
  }
12077
12282
  } catch {
12078
12283
  }
12079
- return path27.basename(workspaceRoot);
12284
+ return path28.basename(workspaceRoot);
12080
12285
  }
12081
12286
  async function runStatus(opts = {}) {
12082
- const start = opts.projectRoot ? path27.resolve(opts.projectRoot) : void 0;
12287
+ const start = opts.projectRoot ? path28.resolve(opts.projectRoot) : void 0;
12083
12288
  const agentRoot2 = findSubProjectRoot9("agent", start);
12084
- const agentData = agentRoot2 !== null ? loadToml(path27.join(agentRoot2, "studio.toml")) : {};
12289
+ const agentData = agentRoot2 !== null ? loadToml(path28.join(agentRoot2, "studio.toml")) : {};
12085
12290
  const deployRaw = agentData.deploy;
12086
12291
  const deploy = deployRaw !== null && typeof deployRaw === "object" && !Array.isArray(deployRaw) ? { ...deployRaw } : {};
12087
12292
  const runtimeArn = deploy.runtime_arn ? String(deploy.runtime_arn) : null;
@@ -12094,8 +12299,8 @@ async function runStatus(opts = {}) {
12094
12299
  }
12095
12300
  const onchainEndpoint = identity.endpoint ? String(identity.endpoint) : null;
12096
12301
  const agentReachable = null;
12097
- const workspaceBase2 = findWorkspaceRoot5(start) ?? (agentRoot2 !== null ? path27.dirname(agentRoot2) : null);
12098
- const workspaceRoot = workspaceBase2 !== null && path27.basename(workspaceBase2) === APP_DIR2 ? path27.dirname(workspaceBase2) : workspaceBase2;
12302
+ const workspaceBase2 = findWorkspaceRoot5(start) ?? (agentRoot2 !== null ? path28.dirname(agentRoot2) : null);
12303
+ const workspaceRoot = workspaceBase2 !== null && path28.basename(workspaceBase2) === APP_DIR2 ? path28.dirname(workspaceBase2) : workspaceBase2;
12099
12304
  let region = null;
12100
12305
  let account = null;
12101
12306
  let secretId = null;
@@ -12163,9 +12368,9 @@ function nullRecordedState(workspaceRoot) {
12163
12368
  if (agentRoot2 === null) {
12164
12369
  return;
12165
12370
  }
12166
- const ap = path28.join(agentRoot2, "studio.toml");
12371
+ const ap = path29.join(agentRoot2, "studio.toml");
12167
12372
  try {
12168
- if (!fs29.statSync(ap).isFile()) {
12373
+ if (!fs30.statSync(ap).isFile()) {
12169
12374
  return;
12170
12375
  }
12171
12376
  } catch {
@@ -12229,8 +12434,8 @@ async function runDestroy(opts) {
12229
12434
  }
12230
12435
 
12231
12436
  // src/cli/_deploy/packaging.ts
12232
- import * as fs30 from "fs";
12233
- import * as path29 from "path";
12437
+ import * as fs31 from "fs";
12438
+ import * as path30 from "path";
12234
12439
  import {
12235
12440
  findSubProjectRoot as findSubProjectRoot11,
12236
12441
  loadStudioToml as loadStudioToml15
@@ -12239,9 +12444,9 @@ function agentRootOf2(root) {
12239
12444
  return findSubProjectRoot11("agent", root);
12240
12445
  }
12241
12446
  function agentTable(agentRoot2, key) {
12242
- const tomlPath = path29.join(agentRoot2, "studio.toml");
12447
+ const tomlPath = path30.join(agentRoot2, "studio.toml");
12243
12448
  try {
12244
- if (!fs30.statSync(tomlPath).isFile()) {
12449
+ if (!fs31.statSync(tomlPath).isFile()) {
12245
12450
  return {};
12246
12451
  }
12247
12452
  } catch {
@@ -12308,10 +12513,10 @@ function checkPackagingDrift(root, destination, walletKind2, force) {
12308
12513
  );
12309
12514
  return 1;
12310
12515
  }
12311
- const dockerfile = path29.join(agentRoot2, "Dockerfile");
12516
+ const dockerfile = path30.join(agentRoot2, "Dockerfile");
12312
12517
  let dockerfilePresent = false;
12313
12518
  try {
12314
- dockerfilePresent = fs30.statSync(dockerfile).isFile();
12519
+ dockerfilePresent = fs31.statSync(dockerfile).isFile();
12315
12520
  } catch {
12316
12521
  dockerfilePresent = false;
12317
12522
  }
@@ -12352,7 +12557,7 @@ function deployWalletKindSafe(root) {
12352
12557
  }
12353
12558
  let cfg;
12354
12559
  try {
12355
- cfg = loadStudioToml15(path29.join(agentRoot2, "studio.toml"));
12560
+ cfg = loadStudioToml15(path30.join(agentRoot2, "studio.toml"));
12356
12561
  } catch {
12357
12562
  return "evm-local";
12358
12563
  }
@@ -12365,22 +12570,22 @@ function deployWalletKindSafe(root) {
12365
12570
  import { findStudioWorkspaceRoot as findStudioWorkspaceRoot2 } from "@bnbagent/studio-runtime/config";
12366
12571
 
12367
12572
  // src/cli/_deploy/checks/blocked.ts
12368
- import * as fs31 from "fs";
12369
- import * as path30 from "path";
12573
+ import * as fs32 from "fs";
12574
+ import * as path31 from "path";
12370
12575
  import {
12371
12576
  findSubProjectRoot as findSubProjectRoot12,
12372
12577
  loadStudioToml as loadStudioToml16
12373
12578
  } from "@bnbagent/studio-runtime/config";
12374
- function isFile12(p) {
12579
+ function isFile13(p) {
12375
12580
  try {
12376
- return fs31.statSync(p).isFile();
12581
+ return fs32.statSync(p).isFile();
12377
12582
  } catch {
12378
12583
  return false;
12379
12584
  }
12380
12585
  }
12381
12586
  function isDir6(p) {
12382
12587
  try {
12383
- return fs31.statSync(p).isDirectory();
12588
+ return fs32.statSync(p).isDirectory();
12384
12589
  } catch {
12385
12590
  return false;
12386
12591
  }
@@ -12391,8 +12596,8 @@ async function checkStudioTomlPresent(root, _target) {
12391
12596
  agent: findSubProjectRoot12("agent", root)
12392
12597
  };
12393
12598
  for (const [side, subRoot] of Object.entries(layers)) {
12394
- const tomlPath = subRoot === null ? null : path30.join(subRoot, "studio.toml");
12395
- if (tomlPath === null || !isFile12(tomlPath)) {
12599
+ const tomlPath = subRoot === null ? null : path31.join(subRoot, "studio.toml");
12600
+ if (tomlPath === null || !isFile13(tomlPath)) {
12396
12601
  out.push({
12397
12602
  level: Level.BLOCKED,
12398
12603
  name: "studio_toml_present",
@@ -12416,8 +12621,8 @@ async function checkStudioTomlPresent(root, _target) {
12416
12621
  return out;
12417
12622
  }
12418
12623
  async function checkCwdIsProjectRoot(root, _target) {
12419
- const cwd = path30.resolve(process.cwd());
12420
- const rr = path30.resolve(root);
12624
+ const cwd = path31.resolve(process.cwd());
12625
+ const rr = path31.resolve(root);
12421
12626
  if (cwd !== rr) {
12422
12627
  return [
12423
12628
  {
@@ -12431,7 +12636,7 @@ async function checkCwdIsProjectRoot(root, _target) {
12431
12636
  return [];
12432
12637
  }
12433
12638
  async function checkNoSecretInGitHistory(root, _target) {
12434
- if (!isDir6(path30.join(root, ".git"))) {
12639
+ if (!isDir6(path31.join(root, ".git"))) {
12435
12640
  return [];
12436
12641
  }
12437
12642
  const needles = [".env.local", "WALLET_PASSWORD"];
@@ -12469,8 +12674,8 @@ var allChecks2 = [
12469
12674
  ];
12470
12675
 
12471
12676
  // src/cli/_deploy/checks/info.ts
12472
- import * as fs32 from "fs";
12473
- import * as path31 from "path";
12677
+ import * as fs33 from "fs";
12678
+ import * as path32 from "path";
12474
12679
  async function checkPreviousDeployStatus(root, _target) {
12475
12680
  const deploy = tableOf2(loadAgentToml(root), "deploy");
12476
12681
  const last = deploy.last_deploy_at;
@@ -12494,10 +12699,10 @@ async function checkPreviousDeployStatus(root, _target) {
12494
12699
  ];
12495
12700
  }
12496
12701
  async function checkInstalledRecipesList(root, _target) {
12497
- const manifest = path31.join(root, ".studio", "recipes", "manifest.json");
12702
+ const manifest = path32.join(root, ".studio", "recipes", "manifest.json");
12498
12703
  let exists = false;
12499
12704
  try {
12500
- exists = fs32.statSync(manifest).isFile();
12705
+ exists = fs33.statSync(manifest).isFile();
12501
12706
  } catch {
12502
12707
  exists = false;
12503
12708
  }
@@ -12513,7 +12718,7 @@ async function checkInstalledRecipesList(root, _target) {
12513
12718
  }
12514
12719
  let data;
12515
12720
  try {
12516
- data = JSON.parse(fs32.readFileSync(manifest, "utf-8"));
12721
+ data = JSON.parse(fs33.readFileSync(manifest, "utf-8"));
12517
12722
  } catch {
12518
12723
  return [
12519
12724
  {
@@ -12616,8 +12821,8 @@ var allChecks3 = [
12616
12821
  ];
12617
12822
 
12618
12823
  // src/cli/_deploy/checks/platform.ts
12619
- import * as fs34 from "fs";
12620
- import * as path33 from "path";
12824
+ import * as fs35 from "fs";
12825
+ import * as path34 from "path";
12621
12826
  import {
12622
12827
  findSubProjectRoot as findSubProjectRoot13,
12623
12828
  loadStudioToml as loadStudioToml17
@@ -12626,16 +12831,16 @@ import { BSC_TESTNET_FAUCET_URLS } from "@bnbagent/studio-runtime/networks";
12626
12831
 
12627
12832
  // src/cli/_deploy/checks/warning.ts
12628
12833
  import * as crypto4 from "crypto";
12629
- import * as fs33 from "fs";
12630
- import * as path32 from "path";
12834
+ import * as fs34 from "fs";
12835
+ import * as path33 from "path";
12631
12836
  import { envLocalPath as envLocalPath14 } from "@bnbagent/studio-runtime/config";
12632
12837
  import { show } from "@bnbagent/studio-runtime/erc8004";
12633
12838
  import { DEFAULT_RPC, getNetwork as getNetwork8 } from "@bnbagent/studio-runtime/networks";
12634
12839
  import * as walletRt3 from "@bnbagent/studio-runtime/wallet";
12635
12840
  var TBNB_MIN_WEI = 7n * 10n ** 15n;
12636
- function isFile13(p) {
12841
+ function isFile14(p) {
12637
12842
  try {
12638
- return fs33.statSync(p).isFile();
12843
+ return fs34.statSync(p).isFile();
12639
12844
  } catch {
12640
12845
  return false;
12641
12846
  }
@@ -12838,10 +13043,10 @@ async function checkRuntimeRpcReachable(root, _target) {
12838
13043
  return [];
12839
13044
  }
12840
13045
  async function checkInstalledRecipesUnchanged(root, _target) {
12841
- const manifest = path32.join(root, ".studio", "recipes", "manifest.json");
13046
+ const manifest = path33.join(root, ".studio", "recipes", "manifest.json");
12842
13047
  let data;
12843
13048
  try {
12844
- data = JSON.parse(fs33.readFileSync(manifest, "utf-8"));
13049
+ data = JSON.parse(fs34.readFileSync(manifest, "utf-8"));
12845
13050
  } catch {
12846
13051
  return [];
12847
13052
  }
@@ -12856,11 +13061,11 @@ async function checkInstalledRecipesUnchanged(root, _target) {
12856
13061
  if (!rel || !expected || typeof rel !== "string") {
12857
13062
  continue;
12858
13063
  }
12859
- const p = path32.join(root, rel);
12860
- if (!isFile13(p)) {
13064
+ const p = path33.join(root, rel);
13065
+ if (!isFile14(p)) {
12861
13066
  continue;
12862
13067
  }
12863
- const actual = crypto4.createHash("sha256").update(fs33.readFileSync(p)).digest("hex");
13068
+ const actual = crypto4.createHash("sha256").update(fs34.readFileSync(p)).digest("hex");
12864
13069
  if (actual !== expected) {
12865
13070
  stale.push(rel);
12866
13071
  }
@@ -12911,11 +13116,11 @@ function tableOf11(data, key) {
12911
13116
  return value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
12912
13117
  }
12913
13118
  function agentRoot(root) {
12914
- return findSubProjectRoot13("agent", root) ?? path33.join(root, "app", "agent");
13119
+ return findSubProjectRoot13("agent", root) ?? path34.join(root, "app", "agent");
12915
13120
  }
12916
13121
  function loadAgent(root) {
12917
13122
  try {
12918
- return loadStudioToml17(path33.join(agentRoot(root), "studio.toml"));
13123
+ return loadStudioToml17(path34.join(agentRoot(root), "studio.toml"));
12919
13124
  } catch {
12920
13125
  return {};
12921
13126
  }
@@ -12935,10 +13140,10 @@ var checkPlatformEntrypointPresent = async (root, _target) => {
12935
13140
  const filenames = [`${stem2}.ts`];
12936
13141
  if (stem2 === "dualMain") filenames.push("mcpMain.ts");
12937
13142
  const filename = filenames.find(
12938
- (candidate) => !fs34.existsSync(path33.join(agentRoot(root), "src", candidate))
13143
+ (candidate) => !fs35.existsSync(path34.join(agentRoot(root), "src", candidate))
12939
13144
  );
12940
13145
  if (filename === void 0) return [];
12941
- const expected = path33.join(agentRoot(root), "src", filename);
13146
+ const expected = path34.join(agentRoot(root), "src", filename);
12942
13147
  return [
12943
13148
  {
12944
13149
  level: Level.CRITICAL,
@@ -12952,18 +13157,18 @@ var checkPlatformKeystoreNotInArtifact = async (root, _target) => {
12952
13157
  const data = loadAgent(root);
12953
13158
  const wallet = tableOf11(data, "wallet");
12954
13159
  if (String(wallet.kind ?? "evm-local") === "twak") return [];
12955
- const agent = path33.resolve(agentRoot(root));
13160
+ const agent = path34.resolve(agentRoot(root));
12956
13161
  const configured = String(wallet.keystore_dir ?? ".studio/wallets");
12957
- const keystore = path33.resolve(agent, configured);
13162
+ const keystore = path34.resolve(agent, configured);
12958
13163
  let jsonFiles;
12959
13164
  try {
12960
- jsonFiles = fs34.readdirSync(keystore).filter((name) => name.endsWith(".json"));
13165
+ jsonFiles = fs35.readdirSync(keystore).filter((name) => name.endsWith(".json"));
12961
13166
  } catch {
12962
13167
  return [];
12963
13168
  }
12964
13169
  if (jsonFiles.length === 0) return [];
12965
- const rel = path33.relative(agent, keystore);
12966
- if (rel.startsWith("..") || path33.isAbsolute(rel)) return [];
13170
+ const rel = path34.relative(agent, keystore);
13171
+ if (rel.startsWith("..") || path34.isAbsolute(rel)) return [];
12967
13172
  return [
12968
13173
  {
12969
13174
  level: Level.CRITICAL,
@@ -13190,7 +13395,7 @@ async function runProducers(producers, root, target) {
13190
13395
  }
13191
13396
 
13192
13397
  // src/cli/_deploy/verify.ts
13193
- import * as path35 from "path";
13398
+ import * as path36 from "path";
13194
13399
  import {
13195
13400
  findSubProjectRoot as findSubProjectRoot14,
13196
13401
  loadStudioToml as loadStudioToml18
@@ -13203,11 +13408,11 @@ import {
13203
13408
  import * as walletRt4 from "@bnbagent/studio-runtime/wallet";
13204
13409
 
13205
13410
  // src/cli/_identity.ts
13206
- import * as fs35 from "fs";
13207
- import * as path34 from "path";
13411
+ import * as fs36 from "fs";
13412
+ import * as path35 from "path";
13208
13413
  function writeIdentityBlock(root, identity) {
13209
- const p = path34.join(root, "studio.toml");
13210
- const text2 = fs35.readFileSync(p, "utf-8");
13414
+ const p = path35.join(root, "studio.toml");
13415
+ const text2 = fs36.readFileSync(p, "utf-8");
13211
13416
  const lines = text2.split(/\r?\n/);
13212
13417
  if (lines.length > 0 && lines[lines.length - 1] === "") {
13213
13418
  lines.pop();
@@ -13246,7 +13451,7 @@ function writeIdentityBlock(root, identity) {
13246
13451
  }
13247
13452
  }
13248
13453
  out.push("");
13249
- fs35.writeFileSync(p, out.join("\n"), "utf-8");
13454
+ fs36.writeFileSync(p, out.join("\n"), "utf-8");
13250
13455
  }
13251
13456
 
13252
13457
  // src/cli/_deploy/verify.ts
@@ -13364,7 +13569,7 @@ async function runVerify(opts) {
13364
13569
  const endpoint = opts.endpoint;
13365
13570
  const runtime = opts.runtime ?? "agentcore";
13366
13571
  const skipRegister = opts.skipRegister ?? false;
13367
- const start = opts.projectRoot ? path35.resolve(opts.projectRoot) : void 0;
13572
+ const start = opts.projectRoot ? path36.resolve(opts.projectRoot) : void 0;
13368
13573
  const root = findSubProjectRoot14("agent", start);
13369
13574
  if (root === null) {
13370
13575
  return baseResult(endpoint, runtime, {
@@ -13384,7 +13589,7 @@ async function runVerify(opts) {
13384
13589
  }
13385
13590
  let data;
13386
13591
  try {
13387
- data = loadStudioToml18(path35.join(root, "studio.toml"));
13592
+ data = loadStudioToml18(path36.join(root, "studio.toml"));
13388
13593
  } catch (exc) {
13389
13594
  return baseResult(endpoint, runtime, {
13390
13595
  awsAccount,
@@ -13545,8 +13750,8 @@ async function runVerify(opts) {
13545
13750
  }
13546
13751
 
13547
13752
  // src/cli/_hosted/deployOps.ts
13548
- import * as fs36 from "fs";
13549
- import * as path36 from "path";
13753
+ import * as fs37 from "fs";
13754
+ import * as path37 from "path";
13550
13755
  import {
13551
13756
  envLocalPath as envLocalPath15,
13552
13757
  findSubProjectRoot as findSubProjectRoot15,
@@ -13557,7 +13762,12 @@ var PLATFORM_SECTION = "deploy.platform";
13557
13762
  var WALLET_SECTION = "wallet";
13558
13763
  var KEYSTORE_JSON_ENV2 = "WALLET_KEYSTORE_JSON";
13559
13764
  var TWAK_WALLET_JSON_ENV2 = "TWAK_WALLET_JSON";
13560
- var WALLET_MATERIAL_KEYS = [KEYSTORE_JSON_ENV2, TWAK_WALLET_JSON_ENV2];
13765
+ var ALTANA_SESSION_ENV2 = "ALTANA_SESSION";
13766
+ var WALLET_MATERIAL_KEYS = [
13767
+ KEYSTORE_JSON_ENV2,
13768
+ TWAK_WALLET_JSON_ENV2,
13769
+ ALTANA_SESSION_ENV2
13770
+ ];
13561
13771
  var RETIRED_AGENT_STATES = /* @__PURE__ */ new Set([
13562
13772
  "deleted",
13563
13773
  "retired",
@@ -13587,8 +13797,8 @@ function agentTomlPath2(root) {
13587
13797
  if (agentRoot2 === null) {
13588
13798
  return null;
13589
13799
  }
13590
- const tomlPath = path36.join(agentRoot2, "studio.toml");
13591
- return isFile14(tomlPath) ? tomlPath : null;
13800
+ const tomlPath = path37.join(agentRoot2, "studio.toml");
13801
+ return isFile15(tomlPath) ? tomlPath : null;
13592
13802
  }
13593
13803
  function loadAgentCfg(root) {
13594
13804
  const tomlPath = agentTomlPath2(root);
@@ -13605,12 +13815,12 @@ function platformCfg(root) {
13605
13815
  return tableOf12(tableOf12(loadAgentCfg(root), "deploy"), "platform");
13606
13816
  }
13607
13817
  function patchTomlKv2(tomlPath, section, key, value) {
13608
- let text2 = fs36.readFileSync(tomlPath, "utf-8");
13818
+ let text2 = fs37.readFileSync(tomlPath, "utf-8");
13609
13819
  if (!hasSection(text2, section)) {
13610
13820
  text2 = addSection(text2, section);
13611
13821
  }
13612
13822
  text2 = hasKey(text2, section, key) ? setExistingKey(text2, section, key, value) : addKeyToSection(text2, section, key, value);
13613
- fs36.writeFileSync(tomlPath, text2);
13823
+ fs37.writeFileSync(tomlPath, text2);
13614
13824
  }
13615
13825
  function recordPlatformKv(root, key, value) {
13616
13826
  const tomlPath = agentTomlPath2(root);
@@ -13709,8 +13919,8 @@ function clearIdentityEndpointIfMatches(root, oldUrl) {
13709
13919
  }
13710
13920
  }
13711
13921
  function persistedPackaging2(agentRoot2) {
13712
- const tomlPath = path36.join(agentRoot2, "studio.toml");
13713
- if (!isFile14(tomlPath)) {
13922
+ const tomlPath = path37.join(agentRoot2, "studio.toml");
13923
+ if (!isFile15(tomlPath)) {
13714
13924
  return null;
13715
13925
  }
13716
13926
  try {
@@ -13722,8 +13932,8 @@ function persistedPackaging2(agentRoot2) {
13722
13932
  }
13723
13933
  }
13724
13934
  function resolvePlatformArtifact2(agentRoot2) {
13725
- const tomlPath = path36.join(agentRoot2, "studio.toml");
13726
- if (isFile14(tomlPath)) {
13935
+ const tomlPath = path37.join(agentRoot2, "studio.toml");
13936
+ if (isFile15(tomlPath)) {
13727
13937
  try {
13728
13938
  const cfg = loadStudioToml19(tomlPath);
13729
13939
  const explicit = tableOf12(cfg, "deploy").platform_artifact;
@@ -13746,7 +13956,7 @@ function platformPackaging(root) {
13746
13956
  }
13747
13957
  function loadCfgAt(agentRoot2) {
13748
13958
  try {
13749
- return loadStudioToml19(path36.join(agentRoot2, "studio.toml"));
13959
+ return loadStudioToml19(path37.join(agentRoot2, "studio.toml"));
13750
13960
  } catch {
13751
13961
  return {};
13752
13962
  }
@@ -13823,7 +14033,7 @@ function resolveSlug(root) {
13823
14033
  let name = String(tableOf12(loadAgentCfg(root), "project").name ?? "");
13824
14034
  name = name.replace(/-(agent|service)$/, "");
13825
14035
  if (!name) {
13826
- name = path36.basename(findWorkspaceRoot6(root) ?? root);
14036
+ name = path37.basename(findWorkspaceRoot6(root) ?? root);
13827
14037
  }
13828
14038
  let base = name.toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-+|-+$/g, "");
13829
14039
  base = base || "agent";
@@ -14065,6 +14275,19 @@ function walletWarning(root, secrets) {
14065
14275
  return;
14066
14276
  }
14067
14277
  const address = tableOf12(loadAgentCfg(root), "wallet").address;
14278
+ if (ALTANA_SESSION_ENV2 in secrets) {
14279
+ const who2 = typeof address === "string" && address ? ` (wallet ${address})` : "";
14280
+ warn(
14281
+ `
14282
+ !!! session exposure (platform trial) !!!
14283
+ 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.
14284
+ If the current budget or expiry is wider than you want an operator-held key to carry, stop and grant a tighter one first:
14285
+ bag wallet session grant --force --budget-u <small> --expiry-days <short>
14286
+ You can revoke it on-chain at any time with \`bag wallet session revoke\`.
14287
+ `
14288
+ );
14289
+ return;
14290
+ }
14068
14291
  const who = typeof address === "string" && address ? `key (address ${address})` : "signing key";
14069
14292
  warn(
14070
14293
  `
@@ -14281,15 +14504,15 @@ function printAgentClientPrompt(root, invokeUrl, status) {
14281
14504
  }
14282
14505
  function persistDeploySummary(root, text2) {
14283
14506
  try {
14284
- if (!fs36.statSync(path36.resolve(root)).isDirectory()) {
14507
+ if (!fs37.statSync(path37.resolve(root)).isDirectory()) {
14285
14508
  return null;
14286
14509
  }
14287
- const p = path36.join(
14288
- path36.dirname(envLocalPath15(root)),
14510
+ const p = path37.join(
14511
+ path37.dirname(envLocalPath15(root)),
14289
14512
  "last-deploy-summary.txt"
14290
14513
  );
14291
- fs36.mkdirSync(path36.dirname(p), { recursive: true });
14292
- fs36.writeFileSync(p, `${text2}
14514
+ fs37.mkdirSync(path37.dirname(p), { recursive: true });
14515
+ fs37.writeFileSync(p, `${text2}
14293
14516
  `);
14294
14517
  return p;
14295
14518
  } catch {
@@ -14444,9 +14667,9 @@ async function deletePlatformAgent(slug, deps = {}) {
14444
14667
  }
14445
14668
  return 0;
14446
14669
  }
14447
- function isFile14(p) {
14670
+ function isFile15(p) {
14448
14671
  try {
14449
- return fs36.statSync(p).isFile();
14672
+ return fs37.statSync(p).isFile();
14450
14673
  } catch {
14451
14674
  return false;
14452
14675
  }
@@ -14459,16 +14682,16 @@ var ADVERTISED_DEPLOY_RUNTIME_TARGETS = ["agentcore"];
14459
14682
  // src/cli/deploy.ts
14460
14683
  var TARGET_CHOICES = [...DEPLOY_RUNTIME_TARGETS];
14461
14684
  var ADVERTISED_TARGET_CHOICES = [...ADVERTISED_DEPLOY_RUNTIME_TARGETS];
14462
- function isFile15(p) {
14685
+ function isFile16(p) {
14463
14686
  try {
14464
- return fs37.statSync(p).isFile();
14687
+ return fs38.statSync(p).isFile();
14465
14688
  } catch {
14466
14689
  return false;
14467
14690
  }
14468
14691
  }
14469
14692
  function isDir7(p) {
14470
14693
  try {
14471
- return fs37.statSync(p).isDirectory();
14694
+ return fs38.statSync(p).isDirectory();
14472
14695
  } catch {
14473
14696
  return false;
14474
14697
  }
@@ -14485,8 +14708,8 @@ function loadAgentCfg2(root) {
14485
14708
  if (agentRoot2 === null) {
14486
14709
  return null;
14487
14710
  }
14488
- const tomlPath = path37.join(agentRoot2, "studio.toml");
14489
- if (!isFile15(tomlPath)) {
14711
+ const tomlPath = path38.join(agentRoot2, "studio.toml");
14712
+ if (!isFile16(tomlPath)) {
14490
14713
  return null;
14491
14714
  }
14492
14715
  try {
@@ -14663,9 +14886,9 @@ function applyProjectRoot(projectRoot, requireToml = true) {
14663
14886
  if (projectRoot === void 0) {
14664
14887
  return null;
14665
14888
  }
14666
- const p = path37.resolve(projectRoot);
14889
+ const p = path38.resolve(projectRoot);
14667
14890
  const agentRoot2 = findSubProjectRoot16("agent", p);
14668
- if (requireToml && !isFile15(path37.join(p, "studio.toml")) && (agentRoot2 === null || !isFile15(path37.join(agentRoot2, "studio.toml")))) {
14891
+ if (requireToml && !isFile16(path38.join(p, "studio.toml")) && (agentRoot2 === null || !isFile16(path38.join(agentRoot2, "studio.toml")))) {
14669
14892
  printErr(`error: no studio.toml under --project-root ${p}`);
14670
14893
  return 2;
14671
14894
  }
@@ -14677,7 +14900,7 @@ function applyProjectRoot(projectRoot, requireToml = true) {
14677
14900
  return null;
14678
14901
  }
14679
14902
  function resolveProjectRoot2(_projectRoot) {
14680
- const cwd = path37.resolve(process.cwd());
14903
+ const cwd = path38.resolve(process.cwd());
14681
14904
  return findStudioWorkspaceRoot3(cwd) ?? cwd;
14682
14905
  }
14683
14906
  function deployWorkspaceRoot2(root) {
@@ -14743,7 +14966,7 @@ function validateRuntimeAgainstStack(target, force, root) {
14743
14966
  async function cmdPrepare(opts) {
14744
14967
  let root;
14745
14968
  if (opts.projectRoot !== void 0) {
14746
- const p = path37.resolve(opts.projectRoot);
14969
+ const p = path38.resolve(opts.projectRoot);
14747
14970
  if (!isDir7(p)) {
14748
14971
  printErr(`error: --project-root ${p} is not a directory`);
14749
14972
  return 2;
@@ -14751,7 +14974,7 @@ async function cmdPrepare(opts) {
14751
14974
  process.chdir(p);
14752
14975
  root = findStudioWorkspaceRoot3(p) ?? p;
14753
14976
  } else {
14754
- const cwd = path37.resolve(process.cwd());
14977
+ const cwd = path38.resolve(process.cwd());
14755
14978
  root = findStudioWorkspaceRoot3(cwd) ?? cwd;
14756
14979
  }
14757
14980
  const target = resolveTarget(opts, root);
@@ -14893,8 +15116,8 @@ function writeAgentDeployState(workspaceRoot, arn, record = {}, destination = "s
14893
15116
  if (agentRoot2 === null) {
14894
15117
  return;
14895
15118
  }
14896
- const tomlPath = path37.join(agentRoot2, "studio.toml");
14897
- if (!isFile15(tomlPath)) {
15119
+ const tomlPath = path38.join(agentRoot2, "studio.toml");
15120
+ if (!isFile16(tomlPath)) {
14898
15121
  return;
14899
15122
  }
14900
15123
  try {
@@ -14972,10 +15195,10 @@ package and at the repo root).
14972
15195
  `;
14973
15196
  function iamNoticeTomlPath(root) {
14974
15197
  const agentRoot2 = findSubProjectRoot16("agent", root) ?? root;
14975
- return path37.join(agentRoot2, "studio.toml");
15198
+ return path38.join(agentRoot2, "studio.toml");
14976
15199
  }
14977
15200
  function iamNoticeAccepted(tomlPath) {
14978
- if (!isFile15(tomlPath)) {
15201
+ if (!isFile16(tomlPath)) {
14979
15202
  return false;
14980
15203
  }
14981
15204
  let data;
@@ -15026,7 +15249,7 @@ async function iamNoticeGate(root, acceptRisk) {
15026
15249
  return 1;
15027
15250
  }
15028
15251
  async function buildAgentProject(agentRoot2, packaging) {
15029
- if (!isFile15(path37.join(agentRoot2, "package.json"))) {
15252
+ if (!isFile16(path38.join(agentRoot2, "package.json"))) {
15030
15253
  printErr(
15031
15254
  `warning: no package.json under ${agentRoot2} \u2014 skipping the agent \`pnpm build\`; bnbagent-deploy will package whatever dist/ holds.`
15032
15255
  );
@@ -15217,12 +15440,6 @@ async function cmdAgent(opts, agentcoreArgs) {
15217
15440
  const packagingDestination = opts.to ?? opts.destination ?? agentDeployDestination(root);
15218
15441
  const driftAgentRoot = findSubProjectRoot16("agent", root) ?? root;
15219
15442
  const driftKind = deployWalletKind(driftAgentRoot);
15220
- if (driftKind === "altana") {
15221
- printErr(
15222
- "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."
15223
- );
15224
- return 2;
15225
- }
15226
15443
  rc = checkPackagingDrift(
15227
15444
  root,
15228
15445
  packagingDestination,
@@ -15365,7 +15582,7 @@ async function cmdAgent(opts, agentcoreArgs) {
15365
15582
  packagingDestination,
15366
15583
  resolvePlatformArtifact(agentRoot2)
15367
15584
  ) === "container" ? "container" : "zip";
15368
- const walletBlurb = walletKind2 === "twak" ? "the encrypted twak wallet as TWAK_WALLET_JSON" : "the encrypted keystore as WALLET_KEYSTORE_JSON";
15585
+ 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";
15369
15586
  if (secretsMode === "envvars") {
15370
15587
  printErr(
15371
15588
  `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.`
@@ -15483,7 +15700,7 @@ function recordedEndpoint(root) {
15483
15700
  }
15484
15701
  function recordedAgentId(agentRoot2) {
15485
15702
  try {
15486
- const cfg = loadStudioToml20(path37.join(agentRoot2, "studio.toml"));
15703
+ const cfg = loadStudioToml20(path38.join(agentRoot2, "studio.toml"));
15487
15704
  const val = tableOf13(cfg, "identity").agent_id;
15488
15705
  return val !== void 0 && val !== null && val !== "" ? String(val) : null;
15489
15706
  } catch {
@@ -15492,7 +15709,7 @@ function recordedAgentId(agentRoot2) {
15492
15709
  }
15493
15710
  function recordedRuntimeArn(agentRoot2) {
15494
15711
  try {
15495
- const cfg = loadStudioToml20(path37.join(agentRoot2, "studio.toml"));
15712
+ const cfg = loadStudioToml20(path38.join(agentRoot2, "studio.toml"));
15496
15713
  const val = tableOf13(cfg, "deploy").runtime_arn;
15497
15714
  return val ? String(val) : null;
15498
15715
  } catch {
@@ -15501,7 +15718,7 @@ function recordedRuntimeArn(agentRoot2) {
15501
15718
  }
15502
15719
  function recordedOauthClientId(agentRoot2) {
15503
15720
  try {
15504
- const cfg = loadStudioToml20(path37.join(agentRoot2, "studio.toml"));
15721
+ const cfg = loadStudioToml20(path38.join(agentRoot2, "studio.toml"));
15505
15722
  const val = tableOf13(cfg, "deploy").oauth_client_id;
15506
15723
  return val ? String(val) : null;
15507
15724
  } catch {
@@ -15510,7 +15727,7 @@ function recordedOauthClientId(agentRoot2) {
15510
15727
  }
15511
15728
  function agentFacesOf(agentRoot2) {
15512
15729
  try {
15513
- const cfg = loadStudioToml20(path37.join(agentRoot2, "studio.toml"));
15730
+ const cfg = loadStudioToml20(path38.join(agentRoot2, "studio.toml"));
15514
15731
  return stackFaces(tableOf13(cfg, "stack"), tableOf13(cfg, "payments"));
15515
15732
  } catch {
15516
15733
  return ["A2A"];
@@ -15662,15 +15879,15 @@ async function printAgentClientPrompt2(root, destination, opts = {}) {
15662
15879
  }
15663
15880
  function persistDeploySummary2(root, text2) {
15664
15881
  try {
15665
- if (!fs37.statSync(path37.resolve(root)).isDirectory()) {
15882
+ if (!fs38.statSync(path38.resolve(root)).isDirectory()) {
15666
15883
  return null;
15667
15884
  }
15668
- const p = path37.join(
15669
- path37.dirname(envLocalPath16(root)),
15885
+ const p = path38.join(
15886
+ path38.dirname(envLocalPath16(root)),
15670
15887
  "last-deploy-summary.txt"
15671
15888
  );
15672
- fs37.mkdirSync(path37.dirname(p), { recursive: true });
15673
- fs37.writeFileSync(p, `${text2}
15889
+ fs38.mkdirSync(path38.dirname(p), { recursive: true });
15890
+ fs38.writeFileSync(p, `${text2}
15674
15891
  `, "utf-8");
15675
15892
  return p;
15676
15893
  } catch {
@@ -16067,9 +16284,9 @@ async function cmdDestroy(opts) {
16067
16284
  return 2;
16068
16285
  }
16069
16286
  const answer = await promptUser(
16070
- `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: `
16287
+ `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: `
16071
16288
  );
16072
- if (answer.trim() !== path37.basename(workspaceRoot)) {
16289
+ if (answer.trim() !== path38.basename(workspaceRoot)) {
16073
16290
  printErr(
16074
16291
  "error: confirmation did not match the project name; aborting."
16075
16292
  );
@@ -16185,8 +16402,8 @@ async function cmdProvisionCognito(opts) {
16185
16402
 
16186
16403
  // src/cli/doctor.ts
16187
16404
  import * as crypto5 from "crypto";
16188
- import * as fs38 from "fs";
16189
- import * as path38 from "path";
16405
+ import * as fs39 from "fs";
16406
+ import * as path39 from "path";
16190
16407
  import { EVMWalletProvider as EVMWalletProvider2 } from "@bnbagent/sdk";
16191
16408
  import {
16192
16409
  envLocalPath as envLocalPath17,
@@ -16232,23 +16449,23 @@ function tableOf14(cfg, key) {
16232
16449
  const v = cfg[key];
16233
16450
  return v !== null && typeof v === "object" && !Array.isArray(v) ? v : {};
16234
16451
  }
16235
- function isFile16(p) {
16452
+ function isFile17(p) {
16236
16453
  try {
16237
- return fs38.statSync(p).isFile();
16454
+ return fs39.statSync(p).isFile();
16238
16455
  } catch {
16239
16456
  return false;
16240
16457
  }
16241
16458
  }
16242
16459
  function isDir8(p) {
16243
16460
  try {
16244
- return fs38.statSync(p).isDirectory();
16461
+ return fs39.statSync(p).isDirectory();
16245
16462
  } catch {
16246
16463
  return false;
16247
16464
  }
16248
16465
  }
16249
16466
  function keystoreJsons(dir) {
16250
16467
  try {
16251
- return fs38.readdirSync(dir).filter((f) => f.endsWith(".json")).sort();
16468
+ return fs39.readdirSync(dir).filter((f) => f.endsWith(".json")).sort();
16252
16469
  } catch {
16253
16470
  return [];
16254
16471
  }
@@ -16277,7 +16494,7 @@ async function cmdDoctor(opts) {
16277
16494
  if (opts.checkEnv) {
16278
16495
  return runCheckEnv(projectRoot);
16279
16496
  }
16280
- const tomlPath = path38.join(projectRoot, "studio.toml");
16497
+ const tomlPath = path39.join(projectRoot, "studio.toml");
16281
16498
  let data;
16282
16499
  try {
16283
16500
  data = loadStudioToml21(tomlPath);
@@ -16313,8 +16530,8 @@ async function cmdDoctor(opts) {
16313
16530
  }
16314
16531
  function resolveProjectRoot3(argRoot) {
16315
16532
  if (argRoot !== void 0) {
16316
- const root2 = path38.resolve(argRoot);
16317
- if (!isFile16(path38.join(root2, "studio.toml"))) {
16533
+ const root2 = path39.resolve(argRoot);
16534
+ if (!isFile17(path39.join(root2, "studio.toml"))) {
16318
16535
  printErr(`error: no studio.toml under --project-root ${root2}`);
16319
16536
  return null;
16320
16537
  }
@@ -16328,15 +16545,15 @@ function resolveProjectRoot3(argRoot) {
16328
16545
  return root;
16329
16546
  }
16330
16547
  function runCheckEnv(projectRoot) {
16331
- const agentDir = workspaceLayers(projectRoot) ?? path38.join(projectRoot, "agent");
16548
+ const agentDir = workspaceLayers(projectRoot) ?? path39.join(projectRoot, "agent");
16332
16549
  const envPath = envLocalPath17(agentDir);
16333
16550
  printOut(`bag doctor --check-env: ${envPath}`);
16334
- if (!isFile16(envPath)) {
16335
- printOut(` (no ${path38.basename(envPath)} found \u2014 nothing to report)`);
16551
+ if (!isFile17(envPath)) {
16552
+ printOut(` (no ${path39.basename(envPath)} found \u2014 nothing to report)`);
16336
16553
  return 0;
16337
16554
  }
16338
16555
  const values = {};
16339
- for (const rawLine of fs38.readFileSync(envPath, "utf-8").split(/\r?\n/)) {
16556
+ for (const rawLine of fs39.readFileSync(envPath, "utf-8").split(/\r?\n/)) {
16340
16557
  const line = rawLine.trim();
16341
16558
  if (!line || line.startsWith("#") || !line.includes("=")) {
16342
16559
  continue;
@@ -16363,25 +16580,25 @@ function runCheckEnv(projectRoot) {
16363
16580
  return 0;
16364
16581
  }
16365
16582
  function workspaceLayers(projectRoot) {
16366
- const parent = path38.dirname(projectRoot);
16367
- if (isFile16(path38.join(parent, "agent", "studio.toml"))) {
16368
- return path38.join(parent, "agent");
16583
+ const parent = path39.dirname(projectRoot);
16584
+ if (isFile17(path39.join(parent, "agent", "studio.toml"))) {
16585
+ return path39.join(parent, "agent");
16369
16586
  }
16370
- if (isFile16(path38.join(projectRoot, "agent", "studio.toml"))) {
16371
- return path38.join(projectRoot, "agent");
16587
+ if (isFile17(path39.join(projectRoot, "agent", "studio.toml"))) {
16588
+ return path39.join(projectRoot, "agent");
16372
16589
  }
16373
16590
  return null;
16374
16591
  }
16375
16592
  function checkAppMain(projectRootArg) {
16376
16593
  let projectRoot = projectRootArg;
16377
- const parent = path38.dirname(projectRoot);
16378
- if (isFile16(path38.join(parent, "agent", "studio.toml"))) {
16594
+ const parent = path39.dirname(projectRoot);
16595
+ if (isFile17(path39.join(parent, "agent", "studio.toml"))) {
16379
16596
  projectRoot = parent;
16380
16597
  }
16381
- const agentDir = path38.join(projectRoot, "agent");
16598
+ const agentDir = path39.join(projectRoot, "agent");
16382
16599
  let config = {};
16383
- const tomlPath = path38.join(agentDir, "studio.toml");
16384
- if (isFile16(tomlPath)) {
16600
+ const tomlPath = path39.join(agentDir, "studio.toml");
16601
+ if (isFile17(tomlPath)) {
16385
16602
  try {
16386
16603
  config = loadStudioToml21(tomlPath);
16387
16604
  } catch {
@@ -16399,8 +16616,8 @@ function checkAppMain(projectRootArg) {
16399
16616
  } else {
16400
16617
  entrypoint = "src/main.ts";
16401
16618
  }
16402
- const entryFile = path38.join(agentDir, entrypoint);
16403
- if (!isFile16(entryFile)) {
16619
+ const entryFile = path39.join(agentDir, entrypoint);
16620
+ if (!isFile17(entryFile)) {
16404
16621
  return [
16405
16622
  {
16406
16623
  name: "agent entrypoint",
@@ -16415,12 +16632,12 @@ function checkAppMain(projectRootArg) {
16415
16632
  function checkAgentcoreName(projectRoot) {
16416
16633
  let cfgPath = null;
16417
16634
  for (const candidate of [
16418
- path38.dirname(path38.dirname(projectRoot)),
16419
- path38.dirname(projectRoot),
16635
+ path39.dirname(path39.dirname(projectRoot)),
16636
+ path39.dirname(projectRoot),
16420
16637
  projectRoot
16421
16638
  ]) {
16422
- const p = path38.join(candidate, "agentcore", "agentcore.json");
16423
- if (isFile16(p)) {
16639
+ const p = path39.join(candidate, "agentcore", "agentcore.json");
16640
+ if (isFile17(p)) {
16424
16641
  cfgPath = p;
16425
16642
  break;
16426
16643
  }
@@ -16430,7 +16647,7 @@ function checkAgentcoreName(projectRoot) {
16430
16647
  }
16431
16648
  let cfg;
16432
16649
  try {
16433
- cfg = JSON.parse(fs38.readFileSync(cfgPath, "utf-8"));
16650
+ cfg = JSON.parse(fs39.readFileSync(cfgPath, "utf-8"));
16434
16651
  } catch {
16435
16652
  return [];
16436
16653
  }
@@ -16462,7 +16679,7 @@ function isLocalEvmWallet(walletCfg) {
16462
16679
  }
16463
16680
  function anchoredKeystoreDir(projectRoot, walletCfg) {
16464
16681
  const rel = String(walletCfg.keystore_dir ?? ".studio/wallets");
16465
- return path38.isAbsolute(rel) ? rel : path38.join(projectRoot, rel);
16682
+ return path39.isAbsolute(rel) ? rel : path39.join(projectRoot, rel);
16466
16683
  }
16467
16684
  async function checkWallet(projectRoot, data) {
16468
16685
  const walletCfg = tableOf14(data, "wallet");
@@ -16508,8 +16725,8 @@ async function checkWallet(projectRoot, data) {
16508
16725
  }
16509
16726
  const address = String(walletCfg.address ?? "").trim();
16510
16727
  if (address) {
16511
- const expected = path38.join(keystoreDir, `${address}.json`);
16512
- if (!isFile16(expected)) {
16728
+ const expected = path39.join(keystoreDir, `${address}.json`);
16729
+ if (!isFile17(expected)) {
16513
16730
  out.push({
16514
16731
  name: "[wallet] address \u2194 keystore",
16515
16732
  status: FAIL,
@@ -16519,7 +16736,7 @@ async function checkWallet(projectRoot, data) {
16519
16736
  out.push({
16520
16737
  name: "[wallet] address \u2194 keystore",
16521
16738
  status: PASS,
16522
- detail: `${address} matches ${path38.basename(expected)}`
16739
+ detail: `${address} matches ${path39.basename(expected)}`
16523
16740
  });
16524
16741
  }
16525
16742
  }
@@ -16536,9 +16753,9 @@ function checkWalletAltana(walletCfg, projectRoot) {
16536
16753
  detail: "no [wallet].address \u2014 run `bag wallet new` first"
16537
16754
  });
16538
16755
  } else {
16539
- const expected = path38.join(keystoreDir, `${address}.json`);
16756
+ const expected = path39.join(keystoreDir, `${address}.json`);
16540
16757
  out.push(
16541
- isFile16(expected) ? {
16758
+ isFile17(expected) ? {
16542
16759
  name: "[wallet] Altana admin",
16543
16760
  status: PASS,
16544
16761
  detail: `${address} matches ${expected}`
@@ -16552,8 +16769,8 @@ function checkWalletAltana(walletCfg, projectRoot) {
16552
16769
  const configured = String(
16553
16770
  walletCfg.session_file ?? ".studio/wallets/altana-session.json"
16554
16771
  );
16555
- const sessionFile = path38.isAbsolute(configured) ? configured : path38.join(projectRoot, configured);
16556
- if (!isFile16(sessionFile)) {
16772
+ const sessionFile = path39.isAbsolute(configured) ? configured : path39.join(projectRoot, configured);
16773
+ if (!isFile17(sessionFile)) {
16557
16774
  out.push({
16558
16775
  name: "[wallet] Altana session",
16559
16776
  status: FAIL,
@@ -16563,7 +16780,7 @@ function checkWalletAltana(walletCfg, projectRoot) {
16563
16780
  }
16564
16781
  let envelope;
16565
16782
  try {
16566
- envelope = JSON.parse(fs38.readFileSync(sessionFile, "utf8"));
16783
+ envelope = JSON.parse(fs39.readFileSync(sessionFile, "utf8"));
16567
16784
  } catch {
16568
16785
  out.push({
16569
16786
  name: "[wallet] Altana session",
@@ -16589,7 +16806,7 @@ function checkWalletAltana(walletCfg, projectRoot) {
16589
16806
  status: remaining <= 0 ? FAIL : remaining < 3 * 24 * 60 * 60 ? WARN : PASS,
16590
16807
  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\``
16591
16808
  });
16592
- if ((fs38.statSync(sessionFile).mode & 63) !== 0) {
16809
+ if ((fs39.statSync(sessionFile).mode & 63) !== 0) {
16593
16810
  out.push({
16594
16811
  name: "[wallet] Altana session permissions",
16595
16812
  status: WARN,
@@ -16647,7 +16864,7 @@ async function checkWalletTwak(walletCfg, projectRoot, data = {}) {
16647
16864
  });
16648
16865
  }
16649
16866
  const walletFile = twakWalletFile(walletCfg, projectRoot);
16650
- if (isFile16(walletFile)) {
16867
+ if (isFile17(walletFile)) {
16651
16868
  out.push({
16652
16869
  name: "[wallet] twak wallet",
16653
16870
  status: PASS,
@@ -16657,7 +16874,7 @@ async function checkWalletTwak(walletCfg, projectRoot, data = {}) {
16657
16874
  let createCmd = "twak wallet create --password <pw> --no-keychain";
16658
16875
  let setupCmd = "twak setup";
16659
16876
  if (walletCfg.twak_home) {
16660
- const home = path38.dirname(path38.dirname(walletFile));
16877
+ const home = path39.dirname(path39.dirname(walletFile));
16661
16878
  createCmd = `HOME=${home} ${createCmd}`;
16662
16879
  setupCmd = `HOME=${home} ${setupCmd}`;
16663
16880
  }
@@ -16759,6 +16976,14 @@ async function checkLlm(data, projectRoot) {
16759
16976
  });
16760
16977
  }
16761
16978
  if (provider === "pieverse-llm") {
16979
+ const walletKind2 = String(tableOf14(data, "wallet").kind ?? "");
16980
+ if (walletKind2 === "altana") {
16981
+ out.push({
16982
+ name: "pieverse wallet compatibility",
16983
+ status: FAIL,
16984
+ detail: "wallet kind 'altana' cannot log in to Pieverse (SIWE needs EIP-191 'sign.message', which altana never exposes) \u2014 `bag llm activate` will always fail. Set [llm].provider to 'openrouter', 'openai', or 'anthropic' in studio.toml."
16985
+ });
16986
+ }
16762
16987
  out.push(...await checkPieverse(data, keyValue));
16763
16988
  }
16764
16989
  return out;
@@ -17413,11 +17638,11 @@ function checkAgentsMdSkillTrigger(projectRoot) {
17413
17638
  if (ws === null) {
17414
17639
  return [];
17415
17640
  }
17416
- const agentsMd = path38.join(ws, "AGENTS.md");
17641
+ const agentsMd = path39.join(ws, "AGENTS.md");
17417
17642
  const line = "For any bnbagent-studio task (deploy, sell, operate, debug), load the `/bnbagent-studio` skill first.";
17418
17643
  let text2;
17419
17644
  try {
17420
- text2 = isFile16(agentsMd) ? fs38.readFileSync(agentsMd, "utf-8") : null;
17645
+ text2 = isFile17(agentsMd) ? fs39.readFileSync(agentsMd, "utf-8") : null;
17421
17646
  } catch {
17422
17647
  return [];
17423
17648
  }
@@ -17454,8 +17679,8 @@ function printChecks(checks) {
17454
17679
  }
17455
17680
 
17456
17681
  // src/cli/env.ts
17457
- import * as fs39 from "fs";
17458
- import * as path39 from "path";
17682
+ import * as fs40 from "fs";
17683
+ import * as path40 from "path";
17459
17684
  var SECRET_KEY_PARTS = ["PASSWORD", "SECRET", "TOKEN", "API_KEY"];
17460
17685
  var WALLET_PASSWORD_KEYS = /* @__PURE__ */ new Set([
17461
17686
  "WALLET_PASSWORD",
@@ -17501,8 +17726,8 @@ function resolveEnvPath(fileArg, rootArg) {
17501
17726
  return [fileArg, null];
17502
17727
  }
17503
17728
  if (rootArg !== void 0) {
17504
- const root2 = path39.resolve(rootArg);
17505
- if (!fs39.existsSync(path39.join(root2, "studio.toml"))) {
17729
+ const root2 = path40.resolve(rootArg);
17730
+ if (!fs40.existsSync(path40.join(root2, "studio.toml"))) {
17506
17731
  return [null, `error: no studio.toml under --project-root ${root2}`];
17507
17732
  }
17508
17733
  return [envLocalPath(root2), null];
@@ -17513,7 +17738,7 @@ function resolveEnvPath(fileArg, rootArg) {
17513
17738
  }
17514
17739
  const target = envLocalPath(root);
17515
17740
  let note = null;
17516
- if (path39.dirname(path39.dirname(target)) !== path39.resolve(process.cwd())) {
17741
+ if (path40.dirname(path40.dirname(target)) !== path40.resolve(process.cwd())) {
17517
17742
  note = `\u2192 writing to ${target} (workspace .studio/, where \`bag dev\` reads)`;
17518
17743
  }
17519
17744
  return [target, note];
@@ -17570,7 +17795,7 @@ function cmdGet2(key, fileArg, rootArg) {
17570
17795
  }
17571
17796
 
17572
17797
  // src/cli/erc8004.ts
17573
- import * as path40 from "path";
17798
+ import * as path41 from "path";
17574
17799
  import { auditedOp as auditedOp3 } from "@bnbagent/studio-runtime/audit";
17575
17800
  import {
17576
17801
  findProjectRoot as findProjectRoot5,
@@ -17580,7 +17805,7 @@ import {
17580
17805
  import {
17581
17806
  getMetadata,
17582
17807
  register as register2,
17583
- resolve as resolve20,
17808
+ resolve as resolve21,
17584
17809
  setMetadata,
17585
17810
  show as show2,
17586
17811
  updateServiceEndpoint as updateServiceEndpoint2
@@ -17691,7 +17916,7 @@ function loadAgentCfg3() {
17691
17916
  return null;
17692
17917
  }
17693
17918
  try {
17694
- return loadStudioToml22(path40.join(root, "studio.toml"));
17919
+ return loadStudioToml22(path41.join(root, "studio.toml"));
17695
17920
  } catch {
17696
17921
  return null;
17697
17922
  }
@@ -17769,7 +17994,7 @@ function loadIdentityBlock(agentRoot2) {
17769
17994
  try {
17770
17995
  return {
17771
17996
  ...tableOf15(
17772
- loadStudioToml22(path40.join(agentRoot2, "studio.toml")),
17997
+ loadStudioToml22(path41.join(agentRoot2, "studio.toml")),
17773
17998
  "identity"
17774
17999
  )
17775
18000
  };
@@ -18108,7 +18333,7 @@ async function cmdResolve(agentId, networkArg) {
18108
18333
  const wallet = walletRt6.getWallet();
18109
18334
  let uri;
18110
18335
  try {
18111
- uri = await resolve20(agentId, {
18336
+ uri = await resolve21(agentId, {
18112
18337
  wallet,
18113
18338
  network: resolveNetwork2(networkArg)
18114
18339
  });
@@ -18121,8 +18346,8 @@ async function cmdResolve(agentId, networkArg) {
18121
18346
  }
18122
18347
 
18123
18348
  // src/cli/erc8183.ts
18124
- import * as fs40 from "fs";
18125
- import * as path41 from "path";
18349
+ import * as fs41 from "fs";
18350
+ import * as path42 from "path";
18126
18351
  import { JobStatus } from "@bnbagent/sdk";
18127
18352
  import {
18128
18353
  buyWorkflow,
@@ -18226,8 +18451,8 @@ function applyProjectRoot2(root) {
18226
18451
  if (root === void 0) {
18227
18452
  return null;
18228
18453
  }
18229
- const p = path41.resolve(root);
18230
- if (!fs40.existsSync(path41.join(p, "studio.toml"))) {
18454
+ const p = path42.resolve(root);
18455
+ if (!fs41.existsSync(path42.join(p, "studio.toml"))) {
18231
18456
  printErr(`error: no studio.toml under --project-root ${p}`);
18232
18457
  return 2;
18233
18458
  }
@@ -18312,7 +18537,7 @@ function parseQuoteEnvelope(raw) {
18312
18537
  let text2 = trimmed;
18313
18538
  if (!trimmed.startsWith("{")) {
18314
18539
  try {
18315
- text2 = fs40.readFileSync(trimmed, "utf-8");
18540
+ text2 = fs41.readFileSync(trimmed, "utf-8");
18316
18541
  } catch (exc) {
18317
18542
  throw new Error(
18318
18543
  `--quote-json is neither inline JSON nor a readable file: ${errMsg5(exc)}`
@@ -18492,9 +18717,9 @@ async function cmdSettle(jobId, opts) {
18492
18717
  }
18493
18718
 
18494
18719
  // src/cli/skills.ts
18495
- import * as fs41 from "fs";
18720
+ import * as fs42 from "fs";
18496
18721
  import * as os6 from "os";
18497
- import * as path42 from "path";
18722
+ import * as path43 from "path";
18498
18723
  import { Option as Option7 } from "commander";
18499
18724
  function registerSkills(program) {
18500
18725
  const skills = program.command("skills").description("Install Claude Code skills into the host IDE.").action(
@@ -18540,7 +18765,7 @@ function cmdList4() {
18540
18765
  for (const p of listSourceSkills(
18541
18766
  SKILLS_SOURCE
18542
18767
  )) {
18543
- printOut(path42.basename(p));
18768
+ printOut(path43.basename(p));
18544
18769
  }
18545
18770
  const refs = listSourceReferences(
18546
18771
  SKILLS_SOURCE
@@ -18551,7 +18776,7 @@ function cmdList4() {
18551
18776
  references (installed under ${ROUTER_SKILL_NAME}/references/, loaded on demand by the skills above):`
18552
18777
  );
18553
18778
  for (const p of refs) {
18554
- printOut(` ${path42.basename(p)}`);
18779
+ printOut(` ${path43.basename(p)}`);
18555
18780
  }
18556
18781
  }
18557
18782
  return 0;
@@ -18763,7 +18988,7 @@ function installTargets(targets, scope) {
18763
18988
  );
18764
18989
  for (const name of result.legacyPresent) {
18765
18990
  const leaf = result.target === "cursor" ? `${name}.mdc` : name;
18766
- printErr(` - ${path42.join(result.targetDir, leaf)}`);
18991
+ printErr(` - ${path43.join(result.targetDir, leaf)}`);
18767
18992
  }
18768
18993
  printErr(
18769
18994
  "\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."
@@ -18776,19 +19001,19 @@ function studioSkillNames() {
18776
19001
  for (const p of listSourceSkills(
18777
19002
  SKILLS_SOURCE
18778
19003
  )) {
18779
- names.add(path42.basename(p).replace(/\.md$/, ""));
19004
+ names.add(path43.basename(p).replace(/\.md$/, ""));
18780
19005
  }
18781
19006
  for (const name of LEGACY_SKILL_NAMES) {
18782
19007
  names.add(name);
18783
19008
  }
18784
- const providersRoot = path42.join(bundledRecipesRoot(), "providers");
19009
+ const providersRoot = path43.join(bundledRecipesRoot(), "providers");
18785
19010
  if (isDir9(providersRoot)) {
18786
- for (const provider of fs41.readdirSync(providersRoot)) {
18787
- const skillDir = path42.join(providersRoot, provider, "skills");
19011
+ for (const provider of fs42.readdirSync(providersRoot)) {
19012
+ const skillDir = path43.join(providersRoot, provider, "skills");
18788
19013
  if (!isDir9(skillDir)) {
18789
19014
  continue;
18790
19015
  }
18791
- for (const md of fs41.readdirSync(skillDir)) {
19016
+ for (const md of fs42.readdirSync(skillDir)) {
18792
19017
  if (md.endsWith(".md")) {
18793
19018
  names.add(md.replace(/\.md$/, ""));
18794
19019
  }
@@ -18799,14 +19024,14 @@ function studioSkillNames() {
18799
19024
  }
18800
19025
  function isDir9(p) {
18801
19026
  try {
18802
- return fs41.statSync(p).isDirectory();
19027
+ return fs42.statSync(p).isDirectory();
18803
19028
  } catch {
18804
19029
  return false;
18805
19030
  }
18806
19031
  }
18807
- function isFile17(p) {
19032
+ function isFile18(p) {
18808
19033
  try {
18809
- return fs41.statSync(p).isFile();
19034
+ return fs42.statSync(p).isFile();
18810
19035
  } catch {
18811
19036
  return false;
18812
19037
  }
@@ -18820,26 +19045,26 @@ function findInstalledSkills(knownNames) {
18820
19045
  if (!isDir9(root)) {
18821
19046
  return;
18822
19047
  }
18823
- const resolved = fs41.realpathSync(root);
18824
- if (!roots.some((r) => fs41.realpathSync(r) === resolved)) {
19048
+ const resolved = fs42.realpathSync(root);
19049
+ if (!roots.some((r) => fs42.realpathSync(r) === resolved)) {
18825
19050
  roots.push(root);
18826
19051
  }
18827
19052
  };
18828
- addRoot(path42.join(home, ".claude", "skills"));
18829
- addRoot(path42.join(home, ".cursor", "rules"));
18830
- addRoot(path42.join(cwd, ".claude", "skills"));
18831
- addRoot(path42.join(cwd, ".cursor", "rules"));
19053
+ addRoot(path43.join(home, ".claude", "skills"));
19054
+ addRoot(path43.join(home, ".cursor", "rules"));
19055
+ addRoot(path43.join(cwd, ".claude", "skills"));
19056
+ addRoot(path43.join(cwd, ".cursor", "rules"));
18832
19057
  for (const root of roots) {
18833
- const isCursor = path42.basename(root) === "rules" && path42.basename(path42.dirname(root)) === ".cursor";
19058
+ const isCursor = path43.basename(root) === "rules" && path43.basename(path43.dirname(root)) === ".cursor";
18834
19059
  for (const name of [...knownNames].sort()) {
18835
- const target = path42.join(root, isCursor ? `${name}.mdc` : name);
18836
- if (isCursor && isFile17(target)) {
19060
+ const target = path43.join(root, isCursor ? `${name}.mdc` : name);
19061
+ if (isCursor && isFile18(target)) {
18837
19062
  found.push(target);
18838
19063
  } else if (!isCursor && isDir9(target)) {
18839
19064
  found.push(target);
18840
19065
  }
18841
- if (isCursor && isDir9(path42.join(root, name))) {
18842
- found.push(path42.join(root, name));
19066
+ if (isCursor && isDir9(path43.join(root, name))) {
19067
+ found.push(path43.join(root, name));
18843
19068
  }
18844
19069
  }
18845
19070
  }
@@ -18867,7 +19092,7 @@ async function cmdUninstall(flags) {
18867
19092
  }
18868
19093
  }
18869
19094
  for (const p of installed) {
18870
- fs41.rmSync(p, { recursive: true, force: true });
19095
+ fs42.rmSync(p, { recursive: true, force: true });
18871
19096
  printOut(` removed: ${p}`);
18872
19097
  }
18873
19098
  }
@@ -18906,7 +19131,7 @@ function registerUninstall(program) {
18906
19131
  }
18907
19132
 
18908
19133
  // src/cli/platform.ts
18909
- import * as path43 from "path";
19134
+ import * as path44 from "path";
18910
19135
  import {
18911
19136
  STUDIO_TOML as STUDIO_TOML2,
18912
19137
  findSubProjectRoot as findSubProjectRoot18,
@@ -19109,7 +19334,7 @@ function localPlatformCfg() {
19109
19334
  if (agentRoot2 === null) {
19110
19335
  return [null, {}];
19111
19336
  }
19112
- const tomlPath = path43.join(agentRoot2, STUDIO_TOML2);
19337
+ const tomlPath = path44.join(agentRoot2, STUDIO_TOML2);
19113
19338
  let cfg;
19114
19339
  try {
19115
19340
  cfg = loadStudioToml23(tomlPath);
@@ -19182,8 +19407,8 @@ function formatRemaining(seconds) {
19182
19407
  }
19183
19408
 
19184
19409
  // src/cli/recipe.ts
19185
- import * as fs42 from "fs";
19186
- import * as path44 from "path";
19410
+ import * as fs43 from "fs";
19411
+ import * as path45 from "path";
19187
19412
  import { parse as parse6 } from "smol-toml";
19188
19413
  function registerRecipe(program) {
19189
19414
  const p = program.command("recipe").description("Print recipe code/files (agent / wallet / 8004).");
@@ -19313,7 +19538,7 @@ function resolvePkgContext(explicit) {
19313
19538
  let data;
19314
19539
  try {
19315
19540
  data = parse6(
19316
- fs42.readFileSync(path44.join(projectRoot, "studio.toml"), "utf-8")
19541
+ fs43.readFileSync(path45.join(projectRoot, "studio.toml"), "utf-8")
19317
19542
  );
19318
19543
  } catch {
19319
19544
  return [null, null];
@@ -19331,8 +19556,8 @@ function resolvePkgContext(explicit) {
19331
19556
  }
19332
19557
 
19333
19558
  // src/cli/scan.ts
19334
- import * as fs43 from "fs";
19335
- import * as path45 from "path";
19559
+ import * as fs44 from "fs";
19560
+ import * as path46 from "path";
19336
19561
  import { Option as Option8 } from "commander";
19337
19562
  import { parse as parse7 } from "smol-toml";
19338
19563
  function registerScan(program) {
@@ -19349,7 +19574,7 @@ function registerScan(program) {
19349
19574
  "note: `--json` is deprecated (JSON is the default output); ignoring."
19350
19575
  );
19351
19576
  }
19352
- const root = path45.resolve(opts.path ?? process.cwd());
19577
+ const root = path46.resolve(opts.path ?? process.cwd());
19353
19578
  const report = scanProject(root);
19354
19579
  if (opts.text) {
19355
19580
  process.stdout.write(formatText(report));
@@ -19361,26 +19586,26 @@ function registerScan(program) {
19361
19586
  })
19362
19587
  );
19363
19588
  }
19364
- function isFile18(p) {
19589
+ function isFile19(p) {
19365
19590
  try {
19366
- return fs43.statSync(p).isFile();
19591
+ return fs44.statSync(p).isFile();
19367
19592
  } catch {
19368
19593
  return false;
19369
19594
  }
19370
19595
  }
19371
19596
  function isDir10(p) {
19372
19597
  try {
19373
- return fs43.statSync(p).isDirectory();
19598
+ return fs44.statSync(p).isDirectory();
19374
19599
  } catch {
19375
19600
  return false;
19376
19601
  }
19377
19602
  }
19378
19603
  function layerBase(root) {
19379
- return isDir10(path45.join(root, "app", "agent")) ? path45.join(root, "app") : root;
19604
+ return isDir10(path46.join(root, "app", "agent")) ? path46.join(root, "app") : root;
19380
19605
  }
19381
19606
  function safeReadJson(p) {
19382
19607
  try {
19383
- const data = JSON.parse(fs43.readFileSync(p, "utf-8"));
19608
+ const data = JSON.parse(fs44.readFileSync(p, "utf-8"));
19384
19609
  return data !== null && typeof data === "object" && !Array.isArray(data) ? data : null;
19385
19610
  } catch {
19386
19611
  return null;
@@ -19388,7 +19613,7 @@ function safeReadJson(p) {
19388
19613
  }
19389
19614
  function safeReadToml(p) {
19390
19615
  try {
19391
- return parse7(fs43.readFileSync(p, "utf-8"));
19616
+ return parse7(fs44.readFileSync(p, "utf-8"));
19392
19617
  } catch {
19393
19618
  return null;
19394
19619
  }
@@ -19418,33 +19643,33 @@ function resolvePackageName(projectName2, root) {
19418
19643
  if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(candidate)) {
19419
19644
  return null;
19420
19645
  }
19421
- if (!isDir10(path45.join(root, candidate))) {
19646
+ if (!isDir10(path46.join(root, candidate))) {
19422
19647
  return null;
19423
19648
  }
19424
19649
  return candidate;
19425
19650
  }
19426
19651
  function inferLayout(root) {
19427
- const agentDir = path45.join(layerBase(root), "agent");
19428
- const hasAgent = isFile18(path45.join(agentDir, "main.ts")) || isFile18(path45.join(agentDir, "main.py"));
19652
+ const agentDir = path46.join(layerBase(root), "agent");
19653
+ const hasAgent = isFile19(path46.join(agentDir, "main.ts")) || isFile19(path46.join(agentDir, "main.py"));
19429
19654
  return {
19430
19655
  has_agent: hasAgent,
19431
- has_agent_descriptor: isFile18(
19432
- path45.join(root, "agentcore", "agentcore.json")
19656
+ has_agent_descriptor: isFile19(
19657
+ path46.join(root, "agentcore", "agentcore.json")
19433
19658
  ),
19434
19659
  role: hasAgent ? "agent" : "none"
19435
19660
  };
19436
19661
  }
19437
19662
  function inferPackageManager(root, hasPackageJson) {
19438
- if (isFile18(path45.join(root, "pnpm-lock.yaml"))) {
19663
+ if (isFile19(path46.join(root, "pnpm-lock.yaml"))) {
19439
19664
  return "pnpm";
19440
19665
  }
19441
- if (isFile18(path45.join(root, "yarn.lock"))) {
19666
+ if (isFile19(path46.join(root, "yarn.lock"))) {
19442
19667
  return "yarn";
19443
19668
  }
19444
- if (isFile18(path45.join(root, "bun.lockb"))) {
19669
+ if (isFile19(path46.join(root, "bun.lockb"))) {
19445
19670
  return "bun";
19446
19671
  }
19447
- if (isFile18(path45.join(root, "package-lock.json"))) {
19672
+ if (isFile19(path46.join(root, "package-lock.json"))) {
19448
19673
  return "npm";
19449
19674
  }
19450
19675
  if (hasPackageJson) {
@@ -19457,7 +19682,7 @@ function inferRecipes(root, studioData, layout) {
19457
19682
  if (layout.has_agent) {
19458
19683
  recipes.push("agent");
19459
19684
  }
19460
- const walletsDir = path45.join(root, ".studio", "wallets");
19685
+ const walletsDir = path46.join(root, ".studio", "wallets");
19461
19686
  const walletSection = studioData?.wallet;
19462
19687
  const hasWalletSection = walletSection !== null && typeof walletSection === "object" && !Array.isArray(walletSection);
19463
19688
  if (isDir10(walletsDir) && hasWalletSection) {
@@ -19466,13 +19691,13 @@ function inferRecipes(root, studioData, layout) {
19466
19691
  return recipes;
19467
19692
  }
19468
19693
  function scanProject(root) {
19469
- const studioToml = path45.join(root, "studio.toml");
19470
- const packageJson = path45.join(root, "package.json");
19471
- const agentcoreJson = path45.join(root, "agentcore", "agentcore.json");
19472
- const hasStudioToml = isFile18(studioToml);
19473
- const hasPackageJson = isFile18(packageJson);
19474
- const hasAgentcoreJson = isFile18(agentcoreJson);
19475
- const hasDotStudioDir = isDir10(path45.join(root, ".studio"));
19694
+ const studioToml = path46.join(root, "studio.toml");
19695
+ const packageJson = path46.join(root, "package.json");
19696
+ const agentcoreJson = path46.join(root, "agentcore", "agentcore.json");
19697
+ const hasStudioToml = isFile19(studioToml);
19698
+ const hasPackageJson = isFile19(packageJson);
19699
+ const hasAgentcoreJson = isFile19(agentcoreJson);
19700
+ const hasDotStudioDir = isDir10(path46.join(root, ".studio"));
19476
19701
  const pkgData = hasPackageJson ? safeReadJson(packageJson) : null;
19477
19702
  const studioData = hasStudioToml ? safeReadToml(studioToml) : null;
19478
19703
  const rawName = pkgData?.name;
@@ -19529,8 +19754,8 @@ function formatText(report) {
19529
19754
  }
19530
19755
 
19531
19756
  // src/cli/x402.ts
19532
- import * as fs44 from "fs";
19533
- import * as path46 from "path";
19757
+ import * as fs45 from "fs";
19758
+ import * as path47 from "path";
19534
19759
  import { auditedOp as auditedOp4 } from "@bnbagent/studio-runtime/audit";
19535
19760
  import {
19536
19761
  envLocalPath as envLocalPath18,
@@ -19724,7 +19949,7 @@ function loadX402Policy() {
19724
19949
  }
19725
19950
  let cfg;
19726
19951
  try {
19727
- cfg = loadStudioToml24(path46.join(root, "studio.toml"));
19952
+ cfg = loadStudioToml24(path47.join(root, "studio.toml"));
19728
19953
  } catch (exc) {
19729
19954
  printErr(`error: failed to parse studio.toml: ${errMsg6(exc)}`);
19730
19955
  return null;
@@ -19738,7 +19963,7 @@ function loadSellerConfig() {
19738
19963
  return null;
19739
19964
  }
19740
19965
  try {
19741
- return [root, loadStudioToml24(path46.join(root, "studio.toml"))];
19966
+ return [root, loadStudioToml24(path47.join(root, "studio.toml"))];
19742
19967
  } catch (exc) {
19743
19968
  printErr(`error: failed to parse studio.toml: ${errMsg6(exc)}`);
19744
19969
  return null;
@@ -19784,8 +20009,8 @@ async function cmdSellInit(priceFlag) {
19784
20009
  const loaded = loadSellerConfig();
19785
20010
  if (loaded === null) return 1;
19786
20011
  const [root, cfg] = loaded;
19787
- const tomlPath = path46.join(root, "studio.toml");
19788
- const original = fs44.readFileSync(tomlPath, "utf8");
20012
+ const tomlPath = path47.join(root, "studio.toml");
20013
+ const original = fs45.readFileSync(tomlPath, "utf8");
19789
20014
  const sellerExists = hasSection(original, "payments.x402_seller");
19790
20015
  let priceUsd;
19791
20016
  try {
@@ -19803,7 +20028,7 @@ async function cmdSellInit(priceFlag) {
19803
20028
  return 1;
19804
20029
  }
19805
20030
  if (!sellerExists) {
19806
- fs44.writeFileSync(
20031
+ fs45.writeFileSync(
19807
20032
  tomlPath,
19808
20033
  updateSection(original, "payments.x402_seller", {
19809
20034
  enabled: true,
@@ -19815,7 +20040,7 @@ async function cmdSellInit(priceFlag) {
19815
20040
  "utf8"
19816
20041
  );
19817
20042
  } else if (priceFlag !== void 0) {
19818
- fs44.writeFileSync(
20043
+ fs45.writeFileSync(
19819
20044
  tomlPath,
19820
20045
  updateSection(original, "payments.x402_seller", {
19821
20046
  price_usd: priceUsd
@@ -20184,14 +20409,14 @@ async function confirmOrAbort(prompt, assumeYes) {
20184
20409
  return answer === "y" || answer === "yes";
20185
20410
  }
20186
20411
  function writeMerchantEntry(tomlPath, fields) {
20187
- const text2 = fs44.readFileSync(tomlPath, "utf-8");
20412
+ const text2 = fs45.readFileSync(tomlPath, "utf-8");
20188
20413
  const entries = {
20189
20414
  domain: fields.domain,
20190
20415
  pay_to: fields.payTo,
20191
20416
  per_call_cap_usd: fields.capUsd,
20192
20417
  verified: fields.verified
20193
20418
  };
20194
- fs44.writeFileSync(
20419
+ fs45.writeFileSync(
20195
20420
  tomlPath,
20196
20421
  updateSection(text2, `payments.x402.merchants.${fields.key}`, entries),
20197
20422
  "utf-8"
@@ -20320,7 +20545,7 @@ The merchant may have rotated its address (or the response was tampered with). U
20320
20545
  printOut("aborted \u2014 nothing written.");
20321
20546
  return 1;
20322
20547
  }
20323
- const tomlPath = path46.join(root, "studio.toml");
20548
+ const tomlPath = path47.join(root, "studio.toml");
20324
20549
  try {
20325
20550
  writeMerchantEntry(tomlPath, {
20326
20551
  key,
@@ -20383,23 +20608,23 @@ function buildProgram() {
20383
20608
  return program;
20384
20609
  }
20385
20610
  function cliVersion() {
20386
- return "0.0.6-alpha.7";
20611
+ return "0.0.6-alpha.9";
20387
20612
  }
20388
20613
 
20389
20614
  // src/cli/updateCheck.ts
20390
- import * as fs45 from "fs";
20615
+ import * as fs46 from "fs";
20391
20616
  import * as os7 from "os";
20392
- import * as path47 from "path";
20617
+ import * as path48 from "path";
20393
20618
  var PACKAGE = "@bnbagent/studio-cli";
20394
20619
  var REGISTRY_LATEST_URL = `https://registry.npmjs.org/${PACKAGE}/latest`;
20395
20620
  var CHECK_INTERVAL_SECONDS = 24 * 3600;
20396
20621
  var TIMEOUT_MS = 2e3;
20397
20622
  function cachePath(home) {
20398
- return path47.join(home, ".bag", "update-check.json");
20623
+ return path48.join(home, ".bag", "update-check.json");
20399
20624
  }
20400
20625
  function loadCache(home) {
20401
20626
  try {
20402
- const data = JSON.parse(fs45.readFileSync(cachePath(home), "utf-8"));
20627
+ const data = JSON.parse(fs46.readFileSync(cachePath(home), "utf-8"));
20403
20628
  return data !== null && typeof data === "object" && !Array.isArray(data) ? data : {};
20404
20629
  } catch {
20405
20630
  return {};
@@ -20408,8 +20633,8 @@ function loadCache(home) {
20408
20633
  function saveCache(state, home) {
20409
20634
  try {
20410
20635
  const p = cachePath(home);
20411
- fs45.mkdirSync(path47.dirname(p), { recursive: true });
20412
- fs45.writeFileSync(p, `${JSON.stringify(state, null, 2)}
20636
+ fs46.mkdirSync(path48.dirname(p), { recursive: true });
20637
+ fs46.writeFileSync(p, `${JSON.stringify(state, null, 2)}
20413
20638
  `);
20414
20639
  } catch {
20415
20640
  }