@bnbagent/studio-cli 0.0.13 → 0.0.14-alpha.1

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.
Files changed (32) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +8 -0
  3. package/dist/_agentcoreName-DZDWEYD3.js +0 -0
  4. package/dist/bag.js +3556 -1565
  5. package/dist/{chunk-H4X2OOLA.js → chunk-QVYWAJEK.js} +228 -72
  6. package/dist/chunk-U7IDQ3K5.js +0 -0
  7. package/dist/{deployCli-22NMZ4G7.js → deployCli-F3AOM5UO.js} +1 -2
  8. package/package.json +12 -13
  9. package/recipes/agent/code/{{PKG}}/deliveryPolicy.ts.tmpl +43 -0
  10. package/recipes/agent/code/{{PKG}}/readToolCatalog.ts.tmpl +102 -0
  11. package/recipes/agent/code/{{PKG}}/signing.ts.tmpl +7 -2
  12. package/recipes/agent/recipe.toml +4 -3
  13. package/recipes/runtimes/agentcore/code/{{PKG}}/dualMain.ts.tmpl +6 -2
  14. package/recipes/runtimes/agentcore/code/{{PKG}}/mcpMain.ts.tmpl +173 -134
  15. package/recipes/runtimes/agentcore/code/{{PKG}}/model.ts.tmpl +7 -0
  16. package/recipes/runtimes/agentcore/code/{{PKG}}/sellerCore.ts.tmpl +31 -46
  17. package/recipes/runtimes/agentcore/code/{{PKG}}/tools.ts.tmpl +19 -48
  18. package/recipes/runtimes/agentcore/code/{{PKG}}/unifiedMain.ts.tmpl +2 -1
  19. package/recipes/runtimes/azure-foundry/code/{{PKG}}/mcpMain.ts.tmpl +173 -134
  20. package/recipes/runtimes/azure-foundry/code/{{PKG}}/model.ts.tmpl +7 -0
  21. package/recipes/runtimes/azure-foundry/code/{{PKG}}/sellerCore.ts.tmpl +31 -46
  22. package/recipes/runtimes/azure-foundry/code/{{PKG}}/tools.ts.tmpl +19 -48
  23. package/recipes/runtimes/azure-foundry/code/{{PKG}}/unifiedMain.ts.tmpl +2 -1
  24. package/recipes/wallet/recipe.toml +3 -2
  25. package/skills/bnbagent-studio.md +12 -1
  26. package/skills/references/bnbagent-studio-operating.md +1 -0
  27. package/skills/references/bnbagent-studio-scaffolding-agent.md +11 -34
  28. package/skills/references/bnbagent-studio-selling-via-b402.md +3 -3
  29. package/skills/references/bnbagent-studio-using-altana-wallet.md +6 -1
  30. package/skills/references/bnbagent-studio-using-twak-wallet.md +24 -76
  31. package/dist/_twak-4XF4H5PL.js +0 -25
  32. package/dist/chunk-RO726HJG.js +0 -175
@@ -1,17 +1,10 @@
1
1
  #!/usr/bin/env node
2
- import {
3
- TWAK_CLI_VERSION,
4
- runCapture,
5
- runCaptureOut,
6
- runStream,
7
- whichTwak
8
- } from "./chunk-RO726HJG.js";
9
2
 
10
3
  // src/cli/_deploy/deployCli.ts
11
- import * as fs5 from "fs";
4
+ import * as fs6 from "fs";
12
5
  import { createRequire } from "module";
13
- import * as os from "os";
14
- import * as path6 from "path";
6
+ import * as os2 from "os";
7
+ import * as path7 from "path";
15
8
  import {
16
9
  findSubProjectRoot as findSubProjectRoot2,
17
10
  loadStudioToml as loadStudioToml3
@@ -587,6 +580,152 @@ function deployCommandOverrideAllowed(environment = process.env, argv = process.
587
580
  return !inCi && ["development", "test"].includes(environment.NODE_ENV ?? "");
588
581
  }
589
582
 
583
+ // src/cli/_twak.ts
584
+ import * as fs2 from "fs";
585
+ import * as os from "os";
586
+ import * as path2 from "path";
587
+ import { resolveTwakHome } from "@bnbagent/studio-runtime/wallet";
588
+
589
+ // src/cli/proc.ts
590
+ import { execa } from "execa";
591
+ async function runCapture(cmd, args, opts = {}) {
592
+ const result = await execa(cmd, args, {
593
+ cwd: opts.cwd,
594
+ env: opts.env,
595
+ input: opts.input,
596
+ timeout: opts.timeoutMs,
597
+ reject: false,
598
+ stripFinalNewline: false
599
+ });
600
+ return {
601
+ code: result.exitCode ?? 1,
602
+ stdout: typeof result.stdout === "string" ? result.stdout : "",
603
+ stderr: typeof result.stderr === "string" ? result.stderr : ""
604
+ };
605
+ }
606
+ async function runStream(cmd, args, opts = {}) {
607
+ const result = await execa(cmd, args, {
608
+ cwd: opts.cwd,
609
+ env: opts.env,
610
+ timeout: opts.timeoutMs,
611
+ reject: false,
612
+ stdio: "inherit"
613
+ });
614
+ return result.exitCode ?? 1;
615
+ }
616
+ async function runCaptureOut(cmd, args, opts = {}) {
617
+ const result = await execa(cmd, args, {
618
+ cwd: opts.cwd,
619
+ env: opts.env,
620
+ input: opts.input,
621
+ timeout: opts.timeoutMs,
622
+ reject: false,
623
+ stripFinalNewline: false,
624
+ stdout: "pipe",
625
+ stderr: "inherit"
626
+ });
627
+ return {
628
+ code: result.exitCode ?? 1,
629
+ stdout: typeof result.stdout === "string" ? result.stdout : ""
630
+ };
631
+ }
632
+
633
+ // src/cli/_twak.ts
634
+ var TWAK_CLI_VERSION = "0.20.0";
635
+ var TWAK_CLI_MIN_VERSION = [
636
+ 0,
637
+ 20,
638
+ 0
639
+ ];
640
+ function twakVersionBelowFloor(installed) {
641
+ const floor = TWAK_CLI_MIN_VERSION;
642
+ for (let i = 0; i < floor.length; i += 1) {
643
+ const a = installed[i] ?? 0;
644
+ const b = floor[i];
645
+ if (a !== b) {
646
+ return a < b;
647
+ }
648
+ }
649
+ return false;
650
+ }
651
+ function projectTwakBin(projectRoot) {
652
+ const name = process.platform === "win32" ? "twak.cmd" : "twak";
653
+ const candidate = path2.join(projectRoot, "node_modules", ".bin", name);
654
+ return fs2.existsSync(candidate) ? candidate : null;
655
+ }
656
+ async function whichTwak(projectRoot) {
657
+ if (projectRoot != null) {
658
+ const pinned = projectTwakBin(projectRoot);
659
+ if (pinned !== null) {
660
+ return pinned;
661
+ }
662
+ }
663
+ const cmd = process.platform === "win32" ? "where" : "which";
664
+ const result = await runCapture(cmd, ["twak"]);
665
+ if (result.code !== 0) {
666
+ return null;
667
+ }
668
+ const line = result.stdout.split("\n")[0]?.trim();
669
+ return line ? line : null;
670
+ }
671
+ async function twakInstalledVersion(projectRoot) {
672
+ const twakBin = await whichTwak(projectRoot);
673
+ if (twakBin === null) {
674
+ return null;
675
+ }
676
+ return twakVersionForBin(twakBin);
677
+ }
678
+ async function twakVersionForBin(twakBin) {
679
+ try {
680
+ const result = await runCapture(twakBin, ["--version"], {
681
+ timeoutMs: 15e3
682
+ });
683
+ const m = /(\d+)\.(\d+)\.(\d+)/.exec(result.stdout || "");
684
+ if (result.code !== 0 || m === null) {
685
+ return null;
686
+ }
687
+ return [
688
+ Number.parseInt(m[1], 10),
689
+ Number.parseInt(m[2], 10),
690
+ Number.parseInt(m[3], 10)
691
+ ];
692
+ } catch {
693
+ return null;
694
+ }
695
+ }
696
+ function twakHomeDir(walletCfg, projectRoot) {
697
+ const home = resolveTwakHome(walletCfg ?? {}, projectRoot ?? null);
698
+ return path2.join(home ?? os.homedir(), ".twak");
699
+ }
700
+ function twakWalletFile(walletCfg, projectRoot) {
701
+ return path2.join(twakHomeDir(walletCfg, projectRoot), "wallet.json");
702
+ }
703
+ function twakDoubledHomeHint(walletFile) {
704
+ const doubled = `${path2.sep}.twak${path2.sep}.twak${path2.sep}`;
705
+ if (!walletFile.includes(doubled)) {
706
+ return null;
707
+ }
708
+ return `hint: the resolved wallet path ${walletFile} nests .twak/.twak \u2014 [wallet].twak_home in studio.toml likely points at the .twak directory itself. Set it to the PARENT directory (the runtime appends .twak/wallet.json) and re-run.`;
709
+ }
710
+ function twakMissingHint() {
711
+ return `Run \`pnpm install\` in the Studio workspace (app/agent/package.json pins @trustwallet/cli@${TWAK_CLI_VERSION}). Projects scaffolded before that pin can add "@trustwallet/cli": "${TWAK_CLI_VERSION}" to app/agent/package.json, or install it on PATH with \`npm install -g @trustwallet/cli@${TWAK_CLI_VERSION}\`.`;
712
+ }
713
+ function twakCreateGuidance(fields) {
714
+ return `error: wallet.kind = "twak" \u2014 \`bag wallet new\` only adopts an existing
715
+ twak wallet's address. Let Studio prepare the project-dedicated wallet with the
716
+ project-pinned @trustwallet/cli@${fields.version}:
717
+
718
+ bag wallet twak-init
719
+
720
+ Create a NaaS app at https://portal.trustwallet.com/dashboard/apps. Studio
721
+ collects its Access ID + HMAC secret through hidden prompts, runs
722
+ \`twak init --json\`, verifies an authenticated read, generates a
723
+ cryptographically secure wallet password, stores it in .studio/.env.local
724
+ (0600), creates the wallet without the keychain, and anchors its address.
725
+ For non-interactive runs, set TWAK_ACCESS_ID and TWAK_HMAC_SECRET first.
726
+ Guide: the bnbagent-studio-using-twak-wallet.md reference (installed by \`bag skills install\`).`;
727
+ }
728
+
590
729
  // src/cli/preflight.ts
591
730
  var OK = "ok";
592
731
  var WARN = "warn";
@@ -703,25 +842,25 @@ async function checkDocker() {
703
842
  fix: "start Docker Desktop (or `open -a Docker` on macOS)"
704
843
  };
705
844
  }
706
- async function checkTwak() {
707
- const found = await whichTwak() !== null;
845
+ async function checkTwak(projectRoot) {
846
+ const found = await whichTwak(projectRoot) !== null;
708
847
  return {
709
848
  name: "twak CLI",
710
849
  ok: found,
711
850
  level: found ? OK : WARN,
712
- detail: found ? "on PATH" : "not found (needed only for wallet.kind='twak' projects)",
713
- fix: found ? "" : `npm install -g @trustwallet/cli@${TWAK_CLI_VERSION}`
851
+ detail: found ? projectRoot ? "found (project-pinned or on PATH)" : "on PATH" : projectRoot ? "not found, neither project-pinned nor on PATH (needed for wallet.kind='twak')" : "not found (needed only for wallet.kind='twak' projects)",
852
+ fix: found ? "" : projectRoot ? `pnpm install (or npm install -g @trustwallet/cli@${TWAK_CLI_VERSION})` : `npm install -g @trustwallet/cli@${TWAK_CLI_VERSION}`
714
853
  };
715
854
  }
716
855
  function requiredChecks() {
717
856
  return [checkNode()];
718
857
  }
719
- async function deployChecks() {
858
+ async function deployChecks(projectRoot) {
720
859
  return [
721
860
  await checkBunx(),
722
861
  checkAws(),
723
862
  await checkDocker(),
724
- await checkTwak()
863
+ await checkTwak(projectRoot)
725
864
  ];
726
865
  }
727
866
  function render(checks) {
@@ -736,8 +875,8 @@ function render(checks) {
736
875
  }
737
876
 
738
877
  // src/cli/_deploy/awsTargets.ts
739
- import * as fs2 from "fs";
740
- import * as path2 from "path";
878
+ import * as fs3 from "fs";
879
+ import * as path3 from "path";
741
880
  var DEFAULT_TARGET_NAME = "default";
742
881
  function isDict(v) {
743
882
  return v !== null && typeof v === "object" && !Array.isArray(v);
@@ -746,10 +885,10 @@ function pickAccount(entry) {
746
885
  return entry.account || entry.accountId;
747
886
  }
748
887
  function readAwsTarget(root, targetName = DEFAULT_TARGET_NAME) {
749
- const p = path2.join(root, "agentcore", "aws-targets.json");
888
+ const p = path3.join(root, "agentcore", "aws-targets.json");
750
889
  let data;
751
890
  try {
752
- data = JSON.parse(fs2.readFileSync(p, "utf-8"));
891
+ data = JSON.parse(fs3.readFileSync(p, "utf-8"));
753
892
  } catch {
754
893
  return [null, null];
755
894
  }
@@ -784,7 +923,7 @@ function readAwsTarget(root, targetName = DEFAULT_TARGET_NAME) {
784
923
  }
785
924
 
786
925
  // src/cli/_deploy/x402.ts
787
- import * as path5 from "path";
926
+ import * as path6 from "path";
788
927
  import {
789
928
  envLocalPath,
790
929
  findSubProjectRoot,
@@ -792,15 +931,15 @@ import {
792
931
  } from "@bnbagent/studio-runtime/config";
793
932
 
794
933
  // src/cli/_packageMetadata.ts
795
- import * as fs3 from "fs";
796
- import * as path3 from "path";
934
+ import * as fs4 from "fs";
935
+ import * as path4 from "path";
797
936
  import { fileURLToPath } from "url";
798
937
  function packageRoot() {
799
- let dir = path3.dirname(fileURLToPath(import.meta.url));
938
+ let dir = path4.dirname(fileURLToPath(import.meta.url));
800
939
  for (; ; ) {
801
- const packageJson = path3.join(dir, "package.json");
802
- if (fs3.existsSync(packageJson)) return dir;
803
- const parent = path3.dirname(dir);
940
+ const packageJson = path4.join(dir, "package.json");
941
+ if (fs4.existsSync(packageJson)) return dir;
942
+ const parent = path4.dirname(dir);
804
943
  if (parent === dir) {
805
944
  throw new Error("cannot locate the studio-cli package root");
806
945
  }
@@ -808,11 +947,11 @@ function packageRoot() {
808
947
  }
809
948
  }
810
949
  function studioCliVersion() {
811
- if ("0.0.13") {
812
- return "0.0.13";
950
+ if ("0.0.14-alpha.1") {
951
+ return "0.0.14-alpha.1";
813
952
  }
814
- const file = path3.join(packageRoot(), "package.json");
815
- const pkg = JSON.parse(fs3.readFileSync(file, "utf-8"));
953
+ const file = path4.join(packageRoot(), "package.json");
954
+ const pkg = JSON.parse(fs4.readFileSync(file, "utf-8"));
816
955
  const value = String(pkg.version ?? "");
817
956
  if (!/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/u.test(value)) {
818
957
  throw new Error(
@@ -825,8 +964,8 @@ function pnpmVersion() {
825
964
  if ("10.24.0") {
826
965
  return "10.24.0";
827
966
  }
828
- const file = path3.join(packageRoot(), "package.json");
829
- const pkg = JSON.parse(fs3.readFileSync(file, "utf-8"));
967
+ const file = path4.join(packageRoot(), "package.json");
968
+ const pkg = JSON.parse(fs4.readFileSync(file, "utf-8"));
830
969
  const value = String(pkg.packageManager ?? "");
831
970
  const match = /^pnpm@(.+)$/u.exec(value);
832
971
  if (!match?.[1]) {
@@ -838,28 +977,28 @@ function pnpmVersion() {
838
977
  }
839
978
 
840
979
  // src/cli/utils/envFile.ts
841
- import * as fs4 from "fs";
842
- import * as path4 from "path";
980
+ import * as fs5 from "fs";
981
+ import * as path5 from "path";
843
982
  var KEY_LINE_RE = /^\s*([A-Za-z_][A-Za-z0-9_]*)\s*=/;
844
983
  function isValidKey(key) {
845
984
  return /^[A-Za-z_][A-Za-z0-9_]*$/.test(key);
846
985
  }
847
986
  function writePrivate(filePath, text) {
848
- fs4.writeFileSync(filePath, text, { encoding: "utf-8", mode: 384 });
849
- fs4.chmodSync(filePath, 384);
987
+ fs5.writeFileSync(filePath, text, { encoding: "utf-8", mode: 384 });
988
+ fs5.chmodSync(filePath, 384);
850
989
  }
851
990
  function setEnvVar(filePath, key, value) {
852
991
  if (!isValidKey(key)) {
853
992
  throw new Error(`invalid env var name: '${key}'`);
854
993
  }
855
994
  const newLine = `${key}=${value}`;
856
- fs4.mkdirSync(path4.dirname(filePath), { recursive: true });
857
- if (!fs4.existsSync(filePath)) {
995
+ fs5.mkdirSync(path5.dirname(filePath), { recursive: true });
996
+ if (!fs5.existsSync(filePath)) {
858
997
  writePrivate(filePath, `${newLine}
859
998
  `);
860
999
  return true;
861
1000
  }
862
- const original = fs4.readFileSync(filePath, "utf-8");
1001
+ const original = fs5.readFileSync(filePath, "utf-8");
863
1002
  const lines = original.split(/\r?\n/);
864
1003
  if (lines.length > 0 && lines[lines.length - 1] === "") {
865
1004
  lines.pop();
@@ -890,10 +1029,10 @@ function setEnvVar(filePath, key, value) {
890
1029
  return true;
891
1030
  }
892
1031
  function getEnvVar(filePath, key) {
893
- if (!fs4.existsSync(filePath)) {
1032
+ if (!fs5.existsSync(filePath)) {
894
1033
  return null;
895
1034
  }
896
- for (const line of fs4.readFileSync(filePath, "utf-8").split(/\r?\n/)) {
1035
+ for (const line of fs5.readFileSync(filePath, "utf-8").split(/\r?\n/)) {
897
1036
  const m = KEY_LINE_RE.exec(line);
898
1037
  if (m && m[1] === key) {
899
1038
  const eq = line.indexOf("=");
@@ -919,12 +1058,15 @@ var X402_CAPABLE_RUNTIMES = /* @__PURE__ */ new Set([
919
1058
  function commerceRails(cfg) {
920
1059
  const payments = table3(cfg.payments);
921
1060
  return {
922
- erc8183: isTable(payments.erc8183),
1061
+ erc8183: railEnabled(payments.erc8183),
923
1062
  // Historical property name retained for callers; this means the common
924
1063
  // B402 seller rail, whether its public adapter is x402 or MPP.
925
1064
  x402: b402SellerConfig(cfg).enabled === true
926
1065
  };
927
1066
  }
1067
+ function railEnabled(value) {
1068
+ return isTable(value) && value.enabled !== false;
1069
+ }
928
1070
  function b402Credentials(agentRoot) {
929
1071
  const values = /* @__PURE__ */ new Map();
930
1072
  const envPath = envLocalPath(agentRoot);
@@ -966,7 +1108,7 @@ function loadDeployConfig(root) {
966
1108
  try {
967
1109
  return {
968
1110
  agentRoot,
969
- cfg: loadStudioToml2(path5.join(agentRoot, "studio.toml"))
1111
+ cfg: loadStudioToml2(path6.join(agentRoot, "studio.toml"))
970
1112
  };
971
1113
  } catch {
972
1114
  return { agentRoot, cfg: {} };
@@ -1016,14 +1158,14 @@ function x402DeploySummary(root, destination, publicUrl) {
1016
1158
  }
1017
1159
  function x402DeploySummaryFromSnapshot(snapshot, runtime, destination, publicUrl, protocol = "x402") {
1018
1160
  const label = protocol === "mpp" ? "MPP" : "x402";
1019
- const path7 = `/${protocol}`;
1161
+ const path8 = `/${protocol}`;
1020
1162
  const activation = `${B402_PAID_ONBOARDING_GUIDANCE} Then run the bnbagent-studio-selling-via-b402 skill, fill the four B402_* variables${protocol === "mpp" ? " plus MPP_SECRET_KEY and MPP_REALM in .studio/.env.local, inject a durable atomic replayStore for production," : " in .studio/.env.local,"} and redeploy.`;
1021
1163
  if (destination !== "platform" && !X402_CAPABLE_RUNTIMES.has(runtime)) {
1022
- return `${protocol} rail is FORCED DORMANT: the ${runtime} runtime has no ${path7} path. Deploy to AgentCore or Azure Foundry (managed platform or self-hosted) to activate the rail.`;
1164
+ return `${protocol} rail is FORCED DORMANT: the ${runtime} runtime has no ${path8} path. Deploy to AgentCore or Azure Foundry (managed platform or self-hosted) to activate the rail.`;
1023
1165
  }
1024
1166
  const azure = runtime === "azure-foundry";
1025
1167
  const runtimeLabel = azure ? "Azure Foundry" : "AgentCore";
1026
- const tunnelLine = azure ? `The front wraps each request as envelope-v1 JSON, {"v":1,"method":"POST","path":"${path7}","headers":{...},"body":"<base64>"}, inside an Entra-authenticated Foundry invocation (POST \u2026/agents/<name>/endpoint/protocols/invocations with an https://ai.azure.com bearer). Limits: 1 MiB request, 5 MiB response, no streaming.` : `The front wraps each request as envelope-v1 JSON, {"v":1,"method":"POST","path":"${path7}","headers":{...},"body":"<base64>"}, inside an authenticated AgentCore invocation. The default Bag self-deploy uses Cognito OAuth over HTTPS; IAM runtimes may use SDK/SigV4. Limits: 1 MiB request, 5 MiB response, no streaming.`;
1168
+ const tunnelLine = azure ? `The front wraps each request as envelope-v1 JSON, {"v":1,"method":"POST","path":"${path8}","headers":{...},"body":"<base64>"}, inside an Entra-authenticated Foundry invocation (POST \u2026/agents/<name>/endpoint/protocols/invocations with an https://ai.azure.com bearer). Limits: 1 MiB request, 5 MiB response, no streaming.` : `The front wraps each request as envelope-v1 JSON, {"v":1,"method":"POST","path":"${path8}","headers":{...},"body":"<base64>"}, inside an authenticated AgentCore invocation. The default Bag self-deploy uses Cognito OAuth over HTTPS; IAM runtimes may use SDK/SigV4. Limits: 1 MiB request, 5 MiB response, no streaming.`;
1027
1169
  const gatewayDocLine = azure ? protocol === "mpp" ? "Gateway contract: docs/guides/mpp-b402-selling.md" : `Gateway example: https://unpkg.com/@bnbagent/studio-cli@${studioCliVersion()}/skills/references/bnbagent-studio-use-azure-foundry.md#x402-external-gateway` : protocol === "mpp" ? "Gateway contract: https://github.com/bnb-chain/bnbagent-studio/blob/main/docs/guides/mpp-b402-selling.md" : "Gateway example: https://github.com/bnb-chain/bnbagent-studio/blob/main/docs/guides/self-hosted-x402-gateway.md";
1028
1170
  if (snapshot.priceMode === "invalid") {
1029
1171
  return `${protocol} rail is DORMANT: price_usd is invalid; run \`bag doctor\`.`;
@@ -1033,7 +1175,7 @@ function x402DeploySummaryFromSnapshot(snapshot, runtime, destination, publicUrl
1033
1175
  return [
1034
1176
  `${protocol} rail is ACTIVE in FREE mode (self-hosted ${runtimeLabel}).`,
1035
1177
  "B402 verify/settle is bypassed; no credentials, token payment, or settlement audit is used.",
1036
- `This target has no anonymous public URL; expose ${path7} with your own HTTP front.`,
1178
+ `This target has no anonymous public URL; expose ${path8} with your own HTTP front.`,
1037
1179
  tunnelLine,
1038
1180
  `You may invoke ${runtimeLabel} with envelope-v1 directly, but that is not a standard public ${label} HTTP endpoint.`,
1039
1181
  gatewayDocLine
@@ -1063,7 +1205,7 @@ function x402DeploySummaryFromSnapshot(snapshot, runtime, destination, publicUrl
1063
1205
  const egressLine = azure ? "PAID also needs fixed facilitator egress. Host the gateway on Azure Container Apps in a workload-profiles environment with a VNet + NAT Gateway static IP and allowlist that IP with B402 \u2014 no relay needed." : "PAID also needs fixed facilitator egress. Operate a restricted B402 Relay on a fixed-IP host such as a user-managed VPS, or use AgentCore VPC mode with a private subnet, NAT Gateway, and Elastic IP.";
1064
1206
  return [
1065
1207
  `${protocol} rail is ACTIVE (self-hosted ${runtimeLabel}).`,
1066
- `This target has no anonymous public URL; expose ${path7} with your own HTTP front.`,
1208
+ `This target has no anonymous public URL; expose ${path8} with your own HTTP front.`,
1067
1209
  tunnelLine,
1068
1210
  `You may invoke ${runtimeLabel} with envelope-v1 directly, but the caller must unpack the inner HTTP response and the result is not a standard public ${label} endpoint.`,
1069
1211
  egressLine,
@@ -1094,12 +1236,12 @@ var require2 = createRequire(import.meta.url);
1094
1236
  function resolveLocalDeployCli() {
1095
1237
  try {
1096
1238
  const manifest = require2.resolve("@bnbagent/deploy-cli/package.json");
1097
- const pkg = JSON.parse(fs5.readFileSync(manifest, "utf-8"));
1239
+ const pkg = JSON.parse(fs6.readFileSync(manifest, "utf-8"));
1098
1240
  if (pkg.version !== DEPLOY_CLI_VERSION) return null;
1099
1241
  const bin = typeof pkg.bin === "string" ? pkg.bin : pkg.bin?.["bnbagent-deploy"];
1100
1242
  if (typeof bin !== "string") return null;
1101
- const entry = path6.resolve(path6.dirname(manifest), bin);
1102
- return fs5.statSync(entry).isFile() ? entry : null;
1243
+ const entry = path7.resolve(path7.dirname(manifest), bin);
1244
+ return fs6.statSync(entry).isFile() ? entry : null;
1103
1245
  } catch {
1104
1246
  return null;
1105
1247
  }
@@ -1148,7 +1290,7 @@ function tableOf(data, key) {
1148
1290
  function descriptorName(root) {
1149
1291
  try {
1150
1292
  const raw = JSON.parse(
1151
- fs5.readFileSync(path6.join(root, "agentcore", "agentcore.json"), "utf-8")
1293
+ fs6.readFileSync(path7.join(root, "agentcore", "agentcore.json"), "utf-8")
1152
1294
  );
1153
1295
  if (raw !== null && typeof raw === "object" && !Array.isArray(raw)) {
1154
1296
  const name = raw.name;
@@ -1193,9 +1335,9 @@ function providerPassthrough(studio, table4) {
1193
1335
  }
1194
1336
  function buildDeploySpec(root, opts) {
1195
1337
  const agentRoot = findSubProjectRoot2("agent", root) ?? root;
1196
- const studio = loadStudioToml3(path6.join(agentRoot, "studio.toml"));
1338
+ const studio = loadStudioToml3(path7.join(agentRoot, "studio.toml"));
1197
1339
  const name = String(
1198
- opts.nameOverride || descriptorName(root) || tableOf(studio, "project").name || path6.basename(root)
1340
+ opts.nameOverride || descriptorName(root) || tableOf(studio, "project").name || path7.basename(root)
1199
1341
  );
1200
1342
  const stack = tableOf(studio, "stack");
1201
1343
  const payments = tableOf(studio, "payments");
@@ -1217,7 +1359,7 @@ function buildDeploySpec(root, opts) {
1217
1359
  OTEL_TRACES_EXPORTER: "none"
1218
1360
  };
1219
1361
  if (isContainer) {
1220
- deploy.dockerfile = path6.join(agentRoot, "Dockerfile");
1362
+ deploy.dockerfile = path7.join(agentRoot, "Dockerfile");
1221
1363
  } else {
1222
1364
  if (!opts.zip) {
1223
1365
  throw new Error("zip packaging requires a prebuilt zip artifact");
@@ -1349,28 +1491,28 @@ function renderSecretEnvFile(payload) {
1349
1491
  `).join("");
1350
1492
  }
1351
1493
  function writePrivateSync(filePath, content) {
1352
- fs5.writeFileSync(filePath, content, { mode: 384 });
1353
- fs5.chmodSync(filePath, 384);
1494
+ fs6.writeFileSync(filePath, content, { mode: 384 });
1495
+ fs6.chmodSync(filePath, 384);
1354
1496
  }
1355
1497
  async function withDeployFiles(root, opts, fn) {
1356
- const scratch = fs5.mkdtempSync(path6.join(os.tmpdir(), "bag-deploy-"));
1498
+ const scratch = fs6.mkdtempSync(path7.join(os2.tmpdir(), "bag-deploy-"));
1357
1499
  try {
1358
1500
  let zip;
1359
1501
  if (opts.packaging === "zip") {
1360
1502
  const agentRoot = findSubProjectRoot2("agent", root) ?? root;
1361
1503
  const studio = loadStudioToml3(
1362
- path6.join(agentRoot, "studio.toml")
1504
+ path7.join(agentRoot, "studio.toml")
1363
1505
  );
1364
1506
  const stack = tableOf(studio, "stack");
1365
1507
  const faces = stackFaces(stack, tableOf(studio, "payments"));
1366
- const outZip = path6.join(scratch, "code.zip");
1508
+ const outZip = path7.join(scratch, "code.zip");
1367
1509
  const built = await (opts.buildZipFn ?? buildZip)(agentRoot, outZip, {
1368
1510
  protocols: faces,
1369
1511
  managedPlatform: opts.target === "bnb/trial"
1370
1512
  });
1371
1513
  zip = { path: outZip, entrypoint: built.entrypoint };
1372
1514
  }
1373
- const secretFile = path6.join(scratch, "secrets.env");
1515
+ const secretFile = path7.join(scratch, "secrets.env");
1374
1516
  const inline = opts.inlineSecrets;
1375
1517
  const payload = opts.secrets ?? {};
1376
1518
  const spec = buildDeploySpec(root, {
@@ -1384,11 +1526,11 @@ async function withDeployFiles(root, opts, fn) {
1384
1526
  if (!inline && Object.keys(payload).length > 0) {
1385
1527
  writePrivateSync(secretFile, renderSecretEnvFile(payload));
1386
1528
  }
1387
- const configPath = path6.join(scratch, "agent-deploy.toml");
1529
+ const configPath = path7.join(scratch, "agent-deploy.toml");
1388
1530
  writePrivateSync(configPath, tomlStringify(spec.doc));
1389
1531
  return await fn({ configPath, scratchDir: scratch }, spec);
1390
1532
  } finally {
1391
- fs5.rmSync(scratch, { recursive: true, force: true });
1533
+ fs6.rmSync(scratch, { recursive: true, force: true });
1392
1534
  }
1393
1535
  }
1394
1536
  var DEPLOY_CLI_HINT = "error: could not start the lockfile-pinned bnbagent-deploy; install Bun 1.3+ and reinstall @bnbagent/studio-cli.";
@@ -1413,7 +1555,7 @@ function bunxInstallDir(environment = process.env) {
1413
1555
  return null;
1414
1556
  }
1415
1557
  const uid = typeof process.getuid === "function" ? process.getuid() : null;
1416
- return uid === null ? null : path6.join(os.tmpdir(), `bunx-${uid}-${DEPLOY_CLI_PACKAGE}`);
1558
+ return uid === null ? null : path7.join(os2.tmpdir(), `bunx-${uid}-${DEPLOY_CLI_PACKAGE}`);
1417
1559
  }
1418
1560
  async function bunxTreeIsIncomplete() {
1419
1561
  const [bin, ...prefix] = deployCommand();
@@ -1432,14 +1574,14 @@ async function withBunxSelfHeal(hasFailed, attempt) {
1432
1574
  if (dir === null || !await bunxTreeIsIncomplete()) {
1433
1575
  return first;
1434
1576
  }
1435
- if (!fs5.existsSync(dir)) {
1577
+ if (!fs6.existsSync(dir)) {
1436
1578
  printErr(BUNX_TREE_HINT);
1437
1579
  return first;
1438
1580
  }
1439
1581
  printErr(
1440
1582
  `note: ${DEPLOY_CLI_PACKAGE} failed to load its dependencies; clearing its incomplete bunx install and retrying once (${dir}).`
1441
1583
  );
1442
- fs5.rmSync(dir, { recursive: true, force: true });
1584
+ fs6.rmSync(dir, { recursive: true, force: true });
1443
1585
  const second = await attempt();
1444
1586
  if (hasFailed(second)) {
1445
1587
  printErr(BUNX_TREE_HINT);
@@ -1515,9 +1657,9 @@ async function runPlatformAccountCommand(argv, opts = {}) {
1515
1657
  if (!opts.slug) {
1516
1658
  return run([...argv, "--provider", "bnb"]);
1517
1659
  }
1518
- const scratch = fs5.mkdtempSync(path6.join(os.tmpdir(), "bag-platform-"));
1660
+ const scratch = fs6.mkdtempSync(path7.join(os2.tmpdir(), "bag-platform-"));
1519
1661
  try {
1520
- const configPath = path6.join(scratch, "agent-deploy.toml");
1662
+ const configPath = path7.join(scratch, "agent-deploy.toml");
1521
1663
  writePrivateSync(
1522
1664
  configPath,
1523
1665
  tomlStringify({
@@ -1528,11 +1670,13 @@ async function runPlatformAccountCommand(argv, opts = {}) {
1528
1670
  );
1529
1671
  return await run([...argv, "--provider", "bnb", "-f", configPath], scratch);
1530
1672
  } finally {
1531
- fs5.rmSync(scratch, { recursive: true, force: true });
1673
+ fs6.rmSync(scratch, { recursive: true, force: true });
1532
1674
  }
1533
1675
  }
1534
1676
 
1535
1677
  export {
1678
+ studioCliVersion,
1679
+ pnpmVersion,
1536
1680
  setEnvVar,
1537
1681
  getEnvVar,
1538
1682
  CliExit,
@@ -1562,6 +1706,20 @@ export {
1562
1706
  x402SellerIsFree,
1563
1707
  b402PaymentProtocol,
1564
1708
  deployCommandOverrideAllowed,
1709
+ runCapture,
1710
+ runStream,
1711
+ TWAK_CLI_VERSION,
1712
+ TWAK_CLI_MIN_VERSION,
1713
+ twakVersionBelowFloor,
1714
+ projectTwakBin,
1715
+ whichTwak,
1716
+ twakInstalledVersion,
1717
+ twakVersionForBin,
1718
+ twakHomeDir,
1719
+ twakWalletFile,
1720
+ twakDoubledHomeHint,
1721
+ twakMissingHint,
1722
+ twakCreateGuidance,
1565
1723
  whichBin,
1566
1724
  agentcoreFlavor,
1567
1725
  checkBunx,
@@ -1571,8 +1729,6 @@ export {
1571
1729
  deployChecks,
1572
1730
  render,
1573
1731
  readAwsTarget,
1574
- studioCliVersion,
1575
- pnpmVersion,
1576
1732
  B402_RUNTIME_KEYS,
1577
1733
  MPP_RUNTIME_KEYS,
1578
1734
  X402_CAPABLE_RUNTIMES,
File without changes
@@ -19,8 +19,7 @@ import {
19
19
  runPlatformAccountCommand,
20
20
  trialFromDeployCliJson,
21
21
  withDeployFiles
22
- } from "./chunk-H4X2OOLA.js";
23
- import "./chunk-RO726HJG.js";
22
+ } from "./chunk-QVYWAJEK.js";
24
23
  export {
25
24
  BNB_PLATFORM_API_URL,
26
25
  BNB_PLATFORM_API_URL_ENV,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bnbagent/studio-cli",
3
- "version": "0.0.13",
3
+ "version": "0.0.14-alpha.1",
4
4
  "description": "Skills-first toolkit and bag CLI for BNB Chain seller agents: ERC-8004 identity, ERC-8183 escrowed commerce, and x402 payments.",
5
5
  "keywords": [
6
6
  "bnb-chain",
@@ -25,7 +25,6 @@
25
25
  "directory": "packages/studio-cli"
26
26
  },
27
27
  "type": "module",
28
- "packageManager": "pnpm@10.24.0",
29
28
  "engines": {
30
29
  "node": ">=22"
31
30
  },
@@ -42,18 +41,9 @@
42
41
  "bin": {
43
42
  "bag": "./dist/bag.js"
44
43
  },
45
- "scripts": {
46
- "build": "tsup",
47
- "pretest": "pnpm --filter @bnbagent/studio-runtime build",
48
- "test": "vitest run",
49
- "lint": "biome check src tests",
50
- "typecheck": "tsc --noEmit",
51
- "check": "pnpm typecheck && pnpm lint && pnpm test && pnpm build"
52
- },
53
44
  "dependencies": {
54
45
  "@bnbagent/deploy-cli": "0.5.15",
55
46
  "@bnbagent/sdk": "0.5.5",
56
- "@bnbagent/studio-runtime": "0.0.13",
57
47
  "ai": "^7.0.29",
58
48
  "archiver": "^8.0.0",
59
49
  "commander": "^15.0.0",
@@ -64,7 +54,8 @@
64
54
  "smol-toml": "^1.3.0",
65
55
  "tar": "^7.4.0",
66
56
  "viem": "^2.54.0",
67
- "yaml": "^2.9.0"
57
+ "yaml": "^2.9.0",
58
+ "@bnbagent/studio-runtime": "0.0.14-alpha.1"
68
59
  },
69
60
  "devDependencies": {
70
61
  "@a2a-js/sdk": "^0.3.14",
@@ -80,5 +71,13 @@
80
71
  "typescript": "^5.5.0",
81
72
  "vitest": "^2.0.0",
82
73
  "zod": "^3.25.76"
74
+ },
75
+ "scripts": {
76
+ "build": "tsup",
77
+ "pretest": "pnpm --filter @bnbagent/studio-runtime build",
78
+ "test": "vitest run",
79
+ "lint": "biome check src tests",
80
+ "typecheck": "tsc --noEmit",
81
+ "check": "pnpm typecheck && pnpm lint && pnpm test && pnpm build"
83
82
  }
84
- }
83
+ }