@bnbagent/studio-cli 0.0.13 → 0.0.14-alpha.2
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/LICENSE +201 -0
- package/README.md +8 -0
- package/dist/_agentcoreName-DZDWEYD3.js +0 -0
- package/dist/bag.js +3741 -1612
- package/dist/{chunk-H4X2OOLA.js → chunk-CFMETPKS.js} +263 -73
- package/dist/chunk-U7IDQ3K5.js +0 -0
- package/dist/{deployCli-22NMZ4G7.js → deployCli-AVWKY3GN.js} +5 -2
- package/package.json +13 -14
- package/recipes/agent/code/{{PKG}}/deliveryPolicy.ts.tmpl +43 -0
- package/recipes/agent/code/{{PKG}}/readToolCatalog.ts.tmpl +102 -0
- package/recipes/agent/code/{{PKG}}/signing.ts.tmpl +7 -2
- package/recipes/agent/recipe.toml +5 -4
- package/recipes/mpp-buyer/recipe.toml +1 -1
- package/recipes/runtimes/agentcore/code/{{PKG}}/dualMain.ts.tmpl +6 -2
- package/recipes/runtimes/agentcore/code/{{PKG}}/mcpMain.ts.tmpl +173 -134
- package/recipes/runtimes/agentcore/code/{{PKG}}/model.ts.tmpl +7 -0
- package/recipes/runtimes/agentcore/code/{{PKG}}/sellerCore.ts.tmpl +31 -46
- package/recipes/runtimes/agentcore/code/{{PKG}}/tools.ts.tmpl +19 -48
- package/recipes/runtimes/agentcore/code/{{PKG}}/unifiedMain.ts.tmpl +2 -1
- package/recipes/runtimes/agentcore/recipe.toml +1 -1
- package/recipes/runtimes/azure-foundry/code/{{PKG}}/mcpMain.ts.tmpl +173 -134
- package/recipes/runtimes/azure-foundry/code/{{PKG}}/model.ts.tmpl +7 -0
- package/recipes/runtimes/azure-foundry/code/{{PKG}}/sellerCore.ts.tmpl +31 -46
- package/recipes/runtimes/azure-foundry/code/{{PKG}}/tools.ts.tmpl +19 -48
- package/recipes/runtimes/azure-foundry/code/{{PKG}}/unifiedMain.ts.tmpl +2 -1
- package/recipes/runtimes/azure-foundry/recipe.toml +1 -1
- package/recipes/wallet/recipe.toml +3 -2
- package/recipes/x402-buyer/recipe.toml +1 -1
- package/skills/bnbagent-studio.md +12 -1
- package/skills/references/bnbagent-studio-operating.md +1 -0
- package/skills/references/bnbagent-studio-scaffolding-agent.md +11 -34
- package/skills/references/bnbagent-studio-selling-via-b402.md +3 -3
- package/skills/references/bnbagent-studio-using-altana-wallet.md +7 -2
- package/skills/references/bnbagent-studio-using-twak-wallet.md +24 -76
- package/dist/_twak-4XF4H5PL.js +0 -25
- 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
|
|
4
|
+
import * as fs6 from "fs";
|
|
12
5
|
import { createRequire } from "module";
|
|
13
|
-
import * as
|
|
14
|
-
import * as
|
|
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: opts.quiet ? "pipe" : "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
|
|
740
|
-
import * as
|
|
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 =
|
|
888
|
+
const p = path3.join(root, "agentcore", "aws-targets.json");
|
|
750
889
|
let data;
|
|
751
890
|
try {
|
|
752
|
-
data = JSON.parse(
|
|
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
|
|
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
|
|
796
|
-
import * as
|
|
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 =
|
|
938
|
+
let dir = path4.dirname(fileURLToPath(import.meta.url));
|
|
800
939
|
for (; ; ) {
|
|
801
|
-
const packageJson =
|
|
802
|
-
if (
|
|
803
|
-
const parent =
|
|
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.
|
|
812
|
-
return "0.0.
|
|
950
|
+
if ("0.0.14-alpha.2") {
|
|
951
|
+
return "0.0.14-alpha.2";
|
|
813
952
|
}
|
|
814
|
-
const file =
|
|
815
|
-
const pkg = JSON.parse(
|
|
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 =
|
|
829
|
-
const pkg = JSON.parse(
|
|
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
|
|
842
|
-
import * as
|
|
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
|
-
|
|
849
|
-
|
|
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
|
-
|
|
857
|
-
if (!
|
|
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 =
|
|
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 (!
|
|
1032
|
+
if (!fs5.existsSync(filePath)) {
|
|
894
1033
|
return null;
|
|
895
1034
|
}
|
|
896
|
-
for (const line of
|
|
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:
|
|
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(
|
|
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
|
|
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 ${
|
|
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":"${
|
|
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 ${
|
|
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 ${
|
|
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(
|
|
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 =
|
|
1102
|
-
return
|
|
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
|
-
|
|
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(
|
|
1338
|
+
const studio = loadStudioToml3(path7.join(agentRoot, "studio.toml"));
|
|
1197
1339
|
const name = String(
|
|
1198
|
-
opts.nameOverride || descriptorName(root) || tableOf(studio, "project").name ||
|
|
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 =
|
|
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
|
-
|
|
1353
|
-
|
|
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 =
|
|
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
|
-
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
-
|
|
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 :
|
|
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 (!
|
|
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
|
-
|
|
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);
|
|
@@ -1468,6 +1610,7 @@ async function runDeployCliJson(argv, opts = {}) {
|
|
|
1468
1610
|
(result) => result.code !== 0,
|
|
1469
1611
|
() => runCaptureOut(bin, [...prefix, ...argv, "--json"], {
|
|
1470
1612
|
cwd: opts.cwd,
|
|
1613
|
+
quiet: opts.quiet,
|
|
1471
1614
|
env: opts.env ? { ...process.env, ...opts.env } : void 0
|
|
1472
1615
|
})
|
|
1473
1616
|
);
|
|
@@ -1478,7 +1621,7 @@ async function runDeployCliJson(argv, opts = {}) {
|
|
|
1478
1621
|
const parsed = JSON.parse(trimmed);
|
|
1479
1622
|
data = parsed !== null && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
|
|
1480
1623
|
} catch {
|
|
1481
|
-
printErr("error: bnbagent-deploy returned invalid JSON");
|
|
1624
|
+
if (!opts.quiet) printErr("error: bnbagent-deploy returned invalid JSON");
|
|
1482
1625
|
return { code: code === 0 ? 1 : code, data: {} };
|
|
1483
1626
|
}
|
|
1484
1627
|
}
|
|
@@ -1504,7 +1647,38 @@ function bnbEnv() {
|
|
|
1504
1647
|
BNBAGENT_CLI_SURFACE: "studio"
|
|
1505
1648
|
};
|
|
1506
1649
|
}
|
|
1650
|
+
function platformSessionFile() {
|
|
1651
|
+
return path7.join(
|
|
1652
|
+
process.env.BNBAGENT_DEPLOY_HOME?.trim() || path7.join(os2.homedir(), ".bnbagent-deploy"),
|
|
1653
|
+
"bnb",
|
|
1654
|
+
"session.json"
|
|
1655
|
+
);
|
|
1656
|
+
}
|
|
1657
|
+
function platformHostMismatchMessage(recorded, target) {
|
|
1658
|
+
return `Your platform login points at ${recorded}, but this command targets ${target}. Run \`bag platform logout && bag platform login\` to switch, then retry. If you intended to use the previous host, set BNBAGENT_API_URL to ${recorded} for login and subsequent commands.`;
|
|
1659
|
+
}
|
|
1660
|
+
function platformSessionHostError() {
|
|
1661
|
+
if (process.env.BNBAGENT_API_TOKEN?.trim()) return null;
|
|
1662
|
+
try {
|
|
1663
|
+
const session = JSON.parse(fs6.readFileSync(platformSessionFile(), "utf8"));
|
|
1664
|
+
const recorded = new URL(session.apiUrl).origin;
|
|
1665
|
+
const target = new URL(bnbPlatformApiUrl()).origin;
|
|
1666
|
+
return recorded === target ? null : platformHostMismatchMessage(recorded, target);
|
|
1667
|
+
} catch {
|
|
1668
|
+
return null;
|
|
1669
|
+
}
|
|
1670
|
+
}
|
|
1507
1671
|
async function runPlatformAccountCommand(argv, opts = {}) {
|
|
1672
|
+
if (!["login", "logout"].includes(argv[0] ?? "")) {
|
|
1673
|
+
const message = platformSessionHostError();
|
|
1674
|
+
if (message) {
|
|
1675
|
+
if (!opts.quiet) printErr(`error: ${message}`);
|
|
1676
|
+
return {
|
|
1677
|
+
code: 1,
|
|
1678
|
+
data: { error: { code: "auth.host_mismatch", message } }
|
|
1679
|
+
};
|
|
1680
|
+
}
|
|
1681
|
+
}
|
|
1508
1682
|
const run = async (args, cwd) => {
|
|
1509
1683
|
if (opts.json) {
|
|
1510
1684
|
return runDeployCliJson(args, { cwd, env: bnbEnv(), quiet: opts.quiet });
|
|
@@ -1515,9 +1689,9 @@ async function runPlatformAccountCommand(argv, opts = {}) {
|
|
|
1515
1689
|
if (!opts.slug) {
|
|
1516
1690
|
return run([...argv, "--provider", "bnb"]);
|
|
1517
1691
|
}
|
|
1518
|
-
const scratch =
|
|
1692
|
+
const scratch = fs6.mkdtempSync(path7.join(os2.tmpdir(), "bag-platform-"));
|
|
1519
1693
|
try {
|
|
1520
|
-
const configPath =
|
|
1694
|
+
const configPath = path7.join(scratch, "agent-deploy.toml");
|
|
1521
1695
|
writePrivateSync(
|
|
1522
1696
|
configPath,
|
|
1523
1697
|
tomlStringify({
|
|
@@ -1528,11 +1702,13 @@ async function runPlatformAccountCommand(argv, opts = {}) {
|
|
|
1528
1702
|
);
|
|
1529
1703
|
return await run([...argv, "--provider", "bnb", "-f", configPath], scratch);
|
|
1530
1704
|
} finally {
|
|
1531
|
-
|
|
1705
|
+
fs6.rmSync(scratch, { recursive: true, force: true });
|
|
1532
1706
|
}
|
|
1533
1707
|
}
|
|
1534
1708
|
|
|
1535
1709
|
export {
|
|
1710
|
+
studioCliVersion,
|
|
1711
|
+
pnpmVersion,
|
|
1536
1712
|
setEnvVar,
|
|
1537
1713
|
getEnvVar,
|
|
1538
1714
|
CliExit,
|
|
@@ -1562,6 +1738,20 @@ export {
|
|
|
1562
1738
|
x402SellerIsFree,
|
|
1563
1739
|
b402PaymentProtocol,
|
|
1564
1740
|
deployCommandOverrideAllowed,
|
|
1741
|
+
runCapture,
|
|
1742
|
+
runStream,
|
|
1743
|
+
TWAK_CLI_VERSION,
|
|
1744
|
+
TWAK_CLI_MIN_VERSION,
|
|
1745
|
+
twakVersionBelowFloor,
|
|
1746
|
+
projectTwakBin,
|
|
1747
|
+
whichTwak,
|
|
1748
|
+
twakInstalledVersion,
|
|
1749
|
+
twakVersionForBin,
|
|
1750
|
+
twakHomeDir,
|
|
1751
|
+
twakWalletFile,
|
|
1752
|
+
twakDoubledHomeHint,
|
|
1753
|
+
twakMissingHint,
|
|
1754
|
+
twakCreateGuidance,
|
|
1565
1755
|
whichBin,
|
|
1566
1756
|
agentcoreFlavor,
|
|
1567
1757
|
checkBunx,
|
|
@@ -1571,8 +1761,6 @@ export {
|
|
|
1571
1761
|
deployChecks,
|
|
1572
1762
|
render,
|
|
1573
1763
|
readAwsTarget,
|
|
1574
|
-
studioCliVersion,
|
|
1575
|
-
pnpmVersion,
|
|
1576
1764
|
B402_RUNTIME_KEYS,
|
|
1577
1765
|
MPP_RUNTIME_KEYS,
|
|
1578
1766
|
X402_CAPABLE_RUNTIMES,
|
|
@@ -1599,5 +1787,7 @@ export {
|
|
|
1599
1787
|
runDeployCliJson,
|
|
1600
1788
|
trialFromDeployCliJson,
|
|
1601
1789
|
bnbEnv,
|
|
1790
|
+
platformSessionFile,
|
|
1791
|
+
platformHostMismatchMessage,
|
|
1602
1792
|
runPlatformAccountCommand
|
|
1603
1793
|
};
|
package/dist/chunk-U7IDQ3K5.js
CHANGED
|
File without changes
|
|
@@ -12,6 +12,8 @@ import {
|
|
|
12
12
|
bunxInstallDir,
|
|
13
13
|
deployCommand,
|
|
14
14
|
deployEndpointValue,
|
|
15
|
+
platformHostMismatchMessage,
|
|
16
|
+
platformSessionFile,
|
|
15
17
|
providerPassthrough,
|
|
16
18
|
renderSecretEnvFile,
|
|
17
19
|
runDeployCliJson,
|
|
@@ -19,8 +21,7 @@ import {
|
|
|
19
21
|
runPlatformAccountCommand,
|
|
20
22
|
trialFromDeployCliJson,
|
|
21
23
|
withDeployFiles
|
|
22
|
-
} from "./chunk-
|
|
23
|
-
import "./chunk-RO726HJG.js";
|
|
24
|
+
} from "./chunk-CFMETPKS.js";
|
|
24
25
|
export {
|
|
25
26
|
BNB_PLATFORM_API_URL,
|
|
26
27
|
BNB_PLATFORM_API_URL_ENV,
|
|
@@ -34,6 +35,8 @@ export {
|
|
|
34
35
|
bunxInstallDir,
|
|
35
36
|
deployCommand,
|
|
36
37
|
deployEndpointValue,
|
|
38
|
+
platformHostMismatchMessage,
|
|
39
|
+
platformSessionFile,
|
|
37
40
|
providerPassthrough,
|
|
38
41
|
renderSecretEnvFile,
|
|
39
42
|
runDeployCliJson,
|