@bnbagent/studio-cli 0.0.6-alpha.8 → 0.0.6
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/_agentcoreName-DZDWEYD3.js +0 -0
- package/dist/_twak-4XF4H5PL.js +0 -0
- package/dist/bag.js +430 -225
- package/dist/{chunk-JZAW6HMV.js → chunk-ODCZKKZJ.js} +2 -2
- package/dist/chunk-RO726HJG.js +0 -0
- package/dist/chunk-U7IDQ3K5.js +0 -0
- package/dist/{deployCli-AJ25A4VK.js → deployCli-VM5TYKQX.js} +1 -1
- package/package.json +13 -12
- package/recipes/agent/code/{{PKG}}/signing.ts.tmpl +9 -7
- package/recipes/agent/recipe.toml +1 -1
- package/recipes/runtimes/agentcore/recipe.toml +1 -1
- package/recipes/runtimes/azure-foundry/recipe.toml +1 -1
- package/recipes/x402-buyer/recipe.toml +1 -1
- package/skills/bnbagent-studio.md +2 -2
- package/skills/references/bnbagent-studio-adding-to-project.md +1 -1
- package/skills/references/bnbagent-studio-buying-via-8183.md +2 -2
- package/skills/references/bnbagent-studio-operating.md +1 -2
- package/skills/references/bnbagent-studio-scaffolding-agent.md +4 -2
- package/skills/references/bnbagent-studio-selling-via-8183.md +2 -5
- package/skills/references/bnbagent-studio-use-aws-agentcore.md +2 -1
- package/skills/references/bnbagent-studio-use-bnb-trial.md +1 -1
- package/skills/references/bnbagent-studio-using-altana-wallet.md +4 -3
- package/LICENSE +0 -201
package/dist/bag.js
CHANGED
|
@@ -44,7 +44,7 @@ import {
|
|
|
44
44
|
x402SellerIsFree,
|
|
45
45
|
x402SellerPricingState,
|
|
46
46
|
x402SellerUsesB402
|
|
47
|
-
} from "./chunk-
|
|
47
|
+
} from "./chunk-ODCZKKZJ.js";
|
|
48
48
|
import {
|
|
49
49
|
TWAK_CLI_MIN_VERSION,
|
|
50
50
|
TWAK_CLI_VERSION,
|
|
@@ -69,35 +69,151 @@ import { ensureAltanaSessionLoaded } from "@bnbagent/studio-runtime/wallet";
|
|
|
69
69
|
import * as fs from "fs";
|
|
70
70
|
import {
|
|
71
71
|
STUDIO_TOML,
|
|
72
|
-
envLocalPath,
|
|
72
|
+
envLocalPath as envLocalPath2,
|
|
73
73
|
findProjectRoot,
|
|
74
74
|
findWorkspaceRoot,
|
|
75
75
|
loadEnv
|
|
76
76
|
} from "@bnbagent/studio-runtime/config";
|
|
77
|
-
|
|
77
|
+
|
|
78
|
+
// src/cli/_erc8183Config.ts
|
|
79
|
+
import { envLocalPath } from "@bnbagent/studio-runtime/config";
|
|
80
|
+
var ERC8183_ADDRESS_OVERRIDE_KEYS = [
|
|
81
|
+
"ERC8183_COMMERCE_ADDRESS",
|
|
82
|
+
"ERC8183_ROUTER_ADDRESS",
|
|
83
|
+
"ERC8183_POLICY_ADDRESS"
|
|
84
|
+
];
|
|
85
|
+
var MAX_UINT256 = 2n ** 256n - 1n;
|
|
86
|
+
function erc8183ContractEnvForProject(agentRoot2, fallback = process.env) {
|
|
87
|
+
const envPath = envLocalPath(agentRoot2);
|
|
88
|
+
const fromFile = {};
|
|
89
|
+
for (const key of ERC8183_ADDRESS_OVERRIDE_KEYS) {
|
|
90
|
+
const raw = getEnvVar(envPath, key);
|
|
91
|
+
if (raw === null) continue;
|
|
92
|
+
const value = raw.trim().replace(/^"(.*)"$/u, "$1").replace(/^'(.*)'$/u, "$1");
|
|
93
|
+
if (value) fromFile[key] = value;
|
|
94
|
+
}
|
|
95
|
+
const fromFallback = {};
|
|
96
|
+
const fallbackOwnsStack = ERC8183_ADDRESS_OVERRIDE_KEYS.some(
|
|
97
|
+
(key) => fallback[key] !== void 0
|
|
98
|
+
);
|
|
99
|
+
for (const key of ERC8183_ADDRESS_OVERRIDE_KEYS) {
|
|
100
|
+
const value = fallback[key]?.trim();
|
|
101
|
+
if (value) fromFallback[key] = value;
|
|
102
|
+
}
|
|
103
|
+
return fallbackOwnsStack ? fromFallback : fromFile;
|
|
104
|
+
}
|
|
105
|
+
function erc8183PricingState(pay) {
|
|
106
|
+
const priceRaw = pay.price;
|
|
107
|
+
const price = String(priceRaw ?? "").trim();
|
|
108
|
+
if (!price) return { kind: "unset" };
|
|
109
|
+
if (typeof priceRaw !== "string") {
|
|
110
|
+
return { kind: "invalid", field: "price", value: price };
|
|
111
|
+
}
|
|
112
|
+
const minRaw = pay.min_price;
|
|
113
|
+
const maxRaw = pay.max_price;
|
|
114
|
+
const minPrice = String(minRaw ?? "").trim() || "0";
|
|
115
|
+
const maxPrice = String(maxRaw ?? "").trim();
|
|
116
|
+
if (minRaw !== void 0 && typeof minRaw !== "string") {
|
|
117
|
+
return { kind: "invalid", field: "min_price", value: minPrice };
|
|
118
|
+
}
|
|
119
|
+
if (maxRaw !== void 0 && typeof maxRaw !== "string") {
|
|
120
|
+
return { kind: "invalid", field: "max_price", value: maxPrice };
|
|
121
|
+
}
|
|
122
|
+
for (const [field, value] of [
|
|
123
|
+
["price", price],
|
|
124
|
+
["min_price", minPrice],
|
|
125
|
+
["max_price", maxPrice]
|
|
126
|
+
]) {
|
|
127
|
+
if ((field !== "max_price" || value !== "") && !/^\d+$/.test(value)) {
|
|
128
|
+
return { kind: "invalid", field, value };
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
const list = BigInt(price);
|
|
132
|
+
const min = BigInt(minPrice);
|
|
133
|
+
const max = maxPrice ? BigInt(maxPrice) : MAX_UINT256;
|
|
134
|
+
if (list > MAX_UINT256 || min > MAX_UINT256 || max > MAX_UINT256) {
|
|
135
|
+
const [field, value] = list > MAX_UINT256 ? ["price", price] : min > MAX_UINT256 ? ["min_price", minPrice] : ["max_price", maxPrice];
|
|
136
|
+
return { kind: "invalid", field, value };
|
|
137
|
+
}
|
|
138
|
+
const clampedToMax = list < max ? list : max;
|
|
139
|
+
const effective = min > clampedToMax ? min : clampedToMax;
|
|
140
|
+
const base = {
|
|
141
|
+
listPrice: list,
|
|
142
|
+
minPrice: min,
|
|
143
|
+
maxPrice: max,
|
|
144
|
+
effectivePrice: effective
|
|
145
|
+
};
|
|
146
|
+
if (list > 0n && effective === 0n) {
|
|
147
|
+
return { kind: "clamped_to_zero", ...base };
|
|
148
|
+
}
|
|
149
|
+
return { kind: effective === 0n ? "free" : "paid", ...base };
|
|
150
|
+
}
|
|
151
|
+
function erc8183ContractOverrideState(env = process.env) {
|
|
152
|
+
const present = ERC8183_ADDRESS_OVERRIDE_KEYS.filter(
|
|
153
|
+
(key) => Boolean(env[key]?.trim())
|
|
154
|
+
);
|
|
155
|
+
const missing = ERC8183_ADDRESS_OVERRIDE_KEYS.filter(
|
|
156
|
+
(key) => !env[key]?.trim()
|
|
157
|
+
);
|
|
158
|
+
const invalid = present.filter(
|
|
159
|
+
(key) => !/^0x[0-9a-fA-F]{40}$/.test(env[key]?.trim() ?? "")
|
|
160
|
+
);
|
|
161
|
+
return {
|
|
162
|
+
mode: present.length === 0 ? "canonical" : invalid.length > 0 ? "invalid" : missing.length === 0 ? "custom" : "partial",
|
|
163
|
+
present: [...present],
|
|
164
|
+
missing: [...missing],
|
|
165
|
+
invalid
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// src/cli/_env.ts
|
|
170
|
+
var autoloadedValues = /* @__PURE__ */ new Map();
|
|
171
|
+
function releaseAutoloadedValues() {
|
|
172
|
+
for (const [key, value] of autoloadedValues) {
|
|
173
|
+
if (process.env[key] === value) {
|
|
174
|
+
delete process.env[key];
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
autoloadedValues.clear();
|
|
178
|
+
}
|
|
179
|
+
function autoloadProjectEnv(start) {
|
|
78
180
|
try {
|
|
79
|
-
|
|
181
|
+
releaseAutoloadedValues();
|
|
182
|
+
const root = findProjectRoot(start);
|
|
80
183
|
if (root === null) {
|
|
81
|
-
return;
|
|
184
|
+
return releaseAutoloadedValues;
|
|
82
185
|
}
|
|
83
|
-
const envPath =
|
|
186
|
+
const envPath = envLocalPath2(root);
|
|
84
187
|
if (!fs.statSync(envPath).isFile()) {
|
|
85
|
-
return;
|
|
188
|
+
return releaseAutoloadedValues;
|
|
86
189
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
process.env[key]
|
|
190
|
+
const explicitContractKeys = new Set(
|
|
191
|
+
ERC8183_ADDRESS_OVERRIDE_KEYS.filter(
|
|
192
|
+
(key) => process.env[key] !== void 0
|
|
193
|
+
)
|
|
194
|
+
);
|
|
195
|
+
const loaded = loadEnv(envPath);
|
|
196
|
+
if (explicitContractKeys.size > 0) {
|
|
197
|
+
for (const key of ERC8183_ADDRESS_OVERRIDE_KEYS) {
|
|
198
|
+
if (!explicitContractKeys.has(key) && key in loaded) {
|
|
199
|
+
delete process.env[key];
|
|
200
|
+
delete loaded[key];
|
|
201
|
+
}
|
|
90
202
|
}
|
|
91
203
|
}
|
|
204
|
+
for (const [key, value] of Object.entries(loaded)) {
|
|
205
|
+
autoloadedValues.set(key, value);
|
|
206
|
+
}
|
|
92
207
|
} catch {
|
|
93
208
|
}
|
|
209
|
+
return releaseAutoloadedValues;
|
|
94
210
|
}
|
|
95
211
|
|
|
96
212
|
// src/cli/_hosted/campaign.ts
|
|
97
213
|
import * as fs2 from "fs";
|
|
98
214
|
import * as path from "path";
|
|
99
215
|
import {
|
|
100
|
-
envLocalPath as
|
|
216
|
+
envLocalPath as envLocalPath3,
|
|
101
217
|
findSubProjectRoot,
|
|
102
218
|
loadStudioToml
|
|
103
219
|
} from "@bnbagent/studio-runtime/config";
|
|
@@ -106,7 +222,7 @@ import {
|
|
|
106
222
|
var CAMPAIGN_DOC_URL = "https://www.bnbchain.org/en/blog/bnb-agent-studio-is-live-on-bnb-chain-ai-agents-from-one-prompt";
|
|
107
223
|
var CAMPAIGN_CHECK_TIMEOUT_MS = 6e3;
|
|
108
224
|
async function fetchCampaignActive() {
|
|
109
|
-
const { bnbPlatformApiUrl: bnbPlatformApiUrl2 } = await import("./deployCli-
|
|
225
|
+
const { bnbPlatformApiUrl: bnbPlatformApiUrl2 } = await import("./deployCli-VM5TYKQX.js");
|
|
110
226
|
const controller = new AbortController();
|
|
111
227
|
const timer = setTimeout(() => controller.abort(), CAMPAIGN_CHECK_TIMEOUT_MS);
|
|
112
228
|
try {
|
|
@@ -158,7 +274,7 @@ var NUDGE_WINDOWS = [
|
|
|
158
274
|
];
|
|
159
275
|
var NUDGE_ORDER = ["", "12h", "1h", "expired"];
|
|
160
276
|
function trialStatePath(start) {
|
|
161
|
-
return path.join(path.dirname(
|
|
277
|
+
return path.join(path.dirname(envLocalPath3(start)), "platform-trial.json");
|
|
162
278
|
}
|
|
163
279
|
function loadTrialState(start) {
|
|
164
280
|
try {
|
|
@@ -521,8 +637,8 @@ function tableOf(cfg, key) {
|
|
|
521
637
|
const v = cfg[key];
|
|
522
638
|
return v !== null && typeof v === "object" && !Array.isArray(v) ? v : {};
|
|
523
639
|
}
|
|
524
|
-
function registerProject(
|
|
525
|
-
const projectRoot = normalizePath(
|
|
640
|
+
function registerProject(projectRootArg2, opts = {}) {
|
|
641
|
+
const projectRoot = normalizePath(projectRootArg2);
|
|
526
642
|
if (!isDir(projectRoot)) {
|
|
527
643
|
throw new Error(`path is not a directory: ${projectRoot}`);
|
|
528
644
|
}
|
|
@@ -1530,7 +1646,7 @@ function cmdDisable(projectRoot) {
|
|
|
1530
1646
|
import * as fs8 from "fs";
|
|
1531
1647
|
import * as path7 from "path";
|
|
1532
1648
|
import {
|
|
1533
|
-
envLocalPath as
|
|
1649
|
+
envLocalPath as envLocalPath4,
|
|
1534
1650
|
findSubProjectRoot as findSubProjectRoot2,
|
|
1535
1651
|
findWorkspaceRoot as findWorkspaceRoot2,
|
|
1536
1652
|
loadStudioToml as loadStudioToml2
|
|
@@ -1796,6 +1912,14 @@ var EXCLUDED_NAMES = /* @__PURE__ */ new Set([
|
|
|
1796
1912
|
".ruff_cache",
|
|
1797
1913
|
".mypy_cache"
|
|
1798
1914
|
]);
|
|
1915
|
+
var CREDENTIAL_FILE_NAMES = /* @__PURE__ */ new Set([
|
|
1916
|
+
".git-credentials",
|
|
1917
|
+
".netrc",
|
|
1918
|
+
".npmrc",
|
|
1919
|
+
".pypirc",
|
|
1920
|
+
".yarnrc",
|
|
1921
|
+
".yarnrc.yml"
|
|
1922
|
+
]);
|
|
1799
1923
|
function registerBundle(program) {
|
|
1800
1924
|
program.command("bundle").description(
|
|
1801
1925
|
"Bundle a seller workspace + pinned SDK/runtime tarballs for handoff."
|
|
@@ -1846,6 +1970,11 @@ async function createBundle(opts = {}) {
|
|
|
1846
1970
|
const archiveBase = `${safeName}-bundle-${stamp}`;
|
|
1847
1971
|
const stagingRoot = path7.join(outputDir, `.${archiveBase}.staging`);
|
|
1848
1972
|
const stagedWorkspace = path7.join(stagingRoot, safeName);
|
|
1973
|
+
if (stagedWorkspace === stagingRoot || !inside(stagedWorkspace, stagingRoot)) {
|
|
1974
|
+
throw new Error(
|
|
1975
|
+
`unsafe project name ${JSON.stringify(projectName2)} escapes the bundle staging directory`
|
|
1976
|
+
);
|
|
1977
|
+
}
|
|
1849
1978
|
const agentRel = path7.relative(workspaceRoot, agentRoot2);
|
|
1850
1979
|
const stagedAgent = path7.join(stagedWorkspace, agentRel);
|
|
1851
1980
|
const archivePath = path7.join(outputDir, `${archiveBase}.tar.gz`);
|
|
@@ -1917,7 +2046,8 @@ function readProjectName(agentRoot2) {
|
|
|
1917
2046
|
return String(name);
|
|
1918
2047
|
}
|
|
1919
2048
|
function excludedName(name) {
|
|
1920
|
-
|
|
2049
|
+
const lowerName = name.toLowerCase();
|
|
2050
|
+
return EXCLUDED_NAMES.has(lowerName) || CREDENTIAL_FILE_NAMES.has(lowerName) || lowerName.startsWith(".env") || lowerName.endsWith(".egg-info") || lowerName.startsWith(".venv-");
|
|
1921
2051
|
}
|
|
1922
2052
|
function inside(child, parent) {
|
|
1923
2053
|
const rel = path7.relative(parent, child);
|
|
@@ -1968,7 +2098,7 @@ function copyWorkspace(sourceRoot, destinationRoot, outputDir) {
|
|
|
1968
2098
|
copy(source, destinationRoot);
|
|
1969
2099
|
}
|
|
1970
2100
|
function writeEnvExample(agentRoot2, stagedWorkspace) {
|
|
1971
|
-
const sourceEnv =
|
|
2101
|
+
const sourceEnv = envLocalPath4(agentRoot2);
|
|
1972
2102
|
const targetDir = path7.join(stagedWorkspace, ".studio");
|
|
1973
2103
|
const target = path7.join(targetDir, ".env.local.example");
|
|
1974
2104
|
fs8.mkdirSync(targetDir, { recursive: true, mode: 448 });
|
|
@@ -1989,8 +2119,13 @@ function writeEnvExample(agentRoot2, stagedWorkspace) {
|
|
|
1989
2119
|
];
|
|
1990
2120
|
}
|
|
1991
2121
|
const stripped = lines.map((line) => {
|
|
1992
|
-
const
|
|
1993
|
-
|
|
2122
|
+
const trimmed = line.trim();
|
|
2123
|
+
if (!trimmed) return line;
|
|
2124
|
+
const commented = /^\s*(?:#\s*)+(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=/u.exec(line);
|
|
2125
|
+
if (commented) return `# ${commented[1]}=`;
|
|
2126
|
+
if (trimmed.startsWith("#")) return "# omitted source comment";
|
|
2127
|
+
const match = /^\s*([A-Za-z_][A-Za-z0-9_]*)\s*=/.exec(line);
|
|
2128
|
+
return match ? `${match[1]}=` : "# omitted unrecognized dotenv entry";
|
|
1994
2129
|
});
|
|
1995
2130
|
fs8.writeFileSync(target, `${[...header, ...stripped].join("\n")}
|
|
1996
2131
|
`, {
|
|
@@ -2004,6 +2139,7 @@ function findStagedLeak(stagedWorkspace) {
|
|
|
2004
2139
|
const full = path7.join(dir, name);
|
|
2005
2140
|
const rel = path7.relative(root, full);
|
|
2006
2141
|
const stat = fs8.lstatSync(full);
|
|
2142
|
+
const lowerName = name.toLowerCase();
|
|
2007
2143
|
if (stat.isSymbolicLink()) {
|
|
2008
2144
|
const link = fs8.readlinkSync(full);
|
|
2009
2145
|
const target = path7.resolve(path7.dirname(full), link);
|
|
@@ -2013,15 +2149,29 @@ function findStagedLeak(stagedWorkspace) {
|
|
|
2013
2149
|
continue;
|
|
2014
2150
|
}
|
|
2015
2151
|
if (stat.isDirectory()) {
|
|
2016
|
-
if (
|
|
2152
|
+
if (lowerName === "wallets" && path7.basename(path7.dirname(full)).toLowerCase() === ".studio") {
|
|
2017
2153
|
return `wallet directory ${rel}`;
|
|
2018
2154
|
}
|
|
2019
2155
|
const nested = walk(full);
|
|
2020
2156
|
if (nested !== null) return nested;
|
|
2021
2157
|
continue;
|
|
2022
2158
|
}
|
|
2023
|
-
if (stat.isFile() &&
|
|
2024
|
-
return `
|
|
2159
|
+
if (stat.isFile() && CREDENTIAL_FILE_NAMES.has(lowerName)) {
|
|
2160
|
+
return `credential file ${rel}`;
|
|
2161
|
+
}
|
|
2162
|
+
if (stat.isFile() && lowerName.startsWith(".env")) {
|
|
2163
|
+
if (lowerName !== ".env.local.example") return `env file ${rel}`;
|
|
2164
|
+
const safeFixedLines = /* @__PURE__ */ new Set([
|
|
2165
|
+
"# Copy to .studio/.env.local and fill in values.",
|
|
2166
|
+
"# Generated by `bag bundle`; secret values were stripped.",
|
|
2167
|
+
"# omitted source comment",
|
|
2168
|
+
"# omitted unrecognized dotenv entry"
|
|
2169
|
+
]);
|
|
2170
|
+
const unsafeExample = fs8.readFileSync(full, "utf-8").split(/\r?\n/u).some((line) => {
|
|
2171
|
+
if (!line.trim() || safeFixedLines.has(line)) return false;
|
|
2172
|
+
return !/^#?\s*[A-Za-z_][A-Za-z0-9_]*=$/u.test(line);
|
|
2173
|
+
});
|
|
2174
|
+
if (unsafeExample) return `non-empty env example ${rel}`;
|
|
2025
2175
|
}
|
|
2026
2176
|
}
|
|
2027
2177
|
return null;
|
|
@@ -2064,6 +2214,7 @@ function writeInstallMd(stagedWorkspace, projectName2) {
|
|
|
2064
2214
|
"",
|
|
2065
2215
|
"- `.studio/.env.local`",
|
|
2066
2216
|
"- `.studio/wallets/` and TWAK/Altana custody state",
|
|
2217
|
+
"- project-level credential files such as `.npmrc`",
|
|
2067
2218
|
"- `node_modules/`, build outputs, caches, and repository history",
|
|
2068
2219
|
""
|
|
2069
2220
|
];
|
|
@@ -2104,77 +2255,6 @@ function devPortInUse(port = 9e3, timeoutMs = 250) {
|
|
|
2104
2255
|
});
|
|
2105
2256
|
}
|
|
2106
2257
|
|
|
2107
|
-
// src/cli/_erc8183Config.ts
|
|
2108
|
-
var ERC8183_ADDRESS_OVERRIDE_KEYS = [
|
|
2109
|
-
"ERC8183_COMMERCE_ADDRESS",
|
|
2110
|
-
"ERC8183_ROUTER_ADDRESS",
|
|
2111
|
-
"ERC8183_POLICY_ADDRESS"
|
|
2112
|
-
];
|
|
2113
|
-
var MAX_UINT256 = 2n ** 256n - 1n;
|
|
2114
|
-
function erc8183PricingState(pay) {
|
|
2115
|
-
const priceRaw = pay.price;
|
|
2116
|
-
const price = String(priceRaw ?? "").trim();
|
|
2117
|
-
if (!price) return { kind: "unset" };
|
|
2118
|
-
if (typeof priceRaw !== "string") {
|
|
2119
|
-
return { kind: "invalid", field: "price", value: price };
|
|
2120
|
-
}
|
|
2121
|
-
const minRaw = pay.min_price;
|
|
2122
|
-
const maxRaw = pay.max_price;
|
|
2123
|
-
const minPrice = String(minRaw ?? "").trim() || "0";
|
|
2124
|
-
const maxPrice = String(maxRaw ?? "").trim();
|
|
2125
|
-
if (minRaw !== void 0 && typeof minRaw !== "string") {
|
|
2126
|
-
return { kind: "invalid", field: "min_price", value: minPrice };
|
|
2127
|
-
}
|
|
2128
|
-
if (maxRaw !== void 0 && typeof maxRaw !== "string") {
|
|
2129
|
-
return { kind: "invalid", field: "max_price", value: maxPrice };
|
|
2130
|
-
}
|
|
2131
|
-
for (const [field, value] of [
|
|
2132
|
-
["price", price],
|
|
2133
|
-
["min_price", minPrice],
|
|
2134
|
-
["max_price", maxPrice]
|
|
2135
|
-
]) {
|
|
2136
|
-
if ((field !== "max_price" || value !== "") && !/^\d+$/.test(value)) {
|
|
2137
|
-
return { kind: "invalid", field, value };
|
|
2138
|
-
}
|
|
2139
|
-
}
|
|
2140
|
-
const list = BigInt(price);
|
|
2141
|
-
const min = BigInt(minPrice);
|
|
2142
|
-
const max = maxPrice ? BigInt(maxPrice) : MAX_UINT256;
|
|
2143
|
-
if (list > MAX_UINT256 || min > MAX_UINT256 || max > MAX_UINT256) {
|
|
2144
|
-
const [field, value] = list > MAX_UINT256 ? ["price", price] : min > MAX_UINT256 ? ["min_price", minPrice] : ["max_price", maxPrice];
|
|
2145
|
-
return { kind: "invalid", field, value };
|
|
2146
|
-
}
|
|
2147
|
-
const clampedToMax = list < max ? list : max;
|
|
2148
|
-
const effective = min > clampedToMax ? min : clampedToMax;
|
|
2149
|
-
const base = {
|
|
2150
|
-
listPrice: list,
|
|
2151
|
-
minPrice: min,
|
|
2152
|
-
maxPrice: max,
|
|
2153
|
-
effectivePrice: effective
|
|
2154
|
-
};
|
|
2155
|
-
if (list > 0n && effective === 0n) {
|
|
2156
|
-
return { kind: "clamped_to_zero", ...base };
|
|
2157
|
-
}
|
|
2158
|
-
return { kind: effective === 0n ? "free" : "paid", ...base };
|
|
2159
|
-
}
|
|
2160
|
-
function erc8183ContractOverrideState(env = process.env) {
|
|
2161
|
-
const present = ERC8183_ADDRESS_OVERRIDE_KEYS.filter(
|
|
2162
|
-
(key) => Boolean(env[key]?.trim())
|
|
2163
|
-
);
|
|
2164
|
-
const missing = ERC8183_ADDRESS_OVERRIDE_KEYS.filter(
|
|
2165
|
-
(key) => !env[key]?.trim()
|
|
2166
|
-
);
|
|
2167
|
-
const invalid = present.filter(
|
|
2168
|
-
(key) => !/^0x[0-9a-fA-F]{40}$/.test(env[key]?.trim() ?? "")
|
|
2169
|
-
);
|
|
2170
|
-
return {
|
|
2171
|
-
mode: present.length === 0 ? "canonical" : invalid.length > 0 ? "invalid" : missing.length === 0 ? "custom" : "partial",
|
|
2172
|
-
present: [...present],
|
|
2173
|
-
missing: [...missing],
|
|
2174
|
-
invalid
|
|
2175
|
-
};
|
|
2176
|
-
}
|
|
2177
|
-
|
|
2178
2258
|
// src/cli/config.ts
|
|
2179
2259
|
var MAX_QUOTE_TTL_SECONDS = NegotiationHandler.MAX_QUOTE_TTL_SECONDS;
|
|
2180
2260
|
function registerConfig(program) {
|
|
@@ -2484,7 +2564,9 @@ async function cmdSet(key, rawValue, typeFlag, projectRoot) {
|
|
|
2484
2564
|
}
|
|
2485
2565
|
if (pricing.kind === "free") {
|
|
2486
2566
|
printOut("pricing: FREE \u2014 buyers fund 0 token units; zero token escrow.");
|
|
2487
|
-
const contracts = erc8183ContractOverrideState(
|
|
2567
|
+
const contracts = erc8183ContractOverrideState(
|
|
2568
|
+
erc8183ContractEnvForProject(root)
|
|
2569
|
+
);
|
|
2488
2570
|
if (contracts.mode === "custom") {
|
|
2489
2571
|
printOut(
|
|
2490
2572
|
"ERC-8183 contracts: custom contract stack selected with all three address overrides."
|
|
@@ -2498,8 +2580,8 @@ async function cmdSet(key, rawValue, typeFlag, projectRoot) {
|
|
|
2498
2580
|
`warning: invalid ERC-8183 address override(s): ${contracts.invalid.join(", ")}.`
|
|
2499
2581
|
);
|
|
2500
2582
|
} else {
|
|
2501
|
-
|
|
2502
|
-
"
|
|
2583
|
+
printOut(
|
|
2584
|
+
"ERC-8183 contracts: canonical contract stack selected; zero-price funding is supported."
|
|
2503
2585
|
);
|
|
2504
2586
|
}
|
|
2505
2587
|
} else if (pricing.kind === "clamped_to_zero") {
|
|
@@ -2554,7 +2636,7 @@ function cmdListKeys(projectRoot) {
|
|
|
2554
2636
|
import * as fs38 from "fs";
|
|
2555
2637
|
import * as path38 from "path";
|
|
2556
2638
|
import {
|
|
2557
|
-
envLocalPath as
|
|
2639
|
+
envLocalPath as envLocalPath17,
|
|
2558
2640
|
findStudioWorkspaceRoot as findStudioWorkspaceRoot3,
|
|
2559
2641
|
findSubProjectRoot as findSubProjectRoot16,
|
|
2560
2642
|
loadStudioToml as loadStudioToml20
|
|
@@ -2566,7 +2648,7 @@ import { Option as Option4 } from "commander";
|
|
|
2566
2648
|
import * as fs10 from "fs";
|
|
2567
2649
|
import * as path9 from "path";
|
|
2568
2650
|
import {
|
|
2569
|
-
envLocalPath as
|
|
2651
|
+
envLocalPath as envLocalPath5,
|
|
2570
2652
|
findWorkspaceRoot as findWorkspaceRoot3,
|
|
2571
2653
|
loadStudioToml as loadStudioToml3
|
|
2572
2654
|
} from "@bnbagent/studio-runtime/config";
|
|
@@ -2649,10 +2731,10 @@ function oauthFacts(workspaceRoot, agentRoot2) {
|
|
|
2649
2731
|
let tokenUrl = envValue(env, "OAUTH_TOKEN_URL");
|
|
2650
2732
|
let scope = envValue(env, "OAUTH_SCOPE");
|
|
2651
2733
|
if (!tokenUrl) {
|
|
2652
|
-
tokenUrl = dotenvValue(
|
|
2734
|
+
tokenUrl = dotenvValue(envLocalPath5(agentRoot2), "OAUTH_TOKEN_URL");
|
|
2653
2735
|
}
|
|
2654
2736
|
if (!scope) {
|
|
2655
|
-
scope = dotenvValue(
|
|
2737
|
+
scope = dotenvValue(envLocalPath5(agentRoot2), "OAUTH_SCOPE");
|
|
2656
2738
|
}
|
|
2657
2739
|
return tokenUrl && scope ? [tokenUrl, scope] : null;
|
|
2658
2740
|
}
|
|
@@ -2687,7 +2769,7 @@ function accessSummaryForAgentcore(agentRoot2, opts = {}) {
|
|
|
2687
2769
|
|
|
2688
2770
|
// src/cli/_deploy/checks/storage.ts
|
|
2689
2771
|
import {
|
|
2690
|
-
envLocalPath as
|
|
2772
|
+
envLocalPath as envLocalPath6,
|
|
2691
2773
|
findSubProjectRoot as findSubProjectRoot4
|
|
2692
2774
|
} from "@bnbagent/studio-runtime/config";
|
|
2693
2775
|
|
|
@@ -2945,7 +3027,7 @@ function agentStorageKind(root) {
|
|
|
2945
3027
|
}
|
|
2946
3028
|
function runtimeEnvResolvable(root, key) {
|
|
2947
3029
|
const agentRoot2 = findSubProjectRoot4("agent", root) ?? root;
|
|
2948
|
-
return Boolean(process.env[key] || getEnvVar(
|
|
3030
|
+
return Boolean(process.env[key] || getEnvVar(envLocalPath6(agentRoot2), key));
|
|
2949
3031
|
}
|
|
2950
3032
|
function storageLocalNotDeployableCheck(root) {
|
|
2951
3033
|
if (agentStorageKind(root) !== "local") {
|
|
@@ -2996,13 +3078,13 @@ function hasIpfsEndpointFinding(result) {
|
|
|
2996
3078
|
// src/cli/_deploy/cognitoCdk.ts
|
|
2997
3079
|
import * as fs28 from "fs";
|
|
2998
3080
|
import * as path27 from "path";
|
|
2999
|
-
import { envLocalPath as
|
|
3081
|
+
import { envLocalPath as envLocalPath14 } from "@bnbagent/studio-runtime/config";
|
|
3000
3082
|
|
|
3001
3083
|
// src/cli/_deploy/secrets.ts
|
|
3002
3084
|
import * as fs27 from "fs";
|
|
3003
3085
|
import * as path26 from "path";
|
|
3004
3086
|
import {
|
|
3005
|
-
envLocalPath as
|
|
3087
|
+
envLocalPath as envLocalPath13,
|
|
3006
3088
|
findSubProjectRoot as findSubProjectRoot8,
|
|
3007
3089
|
loadStudioToml as loadStudioToml13
|
|
3008
3090
|
} from "@bnbagent/studio-runtime/config";
|
|
@@ -3021,7 +3103,7 @@ import { Option as Option3 } from "commander";
|
|
|
3021
3103
|
import * as fs12 from "fs";
|
|
3022
3104
|
import * as path11 from "path";
|
|
3023
3105
|
import {
|
|
3024
|
-
envLocalPath as
|
|
3106
|
+
envLocalPath as envLocalPath7,
|
|
3025
3107
|
findSubProjectRoot as findSubProjectRoot5,
|
|
3026
3108
|
loadStudioToml as loadStudioToml5
|
|
3027
3109
|
} from "@bnbagent/studio-runtime/config";
|
|
@@ -3054,7 +3136,7 @@ function keystoreJsonFiles(dir) {
|
|
|
3054
3136
|
}
|
|
3055
3137
|
function migrateEnvLocal(start) {
|
|
3056
3138
|
try {
|
|
3057
|
-
const target =
|
|
3139
|
+
const target = envLocalPath7(start);
|
|
3058
3140
|
const ws = path11.dirname(path11.dirname(target));
|
|
3059
3141
|
const agentRoot2 = findSubProjectRoot5("agent", start);
|
|
3060
3142
|
const sources = [];
|
|
@@ -3120,7 +3202,7 @@ function migrateKeystoreOutOfCodelocation(start) {
|
|
|
3120
3202
|
if (agentRoot2 === null) {
|
|
3121
3203
|
return;
|
|
3122
3204
|
}
|
|
3123
|
-
const ws = path11.dirname(path11.dirname(
|
|
3205
|
+
const ws = path11.dirname(path11.dirname(envLocalPath7(start)));
|
|
3124
3206
|
const target = path11.join(ws, ".studio", "wallets");
|
|
3125
3207
|
const stash = path11.join(ws, ".bag-keystore-stash");
|
|
3126
3208
|
if (isDir2(stash)) {
|
|
@@ -3469,6 +3551,26 @@ var EXPIRY_WARN_SECONDS = 7 * 24 * 60 * 60;
|
|
|
3469
3551
|
function isAltana(data) {
|
|
3470
3552
|
return tableOf2(data, "wallet").kind === "altana";
|
|
3471
3553
|
}
|
|
3554
|
+
function checkAltanaCustomContractsUnsupported(root, _target) {
|
|
3555
|
+
const data = loadAgentToml(root);
|
|
3556
|
+
if (!isAltana(data)) return [];
|
|
3557
|
+
if (Object.keys(tableOf2(tableOf2(data, "payments"), "erc8183")).length === 0) {
|
|
3558
|
+
return [];
|
|
3559
|
+
}
|
|
3560
|
+
const agentRoot2 = agentRootOf(root);
|
|
3561
|
+
const contracts = erc8183ContractOverrideState(
|
|
3562
|
+
erc8183ContractEnvForProject(agentRoot2)
|
|
3563
|
+
);
|
|
3564
|
+
if (contracts.mode !== "custom") return [];
|
|
3565
|
+
return [
|
|
3566
|
+
{
|
|
3567
|
+
level: Level.CRITICAL,
|
|
3568
|
+
name: "altana_custom_contracts_unsupported",
|
|
3569
|
+
message: "wallet.kind='altana' cannot use custom ERC-8183 targets: its bounded session permissions and quote-checker approval are tied to the canonical Commerce stack. Remove the ERC8183_*_ADDRESS overrides, or use wallet.kind='evm-local' for this custom stack.",
|
|
3570
|
+
details: { override_keys: contracts.present }
|
|
3571
|
+
}
|
|
3572
|
+
];
|
|
3573
|
+
}
|
|
3472
3574
|
function isFile4(p) {
|
|
3473
3575
|
try {
|
|
3474
3576
|
return fs15.statSync(p).isFile();
|
|
@@ -3632,7 +3734,7 @@ function checkAltanaSessionNotInsideAgent(root, _target) {
|
|
|
3632
3734
|
// src/cli/_deploy/checks/twak.ts
|
|
3633
3735
|
import * as fs16 from "fs";
|
|
3634
3736
|
import * as path15 from "path";
|
|
3635
|
-
import { envLocalPath as
|
|
3737
|
+
import { envLocalPath as envLocalPath8 } from "@bnbagent/studio-runtime/config";
|
|
3636
3738
|
import { resolveTwakHome } from "@bnbagent/studio-runtime/wallet";
|
|
3637
3739
|
|
|
3638
3740
|
// src/cli/_twakContractTargets.ts
|
|
@@ -3784,7 +3886,10 @@ function checkTwakCustomContractsUnsupported(root, _target) {
|
|
|
3784
3886
|
return [];
|
|
3785
3887
|
}
|
|
3786
3888
|
const networkName = String(tableOf2(data, "network").default ?? "bsc-testnet");
|
|
3787
|
-
const overrides = twakUnsupportedContractOverrides(
|
|
3889
|
+
const overrides = twakUnsupportedContractOverrides(
|
|
3890
|
+
networkName,
|
|
3891
|
+
erc8183ContractEnvForProject(agentRootOf(root))
|
|
3892
|
+
);
|
|
3788
3893
|
if (overrides.length === 0) {
|
|
3789
3894
|
return [];
|
|
3790
3895
|
}
|
|
@@ -3884,7 +3989,7 @@ async function checkTwakPasswordEnvSet(root, _target) {
|
|
|
3884
3989
|
return [];
|
|
3885
3990
|
}
|
|
3886
3991
|
const agentRoot2 = agentRootOf(root);
|
|
3887
|
-
if (process.env.TWAK_WALLET_PASSWORD || getEnvVar(
|
|
3992
|
+
if (process.env.TWAK_WALLET_PASSWORD || getEnvVar(envLocalPath8(agentRoot2), "TWAK_WALLET_PASSWORD")) {
|
|
3888
3993
|
return [];
|
|
3889
3994
|
}
|
|
3890
3995
|
return [
|
|
@@ -3935,7 +4040,7 @@ async function checkTwakCredentialsAvailable(root, _target) {
|
|
|
3935
4040
|
path15.dirname(twakWalletFile(walletCfg, agentRoot2)),
|
|
3936
4041
|
"credentials.json"
|
|
3937
4042
|
);
|
|
3938
|
-
const envLocal =
|
|
4043
|
+
const envLocal = envLocalPath8(agentRoot2);
|
|
3939
4044
|
const resolvable = (key) => Boolean(process.env[key] || getEnvVar(envLocal, key));
|
|
3940
4045
|
if (isFile5(credentialsFile)) {
|
|
3941
4046
|
return [];
|
|
@@ -3956,9 +4061,9 @@ async function checkTwakCredentialsAvailable(root, _target) {
|
|
|
3956
4061
|
// src/cli/_deploy/fixes.ts
|
|
3957
4062
|
import * as fs17 from "fs";
|
|
3958
4063
|
import * as path16 from "path";
|
|
3959
|
-
import { envLocalPath as
|
|
4064
|
+
import { envLocalPath as envLocalPath9 } from "@bnbagent/studio-runtime/config";
|
|
3960
4065
|
function fixGitignore(root) {
|
|
3961
|
-
const ws = path16.dirname(path16.dirname(
|
|
4066
|
+
const ws = path16.dirname(path16.dirname(envLocalPath9(root)));
|
|
3962
4067
|
const gi = path16.join(ws, ".gitignore");
|
|
3963
4068
|
const required = [".studio/"];
|
|
3964
4069
|
let exists = false;
|
|
@@ -4432,8 +4537,10 @@ var azureFoundryChecks = [
|
|
|
4432
4537
|
checkAccountEqualsSubdomain,
|
|
4433
4538
|
checkEntrypointAndDockerfile,
|
|
4434
4539
|
checkLlmExternalProviderReady,
|
|
4540
|
+
checkTwakCustomContractsUnsupported,
|
|
4435
4541
|
checkTwakPasswordEnvSet,
|
|
4436
4542
|
checkTwakCredentialsAvailable,
|
|
4543
|
+
checkAltanaCustomContractsUnsupported,
|
|
4437
4544
|
checkAltanaSessionReady,
|
|
4438
4545
|
checkAltanaSdkResolvable,
|
|
4439
4546
|
checkAltanaSessionNotInsideAgent
|
|
@@ -4444,7 +4551,7 @@ import * as fs19 from "fs";
|
|
|
4444
4551
|
import * as path18 from "path";
|
|
4445
4552
|
import { query as auditQuery, auditedOp } from "@bnbagent/studio-runtime/audit";
|
|
4446
4553
|
import {
|
|
4447
|
-
envLocalPath as
|
|
4554
|
+
envLocalPath as envLocalPath10,
|
|
4448
4555
|
findProjectRoot as findProjectRoot2,
|
|
4449
4556
|
loadStudioToml as loadStudioToml8
|
|
4450
4557
|
} from "@bnbagent/studio-runtime/config";
|
|
@@ -4533,7 +4640,17 @@ function printUBalanceShortfall(walletAddress, currentRaw, neededRaw, neededUsd,
|
|
|
4533
4640
|
function writeEnvLocal(key, value, envPath = ".env.local") {
|
|
4534
4641
|
return setEnvVar(envPath, key, value);
|
|
4535
4642
|
}
|
|
4643
|
+
function ensureSiweCapable(wallet) {
|
|
4644
|
+
const probe = wallet.supports;
|
|
4645
|
+
if (typeof probe !== "function") return;
|
|
4646
|
+
if (probe.call(wallet, "sign.message")) return;
|
|
4647
|
+
const kind = wallet.kind;
|
|
4648
|
+
throw new PieverseCliError(
|
|
4649
|
+
`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.`
|
|
4650
|
+
);
|
|
4651
|
+
}
|
|
4536
4652
|
async function withSiweRetry(wallet, call, opts = {}) {
|
|
4653
|
+
ensureSiweCapable(wallet);
|
|
4537
4654
|
let token = opts.sessionToken ?? await siweLogin(wallet);
|
|
4538
4655
|
try {
|
|
4539
4656
|
return await call(token);
|
|
@@ -4801,10 +4918,19 @@ async function cmdActivate(opts) {
|
|
|
4801
4918
|
if (wallet === null) {
|
|
4802
4919
|
return 2;
|
|
4803
4920
|
}
|
|
4921
|
+
try {
|
|
4922
|
+
ensureSiweCapable(wallet);
|
|
4923
|
+
} catch (exc) {
|
|
4924
|
+
if (exc instanceof PieverseCliError) {
|
|
4925
|
+
printErr(`error: ${exc.message}`);
|
|
4926
|
+
return 2;
|
|
4927
|
+
}
|
|
4928
|
+
throw exc;
|
|
4929
|
+
}
|
|
4804
4930
|
const pvCfg = loadPieverseConfig(cfg);
|
|
4805
4931
|
const replace = opts.replace === true;
|
|
4806
4932
|
let existingHash = !replace && pvCfg.key_hash ? String(pvCfg.key_hash) : null;
|
|
4807
|
-
const envFileValue = replace ? null : getEnvVar(
|
|
4933
|
+
const envFileValue = replace ? null : getEnvVar(envLocalPath10(root), PIEVERSE_ENV_KEY);
|
|
4808
4934
|
const existingEnv = replace ? null : envFileValue || process.env[PIEVERSE_ENV_KEY];
|
|
4809
4935
|
if (replace) {
|
|
4810
4936
|
printOut(
|
|
@@ -4824,6 +4950,10 @@ async function cmdActivate(opts) {
|
|
|
4824
4950
|
try {
|
|
4825
4951
|
await withSiweRetry(wallet, (token) => inspectKey(token, derivedHash));
|
|
4826
4952
|
} catch (exc) {
|
|
4953
|
+
if (exc instanceof PieverseCliError) {
|
|
4954
|
+
printErr(`error: ${exc.message}`);
|
|
4955
|
+
return 2;
|
|
4956
|
+
}
|
|
4827
4957
|
if (!(exc instanceof PieverseKeyNotFoundError)) {
|
|
4828
4958
|
printErr(
|
|
4829
4959
|
`error: could not verify the existing ${PIEVERSE_ENV_KEY} against Pieverse: ${errMessage(
|
|
@@ -5003,7 +5133,7 @@ Retry: re-run \`bag llm activate\` \u2014 no state was persisted yet.`
|
|
|
5003
5133
|
}
|
|
5004
5134
|
const key = String(result.key);
|
|
5005
5135
|
const keyHash = String(result.hash);
|
|
5006
|
-
writeEnvLocal(PIEVERSE_ENV_KEY, key,
|
|
5136
|
+
writeEnvLocal(PIEVERSE_ENV_KEY, key, envLocalPath10(root));
|
|
5007
5137
|
updateStudioTomlSection(root, "llm.pieverse", {
|
|
5008
5138
|
key_hash: keyHash,
|
|
5009
5139
|
network: networkName
|
|
@@ -5534,7 +5664,7 @@ async function cmdRotate(opts) {
|
|
|
5534
5664
|
`warning: could not auto-disable old key \u2014 manually disable ${oldHash} in the Pieverse dashboard.`
|
|
5535
5665
|
);
|
|
5536
5666
|
}
|
|
5537
|
-
writeEnvLocal(PIEVERSE_ENV_KEY, newKey,
|
|
5667
|
+
writeEnvLocal(PIEVERSE_ENV_KEY, newKey, envLocalPath10(root));
|
|
5538
5668
|
updateStudioTomlSection(root, "llm.pieverse", {
|
|
5539
5669
|
key_hash: newHash,
|
|
5540
5670
|
network: networkName
|
|
@@ -6289,7 +6419,7 @@ import * as os3 from "os";
|
|
|
6289
6419
|
import * as path22 from "path";
|
|
6290
6420
|
import { EVMWalletProvider, SigningPolicy } from "@bnbagent/sdk";
|
|
6291
6421
|
import {
|
|
6292
|
-
envLocalPath as
|
|
6422
|
+
envLocalPath as envLocalPath11,
|
|
6293
6423
|
findProjectRoot as findProjectRoot3,
|
|
6294
6424
|
loadStudioToml as loadStudioToml10
|
|
6295
6425
|
} from "@bnbagent/studio-runtime/config";
|
|
@@ -6600,8 +6730,8 @@ async function cmdSessionGrant(opts) {
|
|
|
6600
6730
|
printOut(granted.publicKey);
|
|
6601
6731
|
return 0;
|
|
6602
6732
|
}
|
|
6603
|
-
function cmdSessionStatus(
|
|
6604
|
-
const projectRoot = resolveProjectRootArg(
|
|
6733
|
+
function cmdSessionStatus(projectRootArg2) {
|
|
6734
|
+
const projectRoot = resolveProjectRootArg(projectRootArg2);
|
|
6605
6735
|
if (projectRoot === null) return 2;
|
|
6606
6736
|
const ctx = loadContext(projectRoot);
|
|
6607
6737
|
const { envelope } = readSession(ctx);
|
|
@@ -6834,7 +6964,7 @@ function requirePassword2() {
|
|
|
6834
6964
|
}
|
|
6835
6965
|
function requireDurablePassword(projectRoot) {
|
|
6836
6966
|
const password = requirePassword2();
|
|
6837
|
-
const envPath =
|
|
6967
|
+
const envPath = envLocalPath11(projectRoot);
|
|
6838
6968
|
const persisted = getEnvVar(envPath, PASSWORD_ENV2);
|
|
6839
6969
|
if (!persisted) {
|
|
6840
6970
|
throw new Error(
|
|
@@ -7207,8 +7337,8 @@ ${detail}` : `error: \`twak wallet create --no-keychain\` did not produce ${wall
|
|
|
7207
7337
|
);
|
|
7208
7338
|
return cmdNewTwak(projectRoot, walletCfg);
|
|
7209
7339
|
}
|
|
7210
|
-
function cmdShow5(
|
|
7211
|
-
const projectRoot = resolveWalletProjectRoot(
|
|
7340
|
+
function cmdShow5(projectRootArg2) {
|
|
7341
|
+
const projectRoot = resolveWalletProjectRoot(projectRootArg2);
|
|
7212
7342
|
const walletCfg = loadWalletCfg(projectRoot);
|
|
7213
7343
|
const kind = walletKind(walletCfg);
|
|
7214
7344
|
if (kind === "twak") {
|
|
@@ -7269,8 +7399,8 @@ function cmdShow5(projectRootArg) {
|
|
|
7269
7399
|
}
|
|
7270
7400
|
return 0;
|
|
7271
7401
|
}
|
|
7272
|
-
function cmdList2(
|
|
7273
|
-
const projectRoot = resolveWalletProjectRoot(
|
|
7402
|
+
function cmdList2(projectRootArg2) {
|
|
7403
|
+
const projectRoot = resolveWalletProjectRoot(projectRootArg2);
|
|
7274
7404
|
const walletCfg = loadWalletCfg(projectRoot);
|
|
7275
7405
|
if (walletKind(walletCfg) === "twak") {
|
|
7276
7406
|
printOut(twakProvider(projectRoot, walletCfg).address);
|
|
@@ -7311,8 +7441,8 @@ function cmdList2(projectRootArg) {
|
|
|
7311
7441
|
}
|
|
7312
7442
|
return 0;
|
|
7313
7443
|
}
|
|
7314
|
-
async function cmdSign(msg,
|
|
7315
|
-
const projectRoot = resolveWalletProjectRoot(
|
|
7444
|
+
async function cmdSign(msg, projectRootArg2) {
|
|
7445
|
+
const projectRoot = resolveWalletProjectRoot(projectRootArg2);
|
|
7316
7446
|
const walletCfg = loadWalletCfg(projectRoot);
|
|
7317
7447
|
const kind = walletKind(walletCfg);
|
|
7318
7448
|
if (kind === "altana") {
|
|
@@ -7405,8 +7535,8 @@ async function cmdBalance(opts) {
|
|
|
7405
7535
|
}
|
|
7406
7536
|
return 0;
|
|
7407
7537
|
}
|
|
7408
|
-
function cmdPolicyShow(asJson,
|
|
7409
|
-
const projectRoot = resolveWalletProjectRoot(
|
|
7538
|
+
function cmdPolicyShow(asJson, projectRootArg2) {
|
|
7539
|
+
const projectRoot = resolveWalletProjectRoot(projectRootArg2);
|
|
7410
7540
|
const walletCfg = loadWalletCfg(projectRoot);
|
|
7411
7541
|
const kind = walletKind(walletCfg);
|
|
7412
7542
|
if (kind === "twak") {
|
|
@@ -7729,7 +7859,7 @@ function registerInit(program) {
|
|
|
7729
7859
|
).addOption(
|
|
7730
7860
|
new Option2(
|
|
7731
7861
|
"--wallet-kind <kind>",
|
|
7732
|
-
"Wallet backend for the Agent (default: evm-local = encrypted local keystore at the workspace root .studio/wallets/; CodeZip deploy). altana \u2014 encrypted local admin keystore plus a bounded runtime session
|
|
7862
|
+
"Wallet backend for the Agent (default: evm-local = encrypted local keystore at the workspace root .studio/wallets/; CodeZip deploy). altana \u2014 encrypted local admin keystore plus a bounded runtime session; deploys ship ONLY the session (ALTANA_SESSION secret). twak \u2014 FULLY SUPPORTED, opt in: Trust Wallet Agent Kit CLI, self-custody encrypted mnemonic in a PROJECT-DEDICATED home (.studio/twak); deploys as a container image."
|
|
7733
7863
|
).choices(["twak", "evm-local", "altana"])
|
|
7734
7864
|
).option(
|
|
7735
7865
|
"--twak-home <path>",
|
|
@@ -7829,6 +7959,9 @@ async function cmdInit(nameArg, opts) {
|
|
|
7829
7959
|
opts.llmProviderSource,
|
|
7830
7960
|
isTty
|
|
7831
7961
|
);
|
|
7962
|
+
if (llmProvider === null) {
|
|
7963
|
+
return 2;
|
|
7964
|
+
}
|
|
7832
7965
|
let rails = await resolveRails(opts.rails, isTty);
|
|
7833
7966
|
if (hasX402Face(faces) && rails === "8183") {
|
|
7834
7967
|
rails = "both";
|
|
@@ -8102,7 +8235,7 @@ async function cmdInit(nameArg, opts) {
|
|
|
8102
8235
|
});
|
|
8103
8236
|
}
|
|
8104
8237
|
if (destination === "platform") {
|
|
8105
|
-
printPlatformWalletSuggestion();
|
|
8238
|
+
printPlatformWalletSuggestion(walletKind2);
|
|
8106
8239
|
}
|
|
8107
8240
|
if (installFailed) {
|
|
8108
8241
|
printErr(
|
|
@@ -8208,7 +8341,7 @@ function scaffold(target, name, o) {
|
|
|
8208
8341
|
fs24.writeFileSync(path23.join(agentRoot2, ".gitignore"), renderAgentGitignore());
|
|
8209
8342
|
fs24.writeFileSync(
|
|
8210
8343
|
path23.join(agentRoot2, "README.md"),
|
|
8211
|
-
renderAgentReadme(name, o.faces, o.destination)
|
|
8344
|
+
renderAgentReadme(name, o.faces, o.destination, o.walletKind)
|
|
8212
8345
|
);
|
|
8213
8346
|
const packaging = derivePackaging(
|
|
8214
8347
|
o.walletKind,
|
|
@@ -8594,8 +8727,7 @@ function renderAgentStudioToml(name, o) {
|
|
|
8594
8727
|
[payments.erc8183]
|
|
8595
8728
|
# Read by the Agent: it quotes the FIXED \`price\`, CLAMPS it to [min,max],
|
|
8596
8729
|
# freezes a short-TTL offer, and EIP-191 signs it \u2014 pricing is rule-based, the
|
|
8597
|
-
# LLM never prices. price=0 is FREE and
|
|
8598
|
-
# ERC-8183 stack selected with all three ERC8183_*_ADDRESS overrides.
|
|
8730
|
+
# LLM never prices. price=0 is FREE and is supported by the canonical stack.
|
|
8599
8731
|
currency = "${currencyAddr}" # $U token address \u2014 prefilled from [network].default
|
|
8600
8732
|
price = "${o.erc8183Price}" # token base units; 0 = FREE (zero token escrow)
|
|
8601
8733
|
min_price = "0" # wei \u2014 clamp floor
|
|
@@ -8722,7 +8854,6 @@ function renderAgentEnvLocal(provider, storageProvider, walletKind2, rails, b402
|
|
|
8722
8854
|
"",
|
|
8723
8855
|
"# Optional ERC-8183 custom contract-stack override. Set all three",
|
|
8724
8856
|
"# together; partial overrides can mix incompatible deployments.",
|
|
8725
|
-
"# Required for price=0 while canonical contracts reject zero funding.",
|
|
8726
8857
|
"# ERC8183_COMMERCE_ADDRESS=",
|
|
8727
8858
|
"# ERC8183_ROUTER_ADDRESS=",
|
|
8728
8859
|
"# ERC8183_POLICY_ADDRESS="
|
|
@@ -8731,7 +8862,7 @@ function renderAgentEnvLocal(provider, storageProvider, walletKind2, rails, b402
|
|
|
8731
8862
|
return `${lines.join("\n")}
|
|
8732
8863
|
`;
|
|
8733
8864
|
}
|
|
8734
|
-
function renderAgentReadme(name, faces, destination) {
|
|
8865
|
+
function renderAgentReadme(name, faces, destination, walletKind2) {
|
|
8735
8866
|
const proto = faces.join(" + ");
|
|
8736
8867
|
const mode = recipeModeOf(faces);
|
|
8737
8868
|
const entry = `src/${entryStemOf(faces)}.ts`;
|
|
@@ -8770,8 +8901,7 @@ entrypoint code in \`src/signing.ts\` \u2014 never an LLM-callable tool.
|
|
|
8770
8901
|
${mode === "both" ? filesBoth : mode === "mcp" ? filesMcp : filesA2a}
|
|
8771
8902
|
${shared}
|
|
8772
8903
|
- \`.env.local\` \u2014 Agent secrets; on deploy they are sent to the **operator's**
|
|
8773
|
-
Secrets Manager (the scoped, consented commitment-#2 exception). Use a
|
|
8774
|
-
THROWAWAY testnet wallet \u2014 \`(cd app/agent && bag wallet new)\`.
|
|
8904
|
+
Secrets Manager (the scoped, consented commitment-#2 exception). ${walletKind2 === "altana" ? "Only the\n bounded session ships (as `ALTANA_SESSION`); tighten it with\n `bag wallet session grant --force` \u2014 do not create a new wallet." : "Use a\n THROWAWAY testnet wallet \u2014 `(cd app/agent && bag wallet new)`."}
|
|
8775
8905
|
|
|
8776
8906
|
## Run locally
|
|
8777
8907
|
|
|
@@ -8902,8 +9032,9 @@ async function resolveLlmProviderForWallet(walletKind2, configuredProvider, valu
|
|
|
8902
9032
|
if (explicitlyConfigured) {
|
|
8903
9033
|
if (configuredProvider === "pieverse-llm") {
|
|
8904
9034
|
printErr(
|
|
8905
|
-
"
|
|
9035
|
+
"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)."
|
|
8906
9036
|
);
|
|
9037
|
+
return null;
|
|
8907
9038
|
}
|
|
8908
9039
|
return configuredProvider;
|
|
8909
9040
|
}
|
|
@@ -9162,8 +9293,8 @@ async function runOnboarding(o) {
|
|
|
9162
9293
|
return false;
|
|
9163
9294
|
}
|
|
9164
9295
|
const agentRoot2 = path23.join(o.workspaceRoot, APP_DIR, AGENT_PKG);
|
|
9165
|
-
const { envLocalPath:
|
|
9166
|
-
setEnvVar(
|
|
9296
|
+
const { envLocalPath: envLocalPath20 } = await import("@bnbagent/studio-runtime/config");
|
|
9297
|
+
setEnvVar(envLocalPath20(agentRoot2), "WALLET_PASSWORD", password);
|
|
9167
9298
|
const savedCwd = process.cwd();
|
|
9168
9299
|
const savedPw = process.env.WALLET_PASSWORD;
|
|
9169
9300
|
let address = null;
|
|
@@ -9202,7 +9333,7 @@ async function runOnboarding(o) {
|
|
|
9202
9333
|
}
|
|
9203
9334
|
}
|
|
9204
9335
|
if (o.storageProvider !== "local") {
|
|
9205
|
-
await onboardIpfsKey(
|
|
9336
|
+
await onboardIpfsKey(envLocalPath20(agentRoot2), o.ipfsKey);
|
|
9206
9337
|
}
|
|
9207
9338
|
if (address) {
|
|
9208
9339
|
await printFaucetHint(o.network, address);
|
|
@@ -9336,8 +9467,8 @@ Guide: the bnbagent-studio-using-twak-wallet.md reference (installed by \`bag sk
|
|
|
9336
9467
|
process.chdir(savedCwd);
|
|
9337
9468
|
}
|
|
9338
9469
|
if (o.storageProvider !== "local") {
|
|
9339
|
-
const { envLocalPath:
|
|
9340
|
-
await onboardIpfsKey(
|
|
9470
|
+
const { envLocalPath: envLocalPath20 } = await import("@bnbagent/studio-runtime/config");
|
|
9471
|
+
await onboardIpfsKey(envLocalPath20(agentRoot2), o.ipfsKey);
|
|
9341
9472
|
}
|
|
9342
9473
|
if (address) {
|
|
9343
9474
|
await printFaucetHint(o.network, address);
|
|
@@ -9518,7 +9649,22 @@ NOTE \u2014 wallet.kind = "altana" (bounded runtime session):
|
|
|
9518
9649
|
\`bag wallet session grant --force\` and redeploy.`
|
|
9519
9650
|
);
|
|
9520
9651
|
}
|
|
9521
|
-
function printPlatformWalletSuggestion() {
|
|
9652
|
+
function printPlatformWalletSuggestion(walletKind2) {
|
|
9653
|
+
if (walletKind2 === "altana") {
|
|
9654
|
+
printOut(
|
|
9655
|
+
`
|
|
9656
|
+
NOTE \u2014 destination = "platform" (48h TESTNET TRIAL on the BNB Chain managed platform):
|
|
9657
|
+
\xB7 This is a sandbox, not a production seller \u2014 the runtime is auto-reclaimed at 48h.
|
|
9658
|
+
\xB7 To sign, ONLY the bounded Altana session is transmitted to the operator's
|
|
9659
|
+
Secrets Manager on deploy \u2014 the admin keystore and WALLET_PASSWORD never
|
|
9660
|
+
ship. The session is budget-limited, expiring, and on-chain revocable.
|
|
9661
|
+
\xB7 Want a smaller blast radius? Re-grant a tighter session before deploying \u2014
|
|
9662
|
+
bag wallet session grant --force --budget-u <small> --expiry-days <short>
|
|
9663
|
+
(do NOT run \`bag wallet new\`: a fresh admin keystore breaks the session's
|
|
9664
|
+
[wallet].address anchor and deploy readiness fails).`
|
|
9665
|
+
);
|
|
9666
|
+
return;
|
|
9667
|
+
}
|
|
9522
9668
|
printOut(
|
|
9523
9669
|
`
|
|
9524
9670
|
NOTE \u2014 destination = "platform" (48h TESTNET TRIAL on the BNB Chain managed platform):
|
|
@@ -9751,20 +9897,7 @@ function printNextSteps(name, provider, o = {}) {
|
|
|
9751
9897
|
}
|
|
9752
9898
|
printOut("");
|
|
9753
9899
|
let nextStep;
|
|
9754
|
-
if (provider === "pieverse-llm"
|
|
9755
|
-
printOut(
|
|
9756
|
-
" # Pieverse `bag llm activate` needs generic SIWE message signing, which"
|
|
9757
|
-
);
|
|
9758
|
-
printOut(
|
|
9759
|
-
" # Altana intentionally does not expose. Runtime paid-model credit renewal"
|
|
9760
|
-
);
|
|
9761
|
-
printOut(
|
|
9762
|
-
" # needs the same SIWE flow, so an existing key works only with auto/free."
|
|
9763
|
-
);
|
|
9764
|
-
printOut(" # Use openrouter/openai/anthropic for paid models.");
|
|
9765
|
-
printOut("");
|
|
9766
|
-
nextStep = 3;
|
|
9767
|
-
} else if (provider === "pieverse-llm") {
|
|
9900
|
+
if (provider === "pieverse-llm") {
|
|
9768
9901
|
printOut(" # 3. activate Pieverse LLM (zero-deposit by default)");
|
|
9769
9902
|
printOut(
|
|
9770
9903
|
" # SIWE login + create API key with $0 allocation. Default model"
|
|
@@ -9887,7 +10020,9 @@ function printConfigSummary(agentRoot2) {
|
|
|
9887
10020
|
const maxPrice = g(agent, "payments", "erc8183", "max_price");
|
|
9888
10021
|
const pricingState = erc8183PricingState(erc8183);
|
|
9889
10022
|
const isFreePrice = pricingState.kind === "free";
|
|
9890
|
-
const contractOverrides = erc8183ContractOverrideState(
|
|
10023
|
+
const contractOverrides = erc8183ContractOverrideState(
|
|
10024
|
+
erc8183ContractEnvForProject(agentRoot2)
|
|
10025
|
+
);
|
|
9891
10026
|
const storageKind2 = shown(g(agent, "storage", "kind"), "?");
|
|
9892
10027
|
const storageDesc = storageKind2 === "ipfs" ? "IPFS (durable, public)" : "local disk (offline dev only)";
|
|
9893
10028
|
const walletKind2 = shown(g(agent, "wallet", "kind"), "evm-local");
|
|
@@ -9987,7 +10122,7 @@ function printConfigSummary(agentRoot2) {
|
|
|
9987
10122
|
` pricing : FREE \u2014 ${weiToU(String(price))} per job; zero token escrow`
|
|
9988
10123
|
);
|
|
9989
10124
|
printOut(
|
|
9990
|
-
contractOverrides.mode === "custom" ? " contracts: custom stack selected (all three address overrides)" : " contracts:
|
|
10125
|
+
contractOverrides.mode === "custom" ? " contracts: custom stack selected (all three address overrides)" : contractOverrides.mode === "canonical" ? " contracts: canonical contract stack selected (zero-price supported)" : " contracts: custom contract overrides are incomplete or invalid; run `bag doctor`"
|
|
9991
10126
|
);
|
|
9992
10127
|
} else {
|
|
9993
10128
|
printOut(
|
|
@@ -10025,9 +10160,9 @@ function printConfigSummary(agentRoot2) {
|
|
|
10025
10160
|
if (hasErc8183 && !maxPrice && !isFreePrice) {
|
|
10026
10161
|
todo.push("[payments.erc8183].max_price \u2014 the price clamp ceiling");
|
|
10027
10162
|
}
|
|
10028
|
-
if (hasErc8183 && isFreePrice && contractOverrides.mode
|
|
10163
|
+
if (hasErc8183 && isFreePrice && (contractOverrides.mode === "partial" || contractOverrides.mode === "invalid")) {
|
|
10029
10164
|
todo.push(
|
|
10030
|
-
"ERC8183_COMMERCE_ADDRESS / ROUTER_ADDRESS / POLICY_ADDRESS \u2014
|
|
10165
|
+
"ERC8183_COMMERCE_ADDRESS / ROUTER_ADDRESS / POLICY_ADDRESS \u2014 fix or remove the incomplete custom contract override"
|
|
10031
10166
|
);
|
|
10032
10167
|
}
|
|
10033
10168
|
if (hasX402Seller && !isFreeX402) {
|
|
@@ -10293,6 +10428,17 @@ function loadEnvFileForDev(p) {
|
|
|
10293
10428
|
if (!isFile10(p)) {
|
|
10294
10429
|
return;
|
|
10295
10430
|
}
|
|
10431
|
+
const contractStackOwnedByShell = ERC8183_ADDRESS_OVERRIDE_KEYS.some(
|
|
10432
|
+
(key) => process.env[key] !== void 0
|
|
10433
|
+
);
|
|
10434
|
+
const configuredContractKeys = ERC8183_ADDRESS_OVERRIDE_KEYS.filter(
|
|
10435
|
+
(key) => Boolean(process.env[key]?.trim())
|
|
10436
|
+
);
|
|
10437
|
+
if (configuredContractKeys.length > 0 && configuredContractKeys.length < ERC8183_ADDRESS_OVERRIDE_KEYS.length) {
|
|
10438
|
+
throw new Error(
|
|
10439
|
+
`ERC-8183 contract override is incomplete; set all of ${ERC8183_ADDRESS_OVERRIDE_KEYS.join(", ")} or unset all three.`
|
|
10440
|
+
);
|
|
10441
|
+
}
|
|
10296
10442
|
for (const line of fs25.readFileSync(p, "utf-8").split(/\r?\n/)) {
|
|
10297
10443
|
if (!line || line.trimStart().startsWith("#")) {
|
|
10298
10444
|
continue;
|
|
@@ -10300,6 +10446,11 @@ function loadEnvFileForDev(p) {
|
|
|
10300
10446
|
const m = KEY_LINE_RE.exec(line);
|
|
10301
10447
|
if (m) {
|
|
10302
10448
|
const key = m[1];
|
|
10449
|
+
if (contractStackOwnedByShell && ERC8183_ADDRESS_OVERRIDE_KEYS.includes(
|
|
10450
|
+
key
|
|
10451
|
+
)) {
|
|
10452
|
+
continue;
|
|
10453
|
+
}
|
|
10303
10454
|
const eq = line.indexOf("=");
|
|
10304
10455
|
const value = eq >= 0 ? line.slice(eq + 1) : "";
|
|
10305
10456
|
if (value !== "") {
|
|
@@ -10538,8 +10689,8 @@ async function cmdDev(opts) {
|
|
|
10538
10689
|
const agentDir = path24.join(workspaceRoot, "agent");
|
|
10539
10690
|
migrateEnvLocal(agentDir);
|
|
10540
10691
|
migrateKeystoreOutOfCodelocation(agentDir);
|
|
10541
|
-
const { envLocalPath:
|
|
10542
|
-
loadEnvFileForDev(
|
|
10692
|
+
const { envLocalPath: envLocalPath20 } = await import("@bnbagent/studio-runtime/config");
|
|
10693
|
+
loadEnvFileForDev(envLocalPath20(agentDir));
|
|
10543
10694
|
ensureStoragePath(workspaceRoot);
|
|
10544
10695
|
const ipfsErr = ipfsPreflight(agentDir);
|
|
10545
10696
|
if (ipfsErr !== null) {
|
|
@@ -10784,7 +10935,7 @@ function networkBanner(agentDir) {
|
|
|
10784
10935
|
import * as fs26 from "fs";
|
|
10785
10936
|
import { createRequire } from "module";
|
|
10786
10937
|
import * as path25 from "path";
|
|
10787
|
-
import { envLocalPath as
|
|
10938
|
+
import { envLocalPath as envLocalPath12, loadStudioToml as loadStudioToml12 } from "@bnbagent/studio-runtime/config";
|
|
10788
10939
|
import { pieverseKeyHash as pieverseKeyHash2 } from "@bnbagent/studio-runtime/llm";
|
|
10789
10940
|
var AGENTCORE_DESCRIPTOR2 = "agentcore/agentcore.json";
|
|
10790
10941
|
function isFile11(p) {
|
|
@@ -10820,7 +10971,10 @@ function runtimeEnvKeys2(agentRoot2) {
|
|
|
10820
10971
|
} catch {
|
|
10821
10972
|
cfg = {};
|
|
10822
10973
|
}
|
|
10823
|
-
const
|
|
10974
|
+
const contractEnv = erc8183ContractEnvForProject(agentRoot2);
|
|
10975
|
+
const resolvable = (key) => ERC8183_ADDRESS_OVERRIDE_KEYS.includes(
|
|
10976
|
+
key
|
|
10977
|
+
) ? Boolean(contractEnv[key]) : Boolean(process.env[key] || getEnvVar(envLocalPath12(agentRoot2), key));
|
|
10824
10978
|
return runtimeEnvKeysCore(cfg, resolvable);
|
|
10825
10979
|
}
|
|
10826
10980
|
var require2 = createRequire(import.meta.url);
|
|
@@ -11040,7 +11194,7 @@ function studioIgnored(lines) {
|
|
|
11040
11194
|
}
|
|
11041
11195
|
async function checkGitignoreExcludesSecrets(root, _target) {
|
|
11042
11196
|
const out = [];
|
|
11043
|
-
const ws = path25.dirname(path25.dirname(
|
|
11197
|
+
const ws = path25.dirname(path25.dirname(envLocalPath12(root)));
|
|
11044
11198
|
const gi = path25.join(ws, ".gitignore");
|
|
11045
11199
|
const lines = gitignoreLines(gi);
|
|
11046
11200
|
if (lines === null) {
|
|
@@ -11146,7 +11300,7 @@ async function checkPieverseKeyHash(root, _target) {
|
|
|
11146
11300
|
];
|
|
11147
11301
|
}
|
|
11148
11302
|
const agentRoot2 = agentRootOf(root);
|
|
11149
|
-
const apiKey = getEnvVar(
|
|
11303
|
+
const apiKey = getEnvVar(envLocalPath12(agentRoot2), "PIEVERSE_LLM_API_KEY") || process.env.PIEVERSE_LLM_API_KEY;
|
|
11150
11304
|
if (!apiKey) return [];
|
|
11151
11305
|
const configured = String(pvCfg.key_hash).trim().toLowerCase().replace(/^0x/u, "");
|
|
11152
11306
|
const actual = pieverseKeyHash2(apiKey);
|
|
@@ -11163,10 +11317,10 @@ async function checkPieverseKeyHash(root, _target) {
|
|
|
11163
11317
|
}
|
|
11164
11318
|
];
|
|
11165
11319
|
}
|
|
11166
|
-
function erc8183RailChecks(cfg) {
|
|
11320
|
+
function erc8183RailChecks(cfg, env = process.env) {
|
|
11167
11321
|
const c2 = tableOf2(tableOf2(cfg, "payments"), "erc8183");
|
|
11168
11322
|
const out = [];
|
|
11169
|
-
const contracts = erc8183ContractOverrideState();
|
|
11323
|
+
const contracts = erc8183ContractOverrideState(env);
|
|
11170
11324
|
if (contracts.mode === "partial") {
|
|
11171
11325
|
out.push({
|
|
11172
11326
|
level: Level.CRITICAL,
|
|
@@ -11218,19 +11372,13 @@ function erc8183RailChecks(cfg) {
|
|
|
11218
11372
|
}
|
|
11219
11373
|
});
|
|
11220
11374
|
} else if (pricing.kind === "free") {
|
|
11221
|
-
if (contracts.mode === "canonical") {
|
|
11222
|
-
|
|
11223
|
-
level: Level.CRITICAL,
|
|
11224
|
-
name: "commerce_zero_price_contract_unsupported",
|
|
11225
|
-
message: "ERC-8183 pricing is FREE (zero token escrow), but the canonical contract stack rejects zero funding. Set ERC8183_COMMERCE_ADDRESS, ERC8183_ROUTER_ADDRESS, and ERC8183_POLICY_ADDRESS together to a zero-price-compatible custom stack.",
|
|
11226
|
-
details: { effective_wei: "0", contract_profile: "canonical" }
|
|
11227
|
-
});
|
|
11228
|
-
} else if (contracts.mode === "custom") {
|
|
11375
|
+
if (contracts.mode === "canonical" || contracts.mode === "custom") {
|
|
11376
|
+
const contractProfile = contracts.mode;
|
|
11229
11377
|
out.push({
|
|
11230
11378
|
level: Level.INFO,
|
|
11231
11379
|
name: "commerce_zero_price_enabled",
|
|
11232
|
-
message:
|
|
11233
|
-
details: { effective_wei: "0", contract_profile:
|
|
11380
|
+
message: `ERC-8183 pricing is FREE \u2014 buyers fund 0 token units with zero token escrow; the ${contractProfile} contract stack is selected.`,
|
|
11381
|
+
details: { effective_wei: "0", contract_profile: contractProfile }
|
|
11234
11382
|
});
|
|
11235
11383
|
}
|
|
11236
11384
|
}
|
|
@@ -11391,7 +11539,14 @@ async function checkCommerceReady(root, target) {
|
|
|
11391
11539
|
const cfg = loadAgentToml(root);
|
|
11392
11540
|
const rails = commerceRails(cfg);
|
|
11393
11541
|
const out = [];
|
|
11394
|
-
if (rails.erc8183)
|
|
11542
|
+
if (rails.erc8183) {
|
|
11543
|
+
out.push(
|
|
11544
|
+
...erc8183RailChecks(
|
|
11545
|
+
cfg,
|
|
11546
|
+
erc8183ContractEnvForProject(agentRootOf(root))
|
|
11547
|
+
)
|
|
11548
|
+
);
|
|
11549
|
+
}
|
|
11395
11550
|
const x402Checks = x402SellerRailChecks(agentRootOf(root), cfg, target);
|
|
11396
11551
|
if (!rails.erc8183 && rails.x402) {
|
|
11397
11552
|
for (const check of x402Checks) {
|
|
@@ -11496,7 +11651,7 @@ async function checkRuntimeSecretsInjected(root, target) {
|
|
|
11496
11651
|
}
|
|
11497
11652
|
const missing = needed.filter((k) => !present[k]);
|
|
11498
11653
|
if (missing.length > 0) {
|
|
11499
|
-
const envLocal =
|
|
11654
|
+
const envLocal = envLocalPath12(root);
|
|
11500
11655
|
const recoverable = missing.filter(
|
|
11501
11656
|
(k) => Boolean(process.env[k] || getEnvVar(envLocal, k))
|
|
11502
11657
|
);
|
|
@@ -11641,12 +11796,18 @@ async function checkAgentcoreQuotaHeadroom(root, target) {
|
|
|
11641
11796
|
}
|
|
11642
11797
|
];
|
|
11643
11798
|
}
|
|
11799
|
+
const quotaRunbook = `Raising ${AGENTCORE_AGENT_QUOTA_CODE} ("Total Agents per Account") is a manual AWS step \u2014 \`bag\` cannot request it for you:
|
|
11800
|
+
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.
|
|
11801
|
+
2. Check where an earlier request stands: aws service-quotas list-requested-service-quota-change-history --service-code bedrock-agentcore --region ${region}
|
|
11802
|
+
3. While the increase is pending, deploy to the managed platform instead: bag deploy --provider bnb`;
|
|
11803
|
+
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}`;
|
|
11644
11804
|
return [
|
|
11645
11805
|
{
|
|
11646
11806
|
level: Level.CRITICAL,
|
|
11647
11807
|
name: "agentcore_quota_headroom",
|
|
11648
|
-
message
|
|
11649
|
-
details
|
|
11808
|
+
message,
|
|
11809
|
+
details,
|
|
11810
|
+
fixCmd: `# raise ${AGENTCORE_AGENT_QUOTA_CODE} in the AWS Service Quotas console (manual), or deploy with: bag deploy --provider bnb`
|
|
11650
11811
|
}
|
|
11651
11812
|
];
|
|
11652
11813
|
}
|
|
@@ -11668,6 +11829,7 @@ var allChecks = [
|
|
|
11668
11829
|
checkTwakCredentialsAvailable,
|
|
11669
11830
|
checkTwakDockerAvailable,
|
|
11670
11831
|
// altana-kind checks (every one early-returns for other kinds).
|
|
11832
|
+
checkAltanaCustomContractsUnsupported,
|
|
11671
11833
|
checkAltanaSessionReady,
|
|
11672
11834
|
checkAltanaSdkResolvable,
|
|
11673
11835
|
checkAltanaSessionNotInsideAgent,
|
|
@@ -11750,7 +11912,7 @@ function readKeystoreJson(agentRoot2) {
|
|
|
11750
11912
|
function readEnvLocal(agentRoot2) {
|
|
11751
11913
|
const values = {};
|
|
11752
11914
|
try {
|
|
11753
|
-
const file =
|
|
11915
|
+
const file = envLocalPath13(agentRoot2);
|
|
11754
11916
|
if (!isFile12(file)) {
|
|
11755
11917
|
return values;
|
|
11756
11918
|
}
|
|
@@ -11778,14 +11940,19 @@ function collectRuntimeSecretsDetailed(root) {
|
|
|
11778
11940
|
const agentRoot2 = findSubProjectRoot8("agent", root) ?? root;
|
|
11779
11941
|
const secretKeys = runtimeEnvKeys2(agentRoot2);
|
|
11780
11942
|
const fileValues = readEnvLocal(agentRoot2);
|
|
11943
|
+
const contractEnv = erc8183ContractEnvForProject(agentRoot2);
|
|
11944
|
+
const contractSource = ERC8183_ADDRESS_OVERRIDE_KEYS.some((key) => process.env[key]?.trim()) ? "process.env" : ".studio/.env.local";
|
|
11781
11945
|
const payload = {};
|
|
11782
11946
|
const sources = {};
|
|
11783
11947
|
for (const k of secretKeys) {
|
|
11784
11948
|
const fromFile = fileValues[k];
|
|
11785
|
-
const
|
|
11949
|
+
const isContractOverride = ERC8183_ADDRESS_OVERRIDE_KEYS.includes(
|
|
11950
|
+
k
|
|
11951
|
+
);
|
|
11952
|
+
const v = isContractOverride ? contractEnv[k] : fromFile || process.env[k];
|
|
11786
11953
|
if (v) {
|
|
11787
11954
|
payload[k] = v;
|
|
11788
|
-
sources[k] = fromFile ? ".studio/.env.local" : "process.env";
|
|
11955
|
+
sources[k] = isContractOverride ? contractSource : fromFile ? ".studio/.env.local" : "process.env";
|
|
11789
11956
|
}
|
|
11790
11957
|
}
|
|
11791
11958
|
const walletKind2 = deployWalletKind(agentRoot2);
|
|
@@ -12219,7 +12386,7 @@ function wireCognitoOutputs(workspaceRoot, outputsFile = null) {
|
|
|
12219
12386
|
});
|
|
12220
12387
|
fs28.writeFileSync(acj, `${JSON.stringify(cfg, null, 2)}
|
|
12221
12388
|
`, "utf-8");
|
|
12222
|
-
const envLocal =
|
|
12389
|
+
const envLocal = envLocalPath14(workspaceRoot);
|
|
12223
12390
|
upsertEnv(envLocal, { OAUTH_TOKEN_URL: tokenUrl, OAUTH_SCOPE: scope });
|
|
12224
12391
|
return {
|
|
12225
12392
|
discoveryUrl: discovery,
|
|
@@ -12813,7 +12980,7 @@ import { BSC_TESTNET_FAUCET_URLS } from "@bnbagent/studio-runtime/networks";
|
|
|
12813
12980
|
import * as crypto4 from "crypto";
|
|
12814
12981
|
import * as fs34 from "fs";
|
|
12815
12982
|
import * as path33 from "path";
|
|
12816
|
-
import { envLocalPath as
|
|
12983
|
+
import { envLocalPath as envLocalPath15 } from "@bnbagent/studio-runtime/config";
|
|
12817
12984
|
import { show } from "@bnbagent/studio-runtime/erc8004";
|
|
12818
12985
|
import { DEFAULT_RPC, getNetwork as getNetwork8 } from "@bnbagent/studio-runtime/networks";
|
|
12819
12986
|
import * as walletRt3 from "@bnbagent/studio-runtime/wallet";
|
|
@@ -12958,7 +13125,7 @@ async function checkNetworkMatchesChainId(root, _target) {
|
|
|
12958
13125
|
return [];
|
|
12959
13126
|
}
|
|
12960
13127
|
async function checkRpcUrlSetForRuntime(root, _target) {
|
|
12961
|
-
const envLocal =
|
|
13128
|
+
const envLocal = envLocalPath15(root);
|
|
12962
13129
|
if (getEnvVar(envLocal, "RPC_URL")) {
|
|
12963
13130
|
return [];
|
|
12964
13131
|
}
|
|
@@ -12983,7 +13150,7 @@ async function checkRuntimeRpcReachable(root, _target) {
|
|
|
12983
13150
|
return [];
|
|
12984
13151
|
}
|
|
12985
13152
|
const expected = getNetwork8(netName).chainId;
|
|
12986
|
-
const configured = process.env.RPC_URL || getEnvVar(
|
|
13153
|
+
const configured = process.env.RPC_URL || getEnvVar(envLocalPath15(root), "RPC_URL") || "";
|
|
12987
13154
|
const rpcUrl = configured || DEFAULT_RPC[netName] || "";
|
|
12988
13155
|
if (!rpcUrl) {
|
|
12989
13156
|
return [];
|
|
@@ -13292,6 +13459,8 @@ var criticalChecks = [
|
|
|
13292
13459
|
checkPlatformLoggedIn,
|
|
13293
13460
|
checkPlatformDockerAvailable,
|
|
13294
13461
|
checkPlatformStorageEndpoint,
|
|
13462
|
+
checkTwakCustomContractsUnsupported,
|
|
13463
|
+
checkAltanaCustomContractsUnsupported,
|
|
13295
13464
|
checkLocalKeystoreExists,
|
|
13296
13465
|
checkWalletPasswordEnvSet,
|
|
13297
13466
|
checkLlmProviderKeySet,
|
|
@@ -13733,7 +13902,7 @@ async function runVerify(opts) {
|
|
|
13733
13902
|
import * as fs37 from "fs";
|
|
13734
13903
|
import * as path37 from "path";
|
|
13735
13904
|
import {
|
|
13736
|
-
envLocalPath as
|
|
13905
|
+
envLocalPath as envLocalPath16,
|
|
13737
13906
|
findSubProjectRoot as findSubProjectRoot15,
|
|
13738
13907
|
findWorkspaceRoot as findWorkspaceRoot6,
|
|
13739
13908
|
loadStudioToml as loadStudioToml19
|
|
@@ -14488,7 +14657,7 @@ function persistDeploySummary(root, text2) {
|
|
|
14488
14657
|
return null;
|
|
14489
14658
|
}
|
|
14490
14659
|
const p = path37.join(
|
|
14491
|
-
path37.dirname(
|
|
14660
|
+
path37.dirname(envLocalPath16(root)),
|
|
14492
14661
|
"last-deploy-summary.txt"
|
|
14493
14662
|
);
|
|
14494
14663
|
fs37.mkdirSync(path37.dirname(p), { recursive: true });
|
|
@@ -15123,10 +15292,10 @@ function writeAgentDeployState(workspaceRoot, arn, record = {}, destination = "s
|
|
|
15123
15292
|
patchTomlKv(tomlPath, "deploy", "oauth_discovery_url", discoveryUrl);
|
|
15124
15293
|
}
|
|
15125
15294
|
if (tokenUrl) {
|
|
15126
|
-
setEnvVar(
|
|
15295
|
+
setEnvVar(envLocalPath17(agentRoot2), "OAUTH_TOKEN_URL", tokenUrl);
|
|
15127
15296
|
}
|
|
15128
15297
|
if (scope) {
|
|
15129
|
-
setEnvVar(
|
|
15298
|
+
setEnvVar(envLocalPath17(agentRoot2), "OAUTH_SCOPE", scope);
|
|
15130
15299
|
}
|
|
15131
15300
|
syncDescriptorOauthFacts(workspaceRoot, {
|
|
15132
15301
|
tokenUrl,
|
|
@@ -15863,7 +16032,7 @@ function persistDeploySummary2(root, text2) {
|
|
|
15863
16032
|
return null;
|
|
15864
16033
|
}
|
|
15865
16034
|
const p = path38.join(
|
|
15866
|
-
path38.dirname(
|
|
16035
|
+
path38.dirname(envLocalPath17(root)),
|
|
15867
16036
|
"last-deploy-summary.txt"
|
|
15868
16037
|
);
|
|
15869
16038
|
fs38.mkdirSync(path38.dirname(p), { recursive: true });
|
|
@@ -16386,7 +16555,7 @@ import * as fs39 from "fs";
|
|
|
16386
16555
|
import * as path39 from "path";
|
|
16387
16556
|
import { EVMWalletProvider as EVMWalletProvider2 } from "@bnbagent/sdk";
|
|
16388
16557
|
import {
|
|
16389
|
-
envLocalPath as
|
|
16558
|
+
envLocalPath as envLocalPath18,
|
|
16390
16559
|
findProjectRoot as findProjectRoot4,
|
|
16391
16560
|
findStudioWorkspaceRoot as findStudioWorkspaceRoot4,
|
|
16392
16561
|
loadStudioToml as loadStudioToml21
|
|
@@ -16495,7 +16664,9 @@ async function cmdDoctor(opts) {
|
|
|
16495
16664
|
checks.push(...await checkLlm(data, projectRoot));
|
|
16496
16665
|
checks.push(...await checkNetwork(data, opts.network));
|
|
16497
16666
|
checks.push(...checkCurrency(data));
|
|
16498
|
-
checks.push(
|
|
16667
|
+
checks.push(
|
|
16668
|
+
...checkErc8183Pricing(data, erc8183ContractEnvForProject(projectRoot))
|
|
16669
|
+
);
|
|
16499
16670
|
checks.push(...checkPriceBounds(data));
|
|
16500
16671
|
checks.push(...checkX402Seller(data, projectRoot));
|
|
16501
16672
|
checks.push(...checkStorage(data));
|
|
@@ -16526,7 +16697,7 @@ function resolveProjectRoot3(argRoot) {
|
|
|
16526
16697
|
}
|
|
16527
16698
|
function runCheckEnv(projectRoot) {
|
|
16528
16699
|
const agentDir = workspaceLayers(projectRoot) ?? path39.join(projectRoot, "agent");
|
|
16529
|
-
const envPath =
|
|
16700
|
+
const envPath = envLocalPath18(agentDir);
|
|
16530
16701
|
printOut(`bag doctor --check-env: ${envPath}`);
|
|
16531
16702
|
if (!isFile17(envPath)) {
|
|
16532
16703
|
printOut(` (no ${path39.basename(envPath)} found \u2014 nothing to report)`);
|
|
@@ -16569,8 +16740,8 @@ function workspaceLayers(projectRoot) {
|
|
|
16569
16740
|
}
|
|
16570
16741
|
return null;
|
|
16571
16742
|
}
|
|
16572
|
-
function checkAppMain(
|
|
16573
|
-
let projectRoot =
|
|
16743
|
+
function checkAppMain(projectRootArg2) {
|
|
16744
|
+
let projectRoot = projectRootArg2;
|
|
16574
16745
|
const parent = path39.dirname(projectRoot);
|
|
16575
16746
|
if (isFile17(path39.join(parent, "agent", "studio.toml"))) {
|
|
16576
16747
|
projectRoot = parent;
|
|
@@ -16667,7 +16838,7 @@ async function checkWallet(projectRoot, data) {
|
|
|
16667
16838
|
return checkWalletTwak(walletCfg, projectRoot, data);
|
|
16668
16839
|
}
|
|
16669
16840
|
if (walletCfg.kind === "altana") {
|
|
16670
|
-
return checkWalletAltana(walletCfg, projectRoot);
|
|
16841
|
+
return checkWalletAltana(walletCfg, projectRoot, data);
|
|
16671
16842
|
}
|
|
16672
16843
|
if (!isLocalEvmWallet(walletCfg)) {
|
|
16673
16844
|
return [
|
|
@@ -16722,8 +16893,18 @@ async function checkWallet(projectRoot, data) {
|
|
|
16722
16893
|
}
|
|
16723
16894
|
return out;
|
|
16724
16895
|
}
|
|
16725
|
-
function checkWalletAltana(walletCfg, projectRoot) {
|
|
16896
|
+
function checkWalletAltana(walletCfg, projectRoot, data) {
|
|
16726
16897
|
const out = [];
|
|
16898
|
+
const contracts = erc8183ContractOverrideState(
|
|
16899
|
+
erc8183ContractEnvForProject(projectRoot)
|
|
16900
|
+
);
|
|
16901
|
+
if (Object.keys(tableOf14(tableOf14(data, "payments"), "erc8183")).length > 0 && contracts.mode === "custom") {
|
|
16902
|
+
out.push({
|
|
16903
|
+
name: "[wallet] Altana contract targets",
|
|
16904
|
+
status: FAIL,
|
|
16905
|
+
detail: "custom ERC-8183 targets are unsupported: this session's permissions and quote-checker approval are tied to the canonical Commerce stack. Remove the ERC8183_*_ADDRESS overrides, or use wallet.kind='evm-local'."
|
|
16906
|
+
});
|
|
16907
|
+
}
|
|
16727
16908
|
const keystoreDir = anchoredKeystoreDir(projectRoot, walletCfg);
|
|
16728
16909
|
const address = String(walletCfg.address ?? "").trim();
|
|
16729
16910
|
if (!address) {
|
|
@@ -16940,7 +17121,7 @@ async function checkLlm(data, projectRoot) {
|
|
|
16940
17121
|
}
|
|
16941
17122
|
];
|
|
16942
17123
|
}
|
|
16943
|
-
const keyValue = getEnvVar(
|
|
17124
|
+
const keyValue = getEnvVar(envLocalPath18(projectRoot), keyEnv) || process.env[keyEnv];
|
|
16944
17125
|
const out = [];
|
|
16945
17126
|
if (keyValue) {
|
|
16946
17127
|
out.push({
|
|
@@ -16956,6 +17137,14 @@ async function checkLlm(data, projectRoot) {
|
|
|
16956
17137
|
});
|
|
16957
17138
|
}
|
|
16958
17139
|
if (provider === "pieverse-llm") {
|
|
17140
|
+
const walletKind2 = String(tableOf14(data, "wallet").kind ?? "");
|
|
17141
|
+
if (walletKind2 === "altana") {
|
|
17142
|
+
out.push({
|
|
17143
|
+
name: "pieverse wallet compatibility",
|
|
17144
|
+
status: FAIL,
|
|
17145
|
+
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."
|
|
17146
|
+
});
|
|
17147
|
+
}
|
|
16959
17148
|
out.push(...await checkPieverse(data, keyValue));
|
|
16960
17149
|
}
|
|
16961
17150
|
return out;
|
|
@@ -17115,7 +17304,7 @@ function checkCurrency(data) {
|
|
|
17115
17304
|
}
|
|
17116
17305
|
return [];
|
|
17117
17306
|
}
|
|
17118
|
-
function checkErc8183Pricing(data) {
|
|
17307
|
+
function checkErc8183Pricing(data, env = process.env) {
|
|
17119
17308
|
const payValue = tableOf14(data, "payments").erc8183;
|
|
17120
17309
|
if (payValue === null || typeof payValue !== "object" || Array.isArray(payValue)) {
|
|
17121
17310
|
return [];
|
|
@@ -17149,7 +17338,7 @@ function checkErc8183Pricing(data) {
|
|
|
17149
17338
|
}
|
|
17150
17339
|
];
|
|
17151
17340
|
}
|
|
17152
|
-
const contracts = erc8183ContractOverrideState();
|
|
17341
|
+
const contracts = erc8183ContractOverrideState(env);
|
|
17153
17342
|
const priceMode = pricing.kind === "free" ? "FREE \u2014 zero token escrow" : `PAID \u2014 effective list price ${pricing.effectivePrice} token base units`;
|
|
17154
17343
|
if (contracts.mode === "partial") {
|
|
17155
17344
|
return [
|
|
@@ -17178,20 +17367,11 @@ function checkErc8183Pricing(data) {
|
|
|
17178
17367
|
}
|
|
17179
17368
|
];
|
|
17180
17369
|
}
|
|
17181
|
-
if (contracts.mode === "custom") {
|
|
17182
|
-
return [
|
|
17183
|
-
{
|
|
17184
|
-
name: "erc8183 pricing",
|
|
17185
|
-
status: PASS,
|
|
17186
|
-
detail: "FREE \u2014 zero token escrow; custom contract stack selected with all three ERC-8183 address overrides."
|
|
17187
|
-
}
|
|
17188
|
-
];
|
|
17189
|
-
}
|
|
17190
17370
|
return [
|
|
17191
17371
|
{
|
|
17192
17372
|
name: "erc8183 pricing",
|
|
17193
|
-
status:
|
|
17194
|
-
detail: "FREE \u2014 zero token escrow
|
|
17373
|
+
status: PASS,
|
|
17374
|
+
detail: contracts.mode === "custom" ? "FREE \u2014 zero token escrow; custom contract stack selected with all three ERC-8183 address overrides." : "FREE \u2014 zero token escrow; canonical contract stack selected with zero-price funding support."
|
|
17195
17375
|
}
|
|
17196
17376
|
];
|
|
17197
17377
|
}
|
|
@@ -17702,13 +17882,13 @@ function resolveEnvPath(fileArg, rootArg) {
|
|
|
17702
17882
|
if (!fs40.existsSync(path40.join(root2, "studio.toml"))) {
|
|
17703
17883
|
return [null, `error: no studio.toml under --project-root ${root2}`];
|
|
17704
17884
|
}
|
|
17705
|
-
return [
|
|
17885
|
+
return [envLocalPath2(root2), null];
|
|
17706
17886
|
}
|
|
17707
17887
|
const root = findProjectRoot();
|
|
17708
17888
|
if (root === null) {
|
|
17709
17889
|
return [".env.local", null];
|
|
17710
17890
|
}
|
|
17711
|
-
const target =
|
|
17891
|
+
const target = envLocalPath2(root);
|
|
17712
17892
|
let note = null;
|
|
17713
17893
|
if (path40.dirname(path40.dirname(target)) !== path40.resolve(process.cwd())) {
|
|
17714
17894
|
note = `\u2192 writing to ${target} (workspace .studio/, where \`bag dev\` reads)`;
|
|
@@ -19730,7 +19910,7 @@ import * as fs45 from "fs";
|
|
|
19730
19910
|
import * as path47 from "path";
|
|
19731
19911
|
import { auditedOp as auditedOp4 } from "@bnbagent/studio-runtime/audit";
|
|
19732
19912
|
import {
|
|
19733
|
-
envLocalPath as
|
|
19913
|
+
envLocalPath as envLocalPath19,
|
|
19734
19914
|
findProjectRoot as findProjectRoot6,
|
|
19735
19915
|
loadStudioToml as loadStudioToml24
|
|
19736
19916
|
} from "@bnbagent/studio-runtime/config";
|
|
@@ -20020,7 +20200,7 @@ async function cmdSellInit(priceFlag) {
|
|
|
20020
20200
|
"utf8"
|
|
20021
20201
|
);
|
|
20022
20202
|
}
|
|
20023
|
-
const envPath =
|
|
20203
|
+
const envPath = envLocalPath19(root);
|
|
20024
20204
|
for (const key of B402_ENV_KEYS) {
|
|
20025
20205
|
const existing = getEnvVar(envPath, key);
|
|
20026
20206
|
if (key === "B402_BASE_URL" && !free && resolveNetwork3(cfg).toLowerCase() === "bsc-testnet" && !process.env.B402_BASE_URL && !existing) {
|
|
@@ -20580,7 +20760,7 @@ function buildProgram() {
|
|
|
20580
20760
|
return program;
|
|
20581
20761
|
}
|
|
20582
20762
|
function cliVersion() {
|
|
20583
|
-
return "0.0.6
|
|
20763
|
+
return "0.0.6";
|
|
20584
20764
|
}
|
|
20585
20765
|
|
|
20586
20766
|
// src/cli/updateCheck.ts
|
|
@@ -20683,11 +20863,18 @@ async function main(argv) {
|
|
|
20683
20863
|
printSetupNudge();
|
|
20684
20864
|
return 0;
|
|
20685
20865
|
}
|
|
20686
|
-
|
|
20866
|
+
const explicitProjectRoot = projectRootArg(args);
|
|
20867
|
+
const releaseProjectEnv = autoloadProjectEnv(explicitProjectRoot);
|
|
20687
20868
|
if (args[0] !== "wallet") {
|
|
20869
|
+
const originalCwd = process.cwd();
|
|
20688
20870
|
try {
|
|
20871
|
+
if (explicitProjectRoot !== void 0) {
|
|
20872
|
+
process.chdir(explicitProjectRoot);
|
|
20873
|
+
}
|
|
20689
20874
|
await ensureAltanaSessionLoaded();
|
|
20690
20875
|
} catch {
|
|
20876
|
+
} finally {
|
|
20877
|
+
process.chdir(originalCwd);
|
|
20691
20878
|
}
|
|
20692
20879
|
}
|
|
20693
20880
|
maybeSyncSkills(args.find((a) => !a.startsWith("-")));
|
|
@@ -20710,7 +20897,25 @@ async function main(argv) {
|
|
|
20710
20897
|
process.stderr.write(`error: ${msg}
|
|
20711
20898
|
`);
|
|
20712
20899
|
return 1;
|
|
20900
|
+
} finally {
|
|
20901
|
+
releaseProjectEnv();
|
|
20902
|
+
}
|
|
20903
|
+
}
|
|
20904
|
+
function projectRootArg(args) {
|
|
20905
|
+
let found;
|
|
20906
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
20907
|
+
const arg = args[i];
|
|
20908
|
+
if (arg === "--") break;
|
|
20909
|
+
if (arg === "--project-root") {
|
|
20910
|
+
found = args[i + 1];
|
|
20911
|
+
i += 1;
|
|
20912
|
+
continue;
|
|
20913
|
+
}
|
|
20914
|
+
if (arg.startsWith("--project-root=")) {
|
|
20915
|
+
found = arg.slice("--project-root=".length);
|
|
20916
|
+
}
|
|
20713
20917
|
}
|
|
20918
|
+
return found;
|
|
20714
20919
|
}
|
|
20715
20920
|
function maybeSyncSkills(command) {
|
|
20716
20921
|
try {
|