@bnbagent/studio-cli 0.0.6-alpha.9 → 0.0.7
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/README.md +269 -9
- package/dist/_agentcoreName-DZDWEYD3.js +0 -0
- package/dist/_twak-4XF4H5PL.js +0 -0
- package/dist/bag.js +385 -208
- 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 +30 -13
- 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 +1 -1
- package/skills/references/bnbagent-studio-use-bnb-trial.md +1 -1
- package/skills/references/bnbagent-studio-using-altana-wallet.md +3 -2
- 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";
|
|
@@ -4823,7 +4930,7 @@ async function cmdActivate(opts) {
|
|
|
4823
4930
|
const pvCfg = loadPieverseConfig(cfg);
|
|
4824
4931
|
const replace = opts.replace === true;
|
|
4825
4932
|
let existingHash = !replace && pvCfg.key_hash ? String(pvCfg.key_hash) : null;
|
|
4826
|
-
const envFileValue = replace ? null : getEnvVar(
|
|
4933
|
+
const envFileValue = replace ? null : getEnvVar(envLocalPath10(root), PIEVERSE_ENV_KEY);
|
|
4827
4934
|
const existingEnv = replace ? null : envFileValue || process.env[PIEVERSE_ENV_KEY];
|
|
4828
4935
|
if (replace) {
|
|
4829
4936
|
printOut(
|
|
@@ -5026,7 +5133,7 @@ Retry: re-run \`bag llm activate\` \u2014 no state was persisted yet.`
|
|
|
5026
5133
|
}
|
|
5027
5134
|
const key = String(result.key);
|
|
5028
5135
|
const keyHash = String(result.hash);
|
|
5029
|
-
writeEnvLocal(PIEVERSE_ENV_KEY, key,
|
|
5136
|
+
writeEnvLocal(PIEVERSE_ENV_KEY, key, envLocalPath10(root));
|
|
5030
5137
|
updateStudioTomlSection(root, "llm.pieverse", {
|
|
5031
5138
|
key_hash: keyHash,
|
|
5032
5139
|
network: networkName
|
|
@@ -5557,7 +5664,7 @@ async function cmdRotate(opts) {
|
|
|
5557
5664
|
`warning: could not auto-disable old key \u2014 manually disable ${oldHash} in the Pieverse dashboard.`
|
|
5558
5665
|
);
|
|
5559
5666
|
}
|
|
5560
|
-
writeEnvLocal(PIEVERSE_ENV_KEY, newKey,
|
|
5667
|
+
writeEnvLocal(PIEVERSE_ENV_KEY, newKey, envLocalPath10(root));
|
|
5561
5668
|
updateStudioTomlSection(root, "llm.pieverse", {
|
|
5562
5669
|
key_hash: newHash,
|
|
5563
5670
|
network: networkName
|
|
@@ -6312,7 +6419,7 @@ import * as os3 from "os";
|
|
|
6312
6419
|
import * as path22 from "path";
|
|
6313
6420
|
import { EVMWalletProvider, SigningPolicy } from "@bnbagent/sdk";
|
|
6314
6421
|
import {
|
|
6315
|
-
envLocalPath as
|
|
6422
|
+
envLocalPath as envLocalPath11,
|
|
6316
6423
|
findProjectRoot as findProjectRoot3,
|
|
6317
6424
|
loadStudioToml as loadStudioToml10
|
|
6318
6425
|
} from "@bnbagent/studio-runtime/config";
|
|
@@ -6623,8 +6730,8 @@ async function cmdSessionGrant(opts) {
|
|
|
6623
6730
|
printOut(granted.publicKey);
|
|
6624
6731
|
return 0;
|
|
6625
6732
|
}
|
|
6626
|
-
function cmdSessionStatus(
|
|
6627
|
-
const projectRoot = resolveProjectRootArg(
|
|
6733
|
+
function cmdSessionStatus(projectRootArg2) {
|
|
6734
|
+
const projectRoot = resolveProjectRootArg(projectRootArg2);
|
|
6628
6735
|
if (projectRoot === null) return 2;
|
|
6629
6736
|
const ctx = loadContext(projectRoot);
|
|
6630
6737
|
const { envelope } = readSession(ctx);
|
|
@@ -6857,7 +6964,7 @@ function requirePassword2() {
|
|
|
6857
6964
|
}
|
|
6858
6965
|
function requireDurablePassword(projectRoot) {
|
|
6859
6966
|
const password = requirePassword2();
|
|
6860
|
-
const envPath =
|
|
6967
|
+
const envPath = envLocalPath11(projectRoot);
|
|
6861
6968
|
const persisted = getEnvVar(envPath, PASSWORD_ENV2);
|
|
6862
6969
|
if (!persisted) {
|
|
6863
6970
|
throw new Error(
|
|
@@ -7230,8 +7337,8 @@ ${detail}` : `error: \`twak wallet create --no-keychain\` did not produce ${wall
|
|
|
7230
7337
|
);
|
|
7231
7338
|
return cmdNewTwak(projectRoot, walletCfg);
|
|
7232
7339
|
}
|
|
7233
|
-
function cmdShow5(
|
|
7234
|
-
const projectRoot = resolveWalletProjectRoot(
|
|
7340
|
+
function cmdShow5(projectRootArg2) {
|
|
7341
|
+
const projectRoot = resolveWalletProjectRoot(projectRootArg2);
|
|
7235
7342
|
const walletCfg = loadWalletCfg(projectRoot);
|
|
7236
7343
|
const kind = walletKind(walletCfg);
|
|
7237
7344
|
if (kind === "twak") {
|
|
@@ -7292,8 +7399,8 @@ function cmdShow5(projectRootArg) {
|
|
|
7292
7399
|
}
|
|
7293
7400
|
return 0;
|
|
7294
7401
|
}
|
|
7295
|
-
function cmdList2(
|
|
7296
|
-
const projectRoot = resolveWalletProjectRoot(
|
|
7402
|
+
function cmdList2(projectRootArg2) {
|
|
7403
|
+
const projectRoot = resolveWalletProjectRoot(projectRootArg2);
|
|
7297
7404
|
const walletCfg = loadWalletCfg(projectRoot);
|
|
7298
7405
|
if (walletKind(walletCfg) === "twak") {
|
|
7299
7406
|
printOut(twakProvider(projectRoot, walletCfg).address);
|
|
@@ -7334,8 +7441,8 @@ function cmdList2(projectRootArg) {
|
|
|
7334
7441
|
}
|
|
7335
7442
|
return 0;
|
|
7336
7443
|
}
|
|
7337
|
-
async function cmdSign(msg,
|
|
7338
|
-
const projectRoot = resolveWalletProjectRoot(
|
|
7444
|
+
async function cmdSign(msg, projectRootArg2) {
|
|
7445
|
+
const projectRoot = resolveWalletProjectRoot(projectRootArg2);
|
|
7339
7446
|
const walletCfg = loadWalletCfg(projectRoot);
|
|
7340
7447
|
const kind = walletKind(walletCfg);
|
|
7341
7448
|
if (kind === "altana") {
|
|
@@ -7428,8 +7535,8 @@ async function cmdBalance(opts) {
|
|
|
7428
7535
|
}
|
|
7429
7536
|
return 0;
|
|
7430
7537
|
}
|
|
7431
|
-
function cmdPolicyShow(asJson,
|
|
7432
|
-
const projectRoot = resolveWalletProjectRoot(
|
|
7538
|
+
function cmdPolicyShow(asJson, projectRootArg2) {
|
|
7539
|
+
const projectRoot = resolveWalletProjectRoot(projectRootArg2);
|
|
7433
7540
|
const walletCfg = loadWalletCfg(projectRoot);
|
|
7434
7541
|
const kind = walletKind(walletCfg);
|
|
7435
7542
|
if (kind === "twak") {
|
|
@@ -7752,7 +7859,7 @@ function registerInit(program) {
|
|
|
7752
7859
|
).addOption(
|
|
7753
7860
|
new Option2(
|
|
7754
7861
|
"--wallet-kind <kind>",
|
|
7755
|
-
"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."
|
|
7756
7863
|
).choices(["twak", "evm-local", "altana"])
|
|
7757
7864
|
).option(
|
|
7758
7865
|
"--twak-home <path>",
|
|
@@ -8128,7 +8235,7 @@ async function cmdInit(nameArg, opts) {
|
|
|
8128
8235
|
});
|
|
8129
8236
|
}
|
|
8130
8237
|
if (destination === "platform") {
|
|
8131
|
-
printPlatformWalletSuggestion();
|
|
8238
|
+
printPlatformWalletSuggestion(walletKind2);
|
|
8132
8239
|
}
|
|
8133
8240
|
if (installFailed) {
|
|
8134
8241
|
printErr(
|
|
@@ -8234,7 +8341,7 @@ function scaffold(target, name, o) {
|
|
|
8234
8341
|
fs24.writeFileSync(path23.join(agentRoot2, ".gitignore"), renderAgentGitignore());
|
|
8235
8342
|
fs24.writeFileSync(
|
|
8236
8343
|
path23.join(agentRoot2, "README.md"),
|
|
8237
|
-
renderAgentReadme(name, o.faces, o.destination)
|
|
8344
|
+
renderAgentReadme(name, o.faces, o.destination, o.walletKind)
|
|
8238
8345
|
);
|
|
8239
8346
|
const packaging = derivePackaging(
|
|
8240
8347
|
o.walletKind,
|
|
@@ -8620,8 +8727,7 @@ function renderAgentStudioToml(name, o) {
|
|
|
8620
8727
|
[payments.erc8183]
|
|
8621
8728
|
# Read by the Agent: it quotes the FIXED \`price\`, CLAMPS it to [min,max],
|
|
8622
8729
|
# freezes a short-TTL offer, and EIP-191 signs it \u2014 pricing is rule-based, the
|
|
8623
|
-
# LLM never prices. price=0 is FREE and
|
|
8624
|
-
# 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.
|
|
8625
8731
|
currency = "${currencyAddr}" # $U token address \u2014 prefilled from [network].default
|
|
8626
8732
|
price = "${o.erc8183Price}" # token base units; 0 = FREE (zero token escrow)
|
|
8627
8733
|
min_price = "0" # wei \u2014 clamp floor
|
|
@@ -8748,7 +8854,6 @@ function renderAgentEnvLocal(provider, storageProvider, walletKind2, rails, b402
|
|
|
8748
8854
|
"",
|
|
8749
8855
|
"# Optional ERC-8183 custom contract-stack override. Set all three",
|
|
8750
8856
|
"# together; partial overrides can mix incompatible deployments.",
|
|
8751
|
-
"# Required for price=0 while canonical contracts reject zero funding.",
|
|
8752
8857
|
"# ERC8183_COMMERCE_ADDRESS=",
|
|
8753
8858
|
"# ERC8183_ROUTER_ADDRESS=",
|
|
8754
8859
|
"# ERC8183_POLICY_ADDRESS="
|
|
@@ -8757,7 +8862,7 @@ function renderAgentEnvLocal(provider, storageProvider, walletKind2, rails, b402
|
|
|
8757
8862
|
return `${lines.join("\n")}
|
|
8758
8863
|
`;
|
|
8759
8864
|
}
|
|
8760
|
-
function renderAgentReadme(name, faces, destination) {
|
|
8865
|
+
function renderAgentReadme(name, faces, destination, walletKind2) {
|
|
8761
8866
|
const proto = faces.join(" + ");
|
|
8762
8867
|
const mode = recipeModeOf(faces);
|
|
8763
8868
|
const entry = `src/${entryStemOf(faces)}.ts`;
|
|
@@ -8796,8 +8901,7 @@ entrypoint code in \`src/signing.ts\` \u2014 never an LLM-callable tool.
|
|
|
8796
8901
|
${mode === "both" ? filesBoth : mode === "mcp" ? filesMcp : filesA2a}
|
|
8797
8902
|
${shared}
|
|
8798
8903
|
- \`.env.local\` \u2014 Agent secrets; on deploy they are sent to the **operator's**
|
|
8799
|
-
Secrets Manager (the scoped, consented commitment-#2 exception). Use a
|
|
8800
|
-
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)`."}
|
|
8801
8905
|
|
|
8802
8906
|
## Run locally
|
|
8803
8907
|
|
|
@@ -9189,8 +9293,8 @@ async function runOnboarding(o) {
|
|
|
9189
9293
|
return false;
|
|
9190
9294
|
}
|
|
9191
9295
|
const agentRoot2 = path23.join(o.workspaceRoot, APP_DIR, AGENT_PKG);
|
|
9192
|
-
const { envLocalPath:
|
|
9193
|
-
setEnvVar(
|
|
9296
|
+
const { envLocalPath: envLocalPath20 } = await import("@bnbagent/studio-runtime/config");
|
|
9297
|
+
setEnvVar(envLocalPath20(agentRoot2), "WALLET_PASSWORD", password);
|
|
9194
9298
|
const savedCwd = process.cwd();
|
|
9195
9299
|
const savedPw = process.env.WALLET_PASSWORD;
|
|
9196
9300
|
let address = null;
|
|
@@ -9229,7 +9333,7 @@ async function runOnboarding(o) {
|
|
|
9229
9333
|
}
|
|
9230
9334
|
}
|
|
9231
9335
|
if (o.storageProvider !== "local") {
|
|
9232
|
-
await onboardIpfsKey(
|
|
9336
|
+
await onboardIpfsKey(envLocalPath20(agentRoot2), o.ipfsKey);
|
|
9233
9337
|
}
|
|
9234
9338
|
if (address) {
|
|
9235
9339
|
await printFaucetHint(o.network, address);
|
|
@@ -9363,8 +9467,8 @@ Guide: the bnbagent-studio-using-twak-wallet.md reference (installed by \`bag sk
|
|
|
9363
9467
|
process.chdir(savedCwd);
|
|
9364
9468
|
}
|
|
9365
9469
|
if (o.storageProvider !== "local") {
|
|
9366
|
-
const { envLocalPath:
|
|
9367
|
-
await onboardIpfsKey(
|
|
9470
|
+
const { envLocalPath: envLocalPath20 } = await import("@bnbagent/studio-runtime/config");
|
|
9471
|
+
await onboardIpfsKey(envLocalPath20(agentRoot2), o.ipfsKey);
|
|
9368
9472
|
}
|
|
9369
9473
|
if (address) {
|
|
9370
9474
|
await printFaucetHint(o.network, address);
|
|
@@ -9545,7 +9649,22 @@ NOTE \u2014 wallet.kind = "altana" (bounded runtime session):
|
|
|
9545
9649
|
\`bag wallet session grant --force\` and redeploy.`
|
|
9546
9650
|
);
|
|
9547
9651
|
}
|
|
9548
|
-
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
|
+
}
|
|
9549
9668
|
printOut(
|
|
9550
9669
|
`
|
|
9551
9670
|
NOTE \u2014 destination = "platform" (48h TESTNET TRIAL on the BNB Chain managed platform):
|
|
@@ -9901,7 +10020,9 @@ function printConfigSummary(agentRoot2) {
|
|
|
9901
10020
|
const maxPrice = g(agent, "payments", "erc8183", "max_price");
|
|
9902
10021
|
const pricingState = erc8183PricingState(erc8183);
|
|
9903
10022
|
const isFreePrice = pricingState.kind === "free";
|
|
9904
|
-
const contractOverrides = erc8183ContractOverrideState(
|
|
10023
|
+
const contractOverrides = erc8183ContractOverrideState(
|
|
10024
|
+
erc8183ContractEnvForProject(agentRoot2)
|
|
10025
|
+
);
|
|
9905
10026
|
const storageKind2 = shown(g(agent, "storage", "kind"), "?");
|
|
9906
10027
|
const storageDesc = storageKind2 === "ipfs" ? "IPFS (durable, public)" : "local disk (offline dev only)";
|
|
9907
10028
|
const walletKind2 = shown(g(agent, "wallet", "kind"), "evm-local");
|
|
@@ -10001,7 +10122,7 @@ function printConfigSummary(agentRoot2) {
|
|
|
10001
10122
|
` pricing : FREE \u2014 ${weiToU(String(price))} per job; zero token escrow`
|
|
10002
10123
|
);
|
|
10003
10124
|
printOut(
|
|
10004
|
-
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`"
|
|
10005
10126
|
);
|
|
10006
10127
|
} else {
|
|
10007
10128
|
printOut(
|
|
@@ -10039,9 +10160,9 @@ function printConfigSummary(agentRoot2) {
|
|
|
10039
10160
|
if (hasErc8183 && !maxPrice && !isFreePrice) {
|
|
10040
10161
|
todo.push("[payments.erc8183].max_price \u2014 the price clamp ceiling");
|
|
10041
10162
|
}
|
|
10042
|
-
if (hasErc8183 && isFreePrice && contractOverrides.mode
|
|
10163
|
+
if (hasErc8183 && isFreePrice && (contractOverrides.mode === "partial" || contractOverrides.mode === "invalid")) {
|
|
10043
10164
|
todo.push(
|
|
10044
|
-
"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"
|
|
10045
10166
|
);
|
|
10046
10167
|
}
|
|
10047
10168
|
if (hasX402Seller && !isFreeX402) {
|
|
@@ -10307,6 +10428,17 @@ function loadEnvFileForDev(p) {
|
|
|
10307
10428
|
if (!isFile10(p)) {
|
|
10308
10429
|
return;
|
|
10309
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
|
+
}
|
|
10310
10442
|
for (const line of fs25.readFileSync(p, "utf-8").split(/\r?\n/)) {
|
|
10311
10443
|
if (!line || line.trimStart().startsWith("#")) {
|
|
10312
10444
|
continue;
|
|
@@ -10314,6 +10446,11 @@ function loadEnvFileForDev(p) {
|
|
|
10314
10446
|
const m = KEY_LINE_RE.exec(line);
|
|
10315
10447
|
if (m) {
|
|
10316
10448
|
const key = m[1];
|
|
10449
|
+
if (contractStackOwnedByShell && ERC8183_ADDRESS_OVERRIDE_KEYS.includes(
|
|
10450
|
+
key
|
|
10451
|
+
)) {
|
|
10452
|
+
continue;
|
|
10453
|
+
}
|
|
10317
10454
|
const eq = line.indexOf("=");
|
|
10318
10455
|
const value = eq >= 0 ? line.slice(eq + 1) : "";
|
|
10319
10456
|
if (value !== "") {
|
|
@@ -10552,8 +10689,8 @@ async function cmdDev(opts) {
|
|
|
10552
10689
|
const agentDir = path24.join(workspaceRoot, "agent");
|
|
10553
10690
|
migrateEnvLocal(agentDir);
|
|
10554
10691
|
migrateKeystoreOutOfCodelocation(agentDir);
|
|
10555
|
-
const { envLocalPath:
|
|
10556
|
-
loadEnvFileForDev(
|
|
10692
|
+
const { envLocalPath: envLocalPath20 } = await import("@bnbagent/studio-runtime/config");
|
|
10693
|
+
loadEnvFileForDev(envLocalPath20(agentDir));
|
|
10557
10694
|
ensureStoragePath(workspaceRoot);
|
|
10558
10695
|
const ipfsErr = ipfsPreflight(agentDir);
|
|
10559
10696
|
if (ipfsErr !== null) {
|
|
@@ -10798,7 +10935,7 @@ function networkBanner(agentDir) {
|
|
|
10798
10935
|
import * as fs26 from "fs";
|
|
10799
10936
|
import { createRequire } from "module";
|
|
10800
10937
|
import * as path25 from "path";
|
|
10801
|
-
import { envLocalPath as
|
|
10938
|
+
import { envLocalPath as envLocalPath12, loadStudioToml as loadStudioToml12 } from "@bnbagent/studio-runtime/config";
|
|
10802
10939
|
import { pieverseKeyHash as pieverseKeyHash2 } from "@bnbagent/studio-runtime/llm";
|
|
10803
10940
|
var AGENTCORE_DESCRIPTOR2 = "agentcore/agentcore.json";
|
|
10804
10941
|
function isFile11(p) {
|
|
@@ -10834,7 +10971,10 @@ function runtimeEnvKeys2(agentRoot2) {
|
|
|
10834
10971
|
} catch {
|
|
10835
10972
|
cfg = {};
|
|
10836
10973
|
}
|
|
10837
|
-
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));
|
|
10838
10978
|
return runtimeEnvKeysCore(cfg, resolvable);
|
|
10839
10979
|
}
|
|
10840
10980
|
var require2 = createRequire(import.meta.url);
|
|
@@ -11054,7 +11194,7 @@ function studioIgnored(lines) {
|
|
|
11054
11194
|
}
|
|
11055
11195
|
async function checkGitignoreExcludesSecrets(root, _target) {
|
|
11056
11196
|
const out = [];
|
|
11057
|
-
const ws = path25.dirname(path25.dirname(
|
|
11197
|
+
const ws = path25.dirname(path25.dirname(envLocalPath12(root)));
|
|
11058
11198
|
const gi = path25.join(ws, ".gitignore");
|
|
11059
11199
|
const lines = gitignoreLines(gi);
|
|
11060
11200
|
if (lines === null) {
|
|
@@ -11160,7 +11300,7 @@ async function checkPieverseKeyHash(root, _target) {
|
|
|
11160
11300
|
];
|
|
11161
11301
|
}
|
|
11162
11302
|
const agentRoot2 = agentRootOf(root);
|
|
11163
|
-
const apiKey = getEnvVar(
|
|
11303
|
+
const apiKey = getEnvVar(envLocalPath12(agentRoot2), "PIEVERSE_LLM_API_KEY") || process.env.PIEVERSE_LLM_API_KEY;
|
|
11164
11304
|
if (!apiKey) return [];
|
|
11165
11305
|
const configured = String(pvCfg.key_hash).trim().toLowerCase().replace(/^0x/u, "");
|
|
11166
11306
|
const actual = pieverseKeyHash2(apiKey);
|
|
@@ -11177,10 +11317,10 @@ async function checkPieverseKeyHash(root, _target) {
|
|
|
11177
11317
|
}
|
|
11178
11318
|
];
|
|
11179
11319
|
}
|
|
11180
|
-
function erc8183RailChecks(cfg) {
|
|
11320
|
+
function erc8183RailChecks(cfg, env = process.env) {
|
|
11181
11321
|
const c2 = tableOf2(tableOf2(cfg, "payments"), "erc8183");
|
|
11182
11322
|
const out = [];
|
|
11183
|
-
const contracts = erc8183ContractOverrideState();
|
|
11323
|
+
const contracts = erc8183ContractOverrideState(env);
|
|
11184
11324
|
if (contracts.mode === "partial") {
|
|
11185
11325
|
out.push({
|
|
11186
11326
|
level: Level.CRITICAL,
|
|
@@ -11232,19 +11372,13 @@ function erc8183RailChecks(cfg) {
|
|
|
11232
11372
|
}
|
|
11233
11373
|
});
|
|
11234
11374
|
} else if (pricing.kind === "free") {
|
|
11235
|
-
if (contracts.mode === "canonical") {
|
|
11236
|
-
|
|
11237
|
-
level: Level.CRITICAL,
|
|
11238
|
-
name: "commerce_zero_price_contract_unsupported",
|
|
11239
|
-
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.",
|
|
11240
|
-
details: { effective_wei: "0", contract_profile: "canonical" }
|
|
11241
|
-
});
|
|
11242
|
-
} else if (contracts.mode === "custom") {
|
|
11375
|
+
if (contracts.mode === "canonical" || contracts.mode === "custom") {
|
|
11376
|
+
const contractProfile = contracts.mode;
|
|
11243
11377
|
out.push({
|
|
11244
11378
|
level: Level.INFO,
|
|
11245
11379
|
name: "commerce_zero_price_enabled",
|
|
11246
|
-
message:
|
|
11247
|
-
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 }
|
|
11248
11382
|
});
|
|
11249
11383
|
}
|
|
11250
11384
|
}
|
|
@@ -11405,7 +11539,14 @@ async function checkCommerceReady(root, target) {
|
|
|
11405
11539
|
const cfg = loadAgentToml(root);
|
|
11406
11540
|
const rails = commerceRails(cfg);
|
|
11407
11541
|
const out = [];
|
|
11408
|
-
if (rails.erc8183)
|
|
11542
|
+
if (rails.erc8183) {
|
|
11543
|
+
out.push(
|
|
11544
|
+
...erc8183RailChecks(
|
|
11545
|
+
cfg,
|
|
11546
|
+
erc8183ContractEnvForProject(agentRootOf(root))
|
|
11547
|
+
)
|
|
11548
|
+
);
|
|
11549
|
+
}
|
|
11409
11550
|
const x402Checks = x402SellerRailChecks(agentRootOf(root), cfg, target);
|
|
11410
11551
|
if (!rails.erc8183 && rails.x402) {
|
|
11411
11552
|
for (const check of x402Checks) {
|
|
@@ -11510,7 +11651,7 @@ async function checkRuntimeSecretsInjected(root, target) {
|
|
|
11510
11651
|
}
|
|
11511
11652
|
const missing = needed.filter((k) => !present[k]);
|
|
11512
11653
|
if (missing.length > 0) {
|
|
11513
|
-
const envLocal =
|
|
11654
|
+
const envLocal = envLocalPath12(root);
|
|
11514
11655
|
const recoverable = missing.filter(
|
|
11515
11656
|
(k) => Boolean(process.env[k] || getEnvVar(envLocal, k))
|
|
11516
11657
|
);
|
|
@@ -11688,6 +11829,7 @@ var allChecks = [
|
|
|
11688
11829
|
checkTwakCredentialsAvailable,
|
|
11689
11830
|
checkTwakDockerAvailable,
|
|
11690
11831
|
// altana-kind checks (every one early-returns for other kinds).
|
|
11832
|
+
checkAltanaCustomContractsUnsupported,
|
|
11691
11833
|
checkAltanaSessionReady,
|
|
11692
11834
|
checkAltanaSdkResolvable,
|
|
11693
11835
|
checkAltanaSessionNotInsideAgent,
|
|
@@ -11770,7 +11912,7 @@ function readKeystoreJson(agentRoot2) {
|
|
|
11770
11912
|
function readEnvLocal(agentRoot2) {
|
|
11771
11913
|
const values = {};
|
|
11772
11914
|
try {
|
|
11773
|
-
const file =
|
|
11915
|
+
const file = envLocalPath13(agentRoot2);
|
|
11774
11916
|
if (!isFile12(file)) {
|
|
11775
11917
|
return values;
|
|
11776
11918
|
}
|
|
@@ -11798,14 +11940,19 @@ function collectRuntimeSecretsDetailed(root) {
|
|
|
11798
11940
|
const agentRoot2 = findSubProjectRoot8("agent", root) ?? root;
|
|
11799
11941
|
const secretKeys = runtimeEnvKeys2(agentRoot2);
|
|
11800
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";
|
|
11801
11945
|
const payload = {};
|
|
11802
11946
|
const sources = {};
|
|
11803
11947
|
for (const k of secretKeys) {
|
|
11804
11948
|
const fromFile = fileValues[k];
|
|
11805
|
-
const
|
|
11949
|
+
const isContractOverride = ERC8183_ADDRESS_OVERRIDE_KEYS.includes(
|
|
11950
|
+
k
|
|
11951
|
+
);
|
|
11952
|
+
const v = isContractOverride ? contractEnv[k] : fromFile || process.env[k];
|
|
11806
11953
|
if (v) {
|
|
11807
11954
|
payload[k] = v;
|
|
11808
|
-
sources[k] = fromFile ? ".studio/.env.local" : "process.env";
|
|
11955
|
+
sources[k] = isContractOverride ? contractSource : fromFile ? ".studio/.env.local" : "process.env";
|
|
11809
11956
|
}
|
|
11810
11957
|
}
|
|
11811
11958
|
const walletKind2 = deployWalletKind(agentRoot2);
|
|
@@ -12239,7 +12386,7 @@ function wireCognitoOutputs(workspaceRoot, outputsFile = null) {
|
|
|
12239
12386
|
});
|
|
12240
12387
|
fs28.writeFileSync(acj, `${JSON.stringify(cfg, null, 2)}
|
|
12241
12388
|
`, "utf-8");
|
|
12242
|
-
const envLocal =
|
|
12389
|
+
const envLocal = envLocalPath14(workspaceRoot);
|
|
12243
12390
|
upsertEnv(envLocal, { OAUTH_TOKEN_URL: tokenUrl, OAUTH_SCOPE: scope });
|
|
12244
12391
|
return {
|
|
12245
12392
|
discoveryUrl: discovery,
|
|
@@ -12833,7 +12980,7 @@ import { BSC_TESTNET_FAUCET_URLS } from "@bnbagent/studio-runtime/networks";
|
|
|
12833
12980
|
import * as crypto4 from "crypto";
|
|
12834
12981
|
import * as fs34 from "fs";
|
|
12835
12982
|
import * as path33 from "path";
|
|
12836
|
-
import { envLocalPath as
|
|
12983
|
+
import { envLocalPath as envLocalPath15 } from "@bnbagent/studio-runtime/config";
|
|
12837
12984
|
import { show } from "@bnbagent/studio-runtime/erc8004";
|
|
12838
12985
|
import { DEFAULT_RPC, getNetwork as getNetwork8 } from "@bnbagent/studio-runtime/networks";
|
|
12839
12986
|
import * as walletRt3 from "@bnbagent/studio-runtime/wallet";
|
|
@@ -12978,7 +13125,7 @@ async function checkNetworkMatchesChainId(root, _target) {
|
|
|
12978
13125
|
return [];
|
|
12979
13126
|
}
|
|
12980
13127
|
async function checkRpcUrlSetForRuntime(root, _target) {
|
|
12981
|
-
const envLocal =
|
|
13128
|
+
const envLocal = envLocalPath15(root);
|
|
12982
13129
|
if (getEnvVar(envLocal, "RPC_URL")) {
|
|
12983
13130
|
return [];
|
|
12984
13131
|
}
|
|
@@ -13003,7 +13150,7 @@ async function checkRuntimeRpcReachable(root, _target) {
|
|
|
13003
13150
|
return [];
|
|
13004
13151
|
}
|
|
13005
13152
|
const expected = getNetwork8(netName).chainId;
|
|
13006
|
-
const configured = process.env.RPC_URL || getEnvVar(
|
|
13153
|
+
const configured = process.env.RPC_URL || getEnvVar(envLocalPath15(root), "RPC_URL") || "";
|
|
13007
13154
|
const rpcUrl = configured || DEFAULT_RPC[netName] || "";
|
|
13008
13155
|
if (!rpcUrl) {
|
|
13009
13156
|
return [];
|
|
@@ -13312,6 +13459,8 @@ var criticalChecks = [
|
|
|
13312
13459
|
checkPlatformLoggedIn,
|
|
13313
13460
|
checkPlatformDockerAvailable,
|
|
13314
13461
|
checkPlatformStorageEndpoint,
|
|
13462
|
+
checkTwakCustomContractsUnsupported,
|
|
13463
|
+
checkAltanaCustomContractsUnsupported,
|
|
13315
13464
|
checkLocalKeystoreExists,
|
|
13316
13465
|
checkWalletPasswordEnvSet,
|
|
13317
13466
|
checkLlmProviderKeySet,
|
|
@@ -13753,7 +13902,7 @@ async function runVerify(opts) {
|
|
|
13753
13902
|
import * as fs37 from "fs";
|
|
13754
13903
|
import * as path37 from "path";
|
|
13755
13904
|
import {
|
|
13756
|
-
envLocalPath as
|
|
13905
|
+
envLocalPath as envLocalPath16,
|
|
13757
13906
|
findSubProjectRoot as findSubProjectRoot15,
|
|
13758
13907
|
findWorkspaceRoot as findWorkspaceRoot6,
|
|
13759
13908
|
loadStudioToml as loadStudioToml19
|
|
@@ -14508,7 +14657,7 @@ function persistDeploySummary(root, text2) {
|
|
|
14508
14657
|
return null;
|
|
14509
14658
|
}
|
|
14510
14659
|
const p = path37.join(
|
|
14511
|
-
path37.dirname(
|
|
14660
|
+
path37.dirname(envLocalPath16(root)),
|
|
14512
14661
|
"last-deploy-summary.txt"
|
|
14513
14662
|
);
|
|
14514
14663
|
fs37.mkdirSync(path37.dirname(p), { recursive: true });
|
|
@@ -15143,10 +15292,10 @@ function writeAgentDeployState(workspaceRoot, arn, record = {}, destination = "s
|
|
|
15143
15292
|
patchTomlKv(tomlPath, "deploy", "oauth_discovery_url", discoveryUrl);
|
|
15144
15293
|
}
|
|
15145
15294
|
if (tokenUrl) {
|
|
15146
|
-
setEnvVar(
|
|
15295
|
+
setEnvVar(envLocalPath17(agentRoot2), "OAUTH_TOKEN_URL", tokenUrl);
|
|
15147
15296
|
}
|
|
15148
15297
|
if (scope) {
|
|
15149
|
-
setEnvVar(
|
|
15298
|
+
setEnvVar(envLocalPath17(agentRoot2), "OAUTH_SCOPE", scope);
|
|
15150
15299
|
}
|
|
15151
15300
|
syncDescriptorOauthFacts(workspaceRoot, {
|
|
15152
15301
|
tokenUrl,
|
|
@@ -15883,7 +16032,7 @@ function persistDeploySummary2(root, text2) {
|
|
|
15883
16032
|
return null;
|
|
15884
16033
|
}
|
|
15885
16034
|
const p = path38.join(
|
|
15886
|
-
path38.dirname(
|
|
16035
|
+
path38.dirname(envLocalPath17(root)),
|
|
15887
16036
|
"last-deploy-summary.txt"
|
|
15888
16037
|
);
|
|
15889
16038
|
fs38.mkdirSync(path38.dirname(p), { recursive: true });
|
|
@@ -16406,7 +16555,7 @@ import * as fs39 from "fs";
|
|
|
16406
16555
|
import * as path39 from "path";
|
|
16407
16556
|
import { EVMWalletProvider as EVMWalletProvider2 } from "@bnbagent/sdk";
|
|
16408
16557
|
import {
|
|
16409
|
-
envLocalPath as
|
|
16558
|
+
envLocalPath as envLocalPath18,
|
|
16410
16559
|
findProjectRoot as findProjectRoot4,
|
|
16411
16560
|
findStudioWorkspaceRoot as findStudioWorkspaceRoot4,
|
|
16412
16561
|
loadStudioToml as loadStudioToml21
|
|
@@ -16515,7 +16664,9 @@ async function cmdDoctor(opts) {
|
|
|
16515
16664
|
checks.push(...await checkLlm(data, projectRoot));
|
|
16516
16665
|
checks.push(...await checkNetwork(data, opts.network));
|
|
16517
16666
|
checks.push(...checkCurrency(data));
|
|
16518
|
-
checks.push(
|
|
16667
|
+
checks.push(
|
|
16668
|
+
...checkErc8183Pricing(data, erc8183ContractEnvForProject(projectRoot))
|
|
16669
|
+
);
|
|
16519
16670
|
checks.push(...checkPriceBounds(data));
|
|
16520
16671
|
checks.push(...checkX402Seller(data, projectRoot));
|
|
16521
16672
|
checks.push(...checkStorage(data));
|
|
@@ -16546,7 +16697,7 @@ function resolveProjectRoot3(argRoot) {
|
|
|
16546
16697
|
}
|
|
16547
16698
|
function runCheckEnv(projectRoot) {
|
|
16548
16699
|
const agentDir = workspaceLayers(projectRoot) ?? path39.join(projectRoot, "agent");
|
|
16549
|
-
const envPath =
|
|
16700
|
+
const envPath = envLocalPath18(agentDir);
|
|
16550
16701
|
printOut(`bag doctor --check-env: ${envPath}`);
|
|
16551
16702
|
if (!isFile17(envPath)) {
|
|
16552
16703
|
printOut(` (no ${path39.basename(envPath)} found \u2014 nothing to report)`);
|
|
@@ -16589,8 +16740,8 @@ function workspaceLayers(projectRoot) {
|
|
|
16589
16740
|
}
|
|
16590
16741
|
return null;
|
|
16591
16742
|
}
|
|
16592
|
-
function checkAppMain(
|
|
16593
|
-
let projectRoot =
|
|
16743
|
+
function checkAppMain(projectRootArg2) {
|
|
16744
|
+
let projectRoot = projectRootArg2;
|
|
16594
16745
|
const parent = path39.dirname(projectRoot);
|
|
16595
16746
|
if (isFile17(path39.join(parent, "agent", "studio.toml"))) {
|
|
16596
16747
|
projectRoot = parent;
|
|
@@ -16687,7 +16838,7 @@ async function checkWallet(projectRoot, data) {
|
|
|
16687
16838
|
return checkWalletTwak(walletCfg, projectRoot, data);
|
|
16688
16839
|
}
|
|
16689
16840
|
if (walletCfg.kind === "altana") {
|
|
16690
|
-
return checkWalletAltana(walletCfg, projectRoot);
|
|
16841
|
+
return checkWalletAltana(walletCfg, projectRoot, data);
|
|
16691
16842
|
}
|
|
16692
16843
|
if (!isLocalEvmWallet(walletCfg)) {
|
|
16693
16844
|
return [
|
|
@@ -16742,8 +16893,18 @@ async function checkWallet(projectRoot, data) {
|
|
|
16742
16893
|
}
|
|
16743
16894
|
return out;
|
|
16744
16895
|
}
|
|
16745
|
-
function checkWalletAltana(walletCfg, projectRoot) {
|
|
16896
|
+
function checkWalletAltana(walletCfg, projectRoot, data) {
|
|
16746
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
|
+
}
|
|
16747
16908
|
const keystoreDir = anchoredKeystoreDir(projectRoot, walletCfg);
|
|
16748
16909
|
const address = String(walletCfg.address ?? "").trim();
|
|
16749
16910
|
if (!address) {
|
|
@@ -16960,7 +17121,7 @@ async function checkLlm(data, projectRoot) {
|
|
|
16960
17121
|
}
|
|
16961
17122
|
];
|
|
16962
17123
|
}
|
|
16963
|
-
const keyValue = getEnvVar(
|
|
17124
|
+
const keyValue = getEnvVar(envLocalPath18(projectRoot), keyEnv) || process.env[keyEnv];
|
|
16964
17125
|
const out = [];
|
|
16965
17126
|
if (keyValue) {
|
|
16966
17127
|
out.push({
|
|
@@ -17143,7 +17304,7 @@ function checkCurrency(data) {
|
|
|
17143
17304
|
}
|
|
17144
17305
|
return [];
|
|
17145
17306
|
}
|
|
17146
|
-
function checkErc8183Pricing(data) {
|
|
17307
|
+
function checkErc8183Pricing(data, env = process.env) {
|
|
17147
17308
|
const payValue = tableOf14(data, "payments").erc8183;
|
|
17148
17309
|
if (payValue === null || typeof payValue !== "object" || Array.isArray(payValue)) {
|
|
17149
17310
|
return [];
|
|
@@ -17177,7 +17338,7 @@ function checkErc8183Pricing(data) {
|
|
|
17177
17338
|
}
|
|
17178
17339
|
];
|
|
17179
17340
|
}
|
|
17180
|
-
const contracts = erc8183ContractOverrideState();
|
|
17341
|
+
const contracts = erc8183ContractOverrideState(env);
|
|
17181
17342
|
const priceMode = pricing.kind === "free" ? "FREE \u2014 zero token escrow" : `PAID \u2014 effective list price ${pricing.effectivePrice} token base units`;
|
|
17182
17343
|
if (contracts.mode === "partial") {
|
|
17183
17344
|
return [
|
|
@@ -17206,20 +17367,11 @@ function checkErc8183Pricing(data) {
|
|
|
17206
17367
|
}
|
|
17207
17368
|
];
|
|
17208
17369
|
}
|
|
17209
|
-
if (contracts.mode === "custom") {
|
|
17210
|
-
return [
|
|
17211
|
-
{
|
|
17212
|
-
name: "erc8183 pricing",
|
|
17213
|
-
status: PASS,
|
|
17214
|
-
detail: "FREE \u2014 zero token escrow; custom contract stack selected with all three ERC-8183 address overrides."
|
|
17215
|
-
}
|
|
17216
|
-
];
|
|
17217
|
-
}
|
|
17218
17370
|
return [
|
|
17219
17371
|
{
|
|
17220
17372
|
name: "erc8183 pricing",
|
|
17221
|
-
status:
|
|
17222
|
-
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."
|
|
17223
17375
|
}
|
|
17224
17376
|
];
|
|
17225
17377
|
}
|
|
@@ -17730,13 +17882,13 @@ function resolveEnvPath(fileArg, rootArg) {
|
|
|
17730
17882
|
if (!fs40.existsSync(path40.join(root2, "studio.toml"))) {
|
|
17731
17883
|
return [null, `error: no studio.toml under --project-root ${root2}`];
|
|
17732
17884
|
}
|
|
17733
|
-
return [
|
|
17885
|
+
return [envLocalPath2(root2), null];
|
|
17734
17886
|
}
|
|
17735
17887
|
const root = findProjectRoot();
|
|
17736
17888
|
if (root === null) {
|
|
17737
17889
|
return [".env.local", null];
|
|
17738
17890
|
}
|
|
17739
|
-
const target =
|
|
17891
|
+
const target = envLocalPath2(root);
|
|
17740
17892
|
let note = null;
|
|
17741
17893
|
if (path40.dirname(path40.dirname(target)) !== path40.resolve(process.cwd())) {
|
|
17742
17894
|
note = `\u2192 writing to ${target} (workspace .studio/, where \`bag dev\` reads)`;
|
|
@@ -19758,7 +19910,7 @@ import * as fs45 from "fs";
|
|
|
19758
19910
|
import * as path47 from "path";
|
|
19759
19911
|
import { auditedOp as auditedOp4 } from "@bnbagent/studio-runtime/audit";
|
|
19760
19912
|
import {
|
|
19761
|
-
envLocalPath as
|
|
19913
|
+
envLocalPath as envLocalPath19,
|
|
19762
19914
|
findProjectRoot as findProjectRoot6,
|
|
19763
19915
|
loadStudioToml as loadStudioToml24
|
|
19764
19916
|
} from "@bnbagent/studio-runtime/config";
|
|
@@ -20048,7 +20200,7 @@ async function cmdSellInit(priceFlag) {
|
|
|
20048
20200
|
"utf8"
|
|
20049
20201
|
);
|
|
20050
20202
|
}
|
|
20051
|
-
const envPath =
|
|
20203
|
+
const envPath = envLocalPath19(root);
|
|
20052
20204
|
for (const key of B402_ENV_KEYS) {
|
|
20053
20205
|
const existing = getEnvVar(envPath, key);
|
|
20054
20206
|
if (key === "B402_BASE_URL" && !free && resolveNetwork3(cfg).toLowerCase() === "bsc-testnet" && !process.env.B402_BASE_URL && !existing) {
|
|
@@ -20608,7 +20760,7 @@ function buildProgram() {
|
|
|
20608
20760
|
return program;
|
|
20609
20761
|
}
|
|
20610
20762
|
function cliVersion() {
|
|
20611
|
-
return "0.0.6
|
|
20763
|
+
return "0.0.6";
|
|
20612
20764
|
}
|
|
20613
20765
|
|
|
20614
20766
|
// src/cli/updateCheck.ts
|
|
@@ -20711,11 +20863,18 @@ async function main(argv) {
|
|
|
20711
20863
|
printSetupNudge();
|
|
20712
20864
|
return 0;
|
|
20713
20865
|
}
|
|
20714
|
-
|
|
20866
|
+
const explicitProjectRoot = projectRootArg(args);
|
|
20867
|
+
const releaseProjectEnv = autoloadProjectEnv(explicitProjectRoot);
|
|
20715
20868
|
if (args[0] !== "wallet") {
|
|
20869
|
+
const originalCwd = process.cwd();
|
|
20716
20870
|
try {
|
|
20871
|
+
if (explicitProjectRoot !== void 0) {
|
|
20872
|
+
process.chdir(explicitProjectRoot);
|
|
20873
|
+
}
|
|
20717
20874
|
await ensureAltanaSessionLoaded();
|
|
20718
20875
|
} catch {
|
|
20876
|
+
} finally {
|
|
20877
|
+
process.chdir(originalCwd);
|
|
20719
20878
|
}
|
|
20720
20879
|
}
|
|
20721
20880
|
maybeSyncSkills(args.find((a) => !a.startsWith("-")));
|
|
@@ -20738,8 +20897,26 @@ async function main(argv) {
|
|
|
20738
20897
|
process.stderr.write(`error: ${msg}
|
|
20739
20898
|
`);
|
|
20740
20899
|
return 1;
|
|
20900
|
+
} finally {
|
|
20901
|
+
releaseProjectEnv();
|
|
20741
20902
|
}
|
|
20742
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
|
+
}
|
|
20917
|
+
}
|
|
20918
|
+
return found;
|
|
20919
|
+
}
|
|
20743
20920
|
function maybeSyncSkills(command) {
|
|
20744
20921
|
try {
|
|
20745
20922
|
if (process.env.BAG_NO_SKILL_SYNC) {
|