@snowyroad/braid 0.75.0 → 0.76.0

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.
@@ -372,7 +372,7 @@ var InviteExpiredError = class extends Error {
372
372
  }
373
373
  };
374
374
  async function redeemInvite(relayHttpUrl, code) {
375
- const { boundedJsonFetch: boundedJsonFetch2 } = await import("./http-SP27G4XU.js");
375
+ const { boundedJsonFetch: boundedJsonFetch2 } = await import("./http-YQS643AJ.js");
376
376
  const r = await boundedJsonFetch2(`${relayHttpUrl.replace(/\/$/, "")}/invites/redeem`, {
377
377
  method: "POST",
378
378
  headers: { "content-type": "application/json" },
@@ -401,7 +401,7 @@ async function redeemInvite(relayHttpUrl, code) {
401
401
 
402
402
  // src/config.ts
403
403
  import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2 } from "fs";
404
- import { dirname as dirname2, join as join3 } from "path";
404
+ import { dirname as dirname2, join as join4 } from "path";
405
405
  import { homedir as homedir4 } from "os";
406
406
 
407
407
  // src/keystore.ts
@@ -461,7 +461,7 @@ function validateReplacementToken(newToken, currentToken, nowMs = Date.now()) {
461
461
  return { ok: true };
462
462
  }
463
463
  async function mintAccessToken(relayHttpUrl, agentKey, fetchFn = fetch, dpopProof) {
464
- const { boundedJsonFetch: boundedJsonFetch2 } = await import("./http-SP27G4XU.js");
464
+ const { boundedJsonFetch: boundedJsonFetch2 } = await import("./http-YQS643AJ.js");
465
465
  const r = await boundedJsonFetch2(`${relayHttpUrl.replace(/\/$/, "")}/agents/token`, {
466
466
  method: "POST",
467
467
  headers: {
@@ -1295,8 +1295,322 @@ async function chooseFirstRunProvider(agentName, io = { input: process.stdin, ou
1295
1295
  return { provider: "claude-code", persist: false };
1296
1296
  }
1297
1297
 
1298
+ // src/scope/scopeConfig.ts
1299
+ import { realpathSync, readdirSync as readdirSync2, lstatSync } from "fs";
1300
+ import { execSync } from "child_process";
1301
+ import { join as join3 } from "path";
1302
+ function resolveIpcProfile(scope, flagValue) {
1303
+ if (flagValue !== void 0) return flagValue;
1304
+ if (scope?.ipcProfile !== void 0) return scope.ipcProfile;
1305
+ return "compat";
1306
+ }
1307
+ var STRICT_IPC_ENV_STRIP = [
1308
+ "SSH_AUTH_SOCK",
1309
+ "DOCKER_HOST",
1310
+ "DBUS_SESSION_BUS_ADDRESS",
1311
+ "DBUS_SYSTEM_BUS_ADDRESS",
1312
+ "GPG_AGENT_INFO",
1313
+ "DISPLAY",
1314
+ "WAYLAND_DISPLAY"
1315
+ ];
1316
+ function strictIpcDenyRead(env, lstatFn = lstatSync) {
1317
+ const base = ["/run", "/var/run", "/tmp/.X11-unix"];
1318
+ const xdg = env["XDG_RUNTIME_DIR"];
1319
+ const candidates = xdg ? (() => {
1320
+ const segments = xdg.split("/").filter((s) => s.length > 0);
1321
+ if (!xdg.startsWith("/") || segments.length < 2) {
1322
+ console.warn(
1323
+ `[braid] warn: XDG_RUNTIME_DIR="${xdg}" failed the sanity gate (must be absolute, not "/", and have \u22652 path segments) \u2014 skipping from strict IPC denyRead shroud`
1324
+ );
1325
+ return base;
1326
+ }
1327
+ return [...base, xdg];
1328
+ })() : base;
1329
+ return candidates.filter((p) => {
1330
+ try {
1331
+ return !lstatFn(p).isSymbolicLink();
1332
+ } catch {
1333
+ return true;
1334
+ }
1335
+ });
1336
+ }
1337
+ var DEFAULT_ALLOWED_DOMAINS = [
1338
+ // Anthropic / Claude
1339
+ "api.anthropic.com",
1340
+ "*.anthropic.com",
1341
+ // OpenAI / Codex
1342
+ "api.openai.com",
1343
+ // Google / Gemini
1344
+ "generativelanguage.googleapis.com",
1345
+ "*.googleapis.com",
1346
+ // xAI / Grok
1347
+ "api.x.ai",
1348
+ // Cursor
1349
+ "api.cursor.sh",
1350
+ // opencode (BL-169): its serve process fetches the models.dev registry AT BOOT;
1351
+ // without it opencode dies inside the jail (`ServeError` / ACP connection closed
1352
+ // on every connect). `models.dev` is repro-CONFIRMED (blocked → 403, allowed →
1353
+ // 200 through the srt proxy). `opencode.ai` (opencode's own service) and the
1354
+ // ChatGPT-sign-in OAuth hosts are opencode's documented auth/boot endpoints
1355
+ // (from the 2026-07-02 dry-run that hard-failed opencode). claude-code was
1356
+ // unaffected because all its hosts were already listed above.
1357
+ "models.dev",
1358
+ "opencode.ai",
1359
+ "*.opencode.ai",
1360
+ "auth.openai.com",
1361
+ "chatgpt.com",
1362
+ // npm
1363
+ "registry.npmjs.org",
1364
+ "*.npmjs.org",
1365
+ // PyPI
1366
+ "pypi.org",
1367
+ "files.pythonhosted.org",
1368
+ // Go modules
1369
+ "proxy.golang.org",
1370
+ // Crates.io
1371
+ "crates.io",
1372
+ "static.crates.io",
1373
+ // Source hosts
1374
+ "github.com",
1375
+ "*.github.com",
1376
+ "*.githubusercontent.com",
1377
+ "gitlab.com",
1378
+ "bitbucket.org"
1379
+ ];
1380
+ var PROVIDER_PATHS = {
1381
+ "claude-code": ["~/.claude", "~/.claude.json"],
1382
+ codex: ["~/.codex"],
1383
+ gemini: ["~/.gemini"],
1384
+ grok: ["~/.grok"],
1385
+ cursor: ["~/.cursor"],
1386
+ opencode: ["~/.local/share/opencode", "~/.config/opencode"],
1387
+ goose: ["~/.config/goose"],
1388
+ cline: ["~/.cline"],
1389
+ copilot: ["~/.copilot"],
1390
+ qwen: ["~/.qwen"]
1391
+ };
1392
+ function expandHome(p, home) {
1393
+ if (p.startsWith("~/")) return `${home}${p.slice(1)}`;
1394
+ if (p === "~") return home;
1395
+ return p;
1396
+ }
1397
+ function canonicalize(p) {
1398
+ try {
1399
+ return realpathSync(p);
1400
+ } catch {
1401
+ return p;
1402
+ }
1403
+ }
1404
+ function parseEnvList(val) {
1405
+ if (!val) return [];
1406
+ return val.split(/[,:]/).map((s) => s.trim()).filter((s) => s.length > 0);
1407
+ }
1408
+ function dedup(arr) {
1409
+ return [...new Set(arr)];
1410
+ }
1411
+ function darwinMdsCacheDir() {
1412
+ try {
1413
+ const cacheRoot = execSync("/usr/bin/getconf DARWIN_USER_CACHE_DIR", {
1414
+ encoding: "utf8"
1415
+ }).trim();
1416
+ if (!cacheRoot) return [];
1417
+ return [`${cacheRoot.replace(/\/+$/, "")}/mds`];
1418
+ } catch {
1419
+ return [];
1420
+ }
1421
+ }
1422
+ function resolvePaths(paths, home) {
1423
+ return dedup(paths.map((p) => canonicalize(expandHome(p, home))));
1424
+ }
1425
+ function foldCase(p, platform) {
1426
+ return platform === "darwin" || platform === "win32" ? p.toLowerCase() : p;
1427
+ }
1428
+ function checkGrantsAgainstReservations(grants, reservations, platform) {
1429
+ const sep2 = platform === "win32" ? "\\" : "/";
1430
+ const out = [];
1431
+ for (const g of grants) {
1432
+ const gf = foldCase(g.path, platform);
1433
+ for (const r of reservations) {
1434
+ const rf = foldCase(r, platform);
1435
+ if (gf === rf) {
1436
+ out.push({ grant: g.path, source: g.source, reservation: r, relation: "equal" });
1437
+ } else if (gf.startsWith(rf + sep2)) {
1438
+ out.push({ grant: g.path, source: g.source, reservation: r, relation: "descendant" });
1439
+ }
1440
+ }
1441
+ }
1442
+ return out;
1443
+ }
1444
+ function resolveScope(cfg, provider, env, platform = process.platform) {
1445
+ const scope = cfg.scope ?? {};
1446
+ const home = env["HOME"] ?? "";
1447
+ const cwd = env["PWD"] ?? process.cwd();
1448
+ const tmpDir = env["TMPDIR"] ?? "/tmp";
1449
+ const braidConfigDir = env["BRAID_CONFIG_DIR"]?.trim() || expandHome("~/.braid", home);
1450
+ const legacyArpConfigDir = expandHome("~/.arp", home);
1451
+ const protectedConfigDirs = braidConfigDir === legacyArpConfigDir ? [braidConfigDir] : [braidConfigDir, legacyArpConfigDir];
1452
+ const flagOverride = cfg.scopeFlags?.scopeOverride;
1453
+ const disabled = flagOverride !== void 0 ? flagOverride === "off" : scope.disabled === true || env["BRAID_SCOPE"] === "off";
1454
+ const secretDirs = [
1455
+ "~/.ssh",
1456
+ "~/.aws",
1457
+ "~/.gnupg",
1458
+ "~/.kube/config"
1459
+ ].map((p) => expandHome(p, home));
1460
+ const protectedConfigDirEntries = protectedConfigDirs.flatMap((configDirPath) => {
1461
+ if (platform !== "win32") return [configDirPath];
1462
+ try {
1463
+ const children = readdirSync2(configDirPath, { withFileTypes: true });
1464
+ const denied = children.filter((entry) => entry.name !== "runtime").map((entry) => canonicalize(join3(configDirPath, entry.name)));
1465
+ if (denied.length === 0) return [configDirPath];
1466
+ return denied;
1467
+ } catch {
1468
+ return [configDirPath];
1469
+ }
1470
+ });
1471
+ const providerPaths = PROVIDER_PATHS[provider].map((p) => expandHome(p, home));
1472
+ const uid = process.getuid?.();
1473
+ const claudeTmpRoot = provider === "claude-code" && uid !== void 0 ? [`${canonicalize("/tmp")}/claude-${uid}`, `${canonicalize("/tmp")}/claude-*-cwd`] : [];
1474
+ const mdsCacheDir = platform === "darwin" ? darwinMdsCacheDir() : [];
1475
+ const opAllowWrite = (scope.allowWrite ?? []).map((p) => expandHome(p, home));
1476
+ const envAllowWrite = parseEnvList(env["BRAID_SCOPE_ALLOW_WRITE"]).map((p) => expandHome(p, home));
1477
+ const flagAllowWrite = (cfg.scopeFlags?.allowWrite ?? []).map((p) => expandHome(p, home));
1478
+ const rawAllowWrite = [
1479
+ cwd,
1480
+ ...providerPaths,
1481
+ ...claudeTmpRoot,
1482
+ ...mdsCacheDir,
1483
+ expandHome("~/.npm", home),
1484
+ tmpDir,
1485
+ ...opAllowWrite,
1486
+ ...envAllowWrite,
1487
+ ...flagAllowWrite
1488
+ ];
1489
+ const allowWrite = resolvePaths(rawAllowWrite, home);
1490
+ const rawDenyWrite = [
1491
+ ...secretDirs,
1492
+ ...protectedConfigDirEntries,
1493
+ ...(scope.denyWrite ?? []).map((p) => expandHome(p, home)),
1494
+ ...parseEnvList(env["BRAID_SCOPE_DENY_WRITE"]).map((p) => expandHome(p, home))
1495
+ ];
1496
+ const denyWrite = resolvePaths(rawDenyWrite, home);
1497
+ const ipcProfile = resolveIpcProfile(scope, cfg.scopeFlags?.ipcProfile);
1498
+ const rawDenyRead = [
1499
+ ...secretDirs,
1500
+ ...protectedConfigDirEntries,
1501
+ ...(scope.denyRead ?? []).map((p) => expandHome(p, home)),
1502
+ ...parseEnvList(env["BRAID_SCOPE_DENY_READ"]).map((p) => expandHome(p, home))
1503
+ ];
1504
+ const denyRead = dedup([
1505
+ ...resolvePaths(rawDenyRead, home),
1506
+ ...ipcProfile === "strict" && platform === "linux" ? strictIpcDenyRead(env) : []
1507
+ ]);
1508
+ const opAllowRead = (scope.allowRead ?? []).map((p) => expandHome(p, home));
1509
+ const envAllowRead = parseEnvList(env["BRAID_SCOPE_ALLOW_READ"]).map((p) => expandHome(p, home));
1510
+ const flagAllowRead = (cfg.scopeFlags?.allowRead ?? []).map((p) => expandHome(p, home));
1511
+ const rawAllowRead = [
1512
+ ...opAllowRead,
1513
+ ...envAllowRead,
1514
+ ...flagAllowRead
1515
+ ];
1516
+ const allowRead = resolvePaths(rawAllowRead, home);
1517
+ if (!disabled) {
1518
+ const reservations = resolvePaths([...secretDirs, ...protectedConfigDirs], home);
1519
+ const labelled = (paths, source) => resolvePaths(paths, home).map((p) => ({ path: p, source }));
1520
+ const grants = [
1521
+ ...labelled([cwd], "launch directory (cwd)"),
1522
+ ...labelled(providerPaths, "provider default paths"),
1523
+ ...labelled(opAllowWrite, "scope.allowWrite"),
1524
+ ...labelled(envAllowWrite, "BRAID_SCOPE_ALLOW_WRITE"),
1525
+ ...labelled(flagAllowWrite, "--allow-write"),
1526
+ ...labelled(opAllowRead, "scope.allowRead"),
1527
+ ...labelled(envAllowRead, "BRAID_SCOPE_ALLOW_READ"),
1528
+ ...labelled(flagAllowRead, "--allow-read")
1529
+ ];
1530
+ const conflicts = checkGrantsAgainstReservations(grants, reservations, platform);
1531
+ if (conflicts.length > 0) {
1532
+ const detail = conflicts.map((c) => ` - ${c.source}: "${c.grant}" is ${c.relation === "equal" ? "" : "inside "}the protected path "${c.reservation}"`).join("\n");
1533
+ throw new Error(
1534
+ `[braid] SCOPE ERROR: a grant covers a protected credential/secret path and was refused:
1535
+ ${detail}
1536
+ Protected paths (never grantable): ${reservations.join(", ")}
1537
+ Narrow the grant to a path outside the protected set. (Ancestor grants like "~" are fine \u2014 the protected dirs are carved back out automatically.)`
1538
+ );
1539
+ }
1540
+ const writableDefaults = resolvePaths(
1541
+ [...providerPaths, expandHome("~/.npm", home), tmpDir],
1542
+ home
1543
+ );
1544
+ const resolvedConfigDir = canonicalize(braidConfigDir);
1545
+ const placement = checkGrantsAgainstReservations(
1546
+ [{ path: resolvedConfigDir, source: "BRAID_CONFIG_DIR" }],
1547
+ writableDefaults,
1548
+ platform
1549
+ );
1550
+ if (placement.length > 0) {
1551
+ const c = placement[0];
1552
+ throw new Error(
1553
+ `[braid] SCOPE ERROR: BRAID_CONFIG_DIR ("${c.grant}") is ${c.relation === "equal" ? "" : "inside "}a default provider-writable location ("${c.reservation}"). The bridge credential store must live outside provider/tmp/npm paths. Move it (default: ~/.braid) or unset BRAID_CONFIG_DIR.`
1554
+ );
1555
+ }
1556
+ }
1557
+ const allowedDomains = dedup([
1558
+ ...DEFAULT_ALLOWED_DOMAINS,
1559
+ ...scope.network?.allowedDomains ?? [],
1560
+ ...cfg.derivedAllowedDomains ?? [],
1561
+ ...parseEnvList(env["BRAID_SCOPE_ALLOW_DOMAINS"]),
1562
+ ...cfg.scopeFlags?.allowDomains ?? []
1563
+ ]);
1564
+ const deniedDomains = dedup([
1565
+ ...scope.network?.deniedDomains ?? [],
1566
+ ...parseEnvList(env["BRAID_SCOPE_DENY_DOMAINS"])
1567
+ ]);
1568
+ function describe() {
1569
+ const lines = [];
1570
+ if (disabled) {
1571
+ lines.push("[scope] SANDBOX DISABLED (BRAID_SCOPE=off or scope.disabled:true) \u2014 agent runs unconfined");
1572
+ return lines;
1573
+ }
1574
+ lines.push("[scope] Agent sandbox is ACTIVE");
1575
+ lines.push(
1576
+ `[scope] protected (never readable/writable by the agent): ${resolvePaths([...secretDirs, ...protectedConfigDirs], home).join(", ")}`
1577
+ );
1578
+ lines.push(`[scope] cwd (writable): ${cwd}`);
1579
+ if (providerPaths.length > 0) {
1580
+ lines.push(`[scope] provider paths (writable): ${providerPaths.join(", ")}`);
1581
+ }
1582
+ lines.push(`[scope] allowed domains (${allowedDomains.length}): ${allowedDomains.slice(0, 5).join(", ")}${allowedDomains.length > 5 ? " ..." : ""}`);
1583
+ if ((cfg.derivedAllowedDomains ?? []).length > 0) {
1584
+ lines.push(`[scope] model endpoints (derived): ${(cfg.derivedAllowedDomains ?? []).join(", ")}`);
1585
+ }
1586
+ lines.push(`[scope] denied read: ${denyRead.join(", ")}`);
1587
+ if (denyWrite.length > 0) {
1588
+ lines.push(`[scope] denied write: ${denyWrite.join(", ")}`);
1589
+ }
1590
+ if (deniedDomains.length > 0) {
1591
+ lines.push(`[scope] denied domains: ${deniedDomains.join(", ")}`);
1592
+ }
1593
+ if (ipcProfile === "compat") {
1594
+ lines.push("[scope] ipc profile: compat \u2014 all unix sockets reachable inside the jail (Linux seccomp constraint)");
1595
+ } else {
1596
+ lines.push("[scope] ipc profile: strict \u2014 /run, /var/run, XDG_RUNTIME_DIR, /tmp/.X11-unix hidden; socket env vars stripped");
1597
+ }
1598
+ lines.push("[scope] To widen: add paths to scope.allowWrite/allowRead in agent config, or BRAID_SCOPE_ALLOW_WRITE/BRAID_SCOPE=off env.");
1599
+ return lines;
1600
+ }
1601
+ return {
1602
+ runtimeConfig: {
1603
+ filesystem: { allowWrite, denyWrite, allowRead, denyRead },
1604
+ network: { allowedDomains, deniedDomains }
1605
+ },
1606
+ disabled,
1607
+ ipcProfile,
1608
+ describe
1609
+ };
1610
+ }
1611
+
1298
1612
  // src/cardSigning.ts
1299
- import canonicalize from "canonicalize";
1613
+ import canonicalize2 from "canonicalize";
1300
1614
  import {
1301
1615
  FlattenedSign,
1302
1616
  flattenedVerify,
@@ -1353,7 +1667,7 @@ function pruneForSigning(card) {
1353
1667
  return pruneNode(clone, REQUIRED_TOP);
1354
1668
  }
1355
1669
  function canonicalCardString(card) {
1356
- return canonicalize(pruneForSigning(card));
1670
+ return canonicalize2(pruneForSigning(card));
1357
1671
  }
1358
1672
  function publicOkpJwk(jwk) {
1359
1673
  return { kty: jwk.kty, crv: jwk.crv, x: jwk.x };
@@ -1825,10 +2139,10 @@ async function loadConfigFromInvite(code, env, flags) {
1825
2139
  }
1826
2140
  function buildJoinScopeBlock(flags, env) {
1827
2141
  const split = (v) => v ? v.split(/[,:]/).map((s) => s.trim()).filter((s) => s.length > 0) : [];
1828
- const dedup = (arr) => [...new Set(arr)];
1829
- const allowWrite = dedup([...split(env.BRAID_SCOPE_ALLOW_WRITE), ...flags?.allowWrite ?? []]);
1830
- const allowRead = dedup([...split(env.BRAID_SCOPE_ALLOW_READ), ...flags?.allowRead ?? []]);
1831
- const allowedDomains = dedup([...split(env.BRAID_SCOPE_ALLOW_DOMAINS), ...flags?.allowDomains ?? []]);
2142
+ const dedup2 = (arr) => [...new Set(arr)];
2143
+ const allowWrite = dedup2([...split(env.BRAID_SCOPE_ALLOW_WRITE), ...flags?.allowWrite ?? []]);
2144
+ const allowRead = dedup2([...split(env.BRAID_SCOPE_ALLOW_READ), ...flags?.allowRead ?? []]);
2145
+ const allowedDomains = dedup2([...split(env.BRAID_SCOPE_ALLOW_DOMAINS), ...flags?.allowDomains ?? []]);
1832
2146
  const disabled = flags?.scope === "off" || flags?.scope === void 0 && env.BRAID_SCOPE === "off";
1833
2147
  if (allowWrite.length === 0 && allowRead.length === 0 && allowedDomains.length === 0 && !disabled) {
1834
2148
  return void 0;
@@ -1901,7 +2215,7 @@ function parseClaudeConfigModel(jsonText) {
1901
2215
  function readClaudeConfigModel(agent) {
1902
2216
  if (agent !== "claude-code") return null;
1903
2217
  try {
1904
- const text = readFileSync2(join3(homedir4(), ".claude.json"), "utf8");
2218
+ const text = readFileSync2(join4(homedir4(), ".claude.json"), "utf8");
1905
2219
  return parseClaudeConfigModel(text);
1906
2220
  } catch {
1907
2221
  return null;
@@ -1920,16 +2234,21 @@ function redactConfig(cfg) {
1920
2234
  return { ...cfg, token: "<redacted>", model };
1921
2235
  }
1922
2236
  function startingLines(cfg) {
1923
- const model = redactConfig(cfg).model;
2237
+ const row = (label, value) => `${label.padEnd(8)} : ${value}`;
2238
+ const anthropicCredential = cfg.agentMode !== "acp" || cfg.agent === "claude-code";
2239
+ const catchUpHours = cfg.catchUpTtlMs % 36e5 === 0 ? `${cfg.catchUpTtlMs / 36e5}h` : `${Math.round(cfg.catchUpTtlMs / 6e4)}min`;
1924
2240
  return [
1925
- `agent : ${sanitizeForTty(cfg.agentName)}`,
1926
- `relay : ${sanitizeForTty(cfg.relayWsUrl)}`,
1927
- `provider : ${cfg.agentMode === "acp" ? cfg.agent : "bundled SDK (generic mode)"}`,
1928
- `model : ${sanitizeForTty(model)}`,
1929
- `tools : ${cfg.toolMode}`,
1930
- ...cfg.authMode ? [`auth : ${cfg.authMode}`] : [],
1931
- ...cfg.fallbackModel ? [`fallback : ${sanitizeForTty(cfg.fallbackModel)}`] : [],
1932
- `sandbox : ${cfg.scope?.disabled ? "OFF (unconfined)" : "on"}`
2241
+ row("agent", sanitizeForTty(cfg.agentName)),
2242
+ row("relay", sanitizeForTty(cfg.relayWsUrl)),
2243
+ row("provider", cfg.agentMode === "acp" ? cfg.agent : "bundled SDK (generic mode)"),
2244
+ row("model", sanitizeForTty(redactConfig(cfg).model)),
2245
+ row("fallback", cfg.fallbackModel ? sanitizeForTty(cfg.fallbackModel) : "(none \u2014 a rate limit is surfaced, not switched)"),
2246
+ row("tools", cfg.toolMode),
2247
+ row("auth", anthropicCredential ? cfg.authMode ?? "auto" : `(managed by ${cfg.agent})`),
2248
+ row("sandbox", cfg.scope?.disabled ? "OFF (unconfined)" : "on"),
2249
+ row("ipc", resolveIpcProfile(cfg.scope, cfg.scopeFlags?.ipcProfile)),
2250
+ row("catch-up", `${catchUpHours} window \xB7 up to ${cfg.catchUpMaxMentions} missed mentions`),
2251
+ row("keystore", cfg.agentFile ? sanitizeForTty(cfg.agentFile) : "(env-provided credential \u2014 no saved file)")
1933
2252
  ];
1934
2253
  }
1935
2254
 
@@ -2162,6 +2481,9 @@ export {
2162
2481
  evaluateAcpPermission,
2163
2482
  evaluateSdkTool,
2164
2483
  pickRejectOptionId,
2484
+ resolveIpcProfile,
2485
+ STRICT_IPC_ENV_STRIP,
2486
+ resolveScope,
2165
2487
  verifyCardSignature,
2166
2488
  cleanContent,
2167
2489
  resolveAgentSelection,