usebeeline 0.0.120 → 0.0.121
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 +4 -4
- package/dist/usebeeline.mjs +1194 -506
- package/package.json +1 -1
package/dist/usebeeline.mjs
CHANGED
|
@@ -11300,10 +11300,12 @@ __export(self_update_exports, {
|
|
|
11300
11300
|
readInstalledBundleIdentity: () => readInstalledBundleIdentity,
|
|
11301
11301
|
readUpdateAttempt: () => readUpdateAttempt,
|
|
11302
11302
|
readUpdateState: () => readUpdateState,
|
|
11303
|
+
releaseIdFromPath: () => releaseIdFromPath,
|
|
11303
11304
|
repairInstallForwarders: () => repairInstallForwarders,
|
|
11304
11305
|
replaceUpdateAttempt: () => replaceUpdateAttempt,
|
|
11305
11306
|
resolveBundleEntrypoint: () => resolveBundleEntrypoint,
|
|
11306
11307
|
rollbackToPreviousRelease: () => rollbackToPreviousRelease,
|
|
11308
|
+
runningReleaseId: () => runningReleaseId,
|
|
11307
11309
|
settleUpdateAttemptOnStart: () => settleUpdateAttemptOnStart,
|
|
11308
11310
|
stageRelease: () => stageRelease,
|
|
11309
11311
|
updateAttemptPath: () => updateAttemptPath,
|
|
@@ -11314,11 +11316,11 @@ __export(self_update_exports, {
|
|
|
11314
11316
|
import { createHash as createHash8 } from "node:crypto";
|
|
11315
11317
|
import { constants as fsConstants2 } from "node:fs";
|
|
11316
11318
|
import { access, chmod as chmod6, lstat as lstat4, mkdir as mkdir17, open, readFile as readFile10, rename as rename6, rm as rm6, symlink as symlink3, writeFile as writeFile11 } from "node:fs/promises";
|
|
11317
|
-
import { spawn as
|
|
11318
|
-
import { homedir as
|
|
11319
|
-
import { dirname as
|
|
11319
|
+
import { spawn as spawn8 } from "node:child_process";
|
|
11320
|
+
import { homedir as homedir12 } from "node:os";
|
|
11321
|
+
import { dirname as dirname15, join as join13, resolve as resolve26 } from "node:path";
|
|
11320
11322
|
function anchorLayout(rawLibDir) {
|
|
11321
|
-
const libDir =
|
|
11323
|
+
const libDir = resolve26(rawLibDir);
|
|
11322
11324
|
const segments = libDir.split(/[/\\]/);
|
|
11323
11325
|
const idx = segments.lastIndexOf(RELEASES_SEGMENT);
|
|
11324
11326
|
if (idx >= 2 && segments[idx - 1] === "lib") {
|
|
@@ -11334,9 +11336,9 @@ function anchorLayout(rawLibDir) {
|
|
|
11334
11336
|
// prefix's bin, NOT <prefix>/lib/bin — deriving it one level up was the
|
|
11335
11337
|
// defect that made activateRelease write its stable forwarders where
|
|
11336
11338
|
// nothing executed them, leaving stale raw wrappers in <prefix>/bin.
|
|
11337
|
-
binDir:
|
|
11339
|
+
binDir: resolve26(libDir, "../../bin"),
|
|
11338
11340
|
libDir,
|
|
11339
|
-
releasesRoot:
|
|
11341
|
+
releasesRoot: resolve26(libDir, `../${RELEASES_SEGMENT}`)
|
|
11340
11342
|
};
|
|
11341
11343
|
}
|
|
11342
11344
|
function beelineInstallLayout(env = process.env) {
|
|
@@ -11345,9 +11347,32 @@ function beelineInstallLayout(env = process.env) {
|
|
|
11345
11347
|
return void 0;
|
|
11346
11348
|
return anchorLayout(raw);
|
|
11347
11349
|
}
|
|
11350
|
+
function releaseIdFromPath(path) {
|
|
11351
|
+
if (!path?.trim())
|
|
11352
|
+
return void 0;
|
|
11353
|
+
const segments = resolve26(path.trim()).split(/[/\\]/);
|
|
11354
|
+
const idx = segments.lastIndexOf(RELEASES_SEGMENT);
|
|
11355
|
+
const id = idx >= 0 ? segments[idx + 1] : void 0;
|
|
11356
|
+
return id ? sanitizeReleaseId(id) : void 0;
|
|
11357
|
+
}
|
|
11358
|
+
function runningReleaseId(layout, env = process.env, invocationPath = process.argv[1]) {
|
|
11359
|
+
const releasesRoot = resolve26(layout.releasesRoot);
|
|
11360
|
+
const anchor = resolve26(layout.libDir);
|
|
11361
|
+
for (const raw of [env.BEELINE_LIB_DIR, invocationPath]) {
|
|
11362
|
+
if (!raw?.trim())
|
|
11363
|
+
continue;
|
|
11364
|
+
const resolved = resolve26(raw.trim());
|
|
11365
|
+
if (resolved !== anchor && !resolved.startsWith(`${releasesRoot}/`))
|
|
11366
|
+
continue;
|
|
11367
|
+
const id = releaseIdFromPath(resolved);
|
|
11368
|
+
if (id)
|
|
11369
|
+
return id;
|
|
11370
|
+
}
|
|
11371
|
+
return void 0;
|
|
11372
|
+
}
|
|
11348
11373
|
function defaultBeelineInstallLayout(env = process.env) {
|
|
11349
|
-
const home = env.HOME?.trim() ||
|
|
11350
|
-
return anchorLayout(
|
|
11374
|
+
const home = env.HOME?.trim() || homedir12();
|
|
11375
|
+
return anchorLayout(resolve26(home, ".local", "lib", "beeline"));
|
|
11351
11376
|
}
|
|
11352
11377
|
function discoveredBeelineInstallLayout(env = process.env) {
|
|
11353
11378
|
const explicitAnchor = env.BEELINE_INSTALL_LIB_DIR?.trim();
|
|
@@ -11355,7 +11380,7 @@ function discoveredBeelineInstallLayout(env = process.env) {
|
|
|
11355
11380
|
return anchorLayout(explicitAnchor);
|
|
11356
11381
|
const explicitBinDir = env.BEELINE_INSTALL_DIR?.trim();
|
|
11357
11382
|
if (explicitBinDir)
|
|
11358
|
-
return anchorLayout(
|
|
11383
|
+
return anchorLayout(resolve26(dirname15(resolve26(explicitBinDir)), "lib", "beeline"));
|
|
11359
11384
|
return defaultBeelineInstallLayout(env);
|
|
11360
11385
|
}
|
|
11361
11386
|
function hostPlatformKey() {
|
|
@@ -11366,7 +11391,7 @@ function hostPlatformKey() {
|
|
|
11366
11391
|
return `${os}-${arch}`;
|
|
11367
11392
|
}
|
|
11368
11393
|
function bundleJsonCandidates(bundleDir) {
|
|
11369
|
-
return [
|
|
11394
|
+
return [join13(bundleDir, "lib", "beeline", "bundle.json"), join13(bundleDir, "bundle.json")];
|
|
11370
11395
|
}
|
|
11371
11396
|
async function readBundleJson(bundleDir) {
|
|
11372
11397
|
let raw;
|
|
@@ -11390,7 +11415,7 @@ async function readBundleJson(bundleDir) {
|
|
|
11390
11415
|
}
|
|
11391
11416
|
}
|
|
11392
11417
|
function updateStatePath(layout) {
|
|
11393
|
-
return
|
|
11418
|
+
return join13(layout.releasesRoot, ".state", "update-state.json");
|
|
11394
11419
|
}
|
|
11395
11420
|
async function readUpdateState(layout) {
|
|
11396
11421
|
try {
|
|
@@ -11400,7 +11425,7 @@ async function readUpdateState(layout) {
|
|
|
11400
11425
|
}
|
|
11401
11426
|
}
|
|
11402
11427
|
async function writeUpdateState(layout, state) {
|
|
11403
|
-
await mkdir17(
|
|
11428
|
+
await mkdir17(join13(layout.releasesRoot, ".state"), { recursive: true });
|
|
11404
11429
|
await writeFile11(updateStatePath(layout), `${JSON.stringify(state, null, 2)}
|
|
11405
11430
|
`, "utf8");
|
|
11406
11431
|
}
|
|
@@ -11464,7 +11489,7 @@ async function fetchText(url, fetchImpl) {
|
|
|
11464
11489
|
}
|
|
11465
11490
|
function run(command, args, timeoutMs) {
|
|
11466
11491
|
return new Promise((resolveRun) => {
|
|
11467
|
-
const child =
|
|
11492
|
+
const child = spawn8(command, args, { stdio: ["ignore", "ignore", "pipe"] });
|
|
11468
11493
|
let stderr = "";
|
|
11469
11494
|
child.stderr?.setEncoding("utf8");
|
|
11470
11495
|
child.stderr?.on("data", (chunk) => {
|
|
@@ -11482,7 +11507,7 @@ function run(command, args, timeoutMs) {
|
|
|
11482
11507
|
});
|
|
11483
11508
|
}
|
|
11484
11509
|
function entrypointCandidates(bundleDir) {
|
|
11485
|
-
return [
|
|
11510
|
+
return [join13(bundleDir, BUNDLE_ENTRYPOINT), join13(bundleDir, "beeline-cli.mjs")];
|
|
11486
11511
|
}
|
|
11487
11512
|
async function resolveBundleEntrypoint(bundleDir) {
|
|
11488
11513
|
for (const candidate of entrypointCandidates(bundleDir)) {
|
|
@@ -11504,8 +11529,8 @@ async function stageRelease(layout, manifestUrl, published, opts = {}) {
|
|
|
11504
11529
|
const fetchImpl = opts.fetchImpl ?? fetch;
|
|
11505
11530
|
const log2 = opts.logger ?? ((line) => console.log(`[body] self-update: ${line}`));
|
|
11506
11531
|
const releaseId = sanitizeReleaseId(published.commit ?? published.version ?? `release-${Date.now()}`);
|
|
11507
|
-
const releaseDir =
|
|
11508
|
-
const okMarker =
|
|
11532
|
+
const releaseDir = join13(layout.releasesRoot, releaseId);
|
|
11533
|
+
const okMarker = join13(releaseDir, ".stage-ok");
|
|
11509
11534
|
let previouslyVerified = false;
|
|
11510
11535
|
try {
|
|
11511
11536
|
const recorded = await readFile10(okMarker, "utf8");
|
|
@@ -11515,7 +11540,7 @@ async function stageRelease(layout, manifestUrl, published, opts = {}) {
|
|
|
11515
11540
|
} catch {
|
|
11516
11541
|
}
|
|
11517
11542
|
await mkdir17(releaseDir, { recursive: true });
|
|
11518
|
-
const tempArchive =
|
|
11543
|
+
const tempArchive = join13(layout.releasesRoot, `.download-${releaseId}-${process.pid}.tar.gz`);
|
|
11519
11544
|
try {
|
|
11520
11545
|
log2(`downloading ${published.file}`);
|
|
11521
11546
|
const response = await fetchImpl(archiveUrlFor(manifestUrl, published.file), {
|
|
@@ -11537,7 +11562,7 @@ async function stageRelease(layout, manifestUrl, published, opts = {}) {
|
|
|
11537
11562
|
}
|
|
11538
11563
|
await writeFile11(tempArchive, Buffer.concat(chunks), { mode: 384 });
|
|
11539
11564
|
const entries = (await new Promise((resolveList, rejectList) => {
|
|
11540
|
-
const child =
|
|
11565
|
+
const child = spawn8("tar", ["-tzf", tempArchive], { stdio: ["ignore", "pipe", "inherit"] });
|
|
11541
11566
|
let out = "";
|
|
11542
11567
|
child.stdout?.on("data", (chunk) => {
|
|
11543
11568
|
out += chunk.toString("utf8");
|
|
@@ -11555,13 +11580,13 @@ async function stageRelease(layout, manifestUrl, published, opts = {}) {
|
|
|
11555
11580
|
throw new Error(`extracting bundle failed: ${extract2.stderr}`);
|
|
11556
11581
|
for (const relative3 of requiredBundlePaths()) {
|
|
11557
11582
|
try {
|
|
11558
|
-
await access(
|
|
11583
|
+
await access(join13(releaseDir, relative3), fsConstants2.F_OK);
|
|
11559
11584
|
} catch {
|
|
11560
11585
|
throw new Error(`staged bundle is missing ${relative3}`);
|
|
11561
11586
|
}
|
|
11562
11587
|
}
|
|
11563
11588
|
if (opts.smokeTestCli !== false) {
|
|
11564
|
-
const probe = await run(process.execPath, [
|
|
11589
|
+
const probe = await run(process.execPath, [join13(releaseDir, BUNDLE_ENTRYPOINT), "--version"], 6e4);
|
|
11565
11590
|
if (probe.status !== 0) {
|
|
11566
11591
|
throw new Error(`staged bundle failed its startup smoke test (--version exited ${probe.status})${probe.stderr ? `: ${probe.stderr.trim()}` : ""}`);
|
|
11567
11592
|
}
|
|
@@ -11599,8 +11624,8 @@ async function replaceFile(path, contents, mode) {
|
|
|
11599
11624
|
await rename6(temp, path);
|
|
11600
11625
|
}
|
|
11601
11626
|
async function activateRelease(layout, releaseId) {
|
|
11602
|
-
const releaseDir =
|
|
11603
|
-
await access(
|
|
11627
|
+
const releaseDir = join13(layout.releasesRoot, releaseId);
|
|
11628
|
+
await access(join13(releaseDir, BUNDLE_ENTRYPOINT), fsConstants2.F_OK);
|
|
11604
11629
|
await mkdir17(layout.releasesRoot, { recursive: true });
|
|
11605
11630
|
await mkdir17(layout.binDir, { recursive: true });
|
|
11606
11631
|
let previousReleaseId = await activeReleaseId(layout);
|
|
@@ -11608,12 +11633,12 @@ async function activateRelease(layout, releaseId) {
|
|
|
11608
11633
|
if (kind === "directory") {
|
|
11609
11634
|
const legacyIdentity = await readBundleJson(layout.libDir);
|
|
11610
11635
|
const legacyId = sanitizeReleaseId(legacyIdentity?.commit ?? legacyIdentity?.version ?? `legacy-${Date.now()}`);
|
|
11611
|
-
const legacyDir =
|
|
11636
|
+
const legacyDir = join13(layout.releasesRoot, legacyId);
|
|
11612
11637
|
try {
|
|
11613
11638
|
await access(legacyDir, fsConstants2.F_OK);
|
|
11614
11639
|
previousReleaseId = `${legacyId}-${Date.now()}`;
|
|
11615
|
-
await rename6(layout.libDir,
|
|
11616
|
-
await normalizeLegacyBundleShape(
|
|
11640
|
+
await rename6(layout.libDir, join13(layout.releasesRoot, previousReleaseId));
|
|
11641
|
+
await normalizeLegacyBundleShape(join13(layout.releasesRoot, previousReleaseId));
|
|
11617
11642
|
} catch {
|
|
11618
11643
|
await rename6(layout.libDir, legacyDir);
|
|
11619
11644
|
await normalizeLegacyBundleShape(legacyDir);
|
|
@@ -11622,18 +11647,18 @@ async function activateRelease(layout, releaseId) {
|
|
|
11622
11647
|
}
|
|
11623
11648
|
const tempLink = `${layout.libDir}.new-${process.pid}`;
|
|
11624
11649
|
await rm6(tempLink, { force: true });
|
|
11625
|
-
await symlink3(
|
|
11650
|
+
await symlink3(join13("beeline-releases", releaseId), tempLink);
|
|
11626
11651
|
await rename6(tempLink, layout.libDir);
|
|
11627
|
-
await fsyncDir(
|
|
11652
|
+
await fsyncDir(dirname15(layout.libDir));
|
|
11628
11653
|
await writeBinForwarders(layout, releaseDir);
|
|
11629
11654
|
return { previousReleaseId };
|
|
11630
11655
|
}
|
|
11631
11656
|
async function normalizeLegacyBundleShape(bundleDir) {
|
|
11632
|
-
const innerLib =
|
|
11657
|
+
const innerLib = join13(bundleDir, "lib", "beeline");
|
|
11633
11658
|
let anyFlat = false;
|
|
11634
11659
|
for (const name of LEGACY_FLAT_BUNDLE_FILES) {
|
|
11635
11660
|
try {
|
|
11636
|
-
await access(
|
|
11661
|
+
await access(join13(bundleDir, name), fsConstants2.F_OK);
|
|
11637
11662
|
anyFlat = true;
|
|
11638
11663
|
break;
|
|
11639
11664
|
} catch {
|
|
@@ -11644,11 +11669,11 @@ async function normalizeLegacyBundleShape(bundleDir) {
|
|
|
11644
11669
|
await mkdir17(innerLib, { recursive: true });
|
|
11645
11670
|
for (const name of LEGACY_FLAT_BUNDLE_FILES) {
|
|
11646
11671
|
try {
|
|
11647
|
-
await access(
|
|
11672
|
+
await access(join13(innerLib, name), fsConstants2.F_OK);
|
|
11648
11673
|
continue;
|
|
11649
11674
|
} catch {
|
|
11650
11675
|
}
|
|
11651
|
-
await rename6(
|
|
11676
|
+
await rename6(join13(bundleDir, name), join13(innerLib, name)).catch(() => void 0);
|
|
11652
11677
|
}
|
|
11653
11678
|
}
|
|
11654
11679
|
async function writeBinForwarders(layout, activeBundleRoot) {
|
|
@@ -11657,13 +11682,13 @@ async function writeBinForwarders(layout, activeBundleRoot) {
|
|
|
11657
11682
|
...Object.entries(FORWARDER_ALIASES).map(([alias, tool]) => [alias, tool])
|
|
11658
11683
|
];
|
|
11659
11684
|
for (const [name, tool] of entries) {
|
|
11660
|
-
const target =
|
|
11685
|
+
const target = join13(activeBundleRoot, "bin", tool);
|
|
11661
11686
|
try {
|
|
11662
11687
|
await access(target, fsConstants2.X_OK);
|
|
11663
11688
|
} catch {
|
|
11664
11689
|
continue;
|
|
11665
11690
|
}
|
|
11666
|
-
await replaceFile(
|
|
11691
|
+
await replaceFile(join13(layout.binDir, name), forwarderScript(tool), 493);
|
|
11667
11692
|
}
|
|
11668
11693
|
}
|
|
11669
11694
|
async function repairInstallForwarders(layout, opts = {}) {
|
|
@@ -11672,7 +11697,7 @@ async function repairInstallForwarders(layout, opts = {}) {
|
|
|
11672
11697
|
const forwarderHealthy = async (name, tool) => {
|
|
11673
11698
|
let current;
|
|
11674
11699
|
try {
|
|
11675
|
-
current = await readFile10(
|
|
11700
|
+
current = await readFile10(join13(layout.binDir, name), "utf8");
|
|
11676
11701
|
} catch {
|
|
11677
11702
|
current = void 0;
|
|
11678
11703
|
}
|
|
@@ -11691,19 +11716,19 @@ async function repairInstallForwarders(layout, opts = {}) {
|
|
|
11691
11716
|
return true;
|
|
11692
11717
|
}
|
|
11693
11718
|
async function rollbackToPreviousRelease(layout, previousReleaseId) {
|
|
11694
|
-
const releaseDir =
|
|
11719
|
+
const releaseDir = join13(layout.releasesRoot, previousReleaseId);
|
|
11695
11720
|
const entrypoint = await resolveBundleEntrypoint(releaseDir);
|
|
11696
11721
|
if (!entrypoint) {
|
|
11697
11722
|
throw new Error(`release ${previousReleaseId} has no runnable CLI entrypoint`);
|
|
11698
11723
|
}
|
|
11699
11724
|
const tempLink = `${layout.libDir}.rollback-${process.pid}`;
|
|
11700
11725
|
await rm6(tempLink, { force: true });
|
|
11701
|
-
await symlink3(
|
|
11726
|
+
await symlink3(join13("beeline-releases", previousReleaseId), tempLink);
|
|
11702
11727
|
await rename6(tempLink, layout.libDir);
|
|
11703
|
-
await fsyncDir(
|
|
11728
|
+
await fsyncDir(dirname15(layout.libDir));
|
|
11704
11729
|
}
|
|
11705
11730
|
function updateAttemptPath(layout) {
|
|
11706
|
-
return
|
|
11731
|
+
return join13(layout.releasesRoot, ".state", "update-attempt.json");
|
|
11707
11732
|
}
|
|
11708
11733
|
async function readUpdateAttempt(layout) {
|
|
11709
11734
|
try {
|
|
@@ -11717,7 +11742,7 @@ async function readUpdateAttempt(layout) {
|
|
|
11717
11742
|
}
|
|
11718
11743
|
}
|
|
11719
11744
|
async function writeUpdateAttempt(layout, record3) {
|
|
11720
|
-
await mkdir17(
|
|
11745
|
+
await mkdir17(join13(layout.releasesRoot, ".state"), { recursive: true });
|
|
11721
11746
|
const path = updateAttemptPath(layout);
|
|
11722
11747
|
const staged = `${path}.${process.pid}.tmp`;
|
|
11723
11748
|
await writeFile11(staged, `${JSON.stringify(record3, null, 2)}
|
|
@@ -11995,7 +12020,7 @@ function configureNetworkFamilyDefaults(network = net) {
|
|
|
11995
12020
|
configureNetworkFamilyDefaults();
|
|
11996
12021
|
|
|
11997
12022
|
// apps/body/dist/cli.js
|
|
11998
|
-
import { dirname as
|
|
12023
|
+
import { dirname as dirname22, resolve as resolve34 } from "node:path";
|
|
11999
12024
|
import { stdin as stdin4, stdout as stdout5 } from "node:process";
|
|
12000
12025
|
|
|
12001
12026
|
// node_modules/@clack/core/dist/index.mjs
|
|
@@ -13444,7 +13469,7 @@ function parseCursorModelsOutput(output) {
|
|
|
13444
13469
|
};
|
|
13445
13470
|
}
|
|
13446
13471
|
async function enumerateCursorModels(env = process.env) {
|
|
13447
|
-
return new Promise((
|
|
13472
|
+
return new Promise((resolve35) => {
|
|
13448
13473
|
const child = spawn("cursor-agent", ["models"], {
|
|
13449
13474
|
env,
|
|
13450
13475
|
stdio: ["ignore", "pipe", "ignore"]
|
|
@@ -13458,11 +13483,11 @@ async function enumerateCursorModels(env = process.env) {
|
|
|
13458
13483
|
});
|
|
13459
13484
|
child.on("error", () => {
|
|
13460
13485
|
clearTimeout(timer);
|
|
13461
|
-
|
|
13486
|
+
resolve35(void 0);
|
|
13462
13487
|
});
|
|
13463
13488
|
child.on("close", (code) => {
|
|
13464
13489
|
clearTimeout(timer);
|
|
13465
|
-
|
|
13490
|
+
resolve35(code === 0 ? parseCursorModelsOutput(output) : void 0);
|
|
13466
13491
|
});
|
|
13467
13492
|
});
|
|
13468
13493
|
}
|
|
@@ -13889,13 +13914,13 @@ var CursorAcpServer = class {
|
|
|
13889
13914
|
consumeLine(line);
|
|
13890
13915
|
});
|
|
13891
13916
|
try {
|
|
13892
|
-
const { code, signal } = await new Promise((
|
|
13917
|
+
const { code, signal } = await new Promise((resolve35) => {
|
|
13893
13918
|
let settled = false;
|
|
13894
13919
|
const finish = (exitCode, exitSignal) => {
|
|
13895
13920
|
if (settled)
|
|
13896
13921
|
return;
|
|
13897
13922
|
settled = true;
|
|
13898
|
-
|
|
13923
|
+
resolve35({ code: exitCode, signal: exitSignal });
|
|
13899
13924
|
};
|
|
13900
13925
|
child.once("error", (error) => {
|
|
13901
13926
|
spawnError = error instanceof Error ? error.message : String(error);
|
|
@@ -14574,6 +14599,132 @@ function parseSandboxMaskEnv(env) {
|
|
|
14574
14599
|
return entries.length ? entries : void 0;
|
|
14575
14600
|
}
|
|
14576
14601
|
|
|
14602
|
+
// apps/body/dist/squire-host.js
|
|
14603
|
+
import { spawn as spawn3 } from "node:child_process";
|
|
14604
|
+
import { existsSync as existsSync4, lstatSync, mkdirSync } from "node:fs";
|
|
14605
|
+
import { createRequire as createRequire2 } from "node:module";
|
|
14606
|
+
import { homedir as homedir2 } from "node:os";
|
|
14607
|
+
import { dirname as dirname3, join as join2, resolve as resolve3 } from "node:path";
|
|
14608
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
14609
|
+
var SQUIRE_BROKER_UNAVAILABLE = "broker unavailable";
|
|
14610
|
+
var TRUSTY_SQUIRE_BROKER_UNIT_NAME = "trusty-squire-broker.service";
|
|
14611
|
+
var SQUIRE_FACADE_FLAG = "--squire-facade";
|
|
14612
|
+
var SQUIRE_BROKER_FLAG = "--squire-broker";
|
|
14613
|
+
var SQUIRE_SERVER_ARGS = ["-y", "@trusty-squire/mcp@latest", "server"];
|
|
14614
|
+
function squireHostPaths(home) {
|
|
14615
|
+
const dir = join2(resolve3(home), ".trusty-squire");
|
|
14616
|
+
return {
|
|
14617
|
+
dir,
|
|
14618
|
+
profileDir: join2(dir, "chrome-profile"),
|
|
14619
|
+
configHome: join2(resolve3(home), ".config"),
|
|
14620
|
+
brokerSocket: join2(dir, "broker.sock")
|
|
14621
|
+
};
|
|
14622
|
+
}
|
|
14623
|
+
function squireHostRewriteEnv(home) {
|
|
14624
|
+
const paths = squireHostPaths(home);
|
|
14625
|
+
return {
|
|
14626
|
+
TRUSTY_SQUIRE_PROFILE_DIR: paths.profileDir,
|
|
14627
|
+
XDG_CONFIG_HOME: paths.configHome,
|
|
14628
|
+
TRUSTY_SQUIRE_BROKER_SOCKET: paths.brokerSocket
|
|
14629
|
+
};
|
|
14630
|
+
}
|
|
14631
|
+
function ensureSquireHostDir(home) {
|
|
14632
|
+
const paths = squireHostPaths(home);
|
|
14633
|
+
mkdirSync(paths.dir, { recursive: true, mode: 448 });
|
|
14634
|
+
mkdirSync(paths.profileDir, { recursive: true, mode: 448 });
|
|
14635
|
+
return paths;
|
|
14636
|
+
}
|
|
14637
|
+
function squireHostBindPaths(home, squireRouteGranted) {
|
|
14638
|
+
if (!squireRouteGranted)
|
|
14639
|
+
return [];
|
|
14640
|
+
return [ensureSquireHostDir(home).dir];
|
|
14641
|
+
}
|
|
14642
|
+
function squireBrokerSocketReady(socketPath) {
|
|
14643
|
+
try {
|
|
14644
|
+
return lstatSync(socketPath).isSocket();
|
|
14645
|
+
} catch {
|
|
14646
|
+
return false;
|
|
14647
|
+
}
|
|
14648
|
+
}
|
|
14649
|
+
function squireFacadeLaunch(home) {
|
|
14650
|
+
const env = squireHostRewriteEnv(home);
|
|
14651
|
+
const meta = "usebeeline:npm";
|
|
14652
|
+
if (meta.startsWith("beeline:")) {
|
|
14653
|
+
const entry = process.argv[1];
|
|
14654
|
+
if (!entry)
|
|
14655
|
+
throw new Error("Squire fa\xE7ade cannot resolve the Beeline CLI entry");
|
|
14656
|
+
return { command: process.execPath, args: [entry, SQUIRE_FACADE_FLAG], env };
|
|
14657
|
+
}
|
|
14658
|
+
const js = fileURLToPath2(new URL("./squire-facade.js", meta));
|
|
14659
|
+
if (existsSync4(js))
|
|
14660
|
+
return { command: process.execPath, args: [js], env };
|
|
14661
|
+
const ts = fileURLToPath2(new URL("./squire-facade.ts", meta));
|
|
14662
|
+
if (existsSync4(ts)) {
|
|
14663
|
+
const tsx = createRequire2(meta).resolve("tsx");
|
|
14664
|
+
return { command: process.execPath, args: ["--import", tsx, ts], env };
|
|
14665
|
+
}
|
|
14666
|
+
throw new Error("Squire fa\xE7ade entry not found next to the Beeline helper");
|
|
14667
|
+
}
|
|
14668
|
+
function squireServerCommand(nodeExecPath = process.execPath) {
|
|
14669
|
+
const binDir = dirname3(nodeExecPath);
|
|
14670
|
+
const sibling = join2(binDir, "npx");
|
|
14671
|
+
const args = [...SQUIRE_SERVER_ARGS];
|
|
14672
|
+
if (existsSync4(sibling))
|
|
14673
|
+
return { command: sibling, args, pathPrefix: binDir };
|
|
14674
|
+
return { command: "npx", args, pathPrefix: binDir };
|
|
14675
|
+
}
|
|
14676
|
+
function trustySquireBrokerUnit() {
|
|
14677
|
+
return `[Unit]
|
|
14678
|
+
Description=Trusty Squire host broker
|
|
14679
|
+
After=network-online.target
|
|
14680
|
+
Wants=network-online.target
|
|
14681
|
+
|
|
14682
|
+
[Service]
|
|
14683
|
+
Type=simple
|
|
14684
|
+
WorkingDirectory=%h
|
|
14685
|
+
Environment=TRUSTY_SQUIRE_PROFILE_DIR=%h/.trusty-squire/chrome-profile
|
|
14686
|
+
Environment=XDG_CONFIG_HOME=%h/.config
|
|
14687
|
+
Environment=TRUSTY_SQUIRE_BROKER_SOCKET=%h/.trusty-squire/broker.sock
|
|
14688
|
+
ExecStartPre=/bin/mkdir -p %h/.trusty-squire
|
|
14689
|
+
ExecStart=%h/.local/bin/beeline ${SQUIRE_BROKER_FLAG}
|
|
14690
|
+
Restart=on-failure
|
|
14691
|
+
RestartSec=5s
|
|
14692
|
+
UMask=0077
|
|
14693
|
+
NoNewPrivileges=yes
|
|
14694
|
+
|
|
14695
|
+
[Install]
|
|
14696
|
+
WantedBy=default.target
|
|
14697
|
+
`;
|
|
14698
|
+
}
|
|
14699
|
+
function spawnSquireServer(env, locateNpx) {
|
|
14700
|
+
const launch = locateNpx ? squireServerCommand() : { command: "npx", args: [...SQUIRE_SERVER_ARGS], pathPrefix: "" };
|
|
14701
|
+
const path = [launch.pathPrefix, env.PATH || "/usr/bin:/bin"].filter(Boolean).join(":");
|
|
14702
|
+
const child = spawn3(launch.command, launch.args, {
|
|
14703
|
+
env: { ...env, PATH: path },
|
|
14704
|
+
stdio: "inherit"
|
|
14705
|
+
});
|
|
14706
|
+
child.on("exit", (code, signal) => {
|
|
14707
|
+
if (signal)
|
|
14708
|
+
process.exit(1);
|
|
14709
|
+
process.exit(code ?? 1);
|
|
14710
|
+
});
|
|
14711
|
+
}
|
|
14712
|
+
function runSquireBroker(env = process.env) {
|
|
14713
|
+
const home = env.HOME?.trim() || homedir2();
|
|
14714
|
+
const paths = ensureSquireHostDir(home);
|
|
14715
|
+
spawnSquireServer({ ...env, ...squireHostRewriteEnv(home), TRUSTY_SQUIRE_BROKER_SOCKET: paths.brokerSocket }, true);
|
|
14716
|
+
}
|
|
14717
|
+
function runSquireFacade(env = process.env) {
|
|
14718
|
+
const socket = env.TRUSTY_SQUIRE_BROKER_SOCKET ?? squireHostPaths(env.HOME?.trim() || homedir2()).brokerSocket;
|
|
14719
|
+
if (!squireBrokerSocketReady(socket)) {
|
|
14720
|
+
process.stderr.write(`${SQUIRE_BROKER_UNAVAILABLE}
|
|
14721
|
+
`);
|
|
14722
|
+
process.exitCode = 1;
|
|
14723
|
+
return;
|
|
14724
|
+
}
|
|
14725
|
+
spawnSquireServer({ ...env, TRUSTY_SQUIRE_BROKER_SOCKET: socket }, false);
|
|
14726
|
+
}
|
|
14727
|
+
|
|
14577
14728
|
// packages/api-contract/dist/agent-access.js
|
|
14578
14729
|
var AGENT_ACCESS_POLICIES = ["everyone", "creator", "allowlist"];
|
|
14579
14730
|
var DEFAULT_AGENT_ACCESS_POLICY = "everyone";
|
|
@@ -14590,10 +14741,10 @@ var ACCESS_REFUSAL_WINDOW_MS = 60 * 60 * 1e3;
|
|
|
14590
14741
|
// apps/body/dist/model-catalog.js
|
|
14591
14742
|
import { mkdtemp, rm } from "node:fs/promises";
|
|
14592
14743
|
import { tmpdir } from "node:os";
|
|
14593
|
-
import { resolve as
|
|
14744
|
+
import { resolve as resolve5 } from "node:path";
|
|
14594
14745
|
|
|
14595
14746
|
// apps/body/dist/acp.js
|
|
14596
|
-
import { spawn as
|
|
14747
|
+
import { spawn as spawn4 } from "node:child_process";
|
|
14597
14748
|
import { EventEmitter } from "node:events";
|
|
14598
14749
|
|
|
14599
14750
|
// apps/body/dist/harness-capabilities.js
|
|
@@ -14656,7 +14807,7 @@ var PROFILES = [
|
|
|
14656
14807
|
match: /(^|[/\\])pi-acp(\.[a-z]+)?$/i,
|
|
14657
14808
|
profile: {
|
|
14658
14809
|
enforcement: "config-isolated",
|
|
14659
|
-
note: "pi-acp
|
|
14810
|
+
note: "pi-acp 0.0.33 still stores session/new mcpServers and never reads them; pi 0.85.1 itself has no MCP client, while optional pi-mcp-adapter reads $PI_CODING_AGENT_DIR/mcp.json and isolated homes exclude the settings.json that would load it"
|
|
14660
14811
|
}
|
|
14661
14812
|
},
|
|
14662
14813
|
{
|
|
@@ -14814,6 +14965,11 @@ function agentMessageChunkText(update) {
|
|
|
14814
14965
|
return "";
|
|
14815
14966
|
}
|
|
14816
14967
|
var CHUNK_CONTINUES_PREVIOUS_WORD = /^[\s'\u2018\u2019\u02bc.,!?;:%)\]}-]/;
|
|
14968
|
+
function continuesPreviousWord(current, delta) {
|
|
14969
|
+
if (/\s$/.test(current))
|
|
14970
|
+
return false;
|
|
14971
|
+
return CHUNK_CONTINUES_PREVIOUS_WORD.test(delta);
|
|
14972
|
+
}
|
|
14817
14973
|
var PI_ACP_HARNESS = /(^|[/\\])pi-acp(?:\.[a-z]+)?$/i;
|
|
14818
14974
|
function isPiAcpHarness(agentLabel) {
|
|
14819
14975
|
return Boolean(agentLabel && PI_ACP_HARNESS.test(agentLabel));
|
|
@@ -14826,17 +14982,12 @@ function agentMessageRuns(updates, agentLabel) {
|
|
|
14826
14982
|
let current = "";
|
|
14827
14983
|
let lastWasText = false;
|
|
14828
14984
|
for (const u4 of updates) {
|
|
14829
|
-
const isToolCall = u4.update.sessionUpdate === "tool_call";
|
|
14830
14985
|
const delta = normalizeStreamDelta(agentMessageChunkText(u4.update), agentLabel);
|
|
14831
14986
|
if (!delta) {
|
|
14832
|
-
if (isToolCall && current) {
|
|
14833
|
-
runs.push(current);
|
|
14834
|
-
current = "";
|
|
14835
|
-
}
|
|
14836
14987
|
lastWasText = false;
|
|
14837
14988
|
continue;
|
|
14838
14989
|
}
|
|
14839
|
-
if (!lastWasText && current &&
|
|
14990
|
+
if (!lastWasText && current && !continuesPreviousWord(current, delta)) {
|
|
14840
14991
|
runs.push(current);
|
|
14841
14992
|
current = "";
|
|
14842
14993
|
}
|
|
@@ -15041,7 +15192,7 @@ var AcpClient = class extends EventEmitter {
|
|
|
15041
15192
|
async start(timeoutMs = 6e4) {
|
|
15042
15193
|
if (this.alive)
|
|
15043
15194
|
return;
|
|
15044
|
-
this.child =
|
|
15195
|
+
this.child = spawn4(this.agentCommand, this.agentArgs, {
|
|
15045
15196
|
// agentEnv is the child's whole environment: buildAgentEnv's allowlist is
|
|
15046
15197
|
// a real boundary, not a decorative one layered over a full inherit.
|
|
15047
15198
|
env: this.inheritProcessEnv ? { ...process.env, ...this.agentEnv } : this.agentEnv,
|
|
@@ -15458,7 +15609,7 @@ var AcpClient = class extends EventEmitter {
|
|
|
15458
15609
|
const current = this.activeRunIds.get(sessionId);
|
|
15459
15610
|
if (current)
|
|
15460
15611
|
return Promise.resolve(current);
|
|
15461
|
-
return new Promise((
|
|
15612
|
+
return new Promise((resolve35, reject) => {
|
|
15462
15613
|
const onUpdate = (update) => {
|
|
15463
15614
|
if (update.sessionId !== sessionId)
|
|
15464
15615
|
return;
|
|
@@ -15466,7 +15617,7 @@ var AcpClient = class extends EventEmitter {
|
|
|
15466
15617
|
if (!runId)
|
|
15467
15618
|
return;
|
|
15468
15619
|
cleanup();
|
|
15469
|
-
|
|
15620
|
+
resolve35(runId);
|
|
15470
15621
|
};
|
|
15471
15622
|
const timer = setTimeout(() => {
|
|
15472
15623
|
cleanup();
|
|
@@ -15550,13 +15701,13 @@ var AcpClient = class extends EventEmitter {
|
|
|
15550
15701
|
}
|
|
15551
15702
|
const id = this.nextId++;
|
|
15552
15703
|
const payload = { jsonrpc: "2.0", id, method, params };
|
|
15553
|
-
return new Promise((
|
|
15704
|
+
return new Promise((resolve35, reject) => {
|
|
15554
15705
|
const timer = setTimeout(() => {
|
|
15555
15706
|
this.pending.delete(id);
|
|
15556
15707
|
reject(new AcpRequestTimeoutError(method, timeoutMs, this.stderrTail, Boolean(onStart), detail));
|
|
15557
15708
|
}, timeoutMs);
|
|
15558
15709
|
this.pending.set(id, {
|
|
15559
|
-
resolve:
|
|
15710
|
+
resolve: resolve35,
|
|
15560
15711
|
reject,
|
|
15561
15712
|
timer,
|
|
15562
15713
|
method,
|
|
@@ -15584,8 +15735,8 @@ function isAllowedAgentModelConfigCategory(category) {
|
|
|
15584
15735
|
}
|
|
15585
15736
|
|
|
15586
15737
|
// apps/body/dist/model-config.js
|
|
15587
|
-
import { lstatSync, readFileSync as readFileSync2 } from "node:fs";
|
|
15588
|
-
import { basename as basename3, resolve as
|
|
15738
|
+
import { lstatSync as lstatSync2, readFileSync as readFileSync2 } from "node:fs";
|
|
15739
|
+
import { basename as basename3, resolve as resolve4 } from "node:path";
|
|
15589
15740
|
var GROK_SESSION_MODEL_AXIS_ID = "beeline:grok-session-model";
|
|
15590
15741
|
var GROK_LAUNCH_EFFORT_AXIS_ID = "beeline:grok-launch-reasoning-effort";
|
|
15591
15742
|
function isGrokAgentCommand(agent) {
|
|
@@ -15754,13 +15905,13 @@ function credentialedProviders(env) {
|
|
|
15754
15905
|
return held;
|
|
15755
15906
|
}
|
|
15756
15907
|
function credentialedPiCustomProviders(env) {
|
|
15757
|
-
const agentDir = env.PI_CODING_AGENT_DIR?.trim() ?
|
|
15908
|
+
const agentDir = env.PI_CODING_AGENT_DIR?.trim() ? resolve4(env.PI_CODING_AGENT_DIR) : env.HOME?.trim() ? resolve4(env.HOME, ".pi/agent") : void 0;
|
|
15758
15909
|
const held = /* @__PURE__ */ new Set();
|
|
15759
15910
|
if (!agentDir)
|
|
15760
15911
|
return held;
|
|
15761
|
-
const path =
|
|
15912
|
+
const path = resolve4(agentDir, "models.json");
|
|
15762
15913
|
try {
|
|
15763
|
-
const stats =
|
|
15914
|
+
const stats = lstatSync2(path);
|
|
15764
15915
|
if (!stats.isFile() || stats.isSymbolicLink() || stats.nlink !== 1 || stats.size > 1048576) {
|
|
15765
15916
|
return held;
|
|
15766
15917
|
}
|
|
@@ -15906,7 +16057,7 @@ function modelCatalogProbeEnvironment(agent, agentEnv, scratchCwd) {
|
|
|
15906
16057
|
return agentEnv;
|
|
15907
16058
|
return {
|
|
15908
16059
|
...agentEnv,
|
|
15909
|
-
GOOSE_PATH_ROOT:
|
|
16060
|
+
GOOSE_PATH_ROOT: resolve5(scratchCwd, "goose")
|
|
15910
16061
|
};
|
|
15911
16062
|
}
|
|
15912
16063
|
function filterAgentModelCatalog(agent, raw, agentEnv) {
|
|
@@ -15916,7 +16067,7 @@ function filterAgentModelCatalog(agent, raw, agentEnv) {
|
|
|
15916
16067
|
async function withAgentModelCatalog(agent, agentEnv, selection, inspect, limits = {}) {
|
|
15917
16068
|
const deadline = limits.timeoutMs === void 0 ? void 0 : Date.now() + limits.timeoutMs;
|
|
15918
16069
|
const remaining = () => deadline === void 0 ? void 0 : Math.max(1, deadline - Date.now());
|
|
15919
|
-
const scratchCwd = await mkdtemp(
|
|
16070
|
+
const scratchCwd = await mkdtemp(resolve5(tmpdir(), "beeline-pair-model-check-"));
|
|
15920
16071
|
const probeEnv = modelCatalogProbeEnvironment(agent, agentEnv, scratchCwd);
|
|
15921
16072
|
const client = new AcpClient({
|
|
15922
16073
|
agentCommand: agent.command,
|
|
@@ -16016,7 +16167,7 @@ async function applyRuntimeModelPreflight(config, agent, selection, validate = v
|
|
|
16016
16167
|
// apps/body/dist/model-catalog-sync.js
|
|
16017
16168
|
import { createHash } from "node:crypto";
|
|
16018
16169
|
import { readFile, writeFile as writeFile2 } from "node:fs/promises";
|
|
16019
|
-
import { resolve as
|
|
16170
|
+
import { resolve as resolve6 } from "node:path";
|
|
16020
16171
|
var MODEL_CATALOG_PROBE_TIMEOUT_MS = 3e4;
|
|
16021
16172
|
var MODEL_CATALOG_HASH_FILE = "model-catalog.sha256";
|
|
16022
16173
|
function modelCatalogHash(options, selection, startupUnavailable) {
|
|
@@ -16041,7 +16192,7 @@ async function withTimeout(work, timeoutMs, what) {
|
|
|
16041
16192
|
async function syncAgentModelCatalog(input) {
|
|
16042
16193
|
const log2 = input.log ?? ((line) => console.log(line));
|
|
16043
16194
|
const fetchCatalog = input.fetchCatalog ?? fetchAgentModelCatalog;
|
|
16044
|
-
const hashPath =
|
|
16195
|
+
const hashPath = resolve6(input.runtimeDir, MODEL_CATALOG_HASH_FILE);
|
|
16045
16196
|
try {
|
|
16046
16197
|
const configuration = await input.api.execute("getAgentConfiguration", {
|
|
16047
16198
|
agentId: input.agentId
|
|
@@ -16075,8 +16226,8 @@ async function syncAgentModelCatalog(input) {
|
|
|
16075
16226
|
}
|
|
16076
16227
|
|
|
16077
16228
|
// apps/body/dist/connector-google.js
|
|
16078
|
-
import { mkdirSync, readFileSync as readFileSync4, writeFileSync } from "node:fs";
|
|
16079
|
-
import { dirname as
|
|
16229
|
+
import { mkdirSync as mkdirSync2, readFileSync as readFileSync4, writeFileSync } from "node:fs";
|
|
16230
|
+
import { dirname as dirname5, join as join4 } from "node:path";
|
|
16080
16231
|
|
|
16081
16232
|
// apps/body/dist/google-workspace-client.js
|
|
16082
16233
|
function credentialsTokenSource(credentials) {
|
|
@@ -16451,11 +16602,11 @@ function googleWorkspaceClient(tokenSource, transport = defaultGoogleApiTranspor
|
|
|
16451
16602
|
}
|
|
16452
16603
|
|
|
16453
16604
|
// apps/body/dist/connector-squire.js
|
|
16454
|
-
import { execFile, spawn as
|
|
16605
|
+
import { execFile, spawn as spawn5 } from "node:child_process";
|
|
16455
16606
|
import { createHash as createHash2 } from "node:crypto";
|
|
16456
|
-
import { lstatSync as
|
|
16457
|
-
import { homedir as
|
|
16458
|
-
import { basename as basename4, dirname as
|
|
16607
|
+
import { lstatSync as lstatSync3, readFileSync as readFileSync3, realpathSync, rmSync } from "node:fs";
|
|
16608
|
+
import { homedir as homedir3, hostname, tmpdir as tmpdir2 } from "node:os";
|
|
16609
|
+
import { basename as basename4, dirname as dirname4, join as join3, resolve as resolve7 } from "node:path";
|
|
16459
16610
|
var SQUIRE_MCP_NAME = "@trusty-squire/mcp";
|
|
16460
16611
|
var SQUIRE_CONNECT_PACKAGE = `${SQUIRE_MCP_NAME}@latest`;
|
|
16461
16612
|
var activeConnectSession;
|
|
@@ -16485,17 +16636,17 @@ function releaseSquireConnectSession(log2) {
|
|
|
16485
16636
|
}
|
|
16486
16637
|
}
|
|
16487
16638
|
function squireChromeProfileDir() {
|
|
16488
|
-
return process.env.TRUSTY_SQUIRE_PROFILE_DIR ??
|
|
16639
|
+
return process.env.TRUSTY_SQUIRE_PROFILE_DIR ?? squireHostPaths(homedir3()).profileDir;
|
|
16489
16640
|
}
|
|
16490
16641
|
function squireProfilePathIdentity(profileDir) {
|
|
16491
|
-
const absolute =
|
|
16642
|
+
const absolute = resolve7(profileDir);
|
|
16492
16643
|
const suffix = [];
|
|
16493
16644
|
let candidate = absolute;
|
|
16494
16645
|
for (; ; ) {
|
|
16495
16646
|
try {
|
|
16496
|
-
return
|
|
16647
|
+
return join3(realpathSync.native(candidate), ...suffix.reverse());
|
|
16497
16648
|
} catch {
|
|
16498
|
-
const parent =
|
|
16649
|
+
const parent = dirname4(candidate);
|
|
16499
16650
|
if (parent === candidate)
|
|
16500
16651
|
return absolute;
|
|
16501
16652
|
suffix.push(basename4(candidate));
|
|
@@ -16505,7 +16656,7 @@ function squireProfilePathIdentity(profileDir) {
|
|
|
16505
16656
|
}
|
|
16506
16657
|
function squireProfileLockPath(profileDir = squireChromeProfileDir(), lockRoot = tmpdir2()) {
|
|
16507
16658
|
const digest = createHash2("sha256").update(squireProfilePathIdentity(profileDir)).digest("hex").slice(0, 24);
|
|
16508
|
-
return
|
|
16659
|
+
return join3(lockRoot, `trusty-squire-profile-${digest}.lock`);
|
|
16509
16660
|
}
|
|
16510
16661
|
var SQUIRE_BROWSER_BUSY_GOOGLE_REASON = "Trusty Squire is still using the browser \u2014 connect Trusty Squire first";
|
|
16511
16662
|
function isSquireBrowserSessionFailure(text2) {
|
|
@@ -16537,7 +16688,7 @@ function lockOwnerIsAlive(owner) {
|
|
|
16537
16688
|
}
|
|
16538
16689
|
function readLockFileOwner(lockPath) {
|
|
16539
16690
|
try {
|
|
16540
|
-
const target =
|
|
16691
|
+
const target = lstatSync3(lockPath).isDirectory() ? join3(lockPath, "owner.json") : lockPath;
|
|
16541
16692
|
const parsed = JSON.parse(readFileSync3(target, "utf8"));
|
|
16542
16693
|
if (typeof parsed.host !== "string" || typeof parsed.pid !== "number")
|
|
16543
16694
|
return void 0;
|
|
@@ -16576,10 +16727,10 @@ function reclaimSquireProfileClaim(options) {
|
|
|
16576
16727
|
options?.log?.(`cleared dead trusty-squire on-disk browser claim (pid ${owner.pid} gone)`);
|
|
16577
16728
|
return { kind: "reclaimed-dead", owner };
|
|
16578
16729
|
}
|
|
16579
|
-
var defaultShellRunner = (command, args) => new Promise((
|
|
16730
|
+
var defaultShellRunner = (command, args) => new Promise((resolve35) => {
|
|
16580
16731
|
execFile(command, [...args], { timeout: 12e4, maxBuffer: 4 * 1024 * 1024, encoding: "utf8" }, (error, stdout6, stderr) => {
|
|
16581
16732
|
const code = error?.code;
|
|
16582
|
-
|
|
16733
|
+
resolve35({
|
|
16583
16734
|
code: typeof code === "number" ? code : error ? 1 : 0,
|
|
16584
16735
|
stdout: String(stdout6 ?? ""),
|
|
16585
16736
|
stderr: String(stderr ?? "")
|
|
@@ -16589,6 +16740,7 @@ var defaultShellRunner = (command, args) => new Promise((resolve33) => {
|
|
|
16589
16740
|
function squireConnectProcessEnv(profileDir = squireChromeProfileDir()) {
|
|
16590
16741
|
return {
|
|
16591
16742
|
...process.env,
|
|
16743
|
+
...squireHostRewriteEnv(homedir3()),
|
|
16592
16744
|
TRUSTY_SQUIRE_PROFILE_DIR: profileDir
|
|
16593
16745
|
};
|
|
16594
16746
|
}
|
|
@@ -16603,8 +16755,8 @@ function killConnectTree(child) {
|
|
|
16603
16755
|
}
|
|
16604
16756
|
child.kill();
|
|
16605
16757
|
}
|
|
16606
|
-
var defaultStreamedRunner = (command, args, env) => new Promise((
|
|
16607
|
-
const child =
|
|
16758
|
+
var defaultStreamedRunner = (command, args, env) => new Promise((resolve35) => {
|
|
16759
|
+
const child = spawn5(command, args, {
|
|
16608
16760
|
stdio: ["ignore", "pipe", "pipe"],
|
|
16609
16761
|
env: env ?? squireConnectProcessEnv(),
|
|
16610
16762
|
detached: true
|
|
@@ -16615,7 +16767,7 @@ var defaultStreamedRunner = (command, args, env) => new Promise((resolve33) => {
|
|
|
16615
16767
|
const safetyTimer = setTimeout(() => {
|
|
16616
16768
|
if (!resolved) {
|
|
16617
16769
|
resolved = true;
|
|
16618
|
-
|
|
16770
|
+
resolve35({ stdout: stdout6, stderr, pid: child.pid ?? void 0, signIn: void 0, abort: () => {
|
|
16619
16771
|
} });
|
|
16620
16772
|
}
|
|
16621
16773
|
killConnectTree(child);
|
|
@@ -16633,18 +16785,22 @@ var defaultStreamedRunner = (command, args, env) => new Promise((resolve33) => {
|
|
|
16633
16785
|
const finish = (result) => {
|
|
16634
16786
|
if (!resolved) {
|
|
16635
16787
|
resolved = true;
|
|
16636
|
-
|
|
16637
|
-
resolve33(result);
|
|
16788
|
+
resolve35(result);
|
|
16638
16789
|
}
|
|
16639
16790
|
};
|
|
16791
|
+
const settle = (result) => {
|
|
16792
|
+
clearTimeout(safetyTimer);
|
|
16793
|
+
finish(result);
|
|
16794
|
+
};
|
|
16640
16795
|
const checkOutput = () => {
|
|
16641
|
-
const
|
|
16642
|
-
${stderr}`;
|
|
16643
|
-
const signIn = parseConnectOutput(combined);
|
|
16796
|
+
const signIn = parseConnectOutput(stdout6) ?? parseConnectOutput(stderr);
|
|
16644
16797
|
if (signIn) {
|
|
16645
16798
|
finish({ stdout: stdout6, stderr, signIn, abort });
|
|
16646
16799
|
}
|
|
16647
16800
|
};
|
|
16801
|
+
const finalSignIn = () => parseConnectOutput(`${stdout6}
|
|
16802
|
+
`) ?? parseConnectOutput(`${stderr}
|
|
16803
|
+
`);
|
|
16648
16804
|
child.stdout?.on("data", (chunk) => {
|
|
16649
16805
|
stdout6 += String(chunk);
|
|
16650
16806
|
checkOutput();
|
|
@@ -16654,11 +16810,17 @@ ${stderr}`;
|
|
|
16654
16810
|
checkOutput();
|
|
16655
16811
|
});
|
|
16656
16812
|
child.on("close", () => {
|
|
16657
|
-
|
|
16658
|
-
|
|
16813
|
+
settle({
|
|
16814
|
+
stdout: stdout6,
|
|
16815
|
+
stderr,
|
|
16816
|
+
pid: child.pid ?? void 0,
|
|
16817
|
+
signIn: finalSignIn(),
|
|
16818
|
+
abort: () => {
|
|
16819
|
+
}
|
|
16820
|
+
});
|
|
16659
16821
|
});
|
|
16660
16822
|
child.on("error", () => {
|
|
16661
|
-
|
|
16823
|
+
settle({ stdout: stdout6, stderr, pid: child.pid ?? void 0, signIn: void 0, abort: () => {
|
|
16662
16824
|
} });
|
|
16663
16825
|
});
|
|
16664
16826
|
});
|
|
@@ -16667,17 +16829,84 @@ var step = (label, status, reason) => ({
|
|
|
16667
16829
|
status,
|
|
16668
16830
|
...reason ? { reason } : {}
|
|
16669
16831
|
});
|
|
16670
|
-
function
|
|
16671
|
-
|
|
16672
|
-
|
|
16673
|
-
|
|
16674
|
-
|
|
16675
|
-
return
|
|
16832
|
+
function isKnownCeremonySurface(url) {
|
|
16833
|
+
try {
|
|
16834
|
+
const parsed = new URL(url);
|
|
16835
|
+
if (parsed.protocol !== "https:")
|
|
16836
|
+
return false;
|
|
16837
|
+
return parsed.hash.startsWith("#p=") || /(^|\/)install(\/|$)/.test(parsed.pathname);
|
|
16838
|
+
} catch {
|
|
16839
|
+
return false;
|
|
16676
16840
|
}
|
|
16677
|
-
|
|
16678
|
-
|
|
16841
|
+
}
|
|
16842
|
+
function isForeignUrl(url) {
|
|
16843
|
+
try {
|
|
16844
|
+
const parsed = new URL(url);
|
|
16845
|
+
const host = parsed.hostname.toLowerCase();
|
|
16846
|
+
if (host === "developers.cloudflare.com")
|
|
16847
|
+
return true;
|
|
16848
|
+
if (host === "github.com" && parsed.pathname.toLowerCase().startsWith("/npm/cli"))
|
|
16849
|
+
return true;
|
|
16850
|
+
return host === "npmjs.com" || host === "www.npmjs.com";
|
|
16851
|
+
} catch {
|
|
16852
|
+
return true;
|
|
16679
16853
|
}
|
|
16680
|
-
|
|
16854
|
+
}
|
|
16855
|
+
var BOXED_ROW = /^\s*\u2502(.*)\u2502\s*$/;
|
|
16856
|
+
var BOX_BORDER = /^\s*[\u2500-\u257F]+\s*$/;
|
|
16857
|
+
function rejoinBoxRows(cells) {
|
|
16858
|
+
const written = cells.filter((cell) => cell.trim() !== "");
|
|
16859
|
+
const pad2 = (measure) => written.length === 0 ? 0 : Math.min(...written.map(measure));
|
|
16860
|
+
const left = pad2((cell) => cell.length - cell.trimStart().length);
|
|
16861
|
+
const right = pad2((cell) => cell.length - cell.trimEnd().length);
|
|
16862
|
+
const lines = [];
|
|
16863
|
+
let carry;
|
|
16864
|
+
for (const cell of cells) {
|
|
16865
|
+
const content = cell.slice(left, cell.length - right);
|
|
16866
|
+
const text2 = content.replace(/\s+$/, "");
|
|
16867
|
+
carry = (carry ?? "") + text2;
|
|
16868
|
+
if (text2.length < content.length) {
|
|
16869
|
+
lines.push(carry);
|
|
16870
|
+
carry = void 0;
|
|
16871
|
+
}
|
|
16872
|
+
}
|
|
16873
|
+
if (carry !== void 0)
|
|
16874
|
+
lines.push(carry);
|
|
16875
|
+
return lines;
|
|
16876
|
+
}
|
|
16877
|
+
function unframeBoxedOutput(output) {
|
|
16878
|
+
const lines = [];
|
|
16879
|
+
let box = [];
|
|
16880
|
+
for (const row of output.split("\n")) {
|
|
16881
|
+
const framed = BOXED_ROW.exec(row);
|
|
16882
|
+
if (framed) {
|
|
16883
|
+
box.push(framed[1] ?? "");
|
|
16884
|
+
continue;
|
|
16885
|
+
}
|
|
16886
|
+
if (box.length > 0 && BOX_BORDER.test(row))
|
|
16887
|
+
lines.push(...rejoinBoxRows(box));
|
|
16888
|
+
box = [];
|
|
16889
|
+
lines.push(row);
|
|
16890
|
+
}
|
|
16891
|
+
return lines.join("\n");
|
|
16892
|
+
}
|
|
16893
|
+
function parseConnectOutput(output) {
|
|
16894
|
+
const urls = unframeBoxedOutput(output).match(/https:\/\/[^\s"'<>]+(?=[\s"'<>])/g) ?? [];
|
|
16895
|
+
const preferred = urls.find(isKnownCeremonySurface);
|
|
16896
|
+
if (preferred)
|
|
16897
|
+
return { method: "streamed-page", url: preferred };
|
|
16898
|
+
const fallback = urls.find((url) => !isForeignUrl(url));
|
|
16899
|
+
if (fallback) {
|
|
16900
|
+
console.log(`[body] squire connect: no known ceremony surface matched; using fallback URL ${fallback}`);
|
|
16901
|
+
return { method: "streamed-page", url: fallback };
|
|
16902
|
+
}
|
|
16903
|
+
return void 0;
|
|
16904
|
+
}
|
|
16905
|
+
function parseConnectAlreadyConnected(output) {
|
|
16906
|
+
return /Already connected \(/i.test(output) && /config refreshed/i.test(output);
|
|
16907
|
+
}
|
|
16908
|
+
function withoutForceReloginHint(output) {
|
|
16909
|
+
return output.split("\n").filter((line) => !/--force-relogin/.test(line)).join("\n").trim();
|
|
16681
16910
|
}
|
|
16682
16911
|
async function installedSquireVersion(run2, spec = SQUIRE_CONNECT_PACKAGE, preferOnline = false) {
|
|
16683
16912
|
const probe = await run2("npx", [
|
|
@@ -16760,15 +16989,11 @@ async function installSquire(options) {
|
|
|
16760
16989
|
if (resolution.reResolved) {
|
|
16761
16990
|
log2(`trusty-squire stale copy ${resolution.resolvedVersion ?? "unknown"} re-resolved against current release ${resolution.currentRelease}`);
|
|
16762
16991
|
}
|
|
16763
|
-
const install = await streamRun("npx", [
|
|
16764
|
-
|
|
16765
|
-
|
|
16766
|
-
|
|
16767
|
-
|
|
16768
|
-
"--skip-browser"
|
|
16769
|
-
], squireConnectProcessEnv(profileDir));
|
|
16770
|
-
if (!install.signIn) {
|
|
16771
|
-
const stderr = install.stderr.trim();
|
|
16992
|
+
const install = await streamRun("npx", [...resolution.npxArgs, "connect", "--target=codex"], squireConnectProcessEnv(profileDir));
|
|
16993
|
+
const alreadyConnected = !install.signIn && parseConnectAlreadyConnected(`${install.stdout}
|
|
16994
|
+
${install.stderr}`);
|
|
16995
|
+
if (!install.signIn && !alreadyConnected) {
|
|
16996
|
+
const stderr = withoutForceReloginHint(install.stderr);
|
|
16772
16997
|
let stepReason = stderr || "connect printed no sign-in URL";
|
|
16773
16998
|
let failReason = stderr || "the trusty-squire connect command printed no sign-in surface";
|
|
16774
16999
|
if (isSquireBrowserSessionFailure(stderr)) {
|
|
@@ -16786,7 +17011,7 @@ async function installSquire(options) {
|
|
|
16786
17011
|
const signIn = install.signIn;
|
|
16787
17012
|
const signedInAs = parseSignedInAs(`${install.stdout}
|
|
16788
17013
|
${install.stderr}`);
|
|
16789
|
-
push(step("waiting for sign-in", "done"));
|
|
17014
|
+
push(step("waiting for sign-in", signIn ? "pending" : "done"));
|
|
16790
17015
|
const pair = await pairSquire(options.mcp, options.workspaceId);
|
|
16791
17016
|
if (!pair.ok) {
|
|
16792
17017
|
push(step("paired to workspace", "failed", pair.reason));
|
|
@@ -16799,10 +17024,18 @@ ${install.stderr}`);
|
|
|
16799
17024
|
};
|
|
16800
17025
|
}
|
|
16801
17026
|
push(step("paired to workspace", "done"));
|
|
17027
|
+
if (signIn) {
|
|
17028
|
+
return {
|
|
17029
|
+
status: "installing",
|
|
17030
|
+
steps,
|
|
17031
|
+
signIn,
|
|
17032
|
+
...version ? { squireVersion: version } : {},
|
|
17033
|
+
...signedInAs ? { signedInAs } : {}
|
|
17034
|
+
};
|
|
17035
|
+
}
|
|
16802
17036
|
return {
|
|
16803
17037
|
status: "connected",
|
|
16804
17038
|
steps,
|
|
16805
|
-
signIn,
|
|
16806
17039
|
...version ? { squireVersion: version } : {},
|
|
16807
17040
|
...signedInAs ? { signedInAs } : {}
|
|
16808
17041
|
};
|
|
@@ -16829,6 +17062,15 @@ function stringList(value) {
|
|
|
16829
17062
|
function numberOrNull(value) {
|
|
16830
17063
|
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
16831
17064
|
}
|
|
17065
|
+
function epochSeconds(value) {
|
|
17066
|
+
const numeric = numberOrNull(value);
|
|
17067
|
+
if (numeric !== null)
|
|
17068
|
+
return numeric;
|
|
17069
|
+
if (typeof value !== "string")
|
|
17070
|
+
return null;
|
|
17071
|
+
const parsed = Date.parse(value);
|
|
17072
|
+
return Number.isNaN(parsed) ? null : Math.floor(parsed / 1e3);
|
|
17073
|
+
}
|
|
16832
17074
|
function vaultConnectionMeta(raw) {
|
|
16833
17075
|
const record3 = asRecord2(raw);
|
|
16834
17076
|
const reference = String(record3.reference ?? record3.id ?? "");
|
|
@@ -16838,7 +17080,7 @@ function vaultConnectionMeta(raw) {
|
|
|
16838
17080
|
label: String(record3.label ?? record3.service ?? reference),
|
|
16839
17081
|
fieldNames: stringList(record3.field_names ?? record3.fieldNames),
|
|
16840
17082
|
allowedHosts: stringList(record3.allowed_hosts ?? record3.allowedHosts ?? record3.login_hosts),
|
|
16841
|
-
createdAt:
|
|
17083
|
+
createdAt: epochSeconds(record3.created_at ?? record3.createdAt) ?? 0,
|
|
16842
17084
|
stale: record3.stale === true,
|
|
16843
17085
|
state: record3.state === "error" ? "error" : "active"
|
|
16844
17086
|
};
|
|
@@ -16933,7 +17175,7 @@ async function readGoogleCredentialsFromVault(mcp) {
|
|
|
16933
17175
|
};
|
|
16934
17176
|
}
|
|
16935
17177
|
function manualGoogleCredentialsSearchPaths(home) {
|
|
16936
|
-
return [
|
|
17178
|
+
return [join4(home, "google-credentials.json")];
|
|
16937
17179
|
}
|
|
16938
17180
|
function loadManualGoogleCredentials(home, env = process.env) {
|
|
16939
17181
|
if (env.BEELINE_GOOGLE_ACCESS_TOKEN) {
|
|
@@ -16966,7 +17208,7 @@ function loadManualGoogleCredentials(home, env = process.env) {
|
|
|
16966
17208
|
}
|
|
16967
17209
|
function persistManualGoogleCredentials(home, credentials) {
|
|
16968
17210
|
const path = manualGoogleCredentialsSearchPaths(home)[0];
|
|
16969
|
-
|
|
17211
|
+
mkdirSync2(dirname5(path), { recursive: true, mode: 448 });
|
|
16970
17212
|
writeFileSync(path, `${JSON.stringify({
|
|
16971
17213
|
accessToken: credentials.accessToken,
|
|
16972
17214
|
...credentials.refreshToken ? { refreshToken: credentials.refreshToken } : {},
|
|
@@ -17044,10 +17286,10 @@ function describe(error) {
|
|
|
17044
17286
|
}
|
|
17045
17287
|
|
|
17046
17288
|
// apps/body/dist/squire-mcp-client.js
|
|
17047
|
-
import { spawn as
|
|
17289
|
+
import { spawn as spawn6 } from "node:child_process";
|
|
17290
|
+
import { homedir as homedir4 } from "node:os";
|
|
17048
17291
|
var INITIALIZE_TIMEOUT_MS = 3e4;
|
|
17049
17292
|
var CALL_TIMEOUT_MS = 12e4;
|
|
17050
|
-
var SQUIRE_MCP_SERVER_ARGS = ["-y", "@trusty-squire/mcp@latest", "server"];
|
|
17051
17293
|
var StdioSquireMcpClient = class {
|
|
17052
17294
|
options;
|
|
17053
17295
|
child;
|
|
@@ -17101,7 +17343,8 @@ var StdioSquireMcpClient = class {
|
|
|
17101
17343
|
return this.initialized;
|
|
17102
17344
|
}
|
|
17103
17345
|
initialize() {
|
|
17104
|
-
const
|
|
17346
|
+
const launch = squireFacadeLaunch(homedir4());
|
|
17347
|
+
const child = (this.options.spawn ?? spawn6)(this.options.command ?? launch.command, [...this.options.args ?? launch.args], { env: this.options.env ?? { ...squireConnectProcessEnv(), ...launch.env } });
|
|
17105
17348
|
this.child = child;
|
|
17106
17349
|
this.buffer = "";
|
|
17107
17350
|
child.stdout.setEncoding("utf8");
|
|
@@ -17135,12 +17378,12 @@ var StdioSquireMcpClient = class {
|
|
|
17135
17378
|
const child = this.child;
|
|
17136
17379
|
if (!child)
|
|
17137
17380
|
return Promise.reject(new Error("Squire MCP session is not running"));
|
|
17138
|
-
return new Promise((
|
|
17381
|
+
return new Promise((resolve35, reject) => {
|
|
17139
17382
|
const timer = setTimeout(() => {
|
|
17140
17383
|
this.pending.delete(id);
|
|
17141
17384
|
reject(new Error(`${method} timed out`));
|
|
17142
17385
|
}, method === "initialize" ? INITIALIZE_TIMEOUT_MS : CALL_TIMEOUT_MS);
|
|
17143
|
-
this.pending.set(id, { resolve:
|
|
17386
|
+
this.pending.set(id, { resolve: resolve35, reject, timer });
|
|
17144
17387
|
child.stdin.write(`${JSON.stringify({ jsonrpc: "2.0", id, method, params })}
|
|
17145
17388
|
`);
|
|
17146
17389
|
});
|
|
@@ -17184,6 +17427,7 @@ function defaultSquireMcpClient() {
|
|
|
17184
17427
|
|
|
17185
17428
|
// apps/body/dist/connector-assignments.js
|
|
17186
17429
|
var CONNECTOR_POLL_INTERVAL_MS = 1e4;
|
|
17430
|
+
var CEREMONY_EXPIRED = "the Trusty Squire sign-in page expired before it was used \xB7 tap Retry to open a new one";
|
|
17187
17431
|
var ConnectorAssignmentLoop = class {
|
|
17188
17432
|
agentId;
|
|
17189
17433
|
api;
|
|
@@ -17356,6 +17600,25 @@ var ConnectorAssignmentLoop = class {
|
|
|
17356
17600
|
}
|
|
17357
17601
|
/** Install Trusty Squire, reporting every step as it settles. */
|
|
17358
17602
|
async runInstall(connectorId) {
|
|
17603
|
+
const claim = squireConnectSession();
|
|
17604
|
+
const spent = claim ? Date.now() - claim.claimedAt >= CONNECT_TIMEOUT_MS : false;
|
|
17605
|
+
if (claim && !spent && isProcessAlive(claim.pid)) {
|
|
17606
|
+
if (!await this.rearmedByHuman(connectorId)) {
|
|
17607
|
+
this.log(`trusty-squire connect still waiting for sign-in (pid ${String(claim.pid)}); leaving it alone`);
|
|
17608
|
+
return;
|
|
17609
|
+
}
|
|
17610
|
+
this.log("trusty-squire re-pair requested; superseding the connect holding the browser");
|
|
17611
|
+
} else if (spent && (await this.connectorRow(connectorId))?.signIn) {
|
|
17612
|
+
releaseSquireConnectSession((message) => this.log(`[trusty-squire] ${message}`));
|
|
17613
|
+
await this.api.execute("postConnectorStatus", {
|
|
17614
|
+
agentId: this.agentId,
|
|
17615
|
+
connectorId,
|
|
17616
|
+
steps: [{ label: "waiting for sign-in", status: "failed", reason: CEREMONY_EXPIRED }],
|
|
17617
|
+
signIn: null,
|
|
17618
|
+
errorMessage: CEREMONY_EXPIRED
|
|
17619
|
+
});
|
|
17620
|
+
return;
|
|
17621
|
+
}
|
|
17359
17622
|
const report = async (steps) => {
|
|
17360
17623
|
try {
|
|
17361
17624
|
await this.api.execute("postConnectorStatus", { agentId: this.agentId, connectorId, steps });
|
|
@@ -17374,6 +17637,7 @@ var ConnectorAssignmentLoop = class {
|
|
|
17374
17637
|
agentId: this.agentId,
|
|
17375
17638
|
connectorId,
|
|
17376
17639
|
steps: result.steps,
|
|
17640
|
+
signIn: null,
|
|
17377
17641
|
errorMessage: result.errorMessage
|
|
17378
17642
|
});
|
|
17379
17643
|
return;
|
|
@@ -17383,8 +17647,7 @@ var ConnectorAssignmentLoop = class {
|
|
|
17383
17647
|
agentId: this.agentId,
|
|
17384
17648
|
connectorId,
|
|
17385
17649
|
...result.squireVersion ? { squireVersion: result.squireVersion } : {},
|
|
17386
|
-
...result.signedInAs ? { signedInAs: result.signedInAs } : {}
|
|
17387
|
-
...result.signIn ? { signIn: result.signIn } : {}
|
|
17650
|
+
...result.signedInAs ? { signedInAs: result.signedInAs } : {}
|
|
17388
17651
|
});
|
|
17389
17652
|
await this.reportVault(connectorId);
|
|
17390
17653
|
return;
|
|
@@ -17393,11 +17656,37 @@ var ConnectorAssignmentLoop = class {
|
|
|
17393
17656
|
agentId: this.agentId,
|
|
17394
17657
|
connectorId,
|
|
17395
17658
|
steps: result.steps,
|
|
17659
|
+
signIn: result.signIn ?? null,
|
|
17396
17660
|
...result.squireVersion ? { squireVersion: result.squireVersion } : {},
|
|
17397
|
-
...result.signedInAs ? { signedInAs: result.signedInAs } : {}
|
|
17398
|
-
...result.signIn ? { signIn: result.signIn } : {}
|
|
17661
|
+
...result.signedInAs ? { signedInAs: result.signedInAs } : {}
|
|
17399
17662
|
});
|
|
17400
17663
|
}
|
|
17664
|
+
/** This connector's own row, or undefined when the server cannot answer. */
|
|
17665
|
+
async connectorRow(connectorId) {
|
|
17666
|
+
try {
|
|
17667
|
+
const status = await this.api.execute("getConnectorStatus", {
|
|
17668
|
+
agentId: this.agentId,
|
|
17669
|
+
connectorId
|
|
17670
|
+
});
|
|
17671
|
+
return status.connectorId === connectorId ? status : void 0;
|
|
17672
|
+
} catch (error) {
|
|
17673
|
+
this.log(`connector status unavailable: ${describe2(error)}`);
|
|
17674
|
+
return void 0;
|
|
17675
|
+
}
|
|
17676
|
+
}
|
|
17677
|
+
/**
|
|
17678
|
+
* True when a human asked for this connector again while a connect of ours
|
|
17679
|
+
* still holds the browser. `pairConnector` re-arms the row to its default
|
|
17680
|
+
* all-pending steps, so a row whose every step is still pending is a fresh
|
|
17681
|
+
* request; the row carrying the ceremony this helper published has settled
|
|
17682
|
+
* ones. An unreadable row is not evidence of a retry.
|
|
17683
|
+
*/
|
|
17684
|
+
async rearmedByHuman(connectorId) {
|
|
17685
|
+
const status = await this.connectorRow(connectorId);
|
|
17686
|
+
if (!status)
|
|
17687
|
+
return false;
|
|
17688
|
+
return status.steps.length > 0 && status.steps.every((step3) => step3.status === "pending");
|
|
17689
|
+
}
|
|
17401
17690
|
/** One vault report covers every live trusty-squire connector on this helper. */
|
|
17402
17691
|
async runSync() {
|
|
17403
17692
|
await this.reportVault();
|
|
@@ -17542,7 +17831,7 @@ function classifyTurnSilence(reason, reasonKind) {
|
|
|
17542
17831
|
if (/command protocol/i.test(text2) || /refusing intake/i.test(text2) || /helper is out of date/i.test(text2)) {
|
|
17543
17832
|
return { kind: "helper-out-of-date" };
|
|
17544
17833
|
}
|
|
17545
|
-
if (/working copy/i.test(text2) || /could not (?:clone|fetch|checkout)/i.test(text2) || /repository not found/i.test(text2) || /could not resolve host/i.test(text2) || /failed to start corner/i.test(text2) || /unable to access/i.test(text2) || /\bgit clone\b/i.test(text2) || /repository state is not verified/i.test(text2) || /incomplete repository binding/i.test(text2) || /no authoritative objective fact/i.test(text2)) {
|
|
17834
|
+
if (/working copy/i.test(text2) || /could not (?:clone|fetch|checkout)/i.test(text2) || /repository not found/i.test(text2) || /could not resolve host/i.test(text2) || /failed to start corner/i.test(text2) || /unable to access/i.test(text2) || /\bgit clone\b/i.test(text2) || /repository state is not verified/i.test(text2) || /incomplete repository binding/i.test(text2) || /no authoritative objective fact/i.test(text2) || /profile_busy/i.test(text2) || /broker unavailable/i.test(text2)) {
|
|
17546
17835
|
return { kind: "workspace-failure", repo: repoFromReason(text2) };
|
|
17547
17836
|
}
|
|
17548
17837
|
if (/helper isn't running/i.test(text2) || /helper is offline/i.test(text2)) {
|
|
@@ -17563,7 +17852,7 @@ function hiccupBackoffMs(attempt) {
|
|
|
17563
17852
|
}
|
|
17564
17853
|
|
|
17565
17854
|
// apps/body/dist/daemon-api-client.js
|
|
17566
|
-
import { resolve as
|
|
17855
|
+
import { resolve as resolve9 } from "node:path";
|
|
17567
17856
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
17568
17857
|
|
|
17569
17858
|
// node_modules/ws/wrapper.mjs
|
|
@@ -17582,9 +17871,9 @@ import { randomBytes as randomBytes5 } from "node:crypto";
|
|
|
17582
17871
|
import { execFile as execFile2 } from "node:child_process";
|
|
17583
17872
|
import { closeSync, openSync, readFileSync as readFileSync5 } from "node:fs";
|
|
17584
17873
|
import { mkdir as mkdir2, readFile as readFile2, readdir, rename as rename2, stat, unlink as unlink2, writeFile as writeFile3 } from "node:fs/promises";
|
|
17585
|
-
import { homedir as
|
|
17586
|
-
import { dirname as
|
|
17587
|
-
import { spawn as
|
|
17874
|
+
import { homedir as homedir5 } from "node:os";
|
|
17875
|
+
import { dirname as dirname6, resolve as resolve8 } from "node:path";
|
|
17876
|
+
import { spawn as spawn7 } from "node:child_process";
|
|
17588
17877
|
import { promisify } from "node:util";
|
|
17589
17878
|
|
|
17590
17879
|
// node_modules/@noble/hashes/_u64.js
|
|
@@ -21971,7 +22260,7 @@ function alphabet(letters) {
|
|
|
21971
22260
|
};
|
|
21972
22261
|
}
|
|
21973
22262
|
// @__NO_SIDE_EFFECTS__
|
|
21974
|
-
function
|
|
22263
|
+
function join5(separator = "") {
|
|
21975
22264
|
astr("join", separator);
|
|
21976
22265
|
return {
|
|
21977
22266
|
encode: (from) => {
|
|
@@ -22101,8 +22390,8 @@ var base64 = hasBase64Builtin ? {
|
|
|
22101
22390
|
decode(s) {
|
|
22102
22391
|
return decodeBase64Builtin(s, false);
|
|
22103
22392
|
}
|
|
22104
|
-
} : /* @__PURE__ */ chain(/* @__PURE__ */ radix2(6), /* @__PURE__ */ alphabet("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"), /* @__PURE__ */ padding(6), /* @__PURE__ */
|
|
22105
|
-
var BECH_ALPHABET = /* @__PURE__ */ chain(/* @__PURE__ */ alphabet("qpzry9x8gf2tvdw0s3jn54khce6mua7l"), /* @__PURE__ */
|
|
22393
|
+
} : /* @__PURE__ */ chain(/* @__PURE__ */ radix2(6), /* @__PURE__ */ alphabet("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"), /* @__PURE__ */ padding(6), /* @__PURE__ */ join5(""));
|
|
22394
|
+
var BECH_ALPHABET = /* @__PURE__ */ chain(/* @__PURE__ */ alphabet("qpzry9x8gf2tvdw0s3jn54khce6mua7l"), /* @__PURE__ */ join5(""));
|
|
22106
22395
|
var POLYMOD_GENERATORS = [996825010, 642813549, 513874426, 1027748829, 705979059];
|
|
22107
22396
|
function bech32Polymod(pre) {
|
|
22108
22397
|
const b = pre >> 25;
|
|
@@ -26120,15 +26409,15 @@ var DEFAULT_AGENT_IDENTITY_NAME = "beeline-agent";
|
|
|
26120
26409
|
var DEFAULT_BODY_IDENTITY_NAME = "beeline-body";
|
|
26121
26410
|
var DEFAULT_DAEMON_MONOLITH_BASE_URL = "https://server.usebeeline.app";
|
|
26122
26411
|
function defaultSupervisorRoot(env = process.env) {
|
|
26123
|
-
return
|
|
26412
|
+
return resolve8(env.XDG_STATE_HOME ?? resolve8(homedir5(), ".local", "state"));
|
|
26124
26413
|
}
|
|
26125
26414
|
function runtimeDirectory(supervisorRoot, publicKey) {
|
|
26126
26415
|
if (!/^[0-9a-f]{64}$/i.test(publicKey))
|
|
26127
26416
|
throw new Error("invalid agent public key");
|
|
26128
|
-
return
|
|
26417
|
+
return resolve8(supervisorRoot, "beeline", "agents", publicKey.toLowerCase());
|
|
26129
26418
|
}
|
|
26130
26419
|
function runtimeConfigPath(supervisorRoot, publicKey) {
|
|
26131
|
-
return
|
|
26420
|
+
return resolve8(runtimeDirectory(supervisorRoot, publicKey), "runtime.json");
|
|
26132
26421
|
}
|
|
26133
26422
|
function identityFromKey(value, name) {
|
|
26134
26423
|
const secretKey = value ? value.startsWith("nsec1") ? decodeNsec(value) : Uint8Array.from(Buffer.from(value, "hex")) : randomBytes5(32);
|
|
@@ -26164,7 +26453,7 @@ function runtimeAgentCommand(runtime, env = process.env) {
|
|
|
26164
26453
|
}
|
|
26165
26454
|
async function writeRuntimeRecord(runtime) {
|
|
26166
26455
|
const path = runtimeConfigPath(runtime.supervisorRoot, runtime.agent.publicKey);
|
|
26167
|
-
await mkdir2(
|
|
26456
|
+
await mkdir2(dirname6(path), { recursive: true, mode: 448 });
|
|
26168
26457
|
const staged = `${path}.${process.pid}.tmp`;
|
|
26169
26458
|
await writeFile3(staged, `${JSON.stringify(runtime, null, 2)}
|
|
26170
26459
|
`, { mode: 384 });
|
|
@@ -26190,7 +26479,7 @@ async function migrateRuntimeRecordAccessPolicy(path) {
|
|
|
26190
26479
|
return { runtime, migrated: true };
|
|
26191
26480
|
}
|
|
26192
26481
|
async function stageMonolithAgentRuntime(input) {
|
|
26193
|
-
const supervisorRoot = input.supervisorRoot ?
|
|
26482
|
+
const supervisorRoot = input.supervisorRoot ? resolve8(input.supervisorRoot) : defaultSupervisorRoot();
|
|
26194
26483
|
const configPath = runtimeConfigPath(supervisorRoot, input.agentIdentity.publicKey);
|
|
26195
26484
|
const configuredBaseUrl = input.monolithBaseUrl ?? DEFAULT_DAEMON_MONOLITH_BASE_URL;
|
|
26196
26485
|
const baseUrl = new URL(configuredBaseUrl).origin;
|
|
@@ -26235,9 +26524,9 @@ async function stageMonolithAgentRuntime(input) {
|
|
|
26235
26524
|
return { runtime, configPath };
|
|
26236
26525
|
}
|
|
26237
26526
|
async function runtimePaths(root) {
|
|
26238
|
-
const agents =
|
|
26527
|
+
const agents = resolve8(root, "beeline", "agents");
|
|
26239
26528
|
const entries = await readdir(agents, { withFileTypes: true }).catch(() => []);
|
|
26240
|
-
return entries.filter((entry) => entry.isDirectory()).map((entry) =>
|
|
26529
|
+
return entries.filter((entry) => entry.isDirectory()).map((entry) => resolve8(agents, entry.name, "runtime.json"));
|
|
26241
26530
|
}
|
|
26242
26531
|
async function findAgentRuntimeConfigPaths(env = process.env, _cwd = process.cwd()) {
|
|
26243
26532
|
return runtimePaths(defaultSupervisorRoot(env));
|
|
@@ -26246,13 +26535,13 @@ async function findRuntimeConfigPaths(cwd = process.cwd(), env = process.env) {
|
|
|
26246
26535
|
return findAgentRuntimeConfigPaths(env, cwd);
|
|
26247
26536
|
}
|
|
26248
26537
|
async function resolveRuntimeConfigPath(path) {
|
|
26249
|
-
return
|
|
26538
|
+
return resolve8(path);
|
|
26250
26539
|
}
|
|
26251
26540
|
async function selectRuntimeConfigPaths(options) {
|
|
26252
26541
|
const hostScope = true;
|
|
26253
26542
|
const configs = await options.findHostRuntimes(options.cwd);
|
|
26254
26543
|
const requestedPubkey = options.requestedPubkey;
|
|
26255
|
-
const paths = requestedPubkey ? configs.filter((path) =>
|
|
26544
|
+
const paths = requestedPubkey ? configs.filter((path) => dirname6(path).endsWith(requestedPubkey)) : [...new Set(configs)];
|
|
26256
26545
|
if (!paths.length)
|
|
26257
26546
|
throw new Error(options.noRuntimeMessage(hostScope));
|
|
26258
26547
|
if (options.requestedPubkey && paths.length > 1)
|
|
@@ -26260,10 +26549,10 @@ async function selectRuntimeConfigPaths(options) {
|
|
|
26260
26549
|
return { paths, hostScope };
|
|
26261
26550
|
}
|
|
26262
26551
|
function daemonPidPath(configPath) {
|
|
26263
|
-
return
|
|
26552
|
+
return resolve8(dirname6(configPath), "daemon.pid");
|
|
26264
26553
|
}
|
|
26265
26554
|
function daemonBirthPath(configPath) {
|
|
26266
|
-
return
|
|
26555
|
+
return resolve8(dirname6(configPath), "daemon.birth");
|
|
26267
26556
|
}
|
|
26268
26557
|
function processBirthIdentity(pid) {
|
|
26269
26558
|
try {
|
|
@@ -26275,7 +26564,7 @@ function processBirthIdentity(pid) {
|
|
|
26275
26564
|
}
|
|
26276
26565
|
}
|
|
26277
26566
|
async function writeDaemonPidRecord(configPath, pid) {
|
|
26278
|
-
const directory =
|
|
26567
|
+
const directory = dirname6(configPath);
|
|
26279
26568
|
await mkdir2(directory, { recursive: true, mode: 448 });
|
|
26280
26569
|
await writeFile3(daemonPidPath(configPath), `${pid}
|
|
26281
26570
|
`, { mode: 384 });
|
|
@@ -26299,11 +26588,11 @@ async function daemonIsThisRuntime(pid, configPath) {
|
|
|
26299
26588
|
try {
|
|
26300
26589
|
const argv = (await readFile2(`/proc/${pid}/cmdline`, "utf8")).split("\0").filter(Boolean);
|
|
26301
26590
|
const flag = argv.lastIndexOf("--config");
|
|
26302
|
-
return flag > 0 && argv[flag - 1] === "daemon" &&
|
|
26591
|
+
return flag > 0 && argv[flag - 1] === "daemon" && resolve8(argv[flag + 1]) === resolve8(configPath);
|
|
26303
26592
|
} catch {
|
|
26304
26593
|
try {
|
|
26305
26594
|
const { stdout: stdout6 } = await execFileAsync("ps", ["-p", String(pid), "-o", "command="]);
|
|
26306
|
-
return stdout6.includes(" daemon ") && stdout6.includes(
|
|
26595
|
+
return stdout6.includes(" daemon ") && stdout6.includes(resolve8(configPath));
|
|
26307
26596
|
} catch {
|
|
26308
26597
|
return false;
|
|
26309
26598
|
}
|
|
@@ -26356,14 +26645,14 @@ async function stopRuntimeDaemon(path, opts = {}) {
|
|
|
26356
26645
|
throw new Error(`agent daemon ${pid} did not stop after ${timeout}ms`);
|
|
26357
26646
|
}
|
|
26358
26647
|
async function launchRuntimeDaemon(configPath, opts = {}) {
|
|
26359
|
-
const directory =
|
|
26648
|
+
const directory = dirname6(configPath);
|
|
26360
26649
|
await mkdir2(directory, { recursive: true, mode: 448 });
|
|
26361
26650
|
const foreground = opts.foreground === true;
|
|
26362
|
-
const output = foreground ? "inherit" : openSync(
|
|
26651
|
+
const output = foreground ? "inherit" : openSync(resolve8(directory, "daemon.log"), "a", 384);
|
|
26363
26652
|
const entrypoint = opts.entrypoint ?? process.argv[1];
|
|
26364
26653
|
if (!entrypoint)
|
|
26365
26654
|
throw new Error("cannot resolve daemon CLI entrypoint");
|
|
26366
|
-
const child =
|
|
26655
|
+
const child = spawn7(process.execPath, [...opts.execArgv ?? [], entrypoint, "daemon", "--config", resolve8(configPath)], {
|
|
26367
26656
|
cwd: directory,
|
|
26368
26657
|
env: opts.env ?? process.env,
|
|
26369
26658
|
detached: !foreground,
|
|
@@ -26625,8 +26914,8 @@ var DaemonApiClient = class {
|
|
|
26625
26914
|
};
|
|
26626
26915
|
async function activateDaemonTransport(path, fetchImpl = fetch) {
|
|
26627
26916
|
const runtime = await readRuntimeRecord(path);
|
|
26628
|
-
const expectedPath =
|
|
26629
|
-
if (
|
|
26917
|
+
const expectedPath = resolve9(runtimeDirectory(runtime.supervisorRoot, runtime.agent.publicKey), "runtime.json");
|
|
26918
|
+
if (resolve9(path) !== expectedPath) {
|
|
26630
26919
|
throw new Error(`refusing daemon token exchange outside canonical runtime path: ${path}`);
|
|
26631
26920
|
}
|
|
26632
26921
|
const transport = runtime.transport;
|
|
@@ -26667,9 +26956,9 @@ async function activateDaemonTransport(path, fetchImpl = fetch) {
|
|
|
26667
26956
|
// apps/body/dist/room-runtime.js
|
|
26668
26957
|
import { execFile as execFile6 } from "node:child_process";
|
|
26669
26958
|
import { createHash as createHash7 } from "node:crypto";
|
|
26670
|
-
import { existsSync as
|
|
26959
|
+
import { existsSync as existsSync6, mkdirSync as mkdirSync3 } from "node:fs";
|
|
26671
26960
|
import { mkdir as mkdir14, rm as rm5 } from "node:fs/promises";
|
|
26672
|
-
import { dirname as
|
|
26961
|
+
import { dirname as dirname12, resolve as resolve23 } from "node:path";
|
|
26673
26962
|
import { promisify as promisify4 } from "node:util";
|
|
26674
26963
|
|
|
26675
26964
|
// apps/body/dist/grant-runner.js
|
|
@@ -26677,10 +26966,10 @@ import { execFile as execFile3 } from "node:child_process";
|
|
|
26677
26966
|
import { createHash as createHash3, randomBytes as randomBytes6 } from "node:crypto";
|
|
26678
26967
|
import { readFile as readFile4 } from "node:fs/promises";
|
|
26679
26968
|
import { createServer } from "node:http";
|
|
26680
|
-
import { dirname as
|
|
26969
|
+
import { dirname as dirname8, resolve as resolve12 } from "node:path";
|
|
26681
26970
|
|
|
26682
26971
|
// packages/api-contract/dist/agent-grants.js
|
|
26683
|
-
var AGENT_GRANT_KINDS = ["path", "host", "secret", "device", "budget", "command"];
|
|
26972
|
+
var AGENT_GRANT_KINDS = ["path", "host", "secret", "device", "budget", "command", "mcp"];
|
|
26684
26973
|
var SHELL_METACHARACTERS = /[;&|<>$`\\'"(){}\n\r\t*?[\]~#!]/;
|
|
26685
26974
|
var SECRET_NAME = /^[A-Z][A-Z0-9_]{0,63}$/;
|
|
26686
26975
|
function parseCommandGrantTarget(target) {
|
|
@@ -26900,9 +27189,9 @@ function surfaceAllows(surface, capability) {
|
|
|
26900
27189
|
|
|
26901
27190
|
// apps/body/dist/bwrap-sandbox.js
|
|
26902
27191
|
import { spawnSync } from "node:child_process";
|
|
26903
|
-
import { lstatSync as
|
|
26904
|
-
import { homedir as
|
|
26905
|
-
import { isAbsolute as isAbsolute2, relative, resolve as
|
|
27192
|
+
import { lstatSync as lstatSync4 } from "node:fs";
|
|
27193
|
+
import { homedir as homedir6 } from "node:os";
|
|
27194
|
+
import { isAbsolute as isAbsolute2, relative, resolve as resolve10 } from "node:path";
|
|
26906
27195
|
var DEFAULT_SANDBOX_POLICY = "bwrap";
|
|
26907
27196
|
function isSandboxPolicy(value) {
|
|
26908
27197
|
return value === "bwrap" || value === "off";
|
|
@@ -26938,35 +27227,34 @@ var HARNESS_HOME_STATE_DIRS = [
|
|
|
26938
27227
|
dirs: [".cursor"]
|
|
26939
27228
|
}
|
|
26940
27229
|
];
|
|
26941
|
-
function harnessHomeStateDirs(agentCommand, home =
|
|
27230
|
+
function harnessHomeStateDirs(agentCommand, home = homedir6()) {
|
|
26942
27231
|
if (!agentCommand)
|
|
26943
27232
|
return [];
|
|
26944
27233
|
for (const { match, dirs } of HARNESS_HOME_STATE_DIRS) {
|
|
26945
27234
|
if (match.test(agentCommand))
|
|
26946
|
-
return dirs.map((dir) =>
|
|
27235
|
+
return dirs.map((dir) => resolve10(home, dir));
|
|
26947
27236
|
}
|
|
26948
27237
|
return [];
|
|
26949
27238
|
}
|
|
26950
27239
|
var KNOWN_CREDENTIAL_MASK_PATHS = [
|
|
26951
27240
|
".config/gh",
|
|
26952
|
-
".config/trusty-squire",
|
|
26953
27241
|
".ssh",
|
|
26954
27242
|
".netrc",
|
|
26955
27243
|
".git-credentials",
|
|
26956
27244
|
".secrets.env"
|
|
26957
27245
|
];
|
|
26958
|
-
function credentialMaskPaths(extraPaths, home =
|
|
27246
|
+
function credentialMaskPaths(extraPaths, home = homedir6(), stat5 = (path) => {
|
|
26959
27247
|
try {
|
|
26960
|
-
const info =
|
|
27248
|
+
const info = lstatSync4(path);
|
|
26961
27249
|
return { isDirectory: info.isDirectory() };
|
|
26962
27250
|
} catch {
|
|
26963
27251
|
return void 0;
|
|
26964
27252
|
}
|
|
26965
27253
|
}, requiredPaths = []) {
|
|
26966
|
-
const required = new Set(requiredPaths.map((path) =>
|
|
27254
|
+
const required = new Set(requiredPaths.map((path) => resolve10(path)));
|
|
26967
27255
|
const candidates = [
|
|
26968
|
-
...KNOWN_CREDENTIAL_MASK_PATHS.map((entry) =>
|
|
26969
|
-
...(extraPaths ?? []).map((entry) =>
|
|
27256
|
+
...KNOWN_CREDENTIAL_MASK_PATHS.map((entry) => resolve10(home, entry)),
|
|
27257
|
+
...(extraPaths ?? []).map((entry) => resolve10(entry))
|
|
26970
27258
|
];
|
|
26971
27259
|
const seen = /* @__PURE__ */ new Set();
|
|
26972
27260
|
const masks = [];
|
|
@@ -26993,7 +27281,7 @@ function normalize(paths) {
|
|
|
26993
27281
|
for (const path of paths) {
|
|
26994
27282
|
if (!path)
|
|
26995
27283
|
continue;
|
|
26996
|
-
seen.add(
|
|
27284
|
+
seen.add(resolve10(path));
|
|
26997
27285
|
}
|
|
26998
27286
|
return Array.from(seen).sort();
|
|
26999
27287
|
}
|
|
@@ -27031,7 +27319,7 @@ function sandboxMountPlan(spec) {
|
|
|
27031
27319
|
writable,
|
|
27032
27320
|
quotaTmpfs: spec.workbench ? [
|
|
27033
27321
|
{
|
|
27034
|
-
target:
|
|
27322
|
+
target: resolve10(spec.workbench.dir),
|
|
27035
27323
|
maxBytes: spec.workbench.maxBytes,
|
|
27036
27324
|
maxInodes: spec.workbench.maxInodes,
|
|
27037
27325
|
blockGit: true
|
|
@@ -27086,7 +27374,7 @@ function buildBwrapArgv(input) {
|
|
|
27086
27374
|
for (const binding of quotaTmpfs) {
|
|
27087
27375
|
args.push("--dir", binding.target, "--size", String(binding.maxBytes), "--tmpfs", binding.target);
|
|
27088
27376
|
if (binding.blockGit)
|
|
27089
|
-
args.push("--ro-bind", "/dev/null",
|
|
27377
|
+
args.push("--ro-bind", "/dev/null", resolve10(binding.target, ".git"));
|
|
27090
27378
|
}
|
|
27091
27379
|
args.push("--chdir", input.cwd);
|
|
27092
27380
|
args.push("--die-with-parent");
|
|
@@ -27146,14 +27434,14 @@ function detectBwrapSandbox(options = {}) {
|
|
|
27146
27434
|
}
|
|
27147
27435
|
return {
|
|
27148
27436
|
path: bwrapPath,
|
|
27149
|
-
advisory: `harness OS sandbox ENABLED via ${bwrapPath}: every ACP child gets a read-only filesystem plus a private /tmp and PID namespace, writable only in its own harness state; ambient credential stores (~/.config/gh, ~/.
|
|
27437
|
+
advisory: `harness OS sandbox ENABLED via ${bwrapPath}: every ACP child gets a read-only filesystem plus a private /tmp and PID namespace, writable only in its own harness state; ambient credential stores (~/.config/gh, ~/.ssh, ~/.netrc, ~/.git-credentials) are masked absent; a repository corner adds its worktree and git dir, then receives its linked repository's GitHub App credential. Hygiene boundary, not confinement \u2014 it shapes where sessions write files and does not restrict other access this account has (e.g. sockets, container runtimes, secrets not on the mask list)`
|
|
27150
27438
|
};
|
|
27151
27439
|
}
|
|
27152
27440
|
|
|
27153
27441
|
// apps/body/dist/provider-key-store.js
|
|
27154
27442
|
import { chmod as chmod2, mkdir as mkdir3, readFile as readFile3, writeFile as writeFile4 } from "node:fs/promises";
|
|
27155
|
-
import { homedir as
|
|
27156
|
-
import { dirname as
|
|
27443
|
+
import { homedir as homedir7 } from "node:os";
|
|
27444
|
+
import { dirname as dirname7, resolve as resolve11 } from "node:path";
|
|
27157
27445
|
var PROVIDER_KEY_ENV_VARS = {
|
|
27158
27446
|
openrouter: "OPENROUTER_API_KEY",
|
|
27159
27447
|
openai: "OPENAI_API_KEY",
|
|
@@ -27163,8 +27451,8 @@ var PROVIDER_KEY_ENV_VARS = {
|
|
|
27163
27451
|
};
|
|
27164
27452
|
var GOOGLE_ENV_ALIAS = "GEMINI_API_KEY";
|
|
27165
27453
|
function providerKeyStorePath(env = process.env) {
|
|
27166
|
-
const configRoot = env.XDG_CONFIG_HOME?.trim() ||
|
|
27167
|
-
return
|
|
27454
|
+
const configRoot = env.XDG_CONFIG_HOME?.trim() || resolve11(homedir7(), ".config");
|
|
27455
|
+
return resolve11(configRoot, "beeline", "providers.json");
|
|
27168
27456
|
}
|
|
27169
27457
|
async function readProviderKeyStore(env = process.env) {
|
|
27170
27458
|
const path = providerKeyStorePath(env);
|
|
@@ -27187,7 +27475,7 @@ async function readSavedProviderKey(provider, env = process.env) {
|
|
|
27187
27475
|
async function saveProviderKey(provider, key, env = process.env) {
|
|
27188
27476
|
const path = providerKeyStorePath(env);
|
|
27189
27477
|
const store = { ...await readProviderKeyStore(env), [provider]: key };
|
|
27190
|
-
await mkdir3(
|
|
27478
|
+
await mkdir3(dirname7(path), { recursive: true, mode: 448 });
|
|
27191
27479
|
await writeFile4(path, `${JSON.stringify(store, null, 2)}
|
|
27192
27480
|
`, { mode: 384 });
|
|
27193
27481
|
await chmod2(path, 384);
|
|
@@ -27224,7 +27512,7 @@ function operatorSecretResolver(env = process.env) {
|
|
|
27224
27512
|
if (saved)
|
|
27225
27513
|
return saved;
|
|
27226
27514
|
}
|
|
27227
|
-
const raw = await readFile4(
|
|
27515
|
+
const raw = await readFile4(resolve12(dirname8(providerKeyStorePath(env)), "secrets.json"), "utf8").catch(() => void 0);
|
|
27228
27516
|
if (!raw)
|
|
27229
27517
|
return void 0;
|
|
27230
27518
|
try {
|
|
@@ -27336,9 +27624,9 @@ var GrantCommandRunner = class {
|
|
|
27336
27624
|
...Object.fromEntries(secrets)
|
|
27337
27625
|
};
|
|
27338
27626
|
const cap = this.options.outputCapBytes ?? GRANT_COMMAND_OUTPUT_CAP_BYTES;
|
|
27339
|
-
const
|
|
27627
|
+
const spawn13 = surfaceAllows(policy.surface, "run-host-command") ? { command: argv[0], args: argv.slice(1) } : roomSandboxCommand(policy, room.cwd, argv);
|
|
27340
27628
|
const outcome = await new Promise((resolveRun) => {
|
|
27341
|
-
const child = execFile3(
|
|
27629
|
+
const child = execFile3(spawn13.command, spawn13.args, {
|
|
27342
27630
|
cwd: room.cwd,
|
|
27343
27631
|
env,
|
|
27344
27632
|
timeout: this.options.timeoutMs ?? GRANT_COMMAND_TIMEOUT_MS,
|
|
@@ -27426,8 +27714,8 @@ function scriptCandidates(cwd, scratch, argv) {
|
|
|
27426
27714
|
if (!argument)
|
|
27427
27715
|
return [];
|
|
27428
27716
|
const paths = [
|
|
27429
|
-
|
|
27430
|
-
...scratch ? [
|
|
27717
|
+
resolve12(cwd, argument.path),
|
|
27718
|
+
...scratch ? [resolve12(scratch, argument.path)] : []
|
|
27431
27719
|
];
|
|
27432
27720
|
return [...new Set(paths)];
|
|
27433
27721
|
}
|
|
@@ -27630,17 +27918,17 @@ function captureConnectionUsage(recorder, turn, calls) {
|
|
|
27630
27918
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
27631
27919
|
import { mkdir as mkdir4, writeFile as writeFile5 } from "node:fs/promises";
|
|
27632
27920
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
27633
|
-
import { dirname as
|
|
27921
|
+
import { dirname as dirname9, join as join6 } from "node:path";
|
|
27634
27922
|
var CommandExecutionContext = class {
|
|
27635
27923
|
generationId = randomUUID3();
|
|
27636
27924
|
path;
|
|
27637
27925
|
current;
|
|
27638
27926
|
constructor(root) {
|
|
27639
|
-
this.path =
|
|
27927
|
+
this.path = join6(root ?? tmpdir3(), `beeline-command-${this.generationId}.json`);
|
|
27640
27928
|
}
|
|
27641
27929
|
async enter(command) {
|
|
27642
27930
|
this.current = command;
|
|
27643
|
-
await mkdir4(
|
|
27931
|
+
await mkdir4(dirname9(this.path), { recursive: true });
|
|
27644
27932
|
await writeFile5(this.path, JSON.stringify({
|
|
27645
27933
|
roomId: command.roomId,
|
|
27646
27934
|
requestId: command.turnRequestId,
|
|
@@ -27762,13 +28050,13 @@ async function runServerCommandIntake(options) {
|
|
|
27762
28050
|
}
|
|
27763
28051
|
}
|
|
27764
28052
|
options.onPoll?.();
|
|
27765
|
-
const reconcile = await new Promise((
|
|
28053
|
+
const reconcile = await new Promise((resolve35) => {
|
|
27766
28054
|
const done = (needed) => {
|
|
27767
28055
|
if (timer)
|
|
27768
28056
|
clearTimeout(timer);
|
|
27769
28057
|
signal?.removeEventListener("abort", aborted);
|
|
27770
28058
|
wake = void 0;
|
|
27771
|
-
|
|
28059
|
+
resolve35(needed);
|
|
27772
28060
|
};
|
|
27773
28061
|
const aborted = () => done(false);
|
|
27774
28062
|
wake = done;
|
|
@@ -27796,13 +28084,13 @@ async function runServerCommandIntake(options) {
|
|
|
27796
28084
|
import { execFile as execFile5 } from "node:child_process";
|
|
27797
28085
|
import { createHash as createHash6 } from "node:crypto";
|
|
27798
28086
|
import { mkdir as mkdir13 } from "node:fs/promises";
|
|
27799
|
-
import { homedir as
|
|
27800
|
-
import { join as
|
|
28087
|
+
import { homedir as homedir10 } from "node:os";
|
|
28088
|
+
import { join as join12 } from "node:path";
|
|
27801
28089
|
import { promisify as promisify3 } from "node:util";
|
|
27802
28090
|
|
|
27803
28091
|
// apps/body/dist/agent-home.js
|
|
27804
|
-
var
|
|
27805
|
-
import { existsSync as
|
|
28092
|
+
var import_yaml2 = __toESM(require_dist(), 1);
|
|
28093
|
+
import { existsSync as existsSync5, readFileSync as readFileSync7 } from "node:fs";
|
|
27806
28094
|
|
|
27807
28095
|
// node_modules/smol-toml/dist/date.js
|
|
27808
28096
|
var DATE_TIME_RE = /^(\d{4}-\d{2}-\d{2})?[T ]?(?:(\d{2}):\d{2}(?::\d{2}(?:\.\d+)?)?)?(Z|[-+]\d{2}:\d{2})?$/i;
|
|
@@ -28601,12 +28889,12 @@ function stringify(obj, { maxDepth = 1e3, numbersAsFloat = false } = {}) {
|
|
|
28601
28889
|
// apps/body/dist/agent-home.js
|
|
28602
28890
|
import { createHash as createHash4, randomUUID as randomUUID4 } from "node:crypto";
|
|
28603
28891
|
import { chmod as chmod3, copyFile, lstat as lstat2, mkdir as mkdir6, readFile as readFile6, readdir as readdir2, realpath, rename as rename3, rm as rm2, symlink, unlink as unlink3, writeFile as writeFile7 } from "node:fs/promises";
|
|
28604
|
-
import { homedir as
|
|
28605
|
-
import { basename as basename5, dirname as
|
|
28892
|
+
import { homedir as homedir8 } from "node:os";
|
|
28893
|
+
import { basename as basename5, dirname as dirname10, join as join8, relative as relative2, resolve as resolve16, sep } from "node:path";
|
|
28606
28894
|
|
|
28607
28895
|
// apps/body/dist/beeline-skill.js
|
|
28608
28896
|
import { readFileSync as readFileSync6 } from "node:fs";
|
|
28609
|
-
import { resolve as
|
|
28897
|
+
import { resolve as resolve13 } from "node:path";
|
|
28610
28898
|
|
|
28611
28899
|
// packages/api-contract/dist/workbench.js
|
|
28612
28900
|
var CONNECTABLE_CONNECTOR_KINDS = [
|
|
@@ -28621,6 +28909,13 @@ var CONNECTABLE_CONNECTOR_KINDS = [
|
|
|
28621
28909
|
var CONNECTOR_OFFER_WINDOW_MS = 2 * 6e4;
|
|
28622
28910
|
var OFFERABLE_CONNECTOR_KINDS = CONNECTABLE_CONNECTOR_KINDS.filter((kind) => kind !== "wallet");
|
|
28623
28911
|
|
|
28912
|
+
// packages/api-contract/dist/phone-guards.js
|
|
28913
|
+
var CLOSED_VIEWER = {
|
|
28914
|
+
identity: { pubkey: "0".repeat(64), kind: "human", name: "" },
|
|
28915
|
+
role: "member",
|
|
28916
|
+
permissions: { send: false, manage: false }
|
|
28917
|
+
};
|
|
28918
|
+
|
|
28624
28919
|
// packages/api-contract/dist/agent-pairing-code.js
|
|
28625
28920
|
var CURRENT_AGENT_PAIRING_CODE = /^[0-9A-F]{8}-[0-9A-F]{8}$/;
|
|
28626
28921
|
var LEGACY_AGENT_PAIRING_CODE = /^BUZZ-(?:[0-9A-F]{8}-[0-9A-F]{8}|[A-HJ-NP-Z2-9]{4}-[A-HJ-NP-Z2-9]{4})$/;
|
|
@@ -28694,7 +28989,7 @@ function runningBeelineReleaseId(env = process.env, read = (path) => readFileSyn
|
|
|
28694
28989
|
const lib = env.BEELINE_LIB_DIR;
|
|
28695
28990
|
if (!lib)
|
|
28696
28991
|
return "source";
|
|
28697
|
-
const manifest = JSON.parse(read(
|
|
28992
|
+
const manifest = JSON.parse(read(resolve13(lib, "bundle.json")));
|
|
28698
28993
|
return [manifest.version, manifest.commit].filter(Boolean).join("-") || "source";
|
|
28699
28994
|
} catch {
|
|
28700
28995
|
return "source";
|
|
@@ -28978,9 +29273,151 @@ function stringArray(value) {
|
|
|
28978
29273
|
return Array.isArray(value) && value.every((entry) => typeof entry === "string") ? value : [];
|
|
28979
29274
|
}
|
|
28980
29275
|
|
|
29276
|
+
// apps/body/dist/host-mcp-route.js
|
|
29277
|
+
import { join as join7, resolve as resolve14 } from "node:path";
|
|
29278
|
+
var import_yaml = __toESM(require_dist(), 1);
|
|
29279
|
+
function grantedMcpServerNames(grants) {
|
|
29280
|
+
const names = /* @__PURE__ */ new Set();
|
|
29281
|
+
for (const grant of grants ?? []) {
|
|
29282
|
+
if (grant.kind !== "mcp")
|
|
29283
|
+
continue;
|
|
29284
|
+
const name = grant.target.trim();
|
|
29285
|
+
if (name)
|
|
29286
|
+
names.add(name);
|
|
29287
|
+
}
|
|
29288
|
+
return [...names];
|
|
29289
|
+
}
|
|
29290
|
+
function ungatedHostServers(hostServers, granted) {
|
|
29291
|
+
const allowed = new Set(granted);
|
|
29292
|
+
return hostServers.filter((name) => !allowed.has(name));
|
|
29293
|
+
}
|
|
29294
|
+
function grantedHostRoutesFromList(result) {
|
|
29295
|
+
if (!result || typeof result !== "object" || !("grants" in result))
|
|
29296
|
+
return [];
|
|
29297
|
+
const grants = result.grants;
|
|
29298
|
+
if (!Array.isArray(grants))
|
|
29299
|
+
return [];
|
|
29300
|
+
return grantedMcpServerNames(grants.flatMap((entry) => {
|
|
29301
|
+
if (!entry || typeof entry !== "object")
|
|
29302
|
+
return [];
|
|
29303
|
+
const row = entry;
|
|
29304
|
+
return typeof row.kind === "string" && typeof row.target === "string" ? [{ kind: row.kind, target: row.target }] : [];
|
|
29305
|
+
}));
|
|
29306
|
+
}
|
|
29307
|
+
function recordValue(value) {
|
|
29308
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
29309
|
+
}
|
|
29310
|
+
function stringArray2(value) {
|
|
29311
|
+
return Array.isArray(value) && value.every((entry) => typeof entry === "string") ? value : [];
|
|
29312
|
+
}
|
|
29313
|
+
function isSquireDeclaration(name, declaration) {
|
|
29314
|
+
if (isCodeOwnedHostMcpName(name))
|
|
29315
|
+
return true;
|
|
29316
|
+
const command = typeof declaration.command === "string" && declaration.command || typeof declaration.cmd === "string" && declaration.cmd || "";
|
|
29317
|
+
return Boolean(command) && isTrustySquireMcpLaunch(command, stringArray2(declaration.args));
|
|
29318
|
+
}
|
|
29319
|
+
function grantedSquireHostRoute(granted, declarations = {}) {
|
|
29320
|
+
return granted.some((name) => {
|
|
29321
|
+
if (isCodeOwnedHostMcpName(name))
|
|
29322
|
+
return true;
|
|
29323
|
+
const declaration = declarations[name];
|
|
29324
|
+
return Boolean(declaration && isSquireDeclaration(name, declaration));
|
|
29325
|
+
});
|
|
29326
|
+
}
|
|
29327
|
+
function hostRouteEnv(hostHome) {
|
|
29328
|
+
return { XDG_CONFIG_HOME: join7(resolve14(hostHome), ".config") };
|
|
29329
|
+
}
|
|
29330
|
+
function rewriteHostMcpDeclaration(name, declaration, hostHome) {
|
|
29331
|
+
const next = { ...declaration };
|
|
29332
|
+
delete next[MCP_ROUTE_CLASS_KEY];
|
|
29333
|
+
const launch = isSquireDeclaration(name, declaration) ? squireFacadeLaunch(hostHome) : void 0;
|
|
29334
|
+
const routeEnv = launch?.env ?? hostRouteEnv(hostHome);
|
|
29335
|
+
const gooseShape = "cmd" in declaration && !("command" in declaration);
|
|
29336
|
+
if (launch) {
|
|
29337
|
+
if (gooseShape)
|
|
29338
|
+
next.cmd = launch.command;
|
|
29339
|
+
else
|
|
29340
|
+
next.command = launch.command;
|
|
29341
|
+
next.args = launch.args;
|
|
29342
|
+
}
|
|
29343
|
+
if (gooseShape)
|
|
29344
|
+
next.envs = { ...recordValue(declaration.envs), ...routeEnv };
|
|
29345
|
+
else
|
|
29346
|
+
next.env = { ...recordValue(declaration.env), ...routeEnv };
|
|
29347
|
+
return next;
|
|
29348
|
+
}
|
|
29349
|
+
function rewriteGrantedHostRoutes(declarations, granted, hostHome) {
|
|
29350
|
+
const allowed = new Set(granted);
|
|
29351
|
+
const rewritten = {};
|
|
29352
|
+
for (const [name, declaration] of Object.entries(declarations)) {
|
|
29353
|
+
if (!allowed.has(name))
|
|
29354
|
+
continue;
|
|
29355
|
+
if (classifyImportedMcpServer({ name, declaration }) !== "host")
|
|
29356
|
+
continue;
|
|
29357
|
+
rewritten[name] = rewriteHostMcpDeclaration(name, declaration, hostHome);
|
|
29358
|
+
}
|
|
29359
|
+
for (const name of granted) {
|
|
29360
|
+
if (rewritten[name] || !isCodeOwnedHostMcpName(name))
|
|
29361
|
+
continue;
|
|
29362
|
+
rewritten[name] = rewriteHostMcpDeclaration(name, {}, hostHome);
|
|
29363
|
+
}
|
|
29364
|
+
return rewritten;
|
|
29365
|
+
}
|
|
29366
|
+
function grantedHostRouteWires(granted, hostHome, declarations = {}) {
|
|
29367
|
+
const routes = rewriteGrantedHostRoutes(declarations, granted, hostHome);
|
|
29368
|
+
return Object.entries(routes).flatMap(([name, declaration]) => {
|
|
29369
|
+
const command = typeof declaration.command === "string" && declaration.command || typeof declaration.cmd === "string" && declaration.cmd || "";
|
|
29370
|
+
if (!command)
|
|
29371
|
+
return [];
|
|
29372
|
+
const envRecord = recordValue(declaration.env) ?? recordValue(declaration.envs) ?? {};
|
|
29373
|
+
const env = Object.entries(envRecord).flatMap(([envName, value]) => typeof value === "string" ? [{ name: envName, value }] : []);
|
|
29374
|
+
return [
|
|
29375
|
+
{
|
|
29376
|
+
name,
|
|
29377
|
+
command,
|
|
29378
|
+
args: stringArray2(declaration.args),
|
|
29379
|
+
...env.length ? { env } : {}
|
|
29380
|
+
}
|
|
29381
|
+
];
|
|
29382
|
+
});
|
|
29383
|
+
}
|
|
29384
|
+
function mergeTomlHostRoutes(existing, routes) {
|
|
29385
|
+
if (Object.keys(routes).length === 0)
|
|
29386
|
+
return existing;
|
|
29387
|
+
const added = stringify({ mcp_servers: routes });
|
|
29388
|
+
const chunk = added.endsWith("\n") ? added : `${added}
|
|
29389
|
+
`;
|
|
29390
|
+
if (!existing?.trim())
|
|
29391
|
+
return chunk;
|
|
29392
|
+
const body = existing.endsWith("\n") ? existing : `${existing}
|
|
29393
|
+
`;
|
|
29394
|
+
return `${body}
|
|
29395
|
+
${chunk}`;
|
|
29396
|
+
}
|
|
29397
|
+
function mergeJsonHostRoutes(existing, routes) {
|
|
29398
|
+
if (Object.keys(routes).length === 0)
|
|
29399
|
+
return existing;
|
|
29400
|
+
return { ...existing ?? {}, ...routes };
|
|
29401
|
+
}
|
|
29402
|
+
function mergeGooseHostRoutes(existing, routes) {
|
|
29403
|
+
if (Object.keys(routes).length === 0)
|
|
29404
|
+
return existing;
|
|
29405
|
+
let parsed = {};
|
|
29406
|
+
if (existing?.trim()) {
|
|
29407
|
+
try {
|
|
29408
|
+
parsed = (0, import_yaml.parse)(existing);
|
|
29409
|
+
} catch {
|
|
29410
|
+
parsed = {};
|
|
29411
|
+
}
|
|
29412
|
+
}
|
|
29413
|
+
const document = recordValue(parsed) ?? {};
|
|
29414
|
+
const extensions = { ...recordValue(document.extensions), ...routes };
|
|
29415
|
+
return (0, import_yaml.stringify)({ ...document, extensions });
|
|
29416
|
+
}
|
|
29417
|
+
|
|
28981
29418
|
// apps/body/dist/openrouter-routing.js
|
|
28982
29419
|
import { mkdir as mkdir5, readFile as readFile5, writeFile as writeFile6 } from "node:fs/promises";
|
|
28983
|
-
import { resolve as
|
|
29420
|
+
import { resolve as resolve15 } from "node:path";
|
|
28984
29421
|
var OPENROUTER_ENDPOINTS_BASE_URL = "https://openrouter.ai/api/v1/models";
|
|
28985
29422
|
var OPENROUTER_COMPLETIONS_URL = "https://openrouter.ai/api/v1/chat/completions";
|
|
28986
29423
|
var OPENROUTER_ROUTING_CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
@@ -29082,10 +29519,10 @@ function openRouterRoutingFor(providers, allowFallbacks = true) {
|
|
|
29082
29519
|
};
|
|
29083
29520
|
}
|
|
29084
29521
|
function openRouterRoutingCacheDir(runtimeDir) {
|
|
29085
|
-
return
|
|
29522
|
+
return resolve15(runtimeDir, "openrouter-routing");
|
|
29086
29523
|
}
|
|
29087
29524
|
function cachePath(cacheDir, model) {
|
|
29088
|
-
return
|
|
29525
|
+
return resolve15(cacheDir, `${model.replace(/[^A-Za-z0-9._-]+/g, "_")}.json`);
|
|
29089
29526
|
}
|
|
29090
29527
|
async function readCache(cacheDir, model) {
|
|
29091
29528
|
try {
|
|
@@ -29116,7 +29553,7 @@ async function writeCache(cacheDir, value) {
|
|
|
29116
29553
|
});
|
|
29117
29554
|
}
|
|
29118
29555
|
function probeCachePath(cacheDir, model) {
|
|
29119
|
-
return
|
|
29556
|
+
return resolve15(cacheDir, `${model.replace(/[^A-Za-z0-9._-]+/g, "_")}.probe.json`);
|
|
29120
29557
|
}
|
|
29121
29558
|
async function readProbeCache(cacheDir, model) {
|
|
29122
29559
|
try {
|
|
@@ -29596,6 +30033,10 @@ var PI_CUSTOM_MODEL_CONFIG = {
|
|
|
29596
30033
|
source: ".pi/agent/models.json",
|
|
29597
30034
|
target: "models.json"
|
|
29598
30035
|
};
|
|
30036
|
+
var PI_MCP_CONFIG = {
|
|
30037
|
+
source: ".pi/agent/mcp.json",
|
|
30038
|
+
target: "mcp.json"
|
|
30039
|
+
};
|
|
29599
30040
|
var CODEX_ROOM_AGENT_LOCKDOWN_TOML = "[agents]\nenabled = false\n";
|
|
29600
30041
|
var CODEX_ROOM_WEB_SEARCH_TOML = "[features]\nstandalone_web_search = true\n";
|
|
29601
30042
|
var HOME_SUBDIRS = [
|
|
@@ -29611,8 +30052,8 @@ var HOME_SUBDIRS = [
|
|
|
29611
30052
|
"tmp"
|
|
29612
30053
|
];
|
|
29613
30054
|
async function prepareRoomAgentHome(input) {
|
|
29614
|
-
const root =
|
|
29615
|
-
const operatorHome = input.operatorHome ??
|
|
30055
|
+
const root = resolve16(input.root);
|
|
30056
|
+
const operatorHome = input.operatorHome ?? homedir8();
|
|
29616
30057
|
try {
|
|
29617
30058
|
await mkdir6(root, { recursive: true, mode: 448 });
|
|
29618
30059
|
const rootStats = await lstat2(root);
|
|
@@ -29620,7 +30061,7 @@ async function prepareRoomAgentHome(input) {
|
|
|
29620
30061
|
throw new AgentHomeSecurityError(`agent home root is not an ordinary directory: ${root}`);
|
|
29621
30062
|
}
|
|
29622
30063
|
for (const subdir of HOME_SUBDIRS) {
|
|
29623
|
-
const path =
|
|
30064
|
+
const path = resolve16(root, subdir);
|
|
29624
30065
|
await mkdir6(path, { recursive: true, mode: 448 });
|
|
29625
30066
|
await assertRealContainedDirectory(path, root);
|
|
29626
30067
|
}
|
|
@@ -29631,15 +30072,15 @@ async function prepareRoomAgentHome(input) {
|
|
|
29631
30072
|
return {};
|
|
29632
30073
|
}
|
|
29633
30074
|
for (const credential of SHARED_CREDENTIALS) {
|
|
29634
|
-
const source =
|
|
29635
|
-
const target =
|
|
29636
|
-
if (!
|
|
30075
|
+
const source = resolve16(operatorHome, credential.source);
|
|
30076
|
+
const target = resolve16(root, credential.dir, credential.target);
|
|
30077
|
+
if (!existsSync5(source) || existsSync5(target))
|
|
29637
30078
|
continue;
|
|
29638
|
-
await mkdir6(
|
|
30079
|
+
await mkdir6(dirname10(target), { recursive: true, mode: 448 }).catch(() => void 0);
|
|
29639
30080
|
await symlink(source, target).catch(() => void 0);
|
|
29640
30081
|
}
|
|
29641
30082
|
const prior = agentHomeProvisionQueues.get(root) ?? Promise.resolve();
|
|
29642
|
-
const provision = prior.catch(() => void 0).then(() => provisionAgentSkillsAndMcp(root, operatorHome, input.skillReleaseId ?? runningBeelineReleaseId(), input.failClosed ?? false, input.sharedSkills ?? [], agentSkillDir(input.agentKind), input.openRouterRouting, input.isReviewer ?? false));
|
|
30083
|
+
const provision = prior.catch(() => void 0).then(() => provisionAgentSkillsAndMcp(root, operatorHome, input.skillReleaseId ?? runningBeelineReleaseId(), input.failClosed ?? false, input.sharedSkills ?? [], agentSkillDir(input.agentKind), input.openRouterRouting, input.isReviewer ?? false, input.grantedHostRoutes ?? [], input.agentKind));
|
|
29643
30084
|
agentHomeProvisionQueues.set(root, provision);
|
|
29644
30085
|
try {
|
|
29645
30086
|
await provision;
|
|
@@ -29649,19 +30090,19 @@ async function prepareRoomAgentHome(input) {
|
|
|
29649
30090
|
}
|
|
29650
30091
|
return roomAgentHomeEnv(root);
|
|
29651
30092
|
}
|
|
29652
|
-
async function provisionAgentSkillsAndMcp(root, operatorHome, skillReleaseId, failClosed, sharedSkills, skillDir, openRouterRouting, isReviewer) {
|
|
30093
|
+
async function provisionAgentSkillsAndMcp(root, operatorHome, skillReleaseId, failClosed, sharedSkills, skillDir, openRouterRouting, isReviewer, grantedHostRoutes, agentKind) {
|
|
29653
30094
|
const managedSkills = [
|
|
29654
30095
|
{ name: USING_BEELINE_SKILL_NAME, content: usingBeelineSkillMarkdown(skillReleaseId) },
|
|
29655
30096
|
{ name: BEELINE_TRIAGE_SKILL_NAME, content: beelineTriageSkillMarkdown(skillReleaseId) },
|
|
29656
30097
|
...isReviewer ? [{ name: BEELINE_REVIEW_SKILL_NAME, content: beelineReviewSkillMarkdown(skillReleaseId) }] : []
|
|
29657
30098
|
];
|
|
29658
30099
|
const shared = await resolveSharedSkillSources(operatorHome, sharedSkills);
|
|
29659
|
-
await provisionManagedSkillsDir(
|
|
30100
|
+
await provisionManagedSkillsDir(resolve16(root, skillDir, "skills"), managedSkills, shared, sharedSkills.length === 0);
|
|
29660
30101
|
for (const config of HARNESS_MCP_CONFIGS) {
|
|
29661
30102
|
try {
|
|
29662
|
-
const source =
|
|
29663
|
-
const target =
|
|
29664
|
-
const mcpSection =
|
|
30103
|
+
const source = resolve16(operatorHome, config.toml);
|
|
30104
|
+
const target = resolve16(root, config.dir, "config.toml");
|
|
30105
|
+
const mcpSection = existsSync5(source) ? localHarnessMcpToml(readFileSync7(source, "utf8")) : void 0;
|
|
29665
30106
|
const section = config.dir === "codex" ? [CODEX_ROOM_AGENT_LOCKDOWN_TOML, CODEX_ROOM_WEB_SEARCH_TOML, mcpSection].filter(Boolean).join("\n") : mcpSection;
|
|
29666
30107
|
if (!section) {
|
|
29667
30108
|
await unlink3(target).catch(() => void 0);
|
|
@@ -29675,12 +30116,12 @@ async function provisionAgentSkillsAndMcp(root, operatorHome, skillReleaseId, fa
|
|
|
29675
30116
|
}
|
|
29676
30117
|
}
|
|
29677
30118
|
try {
|
|
29678
|
-
const gooseConfigDir =
|
|
30119
|
+
const gooseConfigDir = resolve16(root, "goose", "config");
|
|
29679
30120
|
await mkdir6(gooseConfigDir, { recursive: true, mode: 448 });
|
|
29680
30121
|
for (const name of GOOSE_SHARED_CONFIG_FILES) {
|
|
29681
|
-
const source =
|
|
29682
|
-
const target =
|
|
29683
|
-
if (
|
|
30122
|
+
const source = resolve16(operatorHome, ".config", "goose", name);
|
|
30123
|
+
const target = resolve16(gooseConfigDir, name);
|
|
30124
|
+
if (existsSync5(source)) {
|
|
29684
30125
|
const body = readFileSync7(source, "utf8");
|
|
29685
30126
|
await writeIsolatedHarnessFile(target, name === "config.yaml" ? localGooseConfig(body) : body);
|
|
29686
30127
|
} else {
|
|
@@ -29693,9 +30134,9 @@ async function provisionAgentSkillsAndMcp(root, operatorHome, skillReleaseId, fa
|
|
|
29693
30134
|
console.warn("[body] operator Goose configuration passthrough failed:", error);
|
|
29694
30135
|
}
|
|
29695
30136
|
try {
|
|
29696
|
-
const claudeJson =
|
|
29697
|
-
const claudeTarget =
|
|
29698
|
-
const mcpServers =
|
|
30137
|
+
const claudeJson = resolve16(operatorHome, ".claude.json");
|
|
30138
|
+
const claudeTarget = resolve16(root, "claude", ".claude.json");
|
|
30139
|
+
const mcpServers = existsSync5(claudeJson) ? readClaudeUserScopeMcpServers(claudeJson) : void 0;
|
|
29699
30140
|
if (mcpServers && Object.keys(mcpServers).length > 0) {
|
|
29700
30141
|
await writeIsolatedHarnessFile(claudeTarget, `${JSON.stringify({ mcpServers }, null, 2)}
|
|
29701
30142
|
`);
|
|
@@ -29707,20 +30148,100 @@ async function provisionAgentSkillsAndMcp(root, operatorHome, skillReleaseId, fa
|
|
|
29707
30148
|
throw error;
|
|
29708
30149
|
console.warn("[body] operator MCP passthrough failed for claude:", error);
|
|
29709
30150
|
}
|
|
30151
|
+
try {
|
|
30152
|
+
const piJson = resolve16(operatorHome, PI_MCP_CONFIG.source);
|
|
30153
|
+
const piTarget = resolve16(root, "pi", PI_MCP_CONFIG.target);
|
|
30154
|
+
const mcpServers = existsSync5(piJson) ? localMcpServers(recordValue2(readJsonObject(piJson)?.mcpServers) ?? {}) : void 0;
|
|
30155
|
+
if (mcpServers && Object.keys(mcpServers).length > 0) {
|
|
30156
|
+
await writeIsolatedHarnessFile(piTarget, `${JSON.stringify({ mcpServers }, null, 2)}
|
|
30157
|
+
`);
|
|
30158
|
+
} else {
|
|
30159
|
+
await unlink3(piTarget).catch(() => void 0);
|
|
30160
|
+
}
|
|
30161
|
+
} catch (error) {
|
|
30162
|
+
if (failClosed)
|
|
30163
|
+
throw error;
|
|
30164
|
+
console.warn("[body] operator MCP passthrough failed for pi:", error);
|
|
30165
|
+
}
|
|
29710
30166
|
try {
|
|
29711
30167
|
const settings2 = { permissions: { allow: ["WebSearch", "WebFetch"] } };
|
|
29712
|
-
await writeIsolatedHarnessFile(
|
|
30168
|
+
await writeIsolatedHarnessFile(resolve16(root, "claude", "settings.json"), `${JSON.stringify(settings2, null, 2)}
|
|
29713
30169
|
`);
|
|
29714
30170
|
} catch (error) {
|
|
29715
30171
|
if (failClosed)
|
|
29716
30172
|
throw error;
|
|
29717
30173
|
console.warn("[body] claude web-search settings provisioning failed:", error);
|
|
29718
30174
|
}
|
|
30175
|
+
await applyGrantedHostRoutes(root, operatorHome, grantedHostRoutes, agentKind, failClosed);
|
|
29719
30176
|
await provisionPiCustomModelConfig(root, operatorHome, failClosed, openRouterRouting);
|
|
29720
30177
|
}
|
|
30178
|
+
function appliesToHarness(selected, harness) {
|
|
30179
|
+
return !selected || selected === harness;
|
|
30180
|
+
}
|
|
30181
|
+
async function applyGrantedHostRoutes(root, operatorHome, granted, agentKind, failClosed) {
|
|
30182
|
+
if (granted.length === 0)
|
|
30183
|
+
return;
|
|
30184
|
+
try {
|
|
30185
|
+
if (grantedSquireHostRoute(granted, hostImportedMcpDeclarations({ operatorHome, agentKind })))
|
|
30186
|
+
ensureSquireHostDir(operatorHome);
|
|
30187
|
+
const routesFor = (kind) => rewriteGrantedHostRoutes(hostImportedMcpDeclarations({ operatorHome, agentKind: kind }), granted, operatorHome);
|
|
30188
|
+
for (const config of HARNESS_MCP_CONFIGS) {
|
|
30189
|
+
if (!appliesToHarness(agentKind, config.dir))
|
|
30190
|
+
continue;
|
|
30191
|
+
const routes = routesFor(config.dir);
|
|
30192
|
+
if (Object.keys(routes).length === 0)
|
|
30193
|
+
continue;
|
|
30194
|
+
const target = resolve16(root, config.dir, "config.toml");
|
|
30195
|
+
const existing = existsSync5(target) ? readFileSync7(target, "utf8") : void 0;
|
|
30196
|
+
const merged = mergeTomlHostRoutes(existing, routes);
|
|
30197
|
+
if (merged)
|
|
30198
|
+
await writeIsolatedHarnessFile(target, merged);
|
|
30199
|
+
}
|
|
30200
|
+
if (appliesToHarness(agentKind, "goose")) {
|
|
30201
|
+
const routes = routesFor("goose");
|
|
30202
|
+
if (Object.keys(routes).length > 0) {
|
|
30203
|
+
const gooseConfigDir = resolve16(root, "goose", "config");
|
|
30204
|
+
await mkdir6(gooseConfigDir, { recursive: true, mode: 448 });
|
|
30205
|
+
const target = resolve16(gooseConfigDir, "config.yaml");
|
|
30206
|
+
const existing = existsSync5(target) ? readFileSync7(target, "utf8") : void 0;
|
|
30207
|
+
const merged = mergeGooseHostRoutes(existing, routes);
|
|
30208
|
+
if (merged)
|
|
30209
|
+
await writeIsolatedHarnessFile(target, merged);
|
|
30210
|
+
}
|
|
30211
|
+
}
|
|
30212
|
+
if (appliesToHarness(agentKind, "claude")) {
|
|
30213
|
+
const routes = routesFor("claude");
|
|
30214
|
+
if (Object.keys(routes).length > 0) {
|
|
30215
|
+
const target = resolve16(root, "claude", ".claude.json");
|
|
30216
|
+
const parsed = existsSync5(target) ? readJsonObject(target) : void 0;
|
|
30217
|
+
const merged = mergeJsonHostRoutes(recordValue2(parsed?.mcpServers), routes);
|
|
30218
|
+
if (merged && Object.keys(merged).length > 0) {
|
|
30219
|
+
await writeIsolatedHarnessFile(target, `${JSON.stringify({ mcpServers: merged }, null, 2)}
|
|
30220
|
+
`);
|
|
30221
|
+
}
|
|
30222
|
+
}
|
|
30223
|
+
}
|
|
30224
|
+
if (appliesToHarness(agentKind, "pi")) {
|
|
30225
|
+
const routes = routesFor("pi");
|
|
30226
|
+
if (Object.keys(routes).length > 0) {
|
|
30227
|
+
const target = resolve16(root, "pi", PI_MCP_CONFIG.target);
|
|
30228
|
+
const parsed = existsSync5(target) ? readJsonObject(target) : void 0;
|
|
30229
|
+
const merged = mergeJsonHostRoutes(recordValue2(parsed?.mcpServers), routes);
|
|
30230
|
+
if (merged && Object.keys(merged).length > 0) {
|
|
30231
|
+
await writeIsolatedHarnessFile(target, `${JSON.stringify({ mcpServers: merged }, null, 2)}
|
|
30232
|
+
`);
|
|
30233
|
+
}
|
|
30234
|
+
}
|
|
30235
|
+
}
|
|
30236
|
+
} catch (error) {
|
|
30237
|
+
if (failClosed)
|
|
30238
|
+
throw error;
|
|
30239
|
+
console.warn("[body] granted host MCP route passthrough failed:", error);
|
|
30240
|
+
}
|
|
30241
|
+
}
|
|
29721
30242
|
async function provisionPiCustomModelConfig(root, operatorHome, failClosed, openRouterRouting) {
|
|
29722
|
-
const source =
|
|
29723
|
-
const target =
|
|
30243
|
+
const source = resolve16(operatorHome, PI_CUSTOM_MODEL_CONFIG.source);
|
|
30244
|
+
const target = resolve16(root, "pi", PI_CUSTOM_MODEL_CONFIG.target);
|
|
29724
30245
|
let decision2;
|
|
29725
30246
|
if (openRouterRouting) {
|
|
29726
30247
|
decision2 = await resolveOpenRouterRouting(openRouterRouting);
|
|
@@ -29766,7 +30287,7 @@ async function provisionPiCustomModelConfig(root, operatorHome, failClosed, open
|
|
|
29766
30287
|
function readClaudeUserScopeMcpServers(path) {
|
|
29767
30288
|
try {
|
|
29768
30289
|
const parsed = JSON.parse(readFileSync7(path, "utf8"));
|
|
29769
|
-
const servers =
|
|
30290
|
+
const servers = recordValue2(parsed.mcpServers);
|
|
29770
30291
|
if (servers)
|
|
29771
30292
|
return localMcpServers(servers);
|
|
29772
30293
|
} catch {
|
|
@@ -29776,7 +30297,7 @@ function readClaudeUserScopeMcpServers(path) {
|
|
|
29776
30297
|
function localHarnessMcpToml(source) {
|
|
29777
30298
|
let servers;
|
|
29778
30299
|
try {
|
|
29779
|
-
servers =
|
|
30300
|
+
servers = recordValue2(parse5(source).mcp_servers);
|
|
29780
30301
|
} catch {
|
|
29781
30302
|
return void 0;
|
|
29782
30303
|
}
|
|
@@ -29798,21 +30319,21 @@ function localHarnessMcpToml(source) {
|
|
|
29798
30319
|
function localGooseConfig(source) {
|
|
29799
30320
|
let parsed;
|
|
29800
30321
|
try {
|
|
29801
|
-
parsed = (0,
|
|
30322
|
+
parsed = (0, import_yaml2.parse)(source);
|
|
29802
30323
|
} catch {
|
|
29803
30324
|
return source;
|
|
29804
30325
|
}
|
|
29805
|
-
const document =
|
|
29806
|
-
const extensions =
|
|
30326
|
+
const document = recordValue2(parsed);
|
|
30327
|
+
const extensions = recordValue2(document?.extensions);
|
|
29807
30328
|
if (!document || !extensions)
|
|
29808
30329
|
return source;
|
|
29809
30330
|
const local = localMcpServers(extensions);
|
|
29810
30331
|
if (Object.keys(local).length === Object.keys(extensions).length)
|
|
29811
30332
|
return source;
|
|
29812
|
-
return (0,
|
|
30333
|
+
return (0, import_yaml2.stringify)({ ...document, extensions: local });
|
|
29813
30334
|
}
|
|
29814
30335
|
function isHostMcpDeclaration(name, value) {
|
|
29815
|
-
return classifyImportedMcpServer({ name, declaration:
|
|
30336
|
+
return classifyImportedMcpServer({ name, declaration: recordValue2(value) ?? {} }) === "host";
|
|
29816
30337
|
}
|
|
29817
30338
|
function hostMcpServerNames(servers) {
|
|
29818
30339
|
return Object.entries(servers).filter(([name, value]) => isHostMcpDeclaration(name, value)).map(([name]) => name);
|
|
@@ -29820,62 +30341,103 @@ function hostMcpServerNames(servers) {
|
|
|
29820
30341
|
function localMcpServers(servers) {
|
|
29821
30342
|
return Object.fromEntries(Object.entries(servers).filter(([name, value]) => !isHostMcpDeclaration(name, value)));
|
|
29822
30343
|
}
|
|
29823
|
-
function
|
|
30344
|
+
function recordValue2(value) {
|
|
29824
30345
|
return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
29825
30346
|
}
|
|
29826
30347
|
function mountedImportedMcpServerNames(input = {}) {
|
|
29827
30348
|
const names = /* @__PURE__ */ new Set();
|
|
29828
30349
|
if (input.preparedEnv) {
|
|
29829
30350
|
const env = input.preparedEnv;
|
|
29830
|
-
const home = env.HOME ?? input.operatorHome ??
|
|
30351
|
+
const home = env.HOME ?? input.operatorHome ?? homedir8();
|
|
29831
30352
|
const kind = input.agentKind;
|
|
29832
30353
|
if (!kind || kind === "codex") {
|
|
29833
|
-
addTomlMcpNames(names,
|
|
30354
|
+
addTomlMcpNames(names, resolve16(env.CODEX_HOME ?? resolve16(home, ".codex"), "config.toml"));
|
|
29834
30355
|
}
|
|
29835
30356
|
if (!kind || kind === "grok") {
|
|
29836
|
-
addTomlMcpNames(names,
|
|
30357
|
+
addTomlMcpNames(names, resolve16(env.GROK_HOME ?? resolve16(home, ".grok"), "config.toml"));
|
|
29837
30358
|
}
|
|
29838
30359
|
if (!kind || kind === "claude") {
|
|
29839
|
-
addClaudeMcpNames(names,
|
|
30360
|
+
addClaudeMcpNames(names, resolve16(env.CLAUDE_CONFIG_DIR ?? home, ".claude.json"));
|
|
29840
30361
|
}
|
|
29841
30362
|
if (!kind || kind === "goose") {
|
|
29842
|
-
addGooseExtensionNames(names, env.GOOSE_PATH_ROOT ?
|
|
30363
|
+
addGooseExtensionNames(names, env.GOOSE_PATH_ROOT ? resolve16(env.GOOSE_PATH_ROOT, "config/config.yaml") : resolve16(home, ".config/goose/config.yaml"));
|
|
30364
|
+
}
|
|
30365
|
+
if (!kind || kind === "pi") {
|
|
30366
|
+
addClaudeMcpNames(names, resolve16(env.PI_CODING_AGENT_DIR ?? resolve16(home, ".pi/agent"), PI_MCP_CONFIG.target));
|
|
29843
30367
|
}
|
|
29844
30368
|
} else {
|
|
29845
|
-
collectImportedMcpNames(input.operatorHome ??
|
|
30369
|
+
collectImportedMcpNames(input.operatorHome ?? homedir8(), names, input.agentKind);
|
|
29846
30370
|
}
|
|
29847
30371
|
return [...names].sort((left, right) => left.localeCompare(right));
|
|
29848
30372
|
}
|
|
29849
|
-
function
|
|
29850
|
-
const operatorHome = input.operatorHome ??
|
|
30373
|
+
function hostImportedMcpDeclarations(input = {}) {
|
|
30374
|
+
const operatorHome = input.operatorHome ?? homedir8();
|
|
29851
30375
|
const kind = input.agentKind;
|
|
29852
|
-
const
|
|
29853
|
-
|
|
29854
|
-
|
|
29855
|
-
|
|
29856
|
-
|
|
29857
|
-
|
|
29858
|
-
|
|
30376
|
+
const declarations = {};
|
|
30377
|
+
const add = (servers) => {
|
|
30378
|
+
if (!servers)
|
|
30379
|
+
return;
|
|
30380
|
+
for (const [name, value] of Object.entries(servers)) {
|
|
30381
|
+
if (isHostMcpDeclaration(name, value))
|
|
30382
|
+
declarations[name] = recordValue2(value) ?? {};
|
|
30383
|
+
}
|
|
30384
|
+
};
|
|
30385
|
+
if (!kind || kind === "codex")
|
|
30386
|
+
add(readTomlMcpServers(resolve16(operatorHome, ".codex/config.toml")));
|
|
30387
|
+
if (!kind || kind === "grok")
|
|
30388
|
+
add(readTomlMcpServers(resolve16(operatorHome, ".grok/config.toml")));
|
|
29859
30389
|
if (!kind || kind === "claude") {
|
|
29860
|
-
|
|
30390
|
+
add(recordValue2(readJsonObject(resolve16(operatorHome, ".claude.json"))?.mcpServers));
|
|
29861
30391
|
}
|
|
29862
30392
|
if (!kind || kind === "goose") {
|
|
29863
|
-
|
|
30393
|
+
add(readGooseExtensions(resolve16(operatorHome, ".config/goose/config.yaml")));
|
|
29864
30394
|
}
|
|
29865
|
-
|
|
30395
|
+
if (!kind || kind === "pi") {
|
|
30396
|
+
add(recordValue2(readJsonObject(resolve16(operatorHome, PI_MCP_CONFIG.source))?.mcpServers));
|
|
30397
|
+
}
|
|
30398
|
+
return declarations;
|
|
30399
|
+
}
|
|
30400
|
+
function hostImportedMcpServerNames(input = {}) {
|
|
30401
|
+
return Object.keys(hostImportedMcpDeclarations(input)).sort((left, right) => left.localeCompare(right));
|
|
30402
|
+
}
|
|
30403
|
+
function grantedSquireHostBindPaths(input) {
|
|
30404
|
+
const operatorHome = input.operatorHome ?? homedir8();
|
|
30405
|
+
const granted = input.grantedHostRoutes ?? [];
|
|
30406
|
+
if (granted.length === 0)
|
|
30407
|
+
return [];
|
|
30408
|
+
return squireHostBindPaths(operatorHome, grantedSquireHostRoute(granted, hostImportedMcpDeclarations({ operatorHome, agentKind: input.agentKind })));
|
|
30409
|
+
}
|
|
30410
|
+
function expectedMountedImportedMcpServerNames(input) {
|
|
30411
|
+
const local = mountedImportedMcpServerNames({
|
|
30412
|
+
operatorHome: input.operatorHome,
|
|
30413
|
+
agentKind: input.agentKind
|
|
30414
|
+
});
|
|
30415
|
+
const allowed = new Set(input.grantedHostRoutes ?? []);
|
|
30416
|
+
const grantedHost = hostImportedMcpServerNames({
|
|
30417
|
+
operatorHome: input.operatorHome,
|
|
30418
|
+
agentKind: input.agentKind
|
|
30419
|
+
}).filter((name) => allowed.has(name));
|
|
30420
|
+
for (const name of allowed) {
|
|
30421
|
+
if (isCodeOwnedHostMcpName(name))
|
|
30422
|
+
grantedHost.push(name);
|
|
30423
|
+
}
|
|
30424
|
+
return [.../* @__PURE__ */ new Set([...local, ...grantedHost])].sort((left, right) => left.localeCompare(right));
|
|
29866
30425
|
}
|
|
29867
30426
|
function collectImportedMcpNames(operatorHome, names, kind) {
|
|
29868
30427
|
if (!kind || kind === "codex") {
|
|
29869
|
-
addLocalMcpNames(names, readTomlMcpServers(
|
|
30428
|
+
addLocalMcpNames(names, readTomlMcpServers(resolve16(operatorHome, ".codex/config.toml")));
|
|
29870
30429
|
}
|
|
29871
30430
|
if (!kind || kind === "grok") {
|
|
29872
|
-
addLocalMcpNames(names, readTomlMcpServers(
|
|
30431
|
+
addLocalMcpNames(names, readTomlMcpServers(resolve16(operatorHome, ".grok/config.toml")));
|
|
29873
30432
|
}
|
|
29874
30433
|
if (!kind || kind === "claude") {
|
|
29875
|
-
addLocalMcpNames(names,
|
|
30434
|
+
addLocalMcpNames(names, recordValue2(readJsonObject(resolve16(operatorHome, ".claude.json"))?.mcpServers));
|
|
29876
30435
|
}
|
|
29877
30436
|
if (!kind || kind === "goose") {
|
|
29878
|
-
addLocalMcpNames(names, readGooseExtensions(
|
|
30437
|
+
addLocalMcpNames(names, readGooseExtensions(resolve16(operatorHome, ".config/goose/config.yaml")));
|
|
30438
|
+
}
|
|
30439
|
+
if (!kind || kind === "pi") {
|
|
30440
|
+
addLocalMcpNames(names, recordValue2(readJsonObject(resolve16(operatorHome, PI_MCP_CONFIG.source))?.mcpServers));
|
|
29879
30441
|
}
|
|
29880
30442
|
}
|
|
29881
30443
|
function addLocalMcpNames(names, servers) {
|
|
@@ -29884,24 +30446,18 @@ function addLocalMcpNames(names, servers) {
|
|
|
29884
30446
|
for (const name of Object.keys(localMcpServers(servers)))
|
|
29885
30447
|
names.add(name);
|
|
29886
30448
|
}
|
|
29887
|
-
function addHostMcpNames(names, servers) {
|
|
29888
|
-
if (!servers)
|
|
29889
|
-
return;
|
|
29890
|
-
for (const name of hostMcpServerNames(servers))
|
|
29891
|
-
names.add(name);
|
|
29892
|
-
}
|
|
29893
30449
|
function addTomlMcpNames(names, path) {
|
|
29894
30450
|
addMcpNamesFromMap(names, readTomlMcpServers(path));
|
|
29895
30451
|
}
|
|
29896
30452
|
function addClaudeMcpNames(names, path) {
|
|
29897
|
-
addMcpNamesFromMap(names,
|
|
30453
|
+
addMcpNamesFromMap(names, recordValue2(readJsonObject(path)?.mcpServers));
|
|
29898
30454
|
}
|
|
29899
30455
|
function readTomlMcpServers(path) {
|
|
29900
30456
|
const source = readExistingText(path);
|
|
29901
30457
|
if (source === void 0)
|
|
29902
30458
|
return void 0;
|
|
29903
30459
|
try {
|
|
29904
|
-
return
|
|
30460
|
+
return recordValue2(parse5(source).mcp_servers);
|
|
29905
30461
|
} catch {
|
|
29906
30462
|
return void 0;
|
|
29907
30463
|
}
|
|
@@ -29912,11 +30468,11 @@ function readGooseExtensions(path) {
|
|
|
29912
30468
|
return void 0;
|
|
29913
30469
|
let parsed;
|
|
29914
30470
|
try {
|
|
29915
|
-
parsed = (0,
|
|
30471
|
+
parsed = (0, import_yaml2.parse)(source);
|
|
29916
30472
|
} catch {
|
|
29917
30473
|
return void 0;
|
|
29918
30474
|
}
|
|
29919
|
-
return
|
|
30475
|
+
return recordValue2(recordValue2(parsed)?.extensions);
|
|
29920
30476
|
}
|
|
29921
30477
|
function addMcpNamesFromMap(names, servers) {
|
|
29922
30478
|
if (!servers)
|
|
@@ -29928,7 +30484,7 @@ function addGooseExtensionNames(names, path) {
|
|
|
29928
30484
|
addMcpNamesFromMap(names, readGooseExtensions(path));
|
|
29929
30485
|
}
|
|
29930
30486
|
function readExistingText(path) {
|
|
29931
|
-
if (!
|
|
30487
|
+
if (!existsSync5(path))
|
|
29932
30488
|
return void 0;
|
|
29933
30489
|
try {
|
|
29934
30490
|
return readFileSync7(path, "utf8");
|
|
@@ -29948,21 +30504,21 @@ function readJsonObject(path) {
|
|
|
29948
30504
|
}
|
|
29949
30505
|
}
|
|
29950
30506
|
async function provisionManagedSkillsDir(target, managedSkills, sharedSkills, optionalShares) {
|
|
29951
|
-
const parent =
|
|
29952
|
-
await assertRealContainedDirectory(parent,
|
|
30507
|
+
const parent = dirname10(target);
|
|
30508
|
+
await assertRealContainedDirectory(parent, dirname10(parent));
|
|
29953
30509
|
const plan = await planManagedSkills(managedSkills, sharedSkills, optionalShares);
|
|
29954
30510
|
if (await materializedSkillManifest(target) === plan.manifest)
|
|
29955
30511
|
return;
|
|
29956
|
-
const staged =
|
|
30512
|
+
const staged = resolve16(parent, `.skills.${process.pid}.${randomUUID4()}.tmp`);
|
|
29957
30513
|
await mkdir6(staged, { mode: 448 });
|
|
29958
30514
|
try {
|
|
29959
30515
|
for (const entry of plan.entries) {
|
|
29960
30516
|
if (entry.kind === "managed") {
|
|
29961
|
-
const skillDir =
|
|
30517
|
+
const skillDir = resolve16(staged, entry.name);
|
|
29962
30518
|
await mkdir6(skillDir, { recursive: true });
|
|
29963
|
-
await writeIsolatedHarnessFile(
|
|
30519
|
+
await writeIsolatedHarnessFile(resolve16(skillDir, "SKILL.md"), entry.content);
|
|
29964
30520
|
} else {
|
|
29965
|
-
await copySafeSkillTree(entry.source,
|
|
30521
|
+
await copySafeSkillTree(entry.source, resolve16(staged, entry.name), entry.source);
|
|
29966
30522
|
}
|
|
29967
30523
|
}
|
|
29968
30524
|
const existing = await lstat2(target).catch(() => void 0);
|
|
@@ -29989,8 +30545,8 @@ async function planManagedSkills(managedSkills, sharedSkills, optionalShares) {
|
|
|
29989
30545
|
try {
|
|
29990
30546
|
const tree = [];
|
|
29991
30547
|
await walkSafeSkillTree(shared.source, shared.source, {
|
|
29992
|
-
directory: async (rel) => void tree.push(`d ${
|
|
29993
|
-
file: async (rel, realPath) => void tree.push(`f ${
|
|
30548
|
+
directory: async (rel) => void tree.push(`d ${join8(shared.name, rel)}`),
|
|
30549
|
+
file: async (rel, realPath) => void tree.push(`f ${join8(shared.name, rel)} ${sha2563(await readFile6(realPath))}`)
|
|
29994
30550
|
});
|
|
29995
30551
|
entries.push({ kind: "shared", name: shared.name, source: shared.source });
|
|
29996
30552
|
lines.push(...tree);
|
|
@@ -30009,8 +30565,8 @@ async function materializedSkillManifest(target) {
|
|
|
30009
30565
|
const lines = [];
|
|
30010
30566
|
const visit = async (directory, prefix) => {
|
|
30011
30567
|
for (const entry of await readdir2(directory)) {
|
|
30012
|
-
const path =
|
|
30013
|
-
const rel = prefix ?
|
|
30568
|
+
const path = resolve16(directory, entry);
|
|
30569
|
+
const rel = prefix ? join8(prefix, entry) : entry;
|
|
30014
30570
|
const entryStats = await lstat2(path);
|
|
30015
30571
|
if (entryStats.isSymbolicLink())
|
|
30016
30572
|
return false;
|
|
@@ -30044,14 +30600,14 @@ async function resolveSharedSkillSources(operatorHome, names) {
|
|
|
30044
30600
|
const resolved = [];
|
|
30045
30601
|
const skipped = [];
|
|
30046
30602
|
for (const relativeRoot of OPERATOR_SKILL_SOURCE_DIRS) {
|
|
30047
|
-
const sourceRoot =
|
|
30603
|
+
const sourceRoot = resolve16(operatorHome, relativeRoot);
|
|
30048
30604
|
const rootStats = await lstat2(sourceRoot).catch(() => void 0);
|
|
30049
30605
|
if (!rootStats?.isDirectory() || rootStats.isSymbolicLink())
|
|
30050
30606
|
continue;
|
|
30051
30607
|
for (const entry of await readdir2(sourceRoot)) {
|
|
30052
30608
|
if (!isSharedSkillName(entry) || seen.has(entry))
|
|
30053
30609
|
continue;
|
|
30054
|
-
const candidate =
|
|
30610
|
+
const candidate = resolve16(sourceRoot, entry);
|
|
30055
30611
|
try {
|
|
30056
30612
|
const candidateStats = await lstat2(candidate);
|
|
30057
30613
|
if (candidateStats.isSymbolicLink()) {
|
|
@@ -30067,7 +30623,7 @@ async function resolveSharedSkillSources(operatorHome, names) {
|
|
|
30067
30623
|
continue;
|
|
30068
30624
|
}
|
|
30069
30625
|
assertContained(sourceRoot, candidate);
|
|
30070
|
-
const skillMd =
|
|
30626
|
+
const skillMd = resolve16(candidate, "SKILL.md");
|
|
30071
30627
|
const skillStats = await lstat2(skillMd).catch((error) => {
|
|
30072
30628
|
if (isMissingPathError(error)) {
|
|
30073
30629
|
skipped.push({ path: candidate, reason: "missing SKILL.md" });
|
|
@@ -30119,8 +30675,8 @@ async function resolveExplicitSkillSources(operatorHome, names) {
|
|
|
30119
30675
|
for (const name of unique) {
|
|
30120
30676
|
const matches = [];
|
|
30121
30677
|
for (const relativeRoot of OPERATOR_SKILL_SOURCE_DIRS) {
|
|
30122
|
-
const sourceRoot =
|
|
30123
|
-
const candidate =
|
|
30678
|
+
const sourceRoot = resolve16(operatorHome, relativeRoot);
|
|
30679
|
+
const candidate = resolve16(sourceRoot, name);
|
|
30124
30680
|
const rootStats = await lstat2(sourceRoot).catch(() => void 0);
|
|
30125
30681
|
const candidateStats = await lstat2(candidate).catch(() => void 0);
|
|
30126
30682
|
if (!candidateStats)
|
|
@@ -30137,7 +30693,7 @@ async function resolveExplicitSkillSources(operatorHome, names) {
|
|
|
30137
30693
|
if (matches.length !== 1) {
|
|
30138
30694
|
throw new Error(matches.length === 0 ? `shared skill is unavailable: ${name}` : `shared skill source is ambiguous: ${name}`);
|
|
30139
30695
|
}
|
|
30140
|
-
const skillMd =
|
|
30696
|
+
const skillMd = resolve16(matches[0], "SKILL.md");
|
|
30141
30697
|
const skillStats = await lstat2(skillMd).catch(() => void 0);
|
|
30142
30698
|
if (!skillStats?.isFile() || skillStats.isSymbolicLink() || skillStats.nlink !== 1) {
|
|
30143
30699
|
throw new Error(`shared skill requires an ordinary SKILL.md: ${name}`);
|
|
@@ -30148,7 +30704,7 @@ async function resolveExplicitSkillSources(operatorHome, names) {
|
|
|
30148
30704
|
}
|
|
30149
30705
|
function assertContained(root, candidate) {
|
|
30150
30706
|
const rel = relative2(root, candidate);
|
|
30151
|
-
if (rel === ".." || rel.startsWith(`..${sep}`) ||
|
|
30707
|
+
if (rel === ".." || rel.startsWith(`..${sep}`) || resolve16(root, rel) !== resolve16(candidate)) {
|
|
30152
30708
|
throw new Error(`path escapes the agent skill boundary: ${candidate}`);
|
|
30153
30709
|
}
|
|
30154
30710
|
}
|
|
@@ -30163,7 +30719,7 @@ var BLOCKED_SHARED_FILENAMES = /^(?:\.env(?:\..*)?|auth\.json|\.credentials\.jso
|
|
|
30163
30719
|
async function walkSafeSkillTree(source, sourceRoot, visitor, rel = "") {
|
|
30164
30720
|
assertContained(sourceRoot, source);
|
|
30165
30721
|
const resolvedSource = await realpath(source);
|
|
30166
|
-
if (resolvedSource !==
|
|
30722
|
+
if (resolvedSource !== resolve16(source)) {
|
|
30167
30723
|
throw new Error(`shared skill path resolves through a link: ${source}`);
|
|
30168
30724
|
}
|
|
30169
30725
|
assertContained(sourceRoot, resolvedSource);
|
|
@@ -30178,7 +30734,7 @@ async function walkSafeSkillTree(source, sourceRoot, visitor, rel = "") {
|
|
|
30178
30734
|
for (const entry of await readdir2(resolvedSource)) {
|
|
30179
30735
|
if (entry === "." || entry === "..")
|
|
30180
30736
|
throw new Error("invalid shared skill entry");
|
|
30181
|
-
await walkSafeSkillTree(
|
|
30737
|
+
await walkSafeSkillTree(resolve16(source, entry), sourceRoot, visitor, rel ? join8(rel, entry) : entry);
|
|
30182
30738
|
}
|
|
30183
30739
|
return;
|
|
30184
30740
|
}
|
|
@@ -30190,22 +30746,22 @@ async function walkSafeSkillTree(source, sourceRoot, visitor, rel = "") {
|
|
|
30190
30746
|
async function copySafeSkillTree(source, target, sourceRoot) {
|
|
30191
30747
|
await walkSafeSkillTree(source, sourceRoot, {
|
|
30192
30748
|
directory: async (rel) => {
|
|
30193
|
-
await mkdir6(
|
|
30749
|
+
await mkdir6(resolve16(target, rel), { mode: 448 });
|
|
30194
30750
|
},
|
|
30195
30751
|
file: async (rel, realPath) => {
|
|
30196
|
-
const destination =
|
|
30752
|
+
const destination = resolve16(target, rel);
|
|
30197
30753
|
await copyFile(realPath, destination);
|
|
30198
30754
|
await chmod3(destination, 384);
|
|
30199
30755
|
}
|
|
30200
30756
|
});
|
|
30201
30757
|
}
|
|
30202
30758
|
async function writeIsolatedHarnessFile(path, content) {
|
|
30203
|
-
const parent =
|
|
30759
|
+
const parent = dirname10(path);
|
|
30204
30760
|
const parentStats = await lstat2(parent);
|
|
30205
30761
|
if (!parentStats.isDirectory() || parentStats.isSymbolicLink()) {
|
|
30206
30762
|
throw new Error(`isolated harness parent is not a real directory: ${parent}`);
|
|
30207
30763
|
}
|
|
30208
|
-
const temporary =
|
|
30764
|
+
const temporary = resolve16(parent, `.${basename5(path)}.${process.pid}.${randomUUID4()}.tmp`);
|
|
30209
30765
|
try {
|
|
30210
30766
|
await writeFile7(temporary, content, { mode: 384, flag: "wx" });
|
|
30211
30767
|
await chmod3(temporary, 384);
|
|
@@ -30215,18 +30771,18 @@ async function writeIsolatedHarnessFile(path, content) {
|
|
|
30215
30771
|
}
|
|
30216
30772
|
}
|
|
30217
30773
|
function roomAgentHomeEnv(root) {
|
|
30218
|
-
const resolved =
|
|
30774
|
+
const resolved = resolve16(root);
|
|
30219
30775
|
return {
|
|
30220
|
-
HOME:
|
|
30221
|
-
CLAUDE_CONFIG_DIR:
|
|
30222
|
-
CODEX_HOME:
|
|
30223
|
-
GOOSE_PATH_ROOT:
|
|
30224
|
-
GROK_HOME:
|
|
30225
|
-
CURSOR_HOME:
|
|
30226
|
-
PI_CODING_AGENT_DIR:
|
|
30227
|
-
XDG_STATE_HOME:
|
|
30228
|
-
XDG_CACHE_HOME:
|
|
30229
|
-
TMPDIR:
|
|
30776
|
+
HOME: resolve16(resolved, "user"),
|
|
30777
|
+
CLAUDE_CONFIG_DIR: resolve16(resolved, "claude"),
|
|
30778
|
+
CODEX_HOME: resolve16(resolved, "codex"),
|
|
30779
|
+
GOOSE_PATH_ROOT: resolve16(resolved, "goose"),
|
|
30780
|
+
GROK_HOME: resolve16(resolved, "grok"),
|
|
30781
|
+
CURSOR_HOME: resolve16(resolved, "cursor"),
|
|
30782
|
+
PI_CODING_AGENT_DIR: resolve16(resolved, "pi"),
|
|
30783
|
+
XDG_STATE_HOME: resolve16(resolved, "state"),
|
|
30784
|
+
XDG_CACHE_HOME: resolve16(resolved, "cache"),
|
|
30785
|
+
TMPDIR: resolve16(resolved, "tmp")
|
|
30230
30786
|
};
|
|
30231
30787
|
}
|
|
30232
30788
|
var HARNESS_STATE_ENV_VARS = [
|
|
@@ -30245,15 +30801,15 @@ function harnessStateDirsFromEnv(env) {
|
|
|
30245
30801
|
for (const name of HARNESS_STATE_ENV_VARS) {
|
|
30246
30802
|
const value = env[name];
|
|
30247
30803
|
if (value)
|
|
30248
|
-
stateDirs.push(
|
|
30804
|
+
stateDirs.push(resolve16(value));
|
|
30249
30805
|
}
|
|
30250
30806
|
const tmp = env.TMPDIR;
|
|
30251
|
-
return { stateDirs, ...tmp ? { tmpDir:
|
|
30807
|
+
return { stateDirs, ...tmp ? { tmpDir: resolve16(tmp) } : {} };
|
|
30252
30808
|
}
|
|
30253
30809
|
|
|
30254
30810
|
// apps/body/dist/attachment-delivery.js
|
|
30255
30811
|
import { mkdir as mkdir7, writeFile as writeFile8 } from "node:fs/promises";
|
|
30256
|
-
import { basename as basename6, extname, join as
|
|
30812
|
+
import { basename as basename6, extname, join as join9 } from "node:path";
|
|
30257
30813
|
var MAX_ATTACHMENT_BYTES = 25 * 1024 * 1024;
|
|
30258
30814
|
var MEDIA_TTL_HOURS = 24;
|
|
30259
30815
|
var EXPIRED_REASON = `expired: attachments are kept for ${MEDIA_TTL_HOURS} hours and these bytes are past that window`;
|
|
@@ -30313,7 +30869,7 @@ async function deliverAttachments(attachments, dir, fetchImpl = fetch) {
|
|
|
30313
30869
|
return { attachment, reason: EXPIRED_REASON };
|
|
30314
30870
|
if (!fetched.ok)
|
|
30315
30871
|
throw new Error(`HTTP ${fetched.status}`);
|
|
30316
|
-
const path =
|
|
30872
|
+
const path = join9(dir, safeFileName(attachment, index, taken));
|
|
30317
30873
|
await writeFile8(path, fetched.bytes);
|
|
30318
30874
|
const bytes = fetched.bytes;
|
|
30319
30875
|
const mimeType = attachment.mimeType ?? fetched.mimeType;
|
|
@@ -30502,6 +31058,12 @@ function durableReplyText(agentText) {
|
|
|
30502
31058
|
var AgentTurnStream = class {
|
|
30503
31059
|
options;
|
|
30504
31060
|
latest = "";
|
|
31061
|
+
/**
|
|
31062
|
+
* The assistant run currently accumulating — what `finalAgentMessageText`
|
|
31063
|
+
* would return if the prompt ended here. The join above is the draft lane's
|
|
31064
|
+
* material; this is the only part of the stream an ending may commit.
|
|
31065
|
+
*/
|
|
31066
|
+
latestRun = "";
|
|
30505
31067
|
/**
|
|
30506
31068
|
* The newest snapshot not yet handed to a write. A draft is a picture of the
|
|
30507
31069
|
* whole answer so far, so an older snapshot that never reached the wire is
|
|
@@ -30525,10 +31087,14 @@ var AgentTurnStream = class {
|
|
|
30525
31087
|
/**
|
|
30526
31088
|
* The ACP delta hook: hand it straight to `sessionPrompt`. `full` is every
|
|
30527
31089
|
* assistant run so far joined — not the final answer — so it is only ever
|
|
30528
|
-
* shown provisionally.
|
|
31090
|
+
* shown provisionally. A caller that cannot name the current run leaves
|
|
31091
|
+
* `lastRunText` empty rather than letting the join stand in for it: an
|
|
31092
|
+
* unknown last run is not an answer, and an ending that reads one must
|
|
31093
|
+
* settle through whatever else it has.
|
|
30529
31094
|
*/
|
|
30530
|
-
onChunk = (_delta, full) => {
|
|
31095
|
+
onChunk = (_delta, full, currentRun) => {
|
|
30531
31096
|
this.latest = full;
|
|
31097
|
+
this.latestRun = currentRun ?? "";
|
|
30532
31098
|
const text2 = sanitizeAgentReply(full);
|
|
30533
31099
|
if (!text2 || this.closed)
|
|
30534
31100
|
return;
|
|
@@ -30565,9 +31131,19 @@ var AgentTurnStream = class {
|
|
|
30565
31131
|
get streamedText() {
|
|
30566
31132
|
return this.latest;
|
|
30567
31133
|
}
|
|
31134
|
+
/**
|
|
31135
|
+
* The LAST assistant run alone — the same text `PromptResult.agentText`
|
|
31136
|
+
* carries when the prompt returns, available to an ending the prompt never
|
|
31137
|
+
* reached. An earlier run is progress narration around tool work and is not
|
|
31138
|
+
* this turn's answer, however the turn ends.
|
|
31139
|
+
*/
|
|
31140
|
+
get lastRunText() {
|
|
31141
|
+
return this.latestRun;
|
|
31142
|
+
}
|
|
30568
31143
|
/** Forget the previous run's stream text; a re-pinned retry starts clean. */
|
|
30569
31144
|
beginRun() {
|
|
30570
31145
|
this.latest = "";
|
|
31146
|
+
this.latestRun = "";
|
|
30571
31147
|
this.pending = void 0;
|
|
30572
31148
|
}
|
|
30573
31149
|
/**
|
|
@@ -30714,7 +31290,7 @@ function mountedMcpSet(servers) {
|
|
|
30714
31290
|
|
|
30715
31291
|
// apps/body/dist/pi-mcp-bridge.js
|
|
30716
31292
|
import { mkdir as mkdir8 } from "node:fs/promises";
|
|
30717
|
-
import { resolve as
|
|
31293
|
+
import { resolve as resolve17 } from "node:path";
|
|
30718
31294
|
var PI_MCP_BRIDGE_FILENAME = "beeline-mcp-bridge.js";
|
|
30719
31295
|
function isPiAcpCommand(agentCommand) {
|
|
30720
31296
|
return Boolean(agentCommand && /(^|[/\\])pi-acp(\.[a-z]+)?$/i.test(agentCommand));
|
|
@@ -30734,8 +31310,8 @@ async function installPiMcpBridge(input) {
|
|
|
30734
31310
|
return void 0;
|
|
30735
31311
|
if (!input.piHome || !input.servers.length)
|
|
30736
31312
|
return void 0;
|
|
30737
|
-
const directory =
|
|
30738
|
-
const path =
|
|
31313
|
+
const directory = resolve17(input.piHome, "extensions");
|
|
31314
|
+
const path = resolve17(directory, PI_MCP_BRIDGE_FILENAME);
|
|
30739
31315
|
try {
|
|
30740
31316
|
await mkdir8(directory, { recursive: true, mode: 448 });
|
|
30741
31317
|
await writeIsolatedHarnessFile(path, piMcpBridgeSource(input.servers));
|
|
@@ -30747,7 +31323,8 @@ async function installPiMcpBridge(input) {
|
|
|
30747
31323
|
}
|
|
30748
31324
|
var BRIDGE_PREAMBLE = `// Generated by Beeline for one Room session. Do not edit: it is rewritten on
|
|
30749
31325
|
// every activation. It republishes this session's MCP servers as pi tools,
|
|
30750
|
-
// because pi has no MCP client of its own
|
|
31326
|
+
// because pi 0.85.1 has no MCP client of its own and pi-acp 0.0.33 still
|
|
31327
|
+
// drops session/new mcpServers (apps/body/src/pi-mcp-bridge.ts).
|
|
30751
31328
|
import { spawn } from 'node:child_process';
|
|
30752
31329
|
|
|
30753
31330
|
`;
|
|
@@ -30935,7 +31512,7 @@ async function contains(git, head, ancestor) {
|
|
|
30935
31512
|
}
|
|
30936
31513
|
|
|
30937
31514
|
// apps/body/dist/room-session.js
|
|
30938
|
-
import { resolve as
|
|
31515
|
+
import { resolve as resolve18 } from "node:path";
|
|
30939
31516
|
|
|
30940
31517
|
// apps/body/dist/read-only-policy.js
|
|
30941
31518
|
var READ_ONLY_MCP_SERVER_NAME = "beeline-readonly-mcp";
|
|
@@ -31394,14 +31971,14 @@ function readOnlyMcpServer(config, cwd, agentMemoryDir) {
|
|
|
31394
31971
|
command: config.readonlyMcpCommand,
|
|
31395
31972
|
args: [...config.readonlyMcpArgs ?? []],
|
|
31396
31973
|
env: [
|
|
31397
|
-
{ name: "BEELINE_READONLY_ROOT", value:
|
|
31974
|
+
{ name: "BEELINE_READONLY_ROOT", value: resolve18(cwd) },
|
|
31398
31975
|
...config.agentHomeRoot ? [
|
|
31399
31976
|
{
|
|
31400
31977
|
name: "BEELINE_READONLY_AGENT_SKILLS_ROOT",
|
|
31401
|
-
value:
|
|
31978
|
+
value: resolve18(config.agentHomeRoot, skillDir, "skills")
|
|
31402
31979
|
}
|
|
31403
31980
|
] : [],
|
|
31404
|
-
...agentMemoryDir ? [{ name: "BEELINE_READONLY_AGENT_MEMORY_ROOT", value:
|
|
31981
|
+
...agentMemoryDir ? [{ name: "BEELINE_READONLY_AGENT_MEMORY_ROOT", value: resolve18(agentMemoryDir) }] : []
|
|
31405
31982
|
]
|
|
31406
31983
|
};
|
|
31407
31984
|
}
|
|
@@ -31421,7 +31998,7 @@ function youtubeMcpServer(config, accessToken) {
|
|
|
31421
31998
|
|
|
31422
31999
|
// apps/body/dist/pi-turn-record.js
|
|
31423
32000
|
import { readdir as readdir3, readFile as readFile7 } from "node:fs/promises";
|
|
31424
|
-
import { resolve as
|
|
32001
|
+
import { resolve as resolve19 } from "node:path";
|
|
31425
32002
|
function summarizeProviderError(errorMessage2) {
|
|
31426
32003
|
const trimmed = errorMessage2.trim();
|
|
31427
32004
|
const statusMatch = /^(\d{3}):\s*([\s\S]*)$/.exec(trimmed);
|
|
@@ -31442,7 +32019,7 @@ function summarizeProviderError(errorMessage2) {
|
|
|
31442
32019
|
}
|
|
31443
32020
|
async function sessionFileFromMap(home, sessionId) {
|
|
31444
32021
|
try {
|
|
31445
|
-
const raw = await readFile7(
|
|
32022
|
+
const raw = await readFile7(resolve19(home, ".pi", "pi-acp", "session-map.json"), "utf8");
|
|
31446
32023
|
const map = JSON.parse(raw);
|
|
31447
32024
|
const file = map.sessions?.[sessionId]?.sessionFile;
|
|
31448
32025
|
return typeof file === "string" && file ? file : void 0;
|
|
@@ -31451,7 +32028,7 @@ async function sessionFileFromMap(home, sessionId) {
|
|
|
31451
32028
|
}
|
|
31452
32029
|
}
|
|
31453
32030
|
async function sessionFileFromLayout(piDir, sessionId) {
|
|
31454
|
-
const sessionsRoot =
|
|
32031
|
+
const sessionsRoot = resolve19(piDir, "sessions");
|
|
31455
32032
|
const suffix = `_${sessionId}.jsonl`;
|
|
31456
32033
|
let projects;
|
|
31457
32034
|
try {
|
|
@@ -31460,7 +32037,7 @@ async function sessionFileFromLayout(piDir, sessionId) {
|
|
|
31460
32037
|
return void 0;
|
|
31461
32038
|
}
|
|
31462
32039
|
for (const project of projects) {
|
|
31463
|
-
const dir =
|
|
32040
|
+
const dir = resolve19(sessionsRoot, project);
|
|
31464
32041
|
let files;
|
|
31465
32042
|
try {
|
|
31466
32043
|
files = await readdir3(dir);
|
|
@@ -31469,7 +32046,7 @@ async function sessionFileFromLayout(piDir, sessionId) {
|
|
|
31469
32046
|
}
|
|
31470
32047
|
const match = files.find((file) => file.endsWith(suffix));
|
|
31471
32048
|
if (match)
|
|
31472
|
-
return
|
|
32049
|
+
return resolve19(dir, match);
|
|
31473
32050
|
}
|
|
31474
32051
|
return void 0;
|
|
31475
32052
|
}
|
|
@@ -31644,7 +32221,7 @@ async function withTurnReceiptHeartbeat(api, receipt, task, onHeartbeatError) {
|
|
|
31644
32221
|
|
|
31645
32222
|
// apps/body/dist/turn-trace.js
|
|
31646
32223
|
import { appendFile, mkdir as mkdir9, readdir as readdir4, rm as rm3 } from "node:fs/promises";
|
|
31647
|
-
import { resolve as
|
|
32224
|
+
import { resolve as resolve20 } from "node:path";
|
|
31648
32225
|
import { performance as performance2 } from "node:perf_hooks";
|
|
31649
32226
|
var TURN_PHASES = [
|
|
31650
32227
|
/** Enqueued on `SessionScheduler` until this turn holds a slot. A capacity wait lives here. */
|
|
@@ -31874,7 +32451,7 @@ function formatTurnTraceLine(record3) {
|
|
|
31874
32451
|
return [head, ...record3.attempts.map((attempt) => formatTurnAttempt(attempt))].join("\n ");
|
|
31875
32452
|
}
|
|
31876
32453
|
function turnTraceDirectory(runtimeDir) {
|
|
31877
|
-
return
|
|
32454
|
+
return resolve20(runtimeDir, "turn-traces");
|
|
31878
32455
|
}
|
|
31879
32456
|
var TURN_TRACE_RETENTION_DAYS = 7;
|
|
31880
32457
|
function traceFileName(date) {
|
|
@@ -31891,7 +32468,7 @@ var TurnTraceFile = class {
|
|
|
31891
32468
|
this.options = options;
|
|
31892
32469
|
}
|
|
31893
32470
|
path(now2 = (this.options.clock ?? (() => /* @__PURE__ */ new Date()))()) {
|
|
31894
|
-
return
|
|
32471
|
+
return resolve20(this.directory, traceFileName(now2));
|
|
31895
32472
|
}
|
|
31896
32473
|
write(record3) {
|
|
31897
32474
|
this.tail = this.tail.catch(() => void 0).then(async () => {
|
|
@@ -31915,15 +32492,15 @@ var TurnTraceFile = class {
|
|
|
31915
32492
|
this.prunedDay = day;
|
|
31916
32493
|
const cutoff = traceFileName(new Date(now2.getTime() - TURN_TRACE_RETENTION_DAYS * 864e5));
|
|
31917
32494
|
const names = await readdir4(this.directory).catch(() => []);
|
|
31918
|
-
await Promise.all(names.filter((name) => /^turns-\d{4}-\d{2}-\d{2}\.jsonl$/.test(name) && name < cutoff).map((name) => rm3(
|
|
32495
|
+
await Promise.all(names.filter((name) => /^turns-\d{4}-\d{2}-\d{2}\.jsonl$/.test(name) && name < cutoff).map((name) => rm3(resolve20(this.directory, name), { force: true })));
|
|
31919
32496
|
}
|
|
31920
32497
|
};
|
|
31921
32498
|
|
|
31922
32499
|
// apps/body/dist/corner-github-auth.js
|
|
31923
32500
|
import { chmod as chmod4, mkdir as mkdir10, writeFile as writeFile9 } from "node:fs/promises";
|
|
31924
|
-
import { delimiter as delimiter2, resolve as
|
|
32501
|
+
import { delimiter as delimiter2, resolve as resolve21 } from "node:path";
|
|
31925
32502
|
async function installCornerGitHubWrappers(input) {
|
|
31926
|
-
const bin =
|
|
32503
|
+
const bin = resolve21(input.root, "beeline-github-bin");
|
|
31927
32504
|
await mkdir10(bin, { recursive: true, mode: 448 });
|
|
31928
32505
|
const common = {
|
|
31929
32506
|
node: process.execPath,
|
|
@@ -31933,13 +32510,13 @@ async function installCornerGitHubWrappers(input) {
|
|
|
31933
32510
|
featureBranch: input.featureBranch,
|
|
31934
32511
|
targetBranch: input.targetBranch
|
|
31935
32512
|
};
|
|
31936
|
-
await writeLauncher(
|
|
32513
|
+
await writeLauncher(resolve21(bin, "git"), {
|
|
31937
32514
|
...common,
|
|
31938
32515
|
command: input.gitBinary,
|
|
31939
32516
|
launcher: "git"
|
|
31940
32517
|
});
|
|
31941
32518
|
if (input.ghBinary)
|
|
31942
|
-
await writeLauncher(
|
|
32519
|
+
await writeLauncher(resolve21(bin, "gh"), {
|
|
31943
32520
|
...common,
|
|
31944
32521
|
command: input.ghBinary,
|
|
31945
32522
|
launcher: "gh"
|
|
@@ -32077,22 +32654,22 @@ process.exit(result.status ?? 1);
|
|
|
32077
32654
|
import { createHash as createHash5, randomUUID as randomUUID5 } from "node:crypto";
|
|
32078
32655
|
import { constants as fsConstants } from "node:fs";
|
|
32079
32656
|
import { chmod as chmod5, copyFile as copyFile2, link, lstat as lstat3, mkdir as mkdir11, readdir as readdir5, readFile as readFile8, readlink, rename as rename4, rm as rm4, stat as stat2, symlink as symlink2, utimes } from "node:fs/promises";
|
|
32080
|
-
import { dirname as
|
|
32657
|
+
import { dirname as dirname11, join as join10, resolve as resolve22 } from "node:path";
|
|
32081
32658
|
var STORE_FORMAT = "v1";
|
|
32082
32659
|
var STAGING_PREFIX = ".beeline-warm-";
|
|
32083
32660
|
var STAGING_SWEEP_MS = 24 * 60 * 60 * 1e3;
|
|
32084
32661
|
var WARM_STORE_MAX_ENTRIES = 3;
|
|
32085
32662
|
function sharedNpmCacheDir(supervisorRoot) {
|
|
32086
|
-
return
|
|
32663
|
+
return resolve22(supervisorRoot, "beeline", "npm-cache");
|
|
32087
32664
|
}
|
|
32088
32665
|
function warmNodeModulesStoreDir(supervisorRoot) {
|
|
32089
|
-
return
|
|
32666
|
+
return resolve22(supervisorRoot, "beeline", "node-modules");
|
|
32090
32667
|
}
|
|
32091
32668
|
function isPlanRefusal(value) {
|
|
32092
32669
|
return "failure" in value;
|
|
32093
32670
|
}
|
|
32094
32671
|
async function readWarmPlan(worktreePath) {
|
|
32095
|
-
const lockfile = await readFile8(
|
|
32672
|
+
const lockfile = await readFile8(resolve22(worktreePath, "package-lock.json")).catch(() => void 0);
|
|
32096
32673
|
if (!lockfile)
|
|
32097
32674
|
return { failure: "no-lockfile" };
|
|
32098
32675
|
const packages = parseLockfilePackages(lockfile);
|
|
@@ -32131,11 +32708,11 @@ async function seedWarmNodeModules(input) {
|
|
|
32131
32708
|
return { reason: plan.failure, ...plan.detail ? { detail: plan.detail } : {} };
|
|
32132
32709
|
}
|
|
32133
32710
|
for (const tree of plan.trees) {
|
|
32134
|
-
if (await pathExists(
|
|
32711
|
+
if (await pathExists(resolve22(input.worktreePath, tree))) {
|
|
32135
32712
|
return { reason: "present", key: plan.key };
|
|
32136
32713
|
}
|
|
32137
32714
|
}
|
|
32138
|
-
const entry =
|
|
32715
|
+
const entry = resolve22(input.storeRoot, plan.key);
|
|
32139
32716
|
if (!await isDirectory(entry))
|
|
32140
32717
|
return { reason: "cold", key: plan.key };
|
|
32141
32718
|
const [storeDevice, checkoutDevice] = await Promise.all([
|
|
@@ -32145,19 +32722,19 @@ async function seedWarmNodeModules(input) {
|
|
|
32145
32722
|
if (storeDevice === void 0 || storeDevice !== checkoutDevice) {
|
|
32146
32723
|
return { reason: "cross-device", key: plan.key };
|
|
32147
32724
|
}
|
|
32148
|
-
const staging =
|
|
32725
|
+
const staging = resolve22(input.storeRoot, `${STAGING_PREFIX}${process.pid}.${randomUUID5()}`);
|
|
32149
32726
|
const placed = [];
|
|
32150
32727
|
const now2 = (input.now ?? Date.now)();
|
|
32151
32728
|
try {
|
|
32152
32729
|
await sweepStaleStaging(input.storeRoot, now2);
|
|
32153
32730
|
await utimes(entry, now2 / 1e3, now2 / 1e3).catch(() => void 0);
|
|
32154
32731
|
for (const tree of plan.trees) {
|
|
32155
|
-
await cloneTree(
|
|
32732
|
+
await cloneTree(resolve22(entry, tree), resolve22(staging, tree), seedFile);
|
|
32156
32733
|
}
|
|
32157
32734
|
for (const tree of plan.trees) {
|
|
32158
|
-
const target =
|
|
32159
|
-
await mkdir11(
|
|
32160
|
-
await rename4(
|
|
32735
|
+
const target = resolve22(input.worktreePath, tree);
|
|
32736
|
+
await mkdir11(dirname11(target), { recursive: true });
|
|
32737
|
+
await rename4(resolve22(staging, tree), target);
|
|
32161
32738
|
placed.push(target);
|
|
32162
32739
|
}
|
|
32163
32740
|
return { reason: "seeded", key: plan.key };
|
|
@@ -32175,11 +32752,11 @@ async function harvestWarmNodeModules(input) {
|
|
|
32175
32752
|
if (isPlanRefusal(plan)) {
|
|
32176
32753
|
return { reason: plan.failure, ...plan.detail ? { detail: plan.detail } : {} };
|
|
32177
32754
|
}
|
|
32178
|
-
const entry =
|
|
32755
|
+
const entry = resolve22(input.storeRoot, plan.key);
|
|
32179
32756
|
if (await pathExists(entry))
|
|
32180
32757
|
return { reason: "already-warm", key: plan.key };
|
|
32181
32758
|
for (const tree of plan.trees) {
|
|
32182
|
-
if (!await isDirectory(
|
|
32759
|
+
if (!await isDirectory(resolve22(input.worktreePath, tree))) {
|
|
32183
32760
|
return { reason: "no-node-modules", key: plan.key, detail: tree };
|
|
32184
32761
|
}
|
|
32185
32762
|
}
|
|
@@ -32191,12 +32768,12 @@ async function harvestWarmNodeModules(input) {
|
|
|
32191
32768
|
detail: `${missing.length} absent, e.g. ${missing.slice(0, 3).join(", ")}`
|
|
32192
32769
|
};
|
|
32193
32770
|
}
|
|
32194
|
-
const staging =
|
|
32771
|
+
const staging = resolve22(input.storeRoot, `${STAGING_PREFIX}${process.pid}.${randomUUID5()}`);
|
|
32195
32772
|
try {
|
|
32196
32773
|
await mkdir11(input.storeRoot, { recursive: true, mode: 493 });
|
|
32197
32774
|
await sweepStaleStaging(input.storeRoot, (input.now ?? Date.now)());
|
|
32198
32775
|
for (const tree of plan.trees) {
|
|
32199
|
-
await cloneTree(
|
|
32776
|
+
await cloneTree(resolve22(input.worktreePath, tree), resolve22(staging, tree), harvestFile);
|
|
32200
32777
|
}
|
|
32201
32778
|
await input.onCopied?.();
|
|
32202
32779
|
if (!await stagedTreeIsPublishable(input.worktreePath, staging, plan.key)) {
|
|
@@ -32217,18 +32794,18 @@ async function stagedTreeIsPublishable(worktreePath, staging, key) {
|
|
|
32217
32794
|
const settled = await readWarmPlan(worktreePath);
|
|
32218
32795
|
if (isPlanRefusal(settled) || settled.key !== key)
|
|
32219
32796
|
return false;
|
|
32220
|
-
const hidden =
|
|
32797
|
+
const hidden = join10("node_modules", ".package-lock.json");
|
|
32221
32798
|
const [copied, current] = await Promise.all([
|
|
32222
|
-
readFile8(
|
|
32223
|
-
readFile8(
|
|
32799
|
+
readFile8(resolve22(staging, hidden)).catch(() => void 0),
|
|
32800
|
+
readFile8(resolve22(worktreePath, hidden)).catch(() => void 0)
|
|
32224
32801
|
]);
|
|
32225
32802
|
if (!copied || !current || !copied.equals(current))
|
|
32226
32803
|
return false;
|
|
32227
32804
|
return (await missingInstalledPackages(worktreePath, staging)).length === 0;
|
|
32228
32805
|
}
|
|
32229
32806
|
async function missingInstalledPackages(worktreePath, treeRoot = worktreePath) {
|
|
32230
|
-
const wanted = parseLockfilePackages(await readFile8(
|
|
32231
|
-
const installed = parseLockfilePackages(await readFile8(
|
|
32807
|
+
const wanted = parseLockfilePackages(await readFile8(resolve22(worktreePath, "package-lock.json")).catch(() => void 0));
|
|
32808
|
+
const installed = parseLockfilePackages(await readFile8(resolve22(treeRoot, "node_modules", ".package-lock.json")).catch(() => void 0));
|
|
32232
32809
|
if (!wanted)
|
|
32233
32810
|
return ["package-lock.json is unreadable"];
|
|
32234
32811
|
if (!installed)
|
|
@@ -32248,14 +32825,14 @@ async function missingInstalledPackages(worktreePath, treeRoot = worktreePath) {
|
|
|
32248
32825
|
required.push(path);
|
|
32249
32826
|
}
|
|
32250
32827
|
await mapWithLimit(required, INTEGRITY_READ_CONCURRENCY, async (path) => {
|
|
32251
|
-
if (!(path in installed) || !await isInstalledPackage(
|
|
32828
|
+
if (!(path in installed) || !await isInstalledPackage(resolve22(treeRoot, path))) {
|
|
32252
32829
|
missing.push(path);
|
|
32253
32830
|
}
|
|
32254
32831
|
});
|
|
32255
32832
|
return missing.sort();
|
|
32256
32833
|
}
|
|
32257
32834
|
async function isInstalledPackage(path) {
|
|
32258
|
-
return stat2(
|
|
32835
|
+
return stat2(join10(path, "package.json")).then((info) => info.isFile(), () => false);
|
|
32259
32836
|
}
|
|
32260
32837
|
var INTEGRITY_READ_CONCURRENCY = 64;
|
|
32261
32838
|
async function mapWithLimit(values, limit, visit) {
|
|
@@ -32289,8 +32866,8 @@ function isContainedTreePath(value) {
|
|
|
32289
32866
|
async function cloneTree(source, target, file, topLevel = true) {
|
|
32290
32867
|
await mkdir11(target, { recursive: true, mode: 493 });
|
|
32291
32868
|
for (const entry of await readdir5(source, { withFileTypes: true })) {
|
|
32292
|
-
const from =
|
|
32293
|
-
const to =
|
|
32869
|
+
const from = join10(source, entry.name);
|
|
32870
|
+
const to = join10(target, entry.name);
|
|
32294
32871
|
if (entry.isSymbolicLink()) {
|
|
32295
32872
|
await symlink2(await readlink(from), to);
|
|
32296
32873
|
continue;
|
|
@@ -32320,13 +32897,13 @@ async function pruneWarmStore(storeRoot, keep) {
|
|
|
32320
32897
|
const names = (await readdir5(storeRoot).catch(() => [])).filter((name) => !name.startsWith(STAGING_PREFIX));
|
|
32321
32898
|
const entries = [];
|
|
32322
32899
|
for (const name of names) {
|
|
32323
|
-
const info = await lstat3(
|
|
32900
|
+
const info = await lstat3(join10(storeRoot, name)).catch(() => void 0);
|
|
32324
32901
|
if (info?.isDirectory())
|
|
32325
32902
|
entries.push({ name, usedAt: info.mtimeMs });
|
|
32326
32903
|
}
|
|
32327
32904
|
const dropped = entries.sort((a2, b) => b.usedAt - a2.usedAt || a2.name.localeCompare(b.name)).slice(keep);
|
|
32328
32905
|
for (const entry of dropped) {
|
|
32329
|
-
await rm4(
|
|
32906
|
+
await rm4(join10(storeRoot, entry.name), { recursive: true, force: true }).catch(() => void 0);
|
|
32330
32907
|
}
|
|
32331
32908
|
return dropped.map((entry) => entry.name);
|
|
32332
32909
|
}
|
|
@@ -32335,7 +32912,7 @@ async function sweepStaleStaging(storeRoot, now2) {
|
|
|
32335
32912
|
for (const name of entries) {
|
|
32336
32913
|
if (!name.startsWith(STAGING_PREFIX))
|
|
32337
32914
|
continue;
|
|
32338
|
-
const path =
|
|
32915
|
+
const path = join10(storeRoot, name);
|
|
32339
32916
|
const info = await lstat3(path).catch(() => void 0);
|
|
32340
32917
|
if (!info || now2 - info.mtimeMs < STAGING_SWEEP_MS)
|
|
32341
32918
|
continue;
|
|
@@ -32357,8 +32934,8 @@ function describe3(error) {
|
|
|
32357
32934
|
|
|
32358
32935
|
// apps/body/dist/monolith-room-turn.js
|
|
32359
32936
|
import { mkdir as mkdir12 } from "node:fs/promises";
|
|
32360
|
-
import { homedir as
|
|
32361
|
-
import { join as
|
|
32937
|
+
import { homedir as homedir9 } from "node:os";
|
|
32938
|
+
import { join as join11 } from "node:path";
|
|
32362
32939
|
|
|
32363
32940
|
// packages/api-contract/dist/scheduled-prompts.js
|
|
32364
32941
|
var SCHEDULE_SCHEDULER_NAME = "Beeline Scheduler";
|
|
@@ -32508,7 +33085,7 @@ var MonolithRoomTurnLoop = class {
|
|
|
32508
33085
|
...this.options.config.bwrapPath ? { bwrapPath: this.options.config.bwrapPath } : {},
|
|
32509
33086
|
...this.sessionScratchDir ? { scratch: this.sessionScratchDir } : {},
|
|
32510
33087
|
...this.sessionStateDirs.length ? { harnessStateDirs: this.sessionStateDirs } : {},
|
|
32511
|
-
maskPaths: credentialMaskPaths(this.options.config.sandboxMaskPaths, this.options.config.operatorHome ??
|
|
33088
|
+
maskPaths: credentialMaskPaths(this.options.config.sandboxMaskPaths, this.options.config.operatorHome ?? homedir9())
|
|
32512
33089
|
};
|
|
32513
33090
|
}
|
|
32514
33091
|
/**
|
|
@@ -32575,7 +33152,7 @@ var MonolithRoomTurnLoop = class {
|
|
|
32575
33152
|
const cached = this.deliveredAttachments.get(item.id);
|
|
32576
33153
|
if (cached)
|
|
32577
33154
|
return cached;
|
|
32578
|
-
const delivered = await deliverAttachments(item.attachments,
|
|
33155
|
+
const delivered = await deliverAttachments(item.attachments, join11(this.attachmentDir, item.id.replace(/[^\w-]/g, "_")), this.options.fetchImpl);
|
|
32579
33156
|
this.deliveredAttachments.set(item.id, withoutImageData(delivered));
|
|
32580
33157
|
return delivered;
|
|
32581
33158
|
}
|
|
@@ -32608,12 +33185,13 @@ var MonolithRoomTurnLoop = class {
|
|
|
32608
33185
|
return await this.currentSessionFingerprint() === this.sessionFingerprint;
|
|
32609
33186
|
}
|
|
32610
33187
|
async currentSessionFingerprint() {
|
|
32611
|
-
const [configuration, roster] = await Promise.all([
|
|
33188
|
+
const [configuration, roster, grantedHostRoutes] = await Promise.all([
|
|
32612
33189
|
this.options.api.execute("getAgentConfiguration", {
|
|
32613
33190
|
agentId: this.agent.publicKey,
|
|
32614
33191
|
roomId: this.options.roomId
|
|
32615
33192
|
}),
|
|
32616
|
-
this.roster()
|
|
33193
|
+
this.roster(),
|
|
33194
|
+
this.grantedHostRoutes()
|
|
32617
33195
|
]);
|
|
32618
33196
|
const self = roster.members.find((member) => member.identityId === this.agent.publicKey);
|
|
32619
33197
|
return sessionConfigFingerprint({
|
|
@@ -32621,9 +33199,22 @@ var MonolithRoomTurnLoop = class {
|
|
|
32621
33199
|
effort: configuration.effort ?? this.options.config.modelSelection?.effort,
|
|
32622
33200
|
soul: configuration.soul ?? self?.soul,
|
|
32623
33201
|
agentName: self?.name ?? this.agent.name,
|
|
32624
|
-
mcpServers:
|
|
33202
|
+
mcpServers: expectedMountedImportedMcpServerNames({
|
|
33203
|
+
operatorHome: this.options.config.operatorHome,
|
|
33204
|
+
agentKind: this.options.config.agentKind,
|
|
33205
|
+
grantedHostRoutes
|
|
33206
|
+
})
|
|
32625
33207
|
});
|
|
32626
33208
|
}
|
|
33209
|
+
async grantedHostRoutes() {
|
|
33210
|
+
try {
|
|
33211
|
+
return grantedHostRoutesFromList(await this.options.api.execute("listAgentGrants", {
|
|
33212
|
+
agentId: this.agent.publicKey
|
|
33213
|
+
}));
|
|
33214
|
+
} catch {
|
|
33215
|
+
return [];
|
|
33216
|
+
}
|
|
33217
|
+
}
|
|
32627
33218
|
mountedMcpServers(preparedEnv) {
|
|
32628
33219
|
return mountedImportedMcpServerNames({
|
|
32629
33220
|
operatorHome: this.options.config.operatorHome,
|
|
@@ -32635,13 +33226,14 @@ var MonolithRoomTurnLoop = class {
|
|
|
32635
33226
|
if (this.client?.isAlive && this.sessionId)
|
|
32636
33227
|
return this.sessionId;
|
|
32637
33228
|
trace?.noteActivation("cold");
|
|
32638
|
-
const [configuration, roster, repositoryState] = await Promise.all([
|
|
33229
|
+
const [configuration, roster, repositoryState, grantedHostRoutes] = await Promise.all([
|
|
32639
33230
|
this.options.api.execute("getAgentConfiguration", {
|
|
32640
33231
|
agentId: this.agent.publicKey,
|
|
32641
33232
|
roomId: this.options.roomId
|
|
32642
33233
|
}),
|
|
32643
33234
|
this.roster(),
|
|
32644
|
-
this.repositoryState()
|
|
33235
|
+
this.repositoryState(),
|
|
33236
|
+
this.grantedHostRoutes()
|
|
32645
33237
|
]);
|
|
32646
33238
|
const self = roster.members.find((member) => member.identityId === this.agent.publicKey);
|
|
32647
33239
|
const directMessage = Array.isArray(repositoryState.directParticipants) && repositoryState.directParticipants.length === 2;
|
|
@@ -32649,10 +33241,12 @@ var MonolithRoomTurnLoop = class {
|
|
|
32649
33241
|
const selectionModel = configuration.model ?? this.options.config.modelSelection?.model;
|
|
32650
33242
|
const selectionEffort = configuration.effort ?? this.options.config.modelSelection?.effort;
|
|
32651
33243
|
const selection = selectionModel || selectionEffort ? { model: selectionModel, effort: selectionEffort } : void 0;
|
|
33244
|
+
const operatorHome = this.options.config.operatorHome ?? homedir9();
|
|
32652
33245
|
const homeOverlay = this.options.config.agentHomeRoot ? await prepareRoomAgentHome({
|
|
32653
33246
|
root: this.options.config.agentHomeRoot,
|
|
32654
33247
|
sharedSkills: this.options.config.sharedSkills ?? [],
|
|
32655
33248
|
isReviewer: isConfiguredReviewer(self?.handle, configuration.reviewerHandle),
|
|
33249
|
+
grantedHostRoutes,
|
|
32656
33250
|
...this.options.config.agentKind ? { agentKind: this.options.config.agentKind } : {},
|
|
32657
33251
|
...this.options.config.operatorHome ? { operatorHome: this.options.config.operatorHome } : {},
|
|
32658
33252
|
...openRouterRoutingInput(this.options.config, selection, this.options.fetchImpl, {
|
|
@@ -32675,7 +33269,11 @@ var MonolithRoomTurnLoop = class {
|
|
|
32675
33269
|
effort: configuration.effort ?? this.options.config.modelSelection?.effort,
|
|
32676
33270
|
soul: configuration.soul ?? self?.soul,
|
|
32677
33271
|
agentName: self?.name ?? this.agent.name,
|
|
32678
|
-
mcpServers:
|
|
33272
|
+
mcpServers: expectedMountedImportedMcpServerNames({
|
|
33273
|
+
operatorHome: this.options.config.operatorHome,
|
|
33274
|
+
agentKind: this.options.config.agentKind,
|
|
33275
|
+
grantedHostRoutes
|
|
33276
|
+
})
|
|
32679
33277
|
});
|
|
32680
33278
|
this.agentEnv = agentEnv;
|
|
32681
33279
|
const agentArgs = agentArgsWithModelSelection({
|
|
@@ -32683,9 +33281,8 @@ var MonolithRoomTurnLoop = class {
|
|
|
32683
33281
|
command,
|
|
32684
33282
|
args: this.options.config.agentArgs ?? []
|
|
32685
33283
|
}, selection);
|
|
32686
|
-
const operatorHome = this.options.config.operatorHome ?? homedir7();
|
|
32687
33284
|
const { stateDirs, tmpDir } = harnessStateDirsFromEnv(agentEnv);
|
|
32688
|
-
this.attachmentDir = tmpDir ?
|
|
33285
|
+
this.attachmentDir = tmpDir ? join11(tmpDir, "beeline-attachments") : void 0;
|
|
32689
33286
|
this.sessionScratchDir = tmpDir;
|
|
32690
33287
|
this.sessionStateDirs = stateDirs;
|
|
32691
33288
|
const homeStateDirs = harnessHomeStateDirs(harnessLabel, agentEnv.HOME ?? operatorHome);
|
|
@@ -32701,7 +33298,14 @@ var MonolithRoomTurnLoop = class {
|
|
|
32701
33298
|
harnessStateDirs: stateDirs,
|
|
32702
33299
|
harnessHomeStateDirs: homeStateDirs,
|
|
32703
33300
|
...tmpDir ? { tmpDir } : {},
|
|
32704
|
-
|
|
33301
|
+
additionalWritablePaths: [
|
|
33302
|
+
...attachScratchRoot ? [attachScratchRoot] : [],
|
|
33303
|
+
...grantedSquireHostBindPaths({
|
|
33304
|
+
operatorHome,
|
|
33305
|
+
agentKind: this.options.config.agentKind,
|
|
33306
|
+
grantedHostRoutes
|
|
33307
|
+
})
|
|
33308
|
+
],
|
|
32705
33309
|
maskPaths: credentialMaskPaths(this.options.config.sandboxMaskPaths, operatorHome)
|
|
32706
33310
|
},
|
|
32707
33311
|
command,
|
|
@@ -32726,16 +33330,24 @@ var MonolithRoomTurnLoop = class {
|
|
|
32726
33330
|
const youtube = youtubeMcpServer(this.options.config, this.options.youtubeAccessToken);
|
|
32727
33331
|
if (youtube)
|
|
32728
33332
|
servers.push(youtube);
|
|
33333
|
+
const grantedRouteServers = grantedHostRouteWires(grantedHostRoutes, operatorHome, hostImportedMcpDeclarations({
|
|
33334
|
+
operatorHome,
|
|
33335
|
+
agentKind: this.options.config.agentKind
|
|
33336
|
+
}));
|
|
32729
33337
|
await installPiMcpBridge({
|
|
32730
33338
|
agentCommand: harnessLabel,
|
|
32731
33339
|
piHome: agentEnv.PI_CODING_AGENT_DIR,
|
|
32732
|
-
servers
|
|
33340
|
+
servers: [...servers, ...grantedRouteServers]
|
|
32733
33341
|
});
|
|
32734
|
-
const mountedServers =
|
|
32735
|
-
|
|
33342
|
+
const mountedServers = [
|
|
33343
|
+
...servers.map((server) => server.name),
|
|
33344
|
+
...grantedRouteServers.map((server) => server.name),
|
|
33345
|
+
...this.mountedMcpServers(agentEnv)
|
|
33346
|
+
];
|
|
33347
|
+
const hostServers = ungatedHostServers(hostImportedMcpServerNames({
|
|
32736
33348
|
operatorHome: this.options.config.operatorHome,
|
|
32737
33349
|
agentKind: this.options.config.agentKind
|
|
32738
|
-
});
|
|
33350
|
+
}), grantedHostRoutes);
|
|
32739
33351
|
const clientOptions = {
|
|
32740
33352
|
agentCommand: spawnCommand.command,
|
|
32741
33353
|
agentArgs: spawnCommand.args,
|
|
@@ -32971,9 +33583,9 @@ ${JSON.stringify((corners.corners ?? []).filter((corner) => !corner.archived))}`
|
|
|
32971
33583
|
try {
|
|
32972
33584
|
stream.beginRun();
|
|
32973
33585
|
trace.promptSent();
|
|
32974
|
-
result2 = await this.client.sessionPrompt(this.sessionId, nextPrompt, ROOM_PROMPT_INACTIVITY_TIMEOUT_MS, (delta, full) => {
|
|
33586
|
+
result2 = await this.client.sessionPrompt(this.sessionId, nextPrompt, ROOM_PROMPT_INACTIVITY_TIMEOUT_MS, (delta, full, currentRun) => {
|
|
32975
33587
|
trace.firstModelOutput();
|
|
32976
|
-
stream.onChunk(delta, full);
|
|
33588
|
+
stream.onChunk(delta, full, currentRun);
|
|
32977
33589
|
}, void 0, (calls) => {
|
|
32978
33590
|
trace.toolCalls(calls);
|
|
32979
33591
|
if (openedACorner(openCornerToolCall(calls)))
|
|
@@ -33006,8 +33618,8 @@ ${JSON.stringify((corners.corners ?? []).filter((corner) => !corner.archived))}`
|
|
|
33006
33618
|
trace.promptSettled();
|
|
33007
33619
|
let openCornerCall = openCornerToolCall(result.toolCalls);
|
|
33008
33620
|
let cornerOpened = openedACorner(openCornerCall);
|
|
33009
|
-
let explained =
|
|
33010
|
-
if (explained && shouldRetryEmptyTurn(explained)) {
|
|
33621
|
+
let explained = await this.explainEmpty(result);
|
|
33622
|
+
if (!cornerOpened && explained && shouldRetryEmptyTurn(explained)) {
|
|
33011
33623
|
const silent = this.servingProviders();
|
|
33012
33624
|
const next = await this.repinNextProvider(trace, explained.reason);
|
|
33013
33625
|
if (next) {
|
|
@@ -33016,7 +33628,7 @@ ${JSON.stringify((corners.corners ?? []).filter((corner) => !corner.archived))}`
|
|
|
33016
33628
|
trace.promptSettled();
|
|
33017
33629
|
openCornerCall = openCornerToolCall(result.toolCalls);
|
|
33018
33630
|
cornerOpened = openedACorner(openCornerCall);
|
|
33019
|
-
explained =
|
|
33631
|
+
explained = await this.explainEmpty(result);
|
|
33020
33632
|
}
|
|
33021
33633
|
}
|
|
33022
33634
|
if (active.cancelled) {
|
|
@@ -33043,15 +33655,14 @@ ${JSON.stringify((corners.corners ?? []).filter((corner) => !corner.archived))}`
|
|
|
33043
33655
|
}
|
|
33044
33656
|
stream.close();
|
|
33045
33657
|
let reply = durableReplyText(result.agentText);
|
|
33046
|
-
if (!reply && explained) {
|
|
33047
|
-
reply =
|
|
33048
|
-
if (!reply) {
|
|
33049
|
-
throw new Error(turnFailureReasonWithProvider(explained.reason, this.servingProviders()));
|
|
33050
|
-
}
|
|
33051
|
-
console.warn(`[thin-core] monolith Room ${this.options.roomId} turn ${item.id}: ${explained.reason}`);
|
|
33658
|
+
if (!reply && explained?.recoveredText) {
|
|
33659
|
+
reply = durableReplyText(explained.recoveredText);
|
|
33052
33660
|
}
|
|
33053
|
-
if (cornerOpened) {
|
|
33054
|
-
|
|
33661
|
+
if (!reply && explained && !cornerOpened) {
|
|
33662
|
+
throw new Error(turnFailureReasonWithProvider(explained.reason, this.servingProviders()));
|
|
33663
|
+
}
|
|
33664
|
+
if (reply && explained) {
|
|
33665
|
+
console.warn(`[thin-core] monolith Room ${this.options.roomId} turn ${item.id}: ${explained.reason}`);
|
|
33055
33666
|
}
|
|
33056
33667
|
await trace.measure("publish", () => stream.settle(reply, reply ? {
|
|
33057
33668
|
triggerMessageId: item.id
|
|
@@ -33075,9 +33686,14 @@ ${JSON.stringify((corners.corners ?? []).filter((corner) => !corner.archived))}`
|
|
|
33075
33686
|
if (liveCornerOpened && error instanceof AcpRequestTimeoutError && error.inactivity && error.method === "session/prompt") {
|
|
33076
33687
|
console.log(`[thin-core] monolith Room ${this.options.roomId} turn ${item.id}: inactivity timeout after opening a corner; the work continues in the corner`);
|
|
33077
33688
|
this.options.onCornerOpened?.();
|
|
33078
|
-
|
|
33079
|
-
|
|
33080
|
-
|
|
33689
|
+
const lastRun = liveStream?.lastRunText ?? "";
|
|
33690
|
+
const streamed = isPureRetryNarration(lastRun) ? "" : durableReplyText(lastRun);
|
|
33691
|
+
if (liveStream) {
|
|
33692
|
+
await liveStream.settle(streamed, streamed ? { triggerMessageId: item.id } : {}).catch((settleError) => {
|
|
33693
|
+
console.error(`[thin-core] monolith Room ${this.options.roomId} draft settle failed:`, settleError);
|
|
33694
|
+
});
|
|
33695
|
+
await liveStream.retract();
|
|
33696
|
+
}
|
|
33081
33697
|
await api.execute("postAgentTurnReceipt", {
|
|
33082
33698
|
agentId: this.agent.publicKey,
|
|
33083
33699
|
roomId: this.options.roomId,
|
|
@@ -33163,7 +33779,7 @@ var TOOL_OUTPUT_MAX_BYTES = 3200;
|
|
|
33163
33779
|
var TOOL_PATH_LIMIT = 12;
|
|
33164
33780
|
function cornerMergeInstruction(yoloMode, reviewerHandle) {
|
|
33165
33781
|
if (reviewerHandle)
|
|
33166
|
-
return `Commit, push, open the PR, and reply with the URL; do not merge until @${reviewerHandle}
|
|
33782
|
+
return `Commit, push, open the PR, and reply with the URL; do not merge until @${reviewerHandle} has reviewed \u2014 you are woken when that review ends, whether or not it tags you \u2014 then call pr_checks_status and merge with gh pr merge --squash --match-head-commit <sha> only if the complete gate passes.`;
|
|
33167
33783
|
return yoloMode ? "Yolo is on: when the gate passes, merge this pull request with gh." : "Yolo is off: never merge; wait for a human owner to turn yolo on or merge the pull request themselves.";
|
|
33168
33784
|
}
|
|
33169
33785
|
function cornerReviewerInstruction(input) {
|
|
@@ -33486,12 +34102,13 @@ var MonolithCornerTurnLoop = class {
|
|
|
33486
34102
|
return await this.currentSessionFingerprint() === this.sessionFingerprint;
|
|
33487
34103
|
}
|
|
33488
34104
|
async currentSessionFingerprint() {
|
|
33489
|
-
const [configuration, roster] = await Promise.all([
|
|
34105
|
+
const [configuration, roster, grantedHostRoutes] = await Promise.all([
|
|
33490
34106
|
this.options.api.execute("getAgentConfiguration", {
|
|
33491
34107
|
agentId: this.agent.publicKey,
|
|
33492
34108
|
roomId: this.options.cornerId
|
|
33493
34109
|
}),
|
|
33494
|
-
this.roster()
|
|
34110
|
+
this.roster(),
|
|
34111
|
+
this.grantedHostRoutes()
|
|
33495
34112
|
]);
|
|
33496
34113
|
const self = roster.members.find((member) => member.identityId === this.agent.publicKey);
|
|
33497
34114
|
return sessionConfigFingerprint({
|
|
@@ -33500,27 +34117,34 @@ var MonolithCornerTurnLoop = class {
|
|
|
33500
34117
|
soul: configuration.soul ?? self?.soul,
|
|
33501
34118
|
agentName: self?.name ?? this.agent.name,
|
|
33502
34119
|
yoloMode: configuration.yoloMode,
|
|
33503
|
-
mcpServers:
|
|
34120
|
+
mcpServers: expectedMountedImportedMcpServerNames({
|
|
34121
|
+
operatorHome: this.options.config.operatorHome,
|
|
34122
|
+
agentKind: this.options.config.agentKind,
|
|
34123
|
+
grantedHostRoutes
|
|
34124
|
+
}),
|
|
33504
34125
|
reviewerHandle: configuration.reviewerHandle
|
|
33505
34126
|
});
|
|
33506
34127
|
}
|
|
33507
|
-
|
|
33508
|
-
|
|
33509
|
-
|
|
33510
|
-
|
|
33511
|
-
|
|
33512
|
-
}
|
|
34128
|
+
async grantedHostRoutes() {
|
|
34129
|
+
try {
|
|
34130
|
+
return grantedHostRoutesFromList(await this.options.api.execute("listAgentGrants", {
|
|
34131
|
+
agentId: this.agent.publicKey
|
|
34132
|
+
}));
|
|
34133
|
+
} catch {
|
|
34134
|
+
return [];
|
|
34135
|
+
}
|
|
33513
34136
|
}
|
|
33514
34137
|
async activate(trace) {
|
|
33515
34138
|
if (this.client?.isAlive && this.sessionId)
|
|
33516
34139
|
return this.sessionId;
|
|
33517
34140
|
trace?.noteActivation("cold");
|
|
33518
|
-
const [configuration, roster] = await Promise.all([
|
|
34141
|
+
const [configuration, roster, grantedHostRoutes] = await Promise.all([
|
|
33519
34142
|
this.options.api.execute("getAgentConfiguration", {
|
|
33520
34143
|
agentId: this.agent.publicKey,
|
|
33521
34144
|
roomId: this.options.cornerId
|
|
33522
34145
|
}),
|
|
33523
|
-
this.roster()
|
|
34146
|
+
this.roster(),
|
|
34147
|
+
this.grantedHostRoutes()
|
|
33524
34148
|
]);
|
|
33525
34149
|
const self = roster.members.find((member) => member.identityId === this.agent.publicKey);
|
|
33526
34150
|
this.yoloMode = configuration.yoloMode;
|
|
@@ -33551,6 +34175,7 @@ var MonolithCornerTurnLoop = class {
|
|
|
33551
34175
|
root: this.options.config.agentHomeRoot,
|
|
33552
34176
|
sharedSkills: this.options.config.sharedSkills ?? [],
|
|
33553
34177
|
isReviewer: isConfiguredReviewer(self?.handle, configuration.reviewerHandle),
|
|
34178
|
+
grantedHostRoutes,
|
|
33554
34179
|
...this.options.config.agentKind ? { agentKind: this.options.config.agentKind } : {},
|
|
33555
34180
|
...this.options.config.operatorHome ? { operatorHome: this.options.config.operatorHome } : {},
|
|
33556
34181
|
...openRouterRoutingInput(this.options.config, selection, this.options.fetchImpl, {
|
|
@@ -33592,13 +34217,18 @@ var MonolithCornerTurnLoop = class {
|
|
|
33592
34217
|
...githubEnv,
|
|
33593
34218
|
npm_config_cache: npmCacheDir
|
|
33594
34219
|
};
|
|
34220
|
+
const operatorHome = this.options.config.operatorHome ?? homedir10();
|
|
33595
34221
|
const fingerprint = sessionConfigFingerprint({
|
|
33596
34222
|
model: configuration.model ?? this.options.config.modelSelection?.model,
|
|
33597
34223
|
effort: configuration.effort ?? this.options.config.modelSelection?.effort,
|
|
33598
34224
|
soul: configuration.soul ?? self?.soul,
|
|
33599
34225
|
agentName: self?.name ?? this.agent.name,
|
|
33600
34226
|
yoloMode: configuration.yoloMode,
|
|
33601
|
-
mcpServers:
|
|
34227
|
+
mcpServers: expectedMountedImportedMcpServerNames({
|
|
34228
|
+
operatorHome: this.options.config.operatorHome,
|
|
34229
|
+
agentKind: this.options.config.agentKind,
|
|
34230
|
+
grantedHostRoutes
|
|
34231
|
+
}),
|
|
33602
34232
|
reviewerHandle: configuration.reviewerHandle
|
|
33603
34233
|
});
|
|
33604
34234
|
this.agentEnv = agentEnv;
|
|
@@ -33607,9 +34237,8 @@ var MonolithCornerTurnLoop = class {
|
|
|
33607
34237
|
command,
|
|
33608
34238
|
args: this.options.config.agentArgs ?? []
|
|
33609
34239
|
}, selection);
|
|
33610
|
-
const operatorHome = this.options.config.operatorHome ?? homedir8();
|
|
33611
34240
|
const { stateDirs, tmpDir } = harnessStateDirsFromEnv(agentEnv);
|
|
33612
|
-
this.attachmentDir = tmpDir ?
|
|
34241
|
+
this.attachmentDir = tmpDir ? join12(tmpDir, "beeline-attachments") : void 0;
|
|
33613
34242
|
this.sessionScratchDir = tmpDir;
|
|
33614
34243
|
const homeStateDirs = harnessHomeStateDirs(harnessLabel, agentEnv.HOME ?? operatorHome);
|
|
33615
34244
|
await Promise.all(homeStateDirs.map((dir) => mkdir13(dir, { recursive: true })));
|
|
@@ -33632,7 +34261,12 @@ var MonolithCornerTurnLoop = class {
|
|
|
33632
34261
|
// The shared npm cache. npm writes to its cache on every install,
|
|
33633
34262
|
// and this one is deliberately outside the per-corner home so the
|
|
33634
34263
|
// download is paid once per host rather than once per corner.
|
|
33635
|
-
npmCacheDir
|
|
34264
|
+
npmCacheDir,
|
|
34265
|
+
...grantedSquireHostBindPaths({
|
|
34266
|
+
operatorHome,
|
|
34267
|
+
agentKind: this.options.config.agentKind,
|
|
34268
|
+
grantedHostRoutes
|
|
34269
|
+
})
|
|
33636
34270
|
],
|
|
33637
34271
|
maskPaths: credentialMaskPaths(this.options.config.sandboxMaskPaths, operatorHome)
|
|
33638
34272
|
},
|
|
@@ -33686,10 +34320,14 @@ var MonolithCornerTurnLoop = class {
|
|
|
33686
34320
|
const youtube = youtubeMcpServer(this.options.config, this.options.youtubeAccessToken);
|
|
33687
34321
|
if (youtube)
|
|
33688
34322
|
servers.push(youtube);
|
|
34323
|
+
const grantedRouteServers = grantedHostRouteWires(grantedHostRoutes, operatorHome, hostImportedMcpDeclarations({
|
|
34324
|
+
operatorHome,
|
|
34325
|
+
agentKind: this.options.config.agentKind
|
|
34326
|
+
}));
|
|
33689
34327
|
await installPiMcpBridge({
|
|
33690
34328
|
agentCommand: harnessLabel,
|
|
33691
34329
|
piHome: agentEnv.PI_CODING_AGENT_DIR,
|
|
33692
|
-
servers
|
|
34330
|
+
servers: [...servers, ...grantedRouteServers]
|
|
33693
34331
|
});
|
|
33694
34332
|
const persona = configuration.soul ?? self?.soul;
|
|
33695
34333
|
const identityInstructions = `Your Beeline identity is ${self?.name ?? this.agent.name}.`;
|
|
@@ -33714,11 +34352,15 @@ var MonolithCornerTurnLoop = class {
|
|
|
33714
34352
|
selfReviewerInstruction ?? cornerMergeInstruction(configuration.yoloMode, configuration.reviewerHandle)
|
|
33715
34353
|
],
|
|
33716
34354
|
"Do not tag the user when a corner turn finishes: the server posts the merge summary card and its push already cover completion. Tag a human only mid-turn, and only when you need a decision or input.",
|
|
33717
|
-
"Never restate server check or merge notes. On a checks turn, say nothing unless you merge or push a fix, then use one short line. When asked whether the reviewer was woken, call pr_checks_status and report reviewerWake; do not invent a cause. Never merge while approvalPending is true. When approval is pending, wait
|
|
34355
|
+
"Never restate server check or merge notes. On a checks turn, say nothing unless you merge or push a fix, then use one short line. When asked whether the reviewer was woken, call pr_checks_status and report reviewerWake; do not invent a cause. Never merge while approvalPending is true. When approval is pending, wait to be woken. Never merge another pull request. Never create a schedule to poll pr_checks_status or the merge gate: the green transition wakes the reviewer and the end of that review wakes you, tag or no tag, and tagging any agent other than the configured reviewer cannot clear the gate. If a schedule wakes you in this corner anyway, follow the same rule as a checks turn: say nothing unless you merge, push a fix, or report a genuinely new blocker."
|
|
33718
34356
|
] : [
|
|
33719
|
-
"This is a
|
|
34357
|
+
"This is a no-code corner with no repository checkout and no GitHub workflow.",
|
|
33720
34358
|
"Work in this corner's writable workspace. Use write_scratch_file or ordinary tools to create files, then post_artifact with the path to send them back to the corner.",
|
|
33721
|
-
"Do not initialize a repository, create a branch, push, open a pull request, or wait for GitHub checks."
|
|
34359
|
+
"Do not initialize a repository, create a branch, commit, push, open a pull request, or wait for GitHub checks.",
|
|
34360
|
+
// This lane has no pull request URL and no merge card, so the
|
|
34361
|
+
// artifacts and the tag ARE the completion signal. Without the
|
|
34362
|
+
// tag the person who asked is never told the work finished.
|
|
34363
|
+
this.options.requesterHandle ? `Deliver the result as artifacts: post_artifact everything the objective asked for, then finish by replying with @${this.options.requesterHandle} and one line on what you posted. That reply is this corner's only completion signal.` : `Deliver the result as artifacts: post_artifact everything the objective asked for, then finish by replying with one line on what you posted. That reply is this corner's only completion signal.`
|
|
33722
34364
|
]
|
|
33723
34365
|
].filter(Boolean).join("\n\n")
|
|
33724
34366
|
});
|
|
@@ -33837,7 +34479,7 @@ var MonolithCornerTurnLoop = class {
|
|
|
33837
34479
|
const [conversation, roster, delivered] = await trace.measure("context-fetch", () => Promise.all([
|
|
33838
34480
|
api.execute("getRoomConversation", { roomId: cornerId, limit: 200 }),
|
|
33839
34481
|
this.roster(),
|
|
33840
|
-
this.attachmentDir && attachments.length ? deliverAttachments(attachments,
|
|
34482
|
+
this.attachmentDir && attachments.length ? deliverAttachments(attachments, join12(this.attachmentDir, requestId.replace(/[^\w-]/g, "_")), this.options.fetchImpl) : Promise.resolve([])
|
|
33841
34483
|
]));
|
|
33842
34484
|
const names = new Map(roster.members.map((member) => [member.identityId, member.name]));
|
|
33843
34485
|
const requestedBy = requester && !requester.name && names.get(requester.pubkey) ? { ...requester, name: names.get(requester.pubkey) } : requester;
|
|
@@ -33969,7 +34611,7 @@ ${trigger}`,
|
|
|
33969
34611
|
completedNarrationRuns.push(currentNarrationRun);
|
|
33970
34612
|
currentNarrationRun = currentRun;
|
|
33971
34613
|
}
|
|
33972
|
-
stream.onChunk(delta, full);
|
|
34614
|
+
stream.onChunk(delta, full, currentRun);
|
|
33973
34615
|
}, void 0, (calls) => {
|
|
33974
34616
|
trace.toolCalls(calls);
|
|
33975
34617
|
publishToolCalls(calls, true);
|
|
@@ -34619,12 +35261,12 @@ function isStandingCornerStartFault(error) {
|
|
|
34619
35261
|
async function materializeCornerWorktree(input) {
|
|
34620
35262
|
const remote = roomCheckoutRemote(input.remote);
|
|
34621
35263
|
const repositoryHash = createHash7("sha256").update(remote).digest("hex").slice(0, 24);
|
|
34622
|
-
const gitCommonDir =
|
|
34623
|
-
const path =
|
|
34624
|
-
await mkdir14(
|
|
34625
|
-
await mkdir14(
|
|
35264
|
+
const gitCommonDir = resolve23(input.supervisorRoot, "beeline", "repositories", `${repositoryHash}.git`);
|
|
35265
|
+
const path = resolve23(input.supervisorRoot, "beeline", "corners", input.cornerId);
|
|
35266
|
+
await mkdir14(dirname12(gitCommonDir), { recursive: true, mode: 448 });
|
|
35267
|
+
await mkdir14(dirname12(path), { recursive: true, mode: 448 });
|
|
34626
35268
|
const authEnv = githubGitEnv(input.token);
|
|
34627
|
-
if (!
|
|
35269
|
+
if (!existsSync6(resolve23(gitCommonDir, "HEAD"))) {
|
|
34628
35270
|
await execFileAsync4("git", ["clone", "--bare", remote, gitCommonDir], {
|
|
34629
35271
|
env: authEnv,
|
|
34630
35272
|
maxBuffer: 4 * 1024 * 1024
|
|
@@ -34643,7 +35285,7 @@ async function materializeCornerWorktree(input) {
|
|
|
34643
35285
|
"origin",
|
|
34644
35286
|
`+refs/heads/${input.featureBranch}:refs/remotes/origin/${input.featureBranch}`
|
|
34645
35287
|
], { env: authEnv, maxBuffer: 4 * 1024 * 1024 }).then(() => true, () => false);
|
|
34646
|
-
if (!
|
|
35288
|
+
if (!existsSync6(resolve23(path, ".git"))) {
|
|
34647
35289
|
await rm5(path, { recursive: true, force: true });
|
|
34648
35290
|
await execFileAsync4("git", [
|
|
34649
35291
|
`--git-dir=${gitCommonDir}`,
|
|
@@ -34694,7 +35336,7 @@ async function materializeCornerWorktree(input) {
|
|
|
34694
35336
|
`${input.committer.publicKey.slice(0, 16)}@users.noreply.github.com`
|
|
34695
35337
|
]);
|
|
34696
35338
|
const top = await execFileAsync4("git", ["-C", path, "rev-parse", "--show-toplevel"]);
|
|
34697
|
-
if (
|
|
35339
|
+
if (resolve23(top.stdout.trim()) !== resolve23(path)) {
|
|
34698
35340
|
throw new Error(`corner worktree escaped its isolated root: ${top.stdout.trim()}`);
|
|
34699
35341
|
}
|
|
34700
35342
|
return { path, gitCommonDir };
|
|
@@ -34715,7 +35357,7 @@ async function mapWithConcurrency(values, limit, visit) {
|
|
|
34715
35357
|
async function removeCornerWorktreeAndBranches(worktree) {
|
|
34716
35358
|
const localRef = `refs/heads/${worktree.branch}`;
|
|
34717
35359
|
const remoteRef = `refs/heads/${worktree.branch}`;
|
|
34718
|
-
const worktreeExists =
|
|
35360
|
+
const worktreeExists = existsSync6(worktree.path);
|
|
34719
35361
|
const localExists = await gitRefExists(worktree.gitCommonDir, localRef);
|
|
34720
35362
|
if (worktreeExists) {
|
|
34721
35363
|
const checkedOut = await execFileAsync4("git", [
|
|
@@ -34760,8 +35402,8 @@ async function removeCornerWorktreeAndBranches(worktree) {
|
|
|
34760
35402
|
}
|
|
34761
35403
|
var execFileAsync4 = promisify4(execFile6);
|
|
34762
35404
|
async function removeCornerScratchWorkspace(input) {
|
|
34763
|
-
const expected =
|
|
34764
|
-
if (
|
|
35405
|
+
const expected = resolve23(input.roomRoot, "scratch");
|
|
35406
|
+
if (resolve23(input.scratchPath) !== expected) {
|
|
34765
35407
|
throw new Error(`refusing to remove scratch outside corner ${input.cornerId}`);
|
|
34766
35408
|
}
|
|
34767
35409
|
await rm5(expected, { recursive: true, force: true });
|
|
@@ -34982,17 +35624,17 @@ var RoomRuntimeCoordinator = class {
|
|
|
34982
35624
|
return this.runtime.rooms.find((room) => room.channelId === roomId);
|
|
34983
35625
|
}
|
|
34984
35626
|
roomRoot(roomId) {
|
|
34985
|
-
return this.roomRecord(roomId)?.root ??
|
|
35627
|
+
return this.roomRecord(roomId)?.root ?? resolve23(dirname12(this.configPath), "rooms", roomId);
|
|
34986
35628
|
}
|
|
34987
35629
|
roomAgentHomeRoot(workspaceRoot, required = false) {
|
|
34988
35630
|
const flag = process.env.BUZZY_BODY_ROOM_HOME;
|
|
34989
35631
|
if (!required && flag === "0")
|
|
34990
35632
|
return void 0;
|
|
34991
|
-
const home =
|
|
34992
|
-
if (!required && flag !== "1" && !
|
|
35633
|
+
const home = resolve23(workspaceRoot, "agent-home");
|
|
35634
|
+
if (!required && flag !== "1" && !existsSync6(home) && existsSync6(workspaceRoot))
|
|
34993
35635
|
return void 0;
|
|
34994
35636
|
try {
|
|
34995
|
-
|
|
35637
|
+
mkdirSync3(home, { recursive: true, mode: 448 });
|
|
34996
35638
|
return home;
|
|
34997
35639
|
} catch (error) {
|
|
34998
35640
|
console.error(`[thin-core] per-room agent home unavailable at ${home}:`, error);
|
|
@@ -35004,10 +35646,10 @@ var RoomRuntimeCoordinator = class {
|
|
|
35004
35646
|
return {
|
|
35005
35647
|
...this.baseConfig,
|
|
35006
35648
|
workspaceRoot,
|
|
35007
|
-
agentPrivateRoot:
|
|
35008
|
-
agentMemoryRoot:
|
|
35009
|
-
openRouterRoutingCacheDir: openRouterRoutingCacheDir(
|
|
35010
|
-
turnTraceDir: turnTraceDirectory(
|
|
35649
|
+
agentPrivateRoot: resolve23(workspaceRoot, "agent-private"),
|
|
35650
|
+
agentMemoryRoot: resolve23(dirname12(this.configPath), "memory"),
|
|
35651
|
+
openRouterRoutingCacheDir: openRouterRoutingCacheDir(dirname12(this.configPath)),
|
|
35652
|
+
turnTraceDir: turnTraceDirectory(dirname12(this.configPath)),
|
|
35011
35653
|
...agentHomeRoot ? { agentHomeRoot } : {}
|
|
35012
35654
|
};
|
|
35013
35655
|
}
|
|
@@ -35085,11 +35727,11 @@ var RoomRuntimeCoordinator = class {
|
|
|
35085
35727
|
const remote = roomCheckoutRemote(repository.remote);
|
|
35086
35728
|
const targetBranch = repository.targetBranch || "main";
|
|
35087
35729
|
const checkoutId = createHash7("sha256").update(`${remote}\0${targetBranch}`).digest("hex").slice(0, 24);
|
|
35088
|
-
const path =
|
|
35089
|
-
await mkdir14(
|
|
35730
|
+
const path = resolve23(this.runtime.supervisorRoot, "beeline", "room-checkouts", checkoutId);
|
|
35731
|
+
await mkdir14(dirname12(path), { recursive: true, mode: 448 });
|
|
35090
35732
|
const token = remote.startsWith("https://github.com/") ? await this.options.daemonApi.execute("getRoomGitHubToken", { roomId }) : void 0;
|
|
35091
35733
|
const env = token ? githubGitEnv(token.token) : process.env;
|
|
35092
|
-
if (!
|
|
35734
|
+
if (!existsSync6(resolve23(path, ".git"))) {
|
|
35093
35735
|
await execFileAsync4("git", ["clone", "--no-checkout", remote, path], {
|
|
35094
35736
|
env,
|
|
35095
35737
|
maxBuffer: 4 * 1024 * 1024
|
|
@@ -35138,7 +35780,7 @@ var RoomRuntimeCoordinator = class {
|
|
|
35138
35780
|
const objective = (restore.objective ?? "").trim();
|
|
35139
35781
|
if (!objective)
|
|
35140
35782
|
throw new Error("corner has no authoritative objective fact");
|
|
35141
|
-
const repositoryBacked = repository.resolution === "repository";
|
|
35783
|
+
const repositoryBacked = repository.resolution === "repository" && restore.lane !== "no_code";
|
|
35142
35784
|
const targetBranch = repositoryBacked ? repository.targetBranch || "main" : void 0;
|
|
35143
35785
|
const featureBranch = repositoryBacked ? restore.featureBranch ?? `feature/corner-${corner.cornerId.replaceAll("-", "").slice(0, 12)}` : void 0;
|
|
35144
35786
|
const granted = repositoryBacked ? await this.options.daemonApi.execute("getRoomGitHubToken", {
|
|
@@ -35151,7 +35793,7 @@ var RoomRuntimeCoordinator = class {
|
|
|
35151
35793
|
featureBranch,
|
|
35152
35794
|
token: granted.token
|
|
35153
35795
|
}) : void 0;
|
|
35154
|
-
const workspacePath = worktree?.path ??
|
|
35796
|
+
const workspacePath = worktree?.path ?? resolve23(this.roomRoot(corner.cornerId), "scratch");
|
|
35155
35797
|
if (!worktree)
|
|
35156
35798
|
await mkdir14(workspacePath, { recursive: true, mode: 448 });
|
|
35157
35799
|
const isOpener = !corner.openedBy || corner.openedBy === this.agent.publicKey;
|
|
@@ -35177,6 +35819,7 @@ var RoomRuntimeCoordinator = class {
|
|
|
35177
35819
|
...corner.openedBy ? { openedBy: corner.openedBy } : {},
|
|
35178
35820
|
objective,
|
|
35179
35821
|
worktreePath: workspacePath,
|
|
35822
|
+
...restore.requesterHandle ? { requesterHandle: restore.requesterHandle } : {},
|
|
35180
35823
|
...worktree ? {
|
|
35181
35824
|
repository: {
|
|
35182
35825
|
featureBranch,
|
|
@@ -35229,7 +35872,7 @@ var RoomRuntimeCoordinator = class {
|
|
|
35229
35872
|
});
|
|
35230
35873
|
this.standingCornerStartFaults.delete(corner.cornerId);
|
|
35231
35874
|
this.reportedCornerStartFailures.delete(corner.cornerId);
|
|
35232
|
-
console.log(worktree ? `[thin-core] serving corner ${corner.cornerId} on ${featureBranch} at ${workspacePath}` : `[thin-core] serving
|
|
35875
|
+
console.log(worktree ? `[thin-core] serving corner ${corner.cornerId} on ${featureBranch} at ${workspacePath}` : `[thin-core] serving no-code corner ${corner.cornerId} at ${workspacePath}`);
|
|
35233
35876
|
} catch (error) {
|
|
35234
35877
|
console.error(`[thin-core] failed to start corner ${corner.cornerId}:`, error);
|
|
35235
35878
|
const reported = await this.reportCornerStartFailure(corner.cornerId, error);
|
|
@@ -35543,13 +36186,13 @@ var ThinDaemonCore = class {
|
|
|
35543
36186
|
|
|
35544
36187
|
// apps/body/dist/agent-retirement.js
|
|
35545
36188
|
import { mkdir as mkdir16, rename as rename5 } from "node:fs/promises";
|
|
35546
|
-
import { dirname as
|
|
36189
|
+
import { dirname as dirname14, resolve as resolve25 } from "node:path";
|
|
35547
36190
|
|
|
35548
36191
|
// apps/body/dist/systemd.js
|
|
35549
36192
|
import { execFile as execFile7 } from "node:child_process";
|
|
35550
36193
|
import { mkdir as mkdir15, readFile as readFile9, stat as stat3, writeFile as writeFile10 } from "node:fs/promises";
|
|
35551
|
-
import { homedir as
|
|
35552
|
-
import { dirname as
|
|
36194
|
+
import { homedir as homedir11 } from "node:os";
|
|
36195
|
+
import { dirname as dirname13, resolve as resolve24 } from "node:path";
|
|
35553
36196
|
import { setTimeout as sleep } from "node:timers/promises";
|
|
35554
36197
|
import { promisify as promisify5 } from "node:util";
|
|
35555
36198
|
var execFileAsync5 = promisify5(execFile7);
|
|
@@ -35571,6 +36214,7 @@ StartLimitBurst=10
|
|
|
35571
36214
|
Type=notify
|
|
35572
36215
|
NotifyAccess=all
|
|
35573
36216
|
Environment=BEELINE_MANAGED_BY_SYSTEMD=1
|
|
36217
|
+
Environment=PATH=%h/.local/bin:/usr/local/bin:/usr/bin:/bin
|
|
35574
36218
|
ExecStart=%h/.local/bin/beeline daemon --agent %i
|
|
35575
36219
|
Restart=always
|
|
35576
36220
|
RestartSec=5s
|
|
@@ -35591,10 +36235,10 @@ WantedBy=default.target
|
|
|
35591
36235
|
`;
|
|
35592
36236
|
}
|
|
35593
36237
|
function isCanonicalInstalledLauncher(env = process.env, invocationPath = process.argv[1]) {
|
|
35594
|
-
const home = env.HOME?.trim() ||
|
|
35595
|
-
const expectedLibDir =
|
|
36238
|
+
const home = env.HOME?.trim() || homedir11();
|
|
36239
|
+
const expectedLibDir = resolve24(home, ".local", "lib", "beeline");
|
|
35596
36240
|
const expectedPrefix = `${expectedLibDir}/`;
|
|
35597
|
-
return
|
|
36241
|
+
return resolve24(env.BEELINE_LIB_DIR?.trim() || "/") === expectedLibDir && Boolean(invocationPath) && resolve24(invocationPath).startsWith(expectedPrefix);
|
|
35598
36242
|
}
|
|
35599
36243
|
function assertCanonicalInstalledLauncher(env, invocationPath) {
|
|
35600
36244
|
if (isCanonicalInstalledLauncher(env, invocationPath))
|
|
@@ -35602,8 +36246,28 @@ function assertCanonicalInstalledLauncher(env, invocationPath) {
|
|
|
35602
36246
|
throw new Error("refusing to modify the shared Beeline systemd unit outside the canonical ~/.local/bin/beeline launcher");
|
|
35603
36247
|
}
|
|
35604
36248
|
function systemdUserUnitPath(env = process.env) {
|
|
35605
|
-
const configRoot = env.XDG_CONFIG_HOME?.trim() ||
|
|
35606
|
-
return
|
|
36249
|
+
const configRoot = env.XDG_CONFIG_HOME?.trim() || resolve24(homedir11(), ".config");
|
|
36250
|
+
return resolve24(configRoot, "systemd", "user", SYSTEMD_UNIT_NAME);
|
|
36251
|
+
}
|
|
36252
|
+
function systemdBrokerUnitPath(env = process.env) {
|
|
36253
|
+
const configRoot = env.XDG_CONFIG_HOME?.trim() || resolve24(homedir11(), ".config");
|
|
36254
|
+
return resolve24(configRoot, "systemd", "user", TRUSTY_SQUIRE_BROKER_UNIT_NAME);
|
|
36255
|
+
}
|
|
36256
|
+
async function installTrustySquireBrokerService(options = {}) {
|
|
36257
|
+
const env = options.env ?? process.env;
|
|
36258
|
+
assertCanonicalInstalledLauncher(env, options.invocationPath);
|
|
36259
|
+
const home = env.HOME?.trim() || homedir11();
|
|
36260
|
+
ensureSquireHostDir(home);
|
|
36261
|
+
const path = systemdBrokerUnitPath(env);
|
|
36262
|
+
const content = trustySquireBrokerUnit();
|
|
36263
|
+
const existing = await readFile9(path, "utf8").catch(() => "");
|
|
36264
|
+
if (existing !== content) {
|
|
36265
|
+
await mkdir15(dirname13(path), { recursive: true, mode: 448 });
|
|
36266
|
+
await writeFile10(path, content, { mode: 384 });
|
|
36267
|
+
}
|
|
36268
|
+
const run2 = options.run ?? runSystemctl;
|
|
36269
|
+
await run2(["daemon-reload"]);
|
|
36270
|
+
await run2(["enable", "--now", TRUSTY_SQUIRE_BROKER_UNIT_NAME]);
|
|
35607
36271
|
}
|
|
35608
36272
|
var AGENT_SERVICE = /^beeline-agent@([0-9a-f]{64})\.service$/i;
|
|
35609
36273
|
var runSystemctl = async (args) => {
|
|
@@ -35622,7 +36286,7 @@ async function installAgentService(publicKey, options = {}) {
|
|
|
35622
36286
|
const content = agentServiceUnit();
|
|
35623
36287
|
const existing = await readFile9(path, "utf8").catch(() => "");
|
|
35624
36288
|
if (existing !== content) {
|
|
35625
|
-
await mkdir15(
|
|
36289
|
+
await mkdir15(dirname13(path), { recursive: true, mode: 448 });
|
|
35626
36290
|
await writeFile10(path, content, { mode: 384 });
|
|
35627
36291
|
}
|
|
35628
36292
|
const run2 = options.run ?? runSystemctl;
|
|
@@ -35762,15 +36426,15 @@ var SystemdNotifier = class {
|
|
|
35762
36426
|
|
|
35763
36427
|
// apps/body/dist/agent-retirement.js
|
|
35764
36428
|
async function retireRemovedAgent(runtime, options = {}) {
|
|
35765
|
-
const deletedRoot =
|
|
35766
|
-
const target =
|
|
36429
|
+
const deletedRoot = resolve25(runtime.supervisorRoot, "beeline", "deleted-runtimes");
|
|
36430
|
+
const target = resolve25(deletedRoot, `${runtime.agent.publicKey}-${Date.now()}`);
|
|
35767
36431
|
return relocateAgentRuntime(runtime, target, {
|
|
35768
36432
|
...options.run ? { run: options.run } : {}
|
|
35769
36433
|
});
|
|
35770
36434
|
}
|
|
35771
36435
|
async function relocateAgentRuntime(runtime, target, options = {}) {
|
|
35772
36436
|
const source = runtimeDirectory(runtime.supervisorRoot, runtime.agent.publicKey);
|
|
35773
|
-
const destination =
|
|
36437
|
+
const destination = resolve25(target);
|
|
35774
36438
|
if (destination === source || destination.startsWith(`${source}/`)) {
|
|
35775
36439
|
throw new Error("agent runtime destination must be outside the live runtime");
|
|
35776
36440
|
}
|
|
@@ -35779,13 +36443,13 @@ async function relocateAgentRuntime(runtime, target, options = {}) {
|
|
|
35779
36443
|
...options.run ? { run: options.run } : {}
|
|
35780
36444
|
});
|
|
35781
36445
|
}
|
|
35782
|
-
await mkdir16(
|
|
36446
|
+
await mkdir16(dirname14(destination), { recursive: true, mode: 448 });
|
|
35783
36447
|
await rename5(source, destination);
|
|
35784
36448
|
return destination;
|
|
35785
36449
|
}
|
|
35786
36450
|
|
|
35787
36451
|
// apps/body/dist/start-command.js
|
|
35788
|
-
import { basename as basename7, dirname as
|
|
36452
|
+
import { basename as basename7, dirname as dirname18 } from "node:path";
|
|
35789
36453
|
var import_picocolors2 = __toESM(require_picocolors(), 1);
|
|
35790
36454
|
|
|
35791
36455
|
// apps/body/dist/self-update-cli.js
|
|
@@ -35795,22 +36459,22 @@ init_self_update_manifest();
|
|
|
35795
36459
|
|
|
35796
36460
|
// apps/body/dist/managed-update.js
|
|
35797
36461
|
init_self_update();
|
|
35798
|
-
import { spawn as
|
|
36462
|
+
import { spawn as spawn9 } from "node:child_process";
|
|
35799
36463
|
import { mkdir as mkdir19, rm as rm7, stat as stat4, writeFile as writeFile13 } from "node:fs/promises";
|
|
35800
|
-
import { dirname as
|
|
36464
|
+
import { dirname as dirname17, resolve as resolve28 } from "node:path";
|
|
35801
36465
|
|
|
35802
36466
|
// apps/body/dist/update-rollback-alert.js
|
|
35803
36467
|
import { mkdir as mkdir18, readFile as readFile11, rename as rename7, unlink as unlink4, writeFile as writeFile12 } from "node:fs/promises";
|
|
35804
|
-
import { dirname as
|
|
36468
|
+
import { dirname as dirname16, resolve as resolve27 } from "node:path";
|
|
35805
36469
|
var REPORT_INTERVAL_MS = 60 * 60 * 1e3;
|
|
35806
36470
|
var lastLogged = /* @__PURE__ */ new Map();
|
|
35807
36471
|
function updateRollbackAlertPath(runtimeDir) {
|
|
35808
|
-
return
|
|
36472
|
+
return resolve27(runtimeDir, "update-rollback-alert.json");
|
|
35809
36473
|
}
|
|
35810
36474
|
async function writeAlert(runtimeDir, alert) {
|
|
35811
36475
|
const path = updateRollbackAlertPath(runtimeDir);
|
|
35812
36476
|
const staged = `${path}.${process.pid}.tmp`;
|
|
35813
|
-
await mkdir18(
|
|
36477
|
+
await mkdir18(dirname16(path), { recursive: true });
|
|
35814
36478
|
await writeFile12(staged, `${JSON.stringify(alert, null, 2)}
|
|
35815
36479
|
`, { mode: 384 });
|
|
35816
36480
|
await rename7(staged, path);
|
|
@@ -35874,13 +36538,13 @@ var LOCK_STALE_MS = UPDATE_WORKER_DEADLINE_MS + 5 * 6e4;
|
|
|
35874
36538
|
var DEFAULT_UPDATE_INITIAL_DELAY_MS = 0;
|
|
35875
36539
|
async function withInstallLock(layout, work, options = {}) {
|
|
35876
36540
|
const now2 = options.now ?? Date.now;
|
|
35877
|
-
const lock =
|
|
36541
|
+
const lock = resolve28(layout.releasesRoot, ".state", "install.lock");
|
|
35878
36542
|
const deadline = now2() + (options.waitMs ?? 1e4);
|
|
35879
|
-
await mkdir19(
|
|
36543
|
+
await mkdir19(dirname17(lock), { recursive: true });
|
|
35880
36544
|
for (; ; ) {
|
|
35881
36545
|
try {
|
|
35882
36546
|
await mkdir19(lock);
|
|
35883
|
-
await writeFile13(
|
|
36547
|
+
await writeFile13(resolve28(lock, "owner"), `${process.pid}
|
|
35884
36548
|
${now2()}
|
|
35885
36549
|
`, "utf8");
|
|
35886
36550
|
break;
|
|
@@ -35928,10 +36592,11 @@ var ManagedUpdateHandoff = class _ManagedUpdateHandoff {
|
|
|
35928
36592
|
this.#nextUpdateCheckAt = this.#now() + numberEnv(this.#env, "BEELINE_UPDATE_INITIAL_DELAY_MS", DEFAULT_UPDATE_INITIAL_DELAY_MS);
|
|
35929
36593
|
}
|
|
35930
36594
|
static async create(layout, runtimeDir, now2 = Date.now, options = {}) {
|
|
36595
|
+
const env = options.env ?? process.env;
|
|
35931
36596
|
return new _ManagedUpdateHandoff({
|
|
35932
36597
|
layout,
|
|
35933
36598
|
runtimeDir,
|
|
35934
|
-
loadedRelease: await activeReleaseId(layout),
|
|
36599
|
+
loadedRelease: runningReleaseId(layout, env) ?? await activeReleaseId(layout),
|
|
35935
36600
|
now: now2,
|
|
35936
36601
|
...options
|
|
35937
36602
|
});
|
|
@@ -36003,7 +36668,7 @@ var ManagedUpdateHandoff = class _ManagedUpdateHandoff {
|
|
|
36003
36668
|
if (!attempt || attempt.releaseId !== desiredRelease || attempt.status !== "pending") {
|
|
36004
36669
|
const from = await readInstalledBundleIdentity({
|
|
36005
36670
|
...this.#layout,
|
|
36006
|
-
libDir:
|
|
36671
|
+
libDir: resolve28(this.#layout.releasesRoot, this.#loadedRelease)
|
|
36007
36672
|
}).catch(() => void 0) ?? {};
|
|
36008
36673
|
const to = await readInstalledBundleIdentity(this.#layout).catch(() => void 0) ?? {};
|
|
36009
36674
|
const record3 = {
|
|
@@ -36209,7 +36874,7 @@ async function runManagedUpdateWorkerProcess() {
|
|
|
36209
36874
|
if (!entrypoint)
|
|
36210
36875
|
throw new Error("cannot resolve the current Beeline entrypoint");
|
|
36211
36876
|
await new Promise((resolveWorker, rejectWorker) => {
|
|
36212
|
-
const child =
|
|
36877
|
+
const child = spawn9(process.execPath, [entrypoint, "managed-update-worker"], {
|
|
36213
36878
|
detached: true,
|
|
36214
36879
|
env: { ...process.env, BEELINE_INTERNAL_UPDATE_WORKER: "1" },
|
|
36215
36880
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -36290,7 +36955,7 @@ async function proveLoadedReleaseReady(layout, runtimeDir, loadedRelease, option
|
|
|
36290
36955
|
});
|
|
36291
36956
|
if (!accepted)
|
|
36292
36957
|
return false;
|
|
36293
|
-
await writeFile13(
|
|
36958
|
+
await writeFile13(resolve28(runtimeDir, "daemon-ready.json"), `${JSON.stringify({
|
|
36294
36959
|
readyAt: (options.now ?? Date.now)(),
|
|
36295
36960
|
loadedRelease,
|
|
36296
36961
|
functionalProof: options.functionalProof
|
|
@@ -36536,7 +37201,7 @@ async function startStoredRuntime(configPath, opts = {}, dependencyOverrides = {
|
|
|
36536
37201
|
return { status: "started", pid };
|
|
36537
37202
|
}
|
|
36538
37203
|
function agentStartId(configPath) {
|
|
36539
|
-
return basename7(
|
|
37204
|
+
return basename7(dirname18(configPath));
|
|
36540
37205
|
}
|
|
36541
37206
|
async function startRuntime(configPath, spinnerHandle) {
|
|
36542
37207
|
const report = (text2) => spinnerHandle ? spinnerHandle.message(text2) : console.log(text2);
|
|
@@ -36544,6 +37209,11 @@ async function startRuntime(configPath, spinnerHandle) {
|
|
|
36544
37209
|
const selectedAgent = runtimeAgentCommand(runtime);
|
|
36545
37210
|
report(`[body] agent ${runtime.agent.publicKey} binary: ${formatAgentCommand(selectedAgent)}`);
|
|
36546
37211
|
if (process.platform === "linux" && process.env.BEELINE_SYSTEMD_USER !== "0") {
|
|
37212
|
+
try {
|
|
37213
|
+
await installTrustySquireBrokerService();
|
|
37214
|
+
} catch (error) {
|
|
37215
|
+
report(`[beeline] trusty-squire host broker not installed: ${error instanceof Error ? error.message : String(error)}`);
|
|
37216
|
+
}
|
|
36547
37217
|
const existingPid = await runtimeDaemonPid(configPath);
|
|
36548
37218
|
if (existingPid) {
|
|
36549
37219
|
report(`[beeline] agent already running (pid ${existingPid})`);
|
|
@@ -36597,7 +37267,7 @@ async function runStartCommand(args, interactiveUi, dependencyOverrides = {}) {
|
|
|
36597
37267
|
for (const path of unique) {
|
|
36598
37268
|
const id = agentStartId(path);
|
|
36599
37269
|
const spinnerHandle = interactiveUi ? spinner() : void 0;
|
|
36600
|
-
spinnerHandle?.start(`Starting ${
|
|
37270
|
+
spinnerHandle?.start(`Starting ${dirname18(path)}\u2026`);
|
|
36601
37271
|
try {
|
|
36602
37272
|
const outcome = await deps.startOne(path, spinnerHandle);
|
|
36603
37273
|
const report = { id, path, ...outcome };
|
|
@@ -36629,11 +37299,11 @@ async function runStartCommand(args, interactiveUi, dependencyOverrides = {}) {
|
|
|
36629
37299
|
}
|
|
36630
37300
|
|
|
36631
37301
|
// apps/body/dist/connect-command.js
|
|
36632
|
-
import { spawn as
|
|
37302
|
+
import { spawn as spawn11 } from "node:child_process";
|
|
36633
37303
|
import { createHash as createHash9, randomUUID as randomUUID6 } from "node:crypto";
|
|
36634
37304
|
import { chmod as chmod7, mkdir as mkdir20, readFile as readFile12, unlink as unlink5, writeFile as writeFile14 } from "node:fs/promises";
|
|
36635
|
-
import { homedir as
|
|
36636
|
-
import { dirname as
|
|
37305
|
+
import { homedir as homedir13, hostname as hostname2 } from "node:os";
|
|
37306
|
+
import { dirname as dirname19, resolve as resolve29 } from "node:path";
|
|
36637
37307
|
import { stdin as stdin3, stdout as stdout4 } from "node:process";
|
|
36638
37308
|
|
|
36639
37309
|
// apps/body/dist/clack-support.js
|
|
@@ -36717,7 +37387,7 @@ async function verifyProviderKey(input) {
|
|
|
36717
37387
|
}
|
|
36718
37388
|
|
|
36719
37389
|
// apps/body/dist/pair-agent-selection.js
|
|
36720
|
-
import { spawn as
|
|
37390
|
+
import { spawn as spawn10 } from "node:child_process";
|
|
36721
37391
|
import { stdin as stdin2, stdout as stdout3 } from "node:process";
|
|
36722
37392
|
var NO_AGENT_MESSAGE = `No supported ACP-capable coding agent was detected.
|
|
36723
37393
|
Install one of these supported agents:
|
|
@@ -36746,7 +37416,7 @@ async function clackSelectAgent(candidates) {
|
|
|
36746
37416
|
}
|
|
36747
37417
|
async function installAdapter(install, opts) {
|
|
36748
37418
|
await new Promise((resolveInstall, rejectInstall) => {
|
|
36749
|
-
const child =
|
|
37419
|
+
const child = spawn10(install.command, install.args, {
|
|
36750
37420
|
cwd: opts.cwd,
|
|
36751
37421
|
env: opts.env ?? process.env,
|
|
36752
37422
|
stdio: "inherit"
|
|
@@ -36929,7 +37599,17 @@ async function pairDevice(grant, options = {}) {
|
|
|
36929
37599
|
throw new Error("monolith daemon transport activation failed");
|
|
36930
37600
|
let pid;
|
|
36931
37601
|
try {
|
|
36932
|
-
pid = await (options.launch ?? (async (configPath, publicKey) =>
|
|
37602
|
+
pid = await (options.launch ?? (async (configPath, publicKey) => {
|
|
37603
|
+
if (process.platform === "linux" && process.env.BEELINE_SYSTEMD_USER !== "0") {
|
|
37604
|
+
try {
|
|
37605
|
+
await installTrustySquireBrokerService();
|
|
37606
|
+
} catch (error) {
|
|
37607
|
+
console.warn(`[beeline] trusty-squire host broker not installed: ${error instanceof Error ? error.message : String(error)}`);
|
|
37608
|
+
}
|
|
37609
|
+
return installAgentService(publicKey);
|
|
37610
|
+
}
|
|
37611
|
+
return launchRuntimeDaemon(configPath);
|
|
37612
|
+
}))(staged.configPath, agentIdentity.publicKey);
|
|
36933
37613
|
} catch (error) {
|
|
36934
37614
|
throw new Error(`agent ${agentIdentity.publicKey} is connected, but its daemon did not start: ${error instanceof Error ? error.message : String(error)}. Run \`beeline start --agent ${agentIdentity.publicKey}\`.`, { cause: error });
|
|
36935
37615
|
}
|
|
@@ -37251,8 +37931,8 @@ function parseConnectSubscriptions(value) {
|
|
|
37251
37931
|
];
|
|
37252
37932
|
}
|
|
37253
37933
|
async function readMachineId(env = process.env) {
|
|
37254
|
-
const configDir =
|
|
37255
|
-
const machineIdPath =
|
|
37934
|
+
const configDir = resolve29(env.XDG_CONFIG_HOME ?? resolve29(homedir13(), ".config"), "beeline");
|
|
37935
|
+
const machineIdPath = resolve29(configDir, "machine-id");
|
|
37256
37936
|
let machineId;
|
|
37257
37937
|
let machineName = hostname2();
|
|
37258
37938
|
try {
|
|
@@ -37325,7 +38005,7 @@ async function installCurrentRelease(fetchImpl) {
|
|
|
37325
38005
|
});
|
|
37326
38006
|
await activateRelease(layout, releaseId);
|
|
37327
38007
|
return {
|
|
37328
|
-
binary:
|
|
38008
|
+
binary: resolve29(layout.binDir, "beeline"),
|
|
37329
38009
|
version: published.version ?? releaseId
|
|
37330
38010
|
};
|
|
37331
38011
|
}
|
|
@@ -37348,7 +38028,7 @@ function providerEnvironment(selection) {
|
|
|
37348
38028
|
};
|
|
37349
38029
|
}
|
|
37350
38030
|
async function writePrivateJson(path, value) {
|
|
37351
|
-
await mkdir20(
|
|
38031
|
+
await mkdir20(dirname19(path), { recursive: true, mode: 448 });
|
|
37352
38032
|
await writeFile14(path, `${JSON.stringify(value, null, 2)}
|
|
37353
38033
|
`, { mode: 384 });
|
|
37354
38034
|
await chmod7(path, 384);
|
|
@@ -37357,8 +38037,8 @@ async function writeProviderEnv(selection, agentPubkey) {
|
|
|
37357
38037
|
const values = providerEnvironment(selection);
|
|
37358
38038
|
if (Object.keys(values).length === 0)
|
|
37359
38039
|
return void 0;
|
|
37360
|
-
const path =
|
|
37361
|
-
await mkdir20(
|
|
38040
|
+
const path = resolve29(defaultSupervisorRoot(process.env), "beeline", "connect", `${agentPubkey}.env`);
|
|
38041
|
+
await mkdir20(dirname19(path), { recursive: true, mode: 448 });
|
|
37362
38042
|
const contents = Object.entries(values).map(([key, value]) => `${key}=${JSON.stringify(value)}`).join("\n");
|
|
37363
38043
|
await writeFile14(path, `${contents}
|
|
37364
38044
|
`, { mode: 384 });
|
|
@@ -37367,7 +38047,7 @@ async function writeProviderEnv(selection, agentPubkey) {
|
|
|
37367
38047
|
}
|
|
37368
38048
|
async function runInstalledFinish(binary, grantPath) {
|
|
37369
38049
|
await new Promise((resolveRun, rejectRun) => {
|
|
37370
|
-
const child =
|
|
38050
|
+
const child = spawn11(binary, ["connect-finish", grantPath], {
|
|
37371
38051
|
stdio: ["ignore", "pipe", "pipe"]
|
|
37372
38052
|
});
|
|
37373
38053
|
let diagnostic = "";
|
|
@@ -37427,7 +38107,7 @@ async function runConnectWizard(code, fetchImpl, eventSubscriptions, accessPolic
|
|
|
37427
38107
|
await finishConnectedAgentPairing(baseUrl, pairingCode, grant.workspace_joined, eventSubscriptions, fetchImpl);
|
|
37428
38108
|
const installedRelease = await brassSpinner("Installing the Beeline daemon\u2026", () => installCurrentRelease(fetchImpl), (release) => `Installed Beeline helper ${release.version}`);
|
|
37429
38109
|
const llmEnvFile = await writeProviderEnv(selection, grant.agent_pubkey);
|
|
37430
|
-
const grantPath =
|
|
38110
|
+
const grantPath = resolve29(defaultSupervisorRoot(process.env), "beeline", "connect", `grant-${process.pid}-${Date.now()}.json`);
|
|
37431
38111
|
await writePrivateJson(grantPath, {
|
|
37432
38112
|
agentSecretKey: grant.agent_secret_key,
|
|
37433
38113
|
bodySecretKey: grant.body_secret_key,
|
|
@@ -37512,18 +38192,18 @@ async function runConnectFinishCommand(path) {
|
|
|
37512
38192
|
throw new Error("connect-finish may run only from the canonical installed Beeline launcher");
|
|
37513
38193
|
}
|
|
37514
38194
|
try {
|
|
37515
|
-
const grant = JSON.parse(await readFile12(
|
|
38195
|
+
const grant = JSON.parse(await readFile12(resolve29(path), "utf8"));
|
|
37516
38196
|
if (!isDevicePairingGrant(grant))
|
|
37517
38197
|
throw new Error("device connection grant is invalid");
|
|
37518
38198
|
const connected = await completeDevicePairing(grant);
|
|
37519
|
-
await unlink5(
|
|
38199
|
+
await unlink5(resolve29(path));
|
|
37520
38200
|
const providerEnv = grant.llmEnvFile ? await readFile12(grant.llmEnvFile, "utf8").catch(() => "") : "";
|
|
37521
38201
|
const apiKey = (/^OPENROUTER_API_KEY=(\S+)/m.exec(providerEnv)?.[1] ?? "").replace(/^["']|["']$/g, "");
|
|
37522
38202
|
const model = openRouterModelId(grant.model, { OPENROUTER_API_KEY: apiKey });
|
|
37523
38203
|
if (model) {
|
|
37524
38204
|
const decision2 = await resolveOpenRouterRouting({
|
|
37525
38205
|
model,
|
|
37526
|
-
cacheDir: openRouterRoutingCacheDir(
|
|
38206
|
+
cacheDir: openRouterRoutingCacheDir(dirname19(connected.configPath)),
|
|
37527
38207
|
...apiKey ? { apiKey } : {},
|
|
37528
38208
|
probeTimeoutMs: 1e4
|
|
37529
38209
|
});
|
|
@@ -37542,11 +38222,11 @@ init_self_update();
|
|
|
37542
38222
|
|
|
37543
38223
|
// apps/body/dist/daemon-failure.js
|
|
37544
38224
|
import { mkdir as mkdir21, readFile as readFile13, rename as rename8, rm as rm8, writeFile as writeFile15 } from "node:fs/promises";
|
|
37545
|
-
import { dirname as
|
|
38225
|
+
import { dirname as dirname20, resolve as resolve30 } from "node:path";
|
|
37546
38226
|
var DAEMON_FAILURE_LIMIT = 3;
|
|
37547
38227
|
var DAEMON_FAILURE_WINDOW_MS = 5 * 6e4;
|
|
37548
38228
|
function daemonFailurePath(runtimeDir) {
|
|
37549
|
-
return
|
|
38229
|
+
return resolve30(runtimeDir, "daemon-distress.json");
|
|
37550
38230
|
}
|
|
37551
38231
|
async function readFailureRecord(runtimeDir) {
|
|
37552
38232
|
try {
|
|
@@ -37562,7 +38242,7 @@ async function readFailureRecord(runtimeDir) {
|
|
|
37562
38242
|
async function writeFailureRecord(runtimeDir, record3) {
|
|
37563
38243
|
const path = daemonFailurePath(runtimeDir);
|
|
37564
38244
|
const staged = `${path}.${process.pid}.tmp`;
|
|
37565
|
-
await mkdir21(
|
|
38245
|
+
await mkdir21(dirname20(path), { recursive: true, mode: 448 });
|
|
37566
38246
|
await writeFile15(staged, `${JSON.stringify(record3, null, 2)}
|
|
37567
38247
|
`, { mode: 384 });
|
|
37568
38248
|
await rename8(staged, path);
|
|
@@ -37586,8 +38266,8 @@ async function clearDaemonStartFailures(runtimeDir) {
|
|
|
37586
38266
|
|
|
37587
38267
|
// apps/body/dist/update-functional-probe.js
|
|
37588
38268
|
import { mkdir as mkdir22, rm as rm9 } from "node:fs/promises";
|
|
37589
|
-
import { homedir as
|
|
37590
|
-
import { resolve as
|
|
38269
|
+
import { homedir as homedir14 } from "node:os";
|
|
38270
|
+
import { resolve as resolve31 } from "node:path";
|
|
37591
38271
|
var UPDATE_PROBE_SESSION_TIMEOUT_MS = 1e4;
|
|
37592
38272
|
var UPDATE_PROBE_SESSION_OPEN_TIMEOUT_MS = 2e4;
|
|
37593
38273
|
var UPDATE_PROBE_TURN_TIMEOUT_MS = 45e3;
|
|
@@ -37707,9 +38387,9 @@ async function runUpdateFunctionalProbe(input) {
|
|
|
37707
38387
|
modelAnswerReason: `${detail} (the current release has the same host sandbox failure)`
|
|
37708
38388
|
};
|
|
37709
38389
|
}
|
|
37710
|
-
const root = input.probeRoot ??
|
|
37711
|
-
const cwd =
|
|
37712
|
-
const homeRoot =
|
|
38390
|
+
const root = input.probeRoot ?? resolve31(input.runtimeDir, "update-functional-probe");
|
|
38391
|
+
const cwd = resolve31(root, "checkout");
|
|
38392
|
+
const homeRoot = resolve31(root, "agent-home");
|
|
37713
38393
|
await rm9(root, { recursive: true, force: true });
|
|
37714
38394
|
await mkdir22(cwd, { recursive: true, mode: 448 });
|
|
37715
38395
|
let client;
|
|
@@ -37718,7 +38398,7 @@ async function runUpdateFunctionalProbe(input) {
|
|
|
37718
38398
|
...input.config.agentEnv,
|
|
37719
38399
|
...await prepareRoomAgentHome({
|
|
37720
38400
|
root: homeRoot,
|
|
37721
|
-
operatorHome: input.config.operatorHome ??
|
|
38401
|
+
operatorHome: input.config.operatorHome ?? homedir14(),
|
|
37722
38402
|
sharedSkills: input.config.sharedSkills ?? [],
|
|
37723
38403
|
...input.config.agentKind ? { agentKind: input.config.agentKind } : {},
|
|
37724
38404
|
skillReleaseId: input.releaseId,
|
|
@@ -37739,7 +38419,7 @@ async function runUpdateFunctionalProbe(input) {
|
|
|
37739
38419
|
let turnCompleted = true;
|
|
37740
38420
|
if (input.config.bwrapPath) {
|
|
37741
38421
|
const { stateDirs, tmpDir } = harnessStateDirsFromEnv(agentEnv);
|
|
37742
|
-
const operatorHome = input.config.operatorHome ??
|
|
38422
|
+
const operatorHome = input.config.operatorHome ?? homedir14();
|
|
37743
38423
|
const homeStateDirs = harnessHomeStateDirs(harnessLabel, agentEnv.HOME ?? operatorHome);
|
|
37744
38424
|
await Promise.all(homeStateDirs.map((dir) => mkdir22(dir, { recursive: true })));
|
|
37745
38425
|
spawnCommand = wrapAgentCommand({
|
|
@@ -37890,8 +38570,8 @@ async function runUpdateFunctionalProbe(input) {
|
|
|
37890
38570
|
}
|
|
37891
38571
|
|
|
37892
38572
|
// apps/body/dist/current-release-probe.js
|
|
37893
|
-
import { spawn as
|
|
37894
|
-
import { dirname as
|
|
38573
|
+
import { spawn as spawn12 } from "node:child_process";
|
|
38574
|
+
import { dirname as dirname21, join as join14 } from "node:path";
|
|
37895
38575
|
init_self_update();
|
|
37896
38576
|
var CURRENT_RELEASE_PROBE_TIMEOUT_MS = 12e4;
|
|
37897
38577
|
var UPDATE_PROBE_COMMAND = "update-probe";
|
|
@@ -37934,14 +38614,14 @@ function outcomeFromReport(report) {
|
|
|
37934
38614
|
}
|
|
37935
38615
|
}
|
|
37936
38616
|
async function probeReleaseInSubprocess(input) {
|
|
37937
|
-
const bundleDir =
|
|
38617
|
+
const bundleDir = join14(input.layout.releasesRoot, input.releaseId);
|
|
37938
38618
|
const entrypoint = await resolveBundleEntrypoint(bundleDir);
|
|
37939
38619
|
if (!entrypoint) {
|
|
37940
38620
|
return { kind: "unavailable", reason: `release ${input.releaseId} has no runnable CLI entrypoint` };
|
|
37941
38621
|
}
|
|
37942
38622
|
const timeoutMs = input.timeoutMs ?? CURRENT_RELEASE_PROBE_TIMEOUT_MS;
|
|
37943
|
-
return new Promise((
|
|
37944
|
-
const child =
|
|
38623
|
+
return new Promise((resolve35) => {
|
|
38624
|
+
const child = spawn12(input.execPath ?? process.execPath, [entrypoint, UPDATE_PROBE_COMMAND, "--config", input.runtimeConfigPath], { env: input.env ?? process.env, stdio: ["ignore", "pipe", "pipe"] });
|
|
37945
38625
|
let stdout6 = "";
|
|
37946
38626
|
let stderr = "";
|
|
37947
38627
|
let settled = false;
|
|
@@ -37950,7 +38630,7 @@ async function probeReleaseInSubprocess(input) {
|
|
|
37950
38630
|
return;
|
|
37951
38631
|
settled = true;
|
|
37952
38632
|
clearTimeout(timer);
|
|
37953
|
-
|
|
38633
|
+
resolve35(outcome);
|
|
37954
38634
|
};
|
|
37955
38635
|
const timer = setTimeout(() => {
|
|
37956
38636
|
child.kill("SIGKILL");
|
|
@@ -37997,7 +38677,7 @@ async function runUpdateProbeCommand(args, options = {}) {
|
|
|
37997
38677
|
const runtime = await readRuntimeRecord(configPath);
|
|
37998
38678
|
const agent = runtimeAgentCommand(runtime);
|
|
37999
38679
|
const config = loadBodyConfig({
|
|
38000
|
-
workspaceRoot:
|
|
38680
|
+
workspaceRoot: join14(dirname21(configPath), "workspace"),
|
|
38001
38681
|
llmEnvFile: runtime.llmEnvFile,
|
|
38002
38682
|
env: { ...env, BUZZ_AGENT_BIN: agent.command, BUZZ_DEV_MCP_BIN: runtime.mcpBinary },
|
|
38003
38683
|
agent
|
|
@@ -38015,7 +38695,7 @@ async function runUpdateProbeCommand(args, options = {}) {
|
|
|
38015
38695
|
}
|
|
38016
38696
|
const layout = beelineInstallLayout(env);
|
|
38017
38697
|
const releaseId = (layout && await activeReleaseId(layout).catch(() => void 0)) ?? "unknown";
|
|
38018
|
-
const runtimeDir =
|
|
38698
|
+
const runtimeDir = dirname21(configPath);
|
|
38019
38699
|
const outcome = await probeOutcome(() => (options.probe ?? runUpdateFunctionalProbe)({
|
|
38020
38700
|
config,
|
|
38021
38701
|
runtimeDir,
|
|
@@ -38023,7 +38703,7 @@ async function runUpdateProbeCommand(args, options = {}) {
|
|
|
38023
38703
|
sandboxRequired: runtime.sandbox !== "off",
|
|
38024
38704
|
sandboxUnavailableDetail: sandbox.advisory,
|
|
38025
38705
|
// The successor's probe still holds `<runtimeDir>/update-functional-probe`.
|
|
38026
|
-
probeRoot:
|
|
38706
|
+
probeRoot: join14(runtimeDir, "current-release-probe")
|
|
38027
38707
|
}));
|
|
38028
38708
|
const report = outcome.kind === "served" ? { probe: "served" } : outcome.kind === "refused" ? { probe: "refused", status: outcome.status, reason: outcome.reason } : outcome.kind === "sandbox-unavailable" ? { probe: "sandbox-unavailable", reason: outcome.reason } : { probe: "failed", reason: outcome.reason };
|
|
38029
38709
|
write(JSON.stringify(report));
|
|
@@ -38031,7 +38711,7 @@ async function runUpdateProbeCommand(args, options = {}) {
|
|
|
38031
38711
|
|
|
38032
38712
|
// apps/body/dist/release-status.js
|
|
38033
38713
|
import { readFile as readFile14, readdir as readdir6, rename as rename9, writeFile as writeFile16 } from "node:fs/promises";
|
|
38034
|
-
import { resolve as
|
|
38714
|
+
import { resolve as resolve32 } from "node:path";
|
|
38035
38715
|
var DAEMON_RELEASE_STATUS_FILE = "release-status.json";
|
|
38036
38716
|
var RELEASE_VERSION = /^v\d+\.\d+\.\d+$/;
|
|
38037
38717
|
var SOURCE_SHA = /^[0-9a-f]{7,64}$/;
|
|
@@ -38048,7 +38728,7 @@ async function writeDaemonReleaseStatus(runtimeDir, agentPubkey, identity, optio
|
|
|
38048
38728
|
pid: options.pid ?? process.pid,
|
|
38049
38729
|
readyAt: (options.now?.() ?? /* @__PURE__ */ new Date()).toISOString()
|
|
38050
38730
|
};
|
|
38051
|
-
const target =
|
|
38731
|
+
const target = resolve32(runtimeDir, DAEMON_RELEASE_STATUS_FILE);
|
|
38052
38732
|
const temporary = `${target}.${status.pid}.tmp`;
|
|
38053
38733
|
await writeFile16(temporary, `${JSON.stringify(status, null, 2)}
|
|
38054
38734
|
`, { mode: 384 });
|
|
@@ -38058,7 +38738,7 @@ async function writeDaemonReleaseStatus(runtimeDir, agentPubkey, identity, optio
|
|
|
38058
38738
|
|
|
38059
38739
|
// apps/body/dist/scratch-sweep.js
|
|
38060
38740
|
import { lstat as lstat5, readdir as readdir7, rmdir, unlink as unlink6 } from "node:fs/promises";
|
|
38061
|
-
import { resolve as
|
|
38741
|
+
import { resolve as resolve33 } from "node:path";
|
|
38062
38742
|
var DEFAULT_SCRATCH_TTL_HOURS = 72;
|
|
38063
38743
|
var NEVER_SWEEP_SUBDIR_NAMES = new Set(HOME_SUBDIRS.filter((name) => name !== "tmp"));
|
|
38064
38744
|
function scratchTtlMs(env = process.env) {
|
|
@@ -38067,7 +38747,7 @@ function scratchTtlMs(env = process.env) {
|
|
|
38067
38747
|
return (Number.isFinite(hours) && hours > 0 ? hours : DEFAULT_SCRATCH_TTL_HOURS) * 60 * 60 * 1e3;
|
|
38068
38748
|
}
|
|
38069
38749
|
async function discoverAttachScratchRoots(runtimeDir) {
|
|
38070
|
-
const roomsDir =
|
|
38750
|
+
const roomsDir = resolve33(runtimeDir, "rooms");
|
|
38071
38751
|
let entries;
|
|
38072
38752
|
try {
|
|
38073
38753
|
entries = await readdir7(roomsDir, { withFileTypes: true });
|
|
@@ -38078,7 +38758,7 @@ async function discoverAttachScratchRoots(runtimeDir) {
|
|
|
38078
38758
|
for (const entry of entries) {
|
|
38079
38759
|
if (!entry.isDirectory())
|
|
38080
38760
|
continue;
|
|
38081
|
-
const home =
|
|
38761
|
+
const home = resolve33(roomsDir, entry.name, "agent-home");
|
|
38082
38762
|
const stats = await lstat5(home).catch(() => void 0);
|
|
38083
38763
|
if (stats?.isDirectory())
|
|
38084
38764
|
roots.push(home);
|
|
@@ -38097,7 +38777,7 @@ async function removeStaleFiles(dir, cutoffMs, protectNamesHere) {
|
|
|
38097
38777
|
for (const entry of entries) {
|
|
38098
38778
|
if (protectNamesHere && NEVER_SWEEP_SUBDIR_NAMES.has(entry.name))
|
|
38099
38779
|
continue;
|
|
38100
|
-
const path =
|
|
38780
|
+
const path = resolve33(dir, entry.name);
|
|
38101
38781
|
const stats = await lstat5(path).catch(() => void 0);
|
|
38102
38782
|
if (!stats || stats.isSymbolicLink())
|
|
38103
38783
|
continue;
|
|
@@ -38185,7 +38865,7 @@ var DaemonExitError = class extends Error {
|
|
|
38185
38865
|
};
|
|
38186
38866
|
async function runStoredDaemon(pathOrPointer) {
|
|
38187
38867
|
const configPath = await resolveRuntimeConfigPath(pathOrPointer);
|
|
38188
|
-
daemonFailureRuntimeDir =
|
|
38868
|
+
daemonFailureRuntimeDir = dirname22(configPath);
|
|
38189
38869
|
const accessMigration = await migrateRuntimeRecordAccessPolicy(configPath);
|
|
38190
38870
|
let runtime = accessMigration.runtime;
|
|
38191
38871
|
if (!runtime.transport) {
|
|
@@ -38204,7 +38884,7 @@ async function runStoredDaemon(pathOrPointer) {
|
|
|
38204
38884
|
BUZZ_DEV_MCP_BIN: runtime.mcpBinary
|
|
38205
38885
|
};
|
|
38206
38886
|
const config = loadBodyConfig({
|
|
38207
|
-
workspaceRoot:
|
|
38887
|
+
workspaceRoot: resolve34(dirname22(configPath), "workspace"),
|
|
38208
38888
|
llmEnvFile: runtime.llmEnvFile,
|
|
38209
38889
|
env,
|
|
38210
38890
|
agent
|
|
@@ -38239,7 +38919,7 @@ async function runStoredDaemon(pathOrPointer) {
|
|
|
38239
38919
|
const stop = () => controller.abort();
|
|
38240
38920
|
process.once("SIGINT", stop);
|
|
38241
38921
|
process.once("SIGTERM", stop);
|
|
38242
|
-
const runtimeDir =
|
|
38922
|
+
const runtimeDir = dirname22(configPath);
|
|
38243
38923
|
const layout = beelineInstallLayout(process.env);
|
|
38244
38924
|
const notifier = new SystemdNotifier();
|
|
38245
38925
|
let rollbackAlertDrain;
|
|
@@ -38419,6 +39099,14 @@ async function main() {
|
|
|
38419
39099
|
await runCursorAcpStdioServer();
|
|
38420
39100
|
return;
|
|
38421
39101
|
}
|
|
39102
|
+
if (command === SQUIRE_FACADE_FLAG) {
|
|
39103
|
+
runSquireFacade();
|
|
39104
|
+
return;
|
|
39105
|
+
}
|
|
39106
|
+
if (command === SQUIRE_BROKER_FLAG) {
|
|
39107
|
+
runSquireBroker();
|
|
39108
|
+
return;
|
|
39109
|
+
}
|
|
38422
39110
|
if (command === "--help" || command === "-h")
|
|
38423
39111
|
usage(0);
|
|
38424
39112
|
if (command === "managed-update-worker") {
|
|
@@ -38435,7 +39123,7 @@ async function main() {
|
|
|
38435
39123
|
const roomId = roomFlag >= 0 ? args[roomFlag + 1] : void 0;
|
|
38436
39124
|
if (!configPath || !roomId)
|
|
38437
39125
|
throw new Error("corner-read-token requires --config and --room");
|
|
38438
|
-
const activated = await activateDaemonTransport(
|
|
39126
|
+
const activated = await activateDaemonTransport(resolve34(configPath));
|
|
38439
39127
|
if (!activated)
|
|
38440
39128
|
throw new Error("corner-read-token requires monolith transport");
|
|
38441
39129
|
const credential = await activated.client.execute("getRoomGitHubToken", { roomId });
|
|
@@ -38489,14 +39177,14 @@ async function main() {
|
|
|
38489
39177
|
}
|
|
38490
39178
|
if (!configPath && agentPubkey) {
|
|
38491
39179
|
const configs = await findAgentRuntimeConfigPaths(process.env, process.cwd());
|
|
38492
|
-
configPath = configs.find((candidate) =>
|
|
39180
|
+
configPath = configs.find((candidate) => dirname22(candidate).endsWith(agentPubkey));
|
|
38493
39181
|
}
|
|
38494
39182
|
if (!configPath && agentPubkey) {
|
|
38495
39183
|
throw new DaemonExitError(`unknown agent ${agentPubkey}: no durable runtime exists; refusing systemd restart loop`, UNKNOWN_AGENT_EXIT_STATUS);
|
|
38496
39184
|
}
|
|
38497
39185
|
if (!configPath)
|
|
38498
39186
|
throw new Error("daemon requires --config <runtime.json> or --agent <pubkey>");
|
|
38499
|
-
await runStoredDaemon(
|
|
39187
|
+
await runStoredDaemon(resolve34(configPath));
|
|
38500
39188
|
return;
|
|
38501
39189
|
}
|
|
38502
39190
|
if (command === "update") {
|
|
@@ -38517,7 +39205,7 @@ async function main() {
|
|
|
38517
39205
|
if (!agentPubkey)
|
|
38518
39206
|
throw new Error("stop requires --agent <pubkey>");
|
|
38519
39207
|
const configs = await findAgentRuntimeConfigPaths(process.env, process.cwd());
|
|
38520
|
-
const configPath = configs.find((candidate) =>
|
|
39208
|
+
const configPath = configs.find((candidate) => dirname22(candidate).endsWith(agentPubkey));
|
|
38521
39209
|
if (!configPath)
|
|
38522
39210
|
throw new Error(`no stored runtime found for agent ${agentPubkey}`);
|
|
38523
39211
|
const runtime = await readRuntimeRecord(configPath);
|