usebeeline 0.1.34 → 0.1.35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/usebeeline.mjs +797 -564
- package/package.json +1 -1
package/dist/usebeeline.mjs
CHANGED
|
@@ -212,8 +212,8 @@ async function runSquireBrokerLink(options) {
|
|
|
212
212
|
const pending = /* @__PURE__ */ new Map();
|
|
213
213
|
const queued = [];
|
|
214
214
|
let resolveDone;
|
|
215
|
-
const done = new Promise((
|
|
216
|
-
resolveDone =
|
|
215
|
+
const done = new Promise((resolve53) => {
|
|
216
|
+
resolveDone = resolve53;
|
|
217
217
|
});
|
|
218
218
|
const failResponse = (id) => `${JSON.stringify({
|
|
219
219
|
jsonrpc: "2.0",
|
|
@@ -4891,12 +4891,24 @@ async function notify(fields) {
|
|
|
4891
4891
|
async function extendSystemdStartTimeout(ms) {
|
|
4892
4892
|
await notify([`EXTEND_TIMEOUT_USEC=${Math.max(0, Math.round(ms)) * 1e3}`]).catch(() => void 0);
|
|
4893
4893
|
}
|
|
4894
|
-
function startLocalWatchdog(notifier, status, intervalMs = 6e4, env = process.env) {
|
|
4894
|
+
function startLocalWatchdog(notifier, status, workLoopProgress, intervalMs = 6e4, env = process.env) {
|
|
4895
4895
|
if (!env.WATCHDOG_USEC)
|
|
4896
4896
|
return () => void 0;
|
|
4897
|
-
|
|
4897
|
+
let pending = false;
|
|
4898
|
+
let stopped = false;
|
|
4899
|
+
const timer = setInterval(() => {
|
|
4900
|
+
if (pending || stopped)
|
|
4901
|
+
return;
|
|
4902
|
+
pending = true;
|
|
4903
|
+
void workLoopProgress().then((progressed) => stopped || progressed === false ? void 0 : notifier.progress(status(), true)).catch((error) => console.error("[thin-core] watchdog notification failed:", error)).finally(() => {
|
|
4904
|
+
pending = false;
|
|
4905
|
+
});
|
|
4906
|
+
}, intervalMs);
|
|
4898
4907
|
timer.unref?.();
|
|
4899
|
-
return () =>
|
|
4908
|
+
return () => {
|
|
4909
|
+
stopped = true;
|
|
4910
|
+
clearInterval(timer);
|
|
4911
|
+
};
|
|
4900
4912
|
}
|
|
4901
4913
|
var execFileAsync, DELIBERATE_REMOVAL_EXIT_STATUS, DAEMON_DISTRESS_EXIT_STATUS, UNKNOWN_AGENT_EXIT_STATUS, SYSTEMD_UNIT_NAME, SYSTEMD_HELPER_UNIT_NAME, NO_AGENTS_EXIT_STATUS, SYSTEMD_COMMAND_TIMEOUT_MS, SYSTEMD_RESTART_WAIT_MS, AGENT_SERVICE, runSystemctl, SystemdNotifier;
|
|
4902
4914
|
var init_systemd = __esm({
|
|
@@ -4924,8 +4936,8 @@ var init_systemd = __esm({
|
|
|
4924
4936
|
async ready(status) {
|
|
4925
4937
|
await notify(["--ready", `--status=${status}`]);
|
|
4926
4938
|
}
|
|
4927
|
-
async progress(status) {
|
|
4928
|
-
await notify(["WATCHDOG=1", `STATUS=${status}`]);
|
|
4939
|
+
async progress(status, watchdog = false) {
|
|
4940
|
+
await notify([...watchdog ? ["WATCHDOG=1"] : [], `STATUS=${status}`]);
|
|
4929
4941
|
}
|
|
4930
4942
|
async stopping(status) {
|
|
4931
4943
|
await notify(["STOPPING=1", `STATUS=${status}`]);
|
|
@@ -13894,7 +13906,7 @@ function configureNetworkFamilyDefaults(network = net) {
|
|
|
13894
13906
|
configureNetworkFamilyDefaults();
|
|
13895
13907
|
|
|
13896
13908
|
// apps/body/dist/cli.js
|
|
13897
|
-
import { dirname as dirname32, resolve as
|
|
13909
|
+
import { dirname as dirname32, resolve as resolve52 } from "node:path";
|
|
13898
13910
|
import { stdin as stdin4, stdout as stdout5 } from "node:process";
|
|
13899
13911
|
|
|
13900
13912
|
// node_modules/@clack/core/dist/index.mjs
|
|
@@ -15334,7 +15346,7 @@ function parseCursorModelsOutput(output) {
|
|
|
15334
15346
|
};
|
|
15335
15347
|
}
|
|
15336
15348
|
async function enumerateCursorModels(env = process.env) {
|
|
15337
|
-
return new Promise((
|
|
15349
|
+
return new Promise((resolve53) => {
|
|
15338
15350
|
const child = spawn2("cursor-agent", ["models"], {
|
|
15339
15351
|
env,
|
|
15340
15352
|
stdio: ["ignore", "pipe", "ignore"]
|
|
@@ -15348,11 +15360,11 @@ async function enumerateCursorModels(env = process.env) {
|
|
|
15348
15360
|
});
|
|
15349
15361
|
child.on("error", () => {
|
|
15350
15362
|
clearTimeout(timer);
|
|
15351
|
-
|
|
15363
|
+
resolve53(void 0);
|
|
15352
15364
|
});
|
|
15353
15365
|
child.on("close", (code) => {
|
|
15354
15366
|
clearTimeout(timer);
|
|
15355
|
-
|
|
15367
|
+
resolve53(code === 0 ? parseCursorModelsOutput(output) : void 0);
|
|
15356
15368
|
});
|
|
15357
15369
|
});
|
|
15358
15370
|
}
|
|
@@ -15779,13 +15791,13 @@ var CursorAcpServer = class {
|
|
|
15779
15791
|
consumeLine(line);
|
|
15780
15792
|
});
|
|
15781
15793
|
try {
|
|
15782
|
-
const { code, signal } = await new Promise((
|
|
15794
|
+
const { code, signal } = await new Promise((resolve53) => {
|
|
15783
15795
|
let settled = false;
|
|
15784
15796
|
const finish = (exitCode, exitSignal) => {
|
|
15785
15797
|
if (settled)
|
|
15786
15798
|
return;
|
|
15787
15799
|
settled = true;
|
|
15788
|
-
|
|
15800
|
+
resolve53({ code: exitCode, signal: exitSignal });
|
|
15789
15801
|
};
|
|
15790
15802
|
child.once("error", (error) => {
|
|
15791
15803
|
spawnError = error instanceof Error ? error.message : String(error);
|
|
@@ -15930,10 +15942,10 @@ function releaseSquireConnectSession(log2, owner = "") {
|
|
|
15930
15942
|
function squireChromeProfileDir() {
|
|
15931
15943
|
return process.env.TRUSTY_SQUIRE_PROFILE_DIR ?? squireHostPaths(homedir2()).profileDir;
|
|
15932
15944
|
}
|
|
15933
|
-
var defaultShellRunner = (command, args) => new Promise((
|
|
15945
|
+
var defaultShellRunner = (command, args) => new Promise((resolve53) => {
|
|
15934
15946
|
execFile(command, [...args], { timeout: 12e4, maxBuffer: 4 * 1024 * 1024, encoding: "utf8" }, (error, stdout6, stderr) => {
|
|
15935
15947
|
const code = error?.code;
|
|
15936
|
-
|
|
15948
|
+
resolve53({
|
|
15937
15949
|
code: typeof code === "number" ? code : error ? 1 : 0,
|
|
15938
15950
|
stdout: String(stdout6 ?? ""),
|
|
15939
15951
|
stderr: String(stderr ?? "")
|
|
@@ -15958,7 +15970,7 @@ function killConnectTree(child) {
|
|
|
15958
15970
|
}
|
|
15959
15971
|
child.kill();
|
|
15960
15972
|
}
|
|
15961
|
-
var defaultStreamedRunner = (command, args, env, owner = "") => new Promise((
|
|
15973
|
+
var defaultStreamedRunner = (command, args, env, owner = "") => new Promise((resolve53) => {
|
|
15962
15974
|
const child = spawn5(command, args, {
|
|
15963
15975
|
stdio: ["ignore", "pipe", "pipe"],
|
|
15964
15976
|
env: env ?? squireConnectProcessEnv(),
|
|
@@ -15972,7 +15984,7 @@ var defaultStreamedRunner = (command, args, env, owner = "") => new Promise((res
|
|
|
15972
15984
|
const safetyTimer = setTimeout(() => {
|
|
15973
15985
|
if (!resolved) {
|
|
15974
15986
|
resolved = true;
|
|
15975
|
-
|
|
15987
|
+
resolve53({ stdout: stdout6, stderr, pid: child.pid ?? void 0, report, abort: () => {
|
|
15976
15988
|
} });
|
|
15977
15989
|
}
|
|
15978
15990
|
killConnectTree(child);
|
|
@@ -16007,7 +16019,7 @@ var defaultStreamedRunner = (command, args, env, owner = "") => new Promise((res
|
|
|
16007
16019
|
const finish = (result) => {
|
|
16008
16020
|
if (!resolved) {
|
|
16009
16021
|
resolved = true;
|
|
16010
|
-
|
|
16022
|
+
resolve53(result);
|
|
16011
16023
|
}
|
|
16012
16024
|
};
|
|
16013
16025
|
const settle = (result) => {
|
|
@@ -16499,13 +16511,13 @@ var StdioSquireMcpClient = class {
|
|
|
16499
16511
|
const child = this.child;
|
|
16500
16512
|
if (!child)
|
|
16501
16513
|
return Promise.reject(new Error("Squire MCP session is not running"));
|
|
16502
|
-
return new Promise((
|
|
16514
|
+
return new Promise((resolve53, reject) => {
|
|
16503
16515
|
const timeoutMs = method === "initialize" ? INITIALIZE_TIMEOUT_MS : CALL_TIMEOUT_MS;
|
|
16504
16516
|
const timer = setTimeout(() => {
|
|
16505
16517
|
this.pending.delete(id);
|
|
16506
16518
|
reject(new Error(`${toolName2 ?? method} timed out after ${timeoutMs}ms`));
|
|
16507
16519
|
}, timeoutMs);
|
|
16508
|
-
this.pending.set(id, { resolve:
|
|
16520
|
+
this.pending.set(id, { resolve: resolve53, reject, timer });
|
|
16509
16521
|
child.stdin.write(`${JSON.stringify({ jsonrpc: "2.0", id, method, params })}
|
|
16510
16522
|
`);
|
|
16511
16523
|
});
|
|
@@ -16796,9 +16808,9 @@ var SquireTaskRelay = class {
|
|
|
16796
16808
|
response.writeHead(400, { "content-type": "application/json" }).end(JSON.stringify({ error: error instanceof Error ? error.message : "Squire relay failed" }));
|
|
16797
16809
|
}
|
|
16798
16810
|
});
|
|
16799
|
-
await new Promise((
|
|
16811
|
+
await new Promise((resolve53, reject) => {
|
|
16800
16812
|
server.once("error", reject);
|
|
16801
|
-
server.listen(0, "127.0.0.1",
|
|
16813
|
+
server.listen(0, "127.0.0.1", resolve53);
|
|
16802
16814
|
});
|
|
16803
16815
|
this.server = server;
|
|
16804
16816
|
const address = server.address();
|
|
@@ -17904,11 +17916,11 @@ var RegistryMcpHostBroker = class {
|
|
|
17904
17916
|
})();
|
|
17905
17917
|
});
|
|
17906
17918
|
});
|
|
17907
|
-
await new Promise((
|
|
17919
|
+
await new Promise((resolve53, reject) => {
|
|
17908
17920
|
this.server.once("error", reject);
|
|
17909
17921
|
this.server.listen(this.socketPath, () => {
|
|
17910
17922
|
this.server.off("error", reject);
|
|
17911
|
-
|
|
17923
|
+
resolve53();
|
|
17912
17924
|
});
|
|
17913
17925
|
});
|
|
17914
17926
|
chmodSync(this.socketPath, 384);
|
|
@@ -17917,12 +17929,12 @@ var RegistryMcpHostBroker = class {
|
|
|
17917
17929
|
const server = this.server;
|
|
17918
17930
|
this.server = void 0;
|
|
17919
17931
|
if (server)
|
|
17920
|
-
await new Promise((
|
|
17932
|
+
await new Promise((resolve53) => server.close(() => resolve53()));
|
|
17921
17933
|
rmSync2(this.socketPath, { force: true });
|
|
17922
17934
|
}
|
|
17923
17935
|
};
|
|
17924
17936
|
async function brokerRequest(socketPath, request) {
|
|
17925
|
-
return new Promise((
|
|
17937
|
+
return new Promise((resolve53, reject) => {
|
|
17926
17938
|
const socket = createConnection3(socketPath);
|
|
17927
17939
|
let output = "";
|
|
17928
17940
|
socket.setEncoding("utf8");
|
|
@@ -17939,7 +17951,7 @@ async function brokerRequest(socketPath, request) {
|
|
|
17939
17951
|
throw new Error(parsed.error);
|
|
17940
17952
|
if (!Array.isArray(parsed.messages) || !parsed.messages.every((entry) => typeof entry === "string"))
|
|
17941
17953
|
throw new Error("Registry MCP broker returned an invalid response");
|
|
17942
|
-
|
|
17954
|
+
resolve53(parsed.messages);
|
|
17943
17955
|
} catch (error) {
|
|
17944
17956
|
reject(error);
|
|
17945
17957
|
}
|
|
@@ -18738,6 +18750,7 @@ var AgentChannel = class {
|
|
|
18738
18750
|
#registered = false;
|
|
18739
18751
|
/** A register frame is in flight on the current socket. */
|
|
18740
18752
|
#pending = false;
|
|
18753
|
+
#refused = false;
|
|
18741
18754
|
#registeredAt;
|
|
18742
18755
|
#failures = 0;
|
|
18743
18756
|
#retry;
|
|
@@ -18762,7 +18775,7 @@ var AgentChannel = class {
|
|
|
18762
18775
|
return () => this.#openListeners.delete(listener);
|
|
18763
18776
|
}
|
|
18764
18777
|
start() {
|
|
18765
|
-
if (this.#wanted)
|
|
18778
|
+
if (this.#wanted || this.#refused)
|
|
18766
18779
|
return;
|
|
18767
18780
|
this.#wanted = true;
|
|
18768
18781
|
this.machine.want(this);
|
|
@@ -18795,7 +18808,7 @@ var AgentChannel = class {
|
|
|
18795
18808
|
}
|
|
18796
18809
|
/** The socket opened: ask the server to take this agent. */
|
|
18797
18810
|
register() {
|
|
18798
|
-
if (!this.#wanted || this.#registered || this.#pending)
|
|
18811
|
+
if (!this.#wanted || this.#registered || this.#pending || this.#refused)
|
|
18799
18812
|
return;
|
|
18800
18813
|
clearTimeout(this.#retry);
|
|
18801
18814
|
this.#retry = void 0;
|
|
@@ -18828,11 +18841,20 @@ var AgentChannel = class {
|
|
|
18828
18841
|
return;
|
|
18829
18842
|
}
|
|
18830
18843
|
if (event.type === "register-refused") {
|
|
18844
|
+
if (this.#refused)
|
|
18845
|
+
return;
|
|
18831
18846
|
this.#pending = false;
|
|
18832
18847
|
const code = typeof event.code === "string" ? event.code : "refused";
|
|
18833
18848
|
console.warn(`[machine-link] server refused agent ${this.agentId}: ${code}`);
|
|
18849
|
+
this.#refused = ["daemon_token_required", "agent_removed", "too_many_agents"].includes(code);
|
|
18834
18850
|
this.handlers.onRefused?.(code);
|
|
18835
|
-
this.#
|
|
18851
|
+
if (this.#refused) {
|
|
18852
|
+
this.#wanted = false;
|
|
18853
|
+
clearTimeout(this.#retry);
|
|
18854
|
+
this.#retry = void 0;
|
|
18855
|
+
this.machine.unwant(this);
|
|
18856
|
+
} else
|
|
18857
|
+
this.#retryLater();
|
|
18836
18858
|
return;
|
|
18837
18859
|
}
|
|
18838
18860
|
if (event.type === "unregistered") {
|
|
@@ -19461,7 +19483,7 @@ var AgentSignIn = class {
|
|
|
19461
19483
|
};
|
|
19462
19484
|
for (const name of ISOLATION_VARIABLES)
|
|
19463
19485
|
delete env[name];
|
|
19464
|
-
return new Promise((
|
|
19486
|
+
return new Promise((resolve53, reject) => {
|
|
19465
19487
|
let output = "";
|
|
19466
19488
|
let answered = false;
|
|
19467
19489
|
let child;
|
|
@@ -19502,7 +19524,7 @@ var AgentSignIn = class {
|
|
|
19502
19524
|
return;
|
|
19503
19525
|
answered = true;
|
|
19504
19526
|
clearTimeout(linkTimer);
|
|
19505
|
-
|
|
19527
|
+
resolve53(link2);
|
|
19506
19528
|
};
|
|
19507
19529
|
child.stdout?.on("data", read2);
|
|
19508
19530
|
child.stderr?.on("data", read2);
|
|
@@ -28390,19 +28412,19 @@ function wellKnownExecutableDirs(env = process.env) {
|
|
|
28390
28412
|
return [...versioned, resolve7(home, ".local", "bin"), "/usr/local/bin", "/opt/homebrew/bin"];
|
|
28391
28413
|
}
|
|
28392
28414
|
function augmentedSearchDirectories(env = process.env) {
|
|
28393
|
-
const
|
|
28415
|
+
const directories2 = [];
|
|
28394
28416
|
const pushAll = (paths) => {
|
|
28395
28417
|
for (const directory of paths) {
|
|
28396
|
-
if (directory && !
|
|
28397
|
-
|
|
28418
|
+
if (directory && !directories2.includes(directory))
|
|
28419
|
+
directories2.push(directory);
|
|
28398
28420
|
}
|
|
28399
28421
|
};
|
|
28400
28422
|
pushAll((env.PATH ?? "").split(delimiter));
|
|
28401
28423
|
if (env.BEELINE_HARNESS_PATH_AUGMENT === "0")
|
|
28402
|
-
return
|
|
28424
|
+
return directories2;
|
|
28403
28425
|
pushAll(wellKnownExecutableDirs(env));
|
|
28404
28426
|
pushAll((env.BEELINE_LAUNCHER_PATH ?? "").split(delimiter));
|
|
28405
|
-
return
|
|
28427
|
+
return directories2;
|
|
28406
28428
|
}
|
|
28407
28429
|
function describeExecutableSearch(env = process.env) {
|
|
28408
28430
|
return augmentedSearchDirectories(env).join(", ");
|
|
@@ -29351,13 +29373,13 @@ var RoomSupervisor = class {
|
|
|
29351
29373
|
*/
|
|
29352
29374
|
retryDelay(failures, signal, since = this.#wakes) {
|
|
29353
29375
|
const delay = this.delaysMs[failures - 1];
|
|
29354
|
-
return new Promise((
|
|
29376
|
+
return new Promise((resolve53) => {
|
|
29355
29377
|
let timer;
|
|
29356
29378
|
const done = () => {
|
|
29357
29379
|
clearTimeout(timer);
|
|
29358
29380
|
this.#parked.delete(done);
|
|
29359
29381
|
signal?.removeEventListener("abort", done);
|
|
29360
|
-
|
|
29382
|
+
resolve53();
|
|
29361
29383
|
};
|
|
29362
29384
|
this.#parked.add(done);
|
|
29363
29385
|
signal?.addEventListener("abort", done, { once: true });
|
|
@@ -29542,12 +29564,12 @@ async function retryBeforeReady(work, options) {
|
|
|
29542
29564
|
if (wait2 <= 0)
|
|
29543
29565
|
break;
|
|
29544
29566
|
await options.extendStartTimeout(wait2 + 15e3);
|
|
29545
|
-
await new Promise((
|
|
29567
|
+
await new Promise((resolve53) => {
|
|
29546
29568
|
const timer = setTimeout(done, wait2);
|
|
29547
29569
|
function done() {
|
|
29548
29570
|
clearTimeout(timer);
|
|
29549
29571
|
options.signal?.removeEventListener("abort", done);
|
|
29550
|
-
|
|
29572
|
+
resolve53();
|
|
29551
29573
|
}
|
|
29552
29574
|
wake = done;
|
|
29553
29575
|
options.signal?.addEventListener("abort", done, { once: true });
|
|
@@ -31271,9 +31293,9 @@ async function runStartCommand(args, interactiveUi, dependencyOverrides = {}) {
|
|
|
31271
31293
|
// apps/body/dist/connect-command.js
|
|
31272
31294
|
import { spawn as spawn13 } from "node:child_process";
|
|
31273
31295
|
import { createHash as createHash9, randomUUID as randomUUID9 } from "node:crypto";
|
|
31274
|
-
import { chmod as chmod6, mkdir as mkdir16, readFile as
|
|
31296
|
+
import { chmod as chmod6, mkdir as mkdir16, readFile as readFile21, unlink as unlink5, writeFile as writeFile13 } from "node:fs/promises";
|
|
31275
31297
|
import { homedir as homedir12, hostname } from "node:os";
|
|
31276
|
-
import { dirname as dirname17, resolve as
|
|
31298
|
+
import { dirname as dirname17, resolve as resolve23 } from "node:path";
|
|
31277
31299
|
import { stdin as stdin3, stdout as stdout4 } from "node:process";
|
|
31278
31300
|
|
|
31279
31301
|
// packages/api-contract/dist/phone-types.js
|
|
@@ -32340,11 +32362,11 @@ var AcpClient = class extends EventEmitter {
|
|
|
32340
32362
|
}, timeoutMs);
|
|
32341
32363
|
} catch (error) {
|
|
32342
32364
|
if (launch && /EPIPE/.test(String(error)) && this.child?.exitCode === null) {
|
|
32343
|
-
await new Promise((
|
|
32344
|
-
const timer = setTimeout(
|
|
32365
|
+
await new Promise((resolve53) => {
|
|
32366
|
+
const timer = setTimeout(resolve53, 250);
|
|
32345
32367
|
this.child?.once("close", () => {
|
|
32346
32368
|
clearTimeout(timer);
|
|
32347
|
-
|
|
32369
|
+
resolve53();
|
|
32348
32370
|
});
|
|
32349
32371
|
});
|
|
32350
32372
|
}
|
|
@@ -32390,8 +32412,8 @@ ${String(error)}`);
|
|
|
32390
32412
|
try {
|
|
32391
32413
|
oomKilled = await Promise.race([
|
|
32392
32414
|
this.oomKills.consume().catch(() => false),
|
|
32393
|
-
new Promise((
|
|
32394
|
-
diagnosticTimer = setTimeout(() =>
|
|
32415
|
+
new Promise((resolve53) => {
|
|
32416
|
+
diagnosticTimer = setTimeout(() => resolve53(false), 100);
|
|
32395
32417
|
})
|
|
32396
32418
|
]);
|
|
32397
32419
|
} finally {
|
|
@@ -32823,7 +32845,7 @@ ${String(error)}`);
|
|
|
32823
32845
|
const current = this.activeRunIds.get(sessionId);
|
|
32824
32846
|
if (current)
|
|
32825
32847
|
return Promise.resolve(current);
|
|
32826
|
-
return new Promise((
|
|
32848
|
+
return new Promise((resolve53, reject) => {
|
|
32827
32849
|
const onUpdate = (update) => {
|
|
32828
32850
|
if (update.sessionId !== sessionId)
|
|
32829
32851
|
return;
|
|
@@ -32831,7 +32853,7 @@ ${String(error)}`);
|
|
|
32831
32853
|
if (!runId)
|
|
32832
32854
|
return;
|
|
32833
32855
|
cleanup();
|
|
32834
|
-
|
|
32856
|
+
resolve53(runId);
|
|
32835
32857
|
};
|
|
32836
32858
|
const timer = setTimeout(() => {
|
|
32837
32859
|
cleanup();
|
|
@@ -32910,14 +32932,14 @@ ${String(error)}`);
|
|
|
32910
32932
|
}
|
|
32911
32933
|
const id = this.nextId++;
|
|
32912
32934
|
const payload = { jsonrpc: "2.0", id, method, params };
|
|
32913
|
-
return new Promise((
|
|
32935
|
+
return new Promise((resolve53, reject) => {
|
|
32914
32936
|
const timer = backstop ? void 0 : setTimeout(() => {
|
|
32915
32937
|
this.pending.delete(id);
|
|
32916
32938
|
reject(new AcpRequestTimeoutError(method, timeoutMs, this.stderrTail, false, detail));
|
|
32917
32939
|
}, timeoutMs);
|
|
32918
32940
|
const sessionId = params?.sessionId;
|
|
32919
32941
|
this.pending.set(id, {
|
|
32920
|
-
resolve:
|
|
32942
|
+
resolve: resolve53,
|
|
32921
32943
|
reject,
|
|
32922
32944
|
timer,
|
|
32923
32945
|
method,
|
|
@@ -33973,18 +33995,145 @@ async function pairDevice(grant, options = {}) {
|
|
|
33973
33995
|
}
|
|
33974
33996
|
|
|
33975
33997
|
// apps/body/dist/openrouter-routing.js
|
|
33976
|
-
import { mkdir as mkdir14, readFile as
|
|
33998
|
+
import { mkdir as mkdir14, readFile as readFile19, writeFile as writeFile11 } from "node:fs/promises";
|
|
33999
|
+
import { resolve as resolve21 } from "node:path";
|
|
34000
|
+
|
|
34001
|
+
// apps/body/dist/openrouter-history.js
|
|
34002
|
+
import { createReadStream as createReadStream2 } from "node:fs";
|
|
34003
|
+
import { lstat as lstat5, readFile as readFile18, readdir as readdir6 } from "node:fs/promises";
|
|
33977
34004
|
import { resolve as resolve20 } from "node:path";
|
|
34005
|
+
import { createInterface as createInterface6 } from "node:readline";
|
|
34006
|
+
var OPENROUTER_HISTORY_WINDOW_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
34007
|
+
var OPENROUTER_GENERATION_URL = "https://openrouter.ai/api/v1/generation";
|
|
34008
|
+
function openRouterTraffic(observations) {
|
|
34009
|
+
const totals = /* @__PURE__ */ new Map();
|
|
34010
|
+
for (const observation2 of observations) {
|
|
34011
|
+
if (observation2.promptTokens <= 0)
|
|
34012
|
+
continue;
|
|
34013
|
+
const total = totals.get(observation2.provider) ?? { calls: 0, promptTokens: 0, cachedTokens: 0 };
|
|
34014
|
+
total.calls++;
|
|
34015
|
+
total.promptTokens += observation2.promptTokens;
|
|
34016
|
+
total.cachedTokens += Math.min(observation2.promptTokens, Math.max(0, observation2.cachedTokens));
|
|
34017
|
+
totals.set(observation2.provider, total);
|
|
34018
|
+
}
|
|
34019
|
+
return [...totals].map(([provider, total]) => ({ ...total, provider, cacheShare: total.cachedTokens / total.promptTokens }));
|
|
34020
|
+
}
|
|
34021
|
+
async function directories(root) {
|
|
34022
|
+
return (await readdir6(root, { withFileTypes: true }).catch(() => [])).filter((entry) => entry.isDirectory()).map((entry) => resolve20(root, entry.name));
|
|
34023
|
+
}
|
|
34024
|
+
async function openRouterGenerationIds(roomsDir, model, now2) {
|
|
34025
|
+
const ids = /* @__PURE__ */ new Map();
|
|
34026
|
+
for (const room of await directories(roomsDir)) {
|
|
34027
|
+
const ordinary = await Promise.all(["agent-home", "agent-home/pi", "agent-home/pi/sessions"].map(async (path) => {
|
|
34028
|
+
const stat14 = await lstat5(resolve20(room, path)).catch(() => void 0);
|
|
34029
|
+
return stat14?.isDirectory() && !stat14.isSymbolicLink();
|
|
34030
|
+
}));
|
|
34031
|
+
if (!ordinary.every(Boolean))
|
|
34032
|
+
continue;
|
|
34033
|
+
for (const project of await directories(resolve20(room, "agent-home/pi/sessions"))) {
|
|
34034
|
+
const files = await readdir6(project, { withFileTypes: true }).catch(() => []);
|
|
34035
|
+
for (const file of files) {
|
|
34036
|
+
if (!file.isFile() || !file.name.endsWith(".jsonl"))
|
|
34037
|
+
continue;
|
|
34038
|
+
const stream = createReadStream2(resolve20(project, file.name), { encoding: "utf8" });
|
|
34039
|
+
const lines = createInterface6({ input: stream, crlfDelay: Infinity });
|
|
34040
|
+
try {
|
|
34041
|
+
for await (const line of lines) {
|
|
34042
|
+
try {
|
|
34043
|
+
const { message } = JSON.parse(line);
|
|
34044
|
+
if (message?.role !== "assistant" || message.model !== model || typeof message.responseId !== "string")
|
|
34045
|
+
continue;
|
|
34046
|
+
const timestamp = message.timestamp;
|
|
34047
|
+
if (typeof timestamp === "number" && timestamp >= now2 - OPENROUTER_HISTORY_WINDOW_MS && timestamp <= now2) {
|
|
34048
|
+
ids.set(message.responseId, timestamp);
|
|
34049
|
+
}
|
|
34050
|
+
} catch {
|
|
34051
|
+
}
|
|
34052
|
+
}
|
|
34053
|
+
} catch {
|
|
34054
|
+
} finally {
|
|
34055
|
+
lines.close();
|
|
34056
|
+
stream.destroy();
|
|
34057
|
+
}
|
|
34058
|
+
}
|
|
34059
|
+
}
|
|
34060
|
+
}
|
|
34061
|
+
return ids;
|
|
34062
|
+
}
|
|
34063
|
+
function observation(value) {
|
|
34064
|
+
if (!value || typeof value !== "object")
|
|
34065
|
+
return void 0;
|
|
34066
|
+
const row = value;
|
|
34067
|
+
if (typeof row.id !== "string" || typeof row.provider !== "string" || typeof row.timestamp !== "number" || !Number.isFinite(row.timestamp) || typeof row.promptTokens !== "number" || !Number.isFinite(row.promptTokens) || row.promptTokens < 0 || typeof row.cachedTokens !== "number" || !Number.isFinite(row.cachedTokens) || row.cachedTokens < 0)
|
|
34068
|
+
return void 0;
|
|
34069
|
+
return {
|
|
34070
|
+
id: row.id,
|
|
34071
|
+
provider: row.provider,
|
|
34072
|
+
timestamp: row.timestamp,
|
|
34073
|
+
promptTokens: row.promptTokens,
|
|
34074
|
+
cachedTokens: Math.min(row.cachedTokens, row.promptTokens),
|
|
34075
|
+
...typeof row.sessionId === "string" ? { sessionId: row.sessionId } : {}
|
|
34076
|
+
};
|
|
34077
|
+
}
|
|
34078
|
+
async function readOpenRouterTraffic(input) {
|
|
34079
|
+
const path = resolve20(input.cacheDir, `${input.model.replace(/[^A-Za-z0-9._-]+/g, "_")}.generations.json`);
|
|
34080
|
+
let cached = [];
|
|
34081
|
+
try {
|
|
34082
|
+
const value = JSON.parse(await readFile18(path, "utf8"));
|
|
34083
|
+
const record5 = value;
|
|
34084
|
+
if (record5?.model === input.model && Array.isArray(record5.observations)) {
|
|
34085
|
+
cached = record5.observations.map(observation).filter((row) => Boolean(row));
|
|
34086
|
+
}
|
|
34087
|
+
} catch {
|
|
34088
|
+
}
|
|
34089
|
+
const cutoff = input.now - OPENROUTER_HISTORY_WINDOW_MS;
|
|
34090
|
+
const records = new Map(cached.filter((row) => row.timestamp >= cutoff && row.timestamp <= input.now).map((row) => [row.id, row]));
|
|
34091
|
+
const ids = input.roomsDir ? await openRouterGenerationIds(input.roomsDir, input.model, input.now) : /* @__PURE__ */ new Map();
|
|
34092
|
+
const missing = [...ids].filter(([id]) => !records.has(id));
|
|
34093
|
+
let cursor3 = 0;
|
|
34094
|
+
await Promise.all(Array.from({ length: Math.min(6, missing.length) }, async () => {
|
|
34095
|
+
while (cursor3 < missing.length) {
|
|
34096
|
+
const [id, timestamp] = missing[cursor3++];
|
|
34097
|
+
try {
|
|
34098
|
+
const response = await (input.fetchImpl ?? fetch)(`${OPENROUTER_GENERATION_URL}?id=${encodeURIComponent(id)}`, {
|
|
34099
|
+
headers: { authorization: `Bearer ${input.apiKey}` },
|
|
34100
|
+
signal: AbortSignal.timeout(input.timeoutMs ?? 1e4)
|
|
34101
|
+
});
|
|
34102
|
+
if (!response.ok)
|
|
34103
|
+
continue;
|
|
34104
|
+
const { data } = await response.json();
|
|
34105
|
+
if (!data || data.id !== id)
|
|
34106
|
+
continue;
|
|
34107
|
+
const row = observation({
|
|
34108
|
+
id,
|
|
34109
|
+
timestamp,
|
|
34110
|
+
provider: data.provider_name,
|
|
34111
|
+
promptTokens: data.native_tokens_prompt,
|
|
34112
|
+
cachedTokens: data.native_tokens_cached ?? 0,
|
|
34113
|
+
sessionId: data.session_id
|
|
34114
|
+
});
|
|
34115
|
+
if (row)
|
|
34116
|
+
records.set(id, row);
|
|
34117
|
+
} catch {
|
|
34118
|
+
}
|
|
34119
|
+
}
|
|
34120
|
+
}));
|
|
34121
|
+
await writePrivateFileAtomically(path, `${JSON.stringify({ model: input.model, observations: [...records.values()] })}
|
|
34122
|
+
`).catch(() => void 0);
|
|
34123
|
+
return openRouterTraffic([...records.values()]);
|
|
34124
|
+
}
|
|
34125
|
+
|
|
34126
|
+
// apps/body/dist/openrouter-routing.js
|
|
33978
34127
|
var OPENROUTER_ENDPOINTS_BASE_URL = "https://openrouter.ai/api/v1/models";
|
|
33979
34128
|
var OPENROUTER_COMPLETIONS_URL = "https://openrouter.ai/api/v1/chat/completions";
|
|
33980
34129
|
var OPENROUTER_ROUTING_CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
33981
34130
|
var OPENROUTER_ROUTING_FETCH_TIMEOUT_MS = 1e4;
|
|
33982
|
-
var OPENROUTER_PROBE_CACHE_TTL_MS = 6 * 60 * 60 * 1e3;
|
|
33983
34131
|
var OPENROUTER_PROBE_MAX_CANDIDATES = 6;
|
|
33984
34132
|
var OPENROUTER_PROBE_TIMEOUT_MS = 2e4;
|
|
33985
34133
|
var OPENROUTER_UPTIME_BAR = 98;
|
|
33986
34134
|
var OPENROUTER_UPTIME_BAR_RELAXED = 95;
|
|
33987
34135
|
var OPENROUTER_MIN_PROVIDERS = 2;
|
|
34136
|
+
var ROUTING_POLICY = "cache-sticky-v1";
|
|
33988
34137
|
var OPENROUTER_MAX_OUTPUT_TOKENS = 32768;
|
|
33989
34138
|
var OPENROUTER_FALLBACK_PROVIDERS = ["deepinfra", "novita"];
|
|
33990
34139
|
function openRouterModelId(model, env = {}) {
|
|
@@ -34016,12 +34165,19 @@ function parseOpenRouterEndpoints(payload) {
|
|
|
34016
34165
|
const contextLength = typeof endpoint2.context_length === "number" ? endpoint2.context_length : 0;
|
|
34017
34166
|
const maxCompletionTokens = typeof endpoint2.max_completion_tokens === "number" ? endpoint2.max_completion_tokens : 0;
|
|
34018
34167
|
const supported = Array.isArray(endpoint2.supported_parameters) ? endpoint2.supported_parameters : [];
|
|
34168
|
+
const pricing = endpoint2.pricing && typeof endpoint2.pricing === "object" ? endpoint2.pricing : {};
|
|
34169
|
+
const promptPrice = tokenPrice(pricing.prompt);
|
|
34170
|
+
const cacheReadPrice = tokenPrice(pricing.input_cache_read);
|
|
34019
34171
|
endpoints.push({
|
|
34020
34172
|
provider,
|
|
34021
34173
|
uptime,
|
|
34022
34174
|
contextLength,
|
|
34023
34175
|
maxCompletionTokens,
|
|
34024
|
-
tools: supported.includes("tools")
|
|
34176
|
+
tools: supported.includes("tools"),
|
|
34177
|
+
...typeof endpoint2.provider_name === "string" ? { providerName: endpoint2.provider_name } : {},
|
|
34178
|
+
...promptPrice === void 0 ? {} : { promptPrice },
|
|
34179
|
+
...cacheReadPrice === void 0 ? {} : { cacheReadPrice },
|
|
34180
|
+
discountedCacheRead: promptPrice !== void 0 && cacheReadPrice !== void 0 && cacheReadPrice < promptPrice
|
|
34025
34181
|
});
|
|
34026
34182
|
}
|
|
34027
34183
|
const architecture = record5.architecture && typeof record5.architecture === "object" ? record5.architecture : {};
|
|
@@ -34032,6 +34188,30 @@ function parseOpenRouterEndpoints(payload) {
|
|
|
34032
34188
|
inputModalities: modalities?.length ? modalities : void 0
|
|
34033
34189
|
};
|
|
34034
34190
|
}
|
|
34191
|
+
function rankOpenRouterProviders(endpoints, contextLength, traffic, answered) {
|
|
34192
|
+
const shares2 = traffic.filter((row) => row.promptTokens > 0).map((row) => row.cacheShare).sort((a2, b) => a2 - b);
|
|
34193
|
+
const middle = Math.floor(shares2.length / 2);
|
|
34194
|
+
const medianShare = shares2.length ? (shares2[middle] + shares2[Math.floor((shares2.length - 1) / 2)]) / 2 : 0;
|
|
34195
|
+
const normalize2 = (name) => name.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
34196
|
+
const ranked = /* @__PURE__ */ new Map();
|
|
34197
|
+
for (const endpoint2 of endpoints) {
|
|
34198
|
+
if (!endpoint2.tools || endpoint2.uptime < OPENROUTER_UPTIME_BAR_RELAXED || contextLength !== void 0 && endpoint2.contextLength < contextLength || !answered.includes(endpoint2.provider) || endpoint2.promptPrice === void 0)
|
|
34199
|
+
continue;
|
|
34200
|
+
const measured = traffic.find((row2) => normalize2(row2.provider) === normalize2(endpoint2.providerName ?? endpoint2.provider));
|
|
34201
|
+
const cacheShare = measured?.cacheShare ?? medianShare;
|
|
34202
|
+
const effectiveInputPrice = endpoint2.promptPrice * (1 - cacheShare) + (endpoint2.cacheReadPrice ?? endpoint2.promptPrice) * cacheShare;
|
|
34203
|
+
const row = { provider: endpoint2.provider, cacheShare, measuredCalls: measured?.calls ?? 0, effectiveInputPrice };
|
|
34204
|
+
if (!ranked.has(row.provider) || effectiveInputPrice < ranked.get(row.provider).effectiveInputPrice)
|
|
34205
|
+
ranked.set(row.provider, row);
|
|
34206
|
+
}
|
|
34207
|
+
return [...ranked.values()].sort((a2, b) => a2.effectiveInputPrice - b.effectiveInputPrice || a2.provider.localeCompare(b.provider));
|
|
34208
|
+
}
|
|
34209
|
+
function tokenPrice(value) {
|
|
34210
|
+
if (typeof value !== "number" && (typeof value !== "string" || !value.trim()))
|
|
34211
|
+
return void 0;
|
|
34212
|
+
const price = Number(value);
|
|
34213
|
+
return Number.isFinite(price) && price >= 0 ? price : void 0;
|
|
34214
|
+
}
|
|
34035
34215
|
function piInputModalities(modalities) {
|
|
34036
34216
|
if (!modalities)
|
|
34037
34217
|
return void 0;
|
|
@@ -34061,12 +34241,14 @@ function advertisedContextLength(endpoints) {
|
|
|
34061
34241
|
}
|
|
34062
34242
|
function selectReliableOpenRouterProviders(endpoints, contextLength) {
|
|
34063
34243
|
const eligible = endpoints.filter((endpoint2) => endpoint2.tools && (contextLength === void 0 || endpoint2.contextLength >= contextLength));
|
|
34244
|
+
const caching = eligible.filter((endpoint2) => endpoint2.discountedCacheRead && endpoint2.uptime >= OPENROUTER_UPTIME_BAR_RELAXED);
|
|
34245
|
+
const candidates = caching.length ? caching : eligible;
|
|
34064
34246
|
const atBar = (bar) => {
|
|
34065
34247
|
const seen = /* @__PURE__ */ new Set();
|
|
34066
|
-
return
|
|
34248
|
+
return candidates.filter((endpoint2) => endpoint2.uptime >= bar).sort((left, right) => right.uptime - left.uptime).map((endpoint2) => endpoint2.provider).filter((provider) => seen.has(provider) ? false : (seen.add(provider), true));
|
|
34067
34249
|
};
|
|
34068
34250
|
const strict = atBar(OPENROUTER_UPTIME_BAR);
|
|
34069
|
-
if (strict.length >= OPENROUTER_MIN_PROVIDERS) {
|
|
34251
|
+
if (strict.length >= OPENROUTER_MIN_PROVIDERS && (caching.length === 0 || caching.every((endpoint2) => endpoint2.uptime >= OPENROUTER_UPTIME_BAR))) {
|
|
34070
34252
|
return { providers: strict, bar: OPENROUTER_UPTIME_BAR, contextLength };
|
|
34071
34253
|
}
|
|
34072
34254
|
const relaxed = atBar(OPENROUTER_UPTIME_BAR_RELAXED);
|
|
@@ -34088,20 +34270,24 @@ function openRouterModelLimits(endpoints, providers) {
|
|
|
34088
34270
|
function openRouterRoutingFor(providers, allowFallbacks = true) {
|
|
34089
34271
|
return {
|
|
34090
34272
|
only: [...providers],
|
|
34091
|
-
order
|
|
34273
|
+
// provider.order disables OpenRouter's session stickiness. Pi already
|
|
34274
|
+
// sends its session id; OpenRouter keeps the successful cache provider
|
|
34275
|
+
// and falls back on failure, within `only`, without bouncing to the old
|
|
34276
|
+
// first choice on every request. A recovery override remains explicit.
|
|
34277
|
+
...allowFallbacks ? {} : { order: [...providers] },
|
|
34092
34278
|
allow_fallbacks: allowFallbacks,
|
|
34093
34279
|
require_parameters: false
|
|
34094
34280
|
};
|
|
34095
34281
|
}
|
|
34096
34282
|
function openRouterRoutingCacheDir(runtimeDir) {
|
|
34097
|
-
return
|
|
34283
|
+
return resolve21(runtimeDir, "openrouter-routing");
|
|
34098
34284
|
}
|
|
34099
34285
|
function cachePath(cacheDir, model) {
|
|
34100
|
-
return
|
|
34286
|
+
return resolve21(cacheDir, `${model.replace(/[^A-Za-z0-9._-]+/g, "_")}.json`);
|
|
34101
34287
|
}
|
|
34102
34288
|
async function readCache(cacheDir, model) {
|
|
34103
34289
|
try {
|
|
34104
|
-
const parsed = JSON.parse(await
|
|
34290
|
+
const parsed = JSON.parse(await readFile19(cachePath(cacheDir, model), "utf8"));
|
|
34105
34291
|
if (!parsed || typeof parsed !== "object")
|
|
34106
34292
|
return void 0;
|
|
34107
34293
|
const cached = parsed;
|
|
@@ -34111,6 +34297,7 @@ async function readCache(cacheDir, model) {
|
|
|
34111
34297
|
const input = Array.isArray(cached.input) ? cached.input.filter((value) => value === "text" || value === "image") : cached.input === null ? null : void 0;
|
|
34112
34298
|
const limits = cached.limits === null ? null : cachedLimits(cached.limits);
|
|
34113
34299
|
return {
|
|
34300
|
+
policy: typeof cached.policy === "string" ? cached.policy : void 0,
|
|
34114
34301
|
model,
|
|
34115
34302
|
fetchedAt: cached.fetchedAt,
|
|
34116
34303
|
providers: cached.providers,
|
|
@@ -34139,41 +34326,6 @@ async function writeCache(cacheDir, value) {
|
|
|
34139
34326
|
mode: 384
|
|
34140
34327
|
});
|
|
34141
34328
|
}
|
|
34142
|
-
function probeCachePath(cacheDir, model) {
|
|
34143
|
-
return resolve20(cacheDir, `${model.replace(/[^A-Za-z0-9._-]+/g, "_")}.probe.json`);
|
|
34144
|
-
}
|
|
34145
|
-
async function readProbeCache(cacheDir, model) {
|
|
34146
|
-
try {
|
|
34147
|
-
const parsed = JSON.parse(await readFile18(probeCachePath(cacheDir, model), "utf8"));
|
|
34148
|
-
if (!parsed || typeof parsed !== "object")
|
|
34149
|
-
return void 0;
|
|
34150
|
-
const cached = parsed;
|
|
34151
|
-
if (cached.model !== model || typeof cached.fetchedAt !== "number")
|
|
34152
|
-
return void 0;
|
|
34153
|
-
if (!Array.isArray(cached.answered))
|
|
34154
|
-
return void 0;
|
|
34155
|
-
const answered = [];
|
|
34156
|
-
for (const entry of cached.answered) {
|
|
34157
|
-
if (!entry || typeof entry !== "object")
|
|
34158
|
-
return void 0;
|
|
34159
|
-
const { provider, latencyMs } = entry;
|
|
34160
|
-
if (typeof provider !== "string" || !provider || typeof latencyMs !== "number") {
|
|
34161
|
-
return void 0;
|
|
34162
|
-
}
|
|
34163
|
-
answered.push({ provider, latencyMs });
|
|
34164
|
-
}
|
|
34165
|
-
return { model, fetchedAt: cached.fetchedAt, answered };
|
|
34166
|
-
} catch {
|
|
34167
|
-
return void 0;
|
|
34168
|
-
}
|
|
34169
|
-
}
|
|
34170
|
-
async function writeProbeCache(cacheDir, value) {
|
|
34171
|
-
await mkdir14(cacheDir, { recursive: true, mode: 448 });
|
|
34172
|
-
await writeFile11(probeCachePath(cacheDir, value.model), `${JSON.stringify(value, null, 2)}
|
|
34173
|
-
`, {
|
|
34174
|
-
mode: 384
|
|
34175
|
-
});
|
|
34176
|
-
}
|
|
34177
34329
|
var PROBE_TOOL = {
|
|
34178
34330
|
type: "function",
|
|
34179
34331
|
function: {
|
|
@@ -34259,7 +34411,7 @@ async function probeOpenRouterProviders(input) {
|
|
|
34259
34411
|
function decision(model, providers, bar, source, note, allowFallbacks = true, input, limits) {
|
|
34260
34412
|
const criteria = bar === null ? "fallback pair" : `uptime \u2265${bar}%, tools`;
|
|
34261
34413
|
const suffix = [
|
|
34262
|
-
bar === OPENROUTER_UPTIME_BAR_RELAXED ? "bar lowered:
|
|
34414
|
+
bar === OPENROUTER_UPTIME_BAR_RELAXED && !note?.startsWith("daily") ? "bar lowered: reliability fallback or cache continuity" : "",
|
|
34263
34415
|
source === "cache" ? "cached" : "",
|
|
34264
34416
|
source === "stale-cache" ? "stale cache" : "",
|
|
34265
34417
|
note ?? ""
|
|
@@ -34278,7 +34430,7 @@ function decision(model, providers, bar, source, note, allowFallbacks = true, in
|
|
|
34278
34430
|
async function resolveUptimeRouting(input) {
|
|
34279
34431
|
const now2 = input.now ?? Date.now;
|
|
34280
34432
|
const cached = await readCache(input.cacheDir, input.model);
|
|
34281
|
-
if (cached?.input !== void 0 && cached.limits !== void 0 && now2() - cached.fetchedAt < OPENROUTER_ROUTING_CACHE_TTL_MS) {
|
|
34433
|
+
if (cached?.policy === ROUTING_POLICY && cached?.input !== void 0 && cached.limits !== void 0 && now2() - cached.fetchedAt < OPENROUTER_ROUTING_CACHE_TTL_MS) {
|
|
34282
34434
|
return decision(input.model, cached.providers, cached.bar, "cache", void 0, true, cached.input ?? void 0, cached.limits ?? void 0);
|
|
34283
34435
|
}
|
|
34284
34436
|
let failure;
|
|
@@ -34297,8 +34449,16 @@ async function resolveUptimeRouting(input) {
|
|
|
34297
34449
|
if (selected.providers.length === 0) {
|
|
34298
34450
|
return decision(input.model, OPENROUTER_FALLBACK_PROVIDERS, null, "fallback", "no provider met the bar", true, modelInput);
|
|
34299
34451
|
}
|
|
34452
|
+
if (cached?.policy === ROUTING_POLICY) {
|
|
34453
|
+
const retained = cached.providers.filter((provider) => selected.providers.includes(provider));
|
|
34454
|
+
selected.providers = [
|
|
34455
|
+
...retained,
|
|
34456
|
+
...selected.providers.filter((provider) => !retained.includes(provider))
|
|
34457
|
+
];
|
|
34458
|
+
}
|
|
34300
34459
|
const limits = openRouterModelLimits(endpoints, selected.providers);
|
|
34301
34460
|
await writeCache(input.cacheDir, {
|
|
34461
|
+
policy: ROUTING_POLICY,
|
|
34302
34462
|
model: input.model,
|
|
34303
34463
|
fetchedAt: now2(),
|
|
34304
34464
|
providers: selected.providers,
|
|
@@ -34316,62 +34476,106 @@ async function resolveUptimeRouting(input) {
|
|
|
34316
34476
|
}
|
|
34317
34477
|
return decision(input.model, OPENROUTER_FALLBACK_PROVIDERS, null, "fallback", `api unreachable: ${failure}`);
|
|
34318
34478
|
}
|
|
34319
|
-
|
|
34320
|
-
|
|
34321
|
-
return probe.answered.map((entry) => entry.provider).filter((provider) => candidates.includes(provider));
|
|
34479
|
+
function dailyCachePath(input) {
|
|
34480
|
+
return resolve21(input.cacheDir, `${input.model.replace(/[^A-Za-z0-9._-]+/g, "_")}.daily.json`);
|
|
34322
34481
|
}
|
|
34323
|
-
async function
|
|
34324
|
-
|
|
34325
|
-
|
|
34326
|
-
model
|
|
34327
|
-
|
|
34328
|
-
|
|
34329
|
-
|
|
34330
|
-
|
|
34331
|
-
|
|
34332
|
-
|
|
34333
|
-
|
|
34334
|
-
|
|
34335
|
-
|
|
34336
|
-
|
|
34482
|
+
async function readDailyRouting(input) {
|
|
34483
|
+
try {
|
|
34484
|
+
const row = JSON.parse(await readFile19(dailyCachePath(input), "utf8"));
|
|
34485
|
+
if (row.policy !== "cost-daily-v1" || row.model !== input.model || !Number.isFinite(row.fetchedAt) || !Array.isArray(row.providers) || !row.providers.length || row.providers.length > 3 || !row.providers.every((provider) => typeof provider === "string" && provider.length > 0) || !Array.isArray(row.ranking) || !row.ranking.every((entry) => entry && typeof entry.provider === "string" && Number.isFinite(entry.effectiveInputPrice) && entry.effectiveInputPrice >= 0 && Number.isFinite(entry.cacheShare) && entry.cacheShare >= 0 && entry.cacheShare <= 1) || !row.providers.every((provider) => row.ranking.some((entry) => entry.provider === provider)))
|
|
34486
|
+
return void 0;
|
|
34487
|
+
return {
|
|
34488
|
+
policy: "cost-daily-v1",
|
|
34489
|
+
model: row.model,
|
|
34490
|
+
fetchedAt: row.fetchedAt,
|
|
34491
|
+
providers: row.providers,
|
|
34492
|
+
ranking: row.ranking,
|
|
34493
|
+
...Array.isArray(row.input) ? { input: row.input.filter((value) => value === "text" || value === "image") } : {},
|
|
34494
|
+
...cachedLimits(row.limits) ? { limits: cachedLimits(row.limits) } : {}
|
|
34495
|
+
};
|
|
34496
|
+
} catch {
|
|
34337
34497
|
return void 0;
|
|
34338
34498
|
}
|
|
34339
|
-
|
|
34499
|
+
}
|
|
34500
|
+
function dailyDecision(row, source) {
|
|
34501
|
+
return decision(row.model, row.providers, OPENROUTER_UPTIME_BAR_RELAXED, source, "daily effective input cost; seven-day cache shares; answer-probed", true, row.input, row.limits);
|
|
34502
|
+
}
|
|
34503
|
+
async function buildDailyRouting(input) {
|
|
34504
|
+
const now2 = input.now ?? Date.now;
|
|
34505
|
+
const response = await (input.fetchImpl ?? fetch)(`${OPENROUTER_ENDPOINTS_BASE_URL}/${input.model}/endpoints`, {
|
|
34506
|
+
signal: AbortSignal.timeout(input.timeoutMs ?? OPENROUTER_ROUTING_FETCH_TIMEOUT_MS)
|
|
34507
|
+
});
|
|
34508
|
+
if (!response.ok)
|
|
34509
|
+
throw new Error(`HTTP ${response.status}`);
|
|
34510
|
+
const { endpoints, contextLength, inputModalities } = parseOpenRouterEndpoints(await response.json());
|
|
34511
|
+
const eligible = [...new Set(endpoints.filter((endpoint2) => endpoint2.tools && endpoint2.uptime >= OPENROUTER_UPTIME_BAR_RELAXED && endpoint2.promptPrice !== void 0 && (contextLength === void 0 || endpoint2.contextLength >= contextLength)).map((endpoint2) => endpoint2.provider))];
|
|
34512
|
+
if (!eligible.length)
|
|
34513
|
+
throw new Error("no priced provider met the tools/context/95% gate");
|
|
34514
|
+
const [traffic, probes] = await Promise.all([
|
|
34515
|
+
readOpenRouterTraffic({
|
|
34516
|
+
model: input.model,
|
|
34517
|
+
cacheDir: input.cacheDir,
|
|
34518
|
+
...input.historyRoomsDir ? { roomsDir: input.historyRoomsDir } : {},
|
|
34519
|
+
apiKey: input.apiKey,
|
|
34520
|
+
now: now2(),
|
|
34521
|
+
fetchImpl: input.fetchImpl,
|
|
34522
|
+
timeoutMs: input.timeoutMs
|
|
34523
|
+
}),
|
|
34524
|
+
probeOpenRouterProviders({
|
|
34525
|
+
model: input.model,
|
|
34526
|
+
providers: eligible,
|
|
34527
|
+
apiKey: input.apiKey,
|
|
34528
|
+
fetchImpl: input.fetchImpl,
|
|
34529
|
+
now: input.now,
|
|
34530
|
+
timeoutMs: input.probeTimeoutMs,
|
|
34531
|
+
// Gate every eligible provider once per day, rather than using the old
|
|
34532
|
+
// uptime-first six as a proxy for the cheapest qualified set.
|
|
34533
|
+
maxCandidates: input.probeMaxCandidates ?? eligible.length
|
|
34534
|
+
})
|
|
34535
|
+
]);
|
|
34536
|
+
const ranking = rankOpenRouterProviders(endpoints, contextLength, traffic, probes.filter((probe) => probe.answered).map((probe) => probe.provider));
|
|
34537
|
+
if (!ranking.length)
|
|
34538
|
+
throw new Error("no eligible provider answered the text probe");
|
|
34539
|
+
const providers = ranking.slice(0, 3).map((row2) => row2.provider);
|
|
34540
|
+
const row = {
|
|
34541
|
+
policy: "cost-daily-v1",
|
|
34340
34542
|
model: input.model,
|
|
34341
34543
|
fetchedAt: now2(),
|
|
34342
|
-
|
|
34343
|
-
|
|
34344
|
-
|
|
34345
|
-
|
|
34544
|
+
providers,
|
|
34545
|
+
ranking,
|
|
34546
|
+
input: piInputModalities(inputModalities),
|
|
34547
|
+
limits: openRouterModelLimits(endpoints, providers)
|
|
34548
|
+
};
|
|
34549
|
+
await writePrivateFileAtomically(dailyCachePath(input), `${JSON.stringify(row, null, 2)}
|
|
34550
|
+
`).catch(() => void 0);
|
|
34551
|
+
return row;
|
|
34346
34552
|
}
|
|
34553
|
+
var dailyAttempts = /* @__PURE__ */ new Map();
|
|
34347
34554
|
async function resolveOpenRouterRouting(input) {
|
|
34348
|
-
const
|
|
34555
|
+
const cached = await readDailyRouting(input);
|
|
34349
34556
|
const override = input.providerOverride?.trim();
|
|
34350
34557
|
if (override) {
|
|
34558
|
+
const base = cached ? dailyDecision(cached, "cache") : await resolveUptimeRouting(input);
|
|
34351
34559
|
return decision(input.model, [override], base.bar, base.source, "pinned to one provider after an empty completion", false, base.input, base.limits);
|
|
34352
34560
|
}
|
|
34353
|
-
|
|
34354
|
-
|
|
34355
|
-
return base;
|
|
34561
|
+
if (!input.apiKey?.trim())
|
|
34562
|
+
return resolveUptimeRouting(input);
|
|
34356
34563
|
const now2 = input.now ?? Date.now;
|
|
34357
|
-
|
|
34358
|
-
|
|
34359
|
-
const answered = answeringProviders(probe, base.providers);
|
|
34360
|
-
if (answered.length > 0) {
|
|
34361
|
-
return decision(input.model, answered, base.bar, base.source, "answer-probed, cached", true, base.input, base.limits);
|
|
34362
|
-
}
|
|
34363
|
-
}
|
|
34564
|
+
if (cached && now2() - cached.fetchedAt < OPENROUTER_ROUTING_CACHE_TTL_MS)
|
|
34565
|
+
return dailyDecision(cached, "cache");
|
|
34364
34566
|
const key = `${input.cacheDir}\0${input.model}`;
|
|
34365
|
-
let
|
|
34366
|
-
if (!
|
|
34367
|
-
const
|
|
34368
|
-
|
|
34369
|
-
|
|
34567
|
+
let attempt = dailyAttempts.get(key);
|
|
34568
|
+
if (!attempt || now2() - attempt.startedAt >= OPENROUTER_ROUTING_CACHE_TTL_MS) {
|
|
34569
|
+
const result = buildDailyRouting(input).then((row) => dailyDecision(row, "live")).catch(async (error) => {
|
|
34570
|
+
const base = cached ? dailyDecision(cached, "stale-cache") : await resolveUptimeRouting(input);
|
|
34571
|
+
return { ...base, line: `${base.line}; daily ranking unavailable: ${error instanceof Error ? error.message : String(error)}` };
|
|
34370
34572
|
});
|
|
34371
|
-
|
|
34372
|
-
|
|
34573
|
+
attempt = { startedAt: now2(), result };
|
|
34574
|
+
dailyAttempts.set(key, attempt);
|
|
34373
34575
|
}
|
|
34374
|
-
|
|
34576
|
+
if (cached)
|
|
34577
|
+
return { ...dailyDecision(cached, "stale-cache"), refresh: attempt.result };
|
|
34578
|
+
return attempt.result;
|
|
34375
34579
|
}
|
|
34376
34580
|
function withOpenRouterModelRouting(value, pin) {
|
|
34377
34581
|
const root = value && typeof value === "object" && !Array.isArray(value) ? { ...value } : {};
|
|
@@ -34422,7 +34626,7 @@ function openRouterRoutingInput(config, selection, fetchImpl, extra) {
|
|
|
34422
34626
|
openRouterRouting: {
|
|
34423
34627
|
model,
|
|
34424
34628
|
cacheDir: config.openRouterRoutingCacheDir,
|
|
34425
|
-
...apiKey ? { apiKey } : {},
|
|
34629
|
+
...apiKey ? { apiKey, historyRoomsDir: resolve21(config.openRouterRoutingCacheDir, "../rooms") } : {},
|
|
34426
34630
|
...fetchImpl ? { fetchImpl } : {},
|
|
34427
34631
|
...extra?.providerOverride ? { providerOverride: extra.providerOverride } : {},
|
|
34428
34632
|
...extra?.onDecision ? { onDecision: extra.onDecision } : {}
|
|
@@ -34431,9 +34635,9 @@ function openRouterRoutingInput(config, selection, fetchImpl, extra) {
|
|
|
34431
34635
|
}
|
|
34432
34636
|
|
|
34433
34637
|
// apps/body/dist/provider-key-store.js
|
|
34434
|
-
import { chmod as chmod5, mkdir as mkdir15, readFile as
|
|
34638
|
+
import { chmod as chmod5, mkdir as mkdir15, readFile as readFile20, writeFile as writeFile12 } from "node:fs/promises";
|
|
34435
34639
|
import { homedir as homedir11 } from "node:os";
|
|
34436
|
-
import { dirname as dirname16, resolve as
|
|
34640
|
+
import { dirname as dirname16, resolve as resolve22 } from "node:path";
|
|
34437
34641
|
var PROVIDER_KEY_ENV_VARS = {
|
|
34438
34642
|
openrouter: "OPENROUTER_API_KEY",
|
|
34439
34643
|
openai: "OPENAI_API_KEY",
|
|
@@ -34443,12 +34647,12 @@ var PROVIDER_KEY_ENV_VARS = {
|
|
|
34443
34647
|
};
|
|
34444
34648
|
var GOOGLE_ENV_ALIAS = "GEMINI_API_KEY";
|
|
34445
34649
|
function providerKeyStorePath(env = process.env) {
|
|
34446
|
-
const configRoot = env.XDG_CONFIG_HOME?.trim() ||
|
|
34447
|
-
return
|
|
34650
|
+
const configRoot = env.XDG_CONFIG_HOME?.trim() || resolve22(homedir11(), ".config");
|
|
34651
|
+
return resolve22(configRoot, "beeline", "providers.json");
|
|
34448
34652
|
}
|
|
34449
34653
|
async function readProviderKeyStore(env = process.env) {
|
|
34450
34654
|
const path = providerKeyStorePath(env);
|
|
34451
|
-
const raw = await
|
|
34655
|
+
const raw = await readFile20(path, "utf8").catch(() => void 0);
|
|
34452
34656
|
if (!raw)
|
|
34453
34657
|
return {};
|
|
34454
34658
|
try {
|
|
@@ -34822,12 +35026,12 @@ function parseConnectSubscriptions(value) {
|
|
|
34822
35026
|
];
|
|
34823
35027
|
}
|
|
34824
35028
|
async function readMachineId(env = process.env) {
|
|
34825
|
-
const configDir =
|
|
34826
|
-
const machineIdPath =
|
|
35029
|
+
const configDir = resolve23(env.XDG_CONFIG_HOME ?? resolve23(homedir12(), ".config"), "beeline");
|
|
35030
|
+
const machineIdPath = resolve23(configDir, "machine-id");
|
|
34827
35031
|
let machineId;
|
|
34828
35032
|
let machineName = hostname();
|
|
34829
35033
|
try {
|
|
34830
|
-
const existing = await
|
|
35034
|
+
const existing = await readFile21(machineIdPath, "utf8");
|
|
34831
35035
|
machineId = existing.trim();
|
|
34832
35036
|
if (!/^[0-9a-f-]{32,}$/.test(machineId))
|
|
34833
35037
|
throw new Error("invalid persisted machine id");
|
|
@@ -34896,7 +35100,7 @@ async function installCurrentRelease(fetchImpl) {
|
|
|
34896
35100
|
});
|
|
34897
35101
|
await activateRelease(layout, releaseId);
|
|
34898
35102
|
return {
|
|
34899
|
-
binary:
|
|
35103
|
+
binary: resolve23(layout.binDir, "beeline"),
|
|
34900
35104
|
version: published.version ?? releaseId
|
|
34901
35105
|
};
|
|
34902
35106
|
}
|
|
@@ -34928,7 +35132,7 @@ async function writeProviderEnv(selection, agentPubkey) {
|
|
|
34928
35132
|
const values = providerEnvironment(selection);
|
|
34929
35133
|
if (Object.keys(values).length === 0)
|
|
34930
35134
|
return void 0;
|
|
34931
|
-
const path =
|
|
35135
|
+
const path = resolve23(defaultSupervisorRoot(process.env), "beeline", "connect", `${agentPubkey}.env`);
|
|
34932
35136
|
await mkdir16(dirname17(path), { recursive: true, mode: 448 });
|
|
34933
35137
|
const contents = Object.entries(values).map(([key, value]) => `${key}=${JSON.stringify(value)}`).join("\n");
|
|
34934
35138
|
await writeFile13(path, `${contents}
|
|
@@ -34998,7 +35202,7 @@ async function runConnectWizard(code, fetchImpl, eventSubscriptions, accessPolic
|
|
|
34998
35202
|
await finishConnectedAgentPairing(baseUrl, pairingCode, grant.workspace_joined, eventSubscriptions, fetchImpl);
|
|
34999
35203
|
const installedRelease = await brassSpinner("Installing the Beeline daemon\u2026", () => installCurrentRelease(fetchImpl), (release) => `Installed Beeline helper ${release.version}`);
|
|
35000
35204
|
const llmEnvFile = await writeProviderEnv(selection, grant.agent_pubkey);
|
|
35001
|
-
const grantPath =
|
|
35205
|
+
const grantPath = resolve23(defaultSupervisorRoot(process.env), "beeline", "connect", `grant-${process.pid}-${Date.now()}.json`);
|
|
35002
35206
|
await writePrivateJson(grantPath, {
|
|
35003
35207
|
agentSecretKey: grant.agent_secret_key,
|
|
35004
35208
|
bodySecretKey: grant.body_secret_key,
|
|
@@ -35083,12 +35287,12 @@ async function runConnectFinishCommand(path) {
|
|
|
35083
35287
|
throw new Error("connect-finish may run only from the canonical installed Beeline launcher");
|
|
35084
35288
|
}
|
|
35085
35289
|
try {
|
|
35086
|
-
const grant = JSON.parse(await
|
|
35290
|
+
const grant = JSON.parse(await readFile21(resolve23(path), "utf8"));
|
|
35087
35291
|
if (!isDevicePairingGrant(grant))
|
|
35088
35292
|
throw new Error("device connection grant is invalid");
|
|
35089
35293
|
const connected = await completeDevicePairing(grant);
|
|
35090
|
-
await unlink5(
|
|
35091
|
-
const providerEnv = grant.llmEnvFile ? await
|
|
35294
|
+
await unlink5(resolve23(path));
|
|
35295
|
+
const providerEnv = grant.llmEnvFile ? await readFile21(grant.llmEnvFile, "utf8").catch(() => "") : "";
|
|
35092
35296
|
const apiKey = (/^OPENROUTER_API_KEY=(\S+)/m.exec(providerEnv)?.[1] ?? "").replace(/^["']|["']$/g, "");
|
|
35093
35297
|
const model = openRouterModelId(grant.model, { OPENROUTER_API_KEY: apiKey });
|
|
35094
35298
|
if (model) {
|
|
@@ -35114,11 +35318,11 @@ init_self_update();
|
|
|
35114
35318
|
// apps/body/dist/machine-helper.js
|
|
35115
35319
|
import { mkdir as mkdir30, rename as rename14, stat as stat12, writeFile as writeFile23 } from "node:fs/promises";
|
|
35116
35320
|
import { homedir as homedir19 } from "node:os";
|
|
35117
|
-
import { dirname as dirname31, resolve as
|
|
35321
|
+
import { dirname as dirname31, resolve as resolve50 } from "node:path";
|
|
35118
35322
|
|
|
35119
35323
|
// apps/body/dist/agent-runtime.js
|
|
35120
35324
|
import { homedir as homedir18 } from "node:os";
|
|
35121
|
-
import { dirname as dirname30, join as join22, resolve as
|
|
35325
|
+
import { dirname as dirname30, join as join22, resolve as resolve48 } from "node:path";
|
|
35122
35326
|
|
|
35123
35327
|
// apps/body/dist/model-availability.js
|
|
35124
35328
|
var SECRET_VALUE = /(?:token|key|secret|password)=?[^\s,;]*/gi;
|
|
@@ -35180,8 +35384,8 @@ async function applyRuntimeModelPreflight(config, agent, selection, validate = v
|
|
|
35180
35384
|
|
|
35181
35385
|
// apps/body/dist/model-catalog-sync.js
|
|
35182
35386
|
import { createHash as createHash10 } from "node:crypto";
|
|
35183
|
-
import { readFile as
|
|
35184
|
-
import { resolve as
|
|
35387
|
+
import { readFile as readFile22, writeFile as writeFile14 } from "node:fs/promises";
|
|
35388
|
+
import { resolve as resolve24 } from "node:path";
|
|
35185
35389
|
var MODEL_CATALOG_PROBE_TIMEOUT_MS = 3e4;
|
|
35186
35390
|
var MODEL_CATALOG_HASH_FILE = "model-catalog.sha256";
|
|
35187
35391
|
function modelCatalogHash(options, selection, startupUnavailable) {
|
|
@@ -35206,7 +35410,7 @@ async function withTimeout(work, timeoutMs, what) {
|
|
|
35206
35410
|
async function syncAgentModelCatalog(input) {
|
|
35207
35411
|
const log2 = input.log ?? ((line) => console.log(line));
|
|
35208
35412
|
const fetchCatalog = input.fetchCatalog ?? fetchAgentModelCatalog;
|
|
35209
|
-
const hashPath =
|
|
35413
|
+
const hashPath = resolve24(input.runtimeDir, MODEL_CATALOG_HASH_FILE);
|
|
35210
35414
|
try {
|
|
35211
35415
|
const configuration = await input.api.execute("getAgentConfiguration", {
|
|
35212
35416
|
agentId: input.agentId
|
|
@@ -35218,7 +35422,7 @@ async function syncAgentModelCatalog(input) {
|
|
|
35218
35422
|
const { catalog } = await withTimeout(fetchCatalog(input.agent, input.agentEnv, input.startupUnavailable ? void 0 : selection), input.timeoutMs ?? MODEL_CATALOG_PROBE_TIMEOUT_MS, "model catalog probe");
|
|
35219
35423
|
const effectiveCatalog = input.startupUnavailable ? catalog : withEffectiveCurrentValues(catalog, selection);
|
|
35220
35424
|
const hash = modelCatalogHash(effectiveCatalog, selection, input.startupUnavailable);
|
|
35221
|
-
const previous = await
|
|
35425
|
+
const previous = await readFile22(hashPath, "utf8").catch(() => "");
|
|
35222
35426
|
if (!input.force && previous.trim() === hash)
|
|
35223
35427
|
return "unchanged";
|
|
35224
35428
|
await input.api.execute("postAgentModelCatalog", {
|
|
@@ -35252,10 +35456,10 @@ var LOGIN_URL = /https:\/\/login\.tailscale\.com\/[A-Za-z0-9_/-]+/u;
|
|
|
35252
35456
|
function clipped(value) {
|
|
35253
35457
|
return value.length <= OUTPUT_LIMIT ? value : value.slice(value.length - OUTPUT_LIMIT);
|
|
35254
35458
|
}
|
|
35255
|
-
var runTailscaleCommand = (command, args) => new Promise((
|
|
35459
|
+
var runTailscaleCommand = (command, args) => new Promise((resolve53) => {
|
|
35256
35460
|
execFile9(command, [...args], { timeout: COMMAND_TIMEOUT_MS, maxBuffer: OUTPUT_LIMIT * 2 }, (error, stdout6, stderr) => {
|
|
35257
35461
|
const code = error && "code" in error && typeof error.code === "number" ? error.code : error ? null : 0;
|
|
35258
|
-
|
|
35462
|
+
resolve53({ code, stdout: clipped(stdout6), stderr: clipped(stderr) });
|
|
35259
35463
|
});
|
|
35260
35464
|
});
|
|
35261
35465
|
function loginUrlFrom(status, output) {
|
|
@@ -36027,8 +36231,8 @@ import { dirname as dirname18 } from "node:path";
|
|
|
36027
36231
|
// apps/body/dist/browser-share.js
|
|
36028
36232
|
var shares = /* @__PURE__ */ new Map();
|
|
36029
36233
|
function opened(socket) {
|
|
36030
|
-
return new Promise((
|
|
36031
|
-
socket.once("open",
|
|
36234
|
+
return new Promise((resolve53, reject) => {
|
|
36235
|
+
socket.once("open", resolve53);
|
|
36032
36236
|
socket.once("error", reject);
|
|
36033
36237
|
});
|
|
36034
36238
|
}
|
|
@@ -36204,18 +36408,18 @@ var BrowserShareHost = class {
|
|
|
36204
36408
|
})().catch((error) => socket.end(JSON.stringify({ error: error instanceof Error ? error.message : String(error) })));
|
|
36205
36409
|
});
|
|
36206
36410
|
});
|
|
36207
|
-
await new Promise((
|
|
36411
|
+
await new Promise((resolve53, reject) => {
|
|
36208
36412
|
this.server.once("error", reject);
|
|
36209
36413
|
this.server.listen(this.socketPath, () => {
|
|
36210
36414
|
this.server.off("error", reject);
|
|
36211
|
-
|
|
36415
|
+
resolve53();
|
|
36212
36416
|
});
|
|
36213
36417
|
});
|
|
36214
36418
|
chmodSync2(this.socketPath, 384);
|
|
36215
36419
|
}
|
|
36216
36420
|
async stop() {
|
|
36217
36421
|
if (this.server)
|
|
36218
|
-
await new Promise((
|
|
36422
|
+
await new Promise((resolve53) => this.server.close(() => resolve53()));
|
|
36219
36423
|
this.server = void 0;
|
|
36220
36424
|
rmSync3(this.socketPath, { force: true });
|
|
36221
36425
|
}
|
|
@@ -36225,16 +36429,16 @@ var BrowserShareHost = class {
|
|
|
36225
36429
|
import { execFile as execFile19 } from "node:child_process";
|
|
36226
36430
|
import { createHash as createHash17 } from "node:crypto";
|
|
36227
36431
|
import { existsSync as existsSync10, mkdirSync as mkdirSync4 } from "node:fs";
|
|
36228
|
-
import { lstat as
|
|
36229
|
-
import { dirname as dirname28, relative as relative4, resolve as
|
|
36432
|
+
import { lstat as lstat10, mkdir as mkdir28, readdir as readdir14, realpath as realpath4, rm as rm20 } from "node:fs/promises";
|
|
36433
|
+
import { dirname as dirname28, relative as relative4, resolve as resolve43, sep as sep4 } from "node:path";
|
|
36230
36434
|
import { promisify as promisify13 } from "node:util";
|
|
36231
36435
|
|
|
36232
36436
|
// apps/body/dist/grant-runner.js
|
|
36233
36437
|
import { execFile as execFile11 } from "node:child_process";
|
|
36234
36438
|
import { createHash as createHash11, randomBytes as randomBytes9, randomUUID as randomUUID11 } from "node:crypto";
|
|
36235
|
-
import { chmod as chmod7, mkdir as mkdir17, readFile as
|
|
36439
|
+
import { chmod as chmod7, mkdir as mkdir17, readFile as readFile23, readdir as readdir7, rename as rename9, rm as rm13, rmdir, stat as stat9, writeFile as writeFile15 } from "node:fs/promises";
|
|
36236
36440
|
import { createServer as createServer4 } from "node:http";
|
|
36237
|
-
import { dirname as dirname20, resolve as
|
|
36441
|
+
import { dirname as dirname20, resolve as resolve26 } from "node:path";
|
|
36238
36442
|
|
|
36239
36443
|
// packages/api-contract/dist/surface-capabilities.js
|
|
36240
36444
|
var SURFACE_CAPABILITY_TABLE = {
|
|
@@ -36265,7 +36469,7 @@ function surfaceAllows(surface, capability) {
|
|
|
36265
36469
|
import { execFile as execFile10, spawnSync } from "node:child_process";
|
|
36266
36470
|
import { lstatSync as lstatSync3, readdirSync as readdirSync3, readFileSync as readFileSync8, rmSync as rmSync4, writeFileSync as writeFileSync3 } from "node:fs";
|
|
36267
36471
|
import { homedir as homedir13 } from "node:os";
|
|
36268
|
-
import { basename as basename7, dirname as dirname19, isAbsolute as isAbsolute3, relative, resolve as
|
|
36472
|
+
import { basename as basename7, dirname as dirname19, isAbsolute as isAbsolute3, relative, resolve as resolve25, sep } from "node:path";
|
|
36269
36473
|
var DEFAULT_SANDBOX_POLICY = "bwrap";
|
|
36270
36474
|
function isSandboxPolicy(value) {
|
|
36271
36475
|
return value === "bwrap" || value === "off";
|
|
@@ -36310,7 +36514,7 @@ function harnessHomeStateDirs(agentCommand, home = homedir13()) {
|
|
|
36310
36514
|
return [];
|
|
36311
36515
|
for (const { match, dirs } of HARNESS_HOME_STATE_DIRS) {
|
|
36312
36516
|
if (match.test(agentCommand))
|
|
36313
|
-
return dirs.map((dir) =>
|
|
36517
|
+
return dirs.map((dir) => resolve25(home, dir));
|
|
36314
36518
|
}
|
|
36315
36519
|
return [];
|
|
36316
36520
|
}
|
|
@@ -36330,10 +36534,10 @@ function credentialMaskPaths(extraPaths, home = homedir13(), stat14 = (path) =>
|
|
|
36330
36534
|
return void 0;
|
|
36331
36535
|
}
|
|
36332
36536
|
}, requiredPaths = []) {
|
|
36333
|
-
const required = new Set(requiredPaths.map((path) =>
|
|
36537
|
+
const required = new Set(requiredPaths.map((path) => resolve25(path)));
|
|
36334
36538
|
const candidates = [
|
|
36335
|
-
...KNOWN_CREDENTIAL_MASK_PATHS.map((entry) =>
|
|
36336
|
-
...(extraPaths ?? []).map((entry) =>
|
|
36539
|
+
...KNOWN_CREDENTIAL_MASK_PATHS.map((entry) => resolve25(home, entry)),
|
|
36540
|
+
...(extraPaths ?? []).map((entry) => resolve25(entry))
|
|
36337
36541
|
];
|
|
36338
36542
|
const seen = /* @__PURE__ */ new Set();
|
|
36339
36543
|
const masks = [];
|
|
@@ -36358,10 +36562,10 @@ function siblingAgentMaskPaths(ownRuntimeDir, listAgentDirs = (agentsRoot) => {
|
|
|
36358
36562
|
return [];
|
|
36359
36563
|
}
|
|
36360
36564
|
}) {
|
|
36361
|
-
const own =
|
|
36565
|
+
const own = resolve25(ownRuntimeDir);
|
|
36362
36566
|
const agentsRoot = dirname19(own);
|
|
36363
36567
|
const ownName = basename7(own).toLowerCase();
|
|
36364
|
-
return listAgentDirs(agentsRoot).filter((name) => name.toLowerCase() !== ownName).map((name) => ({ path:
|
|
36568
|
+
return listAgentDirs(agentsRoot).filter((name) => name.toLowerCase() !== ownName).map((name) => ({ path: resolve25(agentsRoot, name), kind: "dir" })).sort((a2, b) => a2.path.localeCompare(b.path));
|
|
36365
36569
|
}
|
|
36366
36570
|
var DEFAULT_SANDBOX_DEVICES = ["/dev/kvm"];
|
|
36367
36571
|
function grantedSandboxDevices(result) {
|
|
@@ -36391,7 +36595,7 @@ function sandboxDevicePath(target) {
|
|
|
36391
36595
|
const trimmed = target.trim();
|
|
36392
36596
|
if (!isAbsolute3(trimmed))
|
|
36393
36597
|
return void 0;
|
|
36394
|
-
const path =
|
|
36598
|
+
const path = resolve25(trimmed);
|
|
36395
36599
|
return path.startsWith("/dev/") ? path : void 0;
|
|
36396
36600
|
}
|
|
36397
36601
|
function isUnderTmp(path) {
|
|
@@ -36403,7 +36607,7 @@ function normalize(paths) {
|
|
|
36403
36607
|
for (const path of paths) {
|
|
36404
36608
|
if (!path)
|
|
36405
36609
|
continue;
|
|
36406
|
-
seen.add(
|
|
36610
|
+
seen.add(resolve25(path));
|
|
36407
36611
|
}
|
|
36408
36612
|
return Array.from(seen).sort();
|
|
36409
36613
|
}
|
|
@@ -36440,14 +36644,14 @@ function sandboxMountPlan(spec) {
|
|
|
36440
36644
|
const requiredMounts = [];
|
|
36441
36645
|
const boundaryMasks = [];
|
|
36442
36646
|
if (shared) {
|
|
36443
|
-
const assetRoot =
|
|
36444
|
-
const agentsRoot = dirname19(
|
|
36647
|
+
const assetRoot = resolve25(shared.assetRoot);
|
|
36648
|
+
const agentsRoot = dirname19(resolve25(shared.agentRuntimeDir));
|
|
36445
36649
|
const workspacesRoot = dirname19(dirname19(assetRoot));
|
|
36446
36650
|
boundaryMasks.push({ path: workspacesRoot, kind: "dir" }, { path: agentsRoot, kind: "dir" });
|
|
36447
36651
|
const add = (path, mode, target = path) => {
|
|
36448
|
-
requiredMounts.push({ source:
|
|
36652
|
+
requiredMounts.push({ source: resolve25(path), target: resolve25(target), mode });
|
|
36449
36653
|
};
|
|
36450
|
-
const cwd =
|
|
36654
|
+
const cwd = resolve25(spec.cwd);
|
|
36451
36655
|
const relativeCwd = relative(agentsRoot, cwd);
|
|
36452
36656
|
if (relativeCwd === "" || relativeCwd !== ".." && !relativeCwd.startsWith(`..${sep}`) && !isAbsolute3(relativeCwd))
|
|
36453
36657
|
add(cwd, spec.mode === "edit" ? "bind" : "ro-bind");
|
|
@@ -36456,34 +36660,34 @@ function sandboxMountPlan(spec) {
|
|
|
36456
36660
|
add(shared.privateRoot, "bind");
|
|
36457
36661
|
if (shared.privateAssetRoot && shared.isolatedCategories?.length)
|
|
36458
36662
|
add(shared.privateAssetRoot, "bind");
|
|
36459
|
-
add(
|
|
36663
|
+
add(resolve25(shared.agentRuntimeDir, "runtime.json"), "ro-bind");
|
|
36460
36664
|
for (const path of spec.additionalWritablePaths ?? []) {
|
|
36461
|
-
const rel = relative(cwd,
|
|
36665
|
+
const rel = relative(cwd, resolve25(path));
|
|
36462
36666
|
if (rel && rel !== ".." && !rel.startsWith(`..${sep}`) && !isAbsolute3(rel))
|
|
36463
36667
|
add(path, "bind");
|
|
36464
36668
|
}
|
|
36465
|
-
add(
|
|
36466
|
-
const source = (category, suffix) => shared.privateAssetRoot && shared.isolatedCategories?.includes(category) ?
|
|
36669
|
+
add(resolve25(assetRoot, "cache"), "bind");
|
|
36670
|
+
const source = (category, suffix) => shared.privateAssetRoot && shared.isolatedCategories?.includes(category) ? resolve25(shared.privateAssetRoot, suffix) : resolve25(assetRoot, suffix);
|
|
36467
36671
|
if (shared.privateAssetRoot) {
|
|
36468
36672
|
for (const suffix of shared.isolatedCategories?.includes("package-cache") ? PACKAGE_CACHE_DIRS : [])
|
|
36469
|
-
add(
|
|
36673
|
+
add(resolve25(shared.privateAssetRoot, "cache", suffix), "bind", resolve25(assetRoot, "cache", suffix));
|
|
36470
36674
|
for (const [category, suffix] of [
|
|
36471
36675
|
["codex-download-cache", "cache/codex/download"],
|
|
36472
36676
|
["codex-plugin-cache", "cache/codex/plugins"]
|
|
36473
36677
|
]) {
|
|
36474
36678
|
if (shared.isolatedCategories?.includes(category))
|
|
36475
|
-
add(
|
|
36679
|
+
add(resolve25(shared.privateAssetRoot, suffix), "bind", resolve25(assetRoot, suffix));
|
|
36476
36680
|
}
|
|
36477
36681
|
}
|
|
36478
36682
|
if (shared.codexHome) {
|
|
36479
|
-
add(source("codex-download-cache", "cache/codex/download"), "bind",
|
|
36480
|
-
add(source("codex-plugin-cache", "cache/codex/plugins"), "bind",
|
|
36683
|
+
add(source("codex-download-cache", "cache/codex/download"), "bind", resolve25(shared.codexHome, "cache"));
|
|
36684
|
+
add(source("codex-plugin-cache", "cache/codex/plugins"), "bind", resolve25(shared.codexHome, "plugins/cache"));
|
|
36481
36685
|
}
|
|
36482
36686
|
if (shared.packageHome) {
|
|
36483
|
-
add(source("package-cache", "cache/cargo/registry"), "bind",
|
|
36687
|
+
add(source("package-cache", "cache/cargo/registry"), "bind", resolve25(shared.packageHome, ".cargo/registry"));
|
|
36484
36688
|
}
|
|
36485
36689
|
for (const name of ["tools", "avd-base"])
|
|
36486
|
-
add(
|
|
36690
|
+
add(resolve25(assetRoot, name), "ro-bind");
|
|
36487
36691
|
}
|
|
36488
36692
|
return {
|
|
36489
36693
|
...spec.mode === "edit" ? { rootWritable: true } : {},
|
|
@@ -36491,7 +36695,7 @@ function sandboxMountPlan(spec) {
|
|
|
36491
36695
|
writable,
|
|
36492
36696
|
quotaTmpfs: spec.workbench ? [
|
|
36493
36697
|
{
|
|
36494
|
-
target:
|
|
36698
|
+
target: resolve25(spec.workbench.dir),
|
|
36495
36699
|
maxBytes: spec.workbench.maxBytes,
|
|
36496
36700
|
maxInodes: spec.workbench.maxInodes,
|
|
36497
36701
|
blockGit: true
|
|
@@ -36555,7 +36759,7 @@ function buildBwrapArgv(input) {
|
|
|
36555
36759
|
for (const binding of quotaTmpfs) {
|
|
36556
36760
|
args.push("--dir", binding.target, "--size", String(binding.maxBytes), "--tmpfs", binding.target);
|
|
36557
36761
|
if (binding.blockGit)
|
|
36558
|
-
args.push("--ro-bind", "/dev/null",
|
|
36762
|
+
args.push("--ro-bind", "/dev/null", resolve25(binding.target, ".git"));
|
|
36559
36763
|
}
|
|
36560
36764
|
args.push("--chdir", input.cwd);
|
|
36561
36765
|
args.push("--die-with-parent");
|
|
@@ -36627,7 +36831,7 @@ var INSTALL_RETRY_AFTER_HOURS = 24;
|
|
|
36627
36831
|
var INSTALL_RETRY_AFTER_MS = INSTALL_RETRY_AFTER_HOURS * 60 * 6e4;
|
|
36628
36832
|
var INSTALL_FAILURE_MARKER = "bubblewrap-install-failed";
|
|
36629
36833
|
function installFailureMarker(stateDir) {
|
|
36630
|
-
return
|
|
36834
|
+
return resolve25(stateDir, INSTALL_FAILURE_MARKER);
|
|
36631
36835
|
}
|
|
36632
36836
|
function readInstallFailure(stateDir) {
|
|
36633
36837
|
if (!stateDir)
|
|
@@ -36656,7 +36860,7 @@ function clearInstallFailure(stateDir) {
|
|
|
36656
36860
|
} catch {
|
|
36657
36861
|
}
|
|
36658
36862
|
}
|
|
36659
|
-
var runSandboxInstallCommand = (command, args) => new Promise((
|
|
36863
|
+
var runSandboxInstallCommand = (command, args) => new Promise((resolve53) => {
|
|
36660
36864
|
execFile10(command, [...args], {
|
|
36661
36865
|
timeout: INSTALL_TIMEOUT_MS,
|
|
36662
36866
|
maxBuffer: INSTALL_OUTPUT_LIMIT * 2,
|
|
@@ -36666,7 +36870,7 @@ var runSandboxInstallCommand = (command, args) => new Promise((resolve52) => {
|
|
|
36666
36870
|
}, (error, stdout6, stderr) => {
|
|
36667
36871
|
const code = error && "code" in error && typeof error.code === "number" ? error.code : error ? null : 0;
|
|
36668
36872
|
const output = [stdout6, stderr].join("").trim();
|
|
36669
|
-
|
|
36873
|
+
resolve53({ code, output: output || (error ? error.message : "") });
|
|
36670
36874
|
});
|
|
36671
36875
|
});
|
|
36672
36876
|
function lastLine2(output, fallback) {
|
|
@@ -36775,10 +36979,10 @@ var SANDBOX_STARTED_SCRIPT = ['printf "%s\\n" "$1" >&2', "shift", 'exec "$@"'].j
|
|
|
36775
36979
|
var ROOM_SANDBOX_UNAVAILABLE = "this Room cannot run granted commands: a Room promises a read-only filesystem and that promise is enforced by bubblewrap, which is not usable on this host. Open a corner with open_corner and run it there, where writes belong.";
|
|
36776
36980
|
var ROOM_WRITE_REFUSED_NOTE = "[beeline] the Room filesystem is read-only outside your scratch directory, so this write was refused by the kernel. Open a corner with open_corner to change files.";
|
|
36777
36981
|
function operatorSecretsPath(env = process.env) {
|
|
36778
|
-
return
|
|
36982
|
+
return resolve26(dirname20(providerKeyStorePath(env)), "secrets.json");
|
|
36779
36983
|
}
|
|
36780
36984
|
async function readOperatorSecrets(env = process.env) {
|
|
36781
|
-
const raw = await
|
|
36985
|
+
const raw = await readFile23(operatorSecretsPath(env), "utf8").catch(() => void 0);
|
|
36782
36986
|
if (!raw)
|
|
36783
36987
|
return {};
|
|
36784
36988
|
try {
|
|
@@ -36991,7 +37195,7 @@ ${ROOM_WRITE_REFUSED_NOTE}` : outcome.output, secrets), cap);
|
|
|
36991
37195
|
return;
|
|
36992
37196
|
let bytes;
|
|
36993
37197
|
for (const candidate of candidates) {
|
|
36994
|
-
bytes = await
|
|
37198
|
+
bytes = await readFile23(candidate).catch(() => void 0);
|
|
36995
37199
|
if (bytes)
|
|
36996
37200
|
break;
|
|
36997
37201
|
}
|
|
@@ -37011,8 +37215,8 @@ function scriptCandidates(cwd, scratch, argv) {
|
|
|
37011
37215
|
if (!argument)
|
|
37012
37216
|
return [];
|
|
37013
37217
|
const paths = [
|
|
37014
|
-
|
|
37015
|
-
...scratch ? [
|
|
37218
|
+
resolve26(cwd, argument.path),
|
|
37219
|
+
...scratch ? [resolve26(scratch, argument.path)] : []
|
|
37016
37220
|
];
|
|
37017
37221
|
return [...new Set(paths)];
|
|
37018
37222
|
}
|
|
@@ -37194,13 +37398,13 @@ function captureConnectionUsage(recorder, turn, calls) {
|
|
|
37194
37398
|
}
|
|
37195
37399
|
|
|
37196
37400
|
// apps/body/dist/model-context-window.js
|
|
37197
|
-
import { readFile as
|
|
37401
|
+
import { readFile as readFile24 } from "node:fs/promises";
|
|
37198
37402
|
import { join as join12 } from "node:path";
|
|
37199
37403
|
async function modelContextWindowTokens(model, piHome) {
|
|
37200
37404
|
if (!model || !piHome)
|
|
37201
37405
|
return void 0;
|
|
37202
37406
|
try {
|
|
37203
|
-
const catalog = JSON.parse(await
|
|
37407
|
+
const catalog = JSON.parse(await readFile24(join12(piHome, "models.json"), "utf8"));
|
|
37204
37408
|
const parts = model.split("/");
|
|
37205
37409
|
const preferredProvider = parts.length > 2 ? parts.shift() : void 0;
|
|
37206
37410
|
const modelId = parts.join("/");
|
|
@@ -37216,11 +37420,11 @@ async function modelContextWindowTokens(model, piHome) {
|
|
|
37216
37420
|
}
|
|
37217
37421
|
|
|
37218
37422
|
// apps/body/dist/turn-usage.js
|
|
37219
|
-
import { readFile as
|
|
37423
|
+
import { readFile as readFile26 } from "node:fs/promises";
|
|
37220
37424
|
|
|
37221
37425
|
// apps/body/dist/pi-turn-record.js
|
|
37222
|
-
import { readdir as
|
|
37223
|
-
import { resolve as
|
|
37426
|
+
import { readdir as readdir8, readFile as readFile25 } from "node:fs/promises";
|
|
37427
|
+
import { resolve as resolve27 } from "node:path";
|
|
37224
37428
|
function summarizeProviderError(errorMessage2) {
|
|
37225
37429
|
const trimmed = errorMessage2.trim();
|
|
37226
37430
|
const statusMatch = /^(\d{3}):\s*([\s\S]*)$/.exec(trimmed);
|
|
@@ -37247,7 +37451,7 @@ async function piSessionFilePath(agentEnv, sessionId) {
|
|
|
37247
37451
|
}
|
|
37248
37452
|
async function sessionFileFromMap(home, sessionId) {
|
|
37249
37453
|
try {
|
|
37250
|
-
const raw = await
|
|
37454
|
+
const raw = await readFile25(resolve27(home, ".pi", "pi-acp", "session-map.json"), "utf8");
|
|
37251
37455
|
const map = JSON.parse(raw);
|
|
37252
37456
|
const file = map.sessions?.[sessionId]?.sessionFile;
|
|
37253
37457
|
return typeof file === "string" && file ? file : void 0;
|
|
@@ -37256,25 +37460,25 @@ async function sessionFileFromMap(home, sessionId) {
|
|
|
37256
37460
|
}
|
|
37257
37461
|
}
|
|
37258
37462
|
async function sessionFileFromLayout(piDir, sessionId) {
|
|
37259
|
-
const sessionsRoot =
|
|
37463
|
+
const sessionsRoot = resolve27(piDir, "sessions");
|
|
37260
37464
|
const suffix = `_${sessionId}.jsonl`;
|
|
37261
37465
|
let projects;
|
|
37262
37466
|
try {
|
|
37263
|
-
projects = await
|
|
37467
|
+
projects = await readdir8(sessionsRoot);
|
|
37264
37468
|
} catch {
|
|
37265
37469
|
return void 0;
|
|
37266
37470
|
}
|
|
37267
37471
|
for (const project of projects) {
|
|
37268
|
-
const dir =
|
|
37472
|
+
const dir = resolve27(sessionsRoot, project);
|
|
37269
37473
|
let files;
|
|
37270
37474
|
try {
|
|
37271
|
-
files = await
|
|
37475
|
+
files = await readdir8(dir);
|
|
37272
37476
|
} catch {
|
|
37273
37477
|
continue;
|
|
37274
37478
|
}
|
|
37275
37479
|
const match = files.find((file) => file.endsWith(suffix));
|
|
37276
37480
|
if (match)
|
|
37277
|
-
return
|
|
37481
|
+
return resolve27(dir, match);
|
|
37278
37482
|
}
|
|
37279
37483
|
return void 0;
|
|
37280
37484
|
}
|
|
@@ -37289,7 +37493,7 @@ async function readPiTurnRecord(input) {
|
|
|
37289
37493
|
return void 0;
|
|
37290
37494
|
let raw;
|
|
37291
37495
|
try {
|
|
37292
|
-
raw = await
|
|
37496
|
+
raw = await readFile25(file, "utf8");
|
|
37293
37497
|
} catch {
|
|
37294
37498
|
return void 0;
|
|
37295
37499
|
}
|
|
@@ -37348,7 +37552,7 @@ async function readUsageCalls(input, latestTurn) {
|
|
|
37348
37552
|
const file = await piSessionFilePath(input.agentEnv, input.sessionId);
|
|
37349
37553
|
if (!file)
|
|
37350
37554
|
return latestTurn ? void 0 : [];
|
|
37351
|
-
const raw = await
|
|
37555
|
+
const raw = await readFile26(file, "utf8").catch(() => void 0);
|
|
37352
37556
|
if (raw === void 0)
|
|
37353
37557
|
return void 0;
|
|
37354
37558
|
const calls = [];
|
|
@@ -37576,11 +37780,11 @@ async function runServerCommandIntake(options) {
|
|
|
37576
37780
|
if (attempt === 3)
|
|
37577
37781
|
throw error;
|
|
37578
37782
|
const waitMs = Math.max(250 * 2 ** attempt, error instanceof DaemonApiError ? error.retryAfterMs ?? 0 : 0);
|
|
37579
|
-
await new Promise((
|
|
37783
|
+
await new Promise((resolve53) => {
|
|
37580
37784
|
const done = () => {
|
|
37581
37785
|
clearTimeout(timer);
|
|
37582
37786
|
signal?.removeEventListener("abort", done);
|
|
37583
|
-
|
|
37787
|
+
resolve53();
|
|
37584
37788
|
};
|
|
37585
37789
|
const timer = setTimeout(done, waitMs);
|
|
37586
37790
|
signal?.addEventListener("abort", done, { once: true });
|
|
@@ -37682,11 +37886,11 @@ async function runServerCommandIntake(options) {
|
|
|
37682
37886
|
}
|
|
37683
37887
|
}
|
|
37684
37888
|
options.onPoll?.();
|
|
37685
|
-
const reconcile = await new Promise((
|
|
37889
|
+
const reconcile = await new Promise((resolve53) => {
|
|
37686
37890
|
const done = (needed) => {
|
|
37687
37891
|
signal?.removeEventListener("abort", aborted);
|
|
37688
37892
|
wake = void 0;
|
|
37689
|
-
|
|
37893
|
+
resolve53(needed);
|
|
37690
37894
|
};
|
|
37691
37895
|
const aborted = () => done(false);
|
|
37692
37896
|
wake = done;
|
|
@@ -37729,9 +37933,9 @@ async function runServerCommandIntake(options) {
|
|
|
37729
37933
|
import { execFile as execFile17 } from "node:child_process";
|
|
37730
37934
|
import { createHash as createHash16 } from "node:crypto";
|
|
37731
37935
|
import { existsSync as existsSync9 } from "node:fs";
|
|
37732
|
-
import { mkdir as mkdir27, readFile as
|
|
37936
|
+
import { mkdir as mkdir27, readFile as readFile33, writeFile as writeFile21 } from "node:fs/promises";
|
|
37733
37937
|
import { homedir as homedir17, hostname as hostname4 } from "node:os";
|
|
37734
|
-
import { dirname as dirname26, join as join20, resolve as
|
|
37938
|
+
import { dirname as dirname26, join as join20, resolve as resolve41 } from "node:path";
|
|
37735
37939
|
import { promisify as promisify11 } from "node:util";
|
|
37736
37940
|
|
|
37737
37941
|
// apps/body/dist/machine-host.js
|
|
@@ -37739,16 +37943,16 @@ import { execFile as execFile12 } from "node:child_process";
|
|
|
37739
37943
|
import { hostname as hostname2 } from "node:os";
|
|
37740
37944
|
async function machineHost() {
|
|
37741
37945
|
const local = hostname2();
|
|
37742
|
-
const tailscaleName = await new Promise((
|
|
37946
|
+
const tailscaleName = await new Promise((resolve53) => {
|
|
37743
37947
|
execFile12("tailscale", ["status", "--json"], { timeout: 1500, maxBuffer: 64 * 1024 }, (error, stdout6) => {
|
|
37744
37948
|
if (error)
|
|
37745
|
-
return
|
|
37949
|
+
return resolve53(void 0);
|
|
37746
37950
|
try {
|
|
37747
37951
|
const status = JSON.parse(stdout6);
|
|
37748
37952
|
const name = status.BackendState === "Running" ? status.Self?.DNSName?.replace(/\.$/, "") : void 0;
|
|
37749
|
-
|
|
37953
|
+
resolve53(name || void 0);
|
|
37750
37954
|
} catch {
|
|
37751
|
-
|
|
37955
|
+
resolve53(void 0);
|
|
37752
37956
|
}
|
|
37753
37957
|
});
|
|
37754
37958
|
});
|
|
@@ -38555,9 +38759,9 @@ function stringify(obj, { maxDepth = 1e3, numbersAsFloat = false } = {}) {
|
|
|
38555
38759
|
|
|
38556
38760
|
// apps/body/dist/agent-home.js
|
|
38557
38761
|
import { createHash as createHash13, randomUUID as randomUUID13 } from "node:crypto";
|
|
38558
|
-
import { chmod as chmod8, copyFile, lstat as
|
|
38762
|
+
import { chmod as chmod8, copyFile, lstat as lstat6, mkdir as mkdir19, readFile as readFile27, readlink, readdir as readdir9, realpath as realpath2, rename as rename10, rm as rm14, symlink as symlink2, unlink as unlink6, writeFile as writeFile17 } from "node:fs/promises";
|
|
38559
38763
|
import { homedir as homedir14 } from "node:os";
|
|
38560
|
-
import { basename as basename8, dirname as dirname22, join as join15, relative as relative2, resolve as
|
|
38764
|
+
import { basename as basename8, dirname as dirname22, join as join15, relative as relative2, resolve as resolve31, sep as sep2 } from "node:path";
|
|
38561
38765
|
|
|
38562
38766
|
// apps/body/dist/draw-avatar-skill.js
|
|
38563
38767
|
var DRAW_AVATAR_SKILL_NAME = "draw-avatar";
|
|
@@ -38647,7 +38851,7 @@ set_avatar renders bounded geometry to durable image bytes and replaces your cur
|
|
|
38647
38851
|
// apps/body/dist/android-agent-env.js
|
|
38648
38852
|
import { createHash as createHash12 } from "node:crypto";
|
|
38649
38853
|
import { existsSync as existsSync7 } from "node:fs";
|
|
38650
|
-
import { delimiter as delimiter2, resolve as
|
|
38854
|
+
import { delimiter as delimiter2, resolve as resolve28 } from "node:path";
|
|
38651
38855
|
var ANDROID_FIRST_EMULATOR_PORT = 5600;
|
|
38652
38856
|
var ANDROID_PORT_SLOTS = 100;
|
|
38653
38857
|
function androidAgentEnv(input) {
|
|
@@ -38655,25 +38859,25 @@ function androidAgentEnv(input) {
|
|
|
38655
38859
|
const sdk = [
|
|
38656
38860
|
env.ANDROID_HOME,
|
|
38657
38861
|
env.ANDROID_SDK_ROOT,
|
|
38658
|
-
|
|
38659
|
-
|
|
38660
|
-
].find((path) => path && existsSync7(
|
|
38862
|
+
resolve28(input.operatorHome, "android-sdk"),
|
|
38863
|
+
resolve28(input.operatorHome, "Android/Sdk")
|
|
38864
|
+
].find((path) => path && existsSync7(resolve28(path, "platform-tools/adb")));
|
|
38661
38865
|
if (!sdk)
|
|
38662
38866
|
return {};
|
|
38663
|
-
const emulatorHome = env.ANDROID_EMULATOR_HOME ??
|
|
38664
|
-
const slot = createHash12("sha256").update(
|
|
38867
|
+
const emulatorHome = env.ANDROID_EMULATOR_HOME ?? resolve28(input.operatorHome, ".android");
|
|
38868
|
+
const slot = createHash12("sha256").update(resolve28(input.root)).digest().readUInt32BE(0) % ANDROID_PORT_SLOTS;
|
|
38665
38869
|
const emulatorPort = ANDROID_FIRST_EMULATOR_PORT + slot * 4;
|
|
38666
38870
|
return {
|
|
38667
38871
|
ANDROID_HOME: sdk,
|
|
38668
38872
|
ANDROID_SDK_ROOT: sdk,
|
|
38669
38873
|
ANDROID_EMULATOR_HOME: emulatorHome,
|
|
38670
|
-
ANDROID_AVD_HOME: env.ANDROID_AVD_HOME ??
|
|
38874
|
+
ANDROID_AVD_HOME: env.ANDROID_AVD_HOME ?? resolve28(emulatorHome, "avd"),
|
|
38671
38875
|
ANDROID_ADB_SERVER_PORT: String(emulatorPort + 2),
|
|
38672
38876
|
ADB_EMU: "0",
|
|
38673
38877
|
BEELINE_ANDROID_EMULATOR_PORT: String(emulatorPort),
|
|
38674
38878
|
PATH: [
|
|
38675
|
-
|
|
38676
|
-
|
|
38879
|
+
resolve28(sdk, "platform-tools"),
|
|
38880
|
+
resolve28(sdk, "emulator"),
|
|
38677
38881
|
input.inheritedPath ?? env.PATH
|
|
38678
38882
|
].filter(Boolean).join(delimiter2)
|
|
38679
38883
|
};
|
|
@@ -38681,7 +38885,7 @@ function androidAgentEnv(input) {
|
|
|
38681
38885
|
|
|
38682
38886
|
// apps/body/dist/beeline-skill.js
|
|
38683
38887
|
import { readFileSync as readFileSync9 } from "node:fs";
|
|
38684
|
-
import { resolve as
|
|
38888
|
+
import { resolve as resolve29 } from "node:path";
|
|
38685
38889
|
var USING_BEELINE_SKILL_NAME = "using-beeline";
|
|
38686
38890
|
var BEELINE_TRIAGE_SKILL_NAME = "beeline-triage";
|
|
38687
38891
|
var BEELINE_REVIEW_SKILL_NAME = "beeline-review";
|
|
@@ -38700,7 +38904,7 @@ function runningBeelineReleaseId(env = process.env, read2 = (path) => readFileSy
|
|
|
38700
38904
|
const lib = env.BEELINE_LIB_DIR;
|
|
38701
38905
|
if (!lib)
|
|
38702
38906
|
return "source";
|
|
38703
|
-
const manifest = JSON.parse(read2(
|
|
38907
|
+
const manifest = JSON.parse(read2(resolve29(lib, "bundle.json")));
|
|
38704
38908
|
return [manifest.version, manifest.commit].filter(Boolean).join("-") || "source";
|
|
38705
38909
|
} catch {
|
|
38706
38910
|
return "source";
|
|
@@ -39061,7 +39265,7 @@ var SQUIRE_GOVERNED_TOOLS = [
|
|
|
39061
39265
|
var SQUIRE_GOVERNED_TOOL_SET = new Set(SQUIRE_GOVERNED_TOOLS);
|
|
39062
39266
|
|
|
39063
39267
|
// apps/body/dist/host-mcp-route.js
|
|
39064
|
-
import { join as join14, resolve as
|
|
39268
|
+
import { join as join14, resolve as resolve30 } from "node:path";
|
|
39065
39269
|
var import_yaml = __toESM(require_dist(), 1);
|
|
39066
39270
|
init_squire_host();
|
|
39067
39271
|
function grantedMcpServerNames(grants) {
|
|
@@ -39116,7 +39320,7 @@ function grantedSquireHostRouteNames(granted, declarations = {}) {
|
|
|
39116
39320
|
});
|
|
39117
39321
|
}
|
|
39118
39322
|
function hostRouteEnv(hostHome) {
|
|
39119
|
-
return { XDG_CONFIG_HOME: join14(
|
|
39323
|
+
return { XDG_CONFIG_HOME: join14(resolve30(hostHome), ".config") };
|
|
39120
39324
|
}
|
|
39121
39325
|
function rewriteHostMcpDeclaration(name, declaration, hostHome, resourceAuthFile, squireScope) {
|
|
39122
39326
|
const next = { ...declaration };
|
|
@@ -39510,7 +39714,7 @@ async function withSharedClaudeLoginLock(shared, write2) {
|
|
|
39510
39714
|
} catch (error) {
|
|
39511
39715
|
if (error.code !== "EEXIST")
|
|
39512
39716
|
throw error;
|
|
39513
|
-
const held = await
|
|
39717
|
+
const held = await lstat6(lock).catch(() => void 0);
|
|
39514
39718
|
if (held && Date.now() - held.mtimeMs > CLAUDE_LOGIN_LOCK_STALE_MS) {
|
|
39515
39719
|
await rm14(lock, { force: true });
|
|
39516
39720
|
continue;
|
|
@@ -39527,13 +39731,13 @@ async function withSharedClaudeLoginLock(shared, write2) {
|
|
|
39527
39731
|
}
|
|
39528
39732
|
}
|
|
39529
39733
|
async function writeBackDetachedClaudeLogin(target, source) {
|
|
39530
|
-
const detached = await
|
|
39734
|
+
const detached = await readFile27(target, "utf8");
|
|
39531
39735
|
const detachedExpiresAt = claudeLoginExpiresAt(detached);
|
|
39532
39736
|
if (detachedExpiresAt === void 0)
|
|
39533
39737
|
return "not-newer";
|
|
39534
39738
|
const shared = await realpath2(source);
|
|
39535
39739
|
const isNewer = async () => {
|
|
39536
|
-
const sharedExpiresAt = claudeLoginExpiresAt(await
|
|
39740
|
+
const sharedExpiresAt = claudeLoginExpiresAt(await readFile27(shared, "utf8"));
|
|
39537
39741
|
return sharedExpiresAt !== void 0 && detachedExpiresAt > sharedExpiresAt;
|
|
39538
39742
|
};
|
|
39539
39743
|
if (!await isNewer())
|
|
@@ -39556,7 +39760,7 @@ async function writeBackDetachedClaudeLogin(target, source) {
|
|
|
39556
39760
|
return "busy";
|
|
39557
39761
|
if (!written)
|
|
39558
39762
|
return "not-newer";
|
|
39559
|
-
if (await
|
|
39763
|
+
if (await readFile27(target, "utf8") !== detached)
|
|
39560
39764
|
return "busy";
|
|
39561
39765
|
const link2 = `${target}.beeline-link-${randomUUID13()}`;
|
|
39562
39766
|
await symlink2(source, link2);
|
|
@@ -39564,22 +39768,22 @@ async function writeBackDetachedClaudeLogin(target, source) {
|
|
|
39564
39768
|
return "linked";
|
|
39565
39769
|
}
|
|
39566
39770
|
async function repairRoomAgentCredentialLinks(input) {
|
|
39567
|
-
const root =
|
|
39771
|
+
const root = resolve31(input.root);
|
|
39568
39772
|
const operatorHome = input.operatorHome ?? homedir14();
|
|
39569
39773
|
for (const credential of SHARED_CREDENTIALS) {
|
|
39570
|
-
const source =
|
|
39774
|
+
const source = resolve31(operatorHome, credential.source);
|
|
39571
39775
|
if (!existsSync8(source))
|
|
39572
39776
|
continue;
|
|
39573
|
-
const target =
|
|
39777
|
+
const target = resolve31(root, credential.dir, credential.target);
|
|
39574
39778
|
await mkdir19(dirname22(target), { recursive: true, mode: 448 });
|
|
39575
|
-
const stats = await
|
|
39779
|
+
const stats = await lstat6(target).catch((error) => {
|
|
39576
39780
|
if (isMissingPathError(error))
|
|
39577
39781
|
return void 0;
|
|
39578
39782
|
throw error;
|
|
39579
39783
|
});
|
|
39580
39784
|
if (stats?.isSymbolicLink()) {
|
|
39581
39785
|
const linked = await readlink(target);
|
|
39582
|
-
if (
|
|
39786
|
+
if (resolve31(dirname22(target), linked) === source)
|
|
39583
39787
|
continue;
|
|
39584
39788
|
}
|
|
39585
39789
|
if (stats) {
|
|
@@ -39596,20 +39800,20 @@ async function repairRoomAgentCredentialLinks(input) {
|
|
|
39596
39800
|
}
|
|
39597
39801
|
async function writeBackRoomClaudeLogin(input) {
|
|
39598
39802
|
const claude = SHARED_CREDENTIALS.find((credential) => credential.dir === "claude");
|
|
39599
|
-
const source =
|
|
39803
|
+
const source = resolve31(input.operatorHome ?? homedir14(), claude.source);
|
|
39600
39804
|
if (!existsSync8(source))
|
|
39601
39805
|
return;
|
|
39602
|
-
const target =
|
|
39603
|
-
const stats = await
|
|
39806
|
+
const target = resolve31(input.root, claude.dir, claude.target);
|
|
39807
|
+
const stats = await lstat6(target).catch(() => void 0);
|
|
39604
39808
|
if (!stats?.isFile())
|
|
39605
39809
|
return;
|
|
39606
39810
|
await writeBackDetachedClaudeLogin(target, source);
|
|
39607
39811
|
}
|
|
39608
39812
|
function watchRoomClaudeLogin(input) {
|
|
39609
39813
|
const claude = SHARED_CREDENTIALS.find((credential) => credential.dir === "claude");
|
|
39610
|
-
if (!existsSync8(
|
|
39814
|
+
if (!existsSync8(resolve31(input.operatorHome ?? homedir14(), claude.source)))
|
|
39611
39815
|
return void 0;
|
|
39612
|
-
const dir =
|
|
39816
|
+
const dir = resolve31(input.root, claude.dir);
|
|
39613
39817
|
let pass = Promise.resolve();
|
|
39614
39818
|
let watcher;
|
|
39615
39819
|
try {
|
|
@@ -39632,23 +39836,23 @@ function watchRoomClaudeLogin(input) {
|
|
|
39632
39836
|
return watcher;
|
|
39633
39837
|
}
|
|
39634
39838
|
async function prepareRoomAgentHome(input) {
|
|
39635
|
-
const root =
|
|
39839
|
+
const root = resolve31(input.root);
|
|
39636
39840
|
const operatorHome = input.operatorHome ?? homedir14();
|
|
39637
39841
|
let tmpLinkReady = false;
|
|
39638
39842
|
try {
|
|
39639
39843
|
await mkdir19(root, { recursive: true, mode: 448 });
|
|
39640
|
-
const rootStats = await
|
|
39844
|
+
const rootStats = await lstat6(root);
|
|
39641
39845
|
if (!rootStats.isDirectory() || rootStats.isSymbolicLink()) {
|
|
39642
39846
|
throw new AgentHomeSecurityError(`agent home root is not an ordinary directory: ${root}`);
|
|
39643
39847
|
}
|
|
39644
39848
|
for (const subdir of HOME_SUBDIRS) {
|
|
39645
|
-
const path =
|
|
39849
|
+
const path = resolve31(root, subdir);
|
|
39646
39850
|
await mkdir19(path, { recursive: true, mode: 448 });
|
|
39647
39851
|
await assertRealContainedDirectory(path, root);
|
|
39648
39852
|
}
|
|
39649
39853
|
try {
|
|
39650
39854
|
const tmpLink = roomSessionTmpDir(root);
|
|
39651
|
-
const tmpTarget =
|
|
39855
|
+
const tmpTarget = resolve31(root, "tmp");
|
|
39652
39856
|
if (await readlink(tmpLink).catch(() => void 0) !== tmpTarget) {
|
|
39653
39857
|
await rm14(tmpLink, { recursive: true, force: true });
|
|
39654
39858
|
await symlink2(tmpTarget, tmpLink);
|
|
@@ -39683,7 +39887,7 @@ async function prepareRoomAgentHome(input) {
|
|
|
39683
39887
|
if (agentHomeProvisionQueues.get(root) === provision)
|
|
39684
39888
|
agentHomeProvisionQueues.delete(root);
|
|
39685
39889
|
}
|
|
39686
|
-
const env = tmpLinkReady ? roomAgentHomeEnv(root) : { ...roomAgentHomeEnv(root), TMPDIR:
|
|
39890
|
+
const env = tmpLinkReady ? roomAgentHomeEnv(root) : { ...roomAgentHomeEnv(root), TMPDIR: resolve31(root, "tmp") };
|
|
39687
39891
|
return {
|
|
39688
39892
|
...env,
|
|
39689
39893
|
...androidAgentEnv({
|
|
@@ -39702,11 +39906,11 @@ async function provisionAgentSkillsAndMcp(root, operatorHome, skillReleaseId, fa
|
|
|
39702
39906
|
...isReviewer ? [{ name: BEELINE_REVIEW_SKILL_NAME, content: beelineReviewSkillMarkdown(skillReleaseId) }] : []
|
|
39703
39907
|
];
|
|
39704
39908
|
const shared = await resolveSharedSkillSources(operatorHome, sharedSkills);
|
|
39705
|
-
await provisionManagedSkillsDir(
|
|
39909
|
+
await provisionManagedSkillsDir(resolve31(root, skillDir, "skills"), managedSkills, shared, sharedSkills.length === 0);
|
|
39706
39910
|
for (const config of HARNESS_MCP_CONFIGS) {
|
|
39707
39911
|
try {
|
|
39708
|
-
const source =
|
|
39709
|
-
const target =
|
|
39912
|
+
const source = resolve31(operatorHome, config.toml);
|
|
39913
|
+
const target = resolve31(root, config.dir, "config.toml");
|
|
39710
39914
|
const mcpSection = existsSync8(source) ? localHarnessMcpToml(readFileSync10(source, "utf8")) : void 0;
|
|
39711
39915
|
const section = config.dir === "codex" ? [CODEX_ROOM_AGENT_LOCKDOWN_TOML, CODEX_ROOM_WEB_SEARCH_TOML, mcpSection].filter(Boolean).join("\n") : mcpSection;
|
|
39712
39916
|
if (!section) {
|
|
@@ -39721,11 +39925,11 @@ async function provisionAgentSkillsAndMcp(root, operatorHome, skillReleaseId, fa
|
|
|
39721
39925
|
}
|
|
39722
39926
|
}
|
|
39723
39927
|
try {
|
|
39724
|
-
const gooseConfigDir =
|
|
39928
|
+
const gooseConfigDir = resolve31(root, "goose", "config");
|
|
39725
39929
|
await mkdir19(gooseConfigDir, { recursive: true, mode: 448 });
|
|
39726
39930
|
for (const name of GOOSE_SHARED_CONFIG_FILES) {
|
|
39727
|
-
const source =
|
|
39728
|
-
const target =
|
|
39931
|
+
const source = resolve31(operatorHome, ".config", "goose", name);
|
|
39932
|
+
const target = resolve31(gooseConfigDir, name);
|
|
39729
39933
|
if (existsSync8(source)) {
|
|
39730
39934
|
const body = readFileSync10(source, "utf8");
|
|
39731
39935
|
await writeIsolatedHarnessFile(target, name === "config.yaml" ? localGooseConfig(body) : body);
|
|
@@ -39739,8 +39943,8 @@ async function provisionAgentSkillsAndMcp(root, operatorHome, skillReleaseId, fa
|
|
|
39739
39943
|
console.warn("[body] operator Goose configuration passthrough failed:", error);
|
|
39740
39944
|
}
|
|
39741
39945
|
try {
|
|
39742
|
-
const claudeJson =
|
|
39743
|
-
const claudeTarget =
|
|
39946
|
+
const claudeJson = resolve31(operatorHome, ".claude.json");
|
|
39947
|
+
const claudeTarget = resolve31(root, "claude", ".claude.json");
|
|
39744
39948
|
const mcpServers = existsSync8(claudeJson) ? readClaudeUserScopeMcpServers(claudeJson) : void 0;
|
|
39745
39949
|
if (mcpServers && Object.keys(mcpServers).length > 0) {
|
|
39746
39950
|
await writeIsolatedHarnessFile(claudeTarget, `${JSON.stringify({ mcpServers }, null, 2)}
|
|
@@ -39754,8 +39958,8 @@ async function provisionAgentSkillsAndMcp(root, operatorHome, skillReleaseId, fa
|
|
|
39754
39958
|
console.warn("[body] operator MCP passthrough failed for claude:", error);
|
|
39755
39959
|
}
|
|
39756
39960
|
try {
|
|
39757
|
-
const piJson =
|
|
39758
|
-
const piTarget =
|
|
39961
|
+
const piJson = resolve31(operatorHome, PI_MCP_CONFIG.source);
|
|
39962
|
+
const piTarget = resolve31(root, "pi", PI_MCP_CONFIG.target);
|
|
39759
39963
|
const mcpServers = existsSync8(piJson) ? localMcpServers(recordValue2(readJsonObject2(piJson)?.mcpServers) ?? {}) : void 0;
|
|
39760
39964
|
if (mcpServers && Object.keys(mcpServers).length > 0) {
|
|
39761
39965
|
await writeIsolatedHarnessFile(piTarget, `${JSON.stringify({ mcpServers }, null, 2)}
|
|
@@ -39770,7 +39974,7 @@ async function provisionAgentSkillsAndMcp(root, operatorHome, skillReleaseId, fa
|
|
|
39770
39974
|
}
|
|
39771
39975
|
try {
|
|
39772
39976
|
const settings2 = { permissions: { allow: ["WebSearch", "WebFetch"] } };
|
|
39773
|
-
await writeIsolatedHarnessFile(
|
|
39977
|
+
await writeIsolatedHarnessFile(resolve31(root, "claude", "settings.json"), `${JSON.stringify(settings2, null, 2)}
|
|
39774
39978
|
`);
|
|
39775
39979
|
} catch (error) {
|
|
39776
39980
|
if (failClosed)
|
|
@@ -39784,7 +39988,7 @@ async function provisionAgentSkillsAndMcp(root, operatorHome, skillReleaseId, fa
|
|
|
39784
39988
|
httpIdleTimeoutMs: 3e5,
|
|
39785
39989
|
retry: { enabled: true, maxRetries: 3, baseDelayMs: 2e3 }
|
|
39786
39990
|
};
|
|
39787
|
-
await writeIsolatedHarnessFile(
|
|
39991
|
+
await writeIsolatedHarnessFile(resolve31(root, "pi", "settings.json"), `${JSON.stringify(settings2, null, 2)}
|
|
39788
39992
|
`);
|
|
39789
39993
|
}
|
|
39790
39994
|
}
|
|
@@ -39804,7 +40008,7 @@ async function applyGrantedHostRoutes(root, operatorHome, granted, agentKind, fa
|
|
|
39804
40008
|
const routes = routesFor(config.dir);
|
|
39805
40009
|
if (Object.keys(routes).length === 0)
|
|
39806
40010
|
continue;
|
|
39807
|
-
const target =
|
|
40011
|
+
const target = resolve31(root, config.dir, "config.toml");
|
|
39808
40012
|
const existing = existsSync8(target) ? readFileSync10(target, "utf8") : void 0;
|
|
39809
40013
|
const merged = mergeTomlHostRoutes(existing, routes);
|
|
39810
40014
|
if (merged)
|
|
@@ -39813,9 +40017,9 @@ async function applyGrantedHostRoutes(root, operatorHome, granted, agentKind, fa
|
|
|
39813
40017
|
if (appliesToHarness(agentKind, "goose")) {
|
|
39814
40018
|
const routes = routesFor("goose");
|
|
39815
40019
|
if (Object.keys(routes).length > 0) {
|
|
39816
|
-
const gooseConfigDir =
|
|
40020
|
+
const gooseConfigDir = resolve31(root, "goose", "config");
|
|
39817
40021
|
await mkdir19(gooseConfigDir, { recursive: true, mode: 448 });
|
|
39818
|
-
const target =
|
|
40022
|
+
const target = resolve31(gooseConfigDir, "config.yaml");
|
|
39819
40023
|
const existing = existsSync8(target) ? readFileSync10(target, "utf8") : void 0;
|
|
39820
40024
|
const merged = mergeGooseHostRoutes(existing, routes);
|
|
39821
40025
|
if (merged)
|
|
@@ -39825,7 +40029,7 @@ async function applyGrantedHostRoutes(root, operatorHome, granted, agentKind, fa
|
|
|
39825
40029
|
if (appliesToHarness(agentKind, "claude")) {
|
|
39826
40030
|
const routes = routesFor("claude");
|
|
39827
40031
|
if (Object.keys(routes).length > 0) {
|
|
39828
|
-
const target =
|
|
40032
|
+
const target = resolve31(root, "claude", ".claude.json");
|
|
39829
40033
|
const parsed = existsSync8(target) ? readJsonObject2(target) : void 0;
|
|
39830
40034
|
const merged = mergeJsonHostRoutes(recordValue2(parsed?.mcpServers), routes);
|
|
39831
40035
|
if (merged && Object.keys(merged).length > 0) {
|
|
@@ -39837,7 +40041,7 @@ async function applyGrantedHostRoutes(root, operatorHome, granted, agentKind, fa
|
|
|
39837
40041
|
if (appliesToHarness(agentKind, "pi")) {
|
|
39838
40042
|
const routes = routesFor("pi");
|
|
39839
40043
|
if (Object.keys(routes).length > 0) {
|
|
39840
|
-
const target =
|
|
40044
|
+
const target = resolve31(root, "pi", PI_MCP_CONFIG.target);
|
|
39841
40045
|
const parsed = existsSync8(target) ? readJsonObject2(target) : void 0;
|
|
39842
40046
|
const merged = mergeJsonHostRoutes(recordValue2(parsed?.mcpServers), routes);
|
|
39843
40047
|
if (merged && Object.keys(merged).length > 0) {
|
|
@@ -39853,8 +40057,8 @@ async function applyGrantedHostRoutes(root, operatorHome, granted, agentKind, fa
|
|
|
39853
40057
|
}
|
|
39854
40058
|
}
|
|
39855
40059
|
async function provisionPiCustomModelConfig(root, operatorHome, failClosed, openRouterRouting) {
|
|
39856
|
-
const source =
|
|
39857
|
-
const target =
|
|
40060
|
+
const source = resolve31(operatorHome, PI_CUSTOM_MODEL_CONFIG.source);
|
|
40061
|
+
const target = resolve31(root, "pi", PI_CUSTOM_MODEL_CONFIG.target);
|
|
39858
40062
|
let decision2;
|
|
39859
40063
|
if (openRouterRouting) {
|
|
39860
40064
|
decision2 = await resolveOpenRouterRouting(openRouterRouting);
|
|
@@ -39878,7 +40082,7 @@ async function provisionPiCustomModelConfig(root, operatorHome, failClosed, open
|
|
|
39878
40082
|
limits: decision2.limits ?? { maxTokens: OPENROUTER_MAX_OUTPUT_TOKENS }
|
|
39879
40083
|
} : void 0;
|
|
39880
40084
|
try {
|
|
39881
|
-
const sourceStats = await
|
|
40085
|
+
const sourceStats = await lstat6(source).catch(() => void 0);
|
|
39882
40086
|
if (!sourceStats) {
|
|
39883
40087
|
await writeIsolatedHarnessFile(target, `${JSON.stringify(withOpenRouterModelRouting({}, pin), null, 2)}
|
|
39884
40088
|
`);
|
|
@@ -39968,19 +40172,19 @@ function mountedImportedMcpServerNames(input = {}) {
|
|
|
39968
40172
|
const home = env.HOME ?? input.operatorHome ?? homedir14();
|
|
39969
40173
|
const kind = input.agentKind;
|
|
39970
40174
|
if (!kind || kind === "codex") {
|
|
39971
|
-
addTomlMcpNames(names,
|
|
40175
|
+
addTomlMcpNames(names, resolve31(env.CODEX_HOME ?? resolve31(home, ".codex"), "config.toml"));
|
|
39972
40176
|
}
|
|
39973
40177
|
if (!kind || kind === "grok") {
|
|
39974
|
-
addTomlMcpNames(names,
|
|
40178
|
+
addTomlMcpNames(names, resolve31(env.GROK_HOME ?? resolve31(home, ".grok"), "config.toml"));
|
|
39975
40179
|
}
|
|
39976
40180
|
if (!kind || kind === "claude") {
|
|
39977
|
-
addClaudeMcpNames(names,
|
|
40181
|
+
addClaudeMcpNames(names, resolve31(env.CLAUDE_CONFIG_DIR ?? home, ".claude.json"));
|
|
39978
40182
|
}
|
|
39979
40183
|
if (!kind || kind === "goose") {
|
|
39980
|
-
addGooseExtensionNames(names, env.GOOSE_PATH_ROOT ?
|
|
40184
|
+
addGooseExtensionNames(names, env.GOOSE_PATH_ROOT ? resolve31(env.GOOSE_PATH_ROOT, "config/config.yaml") : resolve31(home, ".config/goose/config.yaml"));
|
|
39981
40185
|
}
|
|
39982
40186
|
if (!kind || kind === "pi") {
|
|
39983
|
-
addClaudeMcpNames(names,
|
|
40187
|
+
addClaudeMcpNames(names, resolve31(env.PI_CODING_AGENT_DIR ?? resolve31(home, ".pi/agent"), PI_MCP_CONFIG.target));
|
|
39984
40188
|
}
|
|
39985
40189
|
} else {
|
|
39986
40190
|
collectImportedMcpNames(input.operatorHome ?? homedir14(), names, input.agentKind);
|
|
@@ -40000,17 +40204,17 @@ function hostImportedMcpDeclarations(input = {}) {
|
|
|
40000
40204
|
}
|
|
40001
40205
|
};
|
|
40002
40206
|
if (!kind || kind === "codex")
|
|
40003
|
-
add(readTomlMcpServers(
|
|
40207
|
+
add(readTomlMcpServers(resolve31(operatorHome, ".codex/config.toml")));
|
|
40004
40208
|
if (!kind || kind === "grok")
|
|
40005
|
-
add(readTomlMcpServers(
|
|
40209
|
+
add(readTomlMcpServers(resolve31(operatorHome, ".grok/config.toml")));
|
|
40006
40210
|
if (!kind || kind === "claude") {
|
|
40007
|
-
add(recordValue2(readJsonObject2(
|
|
40211
|
+
add(recordValue2(readJsonObject2(resolve31(operatorHome, ".claude.json"))?.mcpServers));
|
|
40008
40212
|
}
|
|
40009
40213
|
if (!kind || kind === "goose") {
|
|
40010
|
-
add(readGooseExtensions(
|
|
40214
|
+
add(readGooseExtensions(resolve31(operatorHome, ".config/goose/config.yaml")));
|
|
40011
40215
|
}
|
|
40012
40216
|
if (!kind || kind === "pi") {
|
|
40013
|
-
add(recordValue2(readJsonObject2(
|
|
40217
|
+
add(recordValue2(readJsonObject2(resolve31(operatorHome, PI_MCP_CONFIG.source))?.mcpServers));
|
|
40014
40218
|
}
|
|
40015
40219
|
return declarations;
|
|
40016
40220
|
}
|
|
@@ -40042,19 +40246,19 @@ function expectedMountedImportedMcpServerNames(input) {
|
|
|
40042
40246
|
}
|
|
40043
40247
|
function collectImportedMcpNames(operatorHome, names, kind) {
|
|
40044
40248
|
if (!kind || kind === "codex") {
|
|
40045
|
-
addLocalMcpNames(names, readTomlMcpServers(
|
|
40249
|
+
addLocalMcpNames(names, readTomlMcpServers(resolve31(operatorHome, ".codex/config.toml")));
|
|
40046
40250
|
}
|
|
40047
40251
|
if (!kind || kind === "grok") {
|
|
40048
|
-
addLocalMcpNames(names, readTomlMcpServers(
|
|
40252
|
+
addLocalMcpNames(names, readTomlMcpServers(resolve31(operatorHome, ".grok/config.toml")));
|
|
40049
40253
|
}
|
|
40050
40254
|
if (!kind || kind === "claude") {
|
|
40051
|
-
addLocalMcpNames(names, recordValue2(readJsonObject2(
|
|
40255
|
+
addLocalMcpNames(names, recordValue2(readJsonObject2(resolve31(operatorHome, ".claude.json"))?.mcpServers));
|
|
40052
40256
|
}
|
|
40053
40257
|
if (!kind || kind === "goose") {
|
|
40054
|
-
addLocalMcpNames(names, readGooseExtensions(
|
|
40258
|
+
addLocalMcpNames(names, readGooseExtensions(resolve31(operatorHome, ".config/goose/config.yaml")));
|
|
40055
40259
|
}
|
|
40056
40260
|
if (!kind || kind === "pi") {
|
|
40057
|
-
addLocalMcpNames(names, recordValue2(readJsonObject2(
|
|
40261
|
+
addLocalMcpNames(names, recordValue2(readJsonObject2(resolve31(operatorHome, PI_MCP_CONFIG.source))?.mcpServers));
|
|
40058
40262
|
}
|
|
40059
40263
|
}
|
|
40060
40264
|
function addLocalMcpNames(names, servers) {
|
|
@@ -40126,19 +40330,19 @@ async function provisionManagedSkillsDir(target, managedSkills, sharedSkills, op
|
|
|
40126
40330
|
const plan = await planManagedSkills(managedSkills, sharedSkills, optionalShares);
|
|
40127
40331
|
if (await materializedSkillManifest(target) === plan.manifest)
|
|
40128
40332
|
return;
|
|
40129
|
-
const staged =
|
|
40333
|
+
const staged = resolve31(parent, `.skills.${process.pid}.${randomUUID13()}.tmp`);
|
|
40130
40334
|
await mkdir19(staged, { mode: 448 });
|
|
40131
40335
|
try {
|
|
40132
40336
|
for (const entry of plan.entries) {
|
|
40133
40337
|
if (entry.kind === "managed") {
|
|
40134
|
-
const skillDir =
|
|
40338
|
+
const skillDir = resolve31(staged, entry.name);
|
|
40135
40339
|
await mkdir19(skillDir, { recursive: true });
|
|
40136
|
-
await writeIsolatedHarnessFile(
|
|
40340
|
+
await writeIsolatedHarnessFile(resolve31(skillDir, "SKILL.md"), entry.content);
|
|
40137
40341
|
} else {
|
|
40138
|
-
await copySafeSkillTree(entry.source,
|
|
40342
|
+
await copySafeSkillTree(entry.source, resolve31(staged, entry.name), entry.source);
|
|
40139
40343
|
}
|
|
40140
40344
|
}
|
|
40141
|
-
const existing = await
|
|
40345
|
+
const existing = await lstat6(target).catch(() => void 0);
|
|
40142
40346
|
if (existing)
|
|
40143
40347
|
await rm14(target, { recursive: existing.isDirectory(), force: true });
|
|
40144
40348
|
await rename10(staged, target);
|
|
@@ -40163,7 +40367,7 @@ async function planManagedSkills(managedSkills, sharedSkills, optionalShares) {
|
|
|
40163
40367
|
const tree = [];
|
|
40164
40368
|
await walkSafeSkillTree(shared.source, shared.source, {
|
|
40165
40369
|
directory: async (rel) => void tree.push(`d ${join15(shared.name, rel)}`),
|
|
40166
|
-
file: async (rel, realPath) => void tree.push(`f ${join15(shared.name, rel)} ${sha2563(await
|
|
40370
|
+
file: async (rel, realPath) => void tree.push(`f ${join15(shared.name, rel)} ${sha2563(await readFile27(realPath))}`)
|
|
40167
40371
|
});
|
|
40168
40372
|
entries.push({ kind: "shared", name: shared.name, source: shared.source });
|
|
40169
40373
|
lines.push(...tree);
|
|
@@ -40176,15 +40380,15 @@ async function planManagedSkills(managedSkills, sharedSkills, optionalShares) {
|
|
|
40176
40380
|
return { entries, manifest: lines.sort().join("\n") };
|
|
40177
40381
|
}
|
|
40178
40382
|
async function materializedSkillManifest(target) {
|
|
40179
|
-
const stats = await
|
|
40383
|
+
const stats = await lstat6(target).catch(() => void 0);
|
|
40180
40384
|
if (!stats?.isDirectory() || stats.isSymbolicLink())
|
|
40181
40385
|
return void 0;
|
|
40182
40386
|
const lines = [];
|
|
40183
40387
|
const visit = async (directory, prefix) => {
|
|
40184
|
-
for (const entry of await
|
|
40185
|
-
const path =
|
|
40388
|
+
for (const entry of await readdir9(directory)) {
|
|
40389
|
+
const path = resolve31(directory, entry);
|
|
40186
40390
|
const rel = prefix ? join15(prefix, entry) : entry;
|
|
40187
|
-
const entryStats = await
|
|
40391
|
+
const entryStats = await lstat6(path);
|
|
40188
40392
|
if (entryStats.isSymbolicLink())
|
|
40189
40393
|
return false;
|
|
40190
40394
|
if (entryStats.isDirectory()) {
|
|
@@ -40195,7 +40399,7 @@ async function materializedSkillManifest(target) {
|
|
|
40195
40399
|
}
|
|
40196
40400
|
if (!entryStats.isFile() || entryStats.nlink !== 1)
|
|
40197
40401
|
return false;
|
|
40198
|
-
lines.push(`f ${rel} ${sha2563(await
|
|
40402
|
+
lines.push(`f ${rel} ${sha2563(await readFile27(path))}`);
|
|
40199
40403
|
}
|
|
40200
40404
|
return true;
|
|
40201
40405
|
};
|
|
@@ -40217,16 +40421,16 @@ async function resolveSharedSkillSources(operatorHome, names) {
|
|
|
40217
40421
|
const resolved = [];
|
|
40218
40422
|
const skipped = [];
|
|
40219
40423
|
for (const relativeRoot of OPERATOR_SKILL_SOURCE_DIRS) {
|
|
40220
|
-
const sourceRoot =
|
|
40221
|
-
const rootStats = await
|
|
40424
|
+
const sourceRoot = resolve31(operatorHome, relativeRoot);
|
|
40425
|
+
const rootStats = await lstat6(sourceRoot).catch(() => void 0);
|
|
40222
40426
|
if (!rootStats?.isDirectory() || rootStats.isSymbolicLink())
|
|
40223
40427
|
continue;
|
|
40224
|
-
for (const entry of await
|
|
40428
|
+
for (const entry of await readdir9(sourceRoot)) {
|
|
40225
40429
|
if (!isSharedSkillName(entry) || seen.has(entry))
|
|
40226
40430
|
continue;
|
|
40227
|
-
const candidate =
|
|
40431
|
+
const candidate = resolve31(sourceRoot, entry);
|
|
40228
40432
|
try {
|
|
40229
|
-
const candidateStats = await
|
|
40433
|
+
const candidateStats = await lstat6(candidate);
|
|
40230
40434
|
if (candidateStats.isSymbolicLink()) {
|
|
40231
40435
|
const reason = await realpath2(candidate).then(() => "symlinked directory", (error) => isMissingPathError(error) ? "dangling symlink" : "symlinked directory");
|
|
40232
40436
|
skipped.push({
|
|
@@ -40240,8 +40444,8 @@ async function resolveSharedSkillSources(operatorHome, names) {
|
|
|
40240
40444
|
continue;
|
|
40241
40445
|
}
|
|
40242
40446
|
assertContained(sourceRoot, candidate);
|
|
40243
|
-
const skillMd =
|
|
40244
|
-
const skillStats = await
|
|
40447
|
+
const skillMd = resolve31(candidate, "SKILL.md");
|
|
40448
|
+
const skillStats = await lstat6(skillMd).catch((error) => {
|
|
40245
40449
|
if (isMissingPathError(error)) {
|
|
40246
40450
|
skipped.push({ path: candidate, reason: "missing SKILL.md" });
|
|
40247
40451
|
return void 0;
|
|
@@ -40292,10 +40496,10 @@ async function resolveExplicitSkillSources(operatorHome, names) {
|
|
|
40292
40496
|
for (const name of unique) {
|
|
40293
40497
|
const matches = [];
|
|
40294
40498
|
for (const relativeRoot of OPERATOR_SKILL_SOURCE_DIRS) {
|
|
40295
|
-
const sourceRoot =
|
|
40296
|
-
const candidate =
|
|
40297
|
-
const rootStats = await
|
|
40298
|
-
const candidateStats = await
|
|
40499
|
+
const sourceRoot = resolve31(operatorHome, relativeRoot);
|
|
40500
|
+
const candidate = resolve31(sourceRoot, name);
|
|
40501
|
+
const rootStats = await lstat6(sourceRoot).catch(() => void 0);
|
|
40502
|
+
const candidateStats = await lstat6(candidate).catch(() => void 0);
|
|
40299
40503
|
if (!candidateStats)
|
|
40300
40504
|
continue;
|
|
40301
40505
|
if (!rootStats?.isDirectory() || rootStats.isSymbolicLink()) {
|
|
@@ -40310,8 +40514,8 @@ async function resolveExplicitSkillSources(operatorHome, names) {
|
|
|
40310
40514
|
if (matches.length !== 1) {
|
|
40311
40515
|
throw new Error(matches.length === 0 ? `shared skill is unavailable: ${name}` : `shared skill source is ambiguous: ${name}`);
|
|
40312
40516
|
}
|
|
40313
|
-
const skillMd =
|
|
40314
|
-
const skillStats = await
|
|
40517
|
+
const skillMd = resolve31(matches[0], "SKILL.md");
|
|
40518
|
+
const skillStats = await lstat6(skillMd).catch(() => void 0);
|
|
40315
40519
|
if (!skillStats?.isFile() || skillStats.isSymbolicLink() || skillStats.nlink !== 1) {
|
|
40316
40520
|
throw new Error(`shared skill requires an ordinary SKILL.md: ${name}`);
|
|
40317
40521
|
}
|
|
@@ -40321,13 +40525,13 @@ async function resolveExplicitSkillSources(operatorHome, names) {
|
|
|
40321
40525
|
}
|
|
40322
40526
|
function assertContained(root, candidate) {
|
|
40323
40527
|
const rel = relative2(root, candidate);
|
|
40324
|
-
if (rel === ".." || rel.startsWith(`..${sep2}`) ||
|
|
40528
|
+
if (rel === ".." || rel.startsWith(`..${sep2}`) || resolve31(root, rel) !== resolve31(candidate)) {
|
|
40325
40529
|
throw new Error(`path escapes the agent skill boundary: ${candidate}`);
|
|
40326
40530
|
}
|
|
40327
40531
|
}
|
|
40328
40532
|
async function assertRealContainedDirectory(path, root) {
|
|
40329
40533
|
assertContained(root, path);
|
|
40330
|
-
const stats = await
|
|
40534
|
+
const stats = await lstat6(path);
|
|
40331
40535
|
if (!stats.isDirectory() || stats.isSymbolicLink()) {
|
|
40332
40536
|
throw new AgentHomeSecurityError(`agent skill destination is not an ordinary directory: ${path}`);
|
|
40333
40537
|
}
|
|
@@ -40336,11 +40540,11 @@ var BLOCKED_SHARED_FILENAMES = /^(?:\.env(?:\..*)?|auth\.json|\.credentials\.jso
|
|
|
40336
40540
|
async function walkSafeSkillTree(source, sourceRoot, visitor, rel = "") {
|
|
40337
40541
|
assertContained(sourceRoot, source);
|
|
40338
40542
|
const resolvedSource = await realpath2(source);
|
|
40339
|
-
if (resolvedSource !==
|
|
40543
|
+
if (resolvedSource !== resolve31(source)) {
|
|
40340
40544
|
throw new Error(`shared skill path resolves through a link: ${source}`);
|
|
40341
40545
|
}
|
|
40342
40546
|
assertContained(sourceRoot, resolvedSource);
|
|
40343
|
-
const stats = await
|
|
40547
|
+
const stats = await lstat6(resolvedSource);
|
|
40344
40548
|
if (stats.isSymbolicLink())
|
|
40345
40549
|
throw new Error(`shared skill contains a symlink: ${source}`);
|
|
40346
40550
|
if (BLOCKED_SHARED_FILENAMES.test(basename8(source))) {
|
|
@@ -40348,10 +40552,10 @@ async function walkSafeSkillTree(source, sourceRoot, visitor, rel = "") {
|
|
|
40348
40552
|
}
|
|
40349
40553
|
if (stats.isDirectory()) {
|
|
40350
40554
|
await visitor.directory(rel);
|
|
40351
|
-
for (const entry of await
|
|
40555
|
+
for (const entry of await readdir9(resolvedSource)) {
|
|
40352
40556
|
if (entry === "." || entry === "..")
|
|
40353
40557
|
throw new Error("invalid shared skill entry");
|
|
40354
|
-
await walkSafeSkillTree(
|
|
40558
|
+
await walkSafeSkillTree(resolve31(source, entry), sourceRoot, visitor, rel ? join15(rel, entry) : entry);
|
|
40355
40559
|
}
|
|
40356
40560
|
return;
|
|
40357
40561
|
}
|
|
@@ -40363,10 +40567,10 @@ async function walkSafeSkillTree(source, sourceRoot, visitor, rel = "") {
|
|
|
40363
40567
|
async function copySafeSkillTree(source, target, sourceRoot) {
|
|
40364
40568
|
await walkSafeSkillTree(source, sourceRoot, {
|
|
40365
40569
|
directory: async (rel) => {
|
|
40366
|
-
await mkdir19(
|
|
40570
|
+
await mkdir19(resolve31(target, rel), { mode: 448 });
|
|
40367
40571
|
},
|
|
40368
40572
|
file: async (rel, realPath) => {
|
|
40369
|
-
const destination =
|
|
40573
|
+
const destination = resolve31(target, rel);
|
|
40370
40574
|
await copyFile(realPath, destination);
|
|
40371
40575
|
await chmod8(destination, 384);
|
|
40372
40576
|
}
|
|
@@ -40374,11 +40578,11 @@ async function copySafeSkillTree(source, target, sourceRoot) {
|
|
|
40374
40578
|
}
|
|
40375
40579
|
async function writeIsolatedHarnessFile(path, content) {
|
|
40376
40580
|
const parent = dirname22(path);
|
|
40377
|
-
const parentStats = await
|
|
40581
|
+
const parentStats = await lstat6(parent);
|
|
40378
40582
|
if (!parentStats.isDirectory() || parentStats.isSymbolicLink()) {
|
|
40379
40583
|
throw new Error(`isolated harness parent is not a real directory: ${parent}`);
|
|
40380
40584
|
}
|
|
40381
|
-
const temporary =
|
|
40585
|
+
const temporary = resolve31(parent, `.${basename8(path)}.${process.pid}.${randomUUID13()}.tmp`);
|
|
40382
40586
|
try {
|
|
40383
40587
|
await writeFile17(temporary, content, { mode: 384, flag: "wx" });
|
|
40384
40588
|
await chmod8(temporary, 384);
|
|
@@ -40388,24 +40592,24 @@ async function writeIsolatedHarnessFile(path, content) {
|
|
|
40388
40592
|
}
|
|
40389
40593
|
}
|
|
40390
40594
|
function roomSessionTmpDir(root, base = "/tmp") {
|
|
40391
|
-
const hash = createHash13("sha256").update(
|
|
40595
|
+
const hash = createHash13("sha256").update(resolve31(root)).digest("hex").slice(0, 12);
|
|
40392
40596
|
return join15(base, `beeline-${hash}`);
|
|
40393
40597
|
}
|
|
40394
40598
|
function roomAgentHomeEnv(root) {
|
|
40395
|
-
const resolved =
|
|
40599
|
+
const resolved = resolve31(root);
|
|
40396
40600
|
return {
|
|
40397
|
-
HOME:
|
|
40398
|
-
CLAUDE_CONFIG_DIR:
|
|
40399
|
-
CODEX_HOME:
|
|
40400
|
-
GOOSE_PATH_ROOT:
|
|
40401
|
-
GROK_HOME:
|
|
40402
|
-
CURSOR_HOME:
|
|
40403
|
-
OPENCODE_CONFIG_DIR:
|
|
40404
|
-
PI_CODING_AGENT_DIR:
|
|
40405
|
-
XDG_CONFIG_HOME:
|
|
40406
|
-
XDG_DATA_HOME:
|
|
40407
|
-
XDG_STATE_HOME:
|
|
40408
|
-
XDG_CACHE_HOME:
|
|
40601
|
+
HOME: resolve31(resolved, "user"),
|
|
40602
|
+
CLAUDE_CONFIG_DIR: resolve31(resolved, "claude"),
|
|
40603
|
+
CODEX_HOME: resolve31(resolved, "codex"),
|
|
40604
|
+
GOOSE_PATH_ROOT: resolve31(resolved, "goose"),
|
|
40605
|
+
GROK_HOME: resolve31(resolved, "grok"),
|
|
40606
|
+
CURSOR_HOME: resolve31(resolved, "cursor"),
|
|
40607
|
+
OPENCODE_CONFIG_DIR: resolve31(resolved, "opencode"),
|
|
40608
|
+
PI_CODING_AGENT_DIR: resolve31(resolved, "pi"),
|
|
40609
|
+
XDG_CONFIG_HOME: resolve31(resolved, "user/.config"),
|
|
40610
|
+
XDG_DATA_HOME: resolve31(resolved, "user/.local/share"),
|
|
40611
|
+
XDG_STATE_HOME: resolve31(resolved, "state"),
|
|
40612
|
+
XDG_CACHE_HOME: resolve31(resolved, "cache"),
|
|
40409
40613
|
TMPDIR: roomSessionTmpDir(resolved)
|
|
40410
40614
|
};
|
|
40411
40615
|
}
|
|
@@ -40428,10 +40632,10 @@ function harnessStateDirsFromEnv(env) {
|
|
|
40428
40632
|
for (const name of HARNESS_STATE_ENV_VARS) {
|
|
40429
40633
|
const value = env[name];
|
|
40430
40634
|
if (value)
|
|
40431
|
-
stateDirs.push(
|
|
40635
|
+
stateDirs.push(resolve31(value));
|
|
40432
40636
|
}
|
|
40433
40637
|
const tmp = env.TMPDIR;
|
|
40434
|
-
return { stateDirs, ...tmp ? { tmpDir:
|
|
40638
|
+
return { stateDirs, ...tmp ? { tmpDir: resolve31(tmp) } : {} };
|
|
40435
40639
|
}
|
|
40436
40640
|
|
|
40437
40641
|
// apps/body/dist/agent-command-catalog.js
|
|
@@ -41071,12 +41275,12 @@ function mountedMcpSet(servers) {
|
|
|
41071
41275
|
}
|
|
41072
41276
|
|
|
41073
41277
|
// apps/body/dist/corner-prepare-script.js
|
|
41074
|
-
import { readFile as
|
|
41075
|
-
import { resolve as
|
|
41278
|
+
import { readFile as readFile28 } from "node:fs/promises";
|
|
41279
|
+
import { resolve as resolve32 } from "node:path";
|
|
41076
41280
|
var CORNER_PREPARE_SCRIPT = "corner:prepare";
|
|
41077
41281
|
async function hasCornerPrepareScript(worktreePath) {
|
|
41078
41282
|
try {
|
|
41079
|
-
const parsed = JSON.parse(await
|
|
41283
|
+
const parsed = JSON.parse(await readFile28(resolve32(worktreePath, "package.json"), "utf8"));
|
|
41080
41284
|
return typeof parsed.scripts?.[CORNER_PREPARE_SCRIPT] === "string";
|
|
41081
41285
|
} catch {
|
|
41082
41286
|
return false;
|
|
@@ -41085,9 +41289,9 @@ async function hasCornerPrepareScript(worktreePath) {
|
|
|
41085
41289
|
|
|
41086
41290
|
// apps/body/dist/pi-mcp-bridge.js
|
|
41087
41291
|
import { execFile as execFile13 } from "node:child_process";
|
|
41088
|
-
import { mkdtemp as mkdtemp2, mkdir as mkdir21, readFile as
|
|
41292
|
+
import { mkdtemp as mkdtemp2, mkdir as mkdir21, readFile as readFile29, rm as rm15, unlink as unlink7 } from "node:fs/promises";
|
|
41089
41293
|
import { tmpdir as tmpdir5 } from "node:os";
|
|
41090
|
-
import { resolve as
|
|
41294
|
+
import { resolve as resolve33 } from "node:path";
|
|
41091
41295
|
import { promisify as promisify8 } from "node:util";
|
|
41092
41296
|
var PI_MCP_BRIDGE_FILENAME = "beeline-mcp-bridge.js";
|
|
41093
41297
|
var execFileAsync8 = promisify8(execFile13);
|
|
@@ -41098,7 +41302,7 @@ async function piHasNativeMcp(command, env) {
|
|
|
41098
41302
|
let probe = nativeMcpProbes.get(cacheKey);
|
|
41099
41303
|
if (!probe) {
|
|
41100
41304
|
probe = (async () => {
|
|
41101
|
-
const home = await mkdtemp2(
|
|
41305
|
+
const home = await mkdtemp2(resolve33(tmpdir5(), "beeline-pi-mcp-probe-"));
|
|
41102
41306
|
try {
|
|
41103
41307
|
const { stdout: stdout6 } = await execFileAsync8(command, ["mcp", "list", "--json"], {
|
|
41104
41308
|
cwd: home,
|
|
@@ -41119,7 +41323,7 @@ async function piHasNativeMcp(command, env) {
|
|
|
41119
41323
|
}
|
|
41120
41324
|
async function isolatedPiConfig(piHome) {
|
|
41121
41325
|
try {
|
|
41122
|
-
const parsed = JSON.parse(await
|
|
41326
|
+
const parsed = JSON.parse(await readFile29(resolve33(piHome, "mcp.json"), "utf8"));
|
|
41123
41327
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
|
|
41124
41328
|
} catch (error) {
|
|
41125
41329
|
if (error.code !== "ENOENT")
|
|
@@ -41173,8 +41377,8 @@ async function installPiMcpBridge(input) {
|
|
|
41173
41377
|
return void 0;
|
|
41174
41378
|
if (!input.piHome)
|
|
41175
41379
|
return void 0;
|
|
41176
|
-
const directory =
|
|
41177
|
-
const path =
|
|
41380
|
+
const directory = resolve33(input.piHome, "extensions");
|
|
41381
|
+
const path = resolve33(directory, PI_MCP_BRIDGE_FILENAME);
|
|
41178
41382
|
try {
|
|
41179
41383
|
const config = await isolatedPiConfig(input.piHome);
|
|
41180
41384
|
const nativeMcp = input.nativeMcp ?? await piHasNativeMcp(input.piCommand ?? "pi", input.agentEnv);
|
|
@@ -41187,13 +41391,13 @@ async function installPiMcpBridge(input) {
|
|
|
41187
41391
|
env: Object.fromEntries((server.env ?? []).map((entry) => [entry.name, entry.value])),
|
|
41188
41392
|
exposure: "direct"
|
|
41189
41393
|
};
|
|
41190
|
-
await writeIsolatedHarnessFile(
|
|
41394
|
+
await writeIsolatedHarnessFile(resolve33(input.piHome, "mcp.json"), `${JSON.stringify({ ...config, mcpServers: mcpServers2 }, null, 2)}
|
|
41191
41395
|
`);
|
|
41192
41396
|
await unlink7(path).catch((error) => {
|
|
41193
41397
|
if (error.code !== "ENOENT")
|
|
41194
41398
|
throw error;
|
|
41195
41399
|
});
|
|
41196
|
-
return
|
|
41400
|
+
return resolve33(input.piHome, "mcp.json");
|
|
41197
41401
|
}
|
|
41198
41402
|
const servers = [...input.servers, ...importedStdioServers(config, input.servers)];
|
|
41199
41403
|
if (!servers.length)
|
|
@@ -41206,7 +41410,7 @@ async function installPiMcpBridge(input) {
|
|
|
41206
41410
|
env: Object.fromEntries((server.env ?? []).map((entry) => [entry.name, entry.value])),
|
|
41207
41411
|
enabled: false
|
|
41208
41412
|
};
|
|
41209
|
-
await writeIsolatedHarnessFile(
|
|
41413
|
+
await writeIsolatedHarnessFile(resolve33(input.piHome, "mcp.json"), `${JSON.stringify({ ...config, mcpServers }, null, 2)}
|
|
41210
41414
|
`);
|
|
41211
41415
|
await mkdir21(directory, { recursive: true, mode: 448 });
|
|
41212
41416
|
await writeIsolatedHarnessFile(path, piMcpBridgeSource(servers));
|
|
@@ -41398,8 +41602,8 @@ export default async function (pi) {
|
|
|
41398
41602
|
|
|
41399
41603
|
// apps/body/dist/corner-branch-sync.js
|
|
41400
41604
|
import { execFile as execFile14 } from "node:child_process";
|
|
41401
|
-
import { access as access2, readFile as
|
|
41402
|
-
import { resolve as
|
|
41605
|
+
import { access as access2, readFile as readFile30 } from "node:fs/promises";
|
|
41606
|
+
import { resolve as resolve34 } from "node:path";
|
|
41403
41607
|
var CORNER_GIT_SYNC_TIMEOUT_MS = 12e4;
|
|
41404
41608
|
var CORNER_GIT_SYNC_KILL_GRACE_MS = 1e3;
|
|
41405
41609
|
var CornerGitSyncInterruptedError = class extends Error {
|
|
@@ -41413,7 +41617,7 @@ async function syncCornerBranch(input) {
|
|
|
41413
41617
|
try {
|
|
41414
41618
|
if (signal.aborted)
|
|
41415
41619
|
throw interrupted();
|
|
41416
|
-
return await new Promise((
|
|
41620
|
+
return await new Promise((resolve53, reject) => {
|
|
41417
41621
|
let killTimer;
|
|
41418
41622
|
let stdout6 = "";
|
|
41419
41623
|
let failure = null;
|
|
@@ -41447,19 +41651,19 @@ async function syncCornerBranch(input) {
|
|
|
41447
41651
|
else if (failure)
|
|
41448
41652
|
reject(failure);
|
|
41449
41653
|
else
|
|
41450
|
-
|
|
41654
|
+
resolve53(stdout6);
|
|
41451
41655
|
});
|
|
41452
41656
|
else
|
|
41453
|
-
input.git(args).then(
|
|
41657
|
+
input.git(args).then(resolve53, reject).finally(cleanup2);
|
|
41454
41658
|
});
|
|
41455
41659
|
} finally {
|
|
41456
41660
|
clearTimeout(timer);
|
|
41457
41661
|
}
|
|
41458
41662
|
};
|
|
41459
|
-
const marker = await
|
|
41460
|
-
const gitDir =
|
|
41663
|
+
const marker = await readFile30(resolve34(input.worktreePath, ".git"), "utf8").catch(() => "");
|
|
41664
|
+
const gitDir = resolve34(input.worktreePath, marker.startsWith("gitdir: ") ? marker.slice(8).trim() : ".git");
|
|
41461
41665
|
for (const directory of ["rebase-merge", "rebase-apply"]) {
|
|
41462
|
-
if (await access2(
|
|
41666
|
+
if (await access2(resolve34(gitDir, directory)).then(() => true, () => false))
|
|
41463
41667
|
await git2(["rebase", "--abort"], true);
|
|
41464
41668
|
}
|
|
41465
41669
|
const remoteRef = `refs/remotes/origin/${input.featureBranch}`;
|
|
@@ -41507,7 +41711,7 @@ async function contains(git2, head, ancestor) {
|
|
|
41507
41711
|
}
|
|
41508
41712
|
|
|
41509
41713
|
// apps/body/dist/room-session.js
|
|
41510
|
-
import { resolve as
|
|
41714
|
+
import { resolve as resolve35 } from "node:path";
|
|
41511
41715
|
import { homedir as homedir15 } from "node:os";
|
|
41512
41716
|
|
|
41513
41717
|
// apps/body/dist/read-only-policy.js
|
|
@@ -41749,22 +41953,22 @@ function readOnlyMcpServer(config, cwd, agentMemoryDir) {
|
|
|
41749
41953
|
command: config.readonlyMcpCommand,
|
|
41750
41954
|
args: [...config.readonlyMcpArgs ?? []],
|
|
41751
41955
|
env: [
|
|
41752
|
-
{ name: "BEELINE_READONLY_ROOT", value:
|
|
41956
|
+
{ name: "BEELINE_READONLY_ROOT", value: resolve35(cwd) },
|
|
41753
41957
|
...config.agentHomeRoot ? [
|
|
41754
41958
|
{
|
|
41755
41959
|
name: "BEELINE_READONLY_AGENT_SKILLS_ROOT",
|
|
41756
|
-
value:
|
|
41960
|
+
value: resolve35(config.agentHomeRoot, skillDir, "skills")
|
|
41757
41961
|
}
|
|
41758
41962
|
] : [],
|
|
41759
|
-
...agentMemoryDir ? [{ name: "BEELINE_READONLY_AGENT_MEMORY_ROOT", value:
|
|
41963
|
+
...agentMemoryDir ? [{ name: "BEELINE_READONLY_AGENT_MEMORY_ROOT", value: resolve35(agentMemoryDir) }] : []
|
|
41760
41964
|
]
|
|
41761
41965
|
};
|
|
41762
41966
|
}
|
|
41763
41967
|
|
|
41764
41968
|
// apps/body/dist/scratch-lifecycle.js
|
|
41765
41969
|
import { execFile as execFile15 } from "node:child_process";
|
|
41766
|
-
import { lstat as
|
|
41767
|
-
import { join as join17, resolve as
|
|
41970
|
+
import { lstat as lstat7, readdir as readdir10, rmdir as rmdir2, rm as rm16, stat as stat10, unlink as unlink8 } from "node:fs/promises";
|
|
41971
|
+
import { join as join17, resolve as resolve36 } from "node:path";
|
|
41768
41972
|
import { promisify as promisify9 } from "node:util";
|
|
41769
41973
|
var execFileAsync9 = promisify9(execFile15);
|
|
41770
41974
|
var CORNER_SCRATCH_BUDGET_BYTES = 5 * 1024 ** 3;
|
|
@@ -41772,7 +41976,7 @@ var CORNER_SCRATCH_TTL_MS = 14 * 24 * 60 * 6e4;
|
|
|
41772
41976
|
var SHARED_MODEL_CACHE_BUDGET_BYTES = 32 * 1024 ** 3;
|
|
41773
41977
|
var MODEL_CACHE_IDLE_MS = 24 * 60 * 6e4;
|
|
41774
41978
|
async function allocatedDirectoryBytes(path) {
|
|
41775
|
-
if (!await
|
|
41979
|
+
if (!await lstat7(path).catch(() => void 0))
|
|
41776
41980
|
return 0;
|
|
41777
41981
|
const output = await execFileAsync9("du", ["-s", "-B1", "--", path], {
|
|
41778
41982
|
maxBuffer: 1024 * 1024
|
|
@@ -41794,11 +41998,11 @@ async function sweepStaleCornerScratch(root, now2 = Date.now(), ttlMs = CORNER_S
|
|
|
41794
41998
|
let files = 0;
|
|
41795
41999
|
let bytes = 0;
|
|
41796
42000
|
const visit = async (dir, top) => {
|
|
41797
|
-
for (const entry of await
|
|
42001
|
+
for (const entry of await readdir10(dir, { withFileTypes: true }).catch(() => [])) {
|
|
41798
42002
|
if (top && (entry.name === "agent-home" || entry.name === "agent-private" || entry.name === ".git"))
|
|
41799
42003
|
continue;
|
|
41800
42004
|
const path = join17(dir, entry.name);
|
|
41801
|
-
const info = await
|
|
42005
|
+
const info = await lstat7(path).catch(() => void 0);
|
|
41802
42006
|
if (!info || info.isSymbolicLink())
|
|
41803
42007
|
continue;
|
|
41804
42008
|
if (info.isDirectory()) {
|
|
@@ -41812,8 +42016,8 @@ async function sweepStaleCornerScratch(root, now2 = Date.now(), ttlMs = CORNER_S
|
|
|
41812
42016
|
}
|
|
41813
42017
|
}
|
|
41814
42018
|
};
|
|
41815
|
-
if ((await
|
|
41816
|
-
await visit(
|
|
42019
|
+
if ((await lstat7(root).catch(() => void 0))?.isDirectory())
|
|
42020
|
+
await visit(resolve36(root), true);
|
|
41817
42021
|
return { files, bytes };
|
|
41818
42022
|
}
|
|
41819
42023
|
async function pruneSharedModelCache(root, now2 = Date.now(), budget = SHARED_MODEL_CACHE_BUDGET_BYTES) {
|
|
@@ -41822,7 +42026,7 @@ async function pruneSharedModelCache(root, now2 = Date.now(), budget = SHARED_MO
|
|
|
41822
42026
|
return [];
|
|
41823
42027
|
const candidates = [];
|
|
41824
42028
|
for (const parent of [join17(root, "hub"), root]) {
|
|
41825
|
-
for (const entry of await
|
|
42029
|
+
for (const entry of await readdir10(parent, { withFileTypes: true }).catch(() => [])) {
|
|
41826
42030
|
const eligible = parent === root ? entry.name === "xet" : /^(?:models|datasets|spaces)--/.test(entry.name);
|
|
41827
42031
|
if (!eligible || !entry.isDirectory())
|
|
41828
42032
|
continue;
|
|
@@ -41894,15 +42098,15 @@ async function awaitInstitutionalContext(fetch2, log2 = console.warn, budgetMs =
|
|
|
41894
42098
|
|
|
41895
42099
|
// apps/body/dist/codegraph.js
|
|
41896
42100
|
import { execFile as execFile16 } from "node:child_process";
|
|
41897
|
-
import { access as access3, appendFile, mkdir as mkdir22, readFile as
|
|
41898
|
-
import { dirname as dirname23, isAbsolute as isAbsolute4, resolve as
|
|
42101
|
+
import { access as access3, appendFile, mkdir as mkdir22, readFile as readFile31 } from "node:fs/promises";
|
|
42102
|
+
import { dirname as dirname23, isAbsolute as isAbsolute4, resolve as resolve37 } from "node:path";
|
|
41899
42103
|
import { promisify as promisify10 } from "node:util";
|
|
41900
42104
|
var execFileAsync10 = promisify10(execFile16);
|
|
41901
42105
|
var CODEGRAPH_MCP_SERVER_NAME = "codegraph";
|
|
41902
42106
|
var CODEGRAPH_INDEX_PATH = ".codegraph/codegraph.db";
|
|
41903
42107
|
var CODEGRAPH_PREPARE_TIMEOUT_MS = 12e4;
|
|
41904
42108
|
function codegraphIndexDirectory(cwd) {
|
|
41905
|
-
return
|
|
42109
|
+
return resolve37(cwd, dirname23(CODEGRAPH_INDEX_PATH));
|
|
41906
42110
|
}
|
|
41907
42111
|
function codegraphMcpServer(config, cwd, options) {
|
|
41908
42112
|
if (!config.codegraphCommand)
|
|
@@ -41910,7 +42114,7 @@ function codegraphMcpServer(config, cwd, options) {
|
|
|
41910
42114
|
return {
|
|
41911
42115
|
name: CODEGRAPH_MCP_SERVER_NAME,
|
|
41912
42116
|
command: config.codegraphCommand,
|
|
41913
|
-
args: ["serve", "--mcp", "--path",
|
|
42117
|
+
args: ["serve", "--mcp", "--path", resolve37(cwd), ...options.readonly ? ["--no-watch"] : []],
|
|
41914
42118
|
env: [
|
|
41915
42119
|
{ name: "CODEGRAPH_TELEMETRY", value: "0" },
|
|
41916
42120
|
// One MCP child per harness session is easier to contain than a daemon
|
|
@@ -41928,7 +42132,7 @@ async function isGitWorktree(cwd) {
|
|
|
41928
42132
|
cwd,
|
|
41929
42133
|
timeout: 1e4
|
|
41930
42134
|
});
|
|
41931
|
-
return
|
|
42135
|
+
return resolve37(stdout6.trim()) === resolve37(cwd);
|
|
41932
42136
|
} catch {
|
|
41933
42137
|
return false;
|
|
41934
42138
|
}
|
|
@@ -41942,9 +42146,9 @@ async function excludeIndexFromGitStatus(cwd) {
|
|
|
41942
42146
|
const gitPath = stdout6.trim();
|
|
41943
42147
|
if (!gitPath)
|
|
41944
42148
|
return;
|
|
41945
|
-
const path = isAbsolute4(gitPath) ? gitPath :
|
|
42149
|
+
const path = isAbsolute4(gitPath) ? gitPath : resolve37(cwd, gitPath);
|
|
41946
42150
|
await mkdir22(dirname23(path), { recursive: true });
|
|
41947
|
-
const existing = await
|
|
42151
|
+
const existing = await readFile31(path, "utf8").catch(() => "");
|
|
41948
42152
|
if (existing.split("\n").includes(".codegraph/"))
|
|
41949
42153
|
return;
|
|
41950
42154
|
await appendFile(path, `${existing && !existing.endsWith("\n") ? "\n" : ""}.codegraph/
|
|
@@ -41957,7 +42161,7 @@ async function prepareCodegraphIndex(config, cwd) {
|
|
|
41957
42161
|
if (!command || !await isGitWorktree(cwd))
|
|
41958
42162
|
return false;
|
|
41959
42163
|
await excludeIndexFromGitStatus(cwd);
|
|
41960
|
-
const indexPath =
|
|
42164
|
+
const indexPath = resolve37(cwd, CODEGRAPH_INDEX_PATH);
|
|
41961
42165
|
const indexed = await access3(indexPath).then(() => true, () => false);
|
|
41962
42166
|
const args = indexed ? ["sync", "--quiet", cwd] : ["init", "--yes", cwd];
|
|
41963
42167
|
try {
|
|
@@ -42777,8 +42981,8 @@ function assembleTurnPrompt(context) {
|
|
|
42777
42981
|
}
|
|
42778
42982
|
|
|
42779
42983
|
// apps/body/dist/turn-trace.js
|
|
42780
|
-
import { appendFile as appendFile2, mkdir as mkdir23, readdir as
|
|
42781
|
-
import { resolve as
|
|
42984
|
+
import { appendFile as appendFile2, mkdir as mkdir23, readdir as readdir11, rm as rm17 } from "node:fs/promises";
|
|
42985
|
+
import { resolve as resolve38 } from "node:path";
|
|
42782
42986
|
import { performance as performance3 } from "node:perf_hooks";
|
|
42783
42987
|
var TURN_PHASES = [
|
|
42784
42988
|
/** Enqueued on `SessionScheduler` until this turn holds a slot. A capacity wait lives here. */
|
|
@@ -43067,7 +43271,7 @@ function formatTurnTraceLine(record5) {
|
|
|
43067
43271
|
return [head, ...record5.attempts.map((attempt) => formatTurnAttempt(attempt))].join("\n ");
|
|
43068
43272
|
}
|
|
43069
43273
|
function turnTraceDirectory(runtimeDir) {
|
|
43070
|
-
return
|
|
43274
|
+
return resolve38(runtimeDir, "turn-traces");
|
|
43071
43275
|
}
|
|
43072
43276
|
var TURN_TRACE_RETENTION_DAYS = 7;
|
|
43073
43277
|
function traceFileName(date) {
|
|
@@ -43084,7 +43288,7 @@ var TurnTraceFile = class {
|
|
|
43084
43288
|
this.options = options;
|
|
43085
43289
|
}
|
|
43086
43290
|
path(now2 = (this.options.clock ?? (() => /* @__PURE__ */ new Date()))()) {
|
|
43087
|
-
return
|
|
43291
|
+
return resolve38(this.directory, traceFileName(now2));
|
|
43088
43292
|
}
|
|
43089
43293
|
write(record5) {
|
|
43090
43294
|
this.tail = this.tail.catch(() => void 0).then(async () => {
|
|
@@ -43107,8 +43311,8 @@ var TurnTraceFile = class {
|
|
|
43107
43311
|
return;
|
|
43108
43312
|
this.prunedDay = day;
|
|
43109
43313
|
const cutoff = traceFileName(new Date(now2.getTime() - TURN_TRACE_RETENTION_DAYS * 864e5));
|
|
43110
|
-
const names = await
|
|
43111
|
-
await Promise.all(names.filter((name) => /^turns-\d{4}-\d{2}-\d{2}\.jsonl$/.test(name) && name < cutoff).map((name) => rm17(
|
|
43314
|
+
const names = await readdir11(this.directory).catch(() => []);
|
|
43315
|
+
await Promise.all(names.filter((name) => /^turns-\d{4}-\d{2}-\d{2}\.jsonl$/.test(name) && name < cutoff).map((name) => rm17(resolve38(this.directory, name), { force: true })));
|
|
43112
43316
|
}
|
|
43113
43317
|
};
|
|
43114
43318
|
|
|
@@ -44132,8 +44336,8 @@ var MonolithRoomTurnLoop = class {
|
|
|
44132
44336
|
let timer;
|
|
44133
44337
|
const stats = statsPromise && remaining > 0 ? await Promise.race([
|
|
44134
44338
|
statsPromise,
|
|
44135
|
-
new Promise((
|
|
44136
|
-
timer = setTimeout(() =>
|
|
44339
|
+
new Promise((resolve53) => {
|
|
44340
|
+
timer = setTimeout(() => resolve53(void 0), remaining);
|
|
44137
44341
|
})
|
|
44138
44342
|
]).finally(() => {
|
|
44139
44343
|
if (timer)
|
|
@@ -44550,9 +44754,9 @@ function roomMessagePrompt(author, body, attachments, delivered, harnessAcceptsI
|
|
|
44550
44754
|
|
|
44551
44755
|
// apps/body/dist/corner-github-auth.js
|
|
44552
44756
|
import { chmod as chmod9, mkdir as mkdir25, writeFile as writeFile20 } from "node:fs/promises";
|
|
44553
|
-
import { delimiter as delimiter3, resolve as
|
|
44757
|
+
import { delimiter as delimiter3, resolve as resolve39 } from "node:path";
|
|
44554
44758
|
async function installCornerGitHubWrappers(input) {
|
|
44555
|
-
const bin =
|
|
44759
|
+
const bin = resolve39(input.root, "beeline-github-bin");
|
|
44556
44760
|
await mkdir25(bin, { recursive: true, mode: 448 });
|
|
44557
44761
|
const common = {
|
|
44558
44762
|
node: process.execPath,
|
|
@@ -44564,13 +44768,13 @@ async function installCornerGitHubWrappers(input) {
|
|
|
44564
44768
|
gitCommand: input.gitBinary,
|
|
44565
44769
|
originUrl: input.originUrl ?? ""
|
|
44566
44770
|
};
|
|
44567
|
-
await writeLauncher(
|
|
44771
|
+
await writeLauncher(resolve39(bin, "git"), {
|
|
44568
44772
|
...common,
|
|
44569
44773
|
command: input.gitBinary,
|
|
44570
44774
|
launcher: "git",
|
|
44571
44775
|
restFallback: false
|
|
44572
44776
|
});
|
|
44573
|
-
await writeLauncher(
|
|
44777
|
+
await writeLauncher(resolve39(bin, "gh"), {
|
|
44574
44778
|
...common,
|
|
44575
44779
|
command: input.ghBinary ?? "",
|
|
44576
44780
|
launcher: "gh",
|
|
@@ -45024,32 +45228,32 @@ function agentGitIdentityEnv(agent) {
|
|
|
45024
45228
|
// apps/body/dist/warm-node-modules.js
|
|
45025
45229
|
import { createHash as createHash15, randomUUID as randomUUID14 } from "node:crypto";
|
|
45026
45230
|
import { constants as fsConstants3 } from "node:fs";
|
|
45027
|
-
import { chmod as chmod10, copyFile as copyFile2, link, lstat as
|
|
45028
|
-
import { dirname as dirname25, join as join19, resolve as
|
|
45231
|
+
import { chmod as chmod10, copyFile as copyFile2, link, lstat as lstat8, mkdir as mkdir26, readdir as readdir12, readFile as readFile32, readlink as readlink2, rename as rename11, rm as rm18, stat as stat11, symlink as symlink3, utimes } from "node:fs/promises";
|
|
45232
|
+
import { dirname as dirname25, join as join19, resolve as resolve40 } from "node:path";
|
|
45029
45233
|
var STORE_FORMAT = "v1";
|
|
45030
45234
|
var STAGING_PREFIX = ".beeline-warm-";
|
|
45031
45235
|
var STAGING_SWEEP_MS = 24 * 60 * 60 * 1e3;
|
|
45032
45236
|
var WARM_STORE_MAX_ENTRIES = 3;
|
|
45033
45237
|
function sharedNpmCacheDir(supervisorRoot2) {
|
|
45034
|
-
return
|
|
45238
|
+
return resolve40(supervisorRoot2, "beeline", "npm-cache");
|
|
45035
45239
|
}
|
|
45036
45240
|
function sharedPnpmStoreDir(supervisorRoot2) {
|
|
45037
|
-
return
|
|
45241
|
+
return resolve40(supervisorRoot2, "beeline", "pnpm-store");
|
|
45038
45242
|
}
|
|
45039
45243
|
function sharedTurboCacheDir(supervisorRoot2) {
|
|
45040
|
-
return
|
|
45244
|
+
return resolve40(supervisorRoot2, "beeline", "turbo-cache");
|
|
45041
45245
|
}
|
|
45042
45246
|
function warmNodeModulesStoreDir(supervisorRoot2) {
|
|
45043
|
-
return
|
|
45247
|
+
return resolve40(supervisorRoot2, "beeline", "node-modules");
|
|
45044
45248
|
}
|
|
45045
45249
|
function mobileNodeModulesStoreDir(supervisorRoot2) {
|
|
45046
|
-
return
|
|
45250
|
+
return resolve40(supervisorRoot2, "beeline", "node-modules-mobile");
|
|
45047
45251
|
}
|
|
45048
45252
|
function isPlanRefusal(value) {
|
|
45049
45253
|
return "failure" in value;
|
|
45050
45254
|
}
|
|
45051
45255
|
async function readWarmPlan(worktreePath) {
|
|
45052
|
-
const lockfile = await
|
|
45256
|
+
const lockfile = await readFile32(resolve40(worktreePath, "package-lock.json")).catch(() => void 0);
|
|
45053
45257
|
if (!lockfile)
|
|
45054
45258
|
return { failure: "no-lockfile" };
|
|
45055
45259
|
const packages = parseLockfilePackages(lockfile);
|
|
@@ -45088,11 +45292,11 @@ async function seedWarmNodeModules(input) {
|
|
|
45088
45292
|
return { reason: plan.failure, ...plan.detail ? { detail: plan.detail } : {} };
|
|
45089
45293
|
}
|
|
45090
45294
|
for (const tree of plan.trees) {
|
|
45091
|
-
if (await pathExists(
|
|
45295
|
+
if (await pathExists(resolve40(input.worktreePath, tree))) {
|
|
45092
45296
|
return { reason: "present", key: plan.key };
|
|
45093
45297
|
}
|
|
45094
45298
|
}
|
|
45095
|
-
const entry =
|
|
45299
|
+
const entry = resolve40(input.storeRoot, plan.key);
|
|
45096
45300
|
if (!await isDirectory(entry))
|
|
45097
45301
|
return { reason: "cold", key: plan.key };
|
|
45098
45302
|
const [storeDevice, checkoutDevice] = await Promise.all([
|
|
@@ -45102,19 +45306,19 @@ async function seedWarmNodeModules(input) {
|
|
|
45102
45306
|
if (storeDevice === void 0 || storeDevice !== checkoutDevice) {
|
|
45103
45307
|
return { reason: "cross-device", key: plan.key };
|
|
45104
45308
|
}
|
|
45105
|
-
const staging =
|
|
45309
|
+
const staging = resolve40(input.storeRoot, `${STAGING_PREFIX}${process.pid}.${randomUUID14()}`);
|
|
45106
45310
|
const placed = [];
|
|
45107
45311
|
const now2 = (input.now ?? Date.now)();
|
|
45108
45312
|
try {
|
|
45109
45313
|
await sweepStaleStaging(input.storeRoot, now2);
|
|
45110
45314
|
await utimes(entry, now2 / 1e3, now2 / 1e3).catch(() => void 0);
|
|
45111
45315
|
for (const tree of plan.trees) {
|
|
45112
|
-
await cloneTree(
|
|
45316
|
+
await cloneTree(resolve40(entry, tree), resolve40(staging, tree), seedFile);
|
|
45113
45317
|
}
|
|
45114
45318
|
for (const tree of plan.trees) {
|
|
45115
|
-
const target =
|
|
45319
|
+
const target = resolve40(input.worktreePath, tree);
|
|
45116
45320
|
await mkdir26(dirname25(target), { recursive: true });
|
|
45117
|
-
await rename11(
|
|
45321
|
+
await rename11(resolve40(staging, tree), target);
|
|
45118
45322
|
placed.push(target);
|
|
45119
45323
|
}
|
|
45120
45324
|
return { reason: "seeded", key: plan.key };
|
|
@@ -45132,11 +45336,11 @@ async function harvestWarmNodeModules(input) {
|
|
|
45132
45336
|
if (isPlanRefusal(plan)) {
|
|
45133
45337
|
return { reason: plan.failure, ...plan.detail ? { detail: plan.detail } : {} };
|
|
45134
45338
|
}
|
|
45135
|
-
const entry =
|
|
45339
|
+
const entry = resolve40(input.storeRoot, plan.key);
|
|
45136
45340
|
if (await pathExists(entry))
|
|
45137
45341
|
return { reason: "already-warm", key: plan.key };
|
|
45138
45342
|
for (const tree of plan.trees) {
|
|
45139
|
-
if (!await isDirectory(
|
|
45343
|
+
if (!await isDirectory(resolve40(input.worktreePath, tree))) {
|
|
45140
45344
|
return { reason: "no-node-modules", key: plan.key, detail: tree };
|
|
45141
45345
|
}
|
|
45142
45346
|
}
|
|
@@ -45148,12 +45352,12 @@ async function harvestWarmNodeModules(input) {
|
|
|
45148
45352
|
detail: `${missing.length} absent, e.g. ${missing.slice(0, 3).join(", ")}`
|
|
45149
45353
|
};
|
|
45150
45354
|
}
|
|
45151
|
-
const staging =
|
|
45355
|
+
const staging = resolve40(input.storeRoot, `${STAGING_PREFIX}${process.pid}.${randomUUID14()}`);
|
|
45152
45356
|
try {
|
|
45153
45357
|
await mkdir26(input.storeRoot, { recursive: true, mode: 493 });
|
|
45154
45358
|
await sweepStaleStaging(input.storeRoot, (input.now ?? Date.now)());
|
|
45155
45359
|
for (const tree of plan.trees) {
|
|
45156
|
-
await cloneTree(
|
|
45360
|
+
await cloneTree(resolve40(input.worktreePath, tree), resolve40(staging, tree), harvestFile);
|
|
45157
45361
|
}
|
|
45158
45362
|
await input.onCopied?.();
|
|
45159
45363
|
if (!await stagedTreeIsPublishable(input.worktreePath, staging, plan.key)) {
|
|
@@ -45176,16 +45380,16 @@ async function stagedTreeIsPublishable(worktreePath, staging, key) {
|
|
|
45176
45380
|
return false;
|
|
45177
45381
|
const hidden = join19("node_modules", ".package-lock.json");
|
|
45178
45382
|
const [copied, current] = await Promise.all([
|
|
45179
|
-
|
|
45180
|
-
|
|
45383
|
+
readFile32(resolve40(staging, hidden)).catch(() => void 0),
|
|
45384
|
+
readFile32(resolve40(worktreePath, hidden)).catch(() => void 0)
|
|
45181
45385
|
]);
|
|
45182
45386
|
if (!copied || !current || !copied.equals(current))
|
|
45183
45387
|
return false;
|
|
45184
45388
|
return (await missingInstalledPackages(worktreePath, staging)).length === 0;
|
|
45185
45389
|
}
|
|
45186
45390
|
async function missingInstalledPackages(worktreePath, treeRoot = worktreePath) {
|
|
45187
|
-
const wanted = parseLockfilePackages(await
|
|
45188
|
-
const installed = parseLockfilePackages(await
|
|
45391
|
+
const wanted = parseLockfilePackages(await readFile32(resolve40(worktreePath, "package-lock.json")).catch(() => void 0));
|
|
45392
|
+
const installed = parseLockfilePackages(await readFile32(resolve40(treeRoot, "node_modules", ".package-lock.json")).catch(() => void 0));
|
|
45189
45393
|
if (!wanted)
|
|
45190
45394
|
return ["package-lock.json is unreadable"];
|
|
45191
45395
|
if (!installed)
|
|
@@ -45205,7 +45409,7 @@ async function missingInstalledPackages(worktreePath, treeRoot = worktreePath) {
|
|
|
45205
45409
|
required.push(path);
|
|
45206
45410
|
}
|
|
45207
45411
|
await mapWithLimit(required, INTEGRITY_READ_CONCURRENCY, async (path) => {
|
|
45208
|
-
if (!(path in installed) || !await isInstalledPackage(
|
|
45412
|
+
if (!(path in installed) || !await isInstalledPackage(resolve40(treeRoot, path))) {
|
|
45209
45413
|
missing.push(path);
|
|
45210
45414
|
}
|
|
45211
45415
|
});
|
|
@@ -45245,7 +45449,7 @@ function isContainedTreePath(value) {
|
|
|
45245
45449
|
}
|
|
45246
45450
|
async function cloneTree(source, target, file, topLevel = true) {
|
|
45247
45451
|
await mkdir26(target, { recursive: true, mode: 493 });
|
|
45248
|
-
for (const entry of await
|
|
45452
|
+
for (const entry of await readdir12(source, { withFileTypes: true })) {
|
|
45249
45453
|
const from = join19(source, entry.name);
|
|
45250
45454
|
const to = join19(target, entry.name);
|
|
45251
45455
|
if (entry.isSymbolicLink()) {
|
|
@@ -45274,10 +45478,10 @@ var seedFile = async (source, target, topLevel) => {
|
|
|
45274
45478
|
await chmod10(target, 420);
|
|
45275
45479
|
};
|
|
45276
45480
|
async function pruneWarmStore(storeRoot, keep) {
|
|
45277
|
-
const names = (await
|
|
45481
|
+
const names = (await readdir12(storeRoot).catch(() => [])).filter((name) => !name.startsWith(STAGING_PREFIX));
|
|
45278
45482
|
const entries = [];
|
|
45279
45483
|
for (const name of names) {
|
|
45280
|
-
const info = await
|
|
45484
|
+
const info = await lstat8(join19(storeRoot, name)).catch(() => void 0);
|
|
45281
45485
|
if (info?.isDirectory())
|
|
45282
45486
|
entries.push({ name, usedAt: info.mtimeMs });
|
|
45283
45487
|
}
|
|
@@ -45288,19 +45492,19 @@ async function pruneWarmStore(storeRoot, keep) {
|
|
|
45288
45492
|
return dropped.map((entry) => entry.name);
|
|
45289
45493
|
}
|
|
45290
45494
|
async function sweepStaleStaging(storeRoot, now2) {
|
|
45291
|
-
const entries = await
|
|
45495
|
+
const entries = await readdir12(storeRoot).catch(() => []);
|
|
45292
45496
|
for (const name of entries) {
|
|
45293
45497
|
if (!name.startsWith(STAGING_PREFIX))
|
|
45294
45498
|
continue;
|
|
45295
45499
|
const path = join19(storeRoot, name);
|
|
45296
|
-
const info = await
|
|
45500
|
+
const info = await lstat8(path).catch(() => void 0);
|
|
45297
45501
|
if (!info || now2 - info.mtimeMs < STAGING_SWEEP_MS)
|
|
45298
45502
|
continue;
|
|
45299
45503
|
await rm18(path, { recursive: true, force: true }).catch(() => void 0);
|
|
45300
45504
|
}
|
|
45301
45505
|
}
|
|
45302
45506
|
async function pathExists(path) {
|
|
45303
|
-
return
|
|
45507
|
+
return lstat8(path).then(() => true, () => false);
|
|
45304
45508
|
}
|
|
45305
45509
|
async function deviceOf(path) {
|
|
45306
45510
|
return stat11(path).then((info) => info.dev, () => void 0);
|
|
@@ -45863,7 +46067,7 @@ var MonolithCornerTurnLoop = class {
|
|
|
45863
46067
|
this.options.api.execute("getCornerRestoreState", { cornerId: this.options.cornerId })
|
|
45864
46068
|
]);
|
|
45865
46069
|
const { hostRoutes: grantedHostRoutes, devices: grantedDevices, isolatedCategories } = grants;
|
|
45866
|
-
const privateAssetRoot =
|
|
46070
|
+
const privateAssetRoot = resolve41(runtimeDirectory(this.options.runtime.supervisorRoot, this.options.runtime.agent.publicKey), "private-assets");
|
|
45867
46071
|
const self = roster.members.find((member) => member.identityId === this.agent.publicKey);
|
|
45868
46072
|
const opener = this.options.openedBy ? roster.members.find((member) => member.identityId === this.options.openedBy) : void 0;
|
|
45869
46073
|
const reviewer = Boolean(this.options.repository) && configuration.isReviewer === true;
|
|
@@ -45987,12 +46191,12 @@ var MonolithCornerTurnLoop = class {
|
|
|
45987
46191
|
await prepareCodexCacheTargets(homeOverlay.CODEX_HOME);
|
|
45988
46192
|
if (assets && homeOverlay.HOME)
|
|
45989
46193
|
await preparePackageCacheTargets(homeOverlay.HOME);
|
|
45990
|
-
const cargoTargetDir =
|
|
46194
|
+
const cargoTargetDir = resolve41(this.options.worktreePath, ".beeline-cargo-target");
|
|
45991
46195
|
const npmCacheDir = cacheEnv.npm_config_cache ?? sharedNpmCacheDir(this.options.runtime.supervisorRoot);
|
|
45992
46196
|
const pnpmStoreDir = cacheEnv.PNPM_CONFIG_STORE_DIR ?? sharedPnpmStoreDir(this.options.runtime.supervisorRoot);
|
|
45993
46197
|
const turboCacheDir = cacheEnv.TURBO_CACHE_DIR ?? sharedTurboCacheDir(this.options.runtime.supervisorRoot);
|
|
45994
|
-
const modelCacheDir = cacheEnv.HF_HUB_CACHE ??
|
|
45995
|
-
const hfHomeDir = assets && this.options.config.agentHomeRoot ?
|
|
46198
|
+
const modelCacheDir = cacheEnv.HF_HUB_CACHE ?? resolve41(this.options.runtime.supervisorRoot, "beeline", "model-cache");
|
|
46199
|
+
const hfHomeDir = assets && this.options.config.agentHomeRoot ? resolve41(this.options.config.agentHomeRoot, "cache/huggingface-private") : modelCacheDir;
|
|
45996
46200
|
await Promise.all([npmCacheDir, pnpmStoreDir, cargoTargetDir, turboCacheDir, modelCacheDir].map((path) => mkdir27(path, { recursive: true, mode: 448 })));
|
|
45997
46201
|
const agentEnv = {
|
|
45998
46202
|
...this.options.config.agentEnv,
|
|
@@ -46004,7 +46208,7 @@ var MonolithCornerTurnLoop = class {
|
|
|
46004
46208
|
...cacheEnv,
|
|
46005
46209
|
...androidAssets && this.options.config.agentHomeRoot ? {
|
|
46006
46210
|
ANDROID_AVD_HOME: androidAssets.avdBase,
|
|
46007
|
-
ANDROID_EMULATOR_HOME:
|
|
46211
|
+
ANDROID_EMULATOR_HOME: resolve41(this.options.config.agentHomeRoot, "android-emulator")
|
|
46008
46212
|
} : {},
|
|
46009
46213
|
npm_config_cache: npmCacheDir,
|
|
46010
46214
|
// pnpm reads its settings from PNPM_CONFIG_* environment variables and
|
|
@@ -46015,14 +46219,14 @@ var MonolithCornerTurnLoop = class {
|
|
|
46015
46219
|
HF_HOME: hfHomeDir,
|
|
46016
46220
|
HUGGINGFACE_HUB_CACHE: assets || isolatedCategories.includes("package-cache") ? modelCacheDir : join20(modelCacheDir, "hub"),
|
|
46017
46221
|
...assets && androidAssets && this.options.config.agentHomeRoot ? {
|
|
46018
|
-
BEELINE_ANDROID_LEASE_ROOT:
|
|
46019
|
-
BEELINE_ANDROID_INSTANCE_ROOT:
|
|
46222
|
+
BEELINE_ANDROID_LEASE_ROOT: resolve41(assets.cache, "android-leases"),
|
|
46223
|
+
BEELINE_ANDROID_INSTANCE_ROOT: resolve41(this.options.config.agentHomeRoot, "android-instances"),
|
|
46020
46224
|
BEELINE_ANDROID_BASE_AVD_HOME: androidAssets.avdBase,
|
|
46021
|
-
BEELINE_ANDROID_EMULATOR_BINARY:
|
|
46225
|
+
BEELINE_ANDROID_EMULATOR_BINARY: resolve41(homeOverlay.ANDROID_HOME, "emulator/emulator")
|
|
46022
46226
|
} : {}
|
|
46023
46227
|
};
|
|
46024
46228
|
if (toolchain && assets) {
|
|
46025
|
-
agentEnv.PATH = `${
|
|
46229
|
+
agentEnv.PATH = `${resolve41(toolchain.binDir, "../../bin")}:${toolchain.binDir}:${agentEnv.PATH ?? ""}`;
|
|
46026
46230
|
if (this.options.config.agentKind === "pi")
|
|
46027
46231
|
agentEnv.PI_ACP_PI_COMMAND = toolchain.cliCommand;
|
|
46028
46232
|
}
|
|
@@ -46286,7 +46490,7 @@ var MonolithCornerTurnLoop = class {
|
|
|
46286
46490
|
briefRevision: restore.brief?.revision
|
|
46287
46491
|
}),
|
|
46288
46492
|
...this.options.config.agentHomeRoot && this.options.config.agentKind && !AGENT_SKILL_DIRS.includes(this.options.config.agentKind) ? [
|
|
46289
|
-
`This harness has no verified native skill discovery. Read the release-managed review procedure at ${
|
|
46493
|
+
`This harness has no verified native skill discovery. Read the release-managed review procedure at ${resolve41(this.options.config.agentHomeRoot, "codex", "skills", "beeline-review", "SKILL.md")} before the verdict.`
|
|
46290
46494
|
] : []
|
|
46291
46495
|
].join("\n");
|
|
46292
46496
|
} catch {
|
|
@@ -46404,8 +46608,8 @@ var MonolithCornerTurnLoop = class {
|
|
|
46404
46608
|
let timer;
|
|
46405
46609
|
const stats = statsPromise && remaining > 0 ? await Promise.race([
|
|
46406
46610
|
statsPromise,
|
|
46407
|
-
new Promise((
|
|
46408
|
-
timer = setTimeout(() =>
|
|
46611
|
+
new Promise((resolve53) => {
|
|
46612
|
+
timer = setTimeout(() => resolve53(void 0), remaining);
|
|
46409
46613
|
})
|
|
46410
46614
|
]).finally(() => {
|
|
46411
46615
|
if (timer)
|
|
@@ -46470,7 +46674,7 @@ var MonolithCornerTurnLoop = class {
|
|
|
46470
46674
|
const briefDelivered = this.attachmentDir && briefAttachments.length ? await deliverAttachments(briefAttachments, join20(this.attachmentDir, requestId.replace(/[^\w-]/g, "_"), "brief", String(assignedBrief.revision)), this.options.fetchImpl) : [];
|
|
46471
46675
|
briefFileLines = await Promise.all((assignedBrief?.attachments ?? []).map(async (file, index) => {
|
|
46472
46676
|
const entry = briefDelivered.find((item) => item.attachment === briefAttachments[index]);
|
|
46473
|
-
const verified = entry?.path && createHash16("sha256").update(await
|
|
46677
|
+
const verified = entry?.path && createHash16("sha256").update(await readFile33(entry.path)).digest("hex") === file.sha256;
|
|
46474
46678
|
return `- ${file.title} (${file.purpose}; ${file.required ? "required" : "optional"}; sha256 ${file.sha256}): ${verified ? entry.path : "UNAVAILABLE OR CONTENT MISMATCH"}`;
|
|
46475
46679
|
}));
|
|
46476
46680
|
missingRequiredBriefFile = (assignedBrief?.attachments ?? []).some((file, index) => file.required && briefFileLines[index]?.includes("UNAVAILABLE OR CONTENT MISMATCH"));
|
|
@@ -46908,13 +47112,13 @@ ${continuation}` : assembled;
|
|
|
46908
47112
|
if (this.harvest || !this.options.repository || this.options.config.agentSharedAssetRoot)
|
|
46909
47113
|
return;
|
|
46910
47114
|
const { cornerId, worktreePath, runtime } = this.options;
|
|
46911
|
-
const mobilePath =
|
|
47115
|
+
const mobilePath = resolve41(worktreePath, "apps/mobile");
|
|
46912
47116
|
const jobs = [
|
|
46913
47117
|
harvestWarmNodeModules({
|
|
46914
47118
|
worktreePath,
|
|
46915
47119
|
storeRoot: warmNodeModulesStoreDir(runtime.supervisorRoot)
|
|
46916
47120
|
}),
|
|
46917
|
-
...existsSync9(
|
|
47121
|
+
...existsSync9(resolve41(mobilePath, "package-lock.json")) ? [
|
|
46918
47122
|
harvestWarmNodeModules({
|
|
46919
47123
|
worktreePath: mobilePath,
|
|
46920
47124
|
storeRoot: mobileNodeModulesStoreDir(runtime.supervisorRoot)
|
|
@@ -46962,7 +47166,7 @@ ${continuation}` : assembled;
|
|
|
46962
47166
|
const delay = outage ? Math.min(2e3 * 2 ** attempt, 3e4) : 250 * (attempt + 1);
|
|
46963
47167
|
if ((outage ? Date.now() + delay > outageDeadline : attempt === 2) || this.forcedStop || this.currentTurn && this.stoppedTurns.has(this.currentTurn.requestId))
|
|
46964
47168
|
throw error;
|
|
46965
|
-
await new Promise((
|
|
47169
|
+
await new Promise((resolve53) => setTimeout(resolve53, delay));
|
|
46966
47170
|
}
|
|
46967
47171
|
}
|
|
46968
47172
|
if (!token)
|
|
@@ -47062,8 +47266,8 @@ ${continuation}` : assembled;
|
|
|
47062
47266
|
|
|
47063
47267
|
// apps/body/dist/corner-disk-recovery.js
|
|
47064
47268
|
import { execFile as execFile18 } from "node:child_process";
|
|
47065
|
-
import { lstat as
|
|
47066
|
-
import { basename as basename10, dirname as dirname27, join as join21, relative as relative3, resolve as
|
|
47269
|
+
import { lstat as lstat9, readdir as readdir13, realpath as realpath3, rm as rm19 } from "node:fs/promises";
|
|
47270
|
+
import { basename as basename10, dirname as dirname27, join as join21, relative as relative3, resolve as resolve42, sep as sep3 } from "node:path";
|
|
47067
47271
|
import { promisify as promisify12 } from "node:util";
|
|
47068
47272
|
var execFileAsync12 = promisify12(execFile18);
|
|
47069
47273
|
var GENERATED_DIRS = /* @__PURE__ */ new Set([
|
|
@@ -47078,11 +47282,11 @@ var GENERATED_DIRS = /* @__PURE__ */ new Set([
|
|
|
47078
47282
|
var MAX_DIRECTORY_DEPTH = 4;
|
|
47079
47283
|
var MAX_VISITED_DIRECTORIES = 5e3;
|
|
47080
47284
|
function cornerRecoveryPointerPath(worktree) {
|
|
47081
|
-
const checkout =
|
|
47285
|
+
const checkout = resolve42(worktree.path);
|
|
47082
47286
|
if (basename10(checkout) !== worktree.cornerId || basename10(dirname27(checkout)) !== "corners" || basename10(dirname27(dirname27(checkout))) !== "beeline" || !/^[a-zA-Z0-9-]{1,80}$/.test(worktree.cornerId)) {
|
|
47083
47287
|
throw new Error("refusing recovery pointer outside a Beeline corner checkout");
|
|
47084
47288
|
}
|
|
47085
|
-
return
|
|
47289
|
+
return resolve42(dirname27(dirname27(checkout)), "recovery", "corners", `${worktree.cornerId}.json`);
|
|
47086
47290
|
}
|
|
47087
47291
|
async function git(checkout, args) {
|
|
47088
47292
|
const result = await execFileAsync12("git", ["-C", checkout, ...args], {
|
|
@@ -47100,9 +47304,9 @@ async function ignoredAndUntracked(checkout, path) {
|
|
|
47100
47304
|
return !(await git(checkout, ["ls-files", "--", rel])).trim();
|
|
47101
47305
|
}
|
|
47102
47306
|
async function preserveUnpublishedCornerWorktree(worktree, reason) {
|
|
47103
|
-
const checkout =
|
|
47307
|
+
const checkout = resolve42(worktree.path);
|
|
47104
47308
|
const pointer = cornerRecoveryPointerPath(worktree);
|
|
47105
|
-
const info = await
|
|
47309
|
+
const info = await lstat9(checkout);
|
|
47106
47310
|
if (!info.isDirectory() || await realpath3(checkout) !== checkout) {
|
|
47107
47311
|
throw new Error("refusing to prune a non-canonical corner checkout");
|
|
47108
47312
|
}
|
|
@@ -47126,7 +47330,7 @@ async function preserveUnpublishedCornerWorktree(worktree, reason) {
|
|
|
47126
47330
|
break;
|
|
47127
47331
|
if (current.depth >= MAX_DIRECTORY_DEPTH)
|
|
47128
47332
|
continue;
|
|
47129
|
-
for (const entry of await
|
|
47333
|
+
for (const entry of await readdir13(current.path, { withFileTypes: true })) {
|
|
47130
47334
|
if (!entry.isDirectory() || entry.name === ".git")
|
|
47131
47335
|
continue;
|
|
47132
47336
|
const path = join21(current.path, entry.name);
|
|
@@ -47662,7 +47866,7 @@ function cornerStartConfigKey(repository, objective) {
|
|
|
47662
47866
|
function cornerRepositoryCacheDir(supervisorRoot2, remote) {
|
|
47663
47867
|
const normalizedRemote = roomCheckoutRemote(remote);
|
|
47664
47868
|
const repositoryHash = createHash17("sha256").update(normalizedRemote).digest("hex").slice(0, 24);
|
|
47665
|
-
return
|
|
47869
|
+
return resolve43(supervisorRoot2, "beeline", "repositories", `${repositoryHash}.git`);
|
|
47666
47870
|
}
|
|
47667
47871
|
function isStandingCornerStartFault(error) {
|
|
47668
47872
|
const text2 = error instanceof Error ? error.message : String(error);
|
|
@@ -47671,11 +47875,11 @@ function isStandingCornerStartFault(error) {
|
|
|
47671
47875
|
async function materializeCornerWorktree(input) {
|
|
47672
47876
|
const remote = roomCheckoutRemote(input.remote);
|
|
47673
47877
|
const gitCommonDir = cornerRepositoryCacheDir(input.supervisorRoot, remote);
|
|
47674
|
-
const path =
|
|
47878
|
+
const path = resolve43(input.supervisorRoot, "beeline", "corners", input.cornerId);
|
|
47675
47879
|
await mkdir28(dirname28(gitCommonDir), { recursive: true, mode: 448 });
|
|
47676
47880
|
await mkdir28(dirname28(path), { recursive: true, mode: 448 });
|
|
47677
47881
|
const authEnv = githubGitEnv(input.token);
|
|
47678
|
-
if (!existsSync10(
|
|
47882
|
+
if (!existsSync10(resolve43(gitCommonDir, "HEAD"))) {
|
|
47679
47883
|
await execFileAsync13("git", ["clone", "--bare", remote, gitCommonDir], {
|
|
47680
47884
|
env: authEnv,
|
|
47681
47885
|
maxBuffer: 4 * 1024 * 1024
|
|
@@ -47698,7 +47902,7 @@ async function materializeCornerWorktree(input) {
|
|
|
47698
47902
|
return false;
|
|
47699
47903
|
throw error;
|
|
47700
47904
|
});
|
|
47701
|
-
if (!existsSync10(
|
|
47905
|
+
if (!existsSync10(resolve43(path, ".git"))) {
|
|
47702
47906
|
await rm20(path, { recursive: true, force: true });
|
|
47703
47907
|
await execFileAsync13("git", [
|
|
47704
47908
|
`--git-dir=${gitCommonDir}`,
|
|
@@ -47716,8 +47920,8 @@ async function materializeCornerWorktree(input) {
|
|
|
47716
47920
|
if (seed.reason !== "no-lockfile") {
|
|
47717
47921
|
console.log(`[thin-core] corner ${input.cornerId} warm node_modules: ${seed.reason}${seed.detail ? ` (${seed.detail})` : ""}`);
|
|
47718
47922
|
}
|
|
47719
|
-
const mobilePath =
|
|
47720
|
-
if (existsSync10(
|
|
47923
|
+
const mobilePath = resolve43(path, "apps/mobile");
|
|
47924
|
+
if (existsSync10(resolve43(mobilePath, "package-lock.json"))) {
|
|
47721
47925
|
const mobileSeed = input.workspaceId ? { reason: "no-lockfile" } : await seedWarmNodeModules({
|
|
47722
47926
|
worktreePath: mobilePath,
|
|
47723
47927
|
storeRoot: mobileNodeModulesStoreDir(input.supervisorRoot)
|
|
@@ -47775,9 +47979,9 @@ async function mapWithConcurrency(values, limit, visit) {
|
|
|
47775
47979
|
}));
|
|
47776
47980
|
}
|
|
47777
47981
|
async function discoverCornerWorktree(supervisorRoot2, cornerId) {
|
|
47778
|
-
const cornersRoot =
|
|
47779
|
-
const path =
|
|
47780
|
-
if (dirname28(path) !== cornersRoot || !existsSync10(
|
|
47982
|
+
const cornersRoot = resolve43(supervisorRoot2, "beeline", "corners");
|
|
47983
|
+
const path = resolve43(cornersRoot, cornerId);
|
|
47984
|
+
if (dirname28(path) !== cornersRoot || !existsSync10(resolve43(path, ".git")))
|
|
47781
47985
|
return void 0;
|
|
47782
47986
|
const [canonicalRoot, canonicalPath] = await Promise.all([
|
|
47783
47987
|
realpath4(cornersRoot),
|
|
@@ -47789,8 +47993,8 @@ async function discoverCornerWorktree(supervisorRoot2, cornerId) {
|
|
|
47789
47993
|
const common = await execFileAsync13("git", ["-C", path, "rev-parse", "--git-common-dir"]).catch(() => void 0);
|
|
47790
47994
|
if (!common)
|
|
47791
47995
|
return void 0;
|
|
47792
|
-
const gitCommonDir =
|
|
47793
|
-
const repositoriesRoot =
|
|
47996
|
+
const gitCommonDir = resolve43(path, common.stdout.trim());
|
|
47997
|
+
const repositoriesRoot = resolve43(supervisorRoot2, "beeline", "repositories");
|
|
47794
47998
|
const commonRelative = relative4(repositoriesRoot, gitCommonDir);
|
|
47795
47999
|
if (!commonRelative || commonRelative === ".." || commonRelative.startsWith(`..${sep4}`) || commonRelative.startsWith(sep4)) {
|
|
47796
48000
|
throw new Error(`refusing corner ${cornerId} with git directory outside repository cache`);
|
|
@@ -47798,8 +48002,8 @@ async function discoverCornerWorktree(supervisorRoot2, cornerId) {
|
|
|
47798
48002
|
return { path, gitCommonDir };
|
|
47799
48003
|
}
|
|
47800
48004
|
async function localCornerWorktreeIds(supervisorRoot2) {
|
|
47801
|
-
const root =
|
|
47802
|
-
const entries = await
|
|
48005
|
+
const root = resolve43(supervisorRoot2, "beeline", "corners");
|
|
48006
|
+
const entries = await readdir14(root, { withFileTypes: true }).catch((error) => {
|
|
47803
48007
|
if (error.code === "ENOENT")
|
|
47804
48008
|
return [];
|
|
47805
48009
|
throw error;
|
|
@@ -47904,14 +48108,14 @@ async function originContains(gitCommonDir, head) {
|
|
|
47904
48108
|
}
|
|
47905
48109
|
var execFileAsync13 = promisify13(execFile19);
|
|
47906
48110
|
async function removeCornerScratchWorkspace(input) {
|
|
47907
|
-
const expected =
|
|
47908
|
-
if (
|
|
48111
|
+
const expected = resolve43(input.roomRoot, "scratch");
|
|
48112
|
+
if (resolve43(input.scratchPath) !== expected) {
|
|
47909
48113
|
throw new Error(`refusing to remove scratch outside corner ${input.cornerId}`);
|
|
47910
48114
|
}
|
|
47911
|
-
for (const entry of await
|
|
48115
|
+
for (const entry of await readdir14(expected, { withFileTypes: true }).catch(() => [])) {
|
|
47912
48116
|
if (entry.name === "agent-home" || entry.name === "agent-private")
|
|
47913
48117
|
continue;
|
|
47914
|
-
await rm20(
|
|
48118
|
+
await rm20(resolve43(expected, entry.name), { recursive: true, force: true });
|
|
47915
48119
|
}
|
|
47916
48120
|
}
|
|
47917
48121
|
var RoomRuntimeCoordinator = class {
|
|
@@ -47930,8 +48134,8 @@ var RoomRuntimeCoordinator = class {
|
|
|
47930
48134
|
localWorktreeIds;
|
|
47931
48135
|
/** Event-driven cleanup retries stay scoped to the failed local corner. */
|
|
47932
48136
|
archiveCleanupFaults = /* @__PURE__ */ new Map();
|
|
47933
|
-
/** A
|
|
47934
|
-
|
|
48137
|
+
/** A non-retryable refusal parks this local checkout for the rest of this core's lifetime. */
|
|
48138
|
+
archiveCleanupRefused = /* @__PURE__ */ new Set();
|
|
47935
48139
|
/**
|
|
47936
48140
|
* A corner whose branch cleanup found commits no origin ref contains. That
|
|
47937
48141
|
* is never transient - nothing pushes them later - so retrying it every
|
|
@@ -48387,13 +48591,13 @@ var RoomRuntimeCoordinator = class {
|
|
|
48387
48591
|
return this.runtime.rooms.find((room) => room.channelId === roomId);
|
|
48388
48592
|
}
|
|
48389
48593
|
roomRoot(roomId) {
|
|
48390
|
-
return this.roomRecord(roomId)?.root ??
|
|
48594
|
+
return this.roomRecord(roomId)?.root ?? resolve43(dirname28(this.configPath), "rooms", roomId);
|
|
48391
48595
|
}
|
|
48392
48596
|
roomAgentHomeRoot(workspaceRoot, required = false) {
|
|
48393
48597
|
const flag = process.env.BUZZY_BODY_ROOM_HOME;
|
|
48394
48598
|
if (!required && flag === "0")
|
|
48395
48599
|
return void 0;
|
|
48396
|
-
const home =
|
|
48600
|
+
const home = resolve43(workspaceRoot, "agent-home");
|
|
48397
48601
|
if (!required && flag !== "1" && !existsSync10(home) && existsSync10(workspaceRoot))
|
|
48398
48602
|
return void 0;
|
|
48399
48603
|
try {
|
|
@@ -48410,8 +48614,8 @@ var RoomRuntimeCoordinator = class {
|
|
|
48410
48614
|
...this.baseConfig,
|
|
48411
48615
|
workspaceRoot,
|
|
48412
48616
|
...process.env.BEELINE_SHARED_ASSETS_ENABLED === "0" ? { agentSharedAssetRoot: void 0 } : { agentSharedAssetRoot: workspaceAssetRoot(this.runtime.supervisorRoot, this.runtime.communityId) },
|
|
48413
|
-
agentPrivateRoot:
|
|
48414
|
-
agentMemoryRoot:
|
|
48617
|
+
agentPrivateRoot: resolve43(workspaceRoot, "agent-private"),
|
|
48618
|
+
agentMemoryRoot: resolve43(dirname28(this.configPath), "memory"),
|
|
48415
48619
|
openRouterRoutingCacheDir: openRouterRoutingCacheDir(dirname28(this.configPath)),
|
|
48416
48620
|
turnTraceDir: turnTraceDirectory(dirname28(this.configPath)),
|
|
48417
48621
|
...agentHomeRoot ? { agentHomeRoot } : {}
|
|
@@ -48494,11 +48698,11 @@ var RoomRuntimeCoordinator = class {
|
|
|
48494
48698
|
const remote = roomCheckoutRemote(repository.remote);
|
|
48495
48699
|
const targetBranch = repository.targetBranch || "main";
|
|
48496
48700
|
const checkoutId = createHash17("sha256").update(`${roomId}\0${remote}\0${targetBranch}`).digest("hex").slice(0, 24);
|
|
48497
|
-
const path =
|
|
48701
|
+
const path = resolve43(this.runtime.supervisorRoot, "beeline", "room-checkouts", checkoutId);
|
|
48498
48702
|
await mkdir28(dirname28(path), { recursive: true, mode: 448 });
|
|
48499
48703
|
const token = remote.startsWith("https://github.com/") ? await this.parentRepositoryToken(roomId) : void 0;
|
|
48500
48704
|
const env = token ? githubGitEnv(token.token) : process.env;
|
|
48501
|
-
if (!existsSync10(
|
|
48705
|
+
if (!existsSync10(resolve43(path, ".git"))) {
|
|
48502
48706
|
await execFileAsync13("git", ["clone", "--no-checkout", remote, path], {
|
|
48503
48707
|
env,
|
|
48504
48708
|
maxBuffer: 4 * 1024 * 1024
|
|
@@ -48585,10 +48789,10 @@ var RoomRuntimeCoordinator = class {
|
|
|
48585
48789
|
featureBranch,
|
|
48586
48790
|
token: granted.token
|
|
48587
48791
|
}) : void 0;
|
|
48588
|
-
const workspacePath = worktree?.path ??
|
|
48792
|
+
const workspacePath = worktree?.path ?? resolve43(this.roomRoot(corner.cornerId), "scratch");
|
|
48589
48793
|
if (!worktree)
|
|
48590
48794
|
await mkdir28(workspacePath, { recursive: true, mode: 448 });
|
|
48591
|
-
await writePrivateFileAtomically(
|
|
48795
|
+
await writePrivateFileAtomically(resolve43(this.roomRoot(corner.cornerId), ".beeline-corner.json"), `${JSON.stringify({ cornerId: corner.cornerId, parentRoomId: corner.parentRoomId })}
|
|
48592
48796
|
`);
|
|
48593
48797
|
if (worktree && shouldPostInitialCornerWorkingState(restore)) {
|
|
48594
48798
|
await this.options.daemonApi.execute("postCornerRemoteState", {
|
|
@@ -48913,7 +49117,7 @@ var RoomRuntimeCoordinator = class {
|
|
|
48913
49117
|
this.archiveCleanupAbandoned.delete(cornerId);
|
|
48914
49118
|
continue;
|
|
48915
49119
|
}
|
|
48916
|
-
if (this.archiveCleanupAbandoned.has(cornerId))
|
|
49120
|
+
if (this.archiveCleanupAbandoned.has(cornerId) || this.archiveCleanupRefused.has(cornerId))
|
|
48917
49121
|
continue;
|
|
48918
49122
|
if (!this.archiveCleanupDue(cornerId))
|
|
48919
49123
|
continue;
|
|
@@ -48931,7 +49135,10 @@ var RoomRuntimeCoordinator = class {
|
|
|
48931
49135
|
console.error(`[thin-core] corner ${cornerId} branch cleanup abandoned; unpublished work kept:`, error);
|
|
48932
49136
|
continue;
|
|
48933
49137
|
}
|
|
48934
|
-
|
|
49138
|
+
if (error instanceof DaemonApiError && error.status >= 400 && error.status < 500 && !error.retryable)
|
|
49139
|
+
this.archiveCleanupRefused.add(cornerId);
|
|
49140
|
+
else
|
|
49141
|
+
this.deferArchiveCleanup(cornerId);
|
|
48935
49142
|
console.error(`[thin-core] corner ${cornerId} branch cleanup retry failed:`, error);
|
|
48936
49143
|
}
|
|
48937
49144
|
}
|
|
@@ -48950,9 +49157,8 @@ var RoomRuntimeCoordinator = class {
|
|
|
48950
49157
|
continue;
|
|
48951
49158
|
if (this.archiveCleanupAbandoned.has(cornerId))
|
|
48952
49159
|
continue;
|
|
48953
|
-
if (this.
|
|
49160
|
+
if (this.archiveCleanupRefused.has(cornerId))
|
|
48954
49161
|
continue;
|
|
48955
|
-
this.archiveCleanupAccessDenied.delete(cornerId);
|
|
48956
49162
|
let corner = corners.get(cornerId);
|
|
48957
49163
|
let discovered;
|
|
48958
49164
|
let candidate;
|
|
@@ -48981,7 +49187,7 @@ var RoomRuntimeCoordinator = class {
|
|
|
48981
49187
|
throw new Error(`archived corner ${corner.cornerId} has no authoritative repository`);
|
|
48982
49188
|
}
|
|
48983
49189
|
const expectedCommonDir = cornerRepositoryCacheDir(this.runtime.supervisorRoot, repository.remote);
|
|
48984
|
-
if (
|
|
49190
|
+
if (resolve43(discovered.gitCommonDir) !== expectedCommonDir) {
|
|
48985
49191
|
throw new Error(`archived corner ${corner.cornerId} repository cache does not match`);
|
|
48986
49192
|
}
|
|
48987
49193
|
if (!restore.featureBranch) {
|
|
@@ -49008,8 +49214,8 @@ var RoomRuntimeCoordinator = class {
|
|
|
49008
49214
|
}
|
|
49009
49215
|
continue;
|
|
49010
49216
|
}
|
|
49011
|
-
if (error instanceof DaemonApiError && error.status
|
|
49012
|
-
this.
|
|
49217
|
+
if (error instanceof DaemonApiError && error.status >= 400 && error.status < 500 && !error.retryable)
|
|
49218
|
+
this.archiveCleanupRefused.add(cornerId);
|
|
49013
49219
|
else
|
|
49014
49220
|
this.deferArchiveCleanup(cornerId);
|
|
49015
49221
|
console.error(`[thin-core] archived corner ${cornerId} cleanup deferred:`, error);
|
|
@@ -49069,10 +49275,10 @@ var RoomRuntimeCoordinator = class {
|
|
|
49069
49275
|
async cleanupArchivedCornerLocalState(cornerId, knownArchive) {
|
|
49070
49276
|
if (this.running.has(cornerId) || this.startingCorners.has(cornerId))
|
|
49071
49277
|
return false;
|
|
49072
|
-
const root =
|
|
49278
|
+
const root = resolve43(dirname28(this.configPath), "rooms", cornerId);
|
|
49073
49279
|
if (this.roomRoot(cornerId) !== root || !/^[a-zA-Z0-9-]{1,80}$/.test(cornerId))
|
|
49074
49280
|
return false;
|
|
49075
|
-
const info = await
|
|
49281
|
+
const info = await lstat10(root).catch(() => void 0);
|
|
49076
49282
|
if (!info?.isDirectory() || await realpath4(root) !== root)
|
|
49077
49283
|
return false;
|
|
49078
49284
|
let archived = knownArchive?.has(cornerId) ?? false;
|
|
@@ -49090,9 +49296,9 @@ var RoomRuntimeCoordinator = class {
|
|
|
49090
49296
|
await removeCornerScratchWorkspace({
|
|
49091
49297
|
cornerId,
|
|
49092
49298
|
roomRoot: root,
|
|
49093
|
-
scratchPath:
|
|
49299
|
+
scratchPath: resolve43(root, "scratch")
|
|
49094
49300
|
});
|
|
49095
|
-
await rm20(
|
|
49301
|
+
await rm20(resolve43(root, ".beeline-corner.json"), { force: true });
|
|
49096
49302
|
return true;
|
|
49097
49303
|
}
|
|
49098
49304
|
/** Recover chat-only scratch and per-member homes after missed close events
|
|
@@ -49100,18 +49306,18 @@ var RoomRuntimeCoordinator = class {
|
|
|
49100
49306
|
* checkout has already gone; a scratch directory identifies legacy chat
|
|
49101
49307
|
* corners. Active scratch gets a 14-day file TTL, never a wholesale reap. */
|
|
49102
49308
|
async sweepCornerLocalState(archived, desired) {
|
|
49103
|
-
const root =
|
|
49309
|
+
const root = resolve43(dirname28(this.configPath), "rooms");
|
|
49104
49310
|
const due = this.now() - this.lastCornerScratchSweepAt >= 6 * 60 * 6e4;
|
|
49105
49311
|
if (due)
|
|
49106
49312
|
this.lastCornerScratchSweepAt = this.now();
|
|
49107
|
-
for (const entry of await
|
|
49313
|
+
for (const entry of await readdir14(root, { withFileTypes: true }).catch(() => [])) {
|
|
49108
49314
|
if (!entry.isDirectory() || !/^[a-zA-Z0-9-]{1,80}$/.test(entry.name))
|
|
49109
49315
|
continue;
|
|
49110
|
-
const roomRoot =
|
|
49111
|
-
const scratch =
|
|
49112
|
-
const marker =
|
|
49113
|
-
const hasScratch = (await
|
|
49114
|
-
const hasMarker = (await
|
|
49316
|
+
const roomRoot = resolve43(root, entry.name);
|
|
49317
|
+
const scratch = resolve43(roomRoot, "scratch");
|
|
49318
|
+
const marker = resolve43(roomRoot, ".beeline-corner.json");
|
|
49319
|
+
const hasScratch = (await lstat10(scratch).catch(() => void 0))?.isDirectory() ?? false;
|
|
49320
|
+
const hasMarker = (await lstat10(marker).catch(() => void 0))?.isFile() ?? false;
|
|
49115
49321
|
if (!hasScratch && !hasMarker)
|
|
49116
49322
|
continue;
|
|
49117
49323
|
if (desired.has(entry.name)) {
|
|
@@ -49282,6 +49488,7 @@ var ThinDaemonCore = class {
|
|
|
49282
49488
|
pendingDiscovery = false;
|
|
49283
49489
|
discoveryWaiter;
|
|
49284
49490
|
discoveryStatus = "starting";
|
|
49491
|
+
progressWaiters = /* @__PURE__ */ new Set();
|
|
49285
49492
|
constructor(runtime, configPath, baseConfig, options) {
|
|
49286
49493
|
if (!runtime.transport)
|
|
49287
49494
|
throw new Error("thin daemon requires monolith transport");
|
|
@@ -49292,7 +49499,7 @@ var ThinDaemonCore = class {
|
|
|
49292
49499
|
});
|
|
49293
49500
|
}
|
|
49294
49501
|
async waitForDiscovery(signal) {
|
|
49295
|
-
if (this.pendingDiscovery || signal?.aborted)
|
|
49502
|
+
if (this.pendingDiscovery || this.progressWaiters.size || signal?.aborted)
|
|
49296
49503
|
return;
|
|
49297
49504
|
await new Promise((resolveWait) => {
|
|
49298
49505
|
const done = () => {
|
|
@@ -49302,10 +49509,17 @@ var ThinDaemonCore = class {
|
|
|
49302
49509
|
};
|
|
49303
49510
|
this.discoveryWaiter = done;
|
|
49304
49511
|
signal?.addEventListener("abort", done, { once: true });
|
|
49305
|
-
if (this.pendingDiscovery)
|
|
49512
|
+
if (this.pendingDiscovery || this.progressWaiters.size)
|
|
49306
49513
|
done();
|
|
49307
49514
|
});
|
|
49308
49515
|
}
|
|
49516
|
+
/** The existing machine watchdog tick wakes this loop without discovering Rooms. */
|
|
49517
|
+
requestWorkLoopProgress() {
|
|
49518
|
+
return new Promise((resolveProgress) => {
|
|
49519
|
+
this.progressWaiters.add(resolveProgress);
|
|
49520
|
+
this.discoveryWaiter?.();
|
|
49521
|
+
});
|
|
49522
|
+
}
|
|
49309
49523
|
activeRoomIds() {
|
|
49310
49524
|
return this.roomRuntime.activeRoomIds();
|
|
49311
49525
|
}
|
|
@@ -49369,19 +49583,25 @@ var ThinDaemonCore = class {
|
|
|
49369
49583
|
await opts.onEstablished?.();
|
|
49370
49584
|
const supervisor2 = this.roomRuntime.supervisor;
|
|
49371
49585
|
let failures = 0;
|
|
49586
|
+
let discover = true;
|
|
49372
49587
|
while (!opts.signal?.aborted) {
|
|
49373
|
-
|
|
49588
|
+
const acknowledge = [...this.progressWaiters];
|
|
49589
|
+
const shouldDiscover = discover || this.pendingDiscovery;
|
|
49590
|
+
if (shouldDiscover)
|
|
49591
|
+
this.pendingDiscovery = false;
|
|
49374
49592
|
const wakesBefore = supervisor2.wakes;
|
|
49375
49593
|
try {
|
|
49376
|
-
|
|
49377
|
-
|
|
49378
|
-
|
|
49379
|
-
|
|
49380
|
-
|
|
49594
|
+
if (shouldDiscover) {
|
|
49595
|
+
const membership = await this.roomRuntime.reconcile();
|
|
49596
|
+
if (membership === "not-member")
|
|
49597
|
+
return "agent-removed";
|
|
49598
|
+
this.discoveryStatus = membership === "unknown" ? "monolith membership degraded" : "";
|
|
49599
|
+
failures = 0;
|
|
49600
|
+
}
|
|
49381
49601
|
} catch (error) {
|
|
49382
49602
|
if (isAgentRemovedError(error))
|
|
49383
49603
|
return "agent-removed";
|
|
49384
|
-
failures
|
|
49604
|
+
failures = error instanceof DaemonApiError && !error.retryable ? supervisor2.retries + 1 : failures + 1;
|
|
49385
49605
|
console.error(failures > supervisor2.retries ? "[thin-core] discovery failed; waiting for the next live open or discovery wake:" : `[thin-core] discovery failed; retry ${failures} of ${supervisor2.retries}:`, error);
|
|
49386
49606
|
this.discoveryStatus = `monolith discovery degraded: ${error instanceof Error ? error.message : String(error)}`;
|
|
49387
49607
|
this.roomRuntime.suspectLink(error);
|
|
@@ -49389,16 +49609,24 @@ var ThinDaemonCore = class {
|
|
|
49389
49609
|
if (opts.signal?.aborted)
|
|
49390
49610
|
break;
|
|
49391
49611
|
await opts.onProgress?.(this.healthStatus());
|
|
49392
|
-
|
|
49612
|
+
for (const done of acknowledge) {
|
|
49613
|
+
this.progressWaiters.delete(done);
|
|
49614
|
+
done();
|
|
49615
|
+
}
|
|
49616
|
+
if (failures > 0 && failures <= supervisor2.retries) {
|
|
49393
49617
|
await supervisor2.retryDelay(failures, opts.signal, wakesBefore);
|
|
49394
|
-
|
|
49395
|
-
|
|
49396
|
-
|
|
49618
|
+
discover = true;
|
|
49619
|
+
} else {
|
|
49620
|
+
failures = 0;
|
|
49397
49621
|
await this.waitForDiscovery(opts.signal);
|
|
49622
|
+
discover = this.pendingDiscovery;
|
|
49398
49623
|
}
|
|
49399
49624
|
}
|
|
49400
49625
|
return "aborted";
|
|
49401
49626
|
} finally {
|
|
49627
|
+
for (const done of this.progressWaiters)
|
|
49628
|
+
done();
|
|
49629
|
+
this.progressWaiters.clear();
|
|
49402
49630
|
opts.signal?.removeEventListener("abort", stop);
|
|
49403
49631
|
await this.roomRuntime.shutdown();
|
|
49404
49632
|
}
|
|
@@ -49407,10 +49635,10 @@ var ThinDaemonCore = class {
|
|
|
49407
49635
|
|
|
49408
49636
|
// apps/body/dist/force-update-journal.js
|
|
49409
49637
|
import { mkdirSync as mkdirSync5, readFileSync as readFileSync11, renameSync as renameSync2, writeFileSync as writeFileSync5 } from "node:fs";
|
|
49410
|
-
import { resolve as
|
|
49638
|
+
import { resolve as resolve44 } from "node:path";
|
|
49411
49639
|
var NAME = "force-update-interruptions.json";
|
|
49412
49640
|
function pathFor(runtimeDir) {
|
|
49413
|
-
return
|
|
49641
|
+
return resolve44(runtimeDir, NAME);
|
|
49414
49642
|
}
|
|
49415
49643
|
function read(runtimeDir) {
|
|
49416
49644
|
try {
|
|
@@ -49488,17 +49716,17 @@ function staleGeneration(error) {
|
|
|
49488
49716
|
init_launchd();
|
|
49489
49717
|
init_systemd();
|
|
49490
49718
|
import { mkdir as mkdir29, rename as rename12 } from "node:fs/promises";
|
|
49491
|
-
import { dirname as dirname29, resolve as
|
|
49719
|
+
import { dirname as dirname29, resolve as resolve45 } from "node:path";
|
|
49492
49720
|
async function retireRemovedAgent(runtime, options = {}) {
|
|
49493
|
-
const deletedRoot =
|
|
49494
|
-
const target =
|
|
49721
|
+
const deletedRoot = resolve45(runtime.supervisorRoot, "beeline", "deleted-runtimes");
|
|
49722
|
+
const target = resolve45(deletedRoot, `${runtime.agent.publicKey}-${Date.now()}`);
|
|
49495
49723
|
return relocateAgentRuntime(runtime, target, {
|
|
49496
49724
|
...options.run ? { run: options.run } : {}
|
|
49497
49725
|
});
|
|
49498
49726
|
}
|
|
49499
49727
|
async function relocateAgentRuntime(runtime, target, options = {}) {
|
|
49500
49728
|
const source = runtimeDirectory(runtime.supervisorRoot, runtime.agent.publicKey);
|
|
49501
|
-
const destination =
|
|
49729
|
+
const destination = resolve45(target);
|
|
49502
49730
|
if (destination === source || destination.startsWith(`${source}/`)) {
|
|
49503
49731
|
throw new Error("agent runtime destination must be outside the live runtime");
|
|
49504
49732
|
}
|
|
@@ -49520,8 +49748,8 @@ async function relocateAgentRuntime(runtime, target, options = {}) {
|
|
|
49520
49748
|
init_systemd();
|
|
49521
49749
|
|
|
49522
49750
|
// apps/body/dist/release-status.js
|
|
49523
|
-
import { readFile as
|
|
49524
|
-
import { resolve as
|
|
49751
|
+
import { readFile as readFile34, readdir as readdir15, rename as rename13, writeFile as writeFile22 } from "node:fs/promises";
|
|
49752
|
+
import { resolve as resolve46 } from "node:path";
|
|
49525
49753
|
var DAEMON_RELEASE_STATUS_FILE = "release-status.json";
|
|
49526
49754
|
var RELEASE_VERSION = /^v\d+\.\d+\.\d+$/;
|
|
49527
49755
|
var SOURCE_SHA = /^[0-9a-f]{7,64}$/;
|
|
@@ -49538,7 +49766,7 @@ async function writeDaemonReleaseStatus(runtimeDir, agentPubkey, identity, optio
|
|
|
49538
49766
|
pid: options.pid ?? process.pid,
|
|
49539
49767
|
readyAt: (options.now?.() ?? /* @__PURE__ */ new Date()).toISOString()
|
|
49540
49768
|
};
|
|
49541
|
-
const target =
|
|
49769
|
+
const target = resolve46(runtimeDir, DAEMON_RELEASE_STATUS_FILE);
|
|
49542
49770
|
const temporary = `${target}.${status.pid}.tmp`;
|
|
49543
49771
|
await writeFile22(temporary, `${JSON.stringify(status, null, 2)}
|
|
49544
49772
|
`, { mode: 384 });
|
|
@@ -49547,8 +49775,8 @@ async function writeDaemonReleaseStatus(runtimeDir, agentPubkey, identity, optio
|
|
|
49547
49775
|
}
|
|
49548
49776
|
|
|
49549
49777
|
// apps/body/dist/scratch-sweep.js
|
|
49550
|
-
import { lstat as
|
|
49551
|
-
import { resolve as
|
|
49778
|
+
import { lstat as lstat11, readdir as readdir16, rmdir as rmdir3, unlink as unlink9 } from "node:fs/promises";
|
|
49779
|
+
import { resolve as resolve47 } from "node:path";
|
|
49552
49780
|
var DEFAULT_SCRATCH_TTL_HOURS = 72;
|
|
49553
49781
|
var NEVER_SWEEP_SUBDIR_NAMES = new Set(HOME_SUBDIRS.filter((name) => name !== "tmp"));
|
|
49554
49782
|
function scratchTtlMs(env = process.env) {
|
|
@@ -49557,10 +49785,10 @@ function scratchTtlMs(env = process.env) {
|
|
|
49557
49785
|
return (Number.isFinite(hours) && hours > 0 ? hours : DEFAULT_SCRATCH_TTL_HOURS) * 60 * 60 * 1e3;
|
|
49558
49786
|
}
|
|
49559
49787
|
async function discoverAttachScratchRoots(runtimeDir) {
|
|
49560
|
-
const roomsDir =
|
|
49788
|
+
const roomsDir = resolve47(runtimeDir, "rooms");
|
|
49561
49789
|
let entries;
|
|
49562
49790
|
try {
|
|
49563
|
-
entries = await
|
|
49791
|
+
entries = await readdir16(roomsDir, { withFileTypes: true });
|
|
49564
49792
|
} catch {
|
|
49565
49793
|
return [];
|
|
49566
49794
|
}
|
|
@@ -49568,8 +49796,8 @@ async function discoverAttachScratchRoots(runtimeDir) {
|
|
|
49568
49796
|
for (const entry of entries) {
|
|
49569
49797
|
if (!entry.isDirectory())
|
|
49570
49798
|
continue;
|
|
49571
|
-
const home =
|
|
49572
|
-
const stats = await
|
|
49799
|
+
const home = resolve47(roomsDir, entry.name, "agent-home");
|
|
49800
|
+
const stats = await lstat11(home).catch(() => void 0);
|
|
49573
49801
|
if (stats?.isDirectory())
|
|
49574
49802
|
roots.push(home);
|
|
49575
49803
|
}
|
|
@@ -49578,7 +49806,7 @@ async function discoverAttachScratchRoots(runtimeDir) {
|
|
|
49578
49806
|
async function removeStaleFiles(dir, cutoffMs, protectNamesHere) {
|
|
49579
49807
|
let entries;
|
|
49580
49808
|
try {
|
|
49581
|
-
entries = await
|
|
49809
|
+
entries = await readdir16(dir, { withFileTypes: true });
|
|
49582
49810
|
} catch {
|
|
49583
49811
|
return { removedFiles: 0, removedBytes: 0 };
|
|
49584
49812
|
}
|
|
@@ -49587,15 +49815,15 @@ async function removeStaleFiles(dir, cutoffMs, protectNamesHere) {
|
|
|
49587
49815
|
for (const entry of entries) {
|
|
49588
49816
|
if (protectNamesHere && NEVER_SWEEP_SUBDIR_NAMES.has(entry.name))
|
|
49589
49817
|
continue;
|
|
49590
|
-
const path =
|
|
49591
|
-
const stats = await
|
|
49818
|
+
const path = resolve47(dir, entry.name);
|
|
49819
|
+
const stats = await lstat11(path).catch(() => void 0);
|
|
49592
49820
|
if (!stats || stats.isSymbolicLink())
|
|
49593
49821
|
continue;
|
|
49594
49822
|
if (stats.isDirectory()) {
|
|
49595
49823
|
const nested = await removeStaleFiles(path, cutoffMs, false);
|
|
49596
49824
|
removedFiles += nested.removedFiles;
|
|
49597
49825
|
removedBytes += nested.removedBytes;
|
|
49598
|
-
const remaining = await
|
|
49826
|
+
const remaining = await readdir16(path).catch(() => void 0);
|
|
49599
49827
|
if (remaining && remaining.length === 0)
|
|
49600
49828
|
await rmdir3(path).catch(() => void 0);
|
|
49601
49829
|
continue;
|
|
@@ -49613,7 +49841,7 @@ async function sweepAttachScratchRoots(roots, ttlMs, now2 = Date.now()) {
|
|
|
49613
49841
|
let removedFiles = 0;
|
|
49614
49842
|
let removedBytes = 0;
|
|
49615
49843
|
for (const root of roots) {
|
|
49616
|
-
const stats = await
|
|
49844
|
+
const stats = await lstat11(root).catch(() => void 0);
|
|
49617
49845
|
if (!stats?.isDirectory())
|
|
49618
49846
|
continue;
|
|
49619
49847
|
const result = await removeStaleFiles(root, cutoffMs, true);
|
|
@@ -49657,7 +49885,7 @@ async function runAgentRuntime(configPath, host, signal) {
|
|
|
49657
49885
|
BUZZ_DEV_MCP_BIN: runtime.mcpBinary
|
|
49658
49886
|
};
|
|
49659
49887
|
const config = loadBodyConfig({
|
|
49660
|
-
workspaceRoot:
|
|
49888
|
+
workspaceRoot: resolve48(runtimeDir, "workspace"),
|
|
49661
49889
|
llmEnvFile: runtime.llmEnvFile,
|
|
49662
49890
|
env,
|
|
49663
49891
|
agent
|
|
@@ -49923,26 +50151,26 @@ init_squire_host();
|
|
|
49923
50151
|
|
|
49924
50152
|
// apps/body/dist/host-disk-retention.js
|
|
49925
50153
|
import { execFile as execFile20 } from "node:child_process";
|
|
49926
|
-
import { lstat as
|
|
49927
|
-
import { join as join23, resolve as
|
|
50154
|
+
import { lstat as lstat12, readdir as readdir17, rm as rm21 } from "node:fs/promises";
|
|
50155
|
+
import { join as join23, resolve as resolve49 } from "node:path";
|
|
49928
50156
|
import { promisify as promisify14 } from "node:util";
|
|
49929
50157
|
var execFileAsync14 = promisify14(execFile20);
|
|
49930
50158
|
var DELETED_RUNTIME_TTL_MS = 30 * 24 * 60 * 6e4;
|
|
49931
50159
|
var REPOSITORY_CACHE_TTL_MS = 30 * 24 * 60 * 6e4;
|
|
49932
50160
|
async function pruneDeletedRuntimes(supervisorRoot2, now2 = Date.now()) {
|
|
49933
|
-
const root =
|
|
50161
|
+
const root = resolve49(supervisorRoot2, "beeline", "deleted-runtimes");
|
|
49934
50162
|
const removed = [];
|
|
49935
|
-
for (const entry of await
|
|
50163
|
+
for (const entry of await readdir17(root, { withFileTypes: true }).catch(() => [])) {
|
|
49936
50164
|
const match = /^([a-f0-9]{64})-(\d{13})$/.exec(entry.name);
|
|
49937
50165
|
if (!entry.isDirectory() || !match || now2 - Number(match[2]) < DELETED_RUNTIME_TTL_MS)
|
|
49938
50166
|
continue;
|
|
49939
50167
|
const path = join23(root, entry.name);
|
|
49940
|
-
if (!(await
|
|
50168
|
+
if (!(await lstat12(path)).isDirectory())
|
|
49941
50169
|
continue;
|
|
49942
|
-
const rooms =
|
|
50170
|
+
const rooms = resolve49(path, "rooms");
|
|
49943
50171
|
let retainsHome = false;
|
|
49944
|
-
for (const room of await
|
|
49945
|
-
const home = await
|
|
50172
|
+
for (const room of await readdir17(rooms).catch(() => [])) {
|
|
50173
|
+
const home = await lstat12(resolve49(rooms, room, "agent-home")).catch(() => void 0);
|
|
49946
50174
|
if (home) {
|
|
49947
50175
|
retainsHome = true;
|
|
49948
50176
|
break;
|
|
@@ -49956,19 +50184,19 @@ async function pruneDeletedRuntimes(supervisorRoot2, now2 = Date.now()) {
|
|
|
49956
50184
|
return removed;
|
|
49957
50185
|
}
|
|
49958
50186
|
async function pruneRepositoryCaches(supervisorRoot2, now2 = Date.now()) {
|
|
49959
|
-
const root =
|
|
50187
|
+
const root = resolve49(supervisorRoot2, "beeline", "repositories");
|
|
49960
50188
|
const removed = [];
|
|
49961
|
-
for (const entry of await
|
|
50189
|
+
for (const entry of await readdir17(root, { withFileTypes: true }).catch(() => [])) {
|
|
49962
50190
|
if (!entry.isDirectory() || !/^[a-f0-9]{24}\.git$/.test(entry.name))
|
|
49963
50191
|
continue;
|
|
49964
50192
|
const path = join23(root, entry.name);
|
|
49965
|
-
const info = await
|
|
50193
|
+
const info = await lstat12(path);
|
|
49966
50194
|
if (!info.isDirectory() || now2 - info.mtimeMs < REPOSITORY_CACHE_TTL_MS)
|
|
49967
50195
|
continue;
|
|
49968
50196
|
const listing = await execFileAsync14("git", [`--git-dir=${path}`, "worktree", "list", "--porcelain"]).then((result) => result.stdout, () => void 0);
|
|
49969
50197
|
if (listing === void 0)
|
|
49970
50198
|
continue;
|
|
49971
|
-
const attached = listing.split("\n").some((line) => line.startsWith("worktree ") &&
|
|
50199
|
+
const attached = listing.split("\n").some((line) => line.startsWith("worktree ") && resolve49(line.slice("worktree ".length)) !== path);
|
|
49972
50200
|
if (attached)
|
|
49973
50201
|
continue;
|
|
49974
50202
|
const refs = await execFileAsync14("git", [
|
|
@@ -50034,7 +50262,7 @@ async function runMachineHelper(options = {}) {
|
|
|
50034
50262
|
diskSweepRunning = true;
|
|
50035
50263
|
try {
|
|
50036
50264
|
const modelDue = now2 - lastModelSweepAt >= 60 * 6e4;
|
|
50037
|
-
const removed = modelDue ? await pruneSharedModelCache(
|
|
50265
|
+
const removed = modelDue ? await pruneSharedModelCache(resolve50(supervisorRoot2, "beeline", "model-cache")) : [];
|
|
50038
50266
|
if (modelDue)
|
|
50039
50267
|
lastModelSweepAt = now2;
|
|
50040
50268
|
if (now2 - lastRetentionSweepAt >= 24 * 60 * 6e4) {
|
|
@@ -50360,7 +50588,12 @@ async function runMachineHelper(options = {}) {
|
|
|
50360
50588
|
void rescan().catch((error) => console.error("[helper] rescan failed:", error));
|
|
50361
50589
|
};
|
|
50362
50590
|
signals.on("SIGHUP", onHangup);
|
|
50363
|
-
const stopWatchdog = startLocalWatchdog(notifier, statusLine)
|
|
50591
|
+
const stopWatchdog = startLocalWatchdog(notifier, statusLine, async () => {
|
|
50592
|
+
if ([...slots.values()].some((slot) => slot.running && !slot.controller.signal.aborted && !hosted.has(slot.agentId)))
|
|
50593
|
+
return false;
|
|
50594
|
+
await Promise.all([...hosted.values()].map((agent) => agent.core.requestWorkLoopProgress()));
|
|
50595
|
+
return true;
|
|
50596
|
+
}, void 0, env);
|
|
50364
50597
|
try {
|
|
50365
50598
|
console.log(`[helper] hosting ${initial.length} agent(s) on one machine socket per server`);
|
|
50366
50599
|
for (const configPath of initial)
|
|
@@ -50446,10 +50679,10 @@ function sleep3(ms, signal) {
|
|
|
50446
50679
|
// apps/body/dist/android-emulator-lease.js
|
|
50447
50680
|
import { execFileSync, spawn as spawn14 } from "node:child_process";
|
|
50448
50681
|
import { randomUUID as randomUUID15 } from "node:crypto";
|
|
50449
|
-
import { cp as cp2, mkdir as mkdir31, open as open6, readFile as
|
|
50682
|
+
import { cp as cp2, mkdir as mkdir31, open as open6, readFile as readFile35, rm as rm22, stat as stat13, writeFile as writeFile24 } from "node:fs/promises";
|
|
50450
50683
|
import { createServer as createServer5 } from "node:net";
|
|
50451
50684
|
import { existsSync as existsSync11 } from "node:fs";
|
|
50452
|
-
import { resolve as
|
|
50685
|
+
import { resolve as resolve51 } from "node:path";
|
|
50453
50686
|
var FIRST_PORT = 5554;
|
|
50454
50687
|
var LAST_PORT = 5584;
|
|
50455
50688
|
var PORT_STEP = 4;
|
|
@@ -50462,7 +50695,7 @@ function processAlive(pid) {
|
|
|
50462
50695
|
}
|
|
50463
50696
|
}
|
|
50464
50697
|
async function processStart(pid) {
|
|
50465
|
-
const raw = await
|
|
50698
|
+
const raw = await readFile35(`/proc/${pid}/stat`, "utf8").catch(() => void 0);
|
|
50466
50699
|
if (raw)
|
|
50467
50700
|
return raw.slice(raw.lastIndexOf(")") + 2).split(" ")[19];
|
|
50468
50701
|
try {
|
|
@@ -50479,13 +50712,13 @@ async function portFree(port) {
|
|
|
50479
50712
|
});
|
|
50480
50713
|
}
|
|
50481
50714
|
async function leaseEmulator(root, privateRoot) {
|
|
50482
|
-
const absolute =
|
|
50715
|
+
const absolute = resolve51(root);
|
|
50483
50716
|
await Promise.all([
|
|
50484
50717
|
mkdir31(absolute, { recursive: true, mode: 448 }),
|
|
50485
50718
|
mkdir31(privateRoot, { recursive: true, mode: 448 })
|
|
50486
50719
|
]);
|
|
50487
50720
|
for (let port = FIRST_PORT; port <= LAST_PORT; port += PORT_STEP) {
|
|
50488
|
-
const marker =
|
|
50721
|
+
const marker = resolve51(absolute, `port-${port}.lease`);
|
|
50489
50722
|
let handle2;
|
|
50490
50723
|
for (let attempt = 0; attempt < 2; attempt++) {
|
|
50491
50724
|
try {
|
|
@@ -50494,7 +50727,7 @@ async function leaseEmulator(root, privateRoot) {
|
|
|
50494
50727
|
} catch (error) {
|
|
50495
50728
|
if (error.code !== "EEXIST")
|
|
50496
50729
|
throw error;
|
|
50497
|
-
const old = await
|
|
50730
|
+
const old = await readFile35(marker, "utf8").catch(() => "");
|
|
50498
50731
|
const [pidText, start] = old.split(":");
|
|
50499
50732
|
const pid = Number(pidText);
|
|
50500
50733
|
if (Number.isSafeInteger(pid) && pid > 0 && processAlive(pid)) {
|
|
@@ -50508,20 +50741,20 @@ async function leaseEmulator(root, privateRoot) {
|
|
|
50508
50741
|
if (!before || !await portFree(port) || !await portFree(port + 1) || !await portFree(port + 2))
|
|
50509
50742
|
break;
|
|
50510
50743
|
const after = await stat13(marker).catch(() => void 0);
|
|
50511
|
-
if (after && before.ino === after.ino && await
|
|
50744
|
+
if (after && before.ino === after.ino && await readFile35(marker, "utf8").catch(() => "") === old)
|
|
50512
50745
|
await rm22(marker, { force: true });
|
|
50513
50746
|
}
|
|
50514
50747
|
}
|
|
50515
50748
|
if (!handle2)
|
|
50516
50749
|
continue;
|
|
50517
|
-
const instance =
|
|
50750
|
+
const instance = resolve51(privateRoot, `instance-${randomUUID15()}`);
|
|
50518
50751
|
const ownership = `${process.pid}:${await processStart(process.pid)}:${randomUUID15()}:${instance}`;
|
|
50519
50752
|
try {
|
|
50520
50753
|
await handle2.writeFile(ownership);
|
|
50521
50754
|
await handle2.sync();
|
|
50522
50755
|
if (!await portFree(port) || !await portFree(port + 1) || !await portFree(port + 2)) {
|
|
50523
50756
|
await handle2.close();
|
|
50524
|
-
if (await
|
|
50757
|
+
if (await readFile35(marker, "utf8").catch(() => "") === ownership)
|
|
50525
50758
|
await rm22(marker, { force: true });
|
|
50526
50759
|
continue;
|
|
50527
50760
|
}
|
|
@@ -50532,14 +50765,14 @@ async function leaseEmulator(root, privateRoot) {
|
|
|
50532
50765
|
serial: `emulator-${port}`,
|
|
50533
50766
|
root: instance,
|
|
50534
50767
|
release: async () => {
|
|
50535
|
-
if (await
|
|
50768
|
+
if (await readFile35(marker, "utf8").catch(() => "") === ownership)
|
|
50536
50769
|
await rm22(marker, { force: true });
|
|
50537
50770
|
await rm22(instance, { recursive: true, force: true });
|
|
50538
50771
|
}
|
|
50539
50772
|
};
|
|
50540
50773
|
} catch (error) {
|
|
50541
50774
|
await handle2.close().catch(() => void 0);
|
|
50542
|
-
if (await
|
|
50775
|
+
if (await readFile35(marker, "utf8").catch(() => "") === ownership)
|
|
50543
50776
|
await rm22(marker, { force: true });
|
|
50544
50777
|
throw error;
|
|
50545
50778
|
}
|
|
@@ -50564,19 +50797,19 @@ async function runLeasedEmulator(args, env = process.env) {
|
|
|
50564
50797
|
if (env.ANDROID_EMULATOR_HOME)
|
|
50565
50798
|
await mkdir31(env.ANDROID_EMULATOR_HOME, { recursive: true, mode: 448 });
|
|
50566
50799
|
if (env.ANDROID_HOME) {
|
|
50567
|
-
const adb =
|
|
50800
|
+
const adb = resolve51(env.ANDROID_HOME, "platform-tools/adb");
|
|
50568
50801
|
if (existsSync11(adb))
|
|
50569
50802
|
execFileSync(adb, ["start-server"], { env, timeout: 15e3 });
|
|
50570
50803
|
}
|
|
50571
|
-
const original =
|
|
50572
|
-
const localAvdHome =
|
|
50573
|
-
const local =
|
|
50574
|
-
const data =
|
|
50804
|
+
const original = resolve51(baseAvdHome, `${avdName}.avd`);
|
|
50805
|
+
const localAvdHome = resolve51(lease.root, "avd");
|
|
50806
|
+
const local = resolve51(localAvdHome, `${avdName}.avd`);
|
|
50807
|
+
const data = resolve51(lease.root, "data");
|
|
50575
50808
|
await mkdir31(local, { recursive: true, mode: 448 });
|
|
50576
50809
|
await mkdir31(data, { recursive: true, mode: 448 });
|
|
50577
|
-
await cp2(
|
|
50578
|
-
const metadata = await
|
|
50579
|
-
await writeFile24(
|
|
50810
|
+
await cp2(resolve51(original, "config.ini"), resolve51(local, "config.ini"));
|
|
50811
|
+
const metadata = await readFile35(resolve51(baseAvdHome, `${avdName}.ini`), "utf8");
|
|
50812
|
+
await writeFile24(resolve51(localAvdHome, `${avdName}.ini`), metadata.replace(/^path\s*=.*$/m, `path=${local}`).replace(/^path\.rel\s*=.*\n?/m, ""), { mode: 384 });
|
|
50580
50813
|
const status = await new Promise((done, reject) => {
|
|
50581
50814
|
const child = spawn14(emulator, [...args.filter((arg) => arg !== "-read-only"), "-port", String(lease.port), "-datadir", data], {
|
|
50582
50815
|
env: { ...env, ANDROID_AVD_HOME: localAvdHome, ADB_EMU: "0" },
|
|
@@ -50693,7 +50926,7 @@ async function main() {
|
|
|
50693
50926
|
const roomId = roomFlag >= 0 ? args[roomFlag + 1] : void 0;
|
|
50694
50927
|
if (!configPath || !roomId)
|
|
50695
50928
|
throw new Error("corner-read-token requires --config and --room");
|
|
50696
|
-
const activated = await activateDaemonTransport(
|
|
50929
|
+
const activated = await activateDaemonTransport(resolve52(configPath));
|
|
50697
50930
|
if (!activated)
|
|
50698
50931
|
throw new Error("corner-read-token requires monolith transport");
|
|
50699
50932
|
const credential = await activated.client.execute("getRoomGitHubToken", { roomId });
|
|
@@ -50748,7 +50981,7 @@ async function main() {
|
|
|
50748
50981
|
}
|
|
50749
50982
|
if (!configPath && !args.includes("--machine"))
|
|
50750
50983
|
throw new Error("daemon requires --machine, or --config <runtime.json> for one agent");
|
|
50751
|
-
const { reason, lifecycle } = await runMachineHelper(configPath ? { configPaths: [
|
|
50984
|
+
const { reason, lifecycle } = await runMachineHelper(configPath ? { configPaths: [resolve52(configPath)] } : {});
|
|
50752
50985
|
daemonLifecycle = lifecycle;
|
|
50753
50986
|
lifecycle.exit(reason);
|
|
50754
50987
|
return;
|