usebeeline 0.1.14 → 0.1.17
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 +314 -284
- 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((resolve45) => {
|
|
216
|
+
resolveDone = resolve45;
|
|
217
217
|
});
|
|
218
218
|
const failResponse = (id) => `${JSON.stringify({
|
|
219
219
|
jsonrpc: "2.0",
|
|
@@ -13472,91 +13472,6 @@ import { fileURLToPath } from "node:url";
|
|
|
13472
13472
|
import { spawn } from "node:child_process";
|
|
13473
13473
|
import { readFile } from "node:fs/promises";
|
|
13474
13474
|
import { createInterface } from "node:readline";
|
|
13475
|
-
|
|
13476
|
-
// packages/api-contract/dist/app-connections.js
|
|
13477
|
-
var APP_KEY_MAX_LENGTH = 63;
|
|
13478
|
-
var APP_INPUT_MAX_LENGTH = 200;
|
|
13479
|
-
var SECOND_LEVEL_SUFFIXES = /* @__PURE__ */ new Set(["co", "com", "net", "org", "gov", "edu", "ac"]);
|
|
13480
|
-
function alnum(value) {
|
|
13481
|
-
return value.normalize("NFKD").toLowerCase().replace(/[^a-z0-9]/g, "").slice(0, APP_KEY_MAX_LENGTH);
|
|
13482
|
-
}
|
|
13483
|
-
function hostOf(value) {
|
|
13484
|
-
const trimmed = value.trim().toLowerCase();
|
|
13485
|
-
if (!trimmed)
|
|
13486
|
-
return void 0;
|
|
13487
|
-
if (trimmed.includes("://")) {
|
|
13488
|
-
try {
|
|
13489
|
-
return new URL(trimmed).hostname || void 0;
|
|
13490
|
-
} catch {
|
|
13491
|
-
return void 0;
|
|
13492
|
-
}
|
|
13493
|
-
}
|
|
13494
|
-
const host = trimmed.split(/[/?#]/)[0].replace(/:\d+$/, "").replace(/\.$/, "");
|
|
13495
|
-
return /^[a-z0-9-]+(\.[a-z0-9-]+)+$/.test(host) ? host : void 0;
|
|
13496
|
-
}
|
|
13497
|
-
function registrableDomain(host) {
|
|
13498
|
-
const labels = host.toLowerCase().split(".").filter(Boolean);
|
|
13499
|
-
if (labels.length < 2)
|
|
13500
|
-
return void 0;
|
|
13501
|
-
if (labels.every((label) => /^\d+$/.test(label)))
|
|
13502
|
-
return void 0;
|
|
13503
|
-
const penultimate = labels[labels.length - 2];
|
|
13504
|
-
const keep = labels.length >= 3 && SECOND_LEVEL_SUFFIXES.has(penultimate) ? 3 : 2;
|
|
13505
|
-
return labels.slice(-keep).join(".");
|
|
13506
|
-
}
|
|
13507
|
-
function brandOfDomain(domain) {
|
|
13508
|
-
const key = alnum(domain.split(".")[0] ?? "");
|
|
13509
|
-
return key || void 0;
|
|
13510
|
-
}
|
|
13511
|
-
function appIdentity(input) {
|
|
13512
|
-
const text2 = input.trim();
|
|
13513
|
-
if (!text2 || text2.length > APP_INPUT_MAX_LENGTH)
|
|
13514
|
-
return void 0;
|
|
13515
|
-
const host = hostOf(text2);
|
|
13516
|
-
if (host) {
|
|
13517
|
-
const domain = registrableDomain(host);
|
|
13518
|
-
const key2 = domain ? brandOfDomain(domain) : void 0;
|
|
13519
|
-
return key2 && domain ? { key: key2, domain } : void 0;
|
|
13520
|
-
}
|
|
13521
|
-
const key = alnum(text2);
|
|
13522
|
-
return key ? { key } : void 0;
|
|
13523
|
-
}
|
|
13524
|
-
function appKeyForHost(value) {
|
|
13525
|
-
const host = hostOf(value);
|
|
13526
|
-
const domain = host ? registrableDomain(host) : void 0;
|
|
13527
|
-
return domain ? brandOfDomain(domain) : void 0;
|
|
13528
|
-
}
|
|
13529
|
-
function squireCallAppKeys(args) {
|
|
13530
|
-
if (!args)
|
|
13531
|
-
return [];
|
|
13532
|
-
const keys = /* @__PURE__ */ new Set();
|
|
13533
|
-
const service = args.service;
|
|
13534
|
-
if (typeof service === "string") {
|
|
13535
|
-
const identity = appIdentity(service);
|
|
13536
|
-
if (identity)
|
|
13537
|
-
keys.add(identity.key);
|
|
13538
|
-
}
|
|
13539
|
-
const urls = [args.url, args.signin_url];
|
|
13540
|
-
const http = args.http;
|
|
13541
|
-
if (http && typeof http === "object" && !Array.isArray(http))
|
|
13542
|
-
urls.push(http.url);
|
|
13543
|
-
for (const url of urls) {
|
|
13544
|
-
if (typeof url !== "string" || url.length > 2048)
|
|
13545
|
-
continue;
|
|
13546
|
-
const key = appKeyForHost(url);
|
|
13547
|
-
if (key)
|
|
13548
|
-
keys.add(key);
|
|
13549
|
-
}
|
|
13550
|
-
return [...keys].sort();
|
|
13551
|
-
}
|
|
13552
|
-
|
|
13553
|
-
// packages/api-contract/dist/workbench.js
|
|
13554
|
-
var CONNECTABLE_CONNECTOR_KINDS = [
|
|
13555
|
-
"trusty-squire",
|
|
13556
|
-
"tailscale"
|
|
13557
|
-
];
|
|
13558
|
-
|
|
13559
|
-
// apps/body/dist/resource-mcp-facade.js
|
|
13560
13475
|
var RESOURCE_FACADE_FLAG = "--resource-mcp-facade";
|
|
13561
13476
|
function resourceFacadeArgs() {
|
|
13562
13477
|
const meta = "usebeeline:npm";
|
|
@@ -13891,16 +13806,11 @@ async function postSquireLoginWall(wall, authFile, fetchImpl = fetch) {
|
|
|
13891
13806
|
signal: AbortSignal.timeout(2e4)
|
|
13892
13807
|
});
|
|
13893
13808
|
}
|
|
13894
|
-
function resourceCallFacts(message
|
|
13809
|
+
function resourceCallFacts(message) {
|
|
13895
13810
|
if (message.method !== "tools/call")
|
|
13896
13811
|
return {};
|
|
13897
|
-
const
|
|
13898
|
-
|
|
13899
|
-
const appKeys = target === "squire" ? squireCallAppKeys(record(params?.arguments)) : [];
|
|
13900
|
-
return {
|
|
13901
|
-
...tool ? { operation: tool } : {},
|
|
13902
|
-
...appKeys.length ? { appKeys } : {}
|
|
13903
|
-
};
|
|
13812
|
+
const tool = shortString(record(message.params)?.name);
|
|
13813
|
+
return tool ? { operation: tool } : {};
|
|
13904
13814
|
}
|
|
13905
13815
|
async function authorizeResourceMessage(message, target, authFile, spendsGrant = true, fetchImpl = fetch) {
|
|
13906
13816
|
if (!message || Array.isArray(message) || typeof message !== "object")
|
|
@@ -13922,7 +13832,7 @@ async function authorizeResourceMessage(message, target, authFile, spendsGrant =
|
|
|
13922
13832
|
...context,
|
|
13923
13833
|
target,
|
|
13924
13834
|
...spendsGrant && !NON_CONSUMING.has(message.method) ? {} : { consume: false },
|
|
13925
|
-
...resourceCallFacts(message
|
|
13835
|
+
...resourceCallFacts(message)
|
|
13926
13836
|
}),
|
|
13927
13837
|
signal: AbortSignal.timeout(2e4)
|
|
13928
13838
|
});
|
|
@@ -14126,7 +14036,7 @@ function configureNetworkFamilyDefaults(network = net) {
|
|
|
14126
14036
|
configureNetworkFamilyDefaults();
|
|
14127
14037
|
|
|
14128
14038
|
// apps/body/dist/cli.js
|
|
14129
|
-
import { dirname as dirname31, resolve as
|
|
14039
|
+
import { dirname as dirname31, resolve as resolve44 } from "node:path";
|
|
14130
14040
|
import { stdin as stdin4, stdout as stdout5 } from "node:process";
|
|
14131
14041
|
|
|
14132
14042
|
// node_modules/@clack/core/dist/index.mjs
|
|
@@ -15566,7 +15476,7 @@ function parseCursorModelsOutput(output) {
|
|
|
15566
15476
|
};
|
|
15567
15477
|
}
|
|
15568
15478
|
async function enumerateCursorModels(env = process.env) {
|
|
15569
|
-
return new Promise((
|
|
15479
|
+
return new Promise((resolve45) => {
|
|
15570
15480
|
const child = spawn2("cursor-agent", ["models"], {
|
|
15571
15481
|
env,
|
|
15572
15482
|
stdio: ["ignore", "pipe", "ignore"]
|
|
@@ -15580,11 +15490,11 @@ async function enumerateCursorModels(env = process.env) {
|
|
|
15580
15490
|
});
|
|
15581
15491
|
child.on("error", () => {
|
|
15582
15492
|
clearTimeout(timer);
|
|
15583
|
-
|
|
15493
|
+
resolve45(void 0);
|
|
15584
15494
|
});
|
|
15585
15495
|
child.on("close", (code) => {
|
|
15586
15496
|
clearTimeout(timer);
|
|
15587
|
-
|
|
15497
|
+
resolve45(code === 0 ? parseCursorModelsOutput(output) : void 0);
|
|
15588
15498
|
});
|
|
15589
15499
|
});
|
|
15590
15500
|
}
|
|
@@ -16011,13 +15921,13 @@ var CursorAcpServer = class {
|
|
|
16011
15921
|
consumeLine(line);
|
|
16012
15922
|
});
|
|
16013
15923
|
try {
|
|
16014
|
-
const { code, signal } = await new Promise((
|
|
15924
|
+
const { code, signal } = await new Promise((resolve45) => {
|
|
16015
15925
|
let settled = false;
|
|
16016
15926
|
const finish = (exitCode, exitSignal) => {
|
|
16017
15927
|
if (settled)
|
|
16018
15928
|
return;
|
|
16019
15929
|
settled = true;
|
|
16020
|
-
|
|
15930
|
+
resolve45({ code: exitCode, signal: exitSignal });
|
|
16021
15931
|
};
|
|
16022
15932
|
child.once("error", (error) => {
|
|
16023
15933
|
spawnError = error instanceof Error ? error.message : String(error);
|
|
@@ -16162,10 +16072,10 @@ function releaseSquireConnectSession(log2, owner = "") {
|
|
|
16162
16072
|
function squireChromeProfileDir() {
|
|
16163
16073
|
return process.env.TRUSTY_SQUIRE_PROFILE_DIR ?? squireHostPaths(homedir2()).profileDir;
|
|
16164
16074
|
}
|
|
16165
|
-
var defaultShellRunner = (command, args) => new Promise((
|
|
16075
|
+
var defaultShellRunner = (command, args) => new Promise((resolve45) => {
|
|
16166
16076
|
execFile(command, [...args], { timeout: 12e4, maxBuffer: 4 * 1024 * 1024, encoding: "utf8" }, (error, stdout6, stderr) => {
|
|
16167
16077
|
const code = error?.code;
|
|
16168
|
-
|
|
16078
|
+
resolve45({
|
|
16169
16079
|
code: typeof code === "number" ? code : error ? 1 : 0,
|
|
16170
16080
|
stdout: String(stdout6 ?? ""),
|
|
16171
16081
|
stderr: String(stderr ?? "")
|
|
@@ -16190,7 +16100,7 @@ function killConnectTree(child) {
|
|
|
16190
16100
|
}
|
|
16191
16101
|
child.kill();
|
|
16192
16102
|
}
|
|
16193
|
-
var defaultStreamedRunner = (command, args, env, owner = "") => new Promise((
|
|
16103
|
+
var defaultStreamedRunner = (command, args, env, owner = "") => new Promise((resolve45) => {
|
|
16194
16104
|
const child = spawn5(command, args, {
|
|
16195
16105
|
stdio: ["ignore", "pipe", "pipe"],
|
|
16196
16106
|
env: env ?? squireConnectProcessEnv(),
|
|
@@ -16204,7 +16114,7 @@ var defaultStreamedRunner = (command, args, env, owner = "") => new Promise((res
|
|
|
16204
16114
|
const safetyTimer = setTimeout(() => {
|
|
16205
16115
|
if (!resolved) {
|
|
16206
16116
|
resolved = true;
|
|
16207
|
-
|
|
16117
|
+
resolve45({ stdout: stdout6, stderr, pid: child.pid ?? void 0, report, abort: () => {
|
|
16208
16118
|
} });
|
|
16209
16119
|
}
|
|
16210
16120
|
killConnectTree(child);
|
|
@@ -16239,7 +16149,7 @@ var defaultStreamedRunner = (command, args, env, owner = "") => new Promise((res
|
|
|
16239
16149
|
const finish = (result) => {
|
|
16240
16150
|
if (!resolved) {
|
|
16241
16151
|
resolved = true;
|
|
16242
|
-
|
|
16152
|
+
resolve45(result);
|
|
16243
16153
|
}
|
|
16244
16154
|
};
|
|
16245
16155
|
const settle = (result) => {
|
|
@@ -16729,12 +16639,12 @@ var StdioSquireMcpClient = class {
|
|
|
16729
16639
|
const child = this.child;
|
|
16730
16640
|
if (!child)
|
|
16731
16641
|
return Promise.reject(new Error("Squire MCP session is not running"));
|
|
16732
|
-
return new Promise((
|
|
16642
|
+
return new Promise((resolve45, reject) => {
|
|
16733
16643
|
const timer = setTimeout(() => {
|
|
16734
16644
|
this.pending.delete(id);
|
|
16735
16645
|
reject(new Error(`${method} timed out`));
|
|
16736
16646
|
}, method === "initialize" ? INITIALIZE_TIMEOUT_MS : CALL_TIMEOUT_MS);
|
|
16737
|
-
this.pending.set(id, { resolve:
|
|
16647
|
+
this.pending.set(id, { resolve: resolve45, reject, timer });
|
|
16738
16648
|
child.stdin.write(`${JSON.stringify({ jsonrpc: "2.0", id, method, params })}
|
|
16739
16649
|
`);
|
|
16740
16650
|
});
|
|
@@ -16896,9 +16806,9 @@ var SquireTaskRelay = class {
|
|
|
16896
16806
|
response.writeHead(400, { "content-type": "application/json" }).end(JSON.stringify({ error: error instanceof Error ? error.message : "Squire relay failed" }));
|
|
16897
16807
|
}
|
|
16898
16808
|
});
|
|
16899
|
-
await new Promise((
|
|
16809
|
+
await new Promise((resolve45, reject) => {
|
|
16900
16810
|
server.once("error", reject);
|
|
16901
|
-
server.listen(0, "127.0.0.1",
|
|
16811
|
+
server.listen(0, "127.0.0.1", resolve45);
|
|
16902
16812
|
});
|
|
16903
16813
|
this.server = server;
|
|
16904
16814
|
const address = server.address();
|
|
@@ -17905,11 +17815,11 @@ var RegistryMcpHostBroker = class {
|
|
|
17905
17815
|
})();
|
|
17906
17816
|
});
|
|
17907
17817
|
});
|
|
17908
|
-
await new Promise((
|
|
17818
|
+
await new Promise((resolve45, reject) => {
|
|
17909
17819
|
this.server.once("error", reject);
|
|
17910
17820
|
this.server.listen(this.socketPath, () => {
|
|
17911
17821
|
this.server.off("error", reject);
|
|
17912
|
-
|
|
17822
|
+
resolve45();
|
|
17913
17823
|
});
|
|
17914
17824
|
});
|
|
17915
17825
|
chmodSync(this.socketPath, 384);
|
|
@@ -17918,12 +17828,12 @@ var RegistryMcpHostBroker = class {
|
|
|
17918
17828
|
const server = this.server;
|
|
17919
17829
|
this.server = void 0;
|
|
17920
17830
|
if (server)
|
|
17921
|
-
await new Promise((
|
|
17831
|
+
await new Promise((resolve45) => server.close(() => resolve45()));
|
|
17922
17832
|
rmSync(this.socketPath, { force: true });
|
|
17923
17833
|
}
|
|
17924
17834
|
};
|
|
17925
17835
|
async function brokerRequest(socketPath, request) {
|
|
17926
|
-
return new Promise((
|
|
17836
|
+
return new Promise((resolve45, reject) => {
|
|
17927
17837
|
const socket = createConnection3(socketPath);
|
|
17928
17838
|
let output = "";
|
|
17929
17839
|
socket.setEncoding("utf8");
|
|
@@ -17940,7 +17850,7 @@ async function brokerRequest(socketPath, request) {
|
|
|
17940
17850
|
throw new Error(parsed.error);
|
|
17941
17851
|
if (!Array.isArray(parsed.messages) || !parsed.messages.every((entry) => typeof entry === "string"))
|
|
17942
17852
|
throw new Error("Registry MCP broker returned an invalid response");
|
|
17943
|
-
|
|
17853
|
+
resolve45(parsed.messages);
|
|
17944
17854
|
} catch (error) {
|
|
17945
17855
|
reject(error);
|
|
17946
17856
|
}
|
|
@@ -18429,17 +18339,7 @@ var import_websocket = __toESM(require_websocket(), 1);
|
|
|
18429
18339
|
var import_websocket_server = __toESM(require_websocket_server(), 1);
|
|
18430
18340
|
var wrapper_default = import_websocket.default;
|
|
18431
18341
|
|
|
18432
|
-
// apps/body/dist/
|
|
18433
|
-
var LIVE_LINK_TIMING = Object.freeze({
|
|
18434
|
-
handshakeTimeoutMs: 3e4,
|
|
18435
|
-
pongTimeoutMs: 15e3,
|
|
18436
|
-
backoffBaseMs: 1e3,
|
|
18437
|
-
backoffMaxMs: 3e4,
|
|
18438
|
-
stableSocketMs: 3e4,
|
|
18439
|
-
stableCloseJitterMs: 1e4,
|
|
18440
|
-
keepAliveDelayMs: 5 * 6e4,
|
|
18441
|
-
heartbeatTimeoutMs: 75e3
|
|
18442
|
-
});
|
|
18342
|
+
// apps/body/dist/network-failure.js
|
|
18443
18343
|
var NETWORK_ERROR_CODES = /* @__PURE__ */ new Set([
|
|
18444
18344
|
"ECONNRESET",
|
|
18445
18345
|
"ECONNREFUSED",
|
|
@@ -18466,6 +18366,18 @@ function isNetworkFailure(error) {
|
|
|
18466
18366
|
};
|
|
18467
18367
|
return visit(error);
|
|
18468
18368
|
}
|
|
18369
|
+
|
|
18370
|
+
// apps/body/dist/live-link.js
|
|
18371
|
+
var LIVE_LINK_TIMING = Object.freeze({
|
|
18372
|
+
handshakeTimeoutMs: 3e4,
|
|
18373
|
+
pongTimeoutMs: 15e3,
|
|
18374
|
+
backoffBaseMs: 1e3,
|
|
18375
|
+
backoffMaxMs: 3e4,
|
|
18376
|
+
stableSocketMs: 3e4,
|
|
18377
|
+
stableCloseJitterMs: 1e4,
|
|
18378
|
+
keepAliveDelayMs: 5 * 6e4,
|
|
18379
|
+
heartbeatTimeoutMs: 75e3
|
|
18380
|
+
});
|
|
18469
18381
|
function retryAfterMs(value) {
|
|
18470
18382
|
if (!value)
|
|
18471
18383
|
return void 0;
|
|
@@ -19407,7 +19319,7 @@ var AgentSignIn = class {
|
|
|
19407
19319
|
};
|
|
19408
19320
|
for (const name of ISOLATION_VARIABLES)
|
|
19409
19321
|
delete env[name];
|
|
19410
|
-
return new Promise((
|
|
19322
|
+
return new Promise((resolve45, reject) => {
|
|
19411
19323
|
let output = "";
|
|
19412
19324
|
let answered = false;
|
|
19413
19325
|
let child;
|
|
@@ -19448,7 +19360,7 @@ var AgentSignIn = class {
|
|
|
19448
19360
|
return;
|
|
19449
19361
|
answered = true;
|
|
19450
19362
|
clearTimeout(linkTimer);
|
|
19451
|
-
|
|
19363
|
+
resolve45(link2);
|
|
19452
19364
|
};
|
|
19453
19365
|
child.stdout?.on("data", read2);
|
|
19454
19366
|
child.stderr?.on("data", read2);
|
|
@@ -29290,13 +29202,13 @@ var RoomSupervisor = class {
|
|
|
29290
29202
|
*/
|
|
29291
29203
|
retryDelay(failures, signal, since = this.#wakes) {
|
|
29292
29204
|
const delay = this.delaysMs[failures - 1];
|
|
29293
|
-
return new Promise((
|
|
29205
|
+
return new Promise((resolve45) => {
|
|
29294
29206
|
let timer;
|
|
29295
29207
|
const done = () => {
|
|
29296
29208
|
clearTimeout(timer);
|
|
29297
29209
|
this.#parked.delete(done);
|
|
29298
29210
|
signal?.removeEventListener("abort", done);
|
|
29299
|
-
|
|
29211
|
+
resolve45();
|
|
29300
29212
|
};
|
|
29301
29213
|
this.#parked.add(done);
|
|
29302
29214
|
signal?.addEventListener("abort", done, { once: true });
|
|
@@ -29488,12 +29400,12 @@ async function retryBeforeReady(work, options) {
|
|
|
29488
29400
|
if (wait2 <= 0)
|
|
29489
29401
|
break;
|
|
29490
29402
|
await options.extendStartTimeout(wait2 + 15e3);
|
|
29491
|
-
await new Promise((
|
|
29403
|
+
await new Promise((resolve45) => {
|
|
29492
29404
|
const timer = setTimeout(done, wait2);
|
|
29493
29405
|
function done() {
|
|
29494
29406
|
clearTimeout(timer);
|
|
29495
29407
|
options.signal?.removeEventListener("abort", done);
|
|
29496
|
-
|
|
29408
|
+
resolve45();
|
|
29497
29409
|
}
|
|
29498
29410
|
wake = done;
|
|
29499
29411
|
options.signal?.addEventListener("abort", done, { once: true });
|
|
@@ -30357,8 +30269,8 @@ var AcpClient = class extends EventEmitter {
|
|
|
30357
30269
|
try {
|
|
30358
30270
|
oomKilled = await Promise.race([
|
|
30359
30271
|
this.oomKills.consume().catch(() => false),
|
|
30360
|
-
new Promise((
|
|
30361
|
-
diagnosticTimer = setTimeout(() =>
|
|
30272
|
+
new Promise((resolve45) => {
|
|
30273
|
+
diagnosticTimer = setTimeout(() => resolve45(false), 100);
|
|
30362
30274
|
})
|
|
30363
30275
|
]);
|
|
30364
30276
|
} finally {
|
|
@@ -30782,7 +30694,7 @@ var AcpClient = class extends EventEmitter {
|
|
|
30782
30694
|
const current = this.activeRunIds.get(sessionId);
|
|
30783
30695
|
if (current)
|
|
30784
30696
|
return Promise.resolve(current);
|
|
30785
|
-
return new Promise((
|
|
30697
|
+
return new Promise((resolve45, reject) => {
|
|
30786
30698
|
const onUpdate = (update) => {
|
|
30787
30699
|
if (update.sessionId !== sessionId)
|
|
30788
30700
|
return;
|
|
@@ -30790,7 +30702,7 @@ var AcpClient = class extends EventEmitter {
|
|
|
30790
30702
|
if (!runId)
|
|
30791
30703
|
return;
|
|
30792
30704
|
cleanup();
|
|
30793
|
-
|
|
30705
|
+
resolve45(runId);
|
|
30794
30706
|
};
|
|
30795
30707
|
const timer = setTimeout(() => {
|
|
30796
30708
|
cleanup();
|
|
@@ -30869,14 +30781,14 @@ var AcpClient = class extends EventEmitter {
|
|
|
30869
30781
|
}
|
|
30870
30782
|
const id = this.nextId++;
|
|
30871
30783
|
const payload = { jsonrpc: "2.0", id, method, params };
|
|
30872
|
-
return new Promise((
|
|
30784
|
+
return new Promise((resolve45, reject) => {
|
|
30873
30785
|
const timer = backstop ? void 0 : setTimeout(() => {
|
|
30874
30786
|
this.pending.delete(id);
|
|
30875
30787
|
reject(new AcpRequestTimeoutError(method, timeoutMs, this.stderrTail, false, detail));
|
|
30876
30788
|
}, timeoutMs);
|
|
30877
30789
|
const sessionId = params?.sessionId;
|
|
30878
30790
|
this.pending.set(id, {
|
|
30879
|
-
resolve:
|
|
30791
|
+
resolve: resolve45,
|
|
30880
30792
|
reject,
|
|
30881
30793
|
timer,
|
|
30882
30794
|
method,
|
|
@@ -30907,7 +30819,7 @@ var AcpClient = class extends EventEmitter {
|
|
|
30907
30819
|
|
|
30908
30820
|
// apps/body/dist/agent-home.js
|
|
30909
30821
|
var import_yaml2 = __toESM(require_dist(), 1);
|
|
30910
|
-
import { existsSync as existsSync7, readFileSync as readFileSync5 } from "node:fs";
|
|
30822
|
+
import { existsSync as existsSync7, readFileSync as readFileSync5, watch } from "node:fs";
|
|
30911
30823
|
|
|
30912
30824
|
// node_modules/smol-toml/dist/date.js
|
|
30913
30825
|
var DATE_TIME_RE = /^(\d{4}-\d{2}-\d{2})?[T ]?(?:(\d{2}):\d{2}(?::\d{2}(?:\.\d+)?)?)?(Z|[-+]\d{2}:\d{2})?$/i;
|
|
@@ -32052,6 +31964,12 @@ function interpreterScriptArgument(argv) {
|
|
|
32052
31964
|
return void 0;
|
|
32053
31965
|
}
|
|
32054
31966
|
|
|
31967
|
+
// packages/api-contract/dist/workbench.js
|
|
31968
|
+
var CONNECTABLE_CONNECTOR_KINDS = [
|
|
31969
|
+
"trusty-squire",
|
|
31970
|
+
"tailscale"
|
|
31971
|
+
];
|
|
31972
|
+
|
|
32055
31973
|
// packages/api-contract/dist/connector-offers.js
|
|
32056
31974
|
var CONNECTOR_OFFER_WINDOW_MS = 2 * 6e4;
|
|
32057
31975
|
var OFFERABLE_CONNECTOR_KINDS = [
|
|
@@ -32394,17 +32312,21 @@ function cornerHasRepositoryWork(brief) {
|
|
|
32394
32312
|
return true;
|
|
32395
32313
|
if (brief.repositoryWork !== void 0)
|
|
32396
32314
|
return brief.repositoryWork;
|
|
32397
|
-
const
|
|
32398
|
-
|
|
32399
|
-
|
|
32400
|
-
|
|
32401
|
-
|
|
32402
|
-
const
|
|
32403
|
-
|
|
32404
|
-
|
|
32405
|
-
|
|
32406
|
-
|
|
32407
|
-
|
|
32315
|
+
const nonGoalsSections = [
|
|
32316
|
+
...brief.spec.matchAll(/^## (?:Non-goals|Not doing)\s*\n([\s\S]*?)(?=^## |$(?![\s\S]))/gim)
|
|
32317
|
+
].map((match) => match[1] ?? "");
|
|
32318
|
+
const prohibition = /^(?:repository edits?|repository changes?|pull requests?|(?:edit|modify|change) (?:the )?(?:repository|repo|code)|push(?:es)?|commit(?:s)?)[.!;]*$/i;
|
|
32319
|
+
for (const nonGoals of nonGoalsSections) {
|
|
32320
|
+
for (const line of nonGoals.split("\n")) {
|
|
32321
|
+
const bullet = /^\s*[-*]\s+/.test(line);
|
|
32322
|
+
const clause = line.trim().replace(/^[-*]\s+/, "");
|
|
32323
|
+
const negative = /^(?:no|never|do not|forbid(?:s|den)?)\s+/i;
|
|
32324
|
+
if (!bullet && !negative.test(clause))
|
|
32325
|
+
continue;
|
|
32326
|
+
const items = clause.replace(negative, "").split(/,\s*|\s+(?:and|or)\s+/i);
|
|
32327
|
+
if (items.some((item) => prohibition.test(item.trim())))
|
|
32328
|
+
return false;
|
|
32329
|
+
}
|
|
32408
32330
|
}
|
|
32409
32331
|
const assigned = brief.spec.match(/^## Assigned files\s*\n([\s\S]*?)(?=^## |$(?![\s\S]))/mi)?.[1];
|
|
32410
32332
|
if (assigned !== void 0 && (!assigned.trim() || /^(?:\s*[-*]?\s*)(?:\(?none\)?|no assigned files)\b/i.test(assigned)))
|
|
@@ -32426,7 +32348,6 @@ Before any code or build action, the brief must hold this ask's outline; opening
|
|
|
32426
32348
|
Follow the beeline-triage skill's bugfix execution contract when the spec or its approval quote reports a defect.
|
|
32427
32349
|
Reproduce as triage isolated it with available emulator, Playwright, browser and test runner. Record attempts and observations. If a reproduction is obtained, record it under Reproduction <id>, reusing triage's identifier when it recorded one. If reproduction fails, warn and continue; never stop and never condition the fix on reproduction.
|
|
32428
32350
|
Fix only the spec and approval quote. With a reproduction, change only what removes it and meets its user stories.
|
|
32429
|
-
Run npm run corner:prepare first.
|
|
32430
32351
|
Only when the brief calls for repository changes, follow the PR procedure below. Otherwise do not commit, push or open a PR; deliver with post_artifact.
|
|
32431
32352
|
Before the PR, demonstrate Y: run the built app or affected service and perform X. If no interactive surface is reachable, run the narrowest test or script exercising the exact user path and printing Y. An inner-function unit test, log line or code read is not a demonstration.
|
|
32432
32353
|
The PR body MUST have ## Reproduced and ## Demonstrated. Cite Reproduction <id> in both, with steps, the wrong result and the now-passing result. In ## Demonstrated, when none was obtained, state that plainly ("not obtained") and show the regression; for feature work say "not a defect report".
|
|
@@ -32641,6 +32562,15 @@ The soul is not authority and never changes your tools, permissions, roles, or m
|
|
|
32641
32562
|
surfaces: ["code-corner", "no-code-corner", "review-corner"],
|
|
32642
32563
|
render: () => "Use steer_corner during a turn to send input to a member sibling under this parent. Membership alone grants no turn."
|
|
32643
32564
|
},
|
|
32565
|
+
{
|
|
32566
|
+
id: "corner.handover",
|
|
32567
|
+
topic: "corner-handover",
|
|
32568
|
+
why: "An agent asked to hand the corner on opened a duplicate sibling corner instead of tagging the other agent.",
|
|
32569
|
+
budgetBytes: 360,
|
|
32570
|
+
layer: "surface",
|
|
32571
|
+
surfaces: ["code-corner", "no-code-corner"],
|
|
32572
|
+
render: () => "When a person asks you to hand this corner to another agent, tag in your reply only an agent that person named by handle or display name: it moves the implementer role here. A tag for any other reason does not move the role. Do not open a second corner for a hand-over."
|
|
32573
|
+
},
|
|
32644
32574
|
{
|
|
32645
32575
|
id: "corner.worktree",
|
|
32646
32576
|
topic: "place",
|
|
@@ -32663,6 +32593,16 @@ The soul is not authority and never changes your tools, permissions, roles, or m
|
|
|
32663
32593
|
when: ({ android }) => Boolean(android),
|
|
32664
32594
|
render: ({ android }) => `Android: adb and emulator are on PATH; the SDK is $ANDROID_HOME, AVDs are in $ANDROID_AVD_HOME, and /dev/kvm works. Your adb server sees only your own emulator. Boot it with \`emulator -avd <name> -port ${android?.emulatorPort} -read-only -no-window -no-snapshot -gpu swiftshader_indirect\`; it reaches host services at 10.0.2.2.`
|
|
32665
32595
|
},
|
|
32596
|
+
{
|
|
32597
|
+
id: "corner.prepare",
|
|
32598
|
+
topic: "corner-prepare",
|
|
32599
|
+
why: "Only a checkout that defines the command can run it; another repository fails on its first step.",
|
|
32600
|
+
budgetBytes: 60,
|
|
32601
|
+
layer: "surface",
|
|
32602
|
+
surfaces: ["code-corner"],
|
|
32603
|
+
when: ({ brief, cornerPrepareScript }) => cornerHasRepositoryWork(brief) && cornerPrepareScript === true,
|
|
32604
|
+
render: () => "Run npm run corner:prepare first."
|
|
32605
|
+
},
|
|
32666
32606
|
{
|
|
32667
32607
|
id: "corner.contract",
|
|
32668
32608
|
topic: "author-contract",
|
|
@@ -34309,6 +34249,32 @@ async function writeBackRoomClaudeLogin(input) {
|
|
|
34309
34249
|
return;
|
|
34310
34250
|
await writeBackDetachedClaudeLogin(target, source);
|
|
34311
34251
|
}
|
|
34252
|
+
function watchRoomClaudeLogin(input) {
|
|
34253
|
+
const claude = SHARED_CREDENTIALS.find((credential) => credential.dir === "claude");
|
|
34254
|
+
if (!existsSync7(resolve16(input.operatorHome ?? homedir11(), claude.source)))
|
|
34255
|
+
return void 0;
|
|
34256
|
+
const dir = resolve16(input.root, claude.dir);
|
|
34257
|
+
let pass = Promise.resolve();
|
|
34258
|
+
let watcher;
|
|
34259
|
+
try {
|
|
34260
|
+
watcher = watch(dir, (_event, filename) => {
|
|
34261
|
+
if (filename !== claude.target)
|
|
34262
|
+
return;
|
|
34263
|
+
pass = pass.then(() => writeBackRoomClaudeLogin(input)).catch((error) => {
|
|
34264
|
+
console.error(`[body] could not write back a refreshed Claude login under ${dir}:`, error);
|
|
34265
|
+
});
|
|
34266
|
+
});
|
|
34267
|
+
} catch (error) {
|
|
34268
|
+
console.error(`[body] could not watch the Claude login under ${dir}:`, error);
|
|
34269
|
+
return void 0;
|
|
34270
|
+
}
|
|
34271
|
+
watcher.on("error", (error) => {
|
|
34272
|
+
console.error(`[body] stopped watching the Claude login under ${dir}:`, error);
|
|
34273
|
+
watcher.close();
|
|
34274
|
+
});
|
|
34275
|
+
watcher.unref();
|
|
34276
|
+
return watcher;
|
|
34277
|
+
}
|
|
34312
34278
|
async function prepareRoomAgentHome(input) {
|
|
34313
34279
|
const root = resolve16(input.root);
|
|
34314
34280
|
const operatorHome = input.operatorHome ?? homedir11();
|
|
@@ -35450,7 +35416,7 @@ function clearInstallFailure(stateDir) {
|
|
|
35450
35416
|
} catch {
|
|
35451
35417
|
}
|
|
35452
35418
|
}
|
|
35453
|
-
var runSandboxInstallCommand = (command, args) => new Promise((
|
|
35419
|
+
var runSandboxInstallCommand = (command, args) => new Promise((resolve45) => {
|
|
35454
35420
|
execFile6(command, [...args], {
|
|
35455
35421
|
timeout: INSTALL_TIMEOUT_MS,
|
|
35456
35422
|
maxBuffer: INSTALL_OUTPUT_LIMIT * 2,
|
|
@@ -35460,7 +35426,7 @@ var runSandboxInstallCommand = (command, args) => new Promise((resolve44) => {
|
|
|
35460
35426
|
}, (error, stdout6, stderr) => {
|
|
35461
35427
|
const code = error && "code" in error && typeof error.code === "number" ? error.code : error ? null : 0;
|
|
35462
35428
|
const output = [stdout6, stderr].join("").trim();
|
|
35463
|
-
|
|
35429
|
+
resolve45({ code, output: output || (error ? error.message : "") });
|
|
35464
35430
|
});
|
|
35465
35431
|
});
|
|
35466
35432
|
function lastLine2(output, fallback) {
|
|
@@ -36204,7 +36170,7 @@ function describeCurrentReleaseOutcome(outcome) {
|
|
|
36204
36170
|
async function retryWhileAdapterReinstalls(run2, options = {}) {
|
|
36205
36171
|
const attempts = options.attempts ?? 12;
|
|
36206
36172
|
const delayMs = options.delayMs ?? 5e3;
|
|
36207
|
-
const sleep4 = options.sleep ?? ((ms) => new Promise((
|
|
36173
|
+
const sleep4 = options.sleep ?? ((ms) => new Promise((resolve45) => setTimeout(resolve45, ms)));
|
|
36208
36174
|
for (let attempt = 1; ; attempt += 1) {
|
|
36209
36175
|
try {
|
|
36210
36176
|
return await run2();
|
|
@@ -38826,7 +38792,7 @@ async function probeReleaseInSubprocess(input) {
|
|
|
38826
38792
|
return { kind: "unavailable", reason: `release ${input.releaseId} has no runnable CLI entrypoint` };
|
|
38827
38793
|
}
|
|
38828
38794
|
const timeoutMs = input.timeoutMs ?? CURRENT_RELEASE_PROBE_TIMEOUT_MS;
|
|
38829
|
-
return new Promise((
|
|
38795
|
+
return new Promise((resolve45) => {
|
|
38830
38796
|
const child = spawn14(input.execPath ?? process.execPath, [entrypoint, UPDATE_PROBE_COMMAND, "--config", input.runtimeConfigPath], { env: input.env ?? process.env, stdio: ["ignore", "pipe", "pipe"] });
|
|
38831
38797
|
let stdout6 = "";
|
|
38832
38798
|
let stderr = "";
|
|
@@ -38836,7 +38802,7 @@ async function probeReleaseInSubprocess(input) {
|
|
|
38836
38802
|
return;
|
|
38837
38803
|
settled = true;
|
|
38838
38804
|
clearTimeout(timer);
|
|
38839
|
-
|
|
38805
|
+
resolve45(outcome);
|
|
38840
38806
|
};
|
|
38841
38807
|
const timer = setTimeout(() => {
|
|
38842
38808
|
child.kill("SIGKILL");
|
|
@@ -38921,7 +38887,7 @@ import { dirname as dirname30 } from "node:path";
|
|
|
38921
38887
|
|
|
38922
38888
|
// apps/body/dist/agent-runtime.js
|
|
38923
38889
|
import { homedir as homedir19 } from "node:os";
|
|
38924
|
-
import { dirname as dirname29, join as join21, resolve as
|
|
38890
|
+
import { dirname as dirname29, join as join21, resolve as resolve43 } from "node:path";
|
|
38925
38891
|
|
|
38926
38892
|
// apps/body/dist/model-availability.js
|
|
38927
38893
|
var SECRET_VALUE = /(?:token|key|secret|password)=?[^\s,;]*/gi;
|
|
@@ -39055,10 +39021,10 @@ var LOGIN_URL = /https:\/\/login\.tailscale\.com\/[A-Za-z0-9_/-]+/u;
|
|
|
39055
39021
|
function clipped(value) {
|
|
39056
39022
|
return value.length <= OUTPUT_LIMIT ? value : value.slice(value.length - OUTPUT_LIMIT);
|
|
39057
39023
|
}
|
|
39058
|
-
var runTailscaleCommand = (command, args) => new Promise((
|
|
39024
|
+
var runTailscaleCommand = (command, args) => new Promise((resolve45) => {
|
|
39059
39025
|
execFile7(command, [...args], { timeout: COMMAND_TIMEOUT_MS, maxBuffer: OUTPUT_LIMIT * 2 }, (error, stdout6, stderr) => {
|
|
39060
39026
|
const code = error && "code" in error && typeof error.code === "number" ? error.code : error ? null : 0;
|
|
39061
|
-
|
|
39027
|
+
resolve45({ code, stdout: clipped(stdout6), stderr: clipped(stderr) });
|
|
39062
39028
|
});
|
|
39063
39029
|
});
|
|
39064
39030
|
function loginUrlFrom(status, output) {
|
|
@@ -39622,7 +39588,7 @@ import { execFile as execFile13 } from "node:child_process";
|
|
|
39622
39588
|
import { createHash as createHash15 } from "node:crypto";
|
|
39623
39589
|
import { existsSync as existsSync10, mkdirSync as mkdirSync3 } from "node:fs";
|
|
39624
39590
|
import { mkdir as mkdir27, readdir as readdir9, realpath as realpath2, rm as rm15 } from "node:fs/promises";
|
|
39625
|
-
import { dirname as dirname27, relative as relative3, resolve as
|
|
39591
|
+
import { dirname as dirname27, relative as relative3, resolve as resolve38, sep as sep2 } from "node:path";
|
|
39626
39592
|
import { promisify as promisify8 } from "node:util";
|
|
39627
39593
|
|
|
39628
39594
|
// apps/body/dist/grant-runner.js
|
|
@@ -40342,11 +40308,11 @@ async function runServerCommandIntake(options) {
|
|
|
40342
40308
|
if (attempt === 3)
|
|
40343
40309
|
throw error;
|
|
40344
40310
|
const waitMs = Math.max(250 * 2 ** attempt, error instanceof DaemonApiError ? error.retryAfterMs ?? 0 : 0);
|
|
40345
|
-
await new Promise((
|
|
40311
|
+
await new Promise((resolve45) => {
|
|
40346
40312
|
const done = () => {
|
|
40347
40313
|
clearTimeout(timer);
|
|
40348
40314
|
signal?.removeEventListener("abort", done);
|
|
40349
|
-
|
|
40315
|
+
resolve45();
|
|
40350
40316
|
};
|
|
40351
40317
|
const timer = setTimeout(done, waitMs);
|
|
40352
40318
|
signal?.addEventListener("abort", done, { once: true });
|
|
@@ -40437,11 +40403,11 @@ async function runServerCommandIntake(options) {
|
|
|
40437
40403
|
}
|
|
40438
40404
|
}
|
|
40439
40405
|
options.onPoll?.();
|
|
40440
|
-
const reconcile = await new Promise((
|
|
40406
|
+
const reconcile = await new Promise((resolve45) => {
|
|
40441
40407
|
const done = (needed) => {
|
|
40442
40408
|
signal?.removeEventListener("abort", aborted);
|
|
40443
40409
|
wake = void 0;
|
|
40444
|
-
|
|
40410
|
+
resolve45(needed);
|
|
40445
40411
|
};
|
|
40446
40412
|
const aborted = () => done(false);
|
|
40447
40413
|
wake = done;
|
|
@@ -40484,9 +40450,9 @@ async function runServerCommandIntake(options) {
|
|
|
40484
40450
|
import { execFile as execFile12 } from "node:child_process";
|
|
40485
40451
|
import { createHash as createHash14 } from "node:crypto";
|
|
40486
40452
|
import { existsSync as existsSync9 } from "node:fs";
|
|
40487
|
-
import { mkdir as mkdir26, readFile as
|
|
40453
|
+
import { mkdir as mkdir26, readFile as readFile30, writeFile as writeFile20 } from "node:fs/promises";
|
|
40488
40454
|
import { homedir as homedir18, hostname as hostname3 } from "node:os";
|
|
40489
|
-
import { dirname as dirname26, join as join20, resolve as
|
|
40455
|
+
import { dirname as dirname26, join as join20, resolve as resolve37 } from "node:path";
|
|
40490
40456
|
import { promisify as promisify7 } from "node:util";
|
|
40491
40457
|
|
|
40492
40458
|
// apps/body/dist/agent-command-catalog.js
|
|
@@ -41111,6 +41077,8 @@ function sessionConfigFingerprint(input) {
|
|
|
41111
41077
|
];
|
|
41112
41078
|
if (input.repositoryWork !== void 0)
|
|
41113
41079
|
fingerprint.push({ repositoryWork: input.repositoryWork });
|
|
41080
|
+
if (input.cornerPrepareScript !== void 0)
|
|
41081
|
+
fingerprint.push({ cornerPrepareScript: input.cornerPrepareScript });
|
|
41114
41082
|
if (input.reviewerHandle !== void 0)
|
|
41115
41083
|
fingerprint.push(input.reviewerHandle);
|
|
41116
41084
|
if (input.devices?.length)
|
|
@@ -41121,11 +41089,24 @@ function mountedMcpSet(servers) {
|
|
|
41121
41089
|
return [...new Set(servers ?? [])].sort((left, right) => left.localeCompare(right));
|
|
41122
41090
|
}
|
|
41123
41091
|
|
|
41092
|
+
// apps/body/dist/corner-prepare-script.js
|
|
41093
|
+
import { readFile as readFile25 } from "node:fs/promises";
|
|
41094
|
+
import { resolve as resolve29 } from "node:path";
|
|
41095
|
+
var CORNER_PREPARE_SCRIPT = "corner:prepare";
|
|
41096
|
+
async function hasCornerPrepareScript(worktreePath) {
|
|
41097
|
+
try {
|
|
41098
|
+
const parsed = JSON.parse(await readFile25(resolve29(worktreePath, "package.json"), "utf8"));
|
|
41099
|
+
return typeof parsed.scripts?.[CORNER_PREPARE_SCRIPT] === "string";
|
|
41100
|
+
} catch {
|
|
41101
|
+
return false;
|
|
41102
|
+
}
|
|
41103
|
+
}
|
|
41104
|
+
|
|
41124
41105
|
// apps/body/dist/pi-mcp-bridge.js
|
|
41125
41106
|
import { execFile as execFile9 } from "node:child_process";
|
|
41126
|
-
import { mkdtemp as mkdtemp2, mkdir as mkdir20, readFile as
|
|
41107
|
+
import { mkdtemp as mkdtemp2, mkdir as mkdir20, readFile as readFile26, rm as rm12, unlink as unlink8 } from "node:fs/promises";
|
|
41127
41108
|
import { tmpdir as tmpdir5 } from "node:os";
|
|
41128
|
-
import { resolve as
|
|
41109
|
+
import { resolve as resolve30 } from "node:path";
|
|
41129
41110
|
import { promisify as promisify5 } from "node:util";
|
|
41130
41111
|
var PI_MCP_BRIDGE_FILENAME = "beeline-mcp-bridge.js";
|
|
41131
41112
|
var execFileAsync5 = promisify5(execFile9);
|
|
@@ -41136,7 +41117,7 @@ async function piHasNativeMcp(command, env) {
|
|
|
41136
41117
|
let probe = nativeMcpProbes.get(cacheKey);
|
|
41137
41118
|
if (!probe) {
|
|
41138
41119
|
probe = (async () => {
|
|
41139
|
-
const home = await mkdtemp2(
|
|
41120
|
+
const home = await mkdtemp2(resolve30(tmpdir5(), "beeline-pi-mcp-probe-"));
|
|
41140
41121
|
try {
|
|
41141
41122
|
const { stdout: stdout6 } = await execFileAsync5(command, ["mcp", "list", "--json"], {
|
|
41142
41123
|
cwd: home,
|
|
@@ -41157,7 +41138,7 @@ async function piHasNativeMcp(command, env) {
|
|
|
41157
41138
|
}
|
|
41158
41139
|
async function isolatedPiConfig(piHome) {
|
|
41159
41140
|
try {
|
|
41160
|
-
const parsed = JSON.parse(await
|
|
41141
|
+
const parsed = JSON.parse(await readFile26(resolve30(piHome, "mcp.json"), "utf8"));
|
|
41161
41142
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
|
|
41162
41143
|
} catch (error) {
|
|
41163
41144
|
if (error.code !== "ENOENT")
|
|
@@ -41211,8 +41192,8 @@ async function installPiMcpBridge(input) {
|
|
|
41211
41192
|
return void 0;
|
|
41212
41193
|
if (!input.piHome)
|
|
41213
41194
|
return void 0;
|
|
41214
|
-
const directory =
|
|
41215
|
-
const path =
|
|
41195
|
+
const directory = resolve30(input.piHome, "extensions");
|
|
41196
|
+
const path = resolve30(directory, PI_MCP_BRIDGE_FILENAME);
|
|
41216
41197
|
try {
|
|
41217
41198
|
const config = await isolatedPiConfig(input.piHome);
|
|
41218
41199
|
const nativeMcp = input.nativeMcp ?? await piHasNativeMcp(input.piCommand ?? "pi", input.agentEnv);
|
|
@@ -41225,13 +41206,13 @@ async function installPiMcpBridge(input) {
|
|
|
41225
41206
|
env: Object.fromEntries((server.env ?? []).map((entry) => [entry.name, entry.value])),
|
|
41226
41207
|
exposure: "direct"
|
|
41227
41208
|
};
|
|
41228
|
-
await writeIsolatedHarnessFile(
|
|
41209
|
+
await writeIsolatedHarnessFile(resolve30(input.piHome, "mcp.json"), `${JSON.stringify({ ...config, mcpServers: mcpServers2 }, null, 2)}
|
|
41229
41210
|
`);
|
|
41230
41211
|
await unlink8(path).catch((error) => {
|
|
41231
41212
|
if (error.code !== "ENOENT")
|
|
41232
41213
|
throw error;
|
|
41233
41214
|
});
|
|
41234
|
-
return
|
|
41215
|
+
return resolve30(input.piHome, "mcp.json");
|
|
41235
41216
|
}
|
|
41236
41217
|
const servers = [...input.servers, ...importedStdioServers(config, input.servers)];
|
|
41237
41218
|
if (!servers.length)
|
|
@@ -41244,7 +41225,7 @@ async function installPiMcpBridge(input) {
|
|
|
41244
41225
|
env: Object.fromEntries((server.env ?? []).map((entry) => [entry.name, entry.value])),
|
|
41245
41226
|
enabled: false
|
|
41246
41227
|
};
|
|
41247
|
-
await writeIsolatedHarnessFile(
|
|
41228
|
+
await writeIsolatedHarnessFile(resolve30(input.piHome, "mcp.json"), `${JSON.stringify({ ...config, mcpServers }, null, 2)}
|
|
41248
41229
|
`);
|
|
41249
41230
|
await mkdir20(directory, { recursive: true, mode: 448 });
|
|
41250
41231
|
await writeIsolatedHarnessFile(path, piMcpBridgeSource(servers));
|
|
@@ -41436,8 +41417,8 @@ export default async function (pi) {
|
|
|
41436
41417
|
|
|
41437
41418
|
// apps/body/dist/corner-branch-sync.js
|
|
41438
41419
|
import { execFile as execFile10 } from "node:child_process";
|
|
41439
|
-
import { access as access2, readFile as
|
|
41440
|
-
import { resolve as
|
|
41420
|
+
import { access as access2, readFile as readFile27 } from "node:fs/promises";
|
|
41421
|
+
import { resolve as resolve31 } from "node:path";
|
|
41441
41422
|
var CORNER_GIT_SYNC_TIMEOUT_MS = 12e4;
|
|
41442
41423
|
var CORNER_GIT_SYNC_KILL_GRACE_MS = 1e3;
|
|
41443
41424
|
var CornerGitSyncInterruptedError = class extends Error {
|
|
@@ -41451,7 +41432,7 @@ async function syncCornerBranch(input) {
|
|
|
41451
41432
|
try {
|
|
41452
41433
|
if (signal.aborted)
|
|
41453
41434
|
throw interrupted();
|
|
41454
|
-
return await new Promise((
|
|
41435
|
+
return await new Promise((resolve45, reject) => {
|
|
41455
41436
|
let killTimer;
|
|
41456
41437
|
let stdout6 = "";
|
|
41457
41438
|
let failure = null;
|
|
@@ -41485,19 +41466,19 @@ async function syncCornerBranch(input) {
|
|
|
41485
41466
|
else if (failure)
|
|
41486
41467
|
reject(failure);
|
|
41487
41468
|
else
|
|
41488
|
-
|
|
41469
|
+
resolve45(stdout6);
|
|
41489
41470
|
});
|
|
41490
41471
|
else
|
|
41491
|
-
input.git(args).then(
|
|
41472
|
+
input.git(args).then(resolve45, reject).finally(cleanup2);
|
|
41492
41473
|
});
|
|
41493
41474
|
} finally {
|
|
41494
41475
|
clearTimeout(timer);
|
|
41495
41476
|
}
|
|
41496
41477
|
};
|
|
41497
|
-
const marker = await
|
|
41498
|
-
const gitDir =
|
|
41478
|
+
const marker = await readFile27(resolve31(input.worktreePath, ".git"), "utf8").catch(() => "");
|
|
41479
|
+
const gitDir = resolve31(input.worktreePath, marker.startsWith("gitdir: ") ? marker.slice(8).trim() : ".git");
|
|
41499
41480
|
for (const directory of ["rebase-merge", "rebase-apply"]) {
|
|
41500
|
-
if (await access2(
|
|
41481
|
+
if (await access2(resolve31(gitDir, directory)).then(() => true, () => false))
|
|
41501
41482
|
await git(["rebase", "--abort"], true);
|
|
41502
41483
|
}
|
|
41503
41484
|
const remoteRef = `refs/remotes/origin/${input.featureBranch}`;
|
|
@@ -41545,7 +41526,7 @@ async function contains(git, head, ancestor) {
|
|
|
41545
41526
|
}
|
|
41546
41527
|
|
|
41547
41528
|
// apps/body/dist/room-session.js
|
|
41548
|
-
import { resolve as
|
|
41529
|
+
import { resolve as resolve32 } from "node:path";
|
|
41549
41530
|
import { homedir as homedir16 } from "node:os";
|
|
41550
41531
|
|
|
41551
41532
|
// apps/body/dist/read-only-policy.js
|
|
@@ -41786,14 +41767,14 @@ function readOnlyMcpServer(config, cwd, agentMemoryDir) {
|
|
|
41786
41767
|
command: config.readonlyMcpCommand,
|
|
41787
41768
|
args: [...config.readonlyMcpArgs ?? []],
|
|
41788
41769
|
env: [
|
|
41789
|
-
{ name: "BEELINE_READONLY_ROOT", value:
|
|
41770
|
+
{ name: "BEELINE_READONLY_ROOT", value: resolve32(cwd) },
|
|
41790
41771
|
...config.agentHomeRoot ? [
|
|
41791
41772
|
{
|
|
41792
41773
|
name: "BEELINE_READONLY_AGENT_SKILLS_ROOT",
|
|
41793
|
-
value:
|
|
41774
|
+
value: resolve32(config.agentHomeRoot, skillDir, "skills")
|
|
41794
41775
|
}
|
|
41795
41776
|
] : [],
|
|
41796
|
-
...agentMemoryDir ? [{ name: "BEELINE_READONLY_AGENT_MEMORY_ROOT", value:
|
|
41777
|
+
...agentMemoryDir ? [{ name: "BEELINE_READONLY_AGENT_MEMORY_ROOT", value: resolve32(agentMemoryDir) }] : []
|
|
41797
41778
|
]
|
|
41798
41779
|
};
|
|
41799
41780
|
}
|
|
@@ -41847,15 +41828,15 @@ async function awaitInstitutionalContext(fetch2, log2 = console.warn, budgetMs =
|
|
|
41847
41828
|
|
|
41848
41829
|
// apps/body/dist/codegraph.js
|
|
41849
41830
|
import { execFile as execFile11 } from "node:child_process";
|
|
41850
|
-
import { access as access3, appendFile, mkdir as mkdir21, readFile as
|
|
41851
|
-
import { dirname as dirname23, isAbsolute as isAbsolute3, resolve as
|
|
41831
|
+
import { access as access3, appendFile, mkdir as mkdir21, readFile as readFile28 } from "node:fs/promises";
|
|
41832
|
+
import { dirname as dirname23, isAbsolute as isAbsolute3, resolve as resolve33 } from "node:path";
|
|
41852
41833
|
import { promisify as promisify6 } from "node:util";
|
|
41853
41834
|
var execFileAsync6 = promisify6(execFile11);
|
|
41854
41835
|
var CODEGRAPH_MCP_SERVER_NAME = "codegraph";
|
|
41855
41836
|
var CODEGRAPH_INDEX_PATH = ".codegraph/codegraph.db";
|
|
41856
41837
|
var CODEGRAPH_PREPARE_TIMEOUT_MS = 12e4;
|
|
41857
41838
|
function codegraphIndexDirectory(cwd) {
|
|
41858
|
-
return
|
|
41839
|
+
return resolve33(cwd, dirname23(CODEGRAPH_INDEX_PATH));
|
|
41859
41840
|
}
|
|
41860
41841
|
function codegraphMcpServer(config, cwd, options) {
|
|
41861
41842
|
if (!config.codegraphCommand)
|
|
@@ -41863,7 +41844,7 @@ function codegraphMcpServer(config, cwd, options) {
|
|
|
41863
41844
|
return {
|
|
41864
41845
|
name: CODEGRAPH_MCP_SERVER_NAME,
|
|
41865
41846
|
command: config.codegraphCommand,
|
|
41866
|
-
args: ["serve", "--mcp", "--path",
|
|
41847
|
+
args: ["serve", "--mcp", "--path", resolve33(cwd), ...options.readonly ? ["--no-watch"] : []],
|
|
41867
41848
|
env: [
|
|
41868
41849
|
{ name: "CODEGRAPH_TELEMETRY", value: "0" },
|
|
41869
41850
|
// One MCP child per harness session is easier to contain than a daemon
|
|
@@ -41881,7 +41862,7 @@ async function isGitWorktree(cwd) {
|
|
|
41881
41862
|
cwd,
|
|
41882
41863
|
timeout: 1e4
|
|
41883
41864
|
});
|
|
41884
|
-
return
|
|
41865
|
+
return resolve33(stdout6.trim()) === resolve33(cwd);
|
|
41885
41866
|
} catch {
|
|
41886
41867
|
return false;
|
|
41887
41868
|
}
|
|
@@ -41895,9 +41876,9 @@ async function excludeIndexFromGitStatus(cwd) {
|
|
|
41895
41876
|
const gitPath = stdout6.trim();
|
|
41896
41877
|
if (!gitPath)
|
|
41897
41878
|
return;
|
|
41898
|
-
const path = isAbsolute3(gitPath) ? gitPath :
|
|
41879
|
+
const path = isAbsolute3(gitPath) ? gitPath : resolve33(cwd, gitPath);
|
|
41899
41880
|
await mkdir21(dirname23(path), { recursive: true });
|
|
41900
|
-
const existing = await
|
|
41881
|
+
const existing = await readFile28(path, "utf8").catch(() => "");
|
|
41901
41882
|
if (existing.split("\n").includes(".codegraph/"))
|
|
41902
41883
|
return;
|
|
41903
41884
|
await appendFile(path, `${existing && !existing.endsWith("\n") ? "\n" : ""}.codegraph/
|
|
@@ -41910,7 +41891,7 @@ async function prepareCodegraphIndex(config, cwd) {
|
|
|
41910
41891
|
if (!command || !await isGitWorktree(cwd))
|
|
41911
41892
|
return false;
|
|
41912
41893
|
await excludeIndexFromGitStatus(cwd);
|
|
41913
|
-
const indexPath =
|
|
41894
|
+
const indexPath = resolve33(cwd, CODEGRAPH_INDEX_PATH);
|
|
41914
41895
|
const indexed = await access3(indexPath).then(() => true, () => false);
|
|
41915
41896
|
const args = indexed ? ["sync", "--quiet", cwd] : ["init", "--yes", cwd];
|
|
41916
41897
|
try {
|
|
@@ -41938,7 +41919,7 @@ var SCHEDULE_RAN_VERB = "ran a schedule for";
|
|
|
41938
41919
|
|
|
41939
41920
|
// apps/body/dist/turn-trace.js
|
|
41940
41921
|
import { appendFile as appendFile2, mkdir as mkdir22, readdir as readdir7, rm as rm13 } from "node:fs/promises";
|
|
41941
|
-
import { resolve as
|
|
41922
|
+
import { resolve as resolve34 } from "node:path";
|
|
41942
41923
|
import { performance as performance3 } from "node:perf_hooks";
|
|
41943
41924
|
var TURN_PHASES = [
|
|
41944
41925
|
/** Enqueued on `SessionScheduler` until this turn holds a slot. A capacity wait lives here. */
|
|
@@ -42224,7 +42205,7 @@ function formatTurnTraceLine(record5) {
|
|
|
42224
42205
|
return [head, ...record5.attempts.map((attempt) => formatTurnAttempt(attempt))].join("\n ");
|
|
42225
42206
|
}
|
|
42226
42207
|
function turnTraceDirectory(runtimeDir) {
|
|
42227
|
-
return
|
|
42208
|
+
return resolve34(runtimeDir, "turn-traces");
|
|
42228
42209
|
}
|
|
42229
42210
|
var TURN_TRACE_RETENTION_DAYS = 7;
|
|
42230
42211
|
function traceFileName(date) {
|
|
@@ -42241,7 +42222,7 @@ var TurnTraceFile = class {
|
|
|
42241
42222
|
this.options = options;
|
|
42242
42223
|
}
|
|
42243
42224
|
path(now2 = (this.options.clock ?? (() => /* @__PURE__ */ new Date()))()) {
|
|
42244
|
-
return
|
|
42225
|
+
return resolve34(this.directory, traceFileName(now2));
|
|
42245
42226
|
}
|
|
42246
42227
|
write(record5) {
|
|
42247
42228
|
this.tail = this.tail.catch(() => void 0).then(async () => {
|
|
@@ -42265,7 +42246,7 @@ var TurnTraceFile = class {
|
|
|
42265
42246
|
this.prunedDay = day;
|
|
42266
42247
|
const cutoff = traceFileName(new Date(now2.getTime() - TURN_TRACE_RETENTION_DAYS * 864e5));
|
|
42267
42248
|
const names = await readdir7(this.directory).catch(() => []);
|
|
42268
|
-
await Promise.all(names.filter((name) => /^turns-\d{4}-\d{2}-\d{2}\.jsonl$/.test(name) && name < cutoff).map((name) => rm13(
|
|
42249
|
+
await Promise.all(names.filter((name) => /^turns-\d{4}-\d{2}-\d{2}\.jsonl$/.test(name) && name < cutoff).map((name) => rm13(resolve34(this.directory, name), { force: true })));
|
|
42269
42250
|
}
|
|
42270
42251
|
};
|
|
42271
42252
|
|
|
@@ -42437,6 +42418,7 @@ var MonolithRoomTurnLoop = class {
|
|
|
42437
42418
|
this.wakeIntake = void 0;
|
|
42438
42419
|
}
|
|
42439
42420
|
client;
|
|
42421
|
+
claudeLoginWatch;
|
|
42440
42422
|
sessionId;
|
|
42441
42423
|
sessionCwd;
|
|
42442
42424
|
sessionCommit;
|
|
@@ -42494,7 +42476,7 @@ var MonolithRoomTurnLoop = class {
|
|
|
42494
42476
|
requestId: call.requestId,
|
|
42495
42477
|
generationId: call.generationId,
|
|
42496
42478
|
target: "squire",
|
|
42497
|
-
...resourceCallFacts({ method: "tools/call", params: { name: call.tool
|
|
42479
|
+
...resourceCallFacts({ method: "tools/call", params: { name: call.tool } })
|
|
42498
42480
|
})).allowed, options.config.operatorHome ?? homedir17(), void 0, (decision2) => {
|
|
42499
42481
|
options.api.execute("postSquireApprovalDecision", { roomId: options.roomId, ...decision2 }).catch(() => {
|
|
42500
42482
|
});
|
|
@@ -42658,8 +42640,26 @@ var MonolithRoomTurnLoop = class {
|
|
|
42658
42640
|
...promptBytes ? { promptBytes } : {}
|
|
42659
42641
|
};
|
|
42660
42642
|
}
|
|
42643
|
+
/**
|
|
42644
|
+
* Watch this client's Claude login so a refresh made while the
|
|
42645
|
+
* Room is idle reaches other Rooms at once (see `watchRoomClaudeLogin`).
|
|
42646
|
+
*/
|
|
42647
|
+
watchClaudeLogin() {
|
|
42648
|
+
this.stopClaudeLoginWatch();
|
|
42649
|
+
if (this.options.config.agentKind !== "claude" || !this.options.config.agentHomeRoot)
|
|
42650
|
+
return;
|
|
42651
|
+
this.claudeLoginWatch = watchRoomClaudeLogin({
|
|
42652
|
+
root: this.options.config.agentHomeRoot,
|
|
42653
|
+
operatorHome: this.options.config.operatorHome
|
|
42654
|
+
});
|
|
42655
|
+
}
|
|
42656
|
+
stopClaudeLoginWatch() {
|
|
42657
|
+
this.claudeLoginWatch?.close();
|
|
42658
|
+
this.claudeLoginWatch = void 0;
|
|
42659
|
+
}
|
|
42661
42660
|
async discardSession() {
|
|
42662
42661
|
const client = this.client;
|
|
42662
|
+
this.stopClaudeLoginWatch();
|
|
42663
42663
|
this.client = void 0;
|
|
42664
42664
|
this.sessionId = void 0;
|
|
42665
42665
|
this.sessionCwd = void 0;
|
|
@@ -42967,6 +42967,7 @@ var MonolithRoomTurnLoop = class {
|
|
|
42967
42967
|
};
|
|
42968
42968
|
this.client = (this.options.createAcpClient ?? ((value) => new AcpClient(value)))(clientOptions);
|
|
42969
42969
|
await this.client.start();
|
|
42970
|
+
this.watchClaudeLogin();
|
|
42970
42971
|
const persona = configuration.soul ?? self?.soul;
|
|
42971
42972
|
const repositoryInfo = repositoryState.resolution === "repository" && repositoryState.key ? {
|
|
42972
42973
|
name: repositoryState.key,
|
|
@@ -43082,6 +43083,7 @@ var MonolithRoomTurnLoop = class {
|
|
|
43082
43083
|
return void 0;
|
|
43083
43084
|
trace?.retry({ provider: next, ...reason ? { reason } : {} });
|
|
43084
43085
|
const client = this.client;
|
|
43086
|
+
this.stopClaudeLoginWatch();
|
|
43085
43087
|
this.client = void 0;
|
|
43086
43088
|
this.sessionId = void 0;
|
|
43087
43089
|
this.sessionFingerprint = void 0;
|
|
@@ -43165,8 +43167,8 @@ var MonolithRoomTurnLoop = class {
|
|
|
43165
43167
|
let timer;
|
|
43166
43168
|
const stats = statsPromise && remaining > 0 ? await Promise.race([
|
|
43167
43169
|
statsPromise,
|
|
43168
|
-
new Promise((
|
|
43169
|
-
timer = setTimeout(() =>
|
|
43170
|
+
new Promise((resolve45) => {
|
|
43171
|
+
timer = setTimeout(() => resolve45(void 0), remaining);
|
|
43170
43172
|
})
|
|
43171
43173
|
]).finally(() => {
|
|
43172
43174
|
if (timer)
|
|
@@ -43580,9 +43582,9 @@ function roomMessagePrompt(author, body, attachments, delivered, harnessAcceptsI
|
|
|
43580
43582
|
|
|
43581
43583
|
// apps/body/dist/corner-github-auth.js
|
|
43582
43584
|
import { chmod as chmod9, mkdir as mkdir24, writeFile as writeFile19 } from "node:fs/promises";
|
|
43583
|
-
import { delimiter as delimiter3, resolve as
|
|
43585
|
+
import { delimiter as delimiter3, resolve as resolve35 } from "node:path";
|
|
43584
43586
|
async function installCornerGitHubWrappers(input) {
|
|
43585
|
-
const bin =
|
|
43587
|
+
const bin = resolve35(input.root, "beeline-github-bin");
|
|
43586
43588
|
await mkdir24(bin, { recursive: true, mode: 448 });
|
|
43587
43589
|
const common = {
|
|
43588
43590
|
node: process.execPath,
|
|
@@ -43594,13 +43596,13 @@ async function installCornerGitHubWrappers(input) {
|
|
|
43594
43596
|
gitCommand: input.gitBinary,
|
|
43595
43597
|
originUrl: input.originUrl ?? ""
|
|
43596
43598
|
};
|
|
43597
|
-
await writeLauncher(
|
|
43599
|
+
await writeLauncher(resolve35(bin, "git"), {
|
|
43598
43600
|
...common,
|
|
43599
43601
|
command: input.gitBinary,
|
|
43600
43602
|
launcher: "git",
|
|
43601
43603
|
restFallback: false
|
|
43602
43604
|
});
|
|
43603
|
-
await writeLauncher(
|
|
43605
|
+
await writeLauncher(resolve35(bin, "gh"), {
|
|
43604
43606
|
...common,
|
|
43605
43607
|
command: input.ghBinary ?? "",
|
|
43606
43608
|
launcher: "gh",
|
|
@@ -44028,35 +44030,35 @@ if (!refusal) {
|
|
|
44028
44030
|
// apps/body/dist/warm-node-modules.js
|
|
44029
44031
|
import { createHash as createHash13, randomUUID as randomUUID11 } from "node:crypto";
|
|
44030
44032
|
import { constants as fsConstants3 } from "node:fs";
|
|
44031
|
-
import { chmod as chmod10, copyFile as copyFile2, link, lstat as lstat4, mkdir as mkdir25, readdir as readdir8, readFile as
|
|
44032
|
-
import { dirname as dirname25, join as join19, resolve as
|
|
44033
|
+
import { chmod as chmod10, copyFile as copyFile2, link, lstat as lstat4, mkdir as mkdir25, readdir as readdir8, readFile as readFile29, readlink as readlink2, rename as rename10, rm as rm14, stat as stat8, symlink as symlink3, utimes } from "node:fs/promises";
|
|
44034
|
+
import { dirname as dirname25, join as join19, resolve as resolve36 } from "node:path";
|
|
44033
44035
|
var STORE_FORMAT = "v1";
|
|
44034
44036
|
var STAGING_PREFIX = ".beeline-warm-";
|
|
44035
44037
|
var STAGING_SWEEP_MS = 24 * 60 * 60 * 1e3;
|
|
44036
44038
|
var WARM_STORE_MAX_ENTRIES = 3;
|
|
44037
44039
|
function sharedNpmCacheDir(supervisorRoot) {
|
|
44038
|
-
return
|
|
44040
|
+
return resolve36(supervisorRoot, "beeline", "npm-cache");
|
|
44039
44041
|
}
|
|
44040
44042
|
function sharedPnpmStoreDir(supervisorRoot) {
|
|
44041
|
-
return
|
|
44043
|
+
return resolve36(supervisorRoot, "beeline", "pnpm-store");
|
|
44042
44044
|
}
|
|
44043
44045
|
function sharedCargoTargetDir(supervisorRoot) {
|
|
44044
|
-
return
|
|
44046
|
+
return resolve36(supervisorRoot, "beeline", "cargo-target");
|
|
44045
44047
|
}
|
|
44046
44048
|
function sharedTurboCacheDir(supervisorRoot) {
|
|
44047
|
-
return
|
|
44049
|
+
return resolve36(supervisorRoot, "beeline", "turbo-cache");
|
|
44048
44050
|
}
|
|
44049
44051
|
function warmNodeModulesStoreDir(supervisorRoot) {
|
|
44050
|
-
return
|
|
44052
|
+
return resolve36(supervisorRoot, "beeline", "node-modules");
|
|
44051
44053
|
}
|
|
44052
44054
|
function mobileNodeModulesStoreDir(supervisorRoot) {
|
|
44053
|
-
return
|
|
44055
|
+
return resolve36(supervisorRoot, "beeline", "node-modules-mobile");
|
|
44054
44056
|
}
|
|
44055
44057
|
function isPlanRefusal(value) {
|
|
44056
44058
|
return "failure" in value;
|
|
44057
44059
|
}
|
|
44058
44060
|
async function readWarmPlan(worktreePath) {
|
|
44059
|
-
const lockfile = await
|
|
44061
|
+
const lockfile = await readFile29(resolve36(worktreePath, "package-lock.json")).catch(() => void 0);
|
|
44060
44062
|
if (!lockfile)
|
|
44061
44063
|
return { failure: "no-lockfile" };
|
|
44062
44064
|
const packages = parseLockfilePackages(lockfile);
|
|
@@ -44095,11 +44097,11 @@ async function seedWarmNodeModules(input) {
|
|
|
44095
44097
|
return { reason: plan.failure, ...plan.detail ? { detail: plan.detail } : {} };
|
|
44096
44098
|
}
|
|
44097
44099
|
for (const tree of plan.trees) {
|
|
44098
|
-
if (await pathExists(
|
|
44100
|
+
if (await pathExists(resolve36(input.worktreePath, tree))) {
|
|
44099
44101
|
return { reason: "present", key: plan.key };
|
|
44100
44102
|
}
|
|
44101
44103
|
}
|
|
44102
|
-
const entry =
|
|
44104
|
+
const entry = resolve36(input.storeRoot, plan.key);
|
|
44103
44105
|
if (!await isDirectory(entry))
|
|
44104
44106
|
return { reason: "cold", key: plan.key };
|
|
44105
44107
|
const [storeDevice, checkoutDevice] = await Promise.all([
|
|
@@ -44109,19 +44111,19 @@ async function seedWarmNodeModules(input) {
|
|
|
44109
44111
|
if (storeDevice === void 0 || storeDevice !== checkoutDevice) {
|
|
44110
44112
|
return { reason: "cross-device", key: plan.key };
|
|
44111
44113
|
}
|
|
44112
|
-
const staging =
|
|
44114
|
+
const staging = resolve36(input.storeRoot, `${STAGING_PREFIX}${process.pid}.${randomUUID11()}`);
|
|
44113
44115
|
const placed = [];
|
|
44114
44116
|
const now2 = (input.now ?? Date.now)();
|
|
44115
44117
|
try {
|
|
44116
44118
|
await sweepStaleStaging(input.storeRoot, now2);
|
|
44117
44119
|
await utimes(entry, now2 / 1e3, now2 / 1e3).catch(() => void 0);
|
|
44118
44120
|
for (const tree of plan.trees) {
|
|
44119
|
-
await cloneTree(
|
|
44121
|
+
await cloneTree(resolve36(entry, tree), resolve36(staging, tree), seedFile);
|
|
44120
44122
|
}
|
|
44121
44123
|
for (const tree of plan.trees) {
|
|
44122
|
-
const target =
|
|
44124
|
+
const target = resolve36(input.worktreePath, tree);
|
|
44123
44125
|
await mkdir25(dirname25(target), { recursive: true });
|
|
44124
|
-
await rename10(
|
|
44126
|
+
await rename10(resolve36(staging, tree), target);
|
|
44125
44127
|
placed.push(target);
|
|
44126
44128
|
}
|
|
44127
44129
|
return { reason: "seeded", key: plan.key };
|
|
@@ -44139,11 +44141,11 @@ async function harvestWarmNodeModules(input) {
|
|
|
44139
44141
|
if (isPlanRefusal(plan)) {
|
|
44140
44142
|
return { reason: plan.failure, ...plan.detail ? { detail: plan.detail } : {} };
|
|
44141
44143
|
}
|
|
44142
|
-
const entry =
|
|
44144
|
+
const entry = resolve36(input.storeRoot, plan.key);
|
|
44143
44145
|
if (await pathExists(entry))
|
|
44144
44146
|
return { reason: "already-warm", key: plan.key };
|
|
44145
44147
|
for (const tree of plan.trees) {
|
|
44146
|
-
if (!await isDirectory(
|
|
44148
|
+
if (!await isDirectory(resolve36(input.worktreePath, tree))) {
|
|
44147
44149
|
return { reason: "no-node-modules", key: plan.key, detail: tree };
|
|
44148
44150
|
}
|
|
44149
44151
|
}
|
|
@@ -44155,12 +44157,12 @@ async function harvestWarmNodeModules(input) {
|
|
|
44155
44157
|
detail: `${missing.length} absent, e.g. ${missing.slice(0, 3).join(", ")}`
|
|
44156
44158
|
};
|
|
44157
44159
|
}
|
|
44158
|
-
const staging =
|
|
44160
|
+
const staging = resolve36(input.storeRoot, `${STAGING_PREFIX}${process.pid}.${randomUUID11()}`);
|
|
44159
44161
|
try {
|
|
44160
44162
|
await mkdir25(input.storeRoot, { recursive: true, mode: 493 });
|
|
44161
44163
|
await sweepStaleStaging(input.storeRoot, (input.now ?? Date.now)());
|
|
44162
44164
|
for (const tree of plan.trees) {
|
|
44163
|
-
await cloneTree(
|
|
44165
|
+
await cloneTree(resolve36(input.worktreePath, tree), resolve36(staging, tree), harvestFile);
|
|
44164
44166
|
}
|
|
44165
44167
|
await input.onCopied?.();
|
|
44166
44168
|
if (!await stagedTreeIsPublishable(input.worktreePath, staging, plan.key)) {
|
|
@@ -44183,16 +44185,16 @@ async function stagedTreeIsPublishable(worktreePath, staging, key) {
|
|
|
44183
44185
|
return false;
|
|
44184
44186
|
const hidden = join19("node_modules", ".package-lock.json");
|
|
44185
44187
|
const [copied, current] = await Promise.all([
|
|
44186
|
-
|
|
44187
|
-
|
|
44188
|
+
readFile29(resolve36(staging, hidden)).catch(() => void 0),
|
|
44189
|
+
readFile29(resolve36(worktreePath, hidden)).catch(() => void 0)
|
|
44188
44190
|
]);
|
|
44189
44191
|
if (!copied || !current || !copied.equals(current))
|
|
44190
44192
|
return false;
|
|
44191
44193
|
return (await missingInstalledPackages(worktreePath, staging)).length === 0;
|
|
44192
44194
|
}
|
|
44193
44195
|
async function missingInstalledPackages(worktreePath, treeRoot = worktreePath) {
|
|
44194
|
-
const wanted = parseLockfilePackages(await
|
|
44195
|
-
const installed = parseLockfilePackages(await
|
|
44196
|
+
const wanted = parseLockfilePackages(await readFile29(resolve36(worktreePath, "package-lock.json")).catch(() => void 0));
|
|
44197
|
+
const installed = parseLockfilePackages(await readFile29(resolve36(treeRoot, "node_modules", ".package-lock.json")).catch(() => void 0));
|
|
44196
44198
|
if (!wanted)
|
|
44197
44199
|
return ["package-lock.json is unreadable"];
|
|
44198
44200
|
if (!installed)
|
|
@@ -44212,7 +44214,7 @@ async function missingInstalledPackages(worktreePath, treeRoot = worktreePath) {
|
|
|
44212
44214
|
required.push(path);
|
|
44213
44215
|
}
|
|
44214
44216
|
await mapWithLimit(required, INTEGRITY_READ_CONCURRENCY, async (path) => {
|
|
44215
|
-
if (!(path in installed) || !await isInstalledPackage(
|
|
44217
|
+
if (!(path in installed) || !await isInstalledPackage(resolve36(treeRoot, path))) {
|
|
44216
44218
|
missing.push(path);
|
|
44217
44219
|
}
|
|
44218
44220
|
});
|
|
@@ -44547,6 +44549,7 @@ var MonolithCornerTurnLoop = class {
|
|
|
44547
44549
|
this.wakeIntake?.();
|
|
44548
44550
|
}
|
|
44549
44551
|
client;
|
|
44552
|
+
claudeLoginWatch;
|
|
44550
44553
|
sessionId;
|
|
44551
44554
|
/** The configuration the live session baked in; a change invalidates it. */
|
|
44552
44555
|
sessionFingerprint;
|
|
@@ -44625,7 +44628,7 @@ var MonolithCornerTurnLoop = class {
|
|
|
44625
44628
|
requestId: call.requestId,
|
|
44626
44629
|
generationId: call.generationId,
|
|
44627
44630
|
target: "squire",
|
|
44628
|
-
...resourceCallFacts({ method: "tools/call", params: { name: call.tool
|
|
44631
|
+
...resourceCallFacts({ method: "tools/call", params: { name: call.tool } })
|
|
44629
44632
|
})).allowed, options.config.operatorHome ?? homedir18(), void 0, (decision2) => {
|
|
44630
44633
|
options.api.execute("postSquireApprovalDecision", { roomId: options.cornerId, ...decision2 }).catch(() => {
|
|
44631
44634
|
});
|
|
@@ -44739,8 +44742,26 @@ var MonolithCornerTurnLoop = class {
|
|
|
44739
44742
|
...promptBytes ? { promptBytes } : {}
|
|
44740
44743
|
};
|
|
44741
44744
|
}
|
|
44745
|
+
/**
|
|
44746
|
+
* Watch this client's Claude login so a refresh made while the
|
|
44747
|
+
* corner is idle reaches other Rooms at once (see `watchRoomClaudeLogin`).
|
|
44748
|
+
*/
|
|
44749
|
+
watchClaudeLogin() {
|
|
44750
|
+
this.stopClaudeLoginWatch();
|
|
44751
|
+
if (this.options.config.agentKind !== "claude" || !this.options.config.agentHomeRoot)
|
|
44752
|
+
return;
|
|
44753
|
+
this.claudeLoginWatch = watchRoomClaudeLogin({
|
|
44754
|
+
root: this.options.config.agentHomeRoot,
|
|
44755
|
+
operatorHome: this.options.config.operatorHome
|
|
44756
|
+
});
|
|
44757
|
+
}
|
|
44758
|
+
stopClaudeLoginWatch() {
|
|
44759
|
+
this.claudeLoginWatch?.close();
|
|
44760
|
+
this.claudeLoginWatch = void 0;
|
|
44761
|
+
}
|
|
44742
44762
|
async discardSession() {
|
|
44743
44763
|
const client = this.client;
|
|
44764
|
+
this.stopClaudeLoginWatch();
|
|
44744
44765
|
this.client = void 0;
|
|
44745
44766
|
this.sessionId = void 0;
|
|
44746
44767
|
this.sessionFingerprint = void 0;
|
|
@@ -44757,14 +44778,15 @@ var MonolithCornerTurnLoop = class {
|
|
|
44757
44778
|
return await this.currentSessionFingerprint() === this.sessionFingerprint;
|
|
44758
44779
|
}
|
|
44759
44780
|
async currentSessionFingerprint() {
|
|
44760
|
-
const [configuration, roster, grants, restored] = await Promise.all([
|
|
44781
|
+
const [configuration, roster, grants, restored, cornerPrepareScript] = await Promise.all([
|
|
44761
44782
|
this.options.api.execute("getAgentConfiguration", {
|
|
44762
44783
|
agentId: this.agent.publicKey,
|
|
44763
44784
|
roomId: this.options.cornerId
|
|
44764
44785
|
}),
|
|
44765
44786
|
this.roster(),
|
|
44766
44787
|
this.grantedResources(),
|
|
44767
|
-
this.options.api.execute("getCornerRestoreState", { cornerId: this.options.cornerId })
|
|
44788
|
+
this.options.api.execute("getCornerRestoreState", { cornerId: this.options.cornerId }),
|
|
44789
|
+
hasCornerPrepareScript(this.options.worktreePath)
|
|
44768
44790
|
]);
|
|
44769
44791
|
const { hostRoutes: grantedHostRoutes, devices: grantedDevices } = grants;
|
|
44770
44792
|
const self = roster.members.find((member) => member.identityId === this.agent.publicKey);
|
|
@@ -44778,6 +44800,7 @@ var MonolithCornerTurnLoop = class {
|
|
|
44778
44800
|
agentName: self?.name ?? this.agent.name,
|
|
44779
44801
|
yoloMode: configuration.yoloMode,
|
|
44780
44802
|
repositoryWork: cornerHasRepositoryWork(restored.brief),
|
|
44803
|
+
cornerPrepareScript,
|
|
44781
44804
|
mcpServers: codegraphFingerprintServers(this.options.config, [
|
|
44782
44805
|
...expectedMountedImportedMcpServerNames({
|
|
44783
44806
|
operatorHome: this.options.config.operatorHome,
|
|
@@ -44850,13 +44873,15 @@ var MonolithCornerTurnLoop = class {
|
|
|
44850
44873
|
const selfReviewerInstruction = cornerSelfReviewerInstruction(reviewerInput);
|
|
44851
44874
|
this.sessionSurface = !this.options.repository ? "no-code-corner" : reviewerInstruction ? "review-corner" : "code-corner";
|
|
44852
44875
|
this.repositoryWork = cornerHasRepositoryWork(restored.brief);
|
|
44876
|
+
const cornerPrepareScript = await hasCornerPrepareScript(this.options.worktreePath);
|
|
44853
44877
|
this.sessionPromptContext = {
|
|
44854
44878
|
brief: restored.brief,
|
|
44855
44879
|
surface: this.sessionSurface,
|
|
44856
44880
|
agentName: self?.name ?? this.agent.name,
|
|
44857
44881
|
...configuration.reviewerHandle ? { reviewerHandle: configuration.reviewerHandle } : {},
|
|
44858
44882
|
selfReviewer: Boolean(selfReviewerInstruction),
|
|
44859
|
-
yoloMode: configuration.yoloMode
|
|
44883
|
+
yoloMode: configuration.yoloMode,
|
|
44884
|
+
cornerPrepareScript
|
|
44860
44885
|
};
|
|
44861
44886
|
await mkdir26(this.options.worktreePath, { recursive: true });
|
|
44862
44887
|
const selection = {
|
|
@@ -45022,6 +45047,7 @@ var MonolithCornerTurnLoop = class {
|
|
|
45022
45047
|
};
|
|
45023
45048
|
this.client = (this.options.createAcpClient ?? ((value) => new AcpClient(value)))(clientOptions);
|
|
45024
45049
|
await this.client.start();
|
|
45050
|
+
this.watchClaudeLogin();
|
|
45025
45051
|
const codegraphReady = await prepareCodegraphIndex(this.options.config, this.options.worktreePath);
|
|
45026
45052
|
const fingerprint = sessionConfigFingerprint({
|
|
45027
45053
|
devices: grantedDevices,
|
|
@@ -45032,6 +45058,7 @@ var MonolithCornerTurnLoop = class {
|
|
|
45032
45058
|
agentName: self?.name ?? this.agent.name,
|
|
45033
45059
|
yoloMode: configuration.yoloMode,
|
|
45034
45060
|
repositoryWork: cornerHasRepositoryWork(restored.brief),
|
|
45061
|
+
cornerPrepareScript,
|
|
45035
45062
|
mcpServers: codegraphFingerprintServers(this.options.config, [
|
|
45036
45063
|
...expectedMountedImportedMcpServerNames({
|
|
45037
45064
|
operatorHome: this.options.config.operatorHome,
|
|
@@ -45184,7 +45211,7 @@ var MonolithCornerTurnLoop = class {
|
|
|
45184
45211
|
briefRevision: restore.brief?.revision
|
|
45185
45212
|
}),
|
|
45186
45213
|
...this.options.config.agentHomeRoot && this.options.config.agentKind && !AGENT_SKILL_DIRS.includes(this.options.config.agentKind) ? [
|
|
45187
|
-
`This harness has no verified native skill discovery. Read the release-managed review procedure at ${
|
|
45214
|
+
`This harness has no verified native skill discovery. Read the release-managed review procedure at ${resolve37(this.options.config.agentHomeRoot, "codex", "skills", "beeline-review", "SKILL.md")} before the verdict.`
|
|
45188
45215
|
] : []
|
|
45189
45216
|
].join("\n");
|
|
45190
45217
|
} catch {
|
|
@@ -45263,6 +45290,7 @@ var MonolithCornerTurnLoop = class {
|
|
|
45263
45290
|
return void 0;
|
|
45264
45291
|
trace?.retry({ provider: next, ...reason ? { reason } : {} });
|
|
45265
45292
|
const client = this.client;
|
|
45293
|
+
this.stopClaudeLoginWatch();
|
|
45266
45294
|
this.client = void 0;
|
|
45267
45295
|
this.sessionId = void 0;
|
|
45268
45296
|
this.sessionFingerprint = void 0;
|
|
@@ -45316,8 +45344,8 @@ var MonolithCornerTurnLoop = class {
|
|
|
45316
45344
|
let timer;
|
|
45317
45345
|
const stats = statsPromise && remaining > 0 ? await Promise.race([
|
|
45318
45346
|
statsPromise,
|
|
45319
|
-
new Promise((
|
|
45320
|
-
timer = setTimeout(() =>
|
|
45347
|
+
new Promise((resolve45) => {
|
|
45348
|
+
timer = setTimeout(() => resolve45(void 0), remaining);
|
|
45321
45349
|
})
|
|
45322
45350
|
]).finally(() => {
|
|
45323
45351
|
if (timer)
|
|
@@ -45366,6 +45394,7 @@ var MonolithCornerTurnLoop = class {
|
|
|
45366
45394
|
trace.noteInstitutionalMemoryEmbedding(institutionalContext.embeddingOutcome, institutionalContext.embeddingMs ?? 0);
|
|
45367
45395
|
}
|
|
45368
45396
|
let repositoryWork = cornerHasRepositoryWork(restored.brief);
|
|
45397
|
+
let repositoryHeld = restored.held === true;
|
|
45369
45398
|
let assignedBrief = restored.brief;
|
|
45370
45399
|
const taskDelivered = this.attachmentDir && attachments.length ? await deliverAttachments(attachments, join20(this.attachmentDir, requestId.replace(/[^\w-]/g, "_")), this.options.fetchImpl) : [];
|
|
45371
45400
|
let delivered = taskDelivered;
|
|
@@ -45381,7 +45410,7 @@ var MonolithCornerTurnLoop = class {
|
|
|
45381
45410
|
const briefDelivered = this.attachmentDir && briefAttachments.length ? await deliverAttachments(briefAttachments, join20(this.attachmentDir, requestId.replace(/[^\w-]/g, "_"), "brief", String(assignedBrief.revision)), this.options.fetchImpl) : [];
|
|
45382
45411
|
briefFileLines = await Promise.all((assignedBrief?.attachments ?? []).map(async (file, index) => {
|
|
45383
45412
|
const entry = briefDelivered.find((item) => item.attachment === briefAttachments[index]);
|
|
45384
|
-
const verified = entry?.path && createHash14("sha256").update(await
|
|
45413
|
+
const verified = entry?.path && createHash14("sha256").update(await readFile30(entry.path)).digest("hex") === file.sha256;
|
|
45385
45414
|
return `- ${file.title} (${file.purpose}; ${file.required ? "required" : "optional"}; sha256 ${file.sha256}): ${verified ? entry.path : "UNAVAILABLE OR CONTENT MISMATCH"}`;
|
|
45386
45415
|
}));
|
|
45387
45416
|
missingRequiredBriefFile = (assignedBrief?.attachments ?? []).some((file, index) => file.required && briefFileLines[index]?.includes("UNAVAILABLE OR CONTENT MISMATCH"));
|
|
@@ -45420,7 +45449,7 @@ var MonolithCornerTurnLoop = class {
|
|
|
45420
45449
|
await this.discardSession();
|
|
45421
45450
|
await trace.measure("activation", () => this.activate(trace));
|
|
45422
45451
|
}
|
|
45423
|
-
if (followup === CORNER_DELIVERY_NUDGE && !repositoryWork)
|
|
45452
|
+
if (followup === CORNER_DELIVERY_NUDGE && !(repositoryWork && !repositoryHeld))
|
|
45424
45453
|
followup = "Deliver files with post_artifact; answer plain chat questions directly.";
|
|
45425
45454
|
if (followup && !assignedBrief)
|
|
45426
45455
|
return followup;
|
|
@@ -45689,7 +45718,8 @@ ${continuation}` : assembled;
|
|
|
45689
45718
|
explained = await this.explainEmpty(result);
|
|
45690
45719
|
}
|
|
45691
45720
|
const checksTurn = isCornerChecksTurn(trigger, restates);
|
|
45692
|
-
const
|
|
45721
|
+
const mayPublish = repositoryWork && !repositoryHeld;
|
|
45722
|
+
const deliveryState = !checksTurn && mayPublish && this.options.repository ? await cornerUndeliveredRepositoryState(this.options.worktreePath, this.options.repository.featureBranch, this.options.repository.targetBranch) : void 0;
|
|
45693
45723
|
const needsDeliveryNudge = deliveryState !== void 0 && deliveryState !== this.lastDeliveryNudgeState;
|
|
45694
45724
|
let refreshedReviewerInstruction;
|
|
45695
45725
|
let reviewerSecondPass = false;
|
|
@@ -45701,7 +45731,7 @@ ${continuation}` : assembled;
|
|
|
45701
45731
|
reviewerSecondPass = reviewerTargetChanged || !result.toolCalls.some((call) => /(?:^|[._:/-])(?:approve_merge|record_validation_stage)$/i.test(call.title ?? "") && isCompletedToolCall(call));
|
|
45702
45732
|
}
|
|
45703
45733
|
let replyBeforeNudge = "";
|
|
45704
|
-
if (!explained && (needsDeliveryNudge || checksTurn && (this.reviewerInstructionInput ? reviewerSecondPass : repositoryWork && this.yoloMode && !result.toolCalls.some((call) => /(?:^|[._:/-])pr_checks_status$/i.test(call.title ?? "") && isCompletedToolCall(call))))) {
|
|
45734
|
+
if (!explained && (needsDeliveryNudge || checksTurn && (this.reviewerInstructionInput ? reviewerSecondPass : repositoryWork && !repositoryHeld && this.yoloMode && !result.toolCalls.some((call) => /(?:^|[._:/-])pr_checks_status$/i.test(call.title ?? "") && isCompletedToolCall(call))))) {
|
|
45705
45735
|
if (needsDeliveryNudge)
|
|
45706
45736
|
this.lastDeliveryNudgeState = deliveryState;
|
|
45707
45737
|
await flushToolCalls(result.toolCalls, "");
|
|
@@ -45816,13 +45846,13 @@ ${continuation}` : assembled;
|
|
|
45816
45846
|
if (this.harvest || !this.options.repository)
|
|
45817
45847
|
return;
|
|
45818
45848
|
const { cornerId, worktreePath, runtime } = this.options;
|
|
45819
|
-
const mobilePath =
|
|
45849
|
+
const mobilePath = resolve37(worktreePath, "apps/mobile");
|
|
45820
45850
|
const jobs = [
|
|
45821
45851
|
harvestWarmNodeModules({
|
|
45822
45852
|
worktreePath,
|
|
45823
45853
|
storeRoot: warmNodeModulesStoreDir(runtime.supervisorRoot)
|
|
45824
45854
|
}),
|
|
45825
|
-
...existsSync9(
|
|
45855
|
+
...existsSync9(resolve37(mobilePath, "package-lock.json")) ? [
|
|
45826
45856
|
harvestWarmNodeModules({
|
|
45827
45857
|
worktreePath: mobilePath,
|
|
45828
45858
|
storeRoot: mobileNodeModulesStoreDir(runtime.supervisorRoot)
|
|
@@ -45867,7 +45897,7 @@ ${continuation}` : assembled;
|
|
|
45867
45897
|
} catch (error) {
|
|
45868
45898
|
if (attempt === 2)
|
|
45869
45899
|
throw error;
|
|
45870
|
-
await new Promise((
|
|
45900
|
+
await new Promise((resolve45) => setTimeout(resolve45, 250 * (attempt + 1)));
|
|
45871
45901
|
}
|
|
45872
45902
|
}
|
|
45873
45903
|
if (!token)
|
|
@@ -46479,7 +46509,7 @@ function cornerStartConfigKey(repository, objective) {
|
|
|
46479
46509
|
function cornerRepositoryCacheDir(supervisorRoot, remote) {
|
|
46480
46510
|
const normalizedRemote = roomCheckoutRemote(remote);
|
|
46481
46511
|
const repositoryHash = createHash15("sha256").update(normalizedRemote).digest("hex").slice(0, 24);
|
|
46482
|
-
return
|
|
46512
|
+
return resolve38(supervisorRoot, "beeline", "repositories", `${repositoryHash}.git`);
|
|
46483
46513
|
}
|
|
46484
46514
|
function isStandingCornerStartFault(error) {
|
|
46485
46515
|
const text2 = error instanceof Error ? error.message : String(error);
|
|
@@ -46488,11 +46518,11 @@ function isStandingCornerStartFault(error) {
|
|
|
46488
46518
|
async function materializeCornerWorktree(input) {
|
|
46489
46519
|
const remote = roomCheckoutRemote(input.remote);
|
|
46490
46520
|
const gitCommonDir = cornerRepositoryCacheDir(input.supervisorRoot, remote);
|
|
46491
|
-
const path =
|
|
46521
|
+
const path = resolve38(input.supervisorRoot, "beeline", "corners", input.cornerId);
|
|
46492
46522
|
await mkdir27(dirname27(gitCommonDir), { recursive: true, mode: 448 });
|
|
46493
46523
|
await mkdir27(dirname27(path), { recursive: true, mode: 448 });
|
|
46494
46524
|
const authEnv = githubGitEnv(input.token);
|
|
46495
|
-
if (!existsSync10(
|
|
46525
|
+
if (!existsSync10(resolve38(gitCommonDir, "HEAD"))) {
|
|
46496
46526
|
await execFileAsync8("git", ["clone", "--bare", remote, gitCommonDir], {
|
|
46497
46527
|
env: authEnv,
|
|
46498
46528
|
maxBuffer: 4 * 1024 * 1024
|
|
@@ -46515,7 +46545,7 @@ async function materializeCornerWorktree(input) {
|
|
|
46515
46545
|
return false;
|
|
46516
46546
|
throw error;
|
|
46517
46547
|
});
|
|
46518
|
-
if (!existsSync10(
|
|
46548
|
+
if (!existsSync10(resolve38(path, ".git"))) {
|
|
46519
46549
|
await rm15(path, { recursive: true, force: true });
|
|
46520
46550
|
await execFileAsync8("git", [
|
|
46521
46551
|
`--git-dir=${gitCommonDir}`,
|
|
@@ -46533,8 +46563,8 @@ async function materializeCornerWorktree(input) {
|
|
|
46533
46563
|
if (seed.reason !== "no-lockfile") {
|
|
46534
46564
|
console.log(`[thin-core] corner ${input.cornerId} warm node_modules: ${seed.reason}${seed.detail ? ` (${seed.detail})` : ""}`);
|
|
46535
46565
|
}
|
|
46536
|
-
const mobilePath =
|
|
46537
|
-
if (existsSync10(
|
|
46566
|
+
const mobilePath = resolve38(path, "apps/mobile");
|
|
46567
|
+
if (existsSync10(resolve38(mobilePath, "package-lock.json"))) {
|
|
46538
46568
|
const mobileSeed = await seedWarmNodeModules({
|
|
46539
46569
|
worktreePath: mobilePath,
|
|
46540
46570
|
storeRoot: mobileNodeModulesStoreDir(input.supervisorRoot)
|
|
@@ -46591,9 +46621,9 @@ async function mapWithConcurrency(values, limit, visit) {
|
|
|
46591
46621
|
}));
|
|
46592
46622
|
}
|
|
46593
46623
|
async function discoverCornerWorktree(supervisorRoot, cornerId) {
|
|
46594
|
-
const cornersRoot =
|
|
46595
|
-
const path =
|
|
46596
|
-
if (dirname27(path) !== cornersRoot || !existsSync10(
|
|
46624
|
+
const cornersRoot = resolve38(supervisorRoot, "beeline", "corners");
|
|
46625
|
+
const path = resolve38(cornersRoot, cornerId);
|
|
46626
|
+
if (dirname27(path) !== cornersRoot || !existsSync10(resolve38(path, ".git")))
|
|
46597
46627
|
return void 0;
|
|
46598
46628
|
const [canonicalRoot, canonicalPath] = await Promise.all([
|
|
46599
46629
|
realpath2(cornersRoot),
|
|
@@ -46605,8 +46635,8 @@ async function discoverCornerWorktree(supervisorRoot, cornerId) {
|
|
|
46605
46635
|
const common = await execFileAsync8("git", ["-C", path, "rev-parse", "--git-common-dir"]).catch(() => void 0);
|
|
46606
46636
|
if (!common)
|
|
46607
46637
|
return void 0;
|
|
46608
|
-
const gitCommonDir =
|
|
46609
|
-
const repositoriesRoot =
|
|
46638
|
+
const gitCommonDir = resolve38(path, common.stdout.trim());
|
|
46639
|
+
const repositoriesRoot = resolve38(supervisorRoot, "beeline", "repositories");
|
|
46610
46640
|
const commonRelative = relative3(repositoriesRoot, gitCommonDir);
|
|
46611
46641
|
if (!commonRelative || commonRelative === ".." || commonRelative.startsWith(`..${sep2}`) || commonRelative.startsWith(sep2)) {
|
|
46612
46642
|
throw new Error(`refusing corner ${cornerId} with git directory outside repository cache`);
|
|
@@ -46614,7 +46644,7 @@ async function discoverCornerWorktree(supervisorRoot, cornerId) {
|
|
|
46614
46644
|
return { path, gitCommonDir };
|
|
46615
46645
|
}
|
|
46616
46646
|
async function localCornerWorktreeIds(supervisorRoot) {
|
|
46617
|
-
const root =
|
|
46647
|
+
const root = resolve38(supervisorRoot, "beeline", "corners");
|
|
46618
46648
|
const entries = await readdir9(root, { withFileTypes: true }).catch((error) => {
|
|
46619
46649
|
if (error.code === "ENOENT")
|
|
46620
46650
|
return [];
|
|
@@ -46707,8 +46737,8 @@ async function originContains(gitCommonDir, head) {
|
|
|
46707
46737
|
}
|
|
46708
46738
|
var execFileAsync8 = promisify8(execFile13);
|
|
46709
46739
|
async function removeCornerScratchWorkspace(input) {
|
|
46710
|
-
const expected =
|
|
46711
|
-
if (
|
|
46740
|
+
const expected = resolve38(input.roomRoot, "scratch");
|
|
46741
|
+
if (resolve38(input.scratchPath) !== expected) {
|
|
46712
46742
|
throw new Error(`refusing to remove scratch outside corner ${input.cornerId}`);
|
|
46713
46743
|
}
|
|
46714
46744
|
await rm15(expected, { recursive: true, force: true });
|
|
@@ -47164,13 +47194,13 @@ var RoomRuntimeCoordinator = class {
|
|
|
47164
47194
|
return this.runtime.rooms.find((room) => room.channelId === roomId);
|
|
47165
47195
|
}
|
|
47166
47196
|
roomRoot(roomId) {
|
|
47167
|
-
return this.roomRecord(roomId)?.root ??
|
|
47197
|
+
return this.roomRecord(roomId)?.root ?? resolve38(dirname27(this.configPath), "rooms", roomId);
|
|
47168
47198
|
}
|
|
47169
47199
|
roomAgentHomeRoot(workspaceRoot, required = false) {
|
|
47170
47200
|
const flag = process.env.BUZZY_BODY_ROOM_HOME;
|
|
47171
47201
|
if (!required && flag === "0")
|
|
47172
47202
|
return void 0;
|
|
47173
|
-
const home =
|
|
47203
|
+
const home = resolve38(workspaceRoot, "agent-home");
|
|
47174
47204
|
if (!required && flag !== "1" && !existsSync10(home) && existsSync10(workspaceRoot))
|
|
47175
47205
|
return void 0;
|
|
47176
47206
|
try {
|
|
@@ -47186,8 +47216,8 @@ var RoomRuntimeCoordinator = class {
|
|
|
47186
47216
|
return {
|
|
47187
47217
|
...this.baseConfig,
|
|
47188
47218
|
workspaceRoot,
|
|
47189
|
-
agentPrivateRoot:
|
|
47190
|
-
agentMemoryRoot:
|
|
47219
|
+
agentPrivateRoot: resolve38(workspaceRoot, "agent-private"),
|
|
47220
|
+
agentMemoryRoot: resolve38(dirname27(this.configPath), "memory"),
|
|
47191
47221
|
openRouterRoutingCacheDir: openRouterRoutingCacheDir(dirname27(this.configPath)),
|
|
47192
47222
|
turnTraceDir: turnTraceDirectory(dirname27(this.configPath)),
|
|
47193
47223
|
...agentHomeRoot ? { agentHomeRoot } : {}
|
|
@@ -47270,11 +47300,11 @@ var RoomRuntimeCoordinator = class {
|
|
|
47270
47300
|
const remote = roomCheckoutRemote(repository.remote);
|
|
47271
47301
|
const targetBranch = repository.targetBranch || "main";
|
|
47272
47302
|
const checkoutId = createHash15("sha256").update(`${roomId}\0${remote}\0${targetBranch}`).digest("hex").slice(0, 24);
|
|
47273
|
-
const path =
|
|
47303
|
+
const path = resolve38(this.runtime.supervisorRoot, "beeline", "room-checkouts", checkoutId);
|
|
47274
47304
|
await mkdir27(dirname27(path), { recursive: true, mode: 448 });
|
|
47275
47305
|
const token = remote.startsWith("https://github.com/") ? await this.parentRepositoryToken(roomId) : void 0;
|
|
47276
47306
|
const env = token ? githubGitEnv(token.token) : process.env;
|
|
47277
|
-
if (!existsSync10(
|
|
47307
|
+
if (!existsSync10(resolve38(path, ".git"))) {
|
|
47278
47308
|
await execFileAsync8("git", ["clone", "--no-checkout", remote, path], {
|
|
47279
47309
|
env,
|
|
47280
47310
|
maxBuffer: 4 * 1024 * 1024
|
|
@@ -47351,7 +47381,7 @@ var RoomRuntimeCoordinator = class {
|
|
|
47351
47381
|
if (!objective)
|
|
47352
47382
|
throw new Error("corner has no authoritative objective fact");
|
|
47353
47383
|
const repositoryBacked = repository.resolution === "repository" && restore.lane !== "no_code";
|
|
47354
|
-
const scratchPath =
|
|
47384
|
+
const scratchPath = resolve38(this.roomRoot(corner.cornerId), "scratch");
|
|
47355
47385
|
if (repositoryBacked && existsSync10(scratchPath) && !restore.featureBranch)
|
|
47356
47386
|
throw new Error("promoted corner has no server-assigned feature branch");
|
|
47357
47387
|
const targetBranch = repositoryBacked ? repository.targetBranch || "main" : void 0;
|
|
@@ -47366,7 +47396,7 @@ var RoomRuntimeCoordinator = class {
|
|
|
47366
47396
|
}) : void 0;
|
|
47367
47397
|
if (worktree && existsSync10(scratchPath))
|
|
47368
47398
|
await this.reapCornerScratch({ path: scratchPath, cornerId: corner.cornerId });
|
|
47369
|
-
const workspacePath = worktree?.path ??
|
|
47399
|
+
const workspacePath = worktree?.path ?? resolve38(this.roomRoot(corner.cornerId), "scratch");
|
|
47370
47400
|
if (!worktree)
|
|
47371
47401
|
await mkdir27(workspacePath, { recursive: true, mode: 448 });
|
|
47372
47402
|
if (worktree && shouldPostInitialCornerWorkingState(restore)) {
|
|
@@ -47697,7 +47727,7 @@ var RoomRuntimeCoordinator = class {
|
|
|
47697
47727
|
throw new Error(`archived corner ${corner.cornerId} has no authoritative repository`);
|
|
47698
47728
|
}
|
|
47699
47729
|
const expectedCommonDir = cornerRepositoryCacheDir(this.runtime.supervisorRoot, repository.remote);
|
|
47700
|
-
if (
|
|
47730
|
+
if (resolve38(discovered.gitCommonDir) !== expectedCommonDir) {
|
|
47701
47731
|
throw new Error(`archived corner ${corner.cornerId} repository cache does not match`);
|
|
47702
47732
|
}
|
|
47703
47733
|
if (!restore.featureBranch) {
|
|
@@ -48048,10 +48078,10 @@ var ThinDaemonCore = class {
|
|
|
48048
48078
|
|
|
48049
48079
|
// apps/body/dist/force-update-journal.js
|
|
48050
48080
|
import { mkdirSync as mkdirSync4, readFileSync as readFileSync9, renameSync, writeFileSync as writeFileSync5 } from "node:fs";
|
|
48051
|
-
import { resolve as
|
|
48081
|
+
import { resolve as resolve39 } from "node:path";
|
|
48052
48082
|
var NAME = "force-update-interruptions.json";
|
|
48053
48083
|
function pathFor(runtimeDir) {
|
|
48054
|
-
return
|
|
48084
|
+
return resolve39(runtimeDir, NAME);
|
|
48055
48085
|
}
|
|
48056
48086
|
function read(runtimeDir) {
|
|
48057
48087
|
try {
|
|
@@ -48129,17 +48159,17 @@ function staleGeneration(error) {
|
|
|
48129
48159
|
init_launchd();
|
|
48130
48160
|
init_systemd();
|
|
48131
48161
|
import { mkdir as mkdir28, rename as rename11 } from "node:fs/promises";
|
|
48132
|
-
import { dirname as dirname28, resolve as
|
|
48162
|
+
import { dirname as dirname28, resolve as resolve40 } from "node:path";
|
|
48133
48163
|
async function retireRemovedAgent(runtime, options = {}) {
|
|
48134
|
-
const deletedRoot =
|
|
48135
|
-
const target =
|
|
48164
|
+
const deletedRoot = resolve40(runtime.supervisorRoot, "beeline", "deleted-runtimes");
|
|
48165
|
+
const target = resolve40(deletedRoot, `${runtime.agent.publicKey}-${Date.now()}`);
|
|
48136
48166
|
return relocateAgentRuntime(runtime, target, {
|
|
48137
48167
|
...options.run ? { run: options.run } : {}
|
|
48138
48168
|
});
|
|
48139
48169
|
}
|
|
48140
48170
|
async function relocateAgentRuntime(runtime, target, options = {}) {
|
|
48141
48171
|
const source = runtimeDirectory(runtime.supervisorRoot, runtime.agent.publicKey);
|
|
48142
|
-
const destination =
|
|
48172
|
+
const destination = resolve40(target);
|
|
48143
48173
|
if (destination === source || destination.startsWith(`${source}/`)) {
|
|
48144
48174
|
throw new Error("agent runtime destination must be outside the live runtime");
|
|
48145
48175
|
}
|
|
@@ -48162,8 +48192,8 @@ init_self_update();
|
|
|
48162
48192
|
init_systemd();
|
|
48163
48193
|
|
|
48164
48194
|
// apps/body/dist/release-status.js
|
|
48165
|
-
import { readFile as
|
|
48166
|
-
import { resolve as
|
|
48195
|
+
import { readFile as readFile31, readdir as readdir10, rename as rename12, writeFile as writeFile21 } from "node:fs/promises";
|
|
48196
|
+
import { resolve as resolve41 } from "node:path";
|
|
48167
48197
|
var DAEMON_RELEASE_STATUS_FILE = "release-status.json";
|
|
48168
48198
|
var RELEASE_VERSION = /^v\d+\.\d+\.\d+$/;
|
|
48169
48199
|
var SOURCE_SHA = /^[0-9a-f]{7,64}$/;
|
|
@@ -48180,7 +48210,7 @@ async function writeDaemonReleaseStatus(runtimeDir, agentPubkey, identity, optio
|
|
|
48180
48210
|
pid: options.pid ?? process.pid,
|
|
48181
48211
|
readyAt: (options.now?.() ?? /* @__PURE__ */ new Date()).toISOString()
|
|
48182
48212
|
};
|
|
48183
|
-
const target =
|
|
48213
|
+
const target = resolve41(runtimeDir, DAEMON_RELEASE_STATUS_FILE);
|
|
48184
48214
|
const temporary = `${target}.${status.pid}.tmp`;
|
|
48185
48215
|
await writeFile21(temporary, `${JSON.stringify(status, null, 2)}
|
|
48186
48216
|
`, { mode: 384 });
|
|
@@ -48190,7 +48220,7 @@ async function writeDaemonReleaseStatus(runtimeDir, agentPubkey, identity, optio
|
|
|
48190
48220
|
|
|
48191
48221
|
// apps/body/dist/scratch-sweep.js
|
|
48192
48222
|
import { lstat as lstat5, readdir as readdir11, rmdir as rmdir2, unlink as unlink9 } from "node:fs/promises";
|
|
48193
|
-
import { resolve as
|
|
48223
|
+
import { resolve as resolve42 } from "node:path";
|
|
48194
48224
|
var DEFAULT_SCRATCH_TTL_HOURS = 72;
|
|
48195
48225
|
var NEVER_SWEEP_SUBDIR_NAMES = new Set(HOME_SUBDIRS.filter((name) => name !== "tmp"));
|
|
48196
48226
|
function scratchTtlMs(env = process.env) {
|
|
@@ -48199,7 +48229,7 @@ function scratchTtlMs(env = process.env) {
|
|
|
48199
48229
|
return (Number.isFinite(hours) && hours > 0 ? hours : DEFAULT_SCRATCH_TTL_HOURS) * 60 * 60 * 1e3;
|
|
48200
48230
|
}
|
|
48201
48231
|
async function discoverAttachScratchRoots(runtimeDir) {
|
|
48202
|
-
const roomsDir =
|
|
48232
|
+
const roomsDir = resolve42(runtimeDir, "rooms");
|
|
48203
48233
|
let entries;
|
|
48204
48234
|
try {
|
|
48205
48235
|
entries = await readdir11(roomsDir, { withFileTypes: true });
|
|
@@ -48210,7 +48240,7 @@ async function discoverAttachScratchRoots(runtimeDir) {
|
|
|
48210
48240
|
for (const entry of entries) {
|
|
48211
48241
|
if (!entry.isDirectory())
|
|
48212
48242
|
continue;
|
|
48213
|
-
const home =
|
|
48243
|
+
const home = resolve42(roomsDir, entry.name, "agent-home");
|
|
48214
48244
|
const stats = await lstat5(home).catch(() => void 0);
|
|
48215
48245
|
if (stats?.isDirectory())
|
|
48216
48246
|
roots.push(home);
|
|
@@ -48229,7 +48259,7 @@ async function removeStaleFiles(dir, cutoffMs, protectNamesHere) {
|
|
|
48229
48259
|
for (const entry of entries) {
|
|
48230
48260
|
if (protectNamesHere && NEVER_SWEEP_SUBDIR_NAMES.has(entry.name))
|
|
48231
48261
|
continue;
|
|
48232
|
-
const path =
|
|
48262
|
+
const path = resolve42(dir, entry.name);
|
|
48233
48263
|
const stats = await lstat5(path).catch(() => void 0);
|
|
48234
48264
|
if (!stats || stats.isSymbolicLink())
|
|
48235
48265
|
continue;
|
|
@@ -48314,7 +48344,7 @@ async function runAgentRuntime(configPath, host, signal) {
|
|
|
48314
48344
|
BUZZ_DEV_MCP_BIN: runtime.mcpBinary
|
|
48315
48345
|
};
|
|
48316
48346
|
const config = loadBodyConfig({
|
|
48317
|
-
workspaceRoot:
|
|
48347
|
+
workspaceRoot: resolve43(runtimeDir, "workspace"),
|
|
48318
48348
|
llmEnvFile: runtime.llmEnvFile,
|
|
48319
48349
|
env,
|
|
48320
48350
|
agent
|
|
@@ -49194,7 +49224,7 @@ async function main() {
|
|
|
49194
49224
|
const roomId = roomFlag >= 0 ? args[roomFlag + 1] : void 0;
|
|
49195
49225
|
if (!configPath || !roomId)
|
|
49196
49226
|
throw new Error("corner-read-token requires --config and --room");
|
|
49197
|
-
const activated = await activateDaemonTransport(
|
|
49227
|
+
const activated = await activateDaemonTransport(resolve44(configPath));
|
|
49198
49228
|
if (!activated)
|
|
49199
49229
|
throw new Error("corner-read-token requires monolith transport");
|
|
49200
49230
|
const credential = await activated.client.execute("getRoomGitHubToken", { roomId });
|
|
@@ -49249,7 +49279,7 @@ async function main() {
|
|
|
49249
49279
|
}
|
|
49250
49280
|
if (!configPath && !args.includes("--machine"))
|
|
49251
49281
|
throw new Error("daemon requires --machine, or --config <runtime.json> for one agent");
|
|
49252
|
-
const { reason, lifecycle } = await runMachineHelper(configPath ? { configPaths: [
|
|
49282
|
+
const { reason, lifecycle } = await runMachineHelper(configPath ? { configPaths: [resolve44(configPath)] } : {});
|
|
49253
49283
|
daemonLifecycle = lifecycle;
|
|
49254
49284
|
lifecycle.exit(reason);
|
|
49255
49285
|
return;
|