usebeeline 0.1.20 → 0.1.21
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 +980 -428
- 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((resolve49) => {
|
|
216
|
+
resolveDone = resolve49;
|
|
217
217
|
});
|
|
218
218
|
const failResponse = (id) => `${JSON.stringify({
|
|
219
219
|
jsonrpc: "2.0",
|
|
@@ -480,8 +480,8 @@ function socketHolders(inodes, profileDir, procRoot = "/proc") {
|
|
|
480
480
|
}
|
|
481
481
|
function alive(pid, procRoot) {
|
|
482
482
|
try {
|
|
483
|
-
const
|
|
484
|
-
return
|
|
483
|
+
const stat11 = readFileSync(join(procRoot, String(pid), "stat"), "utf8");
|
|
484
|
+
return stat11.slice(stat11.lastIndexOf(")") + 2, stat11.lastIndexOf(")") + 3) !== "Z";
|
|
485
485
|
} catch {
|
|
486
486
|
return false;
|
|
487
487
|
}
|
|
@@ -5680,11 +5680,11 @@ async function stageRelease(layout, manifestUrl, published, opts = {}) {
|
|
|
5680
5680
|
const extract2 = await run("tar", ["-xzf", tempArchive, "-C", releaseDir], 5 * 6e4);
|
|
5681
5681
|
if (extract2.status !== 0)
|
|
5682
5682
|
throw new Error(`extracting bundle failed: ${extract2.stderr}`);
|
|
5683
|
-
for (const
|
|
5683
|
+
for (const relative5 of requiredBundlePaths()) {
|
|
5684
5684
|
try {
|
|
5685
|
-
await access(join8(releaseDir,
|
|
5685
|
+
await access(join8(releaseDir, relative5), fsConstants2.F_OK);
|
|
5686
5686
|
} catch {
|
|
5687
|
-
throw new Error(`staged bundle is missing ${
|
|
5687
|
+
throw new Error(`staged bundle is missing ${relative5}`);
|
|
5688
5688
|
}
|
|
5689
5689
|
}
|
|
5690
5690
|
const engineMinimum = await readBundleEngineMinimum(releaseDir);
|
|
@@ -10099,10 +10099,10 @@ var require_resolve_block_map = __commonJS({
|
|
|
10099
10099
|
let offset = bm.offset;
|
|
10100
10100
|
let commentEnd = null;
|
|
10101
10101
|
for (const collItem of bm.items) {
|
|
10102
|
-
const { start, key, sep:
|
|
10102
|
+
const { start, key, sep: sep4, value } = collItem;
|
|
10103
10103
|
const keyProps = resolveProps.resolveProps(start, {
|
|
10104
10104
|
indicator: "explicit-key-ind",
|
|
10105
|
-
next: key ??
|
|
10105
|
+
next: key ?? sep4?.[0],
|
|
10106
10106
|
offset,
|
|
10107
10107
|
onError,
|
|
10108
10108
|
parentIndent: bm.indent,
|
|
@@ -10116,7 +10116,7 @@ var require_resolve_block_map = __commonJS({
|
|
|
10116
10116
|
else if ("indent" in key && key.indent !== bm.indent)
|
|
10117
10117
|
onError(offset, "BAD_INDENT", startColMsg);
|
|
10118
10118
|
}
|
|
10119
|
-
if (!keyProps.anchor && !keyProps.tag && !
|
|
10119
|
+
if (!keyProps.anchor && !keyProps.tag && !sep4) {
|
|
10120
10120
|
commentEnd = keyProps.end;
|
|
10121
10121
|
if (keyProps.comment) {
|
|
10122
10122
|
if (map.comment)
|
|
@@ -10140,7 +10140,7 @@ var require_resolve_block_map = __commonJS({
|
|
|
10140
10140
|
ctx.atKey = false;
|
|
10141
10141
|
if (utilMapIncludes.mapIncludes(ctx, map.items, keyNode))
|
|
10142
10142
|
onError(keyStart, "DUPLICATE_KEY", "Map keys must be unique");
|
|
10143
|
-
const valueProps = resolveProps.resolveProps(
|
|
10143
|
+
const valueProps = resolveProps.resolveProps(sep4 ?? [], {
|
|
10144
10144
|
indicator: "map-value-ind",
|
|
10145
10145
|
next: value,
|
|
10146
10146
|
offset: keyNode.range[2],
|
|
@@ -10156,7 +10156,7 @@ var require_resolve_block_map = __commonJS({
|
|
|
10156
10156
|
if (ctx.options.strict && keyProps.start < valueProps.found.offset - 1024)
|
|
10157
10157
|
onError(keyNode.range, "KEY_OVER_1024_CHARS", "The : indicator must be at most 1024 chars after the start of an implicit block mapping key");
|
|
10158
10158
|
}
|
|
10159
|
-
const valueNode = value ? composeNode(ctx, value, valueProps, onError) : composeEmptyNode(ctx, offset,
|
|
10159
|
+
const valueNode = value ? composeNode(ctx, value, valueProps, onError) : composeEmptyNode(ctx, offset, sep4, null, valueProps, onError);
|
|
10160
10160
|
if (ctx.schema.compat)
|
|
10161
10161
|
utilFlowIndentCheck.flowIndentCheck(bm.indent, value, onError);
|
|
10162
10162
|
offset = valueNode.range[2];
|
|
@@ -10247,7 +10247,7 @@ var require_resolve_end = __commonJS({
|
|
|
10247
10247
|
let comment = "";
|
|
10248
10248
|
if (end) {
|
|
10249
10249
|
let hasSpace = false;
|
|
10250
|
-
let
|
|
10250
|
+
let sep4 = "";
|
|
10251
10251
|
for (const token of end) {
|
|
10252
10252
|
const { source, type } = token;
|
|
10253
10253
|
switch (type) {
|
|
@@ -10261,13 +10261,13 @@ var require_resolve_end = __commonJS({
|
|
|
10261
10261
|
if (!comment)
|
|
10262
10262
|
comment = cb;
|
|
10263
10263
|
else
|
|
10264
|
-
comment +=
|
|
10265
|
-
|
|
10264
|
+
comment += sep4 + cb;
|
|
10265
|
+
sep4 = "";
|
|
10266
10266
|
break;
|
|
10267
10267
|
}
|
|
10268
10268
|
case "newline":
|
|
10269
10269
|
if (comment)
|
|
10270
|
-
|
|
10270
|
+
sep4 += source;
|
|
10271
10271
|
hasSpace = true;
|
|
10272
10272
|
break;
|
|
10273
10273
|
default:
|
|
@@ -10310,18 +10310,18 @@ var require_resolve_flow_collection = __commonJS({
|
|
|
10310
10310
|
let offset = fc.offset + fc.start.source.length;
|
|
10311
10311
|
for (let i3 = 0; i3 < fc.items.length; ++i3) {
|
|
10312
10312
|
const collItem = fc.items[i3];
|
|
10313
|
-
const { start, key, sep:
|
|
10313
|
+
const { start, key, sep: sep4, value } = collItem;
|
|
10314
10314
|
const props = resolveProps.resolveProps(start, {
|
|
10315
10315
|
flow: fcName,
|
|
10316
10316
|
indicator: "explicit-key-ind",
|
|
10317
|
-
next: key ??
|
|
10317
|
+
next: key ?? sep4?.[0],
|
|
10318
10318
|
offset,
|
|
10319
10319
|
onError,
|
|
10320
10320
|
parentIndent: fc.indent,
|
|
10321
10321
|
startOnNewline: false
|
|
10322
10322
|
});
|
|
10323
10323
|
if (!props.found) {
|
|
10324
|
-
if (!props.anchor && !props.tag && !
|
|
10324
|
+
if (!props.anchor && !props.tag && !sep4 && !value) {
|
|
10325
10325
|
if (i3 === 0 && props.comma)
|
|
10326
10326
|
onError(props.comma, "UNEXPECTED_TOKEN", `Unexpected , in ${fcName}`);
|
|
10327
10327
|
else if (i3 < fc.items.length - 1)
|
|
@@ -10375,8 +10375,8 @@ var require_resolve_flow_collection = __commonJS({
|
|
|
10375
10375
|
}
|
|
10376
10376
|
}
|
|
10377
10377
|
}
|
|
10378
|
-
if (!isMap && !
|
|
10379
|
-
const valueNode = value ? composeNode(ctx, value, props, onError) : composeEmptyNode(ctx, props.end,
|
|
10378
|
+
if (!isMap && !sep4 && !props.found) {
|
|
10379
|
+
const valueNode = value ? composeNode(ctx, value, props, onError) : composeEmptyNode(ctx, props.end, sep4, null, props, onError);
|
|
10380
10380
|
coll.items.push(valueNode);
|
|
10381
10381
|
offset = valueNode.range[2];
|
|
10382
10382
|
if (isBlock(value))
|
|
@@ -10388,7 +10388,7 @@ var require_resolve_flow_collection = __commonJS({
|
|
|
10388
10388
|
if (isBlock(key))
|
|
10389
10389
|
onError(keyNode.range, "BLOCK_IN_FLOW", blockMsg);
|
|
10390
10390
|
ctx.atKey = false;
|
|
10391
|
-
const valueProps = resolveProps.resolveProps(
|
|
10391
|
+
const valueProps = resolveProps.resolveProps(sep4 ?? [], {
|
|
10392
10392
|
flow: fcName,
|
|
10393
10393
|
indicator: "map-value-ind",
|
|
10394
10394
|
next: value,
|
|
@@ -10399,8 +10399,8 @@ var require_resolve_flow_collection = __commonJS({
|
|
|
10399
10399
|
});
|
|
10400
10400
|
if (valueProps.found) {
|
|
10401
10401
|
if (!isMap && !props.found && ctx.options.strict) {
|
|
10402
|
-
if (
|
|
10403
|
-
for (const st of
|
|
10402
|
+
if (sep4)
|
|
10403
|
+
for (const st of sep4) {
|
|
10404
10404
|
if (st === valueProps.found)
|
|
10405
10405
|
break;
|
|
10406
10406
|
if (st.type === "newline") {
|
|
@@ -10417,7 +10417,7 @@ var require_resolve_flow_collection = __commonJS({
|
|
|
10417
10417
|
else
|
|
10418
10418
|
onError(valueProps.start, "MISSING_CHAR", `Missing , or : between ${fcName} items`);
|
|
10419
10419
|
}
|
|
10420
|
-
const valueNode = value ? composeNode(ctx, value, valueProps, onError) : valueProps.found ? composeEmptyNode(ctx, valueProps.end,
|
|
10420
|
+
const valueNode = value ? composeNode(ctx, value, valueProps, onError) : valueProps.found ? composeEmptyNode(ctx, valueProps.end, sep4, null, valueProps, onError) : null;
|
|
10421
10421
|
if (valueNode) {
|
|
10422
10422
|
if (isBlock(value))
|
|
10423
10423
|
onError(valueNode.range, "BLOCK_IN_FLOW", blockMsg);
|
|
@@ -10597,7 +10597,7 @@ var require_resolve_block_scalar = __commonJS({
|
|
|
10597
10597
|
chompStart = i3 + 1;
|
|
10598
10598
|
}
|
|
10599
10599
|
let value = "";
|
|
10600
|
-
let
|
|
10600
|
+
let sep4 = "";
|
|
10601
10601
|
let prevMoreIndented = false;
|
|
10602
10602
|
for (let i3 = 0; i3 < contentStart; ++i3)
|
|
10603
10603
|
value += lines[i3][0].slice(trimIndent) + "\n";
|
|
@@ -10614,24 +10614,24 @@ var require_resolve_block_scalar = __commonJS({
|
|
|
10614
10614
|
indent = "";
|
|
10615
10615
|
}
|
|
10616
10616
|
if (type === Scalar.Scalar.BLOCK_LITERAL) {
|
|
10617
|
-
value +=
|
|
10618
|
-
|
|
10617
|
+
value += sep4 + indent.slice(trimIndent) + content;
|
|
10618
|
+
sep4 = "\n";
|
|
10619
10619
|
} else if (indent.length > trimIndent || content[0] === " ") {
|
|
10620
|
-
if (
|
|
10621
|
-
|
|
10622
|
-
else if (!prevMoreIndented &&
|
|
10623
|
-
|
|
10624
|
-
value +=
|
|
10625
|
-
|
|
10620
|
+
if (sep4 === " ")
|
|
10621
|
+
sep4 = "\n";
|
|
10622
|
+
else if (!prevMoreIndented && sep4 === "\n")
|
|
10623
|
+
sep4 = "\n\n";
|
|
10624
|
+
value += sep4 + indent.slice(trimIndent) + content;
|
|
10625
|
+
sep4 = "\n";
|
|
10626
10626
|
prevMoreIndented = true;
|
|
10627
10627
|
} else if (content === "") {
|
|
10628
|
-
if (
|
|
10628
|
+
if (sep4 === "\n")
|
|
10629
10629
|
value += "\n";
|
|
10630
10630
|
else
|
|
10631
|
-
|
|
10631
|
+
sep4 = "\n";
|
|
10632
10632
|
} else {
|
|
10633
|
-
value +=
|
|
10634
|
-
|
|
10633
|
+
value += sep4 + content;
|
|
10634
|
+
sep4 = " ";
|
|
10635
10635
|
prevMoreIndented = false;
|
|
10636
10636
|
}
|
|
10637
10637
|
}
|
|
@@ -10813,25 +10813,25 @@ var require_resolve_flow_scalar = __commonJS({
|
|
|
10813
10813
|
if (!match)
|
|
10814
10814
|
return source;
|
|
10815
10815
|
let res = match[1];
|
|
10816
|
-
let
|
|
10816
|
+
let sep4 = " ";
|
|
10817
10817
|
let pos = first.lastIndex;
|
|
10818
10818
|
line.lastIndex = pos;
|
|
10819
10819
|
while (match = line.exec(source)) {
|
|
10820
10820
|
if (match[1] === "") {
|
|
10821
|
-
if (
|
|
10822
|
-
res +=
|
|
10821
|
+
if (sep4 === "\n")
|
|
10822
|
+
res += sep4;
|
|
10823
10823
|
else
|
|
10824
|
-
|
|
10824
|
+
sep4 = "\n";
|
|
10825
10825
|
} else {
|
|
10826
|
-
res +=
|
|
10827
|
-
|
|
10826
|
+
res += sep4 + match[1];
|
|
10827
|
+
sep4 = " ";
|
|
10828
10828
|
}
|
|
10829
10829
|
pos = line.lastIndex;
|
|
10830
10830
|
}
|
|
10831
10831
|
const last = /[ \t]*(.*)/sy;
|
|
10832
10832
|
last.lastIndex = pos;
|
|
10833
10833
|
match = last.exec(source);
|
|
10834
|
-
return res +
|
|
10834
|
+
return res + sep4 + (match?.[1] ?? "");
|
|
10835
10835
|
}
|
|
10836
10836
|
function doubleQuotedValue(source, onError) {
|
|
10837
10837
|
let res = "";
|
|
@@ -11641,14 +11641,14 @@ var require_cst_stringify = __commonJS({
|
|
|
11641
11641
|
}
|
|
11642
11642
|
}
|
|
11643
11643
|
}
|
|
11644
|
-
function stringifyItem({ start, key, sep:
|
|
11644
|
+
function stringifyItem({ start, key, sep: sep4, value }) {
|
|
11645
11645
|
let res = "";
|
|
11646
11646
|
for (const st of start)
|
|
11647
11647
|
res += st.source;
|
|
11648
11648
|
if (key)
|
|
11649
11649
|
res += stringifyToken(key);
|
|
11650
|
-
if (
|
|
11651
|
-
for (const st of
|
|
11650
|
+
if (sep4)
|
|
11651
|
+
for (const st of sep4)
|
|
11652
11652
|
res += st.source;
|
|
11653
11653
|
if (value)
|
|
11654
11654
|
res += stringifyToken(value);
|
|
@@ -12815,18 +12815,18 @@ var require_parser = __commonJS({
|
|
|
12815
12815
|
if (this.type === "map-value-ind") {
|
|
12816
12816
|
const prev = getPrevProps(this.peek(2));
|
|
12817
12817
|
const start = getFirstKeyStartProps(prev);
|
|
12818
|
-
let
|
|
12818
|
+
let sep4;
|
|
12819
12819
|
if (scalar.end) {
|
|
12820
|
-
|
|
12821
|
-
|
|
12820
|
+
sep4 = scalar.end;
|
|
12821
|
+
sep4.push(this.sourceToken);
|
|
12822
12822
|
delete scalar.end;
|
|
12823
12823
|
} else
|
|
12824
|
-
|
|
12824
|
+
sep4 = [this.sourceToken];
|
|
12825
12825
|
const map = {
|
|
12826
12826
|
type: "block-map",
|
|
12827
12827
|
offset: scalar.offset,
|
|
12828
12828
|
indent: scalar.indent,
|
|
12829
|
-
items: [{ start, key: scalar, sep:
|
|
12829
|
+
items: [{ start, key: scalar, sep: sep4 }]
|
|
12830
12830
|
};
|
|
12831
12831
|
this.onKeyLine = true;
|
|
12832
12832
|
this.stack[this.stack.length - 1] = map;
|
|
@@ -12979,15 +12979,15 @@ var require_parser = __commonJS({
|
|
|
12979
12979
|
} else if (isFlowToken(it.key) && !includesToken(it.sep, "newline")) {
|
|
12980
12980
|
const start2 = getFirstKeyStartProps(it.start);
|
|
12981
12981
|
const key = it.key;
|
|
12982
|
-
const
|
|
12983
|
-
|
|
12982
|
+
const sep4 = it.sep;
|
|
12983
|
+
sep4.push(this.sourceToken);
|
|
12984
12984
|
delete it.key;
|
|
12985
12985
|
delete it.sep;
|
|
12986
12986
|
this.stack.push({
|
|
12987
12987
|
type: "block-map",
|
|
12988
12988
|
offset: this.offset,
|
|
12989
12989
|
indent: this.indent,
|
|
12990
|
-
items: [{ start: start2, key, sep:
|
|
12990
|
+
items: [{ start: start2, key, sep: sep4 }]
|
|
12991
12991
|
});
|
|
12992
12992
|
} else if (start.length > 0) {
|
|
12993
12993
|
it.sep = it.sep.concat(start, this.sourceToken);
|
|
@@ -13181,13 +13181,13 @@ var require_parser = __commonJS({
|
|
|
13181
13181
|
const prev = getPrevProps(parent);
|
|
13182
13182
|
const start = getFirstKeyStartProps(prev);
|
|
13183
13183
|
fixFlowSeqItems(fc);
|
|
13184
|
-
const
|
|
13185
|
-
|
|
13184
|
+
const sep4 = fc.end.splice(1, fc.end.length);
|
|
13185
|
+
sep4.push(this.sourceToken);
|
|
13186
13186
|
const map = {
|
|
13187
13187
|
type: "block-map",
|
|
13188
13188
|
offset: fc.offset,
|
|
13189
13189
|
indent: fc.indent,
|
|
13190
|
-
items: [{ start, key: fc, sep:
|
|
13190
|
+
items: [{ start, key: fc, sep: sep4 }]
|
|
13191
13191
|
};
|
|
13192
13192
|
this.onKeyLine = true;
|
|
13193
13193
|
this.stack[this.stack.length - 1] = map;
|
|
@@ -14036,7 +14036,7 @@ function configureNetworkFamilyDefaults(network = net) {
|
|
|
14036
14036
|
configureNetworkFamilyDefaults();
|
|
14037
14037
|
|
|
14038
14038
|
// apps/body/dist/cli.js
|
|
14039
|
-
import { dirname as
|
|
14039
|
+
import { dirname as dirname32, resolve as resolve48 } from "node:path";
|
|
14040
14040
|
import { stdin as stdin4, stdout as stdout5 } from "node:process";
|
|
14041
14041
|
|
|
14042
14042
|
// node_modules/@clack/core/dist/index.mjs
|
|
@@ -15476,7 +15476,7 @@ function parseCursorModelsOutput(output) {
|
|
|
15476
15476
|
};
|
|
15477
15477
|
}
|
|
15478
15478
|
async function enumerateCursorModels(env = process.env) {
|
|
15479
|
-
return new Promise((
|
|
15479
|
+
return new Promise((resolve49) => {
|
|
15480
15480
|
const child = spawn2("cursor-agent", ["models"], {
|
|
15481
15481
|
env,
|
|
15482
15482
|
stdio: ["ignore", "pipe", "ignore"]
|
|
@@ -15490,11 +15490,11 @@ async function enumerateCursorModels(env = process.env) {
|
|
|
15490
15490
|
});
|
|
15491
15491
|
child.on("error", () => {
|
|
15492
15492
|
clearTimeout(timer);
|
|
15493
|
-
|
|
15493
|
+
resolve49(void 0);
|
|
15494
15494
|
});
|
|
15495
15495
|
child.on("close", (code) => {
|
|
15496
15496
|
clearTimeout(timer);
|
|
15497
|
-
|
|
15497
|
+
resolve49(code === 0 ? parseCursorModelsOutput(output) : void 0);
|
|
15498
15498
|
});
|
|
15499
15499
|
});
|
|
15500
15500
|
}
|
|
@@ -15921,13 +15921,13 @@ var CursorAcpServer = class {
|
|
|
15921
15921
|
consumeLine(line);
|
|
15922
15922
|
});
|
|
15923
15923
|
try {
|
|
15924
|
-
const { code, signal } = await new Promise((
|
|
15924
|
+
const { code, signal } = await new Promise((resolve49) => {
|
|
15925
15925
|
let settled = false;
|
|
15926
15926
|
const finish = (exitCode, exitSignal) => {
|
|
15927
15927
|
if (settled)
|
|
15928
15928
|
return;
|
|
15929
15929
|
settled = true;
|
|
15930
|
-
|
|
15930
|
+
resolve49({ code: exitCode, signal: exitSignal });
|
|
15931
15931
|
};
|
|
15932
15932
|
child.once("error", (error) => {
|
|
15933
15933
|
spawnError = error instanceof Error ? error.message : String(error);
|
|
@@ -16072,10 +16072,10 @@ function releaseSquireConnectSession(log2, owner = "") {
|
|
|
16072
16072
|
function squireChromeProfileDir() {
|
|
16073
16073
|
return process.env.TRUSTY_SQUIRE_PROFILE_DIR ?? squireHostPaths(homedir2()).profileDir;
|
|
16074
16074
|
}
|
|
16075
|
-
var defaultShellRunner = (command, args) => new Promise((
|
|
16075
|
+
var defaultShellRunner = (command, args) => new Promise((resolve49) => {
|
|
16076
16076
|
execFile(command, [...args], { timeout: 12e4, maxBuffer: 4 * 1024 * 1024, encoding: "utf8" }, (error, stdout6, stderr) => {
|
|
16077
16077
|
const code = error?.code;
|
|
16078
|
-
|
|
16078
|
+
resolve49({
|
|
16079
16079
|
code: typeof code === "number" ? code : error ? 1 : 0,
|
|
16080
16080
|
stdout: String(stdout6 ?? ""),
|
|
16081
16081
|
stderr: String(stderr ?? "")
|
|
@@ -16100,7 +16100,7 @@ function killConnectTree(child) {
|
|
|
16100
16100
|
}
|
|
16101
16101
|
child.kill();
|
|
16102
16102
|
}
|
|
16103
|
-
var defaultStreamedRunner = (command, args, env, owner = "") => new Promise((
|
|
16103
|
+
var defaultStreamedRunner = (command, args, env, owner = "") => new Promise((resolve49) => {
|
|
16104
16104
|
const child = spawn5(command, args, {
|
|
16105
16105
|
stdio: ["ignore", "pipe", "pipe"],
|
|
16106
16106
|
env: env ?? squireConnectProcessEnv(),
|
|
@@ -16114,7 +16114,7 @@ var defaultStreamedRunner = (command, args, env, owner = "") => new Promise((res
|
|
|
16114
16114
|
const safetyTimer = setTimeout(() => {
|
|
16115
16115
|
if (!resolved) {
|
|
16116
16116
|
resolved = true;
|
|
16117
|
-
|
|
16117
|
+
resolve49({ stdout: stdout6, stderr, pid: child.pid ?? void 0, report, abort: () => {
|
|
16118
16118
|
} });
|
|
16119
16119
|
}
|
|
16120
16120
|
killConnectTree(child);
|
|
@@ -16149,7 +16149,7 @@ var defaultStreamedRunner = (command, args, env, owner = "") => new Promise((res
|
|
|
16149
16149
|
const finish = (result) => {
|
|
16150
16150
|
if (!resolved) {
|
|
16151
16151
|
resolved = true;
|
|
16152
|
-
|
|
16152
|
+
resolve49(result);
|
|
16153
16153
|
}
|
|
16154
16154
|
};
|
|
16155
16155
|
const settle = (result) => {
|
|
@@ -16641,13 +16641,13 @@ var StdioSquireMcpClient = class {
|
|
|
16641
16641
|
const child = this.child;
|
|
16642
16642
|
if (!child)
|
|
16643
16643
|
return Promise.reject(new Error("Squire MCP session is not running"));
|
|
16644
|
-
return new Promise((
|
|
16644
|
+
return new Promise((resolve49, reject) => {
|
|
16645
16645
|
const timeoutMs = method === "initialize" ? INITIALIZE_TIMEOUT_MS : CALL_TIMEOUT_MS;
|
|
16646
16646
|
const timer = setTimeout(() => {
|
|
16647
16647
|
this.pending.delete(id);
|
|
16648
16648
|
reject(new Error(`${toolName2 ?? method} timed out after ${timeoutMs}ms`));
|
|
16649
16649
|
}, timeoutMs);
|
|
16650
|
-
this.pending.set(id, { resolve:
|
|
16650
|
+
this.pending.set(id, { resolve: resolve49, reject, timer });
|
|
16651
16651
|
child.stdin.write(`${JSON.stringify({ jsonrpc: "2.0", id, method, params })}
|
|
16652
16652
|
`);
|
|
16653
16653
|
});
|
|
@@ -16809,9 +16809,9 @@ var SquireTaskRelay = class {
|
|
|
16809
16809
|
response.writeHead(400, { "content-type": "application/json" }).end(JSON.stringify({ error: error instanceof Error ? error.message : "Squire relay failed" }));
|
|
16810
16810
|
}
|
|
16811
16811
|
});
|
|
16812
|
-
await new Promise((
|
|
16812
|
+
await new Promise((resolve49, reject) => {
|
|
16813
16813
|
server.once("error", reject);
|
|
16814
|
-
server.listen(0, "127.0.0.1",
|
|
16814
|
+
server.listen(0, "127.0.0.1", resolve49);
|
|
16815
16815
|
});
|
|
16816
16816
|
this.server = server;
|
|
16817
16817
|
const address = server.address();
|
|
@@ -17850,11 +17850,11 @@ var RegistryMcpHostBroker = class {
|
|
|
17850
17850
|
})();
|
|
17851
17851
|
});
|
|
17852
17852
|
});
|
|
17853
|
-
await new Promise((
|
|
17853
|
+
await new Promise((resolve49, reject) => {
|
|
17854
17854
|
this.server.once("error", reject);
|
|
17855
17855
|
this.server.listen(this.socketPath, () => {
|
|
17856
17856
|
this.server.off("error", reject);
|
|
17857
|
-
|
|
17857
|
+
resolve49();
|
|
17858
17858
|
});
|
|
17859
17859
|
});
|
|
17860
17860
|
chmodSync(this.socketPath, 384);
|
|
@@ -17863,12 +17863,12 @@ var RegistryMcpHostBroker = class {
|
|
|
17863
17863
|
const server = this.server;
|
|
17864
17864
|
this.server = void 0;
|
|
17865
17865
|
if (server)
|
|
17866
|
-
await new Promise((
|
|
17866
|
+
await new Promise((resolve49) => server.close(() => resolve49()));
|
|
17867
17867
|
rmSync(this.socketPath, { force: true });
|
|
17868
17868
|
}
|
|
17869
17869
|
};
|
|
17870
17870
|
async function brokerRequest(socketPath, request) {
|
|
17871
|
-
return new Promise((
|
|
17871
|
+
return new Promise((resolve49, reject) => {
|
|
17872
17872
|
const socket = createConnection3(socketPath);
|
|
17873
17873
|
let output = "";
|
|
17874
17874
|
socket.setEncoding("utf8");
|
|
@@ -17885,7 +17885,7 @@ async function brokerRequest(socketPath, request) {
|
|
|
17885
17885
|
throw new Error(parsed.error);
|
|
17886
17886
|
if (!Array.isArray(parsed.messages) || !parsed.messages.every((entry) => typeof entry === "string"))
|
|
17887
17887
|
throw new Error("Registry MCP broker returned an invalid response");
|
|
17888
|
-
|
|
17888
|
+
resolve49(parsed.messages);
|
|
17889
17889
|
} catch (error) {
|
|
17890
17890
|
reject(error);
|
|
17891
17891
|
}
|
|
@@ -18099,7 +18099,8 @@ var TURN_SILENCE_KINDS = [
|
|
|
18099
18099
|
"helper-out-of-date",
|
|
18100
18100
|
"update-interrupted",
|
|
18101
18101
|
"offline",
|
|
18102
|
-
"context-overflow"
|
|
18102
|
+
"context-overflow",
|
|
18103
|
+
"resource-limit"
|
|
18103
18104
|
];
|
|
18104
18105
|
var TURN_RECEIPT_REASON_KINDS = [
|
|
18105
18106
|
"hiccup",
|
|
@@ -18111,6 +18112,7 @@ var TURN_RECEIPT_REASON_KINDS = [
|
|
|
18111
18112
|
"update-interrupted",
|
|
18112
18113
|
"offline",
|
|
18113
18114
|
"context-overflow",
|
|
18115
|
+
"resource-limit",
|
|
18114
18116
|
"model-selection-unavailable"
|
|
18115
18117
|
];
|
|
18116
18118
|
function isTurnReceiptReasonKind(value) {
|
|
@@ -18158,6 +18160,9 @@ function classifyTurnSilence(reason, reasonKind) {
|
|
|
18158
18160
|
if (isContextOverflowFault(text2)) {
|
|
18159
18161
|
return { kind: "context-overflow" };
|
|
18160
18162
|
}
|
|
18163
|
+
if (/\bresource_limit: ACP session exceeded its \d+ MiB memory limit\b/i.test(text2)) {
|
|
18164
|
+
return { kind: "resource-limit" };
|
|
18165
|
+
}
|
|
18161
18166
|
if (/\b402\b/.test(text2) || /usage limit/i.test(text2) || /more credits/i.test(text2) || /quota/i.test(text2) || /allowance is spent/i.test(text2)) {
|
|
18162
18167
|
return {
|
|
18163
18168
|
kind: "allowance-spent",
|
|
@@ -19354,7 +19359,7 @@ var AgentSignIn = class {
|
|
|
19354
19359
|
};
|
|
19355
19360
|
for (const name of ISOLATION_VARIABLES)
|
|
19356
19361
|
delete env[name];
|
|
19357
|
-
return new Promise((
|
|
19362
|
+
return new Promise((resolve49, reject) => {
|
|
19358
19363
|
let output = "";
|
|
19359
19364
|
let answered = false;
|
|
19360
19365
|
let child;
|
|
@@ -19395,7 +19400,7 @@ var AgentSignIn = class {
|
|
|
19395
19400
|
return;
|
|
19396
19401
|
answered = true;
|
|
19397
19402
|
clearTimeout(linkTimer);
|
|
19398
|
-
|
|
19403
|
+
resolve49(link2);
|
|
19399
19404
|
};
|
|
19400
19405
|
child.stdout?.on("data", read2);
|
|
19401
19406
|
child.stderr?.on("data", read2);
|
|
@@ -29228,13 +29233,13 @@ var RoomSupervisor = class {
|
|
|
29228
29233
|
*/
|
|
29229
29234
|
retryDelay(failures, signal, since = this.#wakes) {
|
|
29230
29235
|
const delay = this.delaysMs[failures - 1];
|
|
29231
|
-
return new Promise((
|
|
29236
|
+
return new Promise((resolve49) => {
|
|
29232
29237
|
let timer;
|
|
29233
29238
|
const done = () => {
|
|
29234
29239
|
clearTimeout(timer);
|
|
29235
29240
|
this.#parked.delete(done);
|
|
29236
29241
|
signal?.removeEventListener("abort", done);
|
|
29237
|
-
|
|
29242
|
+
resolve49();
|
|
29238
29243
|
};
|
|
29239
29244
|
this.#parked.add(done);
|
|
29240
29245
|
signal?.addEventListener("abort", done, { once: true });
|
|
@@ -29426,12 +29431,12 @@ async function retryBeforeReady(work, options) {
|
|
|
29426
29431
|
if (wait2 <= 0)
|
|
29427
29432
|
break;
|
|
29428
29433
|
await options.extendStartTimeout(wait2 + 15e3);
|
|
29429
|
-
await new Promise((
|
|
29434
|
+
await new Promise((resolve49) => {
|
|
29430
29435
|
const timer = setTimeout(done, wait2);
|
|
29431
29436
|
function done() {
|
|
29432
29437
|
clearTimeout(timer);
|
|
29433
29438
|
options.signal?.removeEventListener("abort", done);
|
|
29434
|
-
|
|
29439
|
+
resolve49();
|
|
29435
29440
|
}
|
|
29436
29441
|
wake = done;
|
|
29437
29442
|
options.signal?.addEventListener("abort", done, { once: true });
|
|
@@ -29599,6 +29604,94 @@ import { resolve as resolve20 } from "node:path";
|
|
|
29599
29604
|
import { spawn as spawn11 } from "node:child_process";
|
|
29600
29605
|
import { EventEmitter } from "node:events";
|
|
29601
29606
|
|
|
29607
|
+
// apps/body/dist/acp-resource-scope.js
|
|
29608
|
+
import { execFile as execFile6 } from "node:child_process";
|
|
29609
|
+
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
29610
|
+
import { readFileSync as readFileSync4 } from "node:fs";
|
|
29611
|
+
import { totalmem } from "node:os";
|
|
29612
|
+
import { promisify as promisify5 } from "node:util";
|
|
29613
|
+
var execFileAsync5 = promisify5(execFile6);
|
|
29614
|
+
function acpSessionMemoryMaxBytes(hostMemoryBytes = totalmem()) {
|
|
29615
|
+
return Math.max(8 * 1024 ** 3, Math.floor(hostMemoryBytes / 4));
|
|
29616
|
+
}
|
|
29617
|
+
var ACP_SESSION_MEMORY_MAX_BYTES = acpSessionMemoryMaxBytes();
|
|
29618
|
+
var AcpResourceScope = class {
|
|
29619
|
+
memoryMaxBytes;
|
|
29620
|
+
unit = `beeline-acp-${randomUUID6()}.scope`;
|
|
29621
|
+
#stop;
|
|
29622
|
+
constructor(memoryMaxBytes = ACP_SESSION_MEMORY_MAX_BYTES) {
|
|
29623
|
+
this.memoryMaxBytes = memoryMaxBytes;
|
|
29624
|
+
}
|
|
29625
|
+
launch(command, args, agentEnv) {
|
|
29626
|
+
const env = { ...agentEnv };
|
|
29627
|
+
const stripBus = !Object.hasOwn(agentEnv, "DBUS_SESSION_BUS_ADDRESS");
|
|
29628
|
+
if (stripBus && process.env.DBUS_SESSION_BUS_ADDRESS)
|
|
29629
|
+
env.DBUS_SESSION_BUS_ADDRESS = process.env.DBUS_SESSION_BUS_ADDRESS;
|
|
29630
|
+
if (!env.XDG_RUNTIME_DIR && process.env.XDG_RUNTIME_DIR)
|
|
29631
|
+
env.XDG_RUNTIME_DIR = process.env.XDG_RUNTIME_DIR;
|
|
29632
|
+
const stripRuntime = !Object.hasOwn(agentEnv, "XDG_RUNTIME_DIR");
|
|
29633
|
+
const owner = managedServiceUnit();
|
|
29634
|
+
return {
|
|
29635
|
+
command: "systemd-run",
|
|
29636
|
+
args: [
|
|
29637
|
+
"--user",
|
|
29638
|
+
"--scope",
|
|
29639
|
+
"--quiet",
|
|
29640
|
+
"--same-dir",
|
|
29641
|
+
`--unit=${this.unit}`,
|
|
29642
|
+
`--property=MemoryMax=${this.memoryMaxBytes}`,
|
|
29643
|
+
"--property=MemorySwapMax=0",
|
|
29644
|
+
"--property=OOMPolicy=kill",
|
|
29645
|
+
"--property=KillMode=control-group",
|
|
29646
|
+
"--property=TimeoutStopSec=1s",
|
|
29647
|
+
...owner ? [`--property=BindsTo=${owner}`, `--property=After=${owner}`] : [],
|
|
29648
|
+
"/usr/bin/env",
|
|
29649
|
+
...stripBus ? ["-u", "DBUS_SESSION_BUS_ADDRESS"] : [],
|
|
29650
|
+
...stripRuntime ? ["-u", "XDG_RUNTIME_DIR"] : [],
|
|
29651
|
+
command,
|
|
29652
|
+
...args
|
|
29653
|
+
],
|
|
29654
|
+
env
|
|
29655
|
+
};
|
|
29656
|
+
}
|
|
29657
|
+
/** An OOM result survives process exit until reset-failed unloads the unit. */
|
|
29658
|
+
async exceededMemoryLimit() {
|
|
29659
|
+
try {
|
|
29660
|
+
const { stdout: stdout6 } = await execFileAsync5("systemctl", ["--user", "show", this.unit, "--property=Result", "--value"], { timeout: 5e3 });
|
|
29661
|
+
return stdout6.trim() === "oom-kill";
|
|
29662
|
+
} catch {
|
|
29663
|
+
return false;
|
|
29664
|
+
}
|
|
29665
|
+
}
|
|
29666
|
+
async stop() {
|
|
29667
|
+
return this.#stop ??= (async () => {
|
|
29668
|
+
try {
|
|
29669
|
+
await execFileAsync5("systemctl", ["--user", "stop", this.unit], { timeout: 5e3 });
|
|
29670
|
+
} catch (error) {
|
|
29671
|
+
const { stdout: stdout6 } = await execFileAsync5("systemctl", ["--user", "show", this.unit, "--property=LoadState", "--value"], { timeout: 5e3 });
|
|
29672
|
+
if (stdout6.trim() !== "not-found")
|
|
29673
|
+
throw error;
|
|
29674
|
+
} finally {
|
|
29675
|
+
await execFileAsync5("systemctl", ["--user", "reset-failed", this.unit], { timeout: 5e3 }).catch(() => void 0);
|
|
29676
|
+
}
|
|
29677
|
+
})().catch((error) => {
|
|
29678
|
+
this.#stop = void 0;
|
|
29679
|
+
throw error;
|
|
29680
|
+
});
|
|
29681
|
+
}
|
|
29682
|
+
};
|
|
29683
|
+
function managedServiceUnit() {
|
|
29684
|
+
if (process.env.BEELINE_MANAGED_BY_SYSTEMD !== "1")
|
|
29685
|
+
return void 0;
|
|
29686
|
+
try {
|
|
29687
|
+
const cgroup = readFileSync4("/proc/self/cgroup", "utf8");
|
|
29688
|
+
const path = cgroup.split("\n").find((line) => line.startsWith("0::"))?.slice(3);
|
|
29689
|
+
return path?.split("/").find((part) => /^beeline-(?:helper|agent@.+)\.service$/.test(part));
|
|
29690
|
+
} catch {
|
|
29691
|
+
return void 0;
|
|
29692
|
+
}
|
|
29693
|
+
}
|
|
29694
|
+
|
|
29602
29695
|
// apps/body/dist/harness-capabilities.js
|
|
29603
29696
|
var PROFILES = [
|
|
29604
29697
|
{
|
|
@@ -29912,6 +30005,13 @@ var AcpRuntimeExitedError = class extends Error {
|
|
|
29912
30005
|
this.name = "AcpRuntimeExitedError";
|
|
29913
30006
|
}
|
|
29914
30007
|
};
|
|
30008
|
+
var AcpResourceLimitError = class extends Error {
|
|
30009
|
+
cause = "resource_limit";
|
|
30010
|
+
constructor(memoryMaxBytes) {
|
|
30011
|
+
super(`resource_limit: ACP session exceeded its ${Math.floor(memoryMaxBytes / 1024 / 1024)} MiB memory limit`);
|
|
30012
|
+
this.name = "AcpResourceLimitError";
|
|
30013
|
+
}
|
|
30014
|
+
};
|
|
29915
30015
|
function killChildProcessGroup(child, signal) {
|
|
29916
30016
|
if (!child.pid)
|
|
29917
30017
|
return;
|
|
@@ -30196,6 +30296,10 @@ var AcpClient = class extends EventEmitter {
|
|
|
30196
30296
|
permissionAllowlist;
|
|
30197
30297
|
commandsHandler;
|
|
30198
30298
|
oomKills;
|
|
30299
|
+
useResourceScope;
|
|
30300
|
+
resourceScopeMemoryMaxBytes;
|
|
30301
|
+
resourceScope;
|
|
30302
|
+
resourceScopeUnavailable = false;
|
|
30199
30303
|
/** A deliberate stop owns its SIGKILL; that exit is never labelled OOM. */
|
|
30200
30304
|
stopping = false;
|
|
30201
30305
|
constructor(opts) {
|
|
@@ -30216,21 +30320,25 @@ var AcpClient = class extends EventEmitter {
|
|
|
30216
30320
|
this.permissionAllowlist = opts.permissionAllowlist;
|
|
30217
30321
|
this.commandsHandler = opts.onCommands;
|
|
30218
30322
|
this.oomKills = opts.oomKills ?? new OomKillTracker(cgroupOomKillProbe());
|
|
30323
|
+
this.useResourceScope = opts.resourceScope === "systemd" || opts.resourceScope === void 0 && process.platform === "linux" && process.env.BEELINE_MANAGED_BY_SYSTEMD === "1";
|
|
30324
|
+
this.resourceScopeMemoryMaxBytes = opts.resourceScopeMemoryMaxBytes;
|
|
30219
30325
|
}
|
|
30220
30326
|
async start(timeoutMs = 6e4) {
|
|
30221
30327
|
if (this.alive)
|
|
30222
30328
|
return;
|
|
30223
30329
|
await this.oomKills.prime().catch(() => void 0);
|
|
30224
30330
|
this.stopping = false;
|
|
30225
|
-
|
|
30331
|
+
const childEnv = this.inheritProcessEnv ? { ...process.env, ...this.agentEnv } : this.agentEnv;
|
|
30332
|
+
this.resourceScope = this.useResourceScope && !this.resourceScopeUnavailable ? new AcpResourceScope(this.resourceScopeMemoryMaxBytes) : void 0;
|
|
30333
|
+
const launch = this.resourceScope?.launch(this.agentCommand, this.agentArgs, childEnv);
|
|
30334
|
+
this.child = await withAdapterInstallLock(() => spawn11(launch?.command ?? this.agentCommand, launch?.args ?? this.agentArgs, {
|
|
30226
30335
|
// agentEnv is the child's whole environment: buildAgentEnv's allowlist is
|
|
30227
30336
|
// a real boundary, not a decorative one layered over a full inherit.
|
|
30228
|
-
env:
|
|
30337
|
+
env: launch?.env ?? childEnv,
|
|
30229
30338
|
...this.agentCwd ? { cwd: this.agentCwd } : {},
|
|
30230
|
-
//
|
|
30231
|
-
//
|
|
30232
|
-
|
|
30233
|
-
detached: process.platform !== "win32",
|
|
30339
|
+
// Managed Linux sessions use a cgroup scope. The process-group fallback
|
|
30340
|
+
// covers helpers without a user systemd manager.
|
|
30341
|
+
detached: !launch && process.platform !== "win32",
|
|
30234
30342
|
stdio: ["pipe", "pipe", "pipe"]
|
|
30235
30343
|
}));
|
|
30236
30344
|
this.alive = true;
|
|
@@ -30265,10 +30373,35 @@ var AcpClient = class extends EventEmitter {
|
|
|
30265
30373
|
if (this.listenerCount("error") > 0)
|
|
30266
30374
|
this.emit("error", err);
|
|
30267
30375
|
});
|
|
30268
|
-
|
|
30269
|
-
|
|
30270
|
-
|
|
30271
|
-
|
|
30376
|
+
let initResult;
|
|
30377
|
+
try {
|
|
30378
|
+
initResult = await this.request("initialize", {
|
|
30379
|
+
protocolVersion: 1,
|
|
30380
|
+
clientCapabilities: {}
|
|
30381
|
+
}, timeoutMs);
|
|
30382
|
+
} catch (error) {
|
|
30383
|
+
if (launch && /EPIPE/.test(String(error)) && this.child?.exitCode === null) {
|
|
30384
|
+
await new Promise((resolve49) => {
|
|
30385
|
+
const timer = setTimeout(resolve49, 250);
|
|
30386
|
+
this.child?.once("close", () => {
|
|
30387
|
+
clearTimeout(timer);
|
|
30388
|
+
resolve49();
|
|
30389
|
+
});
|
|
30390
|
+
});
|
|
30391
|
+
}
|
|
30392
|
+
const scopeUnavailable = launch && !this.resourceScopeUnavailable && /(?:Failed to connect to bus|Failed to create bus connection|spawn systemd-run ENOENT)/i.test(`${this.stderrTail}
|
|
30393
|
+
${String(error)}`);
|
|
30394
|
+
await this.stop().catch(() => void 0);
|
|
30395
|
+
if (scopeUnavailable) {
|
|
30396
|
+
this.resourceScopeUnavailable = true;
|
|
30397
|
+
this.resourceScope = void 0;
|
|
30398
|
+
this.child = null;
|
|
30399
|
+
this.alive = false;
|
|
30400
|
+
console.warn("[acp] systemd user scope unavailable; starting ACP session in a process group");
|
|
30401
|
+
return this.start(timeoutMs);
|
|
30402
|
+
}
|
|
30403
|
+
throw error;
|
|
30404
|
+
}
|
|
30272
30405
|
const initMeta = initResult._meta;
|
|
30273
30406
|
const steering = initMeta?.steering;
|
|
30274
30407
|
this.supportsStandardSteering = steering?.supported === true;
|
|
@@ -30281,22 +30414,25 @@ var AcpClient = class extends EventEmitter {
|
|
|
30281
30414
|
}
|
|
30282
30415
|
/**
|
|
30283
30416
|
* One child exit: reject every in-flight request so the turn fails and is
|
|
30284
|
-
* reported instead of hanging, then publish the exit. A
|
|
30285
|
-
*
|
|
30286
|
-
* cause instead of a bare signal.
|
|
30417
|
+
* reported instead of hanging, then publish the exit. A scoped exit reads
|
|
30418
|
+
* that scope's result; an unscoped SIGKILL uses the daemon cgroup's OOM
|
|
30419
|
+
* counter so the rejection can name the cause instead of a bare signal.
|
|
30287
30420
|
*/
|
|
30288
30421
|
async handleChildExit(code, signal) {
|
|
30422
|
+
const child = this.child;
|
|
30289
30423
|
this.alive = false;
|
|
30290
30424
|
for (const p of this.pending.values())
|
|
30291
30425
|
this.clearTimer(p);
|
|
30426
|
+
const scope = this.resourceScope;
|
|
30427
|
+
const memoryLimited = scope && !this.stopping ? await scope.exceededMemoryLimit() : false;
|
|
30292
30428
|
let oomKilled = false;
|
|
30293
|
-
if (signal === "SIGKILL" && !this.stopping) {
|
|
30429
|
+
if (!memoryLimited && signal === "SIGKILL" && !this.stopping) {
|
|
30294
30430
|
let diagnosticTimer;
|
|
30295
30431
|
try {
|
|
30296
30432
|
oomKilled = await Promise.race([
|
|
30297
30433
|
this.oomKills.consume().catch(() => false),
|
|
30298
|
-
new Promise((
|
|
30299
|
-
diagnosticTimer = setTimeout(() =>
|
|
30434
|
+
new Promise((resolve49) => {
|
|
30435
|
+
diagnosticTimer = setTimeout(() => resolve49(false), 100);
|
|
30300
30436
|
})
|
|
30301
30437
|
]);
|
|
30302
30438
|
} finally {
|
|
@@ -30308,13 +30444,21 @@ var AcpClient = class extends EventEmitter {
|
|
|
30308
30444
|
const stderrSuffix = meaningful ? `: ${meaningful}` : "";
|
|
30309
30445
|
for (const [, p] of this.pending) {
|
|
30310
30446
|
this.clearTimer(p);
|
|
30311
|
-
p.reject(new AcpRuntimeExitedError(`${exitText}${stderrSuffix}`));
|
|
30447
|
+
p.reject(memoryLimited ? new AcpResourceLimitError(scope.memoryMaxBytes) : new AcpRuntimeExitedError(`${exitText}${stderrSuffix}`));
|
|
30312
30448
|
}
|
|
30313
30449
|
this.pending.clear();
|
|
30314
30450
|
this.activeRunIds.clear();
|
|
30315
30451
|
this.activePromptSessions.clear();
|
|
30316
30452
|
this.toolCallMetadata.clear();
|
|
30317
30453
|
this.sessionCommands.clear();
|
|
30454
|
+
if (scope) {
|
|
30455
|
+
await scope.stop().then(() => {
|
|
30456
|
+
if (this.resourceScope === scope)
|
|
30457
|
+
this.resourceScope = void 0;
|
|
30458
|
+
if (this.child === child)
|
|
30459
|
+
this.child = null;
|
|
30460
|
+
}).catch((error) => console.error("[acp] resource scope cleanup failed:", error));
|
|
30461
|
+
}
|
|
30318
30462
|
this.emit("exit", { code, signal });
|
|
30319
30463
|
}
|
|
30320
30464
|
failRuntime(detail) {
|
|
@@ -30324,27 +30468,36 @@ var AcpClient = class extends EventEmitter {
|
|
|
30324
30468
|
p.reject(new AcpRuntimeExitedError(detail));
|
|
30325
30469
|
}
|
|
30326
30470
|
this.pending.clear();
|
|
30471
|
+
if (this.resourceScope)
|
|
30472
|
+
void this.resourceScope.stop().catch((error) => console.error("[acp] resource scope cleanup failed:", error));
|
|
30327
30473
|
}
|
|
30328
30474
|
async stop() {
|
|
30329
30475
|
const child = this.child;
|
|
30330
|
-
|
|
30476
|
+
const scope = this.resourceScope;
|
|
30477
|
+
if (!child && !scope)
|
|
30331
30478
|
return;
|
|
30332
30479
|
this.stopping = true;
|
|
30333
30480
|
try {
|
|
30334
|
-
if (
|
|
30481
|
+
if (child?.stdin.writable) {
|
|
30335
30482
|
this.notify("shutdown", {});
|
|
30336
30483
|
}
|
|
30337
30484
|
} catch {
|
|
30338
30485
|
}
|
|
30339
|
-
|
|
30340
|
-
|
|
30341
|
-
|
|
30342
|
-
|
|
30343
|
-
}
|
|
30344
|
-
|
|
30345
|
-
|
|
30346
|
-
|
|
30347
|
-
|
|
30486
|
+
if (scope) {
|
|
30487
|
+
await scope.stop();
|
|
30488
|
+
if (this.resourceScope === scope)
|
|
30489
|
+
this.resourceScope = void 0;
|
|
30490
|
+
} else if (child) {
|
|
30491
|
+
await new Promise((r2) => setTimeout(r2, 300));
|
|
30492
|
+
try {
|
|
30493
|
+
killChildProcessGroup(child, "SIGTERM");
|
|
30494
|
+
} catch {
|
|
30495
|
+
}
|
|
30496
|
+
await new Promise((r2) => setTimeout(r2, 500));
|
|
30497
|
+
try {
|
|
30498
|
+
killChildProcessGroup(child, "SIGKILL");
|
|
30499
|
+
} catch {
|
|
30500
|
+
}
|
|
30348
30501
|
}
|
|
30349
30502
|
this.child = null;
|
|
30350
30503
|
this.alive = false;
|
|
@@ -30720,7 +30873,7 @@ var AcpClient = class extends EventEmitter {
|
|
|
30720
30873
|
const current = this.activeRunIds.get(sessionId);
|
|
30721
30874
|
if (current)
|
|
30722
30875
|
return Promise.resolve(current);
|
|
30723
|
-
return new Promise((
|
|
30876
|
+
return new Promise((resolve49, reject) => {
|
|
30724
30877
|
const onUpdate = (update) => {
|
|
30725
30878
|
if (update.sessionId !== sessionId)
|
|
30726
30879
|
return;
|
|
@@ -30728,7 +30881,7 @@ var AcpClient = class extends EventEmitter {
|
|
|
30728
30881
|
if (!runId)
|
|
30729
30882
|
return;
|
|
30730
30883
|
cleanup();
|
|
30731
|
-
|
|
30884
|
+
resolve49(runId);
|
|
30732
30885
|
};
|
|
30733
30886
|
const timer = setTimeout(() => {
|
|
30734
30887
|
cleanup();
|
|
@@ -30807,14 +30960,14 @@ var AcpClient = class extends EventEmitter {
|
|
|
30807
30960
|
}
|
|
30808
30961
|
const id = this.nextId++;
|
|
30809
30962
|
const payload = { jsonrpc: "2.0", id, method, params };
|
|
30810
|
-
return new Promise((
|
|
30963
|
+
return new Promise((resolve49, reject) => {
|
|
30811
30964
|
const timer = backstop ? void 0 : setTimeout(() => {
|
|
30812
30965
|
this.pending.delete(id);
|
|
30813
30966
|
reject(new AcpRequestTimeoutError(method, timeoutMs, this.stderrTail, false, detail));
|
|
30814
30967
|
}, timeoutMs);
|
|
30815
30968
|
const sessionId = params?.sessionId;
|
|
30816
30969
|
this.pending.set(id, {
|
|
30817
|
-
resolve:
|
|
30970
|
+
resolve: resolve49,
|
|
30818
30971
|
reject,
|
|
30819
30972
|
timer,
|
|
30820
30973
|
method,
|
|
@@ -30845,7 +30998,7 @@ var AcpClient = class extends EventEmitter {
|
|
|
30845
30998
|
|
|
30846
30999
|
// apps/body/dist/agent-home.js
|
|
30847
31000
|
var import_yaml2 = __toESM(require_dist(), 1);
|
|
30848
|
-
import { existsSync as existsSync7, readFileSync as
|
|
31001
|
+
import { existsSync as existsSync7, readFileSync as readFileSync6, watch } from "node:fs";
|
|
30849
31002
|
|
|
30850
31003
|
// node_modules/smol-toml/dist/date.js
|
|
30851
31004
|
var DATE_TIME_RE = /^(\d{4}-\d{2}-\d{2})?[T ]?(?:(\d{2}):\d{2}(?::\d{2}(?:\.\d+)?)?)?(Z|[-+]\d{2}:\d{2})?$/i;
|
|
@@ -31013,7 +31166,7 @@ function skipVoid(ctx, banNewLines, banComments) {
|
|
|
31013
31166
|
skipComment(ctx);
|
|
31014
31167
|
}
|
|
31015
31168
|
}
|
|
31016
|
-
function skipUntil(ctx,
|
|
31169
|
+
function skipUntil(ctx, sep4, end) {
|
|
31017
31170
|
let ptr = ctx.p;
|
|
31018
31171
|
if (!end) {
|
|
31019
31172
|
ptr = indexOfNewline(ctx.s, ptr);
|
|
@@ -31024,7 +31177,7 @@ function skipUntil(ctx, sep3, end) {
|
|
|
31024
31177
|
let c2 = ctx.s.charCodeAt(ctx.p);
|
|
31025
31178
|
if (c2 === 35) {
|
|
31026
31179
|
skipComment(ctx);
|
|
31027
|
-
} else if (c2 === end || c2 ===
|
|
31180
|
+
} else if (c2 === end || c2 === sep4) {
|
|
31028
31181
|
return;
|
|
31029
31182
|
}
|
|
31030
31183
|
}
|
|
@@ -31642,7 +31795,7 @@ function stringify(obj, { maxDepth = 1e3, numbersAsFloat = false } = {}) {
|
|
|
31642
31795
|
}
|
|
31643
31796
|
|
|
31644
31797
|
// apps/body/dist/agent-home.js
|
|
31645
|
-
import { createHash as createHash7, randomUUID as
|
|
31798
|
+
import { createHash as createHash7, randomUUID as randomUUID7 } from "node:crypto";
|
|
31646
31799
|
import { chmod as chmod5, copyFile, lstat as lstat3, mkdir as mkdir11, readFile as readFile16, readlink, readdir as readdir4, realpath, rename as rename7, rm as rm6, symlink as symlink2, unlink as unlink5, writeFile as writeFile9 } from "node:fs/promises";
|
|
31647
31800
|
import { homedir as homedir11 } from "node:os";
|
|
31648
31801
|
import { basename as basename3, dirname as dirname12, join as join12, relative, resolve as resolve16, sep } from "node:path";
|
|
@@ -31768,7 +31921,7 @@ function androidAgentEnv(input) {
|
|
|
31768
31921
|
}
|
|
31769
31922
|
|
|
31770
31923
|
// apps/body/dist/beeline-skill.js
|
|
31771
|
-
import { readFileSync as
|
|
31924
|
+
import { readFileSync as readFileSync5 } from "node:fs";
|
|
31772
31925
|
import { resolve as resolve13 } from "node:path";
|
|
31773
31926
|
|
|
31774
31927
|
// packages/api-contract/dist/phone-types.js
|
|
@@ -32275,7 +32428,7 @@ var BEELINE_ROOM_MECHANICS = [
|
|
|
32275
32428
|
"If you need reach outside the sandbox, call beeline-agent request_grant. If you already know discrete options, call beeline-agent ask_choice (one human, optional) or open_poll (every human in this Room, required deadline). A poll is refused below two electors and above fifty, and in a DM. A plurality is a fact, never permission to deploy, delete, merge, or spend. Open-ended asks stay tagged prose. Never put Always / Once / No on a preference.",
|
|
32276
32429
|
"To state something that happened so the Room and other agents can act on it, call beeline-agent emit_event with your own agent:<slug> kind, one sentence, and optionally the agent members to wake. Chains of events are bounded and a refused emit posts nothing."
|
|
32277
32430
|
].join(" ");
|
|
32278
|
-
function runningBeelineReleaseId(env = process.env, read2 = (path) =>
|
|
32431
|
+
function runningBeelineReleaseId(env = process.env, read2 = (path) => readFileSync5(path, "utf8")) {
|
|
32279
32432
|
try {
|
|
32280
32433
|
const lib = env.BEELINE_LIB_DIR;
|
|
32281
32434
|
if (!lib)
|
|
@@ -32312,7 +32465,7 @@ The tools this build knows, what each is for, and which the owner of this machin
|
|
|
32312
32465
|
|
|
32313
32466
|
**Use available tools before asking the person.** Before asking a person for a code, a status or a file, call workbench_status and check whether a tool or connected app you already have can get it, then use it. This includes an emailed verification code in an already-connected inbox. Ask only when none can, and say why. The key-ownership and grant rules still apply.
|
|
32314
32467
|
|
|
32315
|
-
**Offer the tool at the moment you need it.** When the work in front of you needs a tool the person does not have, do not send them to a settings page and do not stop at naming it. Call workbench_status first - a tool they already have is used, not offered. In a Room or DM, call offer_connector with the connectorType and one short reason: a card appears there, spoken by you, addressed to the person you are answering, with one action. Connector offers are unavailable in corners; use a Room or DM for those. Your turn pauses on the card - say in prose what you are waiting for and end the turn; you are woken when it is added, and then you carry on.
|
|
32468
|
+
**Offer the tool at the moment you need it.** When the work in front of you needs a tool the person does not have, do not send them to a settings page and do not stop at naming it. Call workbench_status first - a tool they already have is used, not offered. In a Room or DM, call offer_connector with the connectorType and one short reason: a card appears there, spoken by you, addressed to the person you are answering, with one action. Connector offers are unavailable in corners; use a Room or DM for those. When the person wants Squire on a different Google account (or its signed-in account is the wrong one), call offer_connector with connectorType trusty-squire and intent "switch" - a plain connect keeps the account it already has. Your turn pauses on the card - say in prose what you are waiting for and end the turn; you are woken when it is added, and then you carry on.
|
|
32316
32469
|
|
|
32317
32470
|
**Research before you offer, and say so.** Never offer a tool you cannot describe. If someone asks you to install or add something you do not already know - by name, by purpose, or by what it will hold - say plainly that you are looking it up first, find out what it is and what it does with credentials, and state what you learned in your reply BEFORE the card appears. A person reading "Add X?" must already have read, in your own words, what X is. Refusing to act blind is part of being trusted with keys.
|
|
32318
32471
|
|
|
@@ -33579,7 +33732,7 @@ async function writeBackDetachedClaudeLogin(target, source) {
|
|
|
33579
33732
|
const written = await withSharedClaudeLoginLock(shared, async () => {
|
|
33580
33733
|
if (!await isNewer())
|
|
33581
33734
|
return false;
|
|
33582
|
-
const temp = `${shared}.beeline-${
|
|
33735
|
+
const temp = `${shared}.beeline-${randomUUID7()}`;
|
|
33583
33736
|
try {
|
|
33584
33737
|
await writeFile9(temp, detached, { flag: "wx", mode: 384 });
|
|
33585
33738
|
await chmod5(temp, 384);
|
|
@@ -33596,7 +33749,7 @@ async function writeBackDetachedClaudeLogin(target, source) {
|
|
|
33596
33749
|
return "not-newer";
|
|
33597
33750
|
if (await readFile16(target, "utf8") !== detached)
|
|
33598
33751
|
return "busy";
|
|
33599
|
-
const link2 = `${target}.beeline-link-${
|
|
33752
|
+
const link2 = `${target}.beeline-link-${randomUUID7()}`;
|
|
33600
33753
|
await symlink2(source, link2);
|
|
33601
33754
|
await rename7(link2, target);
|
|
33602
33755
|
return "linked";
|
|
@@ -33626,7 +33779,7 @@ async function repairRoomAgentCredentialLinks(input) {
|
|
|
33626
33779
|
if (outcome !== "not-newer")
|
|
33627
33780
|
continue;
|
|
33628
33781
|
}
|
|
33629
|
-
const quarantine = `${target}.beeline-quarantine-${Date.now()}-${
|
|
33782
|
+
const quarantine = `${target}.beeline-quarantine-${Date.now()}-${randomUUID7()}`;
|
|
33630
33783
|
await rename7(target, quarantine);
|
|
33631
33784
|
}
|
|
33632
33785
|
await symlink2(source, target);
|
|
@@ -33745,7 +33898,7 @@ async function provisionAgentSkillsAndMcp(root, operatorHome, skillReleaseId, fa
|
|
|
33745
33898
|
try {
|
|
33746
33899
|
const source = resolve16(operatorHome, config.toml);
|
|
33747
33900
|
const target = resolve16(root, config.dir, "config.toml");
|
|
33748
|
-
const mcpSection = existsSync7(source) ? localHarnessMcpToml(
|
|
33901
|
+
const mcpSection = existsSync7(source) ? localHarnessMcpToml(readFileSync6(source, "utf8")) : void 0;
|
|
33749
33902
|
const section = config.dir === "codex" ? [CODEX_ROOM_AGENT_LOCKDOWN_TOML, CODEX_ROOM_WEB_SEARCH_TOML, mcpSection].filter(Boolean).join("\n") : mcpSection;
|
|
33750
33903
|
if (!section) {
|
|
33751
33904
|
await unlink5(target).catch(() => void 0);
|
|
@@ -33765,7 +33918,7 @@ async function provisionAgentSkillsAndMcp(root, operatorHome, skillReleaseId, fa
|
|
|
33765
33918
|
const source = resolve16(operatorHome, ".config", "goose", name);
|
|
33766
33919
|
const target = resolve16(gooseConfigDir, name);
|
|
33767
33920
|
if (existsSync7(source)) {
|
|
33768
|
-
const body =
|
|
33921
|
+
const body = readFileSync6(source, "utf8");
|
|
33769
33922
|
await writeIsolatedHarnessFile(target, name === "config.yaml" ? localGooseConfig(body) : body);
|
|
33770
33923
|
} else {
|
|
33771
33924
|
await unlink5(target).catch(() => void 0);
|
|
@@ -33843,7 +33996,7 @@ async function applyGrantedHostRoutes(root, operatorHome, granted, agentKind, fa
|
|
|
33843
33996
|
if (Object.keys(routes).length === 0)
|
|
33844
33997
|
continue;
|
|
33845
33998
|
const target = resolve16(root, config.dir, "config.toml");
|
|
33846
|
-
const existing = existsSync7(target) ?
|
|
33999
|
+
const existing = existsSync7(target) ? readFileSync6(target, "utf8") : void 0;
|
|
33847
34000
|
const merged = mergeTomlHostRoutes(existing, routes);
|
|
33848
34001
|
if (merged)
|
|
33849
34002
|
await writeIsolatedHarnessFile(target, merged);
|
|
@@ -33854,7 +34007,7 @@ async function applyGrantedHostRoutes(root, operatorHome, granted, agentKind, fa
|
|
|
33854
34007
|
const gooseConfigDir = resolve16(root, "goose", "config");
|
|
33855
34008
|
await mkdir11(gooseConfigDir, { recursive: true, mode: 448 });
|
|
33856
34009
|
const target = resolve16(gooseConfigDir, "config.yaml");
|
|
33857
|
-
const existing = existsSync7(target) ?
|
|
34010
|
+
const existing = existsSync7(target) ? readFileSync6(target, "utf8") : void 0;
|
|
33858
34011
|
const merged = mergeGooseHostRoutes(existing, routes);
|
|
33859
34012
|
if (merged)
|
|
33860
34013
|
await writeIsolatedHarnessFile(target, merged);
|
|
@@ -33929,7 +34082,7 @@ async function provisionPiCustomModelConfig(root, operatorHome, failClosed, open
|
|
|
33929
34082
|
if (resolvedSource !== source) {
|
|
33930
34083
|
throw new AgentHomeSecurityError(`Pi custom model config resolves through a link: ${source}`);
|
|
33931
34084
|
}
|
|
33932
|
-
const sourceValue = JSON.parse(
|
|
34085
|
+
const sourceValue = JSON.parse(readFileSync6(resolvedSource, "utf8"));
|
|
33933
34086
|
await writeIsolatedHarnessFile(target, `${JSON.stringify(withOpenRouterModelRouting(sourceValue, pin), null, 2)}
|
|
33934
34087
|
`);
|
|
33935
34088
|
} catch (error) {
|
|
@@ -33941,7 +34094,7 @@ async function provisionPiCustomModelConfig(root, operatorHome, failClosed, open
|
|
|
33941
34094
|
}
|
|
33942
34095
|
function readClaudeUserScopeMcpServers(path) {
|
|
33943
34096
|
try {
|
|
33944
|
-
const parsed = JSON.parse(
|
|
34097
|
+
const parsed = JSON.parse(readFileSync6(path, "utf8"));
|
|
33945
34098
|
const servers = recordValue2(parsed.mcpServers);
|
|
33946
34099
|
if (servers)
|
|
33947
34100
|
return localMcpServers(servers);
|
|
@@ -34142,7 +34295,7 @@ function readExistingText(path) {
|
|
|
34142
34295
|
if (!existsSync7(path))
|
|
34143
34296
|
return void 0;
|
|
34144
34297
|
try {
|
|
34145
|
-
return
|
|
34298
|
+
return readFileSync6(path, "utf8");
|
|
34146
34299
|
} catch {
|
|
34147
34300
|
return void 0;
|
|
34148
34301
|
}
|
|
@@ -34164,7 +34317,7 @@ async function provisionManagedSkillsDir(target, managedSkills, sharedSkills, op
|
|
|
34164
34317
|
const plan = await planManagedSkills(managedSkills, sharedSkills, optionalShares);
|
|
34165
34318
|
if (await materializedSkillManifest(target) === plan.manifest)
|
|
34166
34319
|
return;
|
|
34167
|
-
const staged = resolve16(parent, `.skills.${process.pid}.${
|
|
34320
|
+
const staged = resolve16(parent, `.skills.${process.pid}.${randomUUID7()}.tmp`);
|
|
34168
34321
|
await mkdir11(staged, { mode: 448 });
|
|
34169
34322
|
try {
|
|
34170
34323
|
for (const entry of plan.entries) {
|
|
@@ -34416,7 +34569,7 @@ async function writeIsolatedHarnessFile(path, content) {
|
|
|
34416
34569
|
if (!parentStats.isDirectory() || parentStats.isSymbolicLink()) {
|
|
34417
34570
|
throw new Error(`isolated harness parent is not a real directory: ${parent}`);
|
|
34418
34571
|
}
|
|
34419
|
-
const temporary = resolve16(parent, `.${basename3(path)}.${process.pid}.${
|
|
34572
|
+
const temporary = resolve16(parent, `.${basename3(path)}.${process.pid}.${randomUUID7()}.tmp`);
|
|
34420
34573
|
try {
|
|
34421
34574
|
await writeFile9(temporary, content, { mode: 384, flag: "wx" });
|
|
34422
34575
|
await chmod5(temporary, 384);
|
|
@@ -34473,8 +34626,8 @@ function harnessStateDirsFromEnv(env) {
|
|
|
34473
34626
|
}
|
|
34474
34627
|
|
|
34475
34628
|
// apps/body/dist/bwrap-sandbox.js
|
|
34476
|
-
import { execFile as
|
|
34477
|
-
import { lstatSync, readdirSync as readdirSync3, readFileSync as
|
|
34629
|
+
import { execFile as execFile7, spawnSync } from "node:child_process";
|
|
34630
|
+
import { lstatSync, readdirSync as readdirSync3, readFileSync as readFileSync7, rmSync as rmSync2, writeFileSync as writeFileSync3 } from "node:fs";
|
|
34478
34631
|
import { homedir as homedir12 } from "node:os";
|
|
34479
34632
|
import { basename as basename4, dirname as dirname13, isAbsolute as isAbsolute2, relative as relative2, resolve as resolve17 } from "node:path";
|
|
34480
34633
|
var DEFAULT_SANDBOX_POLICY = "bwrap";
|
|
@@ -34533,7 +34686,7 @@ var KNOWN_CREDENTIAL_MASK_PATHS = [
|
|
|
34533
34686
|
".secrets.env",
|
|
34534
34687
|
".beeline/registry-mcp"
|
|
34535
34688
|
];
|
|
34536
|
-
function credentialMaskPaths(extraPaths, home = homedir12(),
|
|
34689
|
+
function credentialMaskPaths(extraPaths, home = homedir12(), stat11 = (path) => {
|
|
34537
34690
|
try {
|
|
34538
34691
|
const info = lstatSync(path);
|
|
34539
34692
|
return { isDirectory: info.isDirectory() };
|
|
@@ -34552,7 +34705,7 @@ function credentialMaskPaths(extraPaths, home = homedir12(), stat10 = (path) =>
|
|
|
34552
34705
|
if (seen.has(path))
|
|
34553
34706
|
continue;
|
|
34554
34707
|
seen.add(path);
|
|
34555
|
-
const info =
|
|
34708
|
+
const info = stat11(path);
|
|
34556
34709
|
if (!info) {
|
|
34557
34710
|
if (required.has(path))
|
|
34558
34711
|
masks.push({ path, kind: "dir", create: true });
|
|
@@ -34787,7 +34940,7 @@ function readInstallFailure(stateDir) {
|
|
|
34787
34940
|
if (!stateDir)
|
|
34788
34941
|
return void 0;
|
|
34789
34942
|
try {
|
|
34790
|
-
const at = Number.parseInt(
|
|
34943
|
+
const at = Number.parseInt(readFileSync7(installFailureMarker(stateDir), "utf8").trim(), 10);
|
|
34791
34944
|
return Number.isFinite(at) ? at : void 0;
|
|
34792
34945
|
} catch {
|
|
34793
34946
|
return void 0;
|
|
@@ -34810,8 +34963,8 @@ function clearInstallFailure(stateDir) {
|
|
|
34810
34963
|
} catch {
|
|
34811
34964
|
}
|
|
34812
34965
|
}
|
|
34813
|
-
var runSandboxInstallCommand = (command, args) => new Promise((
|
|
34814
|
-
|
|
34966
|
+
var runSandboxInstallCommand = (command, args) => new Promise((resolve49) => {
|
|
34967
|
+
execFile7(command, [...args], {
|
|
34815
34968
|
timeout: INSTALL_TIMEOUT_MS,
|
|
34816
34969
|
maxBuffer: INSTALL_OUTPUT_LIMIT * 2,
|
|
34817
34970
|
// A dpkg prompt on a host with a held conffile would otherwise sit on
|
|
@@ -34820,7 +34973,7 @@ var runSandboxInstallCommand = (command, args) => new Promise((resolve45) => {
|
|
|
34820
34973
|
}, (error, stdout6, stderr) => {
|
|
34821
34974
|
const code = error && "code" in error && typeof error.code === "number" ? error.code : error ? null : 0;
|
|
34822
34975
|
const output = [stdout6, stderr].join("").trim();
|
|
34823
|
-
|
|
34976
|
+
resolve49({ code, output: output || (error ? error.message : "") });
|
|
34824
34977
|
});
|
|
34825
34978
|
});
|
|
34826
34979
|
function lastLine2(output, fallback) {
|
|
@@ -35105,7 +35258,7 @@ function isAllowedAgentModelConfigCategory(category, id) {
|
|
|
35105
35258
|
}
|
|
35106
35259
|
|
|
35107
35260
|
// apps/body/dist/model-config.js
|
|
35108
|
-
import { lstatSync as lstatSync2, readFileSync as
|
|
35261
|
+
import { lstatSync as lstatSync2, readFileSync as readFileSync8 } from "node:fs";
|
|
35109
35262
|
import { basename as basename5, resolve as resolve19 } from "node:path";
|
|
35110
35263
|
|
|
35111
35264
|
// apps/body/dist/transient-provider-error.js
|
|
@@ -35331,7 +35484,7 @@ function credentialedPiCustomProviders(env) {
|
|
|
35331
35484
|
if (!stats.isFile() || stats.isSymbolicLink() || stats.nlink !== 1 || stats.size > 1048576) {
|
|
35332
35485
|
return held;
|
|
35333
35486
|
}
|
|
35334
|
-
const parsed = JSON.parse(
|
|
35487
|
+
const parsed = JSON.parse(readFileSync8(path, "utf8"));
|
|
35335
35488
|
const providers = parsed.providers;
|
|
35336
35489
|
const remember = (name, config) => {
|
|
35337
35490
|
if (typeof name !== "string" || !name.trim() || !config || typeof config !== "object")
|
|
@@ -35564,7 +35717,7 @@ function describeCurrentReleaseOutcome(outcome) {
|
|
|
35564
35717
|
async function retryWhileAdapterReinstalls(run2, options = {}) {
|
|
35565
35718
|
const attempts = options.attempts ?? 12;
|
|
35566
35719
|
const delayMs = options.delayMs ?? 5e3;
|
|
35567
|
-
const sleep4 = options.sleep ?? ((ms) => new Promise((
|
|
35720
|
+
const sleep4 = options.sleep ?? ((ms) => new Promise((resolve49) => setTimeout(resolve49, ms)));
|
|
35568
35721
|
for (let attempt = 1; ; attempt += 1) {
|
|
35569
35722
|
try {
|
|
35570
35723
|
return await run2();
|
|
@@ -36792,7 +36945,7 @@ async function runStartCommand(args, interactiveUi, dependencyOverrides = {}) {
|
|
|
36792
36945
|
|
|
36793
36946
|
// apps/body/dist/connect-command.js
|
|
36794
36947
|
import { spawn as spawn13 } from "node:child_process";
|
|
36795
|
-
import { createHash as createHash9, randomUUID as
|
|
36948
|
+
import { createHash as createHash9, randomUUID as randomUUID8 } from "node:crypto";
|
|
36796
36949
|
import { chmod as chmod7, mkdir as mkdir16, readFile as readFile20, unlink as unlink7, writeFile as writeFile13 } from "node:fs/promises";
|
|
36797
36950
|
import { homedir as homedir15, hostname } from "node:os";
|
|
36798
36951
|
import { dirname as dirname19, resolve as resolve26 } from "node:path";
|
|
@@ -36912,7 +37065,7 @@ async function validateAgentModelSelection(agent, agentEnv, selection) {
|
|
|
36912
37065
|
}
|
|
36913
37066
|
|
|
36914
37067
|
// apps/body/dist/config.js
|
|
36915
|
-
import { accessSync as accessSync3, constants as constants2, existsSync as existsSync8, readFileSync as
|
|
37068
|
+
import { accessSync as accessSync3, constants as constants2, existsSync as existsSync8, readFileSync as readFileSync9 } from "node:fs";
|
|
36916
37069
|
import { basename as basename7, dirname as dirname17, resolve as resolve24 } from "node:path";
|
|
36917
37070
|
function firstExisting2(paths) {
|
|
36918
37071
|
for (const p of paths) {
|
|
@@ -37009,7 +37162,7 @@ function parseEnvFile(path) {
|
|
|
37009
37162
|
const out = {};
|
|
37010
37163
|
if (!existsSync8(path))
|
|
37011
37164
|
return out;
|
|
37012
|
-
const text2 =
|
|
37165
|
+
const text2 = readFileSync9(path, "utf8");
|
|
37013
37166
|
for (const raw of text2.split("\n")) {
|
|
37014
37167
|
const line = raw.trim();
|
|
37015
37168
|
if (!line || line.startsWith("#"))
|
|
@@ -37856,7 +38009,7 @@ async function readMachineId(env = process.env) {
|
|
|
37856
38009
|
if (!/^[0-9a-f-]{32,}$/.test(machineId))
|
|
37857
38010
|
throw new Error("invalid persisted machine id");
|
|
37858
38011
|
} catch {
|
|
37859
|
-
machineId =
|
|
38012
|
+
machineId = randomUUID8();
|
|
37860
38013
|
try {
|
|
37861
38014
|
await mkdir16(configDir, { recursive: true, mode: 448 });
|
|
37862
38015
|
await writeFile13(machineIdPath, `${machineId}
|
|
@@ -38186,7 +38339,7 @@ async function probeReleaseInSubprocess(input) {
|
|
|
38186
38339
|
return { kind: "unavailable", reason: `release ${input.releaseId} has no runnable CLI entrypoint` };
|
|
38187
38340
|
}
|
|
38188
38341
|
const timeoutMs = input.timeoutMs ?? CURRENT_RELEASE_PROBE_TIMEOUT_MS;
|
|
38189
|
-
return new Promise((
|
|
38342
|
+
return new Promise((resolve49) => {
|
|
38190
38343
|
const child = spawn14(input.execPath ?? process.execPath, [entrypoint, UPDATE_PROBE_COMMAND, "--config", input.runtimeConfigPath], { env: input.env ?? process.env, stdio: ["ignore", "pipe", "pipe"] });
|
|
38191
38344
|
let stdout6 = "";
|
|
38192
38345
|
let stderr = "";
|
|
@@ -38196,7 +38349,7 @@ async function probeReleaseInSubprocess(input) {
|
|
|
38196
38349
|
return;
|
|
38197
38350
|
settled = true;
|
|
38198
38351
|
clearTimeout(timer);
|
|
38199
|
-
|
|
38352
|
+
resolve49(outcome);
|
|
38200
38353
|
};
|
|
38201
38354
|
const timer = setTimeout(() => {
|
|
38202
38355
|
child.kill("SIGKILL");
|
|
@@ -38276,12 +38429,12 @@ async function runUpdateProbeCommand(args, options = {}) {
|
|
|
38276
38429
|
}
|
|
38277
38430
|
|
|
38278
38431
|
// apps/body/dist/machine-helper.js
|
|
38279
|
-
import { mkdir as mkdir29, rename as rename13, stat as
|
|
38280
|
-
import { dirname as
|
|
38432
|
+
import { mkdir as mkdir29, rename as rename13, stat as stat10, writeFile as writeFile22 } from "node:fs/promises";
|
|
38433
|
+
import { dirname as dirname31, resolve as resolve47 } from "node:path";
|
|
38281
38434
|
|
|
38282
38435
|
// apps/body/dist/agent-runtime.js
|
|
38283
38436
|
import { homedir as homedir19 } from "node:os";
|
|
38284
|
-
import { dirname as
|
|
38437
|
+
import { dirname as dirname30, join as join23, resolve as resolve45 } from "node:path";
|
|
38285
38438
|
|
|
38286
38439
|
// apps/body/dist/model-availability.js
|
|
38287
38440
|
var SECRET_VALUE = /(?:token|key|secret|password)=?[^\s,;]*/gi;
|
|
@@ -38404,8 +38557,8 @@ async function syncAgentModelCatalog(input) {
|
|
|
38404
38557
|
}
|
|
38405
38558
|
|
|
38406
38559
|
// apps/body/dist/connector-tailscale.js
|
|
38407
|
-
import { execFile as
|
|
38408
|
-
import { randomUUID as
|
|
38560
|
+
import { execFile as execFile8 } from "node:child_process";
|
|
38561
|
+
import { randomUUID as randomUUID9 } from "node:crypto";
|
|
38409
38562
|
import { rm as rm10 } from "node:fs/promises";
|
|
38410
38563
|
import { tmpdir as tmpdir3, userInfo } from "node:os";
|
|
38411
38564
|
import { join as join14 } from "node:path";
|
|
@@ -38415,10 +38568,10 @@ var LOGIN_URL = /https:\/\/login\.tailscale\.com\/[A-Za-z0-9_/-]+/u;
|
|
|
38415
38568
|
function clipped(value) {
|
|
38416
38569
|
return value.length <= OUTPUT_LIMIT ? value : value.slice(value.length - OUTPUT_LIMIT);
|
|
38417
38570
|
}
|
|
38418
|
-
var runTailscaleCommand = (command, args) => new Promise((
|
|
38419
|
-
|
|
38571
|
+
var runTailscaleCommand = (command, args) => new Promise((resolve49) => {
|
|
38572
|
+
execFile8(command, [...args], { timeout: COMMAND_TIMEOUT_MS, maxBuffer: OUTPUT_LIMIT * 2 }, (error, stdout6, stderr) => {
|
|
38420
38573
|
const code = error && "code" in error && typeof error.code === "number" ? error.code : error ? null : 0;
|
|
38421
|
-
|
|
38574
|
+
resolve49({ code, stdout: clipped(stdout6), stderr: clipped(stderr) });
|
|
38422
38575
|
});
|
|
38423
38576
|
});
|
|
38424
38577
|
function loginUrlFrom(status, output) {
|
|
@@ -38495,7 +38648,7 @@ async function ensureInstalled(run2, onProgress, platform) {
|
|
|
38495
38648
|
}
|
|
38496
38649
|
};
|
|
38497
38650
|
}
|
|
38498
|
-
const script = join14(tmpdir3(), `beeline-tailscale-install-${process.pid}-${
|
|
38651
|
+
const script = join14(tmpdir3(), `beeline-tailscale-install-${process.pid}-${randomUUID9()}.sh`);
|
|
38499
38652
|
const steps2 = [
|
|
38500
38653
|
step2("Tailscale installed", "running", {
|
|
38501
38654
|
command: "curl -fsSL https://tailscale.com/install.sh"
|
|
@@ -38978,16 +39131,16 @@ function describe2(error) {
|
|
|
38978
39131
|
}
|
|
38979
39132
|
|
|
38980
39133
|
// apps/body/dist/room-runtime.js
|
|
38981
|
-
import { execFile as
|
|
39134
|
+
import { execFile as execFile16 } from "node:child_process";
|
|
38982
39135
|
import { createHash as createHash14 } from "node:crypto";
|
|
38983
39136
|
import { existsSync as existsSync10, mkdirSync as mkdirSync3 } from "node:fs";
|
|
38984
|
-
import { mkdir as mkdir27, readdir as
|
|
38985
|
-
import { dirname as
|
|
38986
|
-
import { promisify as
|
|
39137
|
+
import { lstat as lstat7, mkdir as mkdir27, readdir as readdir11, realpath as realpath3, rm as rm17 } from "node:fs/promises";
|
|
39138
|
+
import { dirname as dirname28, relative as relative4, resolve as resolve40, sep as sep3 } from "node:path";
|
|
39139
|
+
import { promisify as promisify11 } from "node:util";
|
|
38987
39140
|
|
|
38988
39141
|
// apps/body/dist/grant-runner.js
|
|
38989
|
-
import { execFile as
|
|
38990
|
-
import { createHash as createHash11, randomBytes as randomBytes9, randomUUID as
|
|
39142
|
+
import { execFile as execFile9 } from "node:child_process";
|
|
39143
|
+
import { createHash as createHash11, randomBytes as randomBytes9, randomUUID as randomUUID10 } from "node:crypto";
|
|
38991
39144
|
import { chmod as chmod8, mkdir as mkdir17, readFile as readFile22, readdir as readdir6, rename as rename9, rm as rm11, rmdir, stat as stat7, writeFile as writeFile15 } from "node:fs/promises";
|
|
38992
39145
|
import { createServer as createServer3 } from "node:http";
|
|
38993
39146
|
import { dirname as dirname21, resolve as resolve28 } from "node:path";
|
|
@@ -39168,7 +39321,7 @@ var GrantCommandRunner = class {
|
|
|
39168
39321
|
const sandboxMarker = runsOnHost ? void 0 : `[beeline-sandbox-started:${randomBytes9(16).toString("hex")}]`;
|
|
39169
39322
|
const spawn15 = runsOnHost ? { command: argv[0], args: argv.slice(1) } : roomSandboxCommand(policy, room.cwd, argv, sandboxMarker);
|
|
39170
39323
|
const outcome = await new Promise((resolveRun) => {
|
|
39171
|
-
const child =
|
|
39324
|
+
const child = execFile9(spawn15.command, spawn15.args, {
|
|
39172
39325
|
cwd: room.cwd,
|
|
39173
39326
|
env,
|
|
39174
39327
|
timeout: this.options.timeoutMs ?? GRANT_COMMAND_TIMEOUT_MS,
|
|
@@ -39538,13 +39691,13 @@ var TurnUsageAccumulator = class {
|
|
|
39538
39691
|
};
|
|
39539
39692
|
|
|
39540
39693
|
// apps/body/dist/server-command-intake.js
|
|
39541
|
-
import { randomUUID as
|
|
39694
|
+
import { randomUUID as randomUUID11 } from "node:crypto";
|
|
39542
39695
|
import { mkdir as mkdir18, writeFile as writeFile16 } from "node:fs/promises";
|
|
39543
39696
|
import { writeFileSync as writeFileSync4 } from "node:fs";
|
|
39544
39697
|
import { tmpdir as tmpdir4 } from "node:os";
|
|
39545
39698
|
import { dirname as dirname22, join as join16 } from "node:path";
|
|
39546
39699
|
var CommandExecutionContext = class {
|
|
39547
|
-
generationId =
|
|
39700
|
+
generationId = randomUUID11();
|
|
39548
39701
|
path;
|
|
39549
39702
|
current;
|
|
39550
39703
|
constructor(root) {
|
|
@@ -39702,11 +39855,11 @@ async function runServerCommandIntake(options) {
|
|
|
39702
39855
|
if (attempt === 3)
|
|
39703
39856
|
throw error;
|
|
39704
39857
|
const waitMs = Math.max(250 * 2 ** attempt, error instanceof DaemonApiError ? error.retryAfterMs ?? 0 : 0);
|
|
39705
|
-
await new Promise((
|
|
39858
|
+
await new Promise((resolve49) => {
|
|
39706
39859
|
const done = () => {
|
|
39707
39860
|
clearTimeout(timer);
|
|
39708
39861
|
signal?.removeEventListener("abort", done);
|
|
39709
|
-
|
|
39862
|
+
resolve49();
|
|
39710
39863
|
};
|
|
39711
39864
|
const timer = setTimeout(done, waitMs);
|
|
39712
39865
|
signal?.addEventListener("abort", done, { once: true });
|
|
@@ -39797,11 +39950,11 @@ async function runServerCommandIntake(options) {
|
|
|
39797
39950
|
}
|
|
39798
39951
|
}
|
|
39799
39952
|
options.onPoll?.();
|
|
39800
|
-
const reconcile = await new Promise((
|
|
39953
|
+
const reconcile = await new Promise((resolve49) => {
|
|
39801
39954
|
const done = (needed) => {
|
|
39802
39955
|
signal?.removeEventListener("abort", aborted);
|
|
39803
39956
|
wake = void 0;
|
|
39804
|
-
|
|
39957
|
+
resolve49(needed);
|
|
39805
39958
|
};
|
|
39806
39959
|
const aborted = () => done(false);
|
|
39807
39960
|
wake = done;
|
|
@@ -39841,13 +39994,13 @@ async function runServerCommandIntake(options) {
|
|
|
39841
39994
|
}
|
|
39842
39995
|
|
|
39843
39996
|
// apps/body/dist/monolith-corner-turn.js
|
|
39844
|
-
import { execFile as
|
|
39997
|
+
import { execFile as execFile14 } from "node:child_process";
|
|
39845
39998
|
import { createHash as createHash13 } from "node:crypto";
|
|
39846
39999
|
import { existsSync as existsSync9 } from "node:fs";
|
|
39847
40000
|
import { mkdir as mkdir26, readFile as readFile30, writeFile as writeFile20 } from "node:fs/promises";
|
|
39848
40001
|
import { homedir as homedir18, hostname as hostname3 } from "node:os";
|
|
39849
|
-
import { dirname as dirname26, join as
|
|
39850
|
-
import { promisify as
|
|
40002
|
+
import { dirname as dirname26, join as join21, resolve as resolve38 } from "node:path";
|
|
40003
|
+
import { promisify as promisify9 } from "node:util";
|
|
39851
40004
|
|
|
39852
40005
|
// apps/body/dist/agent-command-catalog.js
|
|
39853
40006
|
function agentCommandCatalogPublisher(input) {
|
|
@@ -40497,13 +40650,13 @@ async function hasCornerPrepareScript(worktreePath) {
|
|
|
40497
40650
|
}
|
|
40498
40651
|
|
|
40499
40652
|
// apps/body/dist/pi-mcp-bridge.js
|
|
40500
|
-
import { execFile as
|
|
40653
|
+
import { execFile as execFile10 } from "node:child_process";
|
|
40501
40654
|
import { mkdtemp as mkdtemp2, mkdir as mkdir20, readFile as readFile26, rm as rm12, unlink as unlink8 } from "node:fs/promises";
|
|
40502
40655
|
import { tmpdir as tmpdir5 } from "node:os";
|
|
40503
40656
|
import { resolve as resolve30 } from "node:path";
|
|
40504
|
-
import { promisify as
|
|
40657
|
+
import { promisify as promisify6 } from "node:util";
|
|
40505
40658
|
var PI_MCP_BRIDGE_FILENAME = "beeline-mcp-bridge.js";
|
|
40506
|
-
var
|
|
40659
|
+
var execFileAsync6 = promisify6(execFile10);
|
|
40507
40660
|
var nativeMcpProbes = /* @__PURE__ */ new Map();
|
|
40508
40661
|
async function piHasNativeMcp(command, env) {
|
|
40509
40662
|
const path = env?.PATH ?? process.env.PATH ?? "";
|
|
@@ -40513,7 +40666,7 @@ async function piHasNativeMcp(command, env) {
|
|
|
40513
40666
|
probe = (async () => {
|
|
40514
40667
|
const home = await mkdtemp2(resolve30(tmpdir5(), "beeline-pi-mcp-probe-"));
|
|
40515
40668
|
try {
|
|
40516
|
-
const { stdout: stdout6 } = await
|
|
40669
|
+
const { stdout: stdout6 } = await execFileAsync6(command, ["mcp", "list", "--json"], {
|
|
40517
40670
|
cwd: home,
|
|
40518
40671
|
timeout: 1200,
|
|
40519
40672
|
env: { PATH: path, HOME: home, PI_CODING_AGENT_DIR: home, PI_OFFLINE: "1" }
|
|
@@ -40810,7 +40963,7 @@ export default async function (pi) {
|
|
|
40810
40963
|
`;
|
|
40811
40964
|
|
|
40812
40965
|
// apps/body/dist/corner-branch-sync.js
|
|
40813
|
-
import { execFile as
|
|
40966
|
+
import { execFile as execFile11 } from "node:child_process";
|
|
40814
40967
|
import { access as access2, readFile as readFile27 } from "node:fs/promises";
|
|
40815
40968
|
import { resolve as resolve31 } from "node:path";
|
|
40816
40969
|
var CORNER_GIT_SYNC_TIMEOUT_MS = 12e4;
|
|
@@ -40818,7 +40971,7 @@ var CORNER_GIT_SYNC_KILL_GRACE_MS = 1e3;
|
|
|
40818
40971
|
var CornerGitSyncInterruptedError = class extends Error {
|
|
40819
40972
|
};
|
|
40820
40973
|
async function syncCornerBranch(input) {
|
|
40821
|
-
const
|
|
40974
|
+
const git2 = async (args, cleanup = false) => {
|
|
40822
40975
|
const controller = new AbortController();
|
|
40823
40976
|
const signal = input.signal && !cleanup ? AbortSignal.any([input.signal, controller.signal]) : controller.signal;
|
|
40824
40977
|
const timer = setTimeout(() => controller.abort(), CORNER_GIT_SYNC_TIMEOUT_MS);
|
|
@@ -40826,11 +40979,11 @@ async function syncCornerBranch(input) {
|
|
|
40826
40979
|
try {
|
|
40827
40980
|
if (signal.aborted)
|
|
40828
40981
|
throw interrupted();
|
|
40829
|
-
return await new Promise((
|
|
40982
|
+
return await new Promise((resolve49, reject) => {
|
|
40830
40983
|
let killTimer;
|
|
40831
40984
|
let stdout6 = "";
|
|
40832
40985
|
let failure = null;
|
|
40833
|
-
const child = input.git ? void 0 :
|
|
40986
|
+
const child = input.git ? void 0 : execFile11("git", ["-C", input.worktreePath, ...args], {
|
|
40834
40987
|
...input.env ? { env: input.env } : {},
|
|
40835
40988
|
signal,
|
|
40836
40989
|
maxBuffer: 4 * 1024 * 1024
|
|
@@ -40860,10 +41013,10 @@ async function syncCornerBranch(input) {
|
|
|
40860
41013
|
else if (failure)
|
|
40861
41014
|
reject(failure);
|
|
40862
41015
|
else
|
|
40863
|
-
|
|
41016
|
+
resolve49(stdout6);
|
|
40864
41017
|
});
|
|
40865
41018
|
else
|
|
40866
|
-
input.git(args).then(
|
|
41019
|
+
input.git(args).then(resolve49, reject).finally(cleanup2);
|
|
40867
41020
|
});
|
|
40868
41021
|
} finally {
|
|
40869
41022
|
clearTimeout(timer);
|
|
@@ -40873,10 +41026,10 @@ async function syncCornerBranch(input) {
|
|
|
40873
41026
|
const gitDir = resolve31(input.worktreePath, marker.startsWith("gitdir: ") ? marker.slice(8).trim() : ".git");
|
|
40874
41027
|
for (const directory of ["rebase-merge", "rebase-apply"]) {
|
|
40875
41028
|
if (await access2(resolve31(gitDir, directory)).then(() => true, () => false))
|
|
40876
|
-
await
|
|
41029
|
+
await git2(["rebase", "--abort"], true);
|
|
40877
41030
|
}
|
|
40878
41031
|
const remoteRef = `refs/remotes/origin/${input.featureBranch}`;
|
|
40879
|
-
const fetched = await
|
|
41032
|
+
const fetched = await git2([
|
|
40880
41033
|
"fetch",
|
|
40881
41034
|
"origin",
|
|
40882
41035
|
`+refs/heads/${input.featureBranch}:${remoteRef}`
|
|
@@ -40888,31 +41041,31 @@ async function syncCornerBranch(input) {
|
|
|
40888
41041
|
});
|
|
40889
41042
|
if (!fetched)
|
|
40890
41043
|
return "unchanged";
|
|
40891
|
-
const remote = (await
|
|
41044
|
+
const remote = (await git2(["rev-parse", remoteRef])).trim();
|
|
40892
41045
|
if (!remote)
|
|
40893
41046
|
throw new Error(`fetched corner branch has no remote ref: ${remoteRef}`);
|
|
40894
|
-
const local = (await
|
|
41047
|
+
const local = (await git2(["rev-parse", "HEAD"])).trim();
|
|
40895
41048
|
if (local === remote)
|
|
40896
41049
|
return "unchanged";
|
|
40897
|
-
if (await contains(
|
|
41050
|
+
if (await contains(git2, local, remote))
|
|
40898
41051
|
return "unchanged";
|
|
40899
|
-
const behind = await contains(
|
|
41052
|
+
const behind = await contains(git2, remote, local);
|
|
40900
41053
|
try {
|
|
40901
|
-
await
|
|
41054
|
+
await git2(behind ? ["merge", "--ff-only", remote] : ["rebase", remote]);
|
|
40902
41055
|
return behind ? "fast-forwarded" : "rebased";
|
|
40903
41056
|
} catch (error) {
|
|
40904
|
-
await
|
|
41057
|
+
await git2(["rebase", "--abort"], true).catch((error2) => {
|
|
40905
41058
|
if (error2 instanceof CornerGitSyncInterruptedError)
|
|
40906
41059
|
throw error2;
|
|
40907
41060
|
});
|
|
40908
41061
|
if (error instanceof CornerGitSyncInterruptedError)
|
|
40909
41062
|
throw error;
|
|
40910
|
-
await
|
|
41063
|
+
await git2(["reset", "--hard", remote]);
|
|
40911
41064
|
return "realigned";
|
|
40912
41065
|
}
|
|
40913
41066
|
}
|
|
40914
|
-
async function contains(
|
|
40915
|
-
return
|
|
41067
|
+
async function contains(git2, head, ancestor) {
|
|
41068
|
+
return git2(["merge-base", "--is-ancestor", ancestor, head]).then(() => true, (error) => {
|
|
40916
41069
|
if (error instanceof CornerGitSyncInterruptedError)
|
|
40917
41070
|
throw error;
|
|
40918
41071
|
return false;
|
|
@@ -41066,6 +41219,7 @@ var AGENT_SURFACE_TOOL_NAMES = [
|
|
|
41066
41219
|
"pr_checks_status",
|
|
41067
41220
|
"post_artifact",
|
|
41068
41221
|
"write_scratch_file",
|
|
41222
|
+
"scratch_status",
|
|
41069
41223
|
"fetch_image",
|
|
41070
41224
|
"connect_app"
|
|
41071
41225
|
];
|
|
@@ -41138,11 +41292,11 @@ function beelineAgentMcpServer(config, api, context) {
|
|
|
41138
41292
|
{ name: "BEELINE_DAEMON_ROOM_ID", value: context.roomId },
|
|
41139
41293
|
{ name: "BEELINE_DAEMON_WORKSPACE_ID", value: context.workspaceId },
|
|
41140
41294
|
...context.cornerId ? [{ name: "BEELINE_DAEMON_CORNER_ID", value: context.cornerId }] : [],
|
|
41141
|
-
...context.agentMayCloseCorner ? [{ name: "BEELINE_CORNER_AGENT_CLOSE", value: "1" }] : [],
|
|
41142
41295
|
...context.reviewer ? [{ name: "BEELINE_CORNER_REVIEWER", value: "1" }] : [],
|
|
41143
41296
|
...context.cornerId && context.repositoryBacked ? [{ name: "BEELINE_CORNER_REPOSITORY", value: "1" }] : [],
|
|
41144
41297
|
...context.attachRoot ? [{ name: "BEELINE_ATTACH_ROOT", value: context.attachRoot }] : [],
|
|
41145
41298
|
...context.attachScratchRoot ? [{ name: "BEELINE_ATTACH_SCRATCH_ROOT", value: context.attachScratchRoot }] : [],
|
|
41299
|
+
...context.cornerScratchRoot ? [{ name: "BEELINE_CORNER_SCRATCH_ROOT", value: context.cornerScratchRoot }] : [],
|
|
41146
41300
|
...context.grantRunner ? [
|
|
41147
41301
|
{ name: "BEELINE_GRANT_RUNNER_URL", value: context.grantRunner.url },
|
|
41148
41302
|
{ name: "BEELINE_GRANT_RUNNER_TOKEN", value: context.grantRunner.token }
|
|
@@ -41172,6 +41326,90 @@ function readOnlyMcpServer(config, cwd, agentMemoryDir) {
|
|
|
41172
41326
|
};
|
|
41173
41327
|
}
|
|
41174
41328
|
|
|
41329
|
+
// apps/body/dist/scratch-lifecycle.js
|
|
41330
|
+
import { execFile as execFile12 } from "node:child_process";
|
|
41331
|
+
import { lstat as lstat4, readdir as readdir7, rmdir as rmdir2, rm as rm13, stat as stat8, unlink as unlink9 } from "node:fs/promises";
|
|
41332
|
+
import { join as join18, resolve as resolve33 } from "node:path";
|
|
41333
|
+
import { promisify as promisify7 } from "node:util";
|
|
41334
|
+
var execFileAsync7 = promisify7(execFile12);
|
|
41335
|
+
var CORNER_SCRATCH_BUDGET_BYTES = 5 * 1024 ** 3;
|
|
41336
|
+
var CORNER_SCRATCH_TTL_MS = 14 * 24 * 60 * 6e4;
|
|
41337
|
+
var SHARED_MODEL_CACHE_BUDGET_BYTES = 32 * 1024 ** 3;
|
|
41338
|
+
var MODEL_CACHE_IDLE_MS = 24 * 60 * 6e4;
|
|
41339
|
+
async function allocatedDirectoryBytes(path) {
|
|
41340
|
+
if (!await lstat4(path).catch(() => void 0))
|
|
41341
|
+
return 0;
|
|
41342
|
+
const output = await execFileAsync7("du", ["-s", "-B1", "--", path], {
|
|
41343
|
+
maxBuffer: 1024 * 1024
|
|
41344
|
+
}).then((result) => result.stdout);
|
|
41345
|
+
const bytes = Number(output.split(/\s+/)[0]);
|
|
41346
|
+
if (!Number.isSafeInteger(bytes) || bytes < 0)
|
|
41347
|
+
throw new Error("scratch usage could not be measured");
|
|
41348
|
+
return bytes;
|
|
41349
|
+
}
|
|
41350
|
+
function scratchBudgetMessage(usage2, budget = CORNER_SCRATCH_BUDGET_BYTES) {
|
|
41351
|
+
const mib = (bytes) => Math.ceil(bytes / 1024 ** 2);
|
|
41352
|
+
return `Scratch ${mib(usage2)} / ${mib(budget)} MiB; files idle for 14 days expire. Use scratch_status and your shell to inspect, update or delete files. ${usage2 > budget ? "OVER BUDGET: remove files before writing more." : ""}`.trim();
|
|
41353
|
+
}
|
|
41354
|
+
function scratchGrowthExceedsBudget(usage2, atTurnStart, budget = CORNER_SCRATCH_BUDGET_BYTES) {
|
|
41355
|
+
return usage2 > budget && usage2 > atTurnStart;
|
|
41356
|
+
}
|
|
41357
|
+
async function sweepStaleCornerScratch(root, now2 = Date.now(), ttlMs = CORNER_SCRATCH_TTL_MS) {
|
|
41358
|
+
const cutoff = now2 - ttlMs;
|
|
41359
|
+
let files = 0;
|
|
41360
|
+
let bytes = 0;
|
|
41361
|
+
const visit = async (dir, top) => {
|
|
41362
|
+
for (const entry of await readdir7(dir, { withFileTypes: true }).catch(() => [])) {
|
|
41363
|
+
if (top && (entry.name === "agent-home" || entry.name === ".git"))
|
|
41364
|
+
continue;
|
|
41365
|
+
const path = join18(dir, entry.name);
|
|
41366
|
+
const info = await lstat4(path).catch(() => void 0);
|
|
41367
|
+
if (!info || info.isSymbolicLink())
|
|
41368
|
+
continue;
|
|
41369
|
+
if (info.isDirectory()) {
|
|
41370
|
+
await visit(path, false);
|
|
41371
|
+
if (!top)
|
|
41372
|
+
await rmdir2(path).catch(() => void 0);
|
|
41373
|
+
} else if (info.isFile() && info.mtimeMs < cutoff) {
|
|
41374
|
+
await unlink9(path);
|
|
41375
|
+
files++;
|
|
41376
|
+
bytes += info.size;
|
|
41377
|
+
}
|
|
41378
|
+
}
|
|
41379
|
+
};
|
|
41380
|
+
if ((await lstat4(root).catch(() => void 0))?.isDirectory())
|
|
41381
|
+
await visit(resolve33(root), true);
|
|
41382
|
+
return { files, bytes };
|
|
41383
|
+
}
|
|
41384
|
+
async function pruneSharedModelCache(root, now2 = Date.now(), budget = SHARED_MODEL_CACHE_BUDGET_BYTES) {
|
|
41385
|
+
let usage2 = await allocatedDirectoryBytes(root);
|
|
41386
|
+
if (usage2 <= budget)
|
|
41387
|
+
return [];
|
|
41388
|
+
const candidates = [];
|
|
41389
|
+
for (const parent of [join18(root, "hub"), root]) {
|
|
41390
|
+
for (const entry of await readdir7(parent, { withFileTypes: true }).catch(() => [])) {
|
|
41391
|
+
const eligible = parent === root ? entry.name === "xet" : /^(?:models|datasets|spaces)--/.test(entry.name);
|
|
41392
|
+
if (!eligible || !entry.isDirectory())
|
|
41393
|
+
continue;
|
|
41394
|
+
const path = join18(parent, entry.name);
|
|
41395
|
+
const info = await stat8(path);
|
|
41396
|
+
if (info.mtimeMs > now2 - MODEL_CACHE_IDLE_MS)
|
|
41397
|
+
continue;
|
|
41398
|
+
candidates.push({ path, usedAt: info.mtimeMs });
|
|
41399
|
+
}
|
|
41400
|
+
}
|
|
41401
|
+
candidates.sort((a2, b) => a2.usedAt - b.usedAt || a2.path.localeCompare(b.path));
|
|
41402
|
+
const removed = [];
|
|
41403
|
+
for (const item of candidates) {
|
|
41404
|
+
if (usage2 <= budget)
|
|
41405
|
+
break;
|
|
41406
|
+
await rm13(item.path, { recursive: true, force: true });
|
|
41407
|
+
usage2 = await allocatedDirectoryBytes(root);
|
|
41408
|
+
removed.push(item.path);
|
|
41409
|
+
}
|
|
41410
|
+
return removed;
|
|
41411
|
+
}
|
|
41412
|
+
|
|
41175
41413
|
// apps/body/dist/institutional-context.js
|
|
41176
41414
|
import { performance as performance2 } from "node:perf_hooks";
|
|
41177
41415
|
var INSTITUTIONAL_CONTEXT_TIMEOUT_MS = 500;
|
|
@@ -41220,16 +41458,16 @@ async function awaitInstitutionalContext(fetch2, log2 = console.warn, budgetMs =
|
|
|
41220
41458
|
}
|
|
41221
41459
|
|
|
41222
41460
|
// apps/body/dist/codegraph.js
|
|
41223
|
-
import { execFile as
|
|
41461
|
+
import { execFile as execFile13 } from "node:child_process";
|
|
41224
41462
|
import { access as access3, appendFile, mkdir as mkdir21, readFile as readFile28 } from "node:fs/promises";
|
|
41225
|
-
import { dirname as dirname23, isAbsolute as isAbsolute3, resolve as
|
|
41226
|
-
import { promisify as
|
|
41227
|
-
var
|
|
41463
|
+
import { dirname as dirname23, isAbsolute as isAbsolute3, resolve as resolve34 } from "node:path";
|
|
41464
|
+
import { promisify as promisify8 } from "node:util";
|
|
41465
|
+
var execFileAsync8 = promisify8(execFile13);
|
|
41228
41466
|
var CODEGRAPH_MCP_SERVER_NAME = "codegraph";
|
|
41229
41467
|
var CODEGRAPH_INDEX_PATH = ".codegraph/codegraph.db";
|
|
41230
41468
|
var CODEGRAPH_PREPARE_TIMEOUT_MS = 12e4;
|
|
41231
41469
|
function codegraphIndexDirectory(cwd) {
|
|
41232
|
-
return
|
|
41470
|
+
return resolve34(cwd, dirname23(CODEGRAPH_INDEX_PATH));
|
|
41233
41471
|
}
|
|
41234
41472
|
function codegraphMcpServer(config, cwd, options) {
|
|
41235
41473
|
if (!config.codegraphCommand)
|
|
@@ -41237,7 +41475,7 @@ function codegraphMcpServer(config, cwd, options) {
|
|
|
41237
41475
|
return {
|
|
41238
41476
|
name: CODEGRAPH_MCP_SERVER_NAME,
|
|
41239
41477
|
command: config.codegraphCommand,
|
|
41240
|
-
args: ["serve", "--mcp", "--path",
|
|
41478
|
+
args: ["serve", "--mcp", "--path", resolve34(cwd), ...options.readonly ? ["--no-watch"] : []],
|
|
41241
41479
|
env: [
|
|
41242
41480
|
{ name: "CODEGRAPH_TELEMETRY", value: "0" },
|
|
41243
41481
|
// One MCP child per harness session is easier to contain than a daemon
|
|
@@ -41251,25 +41489,25 @@ function codegraphFingerprintServers(config, servers, mounted = Boolean(config.c
|
|
|
41251
41489
|
}
|
|
41252
41490
|
async function isGitWorktree(cwd) {
|
|
41253
41491
|
try {
|
|
41254
|
-
const { stdout: stdout6 } = await
|
|
41492
|
+
const { stdout: stdout6 } = await execFileAsync8("git", ["rev-parse", "--show-toplevel"], {
|
|
41255
41493
|
cwd,
|
|
41256
41494
|
timeout: 1e4
|
|
41257
41495
|
});
|
|
41258
|
-
return
|
|
41496
|
+
return resolve34(stdout6.trim()) === resolve34(cwd);
|
|
41259
41497
|
} catch {
|
|
41260
41498
|
return false;
|
|
41261
41499
|
}
|
|
41262
41500
|
}
|
|
41263
41501
|
async function excludeIndexFromGitStatus(cwd) {
|
|
41264
41502
|
try {
|
|
41265
|
-
const { stdout: stdout6 } = await
|
|
41503
|
+
const { stdout: stdout6 } = await execFileAsync8("git", ["rev-parse", "--git-path", "info/exclude"], {
|
|
41266
41504
|
cwd,
|
|
41267
41505
|
timeout: 1e4
|
|
41268
41506
|
});
|
|
41269
41507
|
const gitPath = stdout6.trim();
|
|
41270
41508
|
if (!gitPath)
|
|
41271
41509
|
return;
|
|
41272
|
-
const path = isAbsolute3(gitPath) ? gitPath :
|
|
41510
|
+
const path = isAbsolute3(gitPath) ? gitPath : resolve34(cwd, gitPath);
|
|
41273
41511
|
await mkdir21(dirname23(path), { recursive: true });
|
|
41274
41512
|
const existing = await readFile28(path, "utf8").catch(() => "");
|
|
41275
41513
|
if (existing.split("\n").includes(".codegraph/"))
|
|
@@ -41284,11 +41522,11 @@ async function prepareCodegraphIndex(config, cwd) {
|
|
|
41284
41522
|
if (!command || !await isGitWorktree(cwd))
|
|
41285
41523
|
return false;
|
|
41286
41524
|
await excludeIndexFromGitStatus(cwd);
|
|
41287
|
-
const indexPath =
|
|
41525
|
+
const indexPath = resolve34(cwd, CODEGRAPH_INDEX_PATH);
|
|
41288
41526
|
const indexed = await access3(indexPath).then(() => true, () => false);
|
|
41289
41527
|
const args = indexed ? ["sync", "--quiet", cwd] : ["init", "--yes", cwd];
|
|
41290
41528
|
try {
|
|
41291
|
-
await
|
|
41529
|
+
await execFileAsync8(command, args, {
|
|
41292
41530
|
cwd,
|
|
41293
41531
|
env: { ...process.env, CODEGRAPH_TELEMETRY: "0", CODEGRAPH_NO_DAEMON: "1" },
|
|
41294
41532
|
timeout: CODEGRAPH_PREPARE_TIMEOUT_MS,
|
|
@@ -41304,7 +41542,7 @@ async function prepareCodegraphIndex(config, cwd) {
|
|
|
41304
41542
|
// apps/body/dist/monolith-room-turn.js
|
|
41305
41543
|
import { mkdir as mkdir23, writeFile as writeFile18 } from "node:fs/promises";
|
|
41306
41544
|
import { homedir as homedir17, hostname as hostname2 } from "node:os";
|
|
41307
|
-
import { dirname as dirname24, join as
|
|
41545
|
+
import { dirname as dirname24, join as join19 } from "node:path";
|
|
41308
41546
|
|
|
41309
41547
|
// packages/api-contract/dist/scheduled-prompts.js
|
|
41310
41548
|
var SCHEDULE_SCHEDULER_NAME = "Beeline Scheduler";
|
|
@@ -41408,6 +41646,7 @@ function cornerHasRepositoryWork(brief) {
|
|
|
41408
41646
|
var CORNER_RUNTIME_AUTHOR_CONTRACT = `The current brief's spec \u2014 stories, criteria, non-goals, risks \u2014 defines scope and done. The human approval quote wins any conflict. The short objective is navigation-only, never scope.
|
|
41409
41647
|
Meet every story; respect every non-goal and risk.
|
|
41410
41648
|
Before any code or build action, the brief must hold this ask's outline; opening and prompting inside it is not that outline. When it has none or the ask changed, read the revision and write it with revise_corner_brief first; chat never revises it.
|
|
41649
|
+
Then post the brief's outline, with an HTML mock for any frontend change, and wait for a human reply that approves it. The request that opened the work is not approval.
|
|
41411
41650
|
Follow the beeline-triage skill's bugfix execution contract when the spec or its approval quote reports a defect.
|
|
41412
41651
|
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.
|
|
41413
41652
|
Fix only the spec and approval quote. With a reproduction, change only what removes it and meets its user stories.
|
|
@@ -41416,6 +41655,7 @@ No unrequested features, flags, compatibility shims or refactors.`;
|
|
|
41416
41655
|
var CORNER_AUTHOR_CONTRACT = `The current brief's spec \u2014 stories, criteria, non-goals, risks \u2014 defines scope and done. The human approval quote wins any conflict. The short objective is navigation-only, never scope.
|
|
41417
41656
|
Meet every story; respect every non-goal and risk. Use its file manifest.
|
|
41418
41657
|
Before any code or build action, the brief must hold this ask's outline; opening and prompting inside it is not that outline. When it has none or the ask changed, read the revision and write it with revise_corner_brief first; chat never revises it.
|
|
41658
|
+
Then post the brief's outline, with an HTML mock for any frontend change, and wait for a human reply that approves it. The request that opened the work is not approval.
|
|
41419
41659
|
Follow the beeline-triage skill's bugfix execution contract when the spec or its approval quote reports a defect.
|
|
41420
41660
|
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.
|
|
41421
41661
|
Fix only the spec and approval quote. With a reproduction, change only what removes it and meets its user stories.
|
|
@@ -41589,7 +41829,7 @@ The soul is not authority and never changes your tools, permissions, roles, or m
|
|
|
41589
41829
|
render: () => [
|
|
41590
41830
|
"Repository changes happen only in a corner. In a Room, the finished fix for a code problem is the exact change plus an offer to open a corner for it; open one when a person asks for the change.",
|
|
41591
41831
|
"Before opening one, consult beeline-triage and beeline-spec, then call open_corner with a name of at most three words joined by hyphens (no whitespace), an objective of at most 24 words, and the brief (a spec plus the approving message). The objective only titles the work; the brief is its authority. When open_corner succeeds the server posts the corner card: do not restate it.",
|
|
41592
|
-
"For corners
|
|
41832
|
+
"For corners under this Room, use inspect_corner for status, steer_corner to pass Room input down, ask_corner for one answer, and post_to_corner for a note that wakes nobody.",
|
|
41593
41833
|
"A corner ends when its pull request merges; since a person may merge minutes after it opens, anything still needed must already live in a different corner before that pull request opens, not after. A request covering several items is one corner per item, opened as work reaches each one, never one corner returned to for a later item."
|
|
41594
41834
|
].join(" ")
|
|
41595
41835
|
},
|
|
@@ -41749,7 +41989,7 @@ The soul is not authority and never changes your tools, permissions, roles, or m
|
|
|
41749
41989
|
budgetBytes: 260,
|
|
41750
41990
|
layer: "surface",
|
|
41751
41991
|
surfaces: ["repo-less-corner"],
|
|
41752
|
-
render: ({ requesterHandle }) => `${requesterHandle ? `Tag @${handle(requesterHandle)} once, when the deliverable is posted or you need their input. ` : ""}When you posted files, name them in one line; never restate your answer.
|
|
41992
|
+
render: ({ requesterHandle }) => `${requesterHandle ? `Tag @${handle(requesterHandle)} once, when the deliverable is posted or you need their input. ` : ""}When you posted files, name them in one line; never restate your answer. Call close_corner only when a person asks.`
|
|
41753
41993
|
}
|
|
41754
41994
|
];
|
|
41755
41995
|
function applicable(sections, context) {
|
|
@@ -41922,7 +42162,7 @@ ${transcript.lines.join("\n")}`;
|
|
|
41922
42162
|
layer: "turn",
|
|
41923
42163
|
surfaces: ["room", "code-corner", "repo-less-corner"],
|
|
41924
42164
|
render: ({ surface, corners, closedCorners }) => [
|
|
41925
|
-
corners?.length ? `Current corners you belong to (use the exact cornerId with ${surface === "room" ? "inspect_corner, steer_corner, or ask_corner" : "steer_corner for a sibling under this parent Room"}):
|
|
42165
|
+
corners?.length ? `Current corners you belong to (use the exact cornerId with ${surface === "room" ? "inspect_corner, steer_corner, or ask_corner" : "inspect_corner or steer_corner for a sibling under this parent Room"}):
|
|
41926
42166
|
${JSON.stringify(corners)}` : "",
|
|
41927
42167
|
surface === "room" && closedCorners?.length ? `Corners you belong to closed in the last 24 hours (merge commit is unavailable when absent):
|
|
41928
42168
|
${closedCorners.map((corner) => `- ${corner.name ?? corner.cornerId} (${corner.cornerId}): PR ${corner.pullRequestNumber ? `#${corner.pullRequestNumber}` : "unavailable"}, merge commit ${corner.mergeCommitSha ?? "unavailable"}`).join("\n")}` : ""
|
|
@@ -41989,8 +42229,8 @@ function assembleTurnPrompt(context) {
|
|
|
41989
42229
|
}
|
|
41990
42230
|
|
|
41991
42231
|
// apps/body/dist/turn-trace.js
|
|
41992
|
-
import { appendFile as appendFile2, mkdir as mkdir22, readdir as
|
|
41993
|
-
import { resolve as
|
|
42232
|
+
import { appendFile as appendFile2, mkdir as mkdir22, readdir as readdir8, rm as rm14 } from "node:fs/promises";
|
|
42233
|
+
import { resolve as resolve35 } from "node:path";
|
|
41994
42234
|
import { performance as performance3 } from "node:perf_hooks";
|
|
41995
42235
|
var TURN_PHASES = [
|
|
41996
42236
|
/** Enqueued on `SessionScheduler` until this turn holds a slot. A capacity wait lives here. */
|
|
@@ -42276,7 +42516,7 @@ function formatTurnTraceLine(record5) {
|
|
|
42276
42516
|
return [head, ...record5.attempts.map((attempt) => formatTurnAttempt(attempt))].join("\n ");
|
|
42277
42517
|
}
|
|
42278
42518
|
function turnTraceDirectory(runtimeDir) {
|
|
42279
|
-
return
|
|
42519
|
+
return resolve35(runtimeDir, "turn-traces");
|
|
42280
42520
|
}
|
|
42281
42521
|
var TURN_TRACE_RETENTION_DAYS = 7;
|
|
42282
42522
|
function traceFileName(date) {
|
|
@@ -42293,7 +42533,7 @@ var TurnTraceFile = class {
|
|
|
42293
42533
|
this.options = options;
|
|
42294
42534
|
}
|
|
42295
42535
|
path(now2 = (this.options.clock ?? (() => /* @__PURE__ */ new Date()))()) {
|
|
42296
|
-
return
|
|
42536
|
+
return resolve35(this.directory, traceFileName(now2));
|
|
42297
42537
|
}
|
|
42298
42538
|
write(record5) {
|
|
42299
42539
|
this.tail = this.tail.catch(() => void 0).then(async () => {
|
|
@@ -42316,8 +42556,8 @@ var TurnTraceFile = class {
|
|
|
42316
42556
|
return;
|
|
42317
42557
|
this.prunedDay = day;
|
|
42318
42558
|
const cutoff = traceFileName(new Date(now2.getTime() - TURN_TRACE_RETENTION_DAYS * 864e5));
|
|
42319
|
-
const names = await
|
|
42320
|
-
await Promise.all(names.filter((name) => /^turns-\d{4}-\d{2}-\d{2}\.jsonl$/.test(name) && name < cutoff).map((name) =>
|
|
42559
|
+
const names = await readdir8(this.directory).catch(() => []);
|
|
42560
|
+
await Promise.all(names.filter((name) => /^turns-\d{4}-\d{2}-\d{2}\.jsonl$/.test(name) && name < cutoff).map((name) => rm14(resolve35(this.directory, name), { force: true })));
|
|
42321
42561
|
}
|
|
42322
42562
|
};
|
|
42323
42563
|
|
|
@@ -42669,7 +42909,7 @@ var MonolithRoomTurnLoop = class {
|
|
|
42669
42909
|
const cached = this.deliveredAttachments.get(item.id);
|
|
42670
42910
|
if (cached?.length === item.attachments.length)
|
|
42671
42911
|
return cached;
|
|
42672
|
-
const delivered = await deliverAttachments(item.attachments,
|
|
42912
|
+
const delivered = await deliverAttachments(item.attachments, join19(this.attachmentDir, item.id.replace(/[^\w-]/g, "_")), this.options.fetchImpl, cached);
|
|
42673
42913
|
this.deliveredAttachments.set(item.id, withoutImageData(delivered.filter((entry) => entry.path)));
|
|
42674
42914
|
return delivered;
|
|
42675
42915
|
}
|
|
@@ -42739,7 +42979,7 @@ var MonolithRoomTurnLoop = class {
|
|
|
42739
42979
|
this.sessionFingerprint = void 0;
|
|
42740
42980
|
this.sessionCodegraphReady = false;
|
|
42741
42981
|
this.pinnedProviderOverride = void 0;
|
|
42742
|
-
if (client
|
|
42982
|
+
if (client)
|
|
42743
42983
|
await client.stop();
|
|
42744
42984
|
}
|
|
42745
42985
|
/**
|
|
@@ -42919,7 +43159,7 @@ var MonolithRoomTurnLoop = class {
|
|
|
42919
43159
|
args: this.options.config.agentArgs ?? []
|
|
42920
43160
|
}, selection);
|
|
42921
43161
|
const { stateDirs, tmpDir } = harnessStateDirsFromEnv(agentEnv);
|
|
42922
|
-
this.attachmentDir = tmpDir ?
|
|
43162
|
+
this.attachmentDir = tmpDir ? join19(tmpDir, "beeline-attachments") : void 0;
|
|
42923
43163
|
this.sessionScratchDir = tmpDir;
|
|
42924
43164
|
this.sessionStateDirs = stateDirs;
|
|
42925
43165
|
const homeStateDirs = harnessHomeStateDirs(harnessLabel, agentEnv.HOME ?? operatorHome);
|
|
@@ -43160,7 +43400,7 @@ var MonolithRoomTurnLoop = class {
|
|
|
43160
43400
|
this.sessionId = void 0;
|
|
43161
43401
|
this.sessionFingerprint = void 0;
|
|
43162
43402
|
this.sessionCodegraphReady = false;
|
|
43163
|
-
if (client
|
|
43403
|
+
if (client)
|
|
43164
43404
|
await client.stop();
|
|
43165
43405
|
this.pinnedProviderOverride = next;
|
|
43166
43406
|
await (trace ? trace.measure("activation", () => this.activate(trace)) : this.activate());
|
|
@@ -43239,8 +43479,8 @@ var MonolithRoomTurnLoop = class {
|
|
|
43239
43479
|
let timer;
|
|
43240
43480
|
const stats = statsPromise && remaining > 0 ? await Promise.race([
|
|
43241
43481
|
statsPromise,
|
|
43242
|
-
new Promise((
|
|
43243
|
-
timer = setTimeout(() =>
|
|
43482
|
+
new Promise((resolve49) => {
|
|
43483
|
+
timer = setTimeout(() => resolve49(void 0), remaining);
|
|
43244
43484
|
})
|
|
43245
43485
|
]).finally(() => {
|
|
43246
43486
|
if (timer)
|
|
@@ -43624,6 +43864,7 @@ var MonolithRoomTurnLoop = class {
|
|
|
43624
43864
|
this.squireRelay.close();
|
|
43625
43865
|
this.options.grantRunner?.unregister(roomId);
|
|
43626
43866
|
await this.options.scheduler.suspend(roomId);
|
|
43867
|
+
this.options.scheduler.forget(roomId);
|
|
43627
43868
|
}
|
|
43628
43869
|
}
|
|
43629
43870
|
};
|
|
@@ -43654,9 +43895,9 @@ function roomMessagePrompt(author, body, attachments, delivered, harnessAcceptsI
|
|
|
43654
43895
|
|
|
43655
43896
|
// apps/body/dist/corner-github-auth.js
|
|
43656
43897
|
import { chmod as chmod9, mkdir as mkdir24, writeFile as writeFile19 } from "node:fs/promises";
|
|
43657
|
-
import { delimiter as delimiter3, resolve as
|
|
43898
|
+
import { delimiter as delimiter3, resolve as resolve36 } from "node:path";
|
|
43658
43899
|
async function installCornerGitHubWrappers(input) {
|
|
43659
|
-
const bin =
|
|
43900
|
+
const bin = resolve36(input.root, "beeline-github-bin");
|
|
43660
43901
|
await mkdir24(bin, { recursive: true, mode: 448 });
|
|
43661
43902
|
const common = {
|
|
43662
43903
|
node: process.execPath,
|
|
@@ -43668,13 +43909,13 @@ async function installCornerGitHubWrappers(input) {
|
|
|
43668
43909
|
gitCommand: input.gitBinary,
|
|
43669
43910
|
originUrl: input.originUrl ?? ""
|
|
43670
43911
|
};
|
|
43671
|
-
await writeLauncher(
|
|
43912
|
+
await writeLauncher(resolve36(bin, "git"), {
|
|
43672
43913
|
...common,
|
|
43673
43914
|
command: input.gitBinary,
|
|
43674
43915
|
launcher: "git",
|
|
43675
43916
|
restFallback: false
|
|
43676
43917
|
});
|
|
43677
|
-
await writeLauncher(
|
|
43918
|
+
await writeLauncher(resolve36(bin, "gh"), {
|
|
43678
43919
|
...common,
|
|
43679
43920
|
command: input.ghBinary ?? "",
|
|
43680
43921
|
launcher: "gh",
|
|
@@ -44109,37 +44350,37 @@ if (!refusal) {
|
|
|
44109
44350
|
}
|
|
44110
44351
|
|
|
44111
44352
|
// apps/body/dist/warm-node-modules.js
|
|
44112
|
-
import { createHash as createHash12, randomUUID as
|
|
44353
|
+
import { createHash as createHash12, randomUUID as randomUUID12 } from "node:crypto";
|
|
44113
44354
|
import { constants as fsConstants3 } from "node:fs";
|
|
44114
|
-
import { chmod as chmod10, copyFile as copyFile2, link, lstat as
|
|
44115
|
-
import { dirname as dirname25, join as
|
|
44355
|
+
import { chmod as chmod10, copyFile as copyFile2, link, lstat as lstat5, mkdir as mkdir25, readdir as readdir9, readFile as readFile29, readlink as readlink2, rename as rename10, rm as rm15, stat as stat9, symlink as symlink3, utimes } from "node:fs/promises";
|
|
44356
|
+
import { dirname as dirname25, join as join20, resolve as resolve37 } from "node:path";
|
|
44116
44357
|
var STORE_FORMAT = "v1";
|
|
44117
44358
|
var STAGING_PREFIX = ".beeline-warm-";
|
|
44118
44359
|
var STAGING_SWEEP_MS = 24 * 60 * 60 * 1e3;
|
|
44119
44360
|
var WARM_STORE_MAX_ENTRIES = 3;
|
|
44120
44361
|
function sharedNpmCacheDir(supervisorRoot) {
|
|
44121
|
-
return
|
|
44362
|
+
return resolve37(supervisorRoot, "beeline", "npm-cache");
|
|
44122
44363
|
}
|
|
44123
44364
|
function sharedPnpmStoreDir(supervisorRoot) {
|
|
44124
|
-
return
|
|
44365
|
+
return resolve37(supervisorRoot, "beeline", "pnpm-store");
|
|
44125
44366
|
}
|
|
44126
44367
|
function sharedCargoTargetDir(supervisorRoot) {
|
|
44127
|
-
return
|
|
44368
|
+
return resolve37(supervisorRoot, "beeline", "cargo-target");
|
|
44128
44369
|
}
|
|
44129
44370
|
function sharedTurboCacheDir(supervisorRoot) {
|
|
44130
|
-
return
|
|
44371
|
+
return resolve37(supervisorRoot, "beeline", "turbo-cache");
|
|
44131
44372
|
}
|
|
44132
44373
|
function warmNodeModulesStoreDir(supervisorRoot) {
|
|
44133
|
-
return
|
|
44374
|
+
return resolve37(supervisorRoot, "beeline", "node-modules");
|
|
44134
44375
|
}
|
|
44135
44376
|
function mobileNodeModulesStoreDir(supervisorRoot) {
|
|
44136
|
-
return
|
|
44377
|
+
return resolve37(supervisorRoot, "beeline", "node-modules-mobile");
|
|
44137
44378
|
}
|
|
44138
44379
|
function isPlanRefusal(value) {
|
|
44139
44380
|
return "failure" in value;
|
|
44140
44381
|
}
|
|
44141
44382
|
async function readWarmPlan(worktreePath) {
|
|
44142
|
-
const lockfile = await readFile29(
|
|
44383
|
+
const lockfile = await readFile29(resolve37(worktreePath, "package-lock.json")).catch(() => void 0);
|
|
44143
44384
|
if (!lockfile)
|
|
44144
44385
|
return { failure: "no-lockfile" };
|
|
44145
44386
|
const packages = parseLockfilePackages(lockfile);
|
|
@@ -44178,11 +44419,11 @@ async function seedWarmNodeModules(input) {
|
|
|
44178
44419
|
return { reason: plan.failure, ...plan.detail ? { detail: plan.detail } : {} };
|
|
44179
44420
|
}
|
|
44180
44421
|
for (const tree of plan.trees) {
|
|
44181
|
-
if (await pathExists(
|
|
44422
|
+
if (await pathExists(resolve37(input.worktreePath, tree))) {
|
|
44182
44423
|
return { reason: "present", key: plan.key };
|
|
44183
44424
|
}
|
|
44184
44425
|
}
|
|
44185
|
-
const entry =
|
|
44426
|
+
const entry = resolve37(input.storeRoot, plan.key);
|
|
44186
44427
|
if (!await isDirectory(entry))
|
|
44187
44428
|
return { reason: "cold", key: plan.key };
|
|
44188
44429
|
const [storeDevice, checkoutDevice] = await Promise.all([
|
|
@@ -44192,29 +44433,29 @@ async function seedWarmNodeModules(input) {
|
|
|
44192
44433
|
if (storeDevice === void 0 || storeDevice !== checkoutDevice) {
|
|
44193
44434
|
return { reason: "cross-device", key: plan.key };
|
|
44194
44435
|
}
|
|
44195
|
-
const staging =
|
|
44436
|
+
const staging = resolve37(input.storeRoot, `${STAGING_PREFIX}${process.pid}.${randomUUID12()}`);
|
|
44196
44437
|
const placed = [];
|
|
44197
44438
|
const now2 = (input.now ?? Date.now)();
|
|
44198
44439
|
try {
|
|
44199
44440
|
await sweepStaleStaging(input.storeRoot, now2);
|
|
44200
44441
|
await utimes(entry, now2 / 1e3, now2 / 1e3).catch(() => void 0);
|
|
44201
44442
|
for (const tree of plan.trees) {
|
|
44202
|
-
await cloneTree(
|
|
44443
|
+
await cloneTree(resolve37(entry, tree), resolve37(staging, tree), seedFile);
|
|
44203
44444
|
}
|
|
44204
44445
|
for (const tree of plan.trees) {
|
|
44205
|
-
const target =
|
|
44446
|
+
const target = resolve37(input.worktreePath, tree);
|
|
44206
44447
|
await mkdir25(dirname25(target), { recursive: true });
|
|
44207
|
-
await rename10(
|
|
44448
|
+
await rename10(resolve37(staging, tree), target);
|
|
44208
44449
|
placed.push(target);
|
|
44209
44450
|
}
|
|
44210
44451
|
return { reason: "seeded", key: plan.key };
|
|
44211
44452
|
} catch (error) {
|
|
44212
44453
|
for (const target of placed) {
|
|
44213
|
-
await
|
|
44454
|
+
await rm15(target, { recursive: true, force: true }).catch(() => void 0);
|
|
44214
44455
|
}
|
|
44215
44456
|
return { reason: "failed", key: plan.key, detail: describe3(error) };
|
|
44216
44457
|
} finally {
|
|
44217
|
-
await
|
|
44458
|
+
await rm15(staging, { recursive: true, force: true }).catch(() => void 0);
|
|
44218
44459
|
}
|
|
44219
44460
|
}
|
|
44220
44461
|
async function harvestWarmNodeModules(input) {
|
|
@@ -44222,11 +44463,11 @@ async function harvestWarmNodeModules(input) {
|
|
|
44222
44463
|
if (isPlanRefusal(plan)) {
|
|
44223
44464
|
return { reason: plan.failure, ...plan.detail ? { detail: plan.detail } : {} };
|
|
44224
44465
|
}
|
|
44225
|
-
const entry =
|
|
44466
|
+
const entry = resolve37(input.storeRoot, plan.key);
|
|
44226
44467
|
if (await pathExists(entry))
|
|
44227
44468
|
return { reason: "already-warm", key: plan.key };
|
|
44228
44469
|
for (const tree of plan.trees) {
|
|
44229
|
-
if (!await isDirectory(
|
|
44470
|
+
if (!await isDirectory(resolve37(input.worktreePath, tree))) {
|
|
44230
44471
|
return { reason: "no-node-modules", key: plan.key, detail: tree };
|
|
44231
44472
|
}
|
|
44232
44473
|
}
|
|
@@ -44238,12 +44479,12 @@ async function harvestWarmNodeModules(input) {
|
|
|
44238
44479
|
detail: `${missing.length} absent, e.g. ${missing.slice(0, 3).join(", ")}`
|
|
44239
44480
|
};
|
|
44240
44481
|
}
|
|
44241
|
-
const staging =
|
|
44482
|
+
const staging = resolve37(input.storeRoot, `${STAGING_PREFIX}${process.pid}.${randomUUID12()}`);
|
|
44242
44483
|
try {
|
|
44243
44484
|
await mkdir25(input.storeRoot, { recursive: true, mode: 493 });
|
|
44244
44485
|
await sweepStaleStaging(input.storeRoot, (input.now ?? Date.now)());
|
|
44245
44486
|
for (const tree of plan.trees) {
|
|
44246
|
-
await cloneTree(
|
|
44487
|
+
await cloneTree(resolve37(input.worktreePath, tree), resolve37(staging, tree), harvestFile);
|
|
44247
44488
|
}
|
|
44248
44489
|
await input.onCopied?.();
|
|
44249
44490
|
if (!await stagedTreeIsPublishable(input.worktreePath, staging, plan.key)) {
|
|
@@ -44257,25 +44498,25 @@ async function harvestWarmNodeModules(input) {
|
|
|
44257
44498
|
return { reason: "already-warm", key: plan.key };
|
|
44258
44499
|
return { reason: "failed", key: plan.key, detail: describe3(error) };
|
|
44259
44500
|
} finally {
|
|
44260
|
-
await
|
|
44501
|
+
await rm15(staging, { recursive: true, force: true }).catch(() => void 0);
|
|
44261
44502
|
}
|
|
44262
44503
|
}
|
|
44263
44504
|
async function stagedTreeIsPublishable(worktreePath, staging, key) {
|
|
44264
44505
|
const settled = await readWarmPlan(worktreePath);
|
|
44265
44506
|
if (isPlanRefusal(settled) || settled.key !== key)
|
|
44266
44507
|
return false;
|
|
44267
|
-
const hidden =
|
|
44508
|
+
const hidden = join20("node_modules", ".package-lock.json");
|
|
44268
44509
|
const [copied, current] = await Promise.all([
|
|
44269
|
-
readFile29(
|
|
44270
|
-
readFile29(
|
|
44510
|
+
readFile29(resolve37(staging, hidden)).catch(() => void 0),
|
|
44511
|
+
readFile29(resolve37(worktreePath, hidden)).catch(() => void 0)
|
|
44271
44512
|
]);
|
|
44272
44513
|
if (!copied || !current || !copied.equals(current))
|
|
44273
44514
|
return false;
|
|
44274
44515
|
return (await missingInstalledPackages(worktreePath, staging)).length === 0;
|
|
44275
44516
|
}
|
|
44276
44517
|
async function missingInstalledPackages(worktreePath, treeRoot = worktreePath) {
|
|
44277
|
-
const wanted = parseLockfilePackages(await readFile29(
|
|
44278
|
-
const installed = parseLockfilePackages(await readFile29(
|
|
44518
|
+
const wanted = parseLockfilePackages(await readFile29(resolve37(worktreePath, "package-lock.json")).catch(() => void 0));
|
|
44519
|
+
const installed = parseLockfilePackages(await readFile29(resolve37(treeRoot, "node_modules", ".package-lock.json")).catch(() => void 0));
|
|
44279
44520
|
if (!wanted)
|
|
44280
44521
|
return ["package-lock.json is unreadable"];
|
|
44281
44522
|
if (!installed)
|
|
@@ -44295,14 +44536,14 @@ async function missingInstalledPackages(worktreePath, treeRoot = worktreePath) {
|
|
|
44295
44536
|
required.push(path);
|
|
44296
44537
|
}
|
|
44297
44538
|
await mapWithLimit(required, INTEGRITY_READ_CONCURRENCY, async (path) => {
|
|
44298
|
-
if (!(path in installed) || !await isInstalledPackage(
|
|
44539
|
+
if (!(path in installed) || !await isInstalledPackage(resolve37(treeRoot, path))) {
|
|
44299
44540
|
missing.push(path);
|
|
44300
44541
|
}
|
|
44301
44542
|
});
|
|
44302
44543
|
return missing.sort();
|
|
44303
44544
|
}
|
|
44304
44545
|
async function isInstalledPackage(path) {
|
|
44305
|
-
return
|
|
44546
|
+
return stat9(join20(path, "package.json")).then((info) => info.isFile(), () => false);
|
|
44306
44547
|
}
|
|
44307
44548
|
var INTEGRITY_READ_CONCURRENCY = 64;
|
|
44308
44549
|
async function mapWithLimit(values, limit, visit) {
|
|
@@ -44335,9 +44576,9 @@ function isContainedTreePath(value) {
|
|
|
44335
44576
|
}
|
|
44336
44577
|
async function cloneTree(source, target, file, topLevel = true) {
|
|
44337
44578
|
await mkdir25(target, { recursive: true, mode: 493 });
|
|
44338
|
-
for (const entry of await
|
|
44339
|
-
const from =
|
|
44340
|
-
const to =
|
|
44579
|
+
for (const entry of await readdir9(source, { withFileTypes: true })) {
|
|
44580
|
+
const from = join20(source, entry.name);
|
|
44581
|
+
const to = join20(target, entry.name);
|
|
44341
44582
|
if (entry.isSymbolicLink()) {
|
|
44342
44583
|
await symlink3(await readlink2(from), to);
|
|
44343
44584
|
continue;
|
|
@@ -44352,7 +44593,7 @@ async function cloneTree(source, target, file, topLevel = true) {
|
|
|
44352
44593
|
}
|
|
44353
44594
|
var harvestFile = async (source, target) => {
|
|
44354
44595
|
await copyFile2(source, target, fsConstants3.COPYFILE_FICLONE);
|
|
44355
|
-
const info = await
|
|
44596
|
+
const info = await stat9(source);
|
|
44356
44597
|
await chmod10(target, info.mode & 4095 & ~146);
|
|
44357
44598
|
};
|
|
44358
44599
|
var seedFile = async (source, target, topLevel) => {
|
|
@@ -44364,46 +44605,46 @@ var seedFile = async (source, target, topLevel) => {
|
|
|
44364
44605
|
await chmod10(target, 420);
|
|
44365
44606
|
};
|
|
44366
44607
|
async function pruneWarmStore(storeRoot, keep) {
|
|
44367
|
-
const names = (await
|
|
44608
|
+
const names = (await readdir9(storeRoot).catch(() => [])).filter((name) => !name.startsWith(STAGING_PREFIX));
|
|
44368
44609
|
const entries = [];
|
|
44369
44610
|
for (const name of names) {
|
|
44370
|
-
const info = await
|
|
44611
|
+
const info = await lstat5(join20(storeRoot, name)).catch(() => void 0);
|
|
44371
44612
|
if (info?.isDirectory())
|
|
44372
44613
|
entries.push({ name, usedAt: info.mtimeMs });
|
|
44373
44614
|
}
|
|
44374
44615
|
const dropped = entries.sort((a2, b) => b.usedAt - a2.usedAt || a2.name.localeCompare(b.name)).slice(keep);
|
|
44375
44616
|
for (const entry of dropped) {
|
|
44376
|
-
await
|
|
44617
|
+
await rm15(join20(storeRoot, entry.name), { recursive: true, force: true }).catch(() => void 0);
|
|
44377
44618
|
}
|
|
44378
44619
|
return dropped.map((entry) => entry.name);
|
|
44379
44620
|
}
|
|
44380
44621
|
async function sweepStaleStaging(storeRoot, now2) {
|
|
44381
|
-
const entries = await
|
|
44622
|
+
const entries = await readdir9(storeRoot).catch(() => []);
|
|
44382
44623
|
for (const name of entries) {
|
|
44383
44624
|
if (!name.startsWith(STAGING_PREFIX))
|
|
44384
44625
|
continue;
|
|
44385
|
-
const path =
|
|
44386
|
-
const info = await
|
|
44626
|
+
const path = join20(storeRoot, name);
|
|
44627
|
+
const info = await lstat5(path).catch(() => void 0);
|
|
44387
44628
|
if (!info || now2 - info.mtimeMs < STAGING_SWEEP_MS)
|
|
44388
44629
|
continue;
|
|
44389
|
-
await
|
|
44630
|
+
await rm15(path, { recursive: true, force: true }).catch(() => void 0);
|
|
44390
44631
|
}
|
|
44391
44632
|
}
|
|
44392
44633
|
async function pathExists(path) {
|
|
44393
|
-
return
|
|
44634
|
+
return lstat5(path).then(() => true, () => false);
|
|
44394
44635
|
}
|
|
44395
44636
|
async function deviceOf(path) {
|
|
44396
|
-
return
|
|
44637
|
+
return stat9(path).then((info) => info.dev, () => void 0);
|
|
44397
44638
|
}
|
|
44398
44639
|
async function isDirectory(path) {
|
|
44399
|
-
return
|
|
44640
|
+
return stat9(path).then((info) => info.isDirectory(), () => false);
|
|
44400
44641
|
}
|
|
44401
44642
|
function describe3(error) {
|
|
44402
44643
|
return error instanceof Error ? error.message : String(error);
|
|
44403
44644
|
}
|
|
44404
44645
|
|
|
44405
44646
|
// apps/body/dist/monolith-corner-turn.js
|
|
44406
|
-
var
|
|
44647
|
+
var execFileAsync9 = promisify9(execFile14);
|
|
44407
44648
|
var TOOL_ARGUMENT_MAX_BYTES = 1200;
|
|
44408
44649
|
var TOOL_OUTPUT_MAX_BYTES = 3200;
|
|
44409
44650
|
var TOOL_PATH_LIMIT = 12;
|
|
@@ -44417,8 +44658,8 @@ function isCornerReviewTurn(reviewer, trigger) {
|
|
|
44417
44658
|
async function cornerUndeliveredRepositoryState(worktreePath, featureBranch, targetBranch) {
|
|
44418
44659
|
try {
|
|
44419
44660
|
const [{ stdout: status }, ahead] = await Promise.all([
|
|
44420
|
-
|
|
44421
|
-
featureBranch ? firstResolvedRemoteRef(worktreePath, [featureBranch, targetBranch]).then((remoteRef) => remoteRef ?
|
|
44661
|
+
execFileAsync9("git", ["-C", worktreePath, "status", "--porcelain=v1"]),
|
|
44662
|
+
featureBranch ? firstResolvedRemoteRef(worktreePath, [featureBranch, targetBranch]).then((remoteRef) => remoteRef ? execFileAsync9("git", [
|
|
44422
44663
|
"-C",
|
|
44423
44664
|
worktreePath,
|
|
44424
44665
|
"rev-list",
|
|
@@ -44438,7 +44679,7 @@ async function firstResolvedRemoteRef(worktreePath, branches) {
|
|
|
44438
44679
|
if (!branch)
|
|
44439
44680
|
continue;
|
|
44440
44681
|
const ref = `refs/remotes/origin/${branch}`;
|
|
44441
|
-
const resolved = await
|
|
44682
|
+
const resolved = await execFileAsync9("git", ["-C", worktreePath, "rev-parse", "--verify", ref]).then(() => true).catch(() => false);
|
|
44442
44683
|
if (resolved)
|
|
44443
44684
|
return ref;
|
|
44444
44685
|
}
|
|
@@ -44590,7 +44831,7 @@ async function cornerToolActivity(call, worktreePath, requestedBy) {
|
|
|
44590
44831
|
let title = oneLine(redactToolDetail(call.title ?? "")) || `${operation} tool`;
|
|
44591
44832
|
if (isSuccessfulCommit(call)) {
|
|
44592
44833
|
try {
|
|
44593
|
-
const shown = await
|
|
44834
|
+
const shown = await execFileAsync9("git", ["-C", worktreePath, "show", "--format=%s", "--name-only", "--no-renames", "HEAD"], { maxBuffer: 1024 * 1024 });
|
|
44594
44835
|
const lines = shown.stdout.split(/\r?\n/);
|
|
44595
44836
|
const subject = oneLine(lines.shift() ?? "commit");
|
|
44596
44837
|
const files = new Set(lines.map(oneLine).filter(Boolean));
|
|
@@ -44851,7 +45092,7 @@ var MonolithCornerTurnLoop = class {
|
|
|
44851
45092
|
this.sessionCodegraphReady = false;
|
|
44852
45093
|
this.pinnedProviderOverride = void 0;
|
|
44853
45094
|
this.sessionModel = null;
|
|
44854
|
-
if (client
|
|
45095
|
+
if (client)
|
|
44855
45096
|
await client.stop();
|
|
44856
45097
|
}
|
|
44857
45098
|
/** See `MonolithRoomTurnLoop.sessionIsCurrent`: retention never keeps a
|
|
@@ -45012,9 +45253,9 @@ var MonolithCornerTurnLoop = class {
|
|
|
45012
45253
|
const repository = this.options.repository;
|
|
45013
45254
|
let githubEnv = repository ? { GH_TOKEN: repository.githubToken, GITHUB_TOKEN: repository.githubToken } : {};
|
|
45014
45255
|
if (repository && this.options.config.runtimeConfigPath && this.options.config.agentHomeRoot) {
|
|
45015
|
-
const gitBinary = (await
|
|
45016
|
-
const ghBinary = await
|
|
45017
|
-
const originUrl = await
|
|
45256
|
+
const gitBinary = (await execFileAsync9("which", ["git"])).stdout.trim();
|
|
45257
|
+
const ghBinary = await execFileAsync9("which", ["gh"]).then((result) => result.stdout.trim()).catch(() => void 0);
|
|
45258
|
+
const originUrl = await execFileAsync9(gitBinary, [
|
|
45018
45259
|
"-C",
|
|
45019
45260
|
this.options.worktreePath,
|
|
45020
45261
|
"remote",
|
|
@@ -45040,7 +45281,8 @@ var MonolithCornerTurnLoop = class {
|
|
|
45040
45281
|
const pnpmStoreDir = sharedPnpmStoreDir(this.options.runtime.supervisorRoot);
|
|
45041
45282
|
const cargoTargetDir = sharedCargoTargetDir(this.options.runtime.supervisorRoot);
|
|
45042
45283
|
const turboCacheDir = sharedTurboCacheDir(this.options.runtime.supervisorRoot);
|
|
45043
|
-
|
|
45284
|
+
const modelCacheDir = resolve38(this.options.runtime.supervisorRoot, "beeline", "model-cache");
|
|
45285
|
+
await Promise.all([npmCacheDir, pnpmStoreDir, cargoTargetDir, turboCacheDir, modelCacheDir].map((path) => mkdir26(path, { recursive: true, mode: 448 })));
|
|
45044
45286
|
const agentEnv = {
|
|
45045
45287
|
...this.options.config.agentEnv,
|
|
45046
45288
|
...homeOverlay,
|
|
@@ -45050,7 +45292,9 @@ var MonolithCornerTurnLoop = class {
|
|
|
45050
45292
|
// hardlinks packages out of this content-addressable store.
|
|
45051
45293
|
PNPM_CONFIG_STORE_DIR: pnpmStoreDir,
|
|
45052
45294
|
CARGO_TARGET_DIR: cargoTargetDir,
|
|
45053
|
-
TURBO_CACHE_DIR: turboCacheDir
|
|
45295
|
+
TURBO_CACHE_DIR: turboCacheDir,
|
|
45296
|
+
HF_HOME: modelCacheDir,
|
|
45297
|
+
HUGGINGFACE_HUB_CACHE: join21(modelCacheDir, "hub")
|
|
45054
45298
|
};
|
|
45055
45299
|
this.agentEnv = agentEnv;
|
|
45056
45300
|
this.modelContextTokens = await modelContextWindowTokens(selection.model, agentEnv.PI_CODING_AGENT_DIR);
|
|
@@ -45060,7 +45304,7 @@ var MonolithCornerTurnLoop = class {
|
|
|
45060
45304
|
args: this.options.config.agentArgs ?? []
|
|
45061
45305
|
}, selection);
|
|
45062
45306
|
const { stateDirs, tmpDir } = harnessStateDirsFromEnv(agentEnv);
|
|
45063
|
-
this.attachmentDir = tmpDir ?
|
|
45307
|
+
this.attachmentDir = tmpDir ? join21(tmpDir, "beeline-attachments") : void 0;
|
|
45064
45308
|
this.sessionScratchDir = tmpDir;
|
|
45065
45309
|
const homeStateDirs = harnessHomeStateDirs(harnessLabel, agentEnv.HOME ?? operatorHome);
|
|
45066
45310
|
await Promise.all(homeStateDirs.map((dir) => mkdir26(dir, { recursive: true })));
|
|
@@ -45087,6 +45331,7 @@ var MonolithCornerTurnLoop = class {
|
|
|
45087
45331
|
pnpmStoreDir,
|
|
45088
45332
|
cargoTargetDir,
|
|
45089
45333
|
turboCacheDir,
|
|
45334
|
+
modelCacheDir,
|
|
45090
45335
|
...registryMcpHostBindPaths(configuration.registryMcpRoutes, this.options.config.registryMcpBrokerSocket),
|
|
45091
45336
|
...grantedSquireHostBindPaths({
|
|
45092
45337
|
operatorHome,
|
|
@@ -45165,7 +45410,9 @@ var MonolithCornerTurnLoop = class {
|
|
|
45165
45410
|
// per-corner cache.
|
|
45166
45411
|
{ name: "npm_config_cache", value: npmCacheDir },
|
|
45167
45412
|
{ name: "PNPM_CONFIG_STORE_DIR", value: pnpmStoreDir },
|
|
45168
|
-
{ name: "CARGO_TARGET_DIR", value: cargoTargetDir }
|
|
45413
|
+
{ name: "CARGO_TARGET_DIR", value: cargoTargetDir },
|
|
45414
|
+
{ name: "HF_HOME", value: modelCacheDir },
|
|
45415
|
+
{ name: "HUGGINGFACE_HUB_CACHE", value: join21(modelCacheDir, "hub") }
|
|
45169
45416
|
]
|
|
45170
45417
|
}
|
|
45171
45418
|
] : [],
|
|
@@ -45173,13 +45420,13 @@ var MonolithCornerTurnLoop = class {
|
|
|
45173
45420
|
roomId: this.options.parentRoomId,
|
|
45174
45421
|
workspaceId: this.options.workspaceId,
|
|
45175
45422
|
cornerId: this.options.cornerId,
|
|
45176
|
-
agentMayCloseCorner: Boolean(repository),
|
|
45177
45423
|
reviewer,
|
|
45178
45424
|
repositoryBacked: Boolean(repository),
|
|
45179
45425
|
attachRoot: this.options.worktreePath,
|
|
45180
45426
|
// The whole per-session overlay, not an enumerated subset: see
|
|
45181
45427
|
// `monolith-room-turn.ts`'s matching comment.
|
|
45182
45428
|
attachScratchRoot,
|
|
45429
|
+
...!repository ? { cornerScratchRoot: this.options.worktreePath } : {},
|
|
45183
45430
|
turnContextPath: this.commandContext.path,
|
|
45184
45431
|
squireRelay: squireScope.relay,
|
|
45185
45432
|
...this.options.grantRunnerEndpoint ? { grantRunner: this.options.grantRunnerEndpoint } : {}
|
|
@@ -45273,7 +45520,7 @@ var MonolithCornerTurnLoop = class {
|
|
|
45273
45520
|
this.options.api.execute("getCornerRestoreState", {
|
|
45274
45521
|
cornerId: this.options.cornerId
|
|
45275
45522
|
}),
|
|
45276
|
-
|
|
45523
|
+
execFileAsync9("git", ["-C", this.options.worktreePath, "rev-parse", "HEAD"]).then(({ stdout: stdout6 }) => stdout6.trim())
|
|
45277
45524
|
]);
|
|
45278
45525
|
const pr = restore.lifecycle?.pr;
|
|
45279
45526
|
if (restore.lifecycle?.checks !== "passing" || !pr?.number || !pr.headSha || pr.headSha !== localHead)
|
|
@@ -45287,7 +45534,7 @@ var MonolithCornerTurnLoop = class {
|
|
|
45287
45534
|
briefRevision: restore.brief?.revision
|
|
45288
45535
|
}),
|
|
45289
45536
|
...this.options.config.agentHomeRoot && this.options.config.agentKind && !AGENT_SKILL_DIRS.includes(this.options.config.agentKind) ? [
|
|
45290
|
-
`This harness has no verified native skill discovery. Read the release-managed review procedure at ${
|
|
45537
|
+
`This harness has no verified native skill discovery. Read the release-managed review procedure at ${resolve38(this.options.config.agentHomeRoot, "codex", "skills", "beeline-review", "SKILL.md")} before the verdict.`
|
|
45291
45538
|
] : []
|
|
45292
45539
|
].join("\n");
|
|
45293
45540
|
} catch {
|
|
@@ -45353,7 +45600,7 @@ var MonolithCornerTurnLoop = class {
|
|
|
45353
45600
|
this.sessionId = void 0;
|
|
45354
45601
|
this.sessionFingerprint = void 0;
|
|
45355
45602
|
this.sessionCodegraphReady = false;
|
|
45356
|
-
if (client
|
|
45603
|
+
if (client)
|
|
45357
45604
|
await client.stop();
|
|
45358
45605
|
this.pinnedProviderOverride = next;
|
|
45359
45606
|
await (trace ? trace.measure("activation", () => this.activate(trace)) : this.activate());
|
|
@@ -45402,8 +45649,8 @@ var MonolithCornerTurnLoop = class {
|
|
|
45402
45649
|
let timer;
|
|
45403
45650
|
const stats = statsPromise && remaining > 0 ? await Promise.race([
|
|
45404
45651
|
statsPromise,
|
|
45405
|
-
new Promise((
|
|
45406
|
-
timer = setTimeout(() =>
|
|
45652
|
+
new Promise((resolve49) => {
|
|
45653
|
+
timer = setTimeout(() => resolve49(void 0), remaining);
|
|
45407
45654
|
})
|
|
45408
45655
|
]).finally(() => {
|
|
45409
45656
|
if (timer)
|
|
@@ -45454,7 +45701,7 @@ var MonolithCornerTurnLoop = class {
|
|
|
45454
45701
|
let repositoryWork = cornerHasRepositoryWork(restored.brief);
|
|
45455
45702
|
let repositoryHeld = restored.held === true;
|
|
45456
45703
|
let assignedBrief = restored.brief;
|
|
45457
|
-
const taskDelivered = this.attachmentDir && attachments.length ? await deliverAttachments(attachments,
|
|
45704
|
+
const taskDelivered = this.attachmentDir && attachments.length ? await deliverAttachments(attachments, join21(this.attachmentDir, requestId.replace(/[^\w-]/g, "_")), this.options.fetchImpl) : [];
|
|
45458
45705
|
let delivered = taskDelivered;
|
|
45459
45706
|
let briefFileLines = [];
|
|
45460
45707
|
let missingRequiredBriefFile = false;
|
|
@@ -45465,7 +45712,7 @@ var MonolithCornerTurnLoop = class {
|
|
|
45465
45712
|
mimeType: file.mime,
|
|
45466
45713
|
size: file.size
|
|
45467
45714
|
}));
|
|
45468
|
-
const briefDelivered = this.attachmentDir && briefAttachments.length ? await deliverAttachments(briefAttachments,
|
|
45715
|
+
const briefDelivered = this.attachmentDir && briefAttachments.length ? await deliverAttachments(briefAttachments, join21(this.attachmentDir, requestId.replace(/[^\w-]/g, "_"), "brief", String(assignedBrief.revision)), this.options.fetchImpl) : [];
|
|
45469
45716
|
briefFileLines = await Promise.all((assignedBrief?.attachments ?? []).map(async (file, index) => {
|
|
45470
45717
|
const entry = briefDelivered.find((item) => item.attachment === briefAttachments[index]);
|
|
45471
45718
|
const verified = entry?.path && createHash13("sha256").update(await readFile30(entry.path)).digest("hex") === file.sha256;
|
|
@@ -45551,11 +45798,19 @@ var MonolithCornerTurnLoop = class {
|
|
|
45551
45798
|
}
|
|
45552
45799
|
});
|
|
45553
45800
|
trace.notePromptSections(assembled.report);
|
|
45554
|
-
trace.notePromptWindow(assembled.text, this.modelContextTokens);
|
|
45555
45801
|
this.commandContext.notePromptSections([
|
|
45556
45802
|
...this.sessionPromptSectionIds,
|
|
45557
45803
|
...assembled.report.map((section) => section.id)
|
|
45558
45804
|
]);
|
|
45805
|
+
if (!repositoryWork) {
|
|
45806
|
+
const usage2 = await allocatedDirectoryBytes(this.options.worktreePath);
|
|
45807
|
+
const text2 = `${assembled.text}
|
|
45808
|
+
|
|
45809
|
+
${scratchBudgetMessage(usage2)}`;
|
|
45810
|
+
trace.notePromptWindow(text2, this.modelContextTokens);
|
|
45811
|
+
return text2;
|
|
45812
|
+
}
|
|
45813
|
+
trace.notePromptWindow(assembled.text, this.modelContextTokens);
|
|
45559
45814
|
return assembled.text;
|
|
45560
45815
|
};
|
|
45561
45816
|
const stream = new AgentTurnStream({
|
|
@@ -45664,24 +45919,34 @@ var MonolithCornerTurnLoop = class {
|
|
|
45664
45919
|
narrationRunBoundary = 0;
|
|
45665
45920
|
currentNarrationRun = "";
|
|
45666
45921
|
trace.promptSent();
|
|
45667
|
-
|
|
45668
|
-
|
|
45669
|
-
|
|
45670
|
-
|
|
45671
|
-
|
|
45672
|
-
|
|
45673
|
-
|
|
45674
|
-
|
|
45675
|
-
if (
|
|
45676
|
-
|
|
45677
|
-
|
|
45922
|
+
const scratchRoot = this.repositoryWork ? void 0 : this.options.worktreePath;
|
|
45923
|
+
const scratchAtStart = scratchRoot ? await allocatedDirectoryBytes(scratchRoot) : 0;
|
|
45924
|
+
try {
|
|
45925
|
+
return await this.turnUsage.measure({ agentEnv: this.agentEnv, sessionId: this.sessionId }, () => this.client.sessionPrompt(this.sessionId, promptWithImages(prompt, attachmentImageBlocks(delivered, this.acceptsImages())), ROOM_PROMPT_BACKSTOP_MS, (delta, full, currentRun, runs) => {
|
|
45926
|
+
trace.firstModelOutput();
|
|
45927
|
+
if (runs) {
|
|
45928
|
+
completedNarrationRuns = runs.slice(narrationRunBoundary);
|
|
45929
|
+
currentNarrationRun = "";
|
|
45930
|
+
} else if (currentRun === void 0)
|
|
45931
|
+
currentNarrationRun += delta;
|
|
45932
|
+
else {
|
|
45933
|
+
if (currentNarrationRun && currentNarrationRun !== currentRun && !currentRun.startsWith(currentNarrationRun))
|
|
45934
|
+
completedNarrationRuns.push(currentNarrationRun);
|
|
45935
|
+
currentNarrationRun = currentRun;
|
|
45936
|
+
}
|
|
45937
|
+
stream.onChunk(delta, full, currentRun);
|
|
45938
|
+
}, void 0, (calls) => {
|
|
45939
|
+
trace.toolCalls(calls);
|
|
45940
|
+
publishToolCalls(calls, true);
|
|
45941
|
+
publishToolCalls(calls, false, lastNarratedToolCall);
|
|
45942
|
+
}));
|
|
45943
|
+
} finally {
|
|
45944
|
+
if (scratchRoot) {
|
|
45945
|
+
const usage2 = await allocatedDirectoryBytes(scratchRoot);
|
|
45946
|
+
if (scratchGrowthExceedsBudget(usage2, scratchAtStart))
|
|
45947
|
+
throw new Error(`Scratch budget exceeded. ${scratchBudgetMessage(usage2)}`);
|
|
45678
45948
|
}
|
|
45679
|
-
|
|
45680
|
-
}, void 0, (calls) => {
|
|
45681
|
-
trace.toolCalls(calls);
|
|
45682
|
-
publishToolCalls(calls, true);
|
|
45683
|
-
publishToolCalls(calls, false, lastNarratedToolCall);
|
|
45684
|
-
}));
|
|
45949
|
+
}
|
|
45685
45950
|
};
|
|
45686
45951
|
let loginRetryUsed = false;
|
|
45687
45952
|
const runPrompt = async (prompt, continuation) => {
|
|
@@ -45886,13 +46151,13 @@ ${continuation}` : assembled;
|
|
|
45886
46151
|
if (this.harvest || !this.options.repository)
|
|
45887
46152
|
return;
|
|
45888
46153
|
const { cornerId, worktreePath, runtime } = this.options;
|
|
45889
|
-
const mobilePath =
|
|
46154
|
+
const mobilePath = resolve38(worktreePath, "apps/mobile");
|
|
45890
46155
|
const jobs = [
|
|
45891
46156
|
harvestWarmNodeModules({
|
|
45892
46157
|
worktreePath,
|
|
45893
46158
|
storeRoot: warmNodeModulesStoreDir(runtime.supervisorRoot)
|
|
45894
46159
|
}),
|
|
45895
|
-
...existsSync9(
|
|
46160
|
+
...existsSync9(resolve38(mobilePath, "package-lock.json")) ? [
|
|
45896
46161
|
harvestWarmNodeModules({
|
|
45897
46162
|
worktreePath: mobilePath,
|
|
45898
46163
|
storeRoot: mobileNodeModulesStoreDir(runtime.supervisorRoot)
|
|
@@ -45940,7 +46205,7 @@ ${continuation}` : assembled;
|
|
|
45940
46205
|
const delay = outage ? Math.min(2e3 * 2 ** attempt, 3e4) : 250 * (attempt + 1);
|
|
45941
46206
|
if ((outage ? Date.now() + delay > outageDeadline : attempt === 2) || this.forcedStop || this.currentTurn && this.stoppedTurns.has(this.currentTurn.requestId))
|
|
45942
46207
|
throw error;
|
|
45943
|
-
await new Promise((
|
|
46208
|
+
await new Promise((resolve49) => setTimeout(resolve49, delay));
|
|
45944
46209
|
}
|
|
45945
46210
|
}
|
|
45946
46211
|
if (!token)
|
|
@@ -46032,11 +46297,95 @@ ${continuation}` : assembled;
|
|
|
46032
46297
|
this.squireRelay.close();
|
|
46033
46298
|
this.options.grantRunner?.unregister(cornerId);
|
|
46034
46299
|
await this.options.scheduler.suspend(cornerId);
|
|
46300
|
+
this.options.scheduler.forget(cornerId);
|
|
46035
46301
|
await this.harvest;
|
|
46036
46302
|
}
|
|
46037
46303
|
}
|
|
46038
46304
|
};
|
|
46039
46305
|
|
|
46306
|
+
// apps/body/dist/corner-disk-recovery.js
|
|
46307
|
+
import { execFile as execFile15 } from "node:child_process";
|
|
46308
|
+
import { lstat as lstat6, readdir as readdir10, realpath as realpath2, rm as rm16 } from "node:fs/promises";
|
|
46309
|
+
import { basename as basename9, dirname as dirname27, join as join22, relative as relative3, resolve as resolve39, sep as sep2 } from "node:path";
|
|
46310
|
+
import { promisify as promisify10 } from "node:util";
|
|
46311
|
+
var execFileAsync10 = promisify10(execFile15);
|
|
46312
|
+
var GENERATED_DIRS = /* @__PURE__ */ new Set([
|
|
46313
|
+
"node_modules",
|
|
46314
|
+
"target",
|
|
46315
|
+
"build",
|
|
46316
|
+
"dist",
|
|
46317
|
+
".next",
|
|
46318
|
+
".turbo",
|
|
46319
|
+
".expo"
|
|
46320
|
+
]);
|
|
46321
|
+
var MAX_DIRECTORY_DEPTH = 4;
|
|
46322
|
+
var MAX_VISITED_DIRECTORIES = 5e3;
|
|
46323
|
+
function cornerRecoveryPointerPath(worktree) {
|
|
46324
|
+
const checkout = resolve39(worktree.path);
|
|
46325
|
+
if (basename9(checkout) !== worktree.cornerId || basename9(dirname27(checkout)) !== "corners" || basename9(dirname27(dirname27(checkout))) !== "beeline" || !/^[a-zA-Z0-9-]{1,80}$/.test(worktree.cornerId)) {
|
|
46326
|
+
throw new Error("refusing recovery pointer outside a Beeline corner checkout");
|
|
46327
|
+
}
|
|
46328
|
+
return resolve39(dirname27(dirname27(checkout)), "recovery", "corners", `${worktree.cornerId}.json`);
|
|
46329
|
+
}
|
|
46330
|
+
async function git(checkout, args) {
|
|
46331
|
+
const result = await execFileAsync10("git", ["-C", checkout, ...args], {
|
|
46332
|
+
maxBuffer: 4 * 1024 * 1024
|
|
46333
|
+
});
|
|
46334
|
+
return result.stdout;
|
|
46335
|
+
}
|
|
46336
|
+
async function ignoredAndUntracked(checkout, path) {
|
|
46337
|
+
const rel = relative3(checkout, path);
|
|
46338
|
+
if (!rel || rel === ".." || rel.startsWith(`..${sep2}`))
|
|
46339
|
+
return false;
|
|
46340
|
+
const ignored = await git(checkout, ["check-ignore", "-q", "--", `${rel}/`]).then(() => true, () => false);
|
|
46341
|
+
if (!ignored)
|
|
46342
|
+
return false;
|
|
46343
|
+
return !(await git(checkout, ["ls-files", "--", rel])).trim();
|
|
46344
|
+
}
|
|
46345
|
+
async function preserveUnpublishedCornerWorktree(worktree, reason) {
|
|
46346
|
+
const checkout = resolve39(worktree.path);
|
|
46347
|
+
const pointer = cornerRecoveryPointerPath(worktree);
|
|
46348
|
+
const info = await lstat6(checkout);
|
|
46349
|
+
if (!info.isDirectory() || await realpath2(checkout) !== checkout) {
|
|
46350
|
+
throw new Error("refusing to prune a non-canonical corner checkout");
|
|
46351
|
+
}
|
|
46352
|
+
const head = (await git(checkout, ["rev-parse", "--verify", "HEAD"])).trim();
|
|
46353
|
+
const record5 = {
|
|
46354
|
+
cornerId: worktree.cornerId,
|
|
46355
|
+
checkout,
|
|
46356
|
+
branch: worktree.branch,
|
|
46357
|
+
head,
|
|
46358
|
+
reason,
|
|
46359
|
+
recordedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
46360
|
+
};
|
|
46361
|
+
await writePrivateFileAtomically(pointer, `${JSON.stringify(record5, null, 2)}
|
|
46362
|
+
`);
|
|
46363
|
+
const pruned = [];
|
|
46364
|
+
const pending = [{ path: checkout, depth: 0 }];
|
|
46365
|
+
let visited = 0;
|
|
46366
|
+
while (pending.length) {
|
|
46367
|
+
const current = pending.shift();
|
|
46368
|
+
if (++visited > MAX_VISITED_DIRECTORIES)
|
|
46369
|
+
break;
|
|
46370
|
+
if (current.depth >= MAX_DIRECTORY_DEPTH)
|
|
46371
|
+
continue;
|
|
46372
|
+
for (const entry of await readdir10(current.path, { withFileTypes: true })) {
|
|
46373
|
+
if (!entry.isDirectory() || entry.name === ".git")
|
|
46374
|
+
continue;
|
|
46375
|
+
const path = join22(current.path, entry.name);
|
|
46376
|
+
if (GENERATED_DIRS.has(entry.name)) {
|
|
46377
|
+
if (await ignoredAndUntracked(checkout, path)) {
|
|
46378
|
+
await rm16(path, { recursive: true, force: true });
|
|
46379
|
+
pruned.push(relative3(checkout, path));
|
|
46380
|
+
}
|
|
46381
|
+
continue;
|
|
46382
|
+
}
|
|
46383
|
+
pending.push({ path, depth: current.depth + 1 });
|
|
46384
|
+
}
|
|
46385
|
+
}
|
|
46386
|
+
return { pointer, pruned };
|
|
46387
|
+
}
|
|
46388
|
+
|
|
46040
46389
|
// apps/body/dist/surface-health.js
|
|
46041
46390
|
var SurfaceHealth = class {
|
|
46042
46391
|
surfaces = /* @__PURE__ */ new Map();
|
|
@@ -46125,7 +46474,7 @@ function resolveSessionIdleMs(env = process.env) {
|
|
|
46125
46474
|
return Number.isSafeInteger(value) && value > 0 ? value : DEFAULT_SESSION_IDLE_MS;
|
|
46126
46475
|
}
|
|
46127
46476
|
var DEFAULT_WORKSPACE_LIVE_SESSIONS_FLOOR = 4;
|
|
46128
|
-
var SessionScheduler = class {
|
|
46477
|
+
var SessionScheduler = class _SessionScheduler {
|
|
46129
46478
|
/** Fixed ceiling when explicitly configured; undefined selects the dynamic one. */
|
|
46130
46479
|
fixedMaxLiveSessions;
|
|
46131
46480
|
perRoomLiveSessions;
|
|
@@ -46140,6 +46489,7 @@ var SessionScheduler = class {
|
|
|
46140
46489
|
queues = /* @__PURE__ */ new Map();
|
|
46141
46490
|
drainingKeys = /* @__PURE__ */ new Set();
|
|
46142
46491
|
physicalHistory = /* @__PURE__ */ new Map();
|
|
46492
|
+
static MAX_GENERATIONS_PER_KEY = 4;
|
|
46143
46493
|
/**
|
|
46144
46494
|
* Sessions already removed from `live` whose process is still being torn
|
|
46145
46495
|
* down. They keep occupying capacity until `suspend()` resolves, so an
|
|
@@ -46263,6 +46613,10 @@ var SessionScheduler = class {
|
|
|
46263
46613
|
generations(key) {
|
|
46264
46614
|
return this.physicalHistory.get(key) ?? [];
|
|
46265
46615
|
}
|
|
46616
|
+
/** A Room/corner loop ended; its diagnostic IDs no longer have a reader. */
|
|
46617
|
+
forget(key) {
|
|
46618
|
+
this.physicalHistory.delete(key);
|
|
46619
|
+
}
|
|
46266
46620
|
/**
|
|
46267
46621
|
* Read-only capacity diagnostic, exported beside the turn trace
|
|
46268
46622
|
* (`turn-trace.ts`) so a stalled turn can be attributed to a capacity wait
|
|
@@ -46336,6 +46690,7 @@ var SessionScheduler = class {
|
|
|
46336
46690
|
this.sweepTimer = void 0;
|
|
46337
46691
|
const sessions = [...this.live.values()];
|
|
46338
46692
|
this.live.clear();
|
|
46693
|
+
this.physicalHistory.clear();
|
|
46339
46694
|
await Promise.all(sessions.map((session) => this.retire(session)));
|
|
46340
46695
|
this.wakeCapacityWaiters();
|
|
46341
46696
|
}
|
|
@@ -46449,6 +46804,8 @@ var SessionScheduler = class {
|
|
|
46449
46804
|
await this.notifyState(lifecycle, "live");
|
|
46450
46805
|
const generations = this.physicalHistory.get(key) ?? [];
|
|
46451
46806
|
generations.push(physicalSessionId);
|
|
46807
|
+
if (generations.length > _SessionScheduler.MAX_GENERATIONS_PER_KEY)
|
|
46808
|
+
generations.shift();
|
|
46452
46809
|
this.physicalHistory.set(key, generations);
|
|
46453
46810
|
return true;
|
|
46454
46811
|
} catch (error) {
|
|
@@ -46548,7 +46905,7 @@ function cornerStartConfigKey(repository, objective) {
|
|
|
46548
46905
|
function cornerRepositoryCacheDir(supervisorRoot, remote) {
|
|
46549
46906
|
const normalizedRemote = roomCheckoutRemote(remote);
|
|
46550
46907
|
const repositoryHash = createHash14("sha256").update(normalizedRemote).digest("hex").slice(0, 24);
|
|
46551
|
-
return
|
|
46908
|
+
return resolve40(supervisorRoot, "beeline", "repositories", `${repositoryHash}.git`);
|
|
46552
46909
|
}
|
|
46553
46910
|
function isStandingCornerStartFault(error) {
|
|
46554
46911
|
const text2 = error instanceof Error ? error.message : String(error);
|
|
@@ -46557,24 +46914,24 @@ function isStandingCornerStartFault(error) {
|
|
|
46557
46914
|
async function materializeCornerWorktree(input) {
|
|
46558
46915
|
const remote = roomCheckoutRemote(input.remote);
|
|
46559
46916
|
const gitCommonDir = cornerRepositoryCacheDir(input.supervisorRoot, remote);
|
|
46560
|
-
const path =
|
|
46561
|
-
await mkdir27(
|
|
46562
|
-
await mkdir27(
|
|
46917
|
+
const path = resolve40(input.supervisorRoot, "beeline", "corners", input.cornerId);
|
|
46918
|
+
await mkdir27(dirname28(gitCommonDir), { recursive: true, mode: 448 });
|
|
46919
|
+
await mkdir27(dirname28(path), { recursive: true, mode: 448 });
|
|
46563
46920
|
const authEnv = githubGitEnv(input.token);
|
|
46564
|
-
if (!existsSync10(
|
|
46565
|
-
await
|
|
46921
|
+
if (!existsSync10(resolve40(gitCommonDir, "HEAD"))) {
|
|
46922
|
+
await execFileAsync11("git", ["clone", "--bare", remote, gitCommonDir], {
|
|
46566
46923
|
env: authEnv,
|
|
46567
46924
|
maxBuffer: 4 * 1024 * 1024
|
|
46568
46925
|
});
|
|
46569
46926
|
}
|
|
46570
|
-
await
|
|
46927
|
+
await execFileAsync11("git", [
|
|
46571
46928
|
`--git-dir=${gitCommonDir}`,
|
|
46572
46929
|
"fetch",
|
|
46573
46930
|
"--prune",
|
|
46574
46931
|
"origin",
|
|
46575
46932
|
`+refs/heads/${input.targetBranch}:refs/remotes/origin/${input.targetBranch}`
|
|
46576
46933
|
], { env: authEnv, maxBuffer: 4 * 1024 * 1024 });
|
|
46577
|
-
const restored = await
|
|
46934
|
+
const restored = await execFileAsync11("git", [
|
|
46578
46935
|
`--git-dir=${gitCommonDir}`,
|
|
46579
46936
|
"fetch",
|
|
46580
46937
|
"origin",
|
|
@@ -46584,9 +46941,9 @@ async function materializeCornerWorktree(input) {
|
|
|
46584
46941
|
return false;
|
|
46585
46942
|
throw error;
|
|
46586
46943
|
});
|
|
46587
|
-
if (!existsSync10(
|
|
46588
|
-
await
|
|
46589
|
-
await
|
|
46944
|
+
if (!existsSync10(resolve40(path, ".git"))) {
|
|
46945
|
+
await rm17(path, { recursive: true, force: true });
|
|
46946
|
+
await execFileAsync11("git", [
|
|
46590
46947
|
`--git-dir=${gitCommonDir}`,
|
|
46591
46948
|
"worktree",
|
|
46592
46949
|
"add",
|
|
@@ -46602,8 +46959,8 @@ async function materializeCornerWorktree(input) {
|
|
|
46602
46959
|
if (seed.reason !== "no-lockfile") {
|
|
46603
46960
|
console.log(`[thin-core] corner ${input.cornerId} warm node_modules: ${seed.reason}${seed.detail ? ` (${seed.detail})` : ""}`);
|
|
46604
46961
|
}
|
|
46605
|
-
const mobilePath =
|
|
46606
|
-
if (existsSync10(
|
|
46962
|
+
const mobilePath = resolve40(path, "apps/mobile");
|
|
46963
|
+
if (existsSync10(resolve40(mobilePath, "package-lock.json"))) {
|
|
46607
46964
|
const mobileSeed = await seedWarmNodeModules({
|
|
46608
46965
|
worktreePath: mobilePath,
|
|
46609
46966
|
storeRoot: mobileNodeModulesStoreDir(input.supervisorRoot)
|
|
@@ -46613,14 +46970,14 @@ async function materializeCornerWorktree(input) {
|
|
|
46613
46970
|
}
|
|
46614
46971
|
}
|
|
46615
46972
|
}
|
|
46616
|
-
await
|
|
46973
|
+
await execFileAsync11("git", [
|
|
46617
46974
|
`--git-dir=${gitCommonDir}`,
|
|
46618
46975
|
"config",
|
|
46619
46976
|
"extensions.worktreeConfig",
|
|
46620
46977
|
"true"
|
|
46621
46978
|
]);
|
|
46622
|
-
await
|
|
46623
|
-
await
|
|
46979
|
+
await execFileAsync11("git", ["-C", path, "config", "--worktree", "core.bare", "false"]);
|
|
46980
|
+
await execFileAsync11("git", [
|
|
46624
46981
|
"-C",
|
|
46625
46982
|
path,
|
|
46626
46983
|
"config",
|
|
@@ -46628,7 +46985,7 @@ async function materializeCornerWorktree(input) {
|
|
|
46628
46985
|
"credential.https://github.com.helper",
|
|
46629
46986
|
"!f() { echo username=x-access-token; echo password=$GH_TOKEN; }; f"
|
|
46630
46987
|
]);
|
|
46631
|
-
await
|
|
46988
|
+
await execFileAsync11("git", [
|
|
46632
46989
|
"-C",
|
|
46633
46990
|
path,
|
|
46634
46991
|
"config",
|
|
@@ -46636,7 +46993,7 @@ async function materializeCornerWorktree(input) {
|
|
|
46636
46993
|
"user.name",
|
|
46637
46994
|
input.committer.name
|
|
46638
46995
|
]);
|
|
46639
|
-
await
|
|
46996
|
+
await execFileAsync11("git", [
|
|
46640
46997
|
"-C",
|
|
46641
46998
|
path,
|
|
46642
46999
|
"config",
|
|
@@ -46644,8 +47001,8 @@ async function materializeCornerWorktree(input) {
|
|
|
46644
47001
|
"user.email",
|
|
46645
47002
|
`${input.committer.publicKey.slice(0, 16)}@users.noreply.github.com`
|
|
46646
47003
|
]);
|
|
46647
|
-
const top = (await
|
|
46648
|
-
if (await
|
|
47004
|
+
const top = (await execFileAsync11("git", ["-C", path, "rev-parse", "--show-toplevel"])).stdout.trim();
|
|
47005
|
+
if (await realpath3(top) !== await realpath3(path)) {
|
|
46649
47006
|
throw new Error(`corner worktree escaped its isolated root: ${top}`);
|
|
46650
47007
|
}
|
|
46651
47008
|
return { path, gitCommonDir };
|
|
@@ -46660,31 +47017,31 @@ async function mapWithConcurrency(values, limit, visit) {
|
|
|
46660
47017
|
}));
|
|
46661
47018
|
}
|
|
46662
47019
|
async function discoverCornerWorktree(supervisorRoot, cornerId) {
|
|
46663
|
-
const cornersRoot =
|
|
46664
|
-
const path =
|
|
46665
|
-
if (
|
|
47020
|
+
const cornersRoot = resolve40(supervisorRoot, "beeline", "corners");
|
|
47021
|
+
const path = resolve40(cornersRoot, cornerId);
|
|
47022
|
+
if (dirname28(path) !== cornersRoot || !existsSync10(resolve40(path, ".git")))
|
|
46666
47023
|
return void 0;
|
|
46667
47024
|
const [canonicalRoot, canonicalPath] = await Promise.all([
|
|
46668
|
-
|
|
46669
|
-
|
|
47025
|
+
realpath3(cornersRoot),
|
|
47026
|
+
realpath3(path).catch(() => void 0)
|
|
46670
47027
|
]);
|
|
46671
|
-
if (!canonicalPath ||
|
|
47028
|
+
if (!canonicalPath || relative4(canonicalRoot, canonicalPath) !== cornerId) {
|
|
46672
47029
|
throw new Error(`refusing corner ${cornerId} whose checkout path is not canonical`);
|
|
46673
47030
|
}
|
|
46674
|
-
const common = await
|
|
47031
|
+
const common = await execFileAsync11("git", ["-C", path, "rev-parse", "--git-common-dir"]).catch(() => void 0);
|
|
46675
47032
|
if (!common)
|
|
46676
47033
|
return void 0;
|
|
46677
|
-
const gitCommonDir =
|
|
46678
|
-
const repositoriesRoot =
|
|
46679
|
-
const commonRelative =
|
|
46680
|
-
if (!commonRelative || commonRelative === ".." || commonRelative.startsWith(`..${
|
|
47034
|
+
const gitCommonDir = resolve40(path, common.stdout.trim());
|
|
47035
|
+
const repositoriesRoot = resolve40(supervisorRoot, "beeline", "repositories");
|
|
47036
|
+
const commonRelative = relative4(repositoriesRoot, gitCommonDir);
|
|
47037
|
+
if (!commonRelative || commonRelative === ".." || commonRelative.startsWith(`..${sep3}`) || commonRelative.startsWith(sep3)) {
|
|
46681
47038
|
throw new Error(`refusing corner ${cornerId} with git directory outside repository cache`);
|
|
46682
47039
|
}
|
|
46683
47040
|
return { path, gitCommonDir };
|
|
46684
47041
|
}
|
|
46685
47042
|
async function localCornerWorktreeIds(supervisorRoot) {
|
|
46686
|
-
const root =
|
|
46687
|
-
const entries = await
|
|
47043
|
+
const root = resolve40(supervisorRoot, "beeline", "corners");
|
|
47044
|
+
const entries = await readdir11(root, { withFileTypes: true }).catch((error) => {
|
|
46688
47045
|
if (error.code === "ENOENT")
|
|
46689
47046
|
return [];
|
|
46690
47047
|
throw error;
|
|
@@ -46698,12 +47055,12 @@ async function removeCornerWorktreeAndBranches(worktree, options = {}) {
|
|
|
46698
47055
|
const worktreeExists = existsSync10(worktree.path);
|
|
46699
47056
|
const localExists = await gitRefExists(worktree.gitCommonDir, localRef);
|
|
46700
47057
|
if (worktreeExists) {
|
|
46701
|
-
const checkedOut = await
|
|
47058
|
+
const checkedOut = await execFileAsync11("git", ["-C", worktree.path, "symbolic-ref", "--quiet", "HEAD"], { maxBuffer: 4 * 1024 * 1024 }).then((result) => result.stdout.trim(), () => void 0);
|
|
46702
47059
|
if (!worktree.recovered && checkedOut !== localRef) {
|
|
46703
47060
|
throw new Error(`corner worktree branch mismatch: expected ${localRef}`);
|
|
46704
47061
|
}
|
|
46705
47062
|
await assertCornerWorktreePublished(worktree);
|
|
46706
|
-
await
|
|
47063
|
+
await execFileAsync11("git", [
|
|
46707
47064
|
`--git-dir=${worktree.gitCommonDir}`,
|
|
46708
47065
|
"worktree",
|
|
46709
47066
|
"remove",
|
|
@@ -46728,7 +47085,7 @@ async function removeCornerWorktreeAndBranches(worktree, options = {}) {
|
|
|
46728
47085
|
await deleteExactRemoteBranch(worktree.gitCommonDir, remoteRef, worktree.token);
|
|
46729
47086
|
}
|
|
46730
47087
|
if (await gitRefExists(worktree.gitCommonDir, localRef)) {
|
|
46731
|
-
await
|
|
47088
|
+
await execFileAsync11("git", [
|
|
46732
47089
|
`--git-dir=${worktree.gitCommonDir}`,
|
|
46733
47090
|
"branch",
|
|
46734
47091
|
"--delete",
|
|
@@ -46739,18 +47096,18 @@ async function removeCornerWorktreeAndBranches(worktree, options = {}) {
|
|
|
46739
47096
|
}
|
|
46740
47097
|
}
|
|
46741
47098
|
async function assertCornerWorktreePublished(worktree) {
|
|
46742
|
-
const status = async () => (await
|
|
46743
|
-
const originalHead = (await
|
|
47099
|
+
const status = async () => (await execFileAsync11("git", ["-C", worktree.path, "status", "--porcelain=v1", "--untracked-files=all"], { maxBuffer: 4 * 1024 * 1024 })).stdout.trim();
|
|
47100
|
+
const originalHead = (await execFileAsync11("git", ["-C", worktree.path, "rev-parse", "--verify", "HEAD"])).stdout.trim();
|
|
46744
47101
|
if (await status())
|
|
46745
47102
|
throw new Error(`corner ${worktree.cornerId} has unpushed working-tree work`);
|
|
46746
47103
|
await assertPublishedOnOrigin(worktree.gitCommonDir, originalHead, worktree.cornerId, worktree.token);
|
|
46747
|
-
const settledHead = (await
|
|
47104
|
+
const settledHead = (await execFileAsync11("git", ["-C", worktree.path, "rev-parse", "--verify", "HEAD"])).stdout.trim();
|
|
46748
47105
|
if (settledHead !== originalHead || await status()) {
|
|
46749
47106
|
throw new Error(`corner ${worktree.cornerId} changed during cleanup`);
|
|
46750
47107
|
}
|
|
46751
47108
|
}
|
|
46752
47109
|
async function assertLocalBranchPublished(worktree) {
|
|
46753
|
-
const head = (await
|
|
47110
|
+
const head = (await execFileAsync11("git", [
|
|
46754
47111
|
`--git-dir=${worktree.gitCommonDir}`,
|
|
46755
47112
|
"rev-parse",
|
|
46756
47113
|
"--verify",
|
|
@@ -46761,7 +47118,7 @@ async function assertLocalBranchPublished(worktree) {
|
|
|
46761
47118
|
async function assertPublishedOnOrigin(gitCommonDir, head, cornerId, token) {
|
|
46762
47119
|
let published = await originContains(gitCommonDir, head);
|
|
46763
47120
|
if (!published) {
|
|
46764
|
-
await
|
|
47121
|
+
await execFileAsync11("git", [
|
|
46765
47122
|
`--git-dir=${gitCommonDir}`,
|
|
46766
47123
|
"fetch",
|
|
46767
47124
|
"--prune",
|
|
@@ -46777,7 +47134,7 @@ function hasUnpublishedWork(error) {
|
|
|
46777
47134
|
return error instanceof Error && / has unpushed (?:commits|working-tree work)$/.test(error.message);
|
|
46778
47135
|
}
|
|
46779
47136
|
async function originContains(gitCommonDir, head) {
|
|
46780
|
-
const result = await
|
|
47137
|
+
const result = await execFileAsync11("git", [
|
|
46781
47138
|
`--git-dir=${gitCommonDir}`,
|
|
46782
47139
|
"for-each-ref",
|
|
46783
47140
|
"--format=%(refname)",
|
|
@@ -46787,13 +47144,13 @@ async function originContains(gitCommonDir, head) {
|
|
|
46787
47144
|
]);
|
|
46788
47145
|
return Boolean(result.stdout.trim());
|
|
46789
47146
|
}
|
|
46790
|
-
var
|
|
47147
|
+
var execFileAsync11 = promisify11(execFile16);
|
|
46791
47148
|
async function removeCornerScratchWorkspace(input) {
|
|
46792
|
-
const expected =
|
|
46793
|
-
if (
|
|
47149
|
+
const expected = resolve40(input.roomRoot, "scratch");
|
|
47150
|
+
if (resolve40(input.scratchPath) !== expected) {
|
|
46794
47151
|
throw new Error(`refusing to remove scratch outside corner ${input.cornerId}`);
|
|
46795
47152
|
}
|
|
46796
|
-
await
|
|
47153
|
+
await rm17(expected, { recursive: true, force: true });
|
|
46797
47154
|
}
|
|
46798
47155
|
var RoomRuntimeCoordinator = class {
|
|
46799
47156
|
configPath;
|
|
@@ -46820,6 +47177,7 @@ var RoomRuntimeCoordinator = class {
|
|
|
46820
47177
|
* then left alone; the checkout and its commits are kept, never deleted.
|
|
46821
47178
|
*/
|
|
46822
47179
|
archiveCleanupAbandoned = /* @__PURE__ */ new Set();
|
|
47180
|
+
lastCornerScratchSweepAt = 0;
|
|
46823
47181
|
startingCorners = /* @__PURE__ */ new Set();
|
|
46824
47182
|
/**
|
|
46825
47183
|
* Rooms whose start is in flight. `running` is not set until the checkout
|
|
@@ -47060,7 +47418,8 @@ var RoomRuntimeCoordinator = class {
|
|
|
47060
47418
|
return;
|
|
47061
47419
|
try {
|
|
47062
47420
|
const result = await this.options.daemonApi.execute("listRoomCorners", {
|
|
47063
|
-
roomId: room.roomId
|
|
47421
|
+
roomId: room.roomId,
|
|
47422
|
+
activeOnly: true
|
|
47064
47423
|
});
|
|
47065
47424
|
for (const corner of result.corners) {
|
|
47066
47425
|
this.monolithCornerParents.set(corner.cornerId, room.roomId);
|
|
@@ -47100,6 +47459,9 @@ var RoomRuntimeCoordinator = class {
|
|
|
47100
47459
|
if (this.stopped)
|
|
47101
47460
|
return "member";
|
|
47102
47461
|
await this.sweepArchivedCornerWorktrees(archivedCorners, desired);
|
|
47462
|
+
if (this.stopped)
|
|
47463
|
+
return "member";
|
|
47464
|
+
await this.sweepCornerLocalState(archivedCorners, desired);
|
|
47103
47465
|
if (this.stopped)
|
|
47104
47466
|
return "member";
|
|
47105
47467
|
for (const cornerId of this.idleCornerSubscriptions.keys()) {
|
|
@@ -47117,6 +47479,10 @@ var RoomRuntimeCoordinator = class {
|
|
|
47117
47479
|
await this.stopRunning(channelId, running);
|
|
47118
47480
|
this.roomRemovalConfirmations.delete(channelId);
|
|
47119
47481
|
}
|
|
47482
|
+
for (const cornerId of this.monolithCornerParents.keys()) {
|
|
47483
|
+
if (!desired.has(cornerId) && !this.running.has(cornerId) && !this.startingCorners.has(cornerId))
|
|
47484
|
+
this.monolithCornerParents.delete(cornerId);
|
|
47485
|
+
}
|
|
47120
47486
|
this.surfaceHealth.retain(/* @__PURE__ */ new Set([...desired, ...this.running.keys()]));
|
|
47121
47487
|
await mapWithConcurrency(desiredTopRooms, ROOM_JOIN_CONCURRENCY, async (roomId) => {
|
|
47122
47488
|
if (this.stopped)
|
|
@@ -47191,6 +47557,8 @@ var RoomRuntimeCoordinator = class {
|
|
|
47191
47557
|
if (event.archived === true) {
|
|
47192
47558
|
this.unwatchCorner(roomId);
|
|
47193
47559
|
this.surfaceHealth.remove(roomId);
|
|
47560
|
+
if (!this.running.has(roomId))
|
|
47561
|
+
this.monolithCornerParents.delete(roomId);
|
|
47194
47562
|
return;
|
|
47195
47563
|
}
|
|
47196
47564
|
this.roomRemovalConfirmations.delete(roomId);
|
|
@@ -47228,18 +47596,20 @@ var RoomRuntimeCoordinator = class {
|
|
|
47228
47596
|
} catch (error) {
|
|
47229
47597
|
console.error(`[thin-core] corner ${channelId} cleanup failed; will retry:`, error);
|
|
47230
47598
|
}
|
|
47599
|
+
if (running.worktree || running.scratch)
|
|
47600
|
+
await this.cleanupArchivedCornerLocalState(channelId);
|
|
47231
47601
|
}
|
|
47232
47602
|
roomRecord(roomId) {
|
|
47233
47603
|
return this.runtime.rooms.find((room) => room.channelId === roomId);
|
|
47234
47604
|
}
|
|
47235
47605
|
roomRoot(roomId) {
|
|
47236
|
-
return this.roomRecord(roomId)?.root ??
|
|
47606
|
+
return this.roomRecord(roomId)?.root ?? resolve40(dirname28(this.configPath), "rooms", roomId);
|
|
47237
47607
|
}
|
|
47238
47608
|
roomAgentHomeRoot(workspaceRoot, required = false) {
|
|
47239
47609
|
const flag = process.env.BUZZY_BODY_ROOM_HOME;
|
|
47240
47610
|
if (!required && flag === "0")
|
|
47241
47611
|
return void 0;
|
|
47242
|
-
const home =
|
|
47612
|
+
const home = resolve40(workspaceRoot, "agent-home");
|
|
47243
47613
|
if (!required && flag !== "1" && !existsSync10(home) && existsSync10(workspaceRoot))
|
|
47244
47614
|
return void 0;
|
|
47245
47615
|
try {
|
|
@@ -47255,10 +47625,10 @@ var RoomRuntimeCoordinator = class {
|
|
|
47255
47625
|
return {
|
|
47256
47626
|
...this.baseConfig,
|
|
47257
47627
|
workspaceRoot,
|
|
47258
|
-
agentPrivateRoot:
|
|
47259
|
-
agentMemoryRoot:
|
|
47260
|
-
openRouterRoutingCacheDir: openRouterRoutingCacheDir(
|
|
47261
|
-
turnTraceDir: turnTraceDirectory(
|
|
47628
|
+
agentPrivateRoot: resolve40(workspaceRoot, "agent-private"),
|
|
47629
|
+
agentMemoryRoot: resolve40(dirname28(this.configPath), "memory"),
|
|
47630
|
+
openRouterRoutingCacheDir: openRouterRoutingCacheDir(dirname28(this.configPath)),
|
|
47631
|
+
turnTraceDir: turnTraceDirectory(dirname28(this.configPath)),
|
|
47262
47632
|
...agentHomeRoot ? { agentHomeRoot } : {}
|
|
47263
47633
|
};
|
|
47264
47634
|
}
|
|
@@ -47339,17 +47709,17 @@ var RoomRuntimeCoordinator = class {
|
|
|
47339
47709
|
const remote = roomCheckoutRemote(repository.remote);
|
|
47340
47710
|
const targetBranch = repository.targetBranch || "main";
|
|
47341
47711
|
const checkoutId = createHash14("sha256").update(`${roomId}\0${remote}\0${targetBranch}`).digest("hex").slice(0, 24);
|
|
47342
|
-
const path =
|
|
47343
|
-
await mkdir27(
|
|
47712
|
+
const path = resolve40(this.runtime.supervisorRoot, "beeline", "room-checkouts", checkoutId);
|
|
47713
|
+
await mkdir27(dirname28(path), { recursive: true, mode: 448 });
|
|
47344
47714
|
const token = remote.startsWith("https://github.com/") ? await this.parentRepositoryToken(roomId) : void 0;
|
|
47345
47715
|
const env = token ? githubGitEnv(token.token) : process.env;
|
|
47346
|
-
if (!existsSync10(
|
|
47347
|
-
await
|
|
47716
|
+
if (!existsSync10(resolve40(path, ".git"))) {
|
|
47717
|
+
await execFileAsync11("git", ["clone", "--no-checkout", remote, path], {
|
|
47348
47718
|
env,
|
|
47349
47719
|
maxBuffer: 4 * 1024 * 1024
|
|
47350
47720
|
});
|
|
47351
47721
|
}
|
|
47352
|
-
const fetched = await
|
|
47722
|
+
const fetched = await execFileAsync11("git", [
|
|
47353
47723
|
"-C",
|
|
47354
47724
|
path,
|
|
47355
47725
|
"fetch",
|
|
@@ -47365,7 +47735,7 @@ var RoomRuntimeCoordinator = class {
|
|
|
47365
47735
|
void this.options.daemonApi.execute("noteEmptyRoomRepository", { roomId }).catch((error) => console.warn(`[thin-core] Room ${roomId} empty-repository notice failed:`, error));
|
|
47366
47736
|
return this.roomRoot(roomId);
|
|
47367
47737
|
}
|
|
47368
|
-
await
|
|
47738
|
+
await execFileAsync11("git", ["-C", path, "checkout", "--detach", "--force", `origin/${targetBranch}`], {
|
|
47369
47739
|
env,
|
|
47370
47740
|
maxBuffer: 4 * 1024 * 1024
|
|
47371
47741
|
});
|
|
@@ -47380,7 +47750,7 @@ var RoomRuntimeCoordinator = class {
|
|
|
47380
47750
|
const cwd = await this.materializeRoomCheckout(roomId, repository);
|
|
47381
47751
|
if (cwd === this.roomRoot(roomId))
|
|
47382
47752
|
return { cwd };
|
|
47383
|
-
const { stdout: stdout6 } = await
|
|
47753
|
+
const { stdout: stdout6 } = await execFileAsync11("git", ["-C", cwd, "rev-parse", "--verify", "HEAD"]);
|
|
47384
47754
|
return { cwd, branch, commit: stdout6.trim() };
|
|
47385
47755
|
} catch (error) {
|
|
47386
47756
|
console.warn(`[thin-core] Room ${roomId} checkout refresh unavailable:`, error);
|
|
@@ -47430,9 +47800,11 @@ var RoomRuntimeCoordinator = class {
|
|
|
47430
47800
|
featureBranch,
|
|
47431
47801
|
token: granted.token
|
|
47432
47802
|
}) : void 0;
|
|
47433
|
-
const workspacePath = worktree?.path ??
|
|
47803
|
+
const workspacePath = worktree?.path ?? resolve40(this.roomRoot(corner.cornerId), "scratch");
|
|
47434
47804
|
if (!worktree)
|
|
47435
47805
|
await mkdir27(workspacePath, { recursive: true, mode: 448 });
|
|
47806
|
+
await writePrivateFileAtomically(resolve40(this.roomRoot(corner.cornerId), ".beeline-corner.json"), `${JSON.stringify({ cornerId: corner.cornerId, parentRoomId: corner.parentRoomId })}
|
|
47807
|
+
`);
|
|
47436
47808
|
if (worktree && shouldPostInitialCornerWorkingState(restore)) {
|
|
47437
47809
|
await this.options.daemonApi.execute("postCornerRemoteState", {
|
|
47438
47810
|
cornerId: corner.cornerId,
|
|
@@ -47486,10 +47858,11 @@ var RoomRuntimeCoordinator = class {
|
|
|
47486
47858
|
this.surfaceHealth.degraded(corner.cornerId, "corner command loop exited");
|
|
47487
47859
|
console.error(`[thin-core] corner ${corner.cornerId} failed:`, error);
|
|
47488
47860
|
}
|
|
47489
|
-
}).finally(() => {
|
|
47861
|
+
}).finally(async () => {
|
|
47490
47862
|
if (this.running.get(corner.cornerId)?.body === loop) {
|
|
47491
47863
|
this.running.delete(corner.cornerId);
|
|
47492
47864
|
}
|
|
47865
|
+
await this.cleanupArchivedCornerLocalState(corner.cornerId).catch((error) => console.error(`[thin-core] corner ${corner.cornerId} local cleanup deferred:`, error));
|
|
47493
47866
|
});
|
|
47494
47867
|
if (this.stopped) {
|
|
47495
47868
|
controller.abort();
|
|
@@ -47606,7 +47979,7 @@ var RoomRuntimeCoordinator = class {
|
|
|
47606
47979
|
await this.restartRunningRoomForRepositoryChange(roomId);
|
|
47607
47980
|
if (this.stopped)
|
|
47608
47981
|
return;
|
|
47609
|
-
const result = await this.options.daemonApi.execute("listRoomCorners", { roomId });
|
|
47982
|
+
const result = await this.options.daemonApi.execute("listRoomCorners", { roomId, activeOnly: true });
|
|
47610
47983
|
for (const corner of result.corners) {
|
|
47611
47984
|
this.monolithCornerParents.set(corner.cornerId, roomId);
|
|
47612
47985
|
if (corner.archived)
|
|
@@ -47763,6 +48136,12 @@ var RoomRuntimeCoordinator = class {
|
|
|
47763
48136
|
} catch (error) {
|
|
47764
48137
|
if (hasUnpublishedWork(error)) {
|
|
47765
48138
|
this.archiveCleanupAbandoned.add(cornerId);
|
|
48139
|
+
try {
|
|
48140
|
+
const saved = await preserveUnpublishedCornerWorktree(worktree, "archived with unpublished local work");
|
|
48141
|
+
console.warn(`[thin-core] corner ${cornerId} recoverable at ${saved.pointer}; pruned ${saved.pruned.join(", ") || "no generated directories"}`);
|
|
48142
|
+
} catch (preserveError) {
|
|
48143
|
+
console.error(`[thin-core] corner ${cornerId} recovery preservation failed:`, preserveError);
|
|
48144
|
+
}
|
|
47766
48145
|
console.error(`[thin-core] corner ${cornerId} branch cleanup abandoned; unpublished work kept:`, error);
|
|
47767
48146
|
continue;
|
|
47768
48147
|
}
|
|
@@ -47783,11 +48162,14 @@ var RoomRuntimeCoordinator = class {
|
|
|
47783
48162
|
continue;
|
|
47784
48163
|
if (!this.archiveCleanupDue(cornerId))
|
|
47785
48164
|
continue;
|
|
48165
|
+
if (this.archiveCleanupAbandoned.has(cornerId))
|
|
48166
|
+
continue;
|
|
47786
48167
|
if (this.archiveCleanupAccessDenied.has(cornerId) && !corners.has(cornerId))
|
|
47787
48168
|
continue;
|
|
47788
48169
|
this.archiveCleanupAccessDenied.delete(cornerId);
|
|
47789
48170
|
let corner = corners.get(cornerId);
|
|
47790
48171
|
let discovered;
|
|
48172
|
+
let candidate;
|
|
47791
48173
|
try {
|
|
47792
48174
|
discovered = await discoverCornerWorktree(this.runtime.supervisorRoot, cornerId);
|
|
47793
48175
|
if (!discovered) {
|
|
@@ -47813,22 +48195,33 @@ var RoomRuntimeCoordinator = class {
|
|
|
47813
48195
|
throw new Error(`archived corner ${corner.cornerId} has no authoritative repository`);
|
|
47814
48196
|
}
|
|
47815
48197
|
const expectedCommonDir = cornerRepositoryCacheDir(this.runtime.supervisorRoot, repository.remote);
|
|
47816
|
-
if (
|
|
48198
|
+
if (resolve40(discovered.gitCommonDir) !== expectedCommonDir) {
|
|
47817
48199
|
throw new Error(`archived corner ${corner.cornerId} repository cache does not match`);
|
|
47818
48200
|
}
|
|
47819
48201
|
if (!restore.featureBranch) {
|
|
47820
48202
|
throw new Error(`archived corner ${corner.cornerId} has no authoritative feature branch`);
|
|
47821
48203
|
}
|
|
47822
|
-
|
|
48204
|
+
candidate = {
|
|
47823
48205
|
...discovered,
|
|
47824
48206
|
cornerId: corner.cornerId,
|
|
47825
48207
|
branch: restore.featureBranch,
|
|
47826
48208
|
parentRoomId: corner.parentRoomId,
|
|
47827
48209
|
token: "",
|
|
47828
48210
|
recovered: true
|
|
47829
|
-
}
|
|
48211
|
+
};
|
|
48212
|
+
await this.reapCornerWorktree(candidate);
|
|
47830
48213
|
console.log(`[thin-core] swept archived corner worktree ${cornerId}`);
|
|
47831
48214
|
} catch (error) {
|
|
48215
|
+
if (candidate && hasUnpublishedWork(error)) {
|
|
48216
|
+
this.archiveCleanupAbandoned.add(cornerId);
|
|
48217
|
+
try {
|
|
48218
|
+
const saved = await preserveUnpublishedCornerWorktree(candidate, "archived with unpublished local work");
|
|
48219
|
+
console.warn(`[thin-core] archived corner ${cornerId} recoverable at ${saved.pointer}; pruned ${saved.pruned.join(", ") || "no generated directories"}`);
|
|
48220
|
+
} catch (preserveError) {
|
|
48221
|
+
console.error(`[thin-core] archived corner ${cornerId} recovery preservation failed:`, preserveError);
|
|
48222
|
+
}
|
|
48223
|
+
continue;
|
|
48224
|
+
}
|
|
47832
48225
|
if (error instanceof DaemonApiError && error.status === 403)
|
|
47833
48226
|
this.archiveCleanupAccessDenied.add(cornerId);
|
|
47834
48227
|
else
|
|
@@ -47885,6 +48278,64 @@ var RoomRuntimeCoordinator = class {
|
|
|
47885
48278
|
scratchPath: scratch.path
|
|
47886
48279
|
});
|
|
47887
48280
|
}
|
|
48281
|
+
/** Reap a corner's private state only after the server confirms archive and
|
|
48282
|
+
* its ACP session has suspended. A missing/failed read is never authority. */
|
|
48283
|
+
async cleanupArchivedCornerLocalState(cornerId, knownArchive) {
|
|
48284
|
+
if (this.running.has(cornerId) || this.startingCorners.has(cornerId))
|
|
48285
|
+
return false;
|
|
48286
|
+
const root = resolve40(dirname28(this.configPath), "rooms", cornerId);
|
|
48287
|
+
if (this.roomRoot(cornerId) !== root || !/^[a-zA-Z0-9-]{1,80}$/.test(cornerId))
|
|
48288
|
+
return false;
|
|
48289
|
+
const info = await lstat7(root).catch(() => void 0);
|
|
48290
|
+
if (!info?.isDirectory() || await realpath3(root) !== root)
|
|
48291
|
+
return false;
|
|
48292
|
+
let archived = knownArchive?.has(cornerId) ?? false;
|
|
48293
|
+
if (!archived) {
|
|
48294
|
+
try {
|
|
48295
|
+
const restore = await this.options.daemonApi.execute("getCornerRestoreState", { cornerId });
|
|
48296
|
+
archived = restore.archived === true;
|
|
48297
|
+
} catch {
|
|
48298
|
+
return false;
|
|
48299
|
+
}
|
|
48300
|
+
}
|
|
48301
|
+
if (!archived)
|
|
48302
|
+
return false;
|
|
48303
|
+
await this.scheduler.suspend(cornerId);
|
|
48304
|
+
await rm17(resolve40(root, "scratch"), { recursive: true, force: true });
|
|
48305
|
+
await rm17(resolve40(root, "agent-home"), { recursive: true, force: true });
|
|
48306
|
+
await rm17(resolve40(root, ".beeline-corner.json"), { force: true });
|
|
48307
|
+
return true;
|
|
48308
|
+
}
|
|
48309
|
+
/** Recover chat-only scratch and per-member homes after missed close events
|
|
48310
|
+
* or a helper restart. A marker identifies new code corners after their
|
|
48311
|
+
* checkout has already gone; a scratch directory identifies legacy chat
|
|
48312
|
+
* corners. Active scratch gets a 14-day file TTL, never a wholesale reap. */
|
|
48313
|
+
async sweepCornerLocalState(archived, desired) {
|
|
48314
|
+
const root = resolve40(dirname28(this.configPath), "rooms");
|
|
48315
|
+
const due = this.now() - this.lastCornerScratchSweepAt >= 6 * 60 * 6e4;
|
|
48316
|
+
if (due)
|
|
48317
|
+
this.lastCornerScratchSweepAt = this.now();
|
|
48318
|
+
for (const entry of await readdir11(root, { withFileTypes: true }).catch(() => [])) {
|
|
48319
|
+
if (!entry.isDirectory() || !/^[a-zA-Z0-9-]{1,80}$/.test(entry.name))
|
|
48320
|
+
continue;
|
|
48321
|
+
const roomRoot = resolve40(root, entry.name);
|
|
48322
|
+
const scratch = resolve40(roomRoot, "scratch");
|
|
48323
|
+
const marker = resolve40(roomRoot, ".beeline-corner.json");
|
|
48324
|
+
const hasScratch = (await lstat7(scratch).catch(() => void 0))?.isDirectory() ?? false;
|
|
48325
|
+
const hasMarker = (await lstat7(marker).catch(() => void 0))?.isFile() ?? false;
|
|
48326
|
+
if (!hasScratch && !hasMarker)
|
|
48327
|
+
continue;
|
|
48328
|
+
if (desired.has(entry.name)) {
|
|
48329
|
+
if (due && hasScratch && !this.startingCorners.has(entry.name) && !this.running.get(entry.name)?.body.isBusy()) {
|
|
48330
|
+
await sweepStaleCornerScratch(scratch, this.now(), CORNER_SCRATCH_TTL_MS).catch((error) => console.error(`[thin-core] corner ${entry.name} scratch TTL sweep failed:`, error));
|
|
48331
|
+
}
|
|
48332
|
+
continue;
|
|
48333
|
+
}
|
|
48334
|
+
if (this.running.has(entry.name) || this.startingCorners.has(entry.name))
|
|
48335
|
+
continue;
|
|
48336
|
+
await this.cleanupArchivedCornerLocalState(entry.name, archived).catch((error) => console.error(`[thin-core] corner ${entry.name} local cleanup deferred:`, error));
|
|
48337
|
+
}
|
|
48338
|
+
}
|
|
47888
48339
|
notePoll(roomId) {
|
|
47889
48340
|
this.surfaceHealth.intakeReady(roomId);
|
|
47890
48341
|
const room = this.running.get(roomId);
|
|
@@ -47969,7 +48420,7 @@ function githubGitEnv(token) {
|
|
|
47969
48420
|
}
|
|
47970
48421
|
async function gitRefExists(gitCommonDir, ref) {
|
|
47971
48422
|
try {
|
|
47972
|
-
await
|
|
48423
|
+
await execFileAsync11("git", [
|
|
47973
48424
|
`--git-dir=${gitCommonDir}`,
|
|
47974
48425
|
"show-ref",
|
|
47975
48426
|
"--verify",
|
|
@@ -47985,7 +48436,7 @@ async function gitRefExists(gitCommonDir, ref) {
|
|
|
47985
48436
|
}
|
|
47986
48437
|
async function repositoryHeadRef(gitCommonDir) {
|
|
47987
48438
|
try {
|
|
47988
|
-
const head = await
|
|
48439
|
+
const head = await execFileAsync11("git", [
|
|
47989
48440
|
`--git-dir=${gitCommonDir}`,
|
|
47990
48441
|
"symbolic-ref",
|
|
47991
48442
|
"--quiet",
|
|
@@ -48005,7 +48456,7 @@ ${gitStderr(error)}`);
|
|
|
48005
48456
|
}
|
|
48006
48457
|
async function deleteExactRemoteBranch(gitCommonDir, remoteRef, token, options = {}) {
|
|
48007
48458
|
const authEnv = githubGitEnv(token);
|
|
48008
|
-
const listRemote = () =>
|
|
48459
|
+
const listRemote = () => execFileAsync11("git", [`--git-dir=${gitCommonDir}`, "ls-remote", "--heads", "origin", remoteRef], {
|
|
48009
48460
|
env: authEnv,
|
|
48010
48461
|
maxBuffer: 4 * 1024 * 1024
|
|
48011
48462
|
});
|
|
@@ -48021,7 +48472,7 @@ async function deleteExactRemoteBranch(gitCommonDir, remoteRef, token, options =
|
|
|
48021
48472
|
try {
|
|
48022
48473
|
const remote = await listRemote();
|
|
48023
48474
|
if (remote.stdout.trim()) {
|
|
48024
|
-
await
|
|
48475
|
+
await execFileAsync11("git", [`--git-dir=${gitCommonDir}`, "push", "origin", `:${remoteRef}`], {
|
|
48025
48476
|
env: authEnv,
|
|
48026
48477
|
maxBuffer: 4 * 1024 * 1024
|
|
48027
48478
|
});
|
|
@@ -48163,15 +48614,15 @@ var ThinDaemonCore = class {
|
|
|
48163
48614
|
};
|
|
48164
48615
|
|
|
48165
48616
|
// apps/body/dist/force-update-journal.js
|
|
48166
|
-
import { mkdirSync as mkdirSync4, readFileSync as
|
|
48167
|
-
import { resolve as
|
|
48617
|
+
import { mkdirSync as mkdirSync4, readFileSync as readFileSync10, renameSync, writeFileSync as writeFileSync5 } from "node:fs";
|
|
48618
|
+
import { resolve as resolve41 } from "node:path";
|
|
48168
48619
|
var NAME = "force-update-interruptions.json";
|
|
48169
48620
|
function pathFor(runtimeDir) {
|
|
48170
|
-
return
|
|
48621
|
+
return resolve41(runtimeDir, NAME);
|
|
48171
48622
|
}
|
|
48172
48623
|
function read(runtimeDir) {
|
|
48173
48624
|
try {
|
|
48174
|
-
const rows = JSON.parse(
|
|
48625
|
+
const rows = JSON.parse(readFileSync10(pathFor(runtimeDir), "utf8"));
|
|
48175
48626
|
if (!Array.isArray(rows))
|
|
48176
48627
|
throw new Error("invalid force-update interruption journal");
|
|
48177
48628
|
return rows.map((row) => {
|
|
@@ -48245,17 +48696,17 @@ function staleGeneration(error) {
|
|
|
48245
48696
|
init_launchd();
|
|
48246
48697
|
init_systemd();
|
|
48247
48698
|
import { mkdir as mkdir28, rename as rename11 } from "node:fs/promises";
|
|
48248
|
-
import { dirname as
|
|
48699
|
+
import { dirname as dirname29, resolve as resolve42 } from "node:path";
|
|
48249
48700
|
async function retireRemovedAgent(runtime, options = {}) {
|
|
48250
|
-
const deletedRoot =
|
|
48251
|
-
const target =
|
|
48701
|
+
const deletedRoot = resolve42(runtime.supervisorRoot, "beeline", "deleted-runtimes");
|
|
48702
|
+
const target = resolve42(deletedRoot, `${runtime.agent.publicKey}-${Date.now()}`);
|
|
48252
48703
|
return relocateAgentRuntime(runtime, target, {
|
|
48253
48704
|
...options.run ? { run: options.run } : {}
|
|
48254
48705
|
});
|
|
48255
48706
|
}
|
|
48256
48707
|
async function relocateAgentRuntime(runtime, target, options = {}) {
|
|
48257
48708
|
const source = runtimeDirectory(runtime.supervisorRoot, runtime.agent.publicKey);
|
|
48258
|
-
const destination =
|
|
48709
|
+
const destination = resolve42(target);
|
|
48259
48710
|
if (destination === source || destination.startsWith(`${source}/`)) {
|
|
48260
48711
|
throw new Error("agent runtime destination must be outside the live runtime");
|
|
48261
48712
|
}
|
|
@@ -48268,7 +48719,7 @@ async function relocateAgentRuntime(runtime, target, options = {}) {
|
|
|
48268
48719
|
...options.run ? { run: options.run } : {}
|
|
48269
48720
|
});
|
|
48270
48721
|
}
|
|
48271
|
-
await mkdir28(
|
|
48722
|
+
await mkdir28(dirname29(destination), { recursive: true, mode: 448 });
|
|
48272
48723
|
await rename11(source, destination);
|
|
48273
48724
|
return destination;
|
|
48274
48725
|
}
|
|
@@ -48278,8 +48729,8 @@ init_self_update();
|
|
|
48278
48729
|
init_systemd();
|
|
48279
48730
|
|
|
48280
48731
|
// apps/body/dist/release-status.js
|
|
48281
|
-
import { readFile as readFile31, readdir as
|
|
48282
|
-
import { resolve as
|
|
48732
|
+
import { readFile as readFile31, readdir as readdir12, rename as rename12, writeFile as writeFile21 } from "node:fs/promises";
|
|
48733
|
+
import { resolve as resolve43 } from "node:path";
|
|
48283
48734
|
var DAEMON_RELEASE_STATUS_FILE = "release-status.json";
|
|
48284
48735
|
var RELEASE_VERSION = /^v\d+\.\d+\.\d+$/;
|
|
48285
48736
|
var SOURCE_SHA = /^[0-9a-f]{7,64}$/;
|
|
@@ -48296,7 +48747,7 @@ async function writeDaemonReleaseStatus(runtimeDir, agentPubkey, identity, optio
|
|
|
48296
48747
|
pid: options.pid ?? process.pid,
|
|
48297
48748
|
readyAt: (options.now?.() ?? /* @__PURE__ */ new Date()).toISOString()
|
|
48298
48749
|
};
|
|
48299
|
-
const target =
|
|
48750
|
+
const target = resolve43(runtimeDir, DAEMON_RELEASE_STATUS_FILE);
|
|
48300
48751
|
const temporary = `${target}.${status.pid}.tmp`;
|
|
48301
48752
|
await writeFile21(temporary, `${JSON.stringify(status, null, 2)}
|
|
48302
48753
|
`, { mode: 384 });
|
|
@@ -48305,8 +48756,8 @@ async function writeDaemonReleaseStatus(runtimeDir, agentPubkey, identity, optio
|
|
|
48305
48756
|
}
|
|
48306
48757
|
|
|
48307
48758
|
// apps/body/dist/scratch-sweep.js
|
|
48308
|
-
import { lstat as
|
|
48309
|
-
import { resolve as
|
|
48759
|
+
import { lstat as lstat8, readdir as readdir13, rmdir as rmdir3, unlink as unlink10 } from "node:fs/promises";
|
|
48760
|
+
import { resolve as resolve44 } from "node:path";
|
|
48310
48761
|
var DEFAULT_SCRATCH_TTL_HOURS = 72;
|
|
48311
48762
|
var NEVER_SWEEP_SUBDIR_NAMES = new Set(HOME_SUBDIRS.filter((name) => name !== "tmp"));
|
|
48312
48763
|
function scratchTtlMs(env = process.env) {
|
|
@@ -48315,10 +48766,10 @@ function scratchTtlMs(env = process.env) {
|
|
|
48315
48766
|
return (Number.isFinite(hours) && hours > 0 ? hours : DEFAULT_SCRATCH_TTL_HOURS) * 60 * 60 * 1e3;
|
|
48316
48767
|
}
|
|
48317
48768
|
async function discoverAttachScratchRoots(runtimeDir) {
|
|
48318
|
-
const roomsDir =
|
|
48769
|
+
const roomsDir = resolve44(runtimeDir, "rooms");
|
|
48319
48770
|
let entries;
|
|
48320
48771
|
try {
|
|
48321
|
-
entries = await
|
|
48772
|
+
entries = await readdir13(roomsDir, { withFileTypes: true });
|
|
48322
48773
|
} catch {
|
|
48323
48774
|
return [];
|
|
48324
48775
|
}
|
|
@@ -48326,8 +48777,8 @@ async function discoverAttachScratchRoots(runtimeDir) {
|
|
|
48326
48777
|
for (const entry of entries) {
|
|
48327
48778
|
if (!entry.isDirectory())
|
|
48328
48779
|
continue;
|
|
48329
|
-
const home =
|
|
48330
|
-
const stats = await
|
|
48780
|
+
const home = resolve44(roomsDir, entry.name, "agent-home");
|
|
48781
|
+
const stats = await lstat8(home).catch(() => void 0);
|
|
48331
48782
|
if (stats?.isDirectory())
|
|
48332
48783
|
roots.push(home);
|
|
48333
48784
|
}
|
|
@@ -48336,7 +48787,7 @@ async function discoverAttachScratchRoots(runtimeDir) {
|
|
|
48336
48787
|
async function removeStaleFiles(dir, cutoffMs, protectNamesHere) {
|
|
48337
48788
|
let entries;
|
|
48338
48789
|
try {
|
|
48339
|
-
entries = await
|
|
48790
|
+
entries = await readdir13(dir, { withFileTypes: true });
|
|
48340
48791
|
} catch {
|
|
48341
48792
|
return { removedFiles: 0, removedBytes: 0 };
|
|
48342
48793
|
}
|
|
@@ -48345,22 +48796,22 @@ async function removeStaleFiles(dir, cutoffMs, protectNamesHere) {
|
|
|
48345
48796
|
for (const entry of entries) {
|
|
48346
48797
|
if (protectNamesHere && NEVER_SWEEP_SUBDIR_NAMES.has(entry.name))
|
|
48347
48798
|
continue;
|
|
48348
|
-
const path =
|
|
48349
|
-
const stats = await
|
|
48799
|
+
const path = resolve44(dir, entry.name);
|
|
48800
|
+
const stats = await lstat8(path).catch(() => void 0);
|
|
48350
48801
|
if (!stats || stats.isSymbolicLink())
|
|
48351
48802
|
continue;
|
|
48352
48803
|
if (stats.isDirectory()) {
|
|
48353
48804
|
const nested = await removeStaleFiles(path, cutoffMs, false);
|
|
48354
48805
|
removedFiles += nested.removedFiles;
|
|
48355
48806
|
removedBytes += nested.removedBytes;
|
|
48356
|
-
const remaining = await
|
|
48807
|
+
const remaining = await readdir13(path).catch(() => void 0);
|
|
48357
48808
|
if (remaining && remaining.length === 0)
|
|
48358
|
-
await
|
|
48809
|
+
await rmdir3(path).catch(() => void 0);
|
|
48359
48810
|
continue;
|
|
48360
48811
|
}
|
|
48361
48812
|
if (!stats.isFile() || stats.mtimeMs >= cutoffMs)
|
|
48362
48813
|
continue;
|
|
48363
|
-
await
|
|
48814
|
+
await unlink10(path).catch(() => void 0);
|
|
48364
48815
|
removedFiles += 1;
|
|
48365
48816
|
removedBytes += stats.size;
|
|
48366
48817
|
}
|
|
@@ -48371,7 +48822,7 @@ async function sweepAttachScratchRoots(roots, ttlMs, now2 = Date.now()) {
|
|
|
48371
48822
|
let removedFiles = 0;
|
|
48372
48823
|
let removedBytes = 0;
|
|
48373
48824
|
for (const root of roots) {
|
|
48374
|
-
const stats = await
|
|
48825
|
+
const stats = await lstat8(root).catch(() => void 0);
|
|
48375
48826
|
if (!stats?.isDirectory())
|
|
48376
48827
|
continue;
|
|
48377
48828
|
const result = await removeStaleFiles(root, cutoffMs, true);
|
|
@@ -48394,7 +48845,7 @@ function runScratchSweepLogged(runtimeDir) {
|
|
|
48394
48845
|
void runScratchSweep(runtimeDir).catch((error) => console.error("[body] scratch sweep failed:", error));
|
|
48395
48846
|
}
|
|
48396
48847
|
async function runAgentRuntime(configPath, host, signal) {
|
|
48397
|
-
const runtimeDir =
|
|
48848
|
+
const runtimeDir = dirname30(configPath);
|
|
48398
48849
|
await convergeRuntimeRecordFileModes(configPath);
|
|
48399
48850
|
const accessMigration = await migrateRuntimeRecordAccessPolicy(configPath);
|
|
48400
48851
|
let runtime = accessMigration.runtime;
|
|
@@ -48430,7 +48881,7 @@ async function runAgentRuntime(configPath, host, signal) {
|
|
|
48430
48881
|
BUZZ_DEV_MCP_BIN: runtime.mcpBinary
|
|
48431
48882
|
};
|
|
48432
48883
|
const config = loadBodyConfig({
|
|
48433
|
-
workspaceRoot:
|
|
48884
|
+
workspaceRoot: resolve45(runtimeDir, "workspace"),
|
|
48434
48885
|
llmEnvFile: runtime.llmEnvFile,
|
|
48435
48886
|
env,
|
|
48436
48887
|
agent
|
|
@@ -48740,7 +49191,7 @@ async function runAgentRuntime(configPath, host, signal) {
|
|
|
48740
49191
|
return exitReason ?? lifecycle.stopReason ?? "stopped";
|
|
48741
49192
|
}
|
|
48742
49193
|
function registryBrokerSocketPath(home, agentId) {
|
|
48743
|
-
return
|
|
49194
|
+
return join23(home ?? homedir19(), ".beeline", "registry-mcp-broker", `${process.pid}-${agentId.slice(0, 8)}.sock`);
|
|
48744
49195
|
}
|
|
48745
49196
|
function interruptHostedAgent(agent) {
|
|
48746
49197
|
agent.lifecycle.quiesce("force-update");
|
|
@@ -48781,6 +49232,78 @@ var ForceUpdateCoordinator = class {
|
|
|
48781
49232
|
init_launchd();
|
|
48782
49233
|
init_self_update();
|
|
48783
49234
|
init_systemd();
|
|
49235
|
+
|
|
49236
|
+
// apps/body/dist/host-disk-retention.js
|
|
49237
|
+
import { execFile as execFile17 } from "node:child_process";
|
|
49238
|
+
import { lstat as lstat9, readdir as readdir14, rm as rm18 } from "node:fs/promises";
|
|
49239
|
+
import { join as join24, resolve as resolve46 } from "node:path";
|
|
49240
|
+
import { promisify as promisify12 } from "node:util";
|
|
49241
|
+
var execFileAsync12 = promisify12(execFile17);
|
|
49242
|
+
var DELETED_RUNTIME_TTL_MS = 30 * 24 * 60 * 6e4;
|
|
49243
|
+
var REPOSITORY_CACHE_TTL_MS = 30 * 24 * 60 * 6e4;
|
|
49244
|
+
async function pruneDeletedRuntimes(supervisorRoot, now2 = Date.now()) {
|
|
49245
|
+
const root = resolve46(supervisorRoot, "beeline", "deleted-runtimes");
|
|
49246
|
+
const removed = [];
|
|
49247
|
+
for (const entry of await readdir14(root, { withFileTypes: true }).catch(() => [])) {
|
|
49248
|
+
const match = /^([a-f0-9]{64})-(\d{13})$/.exec(entry.name);
|
|
49249
|
+
if (!entry.isDirectory() || !match || now2 - Number(match[2]) < DELETED_RUNTIME_TTL_MS)
|
|
49250
|
+
continue;
|
|
49251
|
+
const path = join24(root, entry.name);
|
|
49252
|
+
if (!(await lstat9(path)).isDirectory())
|
|
49253
|
+
continue;
|
|
49254
|
+
await rm18(path, { recursive: true, force: true });
|
|
49255
|
+
removed.push(path);
|
|
49256
|
+
}
|
|
49257
|
+
return removed;
|
|
49258
|
+
}
|
|
49259
|
+
async function pruneRepositoryCaches(supervisorRoot, now2 = Date.now()) {
|
|
49260
|
+
const root = resolve46(supervisorRoot, "beeline", "repositories");
|
|
49261
|
+
const removed = [];
|
|
49262
|
+
for (const entry of await readdir14(root, { withFileTypes: true }).catch(() => [])) {
|
|
49263
|
+
if (!entry.isDirectory() || !/^[a-f0-9]{24}\.git$/.test(entry.name))
|
|
49264
|
+
continue;
|
|
49265
|
+
const path = join24(root, entry.name);
|
|
49266
|
+
const info = await lstat9(path);
|
|
49267
|
+
if (!info.isDirectory() || now2 - info.mtimeMs < REPOSITORY_CACHE_TTL_MS)
|
|
49268
|
+
continue;
|
|
49269
|
+
const listing = await execFileAsync12("git", [`--git-dir=${path}`, "worktree", "list", "--porcelain"]).then((result) => result.stdout, () => void 0);
|
|
49270
|
+
if (listing === void 0)
|
|
49271
|
+
continue;
|
|
49272
|
+
const attached = listing.split("\n").some((line) => line.startsWith("worktree ") && resolve46(line.slice("worktree ".length)) !== path);
|
|
49273
|
+
if (attached)
|
|
49274
|
+
continue;
|
|
49275
|
+
const refs = await execFileAsync12("git", [
|
|
49276
|
+
`--git-dir=${path}`,
|
|
49277
|
+
"for-each-ref",
|
|
49278
|
+
"--format=%(refname) %(objectname)"
|
|
49279
|
+
]).then((result) => result.stdout, () => void 0);
|
|
49280
|
+
if (refs === void 0)
|
|
49281
|
+
continue;
|
|
49282
|
+
const byName = /* @__PURE__ */ new Map();
|
|
49283
|
+
for (const line of refs.trim().split("\n")) {
|
|
49284
|
+
const match = /^(refs\/\S+) ([a-f0-9]{40,64})$/.exec(line);
|
|
49285
|
+
if (match)
|
|
49286
|
+
byName.set(match[1], match[2]);
|
|
49287
|
+
}
|
|
49288
|
+
const unpublishedHead = [...byName].some(([name, oid]) => name.startsWith("refs/heads/") && byName.get(name.replace("refs/heads/", "refs/remotes/origin/")) !== oid);
|
|
49289
|
+
if (unpublishedHead)
|
|
49290
|
+
continue;
|
|
49291
|
+
const unreachable = await execFileAsync12("git", [
|
|
49292
|
+
`--git-dir=${path}`,
|
|
49293
|
+
"fsck",
|
|
49294
|
+
"--unreachable",
|
|
49295
|
+
"--no-reflogs",
|
|
49296
|
+
"--no-progress"
|
|
49297
|
+
]).then((result) => result.stdout, () => void 0);
|
|
49298
|
+
if (unreachable === void 0 || /unreachable commit /.test(unreachable))
|
|
49299
|
+
continue;
|
|
49300
|
+
await rm18(path, { recursive: true, force: true });
|
|
49301
|
+
removed.push(path);
|
|
49302
|
+
}
|
|
49303
|
+
return removed;
|
|
49304
|
+
}
|
|
49305
|
+
|
|
49306
|
+
// apps/body/dist/machine-helper.js
|
|
48784
49307
|
var AGENT_RESTART_BASE_MS = 5e3;
|
|
48785
49308
|
var AGENT_RESTART_MAX_MS = 6e4;
|
|
48786
49309
|
var PREVIOUS_HOLDER_WAIT_MS = 12e4;
|
|
@@ -48801,6 +49324,32 @@ async function runMachineHelper(options = {}) {
|
|
|
48801
49324
|
const slots = /* @__PURE__ */ new Map();
|
|
48802
49325
|
const hosted = /* @__PURE__ */ new Map();
|
|
48803
49326
|
const links = /* @__PURE__ */ new Map();
|
|
49327
|
+
let diskSweepRunning = false;
|
|
49328
|
+
let lastModelSweepAt = 0;
|
|
49329
|
+
let lastRetentionSweepAt = 0;
|
|
49330
|
+
const sweepHostDisk = async () => {
|
|
49331
|
+
const now2 = Date.now();
|
|
49332
|
+
if (controller.signal.aborted || diskSweepRunning || [...slots.values()].some((slot) => slot.state === "starting" || slot.state === "restarting") || [...hosted.values()].some((agent) => !agent.core.isWorkspaceIdle()) || now2 - lastModelSweepAt < 60 * 6e4 && now2 - lastRetentionSweepAt < 24 * 60 * 6e4)
|
|
49333
|
+
return;
|
|
49334
|
+
diskSweepRunning = true;
|
|
49335
|
+
try {
|
|
49336
|
+
const modelDue = now2 - lastModelSweepAt >= 60 * 6e4;
|
|
49337
|
+
const removed = modelDue ? await pruneSharedModelCache(resolve47(supervisorRoot, "beeline", "model-cache")) : [];
|
|
49338
|
+
if (modelDue)
|
|
49339
|
+
lastModelSweepAt = now2;
|
|
49340
|
+
if (now2 - lastRetentionSweepAt >= 24 * 60 * 6e4) {
|
|
49341
|
+
removed.push(...await pruneDeletedRuntimes(supervisorRoot));
|
|
49342
|
+
removed.push(...await pruneRepositoryCaches(supervisorRoot));
|
|
49343
|
+
lastRetentionSweepAt = now2;
|
|
49344
|
+
}
|
|
49345
|
+
if (removed.length)
|
|
49346
|
+
console.log(`[helper] idle disk sweep removed ${removed.length} expired cache/runtime directories`);
|
|
49347
|
+
} catch (error) {
|
|
49348
|
+
console.warn("[helper] idle disk sweep failed:", error);
|
|
49349
|
+
} finally {
|
|
49350
|
+
diskSweepRunning = false;
|
|
49351
|
+
}
|
|
49352
|
+
};
|
|
48804
49353
|
if (!options.configPaths)
|
|
48805
49354
|
await writeHelperPidRecord(supervisorRoot, process.pid);
|
|
48806
49355
|
const layout = beelineInstallLayout(env);
|
|
@@ -48812,7 +49361,7 @@ async function runMachineHelper(options = {}) {
|
|
|
48812
49361
|
const paths = options.configPaths ?? await findAgentRuntimeConfigPaths(env);
|
|
48813
49362
|
const live = [];
|
|
48814
49363
|
for (const path of paths) {
|
|
48815
|
-
if (!await
|
|
49364
|
+
if (!await stat10(path).then(() => true, () => false))
|
|
48816
49365
|
continue;
|
|
48817
49366
|
if (await isAgentStopped(path))
|
|
48818
49367
|
continue;
|
|
@@ -48832,7 +49381,7 @@ async function runMachineHelper(options = {}) {
|
|
|
48832
49381
|
const settle = await settleUpdateAttemptOnStart(layout);
|
|
48833
49382
|
if (settle.kind === "rolled-back") {
|
|
48834
49383
|
for (const path of await hostedRuntimes())
|
|
48835
|
-
await queueUpdateRollbackAlert(
|
|
49384
|
+
await queueUpdateRollbackAlert(dirname31(path), settle.record.releaseId);
|
|
48836
49385
|
console.error(`[helper] self-update ROLLED BACK: bundle ${describeIdentity(settle.record.to)} never confirmed healthy; restored ${settle.record.previousReleaseId ?? "previous release"}`);
|
|
48837
49386
|
return finish(await standDownForRollback());
|
|
48838
49387
|
}
|
|
@@ -48873,7 +49422,7 @@ async function runMachineHelper(options = {}) {
|
|
|
48873
49422
|
since: new Date(slot.since).toISOString()
|
|
48874
49423
|
}]))
|
|
48875
49424
|
};
|
|
48876
|
-
await mkdir29(
|
|
49425
|
+
await mkdir29(dirname31(path), { recursive: true, mode: 448 });
|
|
48877
49426
|
const staged = `${path}.${process.pid}.tmp`;
|
|
48878
49427
|
await writeFile22(staged, `${JSON.stringify(body, null, 2)}
|
|
48879
49428
|
`, { mode: 384 });
|
|
@@ -48966,6 +49515,7 @@ async function runMachineHelper(options = {}) {
|
|
|
48966
49515
|
for (const agent of hosted.values())
|
|
48967
49516
|
agent.lifecycle.resumeAfterFailedUpdate(() => agent.core.resumeServing());
|
|
48968
49517
|
}
|
|
49518
|
+
void sweepHostDisk();
|
|
48969
49519
|
};
|
|
48970
49520
|
let readyResolve;
|
|
48971
49521
|
const allEstablished = new Promise((resolveReady) => {
|
|
@@ -49020,7 +49570,7 @@ async function runMachineHelper(options = {}) {
|
|
|
49020
49570
|
const supervise = async (slot) => {
|
|
49021
49571
|
let failures = 0;
|
|
49022
49572
|
while (!controller.signal.aborted && !slot.controller.signal.aborted) {
|
|
49023
|
-
if (!await
|
|
49573
|
+
if (!await stat10(slot.configPath).then(() => true, () => false)) {
|
|
49024
49574
|
setState(slot, "removed", "runtime no longer on this machine");
|
|
49025
49575
|
break;
|
|
49026
49576
|
}
|
|
@@ -49030,7 +49580,7 @@ async function runMachineHelper(options = {}) {
|
|
|
49030
49580
|
reason = await runAgent(slot.configPath, host, slot.controller.signal);
|
|
49031
49581
|
} catch (error) {
|
|
49032
49582
|
console.error(`[helper] agent ${slot.agentId} failed:`, error);
|
|
49033
|
-
const failure = await settleDaemonStartFailure(
|
|
49583
|
+
const failure = await settleDaemonStartFailure(dirname31(slot.configPath), error).catch(() => ({ distressed: false }));
|
|
49034
49584
|
if (failure.distressed) {
|
|
49035
49585
|
console.error(`[helper] agent ${slot.agentId} failed to start ${failure.count} times; it stays stopped. operator record: ${failure.path}`);
|
|
49036
49586
|
reason = "distress";
|
|
@@ -49079,7 +49629,7 @@ async function runMachineHelper(options = {}) {
|
|
|
49079
49629
|
const runtime = await readRuntimeRecord(configPath).catch(() => void 0);
|
|
49080
49630
|
const slot = existing ?? {
|
|
49081
49631
|
configPath,
|
|
49082
|
-
agentId: runtime?.agent.publicKey ??
|
|
49632
|
+
agentId: runtime?.agent.publicKey ?? dirname31(configPath).split("/").at(-1),
|
|
49083
49633
|
controller: new AbortController(),
|
|
49084
49634
|
state: "starting",
|
|
49085
49635
|
status: "",
|
|
@@ -49119,6 +49669,8 @@ async function runMachineHelper(options = {}) {
|
|
|
49119
49669
|
allEstablished,
|
|
49120
49670
|
new Promise((resolveAbort) => controller.signal.addEventListener("abort", () => resolveAbort(), { once: true }))
|
|
49121
49671
|
]);
|
|
49672
|
+
if (!controller.signal.aborted)
|
|
49673
|
+
void sweepHostDisk();
|
|
49122
49674
|
if (!controller.signal.aborted)
|
|
49123
49675
|
await notifier.ready(`ready; ${statusLine()}`).catch((error) => console.error("[helper] ready notification failed:", error));
|
|
49124
49676
|
if (!controller.signal.aborted)
|
|
@@ -49185,7 +49737,7 @@ async function waitForPreviousHolder(configPath, signal) {
|
|
|
49185
49737
|
return;
|
|
49186
49738
|
if (!announced) {
|
|
49187
49739
|
announced = true;
|
|
49188
|
-
console.log(`[helper] waiting for process ${pid} to let go of ${
|
|
49740
|
+
console.log(`[helper] waiting for process ${pid} to let go of ${dirname31(configPath)}`);
|
|
49189
49741
|
}
|
|
49190
49742
|
const waited = Date.now() - startedAt;
|
|
49191
49743
|
if (waited >= PREVIOUS_HOLDER_WAIT_MS && !asked) {
|
|
@@ -49310,7 +49862,7 @@ async function main() {
|
|
|
49310
49862
|
const roomId = roomFlag >= 0 ? args[roomFlag + 1] : void 0;
|
|
49311
49863
|
if (!configPath || !roomId)
|
|
49312
49864
|
throw new Error("corner-read-token requires --config and --room");
|
|
49313
|
-
const activated = await activateDaemonTransport(
|
|
49865
|
+
const activated = await activateDaemonTransport(resolve48(configPath));
|
|
49314
49866
|
if (!activated)
|
|
49315
49867
|
throw new Error("corner-read-token requires monolith transport");
|
|
49316
49868
|
const credential = await activated.client.execute("getRoomGitHubToken", { roomId });
|
|
@@ -49365,7 +49917,7 @@ async function main() {
|
|
|
49365
49917
|
}
|
|
49366
49918
|
if (!configPath && !args.includes("--machine"))
|
|
49367
49919
|
throw new Error("daemon requires --machine, or --config <runtime.json> for one agent");
|
|
49368
|
-
const { reason, lifecycle } = await runMachineHelper(configPath ? { configPaths: [
|
|
49920
|
+
const { reason, lifecycle } = await runMachineHelper(configPath ? { configPaths: [resolve48(configPath)] } : {});
|
|
49369
49921
|
daemonLifecycle = lifecycle;
|
|
49370
49922
|
lifecycle.exit(reason);
|
|
49371
49923
|
return;
|
|
@@ -49388,7 +49940,7 @@ async function main() {
|
|
|
49388
49940
|
if (!agentPubkey)
|
|
49389
49941
|
throw new Error("stop requires --agent <pubkey>");
|
|
49390
49942
|
const configs = await findAgentRuntimeConfigPaths(process.env, process.cwd());
|
|
49391
|
-
const configPath = configs.find((candidate) =>
|
|
49943
|
+
const configPath = configs.find((candidate) => dirname32(candidate).endsWith(agentPubkey));
|
|
49392
49944
|
if (!configPath)
|
|
49393
49945
|
throw new Error(`no stored runtime found for agent ${agentPubkey}`);
|
|
49394
49946
|
const runtime = await readRuntimeRecord(configPath);
|