usebeeline 0.1.20 → 0.1.22

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.
Files changed (2) hide show
  1. package/dist/usebeeline.mjs +1012 -429
  2. package/package.json +1 -1
@@ -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((resolve45) => {
216
- resolveDone = resolve45;
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 stat10 = readFileSync(join(procRoot, String(pid), "stat"), "utf8");
484
- return stat10.slice(stat10.lastIndexOf(")") + 2, stat10.lastIndexOf(")") + 3) !== "Z";
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 relative4 of requiredBundlePaths()) {
5683
+ for (const relative5 of requiredBundlePaths()) {
5684
5684
  try {
5685
- await access(join8(releaseDir, relative4), fsConstants2.F_OK);
5685
+ await access(join8(releaseDir, relative5), fsConstants2.F_OK);
5686
5686
  } catch {
5687
- throw new Error(`staged bundle is missing ${relative4}`);
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: sep3, value } = collItem;
10102
+ const { start, key, sep: sep4, value } = collItem;
10103
10103
  const keyProps = resolveProps.resolveProps(start, {
10104
10104
  indicator: "explicit-key-ind",
10105
- next: key ?? sep3?.[0],
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 && !sep3) {
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(sep3 ?? [], {
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, sep3, null, valueProps, onError);
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 sep3 = "";
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 += sep3 + cb;
10265
- sep3 = "";
10264
+ comment += sep4 + cb;
10265
+ sep4 = "";
10266
10266
  break;
10267
10267
  }
10268
10268
  case "newline":
10269
10269
  if (comment)
10270
- sep3 += source;
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: sep3, value } = collItem;
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 ?? sep3?.[0],
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 && !sep3 && !value) {
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 && !sep3 && !props.found) {
10379
- const valueNode = value ? composeNode(ctx, value, props, onError) : composeEmptyNode(ctx, props.end, sep3, null, props, onError);
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(sep3 ?? [], {
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 (sep3)
10403
- for (const st of sep3) {
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, sep3, null, valueProps, onError) : null;
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 sep3 = "";
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 += sep3 + indent.slice(trimIndent) + content;
10618
- sep3 = "\n";
10617
+ value += sep4 + indent.slice(trimIndent) + content;
10618
+ sep4 = "\n";
10619
10619
  } else if (indent.length > trimIndent || content[0] === " ") {
10620
- if (sep3 === " ")
10621
- sep3 = "\n";
10622
- else if (!prevMoreIndented && sep3 === "\n")
10623
- sep3 = "\n\n";
10624
- value += sep3 + indent.slice(trimIndent) + content;
10625
- sep3 = "\n";
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 (sep3 === "\n")
10628
+ if (sep4 === "\n")
10629
10629
  value += "\n";
10630
10630
  else
10631
- sep3 = "\n";
10631
+ sep4 = "\n";
10632
10632
  } else {
10633
- value += sep3 + content;
10634
- sep3 = " ";
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 sep3 = " ";
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 (sep3 === "\n")
10822
- res += sep3;
10821
+ if (sep4 === "\n")
10822
+ res += sep4;
10823
10823
  else
10824
- sep3 = "\n";
10824
+ sep4 = "\n";
10825
10825
  } else {
10826
- res += sep3 + match[1];
10827
- sep3 = " ";
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 + sep3 + (match?.[1] ?? "");
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: sep3, value }) {
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 (sep3)
11651
- for (const st of sep3)
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 sep3;
12818
+ let sep4;
12819
12819
  if (scalar.end) {
12820
- sep3 = scalar.end;
12821
- sep3.push(this.sourceToken);
12820
+ sep4 = scalar.end;
12821
+ sep4.push(this.sourceToken);
12822
12822
  delete scalar.end;
12823
12823
  } else
12824
- sep3 = [this.sourceToken];
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: sep3 }]
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 sep3 = it.sep;
12983
- sep3.push(this.sourceToken);
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: sep3 }]
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 sep3 = fc.end.splice(1, fc.end.length);
13185
- sep3.push(this.sourceToken);
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: sep3 }]
13190
+ items: [{ start, key: fc, sep: sep4 }]
13191
13191
  };
13192
13192
  this.onKeyLine = true;
13193
13193
  this.stack[this.stack.length - 1] = map;
@@ -13722,7 +13722,38 @@ function squireApprovalFromMcp(request, response) {
13722
13722
  if (!link2)
13723
13723
  return void 0;
13724
13724
  const args = record(params?.arguments) ?? {};
13725
- return { tool, ...squireApprovalCopy(tool, args), ...link2 };
13725
+ const expiresAt = approvalExpiryIn(response.result);
13726
+ return {
13727
+ tool,
13728
+ ...squireApprovalCopy(tool, args),
13729
+ ...link2,
13730
+ ...expiresAt !== void 0 ? { expiresAt } : {}
13731
+ };
13732
+ }
13733
+ function approvalExpiryIn(value, depth = 0) {
13734
+ if (depth > 6)
13735
+ return void 0;
13736
+ if (typeof value === "string") {
13737
+ if (value.length > 2e4 || !/^[{[]/.test(value.trim()))
13738
+ return void 0;
13739
+ try {
13740
+ return approvalExpiryIn(JSON.parse(value), depth + 1);
13741
+ } catch {
13742
+ return void 0;
13743
+ }
13744
+ }
13745
+ if (Array.isArray(value))
13746
+ return value.map((entry) => approvalExpiryIn(entry, depth + 1)).find((expiry) => expiry !== void 0);
13747
+ const item = record(value);
13748
+ if (!item)
13749
+ return void 0;
13750
+ const raw = item.expires_at ?? item.expiresAt;
13751
+ if (typeof raw === "string") {
13752
+ const parsed = Date.parse(raw);
13753
+ if (Number.isFinite(parsed) && parsed > 0)
13754
+ return parsed;
13755
+ }
13756
+ return Object.values(item).map((entry) => approvalExpiryIn(entry, depth + 1)).find((expiry) => expiry !== void 0);
13726
13757
  }
13727
13758
  function squireLoginWallIn(value, depth = 0) {
13728
13759
  if (depth > 6)
@@ -14036,7 +14067,7 @@ function configureNetworkFamilyDefaults(network = net) {
14036
14067
  configureNetworkFamilyDefaults();
14037
14068
 
14038
14069
  // apps/body/dist/cli.js
14039
- import { dirname as dirname31, resolve as resolve44 } from "node:path";
14070
+ import { dirname as dirname32, resolve as resolve48 } from "node:path";
14040
14071
  import { stdin as stdin4, stdout as stdout5 } from "node:process";
14041
14072
 
14042
14073
  // node_modules/@clack/core/dist/index.mjs
@@ -15476,7 +15507,7 @@ function parseCursorModelsOutput(output) {
15476
15507
  };
15477
15508
  }
15478
15509
  async function enumerateCursorModels(env = process.env) {
15479
- return new Promise((resolve45) => {
15510
+ return new Promise((resolve49) => {
15480
15511
  const child = spawn2("cursor-agent", ["models"], {
15481
15512
  env,
15482
15513
  stdio: ["ignore", "pipe", "ignore"]
@@ -15490,11 +15521,11 @@ async function enumerateCursorModels(env = process.env) {
15490
15521
  });
15491
15522
  child.on("error", () => {
15492
15523
  clearTimeout(timer);
15493
- resolve45(void 0);
15524
+ resolve49(void 0);
15494
15525
  });
15495
15526
  child.on("close", (code) => {
15496
15527
  clearTimeout(timer);
15497
- resolve45(code === 0 ? parseCursorModelsOutput(output) : void 0);
15528
+ resolve49(code === 0 ? parseCursorModelsOutput(output) : void 0);
15498
15529
  });
15499
15530
  });
15500
15531
  }
@@ -15921,13 +15952,13 @@ var CursorAcpServer = class {
15921
15952
  consumeLine(line);
15922
15953
  });
15923
15954
  try {
15924
- const { code, signal } = await new Promise((resolve45) => {
15955
+ const { code, signal } = await new Promise((resolve49) => {
15925
15956
  let settled = false;
15926
15957
  const finish = (exitCode, exitSignal) => {
15927
15958
  if (settled)
15928
15959
  return;
15929
15960
  settled = true;
15930
- resolve45({ code: exitCode, signal: exitSignal });
15961
+ resolve49({ code: exitCode, signal: exitSignal });
15931
15962
  };
15932
15963
  child.once("error", (error) => {
15933
15964
  spawnError = error instanceof Error ? error.message : String(error);
@@ -16072,10 +16103,10 @@ function releaseSquireConnectSession(log2, owner = "") {
16072
16103
  function squireChromeProfileDir() {
16073
16104
  return process.env.TRUSTY_SQUIRE_PROFILE_DIR ?? squireHostPaths(homedir2()).profileDir;
16074
16105
  }
16075
- var defaultShellRunner = (command, args) => new Promise((resolve45) => {
16106
+ var defaultShellRunner = (command, args) => new Promise((resolve49) => {
16076
16107
  execFile(command, [...args], { timeout: 12e4, maxBuffer: 4 * 1024 * 1024, encoding: "utf8" }, (error, stdout6, stderr) => {
16077
16108
  const code = error?.code;
16078
- resolve45({
16109
+ resolve49({
16079
16110
  code: typeof code === "number" ? code : error ? 1 : 0,
16080
16111
  stdout: String(stdout6 ?? ""),
16081
16112
  stderr: String(stderr ?? "")
@@ -16100,7 +16131,7 @@ function killConnectTree(child) {
16100
16131
  }
16101
16132
  child.kill();
16102
16133
  }
16103
- var defaultStreamedRunner = (command, args, env, owner = "") => new Promise((resolve45) => {
16134
+ var defaultStreamedRunner = (command, args, env, owner = "") => new Promise((resolve49) => {
16104
16135
  const child = spawn5(command, args, {
16105
16136
  stdio: ["ignore", "pipe", "pipe"],
16106
16137
  env: env ?? squireConnectProcessEnv(),
@@ -16114,7 +16145,7 @@ var defaultStreamedRunner = (command, args, env, owner = "") => new Promise((res
16114
16145
  const safetyTimer = setTimeout(() => {
16115
16146
  if (!resolved) {
16116
16147
  resolved = true;
16117
- resolve45({ stdout: stdout6, stderr, pid: child.pid ?? void 0, report, abort: () => {
16148
+ resolve49({ stdout: stdout6, stderr, pid: child.pid ?? void 0, report, abort: () => {
16118
16149
  } });
16119
16150
  }
16120
16151
  killConnectTree(child);
@@ -16149,7 +16180,7 @@ var defaultStreamedRunner = (command, args, env, owner = "") => new Promise((res
16149
16180
  const finish = (result) => {
16150
16181
  if (!resolved) {
16151
16182
  resolved = true;
16152
- resolve45(result);
16183
+ resolve49(result);
16153
16184
  }
16154
16185
  };
16155
16186
  const settle = (result) => {
@@ -16641,13 +16672,13 @@ var StdioSquireMcpClient = class {
16641
16672
  const child = this.child;
16642
16673
  if (!child)
16643
16674
  return Promise.reject(new Error("Squire MCP session is not running"));
16644
- return new Promise((resolve45, reject) => {
16675
+ return new Promise((resolve49, reject) => {
16645
16676
  const timeoutMs = method === "initialize" ? INITIALIZE_TIMEOUT_MS : CALL_TIMEOUT_MS;
16646
16677
  const timer = setTimeout(() => {
16647
16678
  this.pending.delete(id);
16648
16679
  reject(new Error(`${toolName2 ?? method} timed out after ${timeoutMs}ms`));
16649
16680
  }, timeoutMs);
16650
- this.pending.set(id, { resolve: resolve45, reject, timer });
16681
+ this.pending.set(id, { resolve: resolve49, reject, timer });
16651
16682
  child.stdin.write(`${JSON.stringify({ jsonrpc: "2.0", id, method, params })}
16652
16683
  `);
16653
16684
  });
@@ -16809,9 +16840,9 @@ var SquireTaskRelay = class {
16809
16840
  response.writeHead(400, { "content-type": "application/json" }).end(JSON.stringify({ error: error instanceof Error ? error.message : "Squire relay failed" }));
16810
16841
  }
16811
16842
  });
16812
- await new Promise((resolve45, reject) => {
16843
+ await new Promise((resolve49, reject) => {
16813
16844
  server.once("error", reject);
16814
- server.listen(0, "127.0.0.1", resolve45);
16845
+ server.listen(0, "127.0.0.1", resolve49);
16815
16846
  });
16816
16847
  this.server = server;
16817
16848
  const address = server.address();
@@ -17850,11 +17881,11 @@ var RegistryMcpHostBroker = class {
17850
17881
  })();
17851
17882
  });
17852
17883
  });
17853
- await new Promise((resolve45, reject) => {
17884
+ await new Promise((resolve49, reject) => {
17854
17885
  this.server.once("error", reject);
17855
17886
  this.server.listen(this.socketPath, () => {
17856
17887
  this.server.off("error", reject);
17857
- resolve45();
17888
+ resolve49();
17858
17889
  });
17859
17890
  });
17860
17891
  chmodSync(this.socketPath, 384);
@@ -17863,12 +17894,12 @@ var RegistryMcpHostBroker = class {
17863
17894
  const server = this.server;
17864
17895
  this.server = void 0;
17865
17896
  if (server)
17866
- await new Promise((resolve45) => server.close(() => resolve45()));
17897
+ await new Promise((resolve49) => server.close(() => resolve49()));
17867
17898
  rmSync(this.socketPath, { force: true });
17868
17899
  }
17869
17900
  };
17870
17901
  async function brokerRequest(socketPath, request) {
17871
- return new Promise((resolve45, reject) => {
17902
+ return new Promise((resolve49, reject) => {
17872
17903
  const socket = createConnection3(socketPath);
17873
17904
  let output = "";
17874
17905
  socket.setEncoding("utf8");
@@ -17885,7 +17916,7 @@ async function brokerRequest(socketPath, request) {
17885
17916
  throw new Error(parsed.error);
17886
17917
  if (!Array.isArray(parsed.messages) || !parsed.messages.every((entry) => typeof entry === "string"))
17887
17918
  throw new Error("Registry MCP broker returned an invalid response");
17888
- resolve45(parsed.messages);
17919
+ resolve49(parsed.messages);
17889
17920
  } catch (error) {
17890
17921
  reject(error);
17891
17922
  }
@@ -18099,7 +18130,8 @@ var TURN_SILENCE_KINDS = [
18099
18130
  "helper-out-of-date",
18100
18131
  "update-interrupted",
18101
18132
  "offline",
18102
- "context-overflow"
18133
+ "context-overflow",
18134
+ "resource-limit"
18103
18135
  ];
18104
18136
  var TURN_RECEIPT_REASON_KINDS = [
18105
18137
  "hiccup",
@@ -18111,6 +18143,7 @@ var TURN_RECEIPT_REASON_KINDS = [
18111
18143
  "update-interrupted",
18112
18144
  "offline",
18113
18145
  "context-overflow",
18146
+ "resource-limit",
18114
18147
  "model-selection-unavailable"
18115
18148
  ];
18116
18149
  function isTurnReceiptReasonKind(value) {
@@ -18158,6 +18191,9 @@ function classifyTurnSilence(reason, reasonKind) {
18158
18191
  if (isContextOverflowFault(text2)) {
18159
18192
  return { kind: "context-overflow" };
18160
18193
  }
18194
+ if (/\bresource_limit: ACP session exceeded its \d+ MiB memory limit\b/i.test(text2)) {
18195
+ return { kind: "resource-limit" };
18196
+ }
18161
18197
  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
18198
  return {
18163
18199
  kind: "allowance-spent",
@@ -19354,7 +19390,7 @@ var AgentSignIn = class {
19354
19390
  };
19355
19391
  for (const name of ISOLATION_VARIABLES)
19356
19392
  delete env[name];
19357
- return new Promise((resolve45, reject) => {
19393
+ return new Promise((resolve49, reject) => {
19358
19394
  let output = "";
19359
19395
  let answered = false;
19360
19396
  let child;
@@ -19395,7 +19431,7 @@ var AgentSignIn = class {
19395
19431
  return;
19396
19432
  answered = true;
19397
19433
  clearTimeout(linkTimer);
19398
- resolve45(link2);
19434
+ resolve49(link2);
19399
19435
  };
19400
19436
  child.stdout?.on("data", read2);
19401
19437
  child.stderr?.on("data", read2);
@@ -29228,13 +29264,13 @@ var RoomSupervisor = class {
29228
29264
  */
29229
29265
  retryDelay(failures, signal, since = this.#wakes) {
29230
29266
  const delay = this.delaysMs[failures - 1];
29231
- return new Promise((resolve45) => {
29267
+ return new Promise((resolve49) => {
29232
29268
  let timer;
29233
29269
  const done = () => {
29234
29270
  clearTimeout(timer);
29235
29271
  this.#parked.delete(done);
29236
29272
  signal?.removeEventListener("abort", done);
29237
- resolve45();
29273
+ resolve49();
29238
29274
  };
29239
29275
  this.#parked.add(done);
29240
29276
  signal?.addEventListener("abort", done, { once: true });
@@ -29426,12 +29462,12 @@ async function retryBeforeReady(work, options) {
29426
29462
  if (wait2 <= 0)
29427
29463
  break;
29428
29464
  await options.extendStartTimeout(wait2 + 15e3);
29429
- await new Promise((resolve45) => {
29465
+ await new Promise((resolve49) => {
29430
29466
  const timer = setTimeout(done, wait2);
29431
29467
  function done() {
29432
29468
  clearTimeout(timer);
29433
29469
  options.signal?.removeEventListener("abort", done);
29434
- resolve45();
29470
+ resolve49();
29435
29471
  }
29436
29472
  wake = done;
29437
29473
  options.signal?.addEventListener("abort", done, { once: true });
@@ -29599,6 +29635,94 @@ import { resolve as resolve20 } from "node:path";
29599
29635
  import { spawn as spawn11 } from "node:child_process";
29600
29636
  import { EventEmitter } from "node:events";
29601
29637
 
29638
+ // apps/body/dist/acp-resource-scope.js
29639
+ import { execFile as execFile6 } from "node:child_process";
29640
+ import { randomUUID as randomUUID6 } from "node:crypto";
29641
+ import { readFileSync as readFileSync4 } from "node:fs";
29642
+ import { totalmem } from "node:os";
29643
+ import { promisify as promisify5 } from "node:util";
29644
+ var execFileAsync5 = promisify5(execFile6);
29645
+ function acpSessionMemoryMaxBytes(hostMemoryBytes = totalmem()) {
29646
+ return Math.max(8 * 1024 ** 3, Math.floor(hostMemoryBytes / 4));
29647
+ }
29648
+ var ACP_SESSION_MEMORY_MAX_BYTES = acpSessionMemoryMaxBytes();
29649
+ var AcpResourceScope = class {
29650
+ memoryMaxBytes;
29651
+ unit = `beeline-acp-${randomUUID6()}.scope`;
29652
+ #stop;
29653
+ constructor(memoryMaxBytes = ACP_SESSION_MEMORY_MAX_BYTES) {
29654
+ this.memoryMaxBytes = memoryMaxBytes;
29655
+ }
29656
+ launch(command, args, agentEnv) {
29657
+ const env = { ...agentEnv };
29658
+ const stripBus = !Object.hasOwn(agentEnv, "DBUS_SESSION_BUS_ADDRESS");
29659
+ if (stripBus && process.env.DBUS_SESSION_BUS_ADDRESS)
29660
+ env.DBUS_SESSION_BUS_ADDRESS = process.env.DBUS_SESSION_BUS_ADDRESS;
29661
+ if (!env.XDG_RUNTIME_DIR && process.env.XDG_RUNTIME_DIR)
29662
+ env.XDG_RUNTIME_DIR = process.env.XDG_RUNTIME_DIR;
29663
+ const stripRuntime = !Object.hasOwn(agentEnv, "XDG_RUNTIME_DIR");
29664
+ const owner = managedServiceUnit();
29665
+ return {
29666
+ command: "systemd-run",
29667
+ args: [
29668
+ "--user",
29669
+ "--scope",
29670
+ "--quiet",
29671
+ "--same-dir",
29672
+ `--unit=${this.unit}`,
29673
+ `--property=MemoryMax=${this.memoryMaxBytes}`,
29674
+ "--property=MemorySwapMax=0",
29675
+ "--property=OOMPolicy=kill",
29676
+ "--property=KillMode=control-group",
29677
+ "--property=TimeoutStopSec=1s",
29678
+ ...owner ? [`--property=BindsTo=${owner}`, `--property=After=${owner}`] : [],
29679
+ "/usr/bin/env",
29680
+ ...stripBus ? ["-u", "DBUS_SESSION_BUS_ADDRESS"] : [],
29681
+ ...stripRuntime ? ["-u", "XDG_RUNTIME_DIR"] : [],
29682
+ command,
29683
+ ...args
29684
+ ],
29685
+ env
29686
+ };
29687
+ }
29688
+ /** An OOM result survives process exit until reset-failed unloads the unit. */
29689
+ async exceededMemoryLimit() {
29690
+ try {
29691
+ const { stdout: stdout6 } = await execFileAsync5("systemctl", ["--user", "show", this.unit, "--property=Result", "--value"], { timeout: 5e3 });
29692
+ return stdout6.trim() === "oom-kill";
29693
+ } catch {
29694
+ return false;
29695
+ }
29696
+ }
29697
+ async stop() {
29698
+ return this.#stop ??= (async () => {
29699
+ try {
29700
+ await execFileAsync5("systemctl", ["--user", "stop", this.unit], { timeout: 5e3 });
29701
+ } catch (error) {
29702
+ const { stdout: stdout6 } = await execFileAsync5("systemctl", ["--user", "show", this.unit, "--property=LoadState", "--value"], { timeout: 5e3 });
29703
+ if (stdout6.trim() !== "not-found")
29704
+ throw error;
29705
+ } finally {
29706
+ await execFileAsync5("systemctl", ["--user", "reset-failed", this.unit], { timeout: 5e3 }).catch(() => void 0);
29707
+ }
29708
+ })().catch((error) => {
29709
+ this.#stop = void 0;
29710
+ throw error;
29711
+ });
29712
+ }
29713
+ };
29714
+ function managedServiceUnit() {
29715
+ if (process.env.BEELINE_MANAGED_BY_SYSTEMD !== "1")
29716
+ return void 0;
29717
+ try {
29718
+ const cgroup = readFileSync4("/proc/self/cgroup", "utf8");
29719
+ const path = cgroup.split("\n").find((line) => line.startsWith("0::"))?.slice(3);
29720
+ return path?.split("/").find((part) => /^beeline-(?:helper|agent@.+)\.service$/.test(part));
29721
+ } catch {
29722
+ return void 0;
29723
+ }
29724
+ }
29725
+
29602
29726
  // apps/body/dist/harness-capabilities.js
29603
29727
  var PROFILES = [
29604
29728
  {
@@ -29912,6 +30036,13 @@ var AcpRuntimeExitedError = class extends Error {
29912
30036
  this.name = "AcpRuntimeExitedError";
29913
30037
  }
29914
30038
  };
30039
+ var AcpResourceLimitError = class extends Error {
30040
+ cause = "resource_limit";
30041
+ constructor(memoryMaxBytes) {
30042
+ super(`resource_limit: ACP session exceeded its ${Math.floor(memoryMaxBytes / 1024 / 1024)} MiB memory limit`);
30043
+ this.name = "AcpResourceLimitError";
30044
+ }
30045
+ };
29915
30046
  function killChildProcessGroup(child, signal) {
29916
30047
  if (!child.pid)
29917
30048
  return;
@@ -30196,6 +30327,10 @@ var AcpClient = class extends EventEmitter {
30196
30327
  permissionAllowlist;
30197
30328
  commandsHandler;
30198
30329
  oomKills;
30330
+ useResourceScope;
30331
+ resourceScopeMemoryMaxBytes;
30332
+ resourceScope;
30333
+ resourceScopeUnavailable = false;
30199
30334
  /** A deliberate stop owns its SIGKILL; that exit is never labelled OOM. */
30200
30335
  stopping = false;
30201
30336
  constructor(opts) {
@@ -30216,21 +30351,25 @@ var AcpClient = class extends EventEmitter {
30216
30351
  this.permissionAllowlist = opts.permissionAllowlist;
30217
30352
  this.commandsHandler = opts.onCommands;
30218
30353
  this.oomKills = opts.oomKills ?? new OomKillTracker(cgroupOomKillProbe());
30354
+ this.useResourceScope = opts.resourceScope === "systemd" || opts.resourceScope === void 0 && process.platform === "linux" && process.env.BEELINE_MANAGED_BY_SYSTEMD === "1";
30355
+ this.resourceScopeMemoryMaxBytes = opts.resourceScopeMemoryMaxBytes;
30219
30356
  }
30220
30357
  async start(timeoutMs = 6e4) {
30221
30358
  if (this.alive)
30222
30359
  return;
30223
30360
  await this.oomKills.prime().catch(() => void 0);
30224
30361
  this.stopping = false;
30225
- this.child = await withAdapterInstallLock(() => spawn11(this.agentCommand, this.agentArgs, {
30362
+ const childEnv = this.inheritProcessEnv ? { ...process.env, ...this.agentEnv } : this.agentEnv;
30363
+ this.resourceScope = this.useResourceScope && !this.resourceScopeUnavailable ? new AcpResourceScope(this.resourceScopeMemoryMaxBytes) : void 0;
30364
+ const launch = this.resourceScope?.launch(this.agentCommand, this.agentArgs, childEnv);
30365
+ this.child = await withAdapterInstallLock(() => spawn11(launch?.command ?? this.agentCommand, launch?.args ?? this.agentArgs, {
30226
30366
  // agentEnv is the child's whole environment: buildAgentEnv's allowlist is
30227
30367
  // a real boundary, not a decorative one layered over a full inherit.
30228
- env: this.inheritProcessEnv ? { ...process.env, ...this.agentEnv } : this.agentEnv,
30368
+ env: launch?.env ?? childEnv,
30229
30369
  ...this.agentCwd ? { cwd: this.agentCwd } : {},
30230
- // The harness and every tool it spawns share a disposable process
30231
- // group. A hard turn deadline can therefore retire the whole tree,
30232
- // never just the ACP parent while a shell/compiler keeps running.
30233
- detached: process.platform !== "win32",
30370
+ // Managed Linux sessions use a cgroup scope. The process-group fallback
30371
+ // covers helpers without a user systemd manager.
30372
+ detached: !launch && process.platform !== "win32",
30234
30373
  stdio: ["pipe", "pipe", "pipe"]
30235
30374
  }));
30236
30375
  this.alive = true;
@@ -30265,10 +30404,35 @@ var AcpClient = class extends EventEmitter {
30265
30404
  if (this.listenerCount("error") > 0)
30266
30405
  this.emit("error", err);
30267
30406
  });
30268
- const initResult = await this.request("initialize", {
30269
- protocolVersion: 1,
30270
- clientCapabilities: {}
30271
- }, timeoutMs);
30407
+ let initResult;
30408
+ try {
30409
+ initResult = await this.request("initialize", {
30410
+ protocolVersion: 1,
30411
+ clientCapabilities: {}
30412
+ }, timeoutMs);
30413
+ } catch (error) {
30414
+ if (launch && /EPIPE/.test(String(error)) && this.child?.exitCode === null) {
30415
+ await new Promise((resolve49) => {
30416
+ const timer = setTimeout(resolve49, 250);
30417
+ this.child?.once("close", () => {
30418
+ clearTimeout(timer);
30419
+ resolve49();
30420
+ });
30421
+ });
30422
+ }
30423
+ const scopeUnavailable = launch && !this.resourceScopeUnavailable && /(?:Failed to connect to bus|Failed to create bus connection|spawn systemd-run ENOENT)/i.test(`${this.stderrTail}
30424
+ ${String(error)}`);
30425
+ await this.stop().catch(() => void 0);
30426
+ if (scopeUnavailable) {
30427
+ this.resourceScopeUnavailable = true;
30428
+ this.resourceScope = void 0;
30429
+ this.child = null;
30430
+ this.alive = false;
30431
+ console.warn("[acp] systemd user scope unavailable; starting ACP session in a process group");
30432
+ return this.start(timeoutMs);
30433
+ }
30434
+ throw error;
30435
+ }
30272
30436
  const initMeta = initResult._meta;
30273
30437
  const steering = initMeta?.steering;
30274
30438
  this.supportsStandardSteering = steering?.supported === true;
@@ -30281,22 +30445,25 @@ var AcpClient = class extends EventEmitter {
30281
30445
  }
30282
30446
  /**
30283
30447
  * One child exit: reject every in-flight request so the turn fails and is
30284
- * reported instead of hanging, then publish the exit. A SIGKILL is checked
30285
- * against the daemon cgroup's OOM counter so the rejection can name the real
30286
- * cause instead of a bare signal.
30448
+ * reported instead of hanging, then publish the exit. A scoped exit reads
30449
+ * that scope's result; an unscoped SIGKILL uses the daemon cgroup's OOM
30450
+ * counter so the rejection can name the cause instead of a bare signal.
30287
30451
  */
30288
30452
  async handleChildExit(code, signal) {
30453
+ const child = this.child;
30289
30454
  this.alive = false;
30290
30455
  for (const p of this.pending.values())
30291
30456
  this.clearTimer(p);
30457
+ const scope = this.resourceScope;
30458
+ const memoryLimited = scope && !this.stopping ? await scope.exceededMemoryLimit() : false;
30292
30459
  let oomKilled = false;
30293
- if (signal === "SIGKILL" && !this.stopping) {
30460
+ if (!memoryLimited && signal === "SIGKILL" && !this.stopping) {
30294
30461
  let diagnosticTimer;
30295
30462
  try {
30296
30463
  oomKilled = await Promise.race([
30297
30464
  this.oomKills.consume().catch(() => false),
30298
- new Promise((resolve45) => {
30299
- diagnosticTimer = setTimeout(() => resolve45(false), 100);
30465
+ new Promise((resolve49) => {
30466
+ diagnosticTimer = setTimeout(() => resolve49(false), 100);
30300
30467
  })
30301
30468
  ]);
30302
30469
  } finally {
@@ -30308,13 +30475,21 @@ var AcpClient = class extends EventEmitter {
30308
30475
  const stderrSuffix = meaningful ? `: ${meaningful}` : "";
30309
30476
  for (const [, p] of this.pending) {
30310
30477
  this.clearTimer(p);
30311
- p.reject(new AcpRuntimeExitedError(`${exitText}${stderrSuffix}`));
30478
+ p.reject(memoryLimited ? new AcpResourceLimitError(scope.memoryMaxBytes) : new AcpRuntimeExitedError(`${exitText}${stderrSuffix}`));
30312
30479
  }
30313
30480
  this.pending.clear();
30314
30481
  this.activeRunIds.clear();
30315
30482
  this.activePromptSessions.clear();
30316
30483
  this.toolCallMetadata.clear();
30317
30484
  this.sessionCommands.clear();
30485
+ if (scope) {
30486
+ await scope.stop().then(() => {
30487
+ if (this.resourceScope === scope)
30488
+ this.resourceScope = void 0;
30489
+ if (this.child === child)
30490
+ this.child = null;
30491
+ }).catch((error) => console.error("[acp] resource scope cleanup failed:", error));
30492
+ }
30318
30493
  this.emit("exit", { code, signal });
30319
30494
  }
30320
30495
  failRuntime(detail) {
@@ -30324,27 +30499,36 @@ var AcpClient = class extends EventEmitter {
30324
30499
  p.reject(new AcpRuntimeExitedError(detail));
30325
30500
  }
30326
30501
  this.pending.clear();
30502
+ if (this.resourceScope)
30503
+ void this.resourceScope.stop().catch((error) => console.error("[acp] resource scope cleanup failed:", error));
30327
30504
  }
30328
30505
  async stop() {
30329
30506
  const child = this.child;
30330
- if (!child)
30507
+ const scope = this.resourceScope;
30508
+ if (!child && !scope)
30331
30509
  return;
30332
30510
  this.stopping = true;
30333
30511
  try {
30334
- if (this.child?.stdin.writable) {
30512
+ if (child?.stdin.writable) {
30335
30513
  this.notify("shutdown", {});
30336
30514
  }
30337
30515
  } catch {
30338
30516
  }
30339
- await new Promise((r2) => setTimeout(r2, 300));
30340
- try {
30341
- killChildProcessGroup(child, "SIGTERM");
30342
- } catch {
30343
- }
30344
- await new Promise((r2) => setTimeout(r2, 500));
30345
- try {
30346
- killChildProcessGroup(child, "SIGKILL");
30347
- } catch {
30517
+ if (scope) {
30518
+ await scope.stop();
30519
+ if (this.resourceScope === scope)
30520
+ this.resourceScope = void 0;
30521
+ } else if (child) {
30522
+ await new Promise((r2) => setTimeout(r2, 300));
30523
+ try {
30524
+ killChildProcessGroup(child, "SIGTERM");
30525
+ } catch {
30526
+ }
30527
+ await new Promise((r2) => setTimeout(r2, 500));
30528
+ try {
30529
+ killChildProcessGroup(child, "SIGKILL");
30530
+ } catch {
30531
+ }
30348
30532
  }
30349
30533
  this.child = null;
30350
30534
  this.alive = false;
@@ -30720,7 +30904,7 @@ var AcpClient = class extends EventEmitter {
30720
30904
  const current = this.activeRunIds.get(sessionId);
30721
30905
  if (current)
30722
30906
  return Promise.resolve(current);
30723
- return new Promise((resolve45, reject) => {
30907
+ return new Promise((resolve49, reject) => {
30724
30908
  const onUpdate = (update) => {
30725
30909
  if (update.sessionId !== sessionId)
30726
30910
  return;
@@ -30728,7 +30912,7 @@ var AcpClient = class extends EventEmitter {
30728
30912
  if (!runId)
30729
30913
  return;
30730
30914
  cleanup();
30731
- resolve45(runId);
30915
+ resolve49(runId);
30732
30916
  };
30733
30917
  const timer = setTimeout(() => {
30734
30918
  cleanup();
@@ -30807,14 +30991,14 @@ var AcpClient = class extends EventEmitter {
30807
30991
  }
30808
30992
  const id = this.nextId++;
30809
30993
  const payload = { jsonrpc: "2.0", id, method, params };
30810
- return new Promise((resolve45, reject) => {
30994
+ return new Promise((resolve49, reject) => {
30811
30995
  const timer = backstop ? void 0 : setTimeout(() => {
30812
30996
  this.pending.delete(id);
30813
30997
  reject(new AcpRequestTimeoutError(method, timeoutMs, this.stderrTail, false, detail));
30814
30998
  }, timeoutMs);
30815
30999
  const sessionId = params?.sessionId;
30816
31000
  this.pending.set(id, {
30817
- resolve: resolve45,
31001
+ resolve: resolve49,
30818
31002
  reject,
30819
31003
  timer,
30820
31004
  method,
@@ -30845,7 +31029,7 @@ var AcpClient = class extends EventEmitter {
30845
31029
 
30846
31030
  // apps/body/dist/agent-home.js
30847
31031
  var import_yaml2 = __toESM(require_dist(), 1);
30848
- import { existsSync as existsSync7, readFileSync as readFileSync5, watch } from "node:fs";
31032
+ import { existsSync as existsSync7, readFileSync as readFileSync6, watch } from "node:fs";
30849
31033
 
30850
31034
  // node_modules/smol-toml/dist/date.js
30851
31035
  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 +31197,7 @@ function skipVoid(ctx, banNewLines, banComments) {
31013
31197
  skipComment(ctx);
31014
31198
  }
31015
31199
  }
31016
- function skipUntil(ctx, sep3, end) {
31200
+ function skipUntil(ctx, sep4, end) {
31017
31201
  let ptr = ctx.p;
31018
31202
  if (!end) {
31019
31203
  ptr = indexOfNewline(ctx.s, ptr);
@@ -31024,7 +31208,7 @@ function skipUntil(ctx, sep3, end) {
31024
31208
  let c2 = ctx.s.charCodeAt(ctx.p);
31025
31209
  if (c2 === 35) {
31026
31210
  skipComment(ctx);
31027
- } else if (c2 === end || c2 === sep3) {
31211
+ } else if (c2 === end || c2 === sep4) {
31028
31212
  return;
31029
31213
  }
31030
31214
  }
@@ -31642,7 +31826,7 @@ function stringify(obj, { maxDepth = 1e3, numbersAsFloat = false } = {}) {
31642
31826
  }
31643
31827
 
31644
31828
  // apps/body/dist/agent-home.js
31645
- import { createHash as createHash7, randomUUID as randomUUID6 } from "node:crypto";
31829
+ import { createHash as createHash7, randomUUID as randomUUID7 } from "node:crypto";
31646
31830
  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
31831
  import { homedir as homedir11 } from "node:os";
31648
31832
  import { basename as basename3, dirname as dirname12, join as join12, relative, resolve as resolve16, sep } from "node:path";
@@ -31768,7 +31952,7 @@ function androidAgentEnv(input) {
31768
31952
  }
31769
31953
 
31770
31954
  // apps/body/dist/beeline-skill.js
31771
- import { readFileSync as readFileSync4 } from "node:fs";
31955
+ import { readFileSync as readFileSync5 } from "node:fs";
31772
31956
  import { resolve as resolve13 } from "node:path";
31773
31957
 
31774
31958
  // packages/api-contract/dist/phone-types.js
@@ -32275,7 +32459,7 @@ var BEELINE_ROOM_MECHANICS = [
32275
32459
  "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
32460
  "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
32461
  ].join(" ");
32278
- function runningBeelineReleaseId(env = process.env, read2 = (path) => readFileSync4(path, "utf8")) {
32462
+ function runningBeelineReleaseId(env = process.env, read2 = (path) => readFileSync5(path, "utf8")) {
32279
32463
  try {
32280
32464
  const lib = env.BEELINE_LIB_DIR;
32281
32465
  if (!lib)
@@ -32312,7 +32496,7 @@ The tools this build knows, what each is for, and which the owner of this machin
32312
32496
 
32313
32497
  **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
32498
 
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.
32499
+ **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
32500
 
32317
32501
  **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
32502
 
@@ -33579,7 +33763,7 @@ async function writeBackDetachedClaudeLogin(target, source) {
33579
33763
  const written = await withSharedClaudeLoginLock(shared, async () => {
33580
33764
  if (!await isNewer())
33581
33765
  return false;
33582
- const temp = `${shared}.beeline-${randomUUID6()}`;
33766
+ const temp = `${shared}.beeline-${randomUUID7()}`;
33583
33767
  try {
33584
33768
  await writeFile9(temp, detached, { flag: "wx", mode: 384 });
33585
33769
  await chmod5(temp, 384);
@@ -33596,7 +33780,7 @@ async function writeBackDetachedClaudeLogin(target, source) {
33596
33780
  return "not-newer";
33597
33781
  if (await readFile16(target, "utf8") !== detached)
33598
33782
  return "busy";
33599
- const link2 = `${target}.beeline-link-${randomUUID6()}`;
33783
+ const link2 = `${target}.beeline-link-${randomUUID7()}`;
33600
33784
  await symlink2(source, link2);
33601
33785
  await rename7(link2, target);
33602
33786
  return "linked";
@@ -33626,7 +33810,7 @@ async function repairRoomAgentCredentialLinks(input) {
33626
33810
  if (outcome !== "not-newer")
33627
33811
  continue;
33628
33812
  }
33629
- const quarantine = `${target}.beeline-quarantine-${Date.now()}-${randomUUID6()}`;
33813
+ const quarantine = `${target}.beeline-quarantine-${Date.now()}-${randomUUID7()}`;
33630
33814
  await rename7(target, quarantine);
33631
33815
  }
33632
33816
  await symlink2(source, target);
@@ -33745,7 +33929,7 @@ async function provisionAgentSkillsAndMcp(root, operatorHome, skillReleaseId, fa
33745
33929
  try {
33746
33930
  const source = resolve16(operatorHome, config.toml);
33747
33931
  const target = resolve16(root, config.dir, "config.toml");
33748
- const mcpSection = existsSync7(source) ? localHarnessMcpToml(readFileSync5(source, "utf8")) : void 0;
33932
+ const mcpSection = existsSync7(source) ? localHarnessMcpToml(readFileSync6(source, "utf8")) : void 0;
33749
33933
  const section = config.dir === "codex" ? [CODEX_ROOM_AGENT_LOCKDOWN_TOML, CODEX_ROOM_WEB_SEARCH_TOML, mcpSection].filter(Boolean).join("\n") : mcpSection;
33750
33934
  if (!section) {
33751
33935
  await unlink5(target).catch(() => void 0);
@@ -33765,7 +33949,7 @@ async function provisionAgentSkillsAndMcp(root, operatorHome, skillReleaseId, fa
33765
33949
  const source = resolve16(operatorHome, ".config", "goose", name);
33766
33950
  const target = resolve16(gooseConfigDir, name);
33767
33951
  if (existsSync7(source)) {
33768
- const body = readFileSync5(source, "utf8");
33952
+ const body = readFileSync6(source, "utf8");
33769
33953
  await writeIsolatedHarnessFile(target, name === "config.yaml" ? localGooseConfig(body) : body);
33770
33954
  } else {
33771
33955
  await unlink5(target).catch(() => void 0);
@@ -33843,7 +34027,7 @@ async function applyGrantedHostRoutes(root, operatorHome, granted, agentKind, fa
33843
34027
  if (Object.keys(routes).length === 0)
33844
34028
  continue;
33845
34029
  const target = resolve16(root, config.dir, "config.toml");
33846
- const existing = existsSync7(target) ? readFileSync5(target, "utf8") : void 0;
34030
+ const existing = existsSync7(target) ? readFileSync6(target, "utf8") : void 0;
33847
34031
  const merged = mergeTomlHostRoutes(existing, routes);
33848
34032
  if (merged)
33849
34033
  await writeIsolatedHarnessFile(target, merged);
@@ -33854,7 +34038,7 @@ async function applyGrantedHostRoutes(root, operatorHome, granted, agentKind, fa
33854
34038
  const gooseConfigDir = resolve16(root, "goose", "config");
33855
34039
  await mkdir11(gooseConfigDir, { recursive: true, mode: 448 });
33856
34040
  const target = resolve16(gooseConfigDir, "config.yaml");
33857
- const existing = existsSync7(target) ? readFileSync5(target, "utf8") : void 0;
34041
+ const existing = existsSync7(target) ? readFileSync6(target, "utf8") : void 0;
33858
34042
  const merged = mergeGooseHostRoutes(existing, routes);
33859
34043
  if (merged)
33860
34044
  await writeIsolatedHarnessFile(target, merged);
@@ -33929,7 +34113,7 @@ async function provisionPiCustomModelConfig(root, operatorHome, failClosed, open
33929
34113
  if (resolvedSource !== source) {
33930
34114
  throw new AgentHomeSecurityError(`Pi custom model config resolves through a link: ${source}`);
33931
34115
  }
33932
- const sourceValue = JSON.parse(readFileSync5(resolvedSource, "utf8"));
34116
+ const sourceValue = JSON.parse(readFileSync6(resolvedSource, "utf8"));
33933
34117
  await writeIsolatedHarnessFile(target, `${JSON.stringify(withOpenRouterModelRouting(sourceValue, pin), null, 2)}
33934
34118
  `);
33935
34119
  } catch (error) {
@@ -33941,7 +34125,7 @@ async function provisionPiCustomModelConfig(root, operatorHome, failClosed, open
33941
34125
  }
33942
34126
  function readClaudeUserScopeMcpServers(path) {
33943
34127
  try {
33944
- const parsed = JSON.parse(readFileSync5(path, "utf8"));
34128
+ const parsed = JSON.parse(readFileSync6(path, "utf8"));
33945
34129
  const servers = recordValue2(parsed.mcpServers);
33946
34130
  if (servers)
33947
34131
  return localMcpServers(servers);
@@ -34142,7 +34326,7 @@ function readExistingText(path) {
34142
34326
  if (!existsSync7(path))
34143
34327
  return void 0;
34144
34328
  try {
34145
- return readFileSync5(path, "utf8");
34329
+ return readFileSync6(path, "utf8");
34146
34330
  } catch {
34147
34331
  return void 0;
34148
34332
  }
@@ -34164,7 +34348,7 @@ async function provisionManagedSkillsDir(target, managedSkills, sharedSkills, op
34164
34348
  const plan = await planManagedSkills(managedSkills, sharedSkills, optionalShares);
34165
34349
  if (await materializedSkillManifest(target) === plan.manifest)
34166
34350
  return;
34167
- const staged = resolve16(parent, `.skills.${process.pid}.${randomUUID6()}.tmp`);
34351
+ const staged = resolve16(parent, `.skills.${process.pid}.${randomUUID7()}.tmp`);
34168
34352
  await mkdir11(staged, { mode: 448 });
34169
34353
  try {
34170
34354
  for (const entry of plan.entries) {
@@ -34416,7 +34600,7 @@ async function writeIsolatedHarnessFile(path, content) {
34416
34600
  if (!parentStats.isDirectory() || parentStats.isSymbolicLink()) {
34417
34601
  throw new Error(`isolated harness parent is not a real directory: ${parent}`);
34418
34602
  }
34419
- const temporary = resolve16(parent, `.${basename3(path)}.${process.pid}.${randomUUID6()}.tmp`);
34603
+ const temporary = resolve16(parent, `.${basename3(path)}.${process.pid}.${randomUUID7()}.tmp`);
34420
34604
  try {
34421
34605
  await writeFile9(temporary, content, { mode: 384, flag: "wx" });
34422
34606
  await chmod5(temporary, 384);
@@ -34473,8 +34657,8 @@ function harnessStateDirsFromEnv(env) {
34473
34657
  }
34474
34658
 
34475
34659
  // apps/body/dist/bwrap-sandbox.js
34476
- import { execFile as execFile6, spawnSync } from "node:child_process";
34477
- import { lstatSync, readdirSync as readdirSync3, readFileSync as readFileSync6, rmSync as rmSync2, writeFileSync as writeFileSync3 } from "node:fs";
34660
+ import { execFile as execFile7, spawnSync } from "node:child_process";
34661
+ import { lstatSync, readdirSync as readdirSync3, readFileSync as readFileSync7, rmSync as rmSync2, writeFileSync as writeFileSync3 } from "node:fs";
34478
34662
  import { homedir as homedir12 } from "node:os";
34479
34663
  import { basename as basename4, dirname as dirname13, isAbsolute as isAbsolute2, relative as relative2, resolve as resolve17 } from "node:path";
34480
34664
  var DEFAULT_SANDBOX_POLICY = "bwrap";
@@ -34533,7 +34717,7 @@ var KNOWN_CREDENTIAL_MASK_PATHS = [
34533
34717
  ".secrets.env",
34534
34718
  ".beeline/registry-mcp"
34535
34719
  ];
34536
- function credentialMaskPaths(extraPaths, home = homedir12(), stat10 = (path) => {
34720
+ function credentialMaskPaths(extraPaths, home = homedir12(), stat11 = (path) => {
34537
34721
  try {
34538
34722
  const info = lstatSync(path);
34539
34723
  return { isDirectory: info.isDirectory() };
@@ -34552,7 +34736,7 @@ function credentialMaskPaths(extraPaths, home = homedir12(), stat10 = (path) =>
34552
34736
  if (seen.has(path))
34553
34737
  continue;
34554
34738
  seen.add(path);
34555
- const info = stat10(path);
34739
+ const info = stat11(path);
34556
34740
  if (!info) {
34557
34741
  if (required.has(path))
34558
34742
  masks.push({ path, kind: "dir", create: true });
@@ -34787,7 +34971,7 @@ function readInstallFailure(stateDir) {
34787
34971
  if (!stateDir)
34788
34972
  return void 0;
34789
34973
  try {
34790
- const at = Number.parseInt(readFileSync6(installFailureMarker(stateDir), "utf8").trim(), 10);
34974
+ const at = Number.parseInt(readFileSync7(installFailureMarker(stateDir), "utf8").trim(), 10);
34791
34975
  return Number.isFinite(at) ? at : void 0;
34792
34976
  } catch {
34793
34977
  return void 0;
@@ -34810,8 +34994,8 @@ function clearInstallFailure(stateDir) {
34810
34994
  } catch {
34811
34995
  }
34812
34996
  }
34813
- var runSandboxInstallCommand = (command, args) => new Promise((resolve45) => {
34814
- execFile6(command, [...args], {
34997
+ var runSandboxInstallCommand = (command, args) => new Promise((resolve49) => {
34998
+ execFile7(command, [...args], {
34815
34999
  timeout: INSTALL_TIMEOUT_MS,
34816
35000
  maxBuffer: INSTALL_OUTPUT_LIMIT * 2,
34817
35001
  // A dpkg prompt on a host with a held conffile would otherwise sit on
@@ -34820,7 +35004,7 @@ var runSandboxInstallCommand = (command, args) => new Promise((resolve45) => {
34820
35004
  }, (error, stdout6, stderr) => {
34821
35005
  const code = error && "code" in error && typeof error.code === "number" ? error.code : error ? null : 0;
34822
35006
  const output = [stdout6, stderr].join("").trim();
34823
- resolve45({ code, output: output || (error ? error.message : "") });
35007
+ resolve49({ code, output: output || (error ? error.message : "") });
34824
35008
  });
34825
35009
  });
34826
35010
  function lastLine2(output, fallback) {
@@ -35105,7 +35289,7 @@ function isAllowedAgentModelConfigCategory(category, id) {
35105
35289
  }
35106
35290
 
35107
35291
  // apps/body/dist/model-config.js
35108
- import { lstatSync as lstatSync2, readFileSync as readFileSync7 } from "node:fs";
35292
+ import { lstatSync as lstatSync2, readFileSync as readFileSync8 } from "node:fs";
35109
35293
  import { basename as basename5, resolve as resolve19 } from "node:path";
35110
35294
 
35111
35295
  // apps/body/dist/transient-provider-error.js
@@ -35331,7 +35515,7 @@ function credentialedPiCustomProviders(env) {
35331
35515
  if (!stats.isFile() || stats.isSymbolicLink() || stats.nlink !== 1 || stats.size > 1048576) {
35332
35516
  return held;
35333
35517
  }
35334
- const parsed = JSON.parse(readFileSync7(path, "utf8"));
35518
+ const parsed = JSON.parse(readFileSync8(path, "utf8"));
35335
35519
  const providers = parsed.providers;
35336
35520
  const remember = (name, config) => {
35337
35521
  if (typeof name !== "string" || !name.trim() || !config || typeof config !== "object")
@@ -35564,7 +35748,7 @@ function describeCurrentReleaseOutcome(outcome) {
35564
35748
  async function retryWhileAdapterReinstalls(run2, options = {}) {
35565
35749
  const attempts = options.attempts ?? 12;
35566
35750
  const delayMs = options.delayMs ?? 5e3;
35567
- const sleep4 = options.sleep ?? ((ms) => new Promise((resolve45) => setTimeout(resolve45, ms)));
35751
+ const sleep4 = options.sleep ?? ((ms) => new Promise((resolve49) => setTimeout(resolve49, ms)));
35568
35752
  for (let attempt = 1; ; attempt += 1) {
35569
35753
  try {
35570
35754
  return await run2();
@@ -36792,7 +36976,7 @@ async function runStartCommand(args, interactiveUi, dependencyOverrides = {}) {
36792
36976
 
36793
36977
  // apps/body/dist/connect-command.js
36794
36978
  import { spawn as spawn13 } from "node:child_process";
36795
- import { createHash as createHash9, randomUUID as randomUUID7 } from "node:crypto";
36979
+ import { createHash as createHash9, randomUUID as randomUUID8 } from "node:crypto";
36796
36980
  import { chmod as chmod7, mkdir as mkdir16, readFile as readFile20, unlink as unlink7, writeFile as writeFile13 } from "node:fs/promises";
36797
36981
  import { homedir as homedir15, hostname } from "node:os";
36798
36982
  import { dirname as dirname19, resolve as resolve26 } from "node:path";
@@ -36912,7 +37096,7 @@ async function validateAgentModelSelection(agent, agentEnv, selection) {
36912
37096
  }
36913
37097
 
36914
37098
  // apps/body/dist/config.js
36915
- import { accessSync as accessSync3, constants as constants2, existsSync as existsSync8, readFileSync as readFileSync8 } from "node:fs";
37099
+ import { accessSync as accessSync3, constants as constants2, existsSync as existsSync8, readFileSync as readFileSync9 } from "node:fs";
36916
37100
  import { basename as basename7, dirname as dirname17, resolve as resolve24 } from "node:path";
36917
37101
  function firstExisting2(paths) {
36918
37102
  for (const p of paths) {
@@ -37009,7 +37193,7 @@ function parseEnvFile(path) {
37009
37193
  const out = {};
37010
37194
  if (!existsSync8(path))
37011
37195
  return out;
37012
- const text2 = readFileSync8(path, "utf8");
37196
+ const text2 = readFileSync9(path, "utf8");
37013
37197
  for (const raw of text2.split("\n")) {
37014
37198
  const line = raw.trim();
37015
37199
  if (!line || line.startsWith("#"))
@@ -37856,7 +38040,7 @@ async function readMachineId(env = process.env) {
37856
38040
  if (!/^[0-9a-f-]{32,}$/.test(machineId))
37857
38041
  throw new Error("invalid persisted machine id");
37858
38042
  } catch {
37859
- machineId = randomUUID7();
38043
+ machineId = randomUUID8();
37860
38044
  try {
37861
38045
  await mkdir16(configDir, { recursive: true, mode: 448 });
37862
38046
  await writeFile13(machineIdPath, `${machineId}
@@ -38186,7 +38370,7 @@ async function probeReleaseInSubprocess(input) {
38186
38370
  return { kind: "unavailable", reason: `release ${input.releaseId} has no runnable CLI entrypoint` };
38187
38371
  }
38188
38372
  const timeoutMs = input.timeoutMs ?? CURRENT_RELEASE_PROBE_TIMEOUT_MS;
38189
- return new Promise((resolve45) => {
38373
+ return new Promise((resolve49) => {
38190
38374
  const child = spawn14(input.execPath ?? process.execPath, [entrypoint, UPDATE_PROBE_COMMAND, "--config", input.runtimeConfigPath], { env: input.env ?? process.env, stdio: ["ignore", "pipe", "pipe"] });
38191
38375
  let stdout6 = "";
38192
38376
  let stderr = "";
@@ -38196,7 +38380,7 @@ async function probeReleaseInSubprocess(input) {
38196
38380
  return;
38197
38381
  settled = true;
38198
38382
  clearTimeout(timer);
38199
- resolve45(outcome);
38383
+ resolve49(outcome);
38200
38384
  };
38201
38385
  const timer = setTimeout(() => {
38202
38386
  child.kill("SIGKILL");
@@ -38276,12 +38460,12 @@ async function runUpdateProbeCommand(args, options = {}) {
38276
38460
  }
38277
38461
 
38278
38462
  // apps/body/dist/machine-helper.js
38279
- import { mkdir as mkdir29, rename as rename13, stat as stat9, writeFile as writeFile22 } from "node:fs/promises";
38280
- import { dirname as dirname30 } from "node:path";
38463
+ import { mkdir as mkdir29, rename as rename13, stat as stat10, writeFile as writeFile22 } from "node:fs/promises";
38464
+ import { dirname as dirname31, resolve as resolve47 } from "node:path";
38281
38465
 
38282
38466
  // apps/body/dist/agent-runtime.js
38283
38467
  import { homedir as homedir19 } from "node:os";
38284
- import { dirname as dirname29, join as join21, resolve as resolve43 } from "node:path";
38468
+ import { dirname as dirname30, join as join23, resolve as resolve45 } from "node:path";
38285
38469
 
38286
38470
  // apps/body/dist/model-availability.js
38287
38471
  var SECRET_VALUE = /(?:token|key|secret|password)=?[^\s,;]*/gi;
@@ -38404,8 +38588,8 @@ async function syncAgentModelCatalog(input) {
38404
38588
  }
38405
38589
 
38406
38590
  // apps/body/dist/connector-tailscale.js
38407
- import { execFile as execFile7 } from "node:child_process";
38408
- import { randomUUID as randomUUID8 } from "node:crypto";
38591
+ import { execFile as execFile8 } from "node:child_process";
38592
+ import { randomUUID as randomUUID9 } from "node:crypto";
38409
38593
  import { rm as rm10 } from "node:fs/promises";
38410
38594
  import { tmpdir as tmpdir3, userInfo } from "node:os";
38411
38595
  import { join as join14 } from "node:path";
@@ -38415,10 +38599,10 @@ var LOGIN_URL = /https:\/\/login\.tailscale\.com\/[A-Za-z0-9_/-]+/u;
38415
38599
  function clipped(value) {
38416
38600
  return value.length <= OUTPUT_LIMIT ? value : value.slice(value.length - OUTPUT_LIMIT);
38417
38601
  }
38418
- var runTailscaleCommand = (command, args) => new Promise((resolve45) => {
38419
- execFile7(command, [...args], { timeout: COMMAND_TIMEOUT_MS, maxBuffer: OUTPUT_LIMIT * 2 }, (error, stdout6, stderr) => {
38602
+ var runTailscaleCommand = (command, args) => new Promise((resolve49) => {
38603
+ execFile8(command, [...args], { timeout: COMMAND_TIMEOUT_MS, maxBuffer: OUTPUT_LIMIT * 2 }, (error, stdout6, stderr) => {
38420
38604
  const code = error && "code" in error && typeof error.code === "number" ? error.code : error ? null : 0;
38421
- resolve45({ code, stdout: clipped(stdout6), stderr: clipped(stderr) });
38605
+ resolve49({ code, stdout: clipped(stdout6), stderr: clipped(stderr) });
38422
38606
  });
38423
38607
  });
38424
38608
  function loginUrlFrom(status, output) {
@@ -38495,7 +38679,7 @@ async function ensureInstalled(run2, onProgress, platform) {
38495
38679
  }
38496
38680
  };
38497
38681
  }
38498
- const script = join14(tmpdir3(), `beeline-tailscale-install-${process.pid}-${randomUUID8()}.sh`);
38682
+ const script = join14(tmpdir3(), `beeline-tailscale-install-${process.pid}-${randomUUID9()}.sh`);
38499
38683
  const steps2 = [
38500
38684
  step2("Tailscale installed", "running", {
38501
38685
  command: "curl -fsSL https://tailscale.com/install.sh"
@@ -38978,16 +39162,16 @@ function describe2(error) {
38978
39162
  }
38979
39163
 
38980
39164
  // apps/body/dist/room-runtime.js
38981
- import { execFile as execFile13 } from "node:child_process";
39165
+ import { execFile as execFile16 } from "node:child_process";
38982
39166
  import { createHash as createHash14 } from "node:crypto";
38983
39167
  import { existsSync as existsSync10, mkdirSync as mkdirSync3 } from "node:fs";
38984
- import { mkdir as mkdir27, readdir as readdir9, realpath as realpath2, rm as rm15 } from "node:fs/promises";
38985
- import { dirname as dirname27, relative as relative3, resolve as resolve38, sep as sep2 } from "node:path";
38986
- import { promisify as promisify8 } from "node:util";
39168
+ import { lstat as lstat7, mkdir as mkdir27, readdir as readdir11, realpath as realpath3, rm as rm17 } from "node:fs/promises";
39169
+ import { dirname as dirname28, relative as relative4, resolve as resolve40, sep as sep3 } from "node:path";
39170
+ import { promisify as promisify11 } from "node:util";
38987
39171
 
38988
39172
  // apps/body/dist/grant-runner.js
38989
- import { execFile as execFile8 } from "node:child_process";
38990
- import { createHash as createHash11, randomBytes as randomBytes9, randomUUID as randomUUID9 } from "node:crypto";
39173
+ import { execFile as execFile9 } from "node:child_process";
39174
+ import { createHash as createHash11, randomBytes as randomBytes9, randomUUID as randomUUID10 } from "node:crypto";
38991
39175
  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
39176
  import { createServer as createServer3 } from "node:http";
38993
39177
  import { dirname as dirname21, resolve as resolve28 } from "node:path";
@@ -39168,7 +39352,7 @@ var GrantCommandRunner = class {
39168
39352
  const sandboxMarker = runsOnHost ? void 0 : `[beeline-sandbox-started:${randomBytes9(16).toString("hex")}]`;
39169
39353
  const spawn15 = runsOnHost ? { command: argv[0], args: argv.slice(1) } : roomSandboxCommand(policy, room.cwd, argv, sandboxMarker);
39170
39354
  const outcome = await new Promise((resolveRun) => {
39171
- const child = execFile8(spawn15.command, spawn15.args, {
39355
+ const child = execFile9(spawn15.command, spawn15.args, {
39172
39356
  cwd: room.cwd,
39173
39357
  env,
39174
39358
  timeout: this.options.timeoutMs ?? GRANT_COMMAND_TIMEOUT_MS,
@@ -39538,13 +39722,13 @@ var TurnUsageAccumulator = class {
39538
39722
  };
39539
39723
 
39540
39724
  // apps/body/dist/server-command-intake.js
39541
- import { randomUUID as randomUUID10 } from "node:crypto";
39725
+ import { randomUUID as randomUUID11 } from "node:crypto";
39542
39726
  import { mkdir as mkdir18, writeFile as writeFile16 } from "node:fs/promises";
39543
39727
  import { writeFileSync as writeFileSync4 } from "node:fs";
39544
39728
  import { tmpdir as tmpdir4 } from "node:os";
39545
39729
  import { dirname as dirname22, join as join16 } from "node:path";
39546
39730
  var CommandExecutionContext = class {
39547
- generationId = randomUUID10();
39731
+ generationId = randomUUID11();
39548
39732
  path;
39549
39733
  current;
39550
39734
  constructor(root) {
@@ -39702,11 +39886,11 @@ async function runServerCommandIntake(options) {
39702
39886
  if (attempt === 3)
39703
39887
  throw error;
39704
39888
  const waitMs = Math.max(250 * 2 ** attempt, error instanceof DaemonApiError ? error.retryAfterMs ?? 0 : 0);
39705
- await new Promise((resolve45) => {
39889
+ await new Promise((resolve49) => {
39706
39890
  const done = () => {
39707
39891
  clearTimeout(timer);
39708
39892
  signal?.removeEventListener("abort", done);
39709
- resolve45();
39893
+ resolve49();
39710
39894
  };
39711
39895
  const timer = setTimeout(done, waitMs);
39712
39896
  signal?.addEventListener("abort", done, { once: true });
@@ -39797,11 +39981,11 @@ async function runServerCommandIntake(options) {
39797
39981
  }
39798
39982
  }
39799
39983
  options.onPoll?.();
39800
- const reconcile = await new Promise((resolve45) => {
39984
+ const reconcile = await new Promise((resolve49) => {
39801
39985
  const done = (needed) => {
39802
39986
  signal?.removeEventListener("abort", aborted);
39803
39987
  wake = void 0;
39804
- resolve45(needed);
39988
+ resolve49(needed);
39805
39989
  };
39806
39990
  const aborted = () => done(false);
39807
39991
  wake = done;
@@ -39841,13 +40025,13 @@ async function runServerCommandIntake(options) {
39841
40025
  }
39842
40026
 
39843
40027
  // apps/body/dist/monolith-corner-turn.js
39844
- import { execFile as execFile12 } from "node:child_process";
40028
+ import { execFile as execFile14 } from "node:child_process";
39845
40029
  import { createHash as createHash13 } from "node:crypto";
39846
40030
  import { existsSync as existsSync9 } from "node:fs";
39847
40031
  import { mkdir as mkdir26, readFile as readFile30, writeFile as writeFile20 } from "node:fs/promises";
39848
40032
  import { homedir as homedir18, hostname as hostname3 } from "node:os";
39849
- import { dirname as dirname26, join as join20, resolve as resolve37 } from "node:path";
39850
- import { promisify as promisify7 } from "node:util";
40033
+ import { dirname as dirname26, join as join21, resolve as resolve38 } from "node:path";
40034
+ import { promisify as promisify9 } from "node:util";
39851
40035
 
39852
40036
  // apps/body/dist/agent-command-catalog.js
39853
40037
  function agentCommandCatalogPublisher(input) {
@@ -40497,13 +40681,13 @@ async function hasCornerPrepareScript(worktreePath) {
40497
40681
  }
40498
40682
 
40499
40683
  // apps/body/dist/pi-mcp-bridge.js
40500
- import { execFile as execFile9 } from "node:child_process";
40684
+ import { execFile as execFile10 } from "node:child_process";
40501
40685
  import { mkdtemp as mkdtemp2, mkdir as mkdir20, readFile as readFile26, rm as rm12, unlink as unlink8 } from "node:fs/promises";
40502
40686
  import { tmpdir as tmpdir5 } from "node:os";
40503
40687
  import { resolve as resolve30 } from "node:path";
40504
- import { promisify as promisify5 } from "node:util";
40688
+ import { promisify as promisify6 } from "node:util";
40505
40689
  var PI_MCP_BRIDGE_FILENAME = "beeline-mcp-bridge.js";
40506
- var execFileAsync5 = promisify5(execFile9);
40690
+ var execFileAsync6 = promisify6(execFile10);
40507
40691
  var nativeMcpProbes = /* @__PURE__ */ new Map();
40508
40692
  async function piHasNativeMcp(command, env) {
40509
40693
  const path = env?.PATH ?? process.env.PATH ?? "";
@@ -40513,7 +40697,7 @@ async function piHasNativeMcp(command, env) {
40513
40697
  probe = (async () => {
40514
40698
  const home = await mkdtemp2(resolve30(tmpdir5(), "beeline-pi-mcp-probe-"));
40515
40699
  try {
40516
- const { stdout: stdout6 } = await execFileAsync5(command, ["mcp", "list", "--json"], {
40700
+ const { stdout: stdout6 } = await execFileAsync6(command, ["mcp", "list", "--json"], {
40517
40701
  cwd: home,
40518
40702
  timeout: 1200,
40519
40703
  env: { PATH: path, HOME: home, PI_CODING_AGENT_DIR: home, PI_OFFLINE: "1" }
@@ -40810,7 +40994,7 @@ export default async function (pi) {
40810
40994
  `;
40811
40995
 
40812
40996
  // apps/body/dist/corner-branch-sync.js
40813
- import { execFile as execFile10 } from "node:child_process";
40997
+ import { execFile as execFile11 } from "node:child_process";
40814
40998
  import { access as access2, readFile as readFile27 } from "node:fs/promises";
40815
40999
  import { resolve as resolve31 } from "node:path";
40816
41000
  var CORNER_GIT_SYNC_TIMEOUT_MS = 12e4;
@@ -40818,7 +41002,7 @@ var CORNER_GIT_SYNC_KILL_GRACE_MS = 1e3;
40818
41002
  var CornerGitSyncInterruptedError = class extends Error {
40819
41003
  };
40820
41004
  async function syncCornerBranch(input) {
40821
- const git = async (args, cleanup = false) => {
41005
+ const git2 = async (args, cleanup = false) => {
40822
41006
  const controller = new AbortController();
40823
41007
  const signal = input.signal && !cleanup ? AbortSignal.any([input.signal, controller.signal]) : controller.signal;
40824
41008
  const timer = setTimeout(() => controller.abort(), CORNER_GIT_SYNC_TIMEOUT_MS);
@@ -40826,11 +41010,11 @@ async function syncCornerBranch(input) {
40826
41010
  try {
40827
41011
  if (signal.aborted)
40828
41012
  throw interrupted();
40829
- return await new Promise((resolve45, reject) => {
41013
+ return await new Promise((resolve49, reject) => {
40830
41014
  let killTimer;
40831
41015
  let stdout6 = "";
40832
41016
  let failure = null;
40833
- const child = input.git ? void 0 : execFile10("git", ["-C", input.worktreePath, ...args], {
41017
+ const child = input.git ? void 0 : execFile11("git", ["-C", input.worktreePath, ...args], {
40834
41018
  ...input.env ? { env: input.env } : {},
40835
41019
  signal,
40836
41020
  maxBuffer: 4 * 1024 * 1024
@@ -40860,10 +41044,10 @@ async function syncCornerBranch(input) {
40860
41044
  else if (failure)
40861
41045
  reject(failure);
40862
41046
  else
40863
- resolve45(stdout6);
41047
+ resolve49(stdout6);
40864
41048
  });
40865
41049
  else
40866
- input.git(args).then(resolve45, reject).finally(cleanup2);
41050
+ input.git(args).then(resolve49, reject).finally(cleanup2);
40867
41051
  });
40868
41052
  } finally {
40869
41053
  clearTimeout(timer);
@@ -40873,10 +41057,10 @@ async function syncCornerBranch(input) {
40873
41057
  const gitDir = resolve31(input.worktreePath, marker.startsWith("gitdir: ") ? marker.slice(8).trim() : ".git");
40874
41058
  for (const directory of ["rebase-merge", "rebase-apply"]) {
40875
41059
  if (await access2(resolve31(gitDir, directory)).then(() => true, () => false))
40876
- await git(["rebase", "--abort"], true);
41060
+ await git2(["rebase", "--abort"], true);
40877
41061
  }
40878
41062
  const remoteRef = `refs/remotes/origin/${input.featureBranch}`;
40879
- const fetched = await git([
41063
+ const fetched = await git2([
40880
41064
  "fetch",
40881
41065
  "origin",
40882
41066
  `+refs/heads/${input.featureBranch}:${remoteRef}`
@@ -40888,31 +41072,31 @@ async function syncCornerBranch(input) {
40888
41072
  });
40889
41073
  if (!fetched)
40890
41074
  return "unchanged";
40891
- const remote = (await git(["rev-parse", remoteRef])).trim();
41075
+ const remote = (await git2(["rev-parse", remoteRef])).trim();
40892
41076
  if (!remote)
40893
41077
  throw new Error(`fetched corner branch has no remote ref: ${remoteRef}`);
40894
- const local = (await git(["rev-parse", "HEAD"])).trim();
41078
+ const local = (await git2(["rev-parse", "HEAD"])).trim();
40895
41079
  if (local === remote)
40896
41080
  return "unchanged";
40897
- if (await contains(git, local, remote))
41081
+ if (await contains(git2, local, remote))
40898
41082
  return "unchanged";
40899
- const behind = await contains(git, remote, local);
41083
+ const behind = await contains(git2, remote, local);
40900
41084
  try {
40901
- await git(behind ? ["merge", "--ff-only", remote] : ["rebase", remote]);
41085
+ await git2(behind ? ["merge", "--ff-only", remote] : ["rebase", remote]);
40902
41086
  return behind ? "fast-forwarded" : "rebased";
40903
41087
  } catch (error) {
40904
- await git(["rebase", "--abort"], true).catch((error2) => {
41088
+ await git2(["rebase", "--abort"], true).catch((error2) => {
40905
41089
  if (error2 instanceof CornerGitSyncInterruptedError)
40906
41090
  throw error2;
40907
41091
  });
40908
41092
  if (error instanceof CornerGitSyncInterruptedError)
40909
41093
  throw error;
40910
- await git(["reset", "--hard", remote]);
41094
+ await git2(["reset", "--hard", remote]);
40911
41095
  return "realigned";
40912
41096
  }
40913
41097
  }
40914
- async function contains(git, head, ancestor) {
40915
- return git(["merge-base", "--is-ancestor", ancestor, head]).then(() => true, (error) => {
41098
+ async function contains(git2, head, ancestor) {
41099
+ return git2(["merge-base", "--is-ancestor", ancestor, head]).then(() => true, (error) => {
40916
41100
  if (error instanceof CornerGitSyncInterruptedError)
40917
41101
  throw error;
40918
41102
  return false;
@@ -41066,6 +41250,7 @@ var AGENT_SURFACE_TOOL_NAMES = [
41066
41250
  "pr_checks_status",
41067
41251
  "post_artifact",
41068
41252
  "write_scratch_file",
41253
+ "scratch_status",
41069
41254
  "fetch_image",
41070
41255
  "connect_app"
41071
41256
  ];
@@ -41138,11 +41323,11 @@ function beelineAgentMcpServer(config, api, context) {
41138
41323
  { name: "BEELINE_DAEMON_ROOM_ID", value: context.roomId },
41139
41324
  { name: "BEELINE_DAEMON_WORKSPACE_ID", value: context.workspaceId },
41140
41325
  ...context.cornerId ? [{ name: "BEELINE_DAEMON_CORNER_ID", value: context.cornerId }] : [],
41141
- ...context.agentMayCloseCorner ? [{ name: "BEELINE_CORNER_AGENT_CLOSE", value: "1" }] : [],
41142
41326
  ...context.reviewer ? [{ name: "BEELINE_CORNER_REVIEWER", value: "1" }] : [],
41143
41327
  ...context.cornerId && context.repositoryBacked ? [{ name: "BEELINE_CORNER_REPOSITORY", value: "1" }] : [],
41144
41328
  ...context.attachRoot ? [{ name: "BEELINE_ATTACH_ROOT", value: context.attachRoot }] : [],
41145
41329
  ...context.attachScratchRoot ? [{ name: "BEELINE_ATTACH_SCRATCH_ROOT", value: context.attachScratchRoot }] : [],
41330
+ ...context.cornerScratchRoot ? [{ name: "BEELINE_CORNER_SCRATCH_ROOT", value: context.cornerScratchRoot }] : [],
41146
41331
  ...context.grantRunner ? [
41147
41332
  { name: "BEELINE_GRANT_RUNNER_URL", value: context.grantRunner.url },
41148
41333
  { name: "BEELINE_GRANT_RUNNER_TOKEN", value: context.grantRunner.token }
@@ -41172,6 +41357,90 @@ function readOnlyMcpServer(config, cwd, agentMemoryDir) {
41172
41357
  };
41173
41358
  }
41174
41359
 
41360
+ // apps/body/dist/scratch-lifecycle.js
41361
+ import { execFile as execFile12 } from "node:child_process";
41362
+ import { lstat as lstat4, readdir as readdir7, rmdir as rmdir2, rm as rm13, stat as stat8, unlink as unlink9 } from "node:fs/promises";
41363
+ import { join as join18, resolve as resolve33 } from "node:path";
41364
+ import { promisify as promisify7 } from "node:util";
41365
+ var execFileAsync7 = promisify7(execFile12);
41366
+ var CORNER_SCRATCH_BUDGET_BYTES = 5 * 1024 ** 3;
41367
+ var CORNER_SCRATCH_TTL_MS = 14 * 24 * 60 * 6e4;
41368
+ var SHARED_MODEL_CACHE_BUDGET_BYTES = 32 * 1024 ** 3;
41369
+ var MODEL_CACHE_IDLE_MS = 24 * 60 * 6e4;
41370
+ async function allocatedDirectoryBytes(path) {
41371
+ if (!await lstat4(path).catch(() => void 0))
41372
+ return 0;
41373
+ const output = await execFileAsync7("du", ["-s", "-B1", "--", path], {
41374
+ maxBuffer: 1024 * 1024
41375
+ }).then((result) => result.stdout);
41376
+ const bytes = Number(output.split(/\s+/)[0]);
41377
+ if (!Number.isSafeInteger(bytes) || bytes < 0)
41378
+ throw new Error("scratch usage could not be measured");
41379
+ return bytes;
41380
+ }
41381
+ function scratchBudgetMessage(usage2, budget = CORNER_SCRATCH_BUDGET_BYTES) {
41382
+ const mib = (bytes) => Math.ceil(bytes / 1024 ** 2);
41383
+ 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();
41384
+ }
41385
+ function scratchGrowthExceedsBudget(usage2, atTurnStart, budget = CORNER_SCRATCH_BUDGET_BYTES) {
41386
+ return usage2 > budget && usage2 > atTurnStart;
41387
+ }
41388
+ async function sweepStaleCornerScratch(root, now2 = Date.now(), ttlMs = CORNER_SCRATCH_TTL_MS) {
41389
+ const cutoff = now2 - ttlMs;
41390
+ let files = 0;
41391
+ let bytes = 0;
41392
+ const visit = async (dir, top) => {
41393
+ for (const entry of await readdir7(dir, { withFileTypes: true }).catch(() => [])) {
41394
+ if (top && (entry.name === "agent-home" || entry.name === ".git"))
41395
+ continue;
41396
+ const path = join18(dir, entry.name);
41397
+ const info = await lstat4(path).catch(() => void 0);
41398
+ if (!info || info.isSymbolicLink())
41399
+ continue;
41400
+ if (info.isDirectory()) {
41401
+ await visit(path, false);
41402
+ if (!top)
41403
+ await rmdir2(path).catch(() => void 0);
41404
+ } else if (info.isFile() && info.mtimeMs < cutoff) {
41405
+ await unlink9(path);
41406
+ files++;
41407
+ bytes += info.size;
41408
+ }
41409
+ }
41410
+ };
41411
+ if ((await lstat4(root).catch(() => void 0))?.isDirectory())
41412
+ await visit(resolve33(root), true);
41413
+ return { files, bytes };
41414
+ }
41415
+ async function pruneSharedModelCache(root, now2 = Date.now(), budget = SHARED_MODEL_CACHE_BUDGET_BYTES) {
41416
+ let usage2 = await allocatedDirectoryBytes(root);
41417
+ if (usage2 <= budget)
41418
+ return [];
41419
+ const candidates = [];
41420
+ for (const parent of [join18(root, "hub"), root]) {
41421
+ for (const entry of await readdir7(parent, { withFileTypes: true }).catch(() => [])) {
41422
+ const eligible = parent === root ? entry.name === "xet" : /^(?:models|datasets|spaces)--/.test(entry.name);
41423
+ if (!eligible || !entry.isDirectory())
41424
+ continue;
41425
+ const path = join18(parent, entry.name);
41426
+ const info = await stat8(path);
41427
+ if (info.mtimeMs > now2 - MODEL_CACHE_IDLE_MS)
41428
+ continue;
41429
+ candidates.push({ path, usedAt: info.mtimeMs });
41430
+ }
41431
+ }
41432
+ candidates.sort((a2, b) => a2.usedAt - b.usedAt || a2.path.localeCompare(b.path));
41433
+ const removed = [];
41434
+ for (const item of candidates) {
41435
+ if (usage2 <= budget)
41436
+ break;
41437
+ await rm13(item.path, { recursive: true, force: true });
41438
+ usage2 = await allocatedDirectoryBytes(root);
41439
+ removed.push(item.path);
41440
+ }
41441
+ return removed;
41442
+ }
41443
+
41175
41444
  // apps/body/dist/institutional-context.js
41176
41445
  import { performance as performance2 } from "node:perf_hooks";
41177
41446
  var INSTITUTIONAL_CONTEXT_TIMEOUT_MS = 500;
@@ -41220,16 +41489,16 @@ async function awaitInstitutionalContext(fetch2, log2 = console.warn, budgetMs =
41220
41489
  }
41221
41490
 
41222
41491
  // apps/body/dist/codegraph.js
41223
- import { execFile as execFile11 } from "node:child_process";
41492
+ import { execFile as execFile13 } from "node:child_process";
41224
41493
  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 resolve33 } from "node:path";
41226
- import { promisify as promisify6 } from "node:util";
41227
- var execFileAsync6 = promisify6(execFile11);
41494
+ import { dirname as dirname23, isAbsolute as isAbsolute3, resolve as resolve34 } from "node:path";
41495
+ import { promisify as promisify8 } from "node:util";
41496
+ var execFileAsync8 = promisify8(execFile13);
41228
41497
  var CODEGRAPH_MCP_SERVER_NAME = "codegraph";
41229
41498
  var CODEGRAPH_INDEX_PATH = ".codegraph/codegraph.db";
41230
41499
  var CODEGRAPH_PREPARE_TIMEOUT_MS = 12e4;
41231
41500
  function codegraphIndexDirectory(cwd) {
41232
- return resolve33(cwd, dirname23(CODEGRAPH_INDEX_PATH));
41501
+ return resolve34(cwd, dirname23(CODEGRAPH_INDEX_PATH));
41233
41502
  }
41234
41503
  function codegraphMcpServer(config, cwd, options) {
41235
41504
  if (!config.codegraphCommand)
@@ -41237,7 +41506,7 @@ function codegraphMcpServer(config, cwd, options) {
41237
41506
  return {
41238
41507
  name: CODEGRAPH_MCP_SERVER_NAME,
41239
41508
  command: config.codegraphCommand,
41240
- args: ["serve", "--mcp", "--path", resolve33(cwd), ...options.readonly ? ["--no-watch"] : []],
41509
+ args: ["serve", "--mcp", "--path", resolve34(cwd), ...options.readonly ? ["--no-watch"] : []],
41241
41510
  env: [
41242
41511
  { name: "CODEGRAPH_TELEMETRY", value: "0" },
41243
41512
  // One MCP child per harness session is easier to contain than a daemon
@@ -41251,25 +41520,25 @@ function codegraphFingerprintServers(config, servers, mounted = Boolean(config.c
41251
41520
  }
41252
41521
  async function isGitWorktree(cwd) {
41253
41522
  try {
41254
- const { stdout: stdout6 } = await execFileAsync6("git", ["rev-parse", "--show-toplevel"], {
41523
+ const { stdout: stdout6 } = await execFileAsync8("git", ["rev-parse", "--show-toplevel"], {
41255
41524
  cwd,
41256
41525
  timeout: 1e4
41257
41526
  });
41258
- return resolve33(stdout6.trim()) === resolve33(cwd);
41527
+ return resolve34(stdout6.trim()) === resolve34(cwd);
41259
41528
  } catch {
41260
41529
  return false;
41261
41530
  }
41262
41531
  }
41263
41532
  async function excludeIndexFromGitStatus(cwd) {
41264
41533
  try {
41265
- const { stdout: stdout6 } = await execFileAsync6("git", ["rev-parse", "--git-path", "info/exclude"], {
41534
+ const { stdout: stdout6 } = await execFileAsync8("git", ["rev-parse", "--git-path", "info/exclude"], {
41266
41535
  cwd,
41267
41536
  timeout: 1e4
41268
41537
  });
41269
41538
  const gitPath = stdout6.trim();
41270
41539
  if (!gitPath)
41271
41540
  return;
41272
- const path = isAbsolute3(gitPath) ? gitPath : resolve33(cwd, gitPath);
41541
+ const path = isAbsolute3(gitPath) ? gitPath : resolve34(cwd, gitPath);
41273
41542
  await mkdir21(dirname23(path), { recursive: true });
41274
41543
  const existing = await readFile28(path, "utf8").catch(() => "");
41275
41544
  if (existing.split("\n").includes(".codegraph/"))
@@ -41284,11 +41553,11 @@ async function prepareCodegraphIndex(config, cwd) {
41284
41553
  if (!command || !await isGitWorktree(cwd))
41285
41554
  return false;
41286
41555
  await excludeIndexFromGitStatus(cwd);
41287
- const indexPath = resolve33(cwd, CODEGRAPH_INDEX_PATH);
41556
+ const indexPath = resolve34(cwd, CODEGRAPH_INDEX_PATH);
41288
41557
  const indexed = await access3(indexPath).then(() => true, () => false);
41289
41558
  const args = indexed ? ["sync", "--quiet", cwd] : ["init", "--yes", cwd];
41290
41559
  try {
41291
- await execFileAsync6(command, args, {
41560
+ await execFileAsync8(command, args, {
41292
41561
  cwd,
41293
41562
  env: { ...process.env, CODEGRAPH_TELEMETRY: "0", CODEGRAPH_NO_DAEMON: "1" },
41294
41563
  timeout: CODEGRAPH_PREPARE_TIMEOUT_MS,
@@ -41304,7 +41573,7 @@ async function prepareCodegraphIndex(config, cwd) {
41304
41573
  // apps/body/dist/monolith-room-turn.js
41305
41574
  import { mkdir as mkdir23, writeFile as writeFile18 } from "node:fs/promises";
41306
41575
  import { homedir as homedir17, hostname as hostname2 } from "node:os";
41307
- import { dirname as dirname24, join as join18 } from "node:path";
41576
+ import { dirname as dirname24, join as join19 } from "node:path";
41308
41577
 
41309
41578
  // packages/api-contract/dist/scheduled-prompts.js
41310
41579
  var SCHEDULE_SCHEDULER_NAME = "Beeline Scheduler";
@@ -41408,6 +41677,7 @@ function cornerHasRepositoryWork(brief) {
41408
41677
  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
41678
  Meet every story; respect every non-goal and risk.
41410
41679
  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.
41680
+ 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
41681
  Follow the beeline-triage skill's bugfix execution contract when the spec or its approval quote reports a defect.
41412
41682
  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
41683
  Fix only the spec and approval quote. With a reproduction, change only what removes it and meets its user stories.
@@ -41416,6 +41686,7 @@ No unrequested features, flags, compatibility shims or refactors.`;
41416
41686
  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
41687
  Meet every story; respect every non-goal and risk. Use its file manifest.
41418
41688
  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.
41689
+ 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
41690
  Follow the beeline-triage skill's bugfix execution contract when the spec or its approval quote reports a defect.
41420
41691
  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
41692
  Fix only the spec and approval quote. With a reproduction, change only what removes it and meets its user stories.
@@ -41589,7 +41860,7 @@ The soul is not authority and never changes your tools, permissions, roles, or m
41589
41860
  render: () => [
41590
41861
  "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
41862
  "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 you belong to, use inspect_corner for status, steer_corner to pass Room input down, and ask_corner for one answer. Never post into a corner without a Room command.",
41863
+ "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
41864
  "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
41865
  ].join(" ")
41595
41866
  },
@@ -41749,7 +42020,7 @@ The soul is not authority and never changes your tools, permissions, roles, or m
41749
42020
  budgetBytes: 260,
41750
42021
  layer: "surface",
41751
42022
  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. Only a human closes this corner.`
42023
+ 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
42024
  }
41754
42025
  ];
41755
42026
  function applicable(sections, context) {
@@ -41922,7 +42193,7 @@ ${transcript.lines.join("\n")}`;
41922
42193
  layer: "turn",
41923
42194
  surfaces: ["room", "code-corner", "repo-less-corner"],
41924
42195
  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"}):
42196
+ 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
42197
  ${JSON.stringify(corners)}` : "",
41927
42198
  surface === "room" && closedCorners?.length ? `Corners you belong to closed in the last 24 hours (merge commit is unavailable when absent):
41928
42199
  ${closedCorners.map((corner) => `- ${corner.name ?? corner.cornerId} (${corner.cornerId}): PR ${corner.pullRequestNumber ? `#${corner.pullRequestNumber}` : "unavailable"}, merge commit ${corner.mergeCommitSha ?? "unavailable"}`).join("\n")}` : ""
@@ -41989,8 +42260,8 @@ function assembleTurnPrompt(context) {
41989
42260
  }
41990
42261
 
41991
42262
  // apps/body/dist/turn-trace.js
41992
- import { appendFile as appendFile2, mkdir as mkdir22, readdir as readdir7, rm as rm13 } from "node:fs/promises";
41993
- import { resolve as resolve34 } from "node:path";
42263
+ import { appendFile as appendFile2, mkdir as mkdir22, readdir as readdir8, rm as rm14 } from "node:fs/promises";
42264
+ import { resolve as resolve35 } from "node:path";
41994
42265
  import { performance as performance3 } from "node:perf_hooks";
41995
42266
  var TURN_PHASES = [
41996
42267
  /** Enqueued on `SessionScheduler` until this turn holds a slot. A capacity wait lives here. */
@@ -42276,7 +42547,7 @@ function formatTurnTraceLine(record5) {
42276
42547
  return [head, ...record5.attempts.map((attempt) => formatTurnAttempt(attempt))].join("\n ");
42277
42548
  }
42278
42549
  function turnTraceDirectory(runtimeDir) {
42279
- return resolve34(runtimeDir, "turn-traces");
42550
+ return resolve35(runtimeDir, "turn-traces");
42280
42551
  }
42281
42552
  var TURN_TRACE_RETENTION_DAYS = 7;
42282
42553
  function traceFileName(date) {
@@ -42293,7 +42564,7 @@ var TurnTraceFile = class {
42293
42564
  this.options = options;
42294
42565
  }
42295
42566
  path(now2 = (this.options.clock ?? (() => /* @__PURE__ */ new Date()))()) {
42296
- return resolve34(this.directory, traceFileName(now2));
42567
+ return resolve35(this.directory, traceFileName(now2));
42297
42568
  }
42298
42569
  write(record5) {
42299
42570
  this.tail = this.tail.catch(() => void 0).then(async () => {
@@ -42316,8 +42587,8 @@ var TurnTraceFile = class {
42316
42587
  return;
42317
42588
  this.prunedDay = day;
42318
42589
  const cutoff = traceFileName(new Date(now2.getTime() - TURN_TRACE_RETENTION_DAYS * 864e5));
42319
- const names = await readdir7(this.directory).catch(() => []);
42320
- await Promise.all(names.filter((name) => /^turns-\d{4}-\d{2}-\d{2}\.jsonl$/.test(name) && name < cutoff).map((name) => rm13(resolve34(this.directory, name), { force: true })));
42590
+ const names = await readdir8(this.directory).catch(() => []);
42591
+ 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
42592
  }
42322
42593
  };
42323
42594
 
@@ -42669,7 +42940,7 @@ var MonolithRoomTurnLoop = class {
42669
42940
  const cached = this.deliveredAttachments.get(item.id);
42670
42941
  if (cached?.length === item.attachments.length)
42671
42942
  return cached;
42672
- const delivered = await deliverAttachments(item.attachments, join18(this.attachmentDir, item.id.replace(/[^\w-]/g, "_")), this.options.fetchImpl, cached);
42943
+ const delivered = await deliverAttachments(item.attachments, join19(this.attachmentDir, item.id.replace(/[^\w-]/g, "_")), this.options.fetchImpl, cached);
42673
42944
  this.deliveredAttachments.set(item.id, withoutImageData(delivered.filter((entry) => entry.path)));
42674
42945
  return delivered;
42675
42946
  }
@@ -42739,7 +43010,7 @@ var MonolithRoomTurnLoop = class {
42739
43010
  this.sessionFingerprint = void 0;
42740
43011
  this.sessionCodegraphReady = false;
42741
43012
  this.pinnedProviderOverride = void 0;
42742
- if (client?.isAlive)
43013
+ if (client)
42743
43014
  await client.stop();
42744
43015
  }
42745
43016
  /**
@@ -42919,7 +43190,7 @@ var MonolithRoomTurnLoop = class {
42919
43190
  args: this.options.config.agentArgs ?? []
42920
43191
  }, selection);
42921
43192
  const { stateDirs, tmpDir } = harnessStateDirsFromEnv(agentEnv);
42922
- this.attachmentDir = tmpDir ? join18(tmpDir, "beeline-attachments") : void 0;
43193
+ this.attachmentDir = tmpDir ? join19(tmpDir, "beeline-attachments") : void 0;
42923
43194
  this.sessionScratchDir = tmpDir;
42924
43195
  this.sessionStateDirs = stateDirs;
42925
43196
  const homeStateDirs = harnessHomeStateDirs(harnessLabel, agentEnv.HOME ?? operatorHome);
@@ -43160,7 +43431,7 @@ var MonolithRoomTurnLoop = class {
43160
43431
  this.sessionId = void 0;
43161
43432
  this.sessionFingerprint = void 0;
43162
43433
  this.sessionCodegraphReady = false;
43163
- if (client?.isAlive)
43434
+ if (client)
43164
43435
  await client.stop();
43165
43436
  this.pinnedProviderOverride = next;
43166
43437
  await (trace ? trace.measure("activation", () => this.activate(trace)) : this.activate());
@@ -43239,8 +43510,8 @@ var MonolithRoomTurnLoop = class {
43239
43510
  let timer;
43240
43511
  const stats = statsPromise && remaining > 0 ? await Promise.race([
43241
43512
  statsPromise,
43242
- new Promise((resolve45) => {
43243
- timer = setTimeout(() => resolve45(void 0), remaining);
43513
+ new Promise((resolve49) => {
43514
+ timer = setTimeout(() => resolve49(void 0), remaining);
43244
43515
  })
43245
43516
  ]).finally(() => {
43246
43517
  if (timer)
@@ -43624,6 +43895,7 @@ var MonolithRoomTurnLoop = class {
43624
43895
  this.squireRelay.close();
43625
43896
  this.options.grantRunner?.unregister(roomId);
43626
43897
  await this.options.scheduler.suspend(roomId);
43898
+ this.options.scheduler.forget(roomId);
43627
43899
  }
43628
43900
  }
43629
43901
  };
@@ -43654,9 +43926,9 @@ function roomMessagePrompt(author, body, attachments, delivered, harnessAcceptsI
43654
43926
 
43655
43927
  // apps/body/dist/corner-github-auth.js
43656
43928
  import { chmod as chmod9, mkdir as mkdir24, writeFile as writeFile19 } from "node:fs/promises";
43657
- import { delimiter as delimiter3, resolve as resolve35 } from "node:path";
43929
+ import { delimiter as delimiter3, resolve as resolve36 } from "node:path";
43658
43930
  async function installCornerGitHubWrappers(input) {
43659
- const bin = resolve35(input.root, "beeline-github-bin");
43931
+ const bin = resolve36(input.root, "beeline-github-bin");
43660
43932
  await mkdir24(bin, { recursive: true, mode: 448 });
43661
43933
  const common = {
43662
43934
  node: process.execPath,
@@ -43668,13 +43940,13 @@ async function installCornerGitHubWrappers(input) {
43668
43940
  gitCommand: input.gitBinary,
43669
43941
  originUrl: input.originUrl ?? ""
43670
43942
  };
43671
- await writeLauncher(resolve35(bin, "git"), {
43943
+ await writeLauncher(resolve36(bin, "git"), {
43672
43944
  ...common,
43673
43945
  command: input.gitBinary,
43674
43946
  launcher: "git",
43675
43947
  restFallback: false
43676
43948
  });
43677
- await writeLauncher(resolve35(bin, "gh"), {
43949
+ await writeLauncher(resolve36(bin, "gh"), {
43678
43950
  ...common,
43679
43951
  command: input.ghBinary ?? "",
43680
43952
  launcher: "gh",
@@ -44109,37 +44381,37 @@ if (!refusal) {
44109
44381
  }
44110
44382
 
44111
44383
  // apps/body/dist/warm-node-modules.js
44112
- import { createHash as createHash12, randomUUID as randomUUID11 } from "node:crypto";
44384
+ import { createHash as createHash12, randomUUID as randomUUID12 } from "node:crypto";
44113
44385
  import { constants as fsConstants3 } from "node:fs";
44114
- import { chmod as chmod10, copyFile as copyFile2, link, lstat as lstat4, mkdir as mkdir25, readdir as readdir8, readFile as readFile29, readlink as readlink2, rename as rename10, rm as rm14, stat as stat8, symlink as symlink3, utimes } from "node:fs/promises";
44115
- import { dirname as dirname25, join as join19, resolve as resolve36 } from "node:path";
44386
+ 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";
44387
+ import { dirname as dirname25, join as join20, resolve as resolve37 } from "node:path";
44116
44388
  var STORE_FORMAT = "v1";
44117
44389
  var STAGING_PREFIX = ".beeline-warm-";
44118
44390
  var STAGING_SWEEP_MS = 24 * 60 * 60 * 1e3;
44119
44391
  var WARM_STORE_MAX_ENTRIES = 3;
44120
44392
  function sharedNpmCacheDir(supervisorRoot) {
44121
- return resolve36(supervisorRoot, "beeline", "npm-cache");
44393
+ return resolve37(supervisorRoot, "beeline", "npm-cache");
44122
44394
  }
44123
44395
  function sharedPnpmStoreDir(supervisorRoot) {
44124
- return resolve36(supervisorRoot, "beeline", "pnpm-store");
44396
+ return resolve37(supervisorRoot, "beeline", "pnpm-store");
44125
44397
  }
44126
44398
  function sharedCargoTargetDir(supervisorRoot) {
44127
- return resolve36(supervisorRoot, "beeline", "cargo-target");
44399
+ return resolve37(supervisorRoot, "beeline", "cargo-target");
44128
44400
  }
44129
44401
  function sharedTurboCacheDir(supervisorRoot) {
44130
- return resolve36(supervisorRoot, "beeline", "turbo-cache");
44402
+ return resolve37(supervisorRoot, "beeline", "turbo-cache");
44131
44403
  }
44132
44404
  function warmNodeModulesStoreDir(supervisorRoot) {
44133
- return resolve36(supervisorRoot, "beeline", "node-modules");
44405
+ return resolve37(supervisorRoot, "beeline", "node-modules");
44134
44406
  }
44135
44407
  function mobileNodeModulesStoreDir(supervisorRoot) {
44136
- return resolve36(supervisorRoot, "beeline", "node-modules-mobile");
44408
+ return resolve37(supervisorRoot, "beeline", "node-modules-mobile");
44137
44409
  }
44138
44410
  function isPlanRefusal(value) {
44139
44411
  return "failure" in value;
44140
44412
  }
44141
44413
  async function readWarmPlan(worktreePath) {
44142
- const lockfile = await readFile29(resolve36(worktreePath, "package-lock.json")).catch(() => void 0);
44414
+ const lockfile = await readFile29(resolve37(worktreePath, "package-lock.json")).catch(() => void 0);
44143
44415
  if (!lockfile)
44144
44416
  return { failure: "no-lockfile" };
44145
44417
  const packages = parseLockfilePackages(lockfile);
@@ -44178,11 +44450,11 @@ async function seedWarmNodeModules(input) {
44178
44450
  return { reason: plan.failure, ...plan.detail ? { detail: plan.detail } : {} };
44179
44451
  }
44180
44452
  for (const tree of plan.trees) {
44181
- if (await pathExists(resolve36(input.worktreePath, tree))) {
44453
+ if (await pathExists(resolve37(input.worktreePath, tree))) {
44182
44454
  return { reason: "present", key: plan.key };
44183
44455
  }
44184
44456
  }
44185
- const entry = resolve36(input.storeRoot, plan.key);
44457
+ const entry = resolve37(input.storeRoot, plan.key);
44186
44458
  if (!await isDirectory(entry))
44187
44459
  return { reason: "cold", key: plan.key };
44188
44460
  const [storeDevice, checkoutDevice] = await Promise.all([
@@ -44192,29 +44464,29 @@ async function seedWarmNodeModules(input) {
44192
44464
  if (storeDevice === void 0 || storeDevice !== checkoutDevice) {
44193
44465
  return { reason: "cross-device", key: plan.key };
44194
44466
  }
44195
- const staging = resolve36(input.storeRoot, `${STAGING_PREFIX}${process.pid}.${randomUUID11()}`);
44467
+ const staging = resolve37(input.storeRoot, `${STAGING_PREFIX}${process.pid}.${randomUUID12()}`);
44196
44468
  const placed = [];
44197
44469
  const now2 = (input.now ?? Date.now)();
44198
44470
  try {
44199
44471
  await sweepStaleStaging(input.storeRoot, now2);
44200
44472
  await utimes(entry, now2 / 1e3, now2 / 1e3).catch(() => void 0);
44201
44473
  for (const tree of plan.trees) {
44202
- await cloneTree(resolve36(entry, tree), resolve36(staging, tree), seedFile);
44474
+ await cloneTree(resolve37(entry, tree), resolve37(staging, tree), seedFile);
44203
44475
  }
44204
44476
  for (const tree of plan.trees) {
44205
- const target = resolve36(input.worktreePath, tree);
44477
+ const target = resolve37(input.worktreePath, tree);
44206
44478
  await mkdir25(dirname25(target), { recursive: true });
44207
- await rename10(resolve36(staging, tree), target);
44479
+ await rename10(resolve37(staging, tree), target);
44208
44480
  placed.push(target);
44209
44481
  }
44210
44482
  return { reason: "seeded", key: plan.key };
44211
44483
  } catch (error) {
44212
44484
  for (const target of placed) {
44213
- await rm14(target, { recursive: true, force: true }).catch(() => void 0);
44485
+ await rm15(target, { recursive: true, force: true }).catch(() => void 0);
44214
44486
  }
44215
44487
  return { reason: "failed", key: plan.key, detail: describe3(error) };
44216
44488
  } finally {
44217
- await rm14(staging, { recursive: true, force: true }).catch(() => void 0);
44489
+ await rm15(staging, { recursive: true, force: true }).catch(() => void 0);
44218
44490
  }
44219
44491
  }
44220
44492
  async function harvestWarmNodeModules(input) {
@@ -44222,11 +44494,11 @@ async function harvestWarmNodeModules(input) {
44222
44494
  if (isPlanRefusal(plan)) {
44223
44495
  return { reason: plan.failure, ...plan.detail ? { detail: plan.detail } : {} };
44224
44496
  }
44225
- const entry = resolve36(input.storeRoot, plan.key);
44497
+ const entry = resolve37(input.storeRoot, plan.key);
44226
44498
  if (await pathExists(entry))
44227
44499
  return { reason: "already-warm", key: plan.key };
44228
44500
  for (const tree of plan.trees) {
44229
- if (!await isDirectory(resolve36(input.worktreePath, tree))) {
44501
+ if (!await isDirectory(resolve37(input.worktreePath, tree))) {
44230
44502
  return { reason: "no-node-modules", key: plan.key, detail: tree };
44231
44503
  }
44232
44504
  }
@@ -44238,12 +44510,12 @@ async function harvestWarmNodeModules(input) {
44238
44510
  detail: `${missing.length} absent, e.g. ${missing.slice(0, 3).join(", ")}`
44239
44511
  };
44240
44512
  }
44241
- const staging = resolve36(input.storeRoot, `${STAGING_PREFIX}${process.pid}.${randomUUID11()}`);
44513
+ const staging = resolve37(input.storeRoot, `${STAGING_PREFIX}${process.pid}.${randomUUID12()}`);
44242
44514
  try {
44243
44515
  await mkdir25(input.storeRoot, { recursive: true, mode: 493 });
44244
44516
  await sweepStaleStaging(input.storeRoot, (input.now ?? Date.now)());
44245
44517
  for (const tree of plan.trees) {
44246
- await cloneTree(resolve36(input.worktreePath, tree), resolve36(staging, tree), harvestFile);
44518
+ await cloneTree(resolve37(input.worktreePath, tree), resolve37(staging, tree), harvestFile);
44247
44519
  }
44248
44520
  await input.onCopied?.();
44249
44521
  if (!await stagedTreeIsPublishable(input.worktreePath, staging, plan.key)) {
@@ -44257,25 +44529,25 @@ async function harvestWarmNodeModules(input) {
44257
44529
  return { reason: "already-warm", key: plan.key };
44258
44530
  return { reason: "failed", key: plan.key, detail: describe3(error) };
44259
44531
  } finally {
44260
- await rm14(staging, { recursive: true, force: true }).catch(() => void 0);
44532
+ await rm15(staging, { recursive: true, force: true }).catch(() => void 0);
44261
44533
  }
44262
44534
  }
44263
44535
  async function stagedTreeIsPublishable(worktreePath, staging, key) {
44264
44536
  const settled = await readWarmPlan(worktreePath);
44265
44537
  if (isPlanRefusal(settled) || settled.key !== key)
44266
44538
  return false;
44267
- const hidden = join19("node_modules", ".package-lock.json");
44539
+ const hidden = join20("node_modules", ".package-lock.json");
44268
44540
  const [copied, current] = await Promise.all([
44269
- readFile29(resolve36(staging, hidden)).catch(() => void 0),
44270
- readFile29(resolve36(worktreePath, hidden)).catch(() => void 0)
44541
+ readFile29(resolve37(staging, hidden)).catch(() => void 0),
44542
+ readFile29(resolve37(worktreePath, hidden)).catch(() => void 0)
44271
44543
  ]);
44272
44544
  if (!copied || !current || !copied.equals(current))
44273
44545
  return false;
44274
44546
  return (await missingInstalledPackages(worktreePath, staging)).length === 0;
44275
44547
  }
44276
44548
  async function missingInstalledPackages(worktreePath, treeRoot = worktreePath) {
44277
- const wanted = parseLockfilePackages(await readFile29(resolve36(worktreePath, "package-lock.json")).catch(() => void 0));
44278
- const installed = parseLockfilePackages(await readFile29(resolve36(treeRoot, "node_modules", ".package-lock.json")).catch(() => void 0));
44549
+ const wanted = parseLockfilePackages(await readFile29(resolve37(worktreePath, "package-lock.json")).catch(() => void 0));
44550
+ const installed = parseLockfilePackages(await readFile29(resolve37(treeRoot, "node_modules", ".package-lock.json")).catch(() => void 0));
44279
44551
  if (!wanted)
44280
44552
  return ["package-lock.json is unreadable"];
44281
44553
  if (!installed)
@@ -44295,14 +44567,14 @@ async function missingInstalledPackages(worktreePath, treeRoot = worktreePath) {
44295
44567
  required.push(path);
44296
44568
  }
44297
44569
  await mapWithLimit(required, INTEGRITY_READ_CONCURRENCY, async (path) => {
44298
- if (!(path in installed) || !await isInstalledPackage(resolve36(treeRoot, path))) {
44570
+ if (!(path in installed) || !await isInstalledPackage(resolve37(treeRoot, path))) {
44299
44571
  missing.push(path);
44300
44572
  }
44301
44573
  });
44302
44574
  return missing.sort();
44303
44575
  }
44304
44576
  async function isInstalledPackage(path) {
44305
- return stat8(join19(path, "package.json")).then((info) => info.isFile(), () => false);
44577
+ return stat9(join20(path, "package.json")).then((info) => info.isFile(), () => false);
44306
44578
  }
44307
44579
  var INTEGRITY_READ_CONCURRENCY = 64;
44308
44580
  async function mapWithLimit(values, limit, visit) {
@@ -44335,9 +44607,9 @@ function isContainedTreePath(value) {
44335
44607
  }
44336
44608
  async function cloneTree(source, target, file, topLevel = true) {
44337
44609
  await mkdir25(target, { recursive: true, mode: 493 });
44338
- for (const entry of await readdir8(source, { withFileTypes: true })) {
44339
- const from = join19(source, entry.name);
44340
- const to = join19(target, entry.name);
44610
+ for (const entry of await readdir9(source, { withFileTypes: true })) {
44611
+ const from = join20(source, entry.name);
44612
+ const to = join20(target, entry.name);
44341
44613
  if (entry.isSymbolicLink()) {
44342
44614
  await symlink3(await readlink2(from), to);
44343
44615
  continue;
@@ -44352,7 +44624,7 @@ async function cloneTree(source, target, file, topLevel = true) {
44352
44624
  }
44353
44625
  var harvestFile = async (source, target) => {
44354
44626
  await copyFile2(source, target, fsConstants3.COPYFILE_FICLONE);
44355
- const info = await stat8(source);
44627
+ const info = await stat9(source);
44356
44628
  await chmod10(target, info.mode & 4095 & ~146);
44357
44629
  };
44358
44630
  var seedFile = async (source, target, topLevel) => {
@@ -44364,46 +44636,46 @@ var seedFile = async (source, target, topLevel) => {
44364
44636
  await chmod10(target, 420);
44365
44637
  };
44366
44638
  async function pruneWarmStore(storeRoot, keep) {
44367
- const names = (await readdir8(storeRoot).catch(() => [])).filter((name) => !name.startsWith(STAGING_PREFIX));
44639
+ const names = (await readdir9(storeRoot).catch(() => [])).filter((name) => !name.startsWith(STAGING_PREFIX));
44368
44640
  const entries = [];
44369
44641
  for (const name of names) {
44370
- const info = await lstat4(join19(storeRoot, name)).catch(() => void 0);
44642
+ const info = await lstat5(join20(storeRoot, name)).catch(() => void 0);
44371
44643
  if (info?.isDirectory())
44372
44644
  entries.push({ name, usedAt: info.mtimeMs });
44373
44645
  }
44374
44646
  const dropped = entries.sort((a2, b) => b.usedAt - a2.usedAt || a2.name.localeCompare(b.name)).slice(keep);
44375
44647
  for (const entry of dropped) {
44376
- await rm14(join19(storeRoot, entry.name), { recursive: true, force: true }).catch(() => void 0);
44648
+ await rm15(join20(storeRoot, entry.name), { recursive: true, force: true }).catch(() => void 0);
44377
44649
  }
44378
44650
  return dropped.map((entry) => entry.name);
44379
44651
  }
44380
44652
  async function sweepStaleStaging(storeRoot, now2) {
44381
- const entries = await readdir8(storeRoot).catch(() => []);
44653
+ const entries = await readdir9(storeRoot).catch(() => []);
44382
44654
  for (const name of entries) {
44383
44655
  if (!name.startsWith(STAGING_PREFIX))
44384
44656
  continue;
44385
- const path = join19(storeRoot, name);
44386
- const info = await lstat4(path).catch(() => void 0);
44657
+ const path = join20(storeRoot, name);
44658
+ const info = await lstat5(path).catch(() => void 0);
44387
44659
  if (!info || now2 - info.mtimeMs < STAGING_SWEEP_MS)
44388
44660
  continue;
44389
- await rm14(path, { recursive: true, force: true }).catch(() => void 0);
44661
+ await rm15(path, { recursive: true, force: true }).catch(() => void 0);
44390
44662
  }
44391
44663
  }
44392
44664
  async function pathExists(path) {
44393
- return lstat4(path).then(() => true, () => false);
44665
+ return lstat5(path).then(() => true, () => false);
44394
44666
  }
44395
44667
  async function deviceOf(path) {
44396
- return stat8(path).then((info) => info.dev, () => void 0);
44668
+ return stat9(path).then((info) => info.dev, () => void 0);
44397
44669
  }
44398
44670
  async function isDirectory(path) {
44399
- return stat8(path).then((info) => info.isDirectory(), () => false);
44671
+ return stat9(path).then((info) => info.isDirectory(), () => false);
44400
44672
  }
44401
44673
  function describe3(error) {
44402
44674
  return error instanceof Error ? error.message : String(error);
44403
44675
  }
44404
44676
 
44405
44677
  // apps/body/dist/monolith-corner-turn.js
44406
- var execFileAsync7 = promisify7(execFile12);
44678
+ var execFileAsync9 = promisify9(execFile14);
44407
44679
  var TOOL_ARGUMENT_MAX_BYTES = 1200;
44408
44680
  var TOOL_OUTPUT_MAX_BYTES = 3200;
44409
44681
  var TOOL_PATH_LIMIT = 12;
@@ -44417,8 +44689,8 @@ function isCornerReviewTurn(reviewer, trigger) {
44417
44689
  async function cornerUndeliveredRepositoryState(worktreePath, featureBranch, targetBranch) {
44418
44690
  try {
44419
44691
  const [{ stdout: status }, ahead] = await Promise.all([
44420
- execFileAsync7("git", ["-C", worktreePath, "status", "--porcelain=v1"]),
44421
- featureBranch ? firstResolvedRemoteRef(worktreePath, [featureBranch, targetBranch]).then((remoteRef) => remoteRef ? execFileAsync7("git", [
44692
+ execFileAsync9("git", ["-C", worktreePath, "status", "--porcelain=v1"]),
44693
+ featureBranch ? firstResolvedRemoteRef(worktreePath, [featureBranch, targetBranch]).then((remoteRef) => remoteRef ? execFileAsync9("git", [
44422
44694
  "-C",
44423
44695
  worktreePath,
44424
44696
  "rev-list",
@@ -44438,7 +44710,7 @@ async function firstResolvedRemoteRef(worktreePath, branches) {
44438
44710
  if (!branch)
44439
44711
  continue;
44440
44712
  const ref = `refs/remotes/origin/${branch}`;
44441
- const resolved = await execFileAsync7("git", ["-C", worktreePath, "rev-parse", "--verify", ref]).then(() => true).catch(() => false);
44713
+ const resolved = await execFileAsync9("git", ["-C", worktreePath, "rev-parse", "--verify", ref]).then(() => true).catch(() => false);
44442
44714
  if (resolved)
44443
44715
  return ref;
44444
44716
  }
@@ -44590,7 +44862,7 @@ async function cornerToolActivity(call, worktreePath, requestedBy) {
44590
44862
  let title = oneLine(redactToolDetail(call.title ?? "")) || `${operation} tool`;
44591
44863
  if (isSuccessfulCommit(call)) {
44592
44864
  try {
44593
- const shown = await execFileAsync7("git", ["-C", worktreePath, "show", "--format=%s", "--name-only", "--no-renames", "HEAD"], { maxBuffer: 1024 * 1024 });
44865
+ const shown = await execFileAsync9("git", ["-C", worktreePath, "show", "--format=%s", "--name-only", "--no-renames", "HEAD"], { maxBuffer: 1024 * 1024 });
44594
44866
  const lines = shown.stdout.split(/\r?\n/);
44595
44867
  const subject = oneLine(lines.shift() ?? "commit");
44596
44868
  const files = new Set(lines.map(oneLine).filter(Boolean));
@@ -44851,7 +45123,7 @@ var MonolithCornerTurnLoop = class {
44851
45123
  this.sessionCodegraphReady = false;
44852
45124
  this.pinnedProviderOverride = void 0;
44853
45125
  this.sessionModel = null;
44854
- if (client?.isAlive)
45126
+ if (client)
44855
45127
  await client.stop();
44856
45128
  }
44857
45129
  /** See `MonolithRoomTurnLoop.sessionIsCurrent`: retention never keeps a
@@ -45012,9 +45284,9 @@ var MonolithCornerTurnLoop = class {
45012
45284
  const repository = this.options.repository;
45013
45285
  let githubEnv = repository ? { GH_TOKEN: repository.githubToken, GITHUB_TOKEN: repository.githubToken } : {};
45014
45286
  if (repository && this.options.config.runtimeConfigPath && this.options.config.agentHomeRoot) {
45015
- const gitBinary = (await execFileAsync7("which", ["git"])).stdout.trim();
45016
- const ghBinary = await execFileAsync7("which", ["gh"]).then((result) => result.stdout.trim()).catch(() => void 0);
45017
- const originUrl = await execFileAsync7(gitBinary, [
45287
+ const gitBinary = (await execFileAsync9("which", ["git"])).stdout.trim();
45288
+ const ghBinary = await execFileAsync9("which", ["gh"]).then((result) => result.stdout.trim()).catch(() => void 0);
45289
+ const originUrl = await execFileAsync9(gitBinary, [
45018
45290
  "-C",
45019
45291
  this.options.worktreePath,
45020
45292
  "remote",
@@ -45040,7 +45312,8 @@ var MonolithCornerTurnLoop = class {
45040
45312
  const pnpmStoreDir = sharedPnpmStoreDir(this.options.runtime.supervisorRoot);
45041
45313
  const cargoTargetDir = sharedCargoTargetDir(this.options.runtime.supervisorRoot);
45042
45314
  const turboCacheDir = sharedTurboCacheDir(this.options.runtime.supervisorRoot);
45043
- await Promise.all([npmCacheDir, pnpmStoreDir, cargoTargetDir, turboCacheDir].map((path) => mkdir26(path, { recursive: true, mode: 448 })));
45315
+ const modelCacheDir = resolve38(this.options.runtime.supervisorRoot, "beeline", "model-cache");
45316
+ await Promise.all([npmCacheDir, pnpmStoreDir, cargoTargetDir, turboCacheDir, modelCacheDir].map((path) => mkdir26(path, { recursive: true, mode: 448 })));
45044
45317
  const agentEnv = {
45045
45318
  ...this.options.config.agentEnv,
45046
45319
  ...homeOverlay,
@@ -45050,7 +45323,9 @@ var MonolithCornerTurnLoop = class {
45050
45323
  // hardlinks packages out of this content-addressable store.
45051
45324
  PNPM_CONFIG_STORE_DIR: pnpmStoreDir,
45052
45325
  CARGO_TARGET_DIR: cargoTargetDir,
45053
- TURBO_CACHE_DIR: turboCacheDir
45326
+ TURBO_CACHE_DIR: turboCacheDir,
45327
+ HF_HOME: modelCacheDir,
45328
+ HUGGINGFACE_HUB_CACHE: join21(modelCacheDir, "hub")
45054
45329
  };
45055
45330
  this.agentEnv = agentEnv;
45056
45331
  this.modelContextTokens = await modelContextWindowTokens(selection.model, agentEnv.PI_CODING_AGENT_DIR);
@@ -45060,7 +45335,7 @@ var MonolithCornerTurnLoop = class {
45060
45335
  args: this.options.config.agentArgs ?? []
45061
45336
  }, selection);
45062
45337
  const { stateDirs, tmpDir } = harnessStateDirsFromEnv(agentEnv);
45063
- this.attachmentDir = tmpDir ? join20(tmpDir, "beeline-attachments") : void 0;
45338
+ this.attachmentDir = tmpDir ? join21(tmpDir, "beeline-attachments") : void 0;
45064
45339
  this.sessionScratchDir = tmpDir;
45065
45340
  const homeStateDirs = harnessHomeStateDirs(harnessLabel, agentEnv.HOME ?? operatorHome);
45066
45341
  await Promise.all(homeStateDirs.map((dir) => mkdir26(dir, { recursive: true })));
@@ -45087,6 +45362,7 @@ var MonolithCornerTurnLoop = class {
45087
45362
  pnpmStoreDir,
45088
45363
  cargoTargetDir,
45089
45364
  turboCacheDir,
45365
+ modelCacheDir,
45090
45366
  ...registryMcpHostBindPaths(configuration.registryMcpRoutes, this.options.config.registryMcpBrokerSocket),
45091
45367
  ...grantedSquireHostBindPaths({
45092
45368
  operatorHome,
@@ -45165,7 +45441,9 @@ var MonolithCornerTurnLoop = class {
45165
45441
  // per-corner cache.
45166
45442
  { name: "npm_config_cache", value: npmCacheDir },
45167
45443
  { name: "PNPM_CONFIG_STORE_DIR", value: pnpmStoreDir },
45168
- { name: "CARGO_TARGET_DIR", value: cargoTargetDir }
45444
+ { name: "CARGO_TARGET_DIR", value: cargoTargetDir },
45445
+ { name: "HF_HOME", value: modelCacheDir },
45446
+ { name: "HUGGINGFACE_HUB_CACHE", value: join21(modelCacheDir, "hub") }
45169
45447
  ]
45170
45448
  }
45171
45449
  ] : [],
@@ -45173,13 +45451,13 @@ var MonolithCornerTurnLoop = class {
45173
45451
  roomId: this.options.parentRoomId,
45174
45452
  workspaceId: this.options.workspaceId,
45175
45453
  cornerId: this.options.cornerId,
45176
- agentMayCloseCorner: Boolean(repository),
45177
45454
  reviewer,
45178
45455
  repositoryBacked: Boolean(repository),
45179
45456
  attachRoot: this.options.worktreePath,
45180
45457
  // The whole per-session overlay, not an enumerated subset: see
45181
45458
  // `monolith-room-turn.ts`'s matching comment.
45182
45459
  attachScratchRoot,
45460
+ ...!repository ? { cornerScratchRoot: this.options.worktreePath } : {},
45183
45461
  turnContextPath: this.commandContext.path,
45184
45462
  squireRelay: squireScope.relay,
45185
45463
  ...this.options.grantRunnerEndpoint ? { grantRunner: this.options.grantRunnerEndpoint } : {}
@@ -45273,7 +45551,7 @@ var MonolithCornerTurnLoop = class {
45273
45551
  this.options.api.execute("getCornerRestoreState", {
45274
45552
  cornerId: this.options.cornerId
45275
45553
  }),
45276
- execFileAsync7("git", ["-C", this.options.worktreePath, "rev-parse", "HEAD"]).then(({ stdout: stdout6 }) => stdout6.trim())
45554
+ execFileAsync9("git", ["-C", this.options.worktreePath, "rev-parse", "HEAD"]).then(({ stdout: stdout6 }) => stdout6.trim())
45277
45555
  ]);
45278
45556
  const pr = restore.lifecycle?.pr;
45279
45557
  if (restore.lifecycle?.checks !== "passing" || !pr?.number || !pr.headSha || pr.headSha !== localHead)
@@ -45287,7 +45565,7 @@ var MonolithCornerTurnLoop = class {
45287
45565
  briefRevision: restore.brief?.revision
45288
45566
  }),
45289
45567
  ...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 ${resolve37(this.options.config.agentHomeRoot, "codex", "skills", "beeline-review", "SKILL.md")} before the verdict.`
45568
+ `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
45569
  ] : []
45292
45570
  ].join("\n");
45293
45571
  } catch {
@@ -45353,7 +45631,7 @@ var MonolithCornerTurnLoop = class {
45353
45631
  this.sessionId = void 0;
45354
45632
  this.sessionFingerprint = void 0;
45355
45633
  this.sessionCodegraphReady = false;
45356
- if (client?.isAlive)
45634
+ if (client)
45357
45635
  await client.stop();
45358
45636
  this.pinnedProviderOverride = next;
45359
45637
  await (trace ? trace.measure("activation", () => this.activate(trace)) : this.activate());
@@ -45402,8 +45680,8 @@ var MonolithCornerTurnLoop = class {
45402
45680
  let timer;
45403
45681
  const stats = statsPromise && remaining > 0 ? await Promise.race([
45404
45682
  statsPromise,
45405
- new Promise((resolve45) => {
45406
- timer = setTimeout(() => resolve45(void 0), remaining);
45683
+ new Promise((resolve49) => {
45684
+ timer = setTimeout(() => resolve49(void 0), remaining);
45407
45685
  })
45408
45686
  ]).finally(() => {
45409
45687
  if (timer)
@@ -45454,7 +45732,7 @@ var MonolithCornerTurnLoop = class {
45454
45732
  let repositoryWork = cornerHasRepositoryWork(restored.brief);
45455
45733
  let repositoryHeld = restored.held === true;
45456
45734
  let assignedBrief = restored.brief;
45457
- const taskDelivered = this.attachmentDir && attachments.length ? await deliverAttachments(attachments, join20(this.attachmentDir, requestId.replace(/[^\w-]/g, "_")), this.options.fetchImpl) : [];
45735
+ const taskDelivered = this.attachmentDir && attachments.length ? await deliverAttachments(attachments, join21(this.attachmentDir, requestId.replace(/[^\w-]/g, "_")), this.options.fetchImpl) : [];
45458
45736
  let delivered = taskDelivered;
45459
45737
  let briefFileLines = [];
45460
45738
  let missingRequiredBriefFile = false;
@@ -45465,7 +45743,7 @@ var MonolithCornerTurnLoop = class {
45465
45743
  mimeType: file.mime,
45466
45744
  size: file.size
45467
45745
  }));
45468
- const briefDelivered = this.attachmentDir && briefAttachments.length ? await deliverAttachments(briefAttachments, join20(this.attachmentDir, requestId.replace(/[^\w-]/g, "_"), "brief", String(assignedBrief.revision)), this.options.fetchImpl) : [];
45746
+ const briefDelivered = this.attachmentDir && briefAttachments.length ? await deliverAttachments(briefAttachments, join21(this.attachmentDir, requestId.replace(/[^\w-]/g, "_"), "brief", String(assignedBrief.revision)), this.options.fetchImpl) : [];
45469
45747
  briefFileLines = await Promise.all((assignedBrief?.attachments ?? []).map(async (file, index) => {
45470
45748
  const entry = briefDelivered.find((item) => item.attachment === briefAttachments[index]);
45471
45749
  const verified = entry?.path && createHash13("sha256").update(await readFile30(entry.path)).digest("hex") === file.sha256;
@@ -45551,11 +45829,19 @@ var MonolithCornerTurnLoop = class {
45551
45829
  }
45552
45830
  });
45553
45831
  trace.notePromptSections(assembled.report);
45554
- trace.notePromptWindow(assembled.text, this.modelContextTokens);
45555
45832
  this.commandContext.notePromptSections([
45556
45833
  ...this.sessionPromptSectionIds,
45557
45834
  ...assembled.report.map((section) => section.id)
45558
45835
  ]);
45836
+ if (!repositoryWork) {
45837
+ const usage2 = await allocatedDirectoryBytes(this.options.worktreePath);
45838
+ const text2 = `${assembled.text}
45839
+
45840
+ ${scratchBudgetMessage(usage2)}`;
45841
+ trace.notePromptWindow(text2, this.modelContextTokens);
45842
+ return text2;
45843
+ }
45844
+ trace.notePromptWindow(assembled.text, this.modelContextTokens);
45559
45845
  return assembled.text;
45560
45846
  };
45561
45847
  const stream = new AgentTurnStream({
@@ -45664,24 +45950,34 @@ var MonolithCornerTurnLoop = class {
45664
45950
  narrationRunBoundary = 0;
45665
45951
  currentNarrationRun = "";
45666
45952
  trace.promptSent();
45667
- return 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) => {
45668
- trace.firstModelOutput();
45669
- if (runs) {
45670
- completedNarrationRuns = runs.slice(narrationRunBoundary);
45671
- currentNarrationRun = "";
45672
- } else if (currentRun === void 0)
45673
- currentNarrationRun += delta;
45674
- else {
45675
- if (currentNarrationRun && currentNarrationRun !== currentRun && !currentRun.startsWith(currentNarrationRun))
45676
- completedNarrationRuns.push(currentNarrationRun);
45677
- currentNarrationRun = currentRun;
45953
+ const scratchRoot = this.repositoryWork ? void 0 : this.options.worktreePath;
45954
+ const scratchAtStart = scratchRoot ? await allocatedDirectoryBytes(scratchRoot) : 0;
45955
+ try {
45956
+ 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) => {
45957
+ trace.firstModelOutput();
45958
+ if (runs) {
45959
+ completedNarrationRuns = runs.slice(narrationRunBoundary);
45960
+ currentNarrationRun = "";
45961
+ } else if (currentRun === void 0)
45962
+ currentNarrationRun += delta;
45963
+ else {
45964
+ if (currentNarrationRun && currentNarrationRun !== currentRun && !currentRun.startsWith(currentNarrationRun))
45965
+ completedNarrationRuns.push(currentNarrationRun);
45966
+ currentNarrationRun = currentRun;
45967
+ }
45968
+ stream.onChunk(delta, full, currentRun);
45969
+ }, void 0, (calls) => {
45970
+ trace.toolCalls(calls);
45971
+ publishToolCalls(calls, true);
45972
+ publishToolCalls(calls, false, lastNarratedToolCall);
45973
+ }));
45974
+ } finally {
45975
+ if (scratchRoot) {
45976
+ const usage2 = await allocatedDirectoryBytes(scratchRoot);
45977
+ if (scratchGrowthExceedsBudget(usage2, scratchAtStart))
45978
+ throw new Error(`Scratch budget exceeded. ${scratchBudgetMessage(usage2)}`);
45678
45979
  }
45679
- stream.onChunk(delta, full, currentRun);
45680
- }, void 0, (calls) => {
45681
- trace.toolCalls(calls);
45682
- publishToolCalls(calls, true);
45683
- publishToolCalls(calls, false, lastNarratedToolCall);
45684
- }));
45980
+ }
45685
45981
  };
45686
45982
  let loginRetryUsed = false;
45687
45983
  const runPrompt = async (prompt, continuation) => {
@@ -45886,13 +46182,13 @@ ${continuation}` : assembled;
45886
46182
  if (this.harvest || !this.options.repository)
45887
46183
  return;
45888
46184
  const { cornerId, worktreePath, runtime } = this.options;
45889
- const mobilePath = resolve37(worktreePath, "apps/mobile");
46185
+ const mobilePath = resolve38(worktreePath, "apps/mobile");
45890
46186
  const jobs = [
45891
46187
  harvestWarmNodeModules({
45892
46188
  worktreePath,
45893
46189
  storeRoot: warmNodeModulesStoreDir(runtime.supervisorRoot)
45894
46190
  }),
45895
- ...existsSync9(resolve37(mobilePath, "package-lock.json")) ? [
46191
+ ...existsSync9(resolve38(mobilePath, "package-lock.json")) ? [
45896
46192
  harvestWarmNodeModules({
45897
46193
  worktreePath: mobilePath,
45898
46194
  storeRoot: mobileNodeModulesStoreDir(runtime.supervisorRoot)
@@ -45940,7 +46236,7 @@ ${continuation}` : assembled;
45940
46236
  const delay = outage ? Math.min(2e3 * 2 ** attempt, 3e4) : 250 * (attempt + 1);
45941
46237
  if ((outage ? Date.now() + delay > outageDeadline : attempt === 2) || this.forcedStop || this.currentTurn && this.stoppedTurns.has(this.currentTurn.requestId))
45942
46238
  throw error;
45943
- await new Promise((resolve45) => setTimeout(resolve45, delay));
46239
+ await new Promise((resolve49) => setTimeout(resolve49, delay));
45944
46240
  }
45945
46241
  }
45946
46242
  if (!token)
@@ -46032,11 +46328,95 @@ ${continuation}` : assembled;
46032
46328
  this.squireRelay.close();
46033
46329
  this.options.grantRunner?.unregister(cornerId);
46034
46330
  await this.options.scheduler.suspend(cornerId);
46331
+ this.options.scheduler.forget(cornerId);
46035
46332
  await this.harvest;
46036
46333
  }
46037
46334
  }
46038
46335
  };
46039
46336
 
46337
+ // apps/body/dist/corner-disk-recovery.js
46338
+ import { execFile as execFile15 } from "node:child_process";
46339
+ import { lstat as lstat6, readdir as readdir10, realpath as realpath2, rm as rm16 } from "node:fs/promises";
46340
+ import { basename as basename9, dirname as dirname27, join as join22, relative as relative3, resolve as resolve39, sep as sep2 } from "node:path";
46341
+ import { promisify as promisify10 } from "node:util";
46342
+ var execFileAsync10 = promisify10(execFile15);
46343
+ var GENERATED_DIRS = /* @__PURE__ */ new Set([
46344
+ "node_modules",
46345
+ "target",
46346
+ "build",
46347
+ "dist",
46348
+ ".next",
46349
+ ".turbo",
46350
+ ".expo"
46351
+ ]);
46352
+ var MAX_DIRECTORY_DEPTH = 4;
46353
+ var MAX_VISITED_DIRECTORIES = 5e3;
46354
+ function cornerRecoveryPointerPath(worktree) {
46355
+ const checkout = resolve39(worktree.path);
46356
+ if (basename9(checkout) !== worktree.cornerId || basename9(dirname27(checkout)) !== "corners" || basename9(dirname27(dirname27(checkout))) !== "beeline" || !/^[a-zA-Z0-9-]{1,80}$/.test(worktree.cornerId)) {
46357
+ throw new Error("refusing recovery pointer outside a Beeline corner checkout");
46358
+ }
46359
+ return resolve39(dirname27(dirname27(checkout)), "recovery", "corners", `${worktree.cornerId}.json`);
46360
+ }
46361
+ async function git(checkout, args) {
46362
+ const result = await execFileAsync10("git", ["-C", checkout, ...args], {
46363
+ maxBuffer: 4 * 1024 * 1024
46364
+ });
46365
+ return result.stdout;
46366
+ }
46367
+ async function ignoredAndUntracked(checkout, path) {
46368
+ const rel = relative3(checkout, path);
46369
+ if (!rel || rel === ".." || rel.startsWith(`..${sep2}`))
46370
+ return false;
46371
+ const ignored = await git(checkout, ["check-ignore", "-q", "--", `${rel}/`]).then(() => true, () => false);
46372
+ if (!ignored)
46373
+ return false;
46374
+ return !(await git(checkout, ["ls-files", "--", rel])).trim();
46375
+ }
46376
+ async function preserveUnpublishedCornerWorktree(worktree, reason) {
46377
+ const checkout = resolve39(worktree.path);
46378
+ const pointer = cornerRecoveryPointerPath(worktree);
46379
+ const info = await lstat6(checkout);
46380
+ if (!info.isDirectory() || await realpath2(checkout) !== checkout) {
46381
+ throw new Error("refusing to prune a non-canonical corner checkout");
46382
+ }
46383
+ const head = (await git(checkout, ["rev-parse", "--verify", "HEAD"])).trim();
46384
+ const record5 = {
46385
+ cornerId: worktree.cornerId,
46386
+ checkout,
46387
+ branch: worktree.branch,
46388
+ head,
46389
+ reason,
46390
+ recordedAt: (/* @__PURE__ */ new Date()).toISOString()
46391
+ };
46392
+ await writePrivateFileAtomically(pointer, `${JSON.stringify(record5, null, 2)}
46393
+ `);
46394
+ const pruned = [];
46395
+ const pending = [{ path: checkout, depth: 0 }];
46396
+ let visited = 0;
46397
+ while (pending.length) {
46398
+ const current = pending.shift();
46399
+ if (++visited > MAX_VISITED_DIRECTORIES)
46400
+ break;
46401
+ if (current.depth >= MAX_DIRECTORY_DEPTH)
46402
+ continue;
46403
+ for (const entry of await readdir10(current.path, { withFileTypes: true })) {
46404
+ if (!entry.isDirectory() || entry.name === ".git")
46405
+ continue;
46406
+ const path = join22(current.path, entry.name);
46407
+ if (GENERATED_DIRS.has(entry.name)) {
46408
+ if (await ignoredAndUntracked(checkout, path)) {
46409
+ await rm16(path, { recursive: true, force: true });
46410
+ pruned.push(relative3(checkout, path));
46411
+ }
46412
+ continue;
46413
+ }
46414
+ pending.push({ path, depth: current.depth + 1 });
46415
+ }
46416
+ }
46417
+ return { pointer, pruned };
46418
+ }
46419
+
46040
46420
  // apps/body/dist/surface-health.js
46041
46421
  var SurfaceHealth = class {
46042
46422
  surfaces = /* @__PURE__ */ new Map();
@@ -46125,7 +46505,7 @@ function resolveSessionIdleMs(env = process.env) {
46125
46505
  return Number.isSafeInteger(value) && value > 0 ? value : DEFAULT_SESSION_IDLE_MS;
46126
46506
  }
46127
46507
  var DEFAULT_WORKSPACE_LIVE_SESSIONS_FLOOR = 4;
46128
- var SessionScheduler = class {
46508
+ var SessionScheduler = class _SessionScheduler {
46129
46509
  /** Fixed ceiling when explicitly configured; undefined selects the dynamic one. */
46130
46510
  fixedMaxLiveSessions;
46131
46511
  perRoomLiveSessions;
@@ -46140,6 +46520,7 @@ var SessionScheduler = class {
46140
46520
  queues = /* @__PURE__ */ new Map();
46141
46521
  drainingKeys = /* @__PURE__ */ new Set();
46142
46522
  physicalHistory = /* @__PURE__ */ new Map();
46523
+ static MAX_GENERATIONS_PER_KEY = 4;
46143
46524
  /**
46144
46525
  * Sessions already removed from `live` whose process is still being torn
46145
46526
  * down. They keep occupying capacity until `suspend()` resolves, so an
@@ -46263,6 +46644,10 @@ var SessionScheduler = class {
46263
46644
  generations(key) {
46264
46645
  return this.physicalHistory.get(key) ?? [];
46265
46646
  }
46647
+ /** A Room/corner loop ended; its diagnostic IDs no longer have a reader. */
46648
+ forget(key) {
46649
+ this.physicalHistory.delete(key);
46650
+ }
46266
46651
  /**
46267
46652
  * Read-only capacity diagnostic, exported beside the turn trace
46268
46653
  * (`turn-trace.ts`) so a stalled turn can be attributed to a capacity wait
@@ -46336,6 +46721,7 @@ var SessionScheduler = class {
46336
46721
  this.sweepTimer = void 0;
46337
46722
  const sessions = [...this.live.values()];
46338
46723
  this.live.clear();
46724
+ this.physicalHistory.clear();
46339
46725
  await Promise.all(sessions.map((session) => this.retire(session)));
46340
46726
  this.wakeCapacityWaiters();
46341
46727
  }
@@ -46449,6 +46835,8 @@ var SessionScheduler = class {
46449
46835
  await this.notifyState(lifecycle, "live");
46450
46836
  const generations = this.physicalHistory.get(key) ?? [];
46451
46837
  generations.push(physicalSessionId);
46838
+ if (generations.length > _SessionScheduler.MAX_GENERATIONS_PER_KEY)
46839
+ generations.shift();
46452
46840
  this.physicalHistory.set(key, generations);
46453
46841
  return true;
46454
46842
  } catch (error) {
@@ -46548,7 +46936,7 @@ function cornerStartConfigKey(repository, objective) {
46548
46936
  function cornerRepositoryCacheDir(supervisorRoot, remote) {
46549
46937
  const normalizedRemote = roomCheckoutRemote(remote);
46550
46938
  const repositoryHash = createHash14("sha256").update(normalizedRemote).digest("hex").slice(0, 24);
46551
- return resolve38(supervisorRoot, "beeline", "repositories", `${repositoryHash}.git`);
46939
+ return resolve40(supervisorRoot, "beeline", "repositories", `${repositoryHash}.git`);
46552
46940
  }
46553
46941
  function isStandingCornerStartFault(error) {
46554
46942
  const text2 = error instanceof Error ? error.message : String(error);
@@ -46557,24 +46945,24 @@ function isStandingCornerStartFault(error) {
46557
46945
  async function materializeCornerWorktree(input) {
46558
46946
  const remote = roomCheckoutRemote(input.remote);
46559
46947
  const gitCommonDir = cornerRepositoryCacheDir(input.supervisorRoot, remote);
46560
- const path = resolve38(input.supervisorRoot, "beeline", "corners", input.cornerId);
46561
- await mkdir27(dirname27(gitCommonDir), { recursive: true, mode: 448 });
46562
- await mkdir27(dirname27(path), { recursive: true, mode: 448 });
46948
+ const path = resolve40(input.supervisorRoot, "beeline", "corners", input.cornerId);
46949
+ await mkdir27(dirname28(gitCommonDir), { recursive: true, mode: 448 });
46950
+ await mkdir27(dirname28(path), { recursive: true, mode: 448 });
46563
46951
  const authEnv = githubGitEnv(input.token);
46564
- if (!existsSync10(resolve38(gitCommonDir, "HEAD"))) {
46565
- await execFileAsync8("git", ["clone", "--bare", remote, gitCommonDir], {
46952
+ if (!existsSync10(resolve40(gitCommonDir, "HEAD"))) {
46953
+ await execFileAsync11("git", ["clone", "--bare", remote, gitCommonDir], {
46566
46954
  env: authEnv,
46567
46955
  maxBuffer: 4 * 1024 * 1024
46568
46956
  });
46569
46957
  }
46570
- await execFileAsync8("git", [
46958
+ await execFileAsync11("git", [
46571
46959
  `--git-dir=${gitCommonDir}`,
46572
46960
  "fetch",
46573
46961
  "--prune",
46574
46962
  "origin",
46575
46963
  `+refs/heads/${input.targetBranch}:refs/remotes/origin/${input.targetBranch}`
46576
46964
  ], { env: authEnv, maxBuffer: 4 * 1024 * 1024 });
46577
- const restored = await execFileAsync8("git", [
46965
+ const restored = await execFileAsync11("git", [
46578
46966
  `--git-dir=${gitCommonDir}`,
46579
46967
  "fetch",
46580
46968
  "origin",
@@ -46584,9 +46972,9 @@ async function materializeCornerWorktree(input) {
46584
46972
  return false;
46585
46973
  throw error;
46586
46974
  });
46587
- if (!existsSync10(resolve38(path, ".git"))) {
46588
- await rm15(path, { recursive: true, force: true });
46589
- await execFileAsync8("git", [
46975
+ if (!existsSync10(resolve40(path, ".git"))) {
46976
+ await rm17(path, { recursive: true, force: true });
46977
+ await execFileAsync11("git", [
46590
46978
  `--git-dir=${gitCommonDir}`,
46591
46979
  "worktree",
46592
46980
  "add",
@@ -46602,8 +46990,8 @@ async function materializeCornerWorktree(input) {
46602
46990
  if (seed.reason !== "no-lockfile") {
46603
46991
  console.log(`[thin-core] corner ${input.cornerId} warm node_modules: ${seed.reason}${seed.detail ? ` (${seed.detail})` : ""}`);
46604
46992
  }
46605
- const mobilePath = resolve38(path, "apps/mobile");
46606
- if (existsSync10(resolve38(mobilePath, "package-lock.json"))) {
46993
+ const mobilePath = resolve40(path, "apps/mobile");
46994
+ if (existsSync10(resolve40(mobilePath, "package-lock.json"))) {
46607
46995
  const mobileSeed = await seedWarmNodeModules({
46608
46996
  worktreePath: mobilePath,
46609
46997
  storeRoot: mobileNodeModulesStoreDir(input.supervisorRoot)
@@ -46613,14 +47001,14 @@ async function materializeCornerWorktree(input) {
46613
47001
  }
46614
47002
  }
46615
47003
  }
46616
- await execFileAsync8("git", [
47004
+ await execFileAsync11("git", [
46617
47005
  `--git-dir=${gitCommonDir}`,
46618
47006
  "config",
46619
47007
  "extensions.worktreeConfig",
46620
47008
  "true"
46621
47009
  ]);
46622
- await execFileAsync8("git", ["-C", path, "config", "--worktree", "core.bare", "false"]);
46623
- await execFileAsync8("git", [
47010
+ await execFileAsync11("git", ["-C", path, "config", "--worktree", "core.bare", "false"]);
47011
+ await execFileAsync11("git", [
46624
47012
  "-C",
46625
47013
  path,
46626
47014
  "config",
@@ -46628,7 +47016,7 @@ async function materializeCornerWorktree(input) {
46628
47016
  "credential.https://github.com.helper",
46629
47017
  "!f() { echo username=x-access-token; echo password=$GH_TOKEN; }; f"
46630
47018
  ]);
46631
- await execFileAsync8("git", [
47019
+ await execFileAsync11("git", [
46632
47020
  "-C",
46633
47021
  path,
46634
47022
  "config",
@@ -46636,7 +47024,7 @@ async function materializeCornerWorktree(input) {
46636
47024
  "user.name",
46637
47025
  input.committer.name
46638
47026
  ]);
46639
- await execFileAsync8("git", [
47027
+ await execFileAsync11("git", [
46640
47028
  "-C",
46641
47029
  path,
46642
47030
  "config",
@@ -46644,8 +47032,8 @@ async function materializeCornerWorktree(input) {
46644
47032
  "user.email",
46645
47033
  `${input.committer.publicKey.slice(0, 16)}@users.noreply.github.com`
46646
47034
  ]);
46647
- const top = (await execFileAsync8("git", ["-C", path, "rev-parse", "--show-toplevel"])).stdout.trim();
46648
- if (await realpath2(top) !== await realpath2(path)) {
47035
+ const top = (await execFileAsync11("git", ["-C", path, "rev-parse", "--show-toplevel"])).stdout.trim();
47036
+ if (await realpath3(top) !== await realpath3(path)) {
46649
47037
  throw new Error(`corner worktree escaped its isolated root: ${top}`);
46650
47038
  }
46651
47039
  return { path, gitCommonDir };
@@ -46660,31 +47048,31 @@ async function mapWithConcurrency(values, limit, visit) {
46660
47048
  }));
46661
47049
  }
46662
47050
  async function discoverCornerWorktree(supervisorRoot, cornerId) {
46663
- const cornersRoot = resolve38(supervisorRoot, "beeline", "corners");
46664
- const path = resolve38(cornersRoot, cornerId);
46665
- if (dirname27(path) !== cornersRoot || !existsSync10(resolve38(path, ".git")))
47051
+ const cornersRoot = resolve40(supervisorRoot, "beeline", "corners");
47052
+ const path = resolve40(cornersRoot, cornerId);
47053
+ if (dirname28(path) !== cornersRoot || !existsSync10(resolve40(path, ".git")))
46666
47054
  return void 0;
46667
47055
  const [canonicalRoot, canonicalPath] = await Promise.all([
46668
- realpath2(cornersRoot),
46669
- realpath2(path).catch(() => void 0)
47056
+ realpath3(cornersRoot),
47057
+ realpath3(path).catch(() => void 0)
46670
47058
  ]);
46671
- if (!canonicalPath || relative3(canonicalRoot, canonicalPath) !== cornerId) {
47059
+ if (!canonicalPath || relative4(canonicalRoot, canonicalPath) !== cornerId) {
46672
47060
  throw new Error(`refusing corner ${cornerId} whose checkout path is not canonical`);
46673
47061
  }
46674
- const common = await execFileAsync8("git", ["-C", path, "rev-parse", "--git-common-dir"]).catch(() => void 0);
47062
+ const common = await execFileAsync11("git", ["-C", path, "rev-parse", "--git-common-dir"]).catch(() => void 0);
46675
47063
  if (!common)
46676
47064
  return void 0;
46677
- const gitCommonDir = resolve38(path, common.stdout.trim());
46678
- const repositoriesRoot = resolve38(supervisorRoot, "beeline", "repositories");
46679
- const commonRelative = relative3(repositoriesRoot, gitCommonDir);
46680
- if (!commonRelative || commonRelative === ".." || commonRelative.startsWith(`..${sep2}`) || commonRelative.startsWith(sep2)) {
47065
+ const gitCommonDir = resolve40(path, common.stdout.trim());
47066
+ const repositoriesRoot = resolve40(supervisorRoot, "beeline", "repositories");
47067
+ const commonRelative = relative4(repositoriesRoot, gitCommonDir);
47068
+ if (!commonRelative || commonRelative === ".." || commonRelative.startsWith(`..${sep3}`) || commonRelative.startsWith(sep3)) {
46681
47069
  throw new Error(`refusing corner ${cornerId} with git directory outside repository cache`);
46682
47070
  }
46683
47071
  return { path, gitCommonDir };
46684
47072
  }
46685
47073
  async function localCornerWorktreeIds(supervisorRoot) {
46686
- const root = resolve38(supervisorRoot, "beeline", "corners");
46687
- const entries = await readdir9(root, { withFileTypes: true }).catch((error) => {
47074
+ const root = resolve40(supervisorRoot, "beeline", "corners");
47075
+ const entries = await readdir11(root, { withFileTypes: true }).catch((error) => {
46688
47076
  if (error.code === "ENOENT")
46689
47077
  return [];
46690
47078
  throw error;
@@ -46698,12 +47086,12 @@ async function removeCornerWorktreeAndBranches(worktree, options = {}) {
46698
47086
  const worktreeExists = existsSync10(worktree.path);
46699
47087
  const localExists = await gitRefExists(worktree.gitCommonDir, localRef);
46700
47088
  if (worktreeExists) {
46701
- const checkedOut = await execFileAsync8("git", ["-C", worktree.path, "symbolic-ref", "--quiet", "HEAD"], { maxBuffer: 4 * 1024 * 1024 }).then((result) => result.stdout.trim(), () => void 0);
47089
+ const checkedOut = await execFileAsync11("git", ["-C", worktree.path, "symbolic-ref", "--quiet", "HEAD"], { maxBuffer: 4 * 1024 * 1024 }).then((result) => result.stdout.trim(), () => void 0);
46702
47090
  if (!worktree.recovered && checkedOut !== localRef) {
46703
47091
  throw new Error(`corner worktree branch mismatch: expected ${localRef}`);
46704
47092
  }
46705
47093
  await assertCornerWorktreePublished(worktree);
46706
- await execFileAsync8("git", [
47094
+ await execFileAsync11("git", [
46707
47095
  `--git-dir=${worktree.gitCommonDir}`,
46708
47096
  "worktree",
46709
47097
  "remove",
@@ -46728,7 +47116,7 @@ async function removeCornerWorktreeAndBranches(worktree, options = {}) {
46728
47116
  await deleteExactRemoteBranch(worktree.gitCommonDir, remoteRef, worktree.token);
46729
47117
  }
46730
47118
  if (await gitRefExists(worktree.gitCommonDir, localRef)) {
46731
- await execFileAsync8("git", [
47119
+ await execFileAsync11("git", [
46732
47120
  `--git-dir=${worktree.gitCommonDir}`,
46733
47121
  "branch",
46734
47122
  "--delete",
@@ -46739,18 +47127,18 @@ async function removeCornerWorktreeAndBranches(worktree, options = {}) {
46739
47127
  }
46740
47128
  }
46741
47129
  async function assertCornerWorktreePublished(worktree) {
46742
- const status = async () => (await execFileAsync8("git", ["-C", worktree.path, "status", "--porcelain=v1", "--untracked-files=all"], { maxBuffer: 4 * 1024 * 1024 })).stdout.trim();
46743
- const originalHead = (await execFileAsync8("git", ["-C", worktree.path, "rev-parse", "--verify", "HEAD"])).stdout.trim();
47130
+ const status = async () => (await execFileAsync11("git", ["-C", worktree.path, "status", "--porcelain=v1", "--untracked-files=all"], { maxBuffer: 4 * 1024 * 1024 })).stdout.trim();
47131
+ const originalHead = (await execFileAsync11("git", ["-C", worktree.path, "rev-parse", "--verify", "HEAD"])).stdout.trim();
46744
47132
  if (await status())
46745
47133
  throw new Error(`corner ${worktree.cornerId} has unpushed working-tree work`);
46746
47134
  await assertPublishedOnOrigin(worktree.gitCommonDir, originalHead, worktree.cornerId, worktree.token);
46747
- const settledHead = (await execFileAsync8("git", ["-C", worktree.path, "rev-parse", "--verify", "HEAD"])).stdout.trim();
47135
+ const settledHead = (await execFileAsync11("git", ["-C", worktree.path, "rev-parse", "--verify", "HEAD"])).stdout.trim();
46748
47136
  if (settledHead !== originalHead || await status()) {
46749
47137
  throw new Error(`corner ${worktree.cornerId} changed during cleanup`);
46750
47138
  }
46751
47139
  }
46752
47140
  async function assertLocalBranchPublished(worktree) {
46753
- const head = (await execFileAsync8("git", [
47141
+ const head = (await execFileAsync11("git", [
46754
47142
  `--git-dir=${worktree.gitCommonDir}`,
46755
47143
  "rev-parse",
46756
47144
  "--verify",
@@ -46761,7 +47149,7 @@ async function assertLocalBranchPublished(worktree) {
46761
47149
  async function assertPublishedOnOrigin(gitCommonDir, head, cornerId, token) {
46762
47150
  let published = await originContains(gitCommonDir, head);
46763
47151
  if (!published) {
46764
- await execFileAsync8("git", [
47152
+ await execFileAsync11("git", [
46765
47153
  `--git-dir=${gitCommonDir}`,
46766
47154
  "fetch",
46767
47155
  "--prune",
@@ -46777,7 +47165,7 @@ function hasUnpublishedWork(error) {
46777
47165
  return error instanceof Error && / has unpushed (?:commits|working-tree work)$/.test(error.message);
46778
47166
  }
46779
47167
  async function originContains(gitCommonDir, head) {
46780
- const result = await execFileAsync8("git", [
47168
+ const result = await execFileAsync11("git", [
46781
47169
  `--git-dir=${gitCommonDir}`,
46782
47170
  "for-each-ref",
46783
47171
  "--format=%(refname)",
@@ -46787,13 +47175,13 @@ async function originContains(gitCommonDir, head) {
46787
47175
  ]);
46788
47176
  return Boolean(result.stdout.trim());
46789
47177
  }
46790
- var execFileAsync8 = promisify8(execFile13);
47178
+ var execFileAsync11 = promisify11(execFile16);
46791
47179
  async function removeCornerScratchWorkspace(input) {
46792
- const expected = resolve38(input.roomRoot, "scratch");
46793
- if (resolve38(input.scratchPath) !== expected) {
47180
+ const expected = resolve40(input.roomRoot, "scratch");
47181
+ if (resolve40(input.scratchPath) !== expected) {
46794
47182
  throw new Error(`refusing to remove scratch outside corner ${input.cornerId}`);
46795
47183
  }
46796
- await rm15(expected, { recursive: true, force: true });
47184
+ await rm17(expected, { recursive: true, force: true });
46797
47185
  }
46798
47186
  var RoomRuntimeCoordinator = class {
46799
47187
  configPath;
@@ -46820,6 +47208,7 @@ var RoomRuntimeCoordinator = class {
46820
47208
  * then left alone; the checkout and its commits are kept, never deleted.
46821
47209
  */
46822
47210
  archiveCleanupAbandoned = /* @__PURE__ */ new Set();
47211
+ lastCornerScratchSweepAt = 0;
46823
47212
  startingCorners = /* @__PURE__ */ new Set();
46824
47213
  /**
46825
47214
  * Rooms whose start is in flight. `running` is not set until the checkout
@@ -47060,7 +47449,8 @@ var RoomRuntimeCoordinator = class {
47060
47449
  return;
47061
47450
  try {
47062
47451
  const result = await this.options.daemonApi.execute("listRoomCorners", {
47063
- roomId: room.roomId
47452
+ roomId: room.roomId,
47453
+ activeOnly: true
47064
47454
  });
47065
47455
  for (const corner of result.corners) {
47066
47456
  this.monolithCornerParents.set(corner.cornerId, room.roomId);
@@ -47100,6 +47490,9 @@ var RoomRuntimeCoordinator = class {
47100
47490
  if (this.stopped)
47101
47491
  return "member";
47102
47492
  await this.sweepArchivedCornerWorktrees(archivedCorners, desired);
47493
+ if (this.stopped)
47494
+ return "member";
47495
+ await this.sweepCornerLocalState(archivedCorners, desired);
47103
47496
  if (this.stopped)
47104
47497
  return "member";
47105
47498
  for (const cornerId of this.idleCornerSubscriptions.keys()) {
@@ -47117,6 +47510,10 @@ var RoomRuntimeCoordinator = class {
47117
47510
  await this.stopRunning(channelId, running);
47118
47511
  this.roomRemovalConfirmations.delete(channelId);
47119
47512
  }
47513
+ for (const cornerId of this.monolithCornerParents.keys()) {
47514
+ if (!desired.has(cornerId) && !this.running.has(cornerId) && !this.startingCorners.has(cornerId))
47515
+ this.monolithCornerParents.delete(cornerId);
47516
+ }
47120
47517
  this.surfaceHealth.retain(/* @__PURE__ */ new Set([...desired, ...this.running.keys()]));
47121
47518
  await mapWithConcurrency(desiredTopRooms, ROOM_JOIN_CONCURRENCY, async (roomId) => {
47122
47519
  if (this.stopped)
@@ -47191,6 +47588,8 @@ var RoomRuntimeCoordinator = class {
47191
47588
  if (event.archived === true) {
47192
47589
  this.unwatchCorner(roomId);
47193
47590
  this.surfaceHealth.remove(roomId);
47591
+ if (!this.running.has(roomId))
47592
+ this.monolithCornerParents.delete(roomId);
47194
47593
  return;
47195
47594
  }
47196
47595
  this.roomRemovalConfirmations.delete(roomId);
@@ -47228,18 +47627,20 @@ var RoomRuntimeCoordinator = class {
47228
47627
  } catch (error) {
47229
47628
  console.error(`[thin-core] corner ${channelId} cleanup failed; will retry:`, error);
47230
47629
  }
47630
+ if (running.worktree || running.scratch)
47631
+ await this.cleanupArchivedCornerLocalState(channelId);
47231
47632
  }
47232
47633
  roomRecord(roomId) {
47233
47634
  return this.runtime.rooms.find((room) => room.channelId === roomId);
47234
47635
  }
47235
47636
  roomRoot(roomId) {
47236
- return this.roomRecord(roomId)?.root ?? resolve38(dirname27(this.configPath), "rooms", roomId);
47637
+ return this.roomRecord(roomId)?.root ?? resolve40(dirname28(this.configPath), "rooms", roomId);
47237
47638
  }
47238
47639
  roomAgentHomeRoot(workspaceRoot, required = false) {
47239
47640
  const flag = process.env.BUZZY_BODY_ROOM_HOME;
47240
47641
  if (!required && flag === "0")
47241
47642
  return void 0;
47242
- const home = resolve38(workspaceRoot, "agent-home");
47643
+ const home = resolve40(workspaceRoot, "agent-home");
47243
47644
  if (!required && flag !== "1" && !existsSync10(home) && existsSync10(workspaceRoot))
47244
47645
  return void 0;
47245
47646
  try {
@@ -47255,10 +47656,10 @@ var RoomRuntimeCoordinator = class {
47255
47656
  return {
47256
47657
  ...this.baseConfig,
47257
47658
  workspaceRoot,
47258
- agentPrivateRoot: resolve38(workspaceRoot, "agent-private"),
47259
- agentMemoryRoot: resolve38(dirname27(this.configPath), "memory"),
47260
- openRouterRoutingCacheDir: openRouterRoutingCacheDir(dirname27(this.configPath)),
47261
- turnTraceDir: turnTraceDirectory(dirname27(this.configPath)),
47659
+ agentPrivateRoot: resolve40(workspaceRoot, "agent-private"),
47660
+ agentMemoryRoot: resolve40(dirname28(this.configPath), "memory"),
47661
+ openRouterRoutingCacheDir: openRouterRoutingCacheDir(dirname28(this.configPath)),
47662
+ turnTraceDir: turnTraceDirectory(dirname28(this.configPath)),
47262
47663
  ...agentHomeRoot ? { agentHomeRoot } : {}
47263
47664
  };
47264
47665
  }
@@ -47339,17 +47740,17 @@ var RoomRuntimeCoordinator = class {
47339
47740
  const remote = roomCheckoutRemote(repository.remote);
47340
47741
  const targetBranch = repository.targetBranch || "main";
47341
47742
  const checkoutId = createHash14("sha256").update(`${roomId}\0${remote}\0${targetBranch}`).digest("hex").slice(0, 24);
47342
- const path = resolve38(this.runtime.supervisorRoot, "beeline", "room-checkouts", checkoutId);
47343
- await mkdir27(dirname27(path), { recursive: true, mode: 448 });
47743
+ const path = resolve40(this.runtime.supervisorRoot, "beeline", "room-checkouts", checkoutId);
47744
+ await mkdir27(dirname28(path), { recursive: true, mode: 448 });
47344
47745
  const token = remote.startsWith("https://github.com/") ? await this.parentRepositoryToken(roomId) : void 0;
47345
47746
  const env = token ? githubGitEnv(token.token) : process.env;
47346
- if (!existsSync10(resolve38(path, ".git"))) {
47347
- await execFileAsync8("git", ["clone", "--no-checkout", remote, path], {
47747
+ if (!existsSync10(resolve40(path, ".git"))) {
47748
+ await execFileAsync11("git", ["clone", "--no-checkout", remote, path], {
47348
47749
  env,
47349
47750
  maxBuffer: 4 * 1024 * 1024
47350
47751
  });
47351
47752
  }
47352
- const fetched = await execFileAsync8("git", [
47753
+ const fetched = await execFileAsync11("git", [
47353
47754
  "-C",
47354
47755
  path,
47355
47756
  "fetch",
@@ -47365,7 +47766,7 @@ var RoomRuntimeCoordinator = class {
47365
47766
  void this.options.daemonApi.execute("noteEmptyRoomRepository", { roomId }).catch((error) => console.warn(`[thin-core] Room ${roomId} empty-repository notice failed:`, error));
47366
47767
  return this.roomRoot(roomId);
47367
47768
  }
47368
- await execFileAsync8("git", ["-C", path, "checkout", "--detach", "--force", `origin/${targetBranch}`], {
47769
+ await execFileAsync11("git", ["-C", path, "checkout", "--detach", "--force", `origin/${targetBranch}`], {
47369
47770
  env,
47370
47771
  maxBuffer: 4 * 1024 * 1024
47371
47772
  });
@@ -47380,7 +47781,7 @@ var RoomRuntimeCoordinator = class {
47380
47781
  const cwd = await this.materializeRoomCheckout(roomId, repository);
47381
47782
  if (cwd === this.roomRoot(roomId))
47382
47783
  return { cwd };
47383
- const { stdout: stdout6 } = await execFileAsync8("git", ["-C", cwd, "rev-parse", "--verify", "HEAD"]);
47784
+ const { stdout: stdout6 } = await execFileAsync11("git", ["-C", cwd, "rev-parse", "--verify", "HEAD"]);
47384
47785
  return { cwd, branch, commit: stdout6.trim() };
47385
47786
  } catch (error) {
47386
47787
  console.warn(`[thin-core] Room ${roomId} checkout refresh unavailable:`, error);
@@ -47430,9 +47831,11 @@ var RoomRuntimeCoordinator = class {
47430
47831
  featureBranch,
47431
47832
  token: granted.token
47432
47833
  }) : void 0;
47433
- const workspacePath = worktree?.path ?? resolve38(this.roomRoot(corner.cornerId), "scratch");
47834
+ const workspacePath = worktree?.path ?? resolve40(this.roomRoot(corner.cornerId), "scratch");
47434
47835
  if (!worktree)
47435
47836
  await mkdir27(workspacePath, { recursive: true, mode: 448 });
47837
+ await writePrivateFileAtomically(resolve40(this.roomRoot(corner.cornerId), ".beeline-corner.json"), `${JSON.stringify({ cornerId: corner.cornerId, parentRoomId: corner.parentRoomId })}
47838
+ `);
47436
47839
  if (worktree && shouldPostInitialCornerWorkingState(restore)) {
47437
47840
  await this.options.daemonApi.execute("postCornerRemoteState", {
47438
47841
  cornerId: corner.cornerId,
@@ -47486,10 +47889,11 @@ var RoomRuntimeCoordinator = class {
47486
47889
  this.surfaceHealth.degraded(corner.cornerId, "corner command loop exited");
47487
47890
  console.error(`[thin-core] corner ${corner.cornerId} failed:`, error);
47488
47891
  }
47489
- }).finally(() => {
47892
+ }).finally(async () => {
47490
47893
  if (this.running.get(corner.cornerId)?.body === loop) {
47491
47894
  this.running.delete(corner.cornerId);
47492
47895
  }
47896
+ await this.cleanupArchivedCornerLocalState(corner.cornerId).catch((error) => console.error(`[thin-core] corner ${corner.cornerId} local cleanup deferred:`, error));
47493
47897
  });
47494
47898
  if (this.stopped) {
47495
47899
  controller.abort();
@@ -47606,7 +48010,7 @@ var RoomRuntimeCoordinator = class {
47606
48010
  await this.restartRunningRoomForRepositoryChange(roomId);
47607
48011
  if (this.stopped)
47608
48012
  return;
47609
- const result = await this.options.daemonApi.execute("listRoomCorners", { roomId });
48013
+ const result = await this.options.daemonApi.execute("listRoomCorners", { roomId, activeOnly: true });
47610
48014
  for (const corner of result.corners) {
47611
48015
  this.monolithCornerParents.set(corner.cornerId, roomId);
47612
48016
  if (corner.archived)
@@ -47763,6 +48167,12 @@ var RoomRuntimeCoordinator = class {
47763
48167
  } catch (error) {
47764
48168
  if (hasUnpublishedWork(error)) {
47765
48169
  this.archiveCleanupAbandoned.add(cornerId);
48170
+ try {
48171
+ const saved = await preserveUnpublishedCornerWorktree(worktree, "archived with unpublished local work");
48172
+ console.warn(`[thin-core] corner ${cornerId} recoverable at ${saved.pointer}; pruned ${saved.pruned.join(", ") || "no generated directories"}`);
48173
+ } catch (preserveError) {
48174
+ console.error(`[thin-core] corner ${cornerId} recovery preservation failed:`, preserveError);
48175
+ }
47766
48176
  console.error(`[thin-core] corner ${cornerId} branch cleanup abandoned; unpublished work kept:`, error);
47767
48177
  continue;
47768
48178
  }
@@ -47783,11 +48193,14 @@ var RoomRuntimeCoordinator = class {
47783
48193
  continue;
47784
48194
  if (!this.archiveCleanupDue(cornerId))
47785
48195
  continue;
48196
+ if (this.archiveCleanupAbandoned.has(cornerId))
48197
+ continue;
47786
48198
  if (this.archiveCleanupAccessDenied.has(cornerId) && !corners.has(cornerId))
47787
48199
  continue;
47788
48200
  this.archiveCleanupAccessDenied.delete(cornerId);
47789
48201
  let corner = corners.get(cornerId);
47790
48202
  let discovered;
48203
+ let candidate;
47791
48204
  try {
47792
48205
  discovered = await discoverCornerWorktree(this.runtime.supervisorRoot, cornerId);
47793
48206
  if (!discovered) {
@@ -47813,22 +48226,33 @@ var RoomRuntimeCoordinator = class {
47813
48226
  throw new Error(`archived corner ${corner.cornerId} has no authoritative repository`);
47814
48227
  }
47815
48228
  const expectedCommonDir = cornerRepositoryCacheDir(this.runtime.supervisorRoot, repository.remote);
47816
- if (resolve38(discovered.gitCommonDir) !== expectedCommonDir) {
48229
+ if (resolve40(discovered.gitCommonDir) !== expectedCommonDir) {
47817
48230
  throw new Error(`archived corner ${corner.cornerId} repository cache does not match`);
47818
48231
  }
47819
48232
  if (!restore.featureBranch) {
47820
48233
  throw new Error(`archived corner ${corner.cornerId} has no authoritative feature branch`);
47821
48234
  }
47822
- await this.reapCornerWorktree({
48235
+ candidate = {
47823
48236
  ...discovered,
47824
48237
  cornerId: corner.cornerId,
47825
48238
  branch: restore.featureBranch,
47826
48239
  parentRoomId: corner.parentRoomId,
47827
48240
  token: "",
47828
48241
  recovered: true
47829
- });
48242
+ };
48243
+ await this.reapCornerWorktree(candidate);
47830
48244
  console.log(`[thin-core] swept archived corner worktree ${cornerId}`);
47831
48245
  } catch (error) {
48246
+ if (candidate && hasUnpublishedWork(error)) {
48247
+ this.archiveCleanupAbandoned.add(cornerId);
48248
+ try {
48249
+ const saved = await preserveUnpublishedCornerWorktree(candidate, "archived with unpublished local work");
48250
+ console.warn(`[thin-core] archived corner ${cornerId} recoverable at ${saved.pointer}; pruned ${saved.pruned.join(", ") || "no generated directories"}`);
48251
+ } catch (preserveError) {
48252
+ console.error(`[thin-core] archived corner ${cornerId} recovery preservation failed:`, preserveError);
48253
+ }
48254
+ continue;
48255
+ }
47832
48256
  if (error instanceof DaemonApiError && error.status === 403)
47833
48257
  this.archiveCleanupAccessDenied.add(cornerId);
47834
48258
  else
@@ -47885,6 +48309,64 @@ var RoomRuntimeCoordinator = class {
47885
48309
  scratchPath: scratch.path
47886
48310
  });
47887
48311
  }
48312
+ /** Reap a corner's private state only after the server confirms archive and
48313
+ * its ACP session has suspended. A missing/failed read is never authority. */
48314
+ async cleanupArchivedCornerLocalState(cornerId, knownArchive) {
48315
+ if (this.running.has(cornerId) || this.startingCorners.has(cornerId))
48316
+ return false;
48317
+ const root = resolve40(dirname28(this.configPath), "rooms", cornerId);
48318
+ if (this.roomRoot(cornerId) !== root || !/^[a-zA-Z0-9-]{1,80}$/.test(cornerId))
48319
+ return false;
48320
+ const info = await lstat7(root).catch(() => void 0);
48321
+ if (!info?.isDirectory() || await realpath3(root) !== root)
48322
+ return false;
48323
+ let archived = knownArchive?.has(cornerId) ?? false;
48324
+ if (!archived) {
48325
+ try {
48326
+ const restore = await this.options.daemonApi.execute("getCornerRestoreState", { cornerId });
48327
+ archived = restore.archived === true;
48328
+ } catch {
48329
+ return false;
48330
+ }
48331
+ }
48332
+ if (!archived)
48333
+ return false;
48334
+ await this.scheduler.suspend(cornerId);
48335
+ await rm17(resolve40(root, "scratch"), { recursive: true, force: true });
48336
+ await rm17(resolve40(root, "agent-home"), { recursive: true, force: true });
48337
+ await rm17(resolve40(root, ".beeline-corner.json"), { force: true });
48338
+ return true;
48339
+ }
48340
+ /** Recover chat-only scratch and per-member homes after missed close events
48341
+ * or a helper restart. A marker identifies new code corners after their
48342
+ * checkout has already gone; a scratch directory identifies legacy chat
48343
+ * corners. Active scratch gets a 14-day file TTL, never a wholesale reap. */
48344
+ async sweepCornerLocalState(archived, desired) {
48345
+ const root = resolve40(dirname28(this.configPath), "rooms");
48346
+ const due = this.now() - this.lastCornerScratchSweepAt >= 6 * 60 * 6e4;
48347
+ if (due)
48348
+ this.lastCornerScratchSweepAt = this.now();
48349
+ for (const entry of await readdir11(root, { withFileTypes: true }).catch(() => [])) {
48350
+ if (!entry.isDirectory() || !/^[a-zA-Z0-9-]{1,80}$/.test(entry.name))
48351
+ continue;
48352
+ const roomRoot = resolve40(root, entry.name);
48353
+ const scratch = resolve40(roomRoot, "scratch");
48354
+ const marker = resolve40(roomRoot, ".beeline-corner.json");
48355
+ const hasScratch = (await lstat7(scratch).catch(() => void 0))?.isDirectory() ?? false;
48356
+ const hasMarker = (await lstat7(marker).catch(() => void 0))?.isFile() ?? false;
48357
+ if (!hasScratch && !hasMarker)
48358
+ continue;
48359
+ if (desired.has(entry.name)) {
48360
+ if (due && hasScratch && !this.startingCorners.has(entry.name) && !this.running.get(entry.name)?.body.isBusy()) {
48361
+ await sweepStaleCornerScratch(scratch, this.now(), CORNER_SCRATCH_TTL_MS).catch((error) => console.error(`[thin-core] corner ${entry.name} scratch TTL sweep failed:`, error));
48362
+ }
48363
+ continue;
48364
+ }
48365
+ if (this.running.has(entry.name) || this.startingCorners.has(entry.name))
48366
+ continue;
48367
+ await this.cleanupArchivedCornerLocalState(entry.name, archived).catch((error) => console.error(`[thin-core] corner ${entry.name} local cleanup deferred:`, error));
48368
+ }
48369
+ }
47888
48370
  notePoll(roomId) {
47889
48371
  this.surfaceHealth.intakeReady(roomId);
47890
48372
  const room = this.running.get(roomId);
@@ -47969,7 +48451,7 @@ function githubGitEnv(token) {
47969
48451
  }
47970
48452
  async function gitRefExists(gitCommonDir, ref) {
47971
48453
  try {
47972
- await execFileAsync8("git", [
48454
+ await execFileAsync11("git", [
47973
48455
  `--git-dir=${gitCommonDir}`,
47974
48456
  "show-ref",
47975
48457
  "--verify",
@@ -47985,7 +48467,7 @@ async function gitRefExists(gitCommonDir, ref) {
47985
48467
  }
47986
48468
  async function repositoryHeadRef(gitCommonDir) {
47987
48469
  try {
47988
- const head = await execFileAsync8("git", [
48470
+ const head = await execFileAsync11("git", [
47989
48471
  `--git-dir=${gitCommonDir}`,
47990
48472
  "symbolic-ref",
47991
48473
  "--quiet",
@@ -48005,7 +48487,7 @@ ${gitStderr(error)}`);
48005
48487
  }
48006
48488
  async function deleteExactRemoteBranch(gitCommonDir, remoteRef, token, options = {}) {
48007
48489
  const authEnv = githubGitEnv(token);
48008
- const listRemote = () => execFileAsync8("git", [`--git-dir=${gitCommonDir}`, "ls-remote", "--heads", "origin", remoteRef], {
48490
+ const listRemote = () => execFileAsync11("git", [`--git-dir=${gitCommonDir}`, "ls-remote", "--heads", "origin", remoteRef], {
48009
48491
  env: authEnv,
48010
48492
  maxBuffer: 4 * 1024 * 1024
48011
48493
  });
@@ -48021,7 +48503,7 @@ async function deleteExactRemoteBranch(gitCommonDir, remoteRef, token, options =
48021
48503
  try {
48022
48504
  const remote = await listRemote();
48023
48505
  if (remote.stdout.trim()) {
48024
- await execFileAsync8("git", [`--git-dir=${gitCommonDir}`, "push", "origin", `:${remoteRef}`], {
48506
+ await execFileAsync11("git", [`--git-dir=${gitCommonDir}`, "push", "origin", `:${remoteRef}`], {
48025
48507
  env: authEnv,
48026
48508
  maxBuffer: 4 * 1024 * 1024
48027
48509
  });
@@ -48163,15 +48645,15 @@ var ThinDaemonCore = class {
48163
48645
  };
48164
48646
 
48165
48647
  // apps/body/dist/force-update-journal.js
48166
- import { mkdirSync as mkdirSync4, readFileSync as readFileSync9, renameSync, writeFileSync as writeFileSync5 } from "node:fs";
48167
- import { resolve as resolve39 } from "node:path";
48648
+ import { mkdirSync as mkdirSync4, readFileSync as readFileSync10, renameSync, writeFileSync as writeFileSync5 } from "node:fs";
48649
+ import { resolve as resolve41 } from "node:path";
48168
48650
  var NAME = "force-update-interruptions.json";
48169
48651
  function pathFor(runtimeDir) {
48170
- return resolve39(runtimeDir, NAME);
48652
+ return resolve41(runtimeDir, NAME);
48171
48653
  }
48172
48654
  function read(runtimeDir) {
48173
48655
  try {
48174
- const rows = JSON.parse(readFileSync9(pathFor(runtimeDir), "utf8"));
48656
+ const rows = JSON.parse(readFileSync10(pathFor(runtimeDir), "utf8"));
48175
48657
  if (!Array.isArray(rows))
48176
48658
  throw new Error("invalid force-update interruption journal");
48177
48659
  return rows.map((row) => {
@@ -48245,17 +48727,17 @@ function staleGeneration(error) {
48245
48727
  init_launchd();
48246
48728
  init_systemd();
48247
48729
  import { mkdir as mkdir28, rename as rename11 } from "node:fs/promises";
48248
- import { dirname as dirname28, resolve as resolve40 } from "node:path";
48730
+ import { dirname as dirname29, resolve as resolve42 } from "node:path";
48249
48731
  async function retireRemovedAgent(runtime, options = {}) {
48250
- const deletedRoot = resolve40(runtime.supervisorRoot, "beeline", "deleted-runtimes");
48251
- const target = resolve40(deletedRoot, `${runtime.agent.publicKey}-${Date.now()}`);
48732
+ const deletedRoot = resolve42(runtime.supervisorRoot, "beeline", "deleted-runtimes");
48733
+ const target = resolve42(deletedRoot, `${runtime.agent.publicKey}-${Date.now()}`);
48252
48734
  return relocateAgentRuntime(runtime, target, {
48253
48735
  ...options.run ? { run: options.run } : {}
48254
48736
  });
48255
48737
  }
48256
48738
  async function relocateAgentRuntime(runtime, target, options = {}) {
48257
48739
  const source = runtimeDirectory(runtime.supervisorRoot, runtime.agent.publicKey);
48258
- const destination = resolve40(target);
48740
+ const destination = resolve42(target);
48259
48741
  if (destination === source || destination.startsWith(`${source}/`)) {
48260
48742
  throw new Error("agent runtime destination must be outside the live runtime");
48261
48743
  }
@@ -48268,7 +48750,7 @@ async function relocateAgentRuntime(runtime, target, options = {}) {
48268
48750
  ...options.run ? { run: options.run } : {}
48269
48751
  });
48270
48752
  }
48271
- await mkdir28(dirname28(destination), { recursive: true, mode: 448 });
48753
+ await mkdir28(dirname29(destination), { recursive: true, mode: 448 });
48272
48754
  await rename11(source, destination);
48273
48755
  return destination;
48274
48756
  }
@@ -48278,8 +48760,8 @@ init_self_update();
48278
48760
  init_systemd();
48279
48761
 
48280
48762
  // apps/body/dist/release-status.js
48281
- import { readFile as readFile31, readdir as readdir10, rename as rename12, writeFile as writeFile21 } from "node:fs/promises";
48282
- import { resolve as resolve41 } from "node:path";
48763
+ import { readFile as readFile31, readdir as readdir12, rename as rename12, writeFile as writeFile21 } from "node:fs/promises";
48764
+ import { resolve as resolve43 } from "node:path";
48283
48765
  var DAEMON_RELEASE_STATUS_FILE = "release-status.json";
48284
48766
  var RELEASE_VERSION = /^v\d+\.\d+\.\d+$/;
48285
48767
  var SOURCE_SHA = /^[0-9a-f]{7,64}$/;
@@ -48296,7 +48778,7 @@ async function writeDaemonReleaseStatus(runtimeDir, agentPubkey, identity, optio
48296
48778
  pid: options.pid ?? process.pid,
48297
48779
  readyAt: (options.now?.() ?? /* @__PURE__ */ new Date()).toISOString()
48298
48780
  };
48299
- const target = resolve41(runtimeDir, DAEMON_RELEASE_STATUS_FILE);
48781
+ const target = resolve43(runtimeDir, DAEMON_RELEASE_STATUS_FILE);
48300
48782
  const temporary = `${target}.${status.pid}.tmp`;
48301
48783
  await writeFile21(temporary, `${JSON.stringify(status, null, 2)}
48302
48784
  `, { mode: 384 });
@@ -48305,8 +48787,8 @@ async function writeDaemonReleaseStatus(runtimeDir, agentPubkey, identity, optio
48305
48787
  }
48306
48788
 
48307
48789
  // apps/body/dist/scratch-sweep.js
48308
- import { lstat as lstat5, readdir as readdir11, rmdir as rmdir2, unlink as unlink9 } from "node:fs/promises";
48309
- import { resolve as resolve42 } from "node:path";
48790
+ import { lstat as lstat8, readdir as readdir13, rmdir as rmdir3, unlink as unlink10 } from "node:fs/promises";
48791
+ import { resolve as resolve44 } from "node:path";
48310
48792
  var DEFAULT_SCRATCH_TTL_HOURS = 72;
48311
48793
  var NEVER_SWEEP_SUBDIR_NAMES = new Set(HOME_SUBDIRS.filter((name) => name !== "tmp"));
48312
48794
  function scratchTtlMs(env = process.env) {
@@ -48315,10 +48797,10 @@ function scratchTtlMs(env = process.env) {
48315
48797
  return (Number.isFinite(hours) && hours > 0 ? hours : DEFAULT_SCRATCH_TTL_HOURS) * 60 * 60 * 1e3;
48316
48798
  }
48317
48799
  async function discoverAttachScratchRoots(runtimeDir) {
48318
- const roomsDir = resolve42(runtimeDir, "rooms");
48800
+ const roomsDir = resolve44(runtimeDir, "rooms");
48319
48801
  let entries;
48320
48802
  try {
48321
- entries = await readdir11(roomsDir, { withFileTypes: true });
48803
+ entries = await readdir13(roomsDir, { withFileTypes: true });
48322
48804
  } catch {
48323
48805
  return [];
48324
48806
  }
@@ -48326,8 +48808,8 @@ async function discoverAttachScratchRoots(runtimeDir) {
48326
48808
  for (const entry of entries) {
48327
48809
  if (!entry.isDirectory())
48328
48810
  continue;
48329
- const home = resolve42(roomsDir, entry.name, "agent-home");
48330
- const stats = await lstat5(home).catch(() => void 0);
48811
+ const home = resolve44(roomsDir, entry.name, "agent-home");
48812
+ const stats = await lstat8(home).catch(() => void 0);
48331
48813
  if (stats?.isDirectory())
48332
48814
  roots.push(home);
48333
48815
  }
@@ -48336,7 +48818,7 @@ async function discoverAttachScratchRoots(runtimeDir) {
48336
48818
  async function removeStaleFiles(dir, cutoffMs, protectNamesHere) {
48337
48819
  let entries;
48338
48820
  try {
48339
- entries = await readdir11(dir, { withFileTypes: true });
48821
+ entries = await readdir13(dir, { withFileTypes: true });
48340
48822
  } catch {
48341
48823
  return { removedFiles: 0, removedBytes: 0 };
48342
48824
  }
@@ -48345,22 +48827,22 @@ async function removeStaleFiles(dir, cutoffMs, protectNamesHere) {
48345
48827
  for (const entry of entries) {
48346
48828
  if (protectNamesHere && NEVER_SWEEP_SUBDIR_NAMES.has(entry.name))
48347
48829
  continue;
48348
- const path = resolve42(dir, entry.name);
48349
- const stats = await lstat5(path).catch(() => void 0);
48830
+ const path = resolve44(dir, entry.name);
48831
+ const stats = await lstat8(path).catch(() => void 0);
48350
48832
  if (!stats || stats.isSymbolicLink())
48351
48833
  continue;
48352
48834
  if (stats.isDirectory()) {
48353
48835
  const nested = await removeStaleFiles(path, cutoffMs, false);
48354
48836
  removedFiles += nested.removedFiles;
48355
48837
  removedBytes += nested.removedBytes;
48356
- const remaining = await readdir11(path).catch(() => void 0);
48838
+ const remaining = await readdir13(path).catch(() => void 0);
48357
48839
  if (remaining && remaining.length === 0)
48358
- await rmdir2(path).catch(() => void 0);
48840
+ await rmdir3(path).catch(() => void 0);
48359
48841
  continue;
48360
48842
  }
48361
48843
  if (!stats.isFile() || stats.mtimeMs >= cutoffMs)
48362
48844
  continue;
48363
- await unlink9(path).catch(() => void 0);
48845
+ await unlink10(path).catch(() => void 0);
48364
48846
  removedFiles += 1;
48365
48847
  removedBytes += stats.size;
48366
48848
  }
@@ -48371,7 +48853,7 @@ async function sweepAttachScratchRoots(roots, ttlMs, now2 = Date.now()) {
48371
48853
  let removedFiles = 0;
48372
48854
  let removedBytes = 0;
48373
48855
  for (const root of roots) {
48374
- const stats = await lstat5(root).catch(() => void 0);
48856
+ const stats = await lstat8(root).catch(() => void 0);
48375
48857
  if (!stats?.isDirectory())
48376
48858
  continue;
48377
48859
  const result = await removeStaleFiles(root, cutoffMs, true);
@@ -48394,7 +48876,7 @@ function runScratchSweepLogged(runtimeDir) {
48394
48876
  void runScratchSweep(runtimeDir).catch((error) => console.error("[body] scratch sweep failed:", error));
48395
48877
  }
48396
48878
  async function runAgentRuntime(configPath, host, signal) {
48397
- const runtimeDir = dirname29(configPath);
48879
+ const runtimeDir = dirname30(configPath);
48398
48880
  await convergeRuntimeRecordFileModes(configPath);
48399
48881
  const accessMigration = await migrateRuntimeRecordAccessPolicy(configPath);
48400
48882
  let runtime = accessMigration.runtime;
@@ -48430,7 +48912,7 @@ async function runAgentRuntime(configPath, host, signal) {
48430
48912
  BUZZ_DEV_MCP_BIN: runtime.mcpBinary
48431
48913
  };
48432
48914
  const config = loadBodyConfig({
48433
- workspaceRoot: resolve43(runtimeDir, "workspace"),
48915
+ workspaceRoot: resolve45(runtimeDir, "workspace"),
48434
48916
  llmEnvFile: runtime.llmEnvFile,
48435
48917
  env,
48436
48918
  agent
@@ -48740,7 +49222,7 @@ async function runAgentRuntime(configPath, host, signal) {
48740
49222
  return exitReason ?? lifecycle.stopReason ?? "stopped";
48741
49223
  }
48742
49224
  function registryBrokerSocketPath(home, agentId) {
48743
- return join21(home ?? homedir19(), ".beeline", "registry-mcp-broker", `${process.pid}-${agentId.slice(0, 8)}.sock`);
49225
+ return join23(home ?? homedir19(), ".beeline", "registry-mcp-broker", `${process.pid}-${agentId.slice(0, 8)}.sock`);
48744
49226
  }
48745
49227
  function interruptHostedAgent(agent) {
48746
49228
  agent.lifecycle.quiesce("force-update");
@@ -48781,6 +49263,78 @@ var ForceUpdateCoordinator = class {
48781
49263
  init_launchd();
48782
49264
  init_self_update();
48783
49265
  init_systemd();
49266
+
49267
+ // apps/body/dist/host-disk-retention.js
49268
+ import { execFile as execFile17 } from "node:child_process";
49269
+ import { lstat as lstat9, readdir as readdir14, rm as rm18 } from "node:fs/promises";
49270
+ import { join as join24, resolve as resolve46 } from "node:path";
49271
+ import { promisify as promisify12 } from "node:util";
49272
+ var execFileAsync12 = promisify12(execFile17);
49273
+ var DELETED_RUNTIME_TTL_MS = 30 * 24 * 60 * 6e4;
49274
+ var REPOSITORY_CACHE_TTL_MS = 30 * 24 * 60 * 6e4;
49275
+ async function pruneDeletedRuntimes(supervisorRoot, now2 = Date.now()) {
49276
+ const root = resolve46(supervisorRoot, "beeline", "deleted-runtimes");
49277
+ const removed = [];
49278
+ for (const entry of await readdir14(root, { withFileTypes: true }).catch(() => [])) {
49279
+ const match = /^([a-f0-9]{64})-(\d{13})$/.exec(entry.name);
49280
+ if (!entry.isDirectory() || !match || now2 - Number(match[2]) < DELETED_RUNTIME_TTL_MS)
49281
+ continue;
49282
+ const path = join24(root, entry.name);
49283
+ if (!(await lstat9(path)).isDirectory())
49284
+ continue;
49285
+ await rm18(path, { recursive: true, force: true });
49286
+ removed.push(path);
49287
+ }
49288
+ return removed;
49289
+ }
49290
+ async function pruneRepositoryCaches(supervisorRoot, now2 = Date.now()) {
49291
+ const root = resolve46(supervisorRoot, "beeline", "repositories");
49292
+ const removed = [];
49293
+ for (const entry of await readdir14(root, { withFileTypes: true }).catch(() => [])) {
49294
+ if (!entry.isDirectory() || !/^[a-f0-9]{24}\.git$/.test(entry.name))
49295
+ continue;
49296
+ const path = join24(root, entry.name);
49297
+ const info = await lstat9(path);
49298
+ if (!info.isDirectory() || now2 - info.mtimeMs < REPOSITORY_CACHE_TTL_MS)
49299
+ continue;
49300
+ const listing = await execFileAsync12("git", [`--git-dir=${path}`, "worktree", "list", "--porcelain"]).then((result) => result.stdout, () => void 0);
49301
+ if (listing === void 0)
49302
+ continue;
49303
+ const attached = listing.split("\n").some((line) => line.startsWith("worktree ") && resolve46(line.slice("worktree ".length)) !== path);
49304
+ if (attached)
49305
+ continue;
49306
+ const refs = await execFileAsync12("git", [
49307
+ `--git-dir=${path}`,
49308
+ "for-each-ref",
49309
+ "--format=%(refname) %(objectname)"
49310
+ ]).then((result) => result.stdout, () => void 0);
49311
+ if (refs === void 0)
49312
+ continue;
49313
+ const byName = /* @__PURE__ */ new Map();
49314
+ for (const line of refs.trim().split("\n")) {
49315
+ const match = /^(refs\/\S+) ([a-f0-9]{40,64})$/.exec(line);
49316
+ if (match)
49317
+ byName.set(match[1], match[2]);
49318
+ }
49319
+ const unpublishedHead = [...byName].some(([name, oid]) => name.startsWith("refs/heads/") && byName.get(name.replace("refs/heads/", "refs/remotes/origin/")) !== oid);
49320
+ if (unpublishedHead)
49321
+ continue;
49322
+ const unreachable = await execFileAsync12("git", [
49323
+ `--git-dir=${path}`,
49324
+ "fsck",
49325
+ "--unreachable",
49326
+ "--no-reflogs",
49327
+ "--no-progress"
49328
+ ]).then((result) => result.stdout, () => void 0);
49329
+ if (unreachable === void 0 || /unreachable commit /.test(unreachable))
49330
+ continue;
49331
+ await rm18(path, { recursive: true, force: true });
49332
+ removed.push(path);
49333
+ }
49334
+ return removed;
49335
+ }
49336
+
49337
+ // apps/body/dist/machine-helper.js
48784
49338
  var AGENT_RESTART_BASE_MS = 5e3;
48785
49339
  var AGENT_RESTART_MAX_MS = 6e4;
48786
49340
  var PREVIOUS_HOLDER_WAIT_MS = 12e4;
@@ -48801,6 +49355,32 @@ async function runMachineHelper(options = {}) {
48801
49355
  const slots = /* @__PURE__ */ new Map();
48802
49356
  const hosted = /* @__PURE__ */ new Map();
48803
49357
  const links = /* @__PURE__ */ new Map();
49358
+ let diskSweepRunning = false;
49359
+ let lastModelSweepAt = 0;
49360
+ let lastRetentionSweepAt = 0;
49361
+ const sweepHostDisk = async () => {
49362
+ const now2 = Date.now();
49363
+ 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)
49364
+ return;
49365
+ diskSweepRunning = true;
49366
+ try {
49367
+ const modelDue = now2 - lastModelSweepAt >= 60 * 6e4;
49368
+ const removed = modelDue ? await pruneSharedModelCache(resolve47(supervisorRoot, "beeline", "model-cache")) : [];
49369
+ if (modelDue)
49370
+ lastModelSweepAt = now2;
49371
+ if (now2 - lastRetentionSweepAt >= 24 * 60 * 6e4) {
49372
+ removed.push(...await pruneDeletedRuntimes(supervisorRoot));
49373
+ removed.push(...await pruneRepositoryCaches(supervisorRoot));
49374
+ lastRetentionSweepAt = now2;
49375
+ }
49376
+ if (removed.length)
49377
+ console.log(`[helper] idle disk sweep removed ${removed.length} expired cache/runtime directories`);
49378
+ } catch (error) {
49379
+ console.warn("[helper] idle disk sweep failed:", error);
49380
+ } finally {
49381
+ diskSweepRunning = false;
49382
+ }
49383
+ };
48804
49384
  if (!options.configPaths)
48805
49385
  await writeHelperPidRecord(supervisorRoot, process.pid);
48806
49386
  const layout = beelineInstallLayout(env);
@@ -48812,7 +49392,7 @@ async function runMachineHelper(options = {}) {
48812
49392
  const paths = options.configPaths ?? await findAgentRuntimeConfigPaths(env);
48813
49393
  const live = [];
48814
49394
  for (const path of paths) {
48815
- if (!await stat9(path).then(() => true, () => false))
49395
+ if (!await stat10(path).then(() => true, () => false))
48816
49396
  continue;
48817
49397
  if (await isAgentStopped(path))
48818
49398
  continue;
@@ -48832,7 +49412,7 @@ async function runMachineHelper(options = {}) {
48832
49412
  const settle = await settleUpdateAttemptOnStart(layout);
48833
49413
  if (settle.kind === "rolled-back") {
48834
49414
  for (const path of await hostedRuntimes())
48835
- await queueUpdateRollbackAlert(dirname30(path), settle.record.releaseId);
49415
+ await queueUpdateRollbackAlert(dirname31(path), settle.record.releaseId);
48836
49416
  console.error(`[helper] self-update ROLLED BACK: bundle ${describeIdentity(settle.record.to)} never confirmed healthy; restored ${settle.record.previousReleaseId ?? "previous release"}`);
48837
49417
  return finish(await standDownForRollback());
48838
49418
  }
@@ -48873,7 +49453,7 @@ async function runMachineHelper(options = {}) {
48873
49453
  since: new Date(slot.since).toISOString()
48874
49454
  }]))
48875
49455
  };
48876
- await mkdir29(dirname30(path), { recursive: true, mode: 448 });
49456
+ await mkdir29(dirname31(path), { recursive: true, mode: 448 });
48877
49457
  const staged = `${path}.${process.pid}.tmp`;
48878
49458
  await writeFile22(staged, `${JSON.stringify(body, null, 2)}
48879
49459
  `, { mode: 384 });
@@ -48966,6 +49546,7 @@ async function runMachineHelper(options = {}) {
48966
49546
  for (const agent of hosted.values())
48967
49547
  agent.lifecycle.resumeAfterFailedUpdate(() => agent.core.resumeServing());
48968
49548
  }
49549
+ void sweepHostDisk();
48969
49550
  };
48970
49551
  let readyResolve;
48971
49552
  const allEstablished = new Promise((resolveReady) => {
@@ -49020,7 +49601,7 @@ async function runMachineHelper(options = {}) {
49020
49601
  const supervise = async (slot) => {
49021
49602
  let failures = 0;
49022
49603
  while (!controller.signal.aborted && !slot.controller.signal.aborted) {
49023
- if (!await stat9(slot.configPath).then(() => true, () => false)) {
49604
+ if (!await stat10(slot.configPath).then(() => true, () => false)) {
49024
49605
  setState(slot, "removed", "runtime no longer on this machine");
49025
49606
  break;
49026
49607
  }
@@ -49030,7 +49611,7 @@ async function runMachineHelper(options = {}) {
49030
49611
  reason = await runAgent(slot.configPath, host, slot.controller.signal);
49031
49612
  } catch (error) {
49032
49613
  console.error(`[helper] agent ${slot.agentId} failed:`, error);
49033
- const failure = await settleDaemonStartFailure(dirname30(slot.configPath), error).catch(() => ({ distressed: false }));
49614
+ const failure = await settleDaemonStartFailure(dirname31(slot.configPath), error).catch(() => ({ distressed: false }));
49034
49615
  if (failure.distressed) {
49035
49616
  console.error(`[helper] agent ${slot.agentId} failed to start ${failure.count} times; it stays stopped. operator record: ${failure.path}`);
49036
49617
  reason = "distress";
@@ -49079,7 +49660,7 @@ async function runMachineHelper(options = {}) {
49079
49660
  const runtime = await readRuntimeRecord(configPath).catch(() => void 0);
49080
49661
  const slot = existing ?? {
49081
49662
  configPath,
49082
- agentId: runtime?.agent.publicKey ?? dirname30(configPath).split("/").at(-1),
49663
+ agentId: runtime?.agent.publicKey ?? dirname31(configPath).split("/").at(-1),
49083
49664
  controller: new AbortController(),
49084
49665
  state: "starting",
49085
49666
  status: "",
@@ -49119,6 +49700,8 @@ async function runMachineHelper(options = {}) {
49119
49700
  allEstablished,
49120
49701
  new Promise((resolveAbort) => controller.signal.addEventListener("abort", () => resolveAbort(), { once: true }))
49121
49702
  ]);
49703
+ if (!controller.signal.aborted)
49704
+ void sweepHostDisk();
49122
49705
  if (!controller.signal.aborted)
49123
49706
  await notifier.ready(`ready; ${statusLine()}`).catch((error) => console.error("[helper] ready notification failed:", error));
49124
49707
  if (!controller.signal.aborted)
@@ -49185,7 +49768,7 @@ async function waitForPreviousHolder(configPath, signal) {
49185
49768
  return;
49186
49769
  if (!announced) {
49187
49770
  announced = true;
49188
- console.log(`[helper] waiting for process ${pid} to let go of ${dirname30(configPath)}`);
49771
+ console.log(`[helper] waiting for process ${pid} to let go of ${dirname31(configPath)}`);
49189
49772
  }
49190
49773
  const waited = Date.now() - startedAt;
49191
49774
  if (waited >= PREVIOUS_HOLDER_WAIT_MS && !asked) {
@@ -49310,7 +49893,7 @@ async function main() {
49310
49893
  const roomId = roomFlag >= 0 ? args[roomFlag + 1] : void 0;
49311
49894
  if (!configPath || !roomId)
49312
49895
  throw new Error("corner-read-token requires --config and --room");
49313
- const activated = await activateDaemonTransport(resolve44(configPath));
49896
+ const activated = await activateDaemonTransport(resolve48(configPath));
49314
49897
  if (!activated)
49315
49898
  throw new Error("corner-read-token requires monolith transport");
49316
49899
  const credential = await activated.client.execute("getRoomGitHubToken", { roomId });
@@ -49365,7 +49948,7 @@ async function main() {
49365
49948
  }
49366
49949
  if (!configPath && !args.includes("--machine"))
49367
49950
  throw new Error("daemon requires --machine, or --config <runtime.json> for one agent");
49368
- const { reason, lifecycle } = await runMachineHelper(configPath ? { configPaths: [resolve44(configPath)] } : {});
49951
+ const { reason, lifecycle } = await runMachineHelper(configPath ? { configPaths: [resolve48(configPath)] } : {});
49369
49952
  daemonLifecycle = lifecycle;
49370
49953
  lifecycle.exit(reason);
49371
49954
  return;
@@ -49388,7 +49971,7 @@ async function main() {
49388
49971
  if (!agentPubkey)
49389
49972
  throw new Error("stop requires --agent <pubkey>");
49390
49973
  const configs = await findAgentRuntimeConfigPaths(process.env, process.cwd());
49391
- const configPath = configs.find((candidate) => dirname31(candidate).endsWith(agentPubkey));
49974
+ const configPath = configs.find((candidate) => dirname32(candidate).endsWith(agentPubkey));
49392
49975
  if (!configPath)
49393
49976
  throw new Error(`no stored runtime found for agent ${agentPubkey}`);
49394
49977
  const runtime = await readRuntimeRecord(configPath);