usebeeline 0.0.65 → 0.0.71

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.
@@ -3986,10 +3986,10 @@ __export(self_update_exports, {
3986
3986
  });
3987
3987
  import { createHash as createHash6 } from "node:crypto";
3988
3988
  import { constants as fsConstants } from "node:fs";
3989
- import { access, chmod as chmod4, lstat as lstat2, mkdir as mkdir13, open, readFile as readFile9, rename as rename3, rm as rm5, symlink as symlink2, writeFile as writeFile9 } from "node:fs/promises";
3989
+ import { access, chmod as chmod4, lstat as lstat2, mkdir as mkdir14, open, readFile as readFile9, rename as rename3, rm as rm5, symlink as symlink2, writeFile as writeFile10 } from "node:fs/promises";
3990
3990
  import { spawn as spawn4 } from "node:child_process";
3991
3991
  import { homedir as homedir9 } from "node:os";
3992
- import { dirname as dirname9, join as join7, resolve as resolve21 } from "node:path";
3992
+ import { dirname as dirname10, join as join8, resolve as resolve21 } from "node:path";
3993
3993
  function anchorLayout(rawLibDir) {
3994
3994
  const libDir = resolve21(rawLibDir);
3995
3995
  const segments = libDir.split(/[/\\]/);
@@ -4028,7 +4028,7 @@ function discoveredBeelineInstallLayout(env = process.env) {
4028
4028
  return anchorLayout(explicitAnchor);
4029
4029
  const explicitBinDir = env.BEELINE_INSTALL_DIR?.trim();
4030
4030
  if (explicitBinDir)
4031
- return anchorLayout(resolve21(dirname9(resolve21(explicitBinDir)), "lib", "beeline"));
4031
+ return anchorLayout(resolve21(dirname10(resolve21(explicitBinDir)), "lib", "beeline"));
4032
4032
  return defaultBeelineInstallLayout(env);
4033
4033
  }
4034
4034
  function hostPlatformKey() {
@@ -4039,7 +4039,7 @@ function hostPlatformKey() {
4039
4039
  return `${os}-${arch}`;
4040
4040
  }
4041
4041
  function bundleJsonCandidates(bundleDir) {
4042
- return [join7(bundleDir, "lib", "beeline", "bundle.json"), join7(bundleDir, "bundle.json")];
4042
+ return [join8(bundleDir, "lib", "beeline", "bundle.json"), join8(bundleDir, "bundle.json")];
4043
4043
  }
4044
4044
  async function readBundleJson(bundleDir) {
4045
4045
  let raw;
@@ -4063,7 +4063,7 @@ async function readBundleJson(bundleDir) {
4063
4063
  }
4064
4064
  }
4065
4065
  function updateStatePath(layout) {
4066
- return join7(layout.releasesRoot, ".state", "update-state.json");
4066
+ return join8(layout.releasesRoot, ".state", "update-state.json");
4067
4067
  }
4068
4068
  async function readUpdateState(layout) {
4069
4069
  try {
@@ -4073,8 +4073,8 @@ async function readUpdateState(layout) {
4073
4073
  }
4074
4074
  }
4075
4075
  async function writeUpdateState(layout, state) {
4076
- await mkdir13(join7(layout.releasesRoot, ".state"), { recursive: true });
4077
- await writeFile9(updateStatePath(layout), `${JSON.stringify(state, null, 2)}
4076
+ await mkdir14(join8(layout.releasesRoot, ".state"), { recursive: true });
4077
+ await writeFile10(updateStatePath(layout), `${JSON.stringify(state, null, 2)}
4078
4078
  `, "utf8");
4079
4079
  }
4080
4080
  async function readInstalledBundleIdentity(layout, _state = {}) {
@@ -4155,7 +4155,7 @@ function run(command, args, timeoutMs) {
4155
4155
  });
4156
4156
  }
4157
4157
  function entrypointCandidates(bundleDir) {
4158
- return [join7(bundleDir, BUNDLE_ENTRYPOINT), join7(bundleDir, "beeline-cli.mjs")];
4158
+ return [join8(bundleDir, BUNDLE_ENTRYPOINT), join8(bundleDir, "beeline-cli.mjs")];
4159
4159
  }
4160
4160
  async function resolveBundleEntrypoint(bundleDir) {
4161
4161
  for (const candidate of entrypointCandidates(bundleDir)) {
@@ -4177,8 +4177,8 @@ async function stageRelease(layout, manifestUrl, published, opts = {}) {
4177
4177
  const fetchImpl = opts.fetchImpl ?? fetch;
4178
4178
  const log2 = opts.logger ?? ((line) => console.log(`[body] self-update: ${line}`));
4179
4179
  const releaseId = sanitizeReleaseId(published.commit ?? published.version ?? `release-${Date.now()}`);
4180
- const releaseDir = join7(layout.releasesRoot, releaseId);
4181
- const okMarker = join7(releaseDir, ".stage-ok");
4180
+ const releaseDir = join8(layout.releasesRoot, releaseId);
4181
+ const okMarker = join8(releaseDir, ".stage-ok");
4182
4182
  let previouslyVerified = false;
4183
4183
  try {
4184
4184
  const recorded = await readFile9(okMarker, "utf8");
@@ -4187,8 +4187,8 @@ async function stageRelease(layout, manifestUrl, published, opts = {}) {
4187
4187
  previouslyVerified = true;
4188
4188
  } catch {
4189
4189
  }
4190
- await mkdir13(releaseDir, { recursive: true });
4191
- const tempArchive = join7(layout.releasesRoot, `.download-${releaseId}-${process.pid}.tar.gz`);
4190
+ await mkdir14(releaseDir, { recursive: true });
4191
+ const tempArchive = join8(layout.releasesRoot, `.download-${releaseId}-${process.pid}.tar.gz`);
4192
4192
  try {
4193
4193
  log2(`downloading ${published.file}`);
4194
4194
  const response = await fetchImpl(archiveUrlFor(manifestUrl, published.file), {
@@ -4208,7 +4208,7 @@ async function stageRelease(layout, manifestUrl, published, opts = {}) {
4208
4208
  if (actual !== published.sha256.toLowerCase()) {
4209
4209
  throw new Error(`checksum mismatch for ${published.file}: expected ${published.sha256}, got ${actual} \u2014 aborting without touching the installed bundle`);
4210
4210
  }
4211
- await writeFile9(tempArchive, Buffer.concat(chunks), { mode: 384 });
4211
+ await writeFile10(tempArchive, Buffer.concat(chunks), { mode: 384 });
4212
4212
  const entries = (await new Promise((resolveList, rejectList) => {
4213
4213
  const child = spawn4("tar", ["-tzf", tempArchive], { stdio: ["ignore", "pipe", "inherit"] });
4214
4214
  let out = "";
@@ -4228,18 +4228,18 @@ async function stageRelease(layout, manifestUrl, published, opts = {}) {
4228
4228
  throw new Error(`extracting bundle failed: ${extract2.stderr}`);
4229
4229
  for (const relative3 of requiredBundlePaths()) {
4230
4230
  try {
4231
- await access(join7(releaseDir, relative3), fsConstants.F_OK);
4231
+ await access(join8(releaseDir, relative3), fsConstants.F_OK);
4232
4232
  } catch {
4233
4233
  throw new Error(`staged bundle is missing ${relative3}`);
4234
4234
  }
4235
4235
  }
4236
4236
  if (opts.smokeTestCli !== false) {
4237
- const probe = await run(process.execPath, [join7(releaseDir, BUNDLE_ENTRYPOINT), "--version"], 6e4);
4237
+ const probe = await run(process.execPath, [join8(releaseDir, BUNDLE_ENTRYPOINT), "--version"], 6e4);
4238
4238
  if (probe.status !== 0) {
4239
4239
  throw new Error(`staged bundle failed its startup smoke test (--version exited ${probe.status})${probe.stderr ? `: ${probe.stderr.trim()}` : ""}`);
4240
4240
  }
4241
4241
  }
4242
- await writeFile9(okMarker, `${published.sha256}
4242
+ await writeFile10(okMarker, `${published.sha256}
4243
4243
  `, "utf8");
4244
4244
  log2(`staged release ${releaseId} (sha256 verified)`);
4245
4245
  return releaseId;
@@ -4267,26 +4267,26 @@ function forwarderScript(tool) {
4267
4267
  }
4268
4268
  async function replaceFile(path, contents, mode) {
4269
4269
  const temp = `${path}.new-${process.pid}`;
4270
- await writeFile9(temp, contents, { mode });
4270
+ await writeFile10(temp, contents, { mode });
4271
4271
  await chmod4(temp, mode);
4272
4272
  await rename3(temp, path);
4273
4273
  }
4274
4274
  async function activateRelease(layout, releaseId) {
4275
- const releaseDir = join7(layout.releasesRoot, releaseId);
4276
- await access(join7(releaseDir, BUNDLE_ENTRYPOINT), fsConstants.F_OK);
4277
- await mkdir13(layout.releasesRoot, { recursive: true });
4278
- await mkdir13(layout.binDir, { recursive: true });
4275
+ const releaseDir = join8(layout.releasesRoot, releaseId);
4276
+ await access(join8(releaseDir, BUNDLE_ENTRYPOINT), fsConstants.F_OK);
4277
+ await mkdir14(layout.releasesRoot, { recursive: true });
4278
+ await mkdir14(layout.binDir, { recursive: true });
4279
4279
  let previousReleaseId = await activeReleaseId(layout);
4280
4280
  const kind = await pathKind(layout.libDir);
4281
4281
  if (kind === "directory") {
4282
4282
  const legacyIdentity = await readBundleJson(layout.libDir);
4283
4283
  const legacyId = sanitizeReleaseId(legacyIdentity?.commit ?? legacyIdentity?.version ?? `legacy-${Date.now()}`);
4284
- const legacyDir = join7(layout.releasesRoot, legacyId);
4284
+ const legacyDir = join8(layout.releasesRoot, legacyId);
4285
4285
  try {
4286
4286
  await access(legacyDir, fsConstants.F_OK);
4287
4287
  previousReleaseId = `${legacyId}-${Date.now()}`;
4288
- await rename3(layout.libDir, join7(layout.releasesRoot, previousReleaseId));
4289
- await normalizeLegacyBundleShape(join7(layout.releasesRoot, previousReleaseId));
4288
+ await rename3(layout.libDir, join8(layout.releasesRoot, previousReleaseId));
4289
+ await normalizeLegacyBundleShape(join8(layout.releasesRoot, previousReleaseId));
4290
4290
  } catch {
4291
4291
  await rename3(layout.libDir, legacyDir);
4292
4292
  await normalizeLegacyBundleShape(legacyDir);
@@ -4295,18 +4295,18 @@ async function activateRelease(layout, releaseId) {
4295
4295
  }
4296
4296
  const tempLink = `${layout.libDir}.new-${process.pid}`;
4297
4297
  await rm5(tempLink, { force: true });
4298
- await symlink2(join7("beeline-releases", releaseId), tempLink);
4298
+ await symlink2(join8("beeline-releases", releaseId), tempLink);
4299
4299
  await rename3(tempLink, layout.libDir);
4300
- await fsyncDir(dirname9(layout.libDir));
4300
+ await fsyncDir(dirname10(layout.libDir));
4301
4301
  await writeBinForwarders(layout, releaseDir);
4302
4302
  return { previousReleaseId };
4303
4303
  }
4304
4304
  async function normalizeLegacyBundleShape(bundleDir) {
4305
- const innerLib = join7(bundleDir, "lib", "beeline");
4305
+ const innerLib = join8(bundleDir, "lib", "beeline");
4306
4306
  let anyFlat = false;
4307
4307
  for (const name of LEGACY_FLAT_BUNDLE_FILES) {
4308
4308
  try {
4309
- await access(join7(bundleDir, name), fsConstants.F_OK);
4309
+ await access(join8(bundleDir, name), fsConstants.F_OK);
4310
4310
  anyFlat = true;
4311
4311
  break;
4312
4312
  } catch {
@@ -4314,14 +4314,14 @@ async function normalizeLegacyBundleShape(bundleDir) {
4314
4314
  }
4315
4315
  if (!anyFlat)
4316
4316
  return;
4317
- await mkdir13(innerLib, { recursive: true });
4317
+ await mkdir14(innerLib, { recursive: true });
4318
4318
  for (const name of LEGACY_FLAT_BUNDLE_FILES) {
4319
4319
  try {
4320
- await access(join7(innerLib, name), fsConstants.F_OK);
4320
+ await access(join8(innerLib, name), fsConstants.F_OK);
4321
4321
  continue;
4322
4322
  } catch {
4323
4323
  }
4324
- await rename3(join7(bundleDir, name), join7(innerLib, name)).catch(() => void 0);
4324
+ await rename3(join8(bundleDir, name), join8(innerLib, name)).catch(() => void 0);
4325
4325
  }
4326
4326
  }
4327
4327
  async function writeBinForwarders(layout, activeBundleRoot) {
@@ -4330,13 +4330,13 @@ async function writeBinForwarders(layout, activeBundleRoot) {
4330
4330
  ...Object.entries(FORWARDER_ALIASES).map(([alias, tool]) => [alias, tool])
4331
4331
  ];
4332
4332
  for (const [name, tool] of entries) {
4333
- const target = join7(activeBundleRoot, "bin", tool);
4333
+ const target = join8(activeBundleRoot, "bin", tool);
4334
4334
  try {
4335
4335
  await access(target, fsConstants.X_OK);
4336
4336
  } catch {
4337
4337
  continue;
4338
4338
  }
4339
- await replaceFile(join7(layout.binDir, name), forwarderScript(tool), 493);
4339
+ await replaceFile(join8(layout.binDir, name), forwarderScript(tool), 493);
4340
4340
  }
4341
4341
  }
4342
4342
  async function repairInstallForwarders(layout, opts = {}) {
@@ -4345,7 +4345,7 @@ async function repairInstallForwarders(layout, opts = {}) {
4345
4345
  const forwarderHealthy = async (name, tool) => {
4346
4346
  let current;
4347
4347
  try {
4348
- current = await readFile9(join7(layout.binDir, name), "utf8");
4348
+ current = await readFile9(join8(layout.binDir, name), "utf8");
4349
4349
  } catch {
4350
4350
  current = void 0;
4351
4351
  }
@@ -4358,25 +4358,25 @@ async function repairInstallForwarders(layout, opts = {}) {
4358
4358
  }
4359
4359
  if (healthy)
4360
4360
  return false;
4361
- await mkdir13(layout.binDir, { recursive: true });
4361
+ await mkdir14(layout.binDir, { recursive: true });
4362
4362
  await writeBinForwarders(layout, layout.libDir);
4363
4363
  opts.logger?.(`[body] self-update: repaired <prefix>/bin forwarders to follow the active-bundle anchor (${layout.libDir})`);
4364
4364
  return true;
4365
4365
  }
4366
4366
  async function rollbackToPreviousRelease(layout, previousReleaseId) {
4367
- const releaseDir = join7(layout.releasesRoot, previousReleaseId);
4367
+ const releaseDir = join8(layout.releasesRoot, previousReleaseId);
4368
4368
  const entrypoint = await resolveBundleEntrypoint(releaseDir);
4369
4369
  if (!entrypoint) {
4370
4370
  throw new Error(`release ${previousReleaseId} has no runnable CLI entrypoint`);
4371
4371
  }
4372
4372
  const tempLink = `${layout.libDir}.rollback-${process.pid}`;
4373
4373
  await rm5(tempLink, { force: true });
4374
- await symlink2(join7("beeline-releases", previousReleaseId), tempLink);
4374
+ await symlink2(join8("beeline-releases", previousReleaseId), tempLink);
4375
4375
  await rename3(tempLink, layout.libDir);
4376
- await fsyncDir(dirname9(layout.libDir));
4376
+ await fsyncDir(dirname10(layout.libDir));
4377
4377
  }
4378
4378
  function updateAttemptPath(layout) {
4379
- return join7(layout.releasesRoot, ".state", "update-attempt.json");
4379
+ return join8(layout.releasesRoot, ".state", "update-attempt.json");
4380
4380
  }
4381
4381
  async function readUpdateAttempt(layout) {
4382
4382
  try {
@@ -4390,10 +4390,10 @@ async function readUpdateAttempt(layout) {
4390
4390
  }
4391
4391
  }
4392
4392
  async function writeUpdateAttempt(layout, record2) {
4393
- await mkdir13(join7(layout.releasesRoot, ".state"), { recursive: true });
4393
+ await mkdir14(join8(layout.releasesRoot, ".state"), { recursive: true });
4394
4394
  const path = updateAttemptPath(layout);
4395
4395
  const staged = `${path}.${process.pid}.tmp`;
4396
- await writeFile9(staged, `${JSON.stringify(record2, null, 2)}
4396
+ await writeFile10(staged, `${JSON.stringify(record2, null, 2)}
4397
4397
  `, { mode: 384 });
4398
4398
  await rename3(staged, path);
4399
4399
  }
@@ -4655,8 +4655,8 @@ var init_self_update = __esm({
4655
4655
  });
4656
4656
 
4657
4657
  // apps/body/dist/cli.js
4658
- import { dirname as dirname15, resolve as resolve29 } from "node:path";
4659
- import { readFile as readFile14, unlink as unlink5, writeFile as writeFile15 } from "node:fs/promises";
4658
+ import { dirname as dirname16, resolve as resolve29 } from "node:path";
4659
+ import { readFile as readFile14, unlink as unlink5, writeFile as writeFile16 } from "node:fs/promises";
4660
4660
  import { stdin as stdin4, stdout as stdout5 } from "node:process";
4661
4661
 
4662
4662
  // node_modules/@clack/core/dist/index.mjs
@@ -6663,20 +6663,6 @@ var ACCESS_NOTICE_WINDOW_MS = 10 * 6e4;
6663
6663
  var DEFAULT_ACCESS_POLICY = DEFAULT_AGENT_ACCESS_POLICY;
6664
6664
  var LEGACY_ACCESS_POLICY = "everyone";
6665
6665
  var ACCESS_REFUSAL_WINDOW_MS = 60 * 60 * 1e3;
6666
- function isSenderPermitted(policy, senderPubkey, ownerPubkey, allowlist = void 0) {
6667
- if (!senderPubkey)
6668
- return false;
6669
- switch (policy) {
6670
- case "everyone":
6671
- return true;
6672
- case "creator":
6673
- return Boolean(ownerPubkey) && senderPubkey === ownerPubkey;
6674
- case "allowlist":
6675
- return Boolean(allowlist?.includes(senderPubkey));
6676
- default:
6677
- return false;
6678
- }
6679
- }
6680
6666
 
6681
6667
  // apps/body/dist/model-catalog.js
6682
6668
  import { mkdtemp, rm } from "node:fs/promises";
@@ -8129,6 +8115,40 @@ async function syncAgentModelCatalog(input) {
8129
8115
  }
8130
8116
  }
8131
8117
 
8118
+ // packages/api-contract/dist/daemon-operations.js
8119
+ function isAgentCommand(value) {
8120
+ if (!value || typeof value !== "object")
8121
+ return false;
8122
+ const c2 = value;
8123
+ if (![
8124
+ "id",
8125
+ "roomId",
8126
+ "agentId",
8127
+ "sourceMessageId",
8128
+ "turnRequestId",
8129
+ "rootCommandId",
8130
+ "rootSourceMessageId",
8131
+ "reason"
8132
+ ].every((key) => typeof c2[key] === "string" && c2[key].length > 0))
8133
+ return false;
8134
+ if (!["input", "resume", "stop"].includes(String(c2.action)) || !Number.isInteger(c2.agentDepth) || Number(c2.agentDepth) < 0 || Number(c2.agentDepth) > 3)
8135
+ return false;
8136
+ const source = c2.source;
8137
+ return Boolean(source && typeof source.id === "string" && typeof source.authorId === "string" && typeof source.body === "string" && typeof source.createdAt === "number" && Array.isArray(source.attachments) && Array.isArray(source.mentionIds));
8138
+ }
8139
+
8140
+ // packages/api-contract/dist/system-events.js
8141
+ var SERVER_EVENT_KINDS = [
8142
+ "joined",
8143
+ "schedule-ran",
8144
+ "corner-opened",
8145
+ "check-passed",
8146
+ "check-failed",
8147
+ "merged",
8148
+ "grant-decided",
8149
+ "turn-cancelled"
8150
+ ];
8151
+
8132
8152
  // apps/body/dist/daemon-api-client.js
8133
8153
  import { resolve as resolve7 } from "node:path";
8134
8154
  import { randomUUID } from "node:crypto";
@@ -16910,32 +16930,6 @@ var DaemonApiError = class extends Error {
16910
16930
  }
16911
16931
  };
16912
16932
  var AGENT_REMOVED_CODE = "agent_removed";
16913
- function laterInboxCursor(left, right) {
16914
- if (!left)
16915
- return right;
16916
- if (!right)
16917
- return left;
16918
- const leftMatch = left.match(/^(\d+),([0-9a-f]{64})$/);
16919
- const rightMatch = right.match(/^(\d+),([0-9a-f]{64})$/);
16920
- if (!leftMatch || !rightMatch)
16921
- return right;
16922
- const timeOrder = BigInt(leftMatch[1]) - BigInt(rightMatch[1]);
16923
- if (timeOrder !== 0n)
16924
- return timeOrder > 0n ? left : right;
16925
- return leftMatch[2] >= rightMatch[2] ? left : right;
16926
- }
16927
- function orderInboxItems(items) {
16928
- return [...items].sort((left, right) => {
16929
- const leftMatch = left.cursor?.match(/^(\d+),([0-9a-f]{64})$/);
16930
- const rightMatch = right.cursor?.match(/^(\d+),([0-9a-f]{64})$/);
16931
- if (!leftMatch || !rightMatch)
16932
- return 0;
16933
- const timeOrder = BigInt(leftMatch[1]) - BigInt(rightMatch[1]);
16934
- if (timeOrder !== 0n)
16935
- return timeOrder < 0n ? -1 : 1;
16936
- return leftMatch[2] < rightMatch[2] ? -1 : leftMatch[2] > rightMatch[2] ? 1 : 0;
16937
- });
16938
- }
16939
16933
  function isAgentRemovedError(error) {
16940
16934
  return error instanceof DaemonApiError && error.status === 403 && error.code === AGENT_REMOVED_CODE;
16941
16935
  }
@@ -16975,20 +16969,23 @@ var DaemonApiClient = class {
16975
16969
  return { baseUrl: this.baseUrl, daemonToken: this.daemonToken, agentId: this.agentId };
16976
16970
  }
16977
16971
  /** Add one Room to this agent's shared live socket. */
16978
- liveSubscribe(roomId, cursor3, onItems, onState, presence) {
16972
+ liveSubscribe(roomId, cursor3, onItems, onState, presence, onCommands) {
16979
16973
  const existing = this.liveRooms.get(roomId);
16980
16974
  if (existing) {
16981
16975
  existing.cursor = cursor3 ?? existing.cursor;
16982
16976
  existing.onItems = onItems ?? existing.onItems;
16983
16977
  existing.onState = onState ?? existing.onState;
16984
16978
  existing.presence = presence ?? existing.presence;
16979
+ existing.onCommands = onCommands ?? existing.onCommands;
16985
16980
  } else {
16986
16981
  this.liveRooms.set(roomId, {
16987
16982
  ...cursor3 ? { cursor: cursor3 } : {},
16988
16983
  pushedIds: /* @__PURE__ */ new Set(),
16984
+ pushedCommandIds: /* @__PURE__ */ new Set(),
16989
16985
  ...onItems ? { onItems } : {},
16990
16986
  ...onState ? { onState } : {},
16991
- ...presence ? { presence } : {}
16987
+ ...presence ? { presence } : {},
16988
+ ...onCommands ? { onCommands } : {}
16992
16989
  });
16993
16990
  }
16994
16991
  this.ensureLiveSocket();
@@ -17058,6 +17055,22 @@ var DaemonApiClient = class {
17058
17055
  });
17059
17056
  return;
17060
17057
  }
17058
+ if (event.type === "commands" && typeof event.roomId === "string" && event.commandProtocol === 1 && Array.isArray(event.commands)) {
17059
+ const room2 = this.liveRooms.get(event.roomId);
17060
+ if (!room2)
17061
+ return;
17062
+ const commands = event.commands.filter((command) => {
17063
+ if (!isAgentCommand(command) || command.roomId !== event.roomId || command.agentId !== this.agentId || room2.pushedCommandIds.has(command.id))
17064
+ return false;
17065
+ room2.pushedCommandIds.add(command.id);
17066
+ return true;
17067
+ });
17068
+ while (room2.pushedCommandIds.size > 1e4)
17069
+ room2.pushedCommandIds.delete(room2.pushedCommandIds.values().next().value);
17070
+ if (commands.length)
17071
+ room2.onCommands?.(commands);
17072
+ return;
17073
+ }
17061
17074
  if (event.type !== "inbox" || typeof event.roomId !== "string" || !Array.isArray(event.items))
17062
17075
  return;
17063
17076
  const room = this.liveRooms.get(event.roomId);
@@ -17153,8 +17166,8 @@ async function activateDaemonTransport(path, fetchImpl = fetch) {
17153
17166
  import { execFile as execFile5 } from "node:child_process";
17154
17167
  import { createHash as createHash5 } from "node:crypto";
17155
17168
  import { existsSync as existsSync4, mkdirSync } from "node:fs";
17156
- import { mkdir as mkdir11, rm as rm4 } from "node:fs/promises";
17157
- import { dirname as dirname6, resolve as resolve19 } from "node:path";
17169
+ import { mkdir as mkdir12, rm as rm4 } from "node:fs/promises";
17170
+ import { dirname as dirname7, resolve as resolve19 } from "node:path";
17158
17171
  import { promisify as promisify4 } from "node:util";
17159
17172
 
17160
17173
  // apps/body/dist/grant-runner.js
@@ -17207,18 +17220,6 @@ function commandGrantMatches(rule, requested) {
17207
17220
  return rule.argv.every((word, index) => requested[index] === word);
17208
17221
  }
17209
17222
  var DECISION_LINE = new RegExp(`^(.+?) (approved once|approved|declined) (${AGENT_GRANT_KINDS.join("|")}) (.+)$`, "s");
17210
- function parseGrantDecisionLine(body) {
17211
- const match = DECISION_LINE.exec(body);
17212
- if (!match)
17213
- return void 0;
17214
- const decision2 = match[2] === "approved once" ? "once" : match[2] === "approved" ? "always" : "deny";
17215
- return {
17216
- deciderName: match[1],
17217
- decision: decision2,
17218
- kind: match[3],
17219
- target: match[4]
17220
- };
17221
- }
17222
17223
  var AGENT_GRANT_ESCALATION_REASONS = {
17223
17224
  "unseen-script": "it runs a script whose contents nobody has read",
17224
17225
  credential: "it names a credential or environment file"
@@ -17798,7 +17799,9 @@ var GrantCommandRunner = class {
17798
17799
  if (!room)
17799
17800
  throw new Error("this daemon is not serving that Room");
17800
17801
  const argv = validateGrantArgv(input.argv);
17801
- const live = await this.options.api.execute("listAgentGrants", { agentId: this.options.agentId });
17802
+ const live = await this.options.api.execute("listAgentGrants", {
17803
+ agentId: this.options.agentId
17804
+ });
17802
17805
  const match = matchCommandGrant(live.grants, room.workspaceId, argv);
17803
17806
  if (!match) {
17804
17807
  throw new Error(`no approved command grant matches: ${argv.join(" ")}. Ask with request_grant kind=command first.`);
@@ -17861,6 +17864,7 @@ ${ROOM_WRITE_REFUSED_NOTE}` : outcome.output, secrets), cap);
17861
17864
  agentId: this.options.agentId,
17862
17865
  roomId: input.roomId,
17863
17866
  requestId: turn?.requestId ?? `grant:${grant.grantId}`,
17867
+ generationId: turn?.generationId,
17864
17868
  activity: [
17865
17869
  {
17866
17870
  kind: "tool",
@@ -17915,7 +17919,10 @@ function scriptCandidates(cwd, scratch, argv) {
17915
17919
  const argument = interpreterScriptArgument(argv);
17916
17920
  if (!argument)
17917
17921
  return [];
17918
- const paths = [resolve10(cwd, argument.path), ...scratch ? [resolve10(scratch, argument.path)] : []];
17922
+ const paths = [
17923
+ resolve10(cwd, argument.path),
17924
+ ...scratch ? [resolve10(scratch, argument.path)] : []
17925
+ ];
17919
17926
  return [...new Set(paths)];
17920
17927
  }
17921
17928
  function roomSandboxCommand(policy, cwd, argv) {
@@ -17994,128 +18001,168 @@ var GrantRunnerServer = class {
17994
18001
  }
17995
18002
  };
17996
18003
 
18004
+ // apps/body/dist/server-command-intake.js
18005
+ import { randomUUID as randomUUID2 } from "node:crypto";
18006
+ import { mkdir as mkdir3, writeFile as writeFile4 } from "node:fs/promises";
18007
+ import { tmpdir as tmpdir2 } from "node:os";
18008
+ import { dirname as dirname5, join as join3 } from "node:path";
18009
+ var CommandExecutionContext = class {
18010
+ generationId = randomUUID2();
18011
+ path;
18012
+ current;
18013
+ constructor(root) {
18014
+ this.path = join3(root ?? tmpdir2(), `beeline-command-${this.generationId}.json`);
18015
+ }
18016
+ async enter(command) {
18017
+ this.current = command;
18018
+ await mkdir3(dirname5(this.path), { recursive: true });
18019
+ await writeFile4(this.path, JSON.stringify({
18020
+ roomId: command.roomId,
18021
+ requestId: command.turnRequestId,
18022
+ generationId: this.generationId
18023
+ }), { mode: 384 });
18024
+ }
18025
+ async leave() {
18026
+ this.current = void 0;
18027
+ await writeFile4(this.path, "{}", { mode: 384 });
18028
+ }
18029
+ bind(api) {
18030
+ return new Proxy(api, {
18031
+ get: (target, key) => {
18032
+ if (key === "execute")
18033
+ return (name, input) => {
18034
+ const turn = this.current;
18035
+ return target.execute(name, {
18036
+ ...input,
18037
+ ...turn && (input.roomId === turn.roomId || input.cornerId === turn.roomId) ? {
18038
+ generationId: this.generationId,
18039
+ requestId: input.requestId ?? input.turnId ?? turn.turnRequestId
18040
+ } : {}
18041
+ });
18042
+ };
18043
+ const value = Reflect.get(target, key);
18044
+ return typeof value === "function" ? value.bind(target) : value;
18045
+ }
18046
+ });
18047
+ }
18048
+ };
18049
+ function validateServerCommand(command, roomId, agentId) {
18050
+ if (!isAgentCommand(command) || command.roomId !== roomId || command.agentId !== agentId)
18051
+ throw new Error("invalid server command");
18052
+ }
18053
+ async function runServerCommandIntake(options) {
18054
+ const { api, roomId, agentId, context, signal } = options;
18055
+ const first = await api.execute("getAgentCommands", { roomId });
18056
+ if (first?.commandProtocol !== 1)
18057
+ throw new Error("server command protocol 1 is required; refusing intake");
18058
+ let busy;
18059
+ let wake;
18060
+ let pushIntakeAcknowledged = false;
18061
+ const pending = new Map(first.commands.map((command) => [command.id, command]));
18062
+ const claimed = /* @__PURE__ */ new Set();
18063
+ const notify2 = (commands = []) => {
18064
+ for (const command of commands)
18065
+ if (!claimed.has(command.id))
18066
+ pending.set(command.id, command);
18067
+ wake?.(false);
18068
+ };
18069
+ options.onWake?.(notify2);
18070
+ const off = api.liveSubscribe?.(roomId, void 0, void 0, (connected, capabilities) => {
18071
+ const acknowledged = connected && capabilities?.pushIntake === true;
18072
+ if (pushIntakeAcknowledged !== acknowledged) {
18073
+ pushIntakeAcknowledged = acknowledged;
18074
+ wake?.(!connected);
18075
+ } else if (!connected) {
18076
+ wake?.(true);
18077
+ }
18078
+ }, options.presence, notify2);
18079
+ try {
18080
+ while (!signal?.aborted) {
18081
+ if (options.closed && await options.closed())
18082
+ return;
18083
+ for (const command of [...pending.values()]) {
18084
+ validateServerCommand(command, roomId, agentId);
18085
+ if (busy && command.action !== "stop")
18086
+ continue;
18087
+ pending.delete(command.id);
18088
+ try {
18089
+ await api.execute("claimAgentCommand", {
18090
+ roomId,
18091
+ commandId: command.id,
18092
+ generationId: context.generationId
18093
+ });
18094
+ } catch (error) {
18095
+ options.onError?.(error);
18096
+ continue;
18097
+ }
18098
+ claimed.add(command.id);
18099
+ if (command.action === "stop") {
18100
+ options.stop(command.turnRequestId);
18101
+ await api.execute("acknowledgeAgentCommand", {
18102
+ roomId,
18103
+ commandId: command.id,
18104
+ generationId: context.generationId
18105
+ });
18106
+ } else {
18107
+ await context.enter(command);
18108
+ busy = options.run(command).catch((error) => {
18109
+ claimed.delete(command.id);
18110
+ options.onError?.(error);
18111
+ }).finally(async () => {
18112
+ await context.leave();
18113
+ busy = void 0;
18114
+ notify2();
18115
+ });
18116
+ }
18117
+ }
18118
+ options.onPoll?.();
18119
+ const reconcile = await new Promise((resolve30) => {
18120
+ const done = (needed) => {
18121
+ if (timer)
18122
+ clearTimeout(timer);
18123
+ signal?.removeEventListener("abort", aborted);
18124
+ wake = void 0;
18125
+ resolve30(needed);
18126
+ };
18127
+ const aborted = () => done(false);
18128
+ wake = done;
18129
+ const timer = setTimeout(() => done(true), pushIntakeAcknowledged ? 6e4 : options.pollMs ?? 1e3);
18130
+ signal?.addEventListener("abort", aborted, { once: true });
18131
+ if (pending.size && !busy)
18132
+ done(false);
18133
+ });
18134
+ if (signal?.aborted)
18135
+ break;
18136
+ if (reconcile) {
18137
+ const page = await api.execute("getAgentCommands", { roomId });
18138
+ if (page.commandProtocol !== 1)
18139
+ throw new Error("server command protocol changed; refusing intake");
18140
+ notify2(page.commands);
18141
+ }
18142
+ }
18143
+ } finally {
18144
+ off?.();
18145
+ options.onWake?.(void 0);
18146
+ if (context.current)
18147
+ options.stop(context.current.turnRequestId);
18148
+ await busy;
18149
+ }
18150
+ }
18151
+
17997
18152
  // apps/body/dist/monolith-corner-turn.js
17998
18153
  import { execFile as execFile4 } from "node:child_process";
17999
18154
  import { createHash as createHash4 } from "node:crypto";
18000
- import { mkdir as mkdir10 } from "node:fs/promises";
18155
+ import { mkdir as mkdir11 } from "node:fs/promises";
18001
18156
  import { homedir as homedir7 } from "node:os";
18002
- import { join as join6 } from "node:path";
18157
+ import { join as join7 } from "node:path";
18003
18158
  import { promisify as promisify3 } from "node:util";
18004
18159
 
18005
- // packages/api-contract/dist/daemon-operations.js
18006
- var AGENT_TO_AGENT_HOP_CAP = 3;
18007
-
18008
- // packages/api-contract/dist/system-events.js
18009
- var SERVER_EVENT_KINDS = [
18010
- "joined",
18011
- "schedule-ran",
18012
- "corner-opened",
18013
- "check-passed",
18014
- "check-failed",
18015
- "merged",
18016
- "grant-decided",
18017
- "turn-cancelled"
18018
- ];
18019
- function isServerEventKind(value) {
18020
- return SERVER_EVENT_KINDS.includes(value);
18021
- }
18022
- var RESUME_KINDS = ["grant-decided"];
18023
- function isResumeKind(value) {
18024
- return RESUME_KINDS.includes(value);
18025
- }
18026
- var CONTROL_KINDS = ["turn-cancelled"];
18027
- function isControlKind(value) {
18028
- return CONTROL_KINDS.includes(value);
18029
- }
18030
-
18031
- // apps/body/dist/agent-response-rule.js
18032
- var INBOX_DEDUPLICATION_LIMIT = 1e4;
18033
- var CONTINUITY_WINDOW_LIMIT = 200;
18034
- var AgentResponseRule = class {
18035
- agentIds = /* @__PURE__ */ new Set();
18036
- lastAgentBySender = /* @__PURE__ */ new Map();
18037
- observedIds = /* @__PURE__ */ new Set();
18038
- recentMessages = [];
18039
- localReplySequence = 0;
18040
- setAgents(agentIds) {
18041
- this.agentIds = new Set(agentIds);
18042
- this.rebuildLastAgentBySender();
18043
- }
18044
- observeAll(items) {
18045
- for (const item of items)
18046
- this.observe(item);
18047
- }
18048
- replaceHistory(items) {
18049
- this.recentMessages.length = 0;
18050
- this.lastAgentBySender.clear();
18051
- for (const item of items)
18052
- this.record(item);
18053
- }
18054
- observe(item) {
18055
- if (this.observedIds.has(item.id))
18056
- return;
18057
- this.observedIds.add(item.id);
18058
- while (this.observedIds.size > INBOX_DEDUPLICATION_LIMIT)
18059
- this.observedIds.delete(this.observedIds.values().next().value);
18060
- this.record(item);
18061
- }
18062
- record(item) {
18063
- if (item.type !== "message")
18064
- return;
18065
- this.recentMessages.push(item);
18066
- while (this.recentMessages.length > CONTINUITY_WINDOW_LIMIT)
18067
- this.recentMessages.shift();
18068
- this.rebuildLastAgentBySender();
18069
- }
18070
- rebuildLastAgentBySender() {
18071
- this.lastAgentBySender.clear();
18072
- for (const recent of this.recentMessages) {
18073
- if (!recent.agentAuthor && !this.agentIds.has(recent.authorId))
18074
- continue;
18075
- const addressed = new Set(recent.mentionIds);
18076
- if (recent.requestAuthorId)
18077
- addressed.add(recent.requestAuthorId);
18078
- if (recent.replyToAuthorId)
18079
- addressed.add(recent.replyToAuthorId);
18080
- for (const senderId of addressed) {
18081
- if (senderId !== recent.authorId)
18082
- this.lastAgentBySender.set(senderId, recent.authorId);
18083
- }
18084
- }
18085
- }
18086
- noteReply(agentId, senderIds) {
18087
- this.record({
18088
- id: `local-reply-${agentId}-${this.localReplySequence++}`,
18089
- authorId: agentId,
18090
- type: "message",
18091
- mentionIds: [...senderIds],
18092
- agentAuthor: true
18093
- });
18094
- }
18095
- /** Whether trigger 2 applies. Explicit mention handling stays with each intake loop. */
18096
- continues(item, agentId) {
18097
- if (item.type !== "message" || item.authorId === agentId)
18098
- return false;
18099
- if (!this.agentIds.has(agentId))
18100
- return false;
18101
- if ((item.agentAuthor || this.agentIds.has(item.authorId)) && (item.agentHopCount ?? 0) >= AGENT_TO_AGENT_HOP_CAP)
18102
- return false;
18103
- if (item.agentMentionIds?.length || item.mentionIds.some((mentioned) => this.agentIds.has(mentioned)))
18104
- return false;
18105
- if (item.replyToMessageId)
18106
- return item.replyToAuthorId === agentId;
18107
- if (this.lastAgentBySender.get(item.authorId) !== agentId)
18108
- return false;
18109
- return true;
18110
- }
18111
- };
18112
-
18113
18160
  // apps/body/dist/agent-home.js
18114
18161
  import { existsSync as existsSync3, readFileSync as readFileSync4 } from "node:fs";
18115
- import { createHash as createHash3, randomUUID as randomUUID2 } from "node:crypto";
18116
- import { chmod as chmod2, copyFile, lstat, mkdir as mkdir4, readFile as readFile6, readdir as readdir2, realpath, rename as rename2, rm as rm2, symlink, unlink, writeFile as writeFile5 } from "node:fs/promises";
18162
+ import { createHash as createHash3, randomUUID as randomUUID3 } from "node:crypto";
18163
+ import { chmod as chmod2, copyFile, lstat, mkdir as mkdir5, readFile as readFile6, readdir as readdir2, realpath, rename as rename2, rm as rm2, symlink, unlink, writeFile as writeFile6 } from "node:fs/promises";
18117
18164
  import { homedir as homedir5 } from "node:os";
18118
- import { basename as basename3, dirname as dirname5, join as join3, relative as relative2, resolve as resolve13, sep } from "node:path";
18165
+ import { basename as basename3, dirname as dirname6, join as join4, relative as relative2, resolve as resolve13, sep } from "node:path";
18119
18166
 
18120
18167
  // apps/body/dist/beeline-skill.js
18121
18168
  import { readFileSync as readFileSync3 } from "node:fs";
@@ -18218,7 +18265,7 @@ var SQUIRE_GOVERNED_TOOLS = [
18218
18265
  var SQUIRE_GOVERNED_TOOL_SET = new Set(SQUIRE_GOVERNED_TOOLS);
18219
18266
 
18220
18267
  // apps/body/dist/openrouter-routing.js
18221
- import { mkdir as mkdir3, readFile as readFile5, writeFile as writeFile4 } from "node:fs/promises";
18268
+ import { mkdir as mkdir4, readFile as readFile5, writeFile as writeFile5 } from "node:fs/promises";
18222
18269
  import { resolve as resolve12 } from "node:path";
18223
18270
  var OPENROUTER_ENDPOINTS_BASE_URL = "https://openrouter.ai/api/v1/models";
18224
18271
  var OPENROUTER_COMPLETIONS_URL = "https://openrouter.ai/api/v1/chat/completions";
@@ -18348,8 +18395,8 @@ async function readCache(cacheDir, model) {
18348
18395
  }
18349
18396
  }
18350
18397
  async function writeCache(cacheDir, value) {
18351
- await mkdir3(cacheDir, { recursive: true, mode: 448 });
18352
- await writeFile4(cachePath(cacheDir, value.model), `${JSON.stringify(value, null, 2)}
18398
+ await mkdir4(cacheDir, { recursive: true, mode: 448 });
18399
+ await writeFile5(cachePath(cacheDir, value.model), `${JSON.stringify(value, null, 2)}
18353
18400
  `, {
18354
18401
  mode: 384
18355
18402
  });
@@ -18383,8 +18430,8 @@ async function readProbeCache(cacheDir, model) {
18383
18430
  }
18384
18431
  }
18385
18432
  async function writeProbeCache(cacheDir, value) {
18386
- await mkdir3(cacheDir, { recursive: true, mode: 448 });
18387
- await writeFile4(probeCachePath(cacheDir, value.model), `${JSON.stringify(value, null, 2)}
18433
+ await mkdir4(cacheDir, { recursive: true, mode: 448 });
18434
+ await writeFile5(probeCachePath(cacheDir, value.model), `${JSON.stringify(value, null, 2)}
18388
18435
  `, {
18389
18436
  mode: 384
18390
18437
  });
@@ -18840,14 +18887,14 @@ async function prepareRoomAgentHome(input) {
18840
18887
  const root = resolve13(input.root);
18841
18888
  const operatorHome = input.operatorHome ?? homedir5();
18842
18889
  try {
18843
- await mkdir4(root, { recursive: true, mode: 448 });
18890
+ await mkdir5(root, { recursive: true, mode: 448 });
18844
18891
  const rootStats = await lstat(root);
18845
18892
  if (!rootStats.isDirectory() || rootStats.isSymbolicLink()) {
18846
18893
  throw new AgentHomeSecurityError(`agent home root is not an ordinary directory: ${root}`);
18847
18894
  }
18848
18895
  for (const subdir of HOME_SUBDIRS) {
18849
18896
  const path = resolve13(root, subdir);
18850
- await mkdir4(path, { recursive: true, mode: 448 });
18897
+ await mkdir5(path, { recursive: true, mode: 448 });
18851
18898
  await assertRealContainedDirectory(path, root);
18852
18899
  }
18853
18900
  } catch (error) {
@@ -18899,7 +18946,7 @@ async function provisionAgentSkillsAndMcp(root, operatorHome, skillReleaseId, fa
18899
18946
  }
18900
18947
  try {
18901
18948
  const gooseConfigDir = resolve13(root, "goose", "config");
18902
- await mkdir4(gooseConfigDir, { recursive: true, mode: 448 });
18949
+ await mkdir5(gooseConfigDir, { recursive: true, mode: 448 });
18903
18950
  for (const name of GOOSE_SHARED_CONFIG_FILES) {
18904
18951
  const source = resolve13(operatorHome, ".config", "goose", name);
18905
18952
  const target = resolve13(gooseConfigDir, name);
@@ -19011,18 +19058,18 @@ function filteredHarnessMcpToml(source) {
19011
19058
  return extractTomlSections(source, ["mcp_servers"], excluded);
19012
19059
  }
19013
19060
  async function provisionManagedSkillsDir(target, managedSkills, sharedSkills, optionalShares) {
19014
- const parent = dirname5(target);
19015
- await assertRealContainedDirectory(parent, dirname5(parent));
19061
+ const parent = dirname6(target);
19062
+ await assertRealContainedDirectory(parent, dirname6(parent));
19016
19063
  const plan = await planManagedSkills(managedSkills, sharedSkills, optionalShares);
19017
19064
  if (await materializedSkillManifest(target) === plan.manifest)
19018
19065
  return;
19019
- const staged = resolve13(parent, `.skills.${process.pid}.${randomUUID2()}.tmp`);
19020
- await mkdir4(staged, { mode: 448 });
19066
+ const staged = resolve13(parent, `.skills.${process.pid}.${randomUUID3()}.tmp`);
19067
+ await mkdir5(staged, { mode: 448 });
19021
19068
  try {
19022
19069
  for (const entry of plan.entries) {
19023
19070
  if (entry.kind === "managed") {
19024
19071
  const skillDir = resolve13(staged, entry.name);
19025
- await mkdir4(skillDir, { recursive: true });
19072
+ await mkdir5(skillDir, { recursive: true });
19026
19073
  await writeIsolatedHarnessFile(resolve13(skillDir, "SKILL.md"), entry.content);
19027
19074
  } else {
19028
19075
  await copySafeSkillTree(entry.source, resolve13(staged, entry.name), entry.source);
@@ -19052,8 +19099,8 @@ async function planManagedSkills(managedSkills, sharedSkills, optionalShares) {
19052
19099
  try {
19053
19100
  const tree = [];
19054
19101
  await walkSafeSkillTree(shared.source, shared.source, {
19055
- directory: async (rel) => void tree.push(`d ${join3(shared.name, rel)}`),
19056
- file: async (rel, realPath) => void tree.push(`f ${join3(shared.name, rel)} ${sha2563(await readFile6(realPath))}`)
19102
+ directory: async (rel) => void tree.push(`d ${join4(shared.name, rel)}`),
19103
+ file: async (rel, realPath) => void tree.push(`f ${join4(shared.name, rel)} ${sha2563(await readFile6(realPath))}`)
19057
19104
  });
19058
19105
  entries.push({ kind: "shared", name: shared.name, source: shared.source });
19059
19106
  lines.push(...tree);
@@ -19073,7 +19120,7 @@ async function materializedSkillManifest(target) {
19073
19120
  const visit = async (directory, prefix) => {
19074
19121
  for (const entry of await readdir2(directory)) {
19075
19122
  const path = resolve13(directory, entry);
19076
- const rel = prefix ? join3(prefix, entry) : entry;
19123
+ const rel = prefix ? join4(prefix, entry) : entry;
19077
19124
  const entryStats = await lstat(path);
19078
19125
  if (entryStats.isSymbolicLink())
19079
19126
  return false;
@@ -19241,7 +19288,7 @@ async function walkSafeSkillTree(source, sourceRoot, visitor, rel = "") {
19241
19288
  for (const entry of await readdir2(resolvedSource)) {
19242
19289
  if (entry === "." || entry === "..")
19243
19290
  throw new Error("invalid shared skill entry");
19244
- await walkSafeSkillTree(resolve13(source, entry), sourceRoot, visitor, rel ? join3(rel, entry) : entry);
19291
+ await walkSafeSkillTree(resolve13(source, entry), sourceRoot, visitor, rel ? join4(rel, entry) : entry);
19245
19292
  }
19246
19293
  return;
19247
19294
  }
@@ -19253,7 +19300,7 @@ async function walkSafeSkillTree(source, sourceRoot, visitor, rel = "") {
19253
19300
  async function copySafeSkillTree(source, target, sourceRoot) {
19254
19301
  await walkSafeSkillTree(source, sourceRoot, {
19255
19302
  directory: async (rel) => {
19256
- await mkdir4(resolve13(target, rel), { mode: 448 });
19303
+ await mkdir5(resolve13(target, rel), { mode: 448 });
19257
19304
  },
19258
19305
  file: async (rel, realPath) => {
19259
19306
  const destination = resolve13(target, rel);
@@ -19263,14 +19310,14 @@ async function copySafeSkillTree(source, target, sourceRoot) {
19263
19310
  });
19264
19311
  }
19265
19312
  async function writeIsolatedHarnessFile(path, content) {
19266
- const parent = dirname5(path);
19313
+ const parent = dirname6(path);
19267
19314
  const parentStats = await lstat(parent);
19268
19315
  if (!parentStats.isDirectory() || parentStats.isSymbolicLink()) {
19269
19316
  throw new Error(`isolated harness parent is not a real directory: ${parent}`);
19270
19317
  }
19271
- const temporary = resolve13(parent, `.${basename3(path)}.${process.pid}.${randomUUID2()}.tmp`);
19318
+ const temporary = resolve13(parent, `.${basename3(path)}.${process.pid}.${randomUUID3()}.tmp`);
19272
19319
  try {
19273
- await writeFile5(temporary, content, { mode: 384, flag: "wx" });
19320
+ await writeFile6(temporary, content, { mode: 384, flag: "wx" });
19274
19321
  await chmod2(temporary, 384);
19275
19322
  await rename2(temporary, path);
19276
19323
  } finally {
@@ -19313,8 +19360,8 @@ function harnessStateDirsFromEnv(env) {
19313
19360
  }
19314
19361
 
19315
19362
  // apps/body/dist/attachment-delivery.js
19316
- import { mkdir as mkdir5, writeFile as writeFile6 } from "node:fs/promises";
19317
- import { basename as basename4, extname, join as join4 } from "node:path";
19363
+ import { mkdir as mkdir6, writeFile as writeFile7 } from "node:fs/promises";
19364
+ import { basename as basename4, extname, join as join5 } from "node:path";
19318
19365
  var MAX_ATTACHMENT_BYTES = 25 * 1024 * 1024;
19319
19366
  var MEDIA_TTL_HOURS = 24;
19320
19367
  var EXPIRED_REASON = `expired: attachments are kept for ${MEDIA_TTL_HOURS} hours and these bytes are past that window`;
@@ -19334,7 +19381,7 @@ async function deliverAttachments(attachments, dir, fetchImpl = fetch) {
19334
19381
  if (!attachments.length)
19335
19382
  return [];
19336
19383
  const taken = /* @__PURE__ */ new Set();
19337
- await mkdir5(dir, { recursive: true });
19384
+ await mkdir6(dir, { recursive: true });
19338
19385
  return Promise.all(attachments.map(async (attachment, index) => {
19339
19386
  const tooLarge = (bytes) => ({
19340
19387
  attachment,
@@ -19358,8 +19405,8 @@ async function deliverAttachments(attachments, dir, fetchImpl = fetch) {
19358
19405
  const bytes = Buffer.from(await response.arrayBuffer());
19359
19406
  if (bytes.length > MAX_ATTACHMENT_BYTES)
19360
19407
  return tooLarge(bytes.length);
19361
- const path = join4(dir, safeFileName(attachment, index, taken));
19362
- await writeFile6(path, bytes);
19408
+ const path = join5(dir, safeFileName(attachment, index, taken));
19409
+ await writeFile7(path, bytes);
19363
19410
  const mimeType = attachment.mimeType ?? response.headers.get("content-type") ?? "";
19364
19411
  if (!mimeType.startsWith("image/"))
19365
19412
  return { attachment, path };
@@ -19545,13 +19592,6 @@ function isCornerStatusRestatement(reply, systemLines) {
19545
19592
  var TurnStoppedError = class extends Error {
19546
19593
  name = "TurnStoppedError";
19547
19594
  };
19548
- function turnStopRequestId(item, agentId) {
19549
- if (item.type !== "system" || !item.mentionIds.includes(agentId))
19550
- return void 0;
19551
- if (item.systemEvent?.kind !== "turn-cancelled")
19552
- return void 0;
19553
- return item.requestId || void 0;
19554
- }
19555
19595
 
19556
19596
  // apps/body/dist/turn-stream.js
19557
19597
  function durableReplyText(agentText) {
@@ -19724,7 +19764,7 @@ function sessionConfigFingerprint(input) {
19724
19764
  }
19725
19765
 
19726
19766
  // apps/body/dist/pi-mcp-bridge.js
19727
- import { mkdir as mkdir6 } from "node:fs/promises";
19767
+ import { mkdir as mkdir7 } from "node:fs/promises";
19728
19768
  import { resolve as resolve14 } from "node:path";
19729
19769
  var PI_MCP_BRIDGE_FILENAME = "beeline-mcp-bridge.js";
19730
19770
  function harnessMountsSessionMcpServers(agentCommand) {
@@ -19748,7 +19788,7 @@ async function installPiMcpBridge(input) {
19748
19788
  const directory = resolve14(input.piHome, "extensions");
19749
19789
  const path = resolve14(directory, PI_MCP_BRIDGE_FILENAME);
19750
19790
  try {
19751
- await mkdir6(directory, { recursive: true, mode: 448 });
19791
+ await mkdir7(directory, { recursive: true, mode: 448 });
19752
19792
  await writeIsolatedHarnessFile(path, piMcpBridgeSource(input.servers));
19753
19793
  return path;
19754
19794
  } catch (error) {
@@ -20153,6 +20193,7 @@ function beelineAgentMcpServer(config, api, context) {
20153
20193
  args: [...config.readonlyMcpArgs ?? []],
20154
20194
  env: [
20155
20195
  { name: "BEELINE_MCP_SURFACE", value: "agent" },
20196
+ ...context.turnContextPath ? [{ name: "BEELINE_TURN_CONTEXT_FILE", value: context.turnContextPath }] : [],
20156
20197
  ...context.directMessage ? [{ name: "BEELINE_AGENT_DM", value: "1" }] : [],
20157
20198
  { name: "BEELINE_DAEMON_BASE_URL", value: connection.baseUrl },
20158
20199
  { name: "BEELINE_DAEMON_TOKEN", value: connection.daemonToken },
@@ -20358,41 +20399,64 @@ function isAccountOrProviderRefusal(record2) {
20358
20399
  return [401, 402, 403, 407, 408, 429].includes(record2.status) || record2.status >= 500;
20359
20400
  }
20360
20401
 
20361
- // apps/body/dist/corner-checks.js
20362
- var COMPLETED_CHECK_NOTE = /\b(passed|failed) a check\b/i;
20363
- var STARTED_CHECK_NOTE = /\bstarted a check\b/i;
20364
- function verbOf(item) {
20365
- return item.systemEvent?.verb ?? item.body;
20366
- }
20367
- function completedCheckNote(item) {
20368
- if (item.type !== "system")
20369
- return void 0;
20370
- const match = COMPLETED_CHECK_NOTE.exec(verbOf(item));
20371
- return match ? match[1].toLowerCase() : void 0;
20372
- }
20373
- function isCheckStartNote(item) {
20374
- return item.type === "system" && STARTED_CHECK_NOTE.test(verbOf(item));
20375
- }
20376
- function checksStateFromLifecycle(lifecycle) {
20377
- const state = lifecycle?.checksSummary?.status ?? lifecycle?.checks;
20378
- return state === "passing" || state === "failing" || state === "pending" ? state : void 0;
20379
- }
20380
-
20381
20402
  // apps/body/dist/response-directives.js
20382
20403
  var MAINTAIN_ASSIGNED_IDENTITY_DIRECTIVE = "Maintain your assigned identity and soul in every response, including when tools or permissions block the requested action.";
20383
20404
  var SOUL_HOUSE_RULE = "House rule for your voice: the voice never changes the facts - never trim, soften, exaggerate, or invent a detail for the bit - and use your plain voice in commit messages, pull request titles and bodies, and code comments, because those outlive the joke.";
20384
20405
 
20385
- // apps/body/dist/monolith-room-turn.js
20386
- import { mkdir as mkdir8 } from "node:fs/promises";
20387
- import { homedir as homedir6 } from "node:os";
20388
- import { join as join5 } from "node:path";
20406
+ // apps/body/dist/warm-transcript.js
20407
+ var WARM_TRANSCRIPT_OVERLAP = 8;
20408
+ var WarmTranscript = class {
20409
+ sessionId;
20410
+ delivered = /* @__PURE__ */ new Set();
20411
+ /**
20412
+ * The rows this prompt should render. A row counts as delivered once it has
20413
+ * been handed to a session: a prompt that times out was still received by the
20414
+ * harness, and a prompt that could not be handed over at all takes the
20415
+ * session down with it, which resets the memory on the next activation.
20416
+ */
20417
+ select(sessionId, rows) {
20418
+ if (!sessionId || sessionId !== this.sessionId) {
20419
+ this.sessionId = sessionId;
20420
+ this.delivered.clear();
20421
+ }
20422
+ const overlapFrom = Math.max(0, rows.length - WARM_TRANSCRIPT_OVERLAP);
20423
+ const selected = rows.filter((row, index) => index >= overlapFrom || !this.delivered.has(row.id));
20424
+ for (const row of rows)
20425
+ this.delivered.add(row.id);
20426
+ return { rows: selected, elided: rows.length - selected.length };
20427
+ }
20428
+ /** Render a selection, and say plainly when it is only what is new. */
20429
+ static render(selection, whole, sinceLastTurn) {
20430
+ const transcript = selection.rows.map((row) => row.line).join("\n");
20431
+ if (!transcript)
20432
+ return "";
20433
+ return `${selection.elided ? sinceLastTurn : whole}
20434
+ ${transcript}`;
20435
+ }
20436
+ };
20389
20437
 
20390
- // packages/api-contract/dist/scheduled-prompts.js
20391
- var SCHEDULE_SCHEDULER_NAME = "Beeline Scheduler";
20392
- var SCHEDULE_RAN_VERB = "ran a schedule for";
20438
+ // apps/body/dist/turn-receipt-heartbeat.js
20439
+ var TURN_RECEIPT_HEARTBEAT_MS = 3e4;
20440
+ async function withTurnReceiptHeartbeat(api, receipt, task, onHeartbeatError) {
20441
+ let tail = Promise.resolve();
20442
+ const timer = setInterval(() => {
20443
+ tail = tail.catch(() => void 0).then(() => api.execute("postAgentTurnReceipt", {
20444
+ ...receipt,
20445
+ status: "working",
20446
+ heartbeat: true
20447
+ })).then(() => void 0).catch(onHeartbeatError);
20448
+ }, TURN_RECEIPT_HEARTBEAT_MS);
20449
+ timer.unref?.();
20450
+ try {
20451
+ return await task();
20452
+ } finally {
20453
+ clearInterval(timer);
20454
+ await tail;
20455
+ }
20456
+ }
20393
20457
 
20394
20458
  // apps/body/dist/turn-trace.js
20395
- import { appendFile, mkdir as mkdir7, readdir as readdir4, rm as rm3 } from "node:fs/promises";
20459
+ import { appendFile, mkdir as mkdir8, readdir as readdir4, rm as rm3 } from "node:fs/promises";
20396
20460
  import { resolve as resolve17 } from "node:path";
20397
20461
  import { performance as performance2 } from "node:perf_hooks";
20398
20462
  var TURN_PHASES = [
@@ -20646,7 +20710,7 @@ var TurnTraceFile = class {
20646
20710
  this.tail = this.tail.catch(() => void 0).then(async () => {
20647
20711
  const now2 = (this.options.clock ?? (() => /* @__PURE__ */ new Date()))();
20648
20712
  const path = this.path(now2);
20649
- await mkdir7(this.directory, { recursive: true, mode: 448 });
20713
+ await mkdir8(this.directory, { recursive: true, mode: 448 });
20650
20714
  await appendFile(path, `${JSON.stringify(record2)}
20651
20715
  `, { mode: 384 });
20652
20716
  await this.prune(now2);
@@ -20668,58 +20732,65 @@ var TurnTraceFile = class {
20668
20732
  }
20669
20733
  };
20670
20734
 
20671
- // apps/body/dist/turn-receipt-heartbeat.js
20672
- var TURN_RECEIPT_HEARTBEAT_MS = 3e4;
20673
- async function withTurnReceiptHeartbeat(api, receipt, task, onHeartbeatError) {
20674
- await api.execute("postAgentTurnReceipt", { ...receipt, status: "working" });
20675
- let tail = Promise.resolve();
20676
- const timer = setInterval(() => {
20677
- tail = tail.catch(() => void 0).then(() => api.execute("postAgentTurnReceipt", {
20678
- ...receipt,
20679
- status: "working",
20680
- heartbeat: true
20681
- })).then(() => void 0).catch(onHeartbeatError);
20682
- }, TURN_RECEIPT_HEARTBEAT_MS);
20683
- timer.unref?.();
20684
- try {
20685
- return await task();
20686
- } finally {
20687
- clearInterval(timer);
20688
- await tail;
20735
+ // apps/body/dist/corner-github-auth.js
20736
+ import { chmod as chmod3, mkdir as mkdir9, writeFile as writeFile8 } from "node:fs/promises";
20737
+ import { delimiter as delimiter2, resolve as resolve18 } from "node:path";
20738
+ async function installCornerGitHubWrappers(input) {
20739
+ const bin = resolve18(input.root, "beeline-github-bin");
20740
+ await mkdir9(bin, { recursive: true, mode: 448 });
20741
+ const common = {
20742
+ node: process.execPath,
20743
+ cli: input.cliEntrypoint,
20744
+ config: input.runtimeConfigPath,
20745
+ room: input.roomId
20746
+ };
20747
+ await writeLauncher(resolve18(bin, "git"), { ...common, command: input.gitBinary });
20748
+ if (input.ghBinary)
20749
+ await writeLauncher(resolve18(bin, "gh"), { ...common, command: input.ghBinary });
20750
+ return {
20751
+ PATH: [bin, input.inheritedPath].filter(Boolean).join(delimiter2),
20752
+ // Static startup tokens take precedence over the refreshed token in gh.
20753
+ GH_TOKEN: "",
20754
+ GITHUB_TOKEN: ""
20755
+ };
20756
+ }
20757
+ async function writeLauncher(path, config) {
20758
+ const source = `#!/usr/bin/env node
20759
+ import { spawnSync } from 'node:child_process';
20760
+ const config = ${JSON.stringify(config)};
20761
+ const authFailure = /(?:authentication failed|bad credentials|could not read username|http(?:\\/\\d(?:\\.\\d)?)? 40[13]|status (?:code )?40[13])/i;
20762
+ function token() {
20763
+ const result = spawnSync(config.node, [config.cli, 'corner-read-token', '--config', config.config, '--room', config.room], { encoding: 'utf8' });
20764
+ if (result.status !== 0) {
20765
+ process.stderr.write(result.stderr || 'Beeline could not refresh the repository credential.\\n');
20766
+ process.exit(result.status || 1);
20689
20767
  }
20768
+ return result.stdout.trim();
20769
+ }
20770
+ function run(value) {
20771
+ const env = { ...process.env, GH_TOKEN: value, GITHUB_TOKEN: value, GIT_TERMINAL_PROMPT: '0' };
20772
+ return spawnSync(config.command, process.argv.slice(2), { env, encoding: 'buffer', stdio: ['inherit', 'pipe', 'pipe'] });
20773
+ }
20774
+ let result = run(token());
20775
+ const diagnostic = Buffer.concat([result.stdout || Buffer.alloc(0), result.stderr || Buffer.alloc(0)]).toString('utf8');
20776
+ if (result.status !== 0 && authFailure.test(diagnostic)) result = run(token());
20777
+ if (result.stdout) process.stdout.write(result.stdout);
20778
+ if (result.stderr) process.stderr.write(result.stderr);
20779
+ if (result.error) throw result.error;
20780
+ process.exit(result.status ?? 1);
20781
+ `;
20782
+ await writeFile8(path, source, { mode: 448 });
20783
+ await chmod3(path, 448);
20690
20784
  }
20691
20785
 
20692
- // apps/body/dist/warm-transcript.js
20693
- var WARM_TRANSCRIPT_OVERLAP = 8;
20694
- var WarmTranscript = class {
20695
- sessionId;
20696
- delivered = /* @__PURE__ */ new Set();
20697
- /**
20698
- * The rows this prompt should render. A row counts as delivered once it has
20699
- * been handed to a session: a prompt that times out was still received by the
20700
- * harness, and a prompt that could not be handed over at all takes the
20701
- * session down with it, which resets the memory on the next activation.
20702
- */
20703
- select(sessionId, rows) {
20704
- if (!sessionId || sessionId !== this.sessionId) {
20705
- this.sessionId = sessionId;
20706
- this.delivered.clear();
20707
- }
20708
- const overlapFrom = Math.max(0, rows.length - WARM_TRANSCRIPT_OVERLAP);
20709
- const selected = rows.filter((row, index) => index >= overlapFrom || !this.delivered.has(row.id));
20710
- for (const row of rows)
20711
- this.delivered.add(row.id);
20712
- return { rows: selected, elided: rows.length - selected.length };
20713
- }
20714
- /** Render a selection, and say plainly when it is only what is new. */
20715
- static render(selection, whole, sinceLastTurn) {
20716
- const transcript = selection.rows.map((row) => row.line).join("\n");
20717
- if (!transcript)
20718
- return "";
20719
- return `${selection.elided ? sinceLastTurn : whole}
20720
- ${transcript}`;
20721
- }
20722
- };
20786
+ // apps/body/dist/monolith-room-turn.js
20787
+ import { mkdir as mkdir10 } from "node:fs/promises";
20788
+ import { homedir as homedir6 } from "node:os";
20789
+ import { join as join6 } from "node:path";
20790
+
20791
+ // packages/api-contract/dist/scheduled-prompts.js
20792
+ var SCHEDULE_SCHEDULER_NAME = "Beeline Scheduler";
20793
+ var SCHEDULE_RAN_VERB = "ran a schedule for";
20723
20794
 
20724
20795
  // apps/body/dist/monolith-room-turn.js
20725
20796
  function isRoomMcpPermissionRequest(request, mountedServers = ROOM_MOUNTED_MCP_SERVERS) {
@@ -20727,15 +20798,6 @@ function isRoomMcpPermissionRequest(request, mountedServers = ROOM_MOUNTED_MCP_S
20727
20798
  return false;
20728
20799
  return isMountedMcpToolPermissionRequest(request, mountedServers);
20729
20800
  }
20730
- function roomPrincipalMayAddressAgent(authority, humanPermitted) {
20731
- if (!authority.member)
20732
- return false;
20733
- if (authority.principalKind === "agent")
20734
- return true;
20735
- if (authority.principalKind !== "human")
20736
- return false;
20737
- return authority.mayAddressAgent ?? humanPermitted;
20738
- }
20739
20801
  function isScheduledPrompt(item, agentId) {
20740
20802
  if (item.type !== "system" || !item.mentionIds.includes(agentId))
20741
20803
  return false;
@@ -20754,30 +20816,6 @@ function inboxItemAuthorName(item, agentId, names) {
20754
20816
  function inboxItemPromptBody(item, agentId) {
20755
20817
  return isScheduledPrompt(item, agentId) ? item.systemEvent?.consequence ?? item.body : item.body;
20756
20818
  }
20757
- function isSubscribedEvent(item, agentId) {
20758
- const kind = item.systemEvent?.kind;
20759
- return item.type === "system" && kind !== void 0 && !isResumeKind(kind) && !isControlKind(kind) && item.mentionIds.includes(agentId);
20760
- }
20761
- function inboxItemSkipsSenderPolicy(item, agentId) {
20762
- if (isGrantDecisionLine(item, agentId))
20763
- return true;
20764
- if (item.type !== "system" || !item.mentionIds.includes(agentId))
20765
- return false;
20766
- const kind = item.systemEvent?.kind;
20767
- return kind === void 0 ? isScheduledPrompt(item, agentId) : isServerEventKind(kind);
20768
- }
20769
- function isGrantDecisionLine(item, agentId) {
20770
- return item.type === "system" && item.mentionIds.includes(agentId) && parseGrantDecisionLine(item.body) !== void 0;
20771
- }
20772
- function inboxItemTriggersTurn(item, agentId, continuesExchange = false) {
20773
- if (item.authorId === agentId)
20774
- return false;
20775
- if (item.type === "message" && continuesExchange)
20776
- return true;
20777
- if (!item.mentionIds.includes(agentId))
20778
- return false;
20779
- return item.type === "message" || isSubscribedEvent(item, agentId) || isScheduledPrompt(item, agentId) || isGrantDecisionLine(item, agentId);
20780
- }
20781
20819
  function pendingGrantToolCall(call) {
20782
20820
  if (!/(?:^|[._:/-])request_grant$/i.test(call.title ?? ""))
20783
20821
  return false;
@@ -20800,6 +20838,7 @@ function roomMentionDirectory(roster, selfId) {
20800
20838
  return "";
20801
20839
  return [
20802
20840
  "Room members, and the exact spelling that tags each one:",
20841
+ "An exact agent tag assigns that agent work; use it only when you are asking that agent to act.",
20803
20842
  ...rows,
20804
20843
  "Write a tag exactly as spelled here. An @name spelled any other way is plain text: it reaches nobody, and nobody is told it was meant for them. Never invent a handle, shorten one, or copy an @name out of the conversation \u2014 old messages carry spellings that no longer exist."
20805
20844
  ].join("\n");
@@ -20812,7 +20851,8 @@ function agentReplyMentionIds(text2, roster, authorId) {
20812
20851
  for (const member of roster.members) {
20813
20852
  if (member.identityId === authorId)
20814
20853
  continue;
20815
- for (const raw of [member.name, member.handle, member.soul?.name]) {
20854
+ const rawAliases = member.kind === "agent" ? [member.handle] : [member.name, member.handle, member.soul?.name];
20855
+ for (const raw of rawAliases) {
20816
20856
  const display = raw?.trim().replace(/^@/, "");
20817
20857
  if (!display)
20818
20858
  continue;
@@ -20823,7 +20863,7 @@ function agentReplyMentionIds(text2, roster, authorId) {
20823
20863
  }
20824
20864
  }
20825
20865
  for (const member of roster.members) {
20826
- if (member.identityId === authorId || !member.handle)
20866
+ if (member.identityId === authorId || member.kind === "agent" || !member.handle)
20827
20867
  continue;
20828
20868
  const handle = member.handle.trim().replace(/^@/, "").toLocaleLowerCase();
20829
20869
  const canonical = aliases.get(handle);
@@ -20846,12 +20886,11 @@ function agentReplyMentionIds(text2, roster, authorId) {
20846
20886
  }
20847
20887
  var MonolithRoomTurnLoop = class {
20848
20888
  options;
20889
+ commandContext;
20849
20890
  agent;
20850
- reconciliationRequested = true;
20851
20891
  wakeIntake;
20852
20892
  /** Called by the daemon's one slow workspace reconciliation sweep. */
20853
20893
  requestReconciliation() {
20854
- this.reconciliationRequested = true;
20855
20894
  this.wakeIntake?.();
20856
20895
  this.wakeIntake = void 0;
20857
20896
  }
@@ -20869,7 +20908,6 @@ var MonolithRoomTurnLoop = class {
20869
20908
  turnInstructionPrefix = "";
20870
20909
  activeTurn;
20871
20910
  queuedTurns = [];
20872
- continuityRebuildRequested = false;
20873
20911
  /** Session scratch directory attachments are downloaded into (`TMPDIR/beeline-attachments`). */
20874
20912
  attachmentDir;
20875
20913
  /** Whether the pinned model takes images; `undefined` when the pin did not say. */
@@ -20888,18 +20926,21 @@ var MonolithRoomTurnLoop = class {
20888
20926
  pausedOnGrantRequestId;
20889
20927
  /** Operator-local turn traces; built once when the daemon configured a directory. */
20890
20928
  turnTraceSink;
20891
- /** Per-sender continuity, shared in shape with corner intake. */
20892
- responseRule = new AgentResponseRule();
20893
20929
  constructor(options) {
20894
20930
  this.options = options;
20895
20931
  this.agent = runtimeIdentity(options.runtime.agent);
20932
+ this.commandContext = new CommandExecutionContext(options.config.agentHomeRoot);
20933
+ this.options = { ...options, api: this.commandContext.bind(options.api) };
20896
20934
  options.grantRunner?.register(options.roomId, {
20897
20935
  workspaceId: options.workspaceId,
20898
20936
  cwd: options.cwd,
20899
20937
  // A top-level Room keeps its read-only promise for grants too: the runner
20900
20938
  // wraps the command in this Room's own mount table (C94).
20901
20939
  writePolicy: () => this.grantWritePolicy(),
20902
- turn: () => this.currentTurnForRunner()
20940
+ turn: () => {
20941
+ const turn = this.currentTurnForRunner();
20942
+ return turn ? { ...turn, generationId: this.commandContext.generationId } : void 0;
20943
+ }
20903
20944
  });
20904
20945
  }
20905
20946
  isBusy() {
@@ -20952,9 +20993,6 @@ var MonolithRoomTurnLoop = class {
20952
20993
  const name = this.memberNames.get(authorId);
20953
20994
  return { pubkey: authorId, ...name ? { name } : {} };
20954
20995
  }
20955
- currentPrincipalCanDrive(_workspaceId, principalId) {
20956
- return Promise.resolve(isSenderPermitted(this.options.config.accessPolicy ?? LEGACY_ACCESS_POLICY, principalId, this.options.config.accessOwnerPubkey, this.options.config.accessAllowlist));
20957
- }
20958
20996
  async refreshPersonaForSoulUpdate() {
20959
20997
  await this.options.scheduler.suspend(this.options.roomId);
20960
20998
  }
@@ -20971,7 +21009,6 @@ var MonolithRoomTurnLoop = class {
20971
21009
  workspaceId: this.options.workspaceId
20972
21010
  });
20973
21011
  this.memberNames = new Map(roster.members.map((member) => [member.identityId, member.name]));
20974
- this.responseRule.setAgents(roster.members.filter((member) => member.kind === "agent").map((member) => member.identityId));
20975
21012
  return roster;
20976
21013
  }
20977
21014
  /**
@@ -20993,7 +21030,7 @@ var MonolithRoomTurnLoop = class {
20993
21030
  const cached = this.deliveredAttachments.get(item.id);
20994
21031
  if (cached)
20995
21032
  return cached;
20996
- const delivered = await deliverAttachments(item.attachments, join5(this.attachmentDir, item.id.replace(/[^\w-]/g, "_")), this.options.fetchImpl);
21033
+ const delivered = await deliverAttachments(item.attachments, join6(this.attachmentDir, item.id.replace(/[^\w-]/g, "_")), this.options.fetchImpl);
20997
21034
  this.deliveredAttachments.set(item.id, withoutImageData(delivered));
20998
21035
  return delivered;
20999
21036
  }
@@ -21060,7 +21097,7 @@ var MonolithRoomTurnLoop = class {
21060
21097
  agentName: self?.name ?? this.agent.name
21061
21098
  });
21062
21099
  const directMessage = Array.isArray(repositoryState.directParticipants) && repositoryState.directParticipants.length === 2;
21063
- await mkdir8(this.options.cwd, { recursive: true });
21100
+ await mkdir10(this.options.cwd, { recursive: true });
21064
21101
  const selection = configuration.model || configuration.effort ? { model: configuration.model, effort: configuration.effort } : this.options.config.modelSelection;
21065
21102
  const homeOverlay = this.options.config.agentHomeRoot ? await prepareRoomAgentHome({
21066
21103
  root: this.options.config.agentHomeRoot,
@@ -21086,14 +21123,14 @@ var MonolithRoomTurnLoop = class {
21086
21123
  }, selection);
21087
21124
  const operatorHome = this.options.config.operatorHome ?? homedir6();
21088
21125
  const { stateDirs, tmpDir } = harnessStateDirsFromEnv(agentEnv);
21089
- this.attachmentDir = tmpDir ? join5(tmpDir, "beeline-attachments") : void 0;
21126
+ this.attachmentDir = tmpDir ? join6(tmpDir, "beeline-attachments") : void 0;
21090
21127
  this.sessionScratchDir = tmpDir;
21091
21128
  this.sessionStateDirs = stateDirs;
21092
21129
  const homeStateDirs = harnessHomeStateDirs(command, agentEnv.HOME ?? operatorHome);
21093
- await Promise.all(homeStateDirs.map((dir) => mkdir8(dir, { recursive: true })));
21130
+ await Promise.all(homeStateDirs.map((dir) => mkdir10(dir, { recursive: true })));
21094
21131
  const attachScratchRoot = this.options.config.agentHomeRoot ?? tmpDir;
21095
21132
  if (attachScratchRoot)
21096
- await mkdir8(attachScratchRoot, { recursive: true });
21133
+ await mkdir10(attachScratchRoot, { recursive: true });
21097
21134
  const spawnCommand = wrapAgentCommand({
21098
21135
  bwrapPath: this.options.config.bwrapPath,
21099
21136
  spec: {
@@ -21119,6 +21156,7 @@ var MonolithRoomTurnLoop = class {
21119
21156
  // images dir, say), so anything inside the overlay it could possibly
21120
21157
  // have written must be attachable, whatever subdirectory that is.
21121
21158
  attachScratchRoot,
21159
+ turnContextPath: this.commandContext.path,
21122
21160
  directMessage,
21123
21161
  ...this.options.grantRunnerEndpoint ? { grantRunner: this.options.grantRunnerEndpoint } : {}
21124
21162
  })
@@ -21251,8 +21289,6 @@ var MonolithRoomTurnLoop = class {
21251
21289
  }).finally(() => {
21252
21290
  if (this.activeTurn === active) {
21253
21291
  this.activeTurn = void 0;
21254
- if (active.rebuildContinuity)
21255
- this.continuityRebuildRequested = true;
21256
21292
  this.wakeIntake?.();
21257
21293
  this.wakeIntake = void 0;
21258
21294
  }
@@ -21279,24 +21315,6 @@ var MonolithRoomTurnLoop = class {
21279
21315
  if (this.client && this.sessionId)
21280
21316
  this.client.sessionCancel(this.sessionId);
21281
21317
  }
21282
- steer(active, item) {
21283
- active.steers.push(item);
21284
- active.steerTail = active.steerTail.catch(() => void 0).then(async () => {
21285
- try {
21286
- const [roster, delivered] = await Promise.all([this.roster(), this.deliver(item)]);
21287
- const author = roster.members.find((member) => member.identityId === item.authorId)?.name ?? item.authorId.slice(0, 12);
21288
- await this.client.sessionSteer(this.sessionId, [
21289
- `Human steer received while the current turn is running from ${author}:`,
21290
- roomMessagePrompt("", item.body, item.attachments, delivered, this.acceptsImages()),
21291
- "Adjust the current work now. Keep the original request and earlier messages as context."
21292
- ].join("\n\n"));
21293
- } catch (error) {
21294
- active.resumeRequested = true;
21295
- this.client?.sessionCancel(this.sessionId);
21296
- console.warn(`[thin-core] monolith Room ${this.options.roomId} live steer unavailable; cancelling and resuming:`, error);
21297
- }
21298
- });
21299
- }
21300
21318
  async prompt(active) {
21301
21319
  const { item } = active;
21302
21320
  const api = this.options.api;
@@ -21309,7 +21327,7 @@ var MonolithRoomTurnLoop = class {
21309
21327
  agentId: this.agent.publicKey,
21310
21328
  roomId: this.options.roomId,
21311
21329
  requestId: item.id,
21312
- generationId: `${this.agent.publicKey}:${this.options.roomId}`
21330
+ generationId: this.commandContext.generationId
21313
21331
  }, async () => {
21314
21332
  await api.execute("postAgentActivity", {
21315
21333
  agentId: this.agent.publicKey,
@@ -21339,7 +21357,7 @@ var MonolithRoomTurnLoop = class {
21339
21357
  id: message.id,
21340
21358
  line: roomMessagePrompt(names.get(message.authorId) ?? message.authorId.slice(0, 12), message.body, message.attachments, this.deliveredAttachments.get(message.id), this.acceptsImages())
21341
21359
  }));
21342
- const grantDecision = isGrantDecisionLine(item, this.agent.publicKey);
21360
+ const grantDecision = this.commandContext.current?.action === "resume";
21343
21361
  const resumedRequestId = grantDecision ? this.pausedOnGrantRequestId : void 0;
21344
21362
  if (grantDecision)
21345
21363
  this.pausedOnGrantRequestId = void 0;
@@ -21417,8 +21435,7 @@ var MonolithRoomTurnLoop = class {
21417
21435
  }
21418
21436
  }
21419
21437
  if (active.cancelled) {
21420
- const stoppedText = durableReplyText(result.agentText);
21421
- await stream.settle(stoppedText, stoppedText ? { triggerMessageId: item.id } : {});
21438
+ stream.close();
21422
21439
  throw new TurnStoppedError("turn stopped by the requester");
21423
21440
  }
21424
21441
  active.phase = "finishing";
@@ -21453,21 +21470,10 @@ var MonolithRoomTurnLoop = class {
21453
21470
  reply = stripCornerOpenEcho(reply);
21454
21471
  }
21455
21472
  const mentionIds = reply ? agentReplyMentionIds(reply, roster, this.agent.publicKey) : [];
21456
- const continuitySenders = reply ? [item.authorId, ...mentionIds] : [];
21457
- if (continuitySenders.length) {
21458
- active.continuitySenders = new Set(continuitySenders);
21459
- active.rebuildContinuity = true;
21460
- }
21461
21473
  await trace.measure("publish", () => stream.settle(reply, reply ? {
21462
21474
  triggerMessageId: item.id,
21463
21475
  mentionIds
21464
- } : {}, reply ? (posted) => {
21465
- this.responseRule.noteReply(this.agent.publicKey, [
21466
- item.authorId,
21467
- ...posted.mentionIds ?? []
21468
- ]);
21469
- active.rebuildContinuity = false;
21470
- } : void 0));
21476
+ } : {}));
21471
21477
  }, { priority: "interactive", roomKey: this.options.roomId });
21472
21478
  }, (error) => console.error(`[thin-core] monolith Room ${this.options.roomId} receipt heartbeat failed:`, error));
21473
21479
  await api.execute("postAgentTurnReceipt", {
@@ -21475,7 +21481,7 @@ var MonolithRoomTurnLoop = class {
21475
21481
  roomId: this.options.roomId,
21476
21482
  requestId: item.id,
21477
21483
  status: "complete",
21478
- generationId: `${this.agent.publicKey}:${this.options.roomId}`
21484
+ generationId: this.commandContext.generationId
21479
21485
  });
21480
21486
  await trace.finish("complete");
21481
21487
  } catch (error) {
@@ -21490,7 +21496,7 @@ var MonolithRoomTurnLoop = class {
21490
21496
  roomId: this.options.roomId,
21491
21497
  requestId: item.id,
21492
21498
  status: "failed",
21493
- generationId: `${this.agent.publicKey}:${this.options.roomId}`,
21499
+ generationId: this.commandContext.generationId,
21494
21500
  reason
21495
21501
  });
21496
21502
  await trace.finish("failed", reason);
@@ -21501,137 +21507,37 @@ var MonolithRoomTurnLoop = class {
21501
21507
  }
21502
21508
  async run() {
21503
21509
  const { api, roomId, signal } = this.options;
21504
- let cursor3;
21505
- const processedInboxIds = /* @__PURE__ */ new Set();
21506
- const deferredContinuity = /* @__PURE__ */ new Map();
21507
- const pushedInbox = [];
21508
- let pendingPushedCursor;
21509
- let liveConnected = false;
21510
- let stopLive;
21511
21510
  try {
21512
- const activation = await api.execute("getRoomInbox", { roomId, startAtLatest: true });
21513
- cursor3 = activation.cursor;
21514
- const rewindSupported = Array.isArray(activation.rewindIds);
21515
- for (const id of activation.rewindIds ?? [])
21516
- processedInboxIds.add(id);
21517
- const [history] = await Promise.all([
21518
- api.execute("getRoomConversation", { roomId, limit: 200, window: "continuity" }),
21519
- this.roster()
21520
- ]);
21521
- this.responseRule.observeAll(history.items);
21522
- stopLive = api.liveSubscribe?.(roomId, cursor3, (items, pushedCursor) => {
21523
- pushedInbox.push(...items);
21524
- pendingPushedCursor = laterInboxCursor(pendingPushedCursor, pushedCursor);
21525
- this.wakeIntake?.();
21526
- this.wakeIntake = void 0;
21527
- }, (connected, capabilities) => {
21528
- liveConnected = connected && capabilities?.pushIntake === true;
21529
- this.options.health.presence(connected && !this.options.config.modelUnavailable ? "online" : "offline");
21530
- this.wakeIntake?.();
21531
- this.wakeIntake = void 0;
21532
- }, {
21533
- ...this.options.config.daemonReleaseVersion ? { releaseVersion: this.options.config.daemonReleaseVersion } : {},
21534
- ...this.options.config.daemonSourceSha ? { sourceSha: this.options.config.daemonSourceSha } : {},
21535
- available: !this.options.config.modelUnavailable
21536
- });
21537
- while (!signal?.aborted) {
21538
- try {
21539
- if (!this.activeTurn && this.continuityRebuildRequested) {
21540
- const history2 = await api.execute("getRoomConversation", {
21541
- roomId,
21542
- limit: 200,
21543
- window: "continuity"
21544
- });
21545
- this.responseRule.replaceHistory(history2.items);
21546
- this.continuityRebuildRequested = false;
21547
- }
21548
- if (!this.activeTurn && deferredContinuity.size === 0 && this.queuedTurns.length) {
21549
- this.startPrompt(this.queuedTurns.shift());
21550
- }
21551
- const pollNow = pushedInbox.length === 0 && (!liveConnected || this.reconciliationRequested);
21552
- const inbox = !pollNow ? { items: [], cursor: void 0 } : await api.execute("getRoomInbox", {
21553
- roomId,
21554
- ...cursor3 ? { after: cursor3 } : {},
21555
- ...rewindSupported ? { rewind: true } : {},
21556
- limit: 200
21557
- });
21558
- if (pollNow) {
21559
- this.reconciliationRequested = false;
21560
- }
21561
- const deferred = this.activeTurn ? [] : [...deferredContinuity.values()];
21562
- if (!this.activeTurn)
21563
- deferredContinuity.clear();
21564
- const delivered = orderInboxItems([
21565
- ...deferred,
21566
- ...pushedInbox.splice(0),
21567
- ...inbox.items
21568
- ]);
21569
- for (const item of delivered) {
21570
- if (processedInboxIds.has(item.id) || deferredContinuity.has(item.id))
21571
- continue;
21572
- const triggers = inboxItemTriggersTurn(item, this.agent.publicKey, this.responseRule.continues(item, this.agent.publicKey));
21573
- const finishing = this.activeTurn;
21574
- if (!triggers && finishing?.phase === "finishing" && finishing.continuitySenders?.has(item.authorId) && item.type === "message" && !item.replyToMessageId) {
21575
- deferredContinuity.set(item.id, item);
21576
- continue;
21577
- }
21578
- processedInboxIds.add(item.id);
21579
- while (processedInboxIds.size > INBOX_DEDUPLICATION_LIMIT)
21580
- processedInboxIds.delete(processedInboxIds.values().next().value);
21581
- const stopped = turnStopRequestId(item, this.agent.publicKey);
21582
- if (stopped) {
21583
- this.stopTurn(stopped);
21584
- continue;
21585
- }
21586
- this.responseRule.observe(item);
21587
- if (!triggers)
21588
- continue;
21589
- if (!inboxItemSkipsSenderPolicy(item, this.agent.publicKey)) {
21590
- const authority = await api.execute("getRoomAuthority", {
21591
- roomId,
21592
- principalId: item.authorId
21593
- });
21594
- const humanPermitted = authority.principalKind === "human" ? await this.currentPrincipalCanDrive(this.options.workspaceId, item.authorId) : false;
21595
- if (!roomPrincipalMayAddressAgent(authority, humanPermitted))
21596
- continue;
21597
- }
21598
- const active = this.activeTurn;
21599
- if (!active)
21600
- this.startPrompt(item);
21601
- else if (active.phase === "prompting")
21602
- this.steer(active, item);
21603
- else
21604
- this.queuedTurns.push(item);
21605
- }
21606
- cursor3 = laterInboxCursor(cursor3, laterInboxCursor(inbox.cursor, pendingPushedCursor));
21607
- pendingPushedCursor = void 0;
21608
- api.updateLiveCursor?.(roomId, cursor3);
21609
- if (pollNow)
21610
- this.options.health.poll();
21611
- if (!pushedInbox.length) {
21612
- await Promise.race([
21613
- wait(liveConnected ? 2147483647 : this.options.pollMs ?? 1e3, signal),
21614
- new Promise((resolve30) => {
21615
- this.wakeIntake = resolve30;
21616
- })
21617
- ]);
21618
- }
21619
- } catch (error) {
21620
- if (signal?.aborted)
21621
- break;
21622
- this.options.health.failure(1e3);
21623
- console.error(`[thin-core] monolith Room ${roomId} turn loop failed:`, error);
21624
- await wait(1e3, signal);
21511
+ await runServerCommandIntake({
21512
+ api,
21513
+ roomId,
21514
+ agentId: this.agent.publicKey,
21515
+ context: this.commandContext,
21516
+ signal,
21517
+ pollMs: this.options.pollMs,
21518
+ presence: {
21519
+ ...this.options.config.daemonReleaseVersion ? { releaseVersion: this.options.config.daemonReleaseVersion } : {},
21520
+ ...this.options.config.daemonSourceSha ? { sourceSha: this.options.config.daemonSourceSha } : {},
21521
+ available: !this.options.config.modelUnavailable
21522
+ },
21523
+ onWake: (wake) => {
21524
+ this.wakeIntake = wake;
21525
+ },
21526
+ onPoll: () => this.options.health.poll(),
21527
+ onError: (error) => console.error("[thin-core] Room command failed", error),
21528
+ stop: (requestId) => this.stopTurn(requestId),
21529
+ run: async (command) => {
21530
+ const item = {
21531
+ ...command.source,
21532
+ id: command.turnRequestId,
21533
+ body: command.action === "resume" ? `Resume the paused turn. The server supplied this grant decision: ${command.source.body}` : command.source.body
21534
+ };
21535
+ this.startPrompt(item);
21536
+ await this.activeTurn?.promise;
21625
21537
  }
21626
- }
21538
+ });
21627
21539
  } finally {
21628
- stopLive?.();
21629
- this.wakeIntake = void 0;
21630
21540
  this.options.grantRunner?.unregister(roomId);
21631
- if (this.activeTurn?.phase === "prompting" && this.client && this.sessionId) {
21632
- this.client.sessionCancel(this.sessionId);
21633
- }
21634
- await this.activeTurn?.promise;
21635
21541
  await this.options.scheduler.suspend(roomId);
21636
21542
  }
21637
21543
  }
@@ -21641,70 +21547,6 @@ function roomMessagePrompt(author, body, attachments, delivered, harnessAcceptsI
21641
21547
  const rendered = author ? `${author}: ${message}` : message;
21642
21548
  return [rendered, ...attachmentPromptLines(attachments, delivered, harnessAcceptsImages)].join("\n");
21643
21549
  }
21644
- async function wait(ms, signal) {
21645
- if (signal?.aborted)
21646
- return;
21647
- await new Promise((resolveWait) => {
21648
- const done = () => {
21649
- clearTimeout(timer);
21650
- signal?.removeEventListener("abort", done);
21651
- resolveWait();
21652
- };
21653
- const timer = setTimeout(done, ms);
21654
- signal?.addEventListener("abort", done, { once: true });
21655
- });
21656
- }
21657
-
21658
- // apps/body/dist/corner-github-auth.js
21659
- import { chmod as chmod3, mkdir as mkdir9, writeFile as writeFile7 } from "node:fs/promises";
21660
- import { delimiter as delimiter2, resolve as resolve18 } from "node:path";
21661
- async function installCornerGitHubWrappers(input) {
21662
- const bin = resolve18(input.root, "beeline-github-bin");
21663
- await mkdir9(bin, { recursive: true, mode: 448 });
21664
- const common = {
21665
- node: process.execPath,
21666
- cli: input.cliEntrypoint,
21667
- config: input.runtimeConfigPath,
21668
- room: input.roomId
21669
- };
21670
- await writeLauncher(resolve18(bin, "git"), { ...common, command: input.gitBinary });
21671
- if (input.ghBinary)
21672
- await writeLauncher(resolve18(bin, "gh"), { ...common, command: input.ghBinary });
21673
- return {
21674
- PATH: [bin, input.inheritedPath].filter(Boolean).join(delimiter2),
21675
- // Static startup tokens take precedence over the refreshed token in gh.
21676
- GH_TOKEN: "",
21677
- GITHUB_TOKEN: ""
21678
- };
21679
- }
21680
- async function writeLauncher(path, config) {
21681
- const source = `#!/usr/bin/env node
21682
- import { spawnSync } from 'node:child_process';
21683
- const config = ${JSON.stringify(config)};
21684
- const authFailure = /(?:authentication failed|bad credentials|could not read username|http(?:\\/\\d(?:\\.\\d)?)? 40[13]|status (?:code )?40[13])/i;
21685
- function token() {
21686
- const result = spawnSync(config.node, [config.cli, 'corner-read-token', '--config', config.config, '--room', config.room], { encoding: 'utf8' });
21687
- if (result.status !== 0) {
21688
- process.stderr.write(result.stderr || 'Beeline could not refresh the repository credential.\\n');
21689
- process.exit(result.status || 1);
21690
- }
21691
- return result.stdout.trim();
21692
- }
21693
- function run(value) {
21694
- const env = { ...process.env, GH_TOKEN: value, GITHUB_TOKEN: value, GIT_TERMINAL_PROMPT: '0' };
21695
- return spawnSync(config.command, process.argv.slice(2), { env, encoding: 'buffer', stdio: ['inherit', 'pipe', 'pipe'] });
21696
- }
21697
- let result = run(token());
21698
- const diagnostic = Buffer.concat([result.stdout || Buffer.alloc(0), result.stderr || Buffer.alloc(0)]).toString('utf8');
21699
- if (result.status !== 0 && authFailure.test(diagnostic)) result = run(token());
21700
- if (result.stdout) process.stdout.write(result.stdout);
21701
- if (result.stderr) process.stderr.write(result.stderr);
21702
- if (result.error) throw result.error;
21703
- process.exit(result.status ?? 1);
21704
- `;
21705
- await writeFile7(path, source, { mode: 448 });
21706
- await chmod3(path, 448);
21707
- }
21708
21550
 
21709
21551
  // apps/body/dist/monolith-corner-turn.js
21710
21552
  var execFileAsync3 = promisify3(execFile4);
@@ -21835,18 +21677,13 @@ async function cornerToolActivity(call, worktreePath, requestedBy) {
21835
21677
  ...paths.length ? { files: paths.map((path) => ({ path })) } : {}
21836
21678
  };
21837
21679
  }
21838
- var CORNER_CLOSE_POLL_BASE_MS = 12e3;
21839
- function cornerClosePollMs(random = Math.random) {
21840
- return CORNER_CLOSE_POLL_BASE_MS + Math.floor(random() * 3e3);
21841
- }
21842
21680
  var MonolithCornerTurnLoop = class {
21843
21681
  options;
21682
+ commandContext;
21844
21683
  agent;
21845
- reconciliationRequested = true;
21846
21684
  wakeIntake;
21847
21685
  /** Called by the daemon's one slow workspace reconciliation sweep. */
21848
21686
  requestReconciliation() {
21849
- this.reconciliationRequested = true;
21850
21687
  this.wakeIntake?.();
21851
21688
  this.wakeIntake = void 0;
21852
21689
  }
@@ -21878,15 +21715,9 @@ var MonolithCornerTurnLoop = class {
21878
21715
  turnTraceSink;
21879
21716
  memberNames = /* @__PURE__ */ new Map();
21880
21717
  /** Agent identities in this Workspace, so a mention can be told from a human's. */
21881
- agentMembers = /* @__PURE__ */ new Set();
21882
- rosterAvailable = false;
21883
21718
  /** Per-sender continuity, shared in shape with top-level Room intake. */
21884
- responseRule = new AgentResponseRule();
21885
- continuityRebuildRequested = false;
21886
21719
  /** The member agent that owns corner-wide lifecycle facts such as checks. */
21887
- carrier;
21888
21720
  /** The last server check state that started a turn; the same state never starts another. */
21889
- lastChecksState;
21890
21721
  /**
21891
21722
  * Request ids the requester has stopped. A corner's intake is blocked while
21892
21723
  * its turn runs, so a stop is recorded from the live-push callback and read
@@ -21897,6 +21728,8 @@ var MonolithCornerTurnLoop = class {
21897
21728
  constructor(options) {
21898
21729
  this.options = options;
21899
21730
  this.agent = runtimeIdentity(options.runtime.agent);
21731
+ this.commandContext = new CommandExecutionContext(options.config.agentHomeRoot);
21732
+ this.options = { ...options, api: this.commandContext.bind(options.api) };
21900
21733
  options.grantRunner?.register(options.cornerId, {
21901
21734
  workspaceId: options.workspaceId,
21902
21735
  cwd: options.worktreePath,
@@ -21907,15 +21740,12 @@ var MonolithCornerTurnLoop = class {
21907
21740
  surface: "corner",
21908
21741
  ...this.sessionScratchDir ? { scratch: this.sessionScratchDir } : {}
21909
21742
  }),
21910
- turn: () => this.currentTurn
21743
+ turn: () => this.currentTurn ? { ...this.currentTurn, generationId: this.commandContext.generationId } : void 0
21911
21744
  });
21912
21745
  }
21913
21746
  isBusy() {
21914
21747
  return this.busy;
21915
21748
  }
21916
- currentPrincipalCanDrive(_workspaceId, _principalId) {
21917
- return Promise.resolve(true);
21918
- }
21919
21749
  refreshPersonaForSoulUpdate() {
21920
21750
  return this.options.scheduler.suspend(this.options.cornerId);
21921
21751
  }
@@ -21950,15 +21780,8 @@ var MonolithCornerTurnLoop = class {
21950
21780
  workspaceId: this.options.workspaceId
21951
21781
  });
21952
21782
  this.memberNames = new Map(roster.members.map((member) => [member.identityId, member.name]));
21953
- this.agentMembers = new Set(roster.members.filter((member) => member.kind === "agent").map((member) => member.identityId));
21954
- this.responseRule.setAgents(this.agentMembers);
21955
- this.rosterAvailable = true;
21956
21783
  return roster;
21957
21784
  }
21958
- async reconcileRoster() {
21959
- if (!this.rosterAvailable)
21960
- await this.roster().catch(() => void 0);
21961
- }
21962
21785
  /**
21963
21786
  * Drop this corner's live harness process. The next activation starts cold.
21964
21787
  * A rotation is a fact about one live session, so the pin goes with it.
@@ -22011,7 +21834,7 @@ var MonolithCornerTurnLoop = class {
22011
21834
  soul: configuration.soul ?? self?.soul,
22012
21835
  agentName: self?.name ?? this.agent.name
22013
21836
  });
22014
- await mkdir10(this.options.worktreePath, { recursive: true });
21837
+ await mkdir11(this.options.worktreePath, { recursive: true });
22015
21838
  const selection = configuration.model || configuration.effort ? { model: configuration.model, effort: configuration.effort } : this.options.config.modelSelection;
22016
21839
  const homeOverlay = this.options.config.agentHomeRoot ? await prepareRoomAgentHome({
22017
21840
  root: this.options.config.agentHomeRoot,
@@ -22056,13 +21879,13 @@ var MonolithCornerTurnLoop = class {
22056
21879
  }, selection);
22057
21880
  const operatorHome = this.options.config.operatorHome ?? homedir7();
22058
21881
  const { stateDirs, tmpDir } = harnessStateDirsFromEnv(agentEnv);
22059
- this.attachmentDir = tmpDir ? join6(tmpDir, "beeline-attachments") : void 0;
21882
+ this.attachmentDir = tmpDir ? join7(tmpDir, "beeline-attachments") : void 0;
22060
21883
  this.sessionScratchDir = tmpDir;
22061
21884
  const homeStateDirs = harnessHomeStateDirs(command, agentEnv.HOME ?? operatorHome);
22062
- await Promise.all(homeStateDirs.map((dir) => mkdir10(dir, { recursive: true })));
21885
+ await Promise.all(homeStateDirs.map((dir) => mkdir11(dir, { recursive: true })));
22063
21886
  const attachScratchRoot = this.options.config.agentHomeRoot ?? tmpDir;
22064
21887
  if (attachScratchRoot)
22065
- await mkdir10(attachScratchRoot, { recursive: true });
21888
+ await mkdir11(attachScratchRoot, { recursive: true });
22066
21889
  const spawnCommand = wrapAgentCommand({
22067
21890
  bwrapPath: this.options.config.bwrapPath,
22068
21891
  spec: {
@@ -22115,6 +21938,7 @@ var MonolithCornerTurnLoop = class {
22115
21938
  // The whole per-session overlay, not an enumerated subset: see
22116
21939
  // `monolith-room-turn.ts`'s matching comment.
22117
21940
  attachScratchRoot,
21941
+ turnContextPath: this.commandContext.path,
22118
21942
  ...this.options.grantRunnerEndpoint ? { grantRunner: this.options.grantRunnerEndpoint } : {}
22119
21943
  })
22120
21944
  ];
@@ -22247,14 +22071,13 @@ var MonolithCornerTurnLoop = class {
22247
22071
  ...this.memberNames.get(requestedById) ? { name: this.memberNames.get(requestedById) } : {}
22248
22072
  } : void 0;
22249
22073
  this.currentTurn = { requestId, ...requester ? { requester } : {} };
22250
- this.carrier = this.agent.publicKey;
22251
22074
  const trace = this.beginTurnTrace(requestId);
22252
22075
  try {
22253
22076
  await withTurnReceiptHeartbeat(api, {
22254
22077
  agentId: this.agent.publicKey,
22255
22078
  roomId: cornerId,
22256
22079
  requestId,
22257
- generationId: `${this.agent.publicKey}:${cornerId}`
22080
+ generationId: this.commandContext.generationId
22258
22081
  }, () => {
22259
22082
  trace.noteScheduler("queue", this.options.scheduler.snapshot());
22260
22083
  trace.start("queue-wait");
@@ -22268,7 +22091,7 @@ var MonolithCornerTurnLoop = class {
22268
22091
  const [conversation, roster, delivered] = await trace.measure("context-fetch", () => Promise.all([
22269
22092
  api.execute("getRoomConversation", { roomId: cornerId, limit: 200 }),
22270
22093
  this.roster(),
22271
- this.attachmentDir && attachments.length ? deliverAttachments(attachments, join6(this.attachmentDir, requestId.replace(/[^\w-]/g, "_")), this.options.fetchImpl) : Promise.resolve([])
22094
+ this.attachmentDir && attachments.length ? deliverAttachments(attachments, join7(this.attachmentDir, requestId.replace(/[^\w-]/g, "_")), this.options.fetchImpl) : Promise.resolve([])
22272
22095
  ]));
22273
22096
  const names = new Map(roster.members.map((member) => [member.identityId, member.name]));
22274
22097
  const requestedBy = requester && !requester.name && names.get(requester.pubkey) ? { ...requester, name: names.get(requester.pubkey) } : requester;
@@ -22283,6 +22106,7 @@ var MonolithCornerTurnLoop = class {
22283
22106
  `Corner objective:
22284
22107
  ${this.options.objective}`,
22285
22108
  WarmTranscript.render(this.warmTranscript.select(this.sessionId, transcriptRows), "Corner transcript:", "New in the corner since your last turn (the earlier transcript is already in this session):"),
22109
+ roomMentionDirectory(roster, this.agent.publicKey),
22286
22110
  [
22287
22111
  `Newest trigger:
22288
22112
  ${trigger}`,
@@ -22414,9 +22238,7 @@ ${trigger}`,
22414
22238
  }
22415
22239
  }
22416
22240
  if (this.stoppedTurns.has(requestId)) {
22417
- const stoppedText = spoken(durableReplyText(result.agentText));
22418
- await flushToolCalls(result.toolCalls, stoppedText);
22419
- await stream.settle(stoppedText);
22241
+ stream.close();
22420
22242
  throw new TurnStoppedError("turn stopped by the requester");
22421
22243
  }
22422
22244
  let reply = durableReplyText(result.agentText);
@@ -22436,12 +22258,11 @@ ${trigger}`,
22436
22258
  console.warn(`[thin-core] corner ${cornerId} turn ${requestId}: ${explained.reason}`);
22437
22259
  }
22438
22260
  const durableReply = spoken(reply);
22439
- if (durableReply && requestedById)
22440
- this.continuityRebuildRequested = true;
22441
- await trace.measure("publish", () => stream.settle(durableReply, requestedById ? { triggerMessageId: requestId } : {}, durableReply && requestedById ? () => {
22442
- this.responseRule.noteReply(this.agent.publicKey, [requestedById]);
22443
- this.continuityRebuildRequested = false;
22444
- } : void 0));
22261
+ const mentionIds = durableReply ? agentReplyMentionIds(durableReply, roster, this.agent.publicKey) : [];
22262
+ await trace.measure("publish", () => stream.settle(durableReply, durableReply ? {
22263
+ ...requestedById ? { triggerMessageId: requestId } : {},
22264
+ mentionIds
22265
+ } : {}));
22445
22266
  }, { priority: "interactive", roomKey: cornerId });
22446
22267
  }, (error) => console.error(`[thin-core] corner ${cornerId} receipt heartbeat failed:`, error));
22447
22268
  await api.execute("postAgentTurnReceipt", {
@@ -22449,7 +22270,7 @@ ${trigger}`,
22449
22270
  roomId: cornerId,
22450
22271
  requestId,
22451
22272
  status: "complete",
22452
- generationId: `${this.agent.publicKey}:${cornerId}`
22273
+ generationId: this.commandContext.generationId
22453
22274
  });
22454
22275
  await trace.finish("complete");
22455
22276
  } catch (error) {
@@ -22464,7 +22285,7 @@ ${trigger}`,
22464
22285
  roomId: cornerId,
22465
22286
  requestId,
22466
22287
  status: "failed",
22467
- generationId: `${this.agent.publicKey}:${cornerId}`,
22288
+ generationId: this.commandContext.generationId,
22468
22289
  reason
22469
22290
  });
22470
22291
  await trace.finish("failed", reason);
@@ -22474,46 +22295,6 @@ ${trigger}`,
22474
22295
  this.currentTurn = void 0;
22475
22296
  }
22476
22297
  }
22477
- /** Whether this agent opened the corner. A corner with no recorded opener
22478
- * behaves exactly as it did before members could carry it. */
22479
- isOpener() {
22480
- return !this.options.openedBy || this.options.openedBy === this.agent.publicKey;
22481
- }
22482
- /**
22483
- * Whether this agent is the one carrying the corner right now.
22484
- *
22485
- * Every member agent polls the corner, but its lifecycle — a server check
22486
- * note, a close request answered with work — is ONE fact and must start ONE
22487
- * turn, not one per member (the "one check turn per changed server state"
22488
- * rule). The carrier is whoever answered in the corner last, which is the
22489
- * opener until a human hands the work to someone else.
22490
- */
22491
- carriesCorner() {
22492
- return (this.carrier ?? this.options.openedBy ?? this.agent.publicKey) === this.agent.publicKey;
22493
- }
22494
- /** Notes an agent's durable message as the corner changing hands. */
22495
- noteCarrier(authorId) {
22496
- if (this.agentMembers.has(authorId))
22497
- this.carrier = authorId;
22498
- }
22499
- async noteIncomingCarrier(item) {
22500
- if (item.agentAuthor && !this.agentMembers.has(item.authorId))
22501
- await this.roster().catch(() => void 0);
22502
- this.noteCarrier(item.authorId);
22503
- }
22504
- /**
22505
- * Whether a message in this corner is addressed to THIS agent.
22506
- *
22507
- * A corner now runs like a Room — every member agent polls it — so an
22508
- * A server-resolved mention always routes to its agent. Otherwise the one
22509
- * agent already exchanging messages with this exact sender continues; the
22510
- * lifecycle carrier is deliberately not a conversational fallback.
22511
- */
22512
- addressesThisAgent(item) {
22513
- if (item.mentionIds.includes(this.agent.publicKey))
22514
- return true;
22515
- return this.responseRule.continues(item, this.agent.publicKey);
22516
- }
22517
22298
  /**
22518
22299
  * Bring this worktree onto the corner's branch as GitHub currently has it,
22519
22300
  * before any work is done on top of it.
@@ -22535,197 +22316,42 @@ ${trigger}`,
22535
22316
  env: { ...process.env, GH_TOKEN: token, GITHUB_TOKEN: token, GIT_TERMINAL_PROMPT: "0" }
22536
22317
  });
22537
22318
  }
22538
- /** The server's check state for this head, or the notes' own verdict when the server carries none. */
22539
- async checksState(notes) {
22540
- try {
22541
- const restore = await this.options.api.execute("getCornerRestoreState", {
22542
- cornerId: this.options.cornerId
22543
- });
22544
- const fromServer = checksStateFromLifecycle(restore.lifecycle);
22545
- if (fromServer)
22546
- return fromServer;
22547
- } catch (error) {
22548
- console.error(`[thin-core] corner ${this.options.cornerId} check state read failed:`, error);
22549
- }
22550
- return notes.some((note) => completedCheckNote(note) === "failed") ? "failing" : "passing";
22551
- }
22552
22319
  async run() {
22553
22320
  const { api, cornerId, signal } = this.options;
22554
- const activation = await api.execute("getRoomInbox", {
22555
- roomId: cornerId,
22556
- startAtLatest: true
22557
- });
22558
- let cursor3 = activation.cursor;
22559
- const processedInboxIds = /* @__PURE__ */ new Set();
22560
- const pushedInbox = [];
22561
- let pendingPushedCursor;
22562
- let liveConnected = false;
22563
- const rewindSupported = Array.isArray(activation.rewindIds);
22564
- for (const id of activation.rewindIds ?? [])
22565
- processedInboxIds.add(id);
22566
- const stopLive = api.liveSubscribe?.(cornerId, cursor3, (items, pushedCursor) => {
22567
- pushedInbox.push(...items);
22568
- for (const item of items) {
22569
- const stopped = turnStopRequestId(item, this.agent.publicKey);
22570
- if (stopped)
22571
- this.stopTurn(stopped);
22572
- }
22573
- pendingPushedCursor = laterInboxCursor(pendingPushedCursor, pushedCursor);
22574
- this.wakeIntake?.();
22575
- this.wakeIntake = void 0;
22576
- }, (connected, capabilities) => {
22577
- liveConnected = connected && capabilities?.pushIntake === true;
22578
- this.wakeIntake?.();
22579
- this.wakeIntake = void 0;
22580
- }, {
22581
- ...this.options.config.daemonReleaseVersion ? { releaseVersion: this.options.config.daemonReleaseVersion } : {},
22582
- ...this.options.config.daemonSourceSha ? { sourceSha: this.options.config.daemonSourceSha } : {},
22583
- available: !this.options.config.modelUnavailable
22584
- });
22585
- const history = await api.execute("getRoomConversation", {
22586
- roomId: cornerId,
22587
- limit: 200,
22588
- window: "continuity"
22589
- });
22590
- await this.roster().catch(() => void 0);
22591
- this.responseRule.observeAll(history.items);
22592
- for (const item of history.items) {
22593
- if (item.type === "message")
22594
- await this.noteIncomingCarrier(item);
22595
- }
22596
- const durableAgentReplies = history.items.filter((item) => item.type === "message" && item.authorId === this.agent.publicKey && item.body.trim() !== this.options.objective.trim());
22597
- if (durableAgentReplies.length === 0 && this.isOpener()) {
22598
- await this.prompt(history.items.find((item) => item.requestId)?.requestId ?? cornerId.replaceAll("-", ""), this.options.objective);
22599
- }
22600
22321
  try {
22601
- let pollWithoutWait = false;
22602
- while (!signal?.aborted) {
22603
- try {
22604
- if (this.continuityRebuildRequested) {
22605
- const reconciled = await api.execute("getRoomConversation", {
22606
- roomId: cornerId,
22607
- limit: 200,
22608
- window: "continuity"
22609
- });
22610
- this.responseRule.replaceHistory(reconciled.items);
22611
- this.carrier = void 0;
22612
- for (const item of reconciled.items) {
22613
- if (item.type === "message")
22614
- await this.noteIncomingCarrier(item);
22615
- }
22616
- this.continuityRebuildRequested = false;
22617
- }
22618
- const pollNow = pushedInbox.length > 0 || !liveConnected || this.reconciliationRequested;
22619
- const inbox = !pollNow ? { items: [], cursor: void 0, closeRequested: false } : await api.execute("getCornerCloseRequests", {
22620
- cornerId,
22621
- ...cursor3 ? { after: cursor3 } : {},
22622
- ...rewindSupported ? { rewind: true } : {}
22623
- });
22624
- if (pollNow) {
22625
- this.reconciliationRequested = false;
22626
- }
22627
- if (inbox.closeRequested) {
22628
- await this.options.onCloseRequested();
22629
- return;
22630
- }
22631
- const checkNotes = [];
22632
- const delivered = orderInboxItems([...pushedInbox.splice(0), ...inbox.items]);
22633
- for (const item of delivered) {
22634
- if (processedInboxIds.has(item.id))
22635
- continue;
22636
- processedInboxIds.add(item.id);
22637
- while (processedInboxIds.size > INBOX_DEDUPLICATION_LIMIT)
22638
- processedInboxIds.delete(processedInboxIds.values().next().value);
22639
- const stoppedTurn = turnStopRequestId(item, this.agent.publicKey);
22640
- if (stoppedTurn) {
22641
- this.stopTurn(stoppedTurn);
22642
- continue;
22643
- }
22644
- if (item.type === "message") {
22645
- if (item.authorId !== this.agent.publicKey)
22646
- await this.reconcileRoster();
22647
- await this.noteIncomingCarrier(item);
22648
- if (item.authorId === this.agent.publicKey)
22649
- continue;
22650
- const addressed = this.addressesThisAgent(item);
22651
- this.responseRule.observe(item);
22652
- if (!addressed)
22653
- continue;
22654
- const authority = await api.execute("getRoomAuthority", {
22655
- roomId: cornerId,
22656
- principalId: item.authorId
22657
- });
22658
- const humanPermitted = authority.principalKind === "human" ? await this.currentPrincipalCanDrive(this.options.workspaceId, item.authorId) : false;
22659
- if (!roomPrincipalMayAddressAgent(authority, humanPermitted))
22660
- continue;
22661
- await this.prompt(item.id, item.body, item.attachments, item.authorId);
22662
- pollWithoutWait = true;
22663
- continue;
22664
- }
22665
- const grantDecision = item.type === "system" && item.mentionIds.includes(this.agent.publicKey) && parseGrantDecisionLine(item.body) !== void 0;
22666
- if (grantDecision) {
22667
- await this.prompt(item.id, `${item.body}
22668
- This answers your grant request; resume the paused work. If approved and it is a command grant, run it with run_granted_command and the exact argv; if declined, try another way or say what you cannot do.`, [], item.authorId);
22669
- pollWithoutWait = true;
22670
- continue;
22671
- }
22672
- if (isCheckStartNote(item)) {
22673
- this.lastChecksState = void 0;
22674
- continue;
22675
- }
22676
- if (completedCheckNote(item))
22677
- checkNotes.push(item);
22678
- }
22679
- if (checkNotes.length && this.carriesCorner()) {
22680
- const state = await this.checksState(checkNotes);
22681
- if (state && state !== "pending" && state !== this.lastChecksState) {
22682
- this.lastChecksState = state;
22683
- const lines = checkNotes.map((note) => note.body);
22684
- await this.prompt(checkNotes[checkNotes.length - 1].id, lines.join("\n"), [], void 0, lines);
22685
- pollWithoutWait = true;
22686
- }
22687
- }
22688
- cursor3 = laterInboxCursor(cursor3, laterInboxCursor(inbox.cursor, pendingPushedCursor));
22689
- pendingPushedCursor = void 0;
22690
- api.updateLiveCursor?.(cornerId, cursor3);
22691
- if (pollNow)
22692
- this.options.onPoll();
22693
- await Promise.race([
22694
- wait2(pollWithoutWait ? 0 : liveConnected ? 2147483647 : this.options.pollMs ?? cornerClosePollMs(), signal),
22695
- pushedInbox.length ? Promise.resolve() : new Promise((resolve30) => {
22696
- this.wakeIntake = resolve30;
22697
- })
22698
- ]);
22699
- pollWithoutWait = false;
22700
- } catch (error) {
22701
- if (signal?.aborted)
22702
- break;
22703
- this.options.onFailure(1e3);
22704
- console.error(`[thin-core] corner ${cornerId} turn loop failed:`, error);
22705
- await wait2(1e3, signal);
22706
- }
22707
- }
22322
+ await runServerCommandIntake({
22323
+ api,
22324
+ roomId: cornerId,
22325
+ agentId: this.agent.publicKey,
22326
+ context: this.commandContext,
22327
+ signal,
22328
+ pollMs: this.options.pollMs,
22329
+ presence: {
22330
+ ...this.options.config.daemonReleaseVersion ? { releaseVersion: this.options.config.daemonReleaseVersion } : {},
22331
+ ...this.options.config.daemonSourceSha ? { sourceSha: this.options.config.daemonSourceSha } : {},
22332
+ available: !this.options.config.modelUnavailable
22333
+ },
22334
+ onWake: (wake) => {
22335
+ this.wakeIntake = wake;
22336
+ },
22337
+ onPoll: () => this.options.onPoll(),
22338
+ onError: (error) => console.error("[thin-core] corner command failed", error),
22339
+ stop: (requestId) => this.stopTurn(requestId),
22340
+ closed: async () => {
22341
+ const state = await api.execute("getCornerRestoreState", { cornerId });
22342
+ if (!state.closeRequested)
22343
+ return false;
22344
+ await this.options.onCloseRequested();
22345
+ return true;
22346
+ },
22347
+ run: (command) => this.prompt(command.turnRequestId, command.source.body, command.source.attachments, command.source.authorId, command.reason === "corner_check" ? [command.source.body] : void 0)
22348
+ });
22708
22349
  } finally {
22709
- stopLive?.();
22710
- this.wakeIntake = void 0;
22711
22350
  this.options.grantRunner?.unregister(cornerId);
22712
22351
  await this.options.scheduler.suspend(cornerId);
22713
22352
  }
22714
22353
  }
22715
22354
  };
22716
- async function wait2(ms, signal) {
22717
- if (signal?.aborted)
22718
- return;
22719
- await new Promise((resolveWait) => {
22720
- const done = () => {
22721
- clearTimeout(timer);
22722
- signal?.removeEventListener("abort", done);
22723
- resolveWait();
22724
- };
22725
- const timer = setTimeout(done, ms);
22726
- signal?.addEventListener("abort", done, { once: true });
22727
- });
22728
- }
22729
22355
 
22730
22356
  // apps/body/dist/session-scheduler.js
22731
22357
  var DEFAULT_PER_ROOM_LIVE_SESSIONS = 10;
@@ -23145,8 +22771,8 @@ async function materializeCornerWorktree(input) {
23145
22771
  const repositoryHash = createHash5("sha256").update(remote).digest("hex").slice(0, 24);
23146
22772
  const gitCommonDir = resolve19(input.supervisorRoot, "beeline", "repositories", `${repositoryHash}.git`);
23147
22773
  const path = resolve19(input.supervisorRoot, "beeline", "corners", input.cornerId);
23148
- await mkdir11(dirname6(gitCommonDir), { recursive: true, mode: 448 });
23149
- await mkdir11(dirname6(path), { recursive: true, mode: 448 });
22774
+ await mkdir12(dirname7(gitCommonDir), { recursive: true, mode: 448 });
22775
+ await mkdir12(dirname7(path), { recursive: true, mode: 448 });
23150
22776
  const authEnv = githubGitEnv(input.token);
23151
22777
  if (!existsSync4(resolve19(gitCommonDir, "HEAD"))) {
23152
22778
  await execFileAsync4("git", ["clone", "--bare", remote, gitCommonDir], {
@@ -23333,9 +22959,6 @@ var RoomRuntimeCoordinator = class {
23333
22959
  this.drainDeadlineAt = Math.min(this.drainDeadlineAt ?? Number.POSITIVE_INFINITY, deadlineAt);
23334
22960
  }
23335
22961
  }
23336
- async currentPrincipalCanDrive(roomId, workspaceId, principalId) {
23337
- return this.running.get(roomId)?.body.currentPrincipalCanDrive(workspaceId, principalId);
23338
- }
23339
22962
  async prepareForForcedUpdateRestart() {
23340
22963
  const rooms = [...this.running.values()];
23341
22964
  await Promise.allSettled(rooms.filter((room) => room.body.isBusy()).map((room) => room.body.prepareForForcedUpdateRestart()));
@@ -23420,7 +23043,7 @@ var RoomRuntimeCoordinator = class {
23420
23043
  return this.runtime.rooms.find((room) => room.channelId === roomId);
23421
23044
  }
23422
23045
  roomRoot(roomId) {
23423
- return this.roomRecord(roomId)?.root ?? resolve19(dirname6(this.configPath), "rooms", roomId);
23046
+ return this.roomRecord(roomId)?.root ?? resolve19(dirname7(this.configPath), "rooms", roomId);
23424
23047
  }
23425
23048
  roomAgentHomeRoot(workspaceRoot, required = false) {
23426
23049
  const flag = process.env.BUZZY_BODY_ROOM_HOME;
@@ -23443,9 +23066,9 @@ var RoomRuntimeCoordinator = class {
23443
23066
  ...this.baseConfig,
23444
23067
  workspaceRoot,
23445
23068
  agentPrivateRoot: resolve19(workspaceRoot, "agent-private"),
23446
- agentMemoryRoot: resolve19(dirname6(this.configPath), "memory"),
23447
- openRouterRoutingCacheDir: openRouterRoutingCacheDir(dirname6(this.configPath)),
23448
- turnTraceDir: turnTraceDirectory(dirname6(this.configPath)),
23069
+ agentMemoryRoot: resolve19(dirname7(this.configPath), "memory"),
23070
+ openRouterRoutingCacheDir: openRouterRoutingCacheDir(dirname7(this.configPath)),
23071
+ turnTraceDir: turnTraceDirectory(dirname7(this.configPath)),
23449
23072
  ...agentHomeRoot ? { agentHomeRoot } : {}
23450
23073
  };
23451
23074
  }
@@ -23513,7 +23136,7 @@ var RoomRuntimeCoordinator = class {
23513
23136
  const targetBranch = repository.targetBranch || "main";
23514
23137
  const checkoutId = createHash5("sha256").update(`${remote}\0${targetBranch}`).digest("hex").slice(0, 24);
23515
23138
  const path = resolve19(this.runtime.supervisorRoot, "beeline", "room-checkouts", checkoutId);
23516
- await mkdir11(dirname6(path), { recursive: true, mode: 448 });
23139
+ await mkdir12(dirname7(path), { recursive: true, mode: 448 });
23517
23140
  const token = remote.startsWith("https://github.com/") ? await this.options.daemonApi.execute("getRoomGitHubToken", { roomId }) : void 0;
23518
23141
  const env = token ? githubGitEnv(token.token) : process.env;
23519
23142
  if (!existsSync4(resolve19(path, ".git"))) {
@@ -23579,7 +23202,7 @@ var RoomRuntimeCoordinator = class {
23579
23202
  }) : void 0;
23580
23203
  const workspacePath = worktree?.path ?? resolve19(this.roomRoot(corner.cornerId), "scratch");
23581
23204
  if (!worktree)
23582
- await mkdir11(workspacePath, { recursive: true, mode: 448 });
23205
+ await mkdir12(workspacePath, { recursive: true, mode: 448 });
23583
23206
  const isOpener = !corner.openedBy || corner.openedBy === this.agent.publicKey;
23584
23207
  if (worktree && shouldPostInitialCornerWorkingState(restore, isOpener)) {
23585
23208
  await this.options.daemonApi.execute("postCornerRemoteState", {
@@ -23878,9 +23501,9 @@ var ThinDaemonCore = class {
23878
23501
 
23879
23502
  // apps/body/dist/systemd.js
23880
23503
  import { execFile as execFile6 } from "node:child_process";
23881
- import { mkdir as mkdir12, readFile as readFile8, writeFile as writeFile8 } from "node:fs/promises";
23504
+ import { mkdir as mkdir13, readFile as readFile8, writeFile as writeFile9 } from "node:fs/promises";
23882
23505
  import { homedir as homedir8 } from "node:os";
23883
- import { dirname as dirname7, resolve as resolve20 } from "node:path";
23506
+ import { dirname as dirname8, resolve as resolve20 } from "node:path";
23884
23507
  import { setTimeout as sleep } from "node:timers/promises";
23885
23508
  import { promisify as promisify5 } from "node:util";
23886
23509
  var execFileAsync5 = promisify5(execFile6);
@@ -23951,8 +23574,8 @@ async function installAgentService(publicKey, options = {}) {
23951
23574
  const content = agentServiceUnit();
23952
23575
  const existing = await readFile8(path, "utf8").catch(() => "");
23953
23576
  if (existing !== content) {
23954
- await mkdir12(dirname7(path), { recursive: true, mode: 448 });
23955
- await writeFile8(path, content, { mode: 384 });
23577
+ await mkdir13(dirname8(path), { recursive: true, mode: 448 });
23578
+ await writeFile9(path, content, { mode: 384 });
23956
23579
  }
23957
23580
  const run2 = options.run ?? runSystemctl;
23958
23581
  await run2(["daemon-reload"]);
@@ -24032,7 +23655,7 @@ async function retireRemovedAgent(runtime, options = {}) {
24032
23655
  }
24033
23656
 
24034
23657
  // apps/body/dist/start-command.js
24035
- import { dirname as dirname8 } from "node:path";
23658
+ import { dirname as dirname9 } from "node:path";
24036
23659
  var import_picocolors = __toESM(require_picocolors(), 1);
24037
23660
  var DEFAULT_RESTART_DRAIN_TIMEOUT_MS = 30 * 6e4;
24038
23661
  var RESTART_WAIT_REPORT_INTERVAL_MS = 3e4;
@@ -24107,7 +23730,7 @@ async function runStartCommand(args, interactiveUi) {
24107
23730
  continue;
24108
23731
  }
24109
23732
  const spinnerHandle = spinner();
24110
- spinnerHandle.start(`Starting ${dirname8(path)}\u2026`);
23733
+ spinnerHandle.start(`Starting ${dirname9(path)}\u2026`);
24111
23734
  try {
24112
23735
  await startRuntime(path, spinnerHandle);
24113
23736
  spinnerHandle.stop(import_picocolors.default.green("Started."));
@@ -24124,8 +23747,8 @@ async function runStartCommand(args, interactiveUi) {
24124
23747
  // apps/body/dist/connect-command.js
24125
23748
  import { spawn as spawn5 } from "node:child_process";
24126
23749
  import { createHash as createHash7 } from "node:crypto";
24127
- import { chmod as chmod5, mkdir as mkdir14, readFile as readFile10, unlink as unlink2, writeFile as writeFile10 } from "node:fs/promises";
24128
- import { dirname as dirname10, resolve as resolve22 } from "node:path";
23750
+ import { chmod as chmod5, mkdir as mkdir15, readFile as readFile10, unlink as unlink2, writeFile as writeFile11 } from "node:fs/promises";
23751
+ import { dirname as dirname11, resolve as resolve22 } from "node:path";
24129
23752
  import { stdin as stdin3, stdout as stdout4 } from "node:process";
24130
23753
 
24131
23754
  // apps/body/dist/clack-support.js
@@ -24769,8 +24392,8 @@ function providerEnvironment(selection) {
24769
24392
  };
24770
24393
  }
24771
24394
  async function writePrivateJson(path, value) {
24772
- await mkdir14(dirname10(path), { recursive: true, mode: 448 });
24773
- await writeFile10(path, `${JSON.stringify(value, null, 2)}
24395
+ await mkdir15(dirname11(path), { recursive: true, mode: 448 });
24396
+ await writeFile11(path, `${JSON.stringify(value, null, 2)}
24774
24397
  `, { mode: 384 });
24775
24398
  await chmod5(path, 384);
24776
24399
  }
@@ -24779,9 +24402,9 @@ async function writeProviderEnv(selection, agentPubkey) {
24779
24402
  if (Object.keys(values).length === 0)
24780
24403
  return void 0;
24781
24404
  const path = resolve22(defaultSupervisorRoot(process.env), "beeline", "connect", `${agentPubkey}.env`);
24782
- await mkdir14(dirname10(path), { recursive: true, mode: 448 });
24405
+ await mkdir15(dirname11(path), { recursive: true, mode: 448 });
24783
24406
  const contents = Object.entries(values).map(([key, value]) => `${key}=${JSON.stringify(value)}`).join("\n");
24784
- await writeFile10(path, `${contents}
24407
+ await writeFile11(path, `${contents}
24785
24408
  `, { mode: 384 });
24786
24409
  await chmod5(path, 384);
24787
24410
  return path;
@@ -24937,7 +24560,7 @@ async function runConnectFinishCommand(path) {
24937
24560
  if (model) {
24938
24561
  const decision2 = await resolveOpenRouterRouting({
24939
24562
  model,
24940
- cacheDir: openRouterRoutingCacheDir(dirname10(connected.configPath)),
24563
+ cacheDir: openRouterRoutingCacheDir(dirname11(connected.configPath)),
24941
24564
  ...apiKey ? { apiKey } : {},
24942
24565
  probeTimeoutMs: 1e4
24943
24566
  });
@@ -24959,12 +24582,12 @@ init_self_update_manifest();
24959
24582
  // apps/body/dist/managed-update.js
24960
24583
  init_self_update();
24961
24584
  import { spawn as spawn6 } from "node:child_process";
24962
- import { mkdir as mkdir16, rm as rm6, stat as stat2, writeFile as writeFile12 } from "node:fs/promises";
24963
- import { dirname as dirname12, resolve as resolve24 } from "node:path";
24585
+ import { mkdir as mkdir17, rm as rm6, stat as stat2, writeFile as writeFile13 } from "node:fs/promises";
24586
+ import { dirname as dirname13, resolve as resolve24 } from "node:path";
24964
24587
 
24965
24588
  // apps/body/dist/update-rollback-alert.js
24966
- import { mkdir as mkdir15, readFile as readFile11, rename as rename4, unlink as unlink3, writeFile as writeFile11 } from "node:fs/promises";
24967
- import { dirname as dirname11, resolve as resolve23 } from "node:path";
24589
+ import { mkdir as mkdir16, readFile as readFile11, rename as rename4, unlink as unlink3, writeFile as writeFile12 } from "node:fs/promises";
24590
+ import { dirname as dirname12, resolve as resolve23 } from "node:path";
24968
24591
  var REPORT_INTERVAL_MS = 60 * 60 * 1e3;
24969
24592
  var lastLogged = /* @__PURE__ */ new Map();
24970
24593
  function updateRollbackAlertPath(runtimeDir) {
@@ -24973,8 +24596,8 @@ function updateRollbackAlertPath(runtimeDir) {
24973
24596
  async function writeAlert(runtimeDir, alert) {
24974
24597
  const path = updateRollbackAlertPath(runtimeDir);
24975
24598
  const staged = `${path}.${process.pid}.tmp`;
24976
- await mkdir15(dirname11(path), { recursive: true });
24977
- await writeFile11(staged, `${JSON.stringify(alert, null, 2)}
24599
+ await mkdir16(dirname12(path), { recursive: true });
24600
+ await writeFile12(staged, `${JSON.stringify(alert, null, 2)}
24978
24601
  `, { mode: 384 });
24979
24602
  await rename4(staged, path);
24980
24603
  }
@@ -25039,11 +24662,11 @@ async function withInstallLock(layout, work, options = {}) {
25039
24662
  const now2 = options.now ?? Date.now;
25040
24663
  const lock = resolve24(layout.releasesRoot, ".state", "install.lock");
25041
24664
  const deadline = now2() + (options.waitMs ?? 1e4);
25042
- await mkdir16(dirname12(lock), { recursive: true });
24665
+ await mkdir17(dirname13(lock), { recursive: true });
25043
24666
  for (; ; ) {
25044
24667
  try {
25045
- await mkdir16(lock);
25046
- await writeFile12(resolve24(lock, "owner"), `${process.pid}
24668
+ await mkdir17(lock);
24669
+ await writeFile13(resolve24(lock, "owner"), `${process.pid}
25047
24670
  ${now2()}
25048
24671
  `, "utf8");
25049
24672
  break;
@@ -25453,7 +25076,7 @@ async function proveLoadedReleaseReady(layout, runtimeDir, loadedRelease, option
25453
25076
  });
25454
25077
  if (!accepted)
25455
25078
  return false;
25456
- await writeFile12(resolve24(runtimeDir, "daemon-ready.json"), `${JSON.stringify({
25079
+ await writeFile13(resolve24(runtimeDir, "daemon-ready.json"), `${JSON.stringify({
25457
25080
  readyAt: (options.now ?? Date.now)(),
25458
25081
  loadedRelease,
25459
25082
  functionalProof: options.functionalProof
@@ -25681,8 +25304,8 @@ async function runUpdateCommand(args) {
25681
25304
  init_self_update();
25682
25305
 
25683
25306
  // apps/body/dist/daemon-failure.js
25684
- import { mkdir as mkdir17, readFile as readFile12, rename as rename5, rm as rm7, writeFile as writeFile13 } from "node:fs/promises";
25685
- import { dirname as dirname13, resolve as resolve25 } from "node:path";
25307
+ import { mkdir as mkdir18, readFile as readFile12, rename as rename5, rm as rm7, writeFile as writeFile14 } from "node:fs/promises";
25308
+ import { dirname as dirname14, resolve as resolve25 } from "node:path";
25686
25309
  var DAEMON_FAILURE_LIMIT = 3;
25687
25310
  var DAEMON_FAILURE_WINDOW_MS = 5 * 6e4;
25688
25311
  function daemonFailurePath(runtimeDir) {
@@ -25702,8 +25325,8 @@ async function readFailureRecord(runtimeDir) {
25702
25325
  async function writeFailureRecord(runtimeDir, record2) {
25703
25326
  const path = daemonFailurePath(runtimeDir);
25704
25327
  const staged = `${path}.${process.pid}.tmp`;
25705
- await mkdir17(dirname13(path), { recursive: true, mode: 448 });
25706
- await writeFile13(staged, `${JSON.stringify(record2, null, 2)}
25328
+ await mkdir18(dirname14(path), { recursive: true, mode: 448 });
25329
+ await writeFile14(staged, `${JSON.stringify(record2, null, 2)}
25707
25330
  `, { mode: 384 });
25708
25331
  await rename5(staged, path);
25709
25332
  }
@@ -25725,7 +25348,7 @@ async function clearDaemonStartFailures(runtimeDir) {
25725
25348
  }
25726
25349
 
25727
25350
  // apps/body/dist/update-functional-probe.js
25728
- import { mkdir as mkdir18, rm as rm8 } from "node:fs/promises";
25351
+ import { mkdir as mkdir19, rm as rm8 } from "node:fs/promises";
25729
25352
  import { homedir as homedir10 } from "node:os";
25730
25353
  import { resolve as resolve26 } from "node:path";
25731
25354
  var UPDATE_PROBE_SESSION_TIMEOUT_MS = 1e4;
@@ -25771,6 +25394,9 @@ async function probeOutcome(run2) {
25771
25394
  await run2();
25772
25395
  return { kind: "served" };
25773
25396
  } catch (error) {
25397
+ if (error instanceof UpdateFunctionalProbeError && error.reason === "sandbox-unavailable") {
25398
+ return { kind: "sandbox-unavailable", reason: error.message };
25399
+ }
25774
25400
  if (error instanceof UpdateFunctionalProbeError && error.providerRefusal) {
25775
25401
  return { kind: "refused", ...error.providerRefusal };
25776
25402
  }
@@ -25783,6 +25409,8 @@ function describeCurrentReleaseOutcome(outcome) {
25783
25409
  return "the current release answered";
25784
25410
  case "refused":
25785
25411
  return `the current release got a different refusal (${outcome.reason})`;
25412
+ case "sandbox-unavailable":
25413
+ return `the current release has the same unavailable sandbox (${outcome.reason})`;
25786
25414
  case "unavailable":
25787
25415
  return `the current release could not be compared (${outcome.reason})`;
25788
25416
  }
@@ -25794,13 +25422,33 @@ async function runUpdateFunctionalProbe(input) {
25794
25422
  throw new UpdateFunctionalProbeError("model-unavailable", input.config.modelUnavailable.detail);
25795
25423
  }
25796
25424
  if (input.sandboxRequired && !input.config.bwrapPath) {
25797
- throw new UpdateFunctionalProbeError("sandbox-unavailable", "the configured bubblewrap boundary did not pass its startup self-test");
25425
+ const detail = input.sandboxUnavailableDetail ?? "the configured bubblewrap boundary did not pass its startup self-test";
25426
+ if (!input.compareWithCurrentRelease) {
25427
+ throw new UpdateFunctionalProbeError("sandbox-unavailable", detail);
25428
+ }
25429
+ const current = await input.compareWithCurrentRelease({
25430
+ kind: "sandbox-unavailable",
25431
+ reason: detail
25432
+ });
25433
+ if (current.kind !== "sandbox-unavailable") {
25434
+ throw new UpdateFunctionalProbeError("sandbox-unavailable", `${detail}; ${describeCurrentReleaseOutcome(current)}`);
25435
+ }
25436
+ console.warn("[body] update probe: the sandbox is unavailable to this release and the current release alike; preserving fail-closed sandboxing and accepting the bundle as inconclusive");
25437
+ return {
25438
+ harness,
25439
+ sandboxed: false,
25440
+ sessionStarted: false,
25441
+ turnCompleted: false,
25442
+ nativeTools: [],
25443
+ modelAnswer: "unavailable",
25444
+ modelAnswerReason: `${detail} (the current release has the same host sandbox failure)`
25445
+ };
25798
25446
  }
25799
25447
  const root = input.probeRoot ?? resolve26(input.runtimeDir, "update-functional-probe");
25800
25448
  const cwd = resolve26(root, "checkout");
25801
25449
  const homeRoot = resolve26(root, "agent-home");
25802
25450
  await rm8(root, { recursive: true, force: true });
25803
- await mkdir18(cwd, { recursive: true, mode: 448 });
25451
+ await mkdir19(cwd, { recursive: true, mode: 448 });
25804
25452
  let client;
25805
25453
  try {
25806
25454
  const agentEnv = {
@@ -25830,7 +25478,7 @@ async function runUpdateFunctionalProbe(input) {
25830
25478
  const { stateDirs, tmpDir } = harnessStateDirsFromEnv(agentEnv);
25831
25479
  const operatorHome = input.config.operatorHome ?? homedir10();
25832
25480
  const homeStateDirs = harnessHomeStateDirs(command, agentEnv.HOME ?? operatorHome);
25833
- await Promise.all(homeStateDirs.map((dir) => mkdir18(dir, { recursive: true })));
25481
+ await Promise.all(homeStateDirs.map((dir) => mkdir19(dir, { recursive: true })));
25834
25482
  spawnCommand = wrapAgentCommand({
25835
25483
  bwrapPath: input.config.bwrapPath,
25836
25484
  spec: {
@@ -25980,7 +25628,7 @@ async function runUpdateFunctionalProbe(input) {
25980
25628
 
25981
25629
  // apps/body/dist/current-release-probe.js
25982
25630
  import { spawn as spawn7 } from "node:child_process";
25983
- import { dirname as dirname14, join as join8 } from "node:path";
25631
+ import { dirname as dirname15, join as join9 } from "node:path";
25984
25632
  init_self_update();
25985
25633
  var CURRENT_RELEASE_PROBE_TIMEOUT_MS = 12e4;
25986
25634
  var UPDATE_PROBE_COMMAND = "update-probe";
@@ -26002,6 +25650,9 @@ function parseReport(line) {
26002
25650
  if (report.probe === "failed" && typeof report.reason === "string") {
26003
25651
  return { probe: "failed", reason: report.reason };
26004
25652
  }
25653
+ if (report.probe === "sandbox-unavailable" && typeof report.reason === "string") {
25654
+ return { probe: "sandbox-unavailable", reason: report.reason };
25655
+ }
26005
25656
  return void 0;
26006
25657
  }
26007
25658
  function outcomeFromReport(report) {
@@ -26010,12 +25661,17 @@ function outcomeFromReport(report) {
26010
25661
  return { kind: "served" };
26011
25662
  case "refused":
26012
25663
  return { kind: "refused", status: report.status, reason: report.reason };
25664
+ case "sandbox-unavailable":
25665
+ return { kind: "sandbox-unavailable", reason: report.reason };
26013
25666
  case "failed":
25667
+ if (report.reason.startsWith("functional update probe failed (sandbox-unavailable):")) {
25668
+ return { kind: "sandbox-unavailable", reason: report.reason };
25669
+ }
26014
25670
  return { kind: "unavailable", reason: report.reason };
26015
25671
  }
26016
25672
  }
26017
25673
  async function probeReleaseInSubprocess(input) {
26018
- const bundleDir = join8(input.layout.releasesRoot, input.releaseId);
25674
+ const bundleDir = join9(input.layout.releasesRoot, input.releaseId);
26019
25675
  const entrypoint = await resolveBundleEntrypoint(bundleDir);
26020
25676
  if (!entrypoint) {
26021
25677
  return { kind: "unavailable", reason: `release ${input.releaseId} has no runnable CLI entrypoint` };
@@ -26078,7 +25734,7 @@ async function runUpdateProbeCommand(args, options = {}) {
26078
25734
  const runtime = await readRuntimeRecord(configPath);
26079
25735
  const agent = runtimeAgentCommand(runtime);
26080
25736
  const config = loadBodyConfig({
26081
- workspaceRoot: join8(dirname14(configPath), "workspace"),
25737
+ workspaceRoot: join9(dirname15(configPath), "workspace"),
26082
25738
  llmEnvFile: runtime.llmEnvFile,
26083
25739
  env: { ...env, BUZZ_AGENT_BIN: agent.command, BUZZ_DEV_MCP_BIN: runtime.mcpBinary },
26084
25740
  agent
@@ -26096,21 +25752,22 @@ async function runUpdateProbeCommand(args, options = {}) {
26096
25752
  }
26097
25753
  const layout = beelineInstallLayout(env);
26098
25754
  const releaseId = (layout && await activeReleaseId(layout).catch(() => void 0)) ?? "unknown";
26099
- const runtimeDir = dirname14(configPath);
25755
+ const runtimeDir = dirname15(configPath);
26100
25756
  const outcome = await probeOutcome(() => (options.probe ?? runUpdateFunctionalProbe)({
26101
25757
  config,
26102
25758
  runtimeDir,
26103
25759
  releaseId,
26104
25760
  sandboxRequired: runtime.sandbox !== "off",
25761
+ sandboxUnavailableDetail: sandbox.advisory,
26105
25762
  // The successor's probe still holds `<runtimeDir>/update-functional-probe`.
26106
- probeRoot: join8(runtimeDir, "current-release-probe")
25763
+ probeRoot: join9(runtimeDir, "current-release-probe")
26107
25764
  }));
26108
- const report = outcome.kind === "served" ? { probe: "served" } : outcome.kind === "refused" ? { probe: "refused", status: outcome.status, reason: outcome.reason } : { probe: "failed", reason: outcome.reason };
25765
+ const report = outcome.kind === "served" ? { probe: "served" } : outcome.kind === "refused" ? { probe: "refused", status: outcome.status, reason: outcome.reason } : outcome.kind === "sandbox-unavailable" ? { probe: "sandbox-unavailable", reason: outcome.reason } : { probe: "failed", reason: outcome.reason };
26109
25766
  write(JSON.stringify(report));
26110
25767
  }
26111
25768
 
26112
25769
  // apps/body/dist/release-status.js
26113
- import { readFile as readFile13, readdir as readdir5, rename as rename6, writeFile as writeFile14 } from "node:fs/promises";
25770
+ import { readFile as readFile13, readdir as readdir5, rename as rename6, writeFile as writeFile15 } from "node:fs/promises";
26114
25771
  import { resolve as resolve27 } from "node:path";
26115
25772
  var DAEMON_RELEASE_STATUS_FILE = "release-status.json";
26116
25773
  var RELEASE_VERSION = /^v\d+\.\d+\.\d+$/;
@@ -26130,7 +25787,7 @@ async function writeDaemonReleaseStatus(runtimeDir, agentPubkey, identity, optio
26130
25787
  };
26131
25788
  const target = resolve27(runtimeDir, DAEMON_RELEASE_STATUS_FILE);
26132
25789
  const temporary = `${target}.${status.pid}.tmp`;
26133
- await writeFile14(temporary, `${JSON.stringify(status, null, 2)}
25790
+ await writeFile15(temporary, `${JSON.stringify(status, null, 2)}
26134
25791
  `, { mode: 384 });
26135
25792
  await rename6(temporary, target);
26136
25793
  return status;
@@ -26264,7 +25921,7 @@ var DaemonExitError = class extends Error {
26264
25921
  };
26265
25922
  async function runStoredDaemon(pathOrPointer) {
26266
25923
  const configPath = await resolveRuntimeConfigPath(pathOrPointer);
26267
- daemonFailureRuntimeDir = dirname15(configPath);
25924
+ daemonFailureRuntimeDir = dirname16(configPath);
26268
25925
  const accessMigration = await migrateRuntimeRecordAccessPolicy(configPath);
26269
25926
  let runtime = accessMigration.runtime;
26270
25927
  if (!runtime.transport) {
@@ -26276,7 +25933,7 @@ async function runStoredDaemon(pathOrPointer) {
26276
25933
  runtime = activated.runtime;
26277
25934
  const daemonApi = activated.client;
26278
25935
  const agent = runtimeAgentCommand(runtime);
26279
- await writeFile15(resolve29(dirname15(configPath), "daemon.pid"), `${process.pid}
25936
+ await writeFile16(resolve29(dirname16(configPath), "daemon.pid"), `${process.pid}
26280
25937
  `, { mode: 384 });
26281
25938
  const env = {
26282
25939
  ...process.env,
@@ -26284,7 +25941,7 @@ async function runStoredDaemon(pathOrPointer) {
26284
25941
  BUZZ_DEV_MCP_BIN: runtime.mcpBinary
26285
25942
  };
26286
25943
  const config = loadBodyConfig({
26287
- workspaceRoot: resolve29(dirname15(configPath), "workspace"),
25944
+ workspaceRoot: resolve29(dirname16(configPath), "workspace"),
26288
25945
  llmEnvFile: runtime.llmEnvFile,
26289
25946
  env,
26290
25947
  agent
@@ -26319,7 +25976,7 @@ async function runStoredDaemon(pathOrPointer) {
26319
25976
  const stop = () => controller.abort();
26320
25977
  process.once("SIGINT", stop);
26321
25978
  process.once("SIGTERM", stop);
26322
- const runtimeDir = dirname15(configPath);
25979
+ const runtimeDir = dirname16(configPath);
26323
25980
  const layout = beelineInstallLayout(process.env);
26324
25981
  const notifier = new SystemdNotifier();
26325
25982
  let rollbackAlertDrain;
@@ -26401,6 +26058,7 @@ async function runStoredDaemon(pathOrPointer) {
26401
26058
  runtimeDir,
26402
26059
  releaseId: loadedRelease ?? "unknown",
26403
26060
  sandboxRequired: runtime.sandbox !== "off",
26061
+ sandboxUnavailableDetail: sandbox.advisory,
26404
26062
  ...currentReleaseId ? {
26405
26063
  compareWithCurrentRelease: async (appeal) => {
26406
26064
  console.warn(`[thin-core] successor probe got no answer from the provider (${appeal.reason}); probing the current release ${currentReleaseId} for the same outcome`);
@@ -26465,7 +26123,7 @@ async function runStoredDaemon(pathOrPointer) {
26465
26123
  } finally {
26466
26124
  clearInterval(scratchSweepTimer);
26467
26125
  await notifier.stopping(stoppingStatus).catch(() => void 0);
26468
- const pidPath = resolve29(dirname15(configPath), "daemon.pid");
26126
+ const pidPath = resolve29(dirname16(configPath), "daemon.pid");
26469
26127
  const recorded = Number((await readFile14(pidPath, "utf8").catch(() => "")).trim());
26470
26128
  if (recorded === process.pid) {
26471
26129
  await unlink5(pidPath).catch(() => void 0);
@@ -26542,7 +26200,7 @@ async function main() {
26542
26200
  const agentPubkey = agentFlag >= 0 ? args[agentFlag + 1] : void 0;
26543
26201
  if (!configPath && agentPubkey) {
26544
26202
  const configs = await findAgentRuntimeConfigPaths(process.env, process.cwd());
26545
- configPath = configs.find((candidate) => dirname15(candidate).endsWith(agentPubkey));
26203
+ configPath = configs.find((candidate) => dirname16(candidate).endsWith(agentPubkey));
26546
26204
  }
26547
26205
  if (!configPath && agentPubkey) {
26548
26206
  throw new DaemonExitError(`unknown agent ${agentPubkey}: no durable runtime exists; refusing systemd restart loop`, UNKNOWN_AGENT_EXIT_STATUS);
@@ -26570,7 +26228,7 @@ async function main() {
26570
26228
  if (!agentPubkey)
26571
26229
  throw new Error("stop requires --agent <pubkey>");
26572
26230
  const configs = await findAgentRuntimeConfigPaths(process.env, process.cwd());
26573
- const configPath = configs.find((candidate) => dirname15(candidate).endsWith(agentPubkey));
26231
+ const configPath = configs.find((candidate) => dirname16(candidate).endsWith(agentPubkey));
26574
26232
  if (!configPath)
26575
26233
  throw new Error(`no stored runtime found for agent ${agentPubkey}`);
26576
26234
  const runtime = await readRuntimeRecord(configPath);