usebeeline 0.0.65 → 0.0.69

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,162 @@ 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
+ const pending = new Map(first.commands.map((command) => [command.id, command]));
18061
+ const claimed = /* @__PURE__ */ new Set();
18062
+ const notify2 = (commands = []) => {
18063
+ for (const command of commands)
18064
+ if (!claimed.has(command.id))
18065
+ pending.set(command.id, command);
18066
+ wake?.(false);
18067
+ };
18068
+ options.onWake?.(notify2);
18069
+ const off = api.liveSubscribe?.(roomId, void 0, void 0, (connected) => {
18070
+ if (!connected)
18071
+ wake?.(true);
18072
+ }, options.presence, notify2);
18073
+ try {
18074
+ while (!signal?.aborted) {
18075
+ if (options.closed && await options.closed())
18076
+ return;
18077
+ for (const command of [...pending.values()]) {
18078
+ validateServerCommand(command, roomId, agentId);
18079
+ if (busy && command.action !== "stop")
18080
+ continue;
18081
+ pending.delete(command.id);
18082
+ try {
18083
+ await api.execute("claimAgentCommand", {
18084
+ roomId,
18085
+ commandId: command.id,
18086
+ generationId: context.generationId
18087
+ });
18088
+ } catch (error) {
18089
+ options.onError?.(error);
18090
+ continue;
18091
+ }
18092
+ claimed.add(command.id);
18093
+ if (command.action === "stop") {
18094
+ options.stop(command.turnRequestId);
18095
+ await api.execute("acknowledgeAgentCommand", {
18096
+ roomId,
18097
+ commandId: command.id,
18098
+ generationId: context.generationId
18099
+ });
18100
+ } else {
18101
+ await context.enter(command);
18102
+ busy = options.run(command).catch((error) => {
18103
+ claimed.delete(command.id);
18104
+ options.onError?.(error);
18105
+ }).finally(async () => {
18106
+ await context.leave();
18107
+ busy = void 0;
18108
+ notify2();
18109
+ });
18110
+ }
18111
+ }
18112
+ options.onPoll?.();
18113
+ const reconcile = await new Promise((resolve30) => {
18114
+ const done = (needed) => {
18115
+ if (timer)
18116
+ clearTimeout(timer);
18117
+ signal?.removeEventListener("abort", aborted);
18118
+ wake = void 0;
18119
+ resolve30(needed);
18120
+ };
18121
+ const aborted = () => done(false);
18122
+ wake = done;
18123
+ const timer = setTimeout(() => done(true), options.pollMs ?? 1e3);
18124
+ signal?.addEventListener("abort", aborted, { once: true });
18125
+ if (pending.size && !busy)
18126
+ done(false);
18127
+ });
18128
+ if (signal?.aborted)
18129
+ break;
18130
+ if (reconcile) {
18131
+ const page = await api.execute("getAgentCommands", { roomId });
18132
+ if (page.commandProtocol !== 1)
18133
+ throw new Error("server command protocol changed; refusing intake");
18134
+ notify2(page.commands);
18135
+ }
18136
+ }
18137
+ } finally {
18138
+ off?.();
18139
+ options.onWake?.(void 0);
18140
+ if (context.current)
18141
+ options.stop(context.current.turnRequestId);
18142
+ await busy;
18143
+ }
18144
+ }
18145
+
17997
18146
  // apps/body/dist/monolith-corner-turn.js
17998
18147
  import { execFile as execFile4 } from "node:child_process";
17999
18148
  import { createHash as createHash4 } from "node:crypto";
18000
- import { mkdir as mkdir10 } from "node:fs/promises";
18149
+ import { mkdir as mkdir11 } from "node:fs/promises";
18001
18150
  import { homedir as homedir7 } from "node:os";
18002
- import { join as join6 } from "node:path";
18151
+ import { join as join7 } from "node:path";
18003
18152
  import { promisify as promisify3 } from "node:util";
18004
18153
 
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
18154
  // apps/body/dist/agent-home.js
18114
18155
  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";
18156
+ import { createHash as createHash3, randomUUID as randomUUID3 } from "node:crypto";
18157
+ 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
18158
  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";
18159
+ import { basename as basename3, dirname as dirname6, join as join4, relative as relative2, resolve as resolve13, sep } from "node:path";
18119
18160
 
18120
18161
  // apps/body/dist/beeline-skill.js
18121
18162
  import { readFileSync as readFileSync3 } from "node:fs";
@@ -18218,7 +18259,7 @@ var SQUIRE_GOVERNED_TOOLS = [
18218
18259
  var SQUIRE_GOVERNED_TOOL_SET = new Set(SQUIRE_GOVERNED_TOOLS);
18219
18260
 
18220
18261
  // apps/body/dist/openrouter-routing.js
18221
- import { mkdir as mkdir3, readFile as readFile5, writeFile as writeFile4 } from "node:fs/promises";
18262
+ import { mkdir as mkdir4, readFile as readFile5, writeFile as writeFile5 } from "node:fs/promises";
18222
18263
  import { resolve as resolve12 } from "node:path";
18223
18264
  var OPENROUTER_ENDPOINTS_BASE_URL = "https://openrouter.ai/api/v1/models";
18224
18265
  var OPENROUTER_COMPLETIONS_URL = "https://openrouter.ai/api/v1/chat/completions";
@@ -18348,8 +18389,8 @@ async function readCache(cacheDir, model) {
18348
18389
  }
18349
18390
  }
18350
18391
  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)}
18392
+ await mkdir4(cacheDir, { recursive: true, mode: 448 });
18393
+ await writeFile5(cachePath(cacheDir, value.model), `${JSON.stringify(value, null, 2)}
18353
18394
  `, {
18354
18395
  mode: 384
18355
18396
  });
@@ -18383,8 +18424,8 @@ async function readProbeCache(cacheDir, model) {
18383
18424
  }
18384
18425
  }
18385
18426
  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)}
18427
+ await mkdir4(cacheDir, { recursive: true, mode: 448 });
18428
+ await writeFile5(probeCachePath(cacheDir, value.model), `${JSON.stringify(value, null, 2)}
18388
18429
  `, {
18389
18430
  mode: 384
18390
18431
  });
@@ -18840,14 +18881,14 @@ async function prepareRoomAgentHome(input) {
18840
18881
  const root = resolve13(input.root);
18841
18882
  const operatorHome = input.operatorHome ?? homedir5();
18842
18883
  try {
18843
- await mkdir4(root, { recursive: true, mode: 448 });
18884
+ await mkdir5(root, { recursive: true, mode: 448 });
18844
18885
  const rootStats = await lstat(root);
18845
18886
  if (!rootStats.isDirectory() || rootStats.isSymbolicLink()) {
18846
18887
  throw new AgentHomeSecurityError(`agent home root is not an ordinary directory: ${root}`);
18847
18888
  }
18848
18889
  for (const subdir of HOME_SUBDIRS) {
18849
18890
  const path = resolve13(root, subdir);
18850
- await mkdir4(path, { recursive: true, mode: 448 });
18891
+ await mkdir5(path, { recursive: true, mode: 448 });
18851
18892
  await assertRealContainedDirectory(path, root);
18852
18893
  }
18853
18894
  } catch (error) {
@@ -18899,7 +18940,7 @@ async function provisionAgentSkillsAndMcp(root, operatorHome, skillReleaseId, fa
18899
18940
  }
18900
18941
  try {
18901
18942
  const gooseConfigDir = resolve13(root, "goose", "config");
18902
- await mkdir4(gooseConfigDir, { recursive: true, mode: 448 });
18943
+ await mkdir5(gooseConfigDir, { recursive: true, mode: 448 });
18903
18944
  for (const name of GOOSE_SHARED_CONFIG_FILES) {
18904
18945
  const source = resolve13(operatorHome, ".config", "goose", name);
18905
18946
  const target = resolve13(gooseConfigDir, name);
@@ -19011,18 +19052,18 @@ function filteredHarnessMcpToml(source) {
19011
19052
  return extractTomlSections(source, ["mcp_servers"], excluded);
19012
19053
  }
19013
19054
  async function provisionManagedSkillsDir(target, managedSkills, sharedSkills, optionalShares) {
19014
- const parent = dirname5(target);
19015
- await assertRealContainedDirectory(parent, dirname5(parent));
19055
+ const parent = dirname6(target);
19056
+ await assertRealContainedDirectory(parent, dirname6(parent));
19016
19057
  const plan = await planManagedSkills(managedSkills, sharedSkills, optionalShares);
19017
19058
  if (await materializedSkillManifest(target) === plan.manifest)
19018
19059
  return;
19019
- const staged = resolve13(parent, `.skills.${process.pid}.${randomUUID2()}.tmp`);
19020
- await mkdir4(staged, { mode: 448 });
19060
+ const staged = resolve13(parent, `.skills.${process.pid}.${randomUUID3()}.tmp`);
19061
+ await mkdir5(staged, { mode: 448 });
19021
19062
  try {
19022
19063
  for (const entry of plan.entries) {
19023
19064
  if (entry.kind === "managed") {
19024
19065
  const skillDir = resolve13(staged, entry.name);
19025
- await mkdir4(skillDir, { recursive: true });
19066
+ await mkdir5(skillDir, { recursive: true });
19026
19067
  await writeIsolatedHarnessFile(resolve13(skillDir, "SKILL.md"), entry.content);
19027
19068
  } else {
19028
19069
  await copySafeSkillTree(entry.source, resolve13(staged, entry.name), entry.source);
@@ -19052,8 +19093,8 @@ async function planManagedSkills(managedSkills, sharedSkills, optionalShares) {
19052
19093
  try {
19053
19094
  const tree = [];
19054
19095
  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))}`)
19096
+ directory: async (rel) => void tree.push(`d ${join4(shared.name, rel)}`),
19097
+ file: async (rel, realPath) => void tree.push(`f ${join4(shared.name, rel)} ${sha2563(await readFile6(realPath))}`)
19057
19098
  });
19058
19099
  entries.push({ kind: "shared", name: shared.name, source: shared.source });
19059
19100
  lines.push(...tree);
@@ -19073,7 +19114,7 @@ async function materializedSkillManifest(target) {
19073
19114
  const visit = async (directory, prefix) => {
19074
19115
  for (const entry of await readdir2(directory)) {
19075
19116
  const path = resolve13(directory, entry);
19076
- const rel = prefix ? join3(prefix, entry) : entry;
19117
+ const rel = prefix ? join4(prefix, entry) : entry;
19077
19118
  const entryStats = await lstat(path);
19078
19119
  if (entryStats.isSymbolicLink())
19079
19120
  return false;
@@ -19241,7 +19282,7 @@ async function walkSafeSkillTree(source, sourceRoot, visitor, rel = "") {
19241
19282
  for (const entry of await readdir2(resolvedSource)) {
19242
19283
  if (entry === "." || entry === "..")
19243
19284
  throw new Error("invalid shared skill entry");
19244
- await walkSafeSkillTree(resolve13(source, entry), sourceRoot, visitor, rel ? join3(rel, entry) : entry);
19285
+ await walkSafeSkillTree(resolve13(source, entry), sourceRoot, visitor, rel ? join4(rel, entry) : entry);
19245
19286
  }
19246
19287
  return;
19247
19288
  }
@@ -19253,7 +19294,7 @@ async function walkSafeSkillTree(source, sourceRoot, visitor, rel = "") {
19253
19294
  async function copySafeSkillTree(source, target, sourceRoot) {
19254
19295
  await walkSafeSkillTree(source, sourceRoot, {
19255
19296
  directory: async (rel) => {
19256
- await mkdir4(resolve13(target, rel), { mode: 448 });
19297
+ await mkdir5(resolve13(target, rel), { mode: 448 });
19257
19298
  },
19258
19299
  file: async (rel, realPath) => {
19259
19300
  const destination = resolve13(target, rel);
@@ -19263,14 +19304,14 @@ async function copySafeSkillTree(source, target, sourceRoot) {
19263
19304
  });
19264
19305
  }
19265
19306
  async function writeIsolatedHarnessFile(path, content) {
19266
- const parent = dirname5(path);
19307
+ const parent = dirname6(path);
19267
19308
  const parentStats = await lstat(parent);
19268
19309
  if (!parentStats.isDirectory() || parentStats.isSymbolicLink()) {
19269
19310
  throw new Error(`isolated harness parent is not a real directory: ${parent}`);
19270
19311
  }
19271
- const temporary = resolve13(parent, `.${basename3(path)}.${process.pid}.${randomUUID2()}.tmp`);
19312
+ const temporary = resolve13(parent, `.${basename3(path)}.${process.pid}.${randomUUID3()}.tmp`);
19272
19313
  try {
19273
- await writeFile5(temporary, content, { mode: 384, flag: "wx" });
19314
+ await writeFile6(temporary, content, { mode: 384, flag: "wx" });
19274
19315
  await chmod2(temporary, 384);
19275
19316
  await rename2(temporary, path);
19276
19317
  } finally {
@@ -19313,8 +19354,8 @@ function harnessStateDirsFromEnv(env) {
19313
19354
  }
19314
19355
 
19315
19356
  // 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";
19357
+ import { mkdir as mkdir6, writeFile as writeFile7 } from "node:fs/promises";
19358
+ import { basename as basename4, extname, join as join5 } from "node:path";
19318
19359
  var MAX_ATTACHMENT_BYTES = 25 * 1024 * 1024;
19319
19360
  var MEDIA_TTL_HOURS = 24;
19320
19361
  var EXPIRED_REASON = `expired: attachments are kept for ${MEDIA_TTL_HOURS} hours and these bytes are past that window`;
@@ -19334,7 +19375,7 @@ async function deliverAttachments(attachments, dir, fetchImpl = fetch) {
19334
19375
  if (!attachments.length)
19335
19376
  return [];
19336
19377
  const taken = /* @__PURE__ */ new Set();
19337
- await mkdir5(dir, { recursive: true });
19378
+ await mkdir6(dir, { recursive: true });
19338
19379
  return Promise.all(attachments.map(async (attachment, index) => {
19339
19380
  const tooLarge = (bytes) => ({
19340
19381
  attachment,
@@ -19358,8 +19399,8 @@ async function deliverAttachments(attachments, dir, fetchImpl = fetch) {
19358
19399
  const bytes = Buffer.from(await response.arrayBuffer());
19359
19400
  if (bytes.length > MAX_ATTACHMENT_BYTES)
19360
19401
  return tooLarge(bytes.length);
19361
- const path = join4(dir, safeFileName(attachment, index, taken));
19362
- await writeFile6(path, bytes);
19402
+ const path = join5(dir, safeFileName(attachment, index, taken));
19403
+ await writeFile7(path, bytes);
19363
19404
  const mimeType = attachment.mimeType ?? response.headers.get("content-type") ?? "";
19364
19405
  if (!mimeType.startsWith("image/"))
19365
19406
  return { attachment, path };
@@ -19545,13 +19586,6 @@ function isCornerStatusRestatement(reply, systemLines) {
19545
19586
  var TurnStoppedError = class extends Error {
19546
19587
  name = "TurnStoppedError";
19547
19588
  };
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
19589
 
19556
19590
  // apps/body/dist/turn-stream.js
19557
19591
  function durableReplyText(agentText) {
@@ -19724,7 +19758,7 @@ function sessionConfigFingerprint(input) {
19724
19758
  }
19725
19759
 
19726
19760
  // apps/body/dist/pi-mcp-bridge.js
19727
- import { mkdir as mkdir6 } from "node:fs/promises";
19761
+ import { mkdir as mkdir7 } from "node:fs/promises";
19728
19762
  import { resolve as resolve14 } from "node:path";
19729
19763
  var PI_MCP_BRIDGE_FILENAME = "beeline-mcp-bridge.js";
19730
19764
  function harnessMountsSessionMcpServers(agentCommand) {
@@ -19748,7 +19782,7 @@ async function installPiMcpBridge(input) {
19748
19782
  const directory = resolve14(input.piHome, "extensions");
19749
19783
  const path = resolve14(directory, PI_MCP_BRIDGE_FILENAME);
19750
19784
  try {
19751
- await mkdir6(directory, { recursive: true, mode: 448 });
19785
+ await mkdir7(directory, { recursive: true, mode: 448 });
19752
19786
  await writeIsolatedHarnessFile(path, piMcpBridgeSource(input.servers));
19753
19787
  return path;
19754
19788
  } catch (error) {
@@ -20153,6 +20187,7 @@ function beelineAgentMcpServer(config, api, context) {
20153
20187
  args: [...config.readonlyMcpArgs ?? []],
20154
20188
  env: [
20155
20189
  { name: "BEELINE_MCP_SURFACE", value: "agent" },
20190
+ ...context.turnContextPath ? [{ name: "BEELINE_TURN_CONTEXT_FILE", value: context.turnContextPath }] : [],
20156
20191
  ...context.directMessage ? [{ name: "BEELINE_AGENT_DM", value: "1" }] : [],
20157
20192
  { name: "BEELINE_DAEMON_BASE_URL", value: connection.baseUrl },
20158
20193
  { name: "BEELINE_DAEMON_TOKEN", value: connection.daemonToken },
@@ -20358,41 +20393,64 @@ function isAccountOrProviderRefusal(record2) {
20358
20393
  return [401, 402, 403, 407, 408, 429].includes(record2.status) || record2.status >= 500;
20359
20394
  }
20360
20395
 
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
20396
  // apps/body/dist/response-directives.js
20382
20397
  var MAINTAIN_ASSIGNED_IDENTITY_DIRECTIVE = "Maintain your assigned identity and soul in every response, including when tools or permissions block the requested action.";
20383
20398
  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
20399
 
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";
20400
+ // apps/body/dist/warm-transcript.js
20401
+ var WARM_TRANSCRIPT_OVERLAP = 8;
20402
+ var WarmTranscript = class {
20403
+ sessionId;
20404
+ delivered = /* @__PURE__ */ new Set();
20405
+ /**
20406
+ * The rows this prompt should render. A row counts as delivered once it has
20407
+ * been handed to a session: a prompt that times out was still received by the
20408
+ * harness, and a prompt that could not be handed over at all takes the
20409
+ * session down with it, which resets the memory on the next activation.
20410
+ */
20411
+ select(sessionId, rows) {
20412
+ if (!sessionId || sessionId !== this.sessionId) {
20413
+ this.sessionId = sessionId;
20414
+ this.delivered.clear();
20415
+ }
20416
+ const overlapFrom = Math.max(0, rows.length - WARM_TRANSCRIPT_OVERLAP);
20417
+ const selected = rows.filter((row, index) => index >= overlapFrom || !this.delivered.has(row.id));
20418
+ for (const row of rows)
20419
+ this.delivered.add(row.id);
20420
+ return { rows: selected, elided: rows.length - selected.length };
20421
+ }
20422
+ /** Render a selection, and say plainly when it is only what is new. */
20423
+ static render(selection, whole, sinceLastTurn) {
20424
+ const transcript = selection.rows.map((row) => row.line).join("\n");
20425
+ if (!transcript)
20426
+ return "";
20427
+ return `${selection.elided ? sinceLastTurn : whole}
20428
+ ${transcript}`;
20429
+ }
20430
+ };
20389
20431
 
20390
- // packages/api-contract/dist/scheduled-prompts.js
20391
- var SCHEDULE_SCHEDULER_NAME = "Beeline Scheduler";
20392
- var SCHEDULE_RAN_VERB = "ran a schedule for";
20432
+ // apps/body/dist/turn-receipt-heartbeat.js
20433
+ var TURN_RECEIPT_HEARTBEAT_MS = 3e4;
20434
+ async function withTurnReceiptHeartbeat(api, receipt, task, onHeartbeatError) {
20435
+ let tail = Promise.resolve();
20436
+ const timer = setInterval(() => {
20437
+ tail = tail.catch(() => void 0).then(() => api.execute("postAgentTurnReceipt", {
20438
+ ...receipt,
20439
+ status: "working",
20440
+ heartbeat: true
20441
+ })).then(() => void 0).catch(onHeartbeatError);
20442
+ }, TURN_RECEIPT_HEARTBEAT_MS);
20443
+ timer.unref?.();
20444
+ try {
20445
+ return await task();
20446
+ } finally {
20447
+ clearInterval(timer);
20448
+ await tail;
20449
+ }
20450
+ }
20393
20451
 
20394
20452
  // apps/body/dist/turn-trace.js
20395
- import { appendFile, mkdir as mkdir7, readdir as readdir4, rm as rm3 } from "node:fs/promises";
20453
+ import { appendFile, mkdir as mkdir8, readdir as readdir4, rm as rm3 } from "node:fs/promises";
20396
20454
  import { resolve as resolve17 } from "node:path";
20397
20455
  import { performance as performance2 } from "node:perf_hooks";
20398
20456
  var TURN_PHASES = [
@@ -20646,7 +20704,7 @@ var TurnTraceFile = class {
20646
20704
  this.tail = this.tail.catch(() => void 0).then(async () => {
20647
20705
  const now2 = (this.options.clock ?? (() => /* @__PURE__ */ new Date()))();
20648
20706
  const path = this.path(now2);
20649
- await mkdir7(this.directory, { recursive: true, mode: 448 });
20707
+ await mkdir8(this.directory, { recursive: true, mode: 448 });
20650
20708
  await appendFile(path, `${JSON.stringify(record2)}
20651
20709
  `, { mode: 384 });
20652
20710
  await this.prune(now2);
@@ -20668,58 +20726,65 @@ var TurnTraceFile = class {
20668
20726
  }
20669
20727
  };
20670
20728
 
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;
20729
+ // apps/body/dist/corner-github-auth.js
20730
+ import { chmod as chmod3, mkdir as mkdir9, writeFile as writeFile8 } from "node:fs/promises";
20731
+ import { delimiter as delimiter2, resolve as resolve18 } from "node:path";
20732
+ async function installCornerGitHubWrappers(input) {
20733
+ const bin = resolve18(input.root, "beeline-github-bin");
20734
+ await mkdir9(bin, { recursive: true, mode: 448 });
20735
+ const common = {
20736
+ node: process.execPath,
20737
+ cli: input.cliEntrypoint,
20738
+ config: input.runtimeConfigPath,
20739
+ room: input.roomId
20740
+ };
20741
+ await writeLauncher(resolve18(bin, "git"), { ...common, command: input.gitBinary });
20742
+ if (input.ghBinary)
20743
+ await writeLauncher(resolve18(bin, "gh"), { ...common, command: input.ghBinary });
20744
+ return {
20745
+ PATH: [bin, input.inheritedPath].filter(Boolean).join(delimiter2),
20746
+ // Static startup tokens take precedence over the refreshed token in gh.
20747
+ GH_TOKEN: "",
20748
+ GITHUB_TOKEN: ""
20749
+ };
20750
+ }
20751
+ async function writeLauncher(path, config) {
20752
+ const source = `#!/usr/bin/env node
20753
+ import { spawnSync } from 'node:child_process';
20754
+ const config = ${JSON.stringify(config)};
20755
+ const authFailure = /(?:authentication failed|bad credentials|could not read username|http(?:\\/\\d(?:\\.\\d)?)? 40[13]|status (?:code )?40[13])/i;
20756
+ function token() {
20757
+ const result = spawnSync(config.node, [config.cli, 'corner-read-token', '--config', config.config, '--room', config.room], { encoding: 'utf8' });
20758
+ if (result.status !== 0) {
20759
+ process.stderr.write(result.stderr || 'Beeline could not refresh the repository credential.\\n');
20760
+ process.exit(result.status || 1);
20689
20761
  }
20762
+ return result.stdout.trim();
20763
+ }
20764
+ function run(value) {
20765
+ const env = { ...process.env, GH_TOKEN: value, GITHUB_TOKEN: value, GIT_TERMINAL_PROMPT: '0' };
20766
+ return spawnSync(config.command, process.argv.slice(2), { env, encoding: 'buffer', stdio: ['inherit', 'pipe', 'pipe'] });
20767
+ }
20768
+ let result = run(token());
20769
+ const diagnostic = Buffer.concat([result.stdout || Buffer.alloc(0), result.stderr || Buffer.alloc(0)]).toString('utf8');
20770
+ if (result.status !== 0 && authFailure.test(diagnostic)) result = run(token());
20771
+ if (result.stdout) process.stdout.write(result.stdout);
20772
+ if (result.stderr) process.stderr.write(result.stderr);
20773
+ if (result.error) throw result.error;
20774
+ process.exit(result.status ?? 1);
20775
+ `;
20776
+ await writeFile8(path, source, { mode: 448 });
20777
+ await chmod3(path, 448);
20690
20778
  }
20691
20779
 
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
- };
20780
+ // apps/body/dist/monolith-room-turn.js
20781
+ import { mkdir as mkdir10 } from "node:fs/promises";
20782
+ import { homedir as homedir6 } from "node:os";
20783
+ import { join as join6 } from "node:path";
20784
+
20785
+ // packages/api-contract/dist/scheduled-prompts.js
20786
+ var SCHEDULE_SCHEDULER_NAME = "Beeline Scheduler";
20787
+ var SCHEDULE_RAN_VERB = "ran a schedule for";
20723
20788
 
20724
20789
  // apps/body/dist/monolith-room-turn.js
20725
20790
  function isRoomMcpPermissionRequest(request, mountedServers = ROOM_MOUNTED_MCP_SERVERS) {
@@ -20727,15 +20792,6 @@ function isRoomMcpPermissionRequest(request, mountedServers = ROOM_MOUNTED_MCP_S
20727
20792
  return false;
20728
20793
  return isMountedMcpToolPermissionRequest(request, mountedServers);
20729
20794
  }
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
20795
  function isScheduledPrompt(item, agentId) {
20740
20796
  if (item.type !== "system" || !item.mentionIds.includes(agentId))
20741
20797
  return false;
@@ -20754,30 +20810,6 @@ function inboxItemAuthorName(item, agentId, names) {
20754
20810
  function inboxItemPromptBody(item, agentId) {
20755
20811
  return isScheduledPrompt(item, agentId) ? item.systemEvent?.consequence ?? item.body : item.body;
20756
20812
  }
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
20813
  function pendingGrantToolCall(call) {
20782
20814
  if (!/(?:^|[._:/-])request_grant$/i.test(call.title ?? ""))
20783
20815
  return false;
@@ -20800,6 +20832,7 @@ function roomMentionDirectory(roster, selfId) {
20800
20832
  return "";
20801
20833
  return [
20802
20834
  "Room members, and the exact spelling that tags each one:",
20835
+ "An exact agent tag assigns that agent work; use it only when you are asking that agent to act.",
20803
20836
  ...rows,
20804
20837
  "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
20838
  ].join("\n");
@@ -20812,7 +20845,8 @@ function agentReplyMentionIds(text2, roster, authorId) {
20812
20845
  for (const member of roster.members) {
20813
20846
  if (member.identityId === authorId)
20814
20847
  continue;
20815
- for (const raw of [member.name, member.handle, member.soul?.name]) {
20848
+ const rawAliases = member.kind === "agent" ? [member.handle] : [member.name, member.handle, member.soul?.name];
20849
+ for (const raw of rawAliases) {
20816
20850
  const display = raw?.trim().replace(/^@/, "");
20817
20851
  if (!display)
20818
20852
  continue;
@@ -20823,7 +20857,7 @@ function agentReplyMentionIds(text2, roster, authorId) {
20823
20857
  }
20824
20858
  }
20825
20859
  for (const member of roster.members) {
20826
- if (member.identityId === authorId || !member.handle)
20860
+ if (member.identityId === authorId || member.kind === "agent" || !member.handle)
20827
20861
  continue;
20828
20862
  const handle = member.handle.trim().replace(/^@/, "").toLocaleLowerCase();
20829
20863
  const canonical = aliases.get(handle);
@@ -20846,12 +20880,11 @@ function agentReplyMentionIds(text2, roster, authorId) {
20846
20880
  }
20847
20881
  var MonolithRoomTurnLoop = class {
20848
20882
  options;
20883
+ commandContext;
20849
20884
  agent;
20850
- reconciliationRequested = true;
20851
20885
  wakeIntake;
20852
20886
  /** Called by the daemon's one slow workspace reconciliation sweep. */
20853
20887
  requestReconciliation() {
20854
- this.reconciliationRequested = true;
20855
20888
  this.wakeIntake?.();
20856
20889
  this.wakeIntake = void 0;
20857
20890
  }
@@ -20869,7 +20902,6 @@ var MonolithRoomTurnLoop = class {
20869
20902
  turnInstructionPrefix = "";
20870
20903
  activeTurn;
20871
20904
  queuedTurns = [];
20872
- continuityRebuildRequested = false;
20873
20905
  /** Session scratch directory attachments are downloaded into (`TMPDIR/beeline-attachments`). */
20874
20906
  attachmentDir;
20875
20907
  /** Whether the pinned model takes images; `undefined` when the pin did not say. */
@@ -20888,18 +20920,21 @@ var MonolithRoomTurnLoop = class {
20888
20920
  pausedOnGrantRequestId;
20889
20921
  /** Operator-local turn traces; built once when the daemon configured a directory. */
20890
20922
  turnTraceSink;
20891
- /** Per-sender continuity, shared in shape with corner intake. */
20892
- responseRule = new AgentResponseRule();
20893
20923
  constructor(options) {
20894
20924
  this.options = options;
20895
20925
  this.agent = runtimeIdentity(options.runtime.agent);
20926
+ this.commandContext = new CommandExecutionContext(options.config.agentHomeRoot);
20927
+ this.options = { ...options, api: this.commandContext.bind(options.api) };
20896
20928
  options.grantRunner?.register(options.roomId, {
20897
20929
  workspaceId: options.workspaceId,
20898
20930
  cwd: options.cwd,
20899
20931
  // A top-level Room keeps its read-only promise for grants too: the runner
20900
20932
  // wraps the command in this Room's own mount table (C94).
20901
20933
  writePolicy: () => this.grantWritePolicy(),
20902
- turn: () => this.currentTurnForRunner()
20934
+ turn: () => {
20935
+ const turn = this.currentTurnForRunner();
20936
+ return turn ? { ...turn, generationId: this.commandContext.generationId } : void 0;
20937
+ }
20903
20938
  });
20904
20939
  }
20905
20940
  isBusy() {
@@ -20952,9 +20987,6 @@ var MonolithRoomTurnLoop = class {
20952
20987
  const name = this.memberNames.get(authorId);
20953
20988
  return { pubkey: authorId, ...name ? { name } : {} };
20954
20989
  }
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
20990
  async refreshPersonaForSoulUpdate() {
20959
20991
  await this.options.scheduler.suspend(this.options.roomId);
20960
20992
  }
@@ -20971,7 +21003,6 @@ var MonolithRoomTurnLoop = class {
20971
21003
  workspaceId: this.options.workspaceId
20972
21004
  });
20973
21005
  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
21006
  return roster;
20976
21007
  }
20977
21008
  /**
@@ -20993,7 +21024,7 @@ var MonolithRoomTurnLoop = class {
20993
21024
  const cached = this.deliveredAttachments.get(item.id);
20994
21025
  if (cached)
20995
21026
  return cached;
20996
- const delivered = await deliverAttachments(item.attachments, join5(this.attachmentDir, item.id.replace(/[^\w-]/g, "_")), this.options.fetchImpl);
21027
+ const delivered = await deliverAttachments(item.attachments, join6(this.attachmentDir, item.id.replace(/[^\w-]/g, "_")), this.options.fetchImpl);
20997
21028
  this.deliveredAttachments.set(item.id, withoutImageData(delivered));
20998
21029
  return delivered;
20999
21030
  }
@@ -21060,7 +21091,7 @@ var MonolithRoomTurnLoop = class {
21060
21091
  agentName: self?.name ?? this.agent.name
21061
21092
  });
21062
21093
  const directMessage = Array.isArray(repositoryState.directParticipants) && repositoryState.directParticipants.length === 2;
21063
- await mkdir8(this.options.cwd, { recursive: true });
21094
+ await mkdir10(this.options.cwd, { recursive: true });
21064
21095
  const selection = configuration.model || configuration.effort ? { model: configuration.model, effort: configuration.effort } : this.options.config.modelSelection;
21065
21096
  const homeOverlay = this.options.config.agentHomeRoot ? await prepareRoomAgentHome({
21066
21097
  root: this.options.config.agentHomeRoot,
@@ -21086,14 +21117,14 @@ var MonolithRoomTurnLoop = class {
21086
21117
  }, selection);
21087
21118
  const operatorHome = this.options.config.operatorHome ?? homedir6();
21088
21119
  const { stateDirs, tmpDir } = harnessStateDirsFromEnv(agentEnv);
21089
- this.attachmentDir = tmpDir ? join5(tmpDir, "beeline-attachments") : void 0;
21120
+ this.attachmentDir = tmpDir ? join6(tmpDir, "beeline-attachments") : void 0;
21090
21121
  this.sessionScratchDir = tmpDir;
21091
21122
  this.sessionStateDirs = stateDirs;
21092
21123
  const homeStateDirs = harnessHomeStateDirs(command, agentEnv.HOME ?? operatorHome);
21093
- await Promise.all(homeStateDirs.map((dir) => mkdir8(dir, { recursive: true })));
21124
+ await Promise.all(homeStateDirs.map((dir) => mkdir10(dir, { recursive: true })));
21094
21125
  const attachScratchRoot = this.options.config.agentHomeRoot ?? tmpDir;
21095
21126
  if (attachScratchRoot)
21096
- await mkdir8(attachScratchRoot, { recursive: true });
21127
+ await mkdir10(attachScratchRoot, { recursive: true });
21097
21128
  const spawnCommand = wrapAgentCommand({
21098
21129
  bwrapPath: this.options.config.bwrapPath,
21099
21130
  spec: {
@@ -21119,6 +21150,7 @@ var MonolithRoomTurnLoop = class {
21119
21150
  // images dir, say), so anything inside the overlay it could possibly
21120
21151
  // have written must be attachable, whatever subdirectory that is.
21121
21152
  attachScratchRoot,
21153
+ turnContextPath: this.commandContext.path,
21122
21154
  directMessage,
21123
21155
  ...this.options.grantRunnerEndpoint ? { grantRunner: this.options.grantRunnerEndpoint } : {}
21124
21156
  })
@@ -21251,8 +21283,6 @@ var MonolithRoomTurnLoop = class {
21251
21283
  }).finally(() => {
21252
21284
  if (this.activeTurn === active) {
21253
21285
  this.activeTurn = void 0;
21254
- if (active.rebuildContinuity)
21255
- this.continuityRebuildRequested = true;
21256
21286
  this.wakeIntake?.();
21257
21287
  this.wakeIntake = void 0;
21258
21288
  }
@@ -21279,24 +21309,6 @@ var MonolithRoomTurnLoop = class {
21279
21309
  if (this.client && this.sessionId)
21280
21310
  this.client.sessionCancel(this.sessionId);
21281
21311
  }
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
21312
  async prompt(active) {
21301
21313
  const { item } = active;
21302
21314
  const api = this.options.api;
@@ -21309,7 +21321,7 @@ var MonolithRoomTurnLoop = class {
21309
21321
  agentId: this.agent.publicKey,
21310
21322
  roomId: this.options.roomId,
21311
21323
  requestId: item.id,
21312
- generationId: `${this.agent.publicKey}:${this.options.roomId}`
21324
+ generationId: this.commandContext.generationId
21313
21325
  }, async () => {
21314
21326
  await api.execute("postAgentActivity", {
21315
21327
  agentId: this.agent.publicKey,
@@ -21339,7 +21351,7 @@ var MonolithRoomTurnLoop = class {
21339
21351
  id: message.id,
21340
21352
  line: roomMessagePrompt(names.get(message.authorId) ?? message.authorId.slice(0, 12), message.body, message.attachments, this.deliveredAttachments.get(message.id), this.acceptsImages())
21341
21353
  }));
21342
- const grantDecision = isGrantDecisionLine(item, this.agent.publicKey);
21354
+ const grantDecision = this.commandContext.current?.action === "resume";
21343
21355
  const resumedRequestId = grantDecision ? this.pausedOnGrantRequestId : void 0;
21344
21356
  if (grantDecision)
21345
21357
  this.pausedOnGrantRequestId = void 0;
@@ -21417,8 +21429,7 @@ var MonolithRoomTurnLoop = class {
21417
21429
  }
21418
21430
  }
21419
21431
  if (active.cancelled) {
21420
- const stoppedText = durableReplyText(result.agentText);
21421
- await stream.settle(stoppedText, stoppedText ? { triggerMessageId: item.id } : {});
21432
+ stream.close();
21422
21433
  throw new TurnStoppedError("turn stopped by the requester");
21423
21434
  }
21424
21435
  active.phase = "finishing";
@@ -21453,21 +21464,10 @@ var MonolithRoomTurnLoop = class {
21453
21464
  reply = stripCornerOpenEcho(reply);
21454
21465
  }
21455
21466
  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
21467
  await trace.measure("publish", () => stream.settle(reply, reply ? {
21462
21468
  triggerMessageId: item.id,
21463
21469
  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));
21470
+ } : {}));
21471
21471
  }, { priority: "interactive", roomKey: this.options.roomId });
21472
21472
  }, (error) => console.error(`[thin-core] monolith Room ${this.options.roomId} receipt heartbeat failed:`, error));
21473
21473
  await api.execute("postAgentTurnReceipt", {
@@ -21475,7 +21475,7 @@ var MonolithRoomTurnLoop = class {
21475
21475
  roomId: this.options.roomId,
21476
21476
  requestId: item.id,
21477
21477
  status: "complete",
21478
- generationId: `${this.agent.publicKey}:${this.options.roomId}`
21478
+ generationId: this.commandContext.generationId
21479
21479
  });
21480
21480
  await trace.finish("complete");
21481
21481
  } catch (error) {
@@ -21490,7 +21490,7 @@ var MonolithRoomTurnLoop = class {
21490
21490
  roomId: this.options.roomId,
21491
21491
  requestId: item.id,
21492
21492
  status: "failed",
21493
- generationId: `${this.agent.publicKey}:${this.options.roomId}`,
21493
+ generationId: this.commandContext.generationId,
21494
21494
  reason
21495
21495
  });
21496
21496
  await trace.finish("failed", reason);
@@ -21501,137 +21501,37 @@ var MonolithRoomTurnLoop = class {
21501
21501
  }
21502
21502
  async run() {
21503
21503
  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
21504
  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);
21505
+ await runServerCommandIntake({
21506
+ api,
21507
+ roomId,
21508
+ agentId: this.agent.publicKey,
21509
+ context: this.commandContext,
21510
+ signal,
21511
+ pollMs: this.options.pollMs,
21512
+ presence: {
21513
+ ...this.options.config.daemonReleaseVersion ? { releaseVersion: this.options.config.daemonReleaseVersion } : {},
21514
+ ...this.options.config.daemonSourceSha ? { sourceSha: this.options.config.daemonSourceSha } : {},
21515
+ available: !this.options.config.modelUnavailable
21516
+ },
21517
+ onWake: (wake) => {
21518
+ this.wakeIntake = wake;
21519
+ },
21520
+ onPoll: () => this.options.health.poll(),
21521
+ onError: (error) => console.error("[thin-core] Room command failed", error),
21522
+ stop: (requestId) => this.stopTurn(requestId),
21523
+ run: async (command) => {
21524
+ const item = {
21525
+ ...command.source,
21526
+ id: command.turnRequestId,
21527
+ body: command.action === "resume" ? `Resume the paused turn. The server supplied this grant decision: ${command.source.body}` : command.source.body
21528
+ };
21529
+ this.startPrompt(item);
21530
+ await this.activeTurn?.promise;
21625
21531
  }
21626
- }
21532
+ });
21627
21533
  } finally {
21628
- stopLive?.();
21629
- this.wakeIntake = void 0;
21630
21534
  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
21535
  await this.options.scheduler.suspend(roomId);
21636
21536
  }
21637
21537
  }
@@ -21641,70 +21541,6 @@ function roomMessagePrompt(author, body, attachments, delivered, harnessAcceptsI
21641
21541
  const rendered = author ? `${author}: ${message}` : message;
21642
21542
  return [rendered, ...attachmentPromptLines(attachments, delivered, harnessAcceptsImages)].join("\n");
21643
21543
  }
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
21544
 
21709
21545
  // apps/body/dist/monolith-corner-turn.js
21710
21546
  var execFileAsync3 = promisify3(execFile4);
@@ -21835,18 +21671,13 @@ async function cornerToolActivity(call, worktreePath, requestedBy) {
21835
21671
  ...paths.length ? { files: paths.map((path) => ({ path })) } : {}
21836
21672
  };
21837
21673
  }
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
21674
  var MonolithCornerTurnLoop = class {
21843
21675
  options;
21676
+ commandContext;
21844
21677
  agent;
21845
- reconciliationRequested = true;
21846
21678
  wakeIntake;
21847
21679
  /** Called by the daemon's one slow workspace reconciliation sweep. */
21848
21680
  requestReconciliation() {
21849
- this.reconciliationRequested = true;
21850
21681
  this.wakeIntake?.();
21851
21682
  this.wakeIntake = void 0;
21852
21683
  }
@@ -21878,15 +21709,9 @@ var MonolithCornerTurnLoop = class {
21878
21709
  turnTraceSink;
21879
21710
  memberNames = /* @__PURE__ */ new Map();
21880
21711
  /** Agent identities in this Workspace, so a mention can be told from a human's. */
21881
- agentMembers = /* @__PURE__ */ new Set();
21882
- rosterAvailable = false;
21883
21712
  /** Per-sender continuity, shared in shape with top-level Room intake. */
21884
- responseRule = new AgentResponseRule();
21885
- continuityRebuildRequested = false;
21886
21713
  /** The member agent that owns corner-wide lifecycle facts such as checks. */
21887
- carrier;
21888
21714
  /** The last server check state that started a turn; the same state never starts another. */
21889
- lastChecksState;
21890
21715
  /**
21891
21716
  * Request ids the requester has stopped. A corner's intake is blocked while
21892
21717
  * its turn runs, so a stop is recorded from the live-push callback and read
@@ -21897,6 +21722,8 @@ var MonolithCornerTurnLoop = class {
21897
21722
  constructor(options) {
21898
21723
  this.options = options;
21899
21724
  this.agent = runtimeIdentity(options.runtime.agent);
21725
+ this.commandContext = new CommandExecutionContext(options.config.agentHomeRoot);
21726
+ this.options = { ...options, api: this.commandContext.bind(options.api) };
21900
21727
  options.grantRunner?.register(options.cornerId, {
21901
21728
  workspaceId: options.workspaceId,
21902
21729
  cwd: options.worktreePath,
@@ -21907,15 +21734,12 @@ var MonolithCornerTurnLoop = class {
21907
21734
  surface: "corner",
21908
21735
  ...this.sessionScratchDir ? { scratch: this.sessionScratchDir } : {}
21909
21736
  }),
21910
- turn: () => this.currentTurn
21737
+ turn: () => this.currentTurn ? { ...this.currentTurn, generationId: this.commandContext.generationId } : void 0
21911
21738
  });
21912
21739
  }
21913
21740
  isBusy() {
21914
21741
  return this.busy;
21915
21742
  }
21916
- currentPrincipalCanDrive(_workspaceId, _principalId) {
21917
- return Promise.resolve(true);
21918
- }
21919
21743
  refreshPersonaForSoulUpdate() {
21920
21744
  return this.options.scheduler.suspend(this.options.cornerId);
21921
21745
  }
@@ -21950,15 +21774,8 @@ var MonolithCornerTurnLoop = class {
21950
21774
  workspaceId: this.options.workspaceId
21951
21775
  });
21952
21776
  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
21777
  return roster;
21957
21778
  }
21958
- async reconcileRoster() {
21959
- if (!this.rosterAvailable)
21960
- await this.roster().catch(() => void 0);
21961
- }
21962
21779
  /**
21963
21780
  * Drop this corner's live harness process. The next activation starts cold.
21964
21781
  * A rotation is a fact about one live session, so the pin goes with it.
@@ -22011,7 +21828,7 @@ var MonolithCornerTurnLoop = class {
22011
21828
  soul: configuration.soul ?? self?.soul,
22012
21829
  agentName: self?.name ?? this.agent.name
22013
21830
  });
22014
- await mkdir10(this.options.worktreePath, { recursive: true });
21831
+ await mkdir11(this.options.worktreePath, { recursive: true });
22015
21832
  const selection = configuration.model || configuration.effort ? { model: configuration.model, effort: configuration.effort } : this.options.config.modelSelection;
22016
21833
  const homeOverlay = this.options.config.agentHomeRoot ? await prepareRoomAgentHome({
22017
21834
  root: this.options.config.agentHomeRoot,
@@ -22056,13 +21873,13 @@ var MonolithCornerTurnLoop = class {
22056
21873
  }, selection);
22057
21874
  const operatorHome = this.options.config.operatorHome ?? homedir7();
22058
21875
  const { stateDirs, tmpDir } = harnessStateDirsFromEnv(agentEnv);
22059
- this.attachmentDir = tmpDir ? join6(tmpDir, "beeline-attachments") : void 0;
21876
+ this.attachmentDir = tmpDir ? join7(tmpDir, "beeline-attachments") : void 0;
22060
21877
  this.sessionScratchDir = tmpDir;
22061
21878
  const homeStateDirs = harnessHomeStateDirs(command, agentEnv.HOME ?? operatorHome);
22062
- await Promise.all(homeStateDirs.map((dir) => mkdir10(dir, { recursive: true })));
21879
+ await Promise.all(homeStateDirs.map((dir) => mkdir11(dir, { recursive: true })));
22063
21880
  const attachScratchRoot = this.options.config.agentHomeRoot ?? tmpDir;
22064
21881
  if (attachScratchRoot)
22065
- await mkdir10(attachScratchRoot, { recursive: true });
21882
+ await mkdir11(attachScratchRoot, { recursive: true });
22066
21883
  const spawnCommand = wrapAgentCommand({
22067
21884
  bwrapPath: this.options.config.bwrapPath,
22068
21885
  spec: {
@@ -22115,6 +21932,7 @@ var MonolithCornerTurnLoop = class {
22115
21932
  // The whole per-session overlay, not an enumerated subset: see
22116
21933
  // `monolith-room-turn.ts`'s matching comment.
22117
21934
  attachScratchRoot,
21935
+ turnContextPath: this.commandContext.path,
22118
21936
  ...this.options.grantRunnerEndpoint ? { grantRunner: this.options.grantRunnerEndpoint } : {}
22119
21937
  })
22120
21938
  ];
@@ -22247,14 +22065,13 @@ var MonolithCornerTurnLoop = class {
22247
22065
  ...this.memberNames.get(requestedById) ? { name: this.memberNames.get(requestedById) } : {}
22248
22066
  } : void 0;
22249
22067
  this.currentTurn = { requestId, ...requester ? { requester } : {} };
22250
- this.carrier = this.agent.publicKey;
22251
22068
  const trace = this.beginTurnTrace(requestId);
22252
22069
  try {
22253
22070
  await withTurnReceiptHeartbeat(api, {
22254
22071
  agentId: this.agent.publicKey,
22255
22072
  roomId: cornerId,
22256
22073
  requestId,
22257
- generationId: `${this.agent.publicKey}:${cornerId}`
22074
+ generationId: this.commandContext.generationId
22258
22075
  }, () => {
22259
22076
  trace.noteScheduler("queue", this.options.scheduler.snapshot());
22260
22077
  trace.start("queue-wait");
@@ -22268,7 +22085,7 @@ var MonolithCornerTurnLoop = class {
22268
22085
  const [conversation, roster, delivered] = await trace.measure("context-fetch", () => Promise.all([
22269
22086
  api.execute("getRoomConversation", { roomId: cornerId, limit: 200 }),
22270
22087
  this.roster(),
22271
- this.attachmentDir && attachments.length ? deliverAttachments(attachments, join6(this.attachmentDir, requestId.replace(/[^\w-]/g, "_")), this.options.fetchImpl) : Promise.resolve([])
22088
+ this.attachmentDir && attachments.length ? deliverAttachments(attachments, join7(this.attachmentDir, requestId.replace(/[^\w-]/g, "_")), this.options.fetchImpl) : Promise.resolve([])
22272
22089
  ]));
22273
22090
  const names = new Map(roster.members.map((member) => [member.identityId, member.name]));
22274
22091
  const requestedBy = requester && !requester.name && names.get(requester.pubkey) ? { ...requester, name: names.get(requester.pubkey) } : requester;
@@ -22283,6 +22100,7 @@ var MonolithCornerTurnLoop = class {
22283
22100
  `Corner objective:
22284
22101
  ${this.options.objective}`,
22285
22102
  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):"),
22103
+ roomMentionDirectory(roster, this.agent.publicKey),
22286
22104
  [
22287
22105
  `Newest trigger:
22288
22106
  ${trigger}`,
@@ -22414,9 +22232,7 @@ ${trigger}`,
22414
22232
  }
22415
22233
  }
22416
22234
  if (this.stoppedTurns.has(requestId)) {
22417
- const stoppedText = spoken(durableReplyText(result.agentText));
22418
- await flushToolCalls(result.toolCalls, stoppedText);
22419
- await stream.settle(stoppedText);
22235
+ stream.close();
22420
22236
  throw new TurnStoppedError("turn stopped by the requester");
22421
22237
  }
22422
22238
  let reply = durableReplyText(result.agentText);
@@ -22436,12 +22252,11 @@ ${trigger}`,
22436
22252
  console.warn(`[thin-core] corner ${cornerId} turn ${requestId}: ${explained.reason}`);
22437
22253
  }
22438
22254
  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));
22255
+ const mentionIds = durableReply ? agentReplyMentionIds(durableReply, roster, this.agent.publicKey) : [];
22256
+ await trace.measure("publish", () => stream.settle(durableReply, durableReply ? {
22257
+ ...requestedById ? { triggerMessageId: requestId } : {},
22258
+ mentionIds
22259
+ } : {}));
22445
22260
  }, { priority: "interactive", roomKey: cornerId });
22446
22261
  }, (error) => console.error(`[thin-core] corner ${cornerId} receipt heartbeat failed:`, error));
22447
22262
  await api.execute("postAgentTurnReceipt", {
@@ -22449,7 +22264,7 @@ ${trigger}`,
22449
22264
  roomId: cornerId,
22450
22265
  requestId,
22451
22266
  status: "complete",
22452
- generationId: `${this.agent.publicKey}:${cornerId}`
22267
+ generationId: this.commandContext.generationId
22453
22268
  });
22454
22269
  await trace.finish("complete");
22455
22270
  } catch (error) {
@@ -22464,7 +22279,7 @@ ${trigger}`,
22464
22279
  roomId: cornerId,
22465
22280
  requestId,
22466
22281
  status: "failed",
22467
- generationId: `${this.agent.publicKey}:${cornerId}`,
22282
+ generationId: this.commandContext.generationId,
22468
22283
  reason
22469
22284
  });
22470
22285
  await trace.finish("failed", reason);
@@ -22474,46 +22289,6 @@ ${trigger}`,
22474
22289
  this.currentTurn = void 0;
22475
22290
  }
22476
22291
  }
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
22292
  /**
22518
22293
  * Bring this worktree onto the corner's branch as GitHub currently has it,
22519
22294
  * before any work is done on top of it.
@@ -22535,197 +22310,42 @@ ${trigger}`,
22535
22310
  env: { ...process.env, GH_TOKEN: token, GITHUB_TOKEN: token, GIT_TERMINAL_PROMPT: "0" }
22536
22311
  });
22537
22312
  }
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
22313
  async run() {
22553
22314
  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
22315
  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
- }
22316
+ await runServerCommandIntake({
22317
+ api,
22318
+ roomId: cornerId,
22319
+ agentId: this.agent.publicKey,
22320
+ context: this.commandContext,
22321
+ signal,
22322
+ pollMs: this.options.pollMs,
22323
+ presence: {
22324
+ ...this.options.config.daemonReleaseVersion ? { releaseVersion: this.options.config.daemonReleaseVersion } : {},
22325
+ ...this.options.config.daemonSourceSha ? { sourceSha: this.options.config.daemonSourceSha } : {},
22326
+ available: !this.options.config.modelUnavailable
22327
+ },
22328
+ onWake: (wake) => {
22329
+ this.wakeIntake = wake;
22330
+ },
22331
+ onPoll: () => this.options.onPoll(),
22332
+ onError: (error) => console.error("[thin-core] corner command failed", error),
22333
+ stop: (requestId) => this.stopTurn(requestId),
22334
+ closed: async () => {
22335
+ const state = await api.execute("getCornerRestoreState", { cornerId });
22336
+ if (!state.closeRequested)
22337
+ return false;
22338
+ await this.options.onCloseRequested();
22339
+ return true;
22340
+ },
22341
+ run: (command) => this.prompt(command.turnRequestId, command.source.body, command.source.attachments, command.source.authorId, command.reason === "corner_check" ? [command.source.body] : void 0)
22342
+ });
22708
22343
  } finally {
22709
- stopLive?.();
22710
- this.wakeIntake = void 0;
22711
22344
  this.options.grantRunner?.unregister(cornerId);
22712
22345
  await this.options.scheduler.suspend(cornerId);
22713
22346
  }
22714
22347
  }
22715
22348
  };
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
22349
 
22730
22350
  // apps/body/dist/session-scheduler.js
22731
22351
  var DEFAULT_PER_ROOM_LIVE_SESSIONS = 10;
@@ -23145,8 +22765,8 @@ async function materializeCornerWorktree(input) {
23145
22765
  const repositoryHash = createHash5("sha256").update(remote).digest("hex").slice(0, 24);
23146
22766
  const gitCommonDir = resolve19(input.supervisorRoot, "beeline", "repositories", `${repositoryHash}.git`);
23147
22767
  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 });
22768
+ await mkdir12(dirname7(gitCommonDir), { recursive: true, mode: 448 });
22769
+ await mkdir12(dirname7(path), { recursive: true, mode: 448 });
23150
22770
  const authEnv = githubGitEnv(input.token);
23151
22771
  if (!existsSync4(resolve19(gitCommonDir, "HEAD"))) {
23152
22772
  await execFileAsync4("git", ["clone", "--bare", remote, gitCommonDir], {
@@ -23333,9 +22953,6 @@ var RoomRuntimeCoordinator = class {
23333
22953
  this.drainDeadlineAt = Math.min(this.drainDeadlineAt ?? Number.POSITIVE_INFINITY, deadlineAt);
23334
22954
  }
23335
22955
  }
23336
- async currentPrincipalCanDrive(roomId, workspaceId, principalId) {
23337
- return this.running.get(roomId)?.body.currentPrincipalCanDrive(workspaceId, principalId);
23338
- }
23339
22956
  async prepareForForcedUpdateRestart() {
23340
22957
  const rooms = [...this.running.values()];
23341
22958
  await Promise.allSettled(rooms.filter((room) => room.body.isBusy()).map((room) => room.body.prepareForForcedUpdateRestart()));
@@ -23420,7 +23037,7 @@ var RoomRuntimeCoordinator = class {
23420
23037
  return this.runtime.rooms.find((room) => room.channelId === roomId);
23421
23038
  }
23422
23039
  roomRoot(roomId) {
23423
- return this.roomRecord(roomId)?.root ?? resolve19(dirname6(this.configPath), "rooms", roomId);
23040
+ return this.roomRecord(roomId)?.root ?? resolve19(dirname7(this.configPath), "rooms", roomId);
23424
23041
  }
23425
23042
  roomAgentHomeRoot(workspaceRoot, required = false) {
23426
23043
  const flag = process.env.BUZZY_BODY_ROOM_HOME;
@@ -23443,9 +23060,9 @@ var RoomRuntimeCoordinator = class {
23443
23060
  ...this.baseConfig,
23444
23061
  workspaceRoot,
23445
23062
  agentPrivateRoot: resolve19(workspaceRoot, "agent-private"),
23446
- agentMemoryRoot: resolve19(dirname6(this.configPath), "memory"),
23447
- openRouterRoutingCacheDir: openRouterRoutingCacheDir(dirname6(this.configPath)),
23448
- turnTraceDir: turnTraceDirectory(dirname6(this.configPath)),
23063
+ agentMemoryRoot: resolve19(dirname7(this.configPath), "memory"),
23064
+ openRouterRoutingCacheDir: openRouterRoutingCacheDir(dirname7(this.configPath)),
23065
+ turnTraceDir: turnTraceDirectory(dirname7(this.configPath)),
23449
23066
  ...agentHomeRoot ? { agentHomeRoot } : {}
23450
23067
  };
23451
23068
  }
@@ -23513,7 +23130,7 @@ var RoomRuntimeCoordinator = class {
23513
23130
  const targetBranch = repository.targetBranch || "main";
23514
23131
  const checkoutId = createHash5("sha256").update(`${remote}\0${targetBranch}`).digest("hex").slice(0, 24);
23515
23132
  const path = resolve19(this.runtime.supervisorRoot, "beeline", "room-checkouts", checkoutId);
23516
- await mkdir11(dirname6(path), { recursive: true, mode: 448 });
23133
+ await mkdir12(dirname7(path), { recursive: true, mode: 448 });
23517
23134
  const token = remote.startsWith("https://github.com/") ? await this.options.daemonApi.execute("getRoomGitHubToken", { roomId }) : void 0;
23518
23135
  const env = token ? githubGitEnv(token.token) : process.env;
23519
23136
  if (!existsSync4(resolve19(path, ".git"))) {
@@ -23579,7 +23196,7 @@ var RoomRuntimeCoordinator = class {
23579
23196
  }) : void 0;
23580
23197
  const workspacePath = worktree?.path ?? resolve19(this.roomRoot(corner.cornerId), "scratch");
23581
23198
  if (!worktree)
23582
- await mkdir11(workspacePath, { recursive: true, mode: 448 });
23199
+ await mkdir12(workspacePath, { recursive: true, mode: 448 });
23583
23200
  const isOpener = !corner.openedBy || corner.openedBy === this.agent.publicKey;
23584
23201
  if (worktree && shouldPostInitialCornerWorkingState(restore, isOpener)) {
23585
23202
  await this.options.daemonApi.execute("postCornerRemoteState", {
@@ -23878,9 +23495,9 @@ var ThinDaemonCore = class {
23878
23495
 
23879
23496
  // apps/body/dist/systemd.js
23880
23497
  import { execFile as execFile6 } from "node:child_process";
23881
- import { mkdir as mkdir12, readFile as readFile8, writeFile as writeFile8 } from "node:fs/promises";
23498
+ import { mkdir as mkdir13, readFile as readFile8, writeFile as writeFile9 } from "node:fs/promises";
23882
23499
  import { homedir as homedir8 } from "node:os";
23883
- import { dirname as dirname7, resolve as resolve20 } from "node:path";
23500
+ import { dirname as dirname8, resolve as resolve20 } from "node:path";
23884
23501
  import { setTimeout as sleep } from "node:timers/promises";
23885
23502
  import { promisify as promisify5 } from "node:util";
23886
23503
  var execFileAsync5 = promisify5(execFile6);
@@ -23951,8 +23568,8 @@ async function installAgentService(publicKey, options = {}) {
23951
23568
  const content = agentServiceUnit();
23952
23569
  const existing = await readFile8(path, "utf8").catch(() => "");
23953
23570
  if (existing !== content) {
23954
- await mkdir12(dirname7(path), { recursive: true, mode: 448 });
23955
- await writeFile8(path, content, { mode: 384 });
23571
+ await mkdir13(dirname8(path), { recursive: true, mode: 448 });
23572
+ await writeFile9(path, content, { mode: 384 });
23956
23573
  }
23957
23574
  const run2 = options.run ?? runSystemctl;
23958
23575
  await run2(["daemon-reload"]);
@@ -24032,7 +23649,7 @@ async function retireRemovedAgent(runtime, options = {}) {
24032
23649
  }
24033
23650
 
24034
23651
  // apps/body/dist/start-command.js
24035
- import { dirname as dirname8 } from "node:path";
23652
+ import { dirname as dirname9 } from "node:path";
24036
23653
  var import_picocolors = __toESM(require_picocolors(), 1);
24037
23654
  var DEFAULT_RESTART_DRAIN_TIMEOUT_MS = 30 * 6e4;
24038
23655
  var RESTART_WAIT_REPORT_INTERVAL_MS = 3e4;
@@ -24107,7 +23724,7 @@ async function runStartCommand(args, interactiveUi) {
24107
23724
  continue;
24108
23725
  }
24109
23726
  const spinnerHandle = spinner();
24110
- spinnerHandle.start(`Starting ${dirname8(path)}\u2026`);
23727
+ spinnerHandle.start(`Starting ${dirname9(path)}\u2026`);
24111
23728
  try {
24112
23729
  await startRuntime(path, spinnerHandle);
24113
23730
  spinnerHandle.stop(import_picocolors.default.green("Started."));
@@ -24124,8 +23741,8 @@ async function runStartCommand(args, interactiveUi) {
24124
23741
  // apps/body/dist/connect-command.js
24125
23742
  import { spawn as spawn5 } from "node:child_process";
24126
23743
  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";
23744
+ import { chmod as chmod5, mkdir as mkdir15, readFile as readFile10, unlink as unlink2, writeFile as writeFile11 } from "node:fs/promises";
23745
+ import { dirname as dirname11, resolve as resolve22 } from "node:path";
24129
23746
  import { stdin as stdin3, stdout as stdout4 } from "node:process";
24130
23747
 
24131
23748
  // apps/body/dist/clack-support.js
@@ -24769,8 +24386,8 @@ function providerEnvironment(selection) {
24769
24386
  };
24770
24387
  }
24771
24388
  async function writePrivateJson(path, value) {
24772
- await mkdir14(dirname10(path), { recursive: true, mode: 448 });
24773
- await writeFile10(path, `${JSON.stringify(value, null, 2)}
24389
+ await mkdir15(dirname11(path), { recursive: true, mode: 448 });
24390
+ await writeFile11(path, `${JSON.stringify(value, null, 2)}
24774
24391
  `, { mode: 384 });
24775
24392
  await chmod5(path, 384);
24776
24393
  }
@@ -24779,9 +24396,9 @@ async function writeProviderEnv(selection, agentPubkey) {
24779
24396
  if (Object.keys(values).length === 0)
24780
24397
  return void 0;
24781
24398
  const path = resolve22(defaultSupervisorRoot(process.env), "beeline", "connect", `${agentPubkey}.env`);
24782
- await mkdir14(dirname10(path), { recursive: true, mode: 448 });
24399
+ await mkdir15(dirname11(path), { recursive: true, mode: 448 });
24783
24400
  const contents = Object.entries(values).map(([key, value]) => `${key}=${JSON.stringify(value)}`).join("\n");
24784
- await writeFile10(path, `${contents}
24401
+ await writeFile11(path, `${contents}
24785
24402
  `, { mode: 384 });
24786
24403
  await chmod5(path, 384);
24787
24404
  return path;
@@ -24937,7 +24554,7 @@ async function runConnectFinishCommand(path) {
24937
24554
  if (model) {
24938
24555
  const decision2 = await resolveOpenRouterRouting({
24939
24556
  model,
24940
- cacheDir: openRouterRoutingCacheDir(dirname10(connected.configPath)),
24557
+ cacheDir: openRouterRoutingCacheDir(dirname11(connected.configPath)),
24941
24558
  ...apiKey ? { apiKey } : {},
24942
24559
  probeTimeoutMs: 1e4
24943
24560
  });
@@ -24959,12 +24576,12 @@ init_self_update_manifest();
24959
24576
  // apps/body/dist/managed-update.js
24960
24577
  init_self_update();
24961
24578
  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";
24579
+ import { mkdir as mkdir17, rm as rm6, stat as stat2, writeFile as writeFile13 } from "node:fs/promises";
24580
+ import { dirname as dirname13, resolve as resolve24 } from "node:path";
24964
24581
 
24965
24582
  // 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";
24583
+ import { mkdir as mkdir16, readFile as readFile11, rename as rename4, unlink as unlink3, writeFile as writeFile12 } from "node:fs/promises";
24584
+ import { dirname as dirname12, resolve as resolve23 } from "node:path";
24968
24585
  var REPORT_INTERVAL_MS = 60 * 60 * 1e3;
24969
24586
  var lastLogged = /* @__PURE__ */ new Map();
24970
24587
  function updateRollbackAlertPath(runtimeDir) {
@@ -24973,8 +24590,8 @@ function updateRollbackAlertPath(runtimeDir) {
24973
24590
  async function writeAlert(runtimeDir, alert) {
24974
24591
  const path = updateRollbackAlertPath(runtimeDir);
24975
24592
  const staged = `${path}.${process.pid}.tmp`;
24976
- await mkdir15(dirname11(path), { recursive: true });
24977
- await writeFile11(staged, `${JSON.stringify(alert, null, 2)}
24593
+ await mkdir16(dirname12(path), { recursive: true });
24594
+ await writeFile12(staged, `${JSON.stringify(alert, null, 2)}
24978
24595
  `, { mode: 384 });
24979
24596
  await rename4(staged, path);
24980
24597
  }
@@ -25039,11 +24656,11 @@ async function withInstallLock(layout, work, options = {}) {
25039
24656
  const now2 = options.now ?? Date.now;
25040
24657
  const lock = resolve24(layout.releasesRoot, ".state", "install.lock");
25041
24658
  const deadline = now2() + (options.waitMs ?? 1e4);
25042
- await mkdir16(dirname12(lock), { recursive: true });
24659
+ await mkdir17(dirname13(lock), { recursive: true });
25043
24660
  for (; ; ) {
25044
24661
  try {
25045
- await mkdir16(lock);
25046
- await writeFile12(resolve24(lock, "owner"), `${process.pid}
24662
+ await mkdir17(lock);
24663
+ await writeFile13(resolve24(lock, "owner"), `${process.pid}
25047
24664
  ${now2()}
25048
24665
  `, "utf8");
25049
24666
  break;
@@ -25453,7 +25070,7 @@ async function proveLoadedReleaseReady(layout, runtimeDir, loadedRelease, option
25453
25070
  });
25454
25071
  if (!accepted)
25455
25072
  return false;
25456
- await writeFile12(resolve24(runtimeDir, "daemon-ready.json"), `${JSON.stringify({
25073
+ await writeFile13(resolve24(runtimeDir, "daemon-ready.json"), `${JSON.stringify({
25457
25074
  readyAt: (options.now ?? Date.now)(),
25458
25075
  loadedRelease,
25459
25076
  functionalProof: options.functionalProof
@@ -25681,8 +25298,8 @@ async function runUpdateCommand(args) {
25681
25298
  init_self_update();
25682
25299
 
25683
25300
  // 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";
25301
+ import { mkdir as mkdir18, readFile as readFile12, rename as rename5, rm as rm7, writeFile as writeFile14 } from "node:fs/promises";
25302
+ import { dirname as dirname14, resolve as resolve25 } from "node:path";
25686
25303
  var DAEMON_FAILURE_LIMIT = 3;
25687
25304
  var DAEMON_FAILURE_WINDOW_MS = 5 * 6e4;
25688
25305
  function daemonFailurePath(runtimeDir) {
@@ -25702,8 +25319,8 @@ async function readFailureRecord(runtimeDir) {
25702
25319
  async function writeFailureRecord(runtimeDir, record2) {
25703
25320
  const path = daemonFailurePath(runtimeDir);
25704
25321
  const staged = `${path}.${process.pid}.tmp`;
25705
- await mkdir17(dirname13(path), { recursive: true, mode: 448 });
25706
- await writeFile13(staged, `${JSON.stringify(record2, null, 2)}
25322
+ await mkdir18(dirname14(path), { recursive: true, mode: 448 });
25323
+ await writeFile14(staged, `${JSON.stringify(record2, null, 2)}
25707
25324
  `, { mode: 384 });
25708
25325
  await rename5(staged, path);
25709
25326
  }
@@ -25725,7 +25342,7 @@ async function clearDaemonStartFailures(runtimeDir) {
25725
25342
  }
25726
25343
 
25727
25344
  // apps/body/dist/update-functional-probe.js
25728
- import { mkdir as mkdir18, rm as rm8 } from "node:fs/promises";
25345
+ import { mkdir as mkdir19, rm as rm8 } from "node:fs/promises";
25729
25346
  import { homedir as homedir10 } from "node:os";
25730
25347
  import { resolve as resolve26 } from "node:path";
25731
25348
  var UPDATE_PROBE_SESSION_TIMEOUT_MS = 1e4;
@@ -25771,6 +25388,9 @@ async function probeOutcome(run2) {
25771
25388
  await run2();
25772
25389
  return { kind: "served" };
25773
25390
  } catch (error) {
25391
+ if (error instanceof UpdateFunctionalProbeError && error.reason === "sandbox-unavailable") {
25392
+ return { kind: "sandbox-unavailable", reason: error.message };
25393
+ }
25774
25394
  if (error instanceof UpdateFunctionalProbeError && error.providerRefusal) {
25775
25395
  return { kind: "refused", ...error.providerRefusal };
25776
25396
  }
@@ -25783,6 +25403,8 @@ function describeCurrentReleaseOutcome(outcome) {
25783
25403
  return "the current release answered";
25784
25404
  case "refused":
25785
25405
  return `the current release got a different refusal (${outcome.reason})`;
25406
+ case "sandbox-unavailable":
25407
+ return `the current release has the same unavailable sandbox (${outcome.reason})`;
25786
25408
  case "unavailable":
25787
25409
  return `the current release could not be compared (${outcome.reason})`;
25788
25410
  }
@@ -25794,13 +25416,33 @@ async function runUpdateFunctionalProbe(input) {
25794
25416
  throw new UpdateFunctionalProbeError("model-unavailable", input.config.modelUnavailable.detail);
25795
25417
  }
25796
25418
  if (input.sandboxRequired && !input.config.bwrapPath) {
25797
- throw new UpdateFunctionalProbeError("sandbox-unavailable", "the configured bubblewrap boundary did not pass its startup self-test");
25419
+ const detail = input.sandboxUnavailableDetail ?? "the configured bubblewrap boundary did not pass its startup self-test";
25420
+ if (!input.compareWithCurrentRelease) {
25421
+ throw new UpdateFunctionalProbeError("sandbox-unavailable", detail);
25422
+ }
25423
+ const current = await input.compareWithCurrentRelease({
25424
+ kind: "sandbox-unavailable",
25425
+ reason: detail
25426
+ });
25427
+ if (current.kind !== "sandbox-unavailable") {
25428
+ throw new UpdateFunctionalProbeError("sandbox-unavailable", `${detail}; ${describeCurrentReleaseOutcome(current)}`);
25429
+ }
25430
+ 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");
25431
+ return {
25432
+ harness,
25433
+ sandboxed: false,
25434
+ sessionStarted: false,
25435
+ turnCompleted: false,
25436
+ nativeTools: [],
25437
+ modelAnswer: "unavailable",
25438
+ modelAnswerReason: `${detail} (the current release has the same host sandbox failure)`
25439
+ };
25798
25440
  }
25799
25441
  const root = input.probeRoot ?? resolve26(input.runtimeDir, "update-functional-probe");
25800
25442
  const cwd = resolve26(root, "checkout");
25801
25443
  const homeRoot = resolve26(root, "agent-home");
25802
25444
  await rm8(root, { recursive: true, force: true });
25803
- await mkdir18(cwd, { recursive: true, mode: 448 });
25445
+ await mkdir19(cwd, { recursive: true, mode: 448 });
25804
25446
  let client;
25805
25447
  try {
25806
25448
  const agentEnv = {
@@ -25830,7 +25472,7 @@ async function runUpdateFunctionalProbe(input) {
25830
25472
  const { stateDirs, tmpDir } = harnessStateDirsFromEnv(agentEnv);
25831
25473
  const operatorHome = input.config.operatorHome ?? homedir10();
25832
25474
  const homeStateDirs = harnessHomeStateDirs(command, agentEnv.HOME ?? operatorHome);
25833
- await Promise.all(homeStateDirs.map((dir) => mkdir18(dir, { recursive: true })));
25475
+ await Promise.all(homeStateDirs.map((dir) => mkdir19(dir, { recursive: true })));
25834
25476
  spawnCommand = wrapAgentCommand({
25835
25477
  bwrapPath: input.config.bwrapPath,
25836
25478
  spec: {
@@ -25980,7 +25622,7 @@ async function runUpdateFunctionalProbe(input) {
25980
25622
 
25981
25623
  // apps/body/dist/current-release-probe.js
25982
25624
  import { spawn as spawn7 } from "node:child_process";
25983
- import { dirname as dirname14, join as join8 } from "node:path";
25625
+ import { dirname as dirname15, join as join9 } from "node:path";
25984
25626
  init_self_update();
25985
25627
  var CURRENT_RELEASE_PROBE_TIMEOUT_MS = 12e4;
25986
25628
  var UPDATE_PROBE_COMMAND = "update-probe";
@@ -26002,6 +25644,9 @@ function parseReport(line) {
26002
25644
  if (report.probe === "failed" && typeof report.reason === "string") {
26003
25645
  return { probe: "failed", reason: report.reason };
26004
25646
  }
25647
+ if (report.probe === "sandbox-unavailable" && typeof report.reason === "string") {
25648
+ return { probe: "sandbox-unavailable", reason: report.reason };
25649
+ }
26005
25650
  return void 0;
26006
25651
  }
26007
25652
  function outcomeFromReport(report) {
@@ -26010,12 +25655,17 @@ function outcomeFromReport(report) {
26010
25655
  return { kind: "served" };
26011
25656
  case "refused":
26012
25657
  return { kind: "refused", status: report.status, reason: report.reason };
25658
+ case "sandbox-unavailable":
25659
+ return { kind: "sandbox-unavailable", reason: report.reason };
26013
25660
  case "failed":
25661
+ if (report.reason.startsWith("functional update probe failed (sandbox-unavailable):")) {
25662
+ return { kind: "sandbox-unavailable", reason: report.reason };
25663
+ }
26014
25664
  return { kind: "unavailable", reason: report.reason };
26015
25665
  }
26016
25666
  }
26017
25667
  async function probeReleaseInSubprocess(input) {
26018
- const bundleDir = join8(input.layout.releasesRoot, input.releaseId);
25668
+ const bundleDir = join9(input.layout.releasesRoot, input.releaseId);
26019
25669
  const entrypoint = await resolveBundleEntrypoint(bundleDir);
26020
25670
  if (!entrypoint) {
26021
25671
  return { kind: "unavailable", reason: `release ${input.releaseId} has no runnable CLI entrypoint` };
@@ -26078,7 +25728,7 @@ async function runUpdateProbeCommand(args, options = {}) {
26078
25728
  const runtime = await readRuntimeRecord(configPath);
26079
25729
  const agent = runtimeAgentCommand(runtime);
26080
25730
  const config = loadBodyConfig({
26081
- workspaceRoot: join8(dirname14(configPath), "workspace"),
25731
+ workspaceRoot: join9(dirname15(configPath), "workspace"),
26082
25732
  llmEnvFile: runtime.llmEnvFile,
26083
25733
  env: { ...env, BUZZ_AGENT_BIN: agent.command, BUZZ_DEV_MCP_BIN: runtime.mcpBinary },
26084
25734
  agent
@@ -26096,21 +25746,22 @@ async function runUpdateProbeCommand(args, options = {}) {
26096
25746
  }
26097
25747
  const layout = beelineInstallLayout(env);
26098
25748
  const releaseId = (layout && await activeReleaseId(layout).catch(() => void 0)) ?? "unknown";
26099
- const runtimeDir = dirname14(configPath);
25749
+ const runtimeDir = dirname15(configPath);
26100
25750
  const outcome = await probeOutcome(() => (options.probe ?? runUpdateFunctionalProbe)({
26101
25751
  config,
26102
25752
  runtimeDir,
26103
25753
  releaseId,
26104
25754
  sandboxRequired: runtime.sandbox !== "off",
25755
+ sandboxUnavailableDetail: sandbox.advisory,
26105
25756
  // The successor's probe still holds `<runtimeDir>/update-functional-probe`.
26106
- probeRoot: join8(runtimeDir, "current-release-probe")
25757
+ probeRoot: join9(runtimeDir, "current-release-probe")
26107
25758
  }));
26108
- const report = outcome.kind === "served" ? { probe: "served" } : outcome.kind === "refused" ? { probe: "refused", status: outcome.status, reason: outcome.reason } : { probe: "failed", reason: outcome.reason };
25759
+ 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
25760
  write(JSON.stringify(report));
26110
25761
  }
26111
25762
 
26112
25763
  // apps/body/dist/release-status.js
26113
- import { readFile as readFile13, readdir as readdir5, rename as rename6, writeFile as writeFile14 } from "node:fs/promises";
25764
+ import { readFile as readFile13, readdir as readdir5, rename as rename6, writeFile as writeFile15 } from "node:fs/promises";
26114
25765
  import { resolve as resolve27 } from "node:path";
26115
25766
  var DAEMON_RELEASE_STATUS_FILE = "release-status.json";
26116
25767
  var RELEASE_VERSION = /^v\d+\.\d+\.\d+$/;
@@ -26130,7 +25781,7 @@ async function writeDaemonReleaseStatus(runtimeDir, agentPubkey, identity, optio
26130
25781
  };
26131
25782
  const target = resolve27(runtimeDir, DAEMON_RELEASE_STATUS_FILE);
26132
25783
  const temporary = `${target}.${status.pid}.tmp`;
26133
- await writeFile14(temporary, `${JSON.stringify(status, null, 2)}
25784
+ await writeFile15(temporary, `${JSON.stringify(status, null, 2)}
26134
25785
  `, { mode: 384 });
26135
25786
  await rename6(temporary, target);
26136
25787
  return status;
@@ -26264,7 +25915,7 @@ var DaemonExitError = class extends Error {
26264
25915
  };
26265
25916
  async function runStoredDaemon(pathOrPointer) {
26266
25917
  const configPath = await resolveRuntimeConfigPath(pathOrPointer);
26267
- daemonFailureRuntimeDir = dirname15(configPath);
25918
+ daemonFailureRuntimeDir = dirname16(configPath);
26268
25919
  const accessMigration = await migrateRuntimeRecordAccessPolicy(configPath);
26269
25920
  let runtime = accessMigration.runtime;
26270
25921
  if (!runtime.transport) {
@@ -26276,7 +25927,7 @@ async function runStoredDaemon(pathOrPointer) {
26276
25927
  runtime = activated.runtime;
26277
25928
  const daemonApi = activated.client;
26278
25929
  const agent = runtimeAgentCommand(runtime);
26279
- await writeFile15(resolve29(dirname15(configPath), "daemon.pid"), `${process.pid}
25930
+ await writeFile16(resolve29(dirname16(configPath), "daemon.pid"), `${process.pid}
26280
25931
  `, { mode: 384 });
26281
25932
  const env = {
26282
25933
  ...process.env,
@@ -26284,7 +25935,7 @@ async function runStoredDaemon(pathOrPointer) {
26284
25935
  BUZZ_DEV_MCP_BIN: runtime.mcpBinary
26285
25936
  };
26286
25937
  const config = loadBodyConfig({
26287
- workspaceRoot: resolve29(dirname15(configPath), "workspace"),
25938
+ workspaceRoot: resolve29(dirname16(configPath), "workspace"),
26288
25939
  llmEnvFile: runtime.llmEnvFile,
26289
25940
  env,
26290
25941
  agent
@@ -26319,7 +25970,7 @@ async function runStoredDaemon(pathOrPointer) {
26319
25970
  const stop = () => controller.abort();
26320
25971
  process.once("SIGINT", stop);
26321
25972
  process.once("SIGTERM", stop);
26322
- const runtimeDir = dirname15(configPath);
25973
+ const runtimeDir = dirname16(configPath);
26323
25974
  const layout = beelineInstallLayout(process.env);
26324
25975
  const notifier = new SystemdNotifier();
26325
25976
  let rollbackAlertDrain;
@@ -26401,6 +26052,7 @@ async function runStoredDaemon(pathOrPointer) {
26401
26052
  runtimeDir,
26402
26053
  releaseId: loadedRelease ?? "unknown",
26403
26054
  sandboxRequired: runtime.sandbox !== "off",
26055
+ sandboxUnavailableDetail: sandbox.advisory,
26404
26056
  ...currentReleaseId ? {
26405
26057
  compareWithCurrentRelease: async (appeal) => {
26406
26058
  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 +26117,7 @@ async function runStoredDaemon(pathOrPointer) {
26465
26117
  } finally {
26466
26118
  clearInterval(scratchSweepTimer);
26467
26119
  await notifier.stopping(stoppingStatus).catch(() => void 0);
26468
- const pidPath = resolve29(dirname15(configPath), "daemon.pid");
26120
+ const pidPath = resolve29(dirname16(configPath), "daemon.pid");
26469
26121
  const recorded = Number((await readFile14(pidPath, "utf8").catch(() => "")).trim());
26470
26122
  if (recorded === process.pid) {
26471
26123
  await unlink5(pidPath).catch(() => void 0);
@@ -26542,7 +26194,7 @@ async function main() {
26542
26194
  const agentPubkey = agentFlag >= 0 ? args[agentFlag + 1] : void 0;
26543
26195
  if (!configPath && agentPubkey) {
26544
26196
  const configs = await findAgentRuntimeConfigPaths(process.env, process.cwd());
26545
- configPath = configs.find((candidate) => dirname15(candidate).endsWith(agentPubkey));
26197
+ configPath = configs.find((candidate) => dirname16(candidate).endsWith(agentPubkey));
26546
26198
  }
26547
26199
  if (!configPath && agentPubkey) {
26548
26200
  throw new DaemonExitError(`unknown agent ${agentPubkey}: no durable runtime exists; refusing systemd restart loop`, UNKNOWN_AGENT_EXIT_STATUS);
@@ -26570,7 +26222,7 @@ async function main() {
26570
26222
  if (!agentPubkey)
26571
26223
  throw new Error("stop requires --agent <pubkey>");
26572
26224
  const configs = await findAgentRuntimeConfigPaths(process.env, process.cwd());
26573
- const configPath = configs.find((candidate) => dirname15(candidate).endsWith(agentPubkey));
26225
+ const configPath = configs.find((candidate) => dirname16(candidate).endsWith(agentPubkey));
26574
26226
  if (!configPath)
26575
26227
  throw new Error(`no stored runtime found for agent ${agentPubkey}`);
26576
26228
  const runtime = await readRuntimeRecord(configPath);