usebeeline 0.0.113 → 0.0.115

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/usebeeline.mjs +1285 -600
  2. package/package.json +1 -1
@@ -2415,7 +2415,7 @@ var require_websocket = __commonJS({
2415
2415
  var http = __require("http");
2416
2416
  var net2 = __require("net");
2417
2417
  var tls = __require("tls");
2418
- var { randomBytes: randomBytes7, createHash: createHash9 } = __require("crypto");
2418
+ var { randomBytes: randomBytes7, createHash: createHash10 } = __require("crypto");
2419
2419
  var { Duplex, Readable } = __require("stream");
2420
2420
  var { URL: URL2 } = __require("url");
2421
2421
  var PerMessageDeflate2 = require_permessage_deflate();
@@ -3083,7 +3083,7 @@ var require_websocket = __commonJS({
3083
3083
  abortHandshake(websocket, socket, "Invalid Upgrade header");
3084
3084
  return;
3085
3085
  }
3086
- const digest = createHash9("sha1").update(key + GUID).digest("base64");
3086
+ const digest = createHash10("sha1").update(key + GUID).digest("base64");
3087
3087
  if (res.headers["sec-websocket-accept"] !== digest) {
3088
3088
  abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
3089
3089
  return;
@@ -3452,7 +3452,7 @@ var require_websocket_server = __commonJS({
3452
3452
  var EventEmitter2 = __require("events");
3453
3453
  var http = __require("http");
3454
3454
  var { Duplex } = __require("stream");
3455
- var { createHash: createHash9 } = __require("crypto");
3455
+ var { createHash: createHash10 } = __require("crypto");
3456
3456
  var extension2 = require_extension();
3457
3457
  var PerMessageDeflate2 = require_permessage_deflate();
3458
3458
  var subprotocol2 = require_subprotocol();
@@ -3759,7 +3759,7 @@ var require_websocket_server = __commonJS({
3759
3759
  );
3760
3760
  }
3761
3761
  if (this._state > RUNNING) return abortHandshake(socket, 503);
3762
- const digest = createHash9("sha1").update(key + GUID).digest("base64");
3762
+ const digest = createHash10("sha1").update(key + GUID).digest("base64");
3763
3763
  const headers = [
3764
3764
  "HTTP/1.1 101 Switching Protocols",
3765
3765
  "Upgrade: websocket",
@@ -3984,14 +3984,14 @@ __export(self_update_exports, {
3984
3984
  writeUpdateAttemptFixture: () => writeUpdateAttemptFixture,
3985
3985
  writeUpdateState: () => writeUpdateState
3986
3986
  });
3987
- import { createHash as createHash7 } from "node:crypto";
3987
+ import { createHash as createHash8 } from "node:crypto";
3988
3988
  import { constants as fsConstants2 } from "node:fs";
3989
3989
  import { access, chmod as chmod5, lstat as lstat3, mkdir as mkdir15, open, readFile as readFile10, rename as rename4, rm as rm6, symlink as symlink3, writeFile as writeFile10 } from "node:fs/promises";
3990
- import { spawn as spawn6 } from "node:child_process";
3991
- import { homedir as homedir9 } from "node:os";
3992
- import { dirname as dirname11, join as join10, resolve as resolve22 } from "node:path";
3990
+ import { spawn as spawn8 } from "node:child_process";
3991
+ import { homedir as homedir10 } from "node:os";
3992
+ import { dirname as dirname12, join as join11, resolve as resolve23 } from "node:path";
3993
3993
  function anchorLayout(rawLibDir) {
3994
- const libDir = resolve22(rawLibDir);
3994
+ const libDir = resolve23(rawLibDir);
3995
3995
  const segments = libDir.split(/[/\\]/);
3996
3996
  const idx = segments.lastIndexOf(RELEASES_SEGMENT);
3997
3997
  if (idx >= 2 && segments[idx - 1] === "lib") {
@@ -4007,9 +4007,9 @@ function anchorLayout(rawLibDir) {
4007
4007
  // prefix's bin, NOT <prefix>/lib/bin — deriving it one level up was the
4008
4008
  // defect that made activateRelease write its stable forwarders where
4009
4009
  // nothing executed them, leaving stale raw wrappers in <prefix>/bin.
4010
- binDir: resolve22(libDir, "../../bin"),
4010
+ binDir: resolve23(libDir, "../../bin"),
4011
4011
  libDir,
4012
- releasesRoot: resolve22(libDir, `../${RELEASES_SEGMENT}`)
4012
+ releasesRoot: resolve23(libDir, `../${RELEASES_SEGMENT}`)
4013
4013
  };
4014
4014
  }
4015
4015
  function beelineInstallLayout(env = process.env) {
@@ -4019,8 +4019,8 @@ function beelineInstallLayout(env = process.env) {
4019
4019
  return anchorLayout(raw);
4020
4020
  }
4021
4021
  function defaultBeelineInstallLayout(env = process.env) {
4022
- const home = env.HOME?.trim() || homedir9();
4023
- return anchorLayout(resolve22(home, ".local", "lib", "beeline"));
4022
+ const home = env.HOME?.trim() || homedir10();
4023
+ return anchorLayout(resolve23(home, ".local", "lib", "beeline"));
4024
4024
  }
4025
4025
  function discoveredBeelineInstallLayout(env = process.env) {
4026
4026
  const explicitAnchor = env.BEELINE_INSTALL_LIB_DIR?.trim();
@@ -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(resolve22(dirname11(resolve22(explicitBinDir)), "lib", "beeline"));
4031
+ return anchorLayout(resolve23(dirname12(resolve23(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 [join10(bundleDir, "lib", "beeline", "bundle.json"), join10(bundleDir, "bundle.json")];
4042
+ return [join11(bundleDir, "lib", "beeline", "bundle.json"), join11(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 join10(layout.releasesRoot, ".state", "update-state.json");
4066
+ return join11(layout.releasesRoot, ".state", "update-state.json");
4067
4067
  }
4068
4068
  async function readUpdateState(layout) {
4069
4069
  try {
@@ -4073,7 +4073,7 @@ async function readUpdateState(layout) {
4073
4073
  }
4074
4074
  }
4075
4075
  async function writeUpdateState(layout, state) {
4076
- await mkdir15(join10(layout.releasesRoot, ".state"), { recursive: true });
4076
+ await mkdir15(join11(layout.releasesRoot, ".state"), { recursive: true });
4077
4077
  await writeFile10(updateStatePath(layout), `${JSON.stringify(state, null, 2)}
4078
4078
  `, "utf8");
4079
4079
  }
@@ -4137,7 +4137,7 @@ async function fetchText(url, fetchImpl) {
4137
4137
  }
4138
4138
  function run(command, args, timeoutMs) {
4139
4139
  return new Promise((resolveRun) => {
4140
- const child = spawn6(command, args, { stdio: ["ignore", "ignore", "pipe"] });
4140
+ const child = spawn8(command, args, { stdio: ["ignore", "ignore", "pipe"] });
4141
4141
  let stderr = "";
4142
4142
  child.stderr?.setEncoding("utf8");
4143
4143
  child.stderr?.on("data", (chunk) => {
@@ -4155,7 +4155,7 @@ function run(command, args, timeoutMs) {
4155
4155
  });
4156
4156
  }
4157
4157
  function entrypointCandidates(bundleDir) {
4158
- return [join10(bundleDir, BUNDLE_ENTRYPOINT), join10(bundleDir, "beeline-cli.mjs")];
4158
+ return [join11(bundleDir, BUNDLE_ENTRYPOINT), join11(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 = join10(layout.releasesRoot, releaseId);
4181
- const okMarker = join10(releaseDir, ".stage-ok");
4180
+ const releaseDir = join11(layout.releasesRoot, releaseId);
4181
+ const okMarker = join11(releaseDir, ".stage-ok");
4182
4182
  let previouslyVerified = false;
4183
4183
  try {
4184
4184
  const recorded = await readFile10(okMarker, "utf8");
@@ -4188,7 +4188,7 @@ async function stageRelease(layout, manifestUrl, published, opts = {}) {
4188
4188
  } catch {
4189
4189
  }
4190
4190
  await mkdir15(releaseDir, { recursive: true });
4191
- const tempArchive = join10(layout.releasesRoot, `.download-${releaseId}-${process.pid}.tar.gz`);
4191
+ const tempArchive = join11(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), {
@@ -4197,7 +4197,7 @@ async function stageRelease(layout, manifestUrl, published, opts = {}) {
4197
4197
  if (!response.ok || !response.body) {
4198
4198
  throw new Error(`downloading ${published.file} failed: HTTP ${response.status}`);
4199
4199
  }
4200
- const hash = createHash7("sha256");
4200
+ const hash = createHash8("sha256");
4201
4201
  const chunks = [];
4202
4202
  for await (const chunk of response.body) {
4203
4203
  const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
@@ -4210,7 +4210,7 @@ async function stageRelease(layout, manifestUrl, published, opts = {}) {
4210
4210
  }
4211
4211
  await writeFile10(tempArchive, Buffer.concat(chunks), { mode: 384 });
4212
4212
  const entries = (await new Promise((resolveList, rejectList) => {
4213
- const child = spawn6("tar", ["-tzf", tempArchive], { stdio: ["ignore", "pipe", "inherit"] });
4213
+ const child = spawn8("tar", ["-tzf", tempArchive], { stdio: ["ignore", "pipe", "inherit"] });
4214
4214
  let out = "";
4215
4215
  child.stdout?.on("data", (chunk) => {
4216
4216
  out += chunk.toString("utf8");
@@ -4228,13 +4228,13 @@ 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(join10(releaseDir, relative3), fsConstants2.F_OK);
4231
+ await access(join11(releaseDir, relative3), fsConstants2.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, [join10(releaseDir, BUNDLE_ENTRYPOINT), "--version"], 6e4);
4237
+ const probe = await run(process.execPath, [join11(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
  }
@@ -4272,8 +4272,8 @@ async function replaceFile(path, contents, mode) {
4272
4272
  await rename4(temp, path);
4273
4273
  }
4274
4274
  async function activateRelease(layout, releaseId) {
4275
- const releaseDir = join10(layout.releasesRoot, releaseId);
4276
- await access(join10(releaseDir, BUNDLE_ENTRYPOINT), fsConstants2.F_OK);
4275
+ const releaseDir = join11(layout.releasesRoot, releaseId);
4276
+ await access(join11(releaseDir, BUNDLE_ENTRYPOINT), fsConstants2.F_OK);
4277
4277
  await mkdir15(layout.releasesRoot, { recursive: true });
4278
4278
  await mkdir15(layout.binDir, { recursive: true });
4279
4279
  let previousReleaseId = await activeReleaseId(layout);
@@ -4281,12 +4281,12 @@ async function activateRelease(layout, releaseId) {
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 = join10(layout.releasesRoot, legacyId);
4284
+ const legacyDir = join11(layout.releasesRoot, legacyId);
4285
4285
  try {
4286
4286
  await access(legacyDir, fsConstants2.F_OK);
4287
4287
  previousReleaseId = `${legacyId}-${Date.now()}`;
4288
- await rename4(layout.libDir, join10(layout.releasesRoot, previousReleaseId));
4289
- await normalizeLegacyBundleShape(join10(layout.releasesRoot, previousReleaseId));
4288
+ await rename4(layout.libDir, join11(layout.releasesRoot, previousReleaseId));
4289
+ await normalizeLegacyBundleShape(join11(layout.releasesRoot, previousReleaseId));
4290
4290
  } catch {
4291
4291
  await rename4(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 rm6(tempLink, { force: true });
4298
- await symlink3(join10("beeline-releases", releaseId), tempLink);
4298
+ await symlink3(join11("beeline-releases", releaseId), tempLink);
4299
4299
  await rename4(tempLink, layout.libDir);
4300
- await fsyncDir(dirname11(layout.libDir));
4300
+ await fsyncDir(dirname12(layout.libDir));
4301
4301
  await writeBinForwarders(layout, releaseDir);
4302
4302
  return { previousReleaseId };
4303
4303
  }
4304
4304
  async function normalizeLegacyBundleShape(bundleDir) {
4305
- const innerLib = join10(bundleDir, "lib", "beeline");
4305
+ const innerLib = join11(bundleDir, "lib", "beeline");
4306
4306
  let anyFlat = false;
4307
4307
  for (const name of LEGACY_FLAT_BUNDLE_FILES) {
4308
4308
  try {
4309
- await access(join10(bundleDir, name), fsConstants2.F_OK);
4309
+ await access(join11(bundleDir, name), fsConstants2.F_OK);
4310
4310
  anyFlat = true;
4311
4311
  break;
4312
4312
  } catch {
@@ -4317,11 +4317,11 @@ async function normalizeLegacyBundleShape(bundleDir) {
4317
4317
  await mkdir15(innerLib, { recursive: true });
4318
4318
  for (const name of LEGACY_FLAT_BUNDLE_FILES) {
4319
4319
  try {
4320
- await access(join10(innerLib, name), fsConstants2.F_OK);
4320
+ await access(join11(innerLib, name), fsConstants2.F_OK);
4321
4321
  continue;
4322
4322
  } catch {
4323
4323
  }
4324
- await rename4(join10(bundleDir, name), join10(innerLib, name)).catch(() => void 0);
4324
+ await rename4(join11(bundleDir, name), join11(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 = join10(activeBundleRoot, "bin", tool);
4333
+ const target = join11(activeBundleRoot, "bin", tool);
4334
4334
  try {
4335
4335
  await access(target, fsConstants2.X_OK);
4336
4336
  } catch {
4337
4337
  continue;
4338
4338
  }
4339
- await replaceFile(join10(layout.binDir, name), forwarderScript(tool), 493);
4339
+ await replaceFile(join11(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 readFile10(join10(layout.binDir, name), "utf8");
4348
+ current = await readFile10(join11(layout.binDir, name), "utf8");
4349
4349
  } catch {
4350
4350
  current = void 0;
4351
4351
  }
@@ -4364,19 +4364,19 @@ async function repairInstallForwarders(layout, opts = {}) {
4364
4364
  return true;
4365
4365
  }
4366
4366
  async function rollbackToPreviousRelease(layout, previousReleaseId) {
4367
- const releaseDir = join10(layout.releasesRoot, previousReleaseId);
4367
+ const releaseDir = join11(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 rm6(tempLink, { force: true });
4374
- await symlink3(join10("beeline-releases", previousReleaseId), tempLink);
4374
+ await symlink3(join11("beeline-releases", previousReleaseId), tempLink);
4375
4375
  await rename4(tempLink, layout.libDir);
4376
- await fsyncDir(dirname11(layout.libDir));
4376
+ await fsyncDir(dirname12(layout.libDir));
4377
4377
  }
4378
4378
  function updateAttemptPath(layout) {
4379
- return join10(layout.releasesRoot, ".state", "update-attempt.json");
4379
+ return join11(layout.releasesRoot, ".state", "update-attempt.json");
4380
4380
  }
4381
4381
  async function readUpdateAttempt(layout) {
4382
4382
  try {
@@ -4390,7 +4390,7 @@ async function readUpdateAttempt(layout) {
4390
4390
  }
4391
4391
  }
4392
4392
  async function writeUpdateAttempt(layout, record3) {
4393
- await mkdir15(join10(layout.releasesRoot, ".state"), { recursive: true });
4393
+ await mkdir15(join11(layout.releasesRoot, ".state"), { recursive: true });
4394
4394
  const path = updateAttemptPath(layout);
4395
4395
  const staged = `${path}.${process.pid}.tmp`;
4396
4396
  await writeFile10(staged, `${JSON.stringify(record3, null, 2)}
@@ -4668,7 +4668,7 @@ function configureNetworkFamilyDefaults(network = net) {
4668
4668
  configureNetworkFamilyDefaults();
4669
4669
 
4670
4670
  // apps/body/dist/cli.js
4671
- import { dirname as dirname17, resolve as resolve30 } from "node:path";
4671
+ import { dirname as dirname18, resolve as resolve31 } from "node:path";
4672
4672
  import { readFile as readFile15, unlink as unlink5, writeFile as writeFile16 } from "node:fs/promises";
4673
4673
  import { stdin as stdin4, stdout as stdout5 } from "node:process";
4674
4674
 
@@ -6079,13 +6079,496 @@ ${r2}
6079
6079
  var import_picocolors3 = __toESM(require_picocolors(), 1);
6080
6080
 
6081
6081
  // apps/body/dist/config.js
6082
- import { accessSync as accessSync2, constants as constants2, existsSync as existsSync2, readFileSync } from "node:fs";
6082
+ import { accessSync as accessSync2, constants as constants2, existsSync as existsSync3, readFileSync } from "node:fs";
6083
6083
  import { basename, dirname, resolve as resolve2 } from "node:path";
6084
6084
 
6085
6085
  // apps/body/dist/agent-command.js
6086
- import { accessSync, constants, existsSync, readdirSync } from "node:fs";
6086
+ import { accessSync, constants, existsSync as existsSync2, readdirSync } from "node:fs";
6087
6087
  import { homedir } from "node:os";
6088
6088
  import { delimiter, isAbsolute, join, resolve } from "node:path";
6089
+
6090
+ // apps/body/dist/cursor-acp-bridge.js
6091
+ import { spawn as spawn2 } from "node:child_process";
6092
+ import { existsSync } from "node:fs";
6093
+ import { createRequire } from "node:module";
6094
+ import { createInterface as createInterface2 } from "node:readline";
6095
+ import { resolve as resolvePath } from "node:path";
6096
+ import { fileURLToPath } from "node:url";
6097
+ import { randomUUID } from "node:crypto";
6098
+
6099
+ // apps/body/dist/cursor-models.js
6100
+ import { spawn } from "node:child_process";
6101
+ var CURSOR_MODELS_TIMEOUT_MS = 1e4;
6102
+ function parseCursorModelsOutput(output) {
6103
+ const options = [];
6104
+ for (const line of output.split(/\r?\n/)) {
6105
+ const match = /^\s*([A-Za-z0-9][A-Za-z0-9._-]*)\s+-\s+(\S.*?)\s*$/.exec(line);
6106
+ if (!match)
6107
+ continue;
6108
+ const id = match[1];
6109
+ const name = match[2].replace(/\s*\(current, default\)\s*$/i, "").trim();
6110
+ options.push({ id, ...name && name !== id ? { name } : {} });
6111
+ }
6112
+ if (!options.length)
6113
+ return void 0;
6114
+ return {
6115
+ currentValue: options.some((option) => option.id === "auto") ? "auto" : options[0].id,
6116
+ options
6117
+ };
6118
+ }
6119
+ async function enumerateCursorModels(env = process.env) {
6120
+ return new Promise((resolve32) => {
6121
+ const child = spawn("cursor-agent", ["models"], {
6122
+ env,
6123
+ stdio: ["ignore", "pipe", "ignore"]
6124
+ });
6125
+ let output = "";
6126
+ const timer = setTimeout(() => {
6127
+ child.kill("SIGKILL");
6128
+ }, CURSOR_MODELS_TIMEOUT_MS);
6129
+ child.stdout?.on("data", (chunk) => {
6130
+ output += chunk.toString();
6131
+ });
6132
+ child.on("error", () => {
6133
+ clearTimeout(timer);
6134
+ resolve32(void 0);
6135
+ });
6136
+ child.on("close", (code) => {
6137
+ clearTimeout(timer);
6138
+ resolve32(code === 0 ? parseCursorModelsOutput(output) : void 0);
6139
+ });
6140
+ });
6141
+ }
6142
+
6143
+ // apps/body/dist/cursor-acp-bridge.js
6144
+ var CURSOR_ACP_BRIDGE_FLAG = "--cursor-acp-bridge";
6145
+ var CURSOR_ACP_BRIDGE_LABEL = "cursor-acp-bridge";
6146
+ var CURSOR_AGENT_FORCE_FLAG = "--force";
6147
+ var CURSOR_AGENT_TRUST_FLAG = "--trust";
6148
+ var CURSOR_HARNESS_COMMAND = /(^|[/\\])(cursor-acp-bridge|cursor-agent-acp)(\.[a-z]+)?$/i;
6149
+ var STDERR_TAIL_MAX_CHARS = 2e3;
6150
+ var MODEL_AXIS_ID = "model";
6151
+ function harnessIdentityLabel(agent) {
6152
+ if (agent.kind === "cursor")
6153
+ return CURSOR_ACP_BRIDGE_LABEL;
6154
+ return agent.command ?? "";
6155
+ }
6156
+ function cursorAcpBridgeLaunch() {
6157
+ const meta = "usebeeline:npm";
6158
+ if (meta === "beeline:bundle" || meta.startsWith("beeline:")) {
6159
+ const entry = process.argv[1];
6160
+ if (!entry) {
6161
+ throw new Error("Cursor ACP bridge cannot resolve the Beeline CLI entry");
6162
+ }
6163
+ return { command: process.execPath, args: [entry, CURSOR_ACP_BRIDGE_FLAG] };
6164
+ }
6165
+ const js = fileURLToPath(new URL("./cursor-acp-bridge.js", meta));
6166
+ const ts = fileURLToPath(new URL("./cursor-acp-bridge.ts", meta));
6167
+ if (existsSync(js))
6168
+ return { command: process.execPath, args: [js] };
6169
+ if (existsSync(ts)) {
6170
+ const tsx = createRequire(meta).resolve("tsx");
6171
+ return { command: process.execPath, args: ["--import", tsx, ts] };
6172
+ }
6173
+ throw new Error("Cursor ACP bridge entry not found next to the Beeline helper");
6174
+ }
6175
+ function cursorAgentArgv(input) {
6176
+ const argv = [
6177
+ "--print",
6178
+ "--output-format",
6179
+ "stream-json",
6180
+ CURSOR_AGENT_TRUST_FLAG,
6181
+ CURSOR_AGENT_FORCE_FLAG
6182
+ ];
6183
+ if (input.model && input.model !== "auto")
6184
+ argv.push("--model", input.model);
6185
+ argv.push(input.prompt);
6186
+ return argv;
6187
+ }
6188
+ function asRecord(value) {
6189
+ return value && typeof value === "object" ? value : void 0;
6190
+ }
6191
+ function textChunksFromContent(content) {
6192
+ if (typeof content === "string" && content)
6193
+ return [content];
6194
+ if (!Array.isArray(content))
6195
+ return [];
6196
+ const chunks = [];
6197
+ for (const block2 of content) {
6198
+ const record3 = asRecord(block2);
6199
+ if (!record3)
6200
+ continue;
6201
+ if (record3.type === "text" && typeof record3.text === "string" && record3.text) {
6202
+ chunks.push(record3.text);
6203
+ }
6204
+ }
6205
+ return chunks;
6206
+ }
6207
+ function thoughtText(event) {
6208
+ if (typeof event.text === "string")
6209
+ return event.text;
6210
+ const record3 = asRecord(event);
6211
+ if (!record3)
6212
+ return "";
6213
+ if (typeof record3.delta === "string")
6214
+ return record3.delta;
6215
+ return textChunksFromContent(record3.content).join("");
6216
+ }
6217
+ function assistantTexts(event) {
6218
+ if (typeof event.text === "string" && event.text)
6219
+ return [event.text];
6220
+ const message = asRecord(event.message);
6221
+ if (message)
6222
+ return textChunksFromContent(message.content);
6223
+ return textChunksFromContent(asRecord(event)?.content);
6224
+ }
6225
+ function chunkUpdate(sessionUpdate, text2) {
6226
+ return { sessionUpdate, content: { type: "text", text: text2 } };
6227
+ }
6228
+ function translateCursorStreamEvent(event) {
6229
+ if (event.type === "thinking") {
6230
+ if (event.subtype === "completed")
6231
+ return [];
6232
+ const text2 = thoughtText(event);
6233
+ return text2 ? [chunkUpdate("agent_thought_chunk", text2)] : [];
6234
+ }
6235
+ if (event.type === "assistant") {
6236
+ return assistantTexts(event).map((text2) => chunkUpdate("agent_message_chunk", text2));
6237
+ }
6238
+ return [];
6239
+ }
6240
+ function resultEventText(event) {
6241
+ if (typeof event.result === "string")
6242
+ return event.result;
6243
+ const record3 = asRecord(event.result);
6244
+ if (record3 && typeof record3.text === "string")
6245
+ return record3.text;
6246
+ return "";
6247
+ }
6248
+ function isCursorResultEvent(event) {
6249
+ return event.type === "result";
6250
+ }
6251
+ function cursorResultIsError(event) {
6252
+ return event.is_error === true || event.subtype === "error";
6253
+ }
6254
+ function trimReason(value) {
6255
+ return value.replace(/\s+/g, " ").trim().slice(0, 200);
6256
+ }
6257
+ function describeCursorTurnFailure(input) {
6258
+ if (input.spawnError) {
6259
+ return trimReason(`cursor-agent failed to start: ${input.spawnError}`);
6260
+ }
6261
+ const stderr = input.stderr?.trim() ?? "";
6262
+ if (input.isError) {
6263
+ const named = input.resultText?.trim() || stderr || "cursor-agent reported an error with no answer text";
6264
+ return trimReason(`cursor-agent reported an error: ${named}`);
6265
+ }
6266
+ if (input.signal) {
6267
+ return trimReason(`cursor-agent terminated by ${input.signal}${stderr ? `: ${stderr}` : ""}`);
6268
+ }
6269
+ if (input.exitCode !== 0 && input.exitCode !== null) {
6270
+ return trimReason(`cursor-agent exited ${input.exitCode}${stderr ? `: ${stderr}` : " with no answer text"}`);
6271
+ }
6272
+ return void 0;
6273
+ }
6274
+ function promptTextFromParams(params, systemPrompt) {
6275
+ const record3 = asRecord(params);
6276
+ const blocks = Array.isArray(record3?.prompt) ? record3.prompt : [];
6277
+ const user = blocks.map((block2) => {
6278
+ const item = asRecord(block2);
6279
+ return item?.type === "text" && typeof item.text === "string" ? item.text : "";
6280
+ }).filter(Boolean).join("\n");
6281
+ return systemPrompt ? `${systemPrompt}
6282
+
6283
+ ${user}` : user;
6284
+ }
6285
+ function defaultSpawnCursorAgent(input) {
6286
+ return spawn2("cursor-agent", input.argv, {
6287
+ cwd: input.cwd,
6288
+ env: input.env,
6289
+ stdio: ["ignore", "pipe", "pipe"]
6290
+ });
6291
+ }
6292
+ var CursorAcpServer = class {
6293
+ write;
6294
+ spawnCursorAgent;
6295
+ enumerateModels;
6296
+ env;
6297
+ sessions = /* @__PURE__ */ new Map();
6298
+ models;
6299
+ modelsLoaded = false;
6300
+ constructor(options) {
6301
+ this.write = options.write;
6302
+ this.spawnCursorAgent = options.spawnCursorAgent ?? defaultSpawnCursorAgent;
6303
+ this.enumerateModels = options.enumerateModels ?? enumerateCursorModels;
6304
+ this.env = options.env ?? process.env;
6305
+ }
6306
+ async handle(message) {
6307
+ const method = typeof message.method === "string" ? message.method : "";
6308
+ const id = message.id;
6309
+ if (!method)
6310
+ return;
6311
+ if (id === void 0) {
6312
+ if (method === "session/cancel")
6313
+ this.cancel(message.params);
6314
+ return;
6315
+ }
6316
+ try {
6317
+ const result = await this.dispatch(method, message.params);
6318
+ this.write({ jsonrpc: "2.0", id, result });
6319
+ } catch (error) {
6320
+ const rpcError = error;
6321
+ this.write({
6322
+ jsonrpc: "2.0",
6323
+ id,
6324
+ error: {
6325
+ code: typeof rpcError.code === "number" ? rpcError.code : -32e3,
6326
+ message: error instanceof Error ? error.message : String(error)
6327
+ }
6328
+ });
6329
+ }
6330
+ }
6331
+ async dispatch(method, params) {
6332
+ switch (method) {
6333
+ case "initialize":
6334
+ return {
6335
+ protocolVersion: 1,
6336
+ agentCapabilities: { promptCapabilities: { image: false } }
6337
+ };
6338
+ case "session/new":
6339
+ return this.sessionNew(params);
6340
+ case "session/prompt":
6341
+ return this.sessionPrompt(params);
6342
+ case "session/set_config_option":
6343
+ return this.setConfigOption(params);
6344
+ case "session/set_model":
6345
+ return this.setModel(params);
6346
+ case "shutdown":
6347
+ this.shutdown();
6348
+ return {};
6349
+ default:
6350
+ return {};
6351
+ }
6352
+ }
6353
+ async loadModels() {
6354
+ if (this.modelsLoaded) {
6355
+ return this.models ?? { currentValue: "auto", options: [{ id: "auto", name: "Auto" }] };
6356
+ }
6357
+ this.modelsLoaded = true;
6358
+ this.models = await this.enumerateModels(this.env);
6359
+ return this.models ?? { currentValue: "auto", options: [{ id: "auto", name: "Auto" }] };
6360
+ }
6361
+ async sessionNew(params) {
6362
+ const record3 = asRecord(params);
6363
+ const cwd = typeof record3?.cwd === "string" && record3.cwd ? record3.cwd : process.cwd();
6364
+ const systemPrompt = typeof record3?.systemPrompt === "string" ? record3.systemPrompt : void 0;
6365
+ const catalog = await this.loadModels();
6366
+ const session = {
6367
+ id: randomUUID(),
6368
+ cwd,
6369
+ ...systemPrompt ? { systemPrompt } : {},
6370
+ model: catalog.currentValue
6371
+ };
6372
+ this.sessions.set(session.id, session);
6373
+ return {
6374
+ sessionId: session.id,
6375
+ configOptions: [
6376
+ {
6377
+ id: MODEL_AXIS_ID,
6378
+ category: "model",
6379
+ currentValue: session.model,
6380
+ options: catalog.options.map((option) => ({
6381
+ id: option.id,
6382
+ ...option.name ? { name: option.name } : {}
6383
+ }))
6384
+ }
6385
+ ]
6386
+ };
6387
+ }
6388
+ session(params) {
6389
+ const record3 = asRecord(params);
6390
+ const sessionId = typeof record3?.sessionId === "string" ? record3.sessionId : "";
6391
+ const session = this.sessions.get(sessionId);
6392
+ if (!session) {
6393
+ const error = new Error(`unknown ACP session ${sessionId || "(missing)"}`);
6394
+ error.code = -32602;
6395
+ throw error;
6396
+ }
6397
+ return session;
6398
+ }
6399
+ setConfigOption(params) {
6400
+ const session = this.session(params);
6401
+ const record3 = asRecord(params);
6402
+ if (record3?.configId === MODEL_AXIS_ID && typeof record3.value === "string" && record3.value) {
6403
+ session.model = record3.value;
6404
+ }
6405
+ return {};
6406
+ }
6407
+ setModel(params) {
6408
+ const session = this.session(params);
6409
+ const record3 = asRecord(params);
6410
+ if (typeof record3?.modelId === "string" && record3.modelId)
6411
+ session.model = record3.modelId;
6412
+ return {};
6413
+ }
6414
+ emitUpdate(sessionId, update) {
6415
+ this.write({
6416
+ jsonrpc: "2.0",
6417
+ method: "session/update",
6418
+ params: { sessionId, update }
6419
+ });
6420
+ }
6421
+ async sessionPrompt(params) {
6422
+ const session = this.session(params);
6423
+ if (session.child) {
6424
+ throw new Error("cursor-agent is already running a turn for this session");
6425
+ }
6426
+ const prompt = promptTextFromParams(params, session.systemPrompt);
6427
+ const argv = cursorAgentArgv({ prompt, model: session.model });
6428
+ let stderr = "";
6429
+ let spawnError;
6430
+ let sawAssistant = false;
6431
+ let resultEvent;
6432
+ const pending = [];
6433
+ const consumeLine = (line) => {
6434
+ const trimmed = line.trim();
6435
+ if (!trimmed)
6436
+ return;
6437
+ let event;
6438
+ try {
6439
+ event = JSON.parse(trimmed);
6440
+ } catch {
6441
+ return;
6442
+ }
6443
+ if (isCursorResultEvent(event)) {
6444
+ resultEvent = event;
6445
+ return;
6446
+ }
6447
+ for (const update of translateCursorStreamEvent(event)) {
6448
+ if (update.sessionUpdate === "agent_message_chunk")
6449
+ sawAssistant = true;
6450
+ this.emitUpdate(session.id, update);
6451
+ }
6452
+ };
6453
+ const child = this.spawnCursorAgent({ argv, cwd: session.cwd, env: this.env });
6454
+ session.child = child;
6455
+ child.stderr?.setEncoding("utf8");
6456
+ child.stderr?.on("data", (chunk) => {
6457
+ stderr = `${stderr}${chunk}`.slice(-STDERR_TAIL_MAX_CHARS);
6458
+ });
6459
+ child.stdout?.setEncoding("utf8");
6460
+ child.stdout?.on("data", (chunk) => {
6461
+ pending.push(chunk);
6462
+ const joined = pending.join("");
6463
+ const lines = joined.split(/\r?\n/);
6464
+ pending.length = 0;
6465
+ const rest = lines.pop();
6466
+ if (rest)
6467
+ pending.push(rest);
6468
+ for (const line of lines)
6469
+ consumeLine(line);
6470
+ });
6471
+ try {
6472
+ const { code, signal } = await new Promise((resolve32) => {
6473
+ let settled = false;
6474
+ const finish = (exitCode, exitSignal) => {
6475
+ if (settled)
6476
+ return;
6477
+ settled = true;
6478
+ resolve32({ code: exitCode, signal: exitSignal });
6479
+ };
6480
+ child.once("error", (error) => {
6481
+ spawnError = error instanceof Error ? error.message : String(error);
6482
+ finish(1, null);
6483
+ });
6484
+ child.once("close", (exitCode, exitSignal) => {
6485
+ finish(exitCode, exitSignal);
6486
+ });
6487
+ });
6488
+ if (pending.length)
6489
+ consumeLine(pending.join(""));
6490
+ const failure = describeCursorTurnFailure({
6491
+ isError: resultEvent ? cursorResultIsError(resultEvent) : false,
6492
+ resultText: resultEvent ? resultEventText(resultEvent) : void 0,
6493
+ exitCode: spawnError ? 1 : code,
6494
+ signal,
6495
+ stderr,
6496
+ spawnError
6497
+ });
6498
+ if (failure)
6499
+ throw new Error(failure);
6500
+ if (!sawAssistant) {
6501
+ const fallback = resultEvent && !cursorResultIsError(resultEvent) ? resultEventText(resultEvent) : "";
6502
+ if (fallback)
6503
+ this.emitUpdate(session.id, chunkUpdate("agent_message_chunk", fallback));
6504
+ }
6505
+ return { stopReason: "end_turn" };
6506
+ } finally {
6507
+ session.child = void 0;
6508
+ }
6509
+ }
6510
+ cancel(params) {
6511
+ const record3 = asRecord(params);
6512
+ const sessionId = typeof record3?.sessionId === "string" ? record3.sessionId : "";
6513
+ const session = this.sessions.get(sessionId);
6514
+ if (!session?.child?.pid)
6515
+ return;
6516
+ try {
6517
+ session.child.kill("SIGTERM");
6518
+ } catch {
6519
+ }
6520
+ }
6521
+ shutdown() {
6522
+ for (const session of this.sessions.values()) {
6523
+ if (!session.child?.pid)
6524
+ continue;
6525
+ try {
6526
+ session.child.kill("SIGTERM");
6527
+ } catch {
6528
+ }
6529
+ }
6530
+ this.sessions.clear();
6531
+ }
6532
+ };
6533
+ async function runCursorAcpStdioServer(options = {}) {
6534
+ const server = new CursorAcpServer({
6535
+ ...options,
6536
+ write: (message) => {
6537
+ process.stdout.write(`${JSON.stringify(message)}
6538
+ `);
6539
+ }
6540
+ });
6541
+ const lines = createInterface2({ input: process.stdin });
6542
+ for await (const line of lines) {
6543
+ const trimmed = line.trim();
6544
+ if (!trimmed)
6545
+ continue;
6546
+ let message;
6547
+ try {
6548
+ message = JSON.parse(trimmed);
6549
+ } catch {
6550
+ continue;
6551
+ }
6552
+ await server.handle(message);
6553
+ if (message.method === "shutdown")
6554
+ break;
6555
+ }
6556
+ }
6557
+ function isDirectBridgeRun() {
6558
+ const entry = process.argv[1];
6559
+ if (!entry || entry.includes(".test."))
6560
+ return false;
6561
+ try {
6562
+ return resolvePath(entry) === resolvePath(fileURLToPath("usebeeline:npm"));
6563
+ } catch {
6564
+ return false;
6565
+ }
6566
+ }
6567
+ if (isDirectBridgeRun()) {
6568
+ void runCursorAcpStdioServer();
6569
+ }
6570
+
6571
+ // apps/body/dist/agent-command.js
6089
6572
  var AGENT_KINDS = [
6090
6573
  "codex",
6091
6574
  "claude",
@@ -6117,10 +6600,6 @@ var ADAPTER_INSTALL_COMMANDS = {
6117
6600
  pi: {
6118
6601
  command: "npm",
6119
6602
  args: ["install", "-g", "pi-acp"]
6120
- },
6121
- cursor: {
6122
- command: "npm",
6123
- args: ["install", "-g", "cursor-agent-acp"]
6124
6603
  }
6125
6604
  };
6126
6605
  function adapterInstallHint(kind) {
@@ -6190,7 +6669,7 @@ function describeExecutableSearch(env = process.env) {
6190
6669
  return augmentedSearchDirectories(env).join(", ");
6191
6670
  }
6192
6671
  function firstExisting(paths) {
6193
- return paths.find((path) => path && existsSync(path));
6672
+ return paths.find((path) => path && existsSync2(path));
6194
6673
  }
6195
6674
  function executableOnPath(name, env = process.env) {
6196
6675
  for (const directory of augmentedSearchDirectories(env)) {
@@ -6303,8 +6782,8 @@ function resolveAgentCommand(opts) {
6303
6782
  }
6304
6783
  if (typedKind === "cursor") {
6305
6784
  requireExecutable("cursor-agent", env, cwd, "Cursor Agent CLI not found. Install it from https://cursor.com/docs/cli, then retry with `--agent cursor`.");
6306
- const command2 = requireExecutable("cursor-agent-acp", env, cwd, `Cursor ACP adapter not found. Install it with \`${adapterInstallHint("cursor")}\`, then retry with \`--agent cursor\`.`);
6307
- return { kind: typedKind, command: command2, args: [] };
6785
+ const bridge = cursorAcpBridgeLaunch();
6786
+ return { kind: typedKind, command: bridge.command, args: bridge.args };
6308
6787
  }
6309
6788
  if (typedKind === "grok") {
6310
6789
  const command2 = requireExecutable("grok", env, cwd, "Grok CLI not found. Install it with `curl -fsSL https://x.ai/cli/install.sh | bash`, then retry with `--agent grok`.");
@@ -6341,7 +6820,7 @@ function detectInstalledAgentCommands(opts = {}) {
6341
6820
  agent: resolveAgentCommand({ kind, env, cwd: opts.cwd })
6342
6821
  });
6343
6822
  } catch {
6344
- if (kind !== "goose" && kind !== "grok") {
6823
+ if (kind !== "goose" && kind !== "grok" && kind !== "cursor") {
6345
6824
  detected.push({
6346
6825
  kind,
6347
6826
  status: "missing-adapter",
@@ -6365,7 +6844,7 @@ function formatAdapterInstallCommand(install) {
6365
6844
  // apps/body/dist/config.js
6366
6845
  function firstExisting2(paths) {
6367
6846
  for (const p of paths) {
6368
- if (p && existsSync2(p))
6847
+ if (p && existsSync3(p))
6369
6848
  return p;
6370
6849
  }
6371
6850
  return void 0;
@@ -6418,7 +6897,7 @@ function resolveReadonlyMcpCommand(env = process.env) {
6418
6897
  if (binary)
6419
6898
  return { command: binary, args: [] };
6420
6899
  const script = env.BEELINE_READONLY_MCP_SCRIPT;
6421
- if (script && existsSync2(script))
6900
+ if (script && existsSync3(script))
6422
6901
  return { command: process.execPath, args: [script] };
6423
6902
  const built = firstExisting2([
6424
6903
  resolve2(process.cwd(), "apps", "body", "dist", "read-only-mcp.js"),
@@ -6453,7 +6932,7 @@ function resolveCodegraphCommand(env = process.env) {
6453
6932
  }
6454
6933
  function parseEnvFile(path) {
6455
6934
  const out = {};
6456
- if (!existsSync2(path))
6935
+ if (!existsSync3(path))
6457
6936
  return out;
6458
6937
  const text2 = readFileSync(path, "utf8");
6459
6938
  for (const raw of text2.split("\n")) {
@@ -6694,7 +7173,7 @@ import { tmpdir } from "node:os";
6694
7173
  import { resolve as resolve4 } from "node:path";
6695
7174
 
6696
7175
  // apps/body/dist/acp.js
6697
- import { spawn } from "node:child_process";
7176
+ import { spawn as spawn3 } from "node:child_process";
6698
7177
  import { EventEmitter } from "node:events";
6699
7178
 
6700
7179
  // apps/body/dist/harness-capabilities.js
@@ -6775,10 +7254,10 @@ var PROFILES = [
6775
7254
  }
6776
7255
  },
6777
7256
  {
6778
- match: /(^|[/\\])cursor-agent-acp(\.[a-z]+)?$/i,
7257
+ match: CURSOR_HARNESS_COMMAND,
6779
7258
  profile: {
6780
7259
  enforcement: "config-isolated",
6781
- note: "cursor-agent-acp bridges cursor-agent to ACP; cursor-agent loads MCP servers from ~/.cursor/mcp.json, so an isolated CURSOR_HOME scopes the session"
7260
+ note: "cursor-acp-bridge drives cursor-agent; cursor-agent loads MCP servers from ~/.cursor/mcp.json, so an isolated CURSOR_HOME scopes the session"
6782
7261
  }
6783
7262
  }
6784
7263
  ];
@@ -6800,7 +7279,7 @@ function matchProfile(agentCommand) {
6800
7279
  }
6801
7280
 
6802
7281
  // apps/body/dist/acp.js
6803
- var STDERR_TAIL_MAX_CHARS = 2e3;
7282
+ var STDERR_TAIL_MAX_CHARS2 = 2e3;
6804
7283
  function braceDelta(line) {
6805
7284
  let delta = 0;
6806
7285
  for (const char of line) {
@@ -7015,7 +7494,7 @@ function agentStreamSnapshot(updates, agentLabel) {
7015
7494
  const completedMessages = [];
7016
7495
  let messageText2 = "";
7017
7496
  let lastWasMessage = false;
7018
- let thoughtText = "";
7497
+ let thoughtText2 = "";
7019
7498
  let thoughtRunOpen = false;
7020
7499
  for (const { update } of updates) {
7021
7500
  const kind = typeof update.sessionUpdate === "string" ? update.sessionUpdate : "";
@@ -7044,8 +7523,8 @@ function agentStreamSnapshot(updates, agentLabel) {
7044
7523
  if (!delta)
7045
7524
  continue;
7046
7525
  if (!thoughtRunOpen)
7047
- thoughtText = "";
7048
- thoughtText += delta;
7526
+ thoughtText2 = "";
7527
+ thoughtText2 += delta;
7049
7528
  thoughtRunOpen = true;
7050
7529
  } else {
7051
7530
  thoughtRunOpen = false;
@@ -7053,7 +7532,7 @@ function agentStreamSnapshot(updates, agentLabel) {
7053
7532
  }
7054
7533
  return {
7055
7534
  messageText: messageText2,
7056
- ...thoughtText || completedMessages.length ? { thoughtText: thoughtText || completedMessages.at(-1) } : {}
7535
+ ...thoughtText2 || completedMessages.length ? { thoughtText: thoughtText2 || completedMessages.at(-1) } : {}
7057
7536
  };
7058
7537
  }
7059
7538
  function toolCallEntries(updates) {
@@ -7139,7 +7618,7 @@ var AcpClient = class extends EventEmitter {
7139
7618
  async start(timeoutMs = 6e4) {
7140
7619
  if (this.alive)
7141
7620
  return;
7142
- this.child = spawn(this.agentCommand, this.agentArgs, {
7621
+ this.child = spawn3(this.agentCommand, this.agentArgs, {
7143
7622
  // agentEnv is the child's whole environment: buildAgentEnv's allowlist is
7144
7623
  // a real boundary, not a decorative one layered over a full inherit.
7145
7624
  env: this.inheritProcessEnv ? { ...process.env, ...this.agentEnv } : this.agentEnv,
@@ -7154,7 +7633,7 @@ var AcpClient = class extends EventEmitter {
7154
7633
  this.stderrTail = "";
7155
7634
  this.child.stderr.setEncoding("utf8");
7156
7635
  this.child.stderr.on("data", (chunk) => {
7157
- this.stderrTail = (this.stderrTail + chunk).slice(-STDERR_TAIL_MAX_CHARS);
7636
+ this.stderrTail = (this.stderrTail + chunk).slice(-STDERR_TAIL_MAX_CHARS2);
7158
7637
  this.emit("stderr", chunk);
7159
7638
  });
7160
7639
  this.child.stdout.setEncoding("utf8");
@@ -7553,7 +8032,7 @@ var AcpClient = class extends EventEmitter {
7553
8032
  const current = this.activeRunIds.get(sessionId);
7554
8033
  if (current)
7555
8034
  return Promise.resolve(current);
7556
- return new Promise((resolve31, reject) => {
8035
+ return new Promise((resolve32, reject) => {
7557
8036
  const onUpdate = (update) => {
7558
8037
  if (update.sessionId !== sessionId)
7559
8038
  return;
@@ -7561,7 +8040,7 @@ var AcpClient = class extends EventEmitter {
7561
8040
  if (!runId)
7562
8041
  return;
7563
8042
  cleanup();
7564
- resolve31(runId);
8043
+ resolve32(runId);
7565
8044
  };
7566
8045
  const timer = setTimeout(() => {
7567
8046
  cleanup();
@@ -7645,13 +8124,13 @@ var AcpClient = class extends EventEmitter {
7645
8124
  }
7646
8125
  const id = this.nextId++;
7647
8126
  const payload = { jsonrpc: "2.0", id, method, params };
7648
- return new Promise((resolve31, reject) => {
8127
+ return new Promise((resolve32, reject) => {
7649
8128
  const timer = setTimeout(() => {
7650
8129
  this.pending.delete(id);
7651
8130
  reject(new AcpRequestTimeoutError(method, timeoutMs, this.stderrTail, Boolean(onStart), detail));
7652
8131
  }, timeoutMs);
7653
8132
  this.pending.set(id, {
7654
- resolve: resolve31,
8133
+ resolve: resolve32,
7655
8134
  reject,
7656
8135
  timer,
7657
8136
  method,
@@ -7945,12 +8424,7 @@ function assertModelSelectionAdvertised(advertisedOptions, selection) {
7945
8424
  continue;
7946
8425
  const axis = advertisedOptions.find((option) => target.categories.includes(option.category));
7947
8426
  if (!axis) {
7948
- throw new ModelSelectionUnavailableError({
7949
- label: target.label,
7950
- value: target.value,
7951
- reason: "axis-missing",
7952
- guidance: `This harness does not advertise a selectable ${target.label} axis.`
7953
- });
8427
+ continue;
7954
8428
  }
7955
8429
  assertModelConfigAxisAllowed(axis.id, advertisedOptions);
7956
8430
  if (!axis.options.some((choice) => choice.id === target.value)) {
@@ -8175,8 +8649,8 @@ async function syncAgentModelCatalog(input) {
8175
8649
  }
8176
8650
 
8177
8651
  // apps/body/dist/connector-google.js
8178
- import { readFileSync as readFileSync3 } from "node:fs";
8179
- import { join as join2 } from "node:path";
8652
+ import { readFileSync as readFileSync4 } from "node:fs";
8653
+ import { join as join3 } from "node:path";
8180
8654
 
8181
8655
  // apps/body/dist/google-workspace-client.js
8182
8656
  function credentialsTokenSource(credentials) {
@@ -8396,182 +8870,164 @@ function googleWorkspaceClient(tokenSource, transport = defaultGoogleApiTranspor
8396
8870
  };
8397
8871
  }
8398
8872
 
8399
- // apps/body/dist/connector-google.js
8400
- var GOOGLE_TOOL_SCOPES = {
8401
- "google-gmail": [
8402
- "https://www.googleapis.com/auth/gmail.send",
8403
- "https://www.googleapis.com/auth/gmail.readonly",
8404
- "https://www.googleapis.com/auth/gmail.compose"
8405
- ],
8406
- "google-calendar": ["https://www.googleapis.com/auth/calendar.events", "https://www.googleapis.com/auth/calendar.readonly"],
8407
- "google-drive": ["https://www.googleapis.com/auth/drive.readonly"],
8408
- "google-youtube": ["https://www.googleapis.com/auth/youtube.readonly"]
8409
- };
8410
- function isGoogleToolConnectorType(type) {
8411
- return type in GOOGLE_TOOL_SCOPES;
8873
+ // apps/body/dist/connector-squire.js
8874
+ import { execFile, spawn as spawn4 } from "node:child_process";
8875
+ import { createHash as createHash2 } from "node:crypto";
8876
+ import { lstatSync as lstatSync2, readFileSync as readFileSync3, realpathSync, rmSync } from "node:fs";
8877
+ import { homedir as homedir2, hostname, tmpdir as tmpdir2 } from "node:os";
8878
+ import { basename as basename3, dirname as dirname2, join as join2, resolve as resolve6 } from "node:path";
8879
+ var SQUIRE_MCP_NAME = "@trusty-squire/mcp";
8880
+ var SQUIRE_CONNECT_PACKAGE = `${SQUIRE_MCP_NAME}@latest`;
8881
+ var activeConnectSession;
8882
+ function squireConnectSession() {
8883
+ return activeConnectSession;
8412
8884
  }
8413
- async function readGoogleCredentialsFromVault(mcp) {
8414
- if (!mcp)
8415
- return { source: "unavailable", reason: "no Trusty Squire connector is paired" };
8416
- let raw;
8885
+ function isProcessAlive(pid) {
8886
+ if (pid === void 0 || pid <= 0)
8887
+ return false;
8417
8888
  try {
8418
- raw = await mcp.call("google_oauth_credentials", {});
8889
+ process.kill(pid, 0);
8890
+ return true;
8419
8891
  } catch (error) {
8420
- return {
8421
- source: "unavailable",
8422
- reason: `Squire has no Google OAuth grant on record yet (connect your Google account in Squire first: ${describe(error)})`
8423
- };
8892
+ return error?.code === "EPERM";
8424
8893
  }
8425
- const record3 = raw && typeof raw === "object" ? raw : {};
8426
- const inner = record3.credentials && typeof record3.credentials === "object" ? record3.credentials : record3;
8427
- const accessToken = inner.accessToken ?? inner.access_token;
8428
- if (!accessToken || typeof accessToken !== "string") {
8429
- return { source: "unavailable", reason: "Squire returned a Google grant without an access token" };
8894
+ }
8895
+ function releaseSquireConnectSession(log2) {
8896
+ const claim = activeConnectSession;
8897
+ activeConnectSession = void 0;
8898
+ if (!claim)
8899
+ return;
8900
+ if (isProcessAlive(claim.pid)) {
8901
+ log2?.(`released trusty-squire connect session claim (pid ${String(claim.pid)} still live \u2014 a fresh connect owns the browser now)`);
8902
+ claim.abort();
8903
+ } else {
8904
+ log2?.("cleared dead trusty-squire connect session claim (owner process gone)");
8430
8905
  }
8431
- return {
8432
- source: "squire",
8433
- credentials: {
8434
- accessToken,
8435
- refreshToken: typeof record3.refreshToken === "string" ? record3.refreshToken : typeof record3.refresh_token === "string" ? record3.refresh_token : void 0,
8436
- expiresAt: typeof record3.expiresAt === "number" ? record3.expiresAt : void 0,
8437
- accountEmail: typeof record3.accountEmail === "string" ? record3.accountEmail : typeof record3.email === "string" ? record3.email : void 0
8438
- }
8439
- };
8440
8906
  }
8441
- function manualGoogleCredentialsSearchPaths(home) {
8442
- return [join2(home, "google-credentials.json")];
8907
+ function squireChromeProfileDir() {
8908
+ return process.env.TRUSTY_SQUIRE_PROFILE_DIR ?? join2(homedir2(), ".trusty-squire", "chrome-profile");
8443
8909
  }
8444
- function loadManualGoogleCredentials(home, env = process.env) {
8445
- if (env.BEELINE_GOOGLE_ACCESS_TOKEN) {
8446
- return {
8447
- source: "manual",
8448
- credentials: { accessToken: env.BEELINE_GOOGLE_ACCESS_TOKEN }
8449
- };
8450
- }
8451
- for (const path of manualGoogleCredentialsSearchPaths(home)) {
8910
+ function squireProfilePathIdentity(profileDir) {
8911
+ const absolute = resolve6(profileDir);
8912
+ const suffix = [];
8913
+ let candidate = absolute;
8914
+ for (; ; ) {
8452
8915
  try {
8453
- const parsed = JSON.parse(readFileSync3(path, "utf8"));
8454
- if (typeof parsed.accessToken === "string" || typeof parsed.access_token === "string") {
8455
- return {
8456
- source: "manual",
8457
- credentials: {
8458
- accessToken: parsed.accessToken ?? parsed.access_token,
8459
- refreshToken: typeof parsed.refreshToken === "string" ? parsed.refreshToken : void 0,
8460
- accountEmail: typeof parsed.accountEmail === "string" ? parsed.accountEmail : void 0
8461
- }
8462
- };
8463
- }
8916
+ return join2(realpathSync.native(candidate), ...suffix.reverse());
8464
8917
  } catch {
8918
+ const parent = dirname2(candidate);
8919
+ if (parent === candidate)
8920
+ return absolute;
8921
+ suffix.push(basename3(candidate));
8922
+ candidate = parent;
8465
8923
  }
8466
8924
  }
8467
- return {
8468
- source: "manual-missing",
8469
- reason: `no Google credentials found. Put a google-credentials.json (OAuth access token) at ${manualGoogleCredentialsSearchPaths(home)[0]} or connect your Google account in Trusty Squire first.`
8470
- };
8471
8925
  }
8472
- var step = (label, status, extra) => ({
8473
- label,
8474
- status,
8475
- ...extra
8476
- });
8477
- function outputTail(text2, maxChars = 800) {
8478
- const trimmed = text2.trim();
8479
- return trimmed.length <= maxChars ? trimmed : `\u2026${trimmed.slice(-maxChars)}`;
8926
+ function squireProfileLockPath(profileDir = squireChromeProfileDir(), lockRoot = tmpdir2()) {
8927
+ const digest = createHash2("sha256").update(squireProfilePathIdentity(profileDir)).digest("hex").slice(0, 24);
8928
+ return join2(lockRoot, `trusty-squire-profile-${digest}.lock`);
8480
8929
  }
8481
- async function installGoogleTool(options) {
8482
- const steps = [step("helper reached", "done")];
8483
- const emit = () => options.onProgress?.([...steps]);
8484
- const push = (next) => {
8485
- steps.push(next);
8486
- emit();
8487
- };
8488
- const fail = (label, reason, output) => {
8489
- push(step(label, "failed", { reason, ...output ? { output } : {} }));
8490
- return { status: "error", steps, errorMessage: reason };
8491
- };
8492
- emit();
8493
- if (!isGoogleToolConnectorType(options.connectorType)) {
8494
- return fail("connector type", `${options.connectorType} is not a Google tool connector`);
8495
- }
8496
- push(step("Google credentials resolved", "running", { output: "resolving\u2026" }));
8497
- const resolved = options.resolvedCredentials ? await options.resolvedCredentials : options.resolveCredentials ? await options.resolveCredentials() : await (async () => {
8498
- const oneClick = await readGoogleCredentialsFromVault(options.squire);
8499
- return oneClick.source === "squire" ? { ...oneClick } : { ...loadManualGoogleCredentials(options.home, options.env) };
8500
- })();
8501
- if (!("credentials" in resolved)) {
8502
- const reason = resolved.reason;
8503
- steps[1] = step("Google credentials resolved", "failed", { reason, output: outputTail(reason) });
8504
- emit();
8505
- return { status: "error", steps, errorMessage: reason };
8506
- }
8507
- steps[1] = step("Google credentials resolved", "done", {
8508
- output: resolved.source === "squire" ? "one-click: read the Google grant from Trusty Squire" : "manual: local google-credentials.json"
8509
- });
8510
- emit();
8511
- const client = options.client ?? googleWorkspaceClient(credentialsTokenSource(resolved.credentials));
8512
- push(step("authorized with Google", "running", { output: "verifying the grant with Google\u2026" }));
8513
- const verify = await client.verify();
8514
- if (!verify.ok) {
8515
- return fail("authorized with Google", verify.reason, outputTail(verify.reason));
8516
- }
8517
- steps[2] = step("authorized with Google", "done", {
8518
- ...verify.account ? { output: `signed in as ${verify.account}` } : {}
8519
- });
8520
- emit();
8521
- push(step("tools enabled", "done", {
8522
- output: `${GOOGLE_TOOL_SCOPES[options.connectorType].length} Google scopes granted`
8523
- }));
8524
- return {
8525
- status: "connected",
8526
- steps,
8527
- ...verify.account ? { signedInAs: verify.account } : {}
8528
- };
8930
+ var SQUIRE_BROWSER_BUSY_GOOGLE_REASON = "Trusty Squire is still using the browser \u2014 connect Trusty Squire first";
8931
+ function isSquireBrowserSessionFailure(text2) {
8932
+ if (typeof text2 !== "string" || text2.length === 0)
8933
+ return false;
8934
+ return /Trusty Squire[\s\S]{0,80}browser/i.test(text2) || /browser[\s\S]{0,80}Trusty Squire/i.test(text2);
8529
8935
  }
8530
- function describe(error) {
8531
- return error instanceof Error ? error.message : String(error);
8936
+ function squireForeignClaimAction(owner) {
8937
+ return `Trusty Squire's browser is in use by another process (pid ${owner.pid}). Finish or close that Trusty Squire session, then press Connect again.`;
8532
8938
  }
8533
-
8534
- // apps/body/dist/connector-squire.js
8535
- import { execFile, spawn as spawn2 } from "node:child_process";
8536
- var SQUIRE_MCP_NAME = "@trusty-squire/mcp";
8537
- var SQUIRE_CONNECT_PACKAGE = `${SQUIRE_MCP_NAME}@latest`;
8538
- var activeConnectSession;
8539
- function isProcessAlive(pid) {
8540
- if (pid === void 0 || pid <= 0)
8541
- return false;
8939
+ function readLinuxStartTime(pid) {
8542
8940
  try {
8543
- process.kill(pid, 0);
8941
+ const stat4 = readFileSync3(`/proc/${pid}/stat`, "utf8");
8942
+ const close = stat4.lastIndexOf(")");
8943
+ return close < 0 ? void 0 : stat4.slice(close + 2).split(" ")[19];
8944
+ } catch {
8945
+ return void 0;
8946
+ }
8947
+ }
8948
+ function lockOwnerIsAlive(owner) {
8949
+ if (!isProcessAlive(owner.pid))
8950
+ return false;
8951
+ if (owner.startTime === null || owner.startTime === "unknown")
8544
8952
  return true;
8545
- } catch (error) {
8546
- return error?.code === "EPERM";
8953
+ const actual = readLinuxStartTime(owner.pid);
8954
+ if (actual === void 0)
8955
+ return true;
8956
+ return actual === owner.startTime;
8957
+ }
8958
+ function readLockFileOwner(lockPath) {
8959
+ try {
8960
+ const target = lstatSync2(lockPath).isDirectory() ? join2(lockPath, "owner.json") : lockPath;
8961
+ const parsed = JSON.parse(readFileSync3(target, "utf8"));
8962
+ if (typeof parsed.host !== "string" || typeof parsed.pid !== "number")
8963
+ return void 0;
8964
+ return {
8965
+ host: parsed.host,
8966
+ pid: parsed.pid,
8967
+ startTime: typeof parsed.start_time === "string" ? parsed.start_time : null
8968
+ };
8969
+ } catch {
8970
+ return void 0;
8547
8971
  }
8548
8972
  }
8549
- function releaseSquireConnectSession(log2) {
8550
- const claim = activeConnectSession;
8551
- activeConnectSession = void 0;
8552
- if (!claim)
8553
- return;
8554
- if (isProcessAlive(claim.pid)) {
8555
- log2?.(`released trusty-squire connect session claim (pid ${String(claim.pid)} still live \u2014 a fresh connect owns the browser now)`);
8556
- claim.abort();
8557
- } else {
8558
- log2?.("cleared dead trusty-squire connect session claim (owner process gone)");
8973
+ function removeProfileLock(lockPath) {
8974
+ rmSync(lockPath, { recursive: true, force: true });
8975
+ }
8976
+ function reclaimSquireProfileClaim(options) {
8977
+ const profileDir = options?.profileDir ?? squireChromeProfileDir();
8978
+ const lockRoot = options?.lockRoot ?? tmpdir2();
8979
+ const lockPath = squireProfileLockPath(profileDir, lockRoot);
8980
+ const owner = readLockFileOwner(lockPath);
8981
+ if (!owner) {
8982
+ return { kind: "free" };
8983
+ }
8984
+ const ours = (options?.ourPids ?? []).includes(owner.pid);
8985
+ if (ours) {
8986
+ removeProfileLock(lockPath);
8987
+ options?.log?.(`released our trusty-squire on-disk browser claim (pid ${owner.pid})`);
8988
+ return { kind: "released-ours", owner };
8559
8989
  }
8990
+ if (owner.host !== hostname() || lockOwnerIsAlive(owner)) {
8991
+ const action = squireForeignClaimAction(owner);
8992
+ options?.log?.(`trusty-squire browser claim blocked by live pid ${owner.pid} \u2014 not superseding a foreign session`);
8993
+ return { kind: "blocked-foreign", owner, action };
8994
+ }
8995
+ removeProfileLock(lockPath);
8996
+ options?.log?.(`cleared dead trusty-squire on-disk browser claim (pid ${owner.pid} gone)`);
8997
+ return { kind: "reclaimed-dead", owner };
8560
8998
  }
8561
- var defaultShellRunner = (command, args) => new Promise((resolve31) => {
8999
+ var defaultShellRunner = (command, args) => new Promise((resolve32) => {
8562
9000
  execFile(command, [...args], { timeout: 12e4, maxBuffer: 4 * 1024 * 1024, encoding: "utf8" }, (error, stdout6, stderr) => {
8563
9001
  const code = error?.code;
8564
- resolve31({
9002
+ resolve32({
8565
9003
  code: typeof code === "number" ? code : error ? 1 : 0,
8566
9004
  stdout: String(stdout6 ?? ""),
8567
9005
  stderr: String(stderr ?? "")
8568
9006
  });
8569
9007
  });
8570
9008
  });
9009
+ function squireConnectProcessEnv(profileDir = squireChromeProfileDir()) {
9010
+ return {
9011
+ ...process.env,
9012
+ TRUSTY_SQUIRE_PROFILE_DIR: profileDir
9013
+ };
9014
+ }
8571
9015
  var CONNECT_TIMEOUT_MS = 3e5;
8572
- var defaultStreamedRunner = (command, args) => new Promise((resolve31) => {
8573
- const child = spawn2(command, args, {
8574
- stdio: ["ignore", "pipe", "pipe"]
9016
+ function killConnectTree(child) {
9017
+ const pid = child.pid;
9018
+ if (pid !== void 0) {
9019
+ try {
9020
+ process.kill(-pid, "SIGTERM");
9021
+ } catch {
9022
+ }
9023
+ }
9024
+ child.kill();
9025
+ }
9026
+ var defaultStreamedRunner = (command, args, env) => new Promise((resolve32) => {
9027
+ const child = spawn4(command, args, {
9028
+ stdio: ["ignore", "pipe", "pipe"],
9029
+ env: env ?? squireConnectProcessEnv(),
9030
+ detached: true
8575
9031
  });
8576
9032
  let stdout6 = "";
8577
9033
  let stderr = "";
@@ -8579,14 +9035,14 @@ var defaultStreamedRunner = (command, args) => new Promise((resolve31) => {
8579
9035
  const safetyTimer = setTimeout(() => {
8580
9036
  if (!resolved) {
8581
9037
  resolved = true;
8582
- resolve31({ stdout: stdout6, stderr, pid: child.pid ?? void 0, signIn: void 0, abort: () => {
9038
+ resolve32({ stdout: stdout6, stderr, pid: child.pid ?? void 0, signIn: void 0, abort: () => {
8583
9039
  } });
8584
9040
  }
8585
- child.kill();
9041
+ killConnectTree(child);
8586
9042
  }, CONNECT_TIMEOUT_MS);
8587
9043
  const abort = () => {
8588
9044
  clearTimeout(safetyTimer);
8589
- child.kill();
9045
+ killConnectTree(child);
8590
9046
  };
8591
9047
  const claim = {
8592
9048
  pid: child.pid ?? void 0,
@@ -8598,7 +9054,7 @@ var defaultStreamedRunner = (command, args) => new Promise((resolve31) => {
8598
9054
  if (!resolved) {
8599
9055
  resolved = true;
8600
9056
  clearTimeout(safetyTimer);
8601
- resolve31(result);
9057
+ resolve32(result);
8602
9058
  }
8603
9059
  };
8604
9060
  const checkOutput = () => {
@@ -8626,7 +9082,7 @@ ${stderr}`;
8626
9082
  } });
8627
9083
  });
8628
9084
  });
8629
- var step2 = (label, status, reason) => ({
9085
+ var step = (label, status, reason) => ({
8630
9086
  label,
8631
9087
  status,
8632
9088
  ...reason ? { reason } : {}
@@ -8690,23 +9146,36 @@ function parseSignedInAs(output) {
8690
9146
  return output.match(/signed in as ([^\s,;]+)/i)?.[1];
8691
9147
  }
8692
9148
  async function installSquire(options) {
9149
+ const profileDir = options.profileDir ?? squireChromeProfileDir();
9150
+ const lockRoot = options.lockRoot ?? tmpdir2();
8693
9151
  const run2 = options.run ?? defaultShellRunner;
8694
9152
  const streamRun = options.streamRun ?? defaultStreamedRunner;
8695
9153
  const log2 = options.log ?? (() => {
8696
9154
  });
8697
- const steps = [step2("helper reached", "done")];
9155
+ const steps = [step("helper reached", "done")];
8698
9156
  const emit = () => options.onProgress?.([...steps]);
8699
9157
  const push = (next) => {
8700
9158
  steps.push(next);
8701
9159
  emit();
8702
9160
  };
8703
9161
  const fail = (reason) => {
8704
- steps.push(step2("waiting for sign-in", "pending"));
9162
+ steps.push(step("waiting for sign-in", "pending"));
8705
9163
  emit();
8706
9164
  return { status: "error", steps, errorMessage: reason };
8707
9165
  };
8708
9166
  emit();
9167
+ const previousPid = squireConnectSession()?.pid;
8709
9168
  releaseSquireConnectSession(log2);
9169
+ const claim = reclaimSquireProfileClaim({
9170
+ log: log2,
9171
+ profileDir,
9172
+ lockRoot,
9173
+ ...previousPid !== void 0 ? { ourPids: [previousPid] } : {}
9174
+ });
9175
+ if (claim.kind === "blocked-foreign") {
9176
+ push(step("trusty-squire installed", "failed", claim.action));
9177
+ return fail(claim.action);
9178
+ }
8710
9179
  const resolution = await resolveSquireConnectSpec(run2);
8711
9180
  if (resolution.reResolved) {
8712
9181
  log2(`trusty-squire stale copy ${resolution.resolvedVersion ?? "unknown"} re-resolved against current release ${resolution.currentRelease}`);
@@ -8717,21 +9186,30 @@ async function installSquire(options) {
8717
9186
  "--force-relogin=google",
8718
9187
  "--target=codex",
8719
9188
  "--skip-browser"
8720
- ]);
9189
+ ], squireConnectProcessEnv(profileDir));
8721
9190
  if (!install.signIn) {
8722
9191
  const stderr = install.stderr.trim();
8723
- push(step2("trusty-squire installed", "failed", stderr || "connect printed no sign-in URL"));
8724
- return fail(stderr || "the trusty-squire connect command printed no sign-in surface");
9192
+ let stepReason = stderr || "connect printed no sign-in URL";
9193
+ let failReason = stderr || "the trusty-squire connect command printed no sign-in surface";
9194
+ if (isSquireBrowserSessionFailure(stderr)) {
9195
+ const again = reclaimSquireProfileClaim({ log: log2, profileDir, lockRoot });
9196
+ if (again.kind === "blocked-foreign") {
9197
+ stepReason = again.action;
9198
+ failReason = again.action;
9199
+ }
9200
+ }
9201
+ push(step("trusty-squire installed", "failed", stepReason));
9202
+ return fail(failReason);
8725
9203
  }
8726
9204
  const version = resolution.resolvedVersion;
8727
- push(step2(`trusty-squire${version ? ` ${version}` : ""} installed`, "done"));
9205
+ push(step(`trusty-squire${version ? ` ${version}` : ""} installed`, "done"));
8728
9206
  const signIn = install.signIn;
8729
9207
  const signedInAs = parseSignedInAs(`${install.stdout}
8730
9208
  ${install.stderr}`);
8731
- push(step2("waiting for sign-in", "done"));
9209
+ push(step("waiting for sign-in", "done"));
8732
9210
  const pair = await pairSquire(options.mcp, options.workspaceId);
8733
9211
  if (!pair.ok) {
8734
- push(step2("paired to workspace", "failed", pair.reason));
9212
+ push(step("paired to workspace", "failed", pair.reason));
8735
9213
  return {
8736
9214
  status: "installing",
8737
9215
  steps,
@@ -8740,7 +9218,7 @@ ${install.stderr}`);
8740
9218
  ...signedInAs ? { signedInAs } : {}
8741
9219
  };
8742
9220
  }
8743
- push(step2("paired to workspace", "done"));
9221
+ push(step("paired to workspace", "done"));
8744
9222
  return {
8745
9223
  status: "connected",
8746
9224
  steps,
@@ -8759,7 +9237,7 @@ async function pairSquire(mcp, _workspaceId) {
8759
9237
  return { ok: false, reason: error instanceof Error ? error.message : String(error) };
8760
9238
  }
8761
9239
  }
8762
- function asRecord(value) {
9240
+ function asRecord2(value) {
8763
9241
  return value && typeof value === "object" ? value : {};
8764
9242
  }
8765
9243
  function asArray(value) {
@@ -8772,7 +9250,7 @@ function numberOrNull(value) {
8772
9250
  return typeof value === "number" && Number.isFinite(value) ? value : null;
8773
9251
  }
8774
9252
  function vaultConnectionMeta(raw) {
8775
- const record3 = asRecord(raw);
9253
+ const record3 = asRecord2(raw);
8776
9254
  const reference = String(record3.reference ?? record3.id ?? "");
8777
9255
  return {
8778
9256
  reference,
@@ -8786,11 +9264,11 @@ function vaultConnectionMeta(raw) {
8786
9264
  };
8787
9265
  }
8788
9266
  async function readVault(mcp) {
8789
- const result = asRecord(await mcp.call("list_credentials"));
9267
+ const result = asRecord2(await mcp.call("list_credentials"));
8790
9268
  return asArray(result.credentials ?? result.items ?? result).map(vaultConnectionMeta);
8791
9269
  }
8792
9270
  function connectionGrant(raw) {
8793
- const record3 = asRecord(raw);
9271
+ const record3 = asRecord2(raw);
8794
9272
  return {
8795
9273
  grantId: String(record3.grant_id ?? record3.grantId ?? record3.id ?? ""),
8796
9274
  credentialRef: String(record3.credential_ref ?? record3.credentialRef ?? record3.reference ?? ""),
@@ -8801,7 +9279,7 @@ function connectionGrant(raw) {
8801
9279
  };
8802
9280
  }
8803
9281
  async function readGrants(mcp, ref) {
8804
- const result = asRecord(await mcp.call("list_app_access", {}));
9282
+ const result = asRecord2(await mcp.call("list_app_access", {}));
8805
9283
  return asArray(result.grants ?? result.items ?? result).map(connectionGrant).filter((grant) => grant.credentialRef === ref && grant.revokedAt === void 0);
8806
9284
  }
8807
9285
  async function revokeGrants(mcp, ref) {
@@ -8810,7 +9288,7 @@ async function revokeGrants(mcp, ref) {
8810
9288
  let failed = 0;
8811
9289
  for (const grant of grants) {
8812
9290
  try {
8813
- const result = asRecord(await mcp.call("revoke_app_access", { grant_id: grant.grantId }));
9291
+ const result = asRecord2(await mcp.call("revoke_app_access", { grant_id: grant.grantId }));
8814
9292
  if (result.revoked === false)
8815
9293
  failed += 1;
8816
9294
  else
@@ -8822,10 +9300,157 @@ async function revokeGrants(mcp, ref) {
8822
9300
  return { revoked, failed };
8823
9301
  }
8824
9302
 
9303
+ // apps/body/dist/connector-google.js
9304
+ var GOOGLE_TOOL_SCOPES = {
9305
+ "google-gmail": [
9306
+ "https://www.googleapis.com/auth/gmail.send",
9307
+ "https://www.googleapis.com/auth/gmail.readonly",
9308
+ "https://www.googleapis.com/auth/gmail.compose"
9309
+ ],
9310
+ "google-calendar": ["https://www.googleapis.com/auth/calendar.events", "https://www.googleapis.com/auth/calendar.readonly"],
9311
+ "google-drive": ["https://www.googleapis.com/auth/drive.readonly"],
9312
+ "google-youtube": ["https://www.googleapis.com/auth/youtube.readonly"]
9313
+ };
9314
+ function isGoogleToolConnectorType(type) {
9315
+ return type in GOOGLE_TOOL_SCOPES;
9316
+ }
9317
+ async function readGoogleCredentialsFromVault(mcp) {
9318
+ if (!mcp)
9319
+ return { source: "unavailable", reason: "no Trusty Squire connector is paired" };
9320
+ let raw;
9321
+ try {
9322
+ raw = await mcp.call("google_oauth_credentials", {});
9323
+ } catch (error) {
9324
+ const detail = describe(error);
9325
+ if (isSquireBrowserSessionFailure(detail)) {
9326
+ return {
9327
+ source: "unavailable",
9328
+ reason: SQUIRE_BROWSER_BUSY_GOOGLE_REASON
9329
+ };
9330
+ }
9331
+ return {
9332
+ source: "unavailable",
9333
+ reason: `Squire has no Google OAuth grant on record yet (connect your Google account in Squire first: ${detail})`
9334
+ };
9335
+ }
9336
+ const record3 = raw && typeof raw === "object" ? raw : {};
9337
+ const inner = record3.credentials && typeof record3.credentials === "object" ? record3.credentials : record3;
9338
+ const accessToken = inner.accessToken ?? inner.access_token;
9339
+ if (!accessToken || typeof accessToken !== "string") {
9340
+ return { source: "unavailable", reason: "Squire returned a Google grant without an access token" };
9341
+ }
9342
+ return {
9343
+ source: "squire",
9344
+ credentials: {
9345
+ accessToken,
9346
+ refreshToken: typeof record3.refreshToken === "string" ? record3.refreshToken : typeof record3.refresh_token === "string" ? record3.refresh_token : void 0,
9347
+ expiresAt: typeof record3.expiresAt === "number" ? record3.expiresAt : void 0,
9348
+ accountEmail: typeof record3.accountEmail === "string" ? record3.accountEmail : typeof record3.email === "string" ? record3.email : void 0
9349
+ }
9350
+ };
9351
+ }
9352
+ function manualGoogleCredentialsSearchPaths(home) {
9353
+ return [join3(home, "google-credentials.json")];
9354
+ }
9355
+ function loadManualGoogleCredentials(home, env = process.env) {
9356
+ if (env.BEELINE_GOOGLE_ACCESS_TOKEN) {
9357
+ return {
9358
+ source: "manual",
9359
+ credentials: { accessToken: env.BEELINE_GOOGLE_ACCESS_TOKEN }
9360
+ };
9361
+ }
9362
+ for (const path of manualGoogleCredentialsSearchPaths(home)) {
9363
+ try {
9364
+ const parsed = JSON.parse(readFileSync4(path, "utf8"));
9365
+ if (typeof parsed.accessToken === "string" || typeof parsed.access_token === "string") {
9366
+ return {
9367
+ source: "manual",
9368
+ credentials: {
9369
+ accessToken: parsed.accessToken ?? parsed.access_token,
9370
+ refreshToken: typeof parsed.refreshToken === "string" ? parsed.refreshToken : void 0,
9371
+ accountEmail: typeof parsed.accountEmail === "string" ? parsed.accountEmail : void 0
9372
+ }
9373
+ };
9374
+ }
9375
+ } catch {
9376
+ }
9377
+ }
9378
+ return {
9379
+ source: "manual-missing",
9380
+ reason: `no Google credentials found. Put a google-credentials.json (OAuth access token) at ${manualGoogleCredentialsSearchPaths(home)[0]} or connect your Google account in Trusty Squire first.`
9381
+ };
9382
+ }
9383
+ var step2 = (label, status, extra) => ({
9384
+ label,
9385
+ status,
9386
+ ...extra
9387
+ });
9388
+ function outputTail(text2, maxChars = 800) {
9389
+ const trimmed = text2.trim();
9390
+ return trimmed.length <= maxChars ? trimmed : `\u2026${trimmed.slice(-maxChars)}`;
9391
+ }
9392
+ async function installGoogleTool(options) {
9393
+ const steps = [step2("helper reached", "done")];
9394
+ const emit = () => options.onProgress?.([...steps]);
9395
+ const push = (next) => {
9396
+ steps.push(next);
9397
+ emit();
9398
+ };
9399
+ const fail = (label, reason, output) => {
9400
+ push(step2(label, "failed", { reason, ...output ? { output } : {} }));
9401
+ return { status: "error", steps, errorMessage: reason };
9402
+ };
9403
+ emit();
9404
+ if (!isGoogleToolConnectorType(options.connectorType)) {
9405
+ return fail("connector type", `${options.connectorType} is not a Google tool connector`);
9406
+ }
9407
+ push(step2("Google credentials resolved", "running", { output: "resolving\u2026" }));
9408
+ const resolved = options.resolvedCredentials ? await options.resolvedCredentials : options.resolveCredentials ? await options.resolveCredentials() : await (async () => {
9409
+ const oneClick = await readGoogleCredentialsFromVault(options.squire);
9410
+ if (oneClick.source === "squire")
9411
+ return oneClick;
9412
+ if (isSquireBrowserSessionFailure(oneClick.reason))
9413
+ return oneClick;
9414
+ return loadManualGoogleCredentials(options.home, options.env);
9415
+ })();
9416
+ if (!("credentials" in resolved)) {
9417
+ const reason = resolved.reason;
9418
+ steps[1] = step2("Google credentials resolved", "failed", { reason, output: outputTail(reason) });
9419
+ emit();
9420
+ return { status: "error", steps, errorMessage: reason };
9421
+ }
9422
+ steps[1] = step2("Google credentials resolved", "done", {
9423
+ output: resolved.source === "squire" ? "one-click: read the Google grant from Trusty Squire" : "manual: local google-credentials.json"
9424
+ });
9425
+ emit();
9426
+ const client = options.client ?? googleWorkspaceClient(credentialsTokenSource(resolved.credentials));
9427
+ push(step2("authorized with Google", "running", { output: "verifying the grant with Google\u2026" }));
9428
+ const verify = await client.verify();
9429
+ if (!verify.ok) {
9430
+ return fail("authorized with Google", verify.reason, outputTail(verify.reason));
9431
+ }
9432
+ steps[2] = step2("authorized with Google", "done", {
9433
+ ...verify.account ? { output: `signed in as ${verify.account}` } : {}
9434
+ });
9435
+ emit();
9436
+ push(step2("tools enabled", "done", {
9437
+ output: `${GOOGLE_TOOL_SCOPES[options.connectorType].length} Google scopes granted`
9438
+ }));
9439
+ return {
9440
+ status: "connected",
9441
+ steps,
9442
+ ...verify.account ? { signedInAs: verify.account } : {}
9443
+ };
9444
+ }
9445
+ function describe(error) {
9446
+ return error instanceof Error ? error.message : String(error);
9447
+ }
9448
+
8825
9449
  // apps/body/dist/squire-mcp-client.js
8826
- import { spawn as spawn3 } from "node:child_process";
9450
+ import { spawn as spawn5 } from "node:child_process";
8827
9451
  var INITIALIZE_TIMEOUT_MS = 3e4;
8828
9452
  var CALL_TIMEOUT_MS = 12e4;
9453
+ var SQUIRE_MCP_SERVER_ARGS = ["-y", "@trusty-squire/mcp@latest", "server"];
8829
9454
  var StdioSquireMcpClient = class {
8830
9455
  options;
8831
9456
  child;
@@ -8879,12 +9504,7 @@ var StdioSquireMcpClient = class {
8879
9504
  return this.initialized;
8880
9505
  }
8881
9506
  initialize() {
8882
- const child = (this.options.spawn ?? spawn3)(this.options.command ?? "npx", [
8883
- // `@latest`: the current release, never a source-level version pin
8884
- // (captain). Only the vault MCP server the agent spawns; the connect
8885
- // install path verifies freshness itself (connector-squire.ts).
8886
- ...this.options.args ?? ["-y", "@trusty-squire/mcp@latest"]
8887
- ]);
9507
+ const child = (this.options.spawn ?? spawn5)(this.options.command ?? "npx", [...this.options.args ?? [...SQUIRE_MCP_SERVER_ARGS]], { env: this.options.env ?? squireConnectProcessEnv() });
8888
9508
  this.child = child;
8889
9509
  this.buffer = "";
8890
9510
  child.stdout.setEncoding("utf8");
@@ -8918,12 +9538,12 @@ var StdioSquireMcpClient = class {
8918
9538
  const child = this.child;
8919
9539
  if (!child)
8920
9540
  return Promise.reject(new Error("Squire MCP session is not running"));
8921
- return new Promise((resolve31, reject) => {
9541
+ return new Promise((resolve32, reject) => {
8922
9542
  const timer = setTimeout(() => {
8923
9543
  this.pending.delete(id);
8924
9544
  reject(new Error(`${method} timed out`));
8925
9545
  }, method === "initialize" ? INITIALIZE_TIMEOUT_MS : CALL_TIMEOUT_MS);
8926
- this.pending.set(id, { resolve: resolve31, reject, timer });
9546
+ this.pending.set(id, { resolve: resolve32, reject, timer });
8927
9547
  child.stdin.write(`${JSON.stringify({ jsonrpc: "2.0", id, method, params })}
8928
9548
  `);
8929
9549
  });
@@ -9039,6 +9659,7 @@ var ConnectorAssignmentLoop = class {
9039
9659
  this.log(`connector assignments unavailable: ${describe2(error)}`);
9040
9660
  return;
9041
9661
  }
9662
+ const squireWork = [];
9042
9663
  let googleBatch;
9043
9664
  for (const assignment of assignments) {
9044
9665
  const key = `${assignment.kind}:${assignment.connectorId}`;
@@ -9054,17 +9675,15 @@ var ConnectorAssignmentLoop = class {
9054
9675
  if (this.inFlight.has(key))
9055
9676
  continue;
9056
9677
  this.inFlight.add(key);
9057
- void this.handle(assignment).catch((error) => this.log(`connector assignment ${key} failed: ${describe2(error)}`)).finally(() => this.inFlight.delete(key));
9678
+ squireWork.push(this.handle(assignment).catch((error) => this.log(`connector assignment ${key} failed: ${describe2(error)}`)).finally(() => this.inFlight.delete(key)));
9679
+ }
9680
+ if (googleBatch) {
9681
+ const keys = googleBatch.map((assignment) => `${assignment.kind}:${assignment.connectorId}`);
9682
+ void Promise.all(squireWork).then(() => this.runGoogleBatch(googleBatch)).catch((error) => this.log(`google connector installs failed: ${describe2(error)}`)).finally(() => {
9683
+ for (const key of keys)
9684
+ this.inFlight.delete(key);
9685
+ });
9058
9686
  }
9059
- if (googleBatch)
9060
- this.flushGoogleBatch(googleBatch);
9061
- }
9062
- flushGoogleBatch(batch) {
9063
- const keys = batch.map((a2) => `${a2.kind}:${a2.connectorId}`);
9064
- void this.runGoogleBatch(batch).catch((error) => this.log(`google connector installs failed: ${describe2(error)}`)).finally(() => {
9065
- for (const key of keys)
9066
- this.inFlight.delete(key);
9067
- });
9068
9687
  }
9069
9688
  /** The Google tool connectors ride ONE grant: every install in the batch
9070
9689
  * shares one credential resolution (the single Google consent) and the
@@ -9088,6 +9707,8 @@ var ConnectorAssignmentLoop = class {
9088
9707
  const oneClick = await readGoogleCredentialsFromVault(this.squire());
9089
9708
  if (oneClick.source === "squire")
9090
9709
  return oneClick;
9710
+ if (isSquireBrowserSessionFailure(oneClick.reason))
9711
+ return oneClick;
9091
9712
  } catch (error) {
9092
9713
  this.log(`google one-click grant lookup failed: ${describe2(error)}`);
9093
9714
  }
@@ -9232,12 +9853,13 @@ var SERVER_EVENT_KINDS = [
9232
9853
  "check-failed",
9233
9854
  "merged",
9234
9855
  "grant-decided",
9856
+ "connector-offer-decided",
9235
9857
  "turn-cancelled"
9236
9858
  ];
9237
9859
 
9238
9860
  // apps/body/dist/daemon-api-client.js
9239
- import { resolve as resolve7 } from "node:path";
9240
- import { randomUUID } from "node:crypto";
9861
+ import { resolve as resolve8 } from "node:path";
9862
+ import { randomUUID as randomUUID2 } from "node:crypto";
9241
9863
 
9242
9864
  // node_modules/ws/wrapper.mjs
9243
9865
  var import_stream = __toESM(require_stream(), 1);
@@ -9255,9 +9877,9 @@ import { randomBytes as randomBytes5 } from "node:crypto";
9255
9877
  import { execFile as execFile2 } from "node:child_process";
9256
9878
  import { closeSync, openSync } from "node:fs";
9257
9879
  import { mkdir, readFile as readFile2, readdir, rename, stat, writeFile as writeFile2 } from "node:fs/promises";
9258
- import { homedir as homedir2 } from "node:os";
9259
- import { dirname as dirname2, resolve as resolve6 } from "node:path";
9260
- import { spawn as spawn4 } from "node:child_process";
9880
+ import { homedir as homedir3 } from "node:os";
9881
+ import { dirname as dirname3, resolve as resolve7 } from "node:path";
9882
+ import { spawn as spawn6 } from "node:child_process";
9261
9883
  import { promisify } from "node:util";
9262
9884
 
9263
9885
  // node_modules/@noble/hashes/_u64.js
@@ -13644,7 +14266,7 @@ function alphabet(letters) {
13644
14266
  };
13645
14267
  }
13646
14268
  // @__NO_SIDE_EFFECTS__
13647
- function join3(separator = "") {
14269
+ function join4(separator = "") {
13648
14270
  astr("join", separator);
13649
14271
  return {
13650
14272
  encode: (from) => {
@@ -13774,8 +14396,8 @@ var base64 = hasBase64Builtin ? {
13774
14396
  decode(s) {
13775
14397
  return decodeBase64Builtin(s, false);
13776
14398
  }
13777
- } : /* @__PURE__ */ chain(/* @__PURE__ */ radix2(6), /* @__PURE__ */ alphabet("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"), /* @__PURE__ */ padding(6), /* @__PURE__ */ join3(""));
13778
- var BECH_ALPHABET = /* @__PURE__ */ chain(/* @__PURE__ */ alphabet("qpzry9x8gf2tvdw0s3jn54khce6mua7l"), /* @__PURE__ */ join3(""));
14399
+ } : /* @__PURE__ */ chain(/* @__PURE__ */ radix2(6), /* @__PURE__ */ alphabet("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"), /* @__PURE__ */ padding(6), /* @__PURE__ */ join4(""));
14400
+ var BECH_ALPHABET = /* @__PURE__ */ chain(/* @__PURE__ */ alphabet("qpzry9x8gf2tvdw0s3jn54khce6mua7l"), /* @__PURE__ */ join4(""));
13779
14401
  var POLYMOD_GENERATORS = [996825010, 642813549, 513874426, 1027748829, 705979059];
13780
14402
  function bech32Polymod(pre) {
13781
14403
  const b = pre >> 25;
@@ -17793,15 +18415,15 @@ var DEFAULT_AGENT_IDENTITY_NAME = "beeline-agent";
17793
18415
  var DEFAULT_BODY_IDENTITY_NAME = "beeline-body";
17794
18416
  var DEFAULT_DAEMON_MONOLITH_BASE_URL = "https://server.usebeeline.app";
17795
18417
  function defaultSupervisorRoot(env = process.env) {
17796
- return resolve6(env.XDG_STATE_HOME ?? resolve6(homedir2(), ".local", "state"));
18418
+ return resolve7(env.XDG_STATE_HOME ?? resolve7(homedir3(), ".local", "state"));
17797
18419
  }
17798
18420
  function runtimeDirectory(supervisorRoot, publicKey) {
17799
18421
  if (!/^[0-9a-f]{64}$/i.test(publicKey))
17800
18422
  throw new Error("invalid agent public key");
17801
- return resolve6(supervisorRoot, "beeline", "agents", publicKey.toLowerCase());
18423
+ return resolve7(supervisorRoot, "beeline", "agents", publicKey.toLowerCase());
17802
18424
  }
17803
18425
  function runtimeConfigPath(supervisorRoot, publicKey) {
17804
- return resolve6(runtimeDirectory(supervisorRoot, publicKey), "runtime.json");
18426
+ return resolve7(runtimeDirectory(supervisorRoot, publicKey), "runtime.json");
17805
18427
  }
17806
18428
  function identityFromKey(value, name) {
17807
18429
  const secretKey = value ? value.startsWith("nsec1") ? decodeNsec(value) : Uint8Array.from(Buffer.from(value, "hex")) : randomBytes5(32);
@@ -17822,7 +18444,13 @@ function runtimeIdentity(identity) {
17822
18444
  throw new Error("stored identity public key mismatch");
17823
18445
  return restored;
17824
18446
  }
17825
- function runtimeAgentCommand(runtime) {
18447
+ function runtimeAgentCommand(runtime, env = process.env) {
18448
+ if (runtime.agentKind === "cursor") {
18449
+ try {
18450
+ return resolveAgentCommand({ kind: "cursor", env });
18451
+ } catch {
18452
+ }
18453
+ }
17826
18454
  return {
17827
18455
  kind: runtime.agentKind ?? "reference",
17828
18456
  command: runtime.agentCommand ?? runtime.agentBinary,
@@ -17831,7 +18459,7 @@ function runtimeAgentCommand(runtime) {
17831
18459
  }
17832
18460
  async function writeRuntimeRecord(runtime) {
17833
18461
  const path = runtimeConfigPath(runtime.supervisorRoot, runtime.agent.publicKey);
17834
- await mkdir(dirname2(path), { recursive: true, mode: 448 });
18462
+ await mkdir(dirname3(path), { recursive: true, mode: 448 });
17835
18463
  const staged = `${path}.${process.pid}.tmp`;
17836
18464
  await writeFile2(staged, `${JSON.stringify(runtime, null, 2)}
17837
18465
  `, { mode: 384 });
@@ -17857,7 +18485,7 @@ async function migrateRuntimeRecordAccessPolicy(path) {
17857
18485
  return { runtime, migrated: true };
17858
18486
  }
17859
18487
  async function stageMonolithAgentRuntime(input) {
17860
- const supervisorRoot = input.supervisorRoot ? resolve6(input.supervisorRoot) : defaultSupervisorRoot();
18488
+ const supervisorRoot = input.supervisorRoot ? resolve7(input.supervisorRoot) : defaultSupervisorRoot();
17861
18489
  const configPath = runtimeConfigPath(supervisorRoot, input.agentIdentity.publicKey);
17862
18490
  const configuredBaseUrl = input.monolithBaseUrl ?? DEFAULT_DAEMON_MONOLITH_BASE_URL;
17863
18491
  const baseUrl = new URL(configuredBaseUrl).origin;
@@ -17902,9 +18530,9 @@ async function stageMonolithAgentRuntime(input) {
17902
18530
  return { runtime, configPath };
17903
18531
  }
17904
18532
  async function runtimePaths(root) {
17905
- const agents = resolve6(root, "beeline", "agents");
18533
+ const agents = resolve7(root, "beeline", "agents");
17906
18534
  const entries = await readdir(agents, { withFileTypes: true }).catch(() => []);
17907
- return entries.filter((entry) => entry.isDirectory()).map((entry) => resolve6(agents, entry.name, "runtime.json"));
18535
+ return entries.filter((entry) => entry.isDirectory()).map((entry) => resolve7(agents, entry.name, "runtime.json"));
17908
18536
  }
17909
18537
  async function findAgentRuntimeConfigPaths(env = process.env, _cwd = process.cwd()) {
17910
18538
  return runtimePaths(defaultSupervisorRoot(env));
@@ -17913,13 +18541,13 @@ async function findRuntimeConfigPaths(cwd = process.cwd(), env = process.env) {
17913
18541
  return findAgentRuntimeConfigPaths(env, cwd);
17914
18542
  }
17915
18543
  async function resolveRuntimeConfigPath(path) {
17916
- return resolve6(path);
18544
+ return resolve7(path);
17917
18545
  }
17918
18546
  async function selectRuntimeConfigPaths(options) {
17919
18547
  const hostScope = true;
17920
18548
  const configs = await options.findHostRuntimes(options.cwd);
17921
18549
  const requestedPubkey = options.requestedPubkey;
17922
- const paths = requestedPubkey ? configs.filter((path) => dirname2(path).endsWith(requestedPubkey)) : [...new Set(configs)];
18550
+ const paths = requestedPubkey ? configs.filter((path) => dirname3(path).endsWith(requestedPubkey)) : [...new Set(configs)];
17923
18551
  if (!paths.length)
17924
18552
  throw new Error(options.noRuntimeMessage(hostScope));
17925
18553
  if (options.requestedPubkey && paths.length > 1)
@@ -17928,7 +18556,7 @@ async function selectRuntimeConfigPaths(options) {
17928
18556
  }
17929
18557
  async function runtimeDaemonPid(configPath) {
17930
18558
  try {
17931
- const pid = Number((await readFile2(resolve6(dirname2(configPath), "daemon.pid"), "utf8")).trim());
18559
+ const pid = Number((await readFile2(resolve7(dirname3(configPath), "daemon.pid"), "utf8")).trim());
17932
18560
  if (!Number.isSafeInteger(pid) || pid <= 0)
17933
18561
  return null;
17934
18562
  process.kill(pid, 0);
@@ -17941,11 +18569,11 @@ async function daemonIsThisRuntime(pid, configPath) {
17941
18569
  try {
17942
18570
  const argv = (await readFile2(`/proc/${pid}/cmdline`, "utf8")).split("\0").filter(Boolean);
17943
18571
  const flag = argv.lastIndexOf("--config");
17944
- return flag > 0 && argv[flag - 1] === "daemon" && resolve6(argv[flag + 1]) === resolve6(configPath);
18572
+ return flag > 0 && argv[flag - 1] === "daemon" && resolve7(argv[flag + 1]) === resolve7(configPath);
17945
18573
  } catch {
17946
18574
  try {
17947
18575
  const { stdout: stdout6 } = await execFileAsync("ps", ["-p", String(pid), "-o", "command="]);
17948
- return stdout6.includes(" daemon ") && stdout6.includes(resolve6(configPath));
18576
+ return stdout6.includes(" daemon ") && stdout6.includes(resolve7(configPath));
17949
18577
  } catch {
17950
18578
  return false;
17951
18579
  }
@@ -17971,14 +18599,14 @@ async function stopRuntimeDaemon(path, opts = {}) {
17971
18599
  throw new Error(`agent daemon ${pid} did not stop after ${timeout}ms`);
17972
18600
  }
17973
18601
  async function launchRuntimeDaemon(configPath, opts = {}) {
17974
- const directory = dirname2(configPath);
18602
+ const directory = dirname3(configPath);
17975
18603
  await mkdir(directory, { recursive: true, mode: 448 });
17976
18604
  const foreground = opts.foreground === true;
17977
- const output = foreground ? "inherit" : openSync(resolve6(directory, "daemon.log"), "a", 384);
18605
+ const output = foreground ? "inherit" : openSync(resolve7(directory, "daemon.log"), "a", 384);
17978
18606
  const entrypoint = opts.entrypoint ?? process.argv[1];
17979
18607
  if (!entrypoint)
17980
18608
  throw new Error("cannot resolve daemon CLI entrypoint");
17981
- const child = spawn4(process.execPath, [...opts.execArgv ?? [], entrypoint, "daemon", "--config", resolve6(configPath)], {
18609
+ const child = spawn6(process.execPath, [...opts.execArgv ?? [], entrypoint, "daemon", "--config", resolve7(configPath)], {
17982
18610
  cwd: directory,
17983
18611
  env: opts.env ?? process.env,
17984
18612
  detached: !foreground,
@@ -17995,9 +18623,9 @@ async function launchRuntimeDaemon(configPath, opts = {}) {
17995
18623
  }
17996
18624
  async function removeAgentRuntime(runtime) {
17997
18625
  const source = runtimeDirectory(runtime.supervisorRoot, runtime.agent.publicKey);
17998
- const deletedRoot = resolve6(runtime.supervisorRoot, "beeline", "deleted-runtimes");
18626
+ const deletedRoot = resolve7(runtime.supervisorRoot, "beeline", "deleted-runtimes");
17999
18627
  await mkdir(deletedRoot, { recursive: true, mode: 448 });
18000
- const target = resolve6(deletedRoot, `${runtime.agent.publicKey}-${Date.now()}`);
18628
+ const target = resolve7(deletedRoot, `${runtime.agent.publicKey}-${Date.now()}`);
18001
18629
  await rename(source, target);
18002
18630
  return target;
18003
18631
  }
@@ -18038,7 +18666,7 @@ var DaemonApiClient = class {
18038
18666
  agentId;
18039
18667
  fetchImpl;
18040
18668
  webSocketFactory;
18041
- presenceLifecycleId = randomUUID();
18669
+ presenceLifecycleId = randomUUID2();
18042
18670
  liveSocket;
18043
18671
  liveReconnect;
18044
18672
  liveReconnectDelayMs = 1e3;
@@ -18232,8 +18860,8 @@ var DaemonApiClient = class {
18232
18860
  };
18233
18861
  async function activateDaemonTransport(path, fetchImpl = fetch) {
18234
18862
  const runtime = await readRuntimeRecord(path);
18235
- const expectedPath = resolve7(runtimeDirectory(runtime.supervisorRoot, runtime.agent.publicKey), "runtime.json");
18236
- if (resolve7(path) !== expectedPath) {
18863
+ const expectedPath = resolve8(runtimeDirectory(runtime.supervisorRoot, runtime.agent.publicKey), "runtime.json");
18864
+ if (resolve8(path) !== expectedPath) {
18237
18865
  throw new Error(`refusing daemon token exchange outside canonical runtime path: ${path}`);
18238
18866
  }
18239
18867
  const transport = runtime.transport;
@@ -18273,18 +18901,18 @@ async function activateDaemonTransport(path, fetchImpl = fetch) {
18273
18901
 
18274
18902
  // apps/body/dist/room-runtime.js
18275
18903
  import { execFile as execFile6 } from "node:child_process";
18276
- import { createHash as createHash6 } from "node:crypto";
18277
- import { existsSync as existsSync4, mkdirSync } from "node:fs";
18904
+ import { createHash as createHash7 } from "node:crypto";
18905
+ import { existsSync as existsSync5, mkdirSync } from "node:fs";
18278
18906
  import { mkdir as mkdir13, rm as rm5 } from "node:fs/promises";
18279
- import { dirname as dirname8, resolve as resolve20 } from "node:path";
18907
+ import { dirname as dirname9, resolve as resolve21 } from "node:path";
18280
18908
  import { promisify as promisify4 } from "node:util";
18281
18909
 
18282
18910
  // apps/body/dist/grant-runner.js
18283
18911
  import { execFile as execFile3 } from "node:child_process";
18284
- import { createHash as createHash2, randomBytes as randomBytes6 } from "node:crypto";
18912
+ import { createHash as createHash3, randomBytes as randomBytes6 } from "node:crypto";
18285
18913
  import { readFile as readFile4 } from "node:fs/promises";
18286
18914
  import { createServer } from "node:http";
18287
- import { dirname as dirname4, resolve as resolve10 } from "node:path";
18915
+ import { dirname as dirname5, resolve as resolve11 } from "node:path";
18288
18916
 
18289
18917
  // packages/api-contract/dist/agent-grants.js
18290
18918
  var AGENT_GRANT_KINDS = ["path", "host", "secret", "device", "budget", "command"];
@@ -18507,9 +19135,9 @@ function surfaceAllows(surface, capability) {
18507
19135
 
18508
19136
  // apps/body/dist/bwrap-sandbox.js
18509
19137
  import { spawnSync } from "node:child_process";
18510
- import { lstatSync as lstatSync2 } from "node:fs";
18511
- import { homedir as homedir3 } from "node:os";
18512
- import { isAbsolute as isAbsolute2, relative, resolve as resolve8 } from "node:path";
19138
+ import { lstatSync as lstatSync3 } from "node:fs";
19139
+ import { homedir as homedir4 } from "node:os";
19140
+ import { isAbsolute as isAbsolute2, relative, resolve as resolve9 } from "node:path";
18513
19141
  var DEFAULT_SANDBOX_POLICY = "bwrap";
18514
19142
  function isSandboxPolicy(value) {
18515
19143
  return value === "bwrap" || value === "off";
@@ -18541,16 +19169,16 @@ var HARNESS_HOME_STATE_DIRS = [
18541
19169
  dirs: [".grok"]
18542
19170
  },
18543
19171
  {
18544
- match: /(^|[/\\])cursor-agent-acp(\.[a-z]+)?$/i,
19172
+ match: CURSOR_HARNESS_COMMAND,
18545
19173
  dirs: [".cursor"]
18546
19174
  }
18547
19175
  ];
18548
- function harnessHomeStateDirs(agentCommand, home = homedir3()) {
19176
+ function harnessHomeStateDirs(agentCommand, home = homedir4()) {
18549
19177
  if (!agentCommand)
18550
19178
  return [];
18551
19179
  for (const { match, dirs } of HARNESS_HOME_STATE_DIRS) {
18552
19180
  if (match.test(agentCommand))
18553
- return dirs.map((dir) => resolve8(home, dir));
19181
+ return dirs.map((dir) => resolve9(home, dir));
18554
19182
  }
18555
19183
  return [];
18556
19184
  }
@@ -18562,18 +19190,18 @@ var KNOWN_CREDENTIAL_MASK_PATHS = [
18562
19190
  ".git-credentials",
18563
19191
  ".secrets.env"
18564
19192
  ];
18565
- function credentialMaskPaths(extraPaths, home = homedir3(), stat4 = (path) => {
19193
+ function credentialMaskPaths(extraPaths, home = homedir4(), stat4 = (path) => {
18566
19194
  try {
18567
- const info = lstatSync2(path);
19195
+ const info = lstatSync3(path);
18568
19196
  return { isDirectory: info.isDirectory() };
18569
19197
  } catch {
18570
19198
  return void 0;
18571
19199
  }
18572
19200
  }, requiredPaths = []) {
18573
- const required = new Set(requiredPaths.map((path) => resolve8(path)));
19201
+ const required = new Set(requiredPaths.map((path) => resolve9(path)));
18574
19202
  const candidates = [
18575
- ...KNOWN_CREDENTIAL_MASK_PATHS.map((entry) => resolve8(home, entry)),
18576
- ...(extraPaths ?? []).map((entry) => resolve8(entry))
19203
+ ...KNOWN_CREDENTIAL_MASK_PATHS.map((entry) => resolve9(home, entry)),
19204
+ ...(extraPaths ?? []).map((entry) => resolve9(entry))
18577
19205
  ];
18578
19206
  const seen = /* @__PURE__ */ new Set();
18579
19207
  const masks = [];
@@ -18600,7 +19228,7 @@ function normalize(paths) {
18600
19228
  for (const path of paths) {
18601
19229
  if (!path)
18602
19230
  continue;
18603
- seen.add(resolve8(path));
19231
+ seen.add(resolve9(path));
18604
19232
  }
18605
19233
  return Array.from(seen).sort();
18606
19234
  }
@@ -18638,7 +19266,7 @@ function sandboxMountPlan(spec) {
18638
19266
  writable,
18639
19267
  quotaTmpfs: spec.workbench ? [
18640
19268
  {
18641
- target: resolve8(spec.workbench.dir),
19269
+ target: resolve9(spec.workbench.dir),
18642
19270
  maxBytes: spec.workbench.maxBytes,
18643
19271
  maxInodes: spec.workbench.maxInodes,
18644
19272
  blockGit: true
@@ -18693,7 +19321,7 @@ function buildBwrapArgv(input) {
18693
19321
  for (const binding of quotaTmpfs) {
18694
19322
  args.push("--dir", binding.target, "--size", String(binding.maxBytes), "--tmpfs", binding.target);
18695
19323
  if (binding.blockGit)
18696
- args.push("--ro-bind", "/dev/null", resolve8(binding.target, ".git"));
19324
+ args.push("--ro-bind", "/dev/null", resolve9(binding.target, ".git"));
18697
19325
  }
18698
19326
  args.push("--chdir", input.cwd);
18699
19327
  args.push("--die-with-parent");
@@ -18759,8 +19387,8 @@ function detectBwrapSandbox(options = {}) {
18759
19387
 
18760
19388
  // apps/body/dist/provider-key-store.js
18761
19389
  import { chmod, mkdir as mkdir2, readFile as readFile3, writeFile as writeFile3 } from "node:fs/promises";
18762
- import { homedir as homedir4 } from "node:os";
18763
- import { dirname as dirname3, resolve as resolve9 } from "node:path";
19390
+ import { homedir as homedir5 } from "node:os";
19391
+ import { dirname as dirname4, resolve as resolve10 } from "node:path";
18764
19392
  var PROVIDER_KEY_ENV_VARS = {
18765
19393
  openrouter: "OPENROUTER_API_KEY",
18766
19394
  openai: "OPENAI_API_KEY",
@@ -18770,8 +19398,8 @@ var PROVIDER_KEY_ENV_VARS = {
18770
19398
  };
18771
19399
  var GOOGLE_ENV_ALIAS = "GEMINI_API_KEY";
18772
19400
  function providerKeyStorePath(env = process.env) {
18773
- const configRoot = env.XDG_CONFIG_HOME?.trim() || resolve9(homedir4(), ".config");
18774
- return resolve9(configRoot, "beeline", "providers.json");
19401
+ const configRoot = env.XDG_CONFIG_HOME?.trim() || resolve10(homedir5(), ".config");
19402
+ return resolve10(configRoot, "beeline", "providers.json");
18775
19403
  }
18776
19404
  async function readProviderKeyStore(env = process.env) {
18777
19405
  const path = providerKeyStorePath(env);
@@ -18794,7 +19422,7 @@ async function readSavedProviderKey(provider, env = process.env) {
18794
19422
  async function saveProviderKey(provider, key, env = process.env) {
18795
19423
  const path = providerKeyStorePath(env);
18796
19424
  const store = { ...await readProviderKeyStore(env), [provider]: key };
18797
- await mkdir2(dirname3(path), { recursive: true, mode: 448 });
19425
+ await mkdir2(dirname4(path), { recursive: true, mode: 448 });
18798
19426
  await writeFile3(path, `${JSON.stringify(store, null, 2)}
18799
19427
  `, { mode: 384 });
18800
19428
  await chmod(path, 384);
@@ -18831,7 +19459,7 @@ function operatorSecretResolver(env = process.env) {
18831
19459
  if (saved)
18832
19460
  return saved;
18833
19461
  }
18834
- const raw = await readFile4(resolve10(dirname4(providerKeyStorePath(env)), "secrets.json"), "utf8").catch(() => void 0);
19462
+ const raw = await readFile4(resolve11(dirname5(providerKeyStorePath(env)), "secrets.json"), "utf8").catch(() => void 0);
18835
19463
  if (!raw)
18836
19464
  return void 0;
18837
19465
  try {
@@ -18943,9 +19571,9 @@ var GrantCommandRunner = class {
18943
19571
  ...Object.fromEntries(secrets)
18944
19572
  };
18945
19573
  const cap = this.options.outputCapBytes ?? GRANT_COMMAND_OUTPUT_CAP_BYTES;
18946
- const spawn10 = surfaceAllows(policy.surface, "run-host-command") ? { command: argv[0], args: argv.slice(1) } : roomSandboxCommand(policy, room.cwd, argv);
19574
+ const spawn12 = surfaceAllows(policy.surface, "run-host-command") ? { command: argv[0], args: argv.slice(1) } : roomSandboxCommand(policy, room.cwd, argv);
18947
19575
  const outcome = await new Promise((resolveRun) => {
18948
- const child = execFile3(spawn10.command, spawn10.args, {
19576
+ const child = execFile3(spawn12.command, spawn12.args, {
18949
19577
  cwd: room.cwd,
18950
19578
  env,
18951
19579
  timeout: this.options.timeoutMs ?? GRANT_COMMAND_TIMEOUT_MS,
@@ -19023,7 +19651,7 @@ ${ROOM_WRITE_REFUSED_NOTE}` : outcome.output, secrets), cap);
19023
19651
  if (!script || script.path !== argument.path) {
19024
19652
  throw new Error(`${argument.path} is a script no human has read: this grant was approved without it. Ask with request_grant kind=command so the card carries what the command runs.`);
19025
19653
  }
19026
- if (createHash2("sha256").update(bytes).digest("hex") !== script.sha256) {
19654
+ if (createHash3("sha256").update(bytes).digest("hex") !== script.sha256) {
19027
19655
  throw new Error(`${argument.path} changed after it was approved, so the approval no longer covers it. Ask with request_grant kind=command again so a human reads what runs now.`);
19028
19656
  }
19029
19657
  }
@@ -19033,8 +19661,8 @@ function scriptCandidates(cwd, scratch, argv) {
19033
19661
  if (!argument)
19034
19662
  return [];
19035
19663
  const paths = [
19036
- resolve10(cwd, argument.path),
19037
- ...scratch ? [resolve10(scratch, argument.path)] : []
19664
+ resolve11(cwd, argument.path),
19665
+ ...scratch ? [resolve11(scratch, argument.path)] : []
19038
19666
  ];
19039
19667
  return [...new Set(paths)];
19040
19668
  }
@@ -19215,20 +19843,20 @@ function captureConnectionUsage(recorder, turn, calls) {
19215
19843
  }
19216
19844
 
19217
19845
  // apps/body/dist/server-command-intake.js
19218
- import { randomUUID as randomUUID2 } from "node:crypto";
19846
+ import { randomUUID as randomUUID3 } from "node:crypto";
19219
19847
  import { mkdir as mkdir3, writeFile as writeFile4 } from "node:fs/promises";
19220
- import { tmpdir as tmpdir2 } from "node:os";
19221
- import { dirname as dirname5, join as join4 } from "node:path";
19848
+ import { tmpdir as tmpdir3 } from "node:os";
19849
+ import { dirname as dirname6, join as join5 } from "node:path";
19222
19850
  var CommandExecutionContext = class {
19223
- generationId = randomUUID2();
19851
+ generationId = randomUUID3();
19224
19852
  path;
19225
19853
  current;
19226
19854
  constructor(root) {
19227
- this.path = join4(root ?? tmpdir2(), `beeline-command-${this.generationId}.json`);
19855
+ this.path = join5(root ?? tmpdir3(), `beeline-command-${this.generationId}.json`);
19228
19856
  }
19229
19857
  async enter(command) {
19230
19858
  this.current = command;
19231
- await mkdir3(dirname5(this.path), { recursive: true });
19859
+ await mkdir3(dirname6(this.path), { recursive: true });
19232
19860
  await writeFile4(this.path, JSON.stringify({
19233
19861
  roomId: command.roomId,
19234
19862
  requestId: command.turnRequestId,
@@ -19350,13 +19978,13 @@ async function runServerCommandIntake(options) {
19350
19978
  }
19351
19979
  }
19352
19980
  options.onPoll?.();
19353
- const reconcile = await new Promise((resolve31) => {
19981
+ const reconcile = await new Promise((resolve32) => {
19354
19982
  const done = (needed) => {
19355
19983
  if (timer)
19356
19984
  clearTimeout(timer);
19357
19985
  signal?.removeEventListener("abort", aborted);
19358
19986
  wake = void 0;
19359
- resolve31(needed);
19987
+ resolve32(needed);
19360
19988
  };
19361
19989
  const aborted = () => done(false);
19362
19990
  wake = done;
@@ -19382,22 +20010,35 @@ async function runServerCommandIntake(options) {
19382
20010
 
19383
20011
  // apps/body/dist/monolith-corner-turn.js
19384
20012
  import { execFile as execFile5 } from "node:child_process";
19385
- import { createHash as createHash5 } from "node:crypto";
20013
+ import { createHash as createHash6 } from "node:crypto";
19386
20014
  import { mkdir as mkdir12 } from "node:fs/promises";
19387
- import { homedir as homedir7 } from "node:os";
19388
- import { join as join9 } from "node:path";
20015
+ import { homedir as homedir8 } from "node:os";
20016
+ import { join as join10 } from "node:path";
19389
20017
  import { promisify as promisify3 } from "node:util";
19390
20018
 
19391
20019
  // apps/body/dist/agent-home.js
19392
- import { existsSync as existsSync3, readFileSync as readFileSync5 } from "node:fs";
19393
- import { createHash as createHash3, randomUUID as randomUUID3 } from "node:crypto";
20020
+ import { existsSync as existsSync4, readFileSync as readFileSync6 } from "node:fs";
20021
+ import { createHash as createHash4, randomUUID as randomUUID4 } from "node:crypto";
19394
20022
  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";
19395
- import { homedir as homedir5 } from "node:os";
19396
- import { basename as basename3, dirname as dirname6, join as join5, relative as relative2, resolve as resolve13, sep } from "node:path";
20023
+ import { homedir as homedir6 } from "node:os";
20024
+ import { basename as basename4, dirname as dirname7, join as join6, relative as relative2, resolve as resolve14, sep } from "node:path";
19397
20025
 
19398
20026
  // apps/body/dist/beeline-skill.js
19399
- import { readFileSync as readFileSync4 } from "node:fs";
19400
- import { resolve as resolve11 } from "node:path";
20027
+ import { readFileSync as readFileSync5 } from "node:fs";
20028
+ import { resolve as resolve12 } from "node:path";
20029
+
20030
+ // packages/api-contract/dist/workbench.js
20031
+ var CONNECTABLE_CONNECTOR_KINDS = [
20032
+ "trusty-squire",
20033
+ "google-gmail",
20034
+ "google-calendar",
20035
+ "google-drive",
20036
+ "google-youtube"
20037
+ ];
20038
+
20039
+ // packages/api-contract/dist/connector-offers.js
20040
+ var CONNECTOR_OFFER_WINDOW_MS = 2 * 6e4;
20041
+ var OFFERABLE_CONNECTOR_KINDS = CONNECTABLE_CONNECTOR_KINDS.filter((kind) => kind !== "wallet");
19401
20042
 
19402
20043
  // packages/api-contract/dist/agent-pairing-code.js
19403
20044
  var CURRENT_AGENT_PAIRING_CODE = /^[0-9A-F]{8}-[0-9A-F]{8}$/;
@@ -19462,12 +20103,12 @@ function beelineCapabilityContextForHarness(agentCommand, repository, directMess
19462
20103
  ...harnessHonorsSessionSystemPrompt(agentCommand) ? {} : { compatibilityTurnPrefix: primer }
19463
20104
  };
19464
20105
  }
19465
- function runningBeelineReleaseId(env = process.env, read = (path) => readFileSync4(path, "utf8")) {
20106
+ function runningBeelineReleaseId(env = process.env, read = (path) => readFileSync5(path, "utf8")) {
19466
20107
  try {
19467
20108
  const lib = env.BEELINE_LIB_DIR;
19468
20109
  if (!lib)
19469
20110
  return "source";
19470
- const manifest = JSON.parse(read(resolve11(lib, "bundle.json")));
20111
+ const manifest = JSON.parse(read(resolve12(lib, "bundle.json")));
19471
20112
  return [manifest.version, manifest.commit].filter(Boolean).join("-") || "source";
19472
20113
  } catch {
19473
20114
  return "source";
@@ -19489,13 +20130,17 @@ When your corner's pull request is ready, merging is your step: once the configu
19489
20130
 
19490
20131
  ## Tools and the Workbench
19491
20132
 
19492
- A **tool** is something you can use once a human pairs it; a **key** is the credential that tool holds for that human. You spend a key through the mounted connector and never see the credential itself.
20133
+ A **tool** is something you can use once a human adds it; a **key** is the credential that tool holds for that human. You spend a key through the mounted connector and never see the credential itself.
19493
20134
 
19494
- This build knows one tool: Trusty Squire - vaulted credentials and a browser that signs in for you. Wallet and Tailscale are named in the Workbench but not yet available.
20135
+ The tools this build knows, what each is for, and which the person you are answering already has are one call away: beeline-agent workbench_status. Trusty Squire is vaulted credentials plus a browser that signs up and signs in for you; the Google tools (Gmail, Calendar, Drive, YouTube) work through the person's own Google sign-in. The wallet is created only from the Workbench page, and Tailscale is not available yet.
19495
20136
 
19496
- You NEVER pair a tool and never ask for a raw credential in chat. When a task needs one you do not have, say so plainly, name the tool that would solve it, and tell the person exactly where to go: Settings \u2192 Workbench \u2192 Tools.
20137
+ **Offer the tool at the moment you need it.** When the work in front of you needs a tool the person does not have, do not send them to a settings page and do not stop at naming it. Call workbench_status first - a tool they already have is used, not offered. Then call offer_connector with the connectorType and one short reason: a card appears in this Room, spoken by you, addressed to the person you are answering, with one action. Only that person or a Workspace admin can accept it; accepting adds the tool on your machine, and the sign-in or keys stay theirs. Your turn pauses on the card - say in prose what you are waiting for and end the turn; you are woken when it is added, and then you carry on.
19497
20138
 
19498
- Keys are sovereign: they belong to the human who provisioned them. You cannot use another member's key and must not ask a member to share one.
20139
+ **Research before you offer, and say so.** Never offer a tool you cannot describe. If someone asks you to install or add something you do not already know - by name, by purpose, or by what it will hold - say plainly that you are looking it up first, find out what it is and what it does with credentials, and state what you learned in your reply BEFORE the card appears. A person reading "Add X?" must already have read, in your own words, what X is. Refusing to act blind is part of being trusted with keys.
20140
+
20141
+ An offer is setup, never authority: it does not replace a grant, write permission, target-branch confirmation, or the merge gate, and it never needs a raw credential in chat. You never pair a tool yourself and never ask anyone for a key value; once a tool is added, provisioning happens inside it and receipts reach the person through the tool's own status message.
20142
+
20143
+ Keys are sovereign: they belong to the human who provisioned them. You cannot use another member's key and must not ask a member to share one. The Workbench page remains the place a person manages tools and keys by hand (Settings \u2192 Workbench); you point there to MANAGE what exists, not to add what you need.
19499
20144
 
19500
20145
  ## Showing a mock
19501
20146
 
@@ -19649,7 +20294,7 @@ var SQUIRE_GOVERNED_TOOL_SET = new Set(SQUIRE_GOVERNED_TOOLS);
19649
20294
 
19650
20295
  // apps/body/dist/openrouter-routing.js
19651
20296
  import { mkdir as mkdir4, readFile as readFile5, writeFile as writeFile5 } from "node:fs/promises";
19652
- import { resolve as resolve12 } from "node:path";
20297
+ import { resolve as resolve13 } from "node:path";
19653
20298
  var OPENROUTER_ENDPOINTS_BASE_URL = "https://openrouter.ai/api/v1/models";
19654
20299
  var OPENROUTER_COMPLETIONS_URL = "https://openrouter.ai/api/v1/chat/completions";
19655
20300
  var OPENROUTER_ROUTING_CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
@@ -19751,10 +20396,10 @@ function openRouterRoutingFor(providers, allowFallbacks = true) {
19751
20396
  };
19752
20397
  }
19753
20398
  function openRouterRoutingCacheDir(runtimeDir) {
19754
- return resolve12(runtimeDir, "openrouter-routing");
20399
+ return resolve13(runtimeDir, "openrouter-routing");
19755
20400
  }
19756
20401
  function cachePath(cacheDir, model) {
19757
- return resolve12(cacheDir, `${model.replace(/[^A-Za-z0-9._-]+/g, "_")}.json`);
20402
+ return resolve13(cacheDir, `${model.replace(/[^A-Za-z0-9._-]+/g, "_")}.json`);
19758
20403
  }
19759
20404
  async function readCache(cacheDir, model) {
19760
20405
  try {
@@ -19785,7 +20430,7 @@ async function writeCache(cacheDir, value) {
19785
20430
  });
19786
20431
  }
19787
20432
  function probeCachePath(cacheDir, model) {
19788
- return resolve12(cacheDir, `${model.replace(/[^A-Za-z0-9._-]+/g, "_")}.probe.json`);
20433
+ return resolve13(cacheDir, `${model.replace(/[^A-Za-z0-9._-]+/g, "_")}.probe.json`);
19789
20434
  }
19790
20435
  async function readProbeCache(cacheDir, model) {
19791
20436
  try {
@@ -20225,8 +20870,8 @@ var SHARED_CREDENTIALS = [
20225
20870
  // shape as codex).
20226
20871
  { dir: "grok", source: ".grok/auth.json", target: "auth.json" },
20227
20872
  { dir: "pi", source: ".pi/agent/auth.json", target: "auth.json" },
20228
- // Cursor CLI stores auth state under ~/.cursor/; cursor-agent-acp
20229
- // reads CURSOR_HOME to relocate the data directory.
20873
+ // Cursor CLI stores auth state under ~/.cursor/; cursor-agent reads
20874
+ // CURSOR_HOME to relocate the data directory.
20230
20875
  { dir: "cursor", source: ".cursor/agent-cli-state.json", target: "agent-cli-state.json" }
20231
20876
  ];
20232
20877
  var GOOSE_SHARED_CONFIG_FILES = ["config.yaml", "secrets.yaml"];
@@ -20275,8 +20920,8 @@ var HOME_SUBDIRS = [
20275
20920
  "tmp"
20276
20921
  ];
20277
20922
  async function prepareRoomAgentHome(input) {
20278
- const root = resolve13(input.root);
20279
- const operatorHome = input.operatorHome ?? homedir5();
20923
+ const root = resolve14(input.root);
20924
+ const operatorHome = input.operatorHome ?? homedir6();
20280
20925
  try {
20281
20926
  await mkdir5(root, { recursive: true, mode: 448 });
20282
20927
  const rootStats = await lstat(root);
@@ -20284,7 +20929,7 @@ async function prepareRoomAgentHome(input) {
20284
20929
  throw new AgentHomeSecurityError(`agent home root is not an ordinary directory: ${root}`);
20285
20930
  }
20286
20931
  for (const subdir of HOME_SUBDIRS) {
20287
- const path = resolve13(root, subdir);
20932
+ const path = resolve14(root, subdir);
20288
20933
  await mkdir5(path, { recursive: true, mode: 448 });
20289
20934
  await assertRealContainedDirectory(path, root);
20290
20935
  }
@@ -20295,9 +20940,9 @@ async function prepareRoomAgentHome(input) {
20295
20940
  return {};
20296
20941
  }
20297
20942
  for (const credential of SHARED_CREDENTIALS) {
20298
- const source = resolve13(operatorHome, credential.source);
20299
- const target = resolve13(root, credential.dir, credential.target);
20300
- if (!existsSync3(source) || existsSync3(target))
20943
+ const source = resolve14(operatorHome, credential.source);
20944
+ const target = resolve14(root, credential.dir, credential.target);
20945
+ if (!existsSync4(source) || existsSync4(target))
20301
20946
  continue;
20302
20947
  await symlink(source, target).catch(() => void 0);
20303
20948
  }
@@ -20319,12 +20964,12 @@ async function provisionAgentSkillsAndMcp(root, operatorHome, skillReleaseId, fa
20319
20964
  ...isReviewer ? [{ name: BEELINE_REVIEW_SKILL_NAME, content: beelineReviewSkillMarkdown(skillReleaseId) }] : []
20320
20965
  ];
20321
20966
  const shared = await resolveSharedSkillSources(operatorHome, sharedSkills);
20322
- await provisionManagedSkillsDir(resolve13(root, skillDir, "skills"), managedSkills, shared, sharedSkills.length === 0);
20967
+ await provisionManagedSkillsDir(resolve14(root, skillDir, "skills"), managedSkills, shared, sharedSkills.length === 0);
20323
20968
  for (const config of HARNESS_MCP_CONFIGS) {
20324
20969
  try {
20325
- const source = resolve13(operatorHome, config.toml);
20326
- const target = resolve13(root, config.dir, "config.toml");
20327
- const mcpSection = existsSync3(source) ? filteredHarnessMcpToml(readFileSync5(source, "utf8")) : void 0;
20970
+ const source = resolve14(operatorHome, config.toml);
20971
+ const target = resolve14(root, config.dir, "config.toml");
20972
+ const mcpSection = existsSync4(source) ? filteredHarnessMcpToml(readFileSync6(source, "utf8")) : void 0;
20328
20973
  const section = config.dir === "codex" ? [CODEX_ROOM_AGENT_LOCKDOWN_TOML, CODEX_ROOM_WEB_SEARCH_TOML, mcpSection].filter(Boolean).join("\n") : mcpSection;
20329
20974
  if (!section) {
20330
20975
  await unlink(target).catch(() => void 0);
@@ -20338,13 +20983,13 @@ async function provisionAgentSkillsAndMcp(root, operatorHome, skillReleaseId, fa
20338
20983
  }
20339
20984
  }
20340
20985
  try {
20341
- const gooseConfigDir = resolve13(root, "goose", "config");
20986
+ const gooseConfigDir = resolve14(root, "goose", "config");
20342
20987
  await mkdir5(gooseConfigDir, { recursive: true, mode: 448 });
20343
20988
  for (const name of GOOSE_SHARED_CONFIG_FILES) {
20344
- const source = resolve13(operatorHome, ".config", "goose", name);
20345
- const target = resolve13(gooseConfigDir, name);
20346
- if (existsSync3(source)) {
20347
- await writeIsolatedHarnessFile(target, readFileSync5(source, "utf8"));
20989
+ const source = resolve14(operatorHome, ".config", "goose", name);
20990
+ const target = resolve14(gooseConfigDir, name);
20991
+ if (existsSync4(source)) {
20992
+ await writeIsolatedHarnessFile(target, readFileSync6(source, "utf8"));
20348
20993
  } else {
20349
20994
  await unlink(target).catch(() => void 0);
20350
20995
  }
@@ -20355,9 +21000,9 @@ async function provisionAgentSkillsAndMcp(root, operatorHome, skillReleaseId, fa
20355
21000
  console.warn("[body] operator Goose configuration passthrough failed:", error);
20356
21001
  }
20357
21002
  try {
20358
- const claudeJson = resolve13(operatorHome, ".claude.json");
20359
- const claudeTarget = resolve13(root, "claude", ".claude.json");
20360
- const mcpServers = existsSync3(claudeJson) ? readClaudeUserScopeMcpServers(claudeJson) : void 0;
21003
+ const claudeJson = resolve14(operatorHome, ".claude.json");
21004
+ const claudeTarget = resolve14(root, "claude", ".claude.json");
21005
+ const mcpServers = existsSync4(claudeJson) ? readClaudeUserScopeMcpServers(claudeJson) : void 0;
20361
21006
  if (mcpServers && Object.keys(mcpServers).length > 0) {
20362
21007
  await writeIsolatedHarnessFile(claudeTarget, `${JSON.stringify({ mcpServers }, null, 2)}
20363
21008
  `);
@@ -20371,7 +21016,7 @@ async function provisionAgentSkillsAndMcp(root, operatorHome, skillReleaseId, fa
20371
21016
  }
20372
21017
  try {
20373
21018
  const settings2 = { permissions: { allow: ["WebSearch", "WebFetch"] } };
20374
- await writeIsolatedHarnessFile(resolve13(root, "claude", "settings.json"), `${JSON.stringify(settings2, null, 2)}
21019
+ await writeIsolatedHarnessFile(resolve14(root, "claude", "settings.json"), `${JSON.stringify(settings2, null, 2)}
20375
21020
  `);
20376
21021
  } catch (error) {
20377
21022
  if (failClosed)
@@ -20381,8 +21026,8 @@ async function provisionAgentSkillsAndMcp(root, operatorHome, skillReleaseId, fa
20381
21026
  await provisionPiCustomModelConfig(root, operatorHome, failClosed, openRouterRouting);
20382
21027
  }
20383
21028
  async function provisionPiCustomModelConfig(root, operatorHome, failClosed, openRouterRouting) {
20384
- const source = resolve13(operatorHome, PI_CUSTOM_MODEL_CONFIG.source);
20385
- const target = resolve13(root, "pi", PI_CUSTOM_MODEL_CONFIG.target);
21029
+ const source = resolve14(operatorHome, PI_CUSTOM_MODEL_CONFIG.source);
21030
+ const target = resolve14(root, "pi", PI_CUSTOM_MODEL_CONFIG.target);
20386
21031
  let decision2;
20387
21032
  if (openRouterRouting) {
20388
21033
  decision2 = await resolveOpenRouterRouting(openRouterRouting);
@@ -20415,7 +21060,7 @@ async function provisionPiCustomModelConfig(root, operatorHome, failClosed, open
20415
21060
  if (resolvedSource !== source) {
20416
21061
  throw new AgentHomeSecurityError(`Pi custom model config resolves through a link: ${source}`);
20417
21062
  }
20418
- const sourceValue = JSON.parse(readFileSync5(resolvedSource, "utf8"));
21063
+ const sourceValue = JSON.parse(readFileSync6(resolvedSource, "utf8"));
20419
21064
  await writeIsolatedHarnessFile(target, `${JSON.stringify(withOpenRouterModelRouting(sourceValue, pin), null, 2)}
20420
21065
  `);
20421
21066
  } catch (error) {
@@ -20427,7 +21072,7 @@ async function provisionPiCustomModelConfig(root, operatorHome, failClosed, open
20427
21072
  }
20428
21073
  function readClaudeUserScopeMcpServers(path) {
20429
21074
  try {
20430
- const parsed = JSON.parse(readFileSync5(path, "utf8"));
21075
+ const parsed = JSON.parse(readFileSync6(path, "utf8"));
20431
21076
  if (parsed && typeof parsed.mcpServers === "object" && parsed.mcpServers !== null) {
20432
21077
  return Object.fromEntries(Object.entries(parsed.mcpServers).filter(([name, value]) => {
20433
21078
  if (name === "squire")
@@ -20451,21 +21096,21 @@ function filteredHarnessMcpToml(source) {
20451
21096
  return extractTomlSections(source, ["mcp_servers"], excluded);
20452
21097
  }
20453
21098
  async function provisionManagedSkillsDir(target, managedSkills, sharedSkills, optionalShares) {
20454
- const parent = dirname6(target);
20455
- await assertRealContainedDirectory(parent, dirname6(parent));
21099
+ const parent = dirname7(target);
21100
+ await assertRealContainedDirectory(parent, dirname7(parent));
20456
21101
  const plan = await planManagedSkills(managedSkills, sharedSkills, optionalShares);
20457
21102
  if (await materializedSkillManifest(target) === plan.manifest)
20458
21103
  return;
20459
- const staged = resolve13(parent, `.skills.${process.pid}.${randomUUID3()}.tmp`);
21104
+ const staged = resolve14(parent, `.skills.${process.pid}.${randomUUID4()}.tmp`);
20460
21105
  await mkdir5(staged, { mode: 448 });
20461
21106
  try {
20462
21107
  for (const entry of plan.entries) {
20463
21108
  if (entry.kind === "managed") {
20464
- const skillDir = resolve13(staged, entry.name);
21109
+ const skillDir = resolve14(staged, entry.name);
20465
21110
  await mkdir5(skillDir, { recursive: true });
20466
- await writeIsolatedHarnessFile(resolve13(skillDir, "SKILL.md"), entry.content);
21111
+ await writeIsolatedHarnessFile(resolve14(skillDir, "SKILL.md"), entry.content);
20467
21112
  } else {
20468
- await copySafeSkillTree(entry.source, resolve13(staged, entry.name), entry.source);
21113
+ await copySafeSkillTree(entry.source, resolve14(staged, entry.name), entry.source);
20469
21114
  }
20470
21115
  }
20471
21116
  const existing = await lstat(target).catch(() => void 0);
@@ -20492,8 +21137,8 @@ async function planManagedSkills(managedSkills, sharedSkills, optionalShares) {
20492
21137
  try {
20493
21138
  const tree = [];
20494
21139
  await walkSafeSkillTree(shared.source, shared.source, {
20495
- directory: async (rel) => void tree.push(`d ${join5(shared.name, rel)}`),
20496
- file: async (rel, realPath) => void tree.push(`f ${join5(shared.name, rel)} ${sha2563(await readFile6(realPath))}`)
21140
+ directory: async (rel) => void tree.push(`d ${join6(shared.name, rel)}`),
21141
+ file: async (rel, realPath) => void tree.push(`f ${join6(shared.name, rel)} ${sha2563(await readFile6(realPath))}`)
20497
21142
  });
20498
21143
  entries.push({ kind: "shared", name: shared.name, source: shared.source });
20499
21144
  lines.push(...tree);
@@ -20512,8 +21157,8 @@ async function materializedSkillManifest(target) {
20512
21157
  const lines = [];
20513
21158
  const visit = async (directory, prefix) => {
20514
21159
  for (const entry of await readdir2(directory)) {
20515
- const path = resolve13(directory, entry);
20516
- const rel = prefix ? join5(prefix, entry) : entry;
21160
+ const path = resolve14(directory, entry);
21161
+ const rel = prefix ? join6(prefix, entry) : entry;
20517
21162
  const entryStats = await lstat(path);
20518
21163
  if (entryStats.isSymbolicLink())
20519
21164
  return false;
@@ -20538,7 +21183,7 @@ async function materializedSkillManifest(target) {
20538
21183
  return lines.sort().join("\n");
20539
21184
  }
20540
21185
  function sha2563(value) {
20541
- return createHash3("sha256").update(value).digest("hex");
21186
+ return createHash4("sha256").update(value).digest("hex");
20542
21187
  }
20543
21188
  async function resolveSharedSkillSources(operatorHome, names) {
20544
21189
  if (names.length > 0)
@@ -20547,14 +21192,14 @@ async function resolveSharedSkillSources(operatorHome, names) {
20547
21192
  const resolved = [];
20548
21193
  const skipped = [];
20549
21194
  for (const relativeRoot of OPERATOR_SKILL_SOURCE_DIRS) {
20550
- const sourceRoot = resolve13(operatorHome, relativeRoot);
21195
+ const sourceRoot = resolve14(operatorHome, relativeRoot);
20551
21196
  const rootStats = await lstat(sourceRoot).catch(() => void 0);
20552
21197
  if (!rootStats?.isDirectory() || rootStats.isSymbolicLink())
20553
21198
  continue;
20554
21199
  for (const entry of await readdir2(sourceRoot)) {
20555
21200
  if (!isSharedSkillName(entry) || seen.has(entry))
20556
21201
  continue;
20557
- const candidate = resolve13(sourceRoot, entry);
21202
+ const candidate = resolve14(sourceRoot, entry);
20558
21203
  try {
20559
21204
  const candidateStats = await lstat(candidate);
20560
21205
  if (candidateStats.isSymbolicLink()) {
@@ -20570,7 +21215,7 @@ async function resolveSharedSkillSources(operatorHome, names) {
20570
21215
  continue;
20571
21216
  }
20572
21217
  assertContained(sourceRoot, candidate);
20573
- const skillMd = resolve13(candidate, "SKILL.md");
21218
+ const skillMd = resolve14(candidate, "SKILL.md");
20574
21219
  const skillStats = await lstat(skillMd).catch((error) => {
20575
21220
  if (isMissingPathError(error)) {
20576
21221
  skipped.push({ path: candidate, reason: "missing SKILL.md" });
@@ -20622,8 +21267,8 @@ async function resolveExplicitSkillSources(operatorHome, names) {
20622
21267
  for (const name of unique) {
20623
21268
  const matches = [];
20624
21269
  for (const relativeRoot of OPERATOR_SKILL_SOURCE_DIRS) {
20625
- const sourceRoot = resolve13(operatorHome, relativeRoot);
20626
- const candidate = resolve13(sourceRoot, name);
21270
+ const sourceRoot = resolve14(operatorHome, relativeRoot);
21271
+ const candidate = resolve14(sourceRoot, name);
20627
21272
  const rootStats = await lstat(sourceRoot).catch(() => void 0);
20628
21273
  const candidateStats = await lstat(candidate).catch(() => void 0);
20629
21274
  if (!candidateStats)
@@ -20640,7 +21285,7 @@ async function resolveExplicitSkillSources(operatorHome, names) {
20640
21285
  if (matches.length !== 1) {
20641
21286
  throw new Error(matches.length === 0 ? `shared skill is unavailable: ${name}` : `shared skill source is ambiguous: ${name}`);
20642
21287
  }
20643
- const skillMd = resolve13(matches[0], "SKILL.md");
21288
+ const skillMd = resolve14(matches[0], "SKILL.md");
20644
21289
  const skillStats = await lstat(skillMd).catch(() => void 0);
20645
21290
  if (!skillStats?.isFile() || skillStats.isSymbolicLink() || skillStats.nlink !== 1) {
20646
21291
  throw new Error(`shared skill requires an ordinary SKILL.md: ${name}`);
@@ -20651,7 +21296,7 @@ async function resolveExplicitSkillSources(operatorHome, names) {
20651
21296
  }
20652
21297
  function assertContained(root, candidate) {
20653
21298
  const rel = relative2(root, candidate);
20654
- if (rel === ".." || rel.startsWith(`..${sep}`) || resolve13(root, rel) !== resolve13(candidate)) {
21299
+ if (rel === ".." || rel.startsWith(`..${sep}`) || resolve14(root, rel) !== resolve14(candidate)) {
20655
21300
  throw new Error(`path escapes the agent skill boundary: ${candidate}`);
20656
21301
  }
20657
21302
  }
@@ -20666,14 +21311,14 @@ var BLOCKED_SHARED_FILENAMES = /^(?:\.env(?:\..*)?|auth\.json|\.credentials\.jso
20666
21311
  async function walkSafeSkillTree(source, sourceRoot, visitor, rel = "") {
20667
21312
  assertContained(sourceRoot, source);
20668
21313
  const resolvedSource = await realpath(source);
20669
- if (resolvedSource !== resolve13(source)) {
21314
+ if (resolvedSource !== resolve14(source)) {
20670
21315
  throw new Error(`shared skill path resolves through a link: ${source}`);
20671
21316
  }
20672
21317
  assertContained(sourceRoot, resolvedSource);
20673
21318
  const stats = await lstat(resolvedSource);
20674
21319
  if (stats.isSymbolicLink())
20675
21320
  throw new Error(`shared skill contains a symlink: ${source}`);
20676
- if (BLOCKED_SHARED_FILENAMES.test(basename3(source))) {
21321
+ if (BLOCKED_SHARED_FILENAMES.test(basename4(source))) {
20677
21322
  throw new Error(`shared skill contains credential or configuration material: ${source}`);
20678
21323
  }
20679
21324
  if (stats.isDirectory()) {
@@ -20681,7 +21326,7 @@ async function walkSafeSkillTree(source, sourceRoot, visitor, rel = "") {
20681
21326
  for (const entry of await readdir2(resolvedSource)) {
20682
21327
  if (entry === "." || entry === "..")
20683
21328
  throw new Error("invalid shared skill entry");
20684
- await walkSafeSkillTree(resolve13(source, entry), sourceRoot, visitor, rel ? join5(rel, entry) : entry);
21329
+ await walkSafeSkillTree(resolve14(source, entry), sourceRoot, visitor, rel ? join6(rel, entry) : entry);
20685
21330
  }
20686
21331
  return;
20687
21332
  }
@@ -20693,22 +21338,22 @@ async function walkSafeSkillTree(source, sourceRoot, visitor, rel = "") {
20693
21338
  async function copySafeSkillTree(source, target, sourceRoot) {
20694
21339
  await walkSafeSkillTree(source, sourceRoot, {
20695
21340
  directory: async (rel) => {
20696
- await mkdir5(resolve13(target, rel), { mode: 448 });
21341
+ await mkdir5(resolve14(target, rel), { mode: 448 });
20697
21342
  },
20698
21343
  file: async (rel, realPath) => {
20699
- const destination = resolve13(target, rel);
21344
+ const destination = resolve14(target, rel);
20700
21345
  await copyFile(realPath, destination);
20701
21346
  await chmod2(destination, 384);
20702
21347
  }
20703
21348
  });
20704
21349
  }
20705
21350
  async function writeIsolatedHarnessFile(path, content) {
20706
- const parent = dirname6(path);
21351
+ const parent = dirname7(path);
20707
21352
  const parentStats = await lstat(parent);
20708
21353
  if (!parentStats.isDirectory() || parentStats.isSymbolicLink()) {
20709
21354
  throw new Error(`isolated harness parent is not a real directory: ${parent}`);
20710
21355
  }
20711
- const temporary = resolve13(parent, `.${basename3(path)}.${process.pid}.${randomUUID3()}.tmp`);
21356
+ const temporary = resolve14(parent, `.${basename4(path)}.${process.pid}.${randomUUID4()}.tmp`);
20712
21357
  try {
20713
21358
  await writeFile6(temporary, content, { mode: 384, flag: "wx" });
20714
21359
  await chmod2(temporary, 384);
@@ -20718,18 +21363,18 @@ async function writeIsolatedHarnessFile(path, content) {
20718
21363
  }
20719
21364
  }
20720
21365
  function roomAgentHomeEnv(root) {
20721
- const resolved = resolve13(root);
21366
+ const resolved = resolve14(root);
20722
21367
  return {
20723
- HOME: resolve13(resolved, "user"),
20724
- CLAUDE_CONFIG_DIR: resolve13(resolved, "claude"),
20725
- CODEX_HOME: resolve13(resolved, "codex"),
20726
- GOOSE_PATH_ROOT: resolve13(resolved, "goose"),
20727
- GROK_HOME: resolve13(resolved, "grok"),
20728
- CURSOR_HOME: resolve13(resolved, "cursor"),
20729
- PI_CODING_AGENT_DIR: resolve13(resolved, "pi"),
20730
- XDG_STATE_HOME: resolve13(resolved, "state"),
20731
- XDG_CACHE_HOME: resolve13(resolved, "cache"),
20732
- TMPDIR: resolve13(resolved, "tmp")
21368
+ HOME: resolve14(resolved, "user"),
21369
+ CLAUDE_CONFIG_DIR: resolve14(resolved, "claude"),
21370
+ CODEX_HOME: resolve14(resolved, "codex"),
21371
+ GOOSE_PATH_ROOT: resolve14(resolved, "goose"),
21372
+ GROK_HOME: resolve14(resolved, "grok"),
21373
+ CURSOR_HOME: resolve14(resolved, "cursor"),
21374
+ PI_CODING_AGENT_DIR: resolve14(resolved, "pi"),
21375
+ XDG_STATE_HOME: resolve14(resolved, "state"),
21376
+ XDG_CACHE_HOME: resolve14(resolved, "cache"),
21377
+ TMPDIR: resolve14(resolved, "tmp")
20733
21378
  };
20734
21379
  }
20735
21380
  var HARNESS_STATE_ENV_VARS = [
@@ -20748,22 +21393,22 @@ function harnessStateDirsFromEnv(env) {
20748
21393
  for (const name of HARNESS_STATE_ENV_VARS) {
20749
21394
  const value = env[name];
20750
21395
  if (value)
20751
- stateDirs.push(resolve13(value));
21396
+ stateDirs.push(resolve14(value));
20752
21397
  }
20753
21398
  const tmp = env.TMPDIR;
20754
- return { stateDirs, ...tmp ? { tmpDir: resolve13(tmp) } : {} };
21399
+ return { stateDirs, ...tmp ? { tmpDir: resolve14(tmp) } : {} };
20755
21400
  }
20756
21401
 
20757
21402
  // apps/body/dist/attachment-delivery.js
20758
21403
  import { mkdir as mkdir6, writeFile as writeFile7 } from "node:fs/promises";
20759
- import { basename as basename4, extname, join as join6 } from "node:path";
21404
+ import { basename as basename5, extname, join as join7 } from "node:path";
20760
21405
  var MAX_ATTACHMENT_BYTES = 25 * 1024 * 1024;
20761
21406
  var MEDIA_TTL_HOURS = 24;
20762
21407
  var EXPIRED_REASON = `expired: attachments are kept for ${MEDIA_TTL_HOURS} hours and these bytes are past that window`;
20763
21408
  var FETCH_TIMEOUT_MS = 3e4;
20764
21409
  var MAX_INLINE_IMAGE_BYTES = 5 * 1024 * 1024;
20765
21410
  function safeFileName(attachment, index, taken) {
20766
- const raw = basename4(attachment.name ?? "").replace(/[^\w.-]+/g, "_").replace(/^\.+/, "");
21411
+ const raw = basename5(attachment.name ?? "").replace(/[^\w.-]+/g, "_").replace(/^\.+/, "");
20767
21412
  let name = raw || `attachment-${index + 1}`;
20768
21413
  if (taken.has(name)) {
20769
21414
  const ext = extname(name);
@@ -20800,7 +21445,7 @@ async function deliverAttachments(attachments, dir, fetchImpl = fetch) {
20800
21445
  const bytes = Buffer.from(await response.arrayBuffer());
20801
21446
  if (bytes.length > MAX_ATTACHMENT_BYTES)
20802
21447
  return tooLarge(bytes.length);
20803
- const path = join6(dir, safeFileName(attachment, index, taken));
21448
+ const path = join7(dir, safeFileName(attachment, index, taken));
20804
21449
  await writeFile7(path, bytes);
20805
21450
  const mimeType = attachment.mimeType ?? response.headers.get("content-type") ?? "";
20806
21451
  if (!mimeType.startsWith("image/"))
@@ -21191,7 +21836,7 @@ function sessionConfigFingerprint(input) {
21191
21836
 
21192
21837
  // apps/body/dist/pi-mcp-bridge.js
21193
21838
  import { mkdir as mkdir7 } from "node:fs/promises";
21194
- import { resolve as resolve14 } from "node:path";
21839
+ import { resolve as resolve15 } from "node:path";
21195
21840
  var PI_MCP_BRIDGE_FILENAME = "beeline-mcp-bridge.js";
21196
21841
  function harnessMountsSessionMcpServers(agentCommand) {
21197
21842
  return !(agentCommand && /(^|[/\\])pi-acp(\.[a-z]+)?$/i.test(agentCommand));
@@ -21211,8 +21856,8 @@ async function installPiMcpBridge(input) {
21211
21856
  return void 0;
21212
21857
  if (!input.piHome || !input.servers.length)
21213
21858
  return void 0;
21214
- const directory = resolve14(input.piHome, "extensions");
21215
- const path = resolve14(directory, PI_MCP_BRIDGE_FILENAME);
21859
+ const directory = resolve15(input.piHome, "extensions");
21860
+ const path = resolve15(directory, PI_MCP_BRIDGE_FILENAME);
21216
21861
  try {
21217
21862
  await mkdir7(directory, { recursive: true, mode: 448 });
21218
21863
  await writeIsolatedHarnessFile(path, piMcpBridgeSource(input.servers));
@@ -21412,7 +22057,7 @@ async function contains(git, head, ancestor) {
21412
22057
  }
21413
22058
 
21414
22059
  // apps/body/dist/room-session.js
21415
- import { resolve as resolve15 } from "node:path";
22060
+ import { resolve as resolve16 } from "node:path";
21416
22061
 
21417
22062
  // apps/body/dist/read-only-policy.js
21418
22063
  var READ_ONLY_MCP_SERVER_NAME = "beeline-readonly-mcp";
@@ -21637,21 +22282,21 @@ function readOnlyMcpServer(config, cwd, agentMemoryDir) {
21637
22282
  command: config.readonlyMcpCommand,
21638
22283
  args: [...config.readonlyMcpArgs ?? []],
21639
22284
  env: [
21640
- { name: "BEELINE_READONLY_ROOT", value: resolve15(cwd) },
22285
+ { name: "BEELINE_READONLY_ROOT", value: resolve16(cwd) },
21641
22286
  ...config.agentHomeRoot ? [
21642
22287
  {
21643
22288
  name: "BEELINE_READONLY_AGENT_SKILLS_ROOT",
21644
- value: resolve15(config.agentHomeRoot, skillDir, "skills")
22289
+ value: resolve16(config.agentHomeRoot, skillDir, "skills")
21645
22290
  }
21646
22291
  ] : [],
21647
- ...agentMemoryDir ? [{ name: "BEELINE_READONLY_AGENT_MEMORY_ROOT", value: resolve15(agentMemoryDir) }] : []
22292
+ ...agentMemoryDir ? [{ name: "BEELINE_READONLY_AGENT_MEMORY_ROOT", value: resolve16(agentMemoryDir) }] : []
21648
22293
  ]
21649
22294
  };
21650
22295
  }
21651
22296
 
21652
22297
  // apps/body/dist/pi-turn-record.js
21653
22298
  import { readdir as readdir3, readFile as readFile7 } from "node:fs/promises";
21654
- import { resolve as resolve16 } from "node:path";
22299
+ import { resolve as resolve17 } from "node:path";
21655
22300
  function summarizeProviderError(errorMessage2) {
21656
22301
  const trimmed = errorMessage2.trim();
21657
22302
  const statusMatch = /^(\d{3}):\s*([\s\S]*)$/.exec(trimmed);
@@ -21672,7 +22317,7 @@ function summarizeProviderError(errorMessage2) {
21672
22317
  }
21673
22318
  async function sessionFileFromMap(home, sessionId) {
21674
22319
  try {
21675
- const raw = await readFile7(resolve16(home, ".pi", "pi-acp", "session-map.json"), "utf8");
22320
+ const raw = await readFile7(resolve17(home, ".pi", "pi-acp", "session-map.json"), "utf8");
21676
22321
  const map = JSON.parse(raw);
21677
22322
  const file = map.sessions?.[sessionId]?.sessionFile;
21678
22323
  return typeof file === "string" && file ? file : void 0;
@@ -21681,7 +22326,7 @@ async function sessionFileFromMap(home, sessionId) {
21681
22326
  }
21682
22327
  }
21683
22328
  async function sessionFileFromLayout(piDir, sessionId) {
21684
- const sessionsRoot = resolve16(piDir, "sessions");
22329
+ const sessionsRoot = resolve17(piDir, "sessions");
21685
22330
  const suffix = `_${sessionId}.jsonl`;
21686
22331
  let projects;
21687
22332
  try {
@@ -21690,7 +22335,7 @@ async function sessionFileFromLayout(piDir, sessionId) {
21690
22335
  return void 0;
21691
22336
  }
21692
22337
  for (const project of projects) {
21693
- const dir = resolve16(sessionsRoot, project);
22338
+ const dir = resolve17(sessionsRoot, project);
21694
22339
  let files;
21695
22340
  try {
21696
22341
  files = await readdir3(dir);
@@ -21699,7 +22344,7 @@ async function sessionFileFromLayout(piDir, sessionId) {
21699
22344
  }
21700
22345
  const match = files.find((file) => file.endsWith(suffix));
21701
22346
  if (match)
21702
- return resolve16(dir, match);
22347
+ return resolve17(dir, match);
21703
22348
  }
21704
22349
  return void 0;
21705
22350
  }
@@ -21874,7 +22519,7 @@ async function withTurnReceiptHeartbeat(api, receipt, task, onHeartbeatError) {
21874
22519
 
21875
22520
  // apps/body/dist/turn-trace.js
21876
22521
  import { appendFile, mkdir as mkdir8, readdir as readdir4, rm as rm3 } from "node:fs/promises";
21877
- import { resolve as resolve17 } from "node:path";
22522
+ import { resolve as resolve18 } from "node:path";
21878
22523
  import { performance as performance2 } from "node:perf_hooks";
21879
22524
  var TURN_PHASES = [
21880
22525
  /** Enqueued on `SessionScheduler` until this turn holds a slot. A capacity wait lives here. */
@@ -22104,7 +22749,7 @@ function formatTurnTraceLine(record3) {
22104
22749
  return [head, ...record3.attempts.map((attempt) => formatTurnAttempt(attempt))].join("\n ");
22105
22750
  }
22106
22751
  function turnTraceDirectory(runtimeDir) {
22107
- return resolve17(runtimeDir, "turn-traces");
22752
+ return resolve18(runtimeDir, "turn-traces");
22108
22753
  }
22109
22754
  var TURN_TRACE_RETENTION_DAYS = 7;
22110
22755
  function traceFileName(date) {
@@ -22121,7 +22766,7 @@ var TurnTraceFile = class {
22121
22766
  this.options = options;
22122
22767
  }
22123
22768
  path(now2 = (this.options.clock ?? (() => /* @__PURE__ */ new Date()))()) {
22124
- return resolve17(this.directory, traceFileName(now2));
22769
+ return resolve18(this.directory, traceFileName(now2));
22125
22770
  }
22126
22771
  write(record3) {
22127
22772
  this.tail = this.tail.catch(() => void 0).then(async () => {
@@ -22145,15 +22790,15 @@ var TurnTraceFile = class {
22145
22790
  this.prunedDay = day;
22146
22791
  const cutoff = traceFileName(new Date(now2.getTime() - TURN_TRACE_RETENTION_DAYS * 864e5));
22147
22792
  const names = await readdir4(this.directory).catch(() => []);
22148
- await Promise.all(names.filter((name) => /^turns-\d{4}-\d{2}-\d{2}\.jsonl$/.test(name) && name < cutoff).map((name) => rm3(resolve17(this.directory, name), { force: true })));
22793
+ await Promise.all(names.filter((name) => /^turns-\d{4}-\d{2}-\d{2}\.jsonl$/.test(name) && name < cutoff).map((name) => rm3(resolve18(this.directory, name), { force: true })));
22149
22794
  }
22150
22795
  };
22151
22796
 
22152
22797
  // apps/body/dist/corner-github-auth.js
22153
22798
  import { chmod as chmod3, mkdir as mkdir9, writeFile as writeFile8 } from "node:fs/promises";
22154
- import { delimiter as delimiter2, resolve as resolve18 } from "node:path";
22799
+ import { delimiter as delimiter2, resolve as resolve19 } from "node:path";
22155
22800
  async function installCornerGitHubWrappers(input) {
22156
- const bin = resolve18(input.root, "beeline-github-bin");
22801
+ const bin = resolve19(input.root, "beeline-github-bin");
22157
22802
  await mkdir9(bin, { recursive: true, mode: 448 });
22158
22803
  const common = {
22159
22804
  node: process.execPath,
@@ -22163,13 +22808,13 @@ async function installCornerGitHubWrappers(input) {
22163
22808
  featureBranch: input.featureBranch,
22164
22809
  targetBranch: input.targetBranch
22165
22810
  };
22166
- await writeLauncher(resolve18(bin, "git"), {
22811
+ await writeLauncher(resolve19(bin, "git"), {
22167
22812
  ...common,
22168
22813
  command: input.gitBinary,
22169
22814
  launcher: "git"
22170
22815
  });
22171
22816
  if (input.ghBinary)
22172
- await writeLauncher(resolve18(bin, "gh"), {
22817
+ await writeLauncher(resolve19(bin, "gh"), {
22173
22818
  ...common,
22174
22819
  command: input.ghBinary,
22175
22820
  launcher: "gh"
@@ -22304,25 +22949,25 @@ process.exit(result.status ?? 1);
22304
22949
  }
22305
22950
 
22306
22951
  // apps/body/dist/warm-node-modules.js
22307
- import { createHash as createHash4, randomUUID as randomUUID4 } from "node:crypto";
22952
+ import { createHash as createHash5, randomUUID as randomUUID5 } from "node:crypto";
22308
22953
  import { constants as fsConstants } from "node:fs";
22309
22954
  import { chmod as chmod4, copyFile as copyFile2, link, lstat as lstat2, mkdir as mkdir10, readdir as readdir5, readFile as readFile8, readlink, rename as rename3, rm as rm4, stat as stat2, symlink as symlink2, utimes } from "node:fs/promises";
22310
- import { dirname as dirname7, join as join7, resolve as resolve19 } from "node:path";
22955
+ import { dirname as dirname8, join as join8, resolve as resolve20 } from "node:path";
22311
22956
  var STORE_FORMAT = "v1";
22312
22957
  var STAGING_PREFIX = ".beeline-warm-";
22313
22958
  var STAGING_SWEEP_MS = 24 * 60 * 60 * 1e3;
22314
22959
  var WARM_STORE_MAX_ENTRIES = 3;
22315
22960
  function sharedNpmCacheDir(supervisorRoot) {
22316
- return resolve19(supervisorRoot, "beeline", "npm-cache");
22961
+ return resolve20(supervisorRoot, "beeline", "npm-cache");
22317
22962
  }
22318
22963
  function warmNodeModulesStoreDir(supervisorRoot) {
22319
- return resolve19(supervisorRoot, "beeline", "node-modules");
22964
+ return resolve20(supervisorRoot, "beeline", "node-modules");
22320
22965
  }
22321
22966
  function isPlanRefusal(value) {
22322
22967
  return "failure" in value;
22323
22968
  }
22324
22969
  async function readWarmPlan(worktreePath) {
22325
- const lockfile = await readFile8(resolve19(worktreePath, "package-lock.json")).catch(() => void 0);
22970
+ const lockfile = await readFile8(resolve20(worktreePath, "package-lock.json")).catch(() => void 0);
22326
22971
  if (!lockfile)
22327
22972
  return { failure: "no-lockfile" };
22328
22973
  const packages = parseLockfilePackages(lockfile);
@@ -22337,7 +22982,7 @@ async function readWarmPlan(worktreePath) {
22337
22982
  const unsafe = trees.find((tree) => !isContainedTreePath(tree));
22338
22983
  if (unsafe)
22339
22984
  return { failure: "unsafe-lockfile", detail: unsafe };
22340
- const key = createHash4("sha256").update(`${STORE_FORMAT}\0${process.platform}\0${process.arch}\0${process.versions.modules}\0`).update(lockfile).digest("hex").slice(0, 32);
22985
+ const key = createHash5("sha256").update(`${STORE_FORMAT}\0${process.platform}\0${process.arch}\0${process.versions.modules}\0`).update(lockfile).digest("hex").slice(0, 32);
22341
22986
  return { key, trees };
22342
22987
  }
22343
22988
  function nodeModulesTreePaths(packages) {
@@ -22361,11 +23006,11 @@ async function seedWarmNodeModules(input) {
22361
23006
  return { reason: plan.failure, ...plan.detail ? { detail: plan.detail } : {} };
22362
23007
  }
22363
23008
  for (const tree of plan.trees) {
22364
- if (await pathExists(resolve19(input.worktreePath, tree))) {
23009
+ if (await pathExists(resolve20(input.worktreePath, tree))) {
22365
23010
  return { reason: "present", key: plan.key };
22366
23011
  }
22367
23012
  }
22368
- const entry = resolve19(input.storeRoot, plan.key);
23013
+ const entry = resolve20(input.storeRoot, plan.key);
22369
23014
  if (!await isDirectory(entry))
22370
23015
  return { reason: "cold", key: plan.key };
22371
23016
  const [storeDevice, checkoutDevice] = await Promise.all([
@@ -22375,19 +23020,19 @@ async function seedWarmNodeModules(input) {
22375
23020
  if (storeDevice === void 0 || storeDevice !== checkoutDevice) {
22376
23021
  return { reason: "cross-device", key: plan.key };
22377
23022
  }
22378
- const staging = resolve19(input.storeRoot, `${STAGING_PREFIX}${process.pid}.${randomUUID4()}`);
23023
+ const staging = resolve20(input.storeRoot, `${STAGING_PREFIX}${process.pid}.${randomUUID5()}`);
22379
23024
  const placed = [];
22380
23025
  const now2 = (input.now ?? Date.now)();
22381
23026
  try {
22382
23027
  await sweepStaleStaging(input.storeRoot, now2);
22383
23028
  await utimes(entry, now2 / 1e3, now2 / 1e3).catch(() => void 0);
22384
23029
  for (const tree of plan.trees) {
22385
- await cloneTree(resolve19(entry, tree), resolve19(staging, tree), seedFile);
23030
+ await cloneTree(resolve20(entry, tree), resolve20(staging, tree), seedFile);
22386
23031
  }
22387
23032
  for (const tree of plan.trees) {
22388
- const target = resolve19(input.worktreePath, tree);
22389
- await mkdir10(dirname7(target), { recursive: true });
22390
- await rename3(resolve19(staging, tree), target);
23033
+ const target = resolve20(input.worktreePath, tree);
23034
+ await mkdir10(dirname8(target), { recursive: true });
23035
+ await rename3(resolve20(staging, tree), target);
22391
23036
  placed.push(target);
22392
23037
  }
22393
23038
  return { reason: "seeded", key: plan.key };
@@ -22405,11 +23050,11 @@ async function harvestWarmNodeModules(input) {
22405
23050
  if (isPlanRefusal(plan)) {
22406
23051
  return { reason: plan.failure, ...plan.detail ? { detail: plan.detail } : {} };
22407
23052
  }
22408
- const entry = resolve19(input.storeRoot, plan.key);
23053
+ const entry = resolve20(input.storeRoot, plan.key);
22409
23054
  if (await pathExists(entry))
22410
23055
  return { reason: "already-warm", key: plan.key };
22411
23056
  for (const tree of plan.trees) {
22412
- if (!await isDirectory(resolve19(input.worktreePath, tree))) {
23057
+ if (!await isDirectory(resolve20(input.worktreePath, tree))) {
22413
23058
  return { reason: "no-node-modules", key: plan.key, detail: tree };
22414
23059
  }
22415
23060
  }
@@ -22421,12 +23066,12 @@ async function harvestWarmNodeModules(input) {
22421
23066
  detail: `${missing.length} absent, e.g. ${missing.slice(0, 3).join(", ")}`
22422
23067
  };
22423
23068
  }
22424
- const staging = resolve19(input.storeRoot, `${STAGING_PREFIX}${process.pid}.${randomUUID4()}`);
23069
+ const staging = resolve20(input.storeRoot, `${STAGING_PREFIX}${process.pid}.${randomUUID5()}`);
22425
23070
  try {
22426
23071
  await mkdir10(input.storeRoot, { recursive: true, mode: 493 });
22427
23072
  await sweepStaleStaging(input.storeRoot, (input.now ?? Date.now)());
22428
23073
  for (const tree of plan.trees) {
22429
- await cloneTree(resolve19(input.worktreePath, tree), resolve19(staging, tree), harvestFile);
23074
+ await cloneTree(resolve20(input.worktreePath, tree), resolve20(staging, tree), harvestFile);
22430
23075
  }
22431
23076
  await input.onCopied?.();
22432
23077
  if (!await stagedTreeIsPublishable(input.worktreePath, staging, plan.key)) {
@@ -22447,18 +23092,18 @@ async function stagedTreeIsPublishable(worktreePath, staging, key) {
22447
23092
  const settled = await readWarmPlan(worktreePath);
22448
23093
  if (isPlanRefusal(settled) || settled.key !== key)
22449
23094
  return false;
22450
- const hidden = join7("node_modules", ".package-lock.json");
23095
+ const hidden = join8("node_modules", ".package-lock.json");
22451
23096
  const [copied, current] = await Promise.all([
22452
- readFile8(resolve19(staging, hidden)).catch(() => void 0),
22453
- readFile8(resolve19(worktreePath, hidden)).catch(() => void 0)
23097
+ readFile8(resolve20(staging, hidden)).catch(() => void 0),
23098
+ readFile8(resolve20(worktreePath, hidden)).catch(() => void 0)
22454
23099
  ]);
22455
23100
  if (!copied || !current || !copied.equals(current))
22456
23101
  return false;
22457
23102
  return (await missingInstalledPackages(worktreePath, staging)).length === 0;
22458
23103
  }
22459
23104
  async function missingInstalledPackages(worktreePath, treeRoot = worktreePath) {
22460
- const wanted = parseLockfilePackages(await readFile8(resolve19(worktreePath, "package-lock.json")).catch(() => void 0));
22461
- const installed = parseLockfilePackages(await readFile8(resolve19(treeRoot, "node_modules", ".package-lock.json")).catch(() => void 0));
23105
+ const wanted = parseLockfilePackages(await readFile8(resolve20(worktreePath, "package-lock.json")).catch(() => void 0));
23106
+ const installed = parseLockfilePackages(await readFile8(resolve20(treeRoot, "node_modules", ".package-lock.json")).catch(() => void 0));
22462
23107
  if (!wanted)
22463
23108
  return ["package-lock.json is unreadable"];
22464
23109
  if (!installed)
@@ -22478,14 +23123,14 @@ async function missingInstalledPackages(worktreePath, treeRoot = worktreePath) {
22478
23123
  required.push(path);
22479
23124
  }
22480
23125
  await mapWithLimit(required, INTEGRITY_READ_CONCURRENCY, async (path) => {
22481
- if (!(path in installed) || !await isInstalledPackage(resolve19(treeRoot, path))) {
23126
+ if (!(path in installed) || !await isInstalledPackage(resolve20(treeRoot, path))) {
22482
23127
  missing.push(path);
22483
23128
  }
22484
23129
  });
22485
23130
  return missing.sort();
22486
23131
  }
22487
23132
  async function isInstalledPackage(path) {
22488
- return stat2(join7(path, "package.json")).then((info) => info.isFile(), () => false);
23133
+ return stat2(join8(path, "package.json")).then((info) => info.isFile(), () => false);
22489
23134
  }
22490
23135
  var INTEGRITY_READ_CONCURRENCY = 64;
22491
23136
  async function mapWithLimit(values, limit, visit) {
@@ -22519,8 +23164,8 @@ function isContainedTreePath(value) {
22519
23164
  async function cloneTree(source, target, file, topLevel = true) {
22520
23165
  await mkdir10(target, { recursive: true, mode: 493 });
22521
23166
  for (const entry of await readdir5(source, { withFileTypes: true })) {
22522
- const from = join7(source, entry.name);
22523
- const to = join7(target, entry.name);
23167
+ const from = join8(source, entry.name);
23168
+ const to = join8(target, entry.name);
22524
23169
  if (entry.isSymbolicLink()) {
22525
23170
  await symlink2(await readlink(from), to);
22526
23171
  continue;
@@ -22550,13 +23195,13 @@ async function pruneWarmStore(storeRoot, keep) {
22550
23195
  const names = (await readdir5(storeRoot).catch(() => [])).filter((name) => !name.startsWith(STAGING_PREFIX));
22551
23196
  const entries = [];
22552
23197
  for (const name of names) {
22553
- const info = await lstat2(join7(storeRoot, name)).catch(() => void 0);
23198
+ const info = await lstat2(join8(storeRoot, name)).catch(() => void 0);
22554
23199
  if (info?.isDirectory())
22555
23200
  entries.push({ name, usedAt: info.mtimeMs });
22556
23201
  }
22557
23202
  const dropped = entries.sort((a2, b) => b.usedAt - a2.usedAt || a2.name.localeCompare(b.name)).slice(keep);
22558
23203
  for (const entry of dropped) {
22559
- await rm4(join7(storeRoot, entry.name), { recursive: true, force: true }).catch(() => void 0);
23204
+ await rm4(join8(storeRoot, entry.name), { recursive: true, force: true }).catch(() => void 0);
22560
23205
  }
22561
23206
  return dropped.map((entry) => entry.name);
22562
23207
  }
@@ -22565,7 +23210,7 @@ async function sweepStaleStaging(storeRoot, now2) {
22565
23210
  for (const name of entries) {
22566
23211
  if (!name.startsWith(STAGING_PREFIX))
22567
23212
  continue;
22568
- const path = join7(storeRoot, name);
23213
+ const path = join8(storeRoot, name);
22569
23214
  const info = await lstat2(path).catch(() => void 0);
22570
23215
  if (!info || now2 - info.mtimeMs < STAGING_SWEEP_MS)
22571
23216
  continue;
@@ -22587,8 +23232,8 @@ function describe3(error) {
22587
23232
 
22588
23233
  // apps/body/dist/monolith-room-turn.js
22589
23234
  import { mkdir as mkdir11 } from "node:fs/promises";
22590
- import { homedir as homedir6 } from "node:os";
22591
- import { join as join8 } from "node:path";
23235
+ import { homedir as homedir7 } from "node:os";
23236
+ import { join as join9 } from "node:path";
22592
23237
 
22593
23238
  // packages/api-contract/dist/scheduled-prompts.js
22594
23239
  var SCHEDULE_SCHEDULER_NAME = "Beeline Scheduler";
@@ -22620,9 +23265,23 @@ function inboxItemPromptBody(item) {
22620
23265
  return isScheduledPrompt(item) ? item.systemEvent?.consequence ?? item.body : item.body;
22621
23266
  }
22622
23267
  function pendingGrantToolCall(call) {
22623
- if (!/(?:^|[._:/-])request_grant$/i.test(call.title ?? ""))
23268
+ if (!/(?:^|[._:/-])(?:request_grant|offer_connector)$/i.test(call.title ?? ""))
22624
23269
  return false;
22625
- return /pending, card posted/i.test(typeof call.content === "string" ? call.content : JSON.stringify(call.content ?? ""));
23270
+ return /(?:pending|already offered), card (?:posted|still open)/i.test(typeof call.content === "string" ? call.content : JSON.stringify(call.content ?? ""));
23271
+ }
23272
+ function resumePrompt(item) {
23273
+ if (item.systemEvent?.kind === "connector-offer-decided") {
23274
+ return [
23275
+ `This is the answer to your connector offer: ${item.body}.`,
23276
+ "Your paused work resumes now. The tool is being installed on your machine; its sign-in and status reach the person through the tool\u2019s own status message, not through you.",
23277
+ 'Acknowledge in one short line (for example "Adding Trusty Squire now.") and continue the work that needed it, or say plainly what still has to happen before you can.'
23278
+ ].join(" ");
23279
+ }
23280
+ return [
23281
+ "This is the answer to your grant request; your paused work resumes now.",
23282
+ "If it was approved and it is a command grant, run it with run_granted_command and the exact argv.",
23283
+ "If it was declined, try another way or say plainly what you cannot do."
23284
+ ].join(" ");
22626
23285
  }
22627
23286
  function roomMentionDirectory(roster, selfId) {
22628
23287
  const rows = [];
@@ -22724,7 +23383,7 @@ var MonolithRoomTurnLoop = class {
22724
23383
  ...this.options.config.bwrapPath ? { bwrapPath: this.options.config.bwrapPath } : {},
22725
23384
  ...this.sessionScratchDir ? { scratch: this.sessionScratchDir } : {},
22726
23385
  ...this.sessionStateDirs.length ? { harnessStateDirs: this.sessionStateDirs } : {},
22727
- maskPaths: credentialMaskPaths(this.options.config.sandboxMaskPaths, this.options.config.operatorHome ?? homedir6())
23386
+ maskPaths: credentialMaskPaths(this.options.config.sandboxMaskPaths, this.options.config.operatorHome ?? homedir7())
22728
23387
  };
22729
23388
  }
22730
23389
  /**
@@ -22791,7 +23450,7 @@ var MonolithRoomTurnLoop = class {
22791
23450
  const cached = this.deliveredAttachments.get(item.id);
22792
23451
  if (cached)
22793
23452
  return cached;
22794
- const delivered = await deliverAttachments(item.attachments, join8(this.attachmentDir, item.id.replace(/[^\w-]/g, "_")), this.options.fetchImpl);
23453
+ const delivered = await deliverAttachments(item.attachments, join9(this.attachmentDir, item.id.replace(/[^\w-]/g, "_")), this.options.fetchImpl);
22795
23454
  this.deliveredAttachments.set(item.id, withoutImageData(delivered));
22796
23455
  return delivered;
22797
23456
  }
@@ -22878,6 +23537,10 @@ var MonolithRoomTurnLoop = class {
22878
23537
  })
22879
23538
  }) : {};
22880
23539
  const command = this.options.config.agentCommand ?? this.options.config.agentBinary;
23540
+ const harnessLabel = harnessIdentityLabel({
23541
+ kind: this.options.config.agentKind,
23542
+ command
23543
+ });
22881
23544
  const agentEnv = { ...this.options.config.agentEnv, ...homeOverlay };
22882
23545
  this.agentEnv = agentEnv;
22883
23546
  const agentArgs = agentArgsWithModelSelection({
@@ -22885,12 +23548,12 @@ var MonolithRoomTurnLoop = class {
22885
23548
  command,
22886
23549
  args: this.options.config.agentArgs ?? []
22887
23550
  }, selection);
22888
- const operatorHome = this.options.config.operatorHome ?? homedir6();
23551
+ const operatorHome = this.options.config.operatorHome ?? homedir7();
22889
23552
  const { stateDirs, tmpDir } = harnessStateDirsFromEnv(agentEnv);
22890
- this.attachmentDir = tmpDir ? join8(tmpDir, "beeline-attachments") : void 0;
23553
+ this.attachmentDir = tmpDir ? join9(tmpDir, "beeline-attachments") : void 0;
22891
23554
  this.sessionScratchDir = tmpDir;
22892
23555
  this.sessionStateDirs = stateDirs;
22893
- const homeStateDirs = harnessHomeStateDirs(command, agentEnv.HOME ?? operatorHome);
23556
+ const homeStateDirs = harnessHomeStateDirs(harnessLabel, agentEnv.HOME ?? operatorHome);
22894
23557
  await Promise.all(homeStateDirs.map((dir) => mkdir11(dir, { recursive: true })));
22895
23558
  const attachScratchRoot = this.options.config.agentHomeRoot ?? tmpDir;
22896
23559
  if (attachScratchRoot)
@@ -22926,7 +23589,7 @@ var MonolithRoomTurnLoop = class {
22926
23589
  })
22927
23590
  ];
22928
23591
  await installPiMcpBridge({
22929
- agentCommand: command,
23592
+ agentCommand: harnessLabel,
22930
23593
  piHome: agentEnv.PI_CODING_AGENT_DIR,
22931
23594
  servers
22932
23595
  });
@@ -22936,7 +23599,7 @@ var MonolithRoomTurnLoop = class {
22936
23599
  agentArgs: spawnCommand.args,
22937
23600
  agentEnv,
22938
23601
  agentCwd: this.options.cwd,
22939
- agentLabel: command,
23602
+ agentLabel: harnessLabel,
22940
23603
  // `bwrapPath` is set only when `detectBwrapSandbox` passed its self-test
22941
23604
  // (`config.ts`), which is exactly when `wrapAgentCommand` above wraps.
22942
23605
  osSandbox: Boolean(this.options.config.bwrapPath),
@@ -23012,7 +23675,10 @@ var MonolithRoomTurnLoop = class {
23012
23675
  if (durableReplyText(result.agentText))
23013
23676
  return void 0;
23014
23677
  return explainEmptyAgentTurn({
23015
- agentLabel: this.options.config.agentCommand ?? this.options.config.agentBinary,
23678
+ agentLabel: harnessIdentityLabel({
23679
+ kind: this.options.config.agentKind,
23680
+ command: this.options.config.agentCommand ?? this.options.config.agentBinary
23681
+ }),
23016
23682
  agentEnv: this.agentEnv,
23017
23683
  sessionId: this.sessionId,
23018
23684
  result
@@ -23134,11 +23800,7 @@ var MonolithRoomTurnLoop = class {
23134
23800
  const buildPrompt = () => [
23135
23801
  this.turnInstructionPrefix,
23136
23802
  WarmTranscript.render(this.warmTranscript.select(this.sessionId, transcriptRows), "Room conversation so far:", "New in the Room since your last turn (the earlier conversation is already in this session):"),
23137
- grantDecision ? [
23138
- "This is the answer to your grant request; your paused work resumes now.",
23139
- "If it was approved and it is a command grant, run it with run_granted_command and the exact argv.",
23140
- "If it was declined, try another way or say plainly what you cannot do."
23141
- ].join(" ") : "",
23803
+ grantDecision ? resumePrompt(item) : "",
23142
23804
  roomMentionDirectory(roster, this.agent.publicKey),
23143
23805
  (corners.corners ?? []).some((corner) => !corner.archived) ? `Current corners you belong to (use the exact cornerId with steer_corner):
23144
23806
  ${JSON.stringify((corners.corners ?? []).filter((corner) => !corner.archived))}` : "",
@@ -23224,7 +23886,7 @@ ${JSON.stringify((corners.corners ?? []).filter((corner) => !corner.archived))}`
23224
23886
  this.pausedOnGrantRequestId = item.id;
23225
23887
  console.log(`[thin-core] monolith Room ${this.options.roomId} turn ${item.id} paused on a grant card`);
23226
23888
  } else if (resumedRequestId) {
23227
- console.log(`[thin-core] monolith Room ${this.options.roomId} turn ${resumedRequestId} resumed by grant decision ${item.id}`);
23889
+ console.log(`[thin-core] monolith Room ${this.options.roomId} turn ${resumedRequestId} resumed by card decision ${item.id}`);
23228
23890
  }
23229
23891
  if (openCornerCall) {
23230
23892
  console.log(`[thin-core] monolith Room ${this.options.roomId} tool call: ${openCornerCall.title} (${openCornerCall.status ?? "no status"})`);
@@ -23328,7 +23990,7 @@ ${JSON.stringify((corners.corners ?? []).filter((corner) => !corner.archived))}`
23328
23990
  const item = {
23329
23991
  ...command.source,
23330
23992
  id: command.turnRequestId,
23331
- body: command.action === "resume" ? `Resume the paused turn. The server supplied this grant decision: ${command.source.body}` : command.source.body
23993
+ body: command.action === "resume" ? `Resume the paused turn. The server supplied this answer: ${command.source.body}` : command.source.body
23332
23994
  };
23333
23995
  this.startPrompt(item);
23334
23996
  await this.activeTurn?.promise;
@@ -23507,7 +24169,7 @@ function toolArguments(call) {
23507
24169
  return input ? { input: clampBytes(redactToolDetail(input), TOOL_ARGUMENT_MAX_BYTES) } : {};
23508
24170
  }
23509
24171
  function toolCallKey(call, index) {
23510
- return call.id ? `id-${createHash5("sha256").update(call.id).digest("hex")}` : `tool-${index}`;
24172
+ return call.id ? `id-${createHash6("sha256").update(call.id).digest("hex")}` : `tool-${index}`;
23511
24173
  }
23512
24174
  function toolCallSettled(call) {
23513
24175
  if (call.resultReceived)
@@ -23757,6 +24419,10 @@ var MonolithCornerTurnLoop = class {
23757
24419
  })
23758
24420
  }) : {};
23759
24421
  const command = this.options.config.agentCommand ?? this.options.config.agentBinary;
24422
+ const harnessLabel = harnessIdentityLabel({
24423
+ kind: this.options.config.agentKind,
24424
+ command
24425
+ });
23760
24426
  const repository = this.options.repository;
23761
24427
  let githubEnv = repository ? { GH_TOKEN: repository.githubToken, GITHUB_TOKEN: repository.githubToken } : {};
23762
24428
  if (repository && this.options.config.runtimeConfigPath && this.options.config.agentHomeRoot) {
@@ -23788,11 +24454,11 @@ var MonolithCornerTurnLoop = class {
23788
24454
  command,
23789
24455
  args: this.options.config.agentArgs ?? []
23790
24456
  }, selection);
23791
- const operatorHome = this.options.config.operatorHome ?? homedir7();
24457
+ const operatorHome = this.options.config.operatorHome ?? homedir8();
23792
24458
  const { stateDirs, tmpDir } = harnessStateDirsFromEnv(agentEnv);
23793
- this.attachmentDir = tmpDir ? join9(tmpDir, "beeline-attachments") : void 0;
24459
+ this.attachmentDir = tmpDir ? join10(tmpDir, "beeline-attachments") : void 0;
23794
24460
  this.sessionScratchDir = tmpDir;
23795
- const homeStateDirs = harnessHomeStateDirs(command, agentEnv.HOME ?? operatorHome);
24461
+ const homeStateDirs = harnessHomeStateDirs(harnessLabel, agentEnv.HOME ?? operatorHome);
23796
24462
  await Promise.all(homeStateDirs.map((dir) => mkdir12(dir, { recursive: true })));
23797
24463
  const attachScratchRoot = this.options.config.agentHomeRoot ?? tmpDir;
23798
24464
  if (attachScratchRoot)
@@ -23825,7 +24491,7 @@ var MonolithCornerTurnLoop = class {
23825
24491
  agentArgs: spawnCommand.args,
23826
24492
  agentEnv,
23827
24493
  agentCwd: this.options.worktreePath,
23828
- agentLabel: command,
24494
+ agentLabel: harnessLabel,
23829
24495
  autoApprovePermissions: true,
23830
24496
  permissionHandler: () => Promise.resolve("allow")
23831
24497
  };
@@ -23865,7 +24531,7 @@ var MonolithCornerTurnLoop = class {
23865
24531
  })
23866
24532
  ];
23867
24533
  await installPiMcpBridge({
23868
- agentCommand: command,
24534
+ agentCommand: harnessLabel,
23869
24535
  piHome: agentEnv.PI_CODING_AGENT_DIR,
23870
24536
  servers
23871
24537
  });
@@ -23892,7 +24558,7 @@ var MonolithCornerTurnLoop = class {
23892
24558
  selfReviewerInstruction ?? cornerMergeInstruction(configuration.yoloMode, configuration.reviewerHandle)
23893
24559
  ],
23894
24560
  "Do not tag the user when a corner turn finishes: the server posts the merge summary card and its push already cover completion. Tag a human only mid-turn, and only when you need a decision or input.",
23895
- "Never restate server check or merge notes. On a checks turn, say nothing unless you merge or push a fix, then use one short line. Never merge while approvalPending is true. When approval is pending, wait for the reviewer to tag you. Never merge another pull request. Never create a schedule to poll pr_checks_status or the merge gate: the green transition wakes the reviewer and the reviewer's approval tag wakes you, and tagging any agent other than the configured reviewer cannot clear the gate. If a schedule wakes you in this corner anyway, follow the same rule as a checks turn: say nothing unless you merge, push a fix, or report a genuinely new blocker."
24561
+ "Never restate server check or merge notes. On a checks turn, say nothing unless you merge or push a fix, then use one short line. When asked whether the reviewer was woken, call pr_checks_status and report reviewerWake; do not invent a cause. Never merge while approvalPending is true. When approval is pending, wait for the reviewer to tag you. Never merge another pull request. Never create a schedule to poll pr_checks_status or the merge gate: the green transition wakes the reviewer and the reviewer's approval tag wakes you, and tagging any agent other than the configured reviewer cannot clear the gate. If a schedule wakes you in this corner anyway, follow the same rule as a checks turn: say nothing unless you merge, push a fix, or report a genuinely new blocker."
23896
24562
  ] : [
23897
24563
  "This is a chat-only corner with no repository or GitHub workflow.",
23898
24564
  "Work in this corner's writable workspace. Use write_scratch_file or ordinary tools to create files, then post_artifact with the path to send them back to the corner.",
@@ -23942,7 +24608,10 @@ var MonolithCornerTurnLoop = class {
23942
24608
  if (durableReplyText(result.agentText))
23943
24609
  return void 0;
23944
24610
  return explainEmptyAgentTurn({
23945
- agentLabel: this.options.config.agentCommand ?? this.options.config.agentBinary,
24611
+ agentLabel: harnessIdentityLabel({
24612
+ kind: this.options.config.agentKind,
24613
+ command: this.options.config.agentCommand ?? this.options.config.agentBinary
24614
+ }),
23946
24615
  agentEnv: this.agentEnv,
23947
24616
  sessionId: this.sessionId,
23948
24617
  result
@@ -24011,7 +24680,7 @@ var MonolithCornerTurnLoop = class {
24011
24680
  const [conversation, roster, delivered] = await trace.measure("context-fetch", () => Promise.all([
24012
24681
  api.execute("getRoomConversation", { roomId: cornerId, limit: 200 }),
24013
24682
  this.roster(),
24014
- this.attachmentDir && attachments.length ? deliverAttachments(attachments, join9(this.attachmentDir, requestId.replace(/[^\w-]/g, "_")), this.options.fetchImpl) : Promise.resolve([])
24683
+ this.attachmentDir && attachments.length ? deliverAttachments(attachments, join10(this.attachmentDir, requestId.replace(/[^\w-]/g, "_")), this.options.fetchImpl) : Promise.resolve([])
24015
24684
  ]));
24016
24685
  const names = new Map(roster.members.map((member) => [member.identityId, member.name]));
24017
24686
  const requestedBy = requester && !requester.name && names.get(requester.pubkey) ? { ...requester, name: names.get(requester.pubkey) } : requester;
@@ -24778,13 +25447,13 @@ function shouldPostInitialCornerWorkingState(restore, isOpener = true) {
24778
25447
  }
24779
25448
  async function materializeCornerWorktree(input) {
24780
25449
  const remote = roomCheckoutRemote(input.remote);
24781
- const repositoryHash = createHash6("sha256").update(remote).digest("hex").slice(0, 24);
24782
- const gitCommonDir = resolve20(input.supervisorRoot, "beeline", "repositories", `${repositoryHash}.git`);
24783
- const path = resolve20(input.supervisorRoot, "beeline", "corners", input.cornerId);
24784
- await mkdir13(dirname8(gitCommonDir), { recursive: true, mode: 448 });
24785
- await mkdir13(dirname8(path), { recursive: true, mode: 448 });
25450
+ const repositoryHash = createHash7("sha256").update(remote).digest("hex").slice(0, 24);
25451
+ const gitCommonDir = resolve21(input.supervisorRoot, "beeline", "repositories", `${repositoryHash}.git`);
25452
+ const path = resolve21(input.supervisorRoot, "beeline", "corners", input.cornerId);
25453
+ await mkdir13(dirname9(gitCommonDir), { recursive: true, mode: 448 });
25454
+ await mkdir13(dirname9(path), { recursive: true, mode: 448 });
24786
25455
  const authEnv = githubGitEnv(input.token);
24787
- if (!existsSync4(resolve20(gitCommonDir, "HEAD"))) {
25456
+ if (!existsSync5(resolve21(gitCommonDir, "HEAD"))) {
24788
25457
  await execFileAsync4("git", ["clone", "--bare", remote, gitCommonDir], {
24789
25458
  env: authEnv,
24790
25459
  maxBuffer: 4 * 1024 * 1024
@@ -24803,7 +25472,7 @@ async function materializeCornerWorktree(input) {
24803
25472
  "origin",
24804
25473
  `+refs/heads/${input.featureBranch}:refs/remotes/origin/${input.featureBranch}`
24805
25474
  ], { env: authEnv, maxBuffer: 4 * 1024 * 1024 }).then(() => true, () => false);
24806
- if (!existsSync4(resolve20(path, ".git"))) {
25475
+ if (!existsSync5(resolve21(path, ".git"))) {
24807
25476
  await rm5(path, { recursive: true, force: true });
24808
25477
  await execFileAsync4("git", [
24809
25478
  `--git-dir=${gitCommonDir}`,
@@ -24854,7 +25523,7 @@ async function materializeCornerWorktree(input) {
24854
25523
  `${input.committer.publicKey.slice(0, 16)}@users.noreply.github.com`
24855
25524
  ]);
24856
25525
  const top = await execFileAsync4("git", ["-C", path, "rev-parse", "--show-toplevel"]);
24857
- if (resolve20(top.stdout.trim()) !== resolve20(path)) {
25526
+ if (resolve21(top.stdout.trim()) !== resolve21(path)) {
24858
25527
  throw new Error(`corner worktree escaped its isolated root: ${top.stdout.trim()}`);
24859
25528
  }
24860
25529
  return { path, gitCommonDir };
@@ -24875,7 +25544,7 @@ async function mapWithConcurrency(values, limit, visit) {
24875
25544
  async function removeCornerWorktreeAndBranches(worktree) {
24876
25545
  const localRef = `refs/heads/${worktree.branch}`;
24877
25546
  const remoteRef = `refs/heads/${worktree.branch}`;
24878
- const worktreeExists = existsSync4(worktree.path);
25547
+ const worktreeExists = existsSync5(worktree.path);
24879
25548
  const localExists = await gitRefExists(worktree.gitCommonDir, localRef);
24880
25549
  if (worktreeExists) {
24881
25550
  const checkedOut = await execFileAsync4("git", [
@@ -24920,8 +25589,8 @@ async function removeCornerWorktreeAndBranches(worktree) {
24920
25589
  }
24921
25590
  var execFileAsync4 = promisify4(execFile6);
24922
25591
  async function removeCornerScratchWorkspace(input) {
24923
- const expected = resolve20(input.roomRoot, "scratch");
24924
- if (resolve20(input.scratchPath) !== expected) {
25592
+ const expected = resolve21(input.roomRoot, "scratch");
25593
+ if (resolve21(input.scratchPath) !== expected) {
24925
25594
  throw new Error(`refusing to remove scratch outside corner ${input.cornerId}`);
24926
25595
  }
24927
25596
  await rm5(expected, { recursive: true, force: true });
@@ -25135,14 +25804,14 @@ var RoomRuntimeCoordinator = class {
25135
25804
  return this.runtime.rooms.find((room) => room.channelId === roomId);
25136
25805
  }
25137
25806
  roomRoot(roomId) {
25138
- return this.roomRecord(roomId)?.root ?? resolve20(dirname8(this.configPath), "rooms", roomId);
25807
+ return this.roomRecord(roomId)?.root ?? resolve21(dirname9(this.configPath), "rooms", roomId);
25139
25808
  }
25140
25809
  roomAgentHomeRoot(workspaceRoot, required = false) {
25141
25810
  const flag = process.env.BUZZY_BODY_ROOM_HOME;
25142
25811
  if (!required && flag === "0")
25143
25812
  return void 0;
25144
- const home = resolve20(workspaceRoot, "agent-home");
25145
- if (!required && flag !== "1" && !existsSync4(home) && existsSync4(workspaceRoot))
25813
+ const home = resolve21(workspaceRoot, "agent-home");
25814
+ if (!required && flag !== "1" && !existsSync5(home) && existsSync5(workspaceRoot))
25146
25815
  return void 0;
25147
25816
  try {
25148
25817
  mkdirSync(home, { recursive: true, mode: 448 });
@@ -25157,10 +25826,10 @@ var RoomRuntimeCoordinator = class {
25157
25826
  return {
25158
25827
  ...this.baseConfig,
25159
25828
  workspaceRoot,
25160
- agentPrivateRoot: resolve20(workspaceRoot, "agent-private"),
25161
- agentMemoryRoot: resolve20(dirname8(this.configPath), "memory"),
25162
- openRouterRoutingCacheDir: openRouterRoutingCacheDir(dirname8(this.configPath)),
25163
- turnTraceDir: turnTraceDirectory(dirname8(this.configPath)),
25829
+ agentPrivateRoot: resolve21(workspaceRoot, "agent-private"),
25830
+ agentMemoryRoot: resolve21(dirname9(this.configPath), "memory"),
25831
+ openRouterRoutingCacheDir: openRouterRoutingCacheDir(dirname9(this.configPath)),
25832
+ turnTraceDir: turnTraceDirectory(dirname9(this.configPath)),
25164
25833
  ...agentHomeRoot ? { agentHomeRoot } : {}
25165
25834
  };
25166
25835
  }
@@ -25226,12 +25895,12 @@ var RoomRuntimeCoordinator = class {
25226
25895
  return this.roomRoot(roomId);
25227
25896
  const remote = roomCheckoutRemote(repository.remote);
25228
25897
  const targetBranch = repository.targetBranch || "main";
25229
- const checkoutId = createHash6("sha256").update(`${remote}\0${targetBranch}`).digest("hex").slice(0, 24);
25230
- const path = resolve20(this.runtime.supervisorRoot, "beeline", "room-checkouts", checkoutId);
25231
- await mkdir13(dirname8(path), { recursive: true, mode: 448 });
25898
+ const checkoutId = createHash7("sha256").update(`${remote}\0${targetBranch}`).digest("hex").slice(0, 24);
25899
+ const path = resolve21(this.runtime.supervisorRoot, "beeline", "room-checkouts", checkoutId);
25900
+ await mkdir13(dirname9(path), { recursive: true, mode: 448 });
25232
25901
  const token = remote.startsWith("https://github.com/") ? await this.options.daemonApi.execute("getRoomGitHubToken", { roomId }) : void 0;
25233
25902
  const env = token ? githubGitEnv(token.token) : process.env;
25234
- if (!existsSync4(resolve20(path, ".git"))) {
25903
+ if (!existsSync5(resolve21(path, ".git"))) {
25235
25904
  await execFileAsync4("git", ["clone", "--no-checkout", remote, path], {
25236
25905
  env,
25237
25906
  maxBuffer: 4 * 1024 * 1024
@@ -25284,7 +25953,7 @@ var RoomRuntimeCoordinator = class {
25284
25953
  featureBranch,
25285
25954
  token: granted.token
25286
25955
  }) : void 0;
25287
- const workspacePath = worktree?.path ?? resolve20(this.roomRoot(corner.cornerId), "scratch");
25956
+ const workspacePath = worktree?.path ?? resolve21(this.roomRoot(corner.cornerId), "scratch");
25288
25957
  if (!worktree)
25289
25958
  await mkdir13(workspacePath, { recursive: true, mode: 448 });
25290
25959
  const isOpener = !corner.openedBy || corner.openedBy === this.agent.publicKey;
@@ -25673,8 +26342,8 @@ var ThinDaemonCore = class {
25673
26342
  // apps/body/dist/systemd.js
25674
26343
  import { execFile as execFile7 } from "node:child_process";
25675
26344
  import { mkdir as mkdir14, readFile as readFile9, writeFile as writeFile9 } from "node:fs/promises";
25676
- import { homedir as homedir8 } from "node:os";
25677
- import { dirname as dirname9, resolve as resolve21 } from "node:path";
26345
+ import { homedir as homedir9 } from "node:os";
26346
+ import { dirname as dirname10, resolve as resolve22 } from "node:path";
25678
26347
  import { setTimeout as sleep } from "node:timers/promises";
25679
26348
  import { promisify as promisify5 } from "node:util";
25680
26349
  var execFileAsync5 = promisify5(execFile7);
@@ -25715,10 +26384,10 @@ WantedBy=default.target
25715
26384
  `;
25716
26385
  }
25717
26386
  function isCanonicalInstalledLauncher(env = process.env, invocationPath = process.argv[1]) {
25718
- const home = env.HOME?.trim() || homedir8();
25719
- const expectedLibDir = resolve21(home, ".local", "lib", "beeline");
26387
+ const home = env.HOME?.trim() || homedir9();
26388
+ const expectedLibDir = resolve22(home, ".local", "lib", "beeline");
25720
26389
  const expectedPrefix = `${expectedLibDir}/`;
25721
- return resolve21(env.BEELINE_LIB_DIR?.trim() || "/") === expectedLibDir && Boolean(invocationPath) && resolve21(invocationPath).startsWith(expectedPrefix);
26390
+ return resolve22(env.BEELINE_LIB_DIR?.trim() || "/") === expectedLibDir && Boolean(invocationPath) && resolve22(invocationPath).startsWith(expectedPrefix);
25722
26391
  }
25723
26392
  function assertCanonicalInstalledLauncher(env, invocationPath) {
25724
26393
  if (isCanonicalInstalledLauncher(env, invocationPath))
@@ -25726,8 +26395,8 @@ function assertCanonicalInstalledLauncher(env, invocationPath) {
25726
26395
  throw new Error("refusing to modify the shared Beeline systemd unit outside the canonical ~/.local/bin/beeline launcher");
25727
26396
  }
25728
26397
  function systemdUserUnitPath(env = process.env) {
25729
- const configRoot = env.XDG_CONFIG_HOME?.trim() || resolve21(homedir8(), ".config");
25730
- return resolve21(configRoot, "systemd", "user", SYSTEMD_UNIT_NAME);
26398
+ const configRoot = env.XDG_CONFIG_HOME?.trim() || resolve22(homedir9(), ".config");
26399
+ return resolve22(configRoot, "systemd", "user", SYSTEMD_UNIT_NAME);
25731
26400
  }
25732
26401
  var runSystemctl = async (args) => {
25733
26402
  const result = await execFileAsync5("systemctl", ["--user", ...args], {
@@ -25745,7 +26414,7 @@ async function installAgentService(publicKey, options = {}) {
25745
26414
  const content = agentServiceUnit();
25746
26415
  const existing = await readFile9(path, "utf8").catch(() => "");
25747
26416
  if (existing !== content) {
25748
- await mkdir14(dirname9(path), { recursive: true, mode: 448 });
26417
+ await mkdir14(dirname10(path), { recursive: true, mode: 448 });
25749
26418
  await writeFile9(path, content, { mode: 384 });
25750
26419
  }
25751
26420
  const run2 = options.run ?? runSystemctl;
@@ -25826,7 +26495,7 @@ async function retireRemovedAgent(runtime, options = {}) {
25826
26495
  }
25827
26496
 
25828
26497
  // apps/body/dist/start-command.js
25829
- import { dirname as dirname10 } from "node:path";
26498
+ import { dirname as dirname11 } from "node:path";
25830
26499
  var import_picocolors = __toESM(require_picocolors(), 1);
25831
26500
  var DEFAULT_RESTART_DRAIN_TIMEOUT_MS = 30 * 6e4;
25832
26501
  var RESTART_WAIT_REPORT_INTERVAL_MS = 3e4;
@@ -25901,7 +26570,7 @@ async function runStartCommand(args, interactiveUi) {
25901
26570
  continue;
25902
26571
  }
25903
26572
  const spinnerHandle = spinner();
25904
- spinnerHandle.start(`Starting ${dirname10(path)}\u2026`);
26573
+ spinnerHandle.start(`Starting ${dirname11(path)}\u2026`);
25905
26574
  try {
25906
26575
  await startRuntime(path, spinnerHandle);
25907
26576
  spinnerHandle.stop(import_picocolors.default.green("Started."));
@@ -25916,11 +26585,11 @@ async function runStartCommand(args, interactiveUi) {
25916
26585
  }
25917
26586
 
25918
26587
  // apps/body/dist/connect-command.js
25919
- import { spawn as spawn7 } from "node:child_process";
25920
- import { createHash as createHash8, randomUUID as randomUUID5 } from "node:crypto";
26588
+ import { spawn as spawn9 } from "node:child_process";
26589
+ import { createHash as createHash9, randomUUID as randomUUID6 } from "node:crypto";
25921
26590
  import { chmod as chmod6, mkdir as mkdir16, readFile as readFile11, unlink as unlink2, writeFile as writeFile11 } from "node:fs/promises";
25922
- import { homedir as homedir10, hostname } from "node:os";
25923
- import { dirname as dirname12, resolve as resolve23 } from "node:path";
26591
+ import { homedir as homedir11, hostname as hostname2 } from "node:os";
26592
+ import { dirname as dirname13, resolve as resolve24 } from "node:path";
25924
26593
  import { stdin as stdin3, stdout as stdout4 } from "node:process";
25925
26594
 
25926
26595
  // apps/body/dist/clack-support.js
@@ -26004,7 +26673,7 @@ async function verifyProviderKey(input) {
26004
26673
  }
26005
26674
 
26006
26675
  // apps/body/dist/pair-agent-selection.js
26007
- import { spawn as spawn5 } from "node:child_process";
26676
+ import { spawn as spawn7 } from "node:child_process";
26008
26677
  import { stdin as stdin2, stdout as stdout3 } from "node:process";
26009
26678
  var NO_AGENT_MESSAGE = `No supported ACP-capable coding agent was detected.
26010
26679
  Install one of these supported agents:
@@ -26013,7 +26682,7 @@ Install one of these supported agents:
26013
26682
  goose https://block.github.io/goose/docs/getting-started/installation/
26014
26683
  pi npm install -g @mariozechner/pi-coding-agent pi-acp
26015
26684
  grok curl -fsSL https://x.ai/cli/install.sh | bash
26016
- cursor npm install -g cursor-agent-acp
26685
+ cursor Install Cursor Agent CLI from https://cursor.com/docs/cli
26017
26686
  Then retry, or explicitly use \`--agent reference\` with an LLM key.
26018
26687
  For another ACP server, use \`--agent custom --agent-command "<cmd> [args...]"\`.`;
26019
26688
  async function clackConfirmInstall(message) {
@@ -26033,7 +26702,7 @@ async function clackSelectAgent(candidates) {
26033
26702
  }
26034
26703
  async function installAdapter(install, opts) {
26035
26704
  await new Promise((resolveInstall, rejectInstall) => {
26036
- const child = spawn5(install.command, install.args, {
26705
+ const child = spawn7(install.command, install.args, {
26037
26706
  cwd: opts.cwd,
26038
26707
  env: opts.env ?? process.env,
26039
26708
  stdio: "inherit"
@@ -26253,7 +26922,9 @@ var DEFAULT_MODELS = {
26253
26922
  codex: "gpt-5.4",
26254
26923
  claude: "claude-opus-4-1",
26255
26924
  grok: "grok-4",
26256
- cursor: "claude-sonnet-4"
26925
+ // cursor-agent's own default; always served, and the only model safe to
26926
+ // assume before `cursor-agent models` has been read.
26927
+ cursor: "auto"
26257
26928
  };
26258
26929
  function connectHarnessNeedsProvider(harness) {
26259
26930
  return CONNECT_PROVIDER_HARNESSES.has(harness);
@@ -26351,8 +27022,14 @@ async function loadConnectModelCatalog(input) {
26351
27022
  model
26352
27023
  }), input.model ? { model: input.model } : void 0, input.timeoutMs === void 0 ? {} : { timeoutMs: input.timeoutMs });
26353
27024
  const effort = connectEffortPickerFromAxes(catalog.catalog, catalog.raw);
27025
+ const picker = connectModelPickerFromAxes(catalog.catalog, defaultConnectModel(input.harness, input.provider), input.harness, catalog.raw);
27026
+ if (input.harness === "cursor" && !catalog.catalog.some((axis) => axis.category === "model" && axis.options.length) && !catalog.raw.some((axis) => axis.category === "model" && axis.options.length)) {
27027
+ const cliModels = await enumerateCursorModels();
27028
+ if (cliModels)
27029
+ return { ...cliModels, ...effort ? { effort } : {} };
27030
+ }
26354
27031
  return {
26355
- ...connectModelPickerFromAxes(catalog.catalog, defaultConnectModel(input.harness, input.provider), input.harness, catalog.raw),
27032
+ ...picker,
26356
27033
  ...effort ? { effort } : {}
26357
27034
  };
26358
27035
  }
@@ -26536,23 +27213,23 @@ function parseConnectSubscriptions(value) {
26536
27213
  ];
26537
27214
  }
26538
27215
  async function readMachineId(env = process.env) {
26539
- const configDir = resolve23(env.XDG_CONFIG_HOME ?? resolve23(homedir10(), ".config"), "beeline");
26540
- const machineIdPath = resolve23(configDir, "machine-id");
27216
+ const configDir = resolve24(env.XDG_CONFIG_HOME ?? resolve24(homedir11(), ".config"), "beeline");
27217
+ const machineIdPath = resolve24(configDir, "machine-id");
26541
27218
  let machineId;
26542
- let machineName = hostname();
27219
+ let machineName = hostname2();
26543
27220
  try {
26544
27221
  const existing = await readFile11(machineIdPath, "utf8");
26545
27222
  machineId = existing.trim();
26546
27223
  if (!/^[0-9a-f-]{32,}$/.test(machineId))
26547
27224
  throw new Error("invalid persisted machine id");
26548
27225
  } catch {
26549
- machineId = randomUUID5();
27226
+ machineId = randomUUID6();
26550
27227
  try {
26551
27228
  await mkdir16(configDir, { recursive: true, mode: 448 });
26552
27229
  await writeFile11(machineIdPath, `${machineId}
26553
27230
  `, { mode: 384 });
26554
27231
  } catch {
26555
- machineId = createHash8("sha256").update(machineName).digest("hex").slice(0, 36);
27232
+ machineId = createHash9("sha256").update(machineName).digest("hex").slice(0, 36);
26556
27233
  }
26557
27234
  }
26558
27235
  return { machineId, machineName };
@@ -26561,7 +27238,7 @@ function requestConnectGrant(baseUrl, pairingCode, selection, fetchImpl, machine
26561
27238
  const normalizedPairingCode = normalizeAgentPairingCode(pairingCode);
26562
27239
  if (!normalizedPairingCode)
26563
27240
  throw new Error("invalid pairing code");
26564
- const avatarSeed = createHash8("sha256").update(normalizedPairingCode.toUpperCase()).digest("hex").slice(0, 32);
27241
+ const avatarSeed = createHash9("sha256").update(normalizedPairingCode.toUpperCase()).digest("hex").slice(0, 32);
26565
27242
  return jsonRequest(`${baseUrl}/auth/agent/connect`, {
26566
27243
  pairing_code: normalizedPairingCode,
26567
27244
  harness: selection.harness,
@@ -26610,7 +27287,7 @@ async function installCurrentRelease(fetchImpl) {
26610
27287
  });
26611
27288
  await activateRelease(layout, releaseId);
26612
27289
  return {
26613
- binary: resolve23(layout.binDir, "beeline"),
27290
+ binary: resolve24(layout.binDir, "beeline"),
26614
27291
  version: published.version ?? releaseId
26615
27292
  };
26616
27293
  }
@@ -26633,7 +27310,7 @@ function providerEnvironment(selection) {
26633
27310
  };
26634
27311
  }
26635
27312
  async function writePrivateJson(path, value) {
26636
- await mkdir16(dirname12(path), { recursive: true, mode: 448 });
27313
+ await mkdir16(dirname13(path), { recursive: true, mode: 448 });
26637
27314
  await writeFile11(path, `${JSON.stringify(value, null, 2)}
26638
27315
  `, { mode: 384 });
26639
27316
  await chmod6(path, 384);
@@ -26642,8 +27319,8 @@ async function writeProviderEnv(selection, agentPubkey) {
26642
27319
  const values = providerEnvironment(selection);
26643
27320
  if (Object.keys(values).length === 0)
26644
27321
  return void 0;
26645
- const path = resolve23(defaultSupervisorRoot(process.env), "beeline", "connect", `${agentPubkey}.env`);
26646
- await mkdir16(dirname12(path), { recursive: true, mode: 448 });
27322
+ const path = resolve24(defaultSupervisorRoot(process.env), "beeline", "connect", `${agentPubkey}.env`);
27323
+ await mkdir16(dirname13(path), { recursive: true, mode: 448 });
26647
27324
  const contents = Object.entries(values).map(([key, value]) => `${key}=${JSON.stringify(value)}`).join("\n");
26648
27325
  await writeFile11(path, `${contents}
26649
27326
  `, { mode: 384 });
@@ -26652,7 +27329,7 @@ async function writeProviderEnv(selection, agentPubkey) {
26652
27329
  }
26653
27330
  async function runInstalledFinish(binary, grantPath) {
26654
27331
  await new Promise((resolveRun, rejectRun) => {
26655
- const child = spawn7(binary, ["connect-finish", grantPath], {
27332
+ const child = spawn9(binary, ["connect-finish", grantPath], {
26656
27333
  stdio: ["ignore", "pipe", "pipe"]
26657
27334
  });
26658
27335
  let diagnostic = "";
@@ -26709,7 +27386,7 @@ async function runConnectWizard(code, fetchImpl, eventSubscriptions, accessPolic
26709
27386
  await finishConnectedAgentPairing(baseUrl, pairingCode, grant.workspace_joined, eventSubscriptions, fetchImpl);
26710
27387
  const installedRelease = await brassSpinner("Installing the Beeline daemon\u2026", () => installCurrentRelease(fetchImpl), (release) => `Installed Beeline helper ${release.version}`);
26711
27388
  const llmEnvFile = await writeProviderEnv(selection, grant.agent_pubkey);
26712
- const grantPath = resolve23(defaultSupervisorRoot(process.env), "beeline", "connect", `grant-${process.pid}-${Date.now()}.json`);
27389
+ const grantPath = resolve24(defaultSupervisorRoot(process.env), "beeline", "connect", `grant-${process.pid}-${Date.now()}.json`);
26713
27390
  await writePrivateJson(grantPath, {
26714
27391
  agentSecretKey: grant.agent_secret_key,
26715
27392
  bodySecretKey: grant.body_secret_key,
@@ -26794,18 +27471,18 @@ async function runConnectFinishCommand(path) {
26794
27471
  throw new Error("connect-finish may run only from the canonical installed Beeline launcher");
26795
27472
  }
26796
27473
  try {
26797
- const grant = JSON.parse(await readFile11(resolve23(path), "utf8"));
27474
+ const grant = JSON.parse(await readFile11(resolve24(path), "utf8"));
26798
27475
  if (!isDevicePairingGrant(grant))
26799
27476
  throw new Error("device connection grant is invalid");
26800
27477
  const connected = await completeDevicePairing(grant);
26801
- await unlink2(resolve23(path));
27478
+ await unlink2(resolve24(path));
26802
27479
  const providerEnv = grant.llmEnvFile ? await readFile11(grant.llmEnvFile, "utf8").catch(() => "") : "";
26803
27480
  const apiKey = (/^OPENROUTER_API_KEY=(\S+)/m.exec(providerEnv)?.[1] ?? "").replace(/^["']|["']$/g, "");
26804
27481
  const model = openRouterModelId(grant.model, { OPENROUTER_API_KEY: apiKey });
26805
27482
  if (model) {
26806
27483
  const decision2 = await resolveOpenRouterRouting({
26807
27484
  model,
26808
- cacheDir: openRouterRoutingCacheDir(dirname12(connected.configPath)),
27485
+ cacheDir: openRouterRoutingCacheDir(dirname13(connected.configPath)),
26809
27486
  ...apiKey ? { apiKey } : {},
26810
27487
  probeTimeoutMs: 1e4
26811
27488
  });
@@ -26826,22 +27503,22 @@ init_self_update_manifest();
26826
27503
 
26827
27504
  // apps/body/dist/managed-update.js
26828
27505
  init_self_update();
26829
- import { spawn as spawn8 } from "node:child_process";
27506
+ import { spawn as spawn10 } from "node:child_process";
26830
27507
  import { mkdir as mkdir18, rm as rm7, stat as stat3, writeFile as writeFile13 } from "node:fs/promises";
26831
- import { dirname as dirname14, resolve as resolve25 } from "node:path";
27508
+ import { dirname as dirname15, resolve as resolve26 } from "node:path";
26832
27509
 
26833
27510
  // apps/body/dist/update-rollback-alert.js
26834
27511
  import { mkdir as mkdir17, readFile as readFile12, rename as rename5, unlink as unlink3, writeFile as writeFile12 } from "node:fs/promises";
26835
- import { dirname as dirname13, resolve as resolve24 } from "node:path";
27512
+ import { dirname as dirname14, resolve as resolve25 } from "node:path";
26836
27513
  var REPORT_INTERVAL_MS = 60 * 60 * 1e3;
26837
27514
  var lastLogged = /* @__PURE__ */ new Map();
26838
27515
  function updateRollbackAlertPath(runtimeDir) {
26839
- return resolve24(runtimeDir, "update-rollback-alert.json");
27516
+ return resolve25(runtimeDir, "update-rollback-alert.json");
26840
27517
  }
26841
27518
  async function writeAlert(runtimeDir, alert) {
26842
27519
  const path = updateRollbackAlertPath(runtimeDir);
26843
27520
  const staged = `${path}.${process.pid}.tmp`;
26844
- await mkdir17(dirname13(path), { recursive: true });
27521
+ await mkdir17(dirname14(path), { recursive: true });
26845
27522
  await writeFile12(staged, `${JSON.stringify(alert, null, 2)}
26846
27523
  `, { mode: 384 });
26847
27524
  await rename5(staged, path);
@@ -26905,13 +27582,13 @@ var LOCK_STALE_MS = UPDATE_WORKER_DEADLINE_MS + 5 * 6e4;
26905
27582
  var DEFAULT_UPDATE_INITIAL_DELAY_MS = 0;
26906
27583
  async function withInstallLock(layout, work, options = {}) {
26907
27584
  const now2 = options.now ?? Date.now;
26908
- const lock = resolve25(layout.releasesRoot, ".state", "install.lock");
27585
+ const lock = resolve26(layout.releasesRoot, ".state", "install.lock");
26909
27586
  const deadline = now2() + (options.waitMs ?? 1e4);
26910
- await mkdir18(dirname14(lock), { recursive: true });
27587
+ await mkdir18(dirname15(lock), { recursive: true });
26911
27588
  for (; ; ) {
26912
27589
  try {
26913
27590
  await mkdir18(lock);
26914
- await writeFile13(resolve25(lock, "owner"), `${process.pid}
27591
+ await writeFile13(resolve26(lock, "owner"), `${process.pid}
26915
27592
  ${now2()}
26916
27593
  `, "utf8");
26917
27594
  break;
@@ -27034,7 +27711,7 @@ var ManagedUpdateHandoff = class _ManagedUpdateHandoff {
27034
27711
  if (!attempt || attempt.releaseId !== desiredRelease || attempt.status !== "pending") {
27035
27712
  const from = await readInstalledBundleIdentity({
27036
27713
  ...this.#layout,
27037
- libDir: resolve25(this.#layout.releasesRoot, this.#loadedRelease)
27714
+ libDir: resolve26(this.#layout.releasesRoot, this.#loadedRelease)
27038
27715
  }).catch(() => void 0) ?? {};
27039
27716
  const to = await readInstalledBundleIdentity(this.#layout).catch(() => void 0) ?? {};
27040
27717
  const record3 = {
@@ -27240,7 +27917,7 @@ async function runManagedUpdateWorkerProcess() {
27240
27917
  if (!entrypoint)
27241
27918
  throw new Error("cannot resolve the current Beeline entrypoint");
27242
27919
  await new Promise((resolveWorker, rejectWorker) => {
27243
- const child = spawn8(process.execPath, [entrypoint, "managed-update-worker"], {
27920
+ const child = spawn10(process.execPath, [entrypoint, "managed-update-worker"], {
27244
27921
  detached: true,
27245
27922
  env: { ...process.env, BEELINE_INTERNAL_UPDATE_WORKER: "1" },
27246
27923
  stdio: ["ignore", "pipe", "pipe"]
@@ -27321,7 +27998,7 @@ async function proveLoadedReleaseReady(layout, runtimeDir, loadedRelease, option
27321
27998
  });
27322
27999
  if (!accepted)
27323
28000
  return false;
27324
- await writeFile13(resolve25(runtimeDir, "daemon-ready.json"), `${JSON.stringify({
28001
+ await writeFile13(resolve26(runtimeDir, "daemon-ready.json"), `${JSON.stringify({
27325
28002
  readyAt: (options.now ?? Date.now)(),
27326
28003
  loadedRelease,
27327
28004
  functionalProof: options.functionalProof
@@ -27550,11 +28227,11 @@ init_self_update();
27550
28227
 
27551
28228
  // apps/body/dist/daemon-failure.js
27552
28229
  import { mkdir as mkdir19, readFile as readFile13, rename as rename6, rm as rm8, writeFile as writeFile14 } from "node:fs/promises";
27553
- import { dirname as dirname15, resolve as resolve26 } from "node:path";
28230
+ import { dirname as dirname16, resolve as resolve27 } from "node:path";
27554
28231
  var DAEMON_FAILURE_LIMIT = 3;
27555
28232
  var DAEMON_FAILURE_WINDOW_MS = 5 * 6e4;
27556
28233
  function daemonFailurePath(runtimeDir) {
27557
- return resolve26(runtimeDir, "daemon-distress.json");
28234
+ return resolve27(runtimeDir, "daemon-distress.json");
27558
28235
  }
27559
28236
  async function readFailureRecord(runtimeDir) {
27560
28237
  try {
@@ -27570,7 +28247,7 @@ async function readFailureRecord(runtimeDir) {
27570
28247
  async function writeFailureRecord(runtimeDir, record3) {
27571
28248
  const path = daemonFailurePath(runtimeDir);
27572
28249
  const staged = `${path}.${process.pid}.tmp`;
27573
- await mkdir19(dirname15(path), { recursive: true, mode: 448 });
28250
+ await mkdir19(dirname16(path), { recursive: true, mode: 448 });
27574
28251
  await writeFile14(staged, `${JSON.stringify(record3, null, 2)}
27575
28252
  `, { mode: 384 });
27576
28253
  await rename6(staged, path);
@@ -27594,8 +28271,8 @@ async function clearDaemonStartFailures(runtimeDir) {
27594
28271
 
27595
28272
  // apps/body/dist/update-functional-probe.js
27596
28273
  import { mkdir as mkdir20, rm as rm9 } from "node:fs/promises";
27597
- import { homedir as homedir11 } from "node:os";
27598
- import { resolve as resolve27 } from "node:path";
28274
+ import { homedir as homedir12 } from "node:os";
28275
+ import { resolve as resolve28 } from "node:path";
27599
28276
  var UPDATE_PROBE_SESSION_TIMEOUT_MS = 1e4;
27600
28277
  var UPDATE_PROBE_SESSION_OPEN_TIMEOUT_MS = 2e4;
27601
28278
  var UPDATE_PROBE_TURN_TIMEOUT_MS = 45e3;
@@ -27662,6 +28339,10 @@ function describeCurrentReleaseOutcome(outcome) {
27662
28339
  }
27663
28340
  async function runUpdateFunctionalProbe(input) {
27664
28341
  const command = input.config.agentCommand ?? input.config.agentBinary;
28342
+ const harnessLabel = harnessIdentityLabel({
28343
+ kind: input.config.agentKind,
28344
+ command
28345
+ });
27665
28346
  const harness = input.config.agentKind ?? command;
27666
28347
  if (input.config.modelUnavailable) {
27667
28348
  throw new UpdateFunctionalProbeError("model-unavailable", input.config.modelUnavailable.detail);
@@ -27689,9 +28370,9 @@ async function runUpdateFunctionalProbe(input) {
27689
28370
  modelAnswerReason: `${detail} (the current release has the same host sandbox failure)`
27690
28371
  };
27691
28372
  }
27692
- const root = input.probeRoot ?? resolve27(input.runtimeDir, "update-functional-probe");
27693
- const cwd = resolve27(root, "checkout");
27694
- const homeRoot = resolve27(root, "agent-home");
28373
+ const root = input.probeRoot ?? resolve28(input.runtimeDir, "update-functional-probe");
28374
+ const cwd = resolve28(root, "checkout");
28375
+ const homeRoot = resolve28(root, "agent-home");
27695
28376
  await rm9(root, { recursive: true, force: true });
27696
28377
  await mkdir20(cwd, { recursive: true, mode: 448 });
27697
28378
  let client;
@@ -27700,7 +28381,7 @@ async function runUpdateFunctionalProbe(input) {
27700
28381
  ...input.config.agentEnv,
27701
28382
  ...await prepareRoomAgentHome({
27702
28383
  root: homeRoot,
27703
- operatorHome: input.config.operatorHome ?? homedir11(),
28384
+ operatorHome: input.config.operatorHome ?? homedir12(),
27704
28385
  sharedSkills: input.config.sharedSkills ?? [],
27705
28386
  ...input.config.agentKind ? { agentKind: input.config.agentKind } : {},
27706
28387
  skillReleaseId: input.releaseId,
@@ -27721,8 +28402,8 @@ async function runUpdateFunctionalProbe(input) {
27721
28402
  let turnCompleted = true;
27722
28403
  if (input.config.bwrapPath) {
27723
28404
  const { stateDirs, tmpDir } = harnessStateDirsFromEnv(agentEnv);
27724
- const operatorHome = input.config.operatorHome ?? homedir11();
27725
- const homeStateDirs = harnessHomeStateDirs(command, agentEnv.HOME ?? operatorHome);
28405
+ const operatorHome = input.config.operatorHome ?? homedir12();
28406
+ const homeStateDirs = harnessHomeStateDirs(harnessLabel, agentEnv.HOME ?? operatorHome);
27726
28407
  await Promise.all(homeStateDirs.map((dir) => mkdir20(dir, { recursive: true })));
27727
28408
  spawnCommand = wrapAgentCommand({
27728
28409
  bwrapPath: input.config.bwrapPath,
@@ -27741,7 +28422,7 @@ async function runUpdateFunctionalProbe(input) {
27741
28422
  client = new AcpClient({
27742
28423
  agentCommand: spawnCommand.command,
27743
28424
  agentArgs: spawnCommand.args,
27744
- agentLabel: command,
28425
+ agentLabel: harnessLabel,
27745
28426
  agentEnv,
27746
28427
  agentCwd: cwd,
27747
28428
  autoApprovePermissions: true
@@ -27772,7 +28453,7 @@ async function runUpdateFunctionalProbe(input) {
27772
28453
  modelAnswer = { modelAnswer: "served" };
27773
28454
  } else {
27774
28455
  const explained = await explainEmptyAgentTurn({
27775
- agentLabel: command,
28456
+ agentLabel: harnessLabel,
27776
28457
  agentEnv,
27777
28458
  sessionId,
27778
28459
  result: served
@@ -27872,8 +28553,8 @@ async function runUpdateFunctionalProbe(input) {
27872
28553
  }
27873
28554
 
27874
28555
  // apps/body/dist/current-release-probe.js
27875
- import { spawn as spawn9 } from "node:child_process";
27876
- import { dirname as dirname16, join as join11 } from "node:path";
28556
+ import { spawn as spawn11 } from "node:child_process";
28557
+ import { dirname as dirname17, join as join12 } from "node:path";
27877
28558
  init_self_update();
27878
28559
  var CURRENT_RELEASE_PROBE_TIMEOUT_MS = 12e4;
27879
28560
  var UPDATE_PROBE_COMMAND = "update-probe";
@@ -27916,14 +28597,14 @@ function outcomeFromReport(report) {
27916
28597
  }
27917
28598
  }
27918
28599
  async function probeReleaseInSubprocess(input) {
27919
- const bundleDir = join11(input.layout.releasesRoot, input.releaseId);
28600
+ const bundleDir = join12(input.layout.releasesRoot, input.releaseId);
27920
28601
  const entrypoint = await resolveBundleEntrypoint(bundleDir);
27921
28602
  if (!entrypoint) {
27922
28603
  return { kind: "unavailable", reason: `release ${input.releaseId} has no runnable CLI entrypoint` };
27923
28604
  }
27924
28605
  const timeoutMs = input.timeoutMs ?? CURRENT_RELEASE_PROBE_TIMEOUT_MS;
27925
- return new Promise((resolve31) => {
27926
- const child = spawn9(input.execPath ?? process.execPath, [entrypoint, UPDATE_PROBE_COMMAND, "--config", input.runtimeConfigPath], { env: input.env ?? process.env, stdio: ["ignore", "pipe", "pipe"] });
28606
+ return new Promise((resolve32) => {
28607
+ const child = spawn11(input.execPath ?? process.execPath, [entrypoint, UPDATE_PROBE_COMMAND, "--config", input.runtimeConfigPath], { env: input.env ?? process.env, stdio: ["ignore", "pipe", "pipe"] });
27927
28608
  let stdout6 = "";
27928
28609
  let stderr = "";
27929
28610
  let settled = false;
@@ -27932,7 +28613,7 @@ async function probeReleaseInSubprocess(input) {
27932
28613
  return;
27933
28614
  settled = true;
27934
28615
  clearTimeout(timer);
27935
- resolve31(outcome);
28616
+ resolve32(outcome);
27936
28617
  };
27937
28618
  const timer = setTimeout(() => {
27938
28619
  child.kill("SIGKILL");
@@ -27979,7 +28660,7 @@ async function runUpdateProbeCommand(args, options = {}) {
27979
28660
  const runtime = await readRuntimeRecord(configPath);
27980
28661
  const agent = runtimeAgentCommand(runtime);
27981
28662
  const config = loadBodyConfig({
27982
- workspaceRoot: join11(dirname16(configPath), "workspace"),
28663
+ workspaceRoot: join12(dirname17(configPath), "workspace"),
27983
28664
  llmEnvFile: runtime.llmEnvFile,
27984
28665
  env: { ...env, BUZZ_AGENT_BIN: agent.command, BUZZ_DEV_MCP_BIN: runtime.mcpBinary },
27985
28666
  agent
@@ -27997,7 +28678,7 @@ async function runUpdateProbeCommand(args, options = {}) {
27997
28678
  }
27998
28679
  const layout = beelineInstallLayout(env);
27999
28680
  const releaseId = (layout && await activeReleaseId(layout).catch(() => void 0)) ?? "unknown";
28000
- const runtimeDir = dirname16(configPath);
28681
+ const runtimeDir = dirname17(configPath);
28001
28682
  const outcome = await probeOutcome(() => (options.probe ?? runUpdateFunctionalProbe)({
28002
28683
  config,
28003
28684
  runtimeDir,
@@ -28005,7 +28686,7 @@ async function runUpdateProbeCommand(args, options = {}) {
28005
28686
  sandboxRequired: runtime.sandbox !== "off",
28006
28687
  sandboxUnavailableDetail: sandbox.advisory,
28007
28688
  // The successor's probe still holds `<runtimeDir>/update-functional-probe`.
28008
- probeRoot: join11(runtimeDir, "current-release-probe")
28689
+ probeRoot: join12(runtimeDir, "current-release-probe")
28009
28690
  }));
28010
28691
  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 };
28011
28692
  write(JSON.stringify(report));
@@ -28013,7 +28694,7 @@ async function runUpdateProbeCommand(args, options = {}) {
28013
28694
 
28014
28695
  // apps/body/dist/release-status.js
28015
28696
  import { readFile as readFile14, readdir as readdir6, rename as rename7, writeFile as writeFile15 } from "node:fs/promises";
28016
- import { resolve as resolve28 } from "node:path";
28697
+ import { resolve as resolve29 } from "node:path";
28017
28698
  var DAEMON_RELEASE_STATUS_FILE = "release-status.json";
28018
28699
  var RELEASE_VERSION = /^v\d+\.\d+\.\d+$/;
28019
28700
  var SOURCE_SHA = /^[0-9a-f]{7,64}$/;
@@ -28030,7 +28711,7 @@ async function writeDaemonReleaseStatus(runtimeDir, agentPubkey, identity, optio
28030
28711
  pid: options.pid ?? process.pid,
28031
28712
  readyAt: (options.now?.() ?? /* @__PURE__ */ new Date()).toISOString()
28032
28713
  };
28033
- const target = resolve28(runtimeDir, DAEMON_RELEASE_STATUS_FILE);
28714
+ const target = resolve29(runtimeDir, DAEMON_RELEASE_STATUS_FILE);
28034
28715
  const temporary = `${target}.${status.pid}.tmp`;
28035
28716
  await writeFile15(temporary, `${JSON.stringify(status, null, 2)}
28036
28717
  `, { mode: 384 });
@@ -28040,7 +28721,7 @@ async function writeDaemonReleaseStatus(runtimeDir, agentPubkey, identity, optio
28040
28721
 
28041
28722
  // apps/body/dist/scratch-sweep.js
28042
28723
  import { lstat as lstat4, readdir as readdir7, rmdir, unlink as unlink4 } from "node:fs/promises";
28043
- import { resolve as resolve29 } from "node:path";
28724
+ import { resolve as resolve30 } from "node:path";
28044
28725
  var DEFAULT_SCRATCH_TTL_HOURS = 72;
28045
28726
  var NEVER_SWEEP_SUBDIR_NAMES = new Set(HOME_SUBDIRS.filter((name) => name !== "tmp"));
28046
28727
  function scratchTtlMs(env = process.env) {
@@ -28049,7 +28730,7 @@ function scratchTtlMs(env = process.env) {
28049
28730
  return (Number.isFinite(hours) && hours > 0 ? hours : DEFAULT_SCRATCH_TTL_HOURS) * 60 * 60 * 1e3;
28050
28731
  }
28051
28732
  async function discoverAttachScratchRoots(runtimeDir) {
28052
- const roomsDir = resolve29(runtimeDir, "rooms");
28733
+ const roomsDir = resolve30(runtimeDir, "rooms");
28053
28734
  let entries;
28054
28735
  try {
28055
28736
  entries = await readdir7(roomsDir, { withFileTypes: true });
@@ -28060,7 +28741,7 @@ async function discoverAttachScratchRoots(runtimeDir) {
28060
28741
  for (const entry of entries) {
28061
28742
  if (!entry.isDirectory())
28062
28743
  continue;
28063
- const home = resolve29(roomsDir, entry.name, "agent-home");
28744
+ const home = resolve30(roomsDir, entry.name, "agent-home");
28064
28745
  const stats = await lstat4(home).catch(() => void 0);
28065
28746
  if (stats?.isDirectory())
28066
28747
  roots.push(home);
@@ -28079,7 +28760,7 @@ async function removeStaleFiles(dir, cutoffMs, protectNamesHere) {
28079
28760
  for (const entry of entries) {
28080
28761
  if (protectNamesHere && NEVER_SWEEP_SUBDIR_NAMES.has(entry.name))
28081
28762
  continue;
28082
- const path = resolve29(dir, entry.name);
28763
+ const path = resolve30(dir, entry.name);
28083
28764
  const stats = await lstat4(path).catch(() => void 0);
28084
28765
  if (!stats || stats.isSymbolicLink())
28085
28766
  continue;
@@ -28166,7 +28847,7 @@ var DaemonExitError = class extends Error {
28166
28847
  };
28167
28848
  async function runStoredDaemon(pathOrPointer) {
28168
28849
  const configPath = await resolveRuntimeConfigPath(pathOrPointer);
28169
- daemonFailureRuntimeDir = dirname17(configPath);
28850
+ daemonFailureRuntimeDir = dirname18(configPath);
28170
28851
  const accessMigration = await migrateRuntimeRecordAccessPolicy(configPath);
28171
28852
  let runtime = accessMigration.runtime;
28172
28853
  if (!runtime.transport) {
@@ -28178,7 +28859,7 @@ async function runStoredDaemon(pathOrPointer) {
28178
28859
  runtime = activated.runtime;
28179
28860
  const daemonApi = activated.client;
28180
28861
  const agent = runtimeAgentCommand(runtime);
28181
- await writeFile16(resolve30(dirname17(configPath), "daemon.pid"), `${process.pid}
28862
+ await writeFile16(resolve31(dirname18(configPath), "daemon.pid"), `${process.pid}
28182
28863
  `, { mode: 384 });
28183
28864
  const env = {
28184
28865
  ...process.env,
@@ -28186,7 +28867,7 @@ async function runStoredDaemon(pathOrPointer) {
28186
28867
  BUZZ_DEV_MCP_BIN: runtime.mcpBinary
28187
28868
  };
28188
28869
  const config = loadBodyConfig({
28189
- workspaceRoot: resolve30(dirname17(configPath), "workspace"),
28870
+ workspaceRoot: resolve31(dirname18(configPath), "workspace"),
28190
28871
  llmEnvFile: runtime.llmEnvFile,
28191
28872
  env,
28192
28873
  agent
@@ -28221,7 +28902,7 @@ async function runStoredDaemon(pathOrPointer) {
28221
28902
  const stop = () => controller.abort();
28222
28903
  process.once("SIGINT", stop);
28223
28904
  process.once("SIGTERM", stop);
28224
- const runtimeDir = dirname17(configPath);
28905
+ const runtimeDir = dirname18(configPath);
28225
28906
  const layout = beelineInstallLayout(process.env);
28226
28907
  const notifier = new SystemdNotifier();
28227
28908
  let rollbackAlertDrain;
@@ -28377,7 +29058,7 @@ async function runStoredDaemon(pathOrPointer) {
28377
29058
  } finally {
28378
29059
  clearInterval(scratchSweepTimer);
28379
29060
  await notifier.stopping(stoppingStatus).catch(() => void 0);
28380
- const pidPath = resolve30(dirname17(configPath), "daemon.pid");
29061
+ const pidPath = resolve31(dirname18(configPath), "daemon.pid");
28381
29062
  const recorded = Number((await readFile15(pidPath, "utf8").catch(() => "")).trim());
28382
29063
  if (recorded === process.pid) {
28383
29064
  await unlink5(pidPath).catch(() => void 0);
@@ -28389,6 +29070,10 @@ async function main() {
28389
29070
  if (args.length === 0)
28390
29071
  usage();
28391
29072
  const command = args[0];
29073
+ if (command === CURSOR_ACP_BRIDGE_FLAG) {
29074
+ await runCursorAcpStdioServer();
29075
+ return;
29076
+ }
28392
29077
  if (command === "--help" || command === "-h")
28393
29078
  usage(0);
28394
29079
  if (command === "managed-update-worker") {
@@ -28405,7 +29090,7 @@ async function main() {
28405
29090
  const roomId = roomFlag >= 0 ? args[roomFlag + 1] : void 0;
28406
29091
  if (!configPath || !roomId)
28407
29092
  throw new Error("corner-read-token requires --config and --room");
28408
- const activated = await activateDaemonTransport(resolve30(configPath));
29093
+ const activated = await activateDaemonTransport(resolve31(configPath));
28409
29094
  if (!activated)
28410
29095
  throw new Error("corner-read-token requires monolith transport");
28411
29096
  const credential = await activated.client.execute("getRoomGitHubToken", { roomId });
@@ -28454,14 +29139,14 @@ async function main() {
28454
29139
  const agentPubkey = agentFlag >= 0 ? args[agentFlag + 1] : void 0;
28455
29140
  if (!configPath && agentPubkey) {
28456
29141
  const configs = await findAgentRuntimeConfigPaths(process.env, process.cwd());
28457
- configPath = configs.find((candidate) => dirname17(candidate).endsWith(agentPubkey));
29142
+ configPath = configs.find((candidate) => dirname18(candidate).endsWith(agentPubkey));
28458
29143
  }
28459
29144
  if (!configPath && agentPubkey) {
28460
29145
  throw new DaemonExitError(`unknown agent ${agentPubkey}: no durable runtime exists; refusing systemd restart loop`, UNKNOWN_AGENT_EXIT_STATUS);
28461
29146
  }
28462
29147
  if (!configPath)
28463
29148
  throw new Error("daemon requires --config <runtime.json> or --agent <pubkey>");
28464
- await runStoredDaemon(resolve30(configPath));
29149
+ await runStoredDaemon(resolve31(configPath));
28465
29150
  return;
28466
29151
  }
28467
29152
  if (command === "update") {
@@ -28482,7 +29167,7 @@ async function main() {
28482
29167
  if (!agentPubkey)
28483
29168
  throw new Error("stop requires --agent <pubkey>");
28484
29169
  const configs = await findAgentRuntimeConfigPaths(process.env, process.cwd());
28485
- const configPath = configs.find((candidate) => dirname17(candidate).endsWith(agentPubkey));
29170
+ const configPath = configs.find((candidate) => dirname18(candidate).endsWith(agentPubkey));
28486
29171
  if (!configPath)
28487
29172
  throw new Error(`no stored runtime found for agent ${agentPubkey}`);
28488
29173
  const runtime = await readRuntimeRecord(configPath);