openmausbot 0.1.57 → 0.1.58

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.
@@ -5,10 +5,10 @@ var __export = (target, all2) => {
5
5
  };
6
6
 
7
7
  // server/index.ts
8
- import { createHash as createHash23, randomBytes as randomBytes7, randomUUID as randomUUID16, timingSafeEqual as timingSafeEqual4 } from "node:crypto";
9
- import { existsSync as existsSync24, readFileSync as readFileSync37, rmSync as rmSync6, unlinkSync as unlinkSync9 } from "node:fs";
8
+ import { createHash as createHash24, randomBytes as randomBytes8, randomUUID as randomUUID17, timingSafeEqual as timingSafeEqual4 } from "node:crypto";
9
+ import { existsSync as existsSync25, readFileSync as readFileSync38, rmSync as rmSync6, unlinkSync as unlinkSync9 } from "node:fs";
10
10
  import { createServer as createServer3 } from "node:http";
11
- import { extname as extname5, join as join48 } from "node:path";
11
+ import { extname as extname5, join as join49 } from "node:path";
12
12
 
13
13
  // node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/external.js
14
14
  var external_exports = {};
@@ -1624,8 +1624,8 @@ function emoji() {
1624
1624
  }
1625
1625
  var ipv4 = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/;
1626
1626
  var ipv6 = /^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:))$/;
1627
- var mac = (delimiter4) => {
1628
- const escapedDelim = escapeRegex(delimiter4 ?? ":");
1627
+ var mac = (delimiter5) => {
1628
+ const escapedDelim = escapeRegex(delimiter5 ?? ":");
1629
1629
  return new RegExp(`^(?:[0-9A-F]{2}${escapedDelim}){5}[0-9A-F]{2}$|^(?:[0-9a-f]{2}${escapedDelim}){5}[0-9a-f]{2}$`);
1630
1630
  };
1631
1631
  var cidrv4 = /^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/([0-9]|[1-2][0-9]|3[0-2])$/;
@@ -14878,10 +14878,10 @@ async function requestReview(reviewPermission, request, timeoutMs = AUTO_REVIEW_
14878
14878
  const controller = new AbortController();
14879
14879
  let timer;
14880
14880
  try {
14881
- const timeout2 = new Promise((resolve10) => {
14881
+ const timeout2 = new Promise((resolve11) => {
14882
14882
  timer = setTimeout(() => {
14883
14883
  controller.abort();
14884
- resolve10(null);
14884
+ resolve11(null);
14885
14885
  }, timeoutMs);
14886
14886
  });
14887
14887
  const answer = await Promise.race([reviewPermission(buildReviewPrompt(request), controller.signal), timeout2]);
@@ -15068,8 +15068,8 @@ function whichWin(cli) {
15068
15068
  function nodeExe(near) {
15069
15069
  const local = join(near, "node.exe");
15070
15070
  if (isFile(local)) return local;
15071
- const onPath = whichWin("node.exe");
15072
- if (onPath && extname(onPath).toLowerCase() === ".exe") return onPath;
15071
+ const onPath2 = whichWin("node.exe");
15072
+ if (onPath2 && extname(onPath2).toLowerCase() === ".exe") return onPath2;
15073
15073
  return process.versions.electron ? null : process.execPath;
15074
15074
  }
15075
15075
  function parseCmdShim(shim) {
@@ -15229,14 +15229,14 @@ function stderrOf(error51) {
15229
15229
  return typeof stderr === "string" ? stderr : Buffer.isBuffer(stderr) ? stderr.toString("utf8") : "";
15230
15230
  }
15231
15231
  function run(execute, cli, args, options) {
15232
- return new Promise((resolve10, reject) => {
15232
+ return new Promise((resolve11, reject) => {
15233
15233
  execute(cli, args, options, (error51, stdout, stderr) => {
15234
15234
  if (error51) {
15235
15235
  if (error51.stderr === void 0 && stderr) {
15236
15236
  Object.assign(error51, { stderr });
15237
15237
  }
15238
15238
  reject(error51);
15239
- } else resolve10(stdout);
15239
+ } else resolve11(stdout);
15240
15240
  });
15241
15241
  });
15242
15242
  }
@@ -15542,7 +15542,7 @@ var BrowserCleanupCoordinator = class {
15542
15542
  const current2 = this.#pending.get(request.requestId);
15543
15543
  if (!current2) return true;
15544
15544
  if (current2.phase !== "committed") return false;
15545
- const result = new Promise((resolve10) => {
15545
+ const result = new Promise((resolve11) => {
15546
15546
  const prior = this.#waiters.get(request.requestId);
15547
15547
  if (prior) {
15548
15548
  clearTimeout(prior.timer);
@@ -15551,10 +15551,10 @@ var BrowserCleanupCoordinator = class {
15551
15551
  const timer = setTimeout(() => {
15552
15552
  if (this.#waiters.get(request.requestId)?.timer !== timer) return;
15553
15553
  this.#waiters.delete(request.requestId);
15554
- resolve10(false);
15554
+ resolve11(false);
15555
15555
  }, this.#timeoutMs);
15556
15556
  timer.unref?.();
15557
- this.#waiters.set(request.requestId, { resolve: resolve10, timer });
15557
+ this.#waiters.set(request.requestId, { resolve: resolve11, timer });
15558
15558
  });
15559
15559
  const sent = this.#send({
15560
15560
  type: current2.kind === "bot" ? "openmausbot:browser-bot-deleted" : "openmausbot:browser-profile-deleted",
@@ -16863,8 +16863,8 @@ async function withUploadLock(uploadId, operation) {
16863
16863
  if (!uploadId) return operation();
16864
16864
  const previous2 = uploadLocks.get(uploadId) ?? Promise.resolve();
16865
16865
  let release;
16866
- const current2 = new Promise((resolve10) => {
16867
- release = resolve10;
16866
+ const current2 = new Promise((resolve11) => {
16867
+ release = resolve11;
16868
16868
  });
16869
16869
  uploadLocks.set(uploadId, current2);
16870
16870
  await previous2;
@@ -19674,10 +19674,10 @@ function resolveAll(constructs2, events, context) {
19674
19674
  const called = [];
19675
19675
  let index2 = -1;
19676
19676
  while (++index2 < constructs2.length) {
19677
- const resolve10 = constructs2[index2].resolveAll;
19678
- if (resolve10 && !called.includes(resolve10)) {
19679
- events = resolve10(events, context);
19680
- called.push(resolve10);
19677
+ const resolve11 = constructs2[index2].resolveAll;
19678
+ if (resolve11 && !called.includes(resolve11)) {
19679
+ events = resolve11(events, context);
19680
+ called.push(resolve11);
19681
19681
  }
19682
19682
  }
19683
19683
  return events;
@@ -25360,7 +25360,7 @@ async function confirmAcceptedBoxDeletion(cfg2, boxId, acceptedBody) {
25360
25360
  if (operation?.status === "blocked") throw deletionBlockedError(boxId);
25361
25361
  if (operation) {
25362
25362
  for (const delayMs of BOX_DELETE_OPERATION_POLL_DELAYS_MS) {
25363
- if (delayMs > 0) await new Promise((resolve10) => setTimeout(resolve10, delayMs));
25363
+ if (delayMs > 0) await new Promise((resolve11) => setTimeout(resolve11, delayMs));
25364
25364
  let polled;
25365
25365
  try {
25366
25366
  polled = await boxJson(cfg2, `/deletion-operations/${operation.id}`, {
@@ -25825,7 +25825,7 @@ async function requestBoxCreate(cfg2, botId, ttlSeconds) {
25825
25825
  if (idempotentCreateInProgress(last)) {
25826
25826
  const delay = BOX_CREATE_IN_PROGRESS_RETRY_DELAYS_MS[inProgressRetries++];
25827
25827
  if (delay !== void 0) {
25828
- await new Promise((resolve10) => setTimeout(resolve10, delay));
25828
+ await new Promise((resolve11) => setTimeout(resolve11, delay));
25829
25829
  continue;
25830
25830
  }
25831
25831
  return { ...last, request, createdThisAttempt };
@@ -28138,13 +28138,13 @@ function computeBackoff(attempt, random = Math.random) {
28138
28138
  function interruptibleDelay(ms, signal) {
28139
28139
  let timer = null;
28140
28140
  let onCancel = null;
28141
- const promise2 = new Promise((resolve10) => {
28142
- timer = setTimeout(() => resolve10("elapsed"), Math.max(1, ms));
28141
+ const promise2 = new Promise((resolve11) => {
28142
+ timer = setTimeout(() => resolve11("elapsed"), Math.max(1, ms));
28143
28143
  timer.unref?.();
28144
- if (signal?.aborted) return resolve10("cancelled");
28144
+ if (signal?.aborted) return resolve11("cancelled");
28145
28145
  onCancel = () => {
28146
28146
  clearTimeout(timer);
28147
- resolve10("cancelled");
28147
+ resolve11("cancelled");
28148
28148
  };
28149
28149
  signal?.addEventListener("abort", onCancel, { once: true });
28150
28150
  });
@@ -28236,9 +28236,9 @@ function redactConfiguredValues(value, env) {
28236
28236
  return redacted;
28237
28237
  }
28238
28238
  function probeMcpServer(server2, timeoutMs = DEFAULT_TIMEOUT_MS, signal) {
28239
- return new Promise((resolve10) => {
28239
+ return new Promise((resolve11) => {
28240
28240
  if (signal?.aborted) {
28241
- resolve10({ ok: false, error: publicProbeError("cancelled") });
28241
+ resolve11({ ok: false, error: publicProbeError("cancelled") });
28242
28242
  return;
28243
28243
  }
28244
28244
  let child;
@@ -28249,7 +28249,7 @@ function probeMcpServer(server2, timeoutMs = DEFAULT_TIMEOUT_MS, signal) {
28249
28249
  stdio: ["pipe", "pipe", "pipe"]
28250
28250
  });
28251
28251
  } catch {
28252
- resolve10({ ok: false, error: publicProbeError("spawn") });
28252
+ resolve11({ ok: false, error: publicProbeError("spawn") });
28253
28253
  return;
28254
28254
  }
28255
28255
  let settled = false;
@@ -28263,7 +28263,7 @@ function probeMcpServer(server2, timeoutMs = DEFAULT_TIMEOUT_MS, signal) {
28263
28263
  if (timer) clearTimeout(timer);
28264
28264
  signal?.removeEventListener("abort", onAbort);
28265
28265
  killCliTree(child);
28266
- resolve10(result);
28266
+ resolve11(result);
28267
28267
  };
28268
28268
  const write = (frame) => {
28269
28269
  try {
@@ -28975,7 +28975,7 @@ function createAcpDriver(support11) {
28975
28975
  }
28976
28976
  appendNative(threadId, { dir: "out", source: SOURCE, msg: nativeLogMessage(obj) });
28977
28977
  };
28978
- const request = (method, params, timeoutMs) => new Promise((resolve10, reject) => {
28978
+ const request = (method, params, timeoutMs) => new Promise((resolve11, reject) => {
28979
28979
  const id = nextId++;
28980
28980
  let timer = null;
28981
28981
  if (timeoutMs) {
@@ -28985,7 +28985,7 @@ function createAcpDriver(support11) {
28985
28985
  }, timeoutMs);
28986
28986
  timer.unref?.();
28987
28987
  }
28988
- rpcPending.set(id, { resolve: resolve10, reject, timer });
28988
+ rpcPending.set(id, { resolve: resolve11, reject, timer });
28989
28989
  send({ jsonrpc: "2.0", id, method, params });
28990
28990
  });
28991
28991
  const stop = () => killCliTree(child);
@@ -29421,12 +29421,12 @@ ${turn.text}` : turn.text;
29421
29421
  const snapshot2 = async () => {
29422
29422
  const env = childEnv();
29423
29423
  if (support11.snapshot) return support11.snapshot(env, config2, instanceId);
29424
- const version2 = await new Promise((resolve10) => {
29424
+ const version2 = await new Promise((resolve11) => {
29425
29425
  execCli(
29426
29426
  config2.cli,
29427
29427
  ["--version"],
29428
29428
  { timeout: 8e3, env },
29429
- (err, stdout) => resolve10(err ? null : stdout.trim())
29429
+ (err, stdout) => resolve11(err ? null : stdout.trim())
29430
29430
  );
29431
29431
  });
29432
29432
  if (!version2) return { state: "unavailable", reason: `\`${config2.cli}\` CLI not found` };
@@ -29526,6 +29526,21 @@ function takeLines(buffer) {
29526
29526
  const rest = parts.pop() ?? "";
29527
29527
  return { lines: parts.map((line) => line.replace(/\r$/u, "")), rest };
29528
29528
  }
29529
+ function startupHint(line) {
29530
+ if (/no space left|not enough (?:space|disk)|disk (?:is )?full|winerror\s*112/iu.test(line)) {
29531
+ return "The runtime reported insufficient disk space while starting.";
29532
+ }
29533
+ if (/failed to (?:extract|load (?:python|embedded python))|could not load python/iu.test(line)) {
29534
+ return "The runtime reported a problem unpacking or loading its bundled Python runtime.";
29535
+ }
29536
+ if (/permission denied|access is denied|winerror\s*5\b/iu.test(line)) {
29537
+ return "The runtime reported a file or process permission failure.";
29538
+ }
29539
+ if (/address family not supported|failed to create.*(?:socket|listener)|failed to bind/iu.test(line)) {
29540
+ return "The runtime reported a local network listener failure.";
29541
+ }
29542
+ return void 0;
29543
+ }
29529
29544
  function authorizationUrlFromLine(line) {
29530
29545
  if (line.startsWith(ANTIGRAVITY_AUTH_PREFIX)) return line.slice(ANTIGRAVITY_AUTH_PREFIX.length).trim();
29531
29546
  if (!line.startsWith(BROWSER_MARKER)) return null;
@@ -29590,6 +29605,10 @@ var AntigravityAcpClient = class {
29590
29605
  pending = /* @__PURE__ */ new Map();
29591
29606
  buffer = "";
29592
29607
  diagnosticBuffer = "";
29608
+ initializationComplete = false;
29609
+ startupOutputBytes = 0;
29610
+ startupDiagnosticBytes = 0;
29611
+ nativeStartupHint;
29593
29612
  closed = false;
29594
29613
  onAuthorizationUrl;
29595
29614
  /** Settles once the runtime process is gone. On Windows a running
@@ -29608,14 +29627,19 @@ var AntigravityAcpClient = class {
29608
29627
  this.child.stderr.setEncoding("utf8");
29609
29628
  this.child.stderr.on("data", (chunk) => this.consumeDiagnostics(chunk));
29610
29629
  this.child.once("error", (error51) => this.failAll(error51));
29611
- this.exited = new Promise((resolve10) => {
29612
- this.child.once("close", (code) => {
29613
- if (!this.closed) this.failAll(new Error(`Antigravity ACP exited ${code ?? "unexpectedly"}.`));
29614
- resolve10();
29630
+ this.exited = new Promise((resolve11) => {
29631
+ this.child.once("close", (code, signal) => {
29632
+ this.noteStartupDiagnostic(this.diagnosticBuffer);
29633
+ this.diagnosticBuffer = "";
29634
+ if (!this.closed) this.failAll(new Error(
29635
+ `Antigravity ACP exited ${code ?? signal ?? "unexpectedly"}.${this.nativeStartupHint ? ` ${this.nativeStartupHint}` : ""}`
29636
+ ));
29637
+ resolve11();
29615
29638
  });
29616
29639
  });
29617
29640
  }
29618
29641
  consume(chunk) {
29642
+ if (!this.initializationComplete) this.startupOutputBytes += Buffer.byteLength(chunk);
29619
29643
  this.buffer += chunk;
29620
29644
  if (Buffer.byteLength(this.buffer) > MAX_PROTOCOL_LINE_BYTES) {
29621
29645
  this.failAll(new Error("Antigravity sent a protocol line that is too large."));
@@ -29660,9 +29684,15 @@ var AntigravityAcpClient = class {
29660
29684
  * and released immediately and the tail is capped, so no authorization code
29661
29685
  * is ever held. Draining also keeps the pipe from stalling the server. */
29662
29686
  consumeDiagnostics(chunk) {
29687
+ if (!this.initializationComplete) this.startupDiagnosticBytes += Buffer.byteLength(chunk);
29663
29688
  const { lines, rest } = takeLines(this.diagnosticBuffer + chunk);
29664
29689
  this.diagnosticBuffer = rest.length > MAX_DIAGNOSTIC_LINE_CHARS ? "" : rest;
29665
- for (const line of lines) this.announceAuthorizationUrl(line);
29690
+ for (const line of lines) {
29691
+ if (!this.announceAuthorizationUrl(line)) this.noteStartupDiagnostic(line);
29692
+ }
29693
+ }
29694
+ noteStartupDiagnostic(line) {
29695
+ if (!this.initializationComplete) this.nativeStartupHint ??= startupHint(line);
29666
29696
  }
29667
29697
  failAll(error51) {
29668
29698
  for (const pending of this.pending.values()) {
@@ -29677,7 +29707,12 @@ var AntigravityAcpClient = class {
29677
29707
  return new Promise((resolveRequest, reject) => {
29678
29708
  const timer = setTimeout(() => {
29679
29709
  this.pending.delete(id);
29680
- reject(new Error(`${method} timed out.`));
29710
+ if (method === "initialize") {
29711
+ this.noteStartupDiagnostic(this.diagnosticBuffer);
29712
+ reject(new Error(
29713
+ `Antigravity initialization timed out after ${Math.ceil(timeoutMs / 1e3)} seconds (${process.platform}-${process.arch}). The executable was found, but did not finish starting. ` + (this.nativeStartupHint ? `${this.nativeStartupHint} ` : "") + `Startup output: ${this.startupOutputBytes} bytes; diagnostic output: ${this.startupDiagnosticBytes} bytes. Retry setup. If it still fails, share this error and your OpenMausBot version; do not paste Google sign-in links or tokens.`
29714
+ ));
29715
+ } else reject(new Error(`${method} timed out.`));
29681
29716
  }, timeoutMs);
29682
29717
  timer.unref?.();
29683
29718
  this.pending.set(id, { resolve: resolveRequest, reject, timer });
@@ -29686,11 +29721,14 @@ var AntigravityAcpClient = class {
29686
29721
  });
29687
29722
  }
29688
29723
  async initialize(timeoutMs = STARTUP_TIMEOUT_MS) {
29689
- return this.request("initialize", {
29724
+ const initialized = await this.request("initialize", {
29690
29725
  protocolVersion: 1,
29691
29726
  clientInfo: { name: "openmausbot", version: "0.0.0" },
29692
29727
  clientCapabilities: { fs: { readTextFile: false, writeTextFile: false }, terminal: false }
29693
29728
  }, timeoutMs);
29729
+ this.initializationComplete = true;
29730
+ this.nativeStartupHint = void 0;
29731
+ return initialized;
29694
29732
  }
29695
29733
  close() {
29696
29734
  if (this.closed) return;
@@ -29703,8 +29741,8 @@ var AntigravityAcpClient = class {
29703
29741
  async closeAndWait(timeoutMs = 5e3) {
29704
29742
  this.close();
29705
29743
  let timer;
29706
- const timedOut = new Promise((resolve10) => {
29707
- timer = setTimeout(() => resolve10(false), timeoutMs);
29744
+ const timedOut = new Promise((resolve11) => {
29745
+ timer = setTimeout(() => resolve11(false), timeoutMs);
29708
29746
  timer.unref?.();
29709
29747
  });
29710
29748
  try {
@@ -29839,7 +29877,11 @@ async function validateAntigravityRuntime(runtime, expectedVersion) {
29839
29877
  const profile = await prepareAntigravityProfile({
29840
29878
  instanceId: `verify-${randomUUID7()}`,
29841
29879
  runtime,
29842
- profileDirectory
29880
+ profileDirectory,
29881
+ // Google's Windows one-file executable expands a large Python runtime
29882
+ // into TEMP. Forced shutdown skips its own cleanup. Keep verification's
29883
+ // extraction inside the profile we already remove after confirmed close.
29884
+ baseEnv: process.platform === "win32" ? { ...process.env, TEMP: profileDirectory, TMP: profileDirectory } : void 0
29843
29885
  });
29844
29886
  client = new AntigravityAcpClient(runtime, profile, profileDirectory);
29845
29887
  const initialized = await client.initialize();
@@ -30036,7 +30078,7 @@ function transientWindowsFileError(error51) {
30036
30078
  const code = typeof error51 === "object" && error51 !== null ? Reflect.get(error51, "code") : void 0;
30037
30079
  return code === "EPERM" || code === "EBUSY" || code === "EACCES" || code === "ENOTEMPTY";
30038
30080
  }
30039
- var wait = (ms) => new Promise((resolve10) => setTimeout(resolve10, ms));
30081
+ var wait = (ms) => new Promise((resolve11) => setTimeout(resolve11, ms));
30040
30082
  async function retryOnWindowsFileLock(step, options = {}) {
30041
30083
  const attempts = options.attempts ?? 8;
30042
30084
  const sleep = options.sleep ?? wait;
@@ -30464,8 +30506,9 @@ var AntigravityDriver = {
30464
30506
  async create(input) {
30465
30507
  const base2 = await AcpAntigravityDriver.create(input);
30466
30508
  const auth = new AntigravityAuthController();
30509
+ let installFailure;
30467
30510
  const runtimeAndProfile = async () => {
30468
- const environment = { ...process.env, ...input.environment };
30511
+ const environment = { ...process.env, ...input.environment, PATH: augmentedPath() };
30469
30512
  const runtime = await resolveAntigravityRuntime(input.config.cli, environment);
30470
30513
  const profile = await prepareAntigravityProfile({
30471
30514
  instanceId: input.instanceId,
@@ -30479,9 +30522,20 @@ var AntigravityDriver = {
30479
30522
  get models() {
30480
30523
  return base2.models;
30481
30524
  },
30525
+ snapshot: async () => {
30526
+ const snapshot2 = await base2.snapshot();
30527
+ if (snapshot2.state === "available") installFailure = void 0;
30528
+ return snapshot2.state === "unavailable" && installFailure ? { ...snapshot2, reason: installFailure } : snapshot2;
30529
+ },
30482
30530
  ...antigravityManagedInstallAvailable() ? {
30483
30531
  installRuntime: async () => {
30484
- await installAntigravityRuntime({ validate: validateAntigravityRuntime });
30532
+ installFailure = void 0;
30533
+ try {
30534
+ await installAntigravityRuntime({ validate: validateAntigravityRuntime });
30535
+ } catch (error51) {
30536
+ installFailure = error51 instanceof Error ? error51.message : String(error51);
30537
+ throw error51;
30538
+ }
30485
30539
  }
30486
30540
  } : {},
30487
30541
  startAuthentication: async () => {
@@ -30721,15 +30775,15 @@ import { createServer as createNetServer } from "node:net";
30721
30775
  import { homedir as homedir8, tmpdir as tmpdir3 } from "node:os";
30722
30776
  import { join as join16, dirname as dirname7 } from "node:path";
30723
30777
  function claudeSignedIn(cli, env, run3 = execCli) {
30724
- return new Promise((resolve10) => {
30778
+ return new Promise((resolve11) => {
30725
30779
  run3(cli, ["auth", "status", "--json"], { timeout: 8e3, env }, (_error, stdout) => {
30726
30780
  try {
30727
30781
  const status = JSON.parse(stdout);
30728
- resolve10(
30782
+ resolve11(
30729
30783
  typeof status === "object" && status !== null && "loggedIn" in status && status.loggedIn === true
30730
30784
  );
30731
30785
  } catch {
30732
- resolve10(false);
30786
+ resolve11(false);
30733
30787
  }
30734
30788
  });
30735
30789
  });
@@ -30920,9 +30974,9 @@ async function createPermissionBroker(opts) {
30920
30974
  unlinkSync5(candidate);
30921
30975
  } catch {
30922
30976
  }
30923
- let outcome = await new Promise((resolve10) => {
30924
- attempt.once("listening", () => resolve10("listening"));
30925
- attempt.once("error", (error51) => resolve10(error51));
30977
+ let outcome = await new Promise((resolve11) => {
30978
+ attempt.once("listening", () => resolve11("listening"));
30979
+ attempt.once("error", (error51) => resolve11(error51));
30926
30980
  attempt.listen(candidate);
30927
30981
  });
30928
30982
  if (outcome === "listening" && process.platform !== "win32") {
@@ -31127,19 +31181,19 @@ var ClaudeDriver = {
31127
31181
  };
31128
31182
  const writeUser = (s, threadId, promptMsg) => {
31129
31183
  if (!s.child.stdin.writable || s.child.stdin.destroyed) return Promise.resolve(false);
31130
- return new Promise((resolve10) => {
31184
+ return new Promise((resolve11) => {
31131
31185
  try {
31132
31186
  s.child.stdin.write(JSON.stringify(promptMsg) + "\n", (error51) => {
31133
- if (error51) return resolve10(false);
31187
+ if (error51) return resolve11(false);
31134
31188
  appendNative(threadId, {
31135
31189
  dir: "out",
31136
31190
  source: "claude.sdk.message",
31137
31191
  msg: diagnosticClaudeUserMessage(promptMsg)
31138
31192
  });
31139
- resolve10(true);
31193
+ resolve11(true);
31140
31194
  });
31141
31195
  } catch {
31142
- resolve10(false);
31196
+ resolve11(false);
31143
31197
  }
31144
31198
  });
31145
31199
  };
@@ -31620,19 +31674,19 @@ var ClaudeDriver = {
31620
31674
  };
31621
31675
  const snapshot2 = async () => {
31622
31676
  const env = claudeEnvironment(void 0, { ...process.env, ...input.environment });
31623
- const version2 = await new Promise((resolve10) => {
31677
+ const version2 = await new Promise((resolve11) => {
31624
31678
  execCli(
31625
31679
  config2.cli,
31626
31680
  ["--version"],
31627
31681
  { timeout: 8e3, env },
31628
- (err, stdout) => resolve10(err ? null : stdout.trim())
31682
+ (err, stdout) => resolve11(err ? null : stdout.trim())
31629
31683
  );
31630
31684
  });
31631
31685
  if (!version2) return { state: "unavailable", reason: `\`${config2.cli}\` CLI not found` };
31632
31686
  const authenticated = await claudeSignedIn(config2.cli, env);
31633
31687
  return { state: "available", version: version2, authenticated, billing: "subscription" };
31634
31688
  };
31635
- const generateReview = (prompt, signal) => new Promise((resolve10, reject) => {
31689
+ const generateReview = (prompt, signal) => new Promise((resolve11, reject) => {
31636
31690
  const child = spawnCli(
31637
31691
  config2.cli,
31638
31692
  ["-p", "--model", "claude-haiku-4-5", "--output-format", "text"],
@@ -31650,7 +31704,7 @@ var ClaudeDriver = {
31650
31704
  clearTimeout(timer);
31651
31705
  signal?.removeEventListener("abort", onAbort);
31652
31706
  if (error51) reject(error51);
31653
- else resolve10(stdout.trim());
31707
+ else resolve11(stdout.trim());
31654
31708
  };
31655
31709
  const onAbort = () => {
31656
31710
  killCliTree(child);
@@ -31779,7 +31833,7 @@ function decodeCodexSelection(id) {
31779
31833
  return { model: id, modelProvider: MODEL_ID2.test(id) ? OFFICIAL_CODEX_PROVIDER : null };
31780
31834
  }
31781
31835
  function readCodexAppServerModelCatalog(cli, env, timeoutMs = 8e3) {
31782
- return new Promise((resolve10) => {
31836
+ return new Promise((resolve11) => {
31783
31837
  const child = spawnCli(cli, ["app-server"], {
31784
31838
  cwd: homedir9(),
31785
31839
  env,
@@ -31796,7 +31850,7 @@ function readCodexAppServerModelCatalog(cli, env, timeoutMs = 8e3) {
31796
31850
  settled = true;
31797
31851
  clearTimeout(timer);
31798
31852
  killCliTree(child);
31799
- resolve10(catalog);
31853
+ resolve11(catalog);
31800
31854
  };
31801
31855
  const request = (method, params, kind) => {
31802
31856
  const id = nextId++;
@@ -32481,7 +32535,7 @@ var CodexDriver = {
32481
32535
  msg: codexNativeLogMessage(obj)
32482
32536
  });
32483
32537
  };
32484
- const request = (method, params, timeoutMs = 6e4) => new Promise((resolve10, reject) => {
32538
+ const request = (method, params, timeoutMs = 6e4) => new Promise((resolve11, reject) => {
32485
32539
  const id = nextId++;
32486
32540
  if (method === "config/read") sensitiveResponseIds.add(id);
32487
32541
  const timer = setTimeout(() => {
@@ -32491,7 +32545,7 @@ var CodexDriver = {
32491
32545
  rpcPending.set(id, {
32492
32546
  resolve: (v) => {
32493
32547
  clearTimeout(timer);
32494
- resolve10(v);
32548
+ resolve11(v);
32495
32549
  },
32496
32550
  reject: (e) => {
32497
32551
  clearTimeout(timer);
@@ -32852,8 +32906,8 @@ ${turn.text}` : turn.text;
32852
32906
  });
32853
32907
  abandoned = true;
32854
32908
  killCliTree(child);
32855
- await new Promise((resolve10) => {
32856
- const timer = setTimeout(resolve10, Math.max(1, Math.round(delayMs * retryScale)));
32909
+ await new Promise((resolve11) => {
32910
+ const timer = setTimeout(resolve11, Math.max(1, Math.round(delayMs * retryScale)));
32857
32911
  timer.unref?.();
32858
32912
  });
32859
32913
  if (!stopRequested) {
@@ -32881,21 +32935,21 @@ ${turn.text}` : turn.text;
32881
32935
  };
32882
32936
  const snapshot2 = async () => {
32883
32937
  const env = childEnv();
32884
- const version2 = await new Promise((resolve10) => {
32938
+ const version2 = await new Promise((resolve11) => {
32885
32939
  execCli(
32886
32940
  config2.cli,
32887
32941
  ["--version"],
32888
32942
  { timeout: 8e3, env },
32889
- (err, stdout) => resolve10(err ? null : stdout.trim())
32943
+ (err, stdout) => resolve11(err ? null : stdout.trim())
32890
32944
  );
32891
32945
  });
32892
32946
  if (!version2) return { state: "unavailable", reason: `\`${config2.cli}\` CLI not found` };
32893
- const authenticated = await new Promise((resolve10) => {
32947
+ const authenticated = await new Promise((resolve11) => {
32894
32948
  execCli(
32895
32949
  config2.cli,
32896
32950
  ["login", "status"],
32897
32951
  { timeout: 8e3, env },
32898
- (err, stdout, stderr) => resolve10(!err && /^logged in\b/im.test(`${stdout}
32952
+ (err, stdout, stderr) => resolve11(!err && /^logged in\b/im.test(`${stdout}
32899
32953
  ${stderr ?? ""}`))
32900
32954
  );
32901
32955
  });
@@ -34309,10 +34363,10 @@ function decodeCursorAuthText(text6) {
34309
34363
  return null;
34310
34364
  }
34311
34365
  function execText(run3, cli, args, env) {
34312
- return new Promise((resolve10) => {
34366
+ return new Promise((resolve11) => {
34313
34367
  run3(cli, args, { timeout: EXEC_TIMEOUT_MS, env }, (err, stdout) => {
34314
- if (err) return resolve10(null);
34315
- resolve10(String(stdout ?? ""));
34368
+ if (err) return resolve11(null);
34369
+ resolve11(String(stdout ?? ""));
34316
34370
  });
34317
34371
  });
34318
34372
  }
@@ -34498,7 +34552,7 @@ function parseOpenCodeModelsOutput(stdout) {
34498
34552
  return { default: (preferred ?? options[0]).id, options };
34499
34553
  }
34500
34554
  function runOpenCodeModels(cli, environment, verbose) {
34501
- return new Promise((resolve10, reject) => {
34555
+ return new Promise((resolve11, reject) => {
34502
34556
  execCli(
34503
34557
  cli,
34504
34558
  ["models", ...verbose ? ["--verbose"] : []],
@@ -34508,7 +34562,7 @@ function runOpenCodeModels(cli, environment, verbose) {
34508
34562
  reject(new Error(stderr?.trim() || error51.message, { cause: error51 }));
34509
34563
  return;
34510
34564
  }
34511
- resolve10(stdout);
34565
+ resolve11(stdout);
34512
34566
  }
34513
34567
  );
34514
34568
  });
@@ -41256,12 +41310,12 @@ function hermesConfiguredModel(env = process.env) {
41256
41310
  };
41257
41311
  }
41258
41312
  async function fetchHermesAcpModels(cli, env) {
41259
- return await new Promise((resolve10) => {
41313
+ return await new Promise((resolve11) => {
41260
41314
  let child;
41261
41315
  try {
41262
41316
  child = spawn2(cli, ["acp"], { stdio: ["pipe", "pipe", "ignore"], env });
41263
41317
  } catch {
41264
- return resolve10([]);
41318
+ return resolve11([]);
41265
41319
  }
41266
41320
  let settled = false;
41267
41321
  let timer;
@@ -41282,7 +41336,7 @@ async function fetchHermesAcpModels(cli, env) {
41282
41336
  }
41283
41337
  } catch {
41284
41338
  }
41285
- resolve10(out);
41339
+ resolve11(out);
41286
41340
  };
41287
41341
  timer = setTimeout(() => done([]), 5e3);
41288
41342
  child.once("error", () => done([]));
@@ -41718,7 +41772,7 @@ function readPiDefaultModel(env) {
41718
41772
  }
41719
41773
  async function fetchPiModels(cli, env) {
41720
41774
  const child = spawnCli(cli, PI_ARGS, { stdio: ["pipe", "pipe", "pipe"], env });
41721
- return new Promise((resolve10) => {
41775
+ return new Promise((resolve11) => {
41722
41776
  let buf = "";
41723
41777
  let done = false;
41724
41778
  const fallbackDefault = readPiDefaultModel(env);
@@ -41729,7 +41783,7 @@ async function fetchPiModels(cli, env) {
41729
41783
  killCliTree(child);
41730
41784
  } catch {
41731
41785
  }
41732
- resolve10(catalog);
41786
+ resolve11(catalog);
41733
41787
  };
41734
41788
  const timer = setTimeout(() => finish({ default: "", options: [] }), 15e3);
41735
41789
  timer.unref?.();
@@ -41884,13 +41938,13 @@ var PiDriver = {
41884
41938
  }
41885
41939
  responseWaiters.clear();
41886
41940
  };
41887
- const awaitResponse = (command, timeoutMs = 2e4) => new Promise((resolve10, reject) => {
41941
+ const awaitResponse = (command, timeoutMs = 2e4) => new Promise((resolve11, reject) => {
41888
41942
  const timer = setTimeout(() => {
41889
41943
  responseWaiters.delete(command);
41890
41944
  reject(new Error(`pi ${command} timed out`));
41891
41945
  }, timeoutMs);
41892
41946
  timer.unref?.();
41893
- responseWaiters.set(command, { resolve: resolve10, reject, timer });
41947
+ responseWaiters.set(command, { resolve: resolve11, reject, timer });
41894
41948
  });
41895
41949
  child.stdin.on("error", () => rejectWaiters(new Error("pi stdin closed")));
41896
41950
  const send = (obj) => {
@@ -42098,7 +42152,7 @@ ${turn.text}` : turn.text;
42098
42152
  return { turnId };
42099
42153
  };
42100
42154
  const snapshot2 = async () => {
42101
- const version2 = await new Promise((resolve10) => {
42155
+ const version2 = await new Promise((resolve11) => {
42102
42156
  const child = spawnCli(config2.cli, ["--version"], {
42103
42157
  stdio: ["ignore", "pipe", "pipe"],
42104
42158
  env: piEnvironment({ ...process.env, ...input.environment })
@@ -42111,16 +42165,16 @@ ${turn.text}` : turn.text;
42111
42165
  killCliTree(child);
42112
42166
  } catch {
42113
42167
  }
42114
- resolve10(null);
42168
+ resolve11(null);
42115
42169
  }, 8e3);
42116
42170
  timer.unref?.();
42117
42171
  child.on("error", () => {
42118
42172
  clearTimeout(timer);
42119
- resolve10(null);
42173
+ resolve11(null);
42120
42174
  });
42121
42175
  child.on("close", () => {
42122
42176
  clearTimeout(timer);
42123
- resolve10(out.trim() || null);
42177
+ resolve11(out.trim() || null);
42124
42178
  });
42125
42179
  });
42126
42180
  if (!version2) return { state: "unavailable", reason: `\`${config2.cli}\` CLI not found` };
@@ -43267,7 +43321,7 @@ var Store = class {
43267
43321
  /** A process restart cannot preserve an in-flight room orchestrator. Close
43268
43322
  * every durable working receipt before clients load it, including manual
43269
43323
  * goals that do not have a RoutineRun record to reconcile separately. */
43270
- reconcileInterruptedGroupGoals(resolve10, fallbackDetail = "OpenMausBot restarted before this goal finished.", fallbackFinishedAt = Date.now()) {
43324
+ reconcileInterruptedGroupGoals(resolve11, fallbackDetail = "OpenMausBot restarted before this goal finished.", fallbackFinishedAt = Date.now()) {
43271
43325
  const ownedThreadIds = /* @__PURE__ */ new Set();
43272
43326
  for (const group of this.groups) {
43273
43327
  ownedThreadIds.add(group.threadId);
@@ -43276,7 +43330,7 @@ var Store = class {
43276
43330
  let recovered = 0;
43277
43331
  for (const hit of workingGoalRunMessages()) {
43278
43332
  if (!ownedThreadIds.has(hit.threadId) || !hit.message.goalRun) continue;
43279
- const resolution = resolve10?.(hit.message.goalRun.runId, hit.threadId) ?? {
43333
+ const resolution = resolve11?.(hit.message.goalRun.runId, hit.threadId) ?? {
43280
43334
  status: "failed",
43281
43335
  detail: fallbackDetail,
43282
43336
  finishedAt: fallbackFinishedAt
@@ -44059,7 +44113,7 @@ function requestPeerApproval(bus2, from, target, message3, action, sourceThreadI
44059
44113
  if (allowKeyAllowed(from, peerAllowKey(action, target.id))) {
44060
44114
  return Promise.resolve("allow");
44061
44115
  }
44062
- return new Promise((resolve10) => {
44116
+ return new Promise((resolve11) => {
44063
44117
  const requestId = newId();
44064
44118
  const card = pushApprovalCard(bus2, from, target, message3, action, requestId, sourceThreadId);
44065
44119
  announceCard(bus2, from, card, sourceThreadId);
@@ -44068,11 +44122,11 @@ function requestPeerApproval(bus2, from, target, message3, action, sourceThreadI
44068
44122
  if (!pending) return;
44069
44123
  pendingComms.delete(requestId);
44070
44124
  settleCard(pending, "deny", "system");
44071
- resolve10("deny");
44125
+ resolve11("deny");
44072
44126
  }, APPROVAL_TIMEOUT_MS);
44073
44127
  timer.unref?.();
44074
44128
  pendingComms.set(requestId, {
44075
- resolve: resolve10,
44129
+ resolve: resolve11,
44076
44130
  timer,
44077
44131
  fromBotId: from.id,
44078
44132
  toBotId: target.id,
@@ -47332,28 +47386,28 @@ function vpsSshTunnelArgs(alias, localPort, privateIp) {
47332
47386
  ];
47333
47387
  }
47334
47388
  function unusedLoopbackPort() {
47335
- return new Promise((resolve10, reject) => {
47389
+ return new Promise((resolve11, reject) => {
47336
47390
  const probe = createServer();
47337
47391
  probe.once("error", reject);
47338
47392
  probe.listen(0, "127.0.0.1", () => {
47339
47393
  const port = probe.address().port;
47340
47394
  probe.close((error51) => {
47341
47395
  if (error51) reject(error51);
47342
- else if (port >= 1024) resolve10(port);
47396
+ else if (port >= 1024) resolve11(port);
47343
47397
  else reject(new Error("could not reserve a VPS viewer port"));
47344
47398
  });
47345
47399
  });
47346
47400
  });
47347
47401
  }
47348
47402
  function loopbackAnswers(port) {
47349
- return new Promise((resolve10) => {
47403
+ return new Promise((resolve11) => {
47350
47404
  const socket = createConnection({ host: "127.0.0.1", port });
47351
47405
  let settled = false;
47352
47406
  const finish = (answer) => {
47353
47407
  if (settled) return;
47354
47408
  settled = true;
47355
47409
  socket.destroy();
47356
- resolve10(answer);
47410
+ resolve11(answer);
47357
47411
  };
47358
47412
  socket.once("connect", () => finish(true));
47359
47413
  socket.once("error", () => finish(false));
@@ -47395,7 +47449,7 @@ function tailCollector() {
47395
47449
  };
47396
47450
  }
47397
47451
  function defaultRunner(args, options = {}) {
47398
- return new Promise((resolve10, reject) => {
47452
+ return new Promise((resolve11, reject) => {
47399
47453
  const command = resolveCliSpawn("docker", args);
47400
47454
  const child = spawn3(command.command, command.args, {
47401
47455
  shell: false,
@@ -47448,7 +47502,7 @@ function defaultRunner(args, options = {}) {
47448
47502
  return;
47449
47503
  }
47450
47504
  settle(() => {
47451
- if (code === 0) return resolve10({ stdout: stdout.text(), stderr: stderr.text() });
47505
+ if (code === 0) return resolve11({ stdout: stdout.text(), stderr: stderr.text() });
47452
47506
  const detail = stderr.text().trim().slice(-1e3);
47453
47507
  reject(new Error(detail || `Docker-over-SSH exited ${code ?? signal ?? "without a status"}`));
47454
47508
  });
@@ -47833,8 +47887,8 @@ async function waitForVpsReady(cfg2, botId, runner, budgetMs = 6e4) {
47833
47887
  if (!status.daemonUp || !status.image || !status.imageMatches || !status.managed || status.container !== "running" || status.network !== "private" || status.mounts !== "none" || status.security !== "hardened") {
47834
47888
  return status;
47835
47889
  }
47836
- await new Promise((resolve10) => {
47837
- const sleep = setTimeout(resolve10, Math.min(delayMs, Math.max(0, deadline - Date.now())));
47890
+ await new Promise((resolve11) => {
47891
+ const sleep = setTimeout(resolve11, Math.min(delayMs, Math.max(0, deadline - Date.now())));
47838
47892
  sleep.unref?.();
47839
47893
  });
47840
47894
  delayMs = Math.min(delayMs * 2, 4e3);
@@ -47854,16 +47908,16 @@ async function waitForVpsReady(cfg2, botId, runner, budgetMs = 6e4) {
47854
47908
  async function withVpsLifecycleLock(key3, operation) {
47855
47909
  const previous2 = lifecycleLocks.get(key3);
47856
47910
  let release;
47857
- const current2 = new Promise((resolve10) => {
47858
- release = resolve10;
47911
+ const current2 = new Promise((resolve11) => {
47912
+ release = resolve11;
47859
47913
  });
47860
47914
  lifecycleLocks.set(key3, current2);
47861
47915
  if (previous2) {
47862
47916
  let acquireTimer;
47863
47917
  const acquired = await Promise.race([
47864
47918
  previous2.then(() => true),
47865
- new Promise((resolve10) => {
47866
- acquireTimer = setTimeout(() => resolve10(false), LOCK_ACQUIRE_TIMEOUT_MS);
47919
+ new Promise((resolve11) => {
47920
+ acquireTimer = setTimeout(() => resolve11(false), LOCK_ACQUIRE_TIMEOUT_MS);
47867
47921
  acquireTimer.unref?.();
47868
47922
  })
47869
47923
  ]);
@@ -48035,7 +48089,7 @@ async function vpsComputerJoin(cfg2, botId, runner = defaultRunner) {
48035
48089
  const deadline = Date.now() + 1e4;
48036
48090
  while (Date.now() < deadline && !failure) {
48037
48091
  if (await loopbackAnswers(localPort)) break;
48038
- await new Promise((resolve10) => setTimeout(resolve10, 100));
48092
+ await new Promise((resolve11) => setTimeout(resolve11, 100));
48039
48093
  }
48040
48094
  if (failure || !await loopbackAnswers(localPort)) {
48041
48095
  if (child.exitCode === null && !child.killed) child.kill("SIGTERM");
@@ -49541,6 +49595,124 @@ async function browserScreenshot(connection, capability, fetchImpl = fetch) {
49541
49595
  return { png: body.png, format: body.format ?? "jpeg" };
49542
49596
  }
49543
49597
 
49598
+ // server/browser-engine.ts
49599
+ import { createHash as createHash15, randomBytes as randomBytes5, randomUUID as randomUUID12 } from "node:crypto";
49600
+ import { chmodSync as chmodSync5, existsSync as existsSync18, mkdirSync as mkdirSync19, readFileSync as readFileSync31, renameSync as renameSync5, statSync as statSync8, writeFileSync as writeFileSync15 } from "node:fs";
49601
+ import { delimiter as delimiter4, join as join40, resolve as resolve10 } from "node:path";
49602
+
49603
+ // server/browser-engine-release.ts
49604
+ var AGENT_BROWSER_VERSION = "0.36.0";
49605
+ var RELEASES2 = /* @__PURE__ */ new Map([
49606
+ [
49607
+ "darwin-arm64",
49608
+ { target: "darwin-arm64", asset: "agent-browser-darwin-arm64", sha256: "b2106ab39db0838e7b1772f7f26f760518de56d09053150c56f9dddf15af997d", bytes: 12363200 }
49609
+ ],
49610
+ [
49611
+ "darwin-x64",
49612
+ { target: "darwin-x64", asset: "agent-browser-darwin-x64", sha256: "45d9ac061a7d72e61eaff905326e2e19365f4dadb12142ea2f2d76d84689c708", bytes: 13510280 }
49613
+ ],
49614
+ [
49615
+ "linux-arm64",
49616
+ { target: "linux-arm64", asset: "agent-browser-linux-arm64", sha256: "aeb556addca3903601a433de1acad3ace1c9c61d170084bf58d875884599a990", bytes: 12442720 }
49617
+ ],
49618
+ [
49619
+ "linux-musl-arm64",
49620
+ { target: "linux-musl-arm64", asset: "agent-browser-linux-musl-arm64", sha256: "1ca7e003c9cb185f174fc81e51a609db27c77e3bfe00a0edff60688f8cd14f88", bytes: 12297e3 }
49621
+ ],
49622
+ [
49623
+ "linux-musl-x64",
49624
+ { target: "linux-musl-x64", asset: "agent-browser-linux-musl-x64", sha256: "a20cc2a5202a48f5820372803dedbcd5f556dff7a89421f1b0f2612962b10718", bytes: 13995728 }
49625
+ ],
49626
+ [
49627
+ "linux-x64",
49628
+ { target: "linux-x64", asset: "agent-browser-linux-x64", sha256: "56d15181e51e00213f907fcf39707cfc76bfa804ff20f5a9373661c73f96de5e", bytes: 14156776 }
49629
+ ],
49630
+ [
49631
+ "win32-x64",
49632
+ { target: "win32-x64", asset: "agent-browser-win32-x64.exe", sha256: "412ff72737a109e93f5304b0ff76c988fb6f1f451d0fc7e010577922bcc20ff3", bytes: 13837312 }
49633
+ ]
49634
+ ]);
49635
+ function resolveAgentBrowserReleaseAsset(platform = process.platform, arch = process.arch, musl = false) {
49636
+ const key3 = platform === "linux" && musl ? `linux-musl-${arch}` : `${platform}-${arch}`;
49637
+ return RELEASES2.get(key3) ?? null;
49638
+ }
49639
+
49640
+ // server/browser-engine.ts
49641
+ var ENGINE_DIR = "tools/agent-browser";
49642
+ var KEY_FILE = "browser-engine-key";
49643
+ var DOWNLOAD_TIMEOUT_MS2 = 10 * 6e4;
49644
+ function executableName(platform = process.platform) {
49645
+ return platform === "win32" ? "agent-browser.exe" : "agent-browser";
49646
+ }
49647
+ function isMusl(platform = process.platform, exists = existsSync18) {
49648
+ return platform === "linux" && (exists("/lib/ld-musl-x86_64.so.1") || exists("/lib/ld-musl-aarch64.so.1"));
49649
+ }
49650
+ function pinnedBinaryPath(dataDir = DATA_DIR, platform = process.platform) {
49651
+ return join40(dataDir, ENGINE_DIR, AGENT_BROWSER_VERSION, executableName(platform));
49652
+ }
49653
+ function onPath(env, platform, exists) {
49654
+ const pathValue = platform === "win32" ? Object.entries(env).findLast(([key3]) => key3.toUpperCase() === "PATH")?.[1] : env.PATH;
49655
+ for (const part of (pathValue ?? "").split(delimiter4)) {
49656
+ const dir = part.trim().replace(/^"|"$/gu, "");
49657
+ if (!dir) continue;
49658
+ const candidate = resolve10(dir, executableName(platform));
49659
+ if (exists(candidate)) return candidate;
49660
+ }
49661
+ return null;
49662
+ }
49663
+ function resolveAgentBrowserBinary(options = {}) {
49664
+ const env = options.env ?? process.env;
49665
+ const platform = options.platform ?? process.platform;
49666
+ const exists = options.exists ?? existsSync18;
49667
+ const override = env.OMB_AGENT_BROWSER_PATH?.trim();
49668
+ if (override) return resolve10(override) && exists(resolve10(override)) ? resolve10(override) : null;
49669
+ const pinned = pinnedBinaryPath(options.dataDir, platform);
49670
+ if (exists(pinned)) return pinned;
49671
+ return onPath(env, platform, exists);
49672
+ }
49673
+ function browserEngineEncryptionKey(dataDir = DATA_DIR) {
49674
+ const file2 = join40(dataDir, KEY_FILE);
49675
+ try {
49676
+ const existing = readFileSync31(file2, "utf8").trim();
49677
+ if (/^[0-9a-f]{64}$/u.test(existing)) return existing;
49678
+ } catch {
49679
+ }
49680
+ const key3 = randomBytes5(32).toString("hex");
49681
+ mkdirSync19(dataDir, { recursive: true });
49682
+ writeFileAtomic(file2, `${key3}
49683
+ `, { mode: 384 });
49684
+ return key3;
49685
+ }
49686
+ function browserEngineStatus(options = {}) {
49687
+ const binaryPath = resolveAgentBrowserBinary(options);
49688
+ if (binaryPath) return { kind: "ready", binaryPath, version: AGENT_BROWSER_VERSION };
49689
+ const platform = options.platform ?? process.platform;
49690
+ const asset = resolveAgentBrowserReleaseAsset(platform, process.arch, isMusl(platform));
49691
+ return asset ? { kind: "unavailable", reason: "agent-browser is not installed on this machine yet", installable: true } : { kind: "unavailable", reason: `agent-browser publishes no build for ${platform}-${process.arch}`, installable: false };
49692
+ }
49693
+ function agentBrowserIntegration(input) {
49694
+ const env = {
49695
+ AGENT_BROWSER_SESSION: input.session,
49696
+ // This is a restore *name*, not a boolean. "1" would give every bot
49697
+ // the same saved cookies despite using different daemon sessions.
49698
+ AGENT_BROWSER_RESTORE: input.session,
49699
+ AGENT_BROWSER_RESTORE_SAVE: input.persistent === false ? "never" : "auto",
49700
+ AGENT_BROWSER_ENCRYPTION_KEY: input.encryptionKey
49701
+ };
49702
+ if (input.headless !== false) env.AGENT_BROWSER_HEADLESS = "1";
49703
+ const path = (input.env ?? process.env).PATH;
49704
+ if (path) env.PATH = path;
49705
+ return { command: input.binaryPath, args: ["mcp", "--tools", "core", "--no-webmcp"], env };
49706
+ }
49707
+ function browserSessionId(botId, partitionId) {
49708
+ if (partitionId === "guest") return `guest-${randomUUID12()}`;
49709
+ const raw = partitionId || `bot-${botId}`;
49710
+ return raw.replace(/[^A-Za-z0-9_.-]/gu, "_").slice(0, 96);
49711
+ }
49712
+ function describeBrowserEngine(status) {
49713
+ return status.kind === "ready" ? `browser engine: agent-browser ${status.version} at ${status.binaryPath}` : `browser engine: unavailable (${status.reason})`;
49714
+ }
49715
+
49544
49716
  // server/private-screen-capture.ts
49545
49717
  async function captureOutsideHumanControl(control, capture) {
49546
49718
  const before = control();
@@ -49552,7 +49724,7 @@ async function captureOutsideHumanControl(control, capture) {
49552
49724
  }
49553
49725
 
49554
49726
  // server/screen-frame-gate.ts
49555
- import { createHash as createHash15 } from "node:crypto";
49727
+ import { createHash as createHash16 } from "node:crypto";
49556
49728
  var SCREEN_TOUCHING_TOOLS = /* @__PURE__ */ new Set([
49557
49729
  // cloud box / remote computer
49558
49730
  "screenshot",
@@ -49590,14 +49762,14 @@ function screenTouchingTool(toolName) {
49590
49762
  return SCREEN_TOUCHING_TOOLS.has(bare) || SCREEN_TOUCHING_TOOLS.has(bare.replace(/^(?:computer|browser)_/, ""));
49591
49763
  }
49592
49764
  function screenFrameHash(png) {
49593
- return createHash15("sha256").update(png).digest("hex");
49765
+ return createHash16("sha256").update(png).digest("hex");
49594
49766
  }
49595
49767
  function settledFrameIsNews(shownFrameHash, png) {
49596
49768
  return shownFrameHash === void 0 || screenFrameHash(png) !== shownFrameHash;
49597
49769
  }
49598
49770
 
49599
49771
  // server/routine-requests.ts
49600
- import { createHash as createHash16 } from "node:crypto";
49772
+ import { createHash as createHash17 } from "node:crypto";
49601
49773
  var WEEKDAY_NUMBER = {
49602
49774
  sunday: 0,
49603
49775
  monday: 1,
@@ -50032,7 +50204,7 @@ function routineRequestFingerprint(payload, messageId) {
50032
50204
  threadId: payload.threadId,
50033
50205
  operation: payload.operation
50034
50206
  }));
50035
- return createHash16("sha256").update(JSON.stringify(canonicalValue2(document3))).digest("hex");
50207
+ return createHash17("sha256").update(JSON.stringify(canonicalValue2(document3))).digest("hex");
50036
50208
  }
50037
50209
  function verifyManageSnapshot(operation, manager, botId) {
50038
50210
  const current2 = ownedRoutine(manager, operation.routineId, botId);
@@ -50590,25 +50762,25 @@ function lineDiff(before, after) {
50590
50762
  var PROFILE_REQUEST_FIELDS = ["name", "title", "description", "soul", "cwd"];
50591
50763
 
50592
50764
  // server/profile-revision.ts
50593
- import { createHash as createHash17 } from "node:crypto";
50765
+ import { createHash as createHash18 } from "node:crypto";
50594
50766
  function profileSnapshot(bot) {
50595
50767
  return { name: bot.name, title: bot.title, description: bot.description, soul: bot.soul ?? "", cwd: bot.cwd ?? "" };
50596
50768
  }
50597
50769
  function profileRevision(bot) {
50598
- return createHash17("sha256").update(JSON.stringify({ ...profileSnapshot(bot), lastProfileRequestId: bot.lastProfileRequestId ?? "" }), "utf8").digest("hex");
50770
+ return createHash18("sha256").update(JSON.stringify({ ...profileSnapshot(bot), lastProfileRequestId: bot.lastProfileRequestId ?? "" }), "utf8").digest("hex");
50599
50771
  }
50600
50772
 
50601
50773
  // server/profile-versions.ts
50602
50774
  import { appendFile as appendFile2 } from "node:fs/promises";
50603
- import { createHash as createHash18, randomUUID as randomUUID12 } from "node:crypto";
50604
- import { closeSync as closeSync8, existsSync as existsSync18, fstatSync as fstatSync3, mkdirSync as mkdirSync19, openSync as openSync8, readSync as readSync3 } from "node:fs";
50605
- import { join as join40 } from "node:path";
50775
+ import { createHash as createHash19, randomUUID as randomUUID13 } from "node:crypto";
50776
+ import { closeSync as closeSync8, existsSync as existsSync19, fstatSync as fstatSync3, mkdirSync as mkdirSync20, openSync as openSync8, readSync as readSync3 } from "node:fs";
50777
+ import { join as join41 } from "node:path";
50606
50778
  var FILE_NAME2 = "history.ndjson";
50607
50779
  var ONE_LINER = 200;
50608
50780
  var MAX_HISTORY_READ_BYTES = 8 * 1024 * 1024;
50609
50781
  var writeQueues2 = /* @__PURE__ */ new Map();
50610
50782
  function historyFile(botId) {
50611
- return join40(botFolder(botId), FILE_NAME2);
50783
+ return join41(botFolder(botId), FILE_NAME2);
50612
50784
  }
50613
50785
  function oneLiner(value) {
50614
50786
  return value.replace(/\s+/g, " ").trim().slice(0, ONE_LINER);
@@ -50617,11 +50789,11 @@ function rowFor(field, at, actor, via, before, after) {
50617
50789
  if (field === "soul") {
50618
50790
  const b2 = Buffer.byteLength(before, "utf8");
50619
50791
  const a2 = Buffer.byteLength(after, "utf8");
50620
- return { id: randomUUID12(), at, actor, via, field, summary: `soul: ${b2} \u2192 ${a2} bytes`, before, after };
50792
+ return { id: randomUUID13(), at, actor, via, field, summary: `soul: ${b2} \u2192 ${a2} bytes`, before, after };
50621
50793
  }
50622
50794
  const b = oneLiner(before);
50623
50795
  const a = oneLiner(after);
50624
- return { id: randomUUID12(), at, actor, via, field, summary: `${field}: ${JSON.stringify(b)} \u2192 ${JSON.stringify(a)}`, before: b, after: a };
50796
+ return { id: randomUUID13(), at, actor, via, field, summary: `${field}: ${JSON.stringify(b)} \u2192 ${JSON.stringify(a)}`, before: b, after: a };
50625
50797
  }
50626
50798
  function withRestoreEligibility(row) {
50627
50799
  const redacted = redactSecrets(row);
@@ -50633,9 +50805,9 @@ function withRestoreEligibility(row) {
50633
50805
  };
50634
50806
  }
50635
50807
  async function writeRows(botId, rows) {
50636
- if (!existsSync18(botFolder(botId))) return;
50808
+ if (!existsSync19(botFolder(botId))) return;
50637
50809
  const file2 = historyFile(botId);
50638
- mkdirSync19(botFolder(botId), { recursive: true, mode: 448 });
50810
+ mkdirSync20(botFolder(botId), { recursive: true, mode: 448 });
50639
50811
  const text6 = rows.map((row) => JSON.stringify(withRestoreEligibility(row))).join("\n") + "\n";
50640
50812
  await appendFile2(file2, text6, { mode: 384 });
50641
50813
  }
@@ -50697,7 +50869,7 @@ function readHistory(botId, limit = 100) {
50697
50869
  try {
50698
50870
  const value = JSON.parse(line);
50699
50871
  if (isRow(value)) {
50700
- const id = typeof value.id === "string" && value.id ? value.id : `legacy-${createHash18("sha256").update(`${end}:${line}`).digest("hex")}`;
50872
+ const id = typeof value.id === "string" && value.id ? value.id : `legacy-${createHash19("sha256").update(`${end}:${line}`).digest("hex")}`;
50701
50873
  rows.push(withRestoreEligibility({ ...value, id }));
50702
50874
  }
50703
50875
  } catch {
@@ -51107,8 +51279,8 @@ function matchDirectoryBots(profile, bots, limit = 5) {
51107
51279
  }
51108
51280
 
51109
51281
  // server/project-scout.ts
51110
- import { readFileSync as readFileSync31, readdirSync as readdirSync6, statSync as statSync8 } from "node:fs";
51111
- import { basename as basename5, join as join41 } from "node:path";
51282
+ import { readFileSync as readFileSync32, readdirSync as readdirSync6, statSync as statSync9 } from "node:fs";
51283
+ import { basename as basename5, join as join42 } from "node:path";
51112
51284
 
51113
51285
  // shared/import-name.ts
51114
51286
  function takeImportName(value, taken, maxLength = 100) {
@@ -51291,8 +51463,8 @@ var MAX_FILE_BYTES2 = 256e3;
51291
51463
  var MAX_DIR_ENTRIES = 400;
51292
51464
  function readText2(path) {
51293
51465
  try {
51294
- if (statSync8(path).size > MAX_FILE_BYTES2) return null;
51295
- return readFileSync31(path, "utf8");
51466
+ if (statSync9(path).size > MAX_FILE_BYTES2) return null;
51467
+ return readFileSync32(path, "utf8");
51296
51468
  } catch {
51297
51469
  return null;
51298
51470
  }
@@ -51306,13 +51478,13 @@ function listNames(dir) {
51306
51478
  }
51307
51479
  function isDir(path) {
51308
51480
  try {
51309
- return statSync8(path).isDirectory();
51481
+ return statSync9(path).isDirectory();
51310
51482
  } catch {
51311
51483
  return false;
51312
51484
  }
51313
51485
  }
51314
51486
  function packageJson(cwd) {
51315
- const raw = readText2(join41(cwd, "package.json"));
51487
+ const raw = readText2(join42(cwd, "package.json"));
51316
51488
  if (!raw) return { deps: /* @__PURE__ */ new Set() };
51317
51489
  try {
51318
51490
  const parsed = JSON.parse(raw);
@@ -51335,7 +51507,7 @@ function packageJson(cwd) {
51335
51507
  }
51336
51508
  }
51337
51509
  function readme(cwd) {
51338
- const raw = readText2(join41(cwd, "README.md")) ?? readText2(join41(cwd, "readme.md")) ?? readText2(join41(cwd, "README"));
51510
+ const raw = readText2(join42(cwd, "README.md")) ?? readText2(join42(cwd, "readme.md")) ?? readText2(join42(cwd, "README"));
51339
51511
  if (!raw) return {};
51340
51512
  let title;
51341
51513
  let summary;
@@ -51409,12 +51581,12 @@ function scoutProject(cwd) {
51409
51581
  const pkg = packageJson(cwd);
51410
51582
  const md = readme(cwd);
51411
51583
  const entries = new Set(listNames(cwd));
51412
- const pythonDeps = `${readText2(join41(cwd, "requirements.txt")) ?? ""}
51413
- ${readText2(join41(cwd, "pyproject.toml")) ?? ""}`.toLowerCase();
51584
+ const pythonDeps = `${readText2(join42(cwd, "requirements.txt")) ?? ""}
51585
+ ${readText2(join42(cwd, "pyproject.toml")) ?? ""}`.toLowerCase();
51414
51586
  const hasDep = (dep) => pkg.deps.has(dep) || pythonDeps.length > 1 && pythonDeps.includes(dep);
51415
51587
  const pathEvidence = (path) => {
51416
- if (path.includes("/")) return isDir(join41(cwd, path)) && listNames(join41(cwd, path)).length > 0 ? `${path}/` : null;
51417
- if (entries.has(path)) return isDir(join41(cwd, path)) ? `${path}/` : path;
51588
+ if (path.includes("/")) return isDir(join42(cwd, path)) && listNames(join42(cwd, path)).length > 0 ? `${path}/` : null;
51589
+ if (entries.has(path)) return isDir(join42(cwd, path)) ? `${path}/` : path;
51418
51590
  return null;
51419
51591
  };
51420
51592
  const signals = [];
@@ -51427,7 +51599,7 @@ ${readText2(join41(cwd, "pyproject.toml")) ?? ""}`.toLowerCase();
51427
51599
  }
51428
51600
  if (detector.role === "docs" && evidence.length > 0) {
51429
51601
  const hasMkdocs = evidence.includes("mkdocs.yml");
51430
- const hasMarkdown = listNames(join41(cwd, "docs")).some((name2) => name2.endsWith(".md"));
51602
+ const hasMarkdown = listNames(join42(cwd, "docs")).some((name2) => name2.endsWith(".md"));
51431
51603
  if (!hasMkdocs && !hasMarkdown) continue;
51432
51604
  }
51433
51605
  if (evidence.length > 0) signals.push({ role: detector.role, evidence: evidence.slice(0, 6) });
@@ -52017,7 +52189,7 @@ async function fetchGithubTeam(input, fetcher = fetch) {
52017
52189
 
52018
52190
  // server/thread-events.ts
52019
52191
  import { closeSync as closeSync9, fstatSync as fstatSync4, openSync as openSync9, readSync as readSync4 } from "node:fs";
52020
- import { join as join42 } from "node:path";
52192
+ import { join as join43 } from "node:path";
52021
52193
  var DEFAULT_LIMIT = 300;
52022
52194
  var MAX_LIMIT = 2e3;
52023
52195
  var READ_CHUNK = 64 * 1024;
@@ -52151,8 +52323,8 @@ function readThreadEvents(input) {
52151
52323
  assertThreadId(threadId);
52152
52324
  const requested = input.limit ?? DEFAULT_LIMIT;
52153
52325
  const limit = Number.isFinite(requested) ? Math.max(1, Math.min(Math.trunc(requested), MAX_LIMIT)) : DEFAULT_LIMIT;
52154
- const runtime = readRecentLines(join42(eventsDir, `${threadId}.ndjson`), limit, isRuntimeEvent);
52155
- const native = readRecentLines(join42(nativeDir, `${threadId}.ndjson`), limit, isNativeRecord);
52326
+ const runtime = readRecentLines(join43(eventsDir, `${threadId}.ndjson`), limit, isRuntimeEvent);
52327
+ const native = readRecentLines(join43(nativeDir, `${threadId}.ndjson`), limit, isNativeRecord);
52156
52328
  const merged = [
52157
52329
  ...runtime.lines.map((data) => ({ kind: "runtime", at: data.createdAt, data })),
52158
52330
  ...native.lines.map((data) => ({ kind: "native", at: data.at, data }))
@@ -52289,12 +52461,12 @@ async function listenWebhookIngress(manager, options) {
52289
52461
  const host = options.host ?? "127.0.0.1";
52290
52462
  const advertised = options.publicBaseUrl === void 0 ? void 0 : advertisedWebhookBase(options.publicBaseUrl);
52291
52463
  const server2 = createServer2(createWebhookIngressHandler(manager));
52292
- await new Promise((resolve10, reject) => {
52464
+ await new Promise((resolve11, reject) => {
52293
52465
  const onError = (error51) => reject(error51);
52294
52466
  server2.once("error", onError);
52295
52467
  server2.listen(options.port, host, () => {
52296
52468
  server2.off("error", onError);
52297
- resolve10();
52469
+ resolve11();
52298
52470
  });
52299
52471
  });
52300
52472
  const address = serverAddressSchema.safeParse(server2.address());
@@ -52327,9 +52499,9 @@ function memberTurnSelection(selection) {
52327
52499
  }
52328
52500
 
52329
52501
  // server/webhooks.ts
52330
- import { createHash as createHash19, randomBytes as randomBytes5, randomUUID as randomUUID13, timingSafeEqual } from "node:crypto";
52331
- import { mkdirSync as mkdirSync20, readFileSync as readFileSync32 } from "node:fs";
52332
- import { dirname as dirname13, join as join43 } from "node:path";
52502
+ import { createHash as createHash20, randomBytes as randomBytes6, randomUUID as randomUUID14, timingSafeEqual } from "node:crypto";
52503
+ import { mkdirSync as mkdirSync21, readFileSync as readFileSync33 } from "node:fs";
52504
+ import { dirname as dirname13, join as join44 } from "node:path";
52333
52505
  var MAX_DELIVERIES = 2e3;
52334
52506
  var MAX_ATTEMPTS = 2e3;
52335
52507
  var MAX_EVENT_CHARS = 48e3;
@@ -52405,7 +52577,7 @@ function invalidInput(error51) {
52405
52577
  fail(400, schemaIssue(error51, "Invalid webhook settings"));
52406
52578
  }
52407
52579
  function hashSecret(secret) {
52408
- return createHash19("sha256").update(secret).digest("hex");
52580
+ return createHash20("sha256").update(secret).digest("hex");
52409
52581
  }
52410
52582
  function secretMatches(secret, expectedHex) {
52411
52583
  if (!secret) return false;
@@ -52414,10 +52586,10 @@ function secretMatches(secret, expectedHex) {
52414
52586
  return actual.length === expected.length && timingSafeEqual(actual, expected);
52415
52587
  }
52416
52588
  function newEndpointId() {
52417
- return `wh_${randomBytes5(12).toString("base64url")}`;
52589
+ return `wh_${randomBytes6(12).toString("base64url")}`;
52418
52590
  }
52419
52591
  function newSecret() {
52420
- return `whsec_${randomBytes5(32).toString("base64url")}`;
52592
+ return `whsec_${randomBytes6(32).toString("base64url")}`;
52421
52593
  }
52422
52594
  function cleanInput2(input) {
52423
52595
  const name2 = input.name.trim().slice(0, 80);
@@ -52516,10 +52688,10 @@ var WebhookManager = class {
52516
52688
  rate = /* @__PURE__ */ new Map();
52517
52689
  constructor(options) {
52518
52690
  this.options = options;
52519
- this.file = options.file ?? join43(DATA_DIR, "webhooks.json");
52691
+ this.file = options.file ?? join44(DATA_DIR, "webhooks.json");
52520
52692
  this.now = options.now ?? Date.now;
52521
52693
  try {
52522
- const parsed = webhookFileSchema.safeParse(parseJson(readFileSync32(this.file, "utf8")));
52694
+ const parsed = webhookFileSchema.safeParse(parseJson(readFileSync33(this.file, "utf8")));
52523
52695
  if (!parsed.success) throw parsed.error;
52524
52696
  this.webhooks = parsed.data.webhooks;
52525
52697
  this.deliveries = parsed.data.deliveries.slice(-MAX_DELIVERIES);
@@ -52542,7 +52714,7 @@ var WebhookManager = class {
52542
52714
  const now = this.now();
52543
52715
  const secret = newSecret();
52544
52716
  const trigger = {
52545
- id: randomUUID13(),
52717
+ id: randomUUID14(),
52546
52718
  endpointId: newEndpointId(),
52547
52719
  ...clean2,
52548
52720
  secretHash: hashSecret(secret),
@@ -52638,7 +52810,7 @@ var WebhookManager = class {
52638
52810
  contentType: "application/json",
52639
52811
  eventName: eventName2,
52640
52812
  userAgent: "OpenMausBot webhook tester",
52641
- deliveryId: `test-${randomUUID13()}`
52813
+ deliveryId: `test-${randomUUID14()}`
52642
52814
  });
52643
52815
  }
52644
52816
  recordRejected(endpointId, statusCode, reason, event = {}) {
@@ -52651,7 +52823,7 @@ var WebhookManager = class {
52651
52823
  if (this.options.botState(trigger.botId) === "missing") fail(410, "The assigned MAUS no longer exists");
52652
52824
  const allowed = trigger.eventTypes ?? [];
52653
52825
  if (allowed.length > 0 && (!event.eventName || !allowed.includes(event.eventName))) {
52654
- const deliveryId3 = String(event.deliveryId ?? "").trim().slice(0, 200) || randomUUID13();
52826
+ const deliveryId3 = String(event.deliveryId ?? "").trim().slice(0, 200) || randomUUID14();
52655
52827
  this.appendAttempt(trigger, event, {
52656
52828
  outcome: "ignored",
52657
52829
  statusCode: 202,
@@ -52685,7 +52857,7 @@ var WebhookManager = class {
52685
52857
  if (recent.length >= RATE_LIMIT) fail(429, "Webhook rate limit exceeded");
52686
52858
  recent.push(now);
52687
52859
  this.rate.set(trigger.endpointId, recent);
52688
- const deliveryId2 = requestedDeliveryId || randomUUID13();
52860
+ const deliveryId2 = requestedDeliveryId || randomUUID14();
52689
52861
  const run3 = this.options.enqueue({
52690
52862
  webhookId: trigger.id,
52691
52863
  webhookName: trigger.name,
@@ -52715,7 +52887,7 @@ var WebhookManager = class {
52715
52887
  }
52716
52888
  captureVerification(trigger, event) {
52717
52889
  const receivedAt = this.now();
52718
- const deliveryId2 = String(event.deliveryId ?? "").trim().slice(0, 200) || randomUUID13();
52890
+ const deliveryId2 = String(event.deliveryId ?? "").trim().slice(0, 200) || randomUUID14();
52719
52891
  trigger.verificationPending = false;
52720
52892
  trigger.verifiedAt = receivedAt;
52721
52893
  trigger.lastReceivedAt = receivedAt;
@@ -52749,7 +52921,7 @@ var WebhookManager = class {
52749
52921
  }
52750
52922
  appendAttempt(trigger, event, details) {
52751
52923
  const attempt = {
52752
- id: randomUUID13(),
52924
+ id: randomUUID14(),
52753
52925
  webhookId: trigger.id,
52754
52926
  receivedAt: this.now(),
52755
52927
  outcome: details.outcome,
@@ -52769,7 +52941,7 @@ var WebhookManager = class {
52769
52941
  this.options.emit?.({ kind: "webhook", webhook: publicTrigger(trigger) });
52770
52942
  }
52771
52943
  save() {
52772
- mkdirSync20(dirname13(this.file), { recursive: true });
52944
+ mkdirSync21(dirname13(this.file), { recursive: true });
52773
52945
  writeFileAtomic(
52774
52946
  this.file,
52775
52947
  JSON.stringify({ version: 1, webhooks: this.webhooks, deliveries: this.deliveries, attempts: this.attempts }, null, 2),
@@ -52779,8 +52951,8 @@ var WebhookManager = class {
52779
52951
  };
52780
52952
 
52781
52953
  // server/skill-library.ts
52782
- import { existsSync as existsSync19, readFileSync as readFileSync33, readdirSync as readdirSync7 } from "node:fs";
52783
- import { basename as basename6, join as join44 } from "node:path";
52954
+ import { existsSync as existsSync20, readFileSync as readFileSync34, readdirSync as readdirSync7 } from "node:fs";
52955
+ import { basename as basename6, join as join45 } from "node:path";
52784
52956
  var SAFE_ID = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
52785
52957
  function strings(value) {
52786
52958
  return Array.isArray(value) && value.every((item) => typeof item === "string" && item.trim()) ? value.map((item) => item.trim()) : null;
@@ -52809,26 +52981,26 @@ function parseSkillManifest(value, directory) {
52809
52981
  };
52810
52982
  }
52811
52983
  function loadSkillDirectory(directory) {
52812
- const manifestPath2 = join44(directory, "manifest.json");
52813
- const skillPath = join44(directory, "SKILL.md");
52814
- if (!existsSync19(manifestPath2) || !existsSync19(skillPath)) return null;
52815
- const manifest = parseSkillManifest(JSON.parse(readFileSync33(manifestPath2, "utf8")), directory);
52816
- const instructions = readFileSync33(skillPath, "utf8").trim();
52984
+ const manifestPath2 = join45(directory, "manifest.json");
52985
+ const skillPath = join45(directory, "SKILL.md");
52986
+ if (!existsSync20(manifestPath2) || !existsSync20(skillPath)) return null;
52987
+ const manifest = parseSkillManifest(JSON.parse(readFileSync34(manifestPath2, "utf8")), directory);
52988
+ const instructions = readFileSync34(skillPath, "utf8").trim();
52817
52989
  if (!instructions.startsWith("---")) throw new Error(`${skillPath} has no skill frontmatter`);
52818
52990
  return { manifest, instructions, directory };
52819
52991
  }
52820
- function loadBundledSkills(root = process.env.OMB_SKILLS_DIR || join44(process.cwd(), "skills")) {
52821
- if (!existsSync19(root)) return [];
52992
+ function loadBundledSkills(root = process.env.OMB_SKILLS_DIR || join45(process.cwd(), "skills")) {
52993
+ if (!existsSync20(root)) return [];
52822
52994
  const skills = [];
52823
52995
  for (const name2 of readdirSync7(root).sort()) {
52824
- const directory = join44(root, name2);
52996
+ const directory = join45(root, name2);
52825
52997
  const skill = loadSkillDirectory(directory);
52826
52998
  if (skill) skills.push(skill);
52827
52999
  }
52828
53000
  return skills;
52829
53001
  }
52830
53002
  function loadUserSkills(root) {
52831
- if (!existsSync19(root)) return [];
53003
+ if (!existsSync20(root)) return [];
52832
53004
  let names;
52833
53005
  try {
52834
53006
  names = readdirSync7(root).sort();
@@ -52838,7 +53010,7 @@ function loadUserSkills(root) {
52838
53010
  const skills = [];
52839
53011
  for (const name2 of names) {
52840
53012
  try {
52841
- const skill = loadSkillDirectory(join44(root, name2));
53013
+ const skill = loadSkillDirectory(join45(root, name2));
52842
53014
  if (skill) skills.push(skill);
52843
53015
  } catch {
52844
53016
  }
@@ -53484,7 +53656,7 @@ var PendingTurnCancellations = class {
53484
53656
  this.#ownersByThread.delete(threadId);
53485
53657
  const waiters = this.#clearWaitersByThread.get(threadId);
53486
53658
  this.#clearWaitersByThread.delete(threadId);
53487
- for (const resolve10 of waiters ?? []) resolve10();
53659
+ for (const resolve11 of waiters ?? []) resolve11();
53488
53660
  }
53489
53661
  /** Do not overlap a replacement dispatch with the ambiguous pre-id window.
53490
53662
  * Re-check after every wake: a cancellation can be renewed in the same
@@ -53492,14 +53664,14 @@ var PendingTurnCancellations = class {
53492
53664
  * expiry, so a broken adapter cannot strand this await forever. */
53493
53665
  async waitForClear(threadId) {
53494
53666
  while (this.has(threadId)) {
53495
- await new Promise((resolve10) => {
53667
+ await new Promise((resolve11) => {
53496
53668
  const waiters = this.#clearWaitersByThread.get(threadId) ?? /* @__PURE__ */ new Set();
53497
- waiters.add(resolve10);
53669
+ waiters.add(resolve11);
53498
53670
  this.#clearWaitersByThread.set(threadId, waiters);
53499
53671
  if (!this.has(threadId)) {
53500
- waiters.delete(resolve10);
53672
+ waiters.delete(resolve11);
53501
53673
  if (waiters.size === 0) this.#clearWaitersByThread.delete(threadId);
53502
- resolve10();
53674
+ resolve11();
53503
53675
  }
53504
53676
  });
53505
53677
  }
@@ -53526,8 +53698,8 @@ function createGracefulShutdown({
53526
53698
  if (started) return;
53527
53699
  started = true;
53528
53700
  let timer;
53529
- const deadline = new Promise((resolve10) => {
53530
- timer = setTimeout(resolve10, timeoutMs);
53701
+ const deadline = new Promise((resolve11) => {
53702
+ timer = setTimeout(resolve11, timeoutMs);
53531
53703
  timer.unref?.();
53532
53704
  });
53533
53705
  const settled = Promise.allSettled(cleanup.map((job) => Promise.resolve().then(job))).then(() => void 0);
@@ -53539,10 +53711,10 @@ function createGracefulShutdown({
53539
53711
  }
53540
53712
 
53541
53713
  // electron/data-dir-lease.mjs
53542
- import { createHash as createHash20, randomUUID as randomUUID14 } from "node:crypto";
53543
- import { existsSync as existsSync20, linkSync as linkSync4, mkdirSync as mkdirSync21, readFileSync as readFileSync34, renameSync as renameSync5, unlinkSync as unlinkSync8, writeFileSync as writeFileSync15 } from "node:fs";
53714
+ import { createHash as createHash21, randomUUID as randomUUID15 } from "node:crypto";
53715
+ import { existsSync as existsSync21, linkSync as linkSync4, mkdirSync as mkdirSync22, readFileSync as readFileSync35, renameSync as renameSync6, unlinkSync as unlinkSync8, writeFileSync as writeFileSync16 } from "node:fs";
53544
53716
  import { hostname as hostname4 } from "node:os";
53545
- import { join as join45 } from "node:path";
53717
+ import { join as join46 } from "node:path";
53546
53718
  var LEASE_NAME = "openmausbot-server.lease";
53547
53719
  var DELEGATED_CHILD_DIR = ".openmausbot-server-child";
53548
53720
  var CHILD_LEASE_ENV = "OPENMAUSBOT_INTERNAL_DATA_DIR_LEASE";
@@ -53568,7 +53740,7 @@ function isReaperOwner(value, targetToken) {
53568
53740
  function parseRecord(path, invalidMessage, validate) {
53569
53741
  let raw;
53570
53742
  try {
53571
- raw = readFileSync34(path, "utf8");
53743
+ raw = readFileSync35(path, "utf8");
53572
53744
  } catch (error51) {
53573
53745
  if (error51?.code === "ENOENT") return null;
53574
53746
  throw leaseError("OpenMausBot cannot read the data-directory lease; refusing to start to protect its state.", error51);
@@ -53616,7 +53788,7 @@ function unlinkExact(path, message3) {
53616
53788
  function publishRecord(path, record2, prepareMessage, acquireMessage) {
53617
53789
  const candidatePath = `${path}.candidate-${record2.pid}-${record2.token}`;
53618
53790
  try {
53619
- writeFileSync15(candidatePath, `${JSON.stringify(record2)}
53791
+ writeFileSync16(candidatePath, `${JSON.stringify(record2)}
53620
53792
  `, { flag: "wx", mode: 384, flush: true });
53621
53793
  } catch (error51) {
53622
53794
  throw leaseError(prepareMessage, error51);
@@ -53634,7 +53806,7 @@ function publishRecord(path, record2, prepareMessage, acquireMessage) {
53634
53806
  }
53635
53807
  }
53636
53808
  function successorReaperPath2(leasePath, targetToken, reaperToken) {
53637
- const digest = createHash20("sha256").update(reaperToken).digest("hex").slice(0, 32);
53809
+ const digest = createHash21("sha256").update(reaperToken).digest("hex").slice(0, 32);
53638
53810
  return `${leasePath}.reap-${targetToken}-${digest}`;
53639
53811
  }
53640
53812
  function claimReaperAuthority2(leasePath, expected) {
@@ -53644,7 +53816,7 @@ function claimReaperAuthority2(leasePath, expected) {
53644
53816
  version: 1,
53645
53817
  pid: process.pid,
53646
53818
  host: hostname4(),
53647
- token: randomUUID14(),
53819
+ token: randomUUID15(),
53648
53820
  createdAt: Date.now(),
53649
53821
  targetToken: expected.token
53650
53822
  };
@@ -53689,22 +53861,22 @@ function prepareDataDir(dataDir, legacyDataDir) {
53689
53861
  validateDataDir(dataDir);
53690
53862
  if (legacyDataDir !== void 0) {
53691
53863
  validateDataDir(legacyDataDir);
53692
- if (!existsSync20(dataDir) && existsSync20(legacyDataDir)) {
53864
+ if (!existsSync21(dataDir) && existsSync21(legacyDataDir)) {
53693
53865
  try {
53694
- renameSync5(legacyDataDir, dataDir);
53866
+ renameSync6(legacyDataDir, dataDir);
53695
53867
  } catch {
53696
53868
  }
53697
53869
  }
53698
53870
  }
53699
53871
  try {
53700
- mkdirSync21(dataDir, { recursive: true, mode: 448 });
53872
+ mkdirSync22(dataDir, { recursive: true, mode: 448 });
53701
53873
  } catch (error51) {
53702
53874
  throw leaseError("OpenMausBot cannot create its data directory.", error51);
53703
53875
  }
53704
- return join45(dataDir, LEASE_NAME);
53876
+ return join46(dataDir, LEASE_NAME);
53705
53877
  }
53706
53878
  function assertNoLiveDelegatedChild(dataDir) {
53707
- const childLeasePath = join45(dataDir, DELEGATED_CHILD_DIR, LEASE_NAME);
53879
+ const childLeasePath = join46(dataDir, DELEGATED_CHILD_DIR, LEASE_NAME);
53708
53880
  const child = readOwner(childLeasePath);
53709
53881
  if (!child) return;
53710
53882
  if (child.host !== hostname4()) {
@@ -53746,13 +53918,13 @@ function validateChildDelegation(dataDir, encoded) {
53746
53918
  const capability = parseCapability(encoded);
53747
53919
  const invalid = () => leaseError("The OpenMausBot desktop lease delegation is invalid; refusing to start to protect its state.");
53748
53920
  if (!capability) throw invalid();
53749
- const parentLeasePath = join45(dataDir, LEASE_NAME);
53921
+ const parentLeasePath = join46(dataDir, LEASE_NAME);
53750
53922
  const matchesLiveParent = (owner2) => Boolean(owner2 && owner2.pid === capability.pid && owner2.token === capability.token && owner2.host === hostname4() && processIsAlive2(owner2.pid));
53751
53923
  if (!matchesLiveParent(readOwner(parentLeasePath))) {
53752
53924
  throw invalid();
53753
53925
  }
53754
53926
  const childLease = acquireDataDirLeaseInternal(
53755
- join45(dataDir, DELEGATED_CHILD_DIR),
53927
+ join46(dataDir, DELEGATED_CHILD_DIR),
53756
53928
  { guardDelegatedChild: false }
53757
53929
  );
53758
53930
  if (!matchesLiveParent(readOwner(parentLeasePath))) {
@@ -53774,12 +53946,12 @@ function acquireDataDirLeaseInternal(dataDir, options = {}) {
53774
53946
  version: 1,
53775
53947
  pid: process.pid,
53776
53948
  host: hostname4(),
53777
- token: randomUUID14(),
53949
+ token: randomUUID15(),
53778
53950
  createdAt: Date.now()
53779
53951
  };
53780
53952
  const candidatePath = `${leasePath}.candidate-${owner2.pid}-${owner2.token}`;
53781
53953
  try {
53782
- writeFileSync15(candidatePath, `${JSON.stringify(owner2)}
53954
+ writeFileSync16(candidatePath, `${JSON.stringify(owner2)}
53783
53955
  `, { flag: "wx", mode: 384, flush: true });
53784
53956
  } catch (error51) {
53785
53957
  throw leaseError("OpenMausBot cannot prepare its data-directory lease.", error51);
@@ -53850,15 +54022,15 @@ function acquireDataDirLeaseForProcess(dataDir, environment = process.env) {
53850
54022
  }
53851
54023
 
53852
54024
  // server/enterprise.ts
53853
- import { existsSync as existsSync21 } from "node:fs";
53854
- import { join as join46 } from "node:path";
54025
+ import { existsSync as existsSync22 } from "node:fs";
54026
+ import { join as join47 } from "node:path";
53855
54027
  import { pathToFileURL } from "node:url";
53856
54028
  var layerSchema = external_exports.object({
53857
54029
  customer: external_exports.string().min(1),
53858
54030
  features: external_exports.array(external_exports.string().min(1)),
53859
54031
  expiresAt: external_exports.string().nullable()
53860
54032
  });
53861
- var DEFAULT_DIR = join46(SERVER_ROOT, "..", "enterprise");
54033
+ var DEFAULT_DIR = join47(SERVER_ROOT, "..", "enterprise");
53862
54034
  var current = { edition: "oss", features: [] };
53863
54035
  function oss(notice) {
53864
54036
  current = notice ? { edition: "oss", features: [], notice } : { edition: "oss", features: [] };
@@ -53867,7 +54039,7 @@ function oss(notice) {
53867
54039
  async function loadEnterpriseLayer(options = {}) {
53868
54040
  const dir = options.dir ?? process.env.OMB_ENTERPRISE_DIR ?? DEFAULT_DIR;
53869
54041
  const licenseKey = options.licenseKey ?? process.env.OMB_LICENSE_KEY;
53870
- const entry = [join46(dir, "server", "index.ts"), join46(dir, "server", "index.js")].find((candidate) => existsSync21(candidate));
54042
+ const entry = [join47(dir, "server", "index.ts"), join47(dir, "server", "index.js")].find((candidate) => existsSync22(candidate));
53871
54043
  if (!entry) {
53872
54044
  return oss(
53873
54045
  licenseKey ? `OMB_LICENSE_KEY is set but no enterprise layer exists at ${dir}` : void 0
@@ -54327,8 +54499,8 @@ function resolveRequestAuth(req, options) {
54327
54499
  }
54328
54500
 
54329
54501
  // server/sessions.ts
54330
- import { createHash as createHash21, randomBytes as randomBytes6, randomUUID as randomUUID15, timingSafeEqual as timingSafeEqual3 } from "node:crypto";
54331
- import { chmodSync as chmodSync5, existsSync as existsSync22, mkdirSync as mkdirSync22, readFileSync as readFileSync35, renameSync as renameSync6, writeFileSync as writeFileSync16 } from "node:fs";
54502
+ import { createHash as createHash22, randomBytes as randomBytes7, randomUUID as randomUUID16, timingSafeEqual as timingSafeEqual3 } from "node:crypto";
54503
+ import { chmodSync as chmodSync6, existsSync as existsSync23, mkdirSync as mkdirSync23, readFileSync as readFileSync36, renameSync as renameSync7, writeFileSync as writeFileSync17 } from "node:fs";
54332
54504
  import { dirname as dirname14 } from "node:path";
54333
54505
  var SCOPES = ["admin", "client"];
54334
54506
  var PAIRING_CODE_ALPHABET = "23456789ABCDEFGHJKLMNPQRSTUVWXYZ";
@@ -54351,7 +54523,7 @@ var sessionSchema = external_exports.object({
54351
54523
  expiresAt: external_exports.number()
54352
54524
  });
54353
54525
  var fileSchema2 = external_exports.object({ version: external_exports.literal(1), sessions: external_exports.array(sessionSchema) });
54354
- var sha2562 = (value) => createHash21("sha256").update(value).digest("hex");
54526
+ var sha2562 = (value) => createHash22("sha256").update(value).digest("hex");
54355
54527
  function sameDigest(a, b) {
54356
54528
  const left = Buffer.from(a, "hex");
54357
54529
  const right = Buffer.from(b, "hex");
@@ -54361,7 +54533,7 @@ function generatePairingCode() {
54361
54533
  const limit = Math.floor(256 / PAIRING_CODE_ALPHABET.length) * PAIRING_CODE_ALPHABET.length;
54362
54534
  let code = "";
54363
54535
  while (code.length < PAIRING_CODE_LENGTH) {
54364
- for (const byte of randomBytes6(PAIRING_CODE_LENGTH)) {
54536
+ for (const byte of randomBytes7(PAIRING_CODE_LENGTH)) {
54365
54537
  if (byte >= limit) continue;
54366
54538
  code += PAIRING_CODE_ALPHABET[byte % PAIRING_CODE_ALPHABET.length];
54367
54539
  if (code.length === PAIRING_CODE_LENGTH) break;
@@ -54403,10 +54575,10 @@ var SessionRegistry = class {
54403
54575
  this.load();
54404
54576
  }
54405
54577
  load() {
54406
- if (!existsSync22(this.options.file)) return;
54578
+ if (!existsSync23(this.options.file)) return;
54407
54579
  let raw;
54408
54580
  try {
54409
- raw = JSON.parse(readFileSync35(this.options.file, "utf8"));
54581
+ raw = JSON.parse(readFileSync36(this.options.file, "utf8"));
54410
54582
  } catch {
54411
54583
  return;
54412
54584
  }
@@ -54416,11 +54588,11 @@ var SessionRegistry = class {
54416
54588
  /** Atomic write, owner-only, directory owner-only. */
54417
54589
  persist() {
54418
54590
  const dir = dirname14(this.options.file);
54419
- mkdirSync22(dir, { recursive: true, mode: 448 });
54591
+ mkdirSync23(dir, { recursive: true, mode: 448 });
54420
54592
  const tmp = `${this.options.file}.${process.pid}.tmp`;
54421
- writeFileSync16(tmp, JSON.stringify({ version: 1, sessions: this.sessions }, null, 2) + "\n", { mode: 384 });
54422
- chmodSync5(tmp, 384);
54423
- renameSync6(tmp, this.options.file);
54593
+ writeFileSync17(tmp, JSON.stringify({ version: 1, sessions: this.sessions }, null, 2) + "\n", { mode: 384 });
54594
+ chmodSync6(tmp, 384);
54595
+ renameSync7(tmp, this.options.file);
54424
54596
  }
54425
54597
  prune() {
54426
54598
  const now = this.now();
@@ -54455,7 +54627,7 @@ var SessionRegistry = class {
54455
54627
  const code = generatePairingCode();
54456
54628
  const scopes = input.scopes?.length ? [...new Set(input.scopes)] : [...SCOPES];
54457
54629
  const pairing = {
54458
- id: randomUUID15(),
54630
+ id: randomUUID16(),
54459
54631
  codeHash: sha2562(code),
54460
54632
  scopes,
54461
54633
  label: (input.label ?? "").trim().slice(0, 80),
@@ -54525,9 +54697,9 @@ var SessionRegistry = class {
54525
54697
  }
54526
54698
  const [pairing] = this.pairings.splice(index2, 1);
54527
54699
  this.failures.delete(input.source);
54528
- const token = `omb_sess_${randomBytes6(32).toString("base64url")}`;
54700
+ const token = `omb_sess_${randomBytes7(32).toString("base64url")}`;
54529
54701
  const record2 = {
54530
- id: randomUUID15(),
54702
+ id: randomUUID16(),
54531
54703
  tokenHash: sha2562(token),
54532
54704
  label: (input.label.trim() || pairing.label || input.fallbackLabel?.trim() || "Unnamed device").slice(0, 80),
54533
54705
  scopes: [...pairing.scopes],
@@ -54579,7 +54751,7 @@ var SessionRegistry = class {
54579
54751
  this.prune();
54580
54752
  const mine = [...this.tickets].filter(([, t]) => t.sessionId === sessionId).sort((a, b) => a[1].expiresAt - b[1].expiresAt);
54581
54753
  for (const [hash2] of mine.slice(0, Math.max(0, mine.length - (MAX_STREAM_TICKETS_PER_SESSION - 1)))) this.tickets.delete(hash2);
54582
- const ticket = `omb_tick_${randomBytes6(24).toString("base64url")}`;
54754
+ const ticket = `omb_tick_${randomBytes7(24).toString("base64url")}`;
54583
54755
  const expiresAt = this.now() + STREAM_TICKET_TTL_MS;
54584
54756
  this.tickets.set(sha2562(ticket), { sessionId, expiresAt });
54585
54757
  return { ticket, expiresAt };
@@ -54598,8 +54770,8 @@ var SessionRegistry = class {
54598
54770
  };
54599
54771
 
54600
54772
  // server/brand.ts
54601
- import { existsSync as existsSync23, readFileSync as readFileSync36 } from "node:fs";
54602
- import { join as join47 } from "node:path";
54773
+ import { existsSync as existsSync24, readFileSync as readFileSync37 } from "node:fs";
54774
+ import { join as join48 } from "node:path";
54603
54775
  var HEX_COLOUR = /^#[0-9a-fA-F]{6}$/;
54604
54776
  var MAX_LOGO_CHARS = 3e5;
54605
54777
  var brandSchema = external_exports.object({
@@ -54616,16 +54788,16 @@ var brandSchema = external_exports.object({
54616
54788
  }).strict();
54617
54789
  var DEFAULT_BRAND = { name: "OpenMausBot" };
54618
54790
  function brandFile() {
54619
- return process.env.OMB_BRAND_FILE || join47(DATA_DIR, "brand.json");
54791
+ return process.env.OMB_BRAND_FILE || join48(DATA_DIR, "brand.json");
54620
54792
  }
54621
54793
  function loadBrand(options = {}) {
54622
54794
  const file2 = options.file ?? brandFile();
54623
54795
  const isEntitled = options.isEntitled ?? entitled;
54624
54796
  const fallback = (notice) => notice ? { brand: DEFAULT_BRAND, source: "default", file: file2, notice } : { brand: DEFAULT_BRAND, source: "default", file: file2 };
54625
- if (!existsSync23(file2)) return fallback();
54797
+ if (!existsSync24(file2)) return fallback();
54626
54798
  let raw;
54627
54799
  try {
54628
- raw = JSON.parse(readFileSync36(file2, "utf8"));
54800
+ raw = JSON.parse(readFileSync37(file2, "utf8"));
54629
54801
  } catch (error51) {
54630
54802
  return fallback(`${file2} is not valid JSON (${error51 instanceof Error ? error51.message : String(error51)}); using the default brand`);
54631
54803
  }
@@ -54646,7 +54818,7 @@ function describeBrand(status) {
54646
54818
  }
54647
54819
 
54648
54820
  // server/phone-secret.ts
54649
- import { createECDH, createHash as createHash22 } from "node:crypto";
54821
+ import { createECDH, createHash as createHash23 } from "node:crypto";
54650
54822
 
54651
54823
  // node_modules/.pnpm/@hpke+common@1.10.1/node_modules/@hpke/common/esm/src/errors.js
54652
54824
  var HpkeError = class extends Error {
@@ -56345,8 +56517,8 @@ var Mutex = class {
56345
56517
  }
56346
56518
  async lock() {
56347
56519
  let releaseLock;
56348
- const nextLock = new Promise((resolve10) => {
56349
- releaseLock = resolve10;
56520
+ const nextLock = new Promise((resolve11) => {
56521
+ releaseLock = resolve11;
56350
56522
  });
56351
56523
  const previousLock = __classPrivateFieldGet(this, _Mutex_locked, "f");
56352
56524
  __classPrivateFieldSet(this, _Mutex_locked, nextLock, "f");
@@ -56830,7 +57002,7 @@ function phoneSecretKeyIdFromJwk(jwk) {
56830
57002
  const x = decodeBase64URL(jwk.x, 32);
56831
57003
  const y = decodeBase64URL(jwk.y, 32);
56832
57004
  if (!x || !y) return null;
56833
- return createHash22("sha256").update(Buffer.concat([Buffer.from([4]), x, y])).digest().subarray(0, 16).toString("base64url");
57005
+ return createHash23("sha256").update(Buffer.concat([Buffer.from([4]), x, y])).digest().subarray(0, 16).toString("base64url");
56834
57006
  }
56835
57007
  function phoneSecretAAD(context) {
56836
57008
  const fields = [
@@ -56850,7 +57022,7 @@ function phoneSecretAAD(context) {
56850
57022
  }
56851
57023
  function phoneSecretOperationId(context) {
56852
57024
  const aad = phoneSecretAAD(context);
56853
- return createHash22("sha256").update(aad).update("\0").update(String(context.version)).update("\n").update(context.encapsulatedKey).update("\n").update(context.ciphertext).digest("base64url");
57025
+ return createHash23("sha256").update(aad).update("\0").update(String(context.version)).update("\n").update(context.encapsulatedKey).update("\n").update(context.ciphertext).digest("base64url");
56854
57026
  }
56855
57027
  function assertPhoneSecretRequestMatches(context, authenticatedDeviceId, expected) {
56856
57028
  if (context.deviceId !== authenticatedDeviceId || context.target !== expected.target || context.requestKey !== expected.requestKey) {
@@ -57062,13 +57234,13 @@ var PhoneSecretBridge = class {
57062
57234
  throw new PhoneSecretError("The credential must be between 1 and 4096 bytes");
57063
57235
  }
57064
57236
  const requestId = phoneSecretOperationId(context);
57065
- await new Promise((resolve10, reject) => {
57237
+ await new Promise((resolve11, reject) => {
57066
57238
  const timer = setTimeout(() => {
57067
57239
  this.pending.delete(requestId);
57068
57240
  reject(new PhoneSecretError("The operating-system credential store did not respond. Try again.", 504));
57069
57241
  }, this.timeoutMs);
57070
57242
  timer.unref?.();
57071
- this.pending.set(requestId, { resolve: resolve10, reject, timer });
57243
+ this.pending.set(requestId, { resolve: resolve11, reject, timer });
57072
57244
  if (this.send({
57073
57245
  type: "openmausbot:phone-secret-save",
57074
57246
  requestId,
@@ -57112,7 +57284,7 @@ function releaseDataDirLeaseAtExit() {
57112
57284
  }
57113
57285
  process.once("exit", releaseDataDirLeaseAtExit);
57114
57286
  var ENVIRONMENT_ID = loadEnvironmentId(DATA_DIR);
57115
- var sessions = new SessionRegistry({ file: join48(DATA_DIR, "sessions.json") });
57287
+ var sessions = new SessionRegistry({ file: join49(DATA_DIR, "sessions.json") });
57116
57288
  var SESSION_COOKIE = sessionCookieName(PORT, ENVIRONMENT_ID);
57117
57289
  var DESKTOP_MANAGED = process.env.OMB_DESKTOP_PARENT === "1";
57118
57290
  var desktopMutationToken = DESKTOP_MANAGED ? "" : void 0;
@@ -57122,7 +57294,7 @@ var cfg = loadConfig();
57122
57294
  var registry2 = new ProviderRegistry(BUILT_IN_DRIVERS);
57123
57295
  await registry2.load(instanceConfigs(cfg));
57124
57296
  var bundledSkills = loadBundledSkills();
57125
- var availableSkills = () => mergeSkills(bundledSkills, loadUserSkills(join48(DATA_DIR, "skills")));
57297
+ var availableSkills = () => mergeSkills(bundledSkills, loadUserSkills(join49(DATA_DIR, "skills")));
57126
57298
  var utilityParentPort = process.parentPort;
57127
57299
  function postDesktopPrivateMessage(message3) {
57128
57300
  if (!utilityParentPort) return false;
@@ -57148,7 +57320,7 @@ function applyDesktopMutationTokenMessage(raw) {
57148
57320
  return true;
57149
57321
  }
57150
57322
  var browserCleanup = new BrowserCleanupCoordinator({
57151
- file: join48(DATA_DIR, "browser-cleanups.json"),
57323
+ file: join49(DATA_DIR, "browser-cleanups.json"),
57152
57324
  send: postDesktopPrivateMessage
57153
57325
  });
57154
57326
  var phoneSecrets = new PhoneSecretBridge(postDesktopPrivateMessage);
@@ -57170,7 +57342,7 @@ var INTERNAL_CAPABILITY_ORPHAN_MS = 30 * 24 * 60 * 6e4;
57170
57342
  var internalCapabilities = /* @__PURE__ */ new Map();
57171
57343
  var activeInternalGenerationByThread = /* @__PURE__ */ new Map();
57172
57344
  var internalGenerationByProviderTurn = new ProviderTurnGenerationRegistry();
57173
- function beginInternalCapabilityGeneration(threadId, generation = randomUUID16()) {
57345
+ function beginInternalCapabilityGeneration(threadId, generation = randomUUID17()) {
57174
57346
  const previous2 = activeInternalGenerationByThread.get(threadId);
57175
57347
  if (previous2) revokeInternalCapabilityGeneration(threadId, previous2);
57176
57348
  activeInternalGenerationByThread.set(threadId, generation);
@@ -57180,7 +57352,7 @@ function mintInternalCapability(capability) {
57180
57352
  if (activeInternalGenerationByThread.get(capability.threadId) !== capability.generation) {
57181
57353
  throw new Error("cannot mint an integration capability for an inactive turn");
57182
57354
  }
57183
- const token = randomBytes7(24).toString("hex");
57355
+ const token = randomBytes8(24).toString("hex");
57184
57356
  internalCapabilities.set(token, {
57185
57357
  ...capability,
57186
57358
  orphanExpiresAt: Date.now() + INTERNAL_CAPABILITY_ORPHAN_MS
@@ -57422,9 +57594,9 @@ function cancelDirectTurnDispatch(botId, expectedThreadId) {
57422
57594
  }
57423
57595
  return claim;
57424
57596
  }
57425
- async function browserIntegration(botId, profile, threadId, generation, stillValid = () => true, ownerId = randomUUID16()) {
57597
+ async function browserIntegration(botId, profile, threadId, generation, stillValid = () => true, ownerId = randomUUID17()) {
57426
57598
  const connection = availableBrowserConnection();
57427
- if (!connection) return null;
57599
+ if (!connection) return engineBrowserIntegration(botId, profile);
57428
57600
  const control = controlIntegration(botId, threadId, generation);
57429
57601
  const profileTarget = profile && profile !== "guest" ? browserProfilePartitionTarget(cfg, profile) : null;
57430
57602
  const partitionId = profile === "guest" ? "guest" : profileTarget?.partitionId ?? "";
@@ -57455,6 +57627,36 @@ async function browserIntegration(botId, profile, threadId, generation, stillVal
57455
57627
  }
57456
57628
  };
57457
57629
  }
57630
+ function engineBrowserIntegration(botId, profile) {
57631
+ const status = browserEngineStatus();
57632
+ if (status.kind !== "ready") {
57633
+ if (!engineUnavailableLogged) {
57634
+ engineUnavailableLogged = true;
57635
+ console.warn(`${describeBrowserEngine(status)}; bots get no browser tools until it is installed`);
57636
+ }
57637
+ return null;
57638
+ }
57639
+ const profileTarget = profile && profile !== "guest" ? browserProfilePartitionTarget(cfg, profile) : null;
57640
+ const partitionId = profile === "guest" ? "guest" : profileTarget?.partitionId ?? "";
57641
+ const session = browserSessionId(botId, partitionId);
57642
+ return {
57643
+ connection: null,
57644
+ capability: null,
57645
+ profile: partitionId,
57646
+ integration: agentBrowserIntegration({
57647
+ binaryPath: status.binaryPath,
57648
+ session,
57649
+ encryptionKey: browserEngineEncryptionKey(),
57650
+ persistent: profile !== "guest"
57651
+ })
57652
+ };
57653
+ }
57654
+ var engineUnavailableLogged = false;
57655
+ function browserEngineSummary() {
57656
+ if (availableBrowserConnection()) return { kind: "desktop" };
57657
+ const status = browserEngineStatus();
57658
+ return status.kind === "ready" ? { kind: "headless", version: status.version } : { kind: "unavailable", reason: status.reason, installable: status.installable };
57659
+ }
57458
57660
  function phoneIntegration() {
57459
57661
  const env = { ...AGENTS_NODE_FLAG };
57460
57662
  if (process.env.OMB_ADB_PATH) env.OMB_ADB_PATH = process.env.OMB_ADB_PATH;
@@ -57522,7 +57724,7 @@ function askBotAndWait(targetBotId, message3, depth, fromBotId) {
57522
57724
  const target = store.bot(targetBotId);
57523
57725
  if (!target) return Promise.resolve({ status: "error", text: "(no such bot)" });
57524
57726
  const threadId = target.threadId;
57525
- return new Promise((resolve10) => {
57727
+ return new Promise((resolve11) => {
57526
57728
  let text6 = "";
57527
57729
  let done = false;
57528
57730
  const finish = (out) => {
@@ -57530,7 +57732,7 @@ function askBotAndWait(targetBotId, message3, depth, fromBotId) {
57530
57732
  done = true;
57531
57733
  clearTimeout(timer);
57532
57734
  unsub();
57533
- resolve10(out);
57735
+ resolve11(out);
57534
57736
  };
57535
57737
  const unsub = bus.subscribe((e) => {
57536
57738
  if (shouldIgnoreProviderEvent(e)) return;
@@ -58007,7 +58209,7 @@ function publicGroupState(group) {
58007
58209
  }
58008
58210
  function beginGroupTurnOperation(groupId, threadId, botIds = []) {
58009
58211
  const operation = {
58010
- id: randomUUID16(),
58212
+ id: randomUUID17(),
58011
58213
  threadId,
58012
58214
  botIds: new Set(botIds),
58013
58215
  cancelled: false,
@@ -58117,7 +58319,7 @@ async function waitForGroupMemberBot(bot, operation, onWaiting) {
58117
58319
  const initial = groupMemberBotAvailability(bot.id, operation);
58118
58320
  if (initial !== "busy") return initial;
58119
58321
  onWaiting(`${bot.name} is finishing another conversation.`);
58120
- return await new Promise((resolve10) => {
58322
+ return await new Promise((resolve11) => {
58121
58323
  let settled = false;
58122
58324
  let unsubscribe = () => {
58123
58325
  };
@@ -58127,7 +58329,7 @@ async function waitForGroupMemberBot(bot, operation, onWaiting) {
58127
58329
  clearTimeout(waitCap);
58128
58330
  unsubscribe();
58129
58331
  operation.cancellation.signal.removeEventListener("abort", onAbort);
58130
- resolve10(availability);
58332
+ resolve11(availability);
58131
58333
  };
58132
58334
  const waitCap = setTimeout(() => finish("timed_out"), GROUP_GOAL_WAIT_MAX_MS);
58133
58335
  waitCap.unref?.();
@@ -58307,7 +58509,7 @@ sessions.onSessionRevoked((sessionId) => {
58307
58509
  }
58308
58510
  }
58309
58511
  });
58310
- var STREAM_ID = randomUUID16().slice(0, 8);
58512
+ var STREAM_ID = randomUUID17().slice(0, 8);
58311
58513
  var REPLAY_MAX = 500;
58312
58514
  var configuredSseHeartbeatMs = Number(process.env.OMB_SSE_HEARTBEAT_MS);
58313
58515
  var SSE_HEARTBEAT_MS = Number.isFinite(configuredSseHeartbeatMs) && configuredSseHeartbeatMs > 0 ? configuredSseHeartbeatMs : 15e3;
@@ -59172,7 +59374,7 @@ function markTaskContextExternallyUpdated(bot, threadId) {
59172
59374
  const task2 = store.taskByThread(bot.id, threadId);
59173
59375
  if (!task2) return;
59174
59376
  task2.resumeCursors = {};
59175
- task2.lastInstanceId = `${EXTERNAL_CONTEXT_MARKER_PREFIX}${randomUUID16()}`;
59377
+ task2.lastInstanceId = `${EXTERNAL_CONTEXT_MARKER_PREFIX}${randomUUID17()}`;
59176
59378
  const patch = { unread: true };
59177
59379
  if (bot.threadId === threadId) patch.resumeCursors = {};
59178
59380
  store.patchBot(bot.id, patch);
@@ -59512,7 +59714,7 @@ async function startTurn(botId, text6, opts) {
59512
59714
  }
59513
59715
  let userMessage = opts?.userMessage;
59514
59716
  if (!userMessage) {
59515
- userMessage = opts?.cardContinuation ? { id: `card-${randomUUID16()}`, at: Date.now(), role: "user", kind: "text", text: text6 } : store.appendMessage(threadId, {
59717
+ userMessage = opts?.cardContinuation ? { id: `card-${randomUUID17()}`, at: Date.now(), role: "user", kind: "text", text: text6 } : store.appendMessage(threadId, {
59516
59718
  role: "user",
59517
59719
  kind: "text",
59518
59720
  text: text6,
@@ -59563,7 +59765,7 @@ async function startTurn(botId, text6, opts) {
59563
59765
  const drift = checkSoulDrift(bot.id, bot.soul ?? "", bot.soulHash ?? "");
59564
59766
  if (drift.drift !== Boolean(bot.soulDrift)) store.patchBot(bot.id, { soulDrift: drift.drift });
59565
59767
  }
59566
- const dispatchClaimId = randomUUID16();
59768
+ const dispatchClaimId = randomUUID17();
59567
59769
  directTurnGenerationByBot.set(bot.id, dispatchClaimId);
59568
59770
  directTurnDispatchClaims.set(bot.id, { id: dispatchClaimId, threadId, phase: "setup" });
59569
59771
  beginInternalCapabilityGeneration(threadId, dispatchClaimId);
@@ -59852,9 +60054,9 @@ async function startTurn(botId, text6, opts) {
59852
60054
  if (!isExternalContextMarker(task2.lastInstanceId) || task2.lastInstanceId === externalContextMarker) {
59853
60055
  store.markTaskDispatched(bot.id, threadId, instanceId);
59854
60056
  }
59855
- if (!previewCapture && browser) {
59856
- const { connection } = browser;
59857
- previewCapture = () => browserScreenshot(connection, browser.capability, fetch);
60057
+ if (!previewCapture && browser?.connection && browser.capability) {
60058
+ const { connection, capability } = browser;
60059
+ previewCapture = () => browserScreenshot(connection, capability, fetch);
59858
60060
  }
59859
60061
  if (previewCapture && store.bot(bot.id)?.busy) {
59860
60062
  startScreenPoller(bot.id, previewCapture, { screenIsTheWork: instance.driverKind === "boxAgent" });
@@ -60599,7 +60801,7 @@ ${memorySystemPrompt(bot.id).trim()}` : "" },
60599
60801
  let replyText = "";
60600
60802
  let providerTurnId;
60601
60803
  let abandoned = false;
60602
- const retirementOwner = `room-abandoned:${randomUUID16()}`;
60804
+ const retirementOwner = `room-abandoned:${randomUUID17()}`;
60603
60805
  const abandonProviderTurn = () => {
60604
60806
  if (abandoned) return;
60605
60807
  abandoned = true;
@@ -60608,7 +60810,7 @@ ${memorySystemPrompt(bot.id).trim()}` : "" },
60608
60810
  else markCancelledProviderHandshake(threadId, retirementOwner);
60609
60811
  };
60610
60812
  const timeoutMinutes = roomTurnTimeoutMinutes(cfg);
60611
- const outcome = await new Promise((resolve10) => {
60813
+ const outcome = await new Promise((resolve11) => {
60612
60814
  let done = false;
60613
60815
  let unsub = () => {
60614
60816
  };
@@ -60633,7 +60835,7 @@ ${memorySystemPrompt(bot.id).trim()}` : "" },
60633
60835
  deadline.stop();
60634
60836
  unsub();
60635
60837
  unregisterStall();
60636
- resolve10(value);
60838
+ resolve11(value);
60637
60839
  };
60638
60840
  unsub = bus.subscribe((e) => {
60639
60841
  if (shouldIgnoreProviderEvent(e)) return;
@@ -61146,7 +61348,7 @@ function startGroupTurn(groupId, text6, replyTo, sendId, channelMode = "chat", q
61146
61348
  goalCoordinator ? [] : responders.map((responder) => responder.id)
61147
61349
  );
61148
61350
  if (goalCoordinator) {
61149
- const runId = options.goalRunId?.trim() || `goal-${Date.now().toString(36)}-${randomUUID16()}`;
61351
+ const runId = options.goalRunId?.trim() || `goal-${Date.now().toString(36)}-${randomUUID17()}`;
61150
61352
  const startedAt = Date.now();
61151
61353
  const detail = `${goalCoordinator.name} is coordinating this goal.`;
61152
61354
  const card = store.appendMessage(threadId, {
@@ -61400,7 +61602,7 @@ Adds one line to the prompt index; the body is read only when used.${warnings}`,
61400
61602
  };
61401
61603
  }
61402
61604
  function appendSkillRequestCard(args) {
61403
- const requestId = randomUUID16();
61605
+ const requestId = randomUUID17();
61404
61606
  const copy = skillCardCopy(args.staged);
61405
61607
  const payload = {
61406
61608
  version: 1,
@@ -61506,7 +61708,7 @@ function resolveSkillRequest(args) {
61506
61708
  error: "reviewedSha256 must match the skill shown on the approval card"
61507
61709
  };
61508
61710
  }
61509
- const previewSha256 = createHash23("sha256").update(request.preview).digest("hex");
61711
+ const previewSha256 = createHash24("sha256").update(request.preview).digest("hex");
61510
61712
  if (previewSha256 !== request.sha256) {
61511
61713
  return { claimed: true, status: 422, error: "the skill preview changed after review \u2014 deny and recreate it" };
61512
61714
  }
@@ -61884,7 +62086,7 @@ bus.subscribe((event) => {
61884
62086
  }
61885
62087
  });
61886
62088
  async function testCliBinary(cli, driver) {
61887
- return new Promise((resolve10) => {
62089
+ return new Promise((resolve11) => {
61888
62090
  execCli(
61889
62091
  cli,
61890
62092
  ["--version"],
@@ -61903,10 +62105,10 @@ async function testCliBinary(cli, driver) {
61903
62105
  const exceededBuffer = e.code === "ERR_CHILD_PROCESS_STDIO_MAXBUFFER";
61904
62106
  const isSpawnError = typeof e.code === "string" && !exceededBuffer;
61905
62107
  const message3 = exceededBuffer ? "CLI test produced more than 64 KiB of output" : isSpawnError ? describeSpawnFailure(e, cli).message : e.killed ? "CLI test timed out after 10s" : `CLI exited with error ${String(e.code)}: ${(stderrOf2(err) || "").slice(0, 200) || err.message.split("\n")[0]}`;
61906
- resolve10({ ok: false, message: message3, ...driver?.install && isSpawnError ? { install: driver.install } : {} });
62108
+ resolve11({ ok: false, message: message3, ...driver?.install && isSpawnError ? { install: driver.install } : {} });
61907
62109
  return;
61908
62110
  }
61909
- resolve10({ ok: true, version: stdout.trim().split("\n")[0] });
62111
+ resolve11({ ok: true, version: stdout.trim().split("\n")[0] });
61910
62112
  }
61911
62113
  );
61912
62114
  });
@@ -61963,7 +62165,7 @@ async function readyLocalVmForTurn(botId, target) {
61963
62165
  localVmIdleFor(target).touch();
61964
62166
  const deadline = Date.now() + LOCAL_VM_DESKTOP_WAIT_MS;
61965
62167
  while (!status.ready && status.container === "running" && Date.now() < deadline) {
61966
- await new Promise((resolve10) => setTimeout(resolve10, 2e3));
62168
+ await new Promise((resolve11) => setTimeout(resolve11, 2e3));
61967
62169
  status = await containerComputerStatus(void 0, void 0, target);
61968
62170
  }
61969
62171
  return status;
@@ -61979,7 +62181,7 @@ async function perBotLocalVmCountForModeChange() {
61979
62181
  if (targets.length === 0) return 0;
61980
62182
  const runtime = await containerRuntimeStatus();
61981
62183
  if (!runtime.runtime || !runtime.daemonUp) {
61982
- return targets.some((target) => existsSync24(target.workspaceDir)) ? null : 0;
62184
+ return targets.some((target) => existsSync25(target.workspaceDir)) ? null : 0;
61983
62185
  }
61984
62186
  return existingPerBotLocalVmCount(runtime.runtime);
61985
62187
  }
@@ -62011,6 +62213,9 @@ function configStatus() {
62011
62213
  showToolCalls: showToolCallsEnabled(cfg),
62012
62214
  browser: builtInBrowserEnabled(cfg)
62013
62215
  },
62216
+ // Which browser this server can give bots: the desktop app's surface,
62217
+ // the agent-browser engine, or nothing yet (with the reason).
62218
+ browserEngine: browserEngineSummary(),
62014
62219
  // partitionId is non-secret routing metadata. The renderer needs it to
62015
62220
  // show the same durable session as an agent, but config PATCH validation
62016
62221
  // keeps it read-only and rejects callers that try to choose it.
@@ -62064,15 +62269,15 @@ var claudeUpdatesInFlight = /* @__PURE__ */ new Set();
62064
62269
  function serveStatic(res, path) {
62065
62270
  if (!STATIC_DIR) return false;
62066
62271
  const safe = path === "/" ? "/index.html" : path.replace(/\.\./g, "");
62067
- const file2 = join48(STATIC_DIR, safe);
62272
+ const file2 = join49(STATIC_DIR, safe);
62068
62273
  try {
62069
- const data = readFileSync37(file2);
62274
+ const data = readFileSync38(file2);
62070
62275
  res.writeHead(200, { "content-type": MIME[extname5(file2)] ?? "application/octet-stream" });
62071
62276
  res.end(data);
62072
62277
  return true;
62073
62278
  } catch {
62074
62279
  try {
62075
- const data = readFileSync37(join48(STATIC_DIR, "index.html"));
62280
+ const data = readFileSync38(join49(STATIC_DIR, "index.html"));
62076
62281
  res.writeHead(200, { "content-type": "text/html" });
62077
62282
  res.end(data);
62078
62283
  return true;
@@ -62087,7 +62292,7 @@ function json3(res, status, body) {
62087
62292
  res.end(data);
62088
62293
  }
62089
62294
  function readBody(req, limit = 1e6) {
62090
- return new Promise((resolve10, reject) => {
62295
+ return new Promise((resolve11, reject) => {
62091
62296
  let data = "";
62092
62297
  let bytes = 0;
62093
62298
  let done = false;
@@ -62114,7 +62319,7 @@ function readBody(req, limit = 1e6) {
62114
62319
  return fail2(400, "invalid JSON body");
62115
62320
  }
62116
62321
  done = true;
62117
- resolve10(body);
62322
+ resolve11(body);
62118
62323
  });
62119
62324
  req.on("error", (e) => fail2(400, e instanceof Error ? e.message : String(e)));
62120
62325
  });
@@ -62917,7 +63122,7 @@ var handleRequest = async (req, res) => {
62917
63122
  description: `${reason ? `${target.description} ${reason}` : target.description} ${from.name} can use it but never read it back.`,
62918
63123
  placeholder: target.placeholder,
62919
63124
  helpUrl: target.helpUrl,
62920
- requestKey: randomUUID16()
63125
+ requestKey: randomUUID17()
62921
63126
  }
62922
63127
  });
62923
63128
  return json3(res, 201, { messageId: message3.id, label: target.label });
@@ -63365,7 +63570,7 @@ data: ${JSON.stringify({ kind: "ping" })}
63365
63570
  req.resume();
63366
63571
  return json3(res, 413, { error: `image exceeds ${IMAGE_MAX_BYTES2} bytes` });
63367
63572
  }
63368
- const saved = await new Promise((resolve10, reject) => {
63573
+ const saved = await new Promise((resolve11, reject) => {
63369
63574
  const chunks = [];
63370
63575
  let received = 0;
63371
63576
  let settled = false;
@@ -63384,7 +63589,7 @@ data: ${JSON.stringify({ kind: "ping" })}
63384
63589
  if (settled) return;
63385
63590
  settled = true;
63386
63591
  try {
63387
- resolve10(await saveImageUpload(Buffer.concat(chunks), mime, uploadId));
63592
+ resolve11(await saveImageUpload(Buffer.concat(chunks), mime, uploadId));
63388
63593
  } catch (e) {
63389
63594
  reject(e instanceof Error ? e : new Error(String(e)));
63390
63595
  }
@@ -64020,7 +64225,7 @@ data: ${JSON.stringify({ kind: "ping" })}
64020
64225
  for (const threadId of threadIds) {
64021
64226
  for (const dir of [EVENTS_DIR, NATIVE_DIR]) {
64022
64227
  try {
64023
- unlinkSync9(join48(dir, `${threadId}.ndjson`));
64228
+ unlinkSync9(join49(dir, `${threadId}.ndjson`));
64024
64229
  } catch {
64025
64230
  }
64026
64231
  }
@@ -64661,7 +64866,7 @@ data: ${JSON.stringify({ kind: "ping" })}
64661
64866
  return json3(res, 409, { error: "stop this bot's Local VM turn or setup action before deleting the bot" });
64662
64867
  }
64663
64868
  const vm = await containerComputerStatus(void 0, void 0, target);
64664
- if (!vm.daemonUp && existsSync24(target.workspaceDir)) {
64869
+ if (!vm.daemonUp && existsSync25(target.workspaceDir)) {
64665
64870
  return json3(res, 409, {
64666
64871
  error: "start the container runtime and delete this bot's Local VM before deleting the bot"
64667
64872
  });
@@ -64747,7 +64952,7 @@ data: ${JSON.stringify({ kind: "ping" })}
64747
64952
  }
64748
64953
  for (const dir of [EVENTS_DIR, NATIVE_DIR]) {
64749
64954
  try {
64750
- unlinkSync9(join48(dir, `${bot.threadId}.ndjson`));
64955
+ unlinkSync9(join49(dir, `${bot.threadId}.ndjson`));
64751
64956
  } catch {
64752
64957
  }
64753
64958
  }
@@ -66520,6 +66725,9 @@ var gracefulShutdown = createGracefulShutdown({
66520
66725
  for (const signal of ["SIGINT", "SIGTERM"]) {
66521
66726
  process.on(signal, gracefulShutdown);
66522
66727
  }
66728
+ export {
66729
+ browserEngineSummary
66730
+ };
66523
66731
  /*! Bundled license information:
66524
66732
 
66525
66733
  @hpke/common/esm/src/curve/modular.js: