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.
- package/dist/assets/{index-jWqt5dmY.js → index-CE7W1AIk.js} +1 -1
- package/dist/assets/index-r-WPT-Pu.js +264 -0
- package/dist/index.html +1 -1
- package/dist-server/index.js +466 -258
- package/dist-server/openmausbot.js +15219 -305
- package/dist-server/pair-cli.js +15219 -305
- package/dist-server/server/browser-engine-release.js +44 -0
- package/dist-server/server/browser-engine.js +185 -0
- package/dist-server/server/cli.js +55 -1
- package/dist-server/server/drivers/antigravity-acp.js +60 -9
- package/dist-server/server/drivers/antigravity.js +23 -2
- package/dist-server/server/index.js +45 -4
- package/package.json +1 -1
- package/dist/assets/index-DSh8AIUy.js +0 -264
package/dist-server/index.js
CHANGED
|
@@ -5,10 +5,10 @@ var __export = (target, all2) => {
|
|
|
5
5
|
};
|
|
6
6
|
|
|
7
7
|
// server/index.ts
|
|
8
|
-
import { createHash as
|
|
9
|
-
import { existsSync as
|
|
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
|
|
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 = (
|
|
1628
|
-
const escapedDelim = escapeRegex(
|
|
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((
|
|
14881
|
+
const timeout2 = new Promise((resolve11) => {
|
|
14882
14882
|
timer = setTimeout(() => {
|
|
14883
14883
|
controller.abort();
|
|
14884
|
-
|
|
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
|
|
15072
|
-
if (
|
|
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((
|
|
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
|
|
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((
|
|
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
|
-
|
|
15554
|
+
resolve11(false);
|
|
15555
15555
|
}, this.#timeoutMs);
|
|
15556
15556
|
timer.unref?.();
|
|
15557
|
-
this.#waiters.set(request.requestId, { resolve:
|
|
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((
|
|
16867
|
-
release =
|
|
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
|
|
19678
|
-
if (
|
|
19679
|
-
events =
|
|
19680
|
-
called.push(
|
|
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((
|
|
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((
|
|
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((
|
|
28142
|
-
timer = setTimeout(() =>
|
|
28141
|
+
const promise2 = new Promise((resolve11) => {
|
|
28142
|
+
timer = setTimeout(() => resolve11("elapsed"), Math.max(1, ms));
|
|
28143
28143
|
timer.unref?.();
|
|
28144
|
-
if (signal?.aborted) return
|
|
28144
|
+
if (signal?.aborted) return resolve11("cancelled");
|
|
28145
28145
|
onCancel = () => {
|
|
28146
28146
|
clearTimeout(timer);
|
|
28147
|
-
|
|
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((
|
|
28239
|
+
return new Promise((resolve11) => {
|
|
28240
28240
|
if (signal?.aborted) {
|
|
28241
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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((
|
|
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:
|
|
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((
|
|
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) =>
|
|
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((
|
|
29612
|
-
this.child.once("close", (code) => {
|
|
29613
|
-
|
|
29614
|
-
|
|
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)
|
|
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
|
-
|
|
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
|
-
|
|
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((
|
|
29707
|
-
timer = setTimeout(() =>
|
|
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((
|
|
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
|
-
|
|
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((
|
|
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
|
-
|
|
30782
|
+
resolve11(
|
|
30729
30783
|
typeof status === "object" && status !== null && "loggedIn" in status && status.loggedIn === true
|
|
30730
30784
|
);
|
|
30731
30785
|
} catch {
|
|
30732
|
-
|
|
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((
|
|
30924
|
-
attempt.once("listening", () =>
|
|
30925
|
-
attempt.once("error", (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((
|
|
31184
|
+
return new Promise((resolve11) => {
|
|
31131
31185
|
try {
|
|
31132
31186
|
s.child.stdin.write(JSON.stringify(promptMsg) + "\n", (error51) => {
|
|
31133
|
-
if (error51) return
|
|
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
|
-
|
|
31193
|
+
resolve11(true);
|
|
31140
31194
|
});
|
|
31141
31195
|
} catch {
|
|
31142
|
-
|
|
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((
|
|
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) =>
|
|
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((
|
|
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
|
|
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((
|
|
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
|
-
|
|
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((
|
|
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
|
-
|
|
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((
|
|
32856
|
-
const timer = setTimeout(
|
|
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((
|
|
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) =>
|
|
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((
|
|
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) =>
|
|
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((
|
|
34366
|
+
return new Promise((resolve11) => {
|
|
34313
34367
|
run3(cli, args, { timeout: EXEC_TIMEOUT_MS, env }, (err, stdout) => {
|
|
34314
|
-
if (err) return
|
|
34315
|
-
|
|
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((
|
|
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
|
-
|
|
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((
|
|
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
|
|
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
|
-
|
|
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((
|
|
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
|
-
|
|
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((
|
|
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:
|
|
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((
|
|
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
|
-
|
|
42168
|
+
resolve11(null);
|
|
42115
42169
|
}, 8e3);
|
|
42116
42170
|
timer.unref?.();
|
|
42117
42171
|
child.on("error", () => {
|
|
42118
42172
|
clearTimeout(timer);
|
|
42119
|
-
|
|
42173
|
+
resolve11(null);
|
|
42120
42174
|
});
|
|
42121
42175
|
child.on("close", () => {
|
|
42122
42176
|
clearTimeout(timer);
|
|
42123
|
-
|
|
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(
|
|
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 =
|
|
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((
|
|
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
|
-
|
|
44125
|
+
resolve11("deny");
|
|
44072
44126
|
}, APPROVAL_TIMEOUT_MS);
|
|
44073
44127
|
timer.unref?.();
|
|
44074
44128
|
pendingComms.set(requestId, {
|
|
44075
|
-
resolve:
|
|
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((
|
|
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)
|
|
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((
|
|
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
|
-
|
|
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((
|
|
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
|
|
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((
|
|
47837
|
-
const sleep = setTimeout(
|
|
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((
|
|
47858
|
-
release =
|
|
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((
|
|
47866
|
-
acquireTimer = setTimeout(() =>
|
|
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((
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
50604
|
-
import { closeSync as closeSync8, existsSync as
|
|
50605
|
-
import { join as
|
|
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
|
|
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:
|
|
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:
|
|
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 (!
|
|
50808
|
+
if (!existsSync19(botFolder(botId))) return;
|
|
50637
50809
|
const file2 = historyFile(botId);
|
|
50638
|
-
|
|
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-${
|
|
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
|
|
51111
|
-
import { basename as basename5, join as
|
|
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 (
|
|
51295
|
-
return
|
|
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
|
|
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(
|
|
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(
|
|
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(
|
|
51413
|
-
${readText2(
|
|
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(
|
|
51417
|
-
if (entries.has(path)) return isDir(
|
|
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(
|
|
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
|
|
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(
|
|
52155
|
-
const native = readRecentLines(
|
|
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((
|
|
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
|
-
|
|
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
|
|
52331
|
-
import { mkdirSync as
|
|
52332
|
-
import { dirname as dirname13, join as
|
|
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
|
|
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_${
|
|
52589
|
+
return `wh_${randomBytes6(12).toString("base64url")}`;
|
|
52418
52590
|
}
|
|
52419
52591
|
function newSecret() {
|
|
52420
|
-
return `whsec_${
|
|
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 ??
|
|
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(
|
|
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:
|
|
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-${
|
|
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) ||
|
|
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 ||
|
|
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) ||
|
|
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:
|
|
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
|
-
|
|
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
|
|
52783
|
-
import { basename as basename6, join as
|
|
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 =
|
|
52813
|
-
const skillPath =
|
|
52814
|
-
if (!
|
|
52815
|
-
const manifest = parseSkillManifest(JSON.parse(
|
|
52816
|
-
const instructions =
|
|
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 ||
|
|
52821
|
-
if (!
|
|
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 =
|
|
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 (!
|
|
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(
|
|
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
|
|
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((
|
|
53667
|
+
await new Promise((resolve11) => {
|
|
53496
53668
|
const waiters = this.#clearWaitersByThread.get(threadId) ?? /* @__PURE__ */ new Set();
|
|
53497
|
-
waiters.add(
|
|
53669
|
+
waiters.add(resolve11);
|
|
53498
53670
|
this.#clearWaitersByThread.set(threadId, waiters);
|
|
53499
53671
|
if (!this.has(threadId)) {
|
|
53500
|
-
waiters.delete(
|
|
53672
|
+
waiters.delete(resolve11);
|
|
53501
53673
|
if (waiters.size === 0) this.#clearWaitersByThread.delete(threadId);
|
|
53502
|
-
|
|
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((
|
|
53530
|
-
timer = setTimeout(
|
|
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
|
|
53543
|
-
import { existsSync as
|
|
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
|
|
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 =
|
|
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
|
-
|
|
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 =
|
|
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:
|
|
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 (!
|
|
53864
|
+
if (!existsSync21(dataDir) && existsSync21(legacyDataDir)) {
|
|
53693
53865
|
try {
|
|
53694
|
-
|
|
53866
|
+
renameSync6(legacyDataDir, dataDir);
|
|
53695
53867
|
} catch {
|
|
53696
53868
|
}
|
|
53697
53869
|
}
|
|
53698
53870
|
}
|
|
53699
53871
|
try {
|
|
53700
|
-
|
|
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
|
|
53876
|
+
return join46(dataDir, LEASE_NAME);
|
|
53705
53877
|
}
|
|
53706
53878
|
function assertNoLiveDelegatedChild(dataDir) {
|
|
53707
|
-
const childLeasePath =
|
|
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 =
|
|
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
|
-
|
|
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:
|
|
53949
|
+
token: randomUUID15(),
|
|
53778
53950
|
createdAt: Date.now()
|
|
53779
53951
|
};
|
|
53780
53952
|
const candidatePath = `${leasePath}.candidate-${owner2.pid}-${owner2.token}`;
|
|
53781
53953
|
try {
|
|
53782
|
-
|
|
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
|
|
53854
|
-
import { join as
|
|
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 =
|
|
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 = [
|
|
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
|
|
54331
|
-
import { chmodSync as
|
|
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) =>
|
|
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
|
|
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 (!
|
|
54578
|
+
if (!existsSync23(this.options.file)) return;
|
|
54407
54579
|
let raw;
|
|
54408
54580
|
try {
|
|
54409
|
-
raw = JSON.parse(
|
|
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
|
-
|
|
54591
|
+
mkdirSync23(dir, { recursive: true, mode: 448 });
|
|
54420
54592
|
const tmp = `${this.options.file}.${process.pid}.tmp`;
|
|
54421
|
-
|
|
54422
|
-
|
|
54423
|
-
|
|
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:
|
|
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_${
|
|
54700
|
+
const token = `omb_sess_${randomBytes7(32).toString("base64url")}`;
|
|
54529
54701
|
const record2 = {
|
|
54530
|
-
id:
|
|
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_${
|
|
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
|
|
54602
|
-
import { join as
|
|
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 ||
|
|
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 (!
|
|
54797
|
+
if (!existsSync24(file2)) return fallback();
|
|
54626
54798
|
let raw;
|
|
54627
54799
|
try {
|
|
54628
|
-
raw = JSON.parse(
|
|
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
|
|
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((
|
|
56349
|
-
releaseLock =
|
|
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
|
|
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
|
|
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((
|
|
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:
|
|
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:
|
|
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(
|
|
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:
|
|
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 =
|
|
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 =
|
|
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 =
|
|
57597
|
+
async function browserIntegration(botId, profile, threadId, generation, stillValid = () => true, ownerId = randomUUID17()) {
|
|
57426
57598
|
const connection = availableBrowserConnection();
|
|
57427
|
-
if (!connection) return
|
|
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((
|
|
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
|
-
|
|
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:
|
|
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((
|
|
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
|
-
|
|
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 =
|
|
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}${
|
|
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-${
|
|
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 =
|
|
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,
|
|
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:${
|
|
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((
|
|
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
|
-
|
|
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)}-${
|
|
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 =
|
|
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 =
|
|
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((
|
|
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
|
-
|
|
62108
|
+
resolve11({ ok: false, message: message3, ...driver?.install && isSpawnError ? { install: driver.install } : {} });
|
|
61907
62109
|
return;
|
|
61908
62110
|
}
|
|
61909
|
-
|
|
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((
|
|
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) =>
|
|
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 =
|
|
62272
|
+
const file2 = join49(STATIC_DIR, safe);
|
|
62068
62273
|
try {
|
|
62069
|
-
const data =
|
|
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 =
|
|
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((
|
|
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
|
-
|
|
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:
|
|
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((
|
|
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
|
-
|
|
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(
|
|
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 &&
|
|
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(
|
|
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:
|