openmausbot 0.1.63 → 0.1.66

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/dist/assets/index-BftlaHAF.css +1 -0
  2. package/dist/assets/index-DuR3H-Hf.js +278 -0
  3. package/dist/assets/{index-C-SoIGdn.js → index-kW5L1QeO.js} +1 -1
  4. package/dist/index.html +2 -2
  5. package/dist-server/browser-proxy.js +121 -0
  6. package/dist-server/container-mcp.js +4 -1
  7. package/dist-server/index.js +17996 -15876
  8. package/dist-server/openmausbot.js +752 -245
  9. package/dist-server/pair-cli.js +752 -245
  10. package/dist-server/prepare-cloudflared.js +10 -2
  11. package/dist-server/proxy-paths.js +1 -0
  12. package/dist-server/server/attachments.js +140 -16
  13. package/dist-server/server/browser-engine-release.js +10 -8
  14. package/dist-server/server/browser-engine.js +226 -26
  15. package/dist-server/server/browser-live.js +567 -0
  16. package/dist-server/server/browser-proxy.js +129 -0
  17. package/dist-server/server/browser-runtime.js +370 -0
  18. package/dist-server/server/claude-accounts.js +103 -0
  19. package/dist-server/server/config.js +31 -20
  20. package/dist-server/server/custom-domain.js +196 -0
  21. package/dist-server/server/drivers/claude.js +77 -19
  22. package/dist-server/server/drivers/codex-device-auth.js +234 -0
  23. package/dist-server/server/drivers/codex.js +10 -0
  24. package/dist-server/server/harness/bus.js +9 -4
  25. package/dist-server/server/harness/registry.js +15 -0
  26. package/dist-server/server/index.js +446 -91
  27. package/dist-server/server/provider-auth-sessions.js +118 -0
  28. package/dist-server/server/proxy-paths.js +1 -0
  29. package/dist-server/server/sse-fanout.js +53 -0
  30. package/dist-server/src/lib/composer-attachments.js +23 -6
  31. package/dist-server/vps-container-mcp.js +4 -1
  32. package/package.json +1 -1
  33. package/dist/assets/index-BuntoOSX.js +0 -264
  34. package/dist/assets/index-oPMv6a_k.css +0 -1
@@ -0,0 +1,121 @@
1
+ // server/browser-proxy.ts
2
+ import { pathToFileURL } from "node:url";
3
+ var MAX_INPUT_BYTES = 1048576;
4
+ var MAX_OUTPUT_BYTES = 16777216;
5
+ var MAX_PENDING = 16;
6
+ function failure(id, method, message, code = -32603) {
7
+ return method === "tools/call" ? { jsonrpc: "2.0", id, result: { content: [{ type: "text", text: message }], isError: true } } : { jsonrpc: "2.0", id, error: { code, message } };
8
+ }
9
+ async function boundedJson(response) {
10
+ if (!response.body) throw new Error("Browser server returned an empty response.");
11
+ const reader = response.body.getReader();
12
+ const chunks = [];
13
+ let size = 0;
14
+ try {
15
+ for (; ; ) {
16
+ const { value, done } = await reader.read();
17
+ if (done) break;
18
+ size += value.byteLength;
19
+ if (size > MAX_OUTPUT_BYTES) throw new Error("Browser response exceeded the size limit.");
20
+ chunks.push(Buffer.from(value));
21
+ }
22
+ return JSON.parse(Buffer.concat(chunks).toString("utf8"));
23
+ } finally {
24
+ await reader.cancel().catch(() => {
25
+ });
26
+ }
27
+ }
28
+ async function browserProxyRequest(frame, connection) {
29
+ if (!frame || typeof frame !== "object" || Array.isArray(frame)) return failure(null, null, "Invalid request.", -32600);
30
+ const message = frame;
31
+ const id = message.id ?? null;
32
+ if (message.jsonrpc !== "2.0" || typeof message.method !== "string" || id !== null && typeof id !== "number" && typeof id !== "string") return failure(null, null, "Invalid request.", -32600);
33
+ if (!Object.hasOwn(message, "id")) return void 0;
34
+ if (message.method === "initialize") return {
35
+ jsonrpc: "2.0",
36
+ id,
37
+ result: { protocolVersion: "2024-11-05", capabilities: { tools: {} }, serverInfo: { name: "openmausbot-browser", version: "1" } }
38
+ };
39
+ if (message.method === "ping") return { jsonrpc: "2.0", id, result: {} };
40
+ if (message.method !== "tools/list" && message.method !== "tools/call") return failure(id, message.method, "Method not found.", -32601);
41
+ try {
42
+ const url = new URL(connection.url);
43
+ if (!connection.token || url.protocol !== "http:" || !["127.0.0.1", "localhost", "[::1]"].includes(url.hostname) || url.username || url.password || url.pathname !== "/" || url.search || url.hash) {
44
+ throw new Error("Browser connection is not configured. Start a new bot turn from OpenMausBot.");
45
+ }
46
+ const body = JSON.stringify({ method: message.method, params: message.params ?? {} });
47
+ if (Buffer.byteLength(body) > MAX_INPUT_BYTES) throw new Error("Browser request exceeded the size limit.");
48
+ const response = await fetch(new URL("/api/internal/browser/mcp", url), {
49
+ method: "POST",
50
+ redirect: "error",
51
+ headers: { "content-type": "application/json", authorization: `Bearer ${connection.token}` },
52
+ body,
53
+ signal: AbortSignal.timeout(13e4)
54
+ });
55
+ const payload = await boundedJson(response);
56
+ if (!response.ok || !payload || typeof payload !== "object" || !Object.hasOwn(payload, "result")) {
57
+ throw new Error(typeof payload?.error === "string" ? payload.error.slice(0, 2e3) : "Browser server is unavailable. Start a new bot turn or try again.");
58
+ }
59
+ return { jsonrpc: "2.0", id, result: payload.result };
60
+ } catch (error) {
61
+ return failure(id, message.method, error instanceof Error && !/fetch failed|abort|timeout/i.test(error.message) ? error.message : "Browser connection was interrupted. Do not repeat the action until its state is checked.");
62
+ }
63
+ }
64
+ function run() {
65
+ const connection = { url: process.env.OMB_HARNESS_URL ?? "", token: process.env.OMB_BROWSER_TOKEN ?? "" };
66
+ let input = Buffer.alloc(0);
67
+ let pending = 0;
68
+ const output = (message) => {
69
+ if (message === void 0) return;
70
+ const line = `${JSON.stringify(message)}
71
+ `;
72
+ if (Buffer.byteLength(line) > MAX_OUTPUT_BYTES || process.stdout.writableLength > MAX_OUTPUT_BYTES * 2) {
73
+ process.stdin.destroy();
74
+ process.exitCode = 1;
75
+ return;
76
+ }
77
+ process.stdout.write(line);
78
+ };
79
+ process.stdout.on("error", () => {
80
+ process.stdin.destroy();
81
+ process.exitCode = 1;
82
+ });
83
+ process.stdin.on("data", (chunk) => {
84
+ input = Buffer.concat([input, chunk]);
85
+ let newline;
86
+ while ((newline = input.indexOf(10)) !== -1) {
87
+ if (newline > MAX_INPUT_BYTES) {
88
+ process.stdin.destroy();
89
+ process.exitCode = 1;
90
+ return;
91
+ }
92
+ const line = input.subarray(0, newline).toString("utf8");
93
+ input = input.subarray(newline + 1);
94
+ if (!line.trim()) continue;
95
+ let frame;
96
+ try {
97
+ frame = JSON.parse(line);
98
+ } catch {
99
+ output(failure(null, null, "Parse error.", -32700));
100
+ continue;
101
+ }
102
+ if (pending >= MAX_PENDING) {
103
+ const request = frame;
104
+ if (request && Object.hasOwn(request, "id")) output(failure(request.id ?? null, request.method, "Too many pending browser requests."));
105
+ continue;
106
+ }
107
+ pending++;
108
+ void browserProxyRequest(frame, connection).then(output).finally(() => {
109
+ pending--;
110
+ });
111
+ }
112
+ if (input.length > MAX_INPUT_BYTES) {
113
+ process.stdin.destroy();
114
+ process.exitCode = 1;
115
+ }
116
+ });
117
+ }
118
+ if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) run();
119
+ export {
120
+ browserProxyRequest
121
+ };
@@ -14803,6 +14803,8 @@ var defaultModelSelectionSchema = external_exports.object({
14803
14803
  effort: external_exports.enum(EFFORT_LEVELS).optional()
14804
14804
  });
14805
14805
  var appConfigSchema = external_exports.object({
14806
+ /** Verified by the dedicated domain endpoint, never a generic config patch. */
14807
+ customDomain: external_exports.string().optional(),
14806
14808
  defaultModelSelection: defaultModelSelectionSchema.optional(),
14807
14809
  /** CLI-only launch preferences. Never enable remote access implicitly. */
14808
14810
  cliStartup: external_exports.object({
@@ -14846,7 +14848,7 @@ var appConfigSchema = external_exports.object({
14846
14848
  var storedAppConfigSchema = appConfigSchema.extend({
14847
14849
  browserProfiles: storedBrowserProfilesSchema.optional()
14848
14850
  });
14849
- var appConfigPatchSchema = appConfigSchema.omit({ instances: true, mcpServers: true, cliStartup: true });
14851
+ var appConfigPatchSchema = appConfigSchema.omit({ instances: true, mcpServers: true, cliStartup: true, customDomain: true });
14850
14852
  var jsonObjectSchema = external_exports.record(external_exports.string(), external_exports.json());
14851
14853
  var DATA_DIR = process.env.OMB_DATA_DIR ?? join2(homedir2(), ".openmausbot");
14852
14854
  var LEGACY_DATA_DIR = join2(homedir2(), ".opengrokbot");
@@ -14863,6 +14865,7 @@ function resolveProxy(relative) {
14863
14865
  return existsSync2(source) ? source : join3(SERVER_ROOT, `${relative}.js`);
14864
14866
  }
14865
14867
  var SPAWNED_PROXIES = {
14868
+ browser: resolveProxy("browser-proxy"),
14866
14869
  computer: resolveProxy("computer-proxy"),
14867
14870
  permission: resolveProxy("permission-proxy"),
14868
14871
  containerMcp: resolveProxy("container-mcp"),