openmausbot 0.1.67 → 0.1.68
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-CbaejjQA.js +278 -0
- package/dist/assets/{index-BwpNqgCm.js → index-HqooKFTS.js} +1 -1
- package/dist/assets/index-aJ5EWZOQ.css +1 -0
- package/dist/index.html +2 -2
- package/dist-server/container-mcp.js +2 -0
- package/dist-server/drivers/agents-proxy.js +28 -3
- package/dist-server/enterprise/server/index.js +14587 -0
- package/dist-server/index.js +271 -74
- package/dist-server/openmausbot.js +484 -289
- package/dist-server/pair-cli.js +484 -289
- package/dist-server/server/brand.js +7 -0
- package/dist-server/server/cli.js +23 -1
- package/dist-server/server/config.js +7 -1
- package/dist-server/server/delegations.js +56 -11
- package/dist-server/server/drivers/agents-proxy.js +41 -5
- package/dist-server/server/index.js +194 -60
- package/dist-server/server/routines.js +36 -9
- package/dist-server/server/service-cli.js +63 -0
- package/dist-server/server/service-unit.js +129 -0
- package/dist-server/server/steer-queue.js +2 -1
- package/dist-server/server/store.js +30 -4
- package/dist-server/server/system-prompt.js +1 -0
- package/dist-server/server/turn-dispatch-guard.js +6 -0
- package/dist-server/vps-container-mcp.js +2 -0
- package/enterprise/LICENSE +32 -0
- package/enterprise/README.md +89 -0
- package/enterprise/server/index.js +14587 -0
- package/package.json +2 -1
- package/dist/assets/index-A3CBTxwl.css +0 -1
- package/dist/assets/index-CDuyoVPJ.js +0 -278
|
@@ -17577,9 +17577,9 @@ var init_schema = __esm({
|
|
|
17577
17577
|
});
|
|
17578
17578
|
|
|
17579
17579
|
// server/config.ts
|
|
17580
|
-
import { readFileSync as readFileSync2, mkdirSync as
|
|
17581
|
-
import { homedir as
|
|
17582
|
-
import { join as
|
|
17580
|
+
import { readFileSync as readFileSync2, mkdirSync as mkdirSync4, existsSync as existsSync3, renameSync as renameSync3 } from "node:fs";
|
|
17581
|
+
import { homedir as homedir4 } from "node:os";
|
|
17582
|
+
import { join as join5 } from "node:path";
|
|
17583
17583
|
function isValidSshAlias(value) {
|
|
17584
17584
|
return typeof value === "string" && SSH_ALIAS.test(value);
|
|
17585
17585
|
}
|
|
@@ -17712,7 +17712,7 @@ function parseStoredConfig(value) {
|
|
|
17712
17712
|
function loadConfig() {
|
|
17713
17713
|
let cfg = {};
|
|
17714
17714
|
try {
|
|
17715
|
-
cfg = parseStoredConfig(parseJson(readFileSync2(
|
|
17715
|
+
cfg = parseStoredConfig(parseJson(readFileSync2(join5(DATA_DIR, "config.json"), "utf8")));
|
|
17716
17716
|
} catch {
|
|
17717
17717
|
}
|
|
17718
17718
|
cfg.xai = { ...cfg.xai };
|
|
@@ -17744,7 +17744,7 @@ function stripWorkspaceCredentialEnv(env) {
|
|
|
17744
17744
|
for (const key of WORKSPACE_CREDENTIAL_ENV) delete env[key];
|
|
17745
17745
|
}
|
|
17746
17746
|
function saveConfig(patch, options = {}) {
|
|
17747
|
-
const p =
|
|
17747
|
+
const p = join5(DATA_DIR, "config.json");
|
|
17748
17748
|
let disk = {};
|
|
17749
17749
|
try {
|
|
17750
17750
|
const parsed = jsonObjectSchema.safeParse(parseJson(readFileSync2(p, "utf8")));
|
|
@@ -17754,7 +17754,7 @@ function saveConfig(patch, options = {}) {
|
|
|
17754
17754
|
const checkedPatch = appConfigSchema.partial().parse(patch);
|
|
17755
17755
|
const storedProfiles = storedBrowserProfilesSchema.safeParse(disk.browserProfiles);
|
|
17756
17756
|
if (storedProfiles.success) disk.browserProfiles = storedProfiles.data;
|
|
17757
|
-
for (const key of ["xai", "openaiCompat", "composio", "box", "opencodeGo", "tts", "imageGen", "profile", "rooms", "localVm", "features"]) {
|
|
17757
|
+
for (const key of ["xai", "openaiCompat", "composio", "box", "opencodeGo", "tts", "imageGen", "profile", "rooms", "threads", "localVm", "features"]) {
|
|
17758
17758
|
const section = checkedPatch[key];
|
|
17759
17759
|
if (!section) continue;
|
|
17760
17760
|
const current = jsonObjectSchema.safeParse(disk[key]);
|
|
@@ -17803,7 +17803,7 @@ function saveConfig(patch, options = {}) {
|
|
|
17803
17803
|
}
|
|
17804
17804
|
disk.instances = diskInstances;
|
|
17805
17805
|
}
|
|
17806
|
-
|
|
17806
|
+
mkdirSync4(DATA_DIR, { recursive: true });
|
|
17807
17807
|
writeFileAtomic(p, JSON.stringify(disk, null, 2), { mode: 384 });
|
|
17808
17808
|
}
|
|
17809
17809
|
function injectedEnvironment(cfg, driver) {
|
|
@@ -17875,7 +17875,7 @@ function instanceConfigs(cfg) {
|
|
|
17875
17875
|
}
|
|
17876
17876
|
return map3;
|
|
17877
17877
|
}
|
|
17878
|
-
var optionalText, SSH_ALIAS, LEGACY_BROWSER_PROFILE_ID, BROWSER_PROFILE_ID, MIN_ROOM_TURN_TIMEOUT_MINUTES, MAX_ROOM_TURN_TIMEOUT_MINUTES, MIN_LOCAL_VM_MAX_INSTANCES, MAX_LOCAL_VM_MAX_INSTANCES, vpsConfigSchema, roomConfigSchema, localVmConfigSchema, browserProfileSchema, legacyBrowserProfileSchema, legacyBrowserProfilesSchema, storedBrowserProfilesSchema, browserProfilesSchema, featureConfigSchema, instanceConfigSchema, instanceConfigMapSchema, defaultModelSelectionSchema, appConfigSchema, storedAppConfigSchema, appConfigPatchSchema, jsonObjectSchema, DATA_DIR, LEGACY_DATA_DIR, EVENTS_DIR, NATIVE_DIR, WORKSPACE_CREDENTIAL_ENV, PROVIDER_CREDENTIAL_ENV;
|
|
17878
|
+
var optionalText, SSH_ALIAS, LEGACY_BROWSER_PROFILE_ID, BROWSER_PROFILE_ID, MIN_ROOM_TURN_TIMEOUT_MINUTES, MAX_ROOM_TURN_TIMEOUT_MINUTES, MAX_CONCURRENT_BOT_THREADS, MIN_LOCAL_VM_MAX_INSTANCES, MAX_LOCAL_VM_MAX_INSTANCES, vpsConfigSchema, roomConfigSchema, localVmConfigSchema, browserProfileSchema, legacyBrowserProfileSchema, legacyBrowserProfilesSchema, storedBrowserProfilesSchema, browserProfilesSchema, featureConfigSchema, instanceConfigSchema, instanceConfigMapSchema, defaultModelSelectionSchema, appConfigSchema, storedAppConfigSchema, appConfigPatchSchema, jsonObjectSchema, DATA_DIR, LEGACY_DATA_DIR, EVENTS_DIR, NATIVE_DIR, WORKSPACE_CREDENTIAL_ENV, PROVIDER_CREDENTIAL_ENV;
|
|
17879
17879
|
var init_config = __esm({
|
|
17880
17880
|
"server/config.ts"() {
|
|
17881
17881
|
"use strict";
|
|
@@ -17890,6 +17890,7 @@ var init_config = __esm({
|
|
|
17890
17890
|
BROWSER_PROFILE_ID = /^[a-z0-9_-]{1,40}$/;
|
|
17891
17891
|
MIN_ROOM_TURN_TIMEOUT_MINUTES = 1;
|
|
17892
17892
|
MAX_ROOM_TURN_TIMEOUT_MINUTES = 1440;
|
|
17893
|
+
MAX_CONCURRENT_BOT_THREADS = 10;
|
|
17893
17894
|
MIN_LOCAL_VM_MAX_INSTANCES = 1;
|
|
17894
17895
|
MAX_LOCAL_VM_MAX_INSTANCES = 4;
|
|
17895
17896
|
vpsConfigSchema = external_exports.object({
|
|
@@ -17995,6 +17996,7 @@ var init_config = __esm({
|
|
|
17995
17996
|
* system language. Unknown tags degrade to English in the renderer. */
|
|
17996
17997
|
language: optionalText,
|
|
17997
17998
|
rooms: roomConfigSchema.optional(),
|
|
17999
|
+
threads: external_exports.object({ maxConcurrentPerBot: external_exports.number().int().min(1).max(MAX_CONCURRENT_BOT_THREADS) }).strict().optional(),
|
|
17998
18000
|
localVm: localVmConfigSchema.optional(),
|
|
17999
18001
|
features: featureConfigSchema.optional(),
|
|
18000
18002
|
browserProfiles: browserProfilesSchema.optional(),
|
|
@@ -18010,10 +18012,10 @@ var init_config = __esm({
|
|
|
18010
18012
|
});
|
|
18011
18013
|
appConfigPatchSchema = appConfigSchema.omit({ instances: true, mcpServers: true, cliStartup: true, customDomain: true });
|
|
18012
18014
|
jsonObjectSchema = external_exports.record(external_exports.string(), external_exports.json());
|
|
18013
|
-
DATA_DIR = process.env.OMB_DATA_DIR ??
|
|
18014
|
-
LEGACY_DATA_DIR =
|
|
18015
|
-
EVENTS_DIR =
|
|
18016
|
-
NATIVE_DIR =
|
|
18015
|
+
DATA_DIR = process.env.OMB_DATA_DIR ?? join5(homedir4(), ".openmausbot");
|
|
18016
|
+
LEGACY_DATA_DIR = join5(homedir4(), ".opengrokbot");
|
|
18017
|
+
EVENTS_DIR = join5(DATA_DIR, "events");
|
|
18018
|
+
NATIVE_DIR = join5(DATA_DIR, "native");
|
|
18017
18019
|
WORKSPACE_CREDENTIAL_ENV = [
|
|
18018
18020
|
"XAI_API_KEY",
|
|
18019
18021
|
"OPENAI_COMPAT_API_KEY",
|
|
@@ -18050,9 +18052,9 @@ var init_config = __esm({
|
|
|
18050
18052
|
// electron/data-dir-lease.mjs
|
|
18051
18053
|
import { execFileSync } from "node:child_process";
|
|
18052
18054
|
import { createHash as createHash2, randomUUID as randomUUID5 } from "node:crypto";
|
|
18053
|
-
import { existsSync as existsSync4, linkSync, mkdirSync as
|
|
18055
|
+
import { existsSync as existsSync4, linkSync, mkdirSync as mkdirSync5, readFileSync as readFileSync3, renameSync as renameSync4, unlinkSync as unlinkSync2, writeFileSync as writeFileSync4 } from "node:fs";
|
|
18054
18056
|
import { hostname as hostname4, uptime } from "node:os";
|
|
18055
|
-
import { join as
|
|
18057
|
+
import { join as join6 } from "node:path";
|
|
18056
18058
|
function leaseError(message2, cause) {
|
|
18057
18059
|
return Object.assign(new DataDirLeaseError(message2), { cause });
|
|
18058
18060
|
}
|
|
@@ -18157,7 +18159,7 @@ function unlinkExact(path3, message2) {
|
|
|
18157
18159
|
function publishRecord(path3, record3, prepareMessage, acquireMessage) {
|
|
18158
18160
|
const candidatePath = `${path3}.candidate-${record3.pid}-${record3.token}`;
|
|
18159
18161
|
try {
|
|
18160
|
-
|
|
18162
|
+
writeFileSync4(candidatePath, `${JSON.stringify(record3)}
|
|
18161
18163
|
`, { flag: "wx", mode: 384, flush: true });
|
|
18162
18164
|
} catch (error51) {
|
|
18163
18165
|
throw leaseError(prepareMessage, error51);
|
|
@@ -18240,14 +18242,14 @@ function prepareDataDir(dataDir, legacyDataDir) {
|
|
|
18240
18242
|
}
|
|
18241
18243
|
}
|
|
18242
18244
|
try {
|
|
18243
|
-
|
|
18245
|
+
mkdirSync5(dataDir, { recursive: true, mode: 448 });
|
|
18244
18246
|
} catch (error51) {
|
|
18245
18247
|
throw leaseError("OpenMausBot cannot create its data directory.", error51);
|
|
18246
18248
|
}
|
|
18247
|
-
return
|
|
18249
|
+
return join6(dataDir, LEASE_NAME);
|
|
18248
18250
|
}
|
|
18249
18251
|
function assertNoLiveDelegatedChild(dataDir) {
|
|
18250
|
-
const childLeasePath =
|
|
18252
|
+
const childLeasePath = join6(dataDir, DELEGATED_CHILD_DIR, LEASE_NAME);
|
|
18251
18253
|
const child = readOwner(childLeasePath);
|
|
18252
18254
|
if (!child) return;
|
|
18253
18255
|
if (child.host !== hostname4()) {
|
|
@@ -18278,7 +18280,7 @@ function acquireDataDirLeaseInternal(dataDir, options = {}) {
|
|
|
18278
18280
|
};
|
|
18279
18281
|
const candidatePath = `${leasePath}.candidate-${owner.pid}-${owner.token}`;
|
|
18280
18282
|
try {
|
|
18281
|
-
|
|
18283
|
+
writeFileSync4(candidatePath, `${JSON.stringify(owner)}
|
|
18282
18284
|
`, { flag: "wx", mode: 384, flush: true });
|
|
18283
18285
|
} catch (error51) {
|
|
18284
18286
|
throw leaseError("OpenMausBot cannot prepare its data-directory lease.", error51);
|
|
@@ -18371,62 +18373,62 @@ var init_data_dir_lease2 = __esm({
|
|
|
18371
18373
|
// server/env-path.ts
|
|
18372
18374
|
import { execFile as execFile2 } from "node:child_process";
|
|
18373
18375
|
import { closeSync as closeSync2, existsSync as existsSync5, openSync as openSync2, readFileSync as readFileSync4, readSync, statSync as statSync2, readdirSync } from "node:fs";
|
|
18374
|
-
import { homedir as
|
|
18375
|
-
import { basename, delimiter as delimiter3, dirname as
|
|
18376
|
+
import { homedir as homedir5 } from "node:os";
|
|
18377
|
+
import { basename as basename2, delimiter as delimiter3, dirname as dirname3, extname, join as join7 } from "node:path";
|
|
18376
18378
|
function nvmBinDirs() {
|
|
18377
18379
|
try {
|
|
18378
|
-
const base2 =
|
|
18379
|
-
return readdirSync(base2).filter((v) => v.startsWith("v")).sort((a2, b) => b.localeCompare(a2, void 0, { numeric: true })).map((v) =>
|
|
18380
|
+
const base2 = join7(homedir5(), ".nvm", "versions", "node");
|
|
18381
|
+
return readdirSync(base2).filter((v) => v.startsWith("v")).sort((a2, b) => b.localeCompare(a2, void 0, { numeric: true })).map((v) => join7(base2, v, "bin"));
|
|
18380
18382
|
} catch {
|
|
18381
18383
|
return [];
|
|
18382
18384
|
}
|
|
18383
18385
|
}
|
|
18384
18386
|
function knownDirs() {
|
|
18385
|
-
const home =
|
|
18387
|
+
const home = homedir5();
|
|
18386
18388
|
return [
|
|
18387
|
-
|
|
18389
|
+
join7(home, ".local", "bin"),
|
|
18388
18390
|
// claude installer default
|
|
18389
|
-
|
|
18391
|
+
join7(home, ".npm-global", "bin"),
|
|
18390
18392
|
// npm prefix ~/.npm-global (claude, opencode)
|
|
18391
|
-
|
|
18393
|
+
join7(home, ".kimi-code", "bin"),
|
|
18392
18394
|
// kimi-code installer
|
|
18393
|
-
|
|
18395
|
+
join7(home, ".grok", "bin"),
|
|
18394
18396
|
// x.ai installer
|
|
18395
|
-
|
|
18397
|
+
join7(home, ".opencode", "bin"),
|
|
18396
18398
|
// opencode installer
|
|
18397
|
-
|
|
18399
|
+
join7(home, ".claude", "local"),
|
|
18398
18400
|
// claude "local install"
|
|
18399
18401
|
"/opt/homebrew/bin",
|
|
18400
18402
|
// brew, Apple silicon
|
|
18401
18403
|
"/usr/local/bin",
|
|
18402
18404
|
// brew Intel / classic installs
|
|
18403
|
-
|
|
18404
|
-
|
|
18405
|
-
|
|
18406
|
-
|
|
18407
|
-
|
|
18405
|
+
join7(home, ".volta", "bin"),
|
|
18406
|
+
join7(home, ".bun", "bin"),
|
|
18407
|
+
join7(home, ".asdf", "shims"),
|
|
18408
|
+
join7(home, ".deno", "bin"),
|
|
18409
|
+
join7(home, "bin"),
|
|
18408
18410
|
...nvmBinDirs()
|
|
18409
18411
|
];
|
|
18410
18412
|
}
|
|
18411
18413
|
function windowsKnownDirs() {
|
|
18412
|
-
const home =
|
|
18413
|
-
const appData = process.env.APPDATA ??
|
|
18414
|
-
const localAppData = process.env.LOCALAPPDATA ??
|
|
18414
|
+
const home = homedir5();
|
|
18415
|
+
const appData = process.env.APPDATA ?? join7(home, "AppData", "Roaming");
|
|
18416
|
+
const localAppData = process.env.LOCALAPPDATA ?? join7(home, "AppData", "Local");
|
|
18415
18417
|
return [
|
|
18416
|
-
|
|
18418
|
+
join7(appData, "npm"),
|
|
18417
18419
|
// npm -g shims: claude, codex
|
|
18418
|
-
|
|
18420
|
+
join7(home, ".grok", "bin"),
|
|
18419
18421
|
// x.ai installer
|
|
18420
|
-
|
|
18422
|
+
join7(localAppData, "agy", "bin"),
|
|
18421
18423
|
// Antigravity installer
|
|
18422
|
-
|
|
18424
|
+
join7(home, ".local", "bin"),
|
|
18423
18425
|
// claude native installer
|
|
18424
|
-
|
|
18425
|
-
|
|
18426
|
+
join7(home, ".claude", "local"),
|
|
18427
|
+
join7(home, "bin"),
|
|
18426
18428
|
// Factory droid installer (%USERPROFILE%\bin)
|
|
18427
|
-
|
|
18428
|
-
|
|
18429
|
-
|
|
18429
|
+
join7(home, ".bun", "bin"),
|
|
18430
|
+
join7(home, ".deno", "bin"),
|
|
18431
|
+
join7(home, "go", "bin")
|
|
18430
18432
|
];
|
|
18431
18433
|
}
|
|
18432
18434
|
function resetPathCache() {
|
|
@@ -18480,7 +18482,7 @@ function findCliCandidates(name) {
|
|
|
18480
18482
|
for (const dir of augmentedPath().split(delimiter3)) {
|
|
18481
18483
|
if (!dir) continue;
|
|
18482
18484
|
for (const ext of exts) {
|
|
18483
|
-
const p =
|
|
18485
|
+
const p = join7(dir, name + ext);
|
|
18484
18486
|
if (existsSync5(p)) {
|
|
18485
18487
|
out.push(p);
|
|
18486
18488
|
break;
|
|
@@ -18525,13 +18527,13 @@ function whichWin(cli) {
|
|
|
18525
18527
|
if (/[\\/]/.test(cli) || /^[a-zA-Z]:/.test(cli)) return probe(cli);
|
|
18526
18528
|
for (const dir of augmentedPath().split(delimiter3)) {
|
|
18527
18529
|
if (!dir) continue;
|
|
18528
|
-
const hit = probe(
|
|
18530
|
+
const hit = probe(join7(dir, cli));
|
|
18529
18531
|
if (hit) return hit;
|
|
18530
18532
|
}
|
|
18531
18533
|
return null;
|
|
18532
18534
|
}
|
|
18533
18535
|
function nodeExe(near) {
|
|
18534
|
-
const local =
|
|
18536
|
+
const local = join7(near, "node.exe");
|
|
18535
18537
|
if (isFile(local)) return local;
|
|
18536
18538
|
const onPath2 = whichWin("node.exe");
|
|
18537
18539
|
if (onPath2 && extname(onPath2).toLowerCase() === ".exe") return onPath2;
|
|
@@ -18544,8 +18546,8 @@ function parseCmdShim(shim) {
|
|
|
18544
18546
|
} catch {
|
|
18545
18547
|
return null;
|
|
18546
18548
|
}
|
|
18547
|
-
const dir =
|
|
18548
|
-
const targets = [...text2.matchAll(/"%~?dp0%?\\?([^"]+)"/g)].map((m) =>
|
|
18549
|
+
const dir = dirname3(shim);
|
|
18550
|
+
const targets = [...text2.matchAll(/"%~?dp0%?\\?([^"]+)"/g)].map((m) => join7(dir, m[1])).filter((p) => isFile(p) && basename2(p).toLowerCase() !== "node.exe");
|
|
18549
18551
|
const script = targets.find((p) => /\.[cm]?js$/i.test(p));
|
|
18550
18552
|
if (script) {
|
|
18551
18553
|
const node = nodeExe(dir);
|
|
@@ -18573,7 +18575,7 @@ function parseNodeShebang(file2) {
|
|
|
18573
18575
|
}
|
|
18574
18576
|
}
|
|
18575
18577
|
if (!/^#!.*\bnode(\.exe)?\b/.test(head)) return null;
|
|
18576
|
-
const node = nodeExe(
|
|
18578
|
+
const node = nodeExe(dirname3(file2));
|
|
18577
18579
|
return node ? { command: node, args: [file2] } : null;
|
|
18578
18580
|
}
|
|
18579
18581
|
function resolveWord(cli, args) {
|
|
@@ -18615,7 +18617,7 @@ import {
|
|
|
18615
18617
|
spawn as spawn4,
|
|
18616
18618
|
execFile as execFile3
|
|
18617
18619
|
} from "node:child_process";
|
|
18618
|
-
import { join as
|
|
18620
|
+
import { join as join8 } from "node:path";
|
|
18619
18621
|
function resolveCli(cli, args = []) {
|
|
18620
18622
|
return resolveCliSpawn(cli, args);
|
|
18621
18623
|
}
|
|
@@ -18709,7 +18711,7 @@ function killCliTree(child, timeoutMs = 5e3) {
|
|
|
18709
18711
|
});
|
|
18710
18712
|
}
|
|
18711
18713
|
function brokerSocketPath(dataDir, tag) {
|
|
18712
|
-
return process.platform === "win32" ? `\\\\.\\pipe\\openmausbot-perm-${process.pid}-${tag}` :
|
|
18714
|
+
return process.platform === "win32" ? `\\\\.\\pipe\\openmausbot-perm-${process.pid}-${tag}` : join8(dataDir, `perm-${tag}.sock`);
|
|
18713
18715
|
}
|
|
18714
18716
|
var WINDOWS_SAFE_COMMAND_LINE_CHARS;
|
|
18715
18717
|
var init_procs = __esm({
|
|
@@ -18937,8 +18939,8 @@ var init_registry = __esm({
|
|
|
18937
18939
|
|
|
18938
18940
|
// server/drivers/local-inject.ts
|
|
18939
18941
|
import { readFileSync as readFileSync5 } from "node:fs";
|
|
18940
|
-
import { homedir as
|
|
18941
|
-
import { join as
|
|
18942
|
+
import { homedir as homedir6 } from "node:os";
|
|
18943
|
+
import { join as join9 } from "node:path";
|
|
18942
18944
|
function contextWindowsFromPs(extra) {
|
|
18943
18945
|
const out = /* @__PURE__ */ new Map();
|
|
18944
18946
|
const rec = extra && typeof extra === "object" ? extra : null;
|
|
@@ -19021,9 +19023,9 @@ function firstUnslothToken(row) {
|
|
|
19021
19023
|
return null;
|
|
19022
19024
|
}
|
|
19023
19025
|
function readUnslothKey(env) {
|
|
19024
|
-
const home = env.HOME || env.USERPROFILE ||
|
|
19026
|
+
const home = env.HOME || env.USERPROFILE || homedir6();
|
|
19025
19027
|
try {
|
|
19026
|
-
const raw = JSON.parse(readFileSync5(
|
|
19028
|
+
const raw = JSON.parse(readFileSync5(join9(home, ".unsloth", "studio", "auth", "agent_api_key.json"), "utf8"));
|
|
19027
19029
|
if (raw.servers && typeof raw.servers === "object") {
|
|
19028
19030
|
const servers = raw.servers;
|
|
19029
19031
|
for (const url2 of ["http://127.0.0.1:8888", "http://localhost:8888"]) {
|
|
@@ -19225,17 +19227,17 @@ var init_local_inject = __esm({
|
|
|
19225
19227
|
|
|
19226
19228
|
// server/proxy-paths.ts
|
|
19227
19229
|
import { existsSync as existsSync6 } from "node:fs";
|
|
19228
|
-
import { dirname as
|
|
19230
|
+
import { dirname as dirname4, join as join10 } from "node:path";
|
|
19229
19231
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
19230
19232
|
function resolveProxy(relative2) {
|
|
19231
|
-
const source =
|
|
19232
|
-
return existsSync6(source) ? source :
|
|
19233
|
+
const source = join10(SERVER_ROOT, `${relative2}.ts`);
|
|
19234
|
+
return existsSync6(source) ? source : join10(SERVER_ROOT, `${relative2}.js`);
|
|
19233
19235
|
}
|
|
19234
19236
|
var SERVER_ROOT, SPAWNED_PROXIES;
|
|
19235
19237
|
var init_proxy_paths = __esm({
|
|
19236
19238
|
"server/proxy-paths.ts"() {
|
|
19237
19239
|
"use strict";
|
|
19238
|
-
SERVER_ROOT =
|
|
19240
|
+
SERVER_ROOT = dirname4(fileURLToPath2(import.meta.url));
|
|
19239
19241
|
SPAWNED_PROXIES = {
|
|
19240
19242
|
browser: resolveProxy("browser-proxy"),
|
|
19241
19243
|
computer: resolveProxy("computer-proxy"),
|
|
@@ -19257,7 +19259,7 @@ var init_proxy_paths = __esm({
|
|
|
19257
19259
|
|
|
19258
19260
|
// server/container-computer.ts
|
|
19259
19261
|
import { execFile as execFile4 } from "node:child_process";
|
|
19260
|
-
import { join as
|
|
19262
|
+
import { join as join11, resolve as resolve3 } from "node:path";
|
|
19261
19263
|
import { promisify } from "node:util";
|
|
19262
19264
|
function computerProxyEnv(computer) {
|
|
19263
19265
|
return {
|
|
@@ -19281,7 +19283,7 @@ var init_container_computer = __esm({
|
|
|
19281
19283
|
IMAGE_REPOSITORY = "localhost/openmausbot/cua-local-vm";
|
|
19282
19284
|
IMAGE_LAYER_VERSION = "5";
|
|
19283
19285
|
IMAGE = `${IMAGE_REPOSITORY}:driver-${CUA_DRIVER_VERSION}-v${IMAGE_LAYER_VERSION}`;
|
|
19284
|
-
VM_WORKSPACE_DIR =
|
|
19286
|
+
VM_WORKSPACE_DIR = join11(DATA_DIR, "vm-home");
|
|
19285
19287
|
MEMORY_BYTES = 4 * 1024 * 1024 * 1024;
|
|
19286
19288
|
SHM_BYTES = 512 * 1024 * 1024;
|
|
19287
19289
|
containerMcpPath = SPAWNED_PROXIES.containerMcp;
|
|
@@ -19372,11 +19374,11 @@ var init_redact = __esm({
|
|
|
19372
19374
|
|
|
19373
19375
|
// server/drivers/native.ts
|
|
19374
19376
|
import { appendFileSync } from "node:fs";
|
|
19375
|
-
import { join as
|
|
19377
|
+
import { join as join12 } from "node:path";
|
|
19376
19378
|
function appendNative(threadId, entry) {
|
|
19377
19379
|
try {
|
|
19378
19380
|
appendFileSync(
|
|
19379
|
-
|
|
19381
|
+
join12(NATIVE_DIR, `${threadId}.ndjson`),
|
|
19380
19382
|
JSON.stringify({ at: (/* @__PURE__ */ new Date()).toISOString(), ...entry, msg: redactSecrets(entry.msg) }) + "\n",
|
|
19381
19383
|
{ mode: 384 }
|
|
19382
19384
|
);
|
|
@@ -19392,9 +19394,9 @@ var init_native = __esm({
|
|
|
19392
19394
|
});
|
|
19393
19395
|
|
|
19394
19396
|
// server/drivers/acp/core.ts
|
|
19395
|
-
import { homedir as
|
|
19397
|
+
import { homedir as homedir7 } from "node:os";
|
|
19396
19398
|
import { lstat, mkdir, readFile, realpath, stat, writeFile } from "node:fs/promises";
|
|
19397
|
-
import { basename as
|
|
19399
|
+
import { basename as basename3, dirname as dirname5, isAbsolute, relative, resolve as resolve4 } from "node:path";
|
|
19398
19400
|
function skipSubscriptionAuthForLocalInject(model) {
|
|
19399
19401
|
return Boolean(decodeInjectId(model));
|
|
19400
19402
|
}
|
|
@@ -19579,7 +19581,7 @@ function createAcpDriver(support11) {
|
|
|
19579
19581
|
throw new Error("local computer control requires interactive provider approvals");
|
|
19580
19582
|
}
|
|
19581
19583
|
const turnId = newId();
|
|
19582
|
-
const cwd = turn.cwd ?? turnConfig.workspace ??
|
|
19584
|
+
const cwd = turn.cwd ?? turnConfig.workspace ?? homedir7();
|
|
19583
19585
|
const env = childEnv(turnConfig);
|
|
19584
19586
|
if (support11.requireAuthenticationBeforeSpawn && !skipSubscriptionAuthForLocalInject(turn.model) && !await support11.isAuthenticated(env, turnConfig, instanceId)) {
|
|
19585
19587
|
emit({ ...base2(threadId, turnId), type: "turn.started" });
|
|
@@ -19647,12 +19649,12 @@ function createAcpDriver(support11) {
|
|
|
19647
19649
|
if (lexical === ".." || lexical.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`) || isAbsolute(lexical)) {
|
|
19648
19650
|
throw new Error("ACP file path is outside the session workspace.");
|
|
19649
19651
|
}
|
|
19650
|
-
const suffix = [
|
|
19651
|
-
let ancestor =
|
|
19652
|
+
const suffix = [basename3(requested)];
|
|
19653
|
+
let ancestor = dirname5(requested);
|
|
19652
19654
|
while (!await lstat(ancestor).catch(() => null)) {
|
|
19653
|
-
const parent =
|
|
19655
|
+
const parent = dirname5(ancestor);
|
|
19654
19656
|
if (parent === ancestor) throw new Error("ACP file path has no accessible parent.");
|
|
19655
|
-
suffix.unshift(
|
|
19657
|
+
suffix.unshift(basename3(ancestor));
|
|
19656
19658
|
ancestor = parent;
|
|
19657
19659
|
}
|
|
19658
19660
|
const candidate = resolve4(await realpath(ancestor), ...suffix);
|
|
@@ -19698,7 +19700,7 @@ function createAcpDriver(support11) {
|
|
|
19698
19700
|
if (typeof params.content !== "string" || Buffer.byteLength(params.content) > CLIENT_FILE_MAX_BYTES) {
|
|
19699
19701
|
throw new Error(`ACP can only write text files under ${CLIENT_FILE_MAX_BYTES} bytes.`);
|
|
19700
19702
|
}
|
|
19701
|
-
await mkdir(
|
|
19703
|
+
await mkdir(dirname5(path3), { recursive: true });
|
|
19702
19704
|
await writeFile(path3, params.content, "utf8");
|
|
19703
19705
|
send({ jsonrpc: "2.0", id: msg.id, result: {} });
|
|
19704
19706
|
} catch (error51) {
|
|
@@ -20162,7 +20164,7 @@ import { createHash as createHash3, randomUUID as randomUUID6 } from "node:crypt
|
|
|
20162
20164
|
import { mkdir as mkdir2, mkdtemp, readFile as readFile2, rm, stat as stat2 } from "node:fs/promises";
|
|
20163
20165
|
import { request as httpRequest } from "node:http";
|
|
20164
20166
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
20165
|
-
import { delimiter as delimiter4, join as
|
|
20167
|
+
import { delimiter as delimiter4, join as join13, resolve as resolve5 } from "node:path";
|
|
20166
20168
|
function quoteBrowserArgument(value) {
|
|
20167
20169
|
return `'${value.replaceAll("'", `'"'"'`)}'`;
|
|
20168
20170
|
}
|
|
@@ -20197,11 +20199,11 @@ function authorizationUrlFromLine(line) {
|
|
|
20197
20199
|
}
|
|
20198
20200
|
}
|
|
20199
20201
|
function antigravityProfileDirectory(instanceId, baseDir = DATA_DIR) {
|
|
20200
|
-
return
|
|
20202
|
+
return join13(baseDir, "providers", "antigravity", createHash3("sha256").update(instanceId).digest("hex"));
|
|
20201
20203
|
}
|
|
20202
20204
|
async function prepareAntigravityProfile(input) {
|
|
20203
20205
|
const directory = resolve5(input.profileDirectory ?? antigravityProfileDirectory(input.instanceId, input.baseDir));
|
|
20204
|
-
const acpDirectory =
|
|
20206
|
+
const acpDirectory = join13(directory, "antigravity-acp");
|
|
20205
20207
|
await mkdir2(acpDirectory, { recursive: true, mode: 448 });
|
|
20206
20208
|
if (process.platform !== "win32") {
|
|
20207
20209
|
const { chmod: chmod2 } = await import("node:fs/promises");
|
|
@@ -20209,7 +20211,7 @@ async function prepareAntigravityProfile(input) {
|
|
|
20209
20211
|
await chmod2(acpDirectory, 448);
|
|
20210
20212
|
}
|
|
20211
20213
|
writeFileAtomic(
|
|
20212
|
-
|
|
20214
|
+
join13(acpDirectory, "settings.json"),
|
|
20213
20215
|
`${JSON.stringify({ auth: { type: "oauth-personal" } })}
|
|
20214
20216
|
`,
|
|
20215
20217
|
{ mode: 384 }
|
|
@@ -20232,7 +20234,7 @@ async function prepareAntigravityProfile(input) {
|
|
|
20232
20234
|
PYTHONUNBUFFERED: "1",
|
|
20233
20235
|
ELECTRON_RUN_AS_NODE: "1"
|
|
20234
20236
|
});
|
|
20235
|
-
return { directory, tokenPath:
|
|
20237
|
+
return { directory, tokenPath: join13(acpDirectory, "acp_token.json"), environment };
|
|
20236
20238
|
}
|
|
20237
20239
|
async function antigravityProfileAuthenticated(profile) {
|
|
20238
20240
|
try {
|
|
@@ -20361,7 +20363,7 @@ function isValidAntigravityInitializeResult(initialized, expectedVersion) {
|
|
|
20361
20363
|
return true;
|
|
20362
20364
|
}
|
|
20363
20365
|
async function validateAntigravityRuntime(runtime, expectedVersion) {
|
|
20364
|
-
const profileDirectory = await mkdtemp(
|
|
20366
|
+
const profileDirectory = await mkdtemp(join13(tmpdir2(), "openmaus-antigravity-verify-"));
|
|
20365
20367
|
let client;
|
|
20366
20368
|
let failed = false;
|
|
20367
20369
|
let failure;
|
|
@@ -20750,7 +20752,7 @@ import {
|
|
|
20750
20752
|
writeFile as writeFile2
|
|
20751
20753
|
} from "node:fs/promises";
|
|
20752
20754
|
import { constants } from "node:fs";
|
|
20753
|
-
import { delimiter as delimiter5, dirname as
|
|
20755
|
+
import { delimiter as delimiter5, dirname as dirname6, isAbsolute as isAbsolute2, join as join14, resolve as resolve6 } from "node:path";
|
|
20754
20756
|
import { Transform } from "node:stream";
|
|
20755
20757
|
import { pipeline } from "node:stream/promises";
|
|
20756
20758
|
import { createInflateRaw } from "node:zlib";
|
|
@@ -20771,7 +20773,7 @@ async function retryOnWindowsFileLock(step, options = {}) {
|
|
|
20771
20773
|
}
|
|
20772
20774
|
}
|
|
20773
20775
|
function runtimeRoot(baseDir = DATA_DIR) {
|
|
20774
|
-
return
|
|
20776
|
+
return join14(baseDir, "tools", "antigravity-acp", `${process.platform}-${process.arch}`);
|
|
20775
20777
|
}
|
|
20776
20778
|
function executableNames(platform = process.platform) {
|
|
20777
20779
|
return platform === "win32" ? { executable: "agy_acp_server.exe", harness: "localharness_external.exe" } : { executable: "agy_acp_server.par", harness: "localharness_external" };
|
|
@@ -20788,10 +20790,10 @@ async function executableFile(path3, bytes) {
|
|
|
20788
20790
|
}
|
|
20789
20791
|
async function completedRelease(directory, asset) {
|
|
20790
20792
|
try {
|
|
20791
|
-
const record3 = JSON.parse(await readFile3(
|
|
20793
|
+
const record3 = JSON.parse(await readFile3(join14(directory, INSTALL_RECORD), "utf8"));
|
|
20792
20794
|
if (record3.sha256 !== asset.sha256 || record3.version !== asset.version || record3.executable.name !== asset.executable.name || record3.executable.bytes !== asset.executable.bytes || record3.harness.name !== asset.harness.name || record3.harness.bytes !== asset.harness.bytes) return null;
|
|
20793
|
-
const executablePath =
|
|
20794
|
-
const harnessPath =
|
|
20795
|
+
const executablePath = join14(directory, asset.executable.name);
|
|
20796
|
+
const harnessPath = join14(directory, asset.harness.name);
|
|
20795
20797
|
if (!await executableFile(executablePath, asset.executable.bytes)) return null;
|
|
20796
20798
|
if (!await executableFile(harnessPath, asset.harness.bytes)) return null;
|
|
20797
20799
|
return { executablePath, harnessPath, source: "managed", version: asset.version };
|
|
@@ -20807,7 +20809,7 @@ function pathCandidates(binary2, env) {
|
|
|
20807
20809
|
async function externalRuntime(candidate, source) {
|
|
20808
20810
|
const names = executableNames();
|
|
20809
20811
|
const executablePath = resolve6(candidate);
|
|
20810
|
-
const harnessPath =
|
|
20812
|
+
const harnessPath = join14(dirname6(executablePath), names.harness);
|
|
20811
20813
|
if (!await executableFile(executablePath) || !await executableFile(harnessPath)) return null;
|
|
20812
20814
|
return { executablePath, harnessPath, source, version: null };
|
|
20813
20815
|
}
|
|
@@ -20827,7 +20829,7 @@ async function resolveAntigravityRuntime(binaryPath, env = process.env, baseDir
|
|
|
20827
20829
|
}
|
|
20828
20830
|
const asset = resolveAntigravityReleaseAsset();
|
|
20829
20831
|
if (asset) {
|
|
20830
|
-
const managed = await completedRelease(
|
|
20832
|
+
const managed = await completedRelease(join14(runtimeRoot(baseDir), "versions", asset.sha256), asset);
|
|
20831
20833
|
if (managed) return managed;
|
|
20832
20834
|
}
|
|
20833
20835
|
const names = executableNames();
|
|
@@ -20949,7 +20951,7 @@ async function extractPinnedArchive(archivePath, outputDirectory, asset) {
|
|
|
20949
20951
|
start: dataOffset,
|
|
20950
20952
|
end: dataOffset + entry.compressedBytes - 1
|
|
20951
20953
|
});
|
|
20952
|
-
const destination = createWriteStream(
|
|
20954
|
+
const destination = createWriteStream(join14(outputDirectory, entry.name), { flags: "wx", mode: 448 });
|
|
20953
20955
|
if (entry.compression === 8) await pipeline(source, createInflateRaw(), counter, destination);
|
|
20954
20956
|
else await pipeline(source, counter, destination);
|
|
20955
20957
|
if (bytes !== expectedBytes) throw new Error("An extracted file was truncated.");
|
|
@@ -20960,8 +20962,8 @@ async function installOnce(options) {
|
|
|
20960
20962
|
const asset = options.asset === void 0 ? resolveAntigravityReleaseAsset() : options.asset;
|
|
20961
20963
|
if (!asset) throw new Error(`Google does not publish an Antigravity runtime for ${process.platform}-${process.arch}.`);
|
|
20962
20964
|
const root = runtimeRoot(options.baseDir);
|
|
20963
|
-
const versions =
|
|
20964
|
-
const destination =
|
|
20965
|
+
const versions = join14(root, "versions");
|
|
20966
|
+
const destination = join14(versions, asset.sha256);
|
|
20965
20967
|
await mkdir3(versions, { recursive: true, mode: 448 });
|
|
20966
20968
|
const existing = await completedRelease(destination, asset);
|
|
20967
20969
|
if (existing) {
|
|
@@ -20977,11 +20979,11 @@ async function installOnce(options) {
|
|
|
20977
20979
|
} catch (error51) {
|
|
20978
20980
|
if (error51 instanceof Error && error51.message.includes("Antigravity needs")) throw error51;
|
|
20979
20981
|
}
|
|
20980
|
-
const staging = await mkdtemp2(
|
|
20982
|
+
const staging = await mkdtemp2(join14(versions, `${STAGING_PREFIX}${randomUUID7()}-`));
|
|
20981
20983
|
let failed = false;
|
|
20982
20984
|
try {
|
|
20983
|
-
const archivePath =
|
|
20984
|
-
const runtimeDirectory =
|
|
20985
|
+
const archivePath = join14(staging, "download.zip");
|
|
20986
|
+
const runtimeDirectory = join14(staging, "runtime");
|
|
20985
20987
|
await mkdir3(runtimeDirectory, { mode: 448 });
|
|
20986
20988
|
const controller = new AbortController();
|
|
20987
20989
|
const timeout = setTimeout(() => controller.abort(), DOWNLOAD_TIMEOUT_MS2);
|
|
@@ -21027,12 +21029,12 @@ async function installOnce(options) {
|
|
|
21027
21029
|
}
|
|
21028
21030
|
await extractPinnedArchive(archivePath, runtimeDirectory, asset);
|
|
21029
21031
|
if (process.platform !== "win32") {
|
|
21030
|
-
await chmod(
|
|
21031
|
-
await chmod(
|
|
21032
|
+
await chmod(join14(runtimeDirectory, asset.executable.name), 493);
|
|
21033
|
+
await chmod(join14(runtimeDirectory, asset.harness.name), 493);
|
|
21032
21034
|
}
|
|
21033
21035
|
const candidate = {
|
|
21034
|
-
executablePath:
|
|
21035
|
-
harnessPath:
|
|
21036
|
+
executablePath: join14(runtimeDirectory, asset.executable.name),
|
|
21037
|
+
harnessPath: join14(runtimeDirectory, asset.harness.name),
|
|
21036
21038
|
source: "managed",
|
|
21037
21039
|
version: asset.version
|
|
21038
21040
|
};
|
|
@@ -21043,7 +21045,7 @@ async function installOnce(options) {
|
|
|
21043
21045
|
executable: asset.executable,
|
|
21044
21046
|
harness: asset.harness
|
|
21045
21047
|
};
|
|
21046
|
-
await writeFile2(
|
|
21048
|
+
await writeFile2(join14(runtimeDirectory, INSTALL_RECORD), `${JSON.stringify(record3)}
|
|
21047
21049
|
`, { flag: "wx", mode: 384 });
|
|
21048
21050
|
try {
|
|
21049
21051
|
await retryOnWindowsFileLock(() => rename(runtimeDirectory, destination));
|
|
@@ -21482,15 +21484,15 @@ var init_boxagent = __esm({
|
|
|
21482
21484
|
// server/drivers/claude-login-auth.ts
|
|
21483
21485
|
import { randomUUID as randomUUID8 } from "node:crypto";
|
|
21484
21486
|
import { realpathSync } from "node:fs";
|
|
21485
|
-
import { homedir as
|
|
21486
|
-
import { basename as
|
|
21487
|
+
import { homedir as homedir8 } from "node:os";
|
|
21488
|
+
import { basename as basename4, dirname as dirname7, isAbsolute as isAbsolute3, join as join15, resolve as resolve7 } from "node:path";
|
|
21487
21489
|
import { stripVTControlCharacters as stripVTControlCharacters3 } from "node:util";
|
|
21488
21490
|
function canonicalPath(path3) {
|
|
21489
21491
|
try {
|
|
21490
21492
|
return realpathSync(path3);
|
|
21491
21493
|
} catch {
|
|
21492
|
-
const parent =
|
|
21493
|
-
return parent === path3 ? path3 :
|
|
21494
|
+
const parent = dirname7(path3);
|
|
21495
|
+
return parent === path3 ? path3 : join15(canonicalPath(parent), basename4(path3));
|
|
21494
21496
|
}
|
|
21495
21497
|
}
|
|
21496
21498
|
function claudeSignInLink(value) {
|
|
@@ -21542,11 +21544,11 @@ var init_claude_login_auth = __esm({
|
|
|
21542
21544
|
await this.flow?.stopping;
|
|
21543
21545
|
if (this.disposed) throw new Error("This provider was removed. Refresh Settings before signing in.");
|
|
21544
21546
|
const env = this.options.environment();
|
|
21545
|
-
const home = env.HOME || env.USERPROFILE ||
|
|
21547
|
+
const home = env.HOME || env.USERPROFILE || homedir8();
|
|
21546
21548
|
if (!isAbsolute3(home) || env.CLAUDE_CONFIG_DIR && !isAbsolute3(env.CLAUDE_CONFIG_DIR)) {
|
|
21547
21549
|
throw new Error("Use an absolute HOME and CLAUDE_CONFIG_DIR path for this server's Claude provider before signing in.");
|
|
21548
21550
|
}
|
|
21549
|
-
const homeKey = canonicalPath(resolve7(env.CLAUDE_CONFIG_DIR ||
|
|
21551
|
+
const homeKey = canonicalPath(resolve7(env.CLAUDE_CONFIG_DIR || join15(home, ".claude")));
|
|
21550
21552
|
if (authenticatingHomes.has(homeKey)) {
|
|
21551
21553
|
throw new Error("A Claude sign-in is already running for this server account. Finish or cancel it before starting another.");
|
|
21552
21554
|
}
|
|
@@ -21856,10 +21858,10 @@ var init_retry = __esm({
|
|
|
21856
21858
|
|
|
21857
21859
|
// server/drivers/claude.ts
|
|
21858
21860
|
import { createHash as createHash5, randomBytes as randomBytes2 } from "node:crypto";
|
|
21859
|
-
import { chmodSync as chmodSync3, mkdtempSync as mkdtempSync2, readFileSync as readFileSync6, rmSync as rmSync2, unlinkSync as unlinkSync3, writeFileSync as
|
|
21861
|
+
import { chmodSync as chmodSync3, mkdtempSync as mkdtempSync2, readFileSync as readFileSync6, rmSync as rmSync2, unlinkSync as unlinkSync3, writeFileSync as writeFileSync5 } from "node:fs";
|
|
21860
21862
|
import { createServer as createNetServer } from "node:net";
|
|
21861
|
-
import { homedir as
|
|
21862
|
-
import { join as
|
|
21863
|
+
import { homedir as homedir9, tmpdir as tmpdir3 } from "node:os";
|
|
21864
|
+
import { join as join16, dirname as dirname8, isAbsolute as isAbsolute4, normalize } from "node:path";
|
|
21863
21865
|
function claudeAuthStatus(cli, env, run3 = execCli) {
|
|
21864
21866
|
return new Promise((resolve12) => {
|
|
21865
21867
|
run3(cli, ["auth", "status", "--json"], { timeout: 8e3, maxBuffer: 65536, env }, (_error, stdout2) => {
|
|
@@ -21884,9 +21886,9 @@ function claudeAuthStatus(cli, env, run3 = execCli) {
|
|
|
21884
21886
|
});
|
|
21885
21887
|
}
|
|
21886
21888
|
function resolveClaudeConfigDir(configDir, env = process.env) {
|
|
21887
|
-
const home = env.HOME || env.USERPROFILE ||
|
|
21888
|
-
const configured = configDir?.trim() || env.CLAUDE_CONFIG_DIR?.trim() ||
|
|
21889
|
-
const expanded = configured === "~" ? home : configured.startsWith("~/") ?
|
|
21889
|
+
const home = env.HOME || env.USERPROFILE || homedir9();
|
|
21890
|
+
const configured = configDir?.trim() || env.CLAUDE_CONFIG_DIR?.trim() || join16(home, ".claude");
|
|
21891
|
+
const expanded = configured === "~" ? home : configured.startsWith("~/") ? join16(home, configured.slice(2)) : configured;
|
|
21890
21892
|
if (!isAbsolute4(expanded) || /[\p{Cc}\p{Cf}]/u.test(expanded)) {
|
|
21891
21893
|
throw new Error("claude: configDir must be an absolute path or start with ~/");
|
|
21892
21894
|
}
|
|
@@ -21938,7 +21940,7 @@ function extrasFromUnknown(value) {
|
|
|
21938
21940
|
function readClaudeModelCatalog(env = process.env) {
|
|
21939
21941
|
let settings2 = {};
|
|
21940
21942
|
try {
|
|
21941
|
-
settings2 = JSON.parse(readFileSync6(
|
|
21943
|
+
settings2 = JSON.parse(readFileSync6(join16(resolveClaudeConfigDir(void 0, env), "settings.json"), "utf8"));
|
|
21942
21944
|
} catch {
|
|
21943
21945
|
return STATIC_CLAUDE_MODELS;
|
|
21944
21946
|
}
|
|
@@ -21962,7 +21964,7 @@ function readClaudeModelCatalog(env = process.env) {
|
|
|
21962
21964
|
function removePrivateTempDir(filePath) {
|
|
21963
21965
|
if (!filePath) return true;
|
|
21964
21966
|
try {
|
|
21965
|
-
rmSync2(
|
|
21967
|
+
rmSync2(dirname8(filePath), { recursive: true, force: true, maxRetries: 3, retryDelay: 50 });
|
|
21966
21968
|
return true;
|
|
21967
21969
|
} catch {
|
|
21968
21970
|
return false;
|
|
@@ -21988,7 +21990,7 @@ function brokerSocketCandidates(threadId) {
|
|
|
21988
21990
|
const base2 = permissionSocketPath(threadId);
|
|
21989
21991
|
if (process.platform !== "win32") {
|
|
21990
21992
|
const scope = createHash5("sha256").update(`${DATA_DIR}\0${process.pid}\0${threadId}`).digest("hex").slice(0, 16);
|
|
21991
|
-
return [base2,
|
|
21993
|
+
return [base2, join16(tmpdir3(), `omb-perm-${scope}.sock`)];
|
|
21992
21994
|
}
|
|
21993
21995
|
return [
|
|
21994
21996
|
base2,
|
|
@@ -22454,13 +22456,13 @@ var init_claude = __esm({
|
|
|
22454
22456
|
allowed.push("mcp__ogb");
|
|
22455
22457
|
let mcpConfigPath = null;
|
|
22456
22458
|
if (Object.keys(mcpServers).length) {
|
|
22457
|
-
mcpConfigPath =
|
|
22459
|
+
mcpConfigPath = join16(mkdtempSync2(join16(tmpdir3(), "omb-mcp-")), "mcp.json");
|
|
22458
22460
|
args.push("--mcp-config", mcpConfigPath);
|
|
22459
22461
|
args.push("--allowedTools", allowed.join(","));
|
|
22460
22462
|
}
|
|
22461
22463
|
const env = environment(turnModel);
|
|
22462
22464
|
env.CLAUDE_CODE_DISABLE_BACKGROUND_TASKS = "1";
|
|
22463
|
-
const cwd = turn.cwd ??
|
|
22465
|
+
const cwd = turn.cwd ?? homedir9();
|
|
22464
22466
|
const privateFileFlags = /* @__PURE__ */ new Set(["--mcp-config"]);
|
|
22465
22467
|
const keyArgs = args.filter((a2, i2) => !privateFileFlags.has(a2) && !privateFileFlags.has(args[i2 - 1] ?? ""));
|
|
22466
22468
|
const argsKey = JSON.stringify({
|
|
@@ -22489,7 +22491,7 @@ var init_claude = __esm({
|
|
|
22489
22491
|
retryState.delete(threadId);
|
|
22490
22492
|
if (mcpConfigPath) {
|
|
22491
22493
|
try {
|
|
22492
|
-
rmSync2(
|
|
22494
|
+
rmSync2(dirname8(mcpConfigPath), { recursive: true, force: true });
|
|
22493
22495
|
} catch {
|
|
22494
22496
|
}
|
|
22495
22497
|
}
|
|
@@ -22497,7 +22499,7 @@ var init_claude = __esm({
|
|
|
22497
22499
|
}
|
|
22498
22500
|
if (mcpConfigPath) {
|
|
22499
22501
|
try {
|
|
22500
|
-
rmSync2(
|
|
22502
|
+
rmSync2(dirname8(mcpConfigPath), { recursive: true, force: true });
|
|
22501
22503
|
} catch {
|
|
22502
22504
|
}
|
|
22503
22505
|
}
|
|
@@ -22509,7 +22511,7 @@ var init_claude = __esm({
|
|
|
22509
22511
|
broker = void 0;
|
|
22510
22512
|
if (mcpConfigPath) {
|
|
22511
22513
|
try {
|
|
22512
|
-
rmSync2(
|
|
22514
|
+
rmSync2(dirname8(mcpConfigPath), { recursive: true, force: true });
|
|
22513
22515
|
} catch {
|
|
22514
22516
|
}
|
|
22515
22517
|
mcpConfigPath = null;
|
|
@@ -22522,8 +22524,8 @@ var init_claude = __esm({
|
|
|
22522
22524
|
};
|
|
22523
22525
|
try {
|
|
22524
22526
|
if (turn.system) {
|
|
22525
|
-
systemPromptPath =
|
|
22526
|
-
|
|
22527
|
+
systemPromptPath = join16(mkdtempSync2(join16(tmpdir3(), "omb-system-")), "prompt.txt");
|
|
22528
|
+
writeFileSync5(systemPromptPath, turn.system, { mode: 384 });
|
|
22527
22529
|
args.push("--append-system-prompt-file", systemPromptPath);
|
|
22528
22530
|
}
|
|
22529
22531
|
if (socketPath) {
|
|
@@ -22563,7 +22565,7 @@ var init_claude = __esm({
|
|
|
22563
22565
|
}
|
|
22564
22566
|
}
|
|
22565
22567
|
if (mcpConfigPath) {
|
|
22566
|
-
|
|
22568
|
+
writeFileSync5(mcpConfigPath, JSON.stringify({ mcpServers }), { mode: 384 });
|
|
22567
22569
|
}
|
|
22568
22570
|
if (sessionId) args.push("--resume", sessionId);
|
|
22569
22571
|
else args.push("--session-id", newSessionId);
|
|
@@ -22602,7 +22604,7 @@ var init_claude = __esm({
|
|
|
22602
22604
|
session.broker?.pause();
|
|
22603
22605
|
if (session.mcpConfigPath) {
|
|
22604
22606
|
try {
|
|
22605
|
-
rmSync2(
|
|
22607
|
+
rmSync2(dirname8(session.mcpConfigPath), { recursive: true, force: true });
|
|
22606
22608
|
} catch {
|
|
22607
22609
|
}
|
|
22608
22610
|
session.mcpConfigPath = null;
|
|
@@ -22730,7 +22732,7 @@ var init_claude = __esm({
|
|
|
22730
22732
|
failedBroker?.close();
|
|
22731
22733
|
if (session.mcpConfigPath) {
|
|
22732
22734
|
try {
|
|
22733
|
-
rmSync2(
|
|
22735
|
+
rmSync2(dirname8(session.mcpConfigPath), { recursive: true, force: true });
|
|
22734
22736
|
} catch {
|
|
22735
22737
|
}
|
|
22736
22738
|
session.mcpConfigPath = null;
|
|
@@ -22799,7 +22801,7 @@ var init_claude = __esm({
|
|
|
22799
22801
|
session.broker?.close();
|
|
22800
22802
|
if (session.mcpConfigPath) {
|
|
22801
22803
|
try {
|
|
22802
|
-
rmSync2(
|
|
22804
|
+
rmSync2(dirname8(session.mcpConfigPath), { recursive: true, force: true });
|
|
22803
22805
|
} catch {
|
|
22804
22806
|
}
|
|
22805
22807
|
}
|
|
@@ -22961,8 +22963,8 @@ var init_claude = __esm({
|
|
|
22961
22963
|
|
|
22962
22964
|
// server/drivers/codex-catalog.ts
|
|
22963
22965
|
import { readdirSync as readdirSync2, readFileSync as readFileSync7 } from "node:fs";
|
|
22964
|
-
import { homedir as
|
|
22965
|
-
import { basename as
|
|
22966
|
+
import { homedir as homedir10 } from "node:os";
|
|
22967
|
+
import { basename as basename5, join as join17 } from "node:path";
|
|
22966
22968
|
function encodeCodexSelection(provider, model) {
|
|
22967
22969
|
return `${provider}${SEP}${model}`;
|
|
22968
22970
|
}
|
|
@@ -22977,7 +22979,7 @@ function decodeCodexSelection(id) {
|
|
|
22977
22979
|
function readCodexAppServerModelCatalog(cli, env, timeoutMs = 8e3) {
|
|
22978
22980
|
return new Promise((resolve12) => {
|
|
22979
22981
|
const child = spawnCli(cli, ["app-server"], {
|
|
22980
|
-
cwd:
|
|
22982
|
+
cwd: homedir10(),
|
|
22981
22983
|
env,
|
|
22982
22984
|
stdio: ["pipe", "pipe", "pipe"]
|
|
22983
22985
|
});
|
|
@@ -23078,7 +23080,7 @@ function readCodexAppServerModelCatalog(cli, env, timeoutMs = 8e3) {
|
|
|
23078
23080
|
}
|
|
23079
23081
|
function codexHome(env) {
|
|
23080
23082
|
if (env.CODEX_HOME) return env.CODEX_HOME;
|
|
23081
|
-
return
|
|
23083
|
+
return join17(env.HOME || env.USERPROFILE || homedir10(), ".codex");
|
|
23082
23084
|
}
|
|
23083
23085
|
function unquote(raw) {
|
|
23084
23086
|
let value = raw.trim();
|
|
@@ -23164,11 +23166,11 @@ function niceLabel(model, provider, known, named) {
|
|
|
23164
23166
|
}
|
|
23165
23167
|
function collectCatalogNames(home) {
|
|
23166
23168
|
const named = /* @__PURE__ */ new Map();
|
|
23167
|
-
for (const file2 of listDir(
|
|
23169
|
+
for (const file2 of listDir(join17(home, "model-catalogs"))) {
|
|
23168
23170
|
if (!file2.endsWith(".json")) continue;
|
|
23169
|
-
const provider =
|
|
23171
|
+
const provider = basename5(file2, ".json").replace(/-models$/, "");
|
|
23170
23172
|
if (!PROVIDER_ID.test(provider)) continue;
|
|
23171
|
-
const raw = readText(
|
|
23173
|
+
const raw = readText(join17(home, "model-catalogs", file2));
|
|
23172
23174
|
if (!raw) continue;
|
|
23173
23175
|
let parsed;
|
|
23174
23176
|
try {
|
|
@@ -23220,7 +23222,7 @@ async function probeProviderModels(provider, env, fetchImpl) {
|
|
|
23220
23222
|
async function readCodexModelCatalog(env = process.env, fetchImpl = fetch, cli) {
|
|
23221
23223
|
const official = (cli ? await readCodexAppServerModelCatalog(cli, env) : null) ?? STATIC_CODEX_MODELS;
|
|
23222
23224
|
const home = codexHome(env);
|
|
23223
|
-
const mainText = readText(
|
|
23225
|
+
const mainText = readText(join17(home, "config.toml"));
|
|
23224
23226
|
if (!mainText) return mergeLocalInject(official, env, fetchImpl);
|
|
23225
23227
|
const main2 = parseCodexToml(mainText);
|
|
23226
23228
|
const known = new Map(main2.providers.map((provider) => [provider.id, provider]));
|
|
@@ -23235,7 +23237,7 @@ async function readCodexModelCatalog(env = process.env, fetchImpl = fetch, cli)
|
|
|
23235
23237
|
remember(main2.modelProvider, main2.model);
|
|
23236
23238
|
for (const file2 of listDir(home)) {
|
|
23237
23239
|
if (!file2.endsWith(".config.toml")) continue;
|
|
23238
|
-
const profile = parseCodexToml(readText(
|
|
23240
|
+
const profile = parseCodexToml(readText(join17(home, file2)) ?? "");
|
|
23239
23241
|
for (const provider of profile.providers) {
|
|
23240
23242
|
if (!known.has(provider.id)) known.set(provider.id, provider);
|
|
23241
23243
|
}
|
|
@@ -23301,8 +23303,8 @@ var init_codex_catalog = __esm({
|
|
|
23301
23303
|
|
|
23302
23304
|
// server/drivers/codex-instructions.ts
|
|
23303
23305
|
import { createHash as createHash6 } from "node:crypto";
|
|
23304
|
-
import { mkdirSync as
|
|
23305
|
-
import { join as
|
|
23306
|
+
import { mkdirSync as mkdirSync6, readFileSync as readFileSync8 } from "node:fs";
|
|
23307
|
+
import { join as join18 } from "node:path";
|
|
23306
23308
|
function codexDeveloperInstructions(config2, botInstructions) {
|
|
23307
23309
|
if (!config2 || typeof config2 !== "object" || Array.isArray(config2)) {
|
|
23308
23310
|
throw new Error("Codex returned no effective configuration; cannot safely update bot instructions.");
|
|
@@ -23316,8 +23318,8 @@ function codexDeveloperInstructions(config2, botInstructions) {
|
|
|
23316
23318
|
${configured}` : botInstructions;
|
|
23317
23319
|
}
|
|
23318
23320
|
async function syncCodexInstructions(key, nativeThreadId, instructions, resumed, request) {
|
|
23319
|
-
const directory =
|
|
23320
|
-
const path3 =
|
|
23321
|
+
const directory = join18(DATA_DIR, "codex-instructions");
|
|
23322
|
+
const path3 = join18(directory, `${digest(JSON.stringify([key, nativeThreadId]))}.sha256`);
|
|
23321
23323
|
const fingerprint = digest(instructions);
|
|
23322
23324
|
let previous;
|
|
23323
23325
|
try {
|
|
@@ -23346,7 +23348,7 @@ async function syncCodexInstructions(key, nativeThreadId, instructions, resumed,
|
|
|
23346
23348
|
}
|
|
23347
23349
|
}
|
|
23348
23350
|
if (!resumed || previous !== fingerprint) {
|
|
23349
|
-
|
|
23351
|
+
mkdirSync6(directory, { recursive: true });
|
|
23350
23352
|
writeFileAtomic(path3, fingerprint, { mode: 384 });
|
|
23351
23353
|
}
|
|
23352
23354
|
}
|
|
@@ -23363,15 +23365,15 @@ var init_codex_instructions = __esm({
|
|
|
23363
23365
|
// server/drivers/codex-device-auth.ts
|
|
23364
23366
|
import { randomUUID as randomUUID9 } from "node:crypto";
|
|
23365
23367
|
import { realpathSync as realpathSync2 } from "node:fs";
|
|
23366
|
-
import { homedir as
|
|
23367
|
-
import { basename as
|
|
23368
|
+
import { homedir as homedir11 } from "node:os";
|
|
23369
|
+
import { basename as basename6, dirname as dirname9, isAbsolute as isAbsolute5, join as join19, resolve as resolve8 } from "node:path";
|
|
23368
23370
|
import { stripVTControlCharacters as stripVTControlCharacters4 } from "node:util";
|
|
23369
23371
|
function canonicalPath2(path3) {
|
|
23370
23372
|
try {
|
|
23371
23373
|
return realpathSync2(path3);
|
|
23372
23374
|
} catch {
|
|
23373
|
-
const parent =
|
|
23374
|
-
return parent === path3 ? path3 :
|
|
23375
|
+
const parent = dirname9(path3);
|
|
23376
|
+
return parent === path3 ? path3 : join19(canonicalPath2(parent), basename6(path3));
|
|
23375
23377
|
}
|
|
23376
23378
|
}
|
|
23377
23379
|
function codexDevicePrompt(output) {
|
|
@@ -23417,11 +23419,11 @@ var init_codex_device_auth = __esm({
|
|
|
23417
23419
|
await this.flow?.stopping;
|
|
23418
23420
|
if (this.disposed) throw new Error("This provider was removed. Refresh Settings before signing in.");
|
|
23419
23421
|
const env = this.options.environment();
|
|
23420
|
-
const home = env.HOME || env.USERPROFILE ||
|
|
23422
|
+
const home = env.HOME || env.USERPROFILE || homedir11();
|
|
23421
23423
|
if (!isAbsolute5(home) || env.CODEX_HOME && !isAbsolute5(env.CODEX_HOME)) {
|
|
23422
23424
|
throw new Error("Use an absolute HOME and CODEX_HOME path for this server's Codex provider before signing in.");
|
|
23423
23425
|
}
|
|
23424
|
-
const homeKey = canonicalPath2(resolve8(env.CODEX_HOME ||
|
|
23426
|
+
const homeKey = canonicalPath2(resolve8(env.CODEX_HOME || join19(home, ".codex")));
|
|
23425
23427
|
if (authenticatingHomes2.has(homeKey)) {
|
|
23426
23428
|
throw new Error("A ChatGPT sign-in is already running for this server account. Finish or cancel it before starting another.");
|
|
23427
23429
|
}
|
|
@@ -23580,7 +23582,7 @@ var init_codex_device_auth = __esm({
|
|
|
23580
23582
|
|
|
23581
23583
|
// server/drivers/codex.ts
|
|
23582
23584
|
import { existsSync as existsSync7 } from "node:fs";
|
|
23583
|
-
import { homedir as
|
|
23585
|
+
import { homedir as homedir12 } from "node:os";
|
|
23584
23586
|
function codexPredatesAstra(version2) {
|
|
23585
23587
|
const value = version2.trim();
|
|
23586
23588
|
const match = /\bcodex-cli\s+v?(\d+)\.(\d+)\.(\d+)(?:[-+][0-9a-z.-]+)?(?![\d.])\b/i.exec(value) ?? /^v?(\d+)\.(\d+)\.(\d+)(?:[-+][0-9a-z.-]+)?$/i.exec(value);
|
|
@@ -23983,7 +23985,7 @@ var init_codex = __esm({
|
|
|
23983
23985
|
);
|
|
23984
23986
|
}
|
|
23985
23987
|
const child = spawnCli(config2.cli, appServerArgs, {
|
|
23986
|
-
cwd: turn.cwd ??
|
|
23988
|
+
cwd: turn.cwd ?? homedir12(),
|
|
23987
23989
|
env,
|
|
23988
23990
|
stdio: ["pipe", "pipe", "pipe"]
|
|
23989
23991
|
});
|
|
@@ -24289,7 +24291,7 @@ var init_codex = __esm({
|
|
|
24289
24291
|
let effectiveConfig;
|
|
24290
24292
|
try {
|
|
24291
24293
|
const configured = await request("config/read", {
|
|
24292
|
-
cwd: turn.cwd ??
|
|
24294
|
+
cwd: turn.cwd ?? homedir12(),
|
|
24293
24295
|
includeLayers: false
|
|
24294
24296
|
});
|
|
24295
24297
|
effectiveConfig = configured?.config;
|
|
@@ -24333,7 +24335,7 @@ var init_codex = __esm({
|
|
|
24333
24335
|
const selection = decodeCodexSelection(turn.model);
|
|
24334
24336
|
const startThread = () => request("thread/start", {
|
|
24335
24337
|
developerInstructions,
|
|
24336
|
-
cwd: turn.cwd ??
|
|
24338
|
+
cwd: turn.cwd ?? homedir12(),
|
|
24337
24339
|
model: selection.model,
|
|
24338
24340
|
...selection.modelProvider ? { modelProvider: selection.modelProvider } : {},
|
|
24339
24341
|
...approvalParams.thread,
|
|
@@ -24790,12 +24792,12 @@ var init_grok = __esm({
|
|
|
24790
24792
|
});
|
|
24791
24793
|
|
|
24792
24794
|
// server/drivers/acp/grok.ts
|
|
24793
|
-
import { existsSync as existsSync8, readFileSync as readFileSync9, writeFileSync as
|
|
24794
|
-
import { homedir as
|
|
24795
|
-
import { join as
|
|
24795
|
+
import { existsSync as existsSync8, readFileSync as readFileSync9, writeFileSync as writeFileSync6 } from "node:fs";
|
|
24796
|
+
import { homedir as homedir13 } from "node:os";
|
|
24797
|
+
import { join as join20 } from "node:path";
|
|
24796
24798
|
function grokHome(env) {
|
|
24797
24799
|
if (env.GROK_HOME) return env.GROK_HOME;
|
|
24798
|
-
return
|
|
24800
|
+
return join20(env.HOME || env.USERPROFILE || homedir13(), ".grok");
|
|
24799
24801
|
}
|
|
24800
24802
|
function unquote2(raw) {
|
|
24801
24803
|
const value = raw.trim();
|
|
@@ -24805,7 +24807,7 @@ function unquote2(raw) {
|
|
|
24805
24807
|
return value;
|
|
24806
24808
|
}
|
|
24807
24809
|
function readGrokModelCatalog(env = process.env) {
|
|
24808
|
-
const path3 =
|
|
24810
|
+
const path3 = join20(grokHome(env), "config.toml");
|
|
24809
24811
|
let text2 = "";
|
|
24810
24812
|
try {
|
|
24811
24813
|
text2 = readFileSync9(path3, "utf8");
|
|
@@ -24878,7 +24880,7 @@ function ensureGrokInjectSlug(modelId, env = process.env) {
|
|
|
24878
24880
|
if (!inject) return modelId;
|
|
24879
24881
|
const host = localHost(inject.host);
|
|
24880
24882
|
if (!host) return modelId;
|
|
24881
|
-
const path3 =
|
|
24883
|
+
const path3 = join20(grokHome(env), "config.toml");
|
|
24882
24884
|
let text2 = "";
|
|
24883
24885
|
try {
|
|
24884
24886
|
text2 = readFileSync9(path3, "utf8");
|
|
@@ -24932,7 +24934,7 @@ function ensureGrokInjectSlug(modelId, env = process.env) {
|
|
|
24932
24934
|
const next = text2 && !text2.endsWith("\n") ? `${text2}
|
|
24933
24935
|
|
|
24934
24936
|
${block2}` : `${text2}${text2 ? "\n" : ""}${block2}`;
|
|
24935
|
-
|
|
24937
|
+
writeFileSync6(path3, next);
|
|
24936
24938
|
return slug;
|
|
24937
24939
|
}
|
|
24938
24940
|
var STATIC_GROK_MODELS, SLUG, support2, GrokAgentDriver;
|
|
@@ -25013,7 +25015,7 @@ var init_grok2 = __esm({
|
|
|
25013
25015
|
// an unauthenticated CLI is a user action, not something to paper over.
|
|
25014
25016
|
pickAuthMethod: (methods) => methods.some((m) => m.id === "cached_token") ? "cached_token" : null,
|
|
25015
25017
|
authFailure: "fail",
|
|
25016
|
-
isAuthenticated: () => existsSync8(
|
|
25018
|
+
isAuthenticated: () => existsSync8(join20(homedir13(), ".grok", "auth.json")),
|
|
25017
25019
|
// `--append-system-prompt`/`--rules` are accepted by the CLI but do NOT
|
|
25018
25020
|
// reach the agent-stdio system prompt (verified against 1.0.0), so the
|
|
25019
25021
|
// persona is prepended codex-style.
|
|
@@ -25027,11 +25029,11 @@ ${turn.text}` : turn.text
|
|
|
25027
25029
|
|
|
25028
25030
|
// server/drivers/acp/gemini.ts
|
|
25029
25031
|
import { existsSync as existsSync9, readFileSync as readFileSync10 } from "node:fs";
|
|
25030
|
-
import { homedir as
|
|
25031
|
-
import { join as
|
|
25032
|
+
import { homedir as homedir14 } from "node:os";
|
|
25033
|
+
import { join as join21 } from "node:path";
|
|
25032
25034
|
function liveOauthCredential() {
|
|
25033
25035
|
try {
|
|
25034
|
-
const creds = JSON.parse(readFileSync10(
|
|
25036
|
+
const creds = JSON.parse(readFileSync10(join21(homedir14(), ".gemini", "oauth_creds.json"), "utf8"));
|
|
25035
25037
|
if (typeof creds.access_token !== "string" || creds.access_token.trim().length === 0) return false;
|
|
25036
25038
|
const hasRefresh = typeof creds.refresh_token === "string" && creds.refresh_token.trim().length > 0;
|
|
25037
25039
|
if (creds.expiry_date !== void 0) {
|
|
@@ -25044,7 +25046,7 @@ function liveOauthCredential() {
|
|
|
25044
25046
|
}
|
|
25045
25047
|
}
|
|
25046
25048
|
function geminiIsAuthenticated(env) {
|
|
25047
|
-
return nonBlank(env.GEMINI_API_KEY) || nonBlank(env.GOOGLE_API_KEY) || existsSync9(
|
|
25049
|
+
return nonBlank(env.GEMINI_API_KEY) || nonBlank(env.GOOGLE_API_KEY) || existsSync9(join21(homedir14(), ".gemini", "oauth_creds.json")) && liveOauthCredential();
|
|
25048
25050
|
}
|
|
25049
25051
|
var AUTH_PREFERENCE, nonBlank, support3, GeminiAgentDriver;
|
|
25050
25052
|
var init_gemini = __esm({
|
|
@@ -25086,17 +25088,17 @@ ${turn.text}` : turn.text
|
|
|
25086
25088
|
});
|
|
25087
25089
|
|
|
25088
25090
|
// server/drivers/acp/kimi.ts
|
|
25089
|
-
import { existsSync as existsSync10, mkdirSync as
|
|
25090
|
-
import { homedir as
|
|
25091
|
-
import { join as
|
|
25091
|
+
import { existsSync as existsSync10, mkdirSync as mkdirSync7, readFileSync as readFileSync11, writeFileSync as writeFileSync7 } from "node:fs";
|
|
25092
|
+
import { homedir as homedir15 } from "node:os";
|
|
25093
|
+
import { join as join22 } from "node:path";
|
|
25092
25094
|
function isLocalInjectAlias(slug) {
|
|
25093
25095
|
return LOCAL_PROVIDER_PREFIXES.some((prefix) => slug.startsWith(prefix));
|
|
25094
25096
|
}
|
|
25095
25097
|
function kimiDataRoot(env) {
|
|
25096
|
-
return env.KIMI_CODE_HOME ||
|
|
25098
|
+
return env.KIMI_CODE_HOME || join22(env.HOME || env.USERPROFILE || homedir15(), ".kimi-code");
|
|
25097
25099
|
}
|
|
25098
25100
|
function credentialsPath(env) {
|
|
25099
|
-
return
|
|
25101
|
+
return join22(kimiDataRoot(env), "credentials", "kimi-code.json");
|
|
25100
25102
|
}
|
|
25101
25103
|
function quoteToml2(value) {
|
|
25102
25104
|
return `"${value.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
|
|
@@ -25383,8 +25385,8 @@ function ensureKimiInjectAlias(modelId, env = process.env) {
|
|
|
25383
25385
|
if (!host) return modelId;
|
|
25384
25386
|
const alias = `${inject.host}/${inject.model.replace(/\//g, "-")}`;
|
|
25385
25387
|
const dataRoot = kimiDataRoot(env);
|
|
25386
|
-
|
|
25387
|
-
const path3 =
|
|
25388
|
+
mkdirSync7(dataRoot, { recursive: true });
|
|
25389
|
+
const path3 = join22(dataRoot, "config.toml");
|
|
25388
25390
|
let text2 = "";
|
|
25389
25391
|
try {
|
|
25390
25392
|
text2 = readFileSync11(path3, "utf8");
|
|
@@ -25425,9 +25427,9 @@ function ensureKimiInjectAlias(modelId, env = process.env) {
|
|
|
25425
25427
|
|
|
25426
25428
|
` : text2 ? `${text2}
|
|
25427
25429
|
` : "";
|
|
25428
|
-
|
|
25430
|
+
writeFileSync7(path3, `${prefix}${blocks.join("\n")}`);
|
|
25429
25431
|
} else if (text2 !== original) {
|
|
25430
|
-
|
|
25432
|
+
writeFileSync7(path3, text2);
|
|
25431
25433
|
}
|
|
25432
25434
|
return alias;
|
|
25433
25435
|
}
|
|
@@ -25449,7 +25451,7 @@ function readKimiModelCatalog(env) {
|
|
|
25449
25451
|
const dataRoot = kimiDataRoot(env);
|
|
25450
25452
|
let text2 = "";
|
|
25451
25453
|
try {
|
|
25452
|
-
text2 = readFileSync11(
|
|
25454
|
+
text2 = readFileSync11(join22(dataRoot, "config.toml"), "utf8");
|
|
25453
25455
|
} catch {
|
|
25454
25456
|
return STATIC_KIMI_MODELS;
|
|
25455
25457
|
}
|
|
@@ -25568,19 +25570,19 @@ ${turn.text}` : turn.text
|
|
|
25568
25570
|
});
|
|
25569
25571
|
|
|
25570
25572
|
// server/drivers/acp/droid.ts
|
|
25571
|
-
import { existsSync as existsSync11, mkdirSync as
|
|
25572
|
-
import { homedir as
|
|
25573
|
-
import { join as
|
|
25573
|
+
import { existsSync as existsSync11, mkdirSync as mkdirSync8, readFileSync as readFileSync12, writeFileSync as writeFileSync8 } from "node:fs";
|
|
25574
|
+
import { homedir as homedir16 } from "node:os";
|
|
25575
|
+
import { join as join23 } from "node:path";
|
|
25574
25576
|
function authFilePaths(env) {
|
|
25575
|
-
const home = env.FACTORY_HOME_OVERRIDE || env.HOME ||
|
|
25576
|
-
return AUTH_FILES.map((name) =>
|
|
25577
|
+
const home = env.FACTORY_HOME_OVERRIDE || env.HOME || homedir16();
|
|
25578
|
+
return AUTH_FILES.map((name) => join23(home, ".factory", name));
|
|
25577
25579
|
}
|
|
25578
25580
|
function droidInjectId(host, model) {
|
|
25579
25581
|
const safe = `${host}-${model}`.replace(/[^a-zA-Z0-9._+-]+/g, "-").replace(/-+/g, "-");
|
|
25580
25582
|
return `${INJECT_ID_PREFIX}${safe}`;
|
|
25581
25583
|
}
|
|
25582
25584
|
function factoryHome(env) {
|
|
25583
|
-
return env.FACTORY_HOME_OVERRIDE || env.HOME || env.USERPROFILE ||
|
|
25585
|
+
return env.FACTORY_HOME_OVERRIDE || env.HOME || env.USERPROFILE || homedir16();
|
|
25584
25586
|
}
|
|
25585
25587
|
function ensureDroidInjectModel(modelId, env = process.env) {
|
|
25586
25588
|
const inject = decodeInjectId(modelId);
|
|
@@ -25588,9 +25590,9 @@ function ensureDroidInjectModel(modelId, env = process.env) {
|
|
|
25588
25590
|
const host = localHost(inject.host);
|
|
25589
25591
|
if (!host) return modelId;
|
|
25590
25592
|
const id = droidInjectId(inject.host, inject.model);
|
|
25591
|
-
const dir =
|
|
25592
|
-
|
|
25593
|
-
const path3 =
|
|
25593
|
+
const dir = join23(factoryHome(env), ".factory");
|
|
25594
|
+
mkdirSync8(dir, { recursive: true });
|
|
25595
|
+
const path3 = join23(dir, "settings.json");
|
|
25594
25596
|
let settings2 = {};
|
|
25595
25597
|
try {
|
|
25596
25598
|
settings2 = JSON.parse(readFileSync12(path3, "utf8"));
|
|
@@ -25605,7 +25607,7 @@ function ensureDroidInjectModel(modelId, env = process.env) {
|
|
|
25605
25607
|
if (!match.id) {
|
|
25606
25608
|
match.id = id;
|
|
25607
25609
|
settings2.customModels = custom2;
|
|
25608
|
-
|
|
25610
|
+
writeFileSync8(path3, `${JSON.stringify(settings2, null, 2)}
|
|
25609
25611
|
`);
|
|
25610
25612
|
}
|
|
25611
25613
|
return match.id;
|
|
@@ -25619,7 +25621,7 @@ function ensureDroidInjectModel(modelId, env = process.env) {
|
|
|
25619
25621
|
provider: "generic-chat-completion-api"
|
|
25620
25622
|
});
|
|
25621
25623
|
settings2.customModels = custom2;
|
|
25622
|
-
|
|
25624
|
+
writeFileSync8(path3, `${JSON.stringify(settings2, null, 2)}
|
|
25623
25625
|
`);
|
|
25624
25626
|
return id;
|
|
25625
25627
|
}
|
|
@@ -25630,7 +25632,7 @@ function applyDroidLocalAuthEnv(env, modelId) {
|
|
|
25630
25632
|
env.FACTORY_API_KEY = "openmausbot-local";
|
|
25631
25633
|
}
|
|
25632
25634
|
function readSettings(env) {
|
|
25633
|
-
return JSON.parse(readFileSync12(
|
|
25635
|
+
return JSON.parse(readFileSync12(join23(factoryHome(env), ".factory", "settings.json"), "utf8"));
|
|
25634
25636
|
}
|
|
25635
25637
|
async function resolveModels(env) {
|
|
25636
25638
|
let catalog = MODELS3;
|
|
@@ -26020,9 +26022,9 @@ ${turn.text}` : turn.text
|
|
|
26020
26022
|
});
|
|
26021
26023
|
|
|
26022
26024
|
// server/drivers/acp/opencode-go.ts
|
|
26023
|
-
import { existsSync as existsSync12, mkdirSync as
|
|
26024
|
-
import { homedir as
|
|
26025
|
-
import { join as
|
|
26025
|
+
import { existsSync as existsSync12, mkdirSync as mkdirSync9, readFileSync as readFileSync13, writeFileSync as writeFileSync9 } from "node:fs";
|
|
26026
|
+
import { homedir as homedir17 } from "node:os";
|
|
26027
|
+
import { join as join24 } from "node:path";
|
|
26026
26028
|
function labelForModel(id) {
|
|
26027
26029
|
return id.split(/[-_.]+/g).filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
|
|
26028
26030
|
}
|
|
@@ -26122,8 +26124,8 @@ async function discoverOpenCodeModels(environment, cli = "opencode") {
|
|
|
26122
26124
|
}
|
|
26123
26125
|
}
|
|
26124
26126
|
function opencodeConfigDir(env) {
|
|
26125
|
-
const home = env.HOME || env.USERPROFILE ||
|
|
26126
|
-
return
|
|
26127
|
+
const home = env.HOME || env.USERPROFILE || homedir17();
|
|
26128
|
+
return join24(env.XDG_CONFIG_HOME || join24(home, ".config"), "opencode");
|
|
26127
26129
|
}
|
|
26128
26130
|
function ensureOpenCodeInjectModel(modelId, env = process.env) {
|
|
26129
26131
|
const inject = decodeInjectId(modelId);
|
|
@@ -26132,8 +26134,8 @@ function ensureOpenCodeInjectModel(modelId, env = process.env) {
|
|
|
26132
26134
|
if (!host) return modelId;
|
|
26133
26135
|
const native = `${inject.host}/${inject.model}`;
|
|
26134
26136
|
const dir = opencodeConfigDir(env);
|
|
26135
|
-
|
|
26136
|
-
const path3 =
|
|
26137
|
+
mkdirSync9(dir, { recursive: true });
|
|
26138
|
+
const path3 = join24(dir, "opencode.json");
|
|
26137
26139
|
let config2 = { $schema: "https://opencode.ai/config.json" };
|
|
26138
26140
|
if (existsSync12(path3)) {
|
|
26139
26141
|
try {
|
|
@@ -26164,17 +26166,17 @@ function ensureOpenCodeInjectModel(modelId, env = process.env) {
|
|
|
26164
26166
|
models
|
|
26165
26167
|
};
|
|
26166
26168
|
config2.provider = providers;
|
|
26167
|
-
|
|
26169
|
+
writeFileSync9(path3, `${JSON.stringify(config2, null, 2)}
|
|
26168
26170
|
`);
|
|
26169
26171
|
return native;
|
|
26170
26172
|
}
|
|
26171
26173
|
function storedAuthPaths(env) {
|
|
26172
|
-
const home = env.HOME || env.USERPROFILE ||
|
|
26174
|
+
const home = env.HOME || env.USERPROFILE || homedir17();
|
|
26173
26175
|
const roots = [
|
|
26174
|
-
env.XDG_DATA_HOME ||
|
|
26175
|
-
process.platform === "darwin" ?
|
|
26176
|
+
env.XDG_DATA_HOME || join24(home, ".local", "share"),
|
|
26177
|
+
process.platform === "darwin" ? join24(home, "Library", "Application Support") : process.platform === "win32" ? env.LOCALAPPDATA || join24(home, "AppData", "Local") : ""
|
|
26176
26178
|
].filter(Boolean);
|
|
26177
|
-
return [...new Set(roots)].map((root) =>
|
|
26179
|
+
return [...new Set(roots)].map((root) => join24(root, "opencode", "auth.json"));
|
|
26178
26180
|
}
|
|
26179
26181
|
function usableAuthEntry(parsed) {
|
|
26180
26182
|
return Object.values(parsed).some((auth) => {
|
|
@@ -26304,11 +26306,11 @@ ${turn.text}` : turn.text
|
|
|
26304
26306
|
});
|
|
26305
26307
|
|
|
26306
26308
|
// server/drivers/acp/qwen.ts
|
|
26307
|
-
import { chmodSync as chmodSync4, existsSync as existsSync13, mkdirSync as
|
|
26308
|
-
import { homedir as
|
|
26309
|
-
import { join as
|
|
26309
|
+
import { chmodSync as chmodSync4, existsSync as existsSync13, mkdirSync as mkdirSync10, readFileSync as readFileSync14, writeFileSync as writeFileSync10 } from "node:fs";
|
|
26310
|
+
import { homedir as homedir18 } from "node:os";
|
|
26311
|
+
import { join as join25 } from "node:path";
|
|
26310
26312
|
function qwenHome(env) {
|
|
26311
|
-
return
|
|
26313
|
+
return join25(env.HOME || env.USERPROFILE || homedir18(), ".qwen");
|
|
26312
26314
|
}
|
|
26313
26315
|
function envKeyFor(hostId) {
|
|
26314
26316
|
return `OPENMAUSBOT_QWEN_${hostId.toUpperCase().replace(/[^A-Z0-9]+/g, "_")}_API_KEY`;
|
|
@@ -26319,8 +26321,8 @@ function ensureQwenInjectModel(modelId, env = process.env) {
|
|
|
26319
26321
|
const host = localHost(inject.host);
|
|
26320
26322
|
if (!host) return modelId;
|
|
26321
26323
|
const dir = qwenHome(env);
|
|
26322
|
-
|
|
26323
|
-
const path3 =
|
|
26324
|
+
mkdirSync10(dir, { recursive: true });
|
|
26325
|
+
const path3 = join25(dir, "settings.json");
|
|
26324
26326
|
let settings2 = {};
|
|
26325
26327
|
if (existsSync13(path3)) {
|
|
26326
26328
|
try {
|
|
@@ -26348,7 +26350,7 @@ function ensureQwenInjectModel(modelId, env = process.env) {
|
|
|
26348
26350
|
providers.openai = openai;
|
|
26349
26351
|
settings2.modelProviders = providers;
|
|
26350
26352
|
}
|
|
26351
|
-
|
|
26353
|
+
writeFileSync10(path3, `${JSON.stringify(settings2, null, 2)}
|
|
26352
26354
|
`, { mode: 384 });
|
|
26353
26355
|
try {
|
|
26354
26356
|
chmodSync4(path3, 384);
|
|
@@ -33285,9 +33287,9 @@ var init_browser = __esm({
|
|
|
33285
33287
|
|
|
33286
33288
|
// server/drivers/acp/hermes.ts
|
|
33287
33289
|
import { spawn as spawn5 } from "node:child_process";
|
|
33288
|
-
import { mkdirSync as
|
|
33289
|
-
import { homedir as
|
|
33290
|
-
import { join as
|
|
33290
|
+
import { mkdirSync as mkdirSync11, readFileSync as readFileSync15, writeFileSync as writeFileSync11 } from "node:fs";
|
|
33291
|
+
import { homedir as homedir19 } from "node:os";
|
|
33292
|
+
import { join as join26 } from "node:path";
|
|
33291
33293
|
function bindHermesScreenshotCompat(env, modelId) {
|
|
33292
33294
|
delete env[HERMES_OPENMAUS_SCREENSHOT_COMPAT];
|
|
33293
33295
|
delete env[HERMES_OPENMAUS_SCREENSHOT_COMPAT_MODEL];
|
|
@@ -33297,7 +33299,7 @@ function bindHermesScreenshotCompat(env, modelId) {
|
|
|
33297
33299
|
env[HERMES_OPENMAUS_SCREENSHOT_COMPAT_MODEL] = inject.model;
|
|
33298
33300
|
}
|
|
33299
33301
|
function hermesHome(env) {
|
|
33300
|
-
return env.HERMES_HOME ||
|
|
33302
|
+
return env.HERMES_HOME || join26(env.HOME || env.USERPROFILE || homedir19(), ".hermes");
|
|
33301
33303
|
}
|
|
33302
33304
|
function quoteYaml(value) {
|
|
33303
33305
|
if (/^[\w./:+-]+$/.test(value)) return value;
|
|
@@ -33338,8 +33340,8 @@ function ensureHermesInjectProvider(modelId, env = process.env) {
|
|
|
33338
33340
|
const host = localHost(inject.host);
|
|
33339
33341
|
if (!host) return modelId;
|
|
33340
33342
|
const dir = hermesHome(env);
|
|
33341
|
-
|
|
33342
|
-
const path3 =
|
|
33343
|
+
mkdirSync11(dir, { recursive: true });
|
|
33344
|
+
const path3 = join26(dir, "config.yaml");
|
|
33343
33345
|
let text2 = "";
|
|
33344
33346
|
try {
|
|
33345
33347
|
text2 = readFileSync15(path3, "utf8");
|
|
@@ -33347,7 +33349,7 @@ function ensureHermesInjectProvider(modelId, env = process.env) {
|
|
|
33347
33349
|
text2 = "";
|
|
33348
33350
|
}
|
|
33349
33351
|
const next = upsertHermesProvider(text2, inject.host, host.baseUrl, hostApiKey(host, env));
|
|
33350
|
-
if (next !== text2)
|
|
33352
|
+
if (next !== text2) writeFileSync11(path3, next);
|
|
33351
33353
|
return hermesAcpModelId(modelId) ?? modelId;
|
|
33352
33354
|
}
|
|
33353
33355
|
function hermesAcpModelId(modelId) {
|
|
@@ -33410,13 +33412,13 @@ function hermesConfiguredModel(env = process.env) {
|
|
|
33410
33412
|
const dir = hermesHome(env);
|
|
33411
33413
|
let secrets = "";
|
|
33412
33414
|
try {
|
|
33413
|
-
secrets = readFileSync15(
|
|
33415
|
+
secrets = readFileSync15(join26(dir, ".env"), "utf8");
|
|
33414
33416
|
} catch {
|
|
33415
33417
|
}
|
|
33416
33418
|
const hasHostedProviderKey = HERMES_HOSTED_PROVIDER_KEYS.some((name) => nonEmptyDotenvValue(secrets, name));
|
|
33417
33419
|
let configuredDefault = null;
|
|
33418
33420
|
try {
|
|
33419
|
-
configuredDefault = hermesConfigDefault(readFileSync15(
|
|
33421
|
+
configuredDefault = hermesConfigDefault(readFileSync15(join26(dir, "config.yaml"), "utf8"));
|
|
33420
33422
|
} catch {
|
|
33421
33423
|
}
|
|
33422
33424
|
const configuredProvider = configuredDefault?.provider.toLowerCase() ?? "";
|
|
@@ -33501,7 +33503,7 @@ async function fetchHermesAcpModels(cli, env) {
|
|
|
33501
33503
|
}
|
|
33502
33504
|
if (msg?.id === initId) {
|
|
33503
33505
|
if (!msg.result) return done([]);
|
|
33504
|
-
sessionId = send("session/new", { cwd: env.HOME || env.USERPROFILE ||
|
|
33506
|
+
sessionId = send("session/new", { cwd: env.HOME || env.USERPROFILE || homedir19(), mcpServers: [] });
|
|
33505
33507
|
} else if (sessionId && msg?.id === sessionId) {
|
|
33506
33508
|
const list = Array.isArray(msg.result?.models?.availableModels) ? msg.result.models.availableModels : [];
|
|
33507
33509
|
done(
|
|
@@ -33736,9 +33738,9 @@ var init_openai_compat = __esm({
|
|
|
33736
33738
|
});
|
|
33737
33739
|
|
|
33738
33740
|
// server/drivers/pi.ts
|
|
33739
|
-
import { chmodSync as chmodSync5, existsSync as existsSync14, mkdirSync as
|
|
33740
|
-
import { homedir as
|
|
33741
|
-
import { join as
|
|
33741
|
+
import { chmodSync as chmodSync5, existsSync as existsSync14, mkdirSync as mkdirSync12, mkdtempSync as mkdtempSync3, readFileSync as readFileSync16, rmSync as rmSync3, writeFileSync as writeFileSync12 } from "node:fs";
|
|
33742
|
+
import { homedir as homedir20, tmpdir as tmpdir4 } from "node:os";
|
|
33743
|
+
import { join as join27 } from "node:path";
|
|
33742
33744
|
function readPiPromptImages(turn) {
|
|
33743
33745
|
return (turn.images ?? []).map((image) => ({
|
|
33744
33746
|
type: "image",
|
|
@@ -33845,7 +33847,7 @@ async function applyPiLocalCatalog(catalog, env = process.env, fetchImpl = fetch
|
|
|
33845
33847
|
return preferPiInjectRows(await mergeLocalInject(catalog, env, fetchImpl));
|
|
33846
33848
|
}
|
|
33847
33849
|
function piAgentDir(env) {
|
|
33848
|
-
return
|
|
33850
|
+
return join27(env.HOME || env.USERPROFILE || homedir20(), ".pi", "agent");
|
|
33849
33851
|
}
|
|
33850
33852
|
function ensurePiInjectModel(modelId, env = process.env) {
|
|
33851
33853
|
const split = splitPiModel(modelId);
|
|
@@ -33855,8 +33857,8 @@ function ensurePiInjectModel(modelId, env = process.env) {
|
|
|
33855
33857
|
const host = localHost(inject.host);
|
|
33856
33858
|
if (!host) return split;
|
|
33857
33859
|
const dir = piAgentDir(env);
|
|
33858
|
-
|
|
33859
|
-
const path3 =
|
|
33860
|
+
mkdirSync12(dir, { recursive: true });
|
|
33861
|
+
const path3 = join27(dir, "models.json");
|
|
33860
33862
|
let root = { providers: {} };
|
|
33861
33863
|
if (existsSync14(path3)) {
|
|
33862
33864
|
try {
|
|
@@ -33901,7 +33903,7 @@ function ensurePiInjectModel(modelId, env = process.env) {
|
|
|
33901
33903
|
existing.models = models;
|
|
33902
33904
|
providers[inject.host] = existing;
|
|
33903
33905
|
root.providers = providers;
|
|
33904
|
-
|
|
33906
|
+
writeFileSync12(path3, `${JSON.stringify(root, null, 2)}
|
|
33905
33907
|
`, { mode: 384 });
|
|
33906
33908
|
try {
|
|
33907
33909
|
chmodSync5(path3, 384);
|
|
@@ -33910,7 +33912,7 @@ function ensurePiInjectModel(modelId, env = process.env) {
|
|
|
33910
33912
|
return split;
|
|
33911
33913
|
}
|
|
33912
33914
|
function readPiDefaultModel(env) {
|
|
33913
|
-
const home = env.HOME || env.USERPROFILE ||
|
|
33915
|
+
const home = env.HOME || env.USERPROFILE || homedir20();
|
|
33914
33916
|
try {
|
|
33915
33917
|
const s = JSON.parse(readFileSync16(`${home}/.pi/agent/settings.json`, "utf8"));
|
|
33916
33918
|
return s.defaultProvider && s.defaultModel ? `${s.defaultProvider}/${s.defaultModel}` : "";
|
|
@@ -34058,9 +34060,9 @@ var init_pi = __esm({
|
|
|
34058
34060
|
const mcpServers = buildMcpServers(turn);
|
|
34059
34061
|
let mcpTempDir = null;
|
|
34060
34062
|
if (mcpServers) {
|
|
34061
|
-
mcpTempDir = mkdtempSync3(
|
|
34063
|
+
mcpTempDir = mkdtempSync3(join27(tmpdir4(), "omb-pi-mcp-"));
|
|
34062
34064
|
try {
|
|
34063
|
-
|
|
34065
|
+
writeFileSync12(join27(mcpTempDir, "mcp.json"), JSON.stringify({ mcpServers }), { mode: 384 });
|
|
34064
34066
|
} catch (err) {
|
|
34065
34067
|
try {
|
|
34066
34068
|
rmSync3(mcpTempDir, { recursive: true, force: true });
|
|
@@ -34078,7 +34080,7 @@ var init_pi = __esm({
|
|
|
34078
34080
|
env: piEnvironment({
|
|
34079
34081
|
...process.env,
|
|
34080
34082
|
...input.environment,
|
|
34081
|
-
...mcpServers && mcpTempDir ? { OMB_MCP_CONFIG:
|
|
34083
|
+
...mcpServers && mcpTempDir ? { OMB_MCP_CONFIG: join27(mcpTempDir, "mcp.json") } : {}
|
|
34082
34084
|
})
|
|
34083
34085
|
});
|
|
34084
34086
|
} catch (err) {
|
|
@@ -34416,15 +34418,15 @@ ${turn.text}` : turn.text;
|
|
|
34416
34418
|
|
|
34417
34419
|
// server/drivers/minimax.ts
|
|
34418
34420
|
import { readFileSync as readFileSync17 } from "node:fs";
|
|
34419
|
-
import { homedir as
|
|
34420
|
-
import { join as
|
|
34421
|
+
import { homedir as homedir21 } from "node:os";
|
|
34422
|
+
import { join as join28 } from "node:path";
|
|
34421
34423
|
function normalizedApiUrl(value) {
|
|
34422
34424
|
const root = value.trim().replace(/\/+$/, "");
|
|
34423
34425
|
return root.endsWith("/v1") ? root : `${root}/v1`;
|
|
34424
34426
|
}
|
|
34425
|
-
function loadLocalMiniMaxConfig(home =
|
|
34427
|
+
function loadLocalMiniMaxConfig(home = homedir21()) {
|
|
34426
34428
|
try {
|
|
34427
|
-
const raw = localConfigSchema.parse(JSON.parse(readFileSync17(
|
|
34429
|
+
const raw = localConfigSchema.parse(JSON.parse(readFileSync17(join28(home, ".mmx", "config.json"), "utf8")));
|
|
34428
34430
|
const configuredUrl = raw.base_url?.trim() ? raw.base_url : raw.region === "cn" ? CN_URL : DEFAULT_URL2;
|
|
34429
34431
|
return {
|
|
34430
34432
|
apiKey: raw.api_key?.trim() ?? "",
|
|
@@ -34692,7 +34694,7 @@ __export(cli_setup_exports, {
|
|
|
34692
34694
|
});
|
|
34693
34695
|
import { spawn as spawn6 } from "node:child_process";
|
|
34694
34696
|
import { readFileSync as readFileSync18 } from "node:fs";
|
|
34695
|
-
import { join as
|
|
34697
|
+
import { join as join29, resolve as resolve9 } from "node:path";
|
|
34696
34698
|
import { randomUUID as randomUUID10 } from "node:crypto";
|
|
34697
34699
|
async function inspect(id, entry) {
|
|
34698
34700
|
const registry2 = new ProviderRegistry(BUILT_IN_DRIVERS);
|
|
@@ -34729,7 +34731,7 @@ function assertDataDir(dataDir) {
|
|
|
34729
34731
|
}
|
|
34730
34732
|
function checkStoredConfig(dataDir) {
|
|
34731
34733
|
try {
|
|
34732
|
-
parseStoredConfig(JSON.parse(readFileSync18(
|
|
34734
|
+
parseStoredConfig(JSON.parse(readFileSync18(join29(dataDir, "config.json"), "utf8")));
|
|
34733
34735
|
} catch (error51) {
|
|
34734
34736
|
if (error51.code === "ENOENT") return;
|
|
34735
34737
|
throw new Error("Existing config.json could not be read or validated. Setup has not changed it; repair it before continuing.");
|
|
@@ -35007,7 +35009,7 @@ var init_browser_engine_release = __esm({
|
|
|
35007
35009
|
});
|
|
35008
35010
|
|
|
35009
35011
|
// server/browser-bundle-release.ts
|
|
35010
|
-
import { join as
|
|
35012
|
+
import { join as join30 } from "node:path";
|
|
35011
35013
|
function browserBundleSpec(target) {
|
|
35012
35014
|
if (!Object.hasOwn(CHROME_ASSETS, target)) throw new Error(`Unsupported desktop browser target: ${target}`);
|
|
35013
35015
|
const pinned = CHROME_ASSETS[target];
|
|
@@ -35043,10 +35045,10 @@ function browserBundlePaths(bundleDirectory, target) {
|
|
|
35043
35045
|
const spec = browserBundleSpec(target);
|
|
35044
35046
|
return {
|
|
35045
35047
|
directory: bundleDirectory,
|
|
35046
|
-
manifest:
|
|
35047
|
-
engine:
|
|
35048
|
-
chrome:
|
|
35049
|
-
licenses:
|
|
35048
|
+
manifest: join30(bundleDirectory, "manifest.json"),
|
|
35049
|
+
engine: join30(bundleDirectory, spec.engine.executable),
|
|
35050
|
+
chrome: join30(bundleDirectory, spec.chrome.executable),
|
|
35051
|
+
licenses: join30(bundleDirectory, "licenses")
|
|
35050
35052
|
};
|
|
35051
35053
|
}
|
|
35052
35054
|
var CHROME_VERSION, CHROME_ASSETS;
|
|
@@ -35101,9 +35103,9 @@ __export(browser_engine_exports, {
|
|
|
35101
35103
|
});
|
|
35102
35104
|
import { spawn as spawn7 } from "node:child_process";
|
|
35103
35105
|
import { createHash as createHash7, randomBytes as randomBytes3, randomUUID as randomUUID11 } from "node:crypto";
|
|
35104
|
-
import { chmodSync as chmodSync6, constants as constants2, copyFileSync, existsSync as existsSync15, mkdirSync as
|
|
35105
|
-
import { homedir as
|
|
35106
|
-
import { delimiter as delimiter6, dirname as
|
|
35106
|
+
import { chmodSync as chmodSync6, constants as constants2, copyFileSync, existsSync as existsSync15, mkdirSync as mkdirSync13, readFileSync as readFileSync19, readdirSync as readdirSync3, renameSync as renameSync5, rmSync as rmSync4, statSync as statSync3, unlinkSync as unlinkSync4, writeFileSync as writeFileSync13 } from "node:fs";
|
|
35107
|
+
import { homedir as homedir22, tmpdir as tmpdir5 } from "node:os";
|
|
35108
|
+
import { delimiter as delimiter6, dirname as dirname10, join as join31, resolve as resolve10 } from "node:path";
|
|
35107
35109
|
function browserRestoreKey(session) {
|
|
35108
35110
|
if (!/^[A-Za-z0-9_-]{1,96}$/.test(session)) throw new Error("Invalid browser session.");
|
|
35109
35111
|
return `omb-${createHash7("sha256").update(session).digest("hex")}`;
|
|
@@ -35111,18 +35113,18 @@ function browserRestoreKey(session) {
|
|
|
35111
35113
|
function browserSessionsDirectory(env) {
|
|
35112
35114
|
const namespace = env.AGENT_BROWSER_NAMESPACE;
|
|
35113
35115
|
if (namespace && !/^[a-z0-9]+(?:[-_][a-z0-9]+)*$/.test(namespace)) throw new Error("Invalid browser namespace.");
|
|
35114
|
-
const home = (process.platform === "win32" ? env.USERPROFILE : env.HOME) ||
|
|
35115
|
-
const stateRoot = namespace ?
|
|
35116
|
-
return
|
|
35116
|
+
const home = (process.platform === "win32" ? env.USERPROFILE : env.HOME) || homedir22();
|
|
35117
|
+
const stateRoot = namespace ? join31(home, ".agent-browser", "namespaces", namespace, "state") : join31(home, ".agent-browser");
|
|
35118
|
+
return join31(stateRoot, "sessions");
|
|
35117
35119
|
}
|
|
35118
35120
|
function managedBrowserConfigPath(env) {
|
|
35119
|
-
return
|
|
35121
|
+
return join31(browserSessionsDirectory(env), "..", "omb-managed-config.json");
|
|
35120
35122
|
}
|
|
35121
35123
|
function ensureManagedBrowserConfig(env) {
|
|
35122
35124
|
const path3 = managedBrowserConfigPath(env);
|
|
35123
|
-
|
|
35125
|
+
mkdirSync13(dirname10(path3), { recursive: true, mode: 448 });
|
|
35124
35126
|
try {
|
|
35125
|
-
|
|
35127
|
+
writeFileSync13(path3, "{}\n", { flag: "wx", mode: 384 });
|
|
35126
35128
|
} catch (error51) {
|
|
35127
35129
|
if (error51.code !== "EEXIST") throw error51;
|
|
35128
35130
|
if (readFileSync19(path3, "utf8").trim() !== "{}") throw new Error("The managed browser configuration was changed. Restore it to an empty JSON object before connecting.");
|
|
@@ -35203,11 +35205,11 @@ async function prepareBrowserSessionState(binaryPath, session, options = {}) {
|
|
|
35203
35205
|
ensureManagedBrowserConfig(env);
|
|
35204
35206
|
if (options.persistent === false) return;
|
|
35205
35207
|
const directory = browserSessionsDirectory(env);
|
|
35206
|
-
const key =
|
|
35208
|
+
const key = join31(directory, session);
|
|
35207
35209
|
let pending = preparedBrowserSessions.get(key);
|
|
35208
35210
|
if (!pending) {
|
|
35209
35211
|
pending = (async () => {
|
|
35210
|
-
const targetBase =
|
|
35212
|
+
const targetBase = join31(directory, `${restoreKey}-${session}`);
|
|
35211
35213
|
const hasTarget = () => existsSync15(`${targetBase}.json.enc`) || existsSync15(`${targetBase}.json`);
|
|
35212
35214
|
if (hasTarget()) return;
|
|
35213
35215
|
check2();
|
|
@@ -35217,7 +35219,7 @@ async function prepareBrowserSessionState(binaryPath, session, options = {}) {
|
|
|
35217
35219
|
check2();
|
|
35218
35220
|
if (hasTarget()) return;
|
|
35219
35221
|
const candidates = [".json.enc", ".json"].flatMap((suffix) => {
|
|
35220
|
-
const path3 =
|
|
35222
|
+
const path3 = join31(directory, `${session}-${session}${suffix}`);
|
|
35221
35223
|
try {
|
|
35222
35224
|
const stat4 = statSync3(path3);
|
|
35223
35225
|
if (!stat4.isFile()) throw new Error("Saved browser state is not a file.");
|
|
@@ -35252,7 +35254,7 @@ function isMusl(platform = process.platform, exists = existsSync15) {
|
|
|
35252
35254
|
}
|
|
35253
35255
|
function pinnedBinaryPath(dataDir = DATA_DIR, platform = process.platform, arch = process.arch) {
|
|
35254
35256
|
const version2 = agentBrowserReleaseVersion(resolveAgentBrowserReleaseAsset(platform, arch));
|
|
35255
|
-
return
|
|
35257
|
+
return join31(dataDir, ENGINE_DIR, version2, executableName(platform));
|
|
35256
35258
|
}
|
|
35257
35259
|
function onPath(env, platform, exists) {
|
|
35258
35260
|
const pathValue = platform === "win32" ? Object.entries(env).findLast(([key]) => key.toUpperCase() === "PATH")?.[1] : env.PATH;
|
|
@@ -35268,7 +35270,7 @@ function packagedBrowser(options) {
|
|
|
35268
35270
|
const resources = (options.env ?? process.env).OMB_RESOURCES_PATH;
|
|
35269
35271
|
if (!resources) return null;
|
|
35270
35272
|
try {
|
|
35271
|
-
return browserBundlePaths(
|
|
35273
|
+
return browserBundlePaths(join31(resolve10(resources), "browser-engine"), `${options.platform ?? process.platform}-${options.arch ?? process.arch}`);
|
|
35272
35274
|
} catch {
|
|
35273
35275
|
return null;
|
|
35274
35276
|
}
|
|
@@ -35293,8 +35295,8 @@ async function installAgentBrowserBinary(options = {}) {
|
|
|
35293
35295
|
const asset = options.asset ?? resolveAgentBrowserReleaseAsset(platform, options.arch ?? process.arch, options.musl ?? isMusl(platform));
|
|
35294
35296
|
if (!asset) throw new Error(`agent-browser publishes no build for ${platform}-${options.arch ?? process.arch}.`);
|
|
35295
35297
|
const destination = pinnedBinaryPath(options.dataDir, platform, options.arch);
|
|
35296
|
-
const directory =
|
|
35297
|
-
|
|
35298
|
+
const directory = join31(destination, "..");
|
|
35299
|
+
mkdirSync13(directory, { recursive: true, mode: 448 });
|
|
35298
35300
|
const url2 = agentBrowserReleaseUrl(asset);
|
|
35299
35301
|
options.log?.(`downloading agent-browser ${agentBrowserReleaseVersion(asset)} (${Math.round(asset.bytes / 1024 / 1024)} MB, digest pinned)`);
|
|
35300
35302
|
const controller = new AbortController();
|
|
@@ -35312,7 +35314,7 @@ async function installAgentBrowserBinary(options = {}) {
|
|
|
35312
35314
|
const digest2 = createHash7("sha256").update(body).digest("hex");
|
|
35313
35315
|
if (digest2 !== asset.sha256) throw new Error("the agent-browser download failed its SHA-256 check; nothing was installed");
|
|
35314
35316
|
const staging = `${destination}.${randomBytes3(6).toString("hex")}.part`;
|
|
35315
|
-
|
|
35317
|
+
writeFileSync13(staging, body, { mode: 493 });
|
|
35316
35318
|
if (platform !== "win32") chmodSync6(staging, 493);
|
|
35317
35319
|
renameSync5(staging, destination);
|
|
35318
35320
|
return destination;
|
|
@@ -35345,14 +35347,14 @@ function ensureChrome(binaryPath, options = {}) {
|
|
|
35345
35347
|
});
|
|
35346
35348
|
}
|
|
35347
35349
|
function browserEngineEncryptionKey(dataDir = DATA_DIR) {
|
|
35348
|
-
const file2 =
|
|
35350
|
+
const file2 = join31(dataDir, KEY_FILE);
|
|
35349
35351
|
try {
|
|
35350
35352
|
const existing = readFileSync19(file2, "utf8").trim();
|
|
35351
35353
|
if (/^[0-9a-f]{64}$/u.test(existing)) return existing;
|
|
35352
35354
|
} catch {
|
|
35353
35355
|
}
|
|
35354
35356
|
const key = randomBytes3(32).toString("hex");
|
|
35355
|
-
|
|
35357
|
+
mkdirSync13(dataDir, { recursive: true });
|
|
35356
35358
|
writeFileAtomic(file2, `${key}
|
|
35357
35359
|
`, { mode: 384 });
|
|
35358
35360
|
return key;
|
|
@@ -35405,7 +35407,7 @@ function agentBrowserIntegration(input) {
|
|
|
35405
35407
|
return { command: input.binaryPath, args: ["mcp", "--tools", "core", "--no-webmcp"], env };
|
|
35406
35408
|
}
|
|
35407
35409
|
function agentBrowserFrame(input) {
|
|
35408
|
-
const file2 =
|
|
35410
|
+
const file2 = join31(tmpdir5(), `openmausbot-browser-${randomUUID11()}.png`);
|
|
35409
35411
|
return new Promise((settle, fail) => {
|
|
35410
35412
|
const child = spawn7(input.binaryPath, ["screenshot", file2], {
|
|
35411
35413
|
env: browserRuntimeEnv(input.env),
|
|
@@ -35475,8 +35477,8 @@ async function clearBrowserSessionState(binaryPath, session, options = {}) {
|
|
|
35475
35477
|
}
|
|
35476
35478
|
};
|
|
35477
35479
|
try {
|
|
35478
|
-
for (const base2 of bases) for (const suffix of [".json", ".json.enc", ".json.previous", ".json.enc.previous"]) remove(
|
|
35479
|
-
const pendingDirectory =
|
|
35480
|
+
for (const base2 of bases) for (const suffix of [".json", ".json.enc", ".json.previous", ".json.enc.previous"]) remove(join31(directory, base2 + suffix));
|
|
35481
|
+
const pendingDirectory = join31(directory, ".tmp");
|
|
35480
35482
|
let pendingFiles = [];
|
|
35481
35483
|
try {
|
|
35482
35484
|
pendingFiles = readdirSync3(pendingDirectory);
|
|
@@ -35484,8 +35486,8 @@ async function clearBrowserSessionState(binaryPath, session, options = {}) {
|
|
|
35484
35486
|
if (error51.code !== "ENOENT") throw error51;
|
|
35485
35487
|
}
|
|
35486
35488
|
const candidates = bases.map((base2) => new RegExp(`^${base2}-candidate-[0-9]+\\.json(?:\\.enc)?$`));
|
|
35487
|
-
for (const name of pendingFiles) if (candidates.some((candidate) => candidate.test(name))) remove(
|
|
35488
|
-
preparedBrowserSessions.delete(
|
|
35489
|
+
for (const name of pendingFiles) if (candidates.some((candidate) => candidate.test(name))) remove(join31(pendingDirectory, name));
|
|
35490
|
+
preparedBrowserSessions.delete(join31(directory, session));
|
|
35489
35491
|
return true;
|
|
35490
35492
|
} catch {
|
|
35491
35493
|
return false;
|
|
@@ -35512,9 +35514,9 @@ var init_browser_engine = __esm({
|
|
|
35512
35514
|
// server/cli.ts
|
|
35513
35515
|
var import_qrcode_terminal = __toESM(require_main(), 1);
|
|
35514
35516
|
import { spawn as spawn8 } from "node:child_process";
|
|
35515
|
-
import { closeSync as closeSync3, existsSync as existsSync16, mkdirSync as
|
|
35516
|
-
import { homedir as
|
|
35517
|
-
import { dirname as
|
|
35517
|
+
import { closeSync as closeSync3, existsSync as existsSync16, mkdirSync as mkdirSync14, openSync as openSync3, readFileSync as readFileSync20 } from "node:fs";
|
|
35518
|
+
import { homedir as homedir23 } from "node:os";
|
|
35519
|
+
import { dirname as dirname11, join as join32, resolve as resolve11 } from "node:path";
|
|
35518
35520
|
import { createInterface as createInterface2 } from "node:readline/promises";
|
|
35519
35521
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
35520
35522
|
|
|
@@ -37111,16 +37113,190 @@ function normalizeDomainOption(raw) {
|
|
|
37111
37113
|
return value;
|
|
37112
37114
|
}
|
|
37113
37115
|
|
|
37116
|
+
// server/service-cli.ts
|
|
37117
|
+
import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync3 } from "node:fs";
|
|
37118
|
+
import { homedir as homedir2 } from "node:os";
|
|
37119
|
+
|
|
37120
|
+
// server/service-unit.ts
|
|
37121
|
+
import { homedir, userInfo } from "node:os";
|
|
37122
|
+
import { posix } from "node:path";
|
|
37123
|
+
var { basename, dirname, join: join2 } = posix;
|
|
37124
|
+
var SYSTEMD_UNIT_NAME = "openmausbot.service";
|
|
37125
|
+
var LAUNCHD_LABEL = "com.openmausbot.serve";
|
|
37126
|
+
function quoteSystemd(value) {
|
|
37127
|
+
return /[\s"\\]/.test(value) ? `"${value.replace(/[\\"]/g, "\\$&")}"` : value;
|
|
37128
|
+
}
|
|
37129
|
+
function needsStripTypes(script) {
|
|
37130
|
+
return script.endsWith(".ts");
|
|
37131
|
+
}
|
|
37132
|
+
function serviceCommand(spec) {
|
|
37133
|
+
return [spec.node, ...needsStripTypes(spec.script) ? ["--experimental-strip-types"] : [], spec.script, "serve", ...spec.serveArgs];
|
|
37134
|
+
}
|
|
37135
|
+
function systemdUnit(spec) {
|
|
37136
|
+
const lines = [
|
|
37137
|
+
"# Written by `openmausbot service install`. Re-run it to change the options.",
|
|
37138
|
+
"[Unit]",
|
|
37139
|
+
`Description=OpenMausBot${spec.label ? ` (${spec.label})` : ""}`,
|
|
37140
|
+
"After=network-online.target",
|
|
37141
|
+
"Wants=network-online.target",
|
|
37142
|
+
"",
|
|
37143
|
+
"[Service]",
|
|
37144
|
+
"Type=simple",
|
|
37145
|
+
`User=${spec.user}`,
|
|
37146
|
+
`WorkingDirectory=${spec.home}`,
|
|
37147
|
+
`Environment=HOME=${spec.home}`,
|
|
37148
|
+
`Environment=OMB_DATA_DIR=${spec.dataDir}`,
|
|
37149
|
+
`ExecStart=${serviceCommand(spec).map(quoteSystemd).join(" ")}`,
|
|
37150
|
+
"Restart=always",
|
|
37151
|
+
"RestartSec=3",
|
|
37152
|
+
"KillMode=mixed",
|
|
37153
|
+
"TimeoutStopSec=30"
|
|
37154
|
+
];
|
|
37155
|
+
if (spec.bindsLowPorts) {
|
|
37156
|
+
lines.push("# serve --domain: Caddy binds ports 80 and 443 without running as root.");
|
|
37157
|
+
lines.push("AmbientCapabilities=CAP_NET_BIND_SERVICE");
|
|
37158
|
+
lines.push("CapabilityBoundingSet=CAP_NET_BIND_SERVICE");
|
|
37159
|
+
}
|
|
37160
|
+
lines.push("", "[Install]", "WantedBy=multi-user.target", "");
|
|
37161
|
+
return lines.join("\n");
|
|
37162
|
+
}
|
|
37163
|
+
function xml(value) {
|
|
37164
|
+
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
37165
|
+
}
|
|
37166
|
+
function launchdPlist(spec) {
|
|
37167
|
+
const args = serviceCommand(spec).map((arg) => ` <string>${xml(arg)}</string>`).join("\n");
|
|
37168
|
+
return [
|
|
37169
|
+
'<?xml version="1.0" encoding="UTF-8"?>',
|
|
37170
|
+
'<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">',
|
|
37171
|
+
'<plist version="1.0">',
|
|
37172
|
+
"<dict>",
|
|
37173
|
+
" <key>Label</key>",
|
|
37174
|
+
` <string>${LAUNCHD_LABEL}</string>`,
|
|
37175
|
+
" <key>ProgramArguments</key>",
|
|
37176
|
+
" <array>",
|
|
37177
|
+
args,
|
|
37178
|
+
" </array>",
|
|
37179
|
+
" <key>EnvironmentVariables</key>",
|
|
37180
|
+
" <dict>",
|
|
37181
|
+
" <key>HOME</key>",
|
|
37182
|
+
` <string>${xml(spec.home)}</string>`,
|
|
37183
|
+
" <key>OMB_DATA_DIR</key>",
|
|
37184
|
+
` <string>${xml(spec.dataDir)}</string>`,
|
|
37185
|
+
" <key>PATH</key>",
|
|
37186
|
+
" <string>/usr/local/bin:/opt/homebrew/bin:/usr/bin:/bin</string>",
|
|
37187
|
+
" </dict>",
|
|
37188
|
+
" <key>WorkingDirectory</key>",
|
|
37189
|
+
` <string>${xml(spec.home)}</string>`,
|
|
37190
|
+
" <key>RunAtLoad</key>",
|
|
37191
|
+
" <true/>",
|
|
37192
|
+
" <key>KeepAlive</key>",
|
|
37193
|
+
" <true/>",
|
|
37194
|
+
" <key>StandardOutPath</key>",
|
|
37195
|
+
` <string>${xml(join2(spec.dataDir, "logs", "service.log"))}</string>`,
|
|
37196
|
+
" <key>StandardErrorPath</key>",
|
|
37197
|
+
` <string>${xml(join2(spec.dataDir, "logs", "service.log"))}</string>`,
|
|
37198
|
+
"</dict>",
|
|
37199
|
+
"</plist>",
|
|
37200
|
+
""
|
|
37201
|
+
].join("\n");
|
|
37202
|
+
}
|
|
37203
|
+
function unstableInstallWarning(script) {
|
|
37204
|
+
const normalized = script.replace(/\\/g, "/");
|
|
37205
|
+
if (/\/_npx\//.test(normalized) || /\/\.npm\/_npx\//.test(normalized)) {
|
|
37206
|
+
return `this command runs from an npx cache (${dirname(script)}), which npm may delete at any time. Install it permanently first (npm install -g openmausbot) and run \`openmausbot service install\` from that install.`;
|
|
37207
|
+
}
|
|
37208
|
+
return null;
|
|
37209
|
+
}
|
|
37210
|
+
function servicePlan(platform, dataDir, home = homedir()) {
|
|
37211
|
+
if (platform === "linux") {
|
|
37212
|
+
const installed = `/etc/systemd/system/${SYSTEMD_UNIT_NAME}`;
|
|
37213
|
+
return {
|
|
37214
|
+
file: join2(dataDir, SYSTEMD_UNIT_NAME),
|
|
37215
|
+
installed,
|
|
37216
|
+
activate: [`sudo install -m 644 ${join2(dataDir, SYSTEMD_UNIT_NAME)} ${installed}`, "sudo systemctl daemon-reload", `sudo systemctl enable --now ${basename(SYSTEMD_UNIT_NAME, ".service")}`],
|
|
37217
|
+
deactivate: [`sudo systemctl disable --now ${basename(SYSTEMD_UNIT_NAME, ".service")}`, `sudo rm ${installed}`, "sudo systemctl daemon-reload"]
|
|
37218
|
+
};
|
|
37219
|
+
}
|
|
37220
|
+
if (platform === "darwin") {
|
|
37221
|
+
const installed = join2(home, "Library", "LaunchAgents", `${LAUNCHD_LABEL}.plist`);
|
|
37222
|
+
return {
|
|
37223
|
+
file: join2(dataDir, `${LAUNCHD_LABEL}.plist`),
|
|
37224
|
+
installed,
|
|
37225
|
+
activate: [`mkdir -p ${dirname(installed)} && cp ${join2(dataDir, `${LAUNCHD_LABEL}.plist`)} ${installed}`, `launchctl bootstrap gui/$(id -u) ${installed}`],
|
|
37226
|
+
deactivate: [`launchctl bootout gui/$(id -u)/${LAUNCHD_LABEL}`, `rm ${installed}`]
|
|
37227
|
+
};
|
|
37228
|
+
}
|
|
37229
|
+
return null;
|
|
37230
|
+
}
|
|
37231
|
+
function currentUser() {
|
|
37232
|
+
try {
|
|
37233
|
+
return userInfo().username;
|
|
37234
|
+
} catch {
|
|
37235
|
+
return process.env.USER || process.env.USERNAME || "openmausbot";
|
|
37236
|
+
}
|
|
37237
|
+
}
|
|
37238
|
+
|
|
37239
|
+
// server/service-cli.ts
|
|
37240
|
+
function serviceServeArgs(input) {
|
|
37241
|
+
const args = ["--port", String(input.port), "--data-dir", input.dataDir, "--no-pair"];
|
|
37242
|
+
if (input.domain) args.push("--domain", input.domain);
|
|
37243
|
+
else if (input.tunnel) args.push("--tunnel");
|
|
37244
|
+
else if (input.tailscale) args.push("--tailscale");
|
|
37245
|
+
if (input.label) args.push("--label", input.label);
|
|
37246
|
+
return args;
|
|
37247
|
+
}
|
|
37248
|
+
function runServiceCommand(input, io) {
|
|
37249
|
+
const platform = input.platform ?? process.platform;
|
|
37250
|
+
const home = input.home ?? homedir2();
|
|
37251
|
+
const plan = servicePlan(platform, input.dataDir, home);
|
|
37252
|
+
if (!plan) {
|
|
37253
|
+
io.error("services are written for Linux (systemd) and macOS (launchd); on Windows, use Task Scheduler to run `openmausbot serve` at startup");
|
|
37254
|
+
return 1;
|
|
37255
|
+
}
|
|
37256
|
+
if (input.action === "uninstall") {
|
|
37257
|
+
io.log(`to stop and remove the service:`);
|
|
37258
|
+
for (const line of plan.deactivate) io.log(` ${line}`);
|
|
37259
|
+
return 0;
|
|
37260
|
+
}
|
|
37261
|
+
const warning = unstableInstallWarning(input.script);
|
|
37262
|
+
if (warning) {
|
|
37263
|
+
io.error(warning);
|
|
37264
|
+
return 1;
|
|
37265
|
+
}
|
|
37266
|
+
const spec = {
|
|
37267
|
+
node: input.node,
|
|
37268
|
+
script: input.script,
|
|
37269
|
+
serveArgs: serviceServeArgs(input),
|
|
37270
|
+
dataDir: input.dataDir,
|
|
37271
|
+
user: input.user ?? currentUser(),
|
|
37272
|
+
home,
|
|
37273
|
+
bindsLowPorts: Boolean(input.domain),
|
|
37274
|
+
...input.label ? { label: input.label } : {}
|
|
37275
|
+
};
|
|
37276
|
+
const rendered = platform === "darwin" ? launchdPlist(spec) : systemdUnit(spec);
|
|
37277
|
+
mkdirSync2(input.dataDir, { recursive: true, mode: 448 });
|
|
37278
|
+
writeFileSync3(plan.file, rendered, { mode: 420 });
|
|
37279
|
+
io.log(`wrote ${plan.file}`);
|
|
37280
|
+
io.log("");
|
|
37281
|
+
io.log(platform === "darwin" ? "to install and start it (runs at login):" : "to install and start it (runs at boot, restarts if it stops):");
|
|
37282
|
+
for (const line of plan.activate) io.log(` ${line}`);
|
|
37283
|
+
io.log("");
|
|
37284
|
+
if (input.domain && platform === "linux") io.log("the unit grants Caddy the capability for ports 80 and 443, so no setcap is needed under the service");
|
|
37285
|
+
io.log(`logs: ${platform === "darwin" ? `${input.dataDir}/logs/service.log` : "journalctl -u openmausbot -f"}`);
|
|
37286
|
+
io.log(`change options later by running \`openmausbot service install\` again with the new ones, then: ${platform === "darwin" ? plan.activate[1] : "sudo systemctl daemon-reload && sudo systemctl restart openmausbot"}`);
|
|
37287
|
+
return 0;
|
|
37288
|
+
}
|
|
37289
|
+
|
|
37114
37290
|
// server/tailscale.ts
|
|
37115
37291
|
import { execFile } from "node:child_process";
|
|
37116
37292
|
|
|
37117
37293
|
// companion/src/listener.ts
|
|
37118
|
-
import { homedir, networkInterfaces } from "node:os";
|
|
37119
|
-
import { delimiter as delimiter2, join as
|
|
37120
|
-
function tailscaleCandidates(home =
|
|
37294
|
+
import { homedir as homedir3, networkInterfaces } from "node:os";
|
|
37295
|
+
import { delimiter as delimiter2, join as join3 } from "node:path";
|
|
37296
|
+
function tailscaleCandidates(home = homedir3()) {
|
|
37121
37297
|
return [
|
|
37122
37298
|
"/Applications/Tailscale.app/Contents/MacOS/Tailscale",
|
|
37123
|
-
|
|
37299
|
+
join3(home, "Applications", "Tailscale.app", "Contents", "MacOS", "Tailscale"),
|
|
37124
37300
|
"/opt/homebrew/bin/tailscale",
|
|
37125
37301
|
"/usr/local/bin/tailscale",
|
|
37126
37302
|
"/usr/bin/tailscale",
|
|
@@ -37333,9 +37509,9 @@ function phonePairingInstructions(phone, input) {
|
|
|
37333
37509
|
// server/tunnel.ts
|
|
37334
37510
|
import { spawn as spawn3 } from "node:child_process";
|
|
37335
37511
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
37336
|
-
import { chmodSync as chmodSync2, existsSync as existsSync2, mkdirSync as
|
|
37512
|
+
import { chmodSync as chmodSync2, existsSync as existsSync2, mkdirSync as mkdirSync3, readFileSync, statSync } from "node:fs";
|
|
37337
37513
|
import { hostname } from "node:os";
|
|
37338
|
-
import { dirname, join as
|
|
37514
|
+
import { dirname as dirname2, join as join4, resolve as resolve2 } from "node:path";
|
|
37339
37515
|
import { fileURLToPath } from "node:url";
|
|
37340
37516
|
|
|
37341
37517
|
// electron/secure-credential-state.mjs
|
|
@@ -37408,7 +37584,7 @@ function createSecureCredentialState(initialCredentials, persist, { writable = t
|
|
|
37408
37584
|
|
|
37409
37585
|
// server/tunnel.ts
|
|
37410
37586
|
init_atomic();
|
|
37411
|
-
var HERE =
|
|
37587
|
+
var HERE = dirname2(fileURLToPath(import.meta.url));
|
|
37412
37588
|
var TUNNEL_CREDENTIALS_FILE = "tunnel-account.json";
|
|
37413
37589
|
var TUNNEL_RUNTIME_DIR = "tunnel-runtime";
|
|
37414
37590
|
function plainDocument(value) {
|
|
@@ -37418,7 +37594,7 @@ function plainDocument(value) {
|
|
|
37418
37594
|
return document;
|
|
37419
37595
|
}
|
|
37420
37596
|
function openTunnelCredentials(dataDir) {
|
|
37421
|
-
const file2 =
|
|
37597
|
+
const file2 = join4(dataDir, TUNNEL_CREDENTIALS_FILE);
|
|
37422
37598
|
let initial = {};
|
|
37423
37599
|
let status = "empty";
|
|
37424
37600
|
if (existsSync2(file2)) {
|
|
@@ -37433,7 +37609,7 @@ function openTunnelCredentials(dataDir) {
|
|
|
37433
37609
|
}
|
|
37434
37610
|
}
|
|
37435
37611
|
const persist = (next) => {
|
|
37436
|
-
|
|
37612
|
+
mkdirSync3(dataDir, { recursive: true, mode: 448 });
|
|
37437
37613
|
writeFileAtomic(file2, `${JSON.stringify(next, null, 2)}
|
|
37438
37614
|
`, { mode: 384 });
|
|
37439
37615
|
};
|
|
@@ -37500,11 +37676,11 @@ function cloudflaredPath(dataDir, env = process.env) {
|
|
|
37500
37676
|
return resolveCloudflaredBinary({ isPackaged: false, appPath: dataDir, environment: env });
|
|
37501
37677
|
}
|
|
37502
37678
|
function prepareEntry(here = HERE) {
|
|
37503
|
-
const bundled =
|
|
37679
|
+
const bundled = join4(here, "prepare-cloudflared.js");
|
|
37504
37680
|
return existsSync2(bundled) ? bundled : resolve2(here, "..", "scripts", "prepare-cloudflared.mjs");
|
|
37505
37681
|
}
|
|
37506
37682
|
function guardianEntry(here = HERE) {
|
|
37507
|
-
const bundled =
|
|
37683
|
+
const bundled = join4(here, "tunnel-guardian.js");
|
|
37508
37684
|
if (existsSync2(bundled)) return bundled;
|
|
37509
37685
|
const source = resolve2(here, "..", "electron", "managed-companion-guardian-main.mjs");
|
|
37510
37686
|
return existsSync2(source) ? source : null;
|
|
@@ -37539,7 +37715,7 @@ function startTunnel(options) {
|
|
|
37539
37715
|
const tunnel = createManagedCompanionTunnel({
|
|
37540
37716
|
binaryPath: options.binaryPath,
|
|
37541
37717
|
guardianEntry: options.guardian,
|
|
37542
|
-
runtimeRoot:
|
|
37718
|
+
runtimeRoot: join4(options.dataDir, TUNNEL_RUNTIME_DIR),
|
|
37543
37719
|
originPort,
|
|
37544
37720
|
environment: env,
|
|
37545
37721
|
fetchImpl: options.fetchImpl,
|
|
@@ -37574,8 +37750,8 @@ function describeTunnelState(state, address) {
|
|
|
37574
37750
|
}
|
|
37575
37751
|
|
|
37576
37752
|
// server/cli.ts
|
|
37577
|
-
var HERE2 =
|
|
37578
|
-
var COMMANDS = ["setup", "start", "serve", "pair", "sessions", "status", "login", "logout", "access", "browser", "help", "--help", "-h"];
|
|
37753
|
+
var HERE2 = dirname11(fileURLToPath3(import.meta.url));
|
|
37754
|
+
var COMMANDS = ["setup", "start", "serve", "pair", "sessions", "status", "login", "logout", "access", "service", "browser", "help", "--help", "-h"];
|
|
37579
37755
|
function parseArgs(argv, env = process.env) {
|
|
37580
37756
|
const implicitStart = !argv.length || argv[0].startsWith("--") && argv[0] !== "--help";
|
|
37581
37757
|
const [command = "start", ...rest] = implicitStart ? ["start", ...argv] : argv;
|
|
@@ -37585,7 +37761,7 @@ function parseArgs(argv, env = process.env) {
|
|
|
37585
37761
|
const options = {
|
|
37586
37762
|
command: command === "--help" || command === "-h" ? "help" : command,
|
|
37587
37763
|
port: Number(env.OMB_PORT || 8799),
|
|
37588
|
-
dataDir: env.OMB_DATA_DIR ||
|
|
37764
|
+
dataDir: env.OMB_DATA_DIR || join32(homedir23(), ".openmausbot"),
|
|
37589
37765
|
tailscale: false,
|
|
37590
37766
|
tunnel: false,
|
|
37591
37767
|
client: false,
|
|
@@ -37624,6 +37800,7 @@ function parseArgs(argv, env = process.env) {
|
|
|
37624
37800
|
options.accessAction = arg;
|
|
37625
37801
|
if (arg !== "list") options.email = value();
|
|
37626
37802
|
} else if (options.command === "access" && arg === "--chat-only") options.chatOnly = true;
|
|
37803
|
+
else if (options.command === "service" && !options.serviceAction && (arg === "install" || arg === "uninstall")) options.serviceAction = arg;
|
|
37627
37804
|
else if (options.command === "browser" && (arg === "install" || arg === "status")) options.browserAction = arg;
|
|
37628
37805
|
else if (options.command === "browser" && arg === "--with-deps") options.withDeps = true;
|
|
37629
37806
|
else return { error: `unknown argument "${arg}"` };
|
|
@@ -37635,6 +37812,7 @@ function parseArgs(argv, env = process.env) {
|
|
|
37635
37812
|
if (options.publicUrl && !/^https?:\/\//.test(options.publicUrl)) return { error: "--public-url must start with http:// or https://" };
|
|
37636
37813
|
if (options.tailscale && options.tunnel) return { error: "choose one of --tailscale (your tailnet) and --tunnel (a public address)" };
|
|
37637
37814
|
if (options.command === "access" && !options.accessAction) return { error: "access needs one of: list, add EMAIL [--chat-only], remove EMAIL" };
|
|
37815
|
+
if (options.command === "service" && !options.serviceAction) return { error: "service needs one of: install [the same options as serve], uninstall" };
|
|
37638
37816
|
if (options.domain && (options.tailscale || options.tunnel || options.publicUrl)) return { error: "--domain already gives the server its address; drop --tailscale, --tunnel and --public-url" };
|
|
37639
37817
|
if (options.local && (options.tailscale || options.tunnel || options.publicUrl)) return { error: "--local cannot be combined with a remote-access option" };
|
|
37640
37818
|
if (options.command === "browser" && !options.browserAction) return { error: "browser needs an action: install or status" };
|
|
@@ -37653,6 +37831,7 @@ var USAGE = `openmausbot \u2014 your team of AI bots, ready in a few steps
|
|
|
37653
37831
|
openmausbot login [--email you@example.com]
|
|
37654
37832
|
openmausbot logout
|
|
37655
37833
|
openmausbot access list | add EMAIL [--chat-only] | remove EMAIL
|
|
37834
|
+
openmausbot service install [--domain HOST | --tunnel | --tailscale] [--port N] [--data-dir DIR] | uninstall
|
|
37656
37835
|
openmausbot browser install [--with-deps] | status
|
|
37657
37836
|
|
|
37658
37837
|
setup choose AI access and optional phone access; keep existing bots and chats
|
|
@@ -37667,6 +37846,10 @@ logout releases that address and signs out
|
|
|
37667
37846
|
access who may sign in with an emailed code at /pair: an address or
|
|
37668
37847
|
@domain; --chat-only gives chat and approvals without settings.
|
|
37669
37848
|
Takes effect at once, no restart.
|
|
37849
|
+
service keep the server running across reboots: writes a systemd unit
|
|
37850
|
+
(Linux) or a launchd agent (macOS) for the same serve options and
|
|
37851
|
+
prints the commands that install it. Install the package
|
|
37852
|
+
permanently first (npm install -g openmausbot).
|
|
37670
37853
|
browser install: the bots' browser engine (agent-browser, pinned) into the
|
|
37671
37854
|
data dir, and Chrome for Testing into the user's browser cache.
|
|
37672
37855
|
--with-deps also installs
|
|
@@ -37733,7 +37916,7 @@ async function isWorkspaceRunning(options) {
|
|
|
37733
37916
|
try {
|
|
37734
37917
|
const { status, body } = await api(options.port, "/api/health");
|
|
37735
37918
|
if (status !== 200 || body?.app !== "openmausbot") return false;
|
|
37736
|
-
const expected = readFileSync20(
|
|
37919
|
+
const expected = readFileSync20(join32(options.dataDir, "environment-id"), "utf8").trim();
|
|
37737
37920
|
const descriptor = await api(options.port, "/.well-known/openmausbot/environment");
|
|
37738
37921
|
return /^[0-9a-f-]{36}$/i.test(expected) && descriptor.status === 200 && descriptor.body?.environmentId === expected;
|
|
37739
37922
|
} catch {
|
|
@@ -37933,7 +38116,7 @@ async function runStatus(options, io = defaultIo()) {
|
|
|
37933
38116
|
return code;
|
|
37934
38117
|
}
|
|
37935
38118
|
async function runAccess(options, io = defaultIo()) {
|
|
37936
|
-
const file2 =
|
|
38119
|
+
const file2 = join32(options.dataDir, "config.json");
|
|
37937
38120
|
let raw = {};
|
|
37938
38121
|
if (existsSync16(file2)) {
|
|
37939
38122
|
try {
|
|
@@ -37951,7 +38134,7 @@ async function runAccess(options, io = defaultIo()) {
|
|
|
37951
38134
|
const members = list(Reflect.get(current, "members"));
|
|
37952
38135
|
const overridden = process.env.OMB_SIGNIN_EMAILS !== void 0 || process.env.OMB_SIGNIN_MEMBER_EMAILS !== void 0;
|
|
37953
38136
|
const write = (next) => {
|
|
37954
|
-
|
|
38137
|
+
mkdirSync14(options.dataDir, { recursive: true, mode: 448 });
|
|
37955
38138
|
writeFileAtomic(file2, `${JSON.stringify({ ...raw, signIn: next }, null, 2)}
|
|
37956
38139
|
`, { mode: 384 });
|
|
37957
38140
|
};
|
|
@@ -38085,16 +38268,16 @@ async function runBrowser(options, io = defaultIo()) {
|
|
|
38085
38268
|
return 0;
|
|
38086
38269
|
}
|
|
38087
38270
|
function serverEntry(here = HERE2) {
|
|
38088
|
-
const bundled =
|
|
38271
|
+
const bundled = join32(here, "index.js");
|
|
38089
38272
|
const root = resolve11(here, "..");
|
|
38090
38273
|
if (existsSync16(bundled)) {
|
|
38091
|
-
const staticDir2 = [
|
|
38092
|
-
const skillsDir = existsSync16(
|
|
38274
|
+
const staticDir2 = [join32(root, "dist"), join32(here, "..", "ui")].find((d) => existsSync16(join32(d, "index.html"))) ?? null;
|
|
38275
|
+
const skillsDir = existsSync16(join32(root, "skills")) ? join32(root, "skills") : null;
|
|
38093
38276
|
return { command: process.execPath, args: [bundled], staticDir: staticDir2, skillsDir };
|
|
38094
38277
|
}
|
|
38095
|
-
const source =
|
|
38096
|
-
const staticDir = existsSync16(
|
|
38097
|
-
return { command: process.execPath, args: ["--experimental-strip-types", source], staticDir, skillsDir: existsSync16(
|
|
38278
|
+
const source = join32(here, "index.ts");
|
|
38279
|
+
const staticDir = existsSync16(join32(root, "dist", "index.html")) ? join32(root, "dist") : null;
|
|
38280
|
+
return { command: process.execPath, args: ["--experimental-strip-types", source], staticDir, skillsDir: existsSync16(join32(root, "skills")) ? join32(root, "skills") : null };
|
|
38098
38281
|
}
|
|
38099
38282
|
async function planTunnel(options, log) {
|
|
38100
38283
|
let access2 = null;
|
|
@@ -38194,9 +38377,9 @@ async function runServe(options, log = console.log) {
|
|
|
38194
38377
|
let child;
|
|
38195
38378
|
try {
|
|
38196
38379
|
if (options.guided) {
|
|
38197
|
-
const logsDir =
|
|
38198
|
-
|
|
38199
|
-
logPath =
|
|
38380
|
+
const logsDir = join32(options.dataDir, "logs");
|
|
38381
|
+
mkdirSync14(logsDir, { recursive: true, mode: 448 });
|
|
38382
|
+
logPath = join32(logsDir, `server-${Date.now()}-${process.pid}.log`);
|
|
38200
38383
|
logFd = openSync3(logPath, "wx", 384);
|
|
38201
38384
|
log("\nStarting your workspace\u2026");
|
|
38202
38385
|
}
|
|
@@ -38388,7 +38571,7 @@ async function runOnboardingCommand(options, io = defaultIo(), startServer = run
|
|
|
38388
38571
|
}
|
|
38389
38572
|
if (options.command === "setup") {
|
|
38390
38573
|
io.log("\nAll set. Start with: openmausbot (or npx openmausbot without a global install).");
|
|
38391
|
-
if (options.dataDir !==
|
|
38574
|
+
if (options.dataDir !== join32(homedir23(), ".openmausbot") || options.port !== 8799) {
|
|
38392
38575
|
io.log(`Use the same --data-dir (${options.dataDir}) and --port (${options.port}) options when starting.`);
|
|
38393
38576
|
}
|
|
38394
38577
|
return 0;
|
|
@@ -38426,6 +38609,18 @@ ${USAGE}`);
|
|
|
38426
38609
|
return runLogin(options);
|
|
38427
38610
|
case "access":
|
|
38428
38611
|
return runAccess(options);
|
|
38612
|
+
case "service":
|
|
38613
|
+
return runServiceCommand({
|
|
38614
|
+
action: options.serviceAction ?? "install",
|
|
38615
|
+
dataDir: options.dataDir,
|
|
38616
|
+
port: options.port,
|
|
38617
|
+
domain: options.domain,
|
|
38618
|
+
tunnel: options.tunnel,
|
|
38619
|
+
tailscale: options.tailscale,
|
|
38620
|
+
label: options.label,
|
|
38621
|
+
script: process.argv[1] ?? "",
|
|
38622
|
+
node: process.execPath
|
|
38623
|
+
}, { log: (line) => console.log(line), error: (line) => console.error(line) });
|
|
38429
38624
|
case "logout":
|
|
38430
38625
|
return runLogout(options);
|
|
38431
38626
|
case "browser":
|