openmausbot 0.1.69 → 0.1.71
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-BmHupgVJ.js → index-CJtyBonr.js} +1 -1
- package/dist/assets/index-CYLdYtYp.css +1 -0
- package/dist/assets/index-Di4ovwu5.js +289 -0
- package/dist/index.html +2 -2
- package/dist-server/container-mcp.js +6 -2
- package/dist-server/drivers/agents-proxy.js +305 -16
- package/dist-server/drivers/pi-mcp-extension.ts +1 -1
- package/dist-server/index.js +3141 -1124
- package/dist-server/local-computer-proxy.js +2 -0
- package/dist-server/local-computer.js +2 -1
- package/dist-server/mcp-gate.js +543 -0
- package/dist-server/mcp-server.js +38 -0
- package/dist-server/openmausbot.js +772 -260
- package/dist-server/pair-cli.js +772 -260
- package/dist-server/prepare-cloudflared.js +20 -3
- package/dist-server/proxy-paths.js +1 -0
- package/dist-server/server/agent-tool-policy.js +29 -0
- package/dist-server/server/bot-package.js +55 -2
- package/dist-server/server/browser-live.js +12 -7
- package/dist-server/server/config.js +40 -4
- package/dist-server/server/delegations.js +132 -74
- package/dist-server/server/drivers/acp/core.js +2 -0
- package/dist-server/server/drivers/acp/cursor.js +1 -1
- package/dist-server/server/drivers/acp/grok.js +5 -1
- package/dist-server/server/drivers/agents-proxy.js +324 -16
- package/dist-server/server/drivers/boxagent.js +1 -1
- package/dist-server/server/drivers/claude-login-auth.js +102 -9
- package/dist-server/server/drivers/claude.js +298 -21
- package/dist-server/server/drivers/codex.js +13 -4
- package/dist-server/server/drivers/pi.js +1 -1
- package/dist-server/server/engine-install.js +137 -0
- package/dist-server/server/env-path.js +12 -0
- package/dist-server/server/harness/bus.js +1 -1
- package/dist-server/server/harness/registry.js +31 -6
- package/dist-server/server/index.js +860 -215
- package/dist-server/server/local-computer.js +1 -1
- package/dist-server/server/mcp-gate-config.js +56 -0
- package/dist-server/server/mcp-gate.js +227 -0
- package/dist-server/server/mcp-trim.js +182 -0
- package/dist-server/server/memory-journal.js +440 -0
- package/dist-server/server/memory-store.js +308 -0
- package/dist-server/server/message-db.js +90 -3
- package/dist-server/server/package-export.js +25 -0
- package/dist-server/server/peer-approval.js +1 -1
- package/dist-server/server/peer-provenance.js +6 -2
- package/dist-server/server/proxy-paths.js +1 -0
- package/dist-server/server/redact.js +15 -0
- package/dist-server/server/resume-recovery.js +46 -0
- package/dist-server/server/routines.js +116 -55
- package/dist-server/server/screen-frame-gate.js +9 -6
- package/dist-server/server/skill-library.js +5 -5
- package/dist-server/server/steer-queue.js +20 -1
- package/dist-server/server/store.js +29 -7
- package/dist-server/server/system-prompt.js +14 -1
- package/dist-server/server/team-backup.js +53 -4
- package/dist-server/server/tool-summary.js +39 -0
- package/dist-server/server/tts/speech-text.js +3 -1
- package/dist-server/server/turn-context.js +18 -0
- package/dist-server/server/workspace.js +321 -22
- package/dist-server/shared/approval-mode.js +1 -1
- package/dist-server/shared/team-backup.js +14 -2
- package/dist-server/vps-container-mcp.js +6 -2
- package/package.json +1 -1
- package/skills/create-verification-skill/SKILL.md +2 -3
- package/dist/assets/index-COp5lMnv.js +0 -279
- package/dist/assets/index-Jk7TIeyW.css +0 -1
package/dist-server/pair-cli.js
CHANGED
|
@@ -1181,7 +1181,7 @@ var init_dist = __esm({
|
|
|
1181
1181
|
MODIFIER_RE = new RegExp("\\p{M}+", "gu");
|
|
1182
1182
|
NO_TRUNCATION = { limit: Infinity, ellipsis: "" };
|
|
1183
1183
|
getStringTruncatedWidth = (input, truncationOptions = {}, widthOptions = {}) => {
|
|
1184
|
-
const
|
|
1184
|
+
const LIMIT2 = truncationOptions.limit ?? Infinity;
|
|
1185
1185
|
const ELLIPSIS = truncationOptions.ellipsis ?? "";
|
|
1186
1186
|
const ELLIPSIS_WIDTH = truncationOptions?.ellipsisWidth ?? (ELLIPSIS ? getStringTruncatedWidth(ELLIPSIS, NO_TRUNCATION, widthOptions).width : 0);
|
|
1187
1187
|
const ANSI_WIDTH = 0;
|
|
@@ -1205,7 +1205,7 @@ var init_dist = __esm({
|
|
|
1205
1205
|
let lengthExtra = 0;
|
|
1206
1206
|
let truncationEnabled = false;
|
|
1207
1207
|
let truncationIndex = length;
|
|
1208
|
-
let truncationLimit = Math.max(0,
|
|
1208
|
+
let truncationLimit = Math.max(0, LIMIT2 - ELLIPSIS_WIDTH);
|
|
1209
1209
|
let unmatchedStart = 0;
|
|
1210
1210
|
let unmatchedEnd = 0;
|
|
1211
1211
|
let width = 0;
|
|
@@ -1226,7 +1226,7 @@ var init_dist = __esm({
|
|
|
1226
1226
|
if (width + widthExtra > truncationLimit) {
|
|
1227
1227
|
truncationIndex = Math.min(truncationIndex, Math.max(unmatchedStart, indexPrev) + lengthExtra);
|
|
1228
1228
|
}
|
|
1229
|
-
if (width + widthExtra >
|
|
1229
|
+
if (width + widthExtra > LIMIT2) {
|
|
1230
1230
|
truncationEnabled = true;
|
|
1231
1231
|
break outer;
|
|
1232
1232
|
}
|
|
@@ -1247,7 +1247,7 @@ var init_dist = __esm({
|
|
|
1247
1247
|
if (width + widthExtra > truncationLimit) {
|
|
1248
1248
|
truncationIndex = Math.min(truncationIndex, index + Math.floor((truncationLimit - width) / BLOCK_WIDTH));
|
|
1249
1249
|
}
|
|
1250
|
-
if (width + widthExtra >
|
|
1250
|
+
if (width + widthExtra > LIMIT2) {
|
|
1251
1251
|
truncationEnabled = true;
|
|
1252
1252
|
break outer;
|
|
1253
1253
|
}
|
|
@@ -1264,7 +1264,7 @@ var init_dist = __esm({
|
|
|
1264
1264
|
width: truncationEnabled ? truncationLimit : width,
|
|
1265
1265
|
index: truncationEnabled ? truncationIndex : length,
|
|
1266
1266
|
truncated: truncationEnabled,
|
|
1267
|
-
ellipsed: truncationEnabled &&
|
|
1267
|
+
ellipsed: truncationEnabled && LIMIT2 >= ELLIPSIS_WIDTH
|
|
1268
1268
|
};
|
|
1269
1269
|
};
|
|
1270
1270
|
dist_default = getStringTruncatedWidth;
|
|
@@ -17964,8 +17964,9 @@ var init_config = __esm({
|
|
|
17964
17964
|
});
|
|
17965
17965
|
});
|
|
17966
17966
|
featureConfigSchema = external_exports.object({
|
|
17967
|
-
/**
|
|
17968
|
-
|
|
17967
|
+
/** Bots may draft skills (skill_manage, /learn) for your review. Off unless
|
|
17968
|
+
* explicitly enabled. */
|
|
17969
|
+
skillAuthoring: external_exports.boolean().optional(),
|
|
17969
17970
|
/** Show each tool run in the transcript. Off unless explicitly enabled. */
|
|
17970
17971
|
showToolCalls: external_exports.boolean().optional(),
|
|
17971
17972
|
/** Experimental built-in browser. Off until explicitly enabled; each bot
|
|
@@ -18475,6 +18476,11 @@ function windowsKnownDirs() {
|
|
|
18475
18476
|
join7(home, "go", "bin")
|
|
18476
18477
|
];
|
|
18477
18478
|
}
|
|
18479
|
+
function registerPathDir(dir) {
|
|
18480
|
+
if (registeredDirs.includes(dir)) return;
|
|
18481
|
+
registeredDirs.unshift(dir);
|
|
18482
|
+
resetPathCache();
|
|
18483
|
+
}
|
|
18478
18484
|
function resetPathCache() {
|
|
18479
18485
|
cached2 = null;
|
|
18480
18486
|
probed = false;
|
|
@@ -18482,6 +18488,7 @@ function resetPathCache() {
|
|
|
18482
18488
|
function augmentedPath() {
|
|
18483
18489
|
if (cached2 === null) {
|
|
18484
18490
|
cached2 = mergePaths([
|
|
18491
|
+
...registeredDirs.filter((d) => existsSync5(d)),
|
|
18485
18492
|
...process.env.OMB_EXTRA_PATH ? process.env.OMB_EXTRA_PATH.split(delimiter3) : [],
|
|
18486
18493
|
...process.env.PATH ? process.env.PATH.split(delimiter3) : [],
|
|
18487
18494
|
// Keep the last successful login-shell result while a rescan starts a
|
|
@@ -18646,13 +18653,14 @@ function resolveCliSpawn(cli, args) {
|
|
|
18646
18653
|
}
|
|
18647
18654
|
return resolveWord(cli, args);
|
|
18648
18655
|
}
|
|
18649
|
-
var cached2, probed, loginShellPath;
|
|
18656
|
+
var cached2, probed, loginShellPath, registeredDirs;
|
|
18650
18657
|
var init_env_path = __esm({
|
|
18651
18658
|
"server/env-path.ts"() {
|
|
18652
18659
|
"use strict";
|
|
18653
18660
|
cached2 = null;
|
|
18654
18661
|
probed = false;
|
|
18655
18662
|
loginShellPath = null;
|
|
18663
|
+
registeredDirs = [];
|
|
18656
18664
|
}
|
|
18657
18665
|
});
|
|
18658
18666
|
|
|
@@ -18766,7 +18774,124 @@ var init_procs = __esm({
|
|
|
18766
18774
|
}
|
|
18767
18775
|
});
|
|
18768
18776
|
|
|
18777
|
+
// server/engine-install.ts
|
|
18778
|
+
import { existsSync as existsSync6, mkdirSync as mkdirSync6 } from "node:fs";
|
|
18779
|
+
import { join as join9 } from "node:path";
|
|
18780
|
+
import { stripVTControlCharacters as stripVTControlCharacters3 } from "node:util";
|
|
18781
|
+
function enginesPrefix(baseDir = DATA_DIR) {
|
|
18782
|
+
return join9(baseDir, "tools", "npm");
|
|
18783
|
+
}
|
|
18784
|
+
function enginesBinDir(baseDir = DATA_DIR, platform = process.platform) {
|
|
18785
|
+
return platform === "win32" ? enginesPrefix(baseDir) : join9(enginesPrefix(baseDir), "bin");
|
|
18786
|
+
}
|
|
18787
|
+
function npmPackageOf(install) {
|
|
18788
|
+
const line = install?.command?.linux ?? install?.command?.darwin ?? install?.command?.win32;
|
|
18789
|
+
const match = line ? /^npm install -g ((?:@[\w.-]+\/)?[\w.-]+)$/.exec(line.trim()) : null;
|
|
18790
|
+
return match ? match[1] : null;
|
|
18791
|
+
}
|
|
18792
|
+
function npmAvailable() {
|
|
18793
|
+
return findCliCandidates("npm").length > 0;
|
|
18794
|
+
}
|
|
18795
|
+
function serverInstallFor(install, npmPresent = npmAvailable()) {
|
|
18796
|
+
if (!install || install.managed) return null;
|
|
18797
|
+
const pkg = npmPackageOf(install);
|
|
18798
|
+
return pkg && npmPresent ? { package: pkg } : null;
|
|
18799
|
+
}
|
|
18800
|
+
function installNpmEngine(pkg, options = {}) {
|
|
18801
|
+
const key = `${options.baseDir ?? DATA_DIR} ${pkg}`;
|
|
18802
|
+
const existing = running.get(key);
|
|
18803
|
+
if (existing) return existing;
|
|
18804
|
+
const run3 = installOnce(pkg, options).finally(() => running.delete(key));
|
|
18805
|
+
running.set(key, run3);
|
|
18806
|
+
return run3;
|
|
18807
|
+
}
|
|
18808
|
+
async function installOnce(pkg, options) {
|
|
18809
|
+
const prefix = enginesPrefix(options.baseDir);
|
|
18810
|
+
mkdirSync6(prefix, { recursive: true });
|
|
18811
|
+
const env = {
|
|
18812
|
+
...options.env ?? process.env,
|
|
18813
|
+
PATH: options.path ?? augmentedPath(),
|
|
18814
|
+
NO_COLOR: "1",
|
|
18815
|
+
npm_config_update_notifier: "false",
|
|
18816
|
+
npm_config_fund: "false",
|
|
18817
|
+
npm_config_audit: "false"
|
|
18818
|
+
};
|
|
18819
|
+
stripWorkspaceCredentialEnv(env);
|
|
18820
|
+
const args = ["install", "-g", "--prefix", prefix, "--loglevel=error", `--allow-scripts=${pkg}`, `${pkg}@latest`];
|
|
18821
|
+
const result = await runNpm(args, env, prefix, options.timeoutMs ?? DEFAULT_TIMEOUT_MS);
|
|
18822
|
+
if (result.code !== 0) {
|
|
18823
|
+
throw new Error(`npm could not install ${pkg} on this server.${tail(result.output)}`);
|
|
18824
|
+
}
|
|
18825
|
+
registerPathDir(enginesBinDir(options.baseDir));
|
|
18826
|
+
resetPathCache();
|
|
18827
|
+
if (options.cli) {
|
|
18828
|
+
const binDir = enginesBinDir(options.baseDir);
|
|
18829
|
+
if (!findCliCandidates(options.cli).some((path3) => path3.startsWith(binDir))) {
|
|
18830
|
+
throw new Error(`${pkg} installed, but it did not provide a \`${options.cli}\` command. Check the package name in this engine's install descriptor.`);
|
|
18831
|
+
}
|
|
18832
|
+
}
|
|
18833
|
+
}
|
|
18834
|
+
function tail(output) {
|
|
18835
|
+
const clean = stripVTControlCharacters3(output).trim();
|
|
18836
|
+
if (!clean) return "";
|
|
18837
|
+
const lines = clean.split(/\r?\n/).filter((line) => line.trim()).slice(-6);
|
|
18838
|
+
return `
|
|
18839
|
+
${lines.join("\n").slice(-600)}`;
|
|
18840
|
+
}
|
|
18841
|
+
function runNpm(args, env, cwd, timeoutMs) {
|
|
18842
|
+
return new Promise((resolveRun, rejectRun) => {
|
|
18843
|
+
let child;
|
|
18844
|
+
try {
|
|
18845
|
+
child = spawnCli("npm", args, { env, cwd, stdio: ["pipe", "pipe", "pipe"] });
|
|
18846
|
+
} catch {
|
|
18847
|
+
rejectRun(new Error("npm could not start on this server. Install Node.js with npm for the user running OpenMausBot, then try again."));
|
|
18848
|
+
return;
|
|
18849
|
+
}
|
|
18850
|
+
child.stdin.end();
|
|
18851
|
+
let output = "";
|
|
18852
|
+
const receive = (chunk) => {
|
|
18853
|
+
if (output.length < MAX_OUTPUT) output += chunk.toString("utf8").slice(0, MAX_OUTPUT - output.length);
|
|
18854
|
+
};
|
|
18855
|
+
child.stdout.on("data", receive);
|
|
18856
|
+
child.stderr.on("data", receive);
|
|
18857
|
+
let timedOut = false;
|
|
18858
|
+
const timer = setTimeout(() => {
|
|
18859
|
+
timedOut = true;
|
|
18860
|
+
void killCliTree(child);
|
|
18861
|
+
}, timeoutMs);
|
|
18862
|
+
timer.unref();
|
|
18863
|
+
child.once("error", (error51) => {
|
|
18864
|
+
clearTimeout(timer);
|
|
18865
|
+
rejectRun(new Error(error51.code === "ENOENT" ? "npm is not installed on this server. Install Node.js with npm for the user running OpenMausBot, then try again." : "npm could not start on this server. Check that Node.js is installed for the user running OpenMausBot."));
|
|
18866
|
+
});
|
|
18867
|
+
child.once("close", (code) => {
|
|
18868
|
+
clearTimeout(timer);
|
|
18869
|
+
if (timedOut) {
|
|
18870
|
+
rejectRun(new Error("The install took too long and was stopped. Check the server's network connection and try again."));
|
|
18871
|
+
return;
|
|
18872
|
+
}
|
|
18873
|
+
resolveRun({ code, output });
|
|
18874
|
+
});
|
|
18875
|
+
});
|
|
18876
|
+
}
|
|
18877
|
+
var MAX_OUTPUT, DEFAULT_TIMEOUT_MS, running;
|
|
18878
|
+
var init_engine_install = __esm({
|
|
18879
|
+
"server/engine-install.ts"() {
|
|
18880
|
+
"use strict";
|
|
18881
|
+
init_config();
|
|
18882
|
+
init_env_path();
|
|
18883
|
+
init_procs();
|
|
18884
|
+
MAX_OUTPUT = 64 * 1024;
|
|
18885
|
+
DEFAULT_TIMEOUT_MS = 10 * 6e4;
|
|
18886
|
+
running = /* @__PURE__ */ new Map();
|
|
18887
|
+
}
|
|
18888
|
+
});
|
|
18889
|
+
|
|
18769
18890
|
// server/harness/registry.ts
|
|
18891
|
+
function withServerInstall(install, npmPresent) {
|
|
18892
|
+
const server = install ? serverInstallFor(install, npmPresent) : null;
|
|
18893
|
+
return server ? { ...install, server } : install;
|
|
18894
|
+
}
|
|
18770
18895
|
function cliDefaultOf(driver) {
|
|
18771
18896
|
if (!driver) return void 0;
|
|
18772
18897
|
try {
|
|
@@ -18785,13 +18910,21 @@ var init_registry = __esm({
|
|
|
18785
18910
|
"server/harness/registry.ts"() {
|
|
18786
18911
|
"use strict";
|
|
18787
18912
|
init_env_path();
|
|
18913
|
+
init_engine_install();
|
|
18788
18914
|
ProviderRegistry = class {
|
|
18789
18915
|
byId = /* @__PURE__ */ new Map();
|
|
18790
18916
|
/** decoded per-instance `cli` overrides, for describe() — drivers spawn
|
|
18791
18917
|
* from their own config; this map only reports what was configured */
|
|
18792
18918
|
cliByInstance = /* @__PURE__ */ new Map();
|
|
18793
18919
|
driversByKind;
|
|
18794
|
-
|
|
18920
|
+
/** Where Settings-driven npm installs go; the data directory by default. */
|
|
18921
|
+
enginesBaseDir;
|
|
18922
|
+
/** Whether npm is on this machine; injectable because the PATH scan also
|
|
18923
|
+
* looks in standard install locations, which tests cannot empty. */
|
|
18924
|
+
npmPresent;
|
|
18925
|
+
constructor(drivers, options = {}) {
|
|
18926
|
+
this.enginesBaseDir = options.enginesBaseDir;
|
|
18927
|
+
this.npmPresent = options.npmAvailable ?? npmAvailable;
|
|
18795
18928
|
this.driversByKind = new Map(drivers.map((d) => [d.driverKind, d]));
|
|
18796
18929
|
}
|
|
18797
18930
|
async load(configs) {
|
|
@@ -18866,10 +18999,20 @@ var init_registry = __esm({
|
|
|
18866
18999
|
await instance.refreshModels?.();
|
|
18867
19000
|
return true;
|
|
18868
19001
|
}
|
|
19002
|
+
/** A driver's own installer (a managed download) first; otherwise the
|
|
19003
|
+
* app's npm prefix, when the driver's install one-liner is an npm package
|
|
19004
|
+
* and npm is on PATH. False means Settings has nothing to offer here. */
|
|
18869
19005
|
async installRuntime(instanceId) {
|
|
18870
|
-
const
|
|
18871
|
-
if (!
|
|
18872
|
-
|
|
19006
|
+
const entry = this.byId.get(instanceId);
|
|
19007
|
+
if (!entry) return false;
|
|
19008
|
+
if (entry.live?.installRuntime) {
|
|
19009
|
+
await entry.live.installRuntime();
|
|
19010
|
+
return true;
|
|
19011
|
+
}
|
|
19012
|
+
const driver = this.driversByKind.get(entry.shadow?.driverKind ?? entry.live.driverKind);
|
|
19013
|
+
const server = serverInstallFor(driver?.install, this.npmPresent());
|
|
19014
|
+
if (!server) return false;
|
|
19015
|
+
await installNpmEngine(server.package, { baseDir: this.enginesBaseDir, cli: cliDefaultOf(driver) });
|
|
18873
19016
|
return true;
|
|
18874
19017
|
}
|
|
18875
19018
|
async startAuthentication(instanceId) {
|
|
@@ -18904,6 +19047,7 @@ var init_registry = __esm({
|
|
|
18904
19047
|
candidatesByName.set(name, found);
|
|
18905
19048
|
return found;
|
|
18906
19049
|
};
|
|
19050
|
+
const npmPresent = this.npmPresent();
|
|
18907
19051
|
return Promise.all(
|
|
18908
19052
|
this.entries().map(async (entry) => {
|
|
18909
19053
|
const driver = this.driversByKind.get(entry.shadow?.driverKind ?? entry.live.driverKind);
|
|
@@ -18917,7 +19061,7 @@ var init_registry = __esm({
|
|
|
18917
19061
|
capabilities: { computerMcp: false, agentsMcp: false, localComputerMcp: false },
|
|
18918
19062
|
// an unknown driver has no driver record, hence no install path
|
|
18919
19063
|
access: driver?.metadata.access ?? "subscription",
|
|
18920
|
-
install: driver?.install,
|
|
19064
|
+
install: withServerInstall(driver?.install, npmPresent),
|
|
18921
19065
|
cli: entry.shadow.cli,
|
|
18922
19066
|
cliDefault: cliDefaultOf(driver),
|
|
18923
19067
|
// a shadow is exactly the "your CLI is broken, pick another"
|
|
@@ -18951,7 +19095,7 @@ var init_registry = __esm({
|
|
|
18951
19095
|
approvalReview: inst.reviewPermission !== void 0
|
|
18952
19096
|
},
|
|
18953
19097
|
access: driver?.metadata.access ?? "subscription",
|
|
18954
|
-
install: driver?.install,
|
|
19098
|
+
install: withServerInstall(driver?.install, npmPresent),
|
|
18955
19099
|
authentication: inst.startAuthentication ? {
|
|
18956
19100
|
method: inst.getAuthentication && inst.completeAuthentication ? "paste-code" : inst.getAuthentication ? "device-code" : "browser",
|
|
18957
19101
|
// a link and a callback URL (managed engines)
|
|
@@ -18986,7 +19130,7 @@ var init_registry = __esm({
|
|
|
18986
19130
|
// server/drivers/local-inject.ts
|
|
18987
19131
|
import { readFileSync as readFileSync5 } from "node:fs";
|
|
18988
19132
|
import { homedir as homedir6 } from "node:os";
|
|
18989
|
-
import { join as
|
|
19133
|
+
import { join as join10 } from "node:path";
|
|
18990
19134
|
function contextWindowsFromPs(extra) {
|
|
18991
19135
|
const out = /* @__PURE__ */ new Map();
|
|
18992
19136
|
const rec = extra && typeof extra === "object" ? extra : null;
|
|
@@ -19071,7 +19215,7 @@ function firstUnslothToken(row) {
|
|
|
19071
19215
|
function readUnslothKey(env) {
|
|
19072
19216
|
const home = env.HOME || env.USERPROFILE || homedir6();
|
|
19073
19217
|
try {
|
|
19074
|
-
const raw = JSON.parse(readFileSync5(
|
|
19218
|
+
const raw = JSON.parse(readFileSync5(join10(home, ".unsloth", "studio", "auth", "agent_api_key.json"), "utf8"));
|
|
19075
19219
|
if (raw.servers && typeof raw.servers === "object") {
|
|
19076
19220
|
const servers = raw.servers;
|
|
19077
19221
|
for (const url2 of ["http://127.0.0.1:8888", "http://localhost:8888"]) {
|
|
@@ -19130,12 +19274,12 @@ function loadedIdsFromPayloads(_host, catalog, extra) {
|
|
|
19130
19274
|
};
|
|
19131
19275
|
if (extra && typeof extra === "object") {
|
|
19132
19276
|
const rec = extra;
|
|
19133
|
-
const
|
|
19134
|
-
const hasLoadedFlags =
|
|
19277
|
+
const running2 = Array.isArray(rec.models) ? rec.models : Array.isArray(rec.data) ? rec.data : [];
|
|
19278
|
+
const hasLoadedFlags = running2.some(
|
|
19135
19279
|
(row) => row && typeof row === "object" && ("loaded" in row || "state" in row)
|
|
19136
19280
|
);
|
|
19137
19281
|
if (!hasLoadedFlags && typeof rec.default_model === "string") add(rec.default_model);
|
|
19138
|
-
for (const row of
|
|
19282
|
+
for (const row of running2) {
|
|
19139
19283
|
if (typeof row === "string") {
|
|
19140
19284
|
if (!hasLoadedFlags) add(row);
|
|
19141
19285
|
continue;
|
|
@@ -19272,12 +19416,12 @@ var init_local_inject = __esm({
|
|
|
19272
19416
|
});
|
|
19273
19417
|
|
|
19274
19418
|
// server/proxy-paths.ts
|
|
19275
|
-
import { existsSync as
|
|
19276
|
-
import { dirname as dirname4, join as
|
|
19419
|
+
import { existsSync as existsSync7 } from "node:fs";
|
|
19420
|
+
import { dirname as dirname4, join as join11 } from "node:path";
|
|
19277
19421
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
19278
19422
|
function resolveProxy(relative2) {
|
|
19279
|
-
const source =
|
|
19280
|
-
return
|
|
19423
|
+
const source = join11(SERVER_ROOT, `${relative2}.ts`);
|
|
19424
|
+
return existsSync7(source) ? source : join11(SERVER_ROOT, `${relative2}.js`);
|
|
19281
19425
|
}
|
|
19282
19426
|
var SERVER_ROOT, SPAWNED_PROXIES;
|
|
19283
19427
|
var init_proxy_paths = __esm({
|
|
@@ -19294,6 +19438,7 @@ var init_proxy_paths = __esm({
|
|
|
19294
19438
|
agents: resolveProxy("drivers/agents-proxy"),
|
|
19295
19439
|
dweb: resolveProxy("drivers/dweb-proxy"),
|
|
19296
19440
|
connectors: resolveProxy("connector-proxy"),
|
|
19441
|
+
mcpGate: resolveProxy("mcp-gate"),
|
|
19297
19442
|
phone: resolveProxy("drivers/phone-proxy"),
|
|
19298
19443
|
// Loaded by the external `pi` process via `-e`, not by this server — but
|
|
19299
19444
|
// resolved through the same single source of truth so the packaged layout
|
|
@@ -19305,7 +19450,7 @@ var init_proxy_paths = __esm({
|
|
|
19305
19450
|
|
|
19306
19451
|
// server/container-computer.ts
|
|
19307
19452
|
import { execFile as execFile4 } from "node:child_process";
|
|
19308
|
-
import { join as
|
|
19453
|
+
import { join as join12, resolve as resolve3 } from "node:path";
|
|
19309
19454
|
import { promisify } from "node:util";
|
|
19310
19455
|
function computerProxyEnv(computer) {
|
|
19311
19456
|
return {
|
|
@@ -19329,7 +19474,7 @@ var init_container_computer = __esm({
|
|
|
19329
19474
|
IMAGE_REPOSITORY = "localhost/openmausbot/cua-local-vm";
|
|
19330
19475
|
IMAGE_LAYER_VERSION = "5";
|
|
19331
19476
|
IMAGE = `${IMAGE_REPOSITORY}:driver-${CUA_DRIVER_VERSION}-v${IMAGE_LAYER_VERSION}`;
|
|
19332
|
-
VM_WORKSPACE_DIR =
|
|
19477
|
+
VM_WORKSPACE_DIR = join12(DATA_DIR, "vm-home");
|
|
19333
19478
|
MEMORY_BYTES = 4 * 1024 * 1024 * 1024;
|
|
19334
19479
|
SHM_BYTES = 512 * 1024 * 1024;
|
|
19335
19480
|
containerMcpPath = SPAWNED_PROXIES.containerMcp;
|
|
@@ -19363,6 +19508,9 @@ ${close}`);
|
|
|
19363
19508
|
for (const re of KEY_PREFIXES) out = out.replace(re, (m) => mask(m));
|
|
19364
19509
|
out = out.replace(BEARER, (_m, lead, tok) => `${lead}${mask(tok)}`);
|
|
19365
19510
|
out = out.replace(KEY_VALUE, (_m, key, sep, quote, value) => `${key}${sep}${quote}${mask(value)}${quote}`);
|
|
19511
|
+
out = out.replace(KEY_SUFFIX_ASSIGNMENT, (_m, key, sep, quote, value) => `${key}${sep}${quote}${mask(value)}${quote}`);
|
|
19512
|
+
out = out.replace(SECRET_FLAG, (_m, flag, quote, value) => `${flag}${quote}${mask(value)}${quote}`);
|
|
19513
|
+
out = out.replace(URL_USERINFO, (_m, lead, secret, at) => `${lead}${mask(secret)}${at}`);
|
|
19366
19514
|
return out;
|
|
19367
19515
|
}
|
|
19368
19516
|
function redactSecrets(input, depth = 0) {
|
|
@@ -19387,7 +19535,7 @@ function redactSecrets(input, depth = 0) {
|
|
|
19387
19535
|
}
|
|
19388
19536
|
return out;
|
|
19389
19537
|
}
|
|
19390
|
-
var SECRET_KEY_PARTS, REDACTION_MARKER, mask, KEY_PREFIXES, BEARER, PEM_BLOCK, KEY_VALUE;
|
|
19538
|
+
var SECRET_KEY_PARTS, REDACTION_MARKER, mask, KEY_PREFIXES, BEARER, PEM_BLOCK, KEY_VALUE, KEY_SUFFIX_ASSIGNMENT, SECRET_FLAG, URL_USERINFO;
|
|
19391
19539
|
var init_redact = __esm({
|
|
19392
19540
|
"server/redact.ts"() {
|
|
19393
19541
|
"use strict";
|
|
@@ -19397,6 +19545,12 @@ var init_redact = __esm({
|
|
|
19397
19545
|
KEY_PREFIXES = [
|
|
19398
19546
|
/\bsk-(?:ant-|proj-|live-|test-)?[A-Za-z0-9_-]{16,}/g,
|
|
19399
19547
|
// anthropic / openai / stripe
|
|
19548
|
+
/\bxai-[A-Za-z0-9_-]{20,}/g,
|
|
19549
|
+
// xai (grok)
|
|
19550
|
+
/\bgsk_[A-Za-z0-9]{40,}/g,
|
|
19551
|
+
// groq
|
|
19552
|
+
/\bhf_[A-Za-z0-9]{30,}/g,
|
|
19553
|
+
// hugging face
|
|
19400
19554
|
/\b(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9]{20,}/g,
|
|
19401
19555
|
// github classic
|
|
19402
19556
|
/\bgithub_pat_[A-Za-z0-9_]{20,}/g,
|
|
@@ -19415,16 +19569,19 @@ var init_redact = __esm({
|
|
|
19415
19569
|
BEARER = /(\bBearer\s+)([A-Za-z0-9._~+/=-]{12,})/g;
|
|
19416
19570
|
PEM_BLOCK = /(-----BEGIN [A-Z ]*PRIVATE KEY-----)([\s\S]*?)(-----END [A-Z ]*PRIVATE KEY-----)/g;
|
|
19417
19571
|
KEY_VALUE = /\b((?:[A-Za-z0-9_-]*_)?(?:api[_-]?key|apikey|secret|token|password|passwd|authorization|auth[_-]?token|access[_-]?key|private[_-]?key)s?)(["']?\s*[=:]\s*)(["']?)([A-Za-z0-9._~+/=-]{8,})\3/gi;
|
|
19572
|
+
KEY_SUFFIX_ASSIGNMENT = /\b([A-Za-z][A-Za-z0-9_-]*[_-]key)s?(=)(["']?)([A-Za-z0-9._~+/=-]+)\3/gi;
|
|
19573
|
+
SECRET_FLAG = /(--(?:token|password|passwd|api-key|apikey|secret|access-key|auth-token)(?:=|\s+))(["']?)(?!-)([A-Za-z0-9._~+/=-]+)\2/gi;
|
|
19574
|
+
URL_USERINFO = /(\b[a-z][a-z0-9+.-]*:\/\/[^\s/:@'"]+:)([^\s/@'"«»]+)(@)/gi;
|
|
19418
19575
|
}
|
|
19419
19576
|
});
|
|
19420
19577
|
|
|
19421
19578
|
// server/drivers/native.ts
|
|
19422
19579
|
import { appendFileSync } from "node:fs";
|
|
19423
|
-
import { join as
|
|
19580
|
+
import { join as join13 } from "node:path";
|
|
19424
19581
|
function appendNative(threadId, entry) {
|
|
19425
19582
|
try {
|
|
19426
19583
|
appendFileSync(
|
|
19427
|
-
|
|
19584
|
+
join13(NATIVE_DIR, `${threadId}.ndjson`),
|
|
19428
19585
|
JSON.stringify({ at: (/* @__PURE__ */ new Date()).toISOString(), ...entry, msg: redactSecrets(entry.msg) }) + "\n",
|
|
19429
19586
|
{ mode: 384 }
|
|
19430
19587
|
);
|
|
@@ -19439,6 +19596,36 @@ var init_native = __esm({
|
|
|
19439
19596
|
}
|
|
19440
19597
|
});
|
|
19441
19598
|
|
|
19599
|
+
// server/tool-summary.ts
|
|
19600
|
+
function fieldsOf(input) {
|
|
19601
|
+
if (input === null || typeof input !== "object" || Array.isArray(input)) return void 0;
|
|
19602
|
+
return input;
|
|
19603
|
+
}
|
|
19604
|
+
function commandSummary(input) {
|
|
19605
|
+
const command = fieldsOf(input)?.command;
|
|
19606
|
+
if (typeof command !== "string") return void 0;
|
|
19607
|
+
return cut(command.replace(/\s*[\r\n]+\s*/g, " "), LIMIT);
|
|
19608
|
+
}
|
|
19609
|
+
function askInputSummary(input) {
|
|
19610
|
+
const fields = fieldsOf(input);
|
|
19611
|
+
if (!fields) return void 0;
|
|
19612
|
+
if (typeof fields.question === "string") return cut(fields.question, QUESTION_LIMIT);
|
|
19613
|
+
if (typeof fields.command === "string") return cut(fields.command, LIMIT);
|
|
19614
|
+
if (typeof fields.url === "string") return cut(fields.url, LIMIT);
|
|
19615
|
+
const text2 = JSON.stringify(fields);
|
|
19616
|
+
return text2 === "{}" ? void 0 : cut(text2, LIMIT);
|
|
19617
|
+
}
|
|
19618
|
+
var QUESTION_LIMIT, LIMIT, cut;
|
|
19619
|
+
var init_tool_summary = __esm({
|
|
19620
|
+
"server/tool-summary.ts"() {
|
|
19621
|
+
"use strict";
|
|
19622
|
+
init_redact();
|
|
19623
|
+
QUESTION_LIMIT = 300;
|
|
19624
|
+
LIMIT = 200;
|
|
19625
|
+
cut = (text2, limit) => redactSecretsInText(text2).trim().slice(0, limit);
|
|
19626
|
+
}
|
|
19627
|
+
});
|
|
19628
|
+
|
|
19442
19629
|
// server/drivers/acp/core.ts
|
|
19443
19630
|
import { homedir as homedir7 } from "node:os";
|
|
19444
19631
|
import { lstat, mkdir, readFile, realpath, stat, writeFile } from "node:fs/promises";
|
|
@@ -19883,7 +20070,8 @@ function createAcpDriver(support11) {
|
|
|
19883
20070
|
type: "item.started",
|
|
19884
20071
|
itemType: "tool",
|
|
19885
20072
|
itemId: u4.toolCallId,
|
|
19886
|
-
title: String(u4.rawInput?.command ?? u4.title ?? "tool").slice(0, 80)
|
|
20073
|
+
title: String(u4.rawInput?.command ?? u4.title ?? "tool").slice(0, 80),
|
|
20074
|
+
summary: commandSummary(u4.rawInput)
|
|
19887
20075
|
});
|
|
19888
20076
|
break;
|
|
19889
20077
|
}
|
|
@@ -20193,6 +20381,7 @@ var init_core3 = __esm({
|
|
|
20193
20381
|
init_env_path();
|
|
20194
20382
|
init_approval_mode();
|
|
20195
20383
|
init_native();
|
|
20384
|
+
init_tool_summary();
|
|
20196
20385
|
init_proxy_paths();
|
|
20197
20386
|
COMPUTER_PROXY_PATH = SPAWNED_PROXIES.computer;
|
|
20198
20387
|
envOr = (key, fallback) => Number(process.env[key] ?? fallback);
|
|
@@ -20210,7 +20399,7 @@ import { createHash as createHash3, randomUUID as randomUUID6 } from "node:crypt
|
|
|
20210
20399
|
import { mkdir as mkdir2, mkdtemp, readFile as readFile2, rm, stat as stat2 } from "node:fs/promises";
|
|
20211
20400
|
import { request as httpRequest } from "node:http";
|
|
20212
20401
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
20213
|
-
import { delimiter as delimiter4, join as
|
|
20402
|
+
import { delimiter as delimiter4, join as join14, resolve as resolve5 } from "node:path";
|
|
20214
20403
|
function quoteBrowserArgument(value) {
|
|
20215
20404
|
return `'${value.replaceAll("'", `'"'"'`)}'`;
|
|
20216
20405
|
}
|
|
@@ -20245,11 +20434,11 @@ function authorizationUrlFromLine(line) {
|
|
|
20245
20434
|
}
|
|
20246
20435
|
}
|
|
20247
20436
|
function antigravityProfileDirectory(instanceId, baseDir = DATA_DIR) {
|
|
20248
|
-
return
|
|
20437
|
+
return join14(baseDir, "providers", "antigravity", createHash3("sha256").update(instanceId).digest("hex"));
|
|
20249
20438
|
}
|
|
20250
20439
|
async function prepareAntigravityProfile(input) {
|
|
20251
20440
|
const directory = resolve5(input.profileDirectory ?? antigravityProfileDirectory(input.instanceId, input.baseDir));
|
|
20252
|
-
const acpDirectory =
|
|
20441
|
+
const acpDirectory = join14(directory, "antigravity-acp");
|
|
20253
20442
|
await mkdir2(acpDirectory, { recursive: true, mode: 448 });
|
|
20254
20443
|
if (process.platform !== "win32") {
|
|
20255
20444
|
const { chmod: chmod2 } = await import("node:fs/promises");
|
|
@@ -20257,7 +20446,7 @@ async function prepareAntigravityProfile(input) {
|
|
|
20257
20446
|
await chmod2(acpDirectory, 448);
|
|
20258
20447
|
}
|
|
20259
20448
|
writeFileAtomic(
|
|
20260
|
-
|
|
20449
|
+
join14(acpDirectory, "settings.json"),
|
|
20261
20450
|
`${JSON.stringify({ auth: { type: "oauth-personal" } })}
|
|
20262
20451
|
`,
|
|
20263
20452
|
{ mode: 384 }
|
|
@@ -20280,7 +20469,7 @@ async function prepareAntigravityProfile(input) {
|
|
|
20280
20469
|
PYTHONUNBUFFERED: "1",
|
|
20281
20470
|
ELECTRON_RUN_AS_NODE: "1"
|
|
20282
20471
|
});
|
|
20283
|
-
return { directory, tokenPath:
|
|
20472
|
+
return { directory, tokenPath: join14(acpDirectory, "acp_token.json"), environment };
|
|
20284
20473
|
}
|
|
20285
20474
|
async function antigravityProfileAuthenticated(profile) {
|
|
20286
20475
|
try {
|
|
@@ -20409,7 +20598,7 @@ function isValidAntigravityInitializeResult(initialized, expectedVersion) {
|
|
|
20409
20598
|
return true;
|
|
20410
20599
|
}
|
|
20411
20600
|
async function validateAntigravityRuntime(runtime, expectedVersion) {
|
|
20412
|
-
const profileDirectory = await mkdtemp(
|
|
20601
|
+
const profileDirectory = await mkdtemp(join14(tmpdir2(), "openmaus-antigravity-verify-"));
|
|
20413
20602
|
let client;
|
|
20414
20603
|
let failed = false;
|
|
20415
20604
|
let failure;
|
|
@@ -20798,7 +20987,7 @@ import {
|
|
|
20798
20987
|
writeFile as writeFile2
|
|
20799
20988
|
} from "node:fs/promises";
|
|
20800
20989
|
import { constants } from "node:fs";
|
|
20801
|
-
import { delimiter as delimiter5, dirname as dirname6, isAbsolute as isAbsolute2, join as
|
|
20990
|
+
import { delimiter as delimiter5, dirname as dirname6, isAbsolute as isAbsolute2, join as join15, resolve as resolve6 } from "node:path";
|
|
20802
20991
|
import { Transform } from "node:stream";
|
|
20803
20992
|
import { pipeline } from "node:stream/promises";
|
|
20804
20993
|
import { createInflateRaw } from "node:zlib";
|
|
@@ -20819,7 +21008,7 @@ async function retryOnWindowsFileLock(step, options = {}) {
|
|
|
20819
21008
|
}
|
|
20820
21009
|
}
|
|
20821
21010
|
function runtimeRoot(baseDir = DATA_DIR) {
|
|
20822
|
-
return
|
|
21011
|
+
return join15(baseDir, "tools", "antigravity-acp", `${process.platform}-${process.arch}`);
|
|
20823
21012
|
}
|
|
20824
21013
|
function executableNames(platform = process.platform) {
|
|
20825
21014
|
return platform === "win32" ? { executable: "agy_acp_server.exe", harness: "localharness_external.exe" } : { executable: "agy_acp_server.par", harness: "localharness_external" };
|
|
@@ -20836,10 +21025,10 @@ async function executableFile(path3, bytes) {
|
|
|
20836
21025
|
}
|
|
20837
21026
|
async function completedRelease(directory, asset) {
|
|
20838
21027
|
try {
|
|
20839
|
-
const record3 = JSON.parse(await readFile3(
|
|
21028
|
+
const record3 = JSON.parse(await readFile3(join15(directory, INSTALL_RECORD), "utf8"));
|
|
20840
21029
|
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;
|
|
20841
|
-
const executablePath =
|
|
20842
|
-
const harnessPath =
|
|
21030
|
+
const executablePath = join15(directory, asset.executable.name);
|
|
21031
|
+
const harnessPath = join15(directory, asset.harness.name);
|
|
20843
21032
|
if (!await executableFile(executablePath, asset.executable.bytes)) return null;
|
|
20844
21033
|
if (!await executableFile(harnessPath, asset.harness.bytes)) return null;
|
|
20845
21034
|
return { executablePath, harnessPath, source: "managed", version: asset.version };
|
|
@@ -20855,7 +21044,7 @@ function pathCandidates(binary2, env) {
|
|
|
20855
21044
|
async function externalRuntime(candidate, source) {
|
|
20856
21045
|
const names = executableNames();
|
|
20857
21046
|
const executablePath = resolve6(candidate);
|
|
20858
|
-
const harnessPath =
|
|
21047
|
+
const harnessPath = join15(dirname6(executablePath), names.harness);
|
|
20859
21048
|
if (!await executableFile(executablePath) || !await executableFile(harnessPath)) return null;
|
|
20860
21049
|
return { executablePath, harnessPath, source, version: null };
|
|
20861
21050
|
}
|
|
@@ -20875,7 +21064,7 @@ async function resolveAntigravityRuntime(binaryPath, env = process.env, baseDir
|
|
|
20875
21064
|
}
|
|
20876
21065
|
const asset = resolveAntigravityReleaseAsset();
|
|
20877
21066
|
if (asset) {
|
|
20878
|
-
const managed = await completedRelease(
|
|
21067
|
+
const managed = await completedRelease(join15(runtimeRoot(baseDir), "versions", asset.sha256), asset);
|
|
20879
21068
|
if (managed) return managed;
|
|
20880
21069
|
}
|
|
20881
21070
|
const names = executableNames();
|
|
@@ -20895,25 +21084,25 @@ async function pinnedZipEntries(path3) {
|
|
|
20895
21084
|
try {
|
|
20896
21085
|
const info = await handle.stat();
|
|
20897
21086
|
const tailBytes = Math.min(info.size, MAX_EOCD_BYTES);
|
|
20898
|
-
const
|
|
21087
|
+
const tail2 = Buffer.alloc(tailBytes);
|
|
20899
21088
|
const tailOffset = info.size - tailBytes;
|
|
20900
|
-
if ((await handle.read(
|
|
21089
|
+
if ((await handle.read(tail2, 0, tailBytes, tailOffset)).bytesRead !== tailBytes) {
|
|
20901
21090
|
throw new Error("The verified archive was truncated.");
|
|
20902
21091
|
}
|
|
20903
21092
|
let eocd = -1;
|
|
20904
|
-
for (let cursor4 =
|
|
20905
|
-
if (
|
|
21093
|
+
for (let cursor4 = tail2.length - 22; cursor4 >= 0; cursor4 -= 1) {
|
|
21094
|
+
if (tail2.readUInt32LE(cursor4) === EOCD_SIGNATURE && cursor4 + 22 + tail2.readUInt16LE(cursor4 + 20) === tail2.length) {
|
|
20906
21095
|
eocd = cursor4;
|
|
20907
21096
|
break;
|
|
20908
21097
|
}
|
|
20909
21098
|
}
|
|
20910
21099
|
if (eocd < 0) throw new Error("The verified archive has no valid ZIP directory.");
|
|
20911
|
-
const disk =
|
|
20912
|
-
const directoryDisk =
|
|
20913
|
-
const diskEntries =
|
|
20914
|
-
const entryCount =
|
|
20915
|
-
const directoryBytes =
|
|
20916
|
-
const directoryOffset =
|
|
21100
|
+
const disk = tail2.readUInt16LE(eocd + 4);
|
|
21101
|
+
const directoryDisk = tail2.readUInt16LE(eocd + 6);
|
|
21102
|
+
const diskEntries = tail2.readUInt16LE(eocd + 8);
|
|
21103
|
+
const entryCount = tail2.readUInt16LE(eocd + 10);
|
|
21104
|
+
const directoryBytes = tail2.readUInt32LE(eocd + 12);
|
|
21105
|
+
const directoryOffset = tail2.readUInt32LE(eocd + 16);
|
|
20917
21106
|
const eocdOffset = tailOffset + eocd;
|
|
20918
21107
|
if (disk !== 0 || directoryDisk !== 0 || diskEntries !== entryCount || entryCount !== 2 || directoryBytes === 4294967295 || directoryOffset === 4294967295 || directoryOffset + directoryBytes > eocdOffset) throw new Error("The verified archive uses an unsupported ZIP layout.");
|
|
20919
21108
|
const directory = Buffer.alloc(directoryBytes);
|
|
@@ -20997,19 +21186,19 @@ async function extractPinnedArchive(archivePath, outputDirectory, asset) {
|
|
|
20997
21186
|
start: dataOffset,
|
|
20998
21187
|
end: dataOffset + entry.compressedBytes - 1
|
|
20999
21188
|
});
|
|
21000
|
-
const destination = createWriteStream(
|
|
21189
|
+
const destination = createWriteStream(join15(outputDirectory, entry.name), { flags: "wx", mode: 448 });
|
|
21001
21190
|
if (entry.compression === 8) await pipeline(source, createInflateRaw(), counter, destination);
|
|
21002
21191
|
else await pipeline(source, counter, destination);
|
|
21003
21192
|
if (bytes !== expectedBytes) throw new Error("An extracted file was truncated.");
|
|
21004
21193
|
}
|
|
21005
21194
|
if (seen.size !== 2) throw new Error("The archive is missing an expected file.");
|
|
21006
21195
|
}
|
|
21007
|
-
async function
|
|
21196
|
+
async function installOnce2(options) {
|
|
21008
21197
|
const asset = options.asset === void 0 ? resolveAntigravityReleaseAsset() : options.asset;
|
|
21009
21198
|
if (!asset) throw new Error(`Google does not publish an Antigravity runtime for ${process.platform}-${process.arch}.`);
|
|
21010
21199
|
const root = runtimeRoot(options.baseDir);
|
|
21011
|
-
const versions =
|
|
21012
|
-
const destination =
|
|
21200
|
+
const versions = join15(root, "versions");
|
|
21201
|
+
const destination = join15(versions, asset.sha256);
|
|
21013
21202
|
await mkdir3(versions, { recursive: true, mode: 448 });
|
|
21014
21203
|
const existing = await completedRelease(destination, asset);
|
|
21015
21204
|
if (existing) {
|
|
@@ -21025,11 +21214,11 @@ async function installOnce(options) {
|
|
|
21025
21214
|
} catch (error51) {
|
|
21026
21215
|
if (error51 instanceof Error && error51.message.includes("Antigravity needs")) throw error51;
|
|
21027
21216
|
}
|
|
21028
|
-
const staging = await mkdtemp2(
|
|
21217
|
+
const staging = await mkdtemp2(join15(versions, `${STAGING_PREFIX}${randomUUID7()}-`));
|
|
21029
21218
|
let failed = false;
|
|
21030
21219
|
try {
|
|
21031
|
-
const archivePath =
|
|
21032
|
-
const runtimeDirectory =
|
|
21220
|
+
const archivePath = join15(staging, "download.zip");
|
|
21221
|
+
const runtimeDirectory = join15(staging, "runtime");
|
|
21033
21222
|
await mkdir3(runtimeDirectory, { mode: 448 });
|
|
21034
21223
|
const controller = new AbortController();
|
|
21035
21224
|
const timeout = setTimeout(() => controller.abort(), DOWNLOAD_TIMEOUT_MS2);
|
|
@@ -21075,12 +21264,12 @@ async function installOnce(options) {
|
|
|
21075
21264
|
}
|
|
21076
21265
|
await extractPinnedArchive(archivePath, runtimeDirectory, asset);
|
|
21077
21266
|
if (process.platform !== "win32") {
|
|
21078
|
-
await chmod(
|
|
21079
|
-
await chmod(
|
|
21267
|
+
await chmod(join15(runtimeDirectory, asset.executable.name), 493);
|
|
21268
|
+
await chmod(join15(runtimeDirectory, asset.harness.name), 493);
|
|
21080
21269
|
}
|
|
21081
21270
|
const candidate = {
|
|
21082
|
-
executablePath:
|
|
21083
|
-
harnessPath:
|
|
21271
|
+
executablePath: join15(runtimeDirectory, asset.executable.name),
|
|
21272
|
+
harnessPath: join15(runtimeDirectory, asset.harness.name),
|
|
21084
21273
|
source: "managed",
|
|
21085
21274
|
version: asset.version
|
|
21086
21275
|
};
|
|
@@ -21091,7 +21280,7 @@ async function installOnce(options) {
|
|
|
21091
21280
|
executable: asset.executable,
|
|
21092
21281
|
harness: asset.harness
|
|
21093
21282
|
};
|
|
21094
|
-
await writeFile2(
|
|
21283
|
+
await writeFile2(join15(runtimeDirectory, INSTALL_RECORD), `${JSON.stringify(record3)}
|
|
21095
21284
|
`, { flag: "wx", mode: 384 });
|
|
21096
21285
|
try {
|
|
21097
21286
|
await retryOnWindowsFileLock(() => rename(runtimeDirectory, destination));
|
|
@@ -21118,9 +21307,9 @@ function installAntigravityRuntime(options = {}) {
|
|
|
21118
21307
|
const key = runtimeRoot(options.baseDir);
|
|
21119
21308
|
const existing = installs.get(key);
|
|
21120
21309
|
if (existing) return existing;
|
|
21121
|
-
const
|
|
21122
|
-
installs.set(key,
|
|
21123
|
-
return
|
|
21310
|
+
const running2 = installOnce2(options).finally(() => installs.delete(key));
|
|
21311
|
+
installs.set(key, running2);
|
|
21312
|
+
return running2;
|
|
21124
21313
|
}
|
|
21125
21314
|
function antigravityManagedInstallAvailable() {
|
|
21126
21315
|
return resolveAntigravityReleaseAsset() !== null;
|
|
@@ -21337,7 +21526,7 @@ var init_boxagent = __esm({
|
|
|
21337
21526
|
const listeners = /* @__PURE__ */ new Set();
|
|
21338
21527
|
const active = /* @__PURE__ */ new Map();
|
|
21339
21528
|
const emit = (event) => {
|
|
21340
|
-
for (const l of
|
|
21529
|
+
for (const l of Array.from(listeners)) l(event);
|
|
21341
21530
|
};
|
|
21342
21531
|
const base2 = (threadId, turnId) => ({
|
|
21343
21532
|
eventId: newEventId(),
|
|
@@ -21527,18 +21716,39 @@ var init_boxagent = __esm({
|
|
|
21527
21716
|
}
|
|
21528
21717
|
});
|
|
21529
21718
|
|
|
21719
|
+
// server/resume-recovery.ts
|
|
21720
|
+
function classifyResumeFailure(state) {
|
|
21721
|
+
if (state.producedOutput || state.promptSubmitted) return "after-accept";
|
|
21722
|
+
if (state.attempted && state.rejected) return "before-accept";
|
|
21723
|
+
return "unknown";
|
|
21724
|
+
}
|
|
21725
|
+
function mayReplay(failure) {
|
|
21726
|
+
return failure === "before-accept";
|
|
21727
|
+
}
|
|
21728
|
+
function recoveryPromptFor(input) {
|
|
21729
|
+
if (!mayReplay(input.failure)) return { text: input.currentText, replayed: false };
|
|
21730
|
+
const replay = input.recoveryText?.trim();
|
|
21731
|
+
if (!replay || replay === input.currentText.trim()) return { text: input.currentText, replayed: false };
|
|
21732
|
+
return { text: replay, replayed: true };
|
|
21733
|
+
}
|
|
21734
|
+
var init_resume_recovery = __esm({
|
|
21735
|
+
"server/resume-recovery.ts"() {
|
|
21736
|
+
"use strict";
|
|
21737
|
+
}
|
|
21738
|
+
});
|
|
21739
|
+
|
|
21530
21740
|
// server/drivers/claude-login-auth.ts
|
|
21531
21741
|
import { randomUUID as randomUUID8 } from "node:crypto";
|
|
21532
21742
|
import { realpathSync } from "node:fs";
|
|
21533
21743
|
import { homedir as homedir8 } from "node:os";
|
|
21534
|
-
import { basename as basename4, dirname as dirname7, isAbsolute as isAbsolute3, join as
|
|
21535
|
-
import { stripVTControlCharacters as
|
|
21744
|
+
import { basename as basename4, dirname as dirname7, isAbsolute as isAbsolute3, join as join16, resolve as resolve7 } from "node:path";
|
|
21745
|
+
import { stripVTControlCharacters as stripVTControlCharacters4 } from "node:util";
|
|
21536
21746
|
function canonicalPath(path3) {
|
|
21537
21747
|
try {
|
|
21538
21748
|
return realpathSync(path3);
|
|
21539
21749
|
} catch {
|
|
21540
21750
|
const parent = dirname7(path3);
|
|
21541
|
-
return parent === path3 ? path3 :
|
|
21751
|
+
return parent === path3 ? path3 : join16(canonicalPath(parent), basename4(path3));
|
|
21542
21752
|
}
|
|
21543
21753
|
}
|
|
21544
21754
|
function claudeSignInLink(value) {
|
|
@@ -21553,7 +21763,7 @@ function claudeSignInLink(value) {
|
|
|
21553
21763
|
}
|
|
21554
21764
|
}
|
|
21555
21765
|
function claudeLoginPrompt(output) {
|
|
21556
|
-
const lines =
|
|
21766
|
+
const lines = stripVTControlCharacters4(output).split(/\r?\n/).slice(0, -1);
|
|
21557
21767
|
for (const line of lines) {
|
|
21558
21768
|
const match = /(https:\/\/\S+)/.exec(line.trim());
|
|
21559
21769
|
const link = match ? claudeSignInLink(match[1].replace(/[),.;]+$/, "")) : null;
|
|
@@ -21565,17 +21775,18 @@ function claudeLoginCode(value) {
|
|
|
21565
21775
|
const code = value.trim();
|
|
21566
21776
|
return /^[A-Za-z0-9_\-#.:]{8,1024}$/.test(code) ? code : null;
|
|
21567
21777
|
}
|
|
21568
|
-
var
|
|
21778
|
+
var MAX_OUTPUT2, SIGN_IN_HOSTS, authenticatingHomes, NOT_AVAILABLE, ClaudeLoginController;
|
|
21569
21779
|
var init_claude_login_auth = __esm({
|
|
21570
21780
|
"server/drivers/claude-login-auth.ts"() {
|
|
21571
21781
|
"use strict";
|
|
21572
21782
|
init_procs();
|
|
21573
|
-
|
|
21783
|
+
MAX_OUTPUT2 = 32768;
|
|
21574
21784
|
SIGN_IN_HOSTS = ["claude.com", "claude.ai", "console.anthropic.com", "platform.claude.com"];
|
|
21575
21785
|
authenticatingHomes = /* @__PURE__ */ new Set();
|
|
21576
21786
|
NOT_AVAILABLE = "This sign-in is no longer available. Start sign-in again.";
|
|
21577
21787
|
ClaudeLoginController = class {
|
|
21578
21788
|
flow = null;
|
|
21789
|
+
logoutChild = null;
|
|
21579
21790
|
disposed = false;
|
|
21580
21791
|
options;
|
|
21581
21792
|
constructor(options) {
|
|
@@ -21594,7 +21805,7 @@ var init_claude_login_auth = __esm({
|
|
|
21594
21805
|
if (!isAbsolute3(home) || env.CLAUDE_CONFIG_DIR && !isAbsolute3(env.CLAUDE_CONFIG_DIR)) {
|
|
21595
21806
|
throw new Error("Use an absolute HOME and CLAUDE_CONFIG_DIR path for this server's Claude provider before signing in.");
|
|
21596
21807
|
}
|
|
21597
|
-
const homeKey = canonicalPath(resolve7(env.CLAUDE_CONFIG_DIR ||
|
|
21808
|
+
const homeKey = canonicalPath(resolve7(env.CLAUDE_CONFIG_DIR || join16(home, ".claude")));
|
|
21598
21809
|
if (authenticatingHomes.has(homeKey)) {
|
|
21599
21810
|
throw new Error("A Claude sign-in is already running for this server account. Finish or cancel it before starting another.");
|
|
21600
21811
|
}
|
|
@@ -21667,43 +21878,121 @@ var init_claude_login_auth = __esm({
|
|
|
21667
21878
|
if (this.flow?.status.phase === "waiting") this.finish(this.flow, "cancelled", "Claude sign-in cancelled.");
|
|
21668
21879
|
await this.flow?.stopping;
|
|
21669
21880
|
if (this.flow?.terminationFailed) throw new Error(this.flow.status.message);
|
|
21881
|
+
if (this.logoutChild && !await this.stopChild(this.logoutChild)) {
|
|
21882
|
+
throw new Error("Claude Code could not be stopped on this server. Ask the server administrator to stop the account command before trying again.");
|
|
21883
|
+
}
|
|
21670
21884
|
}
|
|
21671
21885
|
async dispose() {
|
|
21672
21886
|
this.disposed = true;
|
|
21673
21887
|
await this.cancel();
|
|
21674
21888
|
this.flow = null;
|
|
21675
21889
|
}
|
|
21890
|
+
/** Remove the sign-in Claude Code stores for this server account (its
|
|
21891
|
+
* configuration directory) so a different subscription can sign in. A
|
|
21892
|
+
* sign-in in progress is never pulled away underneath the browser
|
|
21893
|
+
* completing it, and the CLI's own status is the verdict, as for sign-in. */
|
|
21894
|
+
async signOut() {
|
|
21895
|
+
if (this.disposed) throw new Error("This provider was removed. Refresh Settings before signing out.");
|
|
21896
|
+
if (this.flow?.status.phase === "waiting") throw new Error("Finish or cancel the Claude sign-in in progress before signing out.");
|
|
21897
|
+
await this.flow?.stopping;
|
|
21898
|
+
if (this.disposed) throw new Error("This provider was removed. Refresh Settings before signing out.");
|
|
21899
|
+
const env = this.options.environment();
|
|
21900
|
+
const home = env.HOME || env.USERPROFILE || homedir8();
|
|
21901
|
+
if (!isAbsolute3(home) || env.CLAUDE_CONFIG_DIR && !isAbsolute3(env.CLAUDE_CONFIG_DIR)) {
|
|
21902
|
+
throw new Error("Use an absolute HOME and CLAUDE_CONFIG_DIR path for this server's Claude provider before signing out.");
|
|
21903
|
+
}
|
|
21904
|
+
const homeKey = canonicalPath(resolve7(env.CLAUDE_CONFIG_DIR || join16(home, ".claude")));
|
|
21905
|
+
if (authenticatingHomes.has(homeKey)) {
|
|
21906
|
+
throw new Error("A Claude sign-in is running for this server account. Finish or cancel it before signing out.");
|
|
21907
|
+
}
|
|
21908
|
+
authenticatingHomes.add(homeKey);
|
|
21909
|
+
try {
|
|
21910
|
+
await this.logout(env);
|
|
21911
|
+
if (this.disposed) throw new Error("This provider was removed. Refresh Settings before signing out.");
|
|
21912
|
+
const status = await this.authStatus(env);
|
|
21913
|
+
if (status === "in") throw new Error("Claude Code still reports a sign-in on this server. Update Claude Code and check its auth status before trying again.");
|
|
21914
|
+
if (status === "unknown") throw new Error("Claude Code could not confirm the sign-out on this server. Update Claude Code and check its auth status before trying again.");
|
|
21915
|
+
} finally {
|
|
21916
|
+
const child = this.logoutChild;
|
|
21917
|
+
if (child && child.exitCode === null && child.signalCode === null) {
|
|
21918
|
+
child.once("close", () => authenticatingHomes.delete(homeKey));
|
|
21919
|
+
} else authenticatingHomes.delete(homeKey);
|
|
21920
|
+
}
|
|
21921
|
+
}
|
|
21922
|
+
/** `claude auth logout`, bounded and non-interactive. Its output stays
|
|
21923
|
+
* here; the status command afterwards decides whether it worked. */
|
|
21924
|
+
logout(env) {
|
|
21925
|
+
return new Promise((resolveDone, rejectDone) => {
|
|
21926
|
+
if (this.disposed) {
|
|
21927
|
+
rejectDone(new Error("This provider was removed. Refresh Settings before signing out."));
|
|
21928
|
+
return;
|
|
21929
|
+
}
|
|
21930
|
+
let child;
|
|
21931
|
+
try {
|
|
21932
|
+
child = spawnCli(this.options.cli, ["auth", "logout"], { env: { ...env, NO_COLOR: "1" }, stdio: ["pipe", "pipe", "pipe"] });
|
|
21933
|
+
} catch {
|
|
21934
|
+
rejectDone(new Error("Claude Code could not start on this server. Install or update the configured Claude CLI, then try again."));
|
|
21935
|
+
return;
|
|
21936
|
+
}
|
|
21937
|
+
this.logoutChild = child;
|
|
21938
|
+
child.stdin.end();
|
|
21939
|
+
child.stdout.on("data", () => {
|
|
21940
|
+
});
|
|
21941
|
+
child.stderr.on("data", () => {
|
|
21942
|
+
});
|
|
21943
|
+
const timer = setTimeout(() => {
|
|
21944
|
+
void this.stopChild(child).catch(() => false).then((stopped) => {
|
|
21945
|
+
if (!stopped) rejectDone(new Error("Claude Code could not be stopped on this server. Ask the server administrator to stop the account command before trying again."));
|
|
21946
|
+
});
|
|
21947
|
+
}, this.options.startupTimeoutMs ?? 3e4);
|
|
21948
|
+
timer.unref();
|
|
21949
|
+
child.once("error", (error51) => {
|
|
21950
|
+
clearTimeout(timer);
|
|
21951
|
+
rejectDone(new Error(error51.code === "ENOENT" ? "Claude Code is not installed on this server. Install it on the server, then try again." : "Claude Code could not start on this server. Check the configured CLI path and its executable permissions."));
|
|
21952
|
+
});
|
|
21953
|
+
child.once("close", () => {
|
|
21954
|
+
clearTimeout(timer);
|
|
21955
|
+
if (this.logoutChild === child) this.logoutChild = null;
|
|
21956
|
+
resolveDone();
|
|
21957
|
+
});
|
|
21958
|
+
});
|
|
21959
|
+
}
|
|
21676
21960
|
signedIn(env) {
|
|
21961
|
+
return this.authStatus(env).then((status) => status === "in");
|
|
21962
|
+
}
|
|
21963
|
+
/** `claude auth status --json`: signed in, signed out, or not answered. */
|
|
21964
|
+
authStatus(env) {
|
|
21677
21965
|
return new Promise((resolveStatus) => {
|
|
21678
21966
|
let child;
|
|
21679
21967
|
try {
|
|
21680
21968
|
child = spawnCli(this.options.cli, ["auth", "status", "--json"], { env: { ...env, NO_COLOR: "1" }, stdio: ["ignore", "pipe", "pipe"] });
|
|
21681
21969
|
} catch {
|
|
21682
|
-
resolveStatus(
|
|
21970
|
+
resolveStatus("unknown");
|
|
21683
21971
|
return;
|
|
21684
21972
|
}
|
|
21685
21973
|
let stdout2 = "";
|
|
21686
21974
|
child.stdout.on("data", (chunk) => {
|
|
21687
|
-
if (stdout2.length <
|
|
21975
|
+
if (stdout2.length < MAX_OUTPUT2) stdout2 += chunk.toString("utf8");
|
|
21688
21976
|
});
|
|
21689
21977
|
child.stderr.on("data", () => {
|
|
21690
21978
|
});
|
|
21691
21979
|
const timer = setTimeout(() => {
|
|
21692
21980
|
child.kill("SIGKILL");
|
|
21693
|
-
resolveStatus(
|
|
21981
|
+
resolveStatus("unknown");
|
|
21694
21982
|
}, 8e3);
|
|
21695
21983
|
timer.unref();
|
|
21696
21984
|
child.once("error", () => {
|
|
21697
21985
|
clearTimeout(timer);
|
|
21698
|
-
resolveStatus(
|
|
21986
|
+
resolveStatus("unknown");
|
|
21699
21987
|
});
|
|
21700
|
-
child.once("close", () => {
|
|
21988
|
+
child.once("close", (code) => {
|
|
21701
21989
|
clearTimeout(timer);
|
|
21702
21990
|
try {
|
|
21703
21991
|
const status = JSON.parse(stdout2);
|
|
21704
|
-
|
|
21992
|
+
const loggedIn = typeof status === "object" && status !== null ? Reflect.get(status, "loggedIn") : void 0;
|
|
21993
|
+
resolveStatus(code === 0 && loggedIn === true ? "in" : code === 1 && loggedIn === false ? "out" : "unknown");
|
|
21705
21994
|
} catch {
|
|
21706
|
-
resolveStatus(
|
|
21995
|
+
resolveStatus("unknown");
|
|
21707
21996
|
}
|
|
21708
21997
|
});
|
|
21709
21998
|
});
|
|
@@ -21724,7 +22013,7 @@ var init_claude_login_auth = __esm({
|
|
|
21724
22013
|
flow.child = child;
|
|
21725
22014
|
const receive = (chunk) => {
|
|
21726
22015
|
if (flow.status.phase !== "waiting") return;
|
|
21727
|
-
if (flow.output.length + chunk.length >
|
|
22016
|
+
if (flow.output.length + chunk.length > MAX_OUTPUT2) {
|
|
21728
22017
|
this.finish(flow, "failed", "Claude Code returned an unexpected sign-in response. Update the server's Claude CLI and try again.");
|
|
21729
22018
|
return;
|
|
21730
22019
|
}
|
|
@@ -21746,7 +22035,7 @@ var init_claude_login_auth = __esm({
|
|
|
21746
22035
|
child.once("close", (code) => {
|
|
21747
22036
|
if (flow.child === child) flow.child = null;
|
|
21748
22037
|
if (flow.status.phase !== "waiting") return;
|
|
21749
|
-
const output =
|
|
22038
|
+
const output = stripVTControlCharacters4(flow.output);
|
|
21750
22039
|
flow.output = "";
|
|
21751
22040
|
void this.signedIn(flow.env).then((signedIn) => {
|
|
21752
22041
|
if (flow.status.phase !== "waiting") return;
|
|
@@ -21779,7 +22068,7 @@ var init_claude_login_auth = __esm({
|
|
|
21779
22068
|
else flow.completion.reject(new Error(message2 ?? "Claude sign-in did not finish."));
|
|
21780
22069
|
flow.completion = void 0;
|
|
21781
22070
|
}
|
|
21782
|
-
flow.stopping = this.stopChild(flow).catch(() => false).then((stopped) => {
|
|
22071
|
+
flow.stopping = this.stopChild(flow.child).catch(() => false).then((stopped) => {
|
|
21783
22072
|
const release = () => authenticatingHomes.delete(flow.homeKey);
|
|
21784
22073
|
if (stopped) {
|
|
21785
22074
|
release();
|
|
@@ -21794,8 +22083,7 @@ var init_claude_login_auth = __esm({
|
|
|
21794
22083
|
if (phase === "succeeded") void this.options.onAuthenticated?.().catch(() => {
|
|
21795
22084
|
});
|
|
21796
22085
|
}
|
|
21797
|
-
async stopChild(
|
|
21798
|
-
const child = flow.child;
|
|
22086
|
+
async stopChild(child) {
|
|
21799
22087
|
if (!child || await killCliTree(child, this.options.terminateTimeoutMs ?? 1500)) return true;
|
|
21800
22088
|
if (process.platform !== "win32" && child.pid) {
|
|
21801
22089
|
try {
|
|
@@ -21819,6 +22107,53 @@ var init_claude_login_auth = __esm({
|
|
|
21819
22107
|
}
|
|
21820
22108
|
});
|
|
21821
22109
|
|
|
22110
|
+
// server/mcp-trim.ts
|
|
22111
|
+
var DEFAULT_RESULT_BUDGET;
|
|
22112
|
+
var init_mcp_trim = __esm({
|
|
22113
|
+
"server/mcp-trim.ts"() {
|
|
22114
|
+
"use strict";
|
|
22115
|
+
DEFAULT_RESULT_BUDGET = 8e3;
|
|
22116
|
+
}
|
|
22117
|
+
});
|
|
22118
|
+
|
|
22119
|
+
// server/mcp-gate-config.ts
|
|
22120
|
+
import { join as join17 } from "node:path";
|
|
22121
|
+
function resultBudget(env = process.env) {
|
|
22122
|
+
const raw = env.OMB_MCP_RESULT_BUDGET;
|
|
22123
|
+
if (raw === void 0 || raw === "") return DEFAULT_RESULT_BUDGET;
|
|
22124
|
+
const parsed = Number(raw);
|
|
22125
|
+
return Number.isFinite(parsed) && parsed >= 0 ? Math.floor(parsed) : DEFAULT_RESULT_BUDGET;
|
|
22126
|
+
}
|
|
22127
|
+
function spillDir(threadId) {
|
|
22128
|
+
return join17(DATA_DIR, "tool-results", threadId.replace(/[^A-Za-z0-9_-]/g, "-").slice(0, 80) || "thread");
|
|
22129
|
+
}
|
|
22130
|
+
function gateServer(input) {
|
|
22131
|
+
const { name, server, budget } = input;
|
|
22132
|
+
if (budget <= 0) return null;
|
|
22133
|
+
if (!server || typeof server !== "object" || Array.isArray(server)) return null;
|
|
22134
|
+
const spec = server;
|
|
22135
|
+
if (typeof spec.command !== "string" || !spec.command) return null;
|
|
22136
|
+
return {
|
|
22137
|
+
command: input.execPath ?? process.execPath,
|
|
22138
|
+
args: [SPAWNED_PROXIES.mcpGate],
|
|
22139
|
+
env: {
|
|
22140
|
+
...input.nodeEnv,
|
|
22141
|
+
OMB_GATE_NAME: name,
|
|
22142
|
+
OMB_GATE_UPSTREAM: JSON.stringify({ command: spec.command, args: spec.args ?? [], env: spec.env ?? {} }),
|
|
22143
|
+
OMB_GATE_SPILL_DIR: spillDir(input.threadId),
|
|
22144
|
+
OMB_GATE_BUDGET: String(budget)
|
|
22145
|
+
}
|
|
22146
|
+
};
|
|
22147
|
+
}
|
|
22148
|
+
var init_mcp_gate_config = __esm({
|
|
22149
|
+
"server/mcp-gate-config.ts"() {
|
|
22150
|
+
"use strict";
|
|
22151
|
+
init_config();
|
|
22152
|
+
init_mcp_trim();
|
|
22153
|
+
init_proxy_paths();
|
|
22154
|
+
}
|
|
22155
|
+
});
|
|
22156
|
+
|
|
21822
22157
|
// server/drivers/retry.ts
|
|
21823
22158
|
function classifyError(err) {
|
|
21824
22159
|
const text2 = messageOf(err);
|
|
@@ -21907,7 +22242,7 @@ import { createHash as createHash5, randomBytes as randomBytes2 } from "node:cry
|
|
|
21907
22242
|
import { chmodSync as chmodSync3, mkdtempSync as mkdtempSync2, readFileSync as readFileSync6, rmSync as rmSync2, unlinkSync as unlinkSync3, writeFileSync as writeFileSync5 } from "node:fs";
|
|
21908
22243
|
import { createServer as createNetServer } from "node:net";
|
|
21909
22244
|
import { homedir as homedir9, tmpdir as tmpdir3 } from "node:os";
|
|
21910
|
-
import { join as
|
|
22245
|
+
import { join as join18, dirname as dirname8, isAbsolute as isAbsolute4, normalize } from "node:path";
|
|
21911
22246
|
function claudeAuthStatus(cli, env, run3 = execCli) {
|
|
21912
22247
|
return new Promise((resolve13) => {
|
|
21913
22248
|
run3(cli, ["auth", "status", "--json"], { timeout: 8e3, maxBuffer: 65536, env }, (_error, stdout2) => {
|
|
@@ -21933,8 +22268,8 @@ function claudeAuthStatus(cli, env, run3 = execCli) {
|
|
|
21933
22268
|
}
|
|
21934
22269
|
function resolveClaudeConfigDir(configDir, env = process.env) {
|
|
21935
22270
|
const home = env.HOME || env.USERPROFILE || homedir9();
|
|
21936
|
-
const configured = configDir?.trim() || env.CLAUDE_CONFIG_DIR?.trim() ||
|
|
21937
|
-
const expanded = configured === "~" ? home : configured.startsWith("~/") ?
|
|
22271
|
+
const configured = configDir?.trim() || env.CLAUDE_CONFIG_DIR?.trim() || join18(home, ".claude");
|
|
22272
|
+
const expanded = configured === "~" ? home : configured.startsWith("~/") ? join18(home, configured.slice(2)) : configured;
|
|
21938
22273
|
if (!isAbsolute4(expanded) || /[\p{Cc}\p{Cf}]/u.test(expanded)) {
|
|
21939
22274
|
throw new Error("claude: configDir must be an absolute path or start with ~/");
|
|
21940
22275
|
}
|
|
@@ -21963,6 +22298,57 @@ function claudeEnvironment(model, source = process.env, configDir, instanceEnvir
|
|
|
21963
22298
|
if (!applied.injected) delete env.ANTHROPIC_API_KEY;
|
|
21964
22299
|
return env;
|
|
21965
22300
|
}
|
|
22301
|
+
function inheritsUserConfig(env) {
|
|
22302
|
+
return env.OMB_CLAUDE_INHERIT_USER_CONFIG === "1";
|
|
22303
|
+
}
|
|
22304
|
+
function projectMcpServers(cwd) {
|
|
22305
|
+
let parsed;
|
|
22306
|
+
try {
|
|
22307
|
+
parsed = JSON.parse(readFileSync6(join18(cwd, ".mcp.json"), "utf8"));
|
|
22308
|
+
} catch {
|
|
22309
|
+
return {};
|
|
22310
|
+
}
|
|
22311
|
+
const servers = parsed?.mcpServers;
|
|
22312
|
+
if (!servers || typeof servers !== "object" || Array.isArray(servers)) return {};
|
|
22313
|
+
const out = {};
|
|
22314
|
+
for (const [name, server] of Object.entries(servers)) {
|
|
22315
|
+
if (server && typeof server === "object" && !Array.isArray(server)) out[name] = server;
|
|
22316
|
+
}
|
|
22317
|
+
return out;
|
|
22318
|
+
}
|
|
22319
|
+
function autoCompactWindow(env) {
|
|
22320
|
+
const raw = (env.OMB_CLAUDE_AUTOCOMPACT ?? "").trim().toLowerCase();
|
|
22321
|
+
if (raw === "off") return null;
|
|
22322
|
+
if (raw === "auto") return "auto";
|
|
22323
|
+
const parsed = raw ? Number(raw) : DEFAULT_AUTOCOMPACT_TOKENS;
|
|
22324
|
+
if (!Number.isFinite(parsed) || parsed <= 0) return String(DEFAULT_AUTOCOMPACT_TOKENS);
|
|
22325
|
+
return String(Math.min(1e6, Math.max(1e5, Math.floor(parsed))));
|
|
22326
|
+
}
|
|
22327
|
+
function parseClaudeCliVersion(stdout2) {
|
|
22328
|
+
const match = /(\d+)\.(\d+)\.(\d+)/.exec(stdout2 ?? "");
|
|
22329
|
+
if (!match) return null;
|
|
22330
|
+
return [Number(match[1]), Number(match[2]), Number(match[3])];
|
|
22331
|
+
}
|
|
22332
|
+
function versionAtLeast(installed, floor) {
|
|
22333
|
+
for (let i2 = 0; i2 < 3; i2 += 1) {
|
|
22334
|
+
if (installed[i2] !== floor[i2]) return installed[i2] > floor[i2];
|
|
22335
|
+
}
|
|
22336
|
+
return true;
|
|
22337
|
+
}
|
|
22338
|
+
function claudeCliSupports(version2, flag) {
|
|
22339
|
+
return version2 === null || versionAtLeast(version2, CLAUDE_FLAG_FLOORS[flag]);
|
|
22340
|
+
}
|
|
22341
|
+
function claudeCliUpdate(version2, cli) {
|
|
22342
|
+
const parsed = parseClaudeCliVersion(version2);
|
|
22343
|
+
if (!parsed || versionAtLeast(parsed, CLAUDE_CONTEXT_CONTROL_MIN_VERSION)) return void 0;
|
|
22344
|
+
const floor = CLAUDE_CONTEXT_CONTROL_MIN_VERSION.join(".");
|
|
22345
|
+
const missing = Object.keys(CLAUDE_FLAG_FLOORS).filter((flag) => !claudeCliSupports(parsed, flag));
|
|
22346
|
+
return {
|
|
22347
|
+
title: "Update Claude Code for context controls",
|
|
22348
|
+
message: `Claude Code ${parsed.join(".")} predates ${floor}, so bots run without ${missing.join(", ")}: no compaction window picked by OpenMausBot` + (missing.includes("--setting-sources") ? ", and bots still see this machine's own Claude Code setup" : "") + ". Update it, then refresh Engines.",
|
|
22349
|
+
command: cli === "claude" ? "claude update" : `${cli} update`
|
|
22350
|
+
};
|
|
22351
|
+
}
|
|
21966
22352
|
async function resolveClaudeTurnModel(model, env) {
|
|
21967
22353
|
if (!model || decodeInjectId(model) || STATIC_CLAUDE_MODELS.options.some((option) => option.id === model)) {
|
|
21968
22354
|
return model;
|
|
@@ -21986,7 +22372,7 @@ function extrasFromUnknown(value) {
|
|
|
21986
22372
|
function readClaudeModelCatalog(env = process.env) {
|
|
21987
22373
|
let settings2 = {};
|
|
21988
22374
|
try {
|
|
21989
|
-
settings2 = JSON.parse(readFileSync6(
|
|
22375
|
+
settings2 = JSON.parse(readFileSync6(join18(resolveClaudeConfigDir(void 0, env), "settings.json"), "utf8"));
|
|
21990
22376
|
} catch {
|
|
21991
22377
|
return STATIC_CLAUDE_MODELS;
|
|
21992
22378
|
}
|
|
@@ -22020,12 +22406,7 @@ function systemEndedReply(kind) {
|
|
|
22020
22406
|
return kind === "question" ? { behavior: "answer", message: "OpenMausBot: the turn is ending \u2014 wrap up." } : { behavior: "deny", message: "OpenMausBot: the turn ended" };
|
|
22021
22407
|
}
|
|
22022
22408
|
function askSummary(ask) {
|
|
22023
|
-
|
|
22024
|
-
if (typeof input.question === "string") return input.question.slice(0, 300);
|
|
22025
|
-
if (typeof input.command === "string") return input.command.slice(0, 200);
|
|
22026
|
-
if (typeof input.url === "string") return input.url.slice(0, 200);
|
|
22027
|
-
const text2 = JSON.stringify(input);
|
|
22028
|
-
return text2 === "{}" ? ask.tool ?? "tool" : text2.slice(0, 200);
|
|
22409
|
+
return askInputSummary(ask.input) ?? ask.tool ?? "tool";
|
|
22029
22410
|
}
|
|
22030
22411
|
function permissionSocketPath(threadId) {
|
|
22031
22412
|
const prefix = threadId.replace(/[^\w-]/g, "").slice(0, 4);
|
|
@@ -22036,7 +22417,7 @@ function brokerSocketCandidates(threadId) {
|
|
|
22036
22417
|
const base2 = permissionSocketPath(threadId);
|
|
22037
22418
|
if (process.platform !== "win32") {
|
|
22038
22419
|
const scope = createHash5("sha256").update(`${DATA_DIR}\0${process.pid}\0${threadId}`).digest("hex").slice(0, 16);
|
|
22039
|
-
return [base2,
|
|
22420
|
+
return [base2, join18(tmpdir3(), `omb-perm-${scope}.sock`)];
|
|
22040
22421
|
}
|
|
22041
22422
|
return [
|
|
22042
22423
|
base2,
|
|
@@ -22159,7 +22540,7 @@ async function createPermissionBroker(opts) {
|
|
|
22159
22540
|
}
|
|
22160
22541
|
if (!server) throw new Error("claude: permission broker could not bind a local socket");
|
|
22161
22542
|
const drain = () => {
|
|
22162
|
-
for (const p of
|
|
22543
|
+
for (const p of Array.from(pending.values())) {
|
|
22163
22544
|
const { behavior, message: message2 } = systemEndedReply(p.ask.kind);
|
|
22164
22545
|
p.finish(behavior, message2, "system");
|
|
22165
22546
|
}
|
|
@@ -22234,6 +22615,17 @@ function firstText(content) {
|
|
|
22234
22615
|
}
|
|
22235
22616
|
return "";
|
|
22236
22617
|
}
|
|
22618
|
+
function withVolatileNote(text2, volatile) {
|
|
22619
|
+
const body = volatile.trim() ? `This part of your instructions changed since this session started. It replaces the earlier copy:
|
|
22620
|
+
|
|
22621
|
+
${volatile.trim()}` : "The notes that were in your instructions when this session started have been cleared.";
|
|
22622
|
+
const note = `<system-reminder>
|
|
22623
|
+
${body}
|
|
22624
|
+
</system-reminder>`;
|
|
22625
|
+
return text2 ? `${note}
|
|
22626
|
+
|
|
22627
|
+
${text2}` : note;
|
|
22628
|
+
}
|
|
22237
22629
|
function claudeUserMessage(text2, images) {
|
|
22238
22630
|
if (!images?.length) return { type: "user", message: { role: "user", content: text2 } };
|
|
22239
22631
|
const content = images.map((image) => ({
|
|
@@ -22265,16 +22657,19 @@ function diagnosticClaudeUserMessage(message2) {
|
|
|
22265
22657
|
}
|
|
22266
22658
|
};
|
|
22267
22659
|
}
|
|
22268
|
-
var CLAUDE_ACCOUNT_ENV_KEYS, DRIVER_KIND2, STATIC_CLAUDE_MODELS, CLAUDE_MODEL_ID, PROXY_PATH, PERM_PROXY_PATH, DWEB_PROXY_PATH, NODE_ENV_FLAG, DENY_TIMEOUT_NOTE, QUESTION_TIMEOUT_NOTE, DUPLICATE_ASK_ID_NOTE, ClaudeDriver;
|
|
22660
|
+
var CLAUDE_ACCOUNT_ENV_KEYS, DEFAULT_AUTOCOMPACT_TOKENS, CLAUDE_FLAG_FLOORS, CLAUDE_CONTEXT_CONTROL_MIN_VERSION, DRIVER_KIND2, STATIC_CLAUDE_MODELS, CLAUDE_MODEL_ID, PROXY_PATH, PERM_PROXY_PATH, DWEB_PROXY_PATH, NODE_ENV_FLAG, DENY_TIMEOUT_NOTE, QUESTION_TIMEOUT_NOTE, DUPLICATE_ASK_ID_NOTE, ClaudeDriver;
|
|
22269
22661
|
var init_claude = __esm({
|
|
22270
22662
|
"server/drivers/claude.ts"() {
|
|
22271
22663
|
"use strict";
|
|
22272
22664
|
init_config();
|
|
22273
22665
|
init_env_path();
|
|
22274
22666
|
init_procs();
|
|
22667
|
+
init_resume_recovery();
|
|
22275
22668
|
init_claude_login_auth();
|
|
22276
22669
|
init_container_computer();
|
|
22670
|
+
init_mcp_gate_config();
|
|
22277
22671
|
init_contracts();
|
|
22672
|
+
init_tool_summary();
|
|
22278
22673
|
init_retry();
|
|
22279
22674
|
init_local_inject();
|
|
22280
22675
|
init_native();
|
|
@@ -22293,6 +22688,13 @@ var init_claude = __esm({
|
|
|
22293
22688
|
"CLAUDE_CODE_USE_VERTEX",
|
|
22294
22689
|
"CLAUDE_CODE_USE_FOUNDRY"
|
|
22295
22690
|
];
|
|
22691
|
+
DEFAULT_AUTOCOMPACT_TOKENS = 2e5;
|
|
22692
|
+
CLAUDE_FLAG_FLOORS = {
|
|
22693
|
+
"--strict-mcp-config": [1, 0, 60],
|
|
22694
|
+
"--setting-sources": [1, 0, 122],
|
|
22695
|
+
"--autocompact": [2, 1, 122]
|
|
22696
|
+
};
|
|
22697
|
+
CLAUDE_CONTEXT_CONTROL_MIN_VERSION = CLAUDE_FLAG_FLOORS["--autocompact"];
|
|
22296
22698
|
DRIVER_KIND2 = "claudeAgent";
|
|
22297
22699
|
STATIC_CLAUDE_MODELS = {
|
|
22298
22700
|
default: "claude-sonnet-5",
|
|
@@ -22343,6 +22745,7 @@ var init_claude = __esm({
|
|
|
22343
22745
|
}
|
|
22344
22746
|
};
|
|
22345
22747
|
await refreshModels();
|
|
22748
|
+
let cliVersion = null;
|
|
22346
22749
|
const listeners = /* @__PURE__ */ new Set();
|
|
22347
22750
|
const active = /* @__PURE__ */ new Map();
|
|
22348
22751
|
const sessions = /* @__PURE__ */ new Map();
|
|
@@ -22393,7 +22796,7 @@ var init_claude = __esm({
|
|
|
22393
22796
|
});
|
|
22394
22797
|
};
|
|
22395
22798
|
const emit = (event) => {
|
|
22396
|
-
for (const l of
|
|
22799
|
+
for (const l of Array.from(listeners)) l(event);
|
|
22397
22800
|
};
|
|
22398
22801
|
const base2 = (threadId, turnId) => ({
|
|
22399
22802
|
eventId: newEventId(),
|
|
@@ -22439,6 +22842,15 @@ var init_claude = __esm({
|
|
|
22439
22842
|
args.push("--disallowedTools", config2.disallowedTools.join(","));
|
|
22440
22843
|
}
|
|
22441
22844
|
const turnEnvironment = environment();
|
|
22845
|
+
const isolated = !inheritsUserConfig(turnEnvironment);
|
|
22846
|
+
if (isolated) {
|
|
22847
|
+
if (claudeCliSupports(cliVersion, "--strict-mcp-config")) args.push("--strict-mcp-config");
|
|
22848
|
+
if (claudeCliSupports(cliVersion, "--setting-sources")) args.push("--setting-sources", "project");
|
|
22849
|
+
}
|
|
22850
|
+
const compactWindow = autoCompactWindow(turnEnvironment);
|
|
22851
|
+
if (compactWindow && claudeCliSupports(cliVersion, "--autocompact")) {
|
|
22852
|
+
args.push("--autocompact", compactWindow);
|
|
22853
|
+
}
|
|
22442
22854
|
const turnModel = await resolveClaudeTurnModel(turn.model, turnEnvironment);
|
|
22443
22855
|
const injected = applyClaudeInject({ ...turnEnvironment }, turnModel);
|
|
22444
22856
|
if (injected.model) args.push("--model", injected.model);
|
|
@@ -22489,9 +22901,23 @@ var init_claude = __esm({
|
|
|
22489
22901
|
};
|
|
22490
22902
|
allowed.push("mcp__dweb");
|
|
22491
22903
|
}
|
|
22904
|
+
const botOwned = /* @__PURE__ */ new Set();
|
|
22492
22905
|
for (const [name, server] of Object.entries(turn.integrations?.custom ?? {})) {
|
|
22493
22906
|
if (name in mcpServers) continue;
|
|
22494
22907
|
mcpServers[name] = { ...server };
|
|
22908
|
+
botOwned.add(name);
|
|
22909
|
+
}
|
|
22910
|
+
if (isolated && turn.cwd) {
|
|
22911
|
+
for (const [name, server] of Object.entries(projectMcpServers(turn.cwd))) {
|
|
22912
|
+
if (name in mcpServers) continue;
|
|
22913
|
+
mcpServers[name] = server;
|
|
22914
|
+
botOwned.add(name);
|
|
22915
|
+
}
|
|
22916
|
+
}
|
|
22917
|
+
const budget = resultBudget(turnEnvironment);
|
|
22918
|
+
for (const name of botOwned) {
|
|
22919
|
+
const gated = gateServer({ name, server: mcpServers[name], threadId, budget, nodeEnv: NODE_ENV_FLAG });
|
|
22920
|
+
if (gated) mcpServers[name] = gated;
|
|
22495
22921
|
}
|
|
22496
22922
|
let broker;
|
|
22497
22923
|
const socketPath = permissionSocketPath(threadId);
|
|
@@ -22502,7 +22928,7 @@ var init_claude = __esm({
|
|
|
22502
22928
|
allowed.push("mcp__ogb");
|
|
22503
22929
|
let mcpConfigPath = null;
|
|
22504
22930
|
if (Object.keys(mcpServers).length) {
|
|
22505
|
-
mcpConfigPath =
|
|
22931
|
+
mcpConfigPath = join18(mkdtempSync2(join18(tmpdir3(), "omb-mcp-")), "mcp.json");
|
|
22506
22932
|
args.push("--mcp-config", mcpConfigPath);
|
|
22507
22933
|
args.push("--allowedTools", allowed.join(","));
|
|
22508
22934
|
}
|
|
@@ -22513,7 +22939,9 @@ var init_claude = __esm({
|
|
|
22513
22939
|
const keyArgs = args.filter((a2, i2) => !privateFileFlags.has(a2) && !privateFileFlags.has(args[i2 - 1] ?? ""));
|
|
22514
22940
|
const argsKey = JSON.stringify({
|
|
22515
22941
|
args: keyArgs,
|
|
22516
|
-
|
|
22942
|
+
// the volatile half is deliberately absent: it must not respawn a
|
|
22943
|
+
// healthy session (see Session.volatile)
|
|
22944
|
+
system: turn.systemStable ?? turn.system ?? null,
|
|
22517
22945
|
mcpServers,
|
|
22518
22946
|
cwd,
|
|
22519
22947
|
model: injected.model ?? null,
|
|
@@ -22529,7 +22957,10 @@ var init_claude = __esm({
|
|
|
22529
22957
|
killCliTree(live.child);
|
|
22530
22958
|
}, turnId, broker: live.broker });
|
|
22531
22959
|
emit({ ...base2(threadId, turnId), type: "turn.started" });
|
|
22532
|
-
const
|
|
22960
|
+
const volatile = turn.systemVolatile ?? "";
|
|
22961
|
+
const message2 = volatile === live.volatile ? promptMsg : claudeUserMessage(withVolatileNote(turn.text, volatile), turn.images);
|
|
22962
|
+
live.volatile = volatile;
|
|
22963
|
+
const written = await writeUser(live, threadId, message2);
|
|
22533
22964
|
if (!written) {
|
|
22534
22965
|
active.delete(threadId);
|
|
22535
22966
|
live.turn = null;
|
|
@@ -22570,7 +23001,7 @@ var init_claude = __esm({
|
|
|
22570
23001
|
};
|
|
22571
23002
|
try {
|
|
22572
23003
|
if (turn.system) {
|
|
22573
|
-
systemPromptPath =
|
|
23004
|
+
systemPromptPath = join18(mkdtempSync2(join18(tmpdir3(), "omb-system-")), "prompt.txt");
|
|
22574
23005
|
writeFileSync5(systemPromptPath, turn.system, { mode: 384 });
|
|
22575
23006
|
args.push("--append-system-prompt-file", systemPromptPath);
|
|
22576
23007
|
}
|
|
@@ -22636,7 +23067,9 @@ var init_claude = __esm({
|
|
|
22636
23067
|
mcpConfigPath,
|
|
22637
23068
|
systemPromptPath,
|
|
22638
23069
|
argsKey,
|
|
23070
|
+
volatile: turn.systemVolatile ?? "",
|
|
22639
23071
|
sessionId: sessionId ?? newSessionId,
|
|
23072
|
+
sawInit: false,
|
|
22640
23073
|
turn: { turnId, settled: false, sawStreamDelta: false },
|
|
22641
23074
|
idleTimer: null,
|
|
22642
23075
|
closing: false,
|
|
@@ -22676,6 +23109,7 @@ var init_claude = __esm({
|
|
|
22676
23109
|
switch (o.type) {
|
|
22677
23110
|
case "system":
|
|
22678
23111
|
if (o.subtype === "init") {
|
|
23112
|
+
session.sawInit = true;
|
|
22679
23113
|
if (typeof o.session_id === "string") session.sessionId = o.session_id;
|
|
22680
23114
|
emit({ ...base2(threadId, currentTurnId()), type: "session.started", sessionId: o.session_id, model: o.model });
|
|
22681
23115
|
} else if (o.subtype === "thinking_tokens") {
|
|
@@ -22712,7 +23146,14 @@ var init_claude = __esm({
|
|
|
22712
23146
|
}
|
|
22713
23147
|
for (const b of Array.isArray(msg.content) ? msg.content : []) {
|
|
22714
23148
|
if (b.type === "tool_use") {
|
|
22715
|
-
emit({
|
|
23149
|
+
emit({
|
|
23150
|
+
...base2(threadId, currentTurnId()),
|
|
23151
|
+
type: "item.started",
|
|
23152
|
+
itemType: "tool",
|
|
23153
|
+
itemId: b.id,
|
|
23154
|
+
title: b.name,
|
|
23155
|
+
summary: commandSummary(b.input)
|
|
23156
|
+
});
|
|
22716
23157
|
}
|
|
22717
23158
|
}
|
|
22718
23159
|
if (msg.usage) {
|
|
@@ -22835,6 +23276,56 @@ var init_claude = __esm({
|
|
|
22835
23276
|
})();
|
|
22836
23277
|
return;
|
|
22837
23278
|
}
|
|
23279
|
+
const resumeFailure = classifyResumeFailure({
|
|
23280
|
+
attempted: Boolean(sessionId),
|
|
23281
|
+
rejected: !session.sawInit,
|
|
23282
|
+
promptSubmitted: session.sawInit,
|
|
23283
|
+
producedOutput: session.turn.sawStreamDelta
|
|
23284
|
+
});
|
|
23285
|
+
if (mayReplay(resumeFailure) && !retry.cancelled) {
|
|
23286
|
+
const recovery = recoveryPromptFor({
|
|
23287
|
+
recoveryText: turn.recoveryText,
|
|
23288
|
+
currentText: turn.text,
|
|
23289
|
+
failure: resumeFailure
|
|
23290
|
+
});
|
|
23291
|
+
session.broker?.close();
|
|
23292
|
+
session.broker = void 0;
|
|
23293
|
+
if (session.mcpConfigPath) {
|
|
23294
|
+
try {
|
|
23295
|
+
rmSync2(dirname8(session.mcpConfigPath), { recursive: true, force: true });
|
|
23296
|
+
} catch {
|
|
23297
|
+
}
|
|
23298
|
+
session.mcpConfigPath = null;
|
|
23299
|
+
}
|
|
23300
|
+
if (session.systemPromptPath) {
|
|
23301
|
+
removePrivateTempDir(session.systemPromptPath);
|
|
23302
|
+
session.systemPromptPath = null;
|
|
23303
|
+
}
|
|
23304
|
+
sessions.delete(threadId);
|
|
23305
|
+
session.turn = null;
|
|
23306
|
+
active.delete(threadId);
|
|
23307
|
+
emit({
|
|
23308
|
+
...base2(threadId, turnId),
|
|
23309
|
+
type: "turn.retrying",
|
|
23310
|
+
attempt: retry.attempt + 1,
|
|
23311
|
+
delayMs: 0,
|
|
23312
|
+
reason: "resume_rejected"
|
|
23313
|
+
});
|
|
23314
|
+
void (async () => {
|
|
23315
|
+
try {
|
|
23316
|
+
await sendTurn({ ...turn, resumeCursor: void 0, recoveryText: void 0, text: recovery.text });
|
|
23317
|
+
} catch (e) {
|
|
23318
|
+
retryState.delete(threadId);
|
|
23319
|
+
emit({
|
|
23320
|
+
...base2(threadId, turnId),
|
|
23321
|
+
type: "runtime.error",
|
|
23322
|
+
message: e instanceof Error ? e.message : String(e)
|
|
23323
|
+
});
|
|
23324
|
+
emit({ ...base2(threadId, turnId), type: "turn.completed", ok: false, stopReason: "exit_before_result", cost: null });
|
|
23325
|
+
}
|
|
23326
|
+
})();
|
|
23327
|
+
return;
|
|
23328
|
+
}
|
|
22838
23329
|
retryState.delete(threadId);
|
|
22839
23330
|
emit({
|
|
22840
23331
|
...base2(threadId, currentTurnId()),
|
|
@@ -22887,8 +23378,10 @@ var init_claude = __esm({
|
|
|
22887
23378
|
);
|
|
22888
23379
|
});
|
|
22889
23380
|
if (!version2) return { state: "unavailable", reason: `\`${config2.cli}\` CLI not found` };
|
|
23381
|
+
cliVersion = parseClaudeCliVersion(version2);
|
|
22890
23382
|
const auth = await claudeAuthStatus(config2.cli, env);
|
|
22891
|
-
|
|
23383
|
+
const update = claudeCliUpdate(version2, config2.cli);
|
|
23384
|
+
return { state: "available", version: version2, ...auth, ...update ? { update } : {}, billing: "subscription" };
|
|
22892
23385
|
};
|
|
22893
23386
|
const generateReview = (prompt, signal) => new Promise((resolve13, reject) => {
|
|
22894
23387
|
const child = spawnCli(
|
|
@@ -22956,6 +23449,7 @@ var init_claude = __esm({
|
|
|
22956
23449
|
getAuthentication: (flowId) => login.get(flowId),
|
|
22957
23450
|
completeAuthentication: (flowId, code) => login.complete(flowId, code),
|
|
22958
23451
|
cancelAuthentication: () => login.cancel(),
|
|
23452
|
+
signOut: () => login.signOut(),
|
|
22959
23453
|
adapter: {
|
|
22960
23454
|
provider: DRIVER_KIND2,
|
|
22961
23455
|
capabilities: {
|
|
@@ -22987,7 +23481,7 @@ var init_claude = __esm({
|
|
|
22987
23481
|
hasSession: (threadId) => active.has(threadId),
|
|
22988
23482
|
stopAll: async () => {
|
|
22989
23483
|
for (const { stop } of active.values()) stop();
|
|
22990
|
-
for (const threadId of
|
|
23484
|
+
for (const threadId of Array.from(sessions.keys())) closeSession(threadId, "stopAll");
|
|
22991
23485
|
},
|
|
22992
23486
|
onEvent: (listener) => {
|
|
22993
23487
|
listeners.add(listener);
|
|
@@ -22997,9 +23491,13 @@ var init_claude = __esm({
|
|
|
22997
23491
|
generateText: (prompt) => generateReview(prompt),
|
|
22998
23492
|
reviewPermission: generateReview,
|
|
22999
23493
|
dispose: async () => {
|
|
23000
|
-
|
|
23001
|
-
|
|
23002
|
-
|
|
23494
|
+
try {
|
|
23495
|
+
await login.dispose();
|
|
23496
|
+
} finally {
|
|
23497
|
+
for (const { stop } of active.values()) stop();
|
|
23498
|
+
for (const threadId of Array.from(sessions.keys())) closeSession(threadId, "dispose");
|
|
23499
|
+
listeners.clear();
|
|
23500
|
+
}
|
|
23003
23501
|
}
|
|
23004
23502
|
};
|
|
23005
23503
|
}
|
|
@@ -23010,7 +23508,7 @@ var init_claude = __esm({
|
|
|
23010
23508
|
// server/drivers/codex-catalog.ts
|
|
23011
23509
|
import { readdirSync as readdirSync2, readFileSync as readFileSync7 } from "node:fs";
|
|
23012
23510
|
import { homedir as homedir10 } from "node:os";
|
|
23013
|
-
import { basename as basename5, join as
|
|
23511
|
+
import { basename as basename5, join as join19 } from "node:path";
|
|
23014
23512
|
function encodeCodexSelection(provider, model) {
|
|
23015
23513
|
return `${provider}${SEP}${model}`;
|
|
23016
23514
|
}
|
|
@@ -23126,7 +23624,7 @@ function readCodexAppServerModelCatalog(cli, env, timeoutMs = 8e3) {
|
|
|
23126
23624
|
}
|
|
23127
23625
|
function codexHome(env) {
|
|
23128
23626
|
if (env.CODEX_HOME) return env.CODEX_HOME;
|
|
23129
|
-
return
|
|
23627
|
+
return join19(env.HOME || env.USERPROFILE || homedir10(), ".codex");
|
|
23130
23628
|
}
|
|
23131
23629
|
function unquote(raw) {
|
|
23132
23630
|
let value = raw.trim();
|
|
@@ -23212,11 +23710,11 @@ function niceLabel(model, provider, known, named) {
|
|
|
23212
23710
|
}
|
|
23213
23711
|
function collectCatalogNames(home) {
|
|
23214
23712
|
const named = /* @__PURE__ */ new Map();
|
|
23215
|
-
for (const file2 of listDir(
|
|
23713
|
+
for (const file2 of listDir(join19(home, "model-catalogs"))) {
|
|
23216
23714
|
if (!file2.endsWith(".json")) continue;
|
|
23217
23715
|
const provider = basename5(file2, ".json").replace(/-models$/, "");
|
|
23218
23716
|
if (!PROVIDER_ID.test(provider)) continue;
|
|
23219
|
-
const raw = readText(
|
|
23717
|
+
const raw = readText(join19(home, "model-catalogs", file2));
|
|
23220
23718
|
if (!raw) continue;
|
|
23221
23719
|
let parsed;
|
|
23222
23720
|
try {
|
|
@@ -23268,7 +23766,7 @@ async function probeProviderModels(provider, env, fetchImpl) {
|
|
|
23268
23766
|
async function readCodexModelCatalog(env = process.env, fetchImpl = fetch, cli) {
|
|
23269
23767
|
const official = (cli ? await readCodexAppServerModelCatalog(cli, env) : null) ?? STATIC_CODEX_MODELS;
|
|
23270
23768
|
const home = codexHome(env);
|
|
23271
|
-
const mainText = readText(
|
|
23769
|
+
const mainText = readText(join19(home, "config.toml"));
|
|
23272
23770
|
if (!mainText) return mergeLocalInject(official, env, fetchImpl);
|
|
23273
23771
|
const main2 = parseCodexToml(mainText);
|
|
23274
23772
|
const known = new Map(main2.providers.map((provider) => [provider.id, provider]));
|
|
@@ -23283,7 +23781,7 @@ async function readCodexModelCatalog(env = process.env, fetchImpl = fetch, cli)
|
|
|
23283
23781
|
remember(main2.modelProvider, main2.model);
|
|
23284
23782
|
for (const file2 of listDir(home)) {
|
|
23285
23783
|
if (!file2.endsWith(".config.toml")) continue;
|
|
23286
|
-
const profile = parseCodexToml(readText(
|
|
23784
|
+
const profile = parseCodexToml(readText(join19(home, file2)) ?? "");
|
|
23287
23785
|
for (const provider of profile.providers) {
|
|
23288
23786
|
if (!known.has(provider.id)) known.set(provider.id, provider);
|
|
23289
23787
|
}
|
|
@@ -23349,8 +23847,8 @@ var init_codex_catalog = __esm({
|
|
|
23349
23847
|
|
|
23350
23848
|
// server/drivers/codex-instructions.ts
|
|
23351
23849
|
import { createHash as createHash6 } from "node:crypto";
|
|
23352
|
-
import { mkdirSync as
|
|
23353
|
-
import { join as
|
|
23850
|
+
import { mkdirSync as mkdirSync7, readFileSync as readFileSync8 } from "node:fs";
|
|
23851
|
+
import { join as join20 } from "node:path";
|
|
23354
23852
|
function codexDeveloperInstructions(config2, botInstructions) {
|
|
23355
23853
|
if (!config2 || typeof config2 !== "object" || Array.isArray(config2)) {
|
|
23356
23854
|
throw new Error("Codex returned no effective configuration; cannot safely update bot instructions.");
|
|
@@ -23364,8 +23862,8 @@ function codexDeveloperInstructions(config2, botInstructions) {
|
|
|
23364
23862
|
${configured}` : botInstructions;
|
|
23365
23863
|
}
|
|
23366
23864
|
async function syncCodexInstructions(key, nativeThreadId, instructions, resumed, request) {
|
|
23367
|
-
const directory =
|
|
23368
|
-
const path3 =
|
|
23865
|
+
const directory = join20(DATA_DIR, "codex-instructions");
|
|
23866
|
+
const path3 = join20(directory, `${digest(JSON.stringify([key, nativeThreadId]))}.sha256`);
|
|
23369
23867
|
const fingerprint = digest(instructions);
|
|
23370
23868
|
let previous;
|
|
23371
23869
|
try {
|
|
@@ -23394,7 +23892,7 @@ async function syncCodexInstructions(key, nativeThreadId, instructions, resumed,
|
|
|
23394
23892
|
}
|
|
23395
23893
|
}
|
|
23396
23894
|
if (!resumed || previous !== fingerprint) {
|
|
23397
|
-
|
|
23895
|
+
mkdirSync7(directory, { recursive: true });
|
|
23398
23896
|
writeFileAtomic(path3, fingerprint, { mode: 384 });
|
|
23399
23897
|
}
|
|
23400
23898
|
}
|
|
@@ -23412,18 +23910,18 @@ var init_codex_instructions = __esm({
|
|
|
23412
23910
|
import { randomUUID as randomUUID9 } from "node:crypto";
|
|
23413
23911
|
import { realpathSync as realpathSync2 } from "node:fs";
|
|
23414
23912
|
import { homedir as homedir11 } from "node:os";
|
|
23415
|
-
import { basename as basename6, dirname as dirname9, isAbsolute as isAbsolute5, join as
|
|
23416
|
-
import { stripVTControlCharacters as
|
|
23913
|
+
import { basename as basename6, dirname as dirname9, isAbsolute as isAbsolute5, join as join21, resolve as resolve8 } from "node:path";
|
|
23914
|
+
import { stripVTControlCharacters as stripVTControlCharacters5 } from "node:util";
|
|
23417
23915
|
function canonicalPath2(path3) {
|
|
23418
23916
|
try {
|
|
23419
23917
|
return realpathSync2(path3);
|
|
23420
23918
|
} catch {
|
|
23421
23919
|
const parent = dirname9(path3);
|
|
23422
|
-
return parent === path3 ? path3 :
|
|
23920
|
+
return parent === path3 ? path3 : join21(canonicalPath2(parent), basename6(path3));
|
|
23423
23921
|
}
|
|
23424
23922
|
}
|
|
23425
23923
|
function codexDevicePrompt(output) {
|
|
23426
|
-
const clean =
|
|
23924
|
+
const clean = stripVTControlCharacters5(output);
|
|
23427
23925
|
const lines = clean.split(/\r?\n/).slice(0, -1).map((line) => line.trim());
|
|
23428
23926
|
if (!lines.some((line) => /^https:\/\/auth\.openai\.com\/codex\/device\/?$/.test(line))) return null;
|
|
23429
23927
|
const userCode = lines.find((line) => /^[A-Z0-9]{4,8}-[A-Z0-9]{4,8}$/.test(line));
|
|
@@ -23441,13 +23939,13 @@ function loginFailure(output) {
|
|
|
23441
23939
|
}
|
|
23442
23940
|
return "ChatGPT sign-in did not finish. Check the server's connection and that device-code login is enabled in ChatGPT, then try again.";
|
|
23443
23941
|
}
|
|
23444
|
-
var DEVICE_URL,
|
|
23942
|
+
var DEVICE_URL, MAX_OUTPUT3, authenticatingHomes2, CodexDeviceAuthController;
|
|
23445
23943
|
var init_codex_device_auth = __esm({
|
|
23446
23944
|
"server/drivers/codex-device-auth.ts"() {
|
|
23447
23945
|
"use strict";
|
|
23448
23946
|
init_procs();
|
|
23449
23947
|
DEVICE_URL = "https://auth.openai.com/codex/device";
|
|
23450
|
-
|
|
23948
|
+
MAX_OUTPUT3 = 16384;
|
|
23451
23949
|
authenticatingHomes2 = /* @__PURE__ */ new Set();
|
|
23452
23950
|
CodexDeviceAuthController = class {
|
|
23453
23951
|
flow = null;
|
|
@@ -23470,7 +23968,7 @@ var init_codex_device_auth = __esm({
|
|
|
23470
23968
|
if (!isAbsolute5(home) || env.CODEX_HOME && !isAbsolute5(env.CODEX_HOME)) {
|
|
23471
23969
|
throw new Error("Use an absolute HOME and CODEX_HOME path for this server's Codex provider before signing in.");
|
|
23472
23970
|
}
|
|
23473
|
-
const homeKey = canonicalPath2(resolve8(env.CODEX_HOME ||
|
|
23971
|
+
const homeKey = canonicalPath2(resolve8(env.CODEX_HOME || join21(home, ".codex")));
|
|
23474
23972
|
if (authenticatingHomes2.has(homeKey)) {
|
|
23475
23973
|
throw new Error("A ChatGPT sign-in is already running for this server account. Finish or cancel it before starting another.");
|
|
23476
23974
|
}
|
|
@@ -23549,7 +24047,7 @@ var init_codex_device_auth = __esm({
|
|
|
23549
24047
|
if (!isAbsolute5(home) || env.CODEX_HOME && !isAbsolute5(env.CODEX_HOME)) {
|
|
23550
24048
|
throw new Error("Use an absolute HOME and CODEX_HOME path for this server's Codex provider before signing out.");
|
|
23551
24049
|
}
|
|
23552
|
-
const homeKey = canonicalPath2(resolve8(env.CODEX_HOME ||
|
|
24050
|
+
const homeKey = canonicalPath2(resolve8(env.CODEX_HOME || join21(home, ".codex")));
|
|
23553
24051
|
if (authenticatingHomes2.has(homeKey)) {
|
|
23554
24052
|
throw new Error("A ChatGPT sign-in is running for this server account. Finish or cancel it before signing out.");
|
|
23555
24053
|
}
|
|
@@ -23592,7 +24090,7 @@ var init_codex_device_auth = __esm({
|
|
|
23592
24090
|
child.stdin.end();
|
|
23593
24091
|
let output = "";
|
|
23594
24092
|
const receive = (chunk) => {
|
|
23595
|
-
if (output.length <
|
|
24093
|
+
if (output.length < MAX_OUTPUT3) output += chunk.toString("utf8").slice(0, MAX_OUTPUT3 - output.length);
|
|
23596
24094
|
};
|
|
23597
24095
|
child.stdout.on("data", receive);
|
|
23598
24096
|
child.stderr.on("data", receive);
|
|
@@ -23609,7 +24107,7 @@ var init_codex_device_auth = __esm({
|
|
|
23609
24107
|
child.once("close", (code) => {
|
|
23610
24108
|
clearTimeout(timer);
|
|
23611
24109
|
if (this.command === child) this.command = null;
|
|
23612
|
-
resolveExec({ code, output:
|
|
24110
|
+
resolveExec({ code, output: stripVTControlCharacters5(output) });
|
|
23613
24111
|
});
|
|
23614
24112
|
});
|
|
23615
24113
|
}
|
|
@@ -23627,7 +24125,7 @@ var init_codex_device_auth = __esm({
|
|
|
23627
24125
|
let output = "";
|
|
23628
24126
|
const receive = (chunk) => {
|
|
23629
24127
|
if (flow.status.phase !== "waiting") return;
|
|
23630
|
-
if (output.length + chunk.length >
|
|
24128
|
+
if (output.length + chunk.length > MAX_OUTPUT3) {
|
|
23631
24129
|
this.finish(flow, "failed", "Codex returned an unexpected sign-in response. Update the server's Codex CLI and try again.");
|
|
23632
24130
|
return;
|
|
23633
24131
|
}
|
|
@@ -23648,7 +24146,7 @@ var init_codex_device_auth = __esm({
|
|
|
23648
24146
|
});
|
|
23649
24147
|
child.once("close", (code) => {
|
|
23650
24148
|
if (flow.child === child) flow.child = null;
|
|
23651
|
-
if (flow.status.phase === "waiting") done(code,
|
|
24149
|
+
if (flow.status.phase === "waiting") done(code, stripVTControlCharacters5(output));
|
|
23652
24150
|
output = "";
|
|
23653
24151
|
});
|
|
23654
24152
|
}
|
|
@@ -23708,11 +24206,11 @@ var init_codex_device_auth = __esm({
|
|
|
23708
24206
|
|
|
23709
24207
|
// server/drivers/codex-identity.ts
|
|
23710
24208
|
import { homedir as homedir12 } from "node:os";
|
|
23711
|
-
import { isAbsolute as isAbsolute6, join as
|
|
24209
|
+
import { isAbsolute as isAbsolute6, join as join22, resolve as resolve9 } from "node:path";
|
|
23712
24210
|
function codexHome2(env) {
|
|
23713
24211
|
if (env.CODEX_HOME) return isAbsolute6(env.CODEX_HOME) ? resolve9(env.CODEX_HOME) : null;
|
|
23714
24212
|
const home = env.HOME || env.USERPROFILE || homedir12();
|
|
23715
|
-
return isAbsolute6(home) ?
|
|
24213
|
+
return isAbsolute6(home) ? join22(home, ".codex") : null;
|
|
23716
24214
|
}
|
|
23717
24215
|
async function codexAccountEmail(cli, env, timeoutMs = 3e3) {
|
|
23718
24216
|
const cwd = env.HOME || env.USERPROFILE || homedir12();
|
|
@@ -23774,7 +24272,7 @@ async function codexAccountEmail(cli, env, timeoutMs = 3e3) {
|
|
|
23774
24272
|
child.stdout.on("data", (chunk) => {
|
|
23775
24273
|
if (finishing) return;
|
|
23776
24274
|
outputBytes += Buffer.byteLength(chunk);
|
|
23777
|
-
if (outputBytes >
|
|
24275
|
+
if (outputBytes > MAX_OUTPUT4) {
|
|
23778
24276
|
void finish(null);
|
|
23779
24277
|
return;
|
|
23780
24278
|
}
|
|
@@ -23809,18 +24307,18 @@ async function codexAccountEmail(cli, env, timeoutMs = 3e3) {
|
|
|
23809
24307
|
send({ id: 1, method: "initialize", params: { clientInfo: { name: "openmausbot", version: "1" } } });
|
|
23810
24308
|
});
|
|
23811
24309
|
}
|
|
23812
|
-
var
|
|
24310
|
+
var MAX_OUTPUT4, EMAIL;
|
|
23813
24311
|
var init_codex_identity = __esm({
|
|
23814
24312
|
"server/drivers/codex-identity.ts"() {
|
|
23815
24313
|
"use strict";
|
|
23816
24314
|
init_procs();
|
|
23817
|
-
|
|
24315
|
+
MAX_OUTPUT4 = 16384;
|
|
23818
24316
|
EMAIL = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
23819
24317
|
}
|
|
23820
24318
|
});
|
|
23821
24319
|
|
|
23822
24320
|
// server/drivers/codex.ts
|
|
23823
|
-
import { existsSync as
|
|
24321
|
+
import { existsSync as existsSync8 } from "node:fs";
|
|
23824
24322
|
import { homedir as homedir13 } from "node:os";
|
|
23825
24323
|
function codexPredatesAstra(version2) {
|
|
23826
24324
|
const value = version2.trim();
|
|
@@ -23837,7 +24335,7 @@ function codexPredatesAstra(version2) {
|
|
|
23837
24335
|
function codexUpdateCommand(cli, platform = process.platform) {
|
|
23838
24336
|
if (cli === "codex") return "codex update";
|
|
23839
24337
|
const trimmed = cli.trim();
|
|
23840
|
-
const tokens = trimmed.includes(" ") &&
|
|
24338
|
+
const tokens = trimmed.includes(" ") && existsSync8(trimmed) ? [trimmed] : splitCliString(trimmed);
|
|
23841
24339
|
const quote = platform === "win32" ? (token) => `'${token.replaceAll("'", "''")}'` : (token) => `'${token.replaceAll("'", `'\\''`)}'`;
|
|
23842
24340
|
const command = (tokens.length > 0 ? tokens : [trimmed]).map(quote).join(" ");
|
|
23843
24341
|
return platform === "win32" ? `& ${command} update` : `${command} update`;
|
|
@@ -24089,6 +24587,7 @@ var init_codex = __esm({
|
|
|
24089
24587
|
init_env_path();
|
|
24090
24588
|
init_retry();
|
|
24091
24589
|
init_native();
|
|
24590
|
+
init_tool_summary();
|
|
24092
24591
|
init_codex_instructions();
|
|
24093
24592
|
init_codex_device_auth();
|
|
24094
24593
|
init_codex_identity();
|
|
@@ -24153,7 +24652,7 @@ var init_codex = __esm({
|
|
|
24153
24652
|
const listeners = /* @__PURE__ */ new Set();
|
|
24154
24653
|
const active = /* @__PURE__ */ new Map();
|
|
24155
24654
|
const emit = (event) => {
|
|
24156
|
-
for (const l of
|
|
24655
|
+
for (const l of Array.from(listeners)) l(event);
|
|
24157
24656
|
};
|
|
24158
24657
|
const base2 = (threadId, turnId) => ({
|
|
24159
24658
|
eventId: newEventId(),
|
|
@@ -24281,7 +24780,7 @@ var init_codex = __esm({
|
|
|
24281
24780
|
const settle = async (ok, stopReason) => {
|
|
24282
24781
|
if (state.settled) return;
|
|
24283
24782
|
state.settled = true;
|
|
24284
|
-
for (const finish of
|
|
24783
|
+
for (const finish of Array.from(asks.values())) finish("deny", "OpenMausBot: the turn ended", "system");
|
|
24285
24784
|
for (const p of rpcPending.values()) p.reject(new Error("turn settled"));
|
|
24286
24785
|
rpcPending.clear();
|
|
24287
24786
|
const complete = () => {
|
|
@@ -24392,7 +24891,16 @@ var init_codex = __esm({
|
|
|
24392
24891
|
case "item/started": {
|
|
24393
24892
|
const item = p.item ?? {};
|
|
24394
24893
|
const title = item.type === "commandExecution" ? String(item.command ?? "shell") : item.type === "fileChange" ? "edit" : item.type === "mcpToolCall" ? item.tool ?? item.name ?? "mcp" : item.type === "webSearch" ? "web_search" : null;
|
|
24395
|
-
if (title)
|
|
24894
|
+
if (title) {
|
|
24895
|
+
emit({
|
|
24896
|
+
...base2(threadId, turnId),
|
|
24897
|
+
type: "item.started",
|
|
24898
|
+
itemType: "tool",
|
|
24899
|
+
itemId: item.id,
|
|
24900
|
+
title,
|
|
24901
|
+
summary: item.type === "commandExecution" ? commandSummary({ command: item.command }) : void 0
|
|
24902
|
+
});
|
|
24903
|
+
}
|
|
24396
24904
|
break;
|
|
24397
24905
|
}
|
|
24398
24906
|
case "item/completed": {
|
|
@@ -25035,12 +25543,12 @@ var init_grok = __esm({
|
|
|
25035
25543
|
});
|
|
25036
25544
|
|
|
25037
25545
|
// server/drivers/acp/grok.ts
|
|
25038
|
-
import { existsSync as
|
|
25546
|
+
import { existsSync as existsSync9, readFileSync as readFileSync9, writeFileSync as writeFileSync6 } from "node:fs";
|
|
25039
25547
|
import { homedir as homedir14 } from "node:os";
|
|
25040
|
-
import { join as
|
|
25548
|
+
import { join as join23 } from "node:path";
|
|
25041
25549
|
function grokHome(env) {
|
|
25042
25550
|
if (env.GROK_HOME) return env.GROK_HOME;
|
|
25043
|
-
return
|
|
25551
|
+
return join23(env.HOME || env.USERPROFILE || homedir14(), ".grok");
|
|
25044
25552
|
}
|
|
25045
25553
|
function unquote2(raw) {
|
|
25046
25554
|
const value = raw.trim();
|
|
@@ -25050,7 +25558,7 @@ function unquote2(raw) {
|
|
|
25050
25558
|
return value;
|
|
25051
25559
|
}
|
|
25052
25560
|
function readGrokModelCatalog(env = process.env) {
|
|
25053
|
-
const path3 =
|
|
25561
|
+
const path3 = join23(grokHome(env), "config.toml");
|
|
25054
25562
|
let text2 = "";
|
|
25055
25563
|
try {
|
|
25056
25564
|
text2 = readFileSync9(path3, "utf8");
|
|
@@ -25123,7 +25631,7 @@ function ensureGrokInjectSlug(modelId, env = process.env) {
|
|
|
25123
25631
|
if (!inject) return modelId;
|
|
25124
25632
|
const host = localHost(inject.host);
|
|
25125
25633
|
if (!host) return modelId;
|
|
25126
|
-
const path3 =
|
|
25634
|
+
const path3 = join23(grokHome(env), "config.toml");
|
|
25127
25635
|
let text2 = "";
|
|
25128
25636
|
try {
|
|
25129
25637
|
text2 = readFileSync9(path3, "utf8");
|
|
@@ -25227,9 +25735,13 @@ var init_grok2 = __esm({
|
|
|
25227
25735
|
// and BEFORE `stdio` (`grok agent -m slug stdio`). Putting -m first is
|
|
25228
25736
|
// accepted as a TUI option and then ignored, so ACP session/new keeps
|
|
25229
25737
|
// [models].default (grok-4.6) and oMLX never sees a request.
|
|
25738
|
+
// Auto selects Grok's native classifier; if its feature gate is disabled,
|
|
25739
|
+
// residual requests still ask. Never replace it with bypassPermissions.
|
|
25740
|
+
// Verified: grok 1.0.3 --help and xai-org/grok-build@37949780,
|
|
25741
|
+
// crates/codegen/xai-grok-pager-bin/src/main.rs:1259-1273.
|
|
25230
25742
|
spawnArgs: (config2, turn) => [
|
|
25231
25743
|
"--permission-mode",
|
|
25232
|
-
config2.fullAuto ? "bypassPermissions" : "default",
|
|
25744
|
+
config2.fullAuto ? "bypassPermissions" : turn.approvalMode === "auto" ? "auto" : "default",
|
|
25233
25745
|
"agent",
|
|
25234
25746
|
...turn.model ? ["-m", turn.model] : [],
|
|
25235
25747
|
// long form on purpose: `--effort` is documented as an alias, and an
|
|
@@ -25258,7 +25770,7 @@ var init_grok2 = __esm({
|
|
|
25258
25770
|
// an unauthenticated CLI is a user action, not something to paper over.
|
|
25259
25771
|
pickAuthMethod: (methods) => methods.some((m) => m.id === "cached_token") ? "cached_token" : null,
|
|
25260
25772
|
authFailure: "fail",
|
|
25261
|
-
isAuthenticated: () =>
|
|
25773
|
+
isAuthenticated: () => existsSync9(join23(homedir14(), ".grok", "auth.json")),
|
|
25262
25774
|
// `--append-system-prompt`/`--rules` are accepted by the CLI but do NOT
|
|
25263
25775
|
// reach the agent-stdio system prompt (verified against 1.0.0), so the
|
|
25264
25776
|
// persona is prepended codex-style.
|
|
@@ -25271,12 +25783,12 @@ ${turn.text}` : turn.text
|
|
|
25271
25783
|
});
|
|
25272
25784
|
|
|
25273
25785
|
// server/drivers/acp/gemini.ts
|
|
25274
|
-
import { existsSync as
|
|
25786
|
+
import { existsSync as existsSync10, readFileSync as readFileSync10 } from "node:fs";
|
|
25275
25787
|
import { homedir as homedir15 } from "node:os";
|
|
25276
|
-
import { join as
|
|
25788
|
+
import { join as join24 } from "node:path";
|
|
25277
25789
|
function liveOauthCredential() {
|
|
25278
25790
|
try {
|
|
25279
|
-
const creds = JSON.parse(readFileSync10(
|
|
25791
|
+
const creds = JSON.parse(readFileSync10(join24(homedir15(), ".gemini", "oauth_creds.json"), "utf8"));
|
|
25280
25792
|
if (typeof creds.access_token !== "string" || creds.access_token.trim().length === 0) return false;
|
|
25281
25793
|
const hasRefresh = typeof creds.refresh_token === "string" && creds.refresh_token.trim().length > 0;
|
|
25282
25794
|
if (creds.expiry_date !== void 0) {
|
|
@@ -25289,7 +25801,7 @@ function liveOauthCredential() {
|
|
|
25289
25801
|
}
|
|
25290
25802
|
}
|
|
25291
25803
|
function geminiIsAuthenticated(env) {
|
|
25292
|
-
return nonBlank(env.GEMINI_API_KEY) || nonBlank(env.GOOGLE_API_KEY) ||
|
|
25804
|
+
return nonBlank(env.GEMINI_API_KEY) || nonBlank(env.GOOGLE_API_KEY) || existsSync10(join24(homedir15(), ".gemini", "oauth_creds.json")) && liveOauthCredential();
|
|
25293
25805
|
}
|
|
25294
25806
|
var AUTH_PREFERENCE, nonBlank, support3, GeminiAgentDriver;
|
|
25295
25807
|
var init_gemini = __esm({
|
|
@@ -25331,17 +25843,17 @@ ${turn.text}` : turn.text
|
|
|
25331
25843
|
});
|
|
25332
25844
|
|
|
25333
25845
|
// server/drivers/acp/kimi.ts
|
|
25334
|
-
import { existsSync as
|
|
25846
|
+
import { existsSync as existsSync11, mkdirSync as mkdirSync8, readFileSync as readFileSync11, writeFileSync as writeFileSync7 } from "node:fs";
|
|
25335
25847
|
import { homedir as homedir16 } from "node:os";
|
|
25336
|
-
import { join as
|
|
25848
|
+
import { join as join25 } from "node:path";
|
|
25337
25849
|
function isLocalInjectAlias(slug) {
|
|
25338
25850
|
return LOCAL_PROVIDER_PREFIXES.some((prefix) => slug.startsWith(prefix));
|
|
25339
25851
|
}
|
|
25340
25852
|
function kimiDataRoot(env) {
|
|
25341
|
-
return env.KIMI_CODE_HOME ||
|
|
25853
|
+
return env.KIMI_CODE_HOME || join25(env.HOME || env.USERPROFILE || homedir16(), ".kimi-code");
|
|
25342
25854
|
}
|
|
25343
25855
|
function credentialsPath(env) {
|
|
25344
|
-
return
|
|
25856
|
+
return join25(kimiDataRoot(env), "credentials", "kimi-code.json");
|
|
25345
25857
|
}
|
|
25346
25858
|
function quoteToml2(value) {
|
|
25347
25859
|
return `"${value.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
|
|
@@ -25628,8 +26140,8 @@ function ensureKimiInjectAlias(modelId, env = process.env) {
|
|
|
25628
26140
|
if (!host) return modelId;
|
|
25629
26141
|
const alias = `${inject.host}/${inject.model.replace(/\//g, "-")}`;
|
|
25630
26142
|
const dataRoot = kimiDataRoot(env);
|
|
25631
|
-
|
|
25632
|
-
const path3 =
|
|
26143
|
+
mkdirSync8(dataRoot, { recursive: true });
|
|
26144
|
+
const path3 = join25(dataRoot, "config.toml");
|
|
25633
26145
|
let text2 = "";
|
|
25634
26146
|
try {
|
|
25635
26147
|
text2 = readFileSync11(path3, "utf8");
|
|
@@ -25694,7 +26206,7 @@ function readKimiModelCatalog(env) {
|
|
|
25694
26206
|
const dataRoot = kimiDataRoot(env);
|
|
25695
26207
|
let text2 = "";
|
|
25696
26208
|
try {
|
|
25697
|
-
text2 = readFileSync11(
|
|
26209
|
+
text2 = readFileSync11(join25(dataRoot, "config.toml"), "utf8");
|
|
25698
26210
|
} catch {
|
|
25699
26211
|
return STATIC_KIMI_MODELS;
|
|
25700
26212
|
}
|
|
@@ -25803,7 +26315,7 @@ var init_kimi = __esm({
|
|
|
25803
26315
|
authFailure: "continue",
|
|
25804
26316
|
// Match the child CLI's own data-root precedence. A custom instance HOME or
|
|
25805
26317
|
// KIMI_CODE_HOME must not be checked against the server user's home instead.
|
|
25806
|
-
isAuthenticated: (env) =>
|
|
26318
|
+
isAuthenticated: (env) => existsSync11(credentialsPath(env)),
|
|
25807
26319
|
buildPromptText: (turn) => turn.system ? `${turn.system}
|
|
25808
26320
|
|
|
25809
26321
|
${turn.text}` : turn.text
|
|
@@ -25813,12 +26325,12 @@ ${turn.text}` : turn.text
|
|
|
25813
26325
|
});
|
|
25814
26326
|
|
|
25815
26327
|
// server/drivers/acp/droid.ts
|
|
25816
|
-
import { existsSync as
|
|
26328
|
+
import { existsSync as existsSync12, mkdirSync as mkdirSync9, readFileSync as readFileSync12, writeFileSync as writeFileSync8 } from "node:fs";
|
|
25817
26329
|
import { homedir as homedir17 } from "node:os";
|
|
25818
|
-
import { join as
|
|
26330
|
+
import { join as join26 } from "node:path";
|
|
25819
26331
|
function authFilePaths(env) {
|
|
25820
26332
|
const home = env.FACTORY_HOME_OVERRIDE || env.HOME || homedir17();
|
|
25821
|
-
return AUTH_FILES.map((name) =>
|
|
26333
|
+
return AUTH_FILES.map((name) => join26(home, ".factory", name));
|
|
25822
26334
|
}
|
|
25823
26335
|
function droidInjectId(host, model) {
|
|
25824
26336
|
const safe = `${host}-${model}`.replace(/[^a-zA-Z0-9._+-]+/g, "-").replace(/-+/g, "-");
|
|
@@ -25833,14 +26345,14 @@ function ensureDroidInjectModel(modelId, env = process.env) {
|
|
|
25833
26345
|
const host = localHost(inject.host);
|
|
25834
26346
|
if (!host) return modelId;
|
|
25835
26347
|
const id = droidInjectId(inject.host, inject.model);
|
|
25836
|
-
const dir =
|
|
25837
|
-
|
|
25838
|
-
const path3 =
|
|
26348
|
+
const dir = join26(factoryHome(env), ".factory");
|
|
26349
|
+
mkdirSync9(dir, { recursive: true });
|
|
26350
|
+
const path3 = join26(dir, "settings.json");
|
|
25839
26351
|
let settings2 = {};
|
|
25840
26352
|
try {
|
|
25841
26353
|
settings2 = JSON.parse(readFileSync12(path3, "utf8"));
|
|
25842
26354
|
} catch (error51) {
|
|
25843
|
-
if (
|
|
26355
|
+
if (existsSync12(path3)) throw error51;
|
|
25844
26356
|
}
|
|
25845
26357
|
const custom2 = Array.isArray(settings2.customModels) ? [...settings2.customModels] : [];
|
|
25846
26358
|
const match = custom2.find(
|
|
@@ -25871,11 +26383,11 @@ function ensureDroidInjectModel(modelId, env = process.env) {
|
|
|
25871
26383
|
function applyDroidLocalAuthEnv(env, modelId) {
|
|
25872
26384
|
if (!decodeInjectId(modelId)) return;
|
|
25873
26385
|
if (env.FACTORY_API_KEY?.trim()) return;
|
|
25874
|
-
if (authFilePaths(env).some(
|
|
26386
|
+
if (authFilePaths(env).some(existsSync12)) return;
|
|
25875
26387
|
env.FACTORY_API_KEY = "openmausbot-local";
|
|
25876
26388
|
}
|
|
25877
26389
|
function readSettings(env) {
|
|
25878
|
-
return JSON.parse(readFileSync12(
|
|
26390
|
+
return JSON.parse(readFileSync12(join26(factoryHome(env), ".factory", "settings.json"), "utf8"));
|
|
25879
26391
|
}
|
|
25880
26392
|
async function resolveModels(env) {
|
|
25881
26393
|
let catalog = MODELS3;
|
|
@@ -25962,7 +26474,7 @@ var init_droid = __esm({
|
|
|
25962
26474
|
// The signed-in CLI is the primary source; FACTORY_API_KEY is the fallback
|
|
25963
26475
|
// droid itself advertises, and it is checked last so an ambient key can
|
|
25964
26476
|
// never be what makes an otherwise logged-out instance look ready.
|
|
25965
|
-
isAuthenticated: (env) => authFilePaths(env).some(
|
|
26477
|
+
isAuthenticated: (env) => authFilePaths(env).some(existsSync12) || Boolean(env.FACTORY_API_KEY),
|
|
25966
26478
|
resolveModels,
|
|
25967
26479
|
resolveTurnModel: (model, env) => model ? ensureDroidInjectModel(model, env) : model,
|
|
25968
26480
|
applyTurnEnv: (env, { requestedModel }) => {
|
|
@@ -26086,7 +26598,7 @@ function decodeCursorModelText(text2) {
|
|
|
26086
26598
|
for (const raw of text2.split(/\r?\n/)) {
|
|
26087
26599
|
const line = raw.trim();
|
|
26088
26600
|
if (!line || line.startsWith("#") || /^available\s+models?\b/i.test(line) || /^models?\b/i.test(line)) continue;
|
|
26089
|
-
const stripped = line.replace(/^[\s
|
|
26601
|
+
const stripped = line.replace(/^[\s*•-]+\s*/, "");
|
|
26090
26602
|
const parts = stripped.split(/\s+[—–|:]\s+|\s+-\s+|\s{2,}/);
|
|
26091
26603
|
const id = (parts[0] ?? "").trim();
|
|
26092
26604
|
const rawLabel = parts.slice(1).join(" ").trim();
|
|
@@ -26265,9 +26777,9 @@ ${turn.text}` : turn.text
|
|
|
26265
26777
|
});
|
|
26266
26778
|
|
|
26267
26779
|
// server/drivers/acp/opencode-go.ts
|
|
26268
|
-
import { existsSync as
|
|
26780
|
+
import { existsSync as existsSync13, mkdirSync as mkdirSync10, readFileSync as readFileSync13, writeFileSync as writeFileSync9 } from "node:fs";
|
|
26269
26781
|
import { homedir as homedir18 } from "node:os";
|
|
26270
|
-
import { join as
|
|
26782
|
+
import { join as join27 } from "node:path";
|
|
26271
26783
|
function labelForModel(id) {
|
|
26272
26784
|
return id.split(/[-_.]+/g).filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
|
|
26273
26785
|
}
|
|
@@ -26368,7 +26880,7 @@ async function discoverOpenCodeModels(environment, cli = "opencode") {
|
|
|
26368
26880
|
}
|
|
26369
26881
|
function opencodeConfigDir(env) {
|
|
26370
26882
|
const home = env.HOME || env.USERPROFILE || homedir18();
|
|
26371
|
-
return
|
|
26883
|
+
return join27(env.XDG_CONFIG_HOME || join27(home, ".config"), "opencode");
|
|
26372
26884
|
}
|
|
26373
26885
|
function ensureOpenCodeInjectModel(modelId, env = process.env) {
|
|
26374
26886
|
const inject = decodeInjectId(modelId);
|
|
@@ -26377,10 +26889,10 @@ function ensureOpenCodeInjectModel(modelId, env = process.env) {
|
|
|
26377
26889
|
if (!host) return modelId;
|
|
26378
26890
|
const native = `${inject.host}/${inject.model}`;
|
|
26379
26891
|
const dir = opencodeConfigDir(env);
|
|
26380
|
-
|
|
26381
|
-
const path3 =
|
|
26892
|
+
mkdirSync10(dir, { recursive: true });
|
|
26893
|
+
const path3 = join27(dir, "opencode.json");
|
|
26382
26894
|
let config2 = { $schema: "https://opencode.ai/config.json" };
|
|
26383
|
-
if (
|
|
26895
|
+
if (existsSync13(path3)) {
|
|
26384
26896
|
try {
|
|
26385
26897
|
config2 = JSON.parse(readFileSync13(path3, "utf8"));
|
|
26386
26898
|
} catch {
|
|
@@ -26416,10 +26928,10 @@ function ensureOpenCodeInjectModel(modelId, env = process.env) {
|
|
|
26416
26928
|
function storedAuthPaths(env) {
|
|
26417
26929
|
const home = env.HOME || env.USERPROFILE || homedir18();
|
|
26418
26930
|
const roots = [
|
|
26419
|
-
env.XDG_DATA_HOME ||
|
|
26420
|
-
process.platform === "darwin" ?
|
|
26931
|
+
env.XDG_DATA_HOME || join27(home, ".local", "share"),
|
|
26932
|
+
process.platform === "darwin" ? join27(home, "Library", "Application Support") : process.platform === "win32" ? env.LOCALAPPDATA || join27(home, "AppData", "Local") : ""
|
|
26421
26933
|
].filter(Boolean);
|
|
26422
|
-
return [...new Set(roots)].map((root) =>
|
|
26934
|
+
return [...new Set(roots)].map((root) => join27(root, "opencode", "auth.json"));
|
|
26423
26935
|
}
|
|
26424
26936
|
function usableAuthEntry(parsed) {
|
|
26425
26937
|
return Object.values(parsed).some((auth) => {
|
|
@@ -26549,13 +27061,13 @@ ${turn.text}` : turn.text
|
|
|
26549
27061
|
});
|
|
26550
27062
|
|
|
26551
27063
|
// server/drivers/acp/qwen.ts
|
|
26552
|
-
import { chmodSync as chmodSync4, existsSync as
|
|
27064
|
+
import { chmodSync as chmodSync4, existsSync as existsSync14, mkdirSync as mkdirSync11, readFileSync as readFileSync14, writeFileSync as writeFileSync10 } from "node:fs";
|
|
26553
27065
|
import { createHash as createHash7 } from "node:crypto";
|
|
26554
27066
|
import { homedir as homedir19 } from "node:os";
|
|
26555
|
-
import { join as
|
|
27067
|
+
import { join as join28 } from "node:path";
|
|
26556
27068
|
function qwenHome(env) {
|
|
26557
27069
|
const home = process.platform === "win32" ? env.USERPROFILE || env.HOME || homedir19() : env.HOME || env.USERPROFILE || homedir19();
|
|
26558
|
-
return
|
|
27070
|
+
return join28(home, ".qwen");
|
|
26559
27071
|
}
|
|
26560
27072
|
function isRecord(value) {
|
|
26561
27073
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
@@ -26567,7 +27079,7 @@ function qwenModelLabel(id, name) {
|
|
|
26567
27079
|
function readQwenRoutes(env) {
|
|
26568
27080
|
let settings2;
|
|
26569
27081
|
try {
|
|
26570
|
-
settings2 = JSON.parse(readFileSync14(
|
|
27082
|
+
settings2 = JSON.parse(readFileSync14(join28(qwenHome(env), "settings.json"), "utf8"));
|
|
26571
27083
|
} catch {
|
|
26572
27084
|
return [];
|
|
26573
27085
|
}
|
|
@@ -26650,10 +27162,10 @@ function ensureQwenInjectModel(modelId, env = process.env) {
|
|
|
26650
27162
|
const host = localHost(inject.host);
|
|
26651
27163
|
if (!host) return modelId;
|
|
26652
27164
|
const dir = qwenHome(env);
|
|
26653
|
-
|
|
26654
|
-
const path3 =
|
|
27165
|
+
mkdirSync11(dir, { recursive: true });
|
|
27166
|
+
const path3 = join28(dir, "settings.json");
|
|
26655
27167
|
let settings2 = {};
|
|
26656
|
-
if (
|
|
27168
|
+
if (existsSync14(path3)) {
|
|
26657
27169
|
try {
|
|
26658
27170
|
settings2 = JSON.parse(readFileSync14(path3, "utf8"));
|
|
26659
27171
|
} catch {
|
|
@@ -33650,9 +34162,9 @@ var init_browser = __esm({
|
|
|
33650
34162
|
|
|
33651
34163
|
// server/drivers/acp/hermes.ts
|
|
33652
34164
|
import { spawn as spawn5 } from "node:child_process";
|
|
33653
|
-
import { mkdirSync as
|
|
34165
|
+
import { mkdirSync as mkdirSync12, readFileSync as readFileSync15, writeFileSync as writeFileSync11 } from "node:fs";
|
|
33654
34166
|
import { homedir as homedir20 } from "node:os";
|
|
33655
|
-
import { join as
|
|
34167
|
+
import { join as join29 } from "node:path";
|
|
33656
34168
|
function bindHermesScreenshotCompat(env, modelId) {
|
|
33657
34169
|
delete env[HERMES_OPENMAUS_SCREENSHOT_COMPAT];
|
|
33658
34170
|
delete env[HERMES_OPENMAUS_SCREENSHOT_COMPAT_MODEL];
|
|
@@ -33662,7 +34174,7 @@ function bindHermesScreenshotCompat(env, modelId) {
|
|
|
33662
34174
|
env[HERMES_OPENMAUS_SCREENSHOT_COMPAT_MODEL] = inject.model;
|
|
33663
34175
|
}
|
|
33664
34176
|
function hermesHome(env) {
|
|
33665
|
-
return env.HERMES_HOME ||
|
|
34177
|
+
return env.HERMES_HOME || join29(env.HOME || env.USERPROFILE || homedir20(), ".hermes");
|
|
33666
34178
|
}
|
|
33667
34179
|
function quoteYaml(value) {
|
|
33668
34180
|
if (/^[\w./:+-]+$/.test(value)) return value;
|
|
@@ -33703,8 +34215,8 @@ function ensureHermesInjectProvider(modelId, env = process.env) {
|
|
|
33703
34215
|
const host = localHost(inject.host);
|
|
33704
34216
|
if (!host) return modelId;
|
|
33705
34217
|
const dir = hermesHome(env);
|
|
33706
|
-
|
|
33707
|
-
const path3 =
|
|
34218
|
+
mkdirSync12(dir, { recursive: true });
|
|
34219
|
+
const path3 = join29(dir, "config.yaml");
|
|
33708
34220
|
let text2 = "";
|
|
33709
34221
|
try {
|
|
33710
34222
|
text2 = readFileSync15(path3, "utf8");
|
|
@@ -33775,13 +34287,13 @@ function hermesConfiguredModel(env = process.env) {
|
|
|
33775
34287
|
const dir = hermesHome(env);
|
|
33776
34288
|
let secrets = "";
|
|
33777
34289
|
try {
|
|
33778
|
-
secrets = readFileSync15(
|
|
34290
|
+
secrets = readFileSync15(join29(dir, ".env"), "utf8");
|
|
33779
34291
|
} catch {
|
|
33780
34292
|
}
|
|
33781
34293
|
const hasHostedProviderKey = HERMES_HOSTED_PROVIDER_KEYS.some((name) => nonEmptyDotenvValue(secrets, name));
|
|
33782
34294
|
let configuredDefault = null;
|
|
33783
34295
|
try {
|
|
33784
|
-
configuredDefault = hermesConfigDefault(readFileSync15(
|
|
34296
|
+
configuredDefault = hermesConfigDefault(readFileSync15(join29(dir, "config.yaml"), "utf8"));
|
|
33785
34297
|
} catch {
|
|
33786
34298
|
}
|
|
33787
34299
|
const configuredProvider = configuredDefault?.provider.toLowerCase() ?? "";
|
|
@@ -34101,9 +34613,9 @@ var init_openai_compat = __esm({
|
|
|
34101
34613
|
});
|
|
34102
34614
|
|
|
34103
34615
|
// server/drivers/pi.ts
|
|
34104
|
-
import { chmodSync as chmodSync5, existsSync as
|
|
34616
|
+
import { chmodSync as chmodSync5, existsSync as existsSync15, mkdirSync as mkdirSync13, mkdtempSync as mkdtempSync3, readFileSync as readFileSync16, rmSync as rmSync3, writeFileSync as writeFileSync12 } from "node:fs";
|
|
34105
34617
|
import { homedir as homedir21, tmpdir as tmpdir4 } from "node:os";
|
|
34106
|
-
import { join as
|
|
34618
|
+
import { join as join30 } from "node:path";
|
|
34107
34619
|
function readPiPromptImages(turn) {
|
|
34108
34620
|
return (turn.images ?? []).map((image) => ({
|
|
34109
34621
|
type: "image",
|
|
@@ -34210,7 +34722,7 @@ async function applyPiLocalCatalog(catalog, env = process.env, fetchImpl = fetch
|
|
|
34210
34722
|
return preferPiInjectRows(await mergeLocalInject(catalog, env, fetchImpl));
|
|
34211
34723
|
}
|
|
34212
34724
|
function piAgentDir(env) {
|
|
34213
|
-
return
|
|
34725
|
+
return join30(env.HOME || env.USERPROFILE || homedir21(), ".pi", "agent");
|
|
34214
34726
|
}
|
|
34215
34727
|
function ensurePiInjectModel(modelId, env = process.env) {
|
|
34216
34728
|
const split = splitPiModel(modelId);
|
|
@@ -34220,10 +34732,10 @@ function ensurePiInjectModel(modelId, env = process.env) {
|
|
|
34220
34732
|
const host = localHost(inject.host);
|
|
34221
34733
|
if (!host) return split;
|
|
34222
34734
|
const dir = piAgentDir(env);
|
|
34223
|
-
|
|
34224
|
-
const path3 =
|
|
34735
|
+
mkdirSync13(dir, { recursive: true });
|
|
34736
|
+
const path3 = join30(dir, "models.json");
|
|
34225
34737
|
let root = { providers: {} };
|
|
34226
|
-
if (
|
|
34738
|
+
if (existsSync15(path3)) {
|
|
34227
34739
|
try {
|
|
34228
34740
|
const parsed = JSON.parse(readFileSync16(path3, "utf8"));
|
|
34229
34741
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
@@ -34395,7 +34907,7 @@ var init_pi = __esm({
|
|
|
34395
34907
|
const listeners = /* @__PURE__ */ new Set();
|
|
34396
34908
|
const active = /* @__PURE__ */ new Map();
|
|
34397
34909
|
const emit = (event) => {
|
|
34398
|
-
for (const l of
|
|
34910
|
+
for (const l of Array.from(listeners)) l(event);
|
|
34399
34911
|
};
|
|
34400
34912
|
const base2 = (threadId, turnId) => ({
|
|
34401
34913
|
eventId: newEventId(),
|
|
@@ -34423,9 +34935,9 @@ var init_pi = __esm({
|
|
|
34423
34935
|
const mcpServers = buildMcpServers(turn);
|
|
34424
34936
|
let mcpTempDir = null;
|
|
34425
34937
|
if (mcpServers) {
|
|
34426
|
-
mcpTempDir = mkdtempSync3(
|
|
34938
|
+
mcpTempDir = mkdtempSync3(join30(tmpdir4(), "omb-pi-mcp-"));
|
|
34427
34939
|
try {
|
|
34428
|
-
writeFileSync12(
|
|
34940
|
+
writeFileSync12(join30(mcpTempDir, "mcp.json"), JSON.stringify({ mcpServers }), { mode: 384 });
|
|
34429
34941
|
} catch (err) {
|
|
34430
34942
|
try {
|
|
34431
34943
|
rmSync3(mcpTempDir, { recursive: true, force: true });
|
|
@@ -34443,7 +34955,7 @@ var init_pi = __esm({
|
|
|
34443
34955
|
env: piEnvironment({
|
|
34444
34956
|
...process.env,
|
|
34445
34957
|
...input.environment,
|
|
34446
|
-
...mcpServers && mcpTempDir ? { OMB_MCP_CONFIG:
|
|
34958
|
+
...mcpServers && mcpTempDir ? { OMB_MCP_CONFIG: join30(mcpTempDir, "mcp.json") } : {}
|
|
34447
34959
|
})
|
|
34448
34960
|
});
|
|
34449
34961
|
} catch (err) {
|
|
@@ -34782,14 +35294,14 @@ ${turn.text}` : turn.text;
|
|
|
34782
35294
|
// server/drivers/minimax.ts
|
|
34783
35295
|
import { readFileSync as readFileSync17 } from "node:fs";
|
|
34784
35296
|
import { homedir as homedir22 } from "node:os";
|
|
34785
|
-
import { join as
|
|
35297
|
+
import { join as join31 } from "node:path";
|
|
34786
35298
|
function normalizedApiUrl(value) {
|
|
34787
35299
|
const root = value.trim().replace(/\/+$/, "");
|
|
34788
35300
|
return root.endsWith("/v1") ? root : `${root}/v1`;
|
|
34789
35301
|
}
|
|
34790
35302
|
function loadLocalMiniMaxConfig(home = homedir22()) {
|
|
34791
35303
|
try {
|
|
34792
|
-
const raw = localConfigSchema.parse(JSON.parse(readFileSync17(
|
|
35304
|
+
const raw = localConfigSchema.parse(JSON.parse(readFileSync17(join31(home, ".mmx", "config.json"), "utf8")));
|
|
34793
35305
|
const configuredUrl = raw.base_url?.trim() ? raw.base_url : raw.region === "cn" ? CN_URL : DEFAULT_URL2;
|
|
34794
35306
|
return {
|
|
34795
35307
|
apiKey: raw.api_key?.trim() ?? "",
|
|
@@ -35057,7 +35569,7 @@ __export(cli_setup_exports, {
|
|
|
35057
35569
|
});
|
|
35058
35570
|
import { spawn as spawn6 } from "node:child_process";
|
|
35059
35571
|
import { readFileSync as readFileSync18 } from "node:fs";
|
|
35060
|
-
import { join as
|
|
35572
|
+
import { join as join32, resolve as resolve10 } from "node:path";
|
|
35061
35573
|
import { randomUUID as randomUUID10 } from "node:crypto";
|
|
35062
35574
|
async function inspect(id, entry) {
|
|
35063
35575
|
const registry2 = new ProviderRegistry(BUILT_IN_DRIVERS);
|
|
@@ -35094,7 +35606,7 @@ function assertDataDir(dataDir) {
|
|
|
35094
35606
|
}
|
|
35095
35607
|
function checkStoredConfig(dataDir) {
|
|
35096
35608
|
try {
|
|
35097
|
-
parseStoredConfig(JSON.parse(readFileSync18(
|
|
35609
|
+
parseStoredConfig(JSON.parse(readFileSync18(join32(dataDir, "config.json"), "utf8")));
|
|
35098
35610
|
} catch (error51) {
|
|
35099
35611
|
if (error51.code === "ENOENT") return;
|
|
35100
35612
|
throw new Error("Existing config.json could not be read or validated. Setup has not changed it; repair it before continuing.");
|
|
@@ -35372,7 +35884,7 @@ var init_browser_engine_release = __esm({
|
|
|
35372
35884
|
});
|
|
35373
35885
|
|
|
35374
35886
|
// server/browser-bundle-release.ts
|
|
35375
|
-
import { join as
|
|
35887
|
+
import { join as join33 } from "node:path";
|
|
35376
35888
|
function browserBundleSpec(target) {
|
|
35377
35889
|
if (!Object.hasOwn(CHROME_ASSETS, target)) throw new Error(`Unsupported desktop browser target: ${target}`);
|
|
35378
35890
|
const pinned = CHROME_ASSETS[target];
|
|
@@ -35408,10 +35920,10 @@ function browserBundlePaths(bundleDirectory, target) {
|
|
|
35408
35920
|
const spec = browserBundleSpec(target);
|
|
35409
35921
|
return {
|
|
35410
35922
|
directory: bundleDirectory,
|
|
35411
|
-
manifest:
|
|
35412
|
-
engine:
|
|
35413
|
-
chrome:
|
|
35414
|
-
licenses:
|
|
35923
|
+
manifest: join33(bundleDirectory, "manifest.json"),
|
|
35924
|
+
engine: join33(bundleDirectory, spec.engine.executable),
|
|
35925
|
+
chrome: join33(bundleDirectory, spec.chrome.executable),
|
|
35926
|
+
licenses: join33(bundleDirectory, "licenses")
|
|
35415
35927
|
};
|
|
35416
35928
|
}
|
|
35417
35929
|
var CHROME_VERSION, CHROME_ASSETS;
|
|
@@ -35466,9 +35978,9 @@ __export(browser_engine_exports, {
|
|
|
35466
35978
|
});
|
|
35467
35979
|
import { spawn as spawn7 } from "node:child_process";
|
|
35468
35980
|
import { createHash as createHash8, randomBytes as randomBytes3, randomUUID as randomUUID11 } from "node:crypto";
|
|
35469
|
-
import { chmodSync as chmodSync6, constants as constants2, copyFileSync, existsSync as
|
|
35981
|
+
import { chmodSync as chmodSync6, constants as constants2, copyFileSync, existsSync as existsSync16, mkdirSync as mkdirSync14, readFileSync as readFileSync19, readdirSync as readdirSync3, renameSync as renameSync5, rmSync as rmSync4, statSync as statSync3, unlinkSync as unlinkSync4, writeFileSync as writeFileSync13 } from "node:fs";
|
|
35470
35982
|
import { homedir as homedir23, tmpdir as tmpdir5 } from "node:os";
|
|
35471
|
-
import { delimiter as delimiter6, dirname as dirname10, join as
|
|
35983
|
+
import { delimiter as delimiter6, dirname as dirname10, join as join34, resolve as resolve11 } from "node:path";
|
|
35472
35984
|
function browserRestoreKey(session) {
|
|
35473
35985
|
if (!/^[A-Za-z0-9_-]{1,96}$/.test(session)) throw new Error("Invalid browser session.");
|
|
35474
35986
|
return `omb-${createHash8("sha256").update(session).digest("hex")}`;
|
|
@@ -35477,15 +35989,15 @@ function browserSessionsDirectory(env) {
|
|
|
35477
35989
|
const namespace = env.AGENT_BROWSER_NAMESPACE;
|
|
35478
35990
|
if (namespace && !/^[a-z0-9]+(?:[-_][a-z0-9]+)*$/.test(namespace)) throw new Error("Invalid browser namespace.");
|
|
35479
35991
|
const home = (process.platform === "win32" ? env.USERPROFILE : env.HOME) || homedir23();
|
|
35480
|
-
const stateRoot = namespace ?
|
|
35481
|
-
return
|
|
35992
|
+
const stateRoot = namespace ? join34(home, ".agent-browser", "namespaces", namespace, "state") : join34(home, ".agent-browser");
|
|
35993
|
+
return join34(stateRoot, "sessions");
|
|
35482
35994
|
}
|
|
35483
35995
|
function managedBrowserConfigPath(env) {
|
|
35484
|
-
return
|
|
35996
|
+
return join34(browserSessionsDirectory(env), "..", "omb-managed-config.json");
|
|
35485
35997
|
}
|
|
35486
35998
|
function ensureManagedBrowserConfig(env) {
|
|
35487
35999
|
const path3 = managedBrowserConfigPath(env);
|
|
35488
|
-
|
|
36000
|
+
mkdirSync14(dirname10(path3), { recursive: true, mode: 448 });
|
|
35489
36001
|
try {
|
|
35490
36002
|
writeFileSync13(path3, "{}\n", { flag: "wx", mode: 384 });
|
|
35491
36003
|
} catch (error51) {
|
|
@@ -35568,12 +36080,12 @@ async function prepareBrowserSessionState(binaryPath, session, options = {}) {
|
|
|
35568
36080
|
ensureManagedBrowserConfig(env);
|
|
35569
36081
|
if (options.persistent === false) return;
|
|
35570
36082
|
const directory = browserSessionsDirectory(env);
|
|
35571
|
-
const key =
|
|
36083
|
+
const key = join34(directory, session);
|
|
35572
36084
|
let pending = preparedBrowserSessions.get(key);
|
|
35573
36085
|
if (!pending) {
|
|
35574
36086
|
pending = (async () => {
|
|
35575
|
-
const targetBase =
|
|
35576
|
-
const hasTarget = () =>
|
|
36087
|
+
const targetBase = join34(directory, `${restoreKey}-${session}`);
|
|
36088
|
+
const hasTarget = () => existsSync16(`${targetBase}.json.enc`) || existsSync16(`${targetBase}.json`);
|
|
35577
36089
|
if (hasTarget()) return;
|
|
35578
36090
|
check2();
|
|
35579
36091
|
if (!await closeBrowserSession(binaryPath, { ...env, AGENT_BROWSER_RESTORE: session }, options.timeoutMs)) {
|
|
@@ -35582,7 +36094,7 @@ async function prepareBrowserSessionState(binaryPath, session, options = {}) {
|
|
|
35582
36094
|
check2();
|
|
35583
36095
|
if (hasTarget()) return;
|
|
35584
36096
|
const candidates = [".json.enc", ".json"].flatMap((suffix) => {
|
|
35585
|
-
const path3 =
|
|
36097
|
+
const path3 = join34(directory, `${session}-${session}${suffix}`);
|
|
35586
36098
|
try {
|
|
35587
36099
|
const stat4 = statSync3(path3);
|
|
35588
36100
|
if (!stat4.isFile()) throw new Error("Saved browser state is not a file.");
|
|
@@ -35612,12 +36124,12 @@ async function prepareBrowserSessionState(binaryPath, session, options = {}) {
|
|
|
35612
36124
|
function executableName(platform = process.platform) {
|
|
35613
36125
|
return platform === "win32" ? "agent-browser.exe" : "agent-browser";
|
|
35614
36126
|
}
|
|
35615
|
-
function isMusl(platform = process.platform, exists =
|
|
36127
|
+
function isMusl(platform = process.platform, exists = existsSync16) {
|
|
35616
36128
|
return platform === "linux" && (exists("/lib/ld-musl-x86_64.so.1") || exists("/lib/ld-musl-aarch64.so.1"));
|
|
35617
36129
|
}
|
|
35618
36130
|
function pinnedBinaryPath(dataDir = DATA_DIR, platform = process.platform, arch = process.arch) {
|
|
35619
36131
|
const version2 = agentBrowserReleaseVersion(resolveAgentBrowserReleaseAsset(platform, arch));
|
|
35620
|
-
return
|
|
36132
|
+
return join34(dataDir, ENGINE_DIR, version2, executableName(platform));
|
|
35621
36133
|
}
|
|
35622
36134
|
function onPath(env, platform, exists) {
|
|
35623
36135
|
const pathValue = platform === "win32" ? Object.entries(env).findLast(([key]) => key.toUpperCase() === "PATH")?.[1] : env.PATH;
|
|
@@ -35633,7 +36145,7 @@ function packagedBrowser(options) {
|
|
|
35633
36145
|
const resources = (options.env ?? process.env).OMB_RESOURCES_PATH;
|
|
35634
36146
|
if (!resources) return null;
|
|
35635
36147
|
try {
|
|
35636
|
-
return browserBundlePaths(
|
|
36148
|
+
return browserBundlePaths(join34(resolve11(resources), "browser-engine"), `${options.platform ?? process.platform}-${options.arch ?? process.arch}`);
|
|
35637
36149
|
} catch {
|
|
35638
36150
|
return null;
|
|
35639
36151
|
}
|
|
@@ -35644,7 +36156,7 @@ function completePackage(bundle, exists) {
|
|
|
35644
36156
|
function resolveAgentBrowserBinary(options = {}) {
|
|
35645
36157
|
const env = options.env ?? process.env;
|
|
35646
36158
|
const platform = options.platform ?? process.platform;
|
|
35647
|
-
const exists = options.exists ??
|
|
36159
|
+
const exists = options.exists ?? existsSync16;
|
|
35648
36160
|
const override = env.OMB_AGENT_BROWSER_PATH?.trim();
|
|
35649
36161
|
if (override) return resolve11(override) && exists(resolve11(override)) ? resolve11(override) : null;
|
|
35650
36162
|
const bundle = packagedBrowser(options);
|
|
@@ -35658,8 +36170,8 @@ async function installAgentBrowserBinary(options = {}) {
|
|
|
35658
36170
|
const asset = options.asset ?? resolveAgentBrowserReleaseAsset(platform, options.arch ?? process.arch, options.musl ?? isMusl(platform));
|
|
35659
36171
|
if (!asset) throw new Error(`agent-browser publishes no build for ${platform}-${options.arch ?? process.arch}.`);
|
|
35660
36172
|
const destination = pinnedBinaryPath(options.dataDir, platform, options.arch);
|
|
35661
|
-
const directory =
|
|
35662
|
-
|
|
36173
|
+
const directory = join34(destination, "..");
|
|
36174
|
+
mkdirSync14(directory, { recursive: true, mode: 448 });
|
|
35663
36175
|
const url2 = agentBrowserReleaseUrl(asset);
|
|
35664
36176
|
options.log?.(`downloading agent-browser ${agentBrowserReleaseVersion(asset)} (${Math.round(asset.bytes / 1024 / 1024)} MB, digest pinned)`);
|
|
35665
36177
|
const controller = new AbortController();
|
|
@@ -35684,7 +36196,7 @@ async function installAgentBrowserBinary(options = {}) {
|
|
|
35684
36196
|
}
|
|
35685
36197
|
function ensureChrome(binaryPath, options = {}) {
|
|
35686
36198
|
const bundle = packagedBrowser(options);
|
|
35687
|
-
if (!options.withDeps && bundle && resolve11(binaryPath) === bundle.engine && completePackage(bundle,
|
|
36199
|
+
if (!options.withDeps && bundle && resolve11(binaryPath) === bundle.engine && completePackage(bundle, existsSync16)) {
|
|
35688
36200
|
options.log?.("agent-browser: the bundled browser is ready; no download needed");
|
|
35689
36201
|
return Promise.resolve();
|
|
35690
36202
|
}
|
|
@@ -35710,14 +36222,14 @@ function ensureChrome(binaryPath, options = {}) {
|
|
|
35710
36222
|
});
|
|
35711
36223
|
}
|
|
35712
36224
|
function browserEngineEncryptionKey(dataDir = DATA_DIR) {
|
|
35713
|
-
const file2 =
|
|
36225
|
+
const file2 = join34(dataDir, KEY_FILE);
|
|
35714
36226
|
try {
|
|
35715
36227
|
const existing = readFileSync19(file2, "utf8").trim();
|
|
35716
36228
|
if (/^[0-9a-f]{64}$/u.test(existing)) return existing;
|
|
35717
36229
|
} catch {
|
|
35718
36230
|
}
|
|
35719
36231
|
const key = randomBytes3(32).toString("hex");
|
|
35720
|
-
|
|
36232
|
+
mkdirSync14(dataDir, { recursive: true });
|
|
35721
36233
|
writeFileAtomic(file2, `${key}
|
|
35722
36234
|
`, { mode: 384 });
|
|
35723
36235
|
return key;
|
|
@@ -35731,7 +36243,7 @@ function browserEngineStatus(options = {}) {
|
|
|
35731
36243
|
const version2 = managed ? agentBrowserReleaseVersion(resolveAgentBrowserReleaseAsset(platform2, options.arch)) : AGENT_BROWSER_VERSION;
|
|
35732
36244
|
return { kind: "ready", binaryPath, version: version2 };
|
|
35733
36245
|
}
|
|
35734
|
-
if (bundle && (options.exists ??
|
|
36246
|
+
if (bundle && (options.exists ?? existsSync16)(bundle.directory)) {
|
|
35735
36247
|
return { kind: "unavailable", reason: "The desktop browser bundle is incomplete. Reinstall or update OpenMausBot to repair it.", installable: false };
|
|
35736
36248
|
}
|
|
35737
36249
|
const platform = options.platform ?? process.platform;
|
|
@@ -35764,13 +36276,13 @@ function agentBrowserIntegration(input) {
|
|
|
35764
36276
|
if (sourceEnv[name]) env[name] = sourceEnv[name];
|
|
35765
36277
|
}
|
|
35766
36278
|
const bundle = packagedBrowser({ env: sourceEnv });
|
|
35767
|
-
if (!env.AGENT_BROWSER_EXECUTABLE_PATH && bundle && resolve11(input.binaryPath) === bundle.engine && completePackage(bundle,
|
|
36279
|
+
if (!env.AGENT_BROWSER_EXECUTABLE_PATH && bundle && resolve11(input.binaryPath) === bundle.engine && completePackage(bundle, existsSync16)) {
|
|
35768
36280
|
env.AGENT_BROWSER_EXECUTABLE_PATH = bundle.chrome;
|
|
35769
36281
|
}
|
|
35770
36282
|
return { command: input.binaryPath, args: ["mcp", "--tools", "core", "--no-webmcp"], env };
|
|
35771
36283
|
}
|
|
35772
36284
|
function agentBrowserFrame(input) {
|
|
35773
|
-
const file2 =
|
|
36285
|
+
const file2 = join34(tmpdir5(), `openmausbot-browser-${randomUUID11()}.png`);
|
|
35774
36286
|
return new Promise((settle, fail) => {
|
|
35775
36287
|
const child = spawn7(input.binaryPath, ["screenshot", file2], {
|
|
35776
36288
|
env: browserRuntimeEnv(input.env),
|
|
@@ -35840,8 +36352,8 @@ async function clearBrowserSessionState(binaryPath, session, options = {}) {
|
|
|
35840
36352
|
}
|
|
35841
36353
|
};
|
|
35842
36354
|
try {
|
|
35843
|
-
for (const base2 of bases) for (const suffix of [".json", ".json.enc", ".json.previous", ".json.enc.previous"]) remove(
|
|
35844
|
-
const pendingDirectory =
|
|
36355
|
+
for (const base2 of bases) for (const suffix of [".json", ".json.enc", ".json.previous", ".json.enc.previous"]) remove(join34(directory, base2 + suffix));
|
|
36356
|
+
const pendingDirectory = join34(directory, ".tmp");
|
|
35845
36357
|
let pendingFiles = [];
|
|
35846
36358
|
try {
|
|
35847
36359
|
pendingFiles = readdirSync3(pendingDirectory);
|
|
@@ -35849,8 +36361,8 @@ async function clearBrowserSessionState(binaryPath, session, options = {}) {
|
|
|
35849
36361
|
if (error51.code !== "ENOENT") throw error51;
|
|
35850
36362
|
}
|
|
35851
36363
|
const candidates = bases.map((base2) => new RegExp(`^${base2}-candidate-[0-9]+\\.json(?:\\.enc)?$`));
|
|
35852
|
-
for (const name of pendingFiles) if (candidates.some((candidate) => candidate.test(name))) remove(
|
|
35853
|
-
preparedBrowserSessions.delete(
|
|
36364
|
+
for (const name of pendingFiles) if (candidates.some((candidate) => candidate.test(name))) remove(join34(pendingDirectory, name));
|
|
36365
|
+
preparedBrowserSessions.delete(join34(directory, session));
|
|
35854
36366
|
return true;
|
|
35855
36367
|
} catch {
|
|
35856
36368
|
return false;
|
|
@@ -35877,9 +36389,9 @@ var init_browser_engine = __esm({
|
|
|
35877
36389
|
// server/cli.ts
|
|
35878
36390
|
var import_qrcode_terminal = __toESM(require_main(), 1);
|
|
35879
36391
|
import { spawn as spawn8 } from "node:child_process";
|
|
35880
|
-
import { closeSync as closeSync3, existsSync as
|
|
36392
|
+
import { closeSync as closeSync3, existsSync as existsSync17, mkdirSync as mkdirSync15, openSync as openSync3, readFileSync as readFileSync20 } from "node:fs";
|
|
35881
36393
|
import { homedir as homedir24 } from "node:os";
|
|
35882
|
-
import { dirname as dirname11, join as
|
|
36394
|
+
import { dirname as dirname11, join as join35, resolve as resolve12 } from "node:path";
|
|
35883
36395
|
import { createInterface as createInterface2 } from "node:readline/promises";
|
|
35884
36396
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
35885
36397
|
|
|
@@ -38124,7 +38636,7 @@ function parseArgs(argv, env = process.env) {
|
|
|
38124
38636
|
const options = {
|
|
38125
38637
|
command: command === "--help" || command === "-h" ? "help" : command,
|
|
38126
38638
|
port: Number(env.OMB_PORT || 8799),
|
|
38127
|
-
dataDir: env.OMB_DATA_DIR ||
|
|
38639
|
+
dataDir: env.OMB_DATA_DIR || join35(homedir24(), ".openmausbot"),
|
|
38128
38640
|
tailscale: false,
|
|
38129
38641
|
tunnel: false,
|
|
38130
38642
|
client: false,
|
|
@@ -38279,7 +38791,7 @@ async function isWorkspaceRunning(options) {
|
|
|
38279
38791
|
try {
|
|
38280
38792
|
const { status, body } = await api(options.port, "/api/health");
|
|
38281
38793
|
if (status !== 200 || body?.app !== "openmausbot") return false;
|
|
38282
|
-
const expected = readFileSync20(
|
|
38794
|
+
const expected = readFileSync20(join35(options.dataDir, "environment-id"), "utf8").trim();
|
|
38283
38795
|
const descriptor = await api(options.port, "/.well-known/openmausbot/environment");
|
|
38284
38796
|
return /^[0-9a-f-]{36}$/i.test(expected) && descriptor.status === 200 && descriptor.body?.environmentId === expected;
|
|
38285
38797
|
} catch {
|
|
@@ -38479,9 +38991,9 @@ async function runStatus(options, io = defaultIo()) {
|
|
|
38479
38991
|
return code;
|
|
38480
38992
|
}
|
|
38481
38993
|
async function runAccess(options, io = defaultIo()) {
|
|
38482
|
-
const file2 =
|
|
38994
|
+
const file2 = join35(options.dataDir, "config.json");
|
|
38483
38995
|
let raw = {};
|
|
38484
|
-
if (
|
|
38996
|
+
if (existsSync17(file2)) {
|
|
38485
38997
|
try {
|
|
38486
38998
|
const parsed = JSON.parse(readFileSync20(file2, "utf8"));
|
|
38487
38999
|
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) throw new Error("not an object");
|
|
@@ -38497,7 +39009,7 @@ async function runAccess(options, io = defaultIo()) {
|
|
|
38497
39009
|
const members = list(Reflect.get(current, "members"));
|
|
38498
39010
|
const overridden = process.env.OMB_SIGNIN_EMAILS !== void 0 || process.env.OMB_SIGNIN_MEMBER_EMAILS !== void 0;
|
|
38499
39011
|
const write = (next) => {
|
|
38500
|
-
|
|
39012
|
+
mkdirSync15(options.dataDir, { recursive: true, mode: 448 });
|
|
38501
39013
|
writeFileAtomic(file2, `${JSON.stringify({ ...raw, signIn: next }, null, 2)}
|
|
38502
39014
|
`, { mode: 384 });
|
|
38503
39015
|
};
|
|
@@ -38631,16 +39143,16 @@ async function runBrowser(options, io = defaultIo()) {
|
|
|
38631
39143
|
return 0;
|
|
38632
39144
|
}
|
|
38633
39145
|
function serverEntry(here = HERE2) {
|
|
38634
|
-
const bundled =
|
|
39146
|
+
const bundled = join35(here, "index.js");
|
|
38635
39147
|
const root = resolve12(here, "..");
|
|
38636
|
-
if (
|
|
38637
|
-
const staticDir2 = [
|
|
38638
|
-
const skillsDir =
|
|
39148
|
+
if (existsSync17(bundled)) {
|
|
39149
|
+
const staticDir2 = [join35(root, "dist"), join35(here, "..", "ui")].find((d) => existsSync17(join35(d, "index.html"))) ?? null;
|
|
39150
|
+
const skillsDir = existsSync17(join35(root, "skills")) ? join35(root, "skills") : null;
|
|
38639
39151
|
return { command: process.execPath, args: [bundled], staticDir: staticDir2, skillsDir };
|
|
38640
39152
|
}
|
|
38641
|
-
const source =
|
|
38642
|
-
const staticDir =
|
|
38643
|
-
return { command: process.execPath, args: ["--experimental-strip-types", source], staticDir, skillsDir:
|
|
39153
|
+
const source = join35(here, "index.ts");
|
|
39154
|
+
const staticDir = existsSync17(join35(root, "dist", "index.html")) ? join35(root, "dist") : null;
|
|
39155
|
+
return { command: process.execPath, args: ["--experimental-strip-types", source], staticDir, skillsDir: existsSync17(join35(root, "skills")) ? join35(root, "skills") : null };
|
|
38644
39156
|
}
|
|
38645
39157
|
async function planTunnel(options, log) {
|
|
38646
39158
|
let access2 = null;
|
|
@@ -38740,9 +39252,9 @@ async function runServe(options, log = console.log) {
|
|
|
38740
39252
|
let child;
|
|
38741
39253
|
try {
|
|
38742
39254
|
if (options.guided) {
|
|
38743
|
-
const logsDir =
|
|
38744
|
-
|
|
38745
|
-
logPath =
|
|
39255
|
+
const logsDir = join35(options.dataDir, "logs");
|
|
39256
|
+
mkdirSync15(logsDir, { recursive: true, mode: 448 });
|
|
39257
|
+
logPath = join35(logsDir, `server-${Date.now()}-${process.pid}.log`);
|
|
38746
39258
|
logFd = openSync3(logPath, "wx", 384);
|
|
38747
39259
|
log("\nStarting your workspace\u2026");
|
|
38748
39260
|
}
|
|
@@ -38934,7 +39446,7 @@ async function runOnboardingCommand(options, io = defaultIo(), startServer = run
|
|
|
38934
39446
|
}
|
|
38935
39447
|
if (options.command === "setup") {
|
|
38936
39448
|
io.log("\nAll set. Start with: openmausbot (or npx openmausbot without a global install).");
|
|
38937
|
-
if (options.dataDir !==
|
|
39449
|
+
if (options.dataDir !== join35(homedir24(), ".openmausbot") || options.port !== 8799) {
|
|
38938
39450
|
io.log(`Use the same --data-dir (${options.dataDir}) and --port (${options.port}) options when starting.`);
|
|
38939
39451
|
}
|
|
38940
39452
|
return 0;
|