openmausbot 0.1.73 → 0.1.75
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-BYbK7ber.js → index-BTlyRwLl.js} +1 -1
- package/dist/assets/index-CeMbvsgx.js +305 -0
- package/dist/assets/index-DH7Zax6L.css +1 -0
- package/dist/index.html +2 -2
- package/dist-server/container-mcp.js +9 -0
- package/dist-server/index.js +1402 -1048
- package/dist-server/mcp-gate.js +58 -16
- package/dist-server/openmausbot.js +543 -271
- package/dist-server/pair-cli.js +543 -271
- package/dist-server/permission-proxy.js +119 -14
- package/dist-server/server/auto-approve.js +44 -205
- package/dist-server/server/channel-queue.js +20 -2
- package/dist-server/server/config.js +36 -1
- package/dist-server/server/drivers/acp/core.js +58 -4
- package/dist-server/server/drivers/acp/grok.js +15 -2
- package/dist-server/server/drivers/antigravity-acp.js +5 -4
- package/dist-server/server/drivers/antigravity.js +9 -4
- package/dist-server/server/drivers/claude.js +113 -13
- package/dist-server/server/drivers/codex.js +37 -15
- package/dist-server/server/drivers/retry.js +4 -0
- package/dist-server/server/engine-install.js +9 -5
- package/dist-server/server/index.js +265 -233
- package/dist-server/server/message-db.js +70 -3
- package/dist-server/server/permission-proxy.js +90 -15
- package/dist-server/server/procs.js +82 -23
- package/dist-server/server/routines.js +67 -8
- package/dist-server/server/setup-mode.js +6 -7
- package/dist-server/server/steer-queue.js +27 -7
- package/dist-server/server/store.js +19 -0
- package/dist-server/server/team-manifest.js +1 -1
- package/dist-server/server/thread-events.js +10 -1
- package/dist-server/server/webhooks.js +4 -1
- package/dist-server/server/workspace-backup.js +24 -9
- package/dist-server/server/workspace.js +13 -0
- package/dist-server/shared/approval-mode.js +11 -10
- package/dist-server/shared/ask-question.js +172 -0
- package/dist-server/shared/provider-safety.js +6 -0
- package/dist-server/vps-container-mcp.js +9 -0
- package/package.json +1 -1
- package/dist/assets/index-BLJ7byG3.js +0 -296
- package/dist/assets/index-De2TRLxu.css +0 -1
- package/dist-server/server/auto-review.js +0 -79
|
@@ -9752,8 +9752,8 @@ var capitalizeFirstCharacter, error28;
|
|
|
9752
9752
|
var init_lt = __esm({
|
|
9753
9753
|
"node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/lt.js"() {
|
|
9754
9754
|
init_util();
|
|
9755
|
-
capitalizeFirstCharacter = (
|
|
9756
|
-
return
|
|
9755
|
+
capitalizeFirstCharacter = (text4) => {
|
|
9756
|
+
return text4.charAt(0).toUpperCase() + text4.slice(1);
|
|
9757
9757
|
};
|
|
9758
9758
|
error28 = () => {
|
|
9759
9759
|
const Sizable = {
|
|
@@ -17585,8 +17585,8 @@ var init_mcp_registry = __esm({
|
|
|
17585
17585
|
});
|
|
17586
17586
|
|
|
17587
17587
|
// server/schema.ts
|
|
17588
|
-
function parseJson(
|
|
17589
|
-
return JSON.parse(
|
|
17588
|
+
function parseJson(text4) {
|
|
17589
|
+
return JSON.parse(text4);
|
|
17590
17590
|
}
|
|
17591
17591
|
function schemaIssue(error51, fallback) {
|
|
17592
17592
|
const issue2 = error51.issues[0];
|
|
@@ -17782,7 +17782,7 @@ function saveConfig(patch, options = {}) {
|
|
|
17782
17782
|
const checkedPatch = appConfigSchema.partial().parse(patch);
|
|
17783
17783
|
const storedProfiles = storedBrowserProfilesSchema.safeParse(disk.browserProfiles);
|
|
17784
17784
|
if (storedProfiles.success) disk.browserProfiles = storedProfiles.data;
|
|
17785
|
-
for (const key of ["xai", "anthropic", "openaiCompat", "composio", "box", "opencodeGo", "tts", "imageGen", "profile", "rooms", "threads", "localVm", "features", "budgets", "billing"]) {
|
|
17785
|
+
for (const key of ["xai", "anthropic", "openaiCompat", "composio", "box", "opencodeGo", "tts", "imageGen", "profile", "rooms", "threads", "localVm", "features", "budgets", "billing", "onboarding"]) {
|
|
17786
17786
|
const section = checkedPatch[key];
|
|
17787
17787
|
if (!section) continue;
|
|
17788
17788
|
const current = jsonObjectSchema.safeParse(disk[key]);
|
|
@@ -17905,7 +17905,7 @@ function instanceConfigs(cfg) {
|
|
|
17905
17905
|
}
|
|
17906
17906
|
return map3;
|
|
17907
17907
|
}
|
|
17908
|
-
var optionalText, SSH_ALIAS, LEGACY_BROWSER_PROFILE_ID, BROWSER_PROFILE_ID, MIN_ROOM_TURN_TIMEOUT_MINUTES, MAX_ROOM_TURN_TIMEOUT_MINUTES, MAX_CONCURRENT_BOT_THREADS, MIN_LOCAL_VM_MAX_INSTANCES, MAX_LOCAL_VM_MAX_INSTANCES, vpsConfigSchema, roomConfigSchema, localVmConfigSchema, browserProfileSchema, legacyBrowserProfileSchema, legacyBrowserProfilesSchema, storedBrowserProfilesSchema, browserProfilesSchema, featureConfigSchema, instanceConfigSchema, instanceConfigMapSchema, defaultModelSelectionSchema, appConfigSchema, storedAppConfigSchema, appConfigPatchSchema, jsonObjectSchema, DATA_DIR, LEGACY_DATA_DIR, EVENTS_DIR, NATIVE_DIR, WORKSPACE_CREDENTIAL_ENV, PROVIDER_CREDENTIAL_ENV;
|
|
17908
|
+
var optionalText, SSH_ALIAS, LEGACY_BROWSER_PROFILE_ID, BROWSER_PROFILE_ID, MIN_ROOM_TURN_TIMEOUT_MINUTES, MAX_ROOM_TURN_TIMEOUT_MINUTES, MAX_CONCURRENT_BOT_THREADS, MIN_LOCAL_VM_MAX_INSTANCES, MAX_LOCAL_VM_MAX_INSTANCES, vpsConfigSchema, roomConfigSchema, localVmConfigSchema, browserProfileSchema, legacyBrowserProfileSchema, legacyBrowserProfilesSchema, storedBrowserProfilesSchema, browserProfilesSchema, featureConfigSchema, onboardingConfigSchema, instanceConfigSchema, instanceConfigMapSchema, defaultModelSelectionSchema, appConfigSchema, storedAppConfigSchema, appConfigPatchSchema, jsonObjectSchema, DATA_DIR, LEGACY_DATA_DIR, EVENTS_DIR, NATIVE_DIR, WORKSPACE_CREDENTIAL_ENV, PROVIDER_CREDENTIAL_ENV;
|
|
17909
17909
|
var init_config = __esm({
|
|
17910
17910
|
"server/config.ts"() {
|
|
17911
17911
|
"use strict";
|
|
@@ -17979,6 +17979,14 @@ var init_config = __esm({
|
|
|
17979
17979
|
* also has its own switch. */
|
|
17980
17980
|
browser: external_exports.boolean().optional()
|
|
17981
17981
|
});
|
|
17982
|
+
onboardingConfigSchema = external_exports.object({
|
|
17983
|
+
/** ISO timestamp of finishing (or skipping to the end of) the welcome flow. */
|
|
17984
|
+
completedAt: external_exports.string().trim().max(40).optional(),
|
|
17985
|
+
/** Which welcome flow was completed; a newer flow may re-show itself. */
|
|
17986
|
+
version: external_exports.number().int().min(0).max(1e3).optional(),
|
|
17987
|
+
reelSeen: external_exports.boolean().optional(),
|
|
17988
|
+
hintsSeen: external_exports.array(external_exports.string().trim().min(1).max(60)).max(100).optional()
|
|
17989
|
+
}).strict();
|
|
17982
17990
|
instanceConfigSchema = external_exports.object({
|
|
17983
17991
|
driver: external_exports.string().min(1),
|
|
17984
17992
|
displayName: optionalText,
|
|
@@ -18072,6 +18080,7 @@ var init_config = __esm({
|
|
|
18072
18080
|
threads: external_exports.object({ maxConcurrentPerBot: external_exports.number().int().min(1).max(MAX_CONCURRENT_BOT_THREADS) }).strict().optional(),
|
|
18073
18081
|
localVm: localVmConfigSchema.optional(),
|
|
18074
18082
|
features: featureConfigSchema.optional(),
|
|
18083
|
+
onboarding: onboardingConfigSchema.optional(),
|
|
18075
18084
|
browserProfiles: browserProfilesSchema.optional(),
|
|
18076
18085
|
instances: instanceConfigMapSchema.optional(),
|
|
18077
18086
|
/** User-configured MCP servers, mounted into every capable engine. Kept
|
|
@@ -18622,14 +18631,14 @@ function nodeExe(near) {
|
|
|
18622
18631
|
return process.versions.electron ? null : process.execPath;
|
|
18623
18632
|
}
|
|
18624
18633
|
function parseCmdShim(shim) {
|
|
18625
|
-
let
|
|
18634
|
+
let text4;
|
|
18626
18635
|
try {
|
|
18627
|
-
|
|
18636
|
+
text4 = readFileSync6(shim, "utf8");
|
|
18628
18637
|
} catch {
|
|
18629
18638
|
return null;
|
|
18630
18639
|
}
|
|
18631
18640
|
const dir = dirname4(shim);
|
|
18632
|
-
const targets = [...
|
|
18641
|
+
const targets = [...text4.matchAll(/"%~?dp0%?\\?([^"]+)"/g)].map((m) => join9(dir, m[1])).filter((p) => isFile(p) && basename2(p).toLowerCase() !== "node.exe");
|
|
18633
18642
|
const script = targets.find((p) => /\.[cm]?js$/i.test(p));
|
|
18634
18643
|
if (script) {
|
|
18635
18644
|
const node = nodeExe(dir);
|
|
@@ -18728,6 +18737,7 @@ function spawnCli(cli, args, opts) {
|
|
|
18728
18737
|
// win32: taskkill /T does the reaping instead (see killCliTree)
|
|
18729
18738
|
...process.platform === "win32" ? { windowsHide: true } : { detached: true }
|
|
18730
18739
|
});
|
|
18740
|
+
if (process.platform !== "win32") cliGroups.add(child);
|
|
18731
18741
|
child.stdin?.on("error", () => {
|
|
18732
18742
|
});
|
|
18733
18743
|
return child;
|
|
@@ -18760,8 +18770,59 @@ function describeSpawnFailure(err, cli) {
|
|
|
18760
18770
|
return { message: `spawn failed: ${err.message}`, setup: false };
|
|
18761
18771
|
}
|
|
18762
18772
|
function killCliTree(child, timeoutMs = 5e3) {
|
|
18773
|
+
const existing = stopping.get(child);
|
|
18774
|
+
if (existing) return existing;
|
|
18763
18775
|
const pid = child.pid;
|
|
18764
|
-
if (!pid
|
|
18776
|
+
if (!pid) return Promise.resolve(true);
|
|
18777
|
+
if (!Number.isInteger(pid) || pid <= 1 || pid === process.pid) return Promise.resolve(false);
|
|
18778
|
+
const run3 = stopCliTree(child, pid, Number.isFinite(timeoutMs) ? Math.max(0, timeoutMs) : 5e3);
|
|
18779
|
+
stopping.set(child, run3);
|
|
18780
|
+
void run3.then((stopped) => {
|
|
18781
|
+
if (!stopped) stopping.delete(child);
|
|
18782
|
+
});
|
|
18783
|
+
return run3;
|
|
18784
|
+
}
|
|
18785
|
+
async function stopCliTree(child, pid, timeoutMs) {
|
|
18786
|
+
const exited = () => child.exitCode !== null || child.signalCode !== null;
|
|
18787
|
+
if (process.platform !== "win32") {
|
|
18788
|
+
const group = cliGroups.has(child);
|
|
18789
|
+
const settled = () => {
|
|
18790
|
+
if (!exited()) return false;
|
|
18791
|
+
if (!group) return true;
|
|
18792
|
+
try {
|
|
18793
|
+
process.kill(-pid, 0);
|
|
18794
|
+
return false;
|
|
18795
|
+
} catch (error51) {
|
|
18796
|
+
return error51.code === "ESRCH";
|
|
18797
|
+
}
|
|
18798
|
+
};
|
|
18799
|
+
const signal = (value) => {
|
|
18800
|
+
try {
|
|
18801
|
+
if (group) process.kill(-pid, value);
|
|
18802
|
+
else child.kill(value);
|
|
18803
|
+
} catch {
|
|
18804
|
+
try {
|
|
18805
|
+
child.kill(value);
|
|
18806
|
+
} catch {
|
|
18807
|
+
}
|
|
18808
|
+
}
|
|
18809
|
+
};
|
|
18810
|
+
const wait2 = async (ms) => {
|
|
18811
|
+
const deadline = Date.now() + ms;
|
|
18812
|
+
while (!settled()) {
|
|
18813
|
+
const remaining = deadline - Date.now();
|
|
18814
|
+
if (remaining <= 0) return false;
|
|
18815
|
+
await new Promise((resolve13) => setTimeout(resolve13, Math.min(25, remaining)));
|
|
18816
|
+
}
|
|
18817
|
+
return true;
|
|
18818
|
+
};
|
|
18819
|
+
if (settled()) return true;
|
|
18820
|
+
signal("SIGTERM");
|
|
18821
|
+
if (await wait2(timeoutMs)) return true;
|
|
18822
|
+
signal("SIGKILL");
|
|
18823
|
+
return wait2(1e3);
|
|
18824
|
+
}
|
|
18825
|
+
if (exited()) return true;
|
|
18765
18826
|
return new Promise((resolve13) => {
|
|
18766
18827
|
let timer;
|
|
18767
18828
|
const done = (stopped) => {
|
|
@@ -18773,35 +18834,26 @@ function killCliTree(child, timeoutMs = 5e3) {
|
|
|
18773
18834
|
child.once("close", closed);
|
|
18774
18835
|
timer = setTimeout(() => done(false), timeoutMs);
|
|
18775
18836
|
timer.unref?.();
|
|
18776
|
-
|
|
18777
|
-
|
|
18778
|
-
if (!err) return;
|
|
18779
|
-
try {
|
|
18780
|
-
child.kill();
|
|
18781
|
-
} catch {
|
|
18782
|
-
}
|
|
18783
|
-
});
|
|
18784
|
-
return;
|
|
18785
|
-
}
|
|
18786
|
-
try {
|
|
18787
|
-
process.kill(-pid, "SIGTERM");
|
|
18788
|
-
} catch {
|
|
18837
|
+
execFile3("taskkill", ["/PID", String(pid), "/T", "/F"], { windowsHide: true }, (err) => {
|
|
18838
|
+
if (!err) return;
|
|
18789
18839
|
try {
|
|
18790
|
-
child.kill(
|
|
18840
|
+
child.kill();
|
|
18791
18841
|
} catch {
|
|
18792
18842
|
}
|
|
18793
|
-
}
|
|
18843
|
+
});
|
|
18794
18844
|
});
|
|
18795
18845
|
}
|
|
18796
18846
|
function brokerSocketPath(dataDir, tag) {
|
|
18797
18847
|
return process.platform === "win32" ? `\\\\.\\pipe\\openmausbot-perm-${process.pid}-${tag}` : join10(dataDir, `perm-${tag}.sock`);
|
|
18798
18848
|
}
|
|
18799
|
-
var WINDOWS_SAFE_COMMAND_LINE_CHARS;
|
|
18849
|
+
var WINDOWS_SAFE_COMMAND_LINE_CHARS, cliGroups, stopping;
|
|
18800
18850
|
var init_procs = __esm({
|
|
18801
18851
|
"server/procs.ts"() {
|
|
18802
18852
|
"use strict";
|
|
18803
18853
|
init_env_path();
|
|
18804
18854
|
WINDOWS_SAFE_COMMAND_LINE_CHARS = 3e4;
|
|
18855
|
+
cliGroups = /* @__PURE__ */ new WeakSet();
|
|
18856
|
+
stopping = /* @__PURE__ */ new WeakMap();
|
|
18805
18857
|
}
|
|
18806
18858
|
});
|
|
18807
18859
|
|
|
@@ -18888,19 +18940,19 @@ function runNpm(args, env, cwd, timeoutMs) {
|
|
|
18888
18940
|
let timedOut = false;
|
|
18889
18941
|
const timer = setTimeout(() => {
|
|
18890
18942
|
timedOut = true;
|
|
18891
|
-
void killCliTree(child)
|
|
18943
|
+
void killCliTree(child).then((stopped) => {
|
|
18944
|
+
rejectRun(new Error(stopped ? "The install took too long and was stopped. Check the server's network connection and try again." : "The install took too long, but npm could not be confirmed stopped. Ask the server administrator to stop the install process before trying again."));
|
|
18945
|
+
});
|
|
18892
18946
|
}, timeoutMs);
|
|
18893
18947
|
timer.unref();
|
|
18894
18948
|
child.once("error", (error51) => {
|
|
18949
|
+
if (timedOut) return;
|
|
18895
18950
|
clearTimeout(timer);
|
|
18896
18951
|
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."));
|
|
18897
18952
|
});
|
|
18898
18953
|
child.once("close", (code) => {
|
|
18899
18954
|
clearTimeout(timer);
|
|
18900
|
-
if (timedOut)
|
|
18901
|
-
rejectRun(new Error("The install took too long and was stopped. Check the server's network connection and try again."));
|
|
18902
|
-
return;
|
|
18903
|
-
}
|
|
18955
|
+
if (timedOut) return;
|
|
18904
18956
|
resolveRun({ code, output });
|
|
18905
18957
|
});
|
|
18906
18958
|
});
|
|
@@ -19515,6 +19567,7 @@ var init_container_computer = __esm({
|
|
|
19515
19567
|
// shared/approval-mode.ts
|
|
19516
19568
|
function supportsApprovalMode(driverKind, mode) {
|
|
19517
19569
|
if (mode === "custom") return driverKind === "codex";
|
|
19570
|
+
if (mode === "edits") return ["claudeAgent", "grokAgent", "antigravityAgent"].includes(driverKind ?? "");
|
|
19518
19571
|
if (mode !== "full") return true;
|
|
19519
19572
|
return ["codex", "claudeAgent", "antigravityAgent", "cursorAgent", "grokAgent", "opencodeGo"].includes(driverKind ?? "");
|
|
19520
19573
|
}
|
|
@@ -19530,9 +19583,9 @@ function isSecretName(name) {
|
|
|
19530
19583
|
if (SECRET_KEY_PARTS.some((part) => lower.includes(part))) return true;
|
|
19531
19584
|
return /(^|[_.-])keys?$/.test(lower);
|
|
19532
19585
|
}
|
|
19533
|
-
function redactSecretsInText(
|
|
19534
|
-
if (!
|
|
19535
|
-
let out =
|
|
19586
|
+
function redactSecretsInText(text4) {
|
|
19587
|
+
if (!text4 || text4.length < 8) return text4;
|
|
19588
|
+
let out = text4;
|
|
19536
19589
|
out = out.replace(PEM_BLOCK, (_m, open2, body, close) => `${open2}
|
|
19537
19590
|
${mask(body.trim())}
|
|
19538
19591
|
${close}`);
|
|
@@ -19643,8 +19696,8 @@ function askInputSummary(input) {
|
|
|
19643
19696
|
if (typeof fields.question === "string") return cut(fields.question, QUESTION_LIMIT);
|
|
19644
19697
|
if (typeof fields.command === "string") return cut(fields.command, LIMIT);
|
|
19645
19698
|
if (typeof fields.url === "string") return cut(fields.url, LIMIT);
|
|
19646
|
-
const
|
|
19647
|
-
return
|
|
19699
|
+
const text4 = JSON.stringify(fields);
|
|
19700
|
+
return text4 === "{}" ? void 0 : cut(text4, LIMIT);
|
|
19648
19701
|
}
|
|
19649
19702
|
var QUESTION_LIMIT, LIMIT, cut;
|
|
19650
19703
|
var init_tool_summary = __esm({
|
|
@@ -19653,7 +19706,7 @@ var init_tool_summary = __esm({
|
|
|
19653
19706
|
init_redact();
|
|
19654
19707
|
QUESTION_LIMIT = 300;
|
|
19655
19708
|
LIMIT = 200;
|
|
19656
|
-
cut = (
|
|
19709
|
+
cut = (text4, limit) => redactSecretsInText(text4).trim().slice(0, limit);
|
|
19657
19710
|
}
|
|
19658
19711
|
});
|
|
19659
19712
|
|
|
@@ -19676,11 +19729,11 @@ function sanitizeToolLogValue(value, budget, depth = 0) {
|
|
|
19676
19729
|
if (typeof value === "string") {
|
|
19677
19730
|
if (/^data:image\//iu.test(value) || budget.text <= 0) return void 0;
|
|
19678
19731
|
const limit = Math.min(TOOL_LOG_TEXT_LIMIT, budget.text);
|
|
19679
|
-
const
|
|
19732
|
+
const text4 = value.length <= limit ? value : `[Earlier output truncated]
|
|
19680
19733
|
|
|
19681
19734
|
${value.slice(-limit)}`;
|
|
19682
|
-
budget.text -=
|
|
19683
|
-
return
|
|
19735
|
+
budget.text -= text4.length;
|
|
19736
|
+
return text4;
|
|
19684
19737
|
}
|
|
19685
19738
|
if (Array.isArray(value)) {
|
|
19686
19739
|
return value.flatMap((entry) => {
|
|
@@ -19712,6 +19765,20 @@ function decodeAcpConfig(defaultCli) {
|
|
|
19712
19765
|
};
|
|
19713
19766
|
};
|
|
19714
19767
|
}
|
|
19768
|
+
function sessionOperationKey(toolCall) {
|
|
19769
|
+
const rawInput = toolCall?.rawInput;
|
|
19770
|
+
const command = typeof rawInput?.command === "string" ? rawInput.command : void 0;
|
|
19771
|
+
const hasInput = rawInput && typeof rawInput === "object" && Object.keys(rawInput).length > 0;
|
|
19772
|
+
if (!command && !hasInput) return null;
|
|
19773
|
+
const stable = (value) => Array.isArray(value) ? value.map(stable) : value && typeof value === "object" ? Object.fromEntries(Object.keys(value).sort().map((key) => [key, stable(value[key])])) : value;
|
|
19774
|
+
return JSON.stringify(stable({
|
|
19775
|
+
kind: toolCall?.kind,
|
|
19776
|
+
title: toolCall?.title,
|
|
19777
|
+
command,
|
|
19778
|
+
input: rawInput,
|
|
19779
|
+
locations: toolCall?.locations
|
|
19780
|
+
}));
|
|
19781
|
+
}
|
|
19715
19782
|
function createAcpDriver(support11) {
|
|
19716
19783
|
const DRIVER_KIND8 = support11.driverKind;
|
|
19717
19784
|
const SOURCE = support11.nativeSource;
|
|
@@ -19755,6 +19822,7 @@ function createAcpDriver(support11) {
|
|
|
19755
19822
|
if (support11.resolveModelsOnCreate !== false) await refreshModels();
|
|
19756
19823
|
const listeners = /* @__PURE__ */ new Set();
|
|
19757
19824
|
const active = /* @__PURE__ */ new Map();
|
|
19825
|
+
const sessionAllows = /* @__PURE__ */ new Map();
|
|
19758
19826
|
const emit = (event) => {
|
|
19759
19827
|
for (const listener of listeners) listener(event);
|
|
19760
19828
|
};
|
|
@@ -19972,10 +20040,10 @@ function createAcpDriver(support11) {
|
|
|
19972
20040
|
}
|
|
19973
20041
|
};
|
|
19974
20042
|
const flushAssistantText = () => {
|
|
19975
|
-
const
|
|
20043
|
+
const text4 = state.text;
|
|
19976
20044
|
state.text = "";
|
|
19977
|
-
if (!
|
|
19978
|
-
emit({ ...base2(threadId, turnId), type: "item.completed", itemType: "assistant_text", text:
|
|
20045
|
+
if (!text4.trim()) return;
|
|
20046
|
+
emit({ ...base2(threadId, turnId), type: "item.completed", itemType: "assistant_text", text: text4 });
|
|
19979
20047
|
};
|
|
19980
20048
|
const settle = (ok, stopReason) => {
|
|
19981
20049
|
if (state.settled) return;
|
|
@@ -20004,6 +20072,7 @@ function createAcpDriver(support11) {
|
|
|
20004
20072
|
flushAssistantText();
|
|
20005
20073
|
const options = Array.isArray(params.options) ? params.options : [];
|
|
20006
20074
|
const optionFor = (want) => options.find((o) => o.kind === `${want}_once` && typeof o.optionId === "string")?.optionId ?? options.find((o) => String(o.kind ?? "").startsWith(want) && typeof o.optionId === "string")?.optionId ?? null;
|
|
20075
|
+
const optionAlways = options.find((o) => o.kind === "allow_always" && typeof o.optionId === "string")?.optionId ?? null;
|
|
20007
20076
|
const cancelled = { outcome: { outcome: "cancelled" } };
|
|
20008
20077
|
const missing = (want) => emit({
|
|
20009
20078
|
...base2(threadId, turnId),
|
|
@@ -20022,15 +20091,28 @@ function createAcpDriver(support11) {
|
|
|
20022
20091
|
});
|
|
20023
20092
|
}
|
|
20024
20093
|
const kind = String(toolCall.kind ?? "");
|
|
20094
|
+
const operationKey = isQuestion || controlsHost ? null : sessionOperationKey(toolCall);
|
|
20095
|
+
if (operationKey && sessionAllows.get(threadId)?.has(operationKey)) {
|
|
20096
|
+
const allow = optionFor("allow");
|
|
20097
|
+
if (allow) {
|
|
20098
|
+
return send({ jsonrpc: "2.0", id: msg.id, result: { outcome: { outcome: "selected", optionId: allow } } });
|
|
20099
|
+
}
|
|
20100
|
+
}
|
|
20025
20101
|
const tool = kind === "execute" ? "shell" : kind === "edit" ? "edit" : kind || "tool";
|
|
20026
20102
|
const summary = String(toolCall.rawInput?.command ?? toolCall.title ?? tool).slice(0, 200);
|
|
20027
20103
|
const requestId = newId();
|
|
20028
|
-
const finish = (behavior, source = "user", message2) => {
|
|
20104
|
+
const finish = (behavior, source = "user", message2, always) => {
|
|
20029
20105
|
if (!asks.delete(requestId)) return;
|
|
20030
20106
|
clearTimeout(timer);
|
|
20031
20107
|
const want = behavior === "allow" ? "allow" : "reject";
|
|
20108
|
+
const forSession = want === "allow" && always === true && !isQuestion && !controlsHost;
|
|
20032
20109
|
const named = isQuestion && behavior === "answer" ? options.filter((option) => option.optionId === message2 || option.name?.trim() === message2) : [];
|
|
20033
|
-
const optionId = behavior === "cancel" ? null : isQuestion ? named.length === 1 && typeof named[0].optionId === "string" ? named[0].optionId : null : optionFor(want);
|
|
20110
|
+
const optionId = behavior === "cancel" ? null : isQuestion ? named.length === 1 && typeof named[0].optionId === "string" ? named[0].optionId : null : forSession ? optionAlways ?? optionFor("allow") : optionFor(want);
|
|
20111
|
+
if (forSession && !optionAlways && optionId && operationKey) {
|
|
20112
|
+
const remembered = sessionAllows.get(threadId) ?? /* @__PURE__ */ new Set();
|
|
20113
|
+
remembered.add(operationKey);
|
|
20114
|
+
sessionAllows.set(threadId, remembered);
|
|
20115
|
+
}
|
|
20034
20116
|
if (behavior !== "cancel" && !optionId) missing(isQuestion ? "matching answer" : want);
|
|
20035
20117
|
send({
|
|
20036
20118
|
jsonrpc: "2.0",
|
|
@@ -20060,7 +20142,9 @@ function createAcpDriver(support11) {
|
|
|
20060
20142
|
tool,
|
|
20061
20143
|
summary,
|
|
20062
20144
|
choices: isQuestion ? options.flatMap((option) => typeof option.name === "string" && option.name.trim() ? [option.name.trim()] : []) : void 0,
|
|
20063
|
-
approvalScope: controlsHost ? "local-computer" : void 0
|
|
20145
|
+
approvalScope: controlsHost ? "local-computer" : void 0,
|
|
20146
|
+
// the driver can honor a session-wide allow either way
|
|
20147
|
+
allowSession: !isQuestion && !controlsHost ? true : void 0
|
|
20064
20148
|
});
|
|
20065
20149
|
};
|
|
20066
20150
|
const handleNotification = (msg) => {
|
|
@@ -20215,13 +20299,14 @@ function createAcpDriver(support11) {
|
|
|
20215
20299
|
}
|
|
20216
20300
|
}
|
|
20217
20301
|
const images = turn.images ?? [];
|
|
20218
|
-
const runtimeAcceptsImages = init?.agentCapabilities?.promptCapabilities?.image === true;
|
|
20302
|
+
const runtimeAcceptsImages = init?.agentCapabilities?.promptCapabilities?.image === true || support11.acceptsUnadvertisedImages?.(init) === true;
|
|
20219
20303
|
if (images.length && support11.images === true && !runtimeAcceptsImages) {
|
|
20220
20304
|
throw new Error(
|
|
20221
20305
|
`${support11.displayName} is configured for image attachments, but this installed runtime does not advertise ACP image input. Update the ${support11.displayName} CLI or send the message without an image.`
|
|
20222
20306
|
);
|
|
20223
20307
|
}
|
|
20224
20308
|
const cursor3 = typeof turn.resumeCursor === "string" ? turn.resumeCursor : null;
|
|
20309
|
+
if (!cursor3) sessionAllows.delete(threadId);
|
|
20225
20310
|
let sessionResult = null;
|
|
20226
20311
|
if (cursor3) {
|
|
20227
20312
|
try {
|
|
@@ -20287,13 +20372,13 @@ function createAcpDriver(support11) {
|
|
|
20287
20372
|
}
|
|
20288
20373
|
emitSessionStarted();
|
|
20289
20374
|
state.promptSent = true;
|
|
20290
|
-
const
|
|
20375
|
+
const text4 = support11.buildPromptText ? support11.buildPromptText(turn) : turn.system ? `${turn.system}
|
|
20291
20376
|
|
|
20292
20377
|
${turn.text}` : turn.text;
|
|
20293
20378
|
const imageBlocks = support11.images === true && runtimeAcceptsImages ? await readAcpImageBlocks(images) : [];
|
|
20294
20379
|
const result = await request("session/prompt", {
|
|
20295
20380
|
sessionId,
|
|
20296
|
-
prompt: [{ type: "text", text:
|
|
20381
|
+
prompt: [{ type: "text", text: text4 }, ...imageBlocks]
|
|
20297
20382
|
});
|
|
20298
20383
|
const usage = result?.usage ?? result?._meta ?? {};
|
|
20299
20384
|
if (typeof usage.inputTokens === "number" || typeof usage.outputTokens === "number") {
|
|
@@ -20380,7 +20465,7 @@ ${turn.text}` : turn.text;
|
|
|
20380
20465
|
const turn = active.get(threadId);
|
|
20381
20466
|
const finish = turn?.asks.get(requestId);
|
|
20382
20467
|
if (!finish) return "unavailable";
|
|
20383
|
-
finish(decision.behavior, "user", decision.message);
|
|
20468
|
+
finish(decision.behavior, "user", decision.message, decision.always === true);
|
|
20384
20469
|
return decision.behavior === "allow" ? "allowed-once" : decision.behavior === "answer" ? "answered" : "rejected";
|
|
20385
20470
|
},
|
|
20386
20471
|
hasSession: (threadId) => active.has(threadId),
|
|
@@ -20715,6 +20800,7 @@ var init_antigravity_acp = __esm({
|
|
|
20715
20800
|
startupDiagnosticBytes = 0;
|
|
20716
20801
|
nativeStartupHint;
|
|
20717
20802
|
closed = false;
|
|
20803
|
+
stopping;
|
|
20718
20804
|
onAuthorizationUrl;
|
|
20719
20805
|
/** Settles once the runtime process is gone. On Windows a running
|
|
20720
20806
|
* executable pins its file and its directory, so an installer must not
|
|
@@ -20839,10 +20925,10 @@ var init_antigravity_acp = __esm({
|
|
|
20839
20925
|
if (this.closed) return;
|
|
20840
20926
|
this.closed = true;
|
|
20841
20927
|
this.failAll(new Error("Antigravity ACP was closed."));
|
|
20842
|
-
killCliTree(this.child);
|
|
20928
|
+
this.stopping = killCliTree(this.child);
|
|
20843
20929
|
}
|
|
20844
|
-
/**
|
|
20845
|
-
async closeAndWait(timeoutMs =
|
|
20930
|
+
/** Allow the shared 5s TERM grace and 1s force-stop verification to finish. */
|
|
20931
|
+
async closeAndWait(timeoutMs = 7e3) {
|
|
20846
20932
|
this.close();
|
|
20847
20933
|
let timer;
|
|
20848
20934
|
const timedOut = new Promise((resolve13) => {
|
|
@@ -20850,7 +20936,7 @@ var init_antigravity_acp = __esm({
|
|
|
20850
20936
|
timer.unref?.();
|
|
20851
20937
|
});
|
|
20852
20938
|
try {
|
|
20853
|
-
return await Promise.race([this.
|
|
20939
|
+
return await Promise.race([this.stopping, timedOut]);
|
|
20854
20940
|
} finally {
|
|
20855
20941
|
clearTimeout(timer);
|
|
20856
20942
|
}
|
|
@@ -21373,8 +21459,9 @@ var init_antigravity_runtime = __esm({
|
|
|
21373
21459
|
});
|
|
21374
21460
|
|
|
21375
21461
|
// server/drivers/antigravity.ts
|
|
21376
|
-
function antigravityPermissionMode(fullAuto) {
|
|
21377
|
-
|
|
21462
|
+
function antigravityPermissionMode(fullAuto, approvalMode) {
|
|
21463
|
+
if (fullAuto) return "yolo";
|
|
21464
|
+
return approvalMode === "edits" ? "auto_edit" : "default";
|
|
21378
21465
|
}
|
|
21379
21466
|
var STATIC_ANTIGRAVITY_MODELS, managedAsset, support, AcpAntigravityDriver, AntigravityDriver;
|
|
21380
21467
|
var init_antigravity = __esm({
|
|
@@ -21458,8 +21545,8 @@ var init_antigravity = __esm({
|
|
|
21458
21545
|
return { state: "unavailable", reason: error51 instanceof Error ? error51.message : String(error51) };
|
|
21459
21546
|
}
|
|
21460
21547
|
},
|
|
21461
|
-
configureSession: async ({ request, sessionId, config: config2 }) => {
|
|
21462
|
-
const wanted = antigravityPermissionMode(config2.fullAuto);
|
|
21548
|
+
configureSession: async ({ request, sessionId, config: config2, turn }) => {
|
|
21549
|
+
const wanted = antigravityPermissionMode(config2.fullAuto, turn.approvalMode);
|
|
21463
21550
|
const result = await request("session/set_config_option", {
|
|
21464
21551
|
sessionId,
|
|
21465
21552
|
configId: "mode",
|
|
@@ -21619,14 +21706,14 @@ var init_boxagent = __esm({
|
|
|
21619
21706
|
let lastText = "";
|
|
21620
21707
|
let pendingText = "";
|
|
21621
21708
|
const flushAssistantText = () => {
|
|
21622
|
-
const
|
|
21709
|
+
const text4 = pendingText;
|
|
21623
21710
|
pendingText = "";
|
|
21624
|
-
if (!
|
|
21625
|
-
emit({ ...base2(threadId, turnId), type: "item.completed", itemType: "assistant_text", text:
|
|
21711
|
+
if (!text4.trim()) return;
|
|
21712
|
+
emit({ ...base2(threadId, turnId), type: "item.completed", itemType: "assistant_text", text: text4 });
|
|
21626
21713
|
};
|
|
21627
|
-
const ingest = (
|
|
21628
|
-
const delta =
|
|
21629
|
-
lastText =
|
|
21714
|
+
const ingest = (text4) => {
|
|
21715
|
+
const delta = text4.startsWith(lastText) ? text4.slice(lastText.length) : text4;
|
|
21716
|
+
lastText = text4;
|
|
21630
21717
|
if (!delta) return;
|
|
21631
21718
|
pendingText += delta;
|
|
21632
21719
|
emit({ ...base2(threadId, turnId), type: "content.delta", streamKind: "assistant_text", delta });
|
|
@@ -21643,9 +21730,9 @@ var init_boxagent = __esm({
|
|
|
21643
21730
|
seen.add(id);
|
|
21644
21731
|
appendNative(threadId, { dir: "in", source: "box.events", msg: ev });
|
|
21645
21732
|
const kind = String(ev.type ?? ev.kind ?? "");
|
|
21646
|
-
const
|
|
21647
|
-
if (/assistant|message|output|response/i.test(kind) && typeof
|
|
21648
|
-
ingest(
|
|
21733
|
+
const text4 = ev.text ?? ev.message ?? ev.data?.text ?? ev.data?.content ?? null;
|
|
21734
|
+
if (/assistant|message|output|response/i.test(kind) && typeof text4 === "string" && text4.trim()) {
|
|
21735
|
+
ingest(text4);
|
|
21649
21736
|
} else if (/tool|command|exec|browse/i.test(kind)) {
|
|
21650
21737
|
flushAssistantText();
|
|
21651
21738
|
emit({
|
|
@@ -22185,25 +22272,36 @@ var init_mcp_gate_config = __esm({
|
|
|
22185
22272
|
}
|
|
22186
22273
|
});
|
|
22187
22274
|
|
|
22275
|
+
// shared/provider-safety.ts
|
|
22276
|
+
function isProviderSafetyBlock(message2) {
|
|
22277
|
+
return /\bblocked by (?:our|the provider['’]s) safety systems\b|\bsafety monitoring\b.{0,100}\b(?:paused|ended|blocked)\b|\b(?:safety_check_failed|safety_policy_violation)\b/i.test(message2);
|
|
22278
|
+
}
|
|
22279
|
+
var init_provider_safety = __esm({
|
|
22280
|
+
"shared/provider-safety.ts"() {
|
|
22281
|
+
"use strict";
|
|
22282
|
+
}
|
|
22283
|
+
});
|
|
22284
|
+
|
|
22188
22285
|
// server/drivers/retry.ts
|
|
22189
22286
|
function classifyError(err) {
|
|
22190
|
-
const
|
|
22287
|
+
const text4 = messageOf(err);
|
|
22288
|
+
if (isProviderSafetyBlock(text4)) return { transient: false, reason: "provider_safety" };
|
|
22191
22289
|
if (err && "exitCode" in err) {
|
|
22192
22290
|
const { exitCode: code } = err;
|
|
22193
22291
|
if (code !== null && code < 0) return { transient: false, reason: "interrupted" };
|
|
22194
22292
|
for (const { pattern, reason } of TRANSIENT_PATTERNS) {
|
|
22195
|
-
if (pattern.test(
|
|
22293
|
+
if (pattern.test(text4)) return { transient: true, reason };
|
|
22196
22294
|
}
|
|
22197
22295
|
for (const { pattern, reason } of TERMINAL_PATTERNS) {
|
|
22198
|
-
if (pattern.test(
|
|
22296
|
+
if (pattern.test(text4)) return { transient: false, reason };
|
|
22199
22297
|
}
|
|
22200
22298
|
return { transient: false, reason: "terminal_exit" };
|
|
22201
22299
|
}
|
|
22202
22300
|
for (const { pattern, reason } of TERMINAL_PATTERNS) {
|
|
22203
|
-
if (pattern.test(
|
|
22301
|
+
if (pattern.test(text4)) return { transient: false, reason };
|
|
22204
22302
|
}
|
|
22205
22303
|
for (const { pattern, reason } of TRANSIENT_PATTERNS) {
|
|
22206
|
-
if (pattern.test(
|
|
22304
|
+
if (pattern.test(text4)) return { transient: true, reason };
|
|
22207
22305
|
}
|
|
22208
22306
|
return { transient: false, reason: "unknown" };
|
|
22209
22307
|
}
|
|
@@ -22234,6 +22332,7 @@ var RETRY_MAX_ATTEMPTS, BACKOFF_BASE_MS, TRANSIENT_PATTERNS, TERMINAL_PATTERNS,
|
|
|
22234
22332
|
var init_retry = __esm({
|
|
22235
22333
|
"server/drivers/retry.ts"() {
|
|
22236
22334
|
"use strict";
|
|
22335
|
+
init_provider_safety();
|
|
22237
22336
|
RETRY_MAX_ATTEMPTS = 3;
|
|
22238
22337
|
BACKOFF_BASE_MS = [1e3, 3e3, 8e3];
|
|
22239
22338
|
TRANSIENT_PATTERNS = [
|
|
@@ -22268,6 +22367,82 @@ var init_retry = __esm({
|
|
|
22268
22367
|
}
|
|
22269
22368
|
});
|
|
22270
22369
|
|
|
22370
|
+
// shared/ask-question.ts
|
|
22371
|
+
function text3(value, limit) {
|
|
22372
|
+
if (typeof value !== "string") return void 0;
|
|
22373
|
+
const trimmed = value.trim();
|
|
22374
|
+
return trimmed ? trimmed.slice(0, limit) : void 0;
|
|
22375
|
+
}
|
|
22376
|
+
function isRecord(value) {
|
|
22377
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
22378
|
+
}
|
|
22379
|
+
function parseOption(value) {
|
|
22380
|
+
if (typeof value === "string") {
|
|
22381
|
+
const label2 = text3(value, MAX_LABEL);
|
|
22382
|
+
return label2 ? { label: label2 } : null;
|
|
22383
|
+
}
|
|
22384
|
+
if (!isRecord(value)) return null;
|
|
22385
|
+
const label = text3(value.label, MAX_LABEL);
|
|
22386
|
+
if (!label) return null;
|
|
22387
|
+
const description = text3(value.description, MAX_DESCRIPTION);
|
|
22388
|
+
return description ? { label, description } : { label };
|
|
22389
|
+
}
|
|
22390
|
+
function parseQuestion(value) {
|
|
22391
|
+
if (!isRecord(value)) return null;
|
|
22392
|
+
const question = text3(value.question, MAX_QUESTION_TEXT);
|
|
22393
|
+
if (!question) return null;
|
|
22394
|
+
const options = [];
|
|
22395
|
+
const seen = /* @__PURE__ */ new Set();
|
|
22396
|
+
for (const raw of Array.isArray(value.options) ? value.options : []) {
|
|
22397
|
+
const option = parseOption(raw);
|
|
22398
|
+
if (!option || seen.has(option.label)) continue;
|
|
22399
|
+
seen.add(option.label);
|
|
22400
|
+
options.push(option);
|
|
22401
|
+
if (options.length === MAX_OPTIONS) break;
|
|
22402
|
+
}
|
|
22403
|
+
const header = text3(value.header, MAX_LABEL);
|
|
22404
|
+
return {
|
|
22405
|
+
question,
|
|
22406
|
+
...header ? { header } : {},
|
|
22407
|
+
...value.multiSelect === true ? { multiSelect: true } : {},
|
|
22408
|
+
options
|
|
22409
|
+
};
|
|
22410
|
+
}
|
|
22411
|
+
function parseAskQuestions(input) {
|
|
22412
|
+
if (!isRecord(input) || !Array.isArray(input.questions)) return null;
|
|
22413
|
+
const questions = [];
|
|
22414
|
+
for (const raw of input.questions) {
|
|
22415
|
+
const question = parseQuestion(raw);
|
|
22416
|
+
if (!question) continue;
|
|
22417
|
+
questions.push(question);
|
|
22418
|
+
if (questions.length === MAX_QUESTIONS) break;
|
|
22419
|
+
}
|
|
22420
|
+
return questions.length ? questions : null;
|
|
22421
|
+
}
|
|
22422
|
+
function askQuestionSummary(questions) {
|
|
22423
|
+
const first = questions[0]?.question ?? "";
|
|
22424
|
+
const rest = questions.length - 1;
|
|
22425
|
+
return rest > 0 ? `${first} (+${rest} more question${rest > 1 ? "s" : ""})` : first;
|
|
22426
|
+
}
|
|
22427
|
+
function questionChoices(questions) {
|
|
22428
|
+
if (questions.length !== 1) return void 0;
|
|
22429
|
+
const only = questions[0];
|
|
22430
|
+
if (only.multiSelect || only.options.length < 2) return void 0;
|
|
22431
|
+
return only.options.map((option) => option.label);
|
|
22432
|
+
}
|
|
22433
|
+
var ASK_USER_QUESTION_TOOL, MAX_QUESTIONS, MAX_OPTIONS, MAX_QUESTION_TEXT, MAX_LABEL, MAX_DESCRIPTION;
|
|
22434
|
+
var init_ask_question = __esm({
|
|
22435
|
+
"shared/ask-question.ts"() {
|
|
22436
|
+
"use strict";
|
|
22437
|
+
ASK_USER_QUESTION_TOOL = "AskUserQuestion";
|
|
22438
|
+
MAX_QUESTIONS = 6;
|
|
22439
|
+
MAX_OPTIONS = 12;
|
|
22440
|
+
MAX_QUESTION_TEXT = 400;
|
|
22441
|
+
MAX_LABEL = 120;
|
|
22442
|
+
MAX_DESCRIPTION = 400;
|
|
22443
|
+
}
|
|
22444
|
+
});
|
|
22445
|
+
|
|
22271
22446
|
// server/drivers/claude.ts
|
|
22272
22447
|
import { createHash as createHash5, randomBytes as randomBytes2 } from "node:crypto";
|
|
22273
22448
|
import { chmodSync as chmodSync4, mkdtempSync as mkdtempSync2, readFileSync as readFileSync8, rmSync as rmSync4, unlinkSync as unlinkSync3, writeFileSync as writeFileSync6 } from "node:fs";
|
|
@@ -22308,9 +22483,9 @@ function resolveClaudeConfigDir(configDir, env = process.env) {
|
|
|
22308
22483
|
}
|
|
22309
22484
|
return normalize(expanded);
|
|
22310
22485
|
}
|
|
22311
|
-
function claudeAuthFailure(frame,
|
|
22486
|
+
function claudeAuthFailure(frame, text4) {
|
|
22312
22487
|
if (frame.is_api_error_message !== true && typeof frame.error !== "string") return false;
|
|
22313
|
-
return frame.error === "authentication_failed" || classifyError({ text:
|
|
22488
|
+
return frame.error === "authentication_failed" || classifyError({ text: text4 }).reason === "auth";
|
|
22314
22489
|
}
|
|
22315
22490
|
function claudeEnvironment(model, source = process.env, configDir, instanceEnvironment = {}) {
|
|
22316
22491
|
const env = { ...source, PATH: augmentedPath(), NPM_CONFIG_LOGLEVEL: "error" };
|
|
@@ -22334,6 +22509,24 @@ function claudeEnvironment(model, source = process.env, configDir, instanceEnvir
|
|
|
22334
22509
|
function inheritsUserConfig(env) {
|
|
22335
22510
|
return env.OMB_CLAUDE_INHERIT_USER_CONFIG === "1";
|
|
22336
22511
|
}
|
|
22512
|
+
function readClaudeAuthSettings(env, instanceEnvironment = {}) {
|
|
22513
|
+
if (CLAUDE_ACCOUNT_ENV_KEYS.some((key) => instanceEnvironment[key])) return {};
|
|
22514
|
+
try {
|
|
22515
|
+
const settings2 = JSON.parse(readFileSync8(join20(resolveClaudeConfigDir(void 0, env), "settings.json"), "utf8"));
|
|
22516
|
+
const authEnv = {};
|
|
22517
|
+
for (const key of CLAUDE_ACCOUNT_ENV_KEYS) {
|
|
22518
|
+
if (!key.endsWith("_FILE_DESCRIPTOR") && typeof settings2?.env?.[key] === "string") {
|
|
22519
|
+
authEnv[key] = settings2.env[key];
|
|
22520
|
+
}
|
|
22521
|
+
}
|
|
22522
|
+
return {
|
|
22523
|
+
...Object.keys(authEnv).length ? { env: authEnv } : {},
|
|
22524
|
+
...typeof settings2?.apiKeyHelper === "string" && settings2.apiKeyHelper.trim() ? { apiKeyHelper: settings2.apiKeyHelper } : {}
|
|
22525
|
+
};
|
|
22526
|
+
} catch {
|
|
22527
|
+
return {};
|
|
22528
|
+
}
|
|
22529
|
+
}
|
|
22337
22530
|
function projectMcpServers(cwd) {
|
|
22338
22531
|
let parsed;
|
|
22339
22532
|
try {
|
|
@@ -22438,7 +22631,12 @@ function removePrivateTempDir(filePath) {
|
|
|
22438
22631
|
function systemEndedReply(kind) {
|
|
22439
22632
|
return kind === "question" ? { behavior: "answer", message: "OpenMausBot: the turn is ending \u2014 wrap up." } : { behavior: "deny", message: "OpenMausBot: the turn ended" };
|
|
22440
22633
|
}
|
|
22634
|
+
function askQuestions(ask) {
|
|
22635
|
+
return ask.tool === ASK_USER_QUESTION_TOOL ? parseAskQuestions(ask.input) : null;
|
|
22636
|
+
}
|
|
22441
22637
|
function askSummary(ask) {
|
|
22638
|
+
const questions = askQuestions(ask);
|
|
22639
|
+
if (questions) return askQuestionSummary(questions).slice(0, 300);
|
|
22442
22640
|
return askInputSummary(ask.input) ?? ask.tool ?? "tool";
|
|
22443
22641
|
}
|
|
22444
22642
|
function permissionSocketPath(threadId) {
|
|
@@ -22505,11 +22703,13 @@ async function createPermissionBroker(opts) {
|
|
|
22505
22703
|
continue;
|
|
22506
22704
|
}
|
|
22507
22705
|
const ask = { id: askId, kind, tool: msg.tool ?? "tool", input: msg.input ?? {}, at: Date.now() };
|
|
22508
|
-
const finish = (behavior, message2, source) => {
|
|
22706
|
+
const finish = (behavior, message2, source, always) => {
|
|
22509
22707
|
if (!pending.delete(askId)) return;
|
|
22510
22708
|
clearTimeout(timer);
|
|
22511
22709
|
try {
|
|
22512
|
-
conn.write(
|
|
22710
|
+
conn.write(
|
|
22711
|
+
JSON.stringify({ t: "answer", id: askId, behavior, message: message2, source, ...always ? { always: true } : {} }) + "\n"
|
|
22712
|
+
);
|
|
22513
22713
|
} catch {
|
|
22514
22714
|
}
|
|
22515
22715
|
opts.onResolve({ ...ask, behavior, source });
|
|
@@ -22579,11 +22779,11 @@ async function createPermissionBroker(opts) {
|
|
|
22579
22779
|
}
|
|
22580
22780
|
};
|
|
22581
22781
|
return {
|
|
22582
|
-
answer(askId, behavior, message2) {
|
|
22782
|
+
answer(askId, behavior, message2, always) {
|
|
22583
22783
|
const p = pending.get(askId);
|
|
22584
22784
|
if (!p) return false;
|
|
22585
22785
|
if (p.ask.kind === "question" ? behavior !== "answer" : behavior === "answer") return false;
|
|
22586
|
-
p.finish(behavior, message2, "user");
|
|
22786
|
+
p.finish(behavior, message2, "user", always && behavior === "allow");
|
|
22587
22787
|
return true;
|
|
22588
22788
|
},
|
|
22589
22789
|
pause() {
|
|
@@ -22648,19 +22848,19 @@ function firstText(content) {
|
|
|
22648
22848
|
}
|
|
22649
22849
|
return "";
|
|
22650
22850
|
}
|
|
22651
|
-
function withVolatileNote(
|
|
22851
|
+
function withVolatileNote(text4, volatile) {
|
|
22652
22852
|
const body = volatile.trim() ? `This part of your instructions changed since this session started. It replaces the earlier copy:
|
|
22653
22853
|
|
|
22654
22854
|
${volatile.trim()}` : "The notes that were in your instructions when this session started have been cleared.";
|
|
22655
22855
|
const note = `<system-reminder>
|
|
22656
22856
|
${body}
|
|
22657
22857
|
</system-reminder>`;
|
|
22658
|
-
return
|
|
22858
|
+
return text4 ? `${note}
|
|
22659
22859
|
|
|
22660
|
-
${
|
|
22860
|
+
${text4}` : note;
|
|
22661
22861
|
}
|
|
22662
|
-
function claudeUserMessage(
|
|
22663
|
-
if (!images?.length) return { type: "user", message: { role: "user", content:
|
|
22862
|
+
function claudeUserMessage(text4, images) {
|
|
22863
|
+
if (!images?.length) return { type: "user", message: { role: "user", content: text4 } };
|
|
22664
22864
|
const content = images.map((image) => ({
|
|
22665
22865
|
type: "image",
|
|
22666
22866
|
source: {
|
|
@@ -22669,7 +22869,7 @@ function claudeUserMessage(text3, images) {
|
|
|
22669
22869
|
data: readFileSync8(image.path).toString("base64")
|
|
22670
22870
|
}
|
|
22671
22871
|
}));
|
|
22672
|
-
if (
|
|
22872
|
+
if (text4) content.push({ type: "text", text: text4 });
|
|
22673
22873
|
return { type: "user", message: { role: "user", content } };
|
|
22674
22874
|
}
|
|
22675
22875
|
function diagnosticClaudeUserMessage(message2) {
|
|
@@ -22707,6 +22907,7 @@ var init_claude = __esm({
|
|
|
22707
22907
|
init_local_inject();
|
|
22708
22908
|
init_native();
|
|
22709
22909
|
init_proxy_paths();
|
|
22910
|
+
init_ask_question();
|
|
22710
22911
|
CLAUDE_ACCOUNT_ENV_KEYS = [
|
|
22711
22912
|
"CLAUDE_CODE_OAUTH_TOKEN",
|
|
22712
22913
|
"CLAUDE_CODE_OAUTH_REFRESH_TOKEN",
|
|
@@ -22785,6 +22986,11 @@ var init_claude = __esm({
|
|
|
22785
22986
|
const configuredIdleMinimum = Number(process.env.OMB_CLAUDE_SESSION_IDLE_MIN_MS);
|
|
22786
22987
|
const sessionIdleMinimum = Number.isFinite(configuredIdleMinimum) && configuredIdleMinimum > 0 ? configuredIdleMinimum : 1e4;
|
|
22787
22988
|
const SESSION_IDLE_MS = Math.max(sessionIdleMinimum, Number(process.env.OMB_CLAUDE_SESSION_IDLE_MS) || 10 * 6e4);
|
|
22989
|
+
const stopSession = (session) => {
|
|
22990
|
+
void killCliTree(session.child).then((stopped) => {
|
|
22991
|
+
if (stopped) void session.finishClose?.();
|
|
22992
|
+
});
|
|
22993
|
+
};
|
|
22788
22994
|
const closeSession = (threadId, why) => {
|
|
22789
22995
|
const s = sessions.get(threadId);
|
|
22790
22996
|
if (!s || s.closing) return;
|
|
@@ -22799,7 +23005,7 @@ var init_claude = __esm({
|
|
|
22799
23005
|
} catch {
|
|
22800
23006
|
}
|
|
22801
23007
|
const kill = setTimeout(() => {
|
|
22802
|
-
|
|
23008
|
+
stopSession(s);
|
|
22803
23009
|
}, 5e3);
|
|
22804
23010
|
kill.unref?.();
|
|
22805
23011
|
};
|
|
@@ -22842,7 +23048,7 @@ var init_claude = __esm({
|
|
|
22842
23048
|
const sendTurn = async (turn) => {
|
|
22843
23049
|
const { threadId } = turn;
|
|
22844
23050
|
if (active.has(threadId)) throw new Error("a turn is already running on this thread");
|
|
22845
|
-
const permissionMode = turn.approvalMode === void 0 ? config2.permissionMode : turn.approvalMode === "full" ? "bypassPermissions" : turn.approvalMode === "auto" ? "auto" : "default";
|
|
23051
|
+
const permissionMode = turn.approvalMode === void 0 ? config2.permissionMode : turn.approvalMode === "full" ? "bypassPermissions" : turn.approvalMode === "auto" ? "auto" : turn.approvalMode === "edits" ? "acceptEdits" : "default";
|
|
22846
23052
|
const controlsHost = turn.integrations?.localComputer?.scope === "local-computer";
|
|
22847
23053
|
if (controlsHost && permissionMode === "bypassPermissions" && turn.approvalMode !== "full") {
|
|
22848
23054
|
throw new Error("local computer control requires the interactive approval broker");
|
|
@@ -22966,9 +23172,12 @@ var init_claude = __esm({
|
|
|
22966
23172
|
args.push("--allowedTools", allowed.join(","));
|
|
22967
23173
|
}
|
|
22968
23174
|
const env = environment(turnModel);
|
|
23175
|
+
const authSettings = isolated && !injected.injected ? readClaudeAuthSettings(env, input.environment) : {};
|
|
23176
|
+
const authSettingsPath = mcpConfigPath && Object.keys(authSettings).length ? join20(dirname9(mcpConfigPath), "auth-settings.json") : null;
|
|
23177
|
+
if (authSettingsPath) args.push("--settings", authSettingsPath);
|
|
22969
23178
|
env.CLAUDE_CODE_DISABLE_BACKGROUND_TASKS = "1";
|
|
22970
23179
|
const cwd = turn.cwd ?? homedir9();
|
|
22971
|
-
const privateFileFlags = /* @__PURE__ */ new Set(["--mcp-config"]);
|
|
23180
|
+
const privateFileFlags = /* @__PURE__ */ new Set(["--mcp-config", "--settings"]);
|
|
22972
23181
|
const keyArgs = args.filter((a2, i2) => !privateFileFlags.has(a2) && !privateFileFlags.has(args[i2 - 1] ?? ""));
|
|
22973
23182
|
const argsKey = JSON.stringify({
|
|
22974
23183
|
args: keyArgs,
|
|
@@ -22979,7 +23188,12 @@ var init_claude = __esm({
|
|
|
22979
23188
|
cwd,
|
|
22980
23189
|
model: injected.model ?? null,
|
|
22981
23190
|
base: env.ANTHROPIC_BASE_URL ?? null,
|
|
22982
|
-
configDir: env.CLAUDE_CONFIG_DIR ?? null
|
|
23191
|
+
configDir: env.CLAUDE_CONFIG_DIR ?? null,
|
|
23192
|
+
// Rotating an account's key/helper must not reuse the old process.
|
|
23193
|
+
auth: createHash5("sha256").update(JSON.stringify({
|
|
23194
|
+
settings: authSettings,
|
|
23195
|
+
env: Object.fromEntries(CLAUDE_ACCOUNT_ENV_KEYS.map((key) => [key, env[key]]))
|
|
23196
|
+
})).digest("hex")
|
|
22983
23197
|
});
|
|
22984
23198
|
const live = sessions.get(threadId);
|
|
22985
23199
|
if (live && !live.turn && !live.closing && live.child.exitCode === null && live.argsKey === argsKey && (!sessionId || sessionId === live.sessionId)) {
|
|
@@ -22987,7 +23201,7 @@ var init_claude = __esm({
|
|
|
22987
23201
|
live.turn = { turnId, settled: false, sawStreamDelta: false };
|
|
22988
23202
|
active.set(threadId, { stop: () => {
|
|
22989
23203
|
closeSession(threadId, "interrupted");
|
|
22990
|
-
|
|
23204
|
+
stopSession(live);
|
|
22991
23205
|
}, turnId, broker: live.broker });
|
|
22992
23206
|
emit({ ...base2(threadId, turnId), type: "turn.started" });
|
|
22993
23207
|
const volatile = turn.systemVolatile ?? "";
|
|
@@ -23046,6 +23260,9 @@ var init_claude = __esm({
|
|
|
23046
23260
|
onAsk: (ask) => {
|
|
23047
23261
|
const eventTurnId = sessions.get(threadId)?.turn?.turnId ?? turnId;
|
|
23048
23262
|
askTools.set(ask.id, typeof ask.tool === "string" ? ask.tool : void 0);
|
|
23263
|
+
const nativeMode = sessions.get(threadId)?.nativePermissionMode ?? null;
|
|
23264
|
+
const nativeReview = permissionMode === "auto" && nativeMode !== null ? nativeMode === "auto" ? "active" : "inactive" : void 0;
|
|
23265
|
+
const questions = askQuestions(ask);
|
|
23049
23266
|
emit({
|
|
23050
23267
|
...base2(threadId, eventTurnId),
|
|
23051
23268
|
type: "request.opened",
|
|
@@ -23053,8 +23270,15 @@ var init_claude = __esm({
|
|
|
23053
23270
|
requestType: ask.kind,
|
|
23054
23271
|
tool: ask.tool,
|
|
23055
23272
|
summary: askSummary(ask),
|
|
23273
|
+
nativeReview,
|
|
23274
|
+
// the proxy hands Claude its own suggested rules on `always`;
|
|
23275
|
+
// host control stays one action at a time
|
|
23276
|
+
allowSession: ask.kind === "permission" && !(controlsHost && typeof ask.tool === "string" && ask.tool.startsWith("mcp__computer")) ? true : void 0,
|
|
23056
23277
|
approvalScope: typeof ask.tool === "string" && controlsHost && ask.tool.startsWith("mcp__computer") ? "local-computer" : void 0,
|
|
23057
|
-
|
|
23278
|
+
questions: questions ?? void 0,
|
|
23279
|
+
// A structured ask still offers flat labels, for the phone
|
|
23280
|
+
// companions and any client that predates the question card.
|
|
23281
|
+
choices: questions ? questionChoices(questions) : Array.isArray(ask.input?.choices) ? ask.input.choices.slice(0, 5) : void 0
|
|
23058
23282
|
});
|
|
23059
23283
|
},
|
|
23060
23284
|
onResolve: (resolved) => {
|
|
@@ -23077,6 +23301,9 @@ var init_claude = __esm({
|
|
|
23077
23301
|
if (mcpConfigPath) {
|
|
23078
23302
|
writeFileSync6(mcpConfigPath, JSON.stringify({ mcpServers }), { mode: 384 });
|
|
23079
23303
|
}
|
|
23304
|
+
if (authSettingsPath) {
|
|
23305
|
+
writeFileSync6(authSettingsPath, JSON.stringify(authSettings), { mode: 384 });
|
|
23306
|
+
}
|
|
23080
23307
|
if (sessionId) args.push("--resume", sessionId);
|
|
23081
23308
|
else args.push("--session-id", newSessionId);
|
|
23082
23309
|
} catch (error51) {
|
|
@@ -23103,6 +23330,7 @@ var init_claude = __esm({
|
|
|
23103
23330
|
volatile: turn.systemVolatile ?? "",
|
|
23104
23331
|
sessionId: sessionId ?? newSessionId,
|
|
23105
23332
|
sawInit: false,
|
|
23333
|
+
nativePermissionMode: null,
|
|
23106
23334
|
turn: { turnId, settled: false, sawStreamDelta: false },
|
|
23107
23335
|
idleTimer: null,
|
|
23108
23336
|
closing: false,
|
|
@@ -23132,6 +23360,7 @@ var init_claude = __esm({
|
|
|
23132
23360
|
};
|
|
23133
23361
|
const currentTurnId = () => session.turn?.turnId ?? turnId;
|
|
23134
23362
|
const handleLine = (line) => {
|
|
23363
|
+
if (session.closing) return;
|
|
23135
23364
|
let o;
|
|
23136
23365
|
try {
|
|
23137
23366
|
o = JSON.parse(line);
|
|
@@ -23143,6 +23372,7 @@ var init_claude = __esm({
|
|
|
23143
23372
|
case "system":
|
|
23144
23373
|
if (o.subtype === "init") {
|
|
23145
23374
|
session.sawInit = true;
|
|
23375
|
+
session.nativePermissionMode = typeof o.permissionMode === "string" ? o.permissionMode : null;
|
|
23146
23376
|
if (typeof o.session_id === "string") session.sessionId = o.session_id;
|
|
23147
23377
|
emit({ ...base2(threadId, currentTurnId()), type: "session.started", sessionId: o.session_id, model: o.model });
|
|
23148
23378
|
} else if (o.subtype === "thinking_tokens") {
|
|
@@ -23164,18 +23394,18 @@ var init_claude = __esm({
|
|
|
23164
23394
|
}
|
|
23165
23395
|
case "assistant": {
|
|
23166
23396
|
const msg = o.message ?? {};
|
|
23167
|
-
const
|
|
23168
|
-
if (claudeAuthFailure(o,
|
|
23397
|
+
const text4 = firstText(msg.content);
|
|
23398
|
+
if (claudeAuthFailure(o, text4)) {
|
|
23169
23399
|
if (session.turn) session.turn.authFailed = true;
|
|
23170
|
-
emit({ ...base2(threadId, currentTurnId()), type: "runtime.error", message:
|
|
23400
|
+
emit({ ...base2(threadId, currentTurnId()), type: "runtime.error", message: text4, setup: true });
|
|
23171
23401
|
break;
|
|
23172
23402
|
}
|
|
23173
|
-
if (
|
|
23403
|
+
if (text4.trim()) {
|
|
23174
23404
|
if (!session.turn?.sawStreamDelta) {
|
|
23175
|
-
emit({ ...base2(threadId, currentTurnId()), type: "content.delta", streamKind: "assistant_text", delta:
|
|
23405
|
+
emit({ ...base2(threadId, currentTurnId()), type: "content.delta", streamKind: "assistant_text", delta: text4 });
|
|
23176
23406
|
}
|
|
23177
23407
|
if (session.turn) session.turn.sawStreamDelta = false;
|
|
23178
|
-
emit({ ...base2(threadId, currentTurnId()), type: "item.completed", itemType: "assistant_text", text:
|
|
23408
|
+
emit({ ...base2(threadId, currentTurnId()), type: "item.completed", itemType: "assistant_text", text: text4 });
|
|
23179
23409
|
}
|
|
23180
23410
|
for (const b of Array.isArray(msg.content) ? msg.content : []) {
|
|
23181
23411
|
if (b.type === "tool_use") {
|
|
@@ -23241,7 +23471,17 @@ var init_claude = __esm({
|
|
|
23241
23471
|
emit({ ...base2(threadId, currentTurnId()), type: "runtime.error", ...describeSpawnFailure(e, config2.cli) });
|
|
23242
23472
|
settle(false, "spawn_error");
|
|
23243
23473
|
});
|
|
23244
|
-
|
|
23474
|
+
let closeFinalized = false;
|
|
23475
|
+
const finalizeClose = async (code) => {
|
|
23476
|
+
if (closeFinalized) return;
|
|
23477
|
+
if (!await killCliTree(child, 0)) {
|
|
23478
|
+
session.broker?.close();
|
|
23479
|
+
session.broker = void 0;
|
|
23480
|
+
emit({ ...base2(threadId, currentTurnId()), type: "runtime.error", message: "Claude could not be confirmed stopped; its helper processes may still be running." });
|
|
23481
|
+
return;
|
|
23482
|
+
}
|
|
23483
|
+
if (closeFinalized) return;
|
|
23484
|
+
closeFinalized = true;
|
|
23245
23485
|
if (session.turn && !session.turn.settled) {
|
|
23246
23486
|
const message2 = `claude exited ${code} before result${session.stderr ? `: ${session.stderr.trim().slice(-300)}` : ""}`;
|
|
23247
23487
|
const verdict = classifyError({ exitCode: code, stderr: message2 });
|
|
@@ -23377,12 +23617,16 @@ var init_claude = __esm({
|
|
|
23377
23617
|
}
|
|
23378
23618
|
removePrivateTempDir(session.systemPromptPath);
|
|
23379
23619
|
if (sessions.get(threadId) === session) sessions.delete(threadId);
|
|
23620
|
+
};
|
|
23621
|
+
child.on("close", (code) => {
|
|
23622
|
+
session.finishClose = () => finalizeClose(code);
|
|
23623
|
+
void session.finishClose();
|
|
23380
23624
|
});
|
|
23381
23625
|
const stop = () => {
|
|
23382
23626
|
closeSession(threadId, "interrupted");
|
|
23383
23627
|
retry.cancelled = true;
|
|
23384
23628
|
retryAbort.abort();
|
|
23385
|
-
|
|
23629
|
+
stopSession(session);
|
|
23386
23630
|
};
|
|
23387
23631
|
active.set(threadId, { stop, turnId, broker });
|
|
23388
23632
|
emit({ ...base2(threadId, turnId), type: "turn.started" });
|
|
@@ -23392,10 +23636,10 @@ var init_claude = __esm({
|
|
|
23392
23636
|
}
|
|
23393
23637
|
return { turnId };
|
|
23394
23638
|
};
|
|
23395
|
-
const steer = async (threadId,
|
|
23639
|
+
const steer = async (threadId, text4) => {
|
|
23396
23640
|
const s = sessions.get(threadId);
|
|
23397
23641
|
if (!s || !s.turn || s.turn.settled || s.closing || s.child.exitCode !== null) return false;
|
|
23398
|
-
return writeUser(s, threadId, claudeUserMessage(
|
|
23642
|
+
return writeUser(s, threadId, claudeUserMessage(text4, void 0));
|
|
23399
23643
|
};
|
|
23400
23644
|
const login = new ClaudeLoginController({ cli: config2.cli, environment, onAuthenticated: async () => {
|
|
23401
23645
|
await refreshModels();
|
|
@@ -23508,7 +23752,7 @@ var init_claude = __esm({
|
|
|
23508
23752
|
const broker = sessions.get(threadId)?.broker ?? active.get(threadId)?.broker;
|
|
23509
23753
|
if (!broker) return "unavailable";
|
|
23510
23754
|
const behavior = decision.behavior === "answer" ? "answer" : decision.behavior;
|
|
23511
|
-
if (!broker.answer(requestId, behavior, decision.message)) return "unavailable";
|
|
23755
|
+
if (!broker.answer(requestId, behavior, decision.message, decision.always)) return "unavailable";
|
|
23512
23756
|
return behavior === "allow" ? "allowed-once" : behavior === "answer" ? "answered" : "rejected";
|
|
23513
23757
|
},
|
|
23514
23758
|
hasSession: (threadId) => active.has(threadId),
|
|
@@ -23673,7 +23917,7 @@ function unquote(raw) {
|
|
|
23673
23917
|
}
|
|
23674
23918
|
return value;
|
|
23675
23919
|
}
|
|
23676
|
-
function parseCodexToml(
|
|
23920
|
+
function parseCodexToml(text4) {
|
|
23677
23921
|
const result = { providers: [] };
|
|
23678
23922
|
const byId = /* @__PURE__ */ new Map();
|
|
23679
23923
|
let section = "root";
|
|
@@ -23686,7 +23930,7 @@ function parseCodexToml(text3) {
|
|
|
23686
23930
|
}
|
|
23687
23931
|
return provider;
|
|
23688
23932
|
};
|
|
23689
|
-
for (const line of
|
|
23933
|
+
for (const line of text4.split(/\r?\n/)) {
|
|
23690
23934
|
const stripped = line.trim();
|
|
23691
23935
|
if (!stripped || stripped.startsWith("#")) continue;
|
|
23692
23936
|
if (stripped.startsWith("[") && stripped.endsWith("]")) {
|
|
@@ -24768,6 +25012,7 @@ var init_codex = __esm({
|
|
|
24768
25012
|
const earlyNotifications = [];
|
|
24769
25013
|
const state = {
|
|
24770
25014
|
settled: false,
|
|
25015
|
+
lastError: "",
|
|
24771
25016
|
lastText: "",
|
|
24772
25017
|
sawStreamDelta: false,
|
|
24773
25018
|
// codex reports token usage as a running THREAD total; the harness
|
|
@@ -24820,11 +25065,17 @@ var init_codex = __esm({
|
|
|
24820
25065
|
});
|
|
24821
25066
|
send({ jsonrpc: "2.0", id, method, params });
|
|
24822
25067
|
});
|
|
24823
|
-
let
|
|
24824
|
-
const terminate = () =>
|
|
24825
|
-
|
|
25068
|
+
let stopping2;
|
|
25069
|
+
const terminate = () => stopping2 ??= killCliTree(child).then((stopped) => {
|
|
25070
|
+
if (!stopped) stopping2 = void 0;
|
|
25071
|
+
return stopped;
|
|
25072
|
+
});
|
|
25073
|
+
let completeStoppedTurn;
|
|
25074
|
+
const stop = async () => {
|
|
24826
25075
|
stopRequested = true;
|
|
24827
|
-
|
|
25076
|
+
const stopped = await terminate();
|
|
25077
|
+
if (stopped) completeStoppedTurn?.();
|
|
25078
|
+
return stopped;
|
|
24828
25079
|
};
|
|
24829
25080
|
const settle = async (ok, stopReason) => {
|
|
24830
25081
|
if (state.settled) return;
|
|
@@ -24837,12 +25088,9 @@ var init_codex = __esm({
|
|
|
24837
25088
|
active.delete(threadId);
|
|
24838
25089
|
emit({ ...base2(threadId, turnId), type: "turn.completed", ok, stopReason, cost: null, ...state.usage ? { usage: state.usage } : {} });
|
|
24839
25090
|
};
|
|
24840
|
-
|
|
24841
|
-
|
|
24842
|
-
} else {
|
|
25091
|
+
completeStoppedTurn = complete;
|
|
25092
|
+
if (!await stop()) {
|
|
24843
25093
|
emit({ ...base2(threadId, turnId), type: "runtime.error", message: "codex did not shut down after termination was requested" });
|
|
24844
|
-
if (child.exitCode !== null || child.signalCode !== null) complete();
|
|
24845
|
-
else child.once("close", complete);
|
|
24846
25094
|
}
|
|
24847
25095
|
};
|
|
24848
25096
|
const controlsHost = turn.integrations?.localComputer?.scope === "local-computer";
|
|
@@ -25026,13 +25274,26 @@ var init_codex = __esm({
|
|
|
25026
25274
|
}
|
|
25027
25275
|
case "turn/completed": {
|
|
25028
25276
|
const t2 = p.turn ?? {};
|
|
25029
|
-
|
|
25277
|
+
const message2 = typeof t2.error?.message === "string" ? t2.error.message.slice(0, 400) : "";
|
|
25278
|
+
if (t2.status !== "completed" && message2 && message2 !== state.lastError) {
|
|
25279
|
+
state.lastError = message2;
|
|
25280
|
+
emit({
|
|
25281
|
+
...base2(threadId, turnId),
|
|
25282
|
+
type: "runtime.error",
|
|
25283
|
+
message: message2,
|
|
25284
|
+
...classifyError({ text: message2 }).reason === "auth" ? { setup: true } : {}
|
|
25285
|
+
});
|
|
25286
|
+
}
|
|
25287
|
+
void settle(t2.status === "completed", t2.status === "completed" ? null : classifyError({ text: message2 || state.lastError }).reason === "provider_safety" ? "provider_safety" : message2 || t2.status || "failed");
|
|
25030
25288
|
break;
|
|
25031
25289
|
}
|
|
25032
25290
|
case "error":
|
|
25033
25291
|
{
|
|
25034
25292
|
const message2 = p.message ?? p.error?.message;
|
|
25035
|
-
if (message2)
|
|
25293
|
+
if (message2) {
|
|
25294
|
+
state.lastError = String(message2).slice(0, 400);
|
|
25295
|
+
emit({ ...base2(threadId, turnId), type: "runtime.error", message: state.lastError });
|
|
25296
|
+
}
|
|
25036
25297
|
}
|
|
25037
25298
|
break;
|
|
25038
25299
|
}
|
|
@@ -25081,6 +25342,10 @@ var init_codex = __esm({
|
|
|
25081
25342
|
});
|
|
25082
25343
|
child.on("close", (code) => {
|
|
25083
25344
|
if (abandoned) return;
|
|
25345
|
+
if (state.settled) {
|
|
25346
|
+
void stop();
|
|
25347
|
+
return;
|
|
25348
|
+
}
|
|
25084
25349
|
if (!state.settled) {
|
|
25085
25350
|
emit({
|
|
25086
25351
|
...base2(threadId, turnId),
|
|
@@ -25236,7 +25501,7 @@ var init_codex = __esm({
|
|
|
25236
25501
|
message: message2,
|
|
25237
25502
|
...needsAuth ? { setup: true } : {}
|
|
25238
25503
|
});
|
|
25239
|
-
await settle(false, needsAuth ? "auth_required" : "rpc_error");
|
|
25504
|
+
await settle(false, needsAuth ? "auth_required" : verdict.reason === "provider_safety" ? "provider_safety" : "rpc_error");
|
|
25240
25505
|
}
|
|
25241
25506
|
}
|
|
25242
25507
|
};
|
|
@@ -25373,7 +25638,7 @@ function createOpenAIChatRuntime(options) {
|
|
|
25373
25638
|
if (!response.body) {
|
|
25374
25639
|
throw new Error(options.noBodyError ?? `${options.httpErrorLabel} returned no response body`);
|
|
25375
25640
|
}
|
|
25376
|
-
let
|
|
25641
|
+
let text4 = "";
|
|
25377
25642
|
let reasoning = "";
|
|
25378
25643
|
let usage = null;
|
|
25379
25644
|
const reader = response.body.getReader();
|
|
@@ -25405,7 +25670,7 @@ function createOpenAIChatRuntime(options) {
|
|
|
25405
25670
|
onDelta?.(reasoningDelta, "reasoning_text");
|
|
25406
25671
|
}
|
|
25407
25672
|
if (contentDelta) {
|
|
25408
|
-
|
|
25673
|
+
text4 += contentDelta;
|
|
25409
25674
|
onDelta?.(contentDelta, "assistant_text");
|
|
25410
25675
|
}
|
|
25411
25676
|
if (chunk.usage) usage = usageFrom(chunk.usage);
|
|
@@ -25415,7 +25680,7 @@ function createOpenAIChatRuntime(options) {
|
|
|
25415
25680
|
await reader.cancel().catch(() => {
|
|
25416
25681
|
});
|
|
25417
25682
|
}
|
|
25418
|
-
return { text:
|
|
25683
|
+
return { text: text4, reasoning, usage };
|
|
25419
25684
|
};
|
|
25420
25685
|
const messagesFor = (turn) => [
|
|
25421
25686
|
...turn.system ? [{ role: "system", content: turn.system }] : [],
|
|
@@ -25532,8 +25797,8 @@ function createOpenAIChatRuntime(options) {
|
|
|
25532
25797
|
},
|
|
25533
25798
|
generateText: async (prompt) => {
|
|
25534
25799
|
const model = options.generateModel?.() ?? options.models().default;
|
|
25535
|
-
const { text:
|
|
25536
|
-
return
|
|
25800
|
+
const { text: text4, reasoning } = await complete([{ role: "user", content: prompt }], model, false);
|
|
25801
|
+
return text4.trim() ? text4 : reasoning;
|
|
25537
25802
|
},
|
|
25538
25803
|
dispose: async () => {
|
|
25539
25804
|
for (const abort of active.values()) abort.abort();
|
|
@@ -25601,7 +25866,7 @@ var init_grok = __esm({
|
|
|
25601
25866
|
nativeLog: {
|
|
25602
25867
|
source: "xai.chat.completions",
|
|
25603
25868
|
outgoing: (_turn, messages, model) => ({ model, messages }),
|
|
25604
|
-
incoming: ({ text:
|
|
25869
|
+
incoming: ({ text: text4, usage }) => ({ text: text4, usage })
|
|
25605
25870
|
}
|
|
25606
25871
|
});
|
|
25607
25872
|
}
|
|
@@ -25626,9 +25891,9 @@ function unquote2(raw) {
|
|
|
25626
25891
|
}
|
|
25627
25892
|
function readGrokModelCatalog(env = process.env) {
|
|
25628
25893
|
const path3 = join25(grokHome(env), "config.toml");
|
|
25629
|
-
let
|
|
25894
|
+
let text4 = "";
|
|
25630
25895
|
try {
|
|
25631
|
-
|
|
25896
|
+
text4 = readFileSync11(path3, "utf8");
|
|
25632
25897
|
} catch {
|
|
25633
25898
|
return STATIC_GROK_MODELS;
|
|
25634
25899
|
}
|
|
@@ -25646,7 +25911,7 @@ function readGrokModelCatalog(env = process.env) {
|
|
|
25646
25911
|
options.push({ id: current.slug, label: current.name || current.slug, custom: true });
|
|
25647
25912
|
current = null;
|
|
25648
25913
|
};
|
|
25649
|
-
for (const line of
|
|
25914
|
+
for (const line of text4.split(/\r?\n/)) {
|
|
25650
25915
|
const stripped = line.trim();
|
|
25651
25916
|
if (stripped === "[models]") {
|
|
25652
25917
|
flush();
|
|
@@ -25699,11 +25964,11 @@ function ensureGrokInjectSlug(modelId, env = process.env) {
|
|
|
25699
25964
|
const host = localHost(inject.host);
|
|
25700
25965
|
if (!host) return modelId;
|
|
25701
25966
|
const path3 = join25(grokHome(env), "config.toml");
|
|
25702
|
-
let
|
|
25967
|
+
let text4 = "";
|
|
25703
25968
|
try {
|
|
25704
|
-
|
|
25969
|
+
text4 = readFileSync11(path3, "utf8");
|
|
25705
25970
|
} catch {
|
|
25706
|
-
|
|
25971
|
+
text4 = "";
|
|
25707
25972
|
}
|
|
25708
25973
|
const taken = new Set(STATIC_GROK_MODELS.options.map((option) => option.id));
|
|
25709
25974
|
let current = null;
|
|
@@ -25716,7 +25981,7 @@ function ensureGrokInjectSlug(modelId, env = process.env) {
|
|
|
25716
25981
|
current = null;
|
|
25717
25982
|
};
|
|
25718
25983
|
let found = null;
|
|
25719
|
-
for (const line of
|
|
25984
|
+
for (const line of text4.split(/\r?\n/)) {
|
|
25720
25985
|
const stripped = line.trim();
|
|
25721
25986
|
if (stripped.startsWith("[model.") && stripped.endsWith("]")) {
|
|
25722
25987
|
flush();
|
|
@@ -25749,12 +26014,18 @@ function ensureGrokInjectSlug(modelId, env = process.env) {
|
|
|
25749
26014
|
`api_key = ${quoteToml(hostApiKey(host, env))}`,
|
|
25750
26015
|
""
|
|
25751
26016
|
].join("\n");
|
|
25752
|
-
const next =
|
|
26017
|
+
const next = text4 && !text4.endsWith("\n") ? `${text4}
|
|
25753
26018
|
|
|
25754
|
-
${block2}` : `${
|
|
26019
|
+
${block2}` : `${text4}${text4 ? "\n" : ""}${block2}`;
|
|
25755
26020
|
writeFileSync7(path3, next);
|
|
25756
26021
|
return slug;
|
|
25757
26022
|
}
|
|
26023
|
+
function grokAcceptsUnadvertisedImages(init) {
|
|
26024
|
+
const meta3 = init?._meta;
|
|
26025
|
+
if (meta3?.grokShell !== true || typeof meta3.agentVersion !== "string") return false;
|
|
26026
|
+
const version2 = /^1\.0\.(\d+)$/.exec(meta3.agentVersion);
|
|
26027
|
+
return Boolean(version2 && Number(version2[1]) >= 25);
|
|
26028
|
+
}
|
|
25758
26029
|
var STATIC_GROK_MODELS, SLUG, support2, GrokAgentDriver;
|
|
25759
26030
|
var init_grok2 = __esm({
|
|
25760
26031
|
"server/drivers/acp/grok.ts"() {
|
|
@@ -25772,7 +26043,8 @@ var init_grok2 = __esm({
|
|
|
25772
26043
|
support2 = {
|
|
25773
26044
|
driverKind: "grokAgent",
|
|
25774
26045
|
displayName: "Grok",
|
|
25775
|
-
images:
|
|
26046
|
+
images: true,
|
|
26047
|
+
acceptsUnadvertisedImages: grokAcceptsUnadvertisedImages,
|
|
25776
26048
|
models: STATIC_GROK_MODELS,
|
|
25777
26049
|
resolveModels: (env) => mergeLocalInject(readGrokModelCatalog(env), env),
|
|
25778
26050
|
// Grok's accepted levels vary by model and the CLI validates lazily — a
|
|
@@ -25808,7 +26080,7 @@ var init_grok2 = __esm({
|
|
|
25808
26080
|
// crates/codegen/xai-grok-pager-bin/src/main.rs:1259-1273.
|
|
25809
26081
|
spawnArgs: (config2, turn) => [
|
|
25810
26082
|
"--permission-mode",
|
|
25811
|
-
config2.fullAuto ? "bypassPermissions" : turn.approvalMode === "auto" ? "auto" : "default",
|
|
26083
|
+
config2.fullAuto ? "bypassPermissions" : turn.approvalMode === "auto" ? "auto" : turn.approvalMode === "edits" ? "acceptEdits" : "default",
|
|
25812
26084
|
"agent",
|
|
25813
26085
|
...turn.model ? ["-m", turn.model] : [],
|
|
25814
26086
|
// long form on purpose: `--effort` is documented as an alias, and an
|
|
@@ -25946,18 +26218,18 @@ function stripTomlLineComment(line) {
|
|
|
25946
26218
|
}
|
|
25947
26219
|
return line;
|
|
25948
26220
|
}
|
|
25949
|
-
function takeTomlBasicEscape(
|
|
25950
|
-
const code =
|
|
26221
|
+
function takeTomlBasicEscape(text4, i2) {
|
|
26222
|
+
const code = text4[i2 + 1];
|
|
25951
26223
|
if (code === void 0) return { ok: false };
|
|
25952
26224
|
if (code === "u") {
|
|
25953
|
-
const hex3 =
|
|
26225
|
+
const hex3 = text4.slice(i2 + 2, i2 + 6);
|
|
25954
26226
|
if (!/^[0-9a-fA-F]{4}$/.test(hex3)) return { ok: false };
|
|
25955
26227
|
const point = parseInt(hex3, 16);
|
|
25956
26228
|
if (point >= 55296 && point <= 57343) return { ok: false };
|
|
25957
26229
|
return { ok: true, value: String.fromCharCode(point), next: i2 + 6 };
|
|
25958
26230
|
}
|
|
25959
26231
|
if (code === "U") {
|
|
25960
|
-
const hex3 =
|
|
26232
|
+
const hex3 = text4.slice(i2 + 2, i2 + 10);
|
|
25961
26233
|
if (!/^[0-9a-fA-F]{8}$/.test(hex3)) return { ok: false };
|
|
25962
26234
|
const point = parseInt(hex3, 16);
|
|
25963
26235
|
if (point > 1114111 || point >= 55296 && point <= 57343) return { ok: false };
|
|
@@ -26029,14 +26301,14 @@ function tomlRowKey(row) {
|
|
|
26029
26301
|
const eq = row.indexOf("=");
|
|
26030
26302
|
return unquoteTomlKey(eq < 0 ? row : row.slice(0, eq));
|
|
26031
26303
|
}
|
|
26032
|
-
function tomlTables(
|
|
26304
|
+
function tomlTables(text4) {
|
|
26033
26305
|
const headings = [];
|
|
26034
26306
|
let mode = "out";
|
|
26035
26307
|
let i2 = 0;
|
|
26036
|
-
const atLineStart = (idx) => idx === 0 ||
|
|
26037
|
-
while (i2 <
|
|
26308
|
+
const atLineStart = (idx) => idx === 0 || text4[idx - 1] === "\n";
|
|
26309
|
+
while (i2 < text4.length) {
|
|
26038
26310
|
if (mode === "mlbasic") {
|
|
26039
|
-
if (
|
|
26311
|
+
if (text4.startsWith('"""', i2)) {
|
|
26040
26312
|
mode = "out";
|
|
26041
26313
|
i2 += 3;
|
|
26042
26314
|
continue;
|
|
@@ -26045,7 +26317,7 @@ function tomlTables(text3) {
|
|
|
26045
26317
|
continue;
|
|
26046
26318
|
}
|
|
26047
26319
|
if (mode === "mllit") {
|
|
26048
|
-
if (
|
|
26320
|
+
if (text4.startsWith("'''", i2)) {
|
|
26049
26321
|
mode = "out";
|
|
26050
26322
|
i2 += 3;
|
|
26051
26323
|
continue;
|
|
@@ -26054,61 +26326,61 @@ function tomlTables(text3) {
|
|
|
26054
26326
|
continue;
|
|
26055
26327
|
}
|
|
26056
26328
|
if (mode === "basic") {
|
|
26057
|
-
if (
|
|
26329
|
+
if (text4[i2] === "\n") {
|
|
26058
26330
|
mode = "out";
|
|
26059
26331
|
i2 += 1;
|
|
26060
26332
|
continue;
|
|
26061
26333
|
}
|
|
26062
|
-
if (
|
|
26334
|
+
if (text4[i2] === "\\") {
|
|
26063
26335
|
i2 += 2;
|
|
26064
26336
|
continue;
|
|
26065
26337
|
}
|
|
26066
|
-
if (
|
|
26338
|
+
if (text4[i2] === '"') mode = "out";
|
|
26067
26339
|
i2 += 1;
|
|
26068
26340
|
continue;
|
|
26069
26341
|
}
|
|
26070
26342
|
if (mode === "literal") {
|
|
26071
|
-
if (
|
|
26343
|
+
if (text4[i2] === "\n") {
|
|
26072
26344
|
mode = "out";
|
|
26073
26345
|
i2 += 1;
|
|
26074
26346
|
continue;
|
|
26075
26347
|
}
|
|
26076
|
-
if (
|
|
26348
|
+
if (text4[i2] === "'") mode = "out";
|
|
26077
26349
|
i2 += 1;
|
|
26078
26350
|
continue;
|
|
26079
26351
|
}
|
|
26080
|
-
if (
|
|
26352
|
+
if (text4.startsWith('"""', i2)) {
|
|
26081
26353
|
mode = "mlbasic";
|
|
26082
26354
|
i2 += 3;
|
|
26083
26355
|
continue;
|
|
26084
26356
|
}
|
|
26085
|
-
if (
|
|
26357
|
+
if (text4.startsWith("'''", i2)) {
|
|
26086
26358
|
mode = "mllit";
|
|
26087
26359
|
i2 += 3;
|
|
26088
26360
|
continue;
|
|
26089
26361
|
}
|
|
26090
|
-
if (
|
|
26362
|
+
if (text4[i2] === '"') {
|
|
26091
26363
|
mode = "basic";
|
|
26092
26364
|
i2 += 1;
|
|
26093
26365
|
continue;
|
|
26094
26366
|
}
|
|
26095
|
-
if (
|
|
26367
|
+
if (text4[i2] === "'") {
|
|
26096
26368
|
mode = "literal";
|
|
26097
26369
|
i2 += 1;
|
|
26098
26370
|
continue;
|
|
26099
26371
|
}
|
|
26100
|
-
if (
|
|
26101
|
-
const nl =
|
|
26102
|
-
i2 = nl < 0 ?
|
|
26372
|
+
if (text4[i2] === "#") {
|
|
26373
|
+
const nl = text4.indexOf("\n", i2);
|
|
26374
|
+
i2 = nl < 0 ? text4.length : nl + 1;
|
|
26103
26375
|
continue;
|
|
26104
26376
|
}
|
|
26105
26377
|
if (atLineStart(i2)) {
|
|
26106
26378
|
let j = i2;
|
|
26107
|
-
while (j <
|
|
26108
|
-
if (
|
|
26109
|
-
const nl =
|
|
26110
|
-
const lineEnd = nl < 0 ?
|
|
26111
|
-
const raw =
|
|
26379
|
+
while (j < text4.length && (text4[j] === " " || text4[j] === " ")) j += 1;
|
|
26380
|
+
if (text4[j] === "[") {
|
|
26381
|
+
const nl = text4.indexOf("\n", j);
|
|
26382
|
+
const lineEnd = nl < 0 ? text4.length : nl;
|
|
26383
|
+
const raw = text4.slice(j, lineEnd).replace(/\r$/, "");
|
|
26112
26384
|
const stripped = stripTomlLineComment(raw).trim();
|
|
26113
26385
|
const array2 = stripped.startsWith("[[");
|
|
26114
26386
|
const name = array2 ? canonicalizeTomlHeading(`[${stripped.replace(/^\s*\[\[/, "").replace(/\]\]\s*$/, "")}]`) : canonicalizeTomlHeading(raw);
|
|
@@ -26121,11 +26393,11 @@ function tomlTables(text3) {
|
|
|
26121
26393
|
}
|
|
26122
26394
|
return headings.map((heading, index) => ({
|
|
26123
26395
|
heading,
|
|
26124
|
-
end: index + 1 < headings.length ? headings[index + 1].lineStart :
|
|
26396
|
+
end: index + 1 < headings.length ? headings[index + 1].lineStart : text4.length
|
|
26125
26397
|
})).filter((entry) => entry.heading.patchable && entry.heading.name).map((entry) => ({
|
|
26126
26398
|
name: entry.heading.name,
|
|
26127
26399
|
headingStart: entry.heading.lineStart,
|
|
26128
|
-
bodyStart: entry.heading.lineEnd + (
|
|
26400
|
+
bodyStart: entry.heading.lineEnd + (text4[entry.heading.lineEnd] === "\n" ? 1 : 0),
|
|
26129
26401
|
end: entry.end
|
|
26130
26402
|
}));
|
|
26131
26403
|
}
|
|
@@ -26181,22 +26453,22 @@ function tomlKeys(block2) {
|
|
|
26181
26453
|
take(block2.length);
|
|
26182
26454
|
return keys;
|
|
26183
26455
|
}
|
|
26184
|
-
function hasTomlTable(
|
|
26456
|
+
function hasTomlTable(text4, heading) {
|
|
26185
26457
|
const name = canonicalizeTomlHeading(heading);
|
|
26186
|
-
return name !== null && tomlTables(
|
|
26458
|
+
return name !== null && tomlTables(text4).some((table) => table.name === name);
|
|
26187
26459
|
}
|
|
26188
|
-
function patchTomlTable(
|
|
26460
|
+
function patchTomlTable(text4, heading, rows) {
|
|
26189
26461
|
const name = canonicalizeTomlHeading(heading);
|
|
26190
|
-
if (!name) return
|
|
26191
|
-
const table = tomlTables(
|
|
26192
|
-
if (!table) return
|
|
26193
|
-
const keys = tomlKeys(
|
|
26462
|
+
if (!name) return text4;
|
|
26463
|
+
const table = tomlTables(text4).find((entry) => entry.name === name);
|
|
26464
|
+
if (!table) return text4;
|
|
26465
|
+
const keys = tomlKeys(text4.slice(table.bodyStart, table.end));
|
|
26194
26466
|
const missing = rows.filter((row) => !keys.has(tomlRowKey(row)));
|
|
26195
|
-
if (!missing.length) return
|
|
26467
|
+
if (!missing.length) return text4;
|
|
26196
26468
|
let insertAt = table.end;
|
|
26197
|
-
while (insertAt > table.bodyStart && (
|
|
26198
|
-
const before =
|
|
26199
|
-
const after =
|
|
26469
|
+
while (insertAt > table.bodyStart && (text4[insertAt - 1] === "\n" || text4[insertAt - 1] === "\r")) insertAt -= 1;
|
|
26470
|
+
const before = text4.slice(0, insertAt);
|
|
26471
|
+
const after = text4.slice(insertAt);
|
|
26200
26472
|
const pad = before.endsWith("\n") || before.length === 0 ? "" : "\n";
|
|
26201
26473
|
return `${before}${pad}${missing.join("\n")}${after.startsWith("\n") ? "" : "\n"}${after}`;
|
|
26202
26474
|
}
|
|
@@ -26209,17 +26481,17 @@ function ensureKimiInjectAlias(modelId, env = process.env) {
|
|
|
26209
26481
|
const dataRoot = kimiDataRoot(env);
|
|
26210
26482
|
mkdirSync10(dataRoot, { recursive: true });
|
|
26211
26483
|
const path3 = join27(dataRoot, "config.toml");
|
|
26212
|
-
let
|
|
26484
|
+
let text4 = "";
|
|
26213
26485
|
try {
|
|
26214
|
-
|
|
26486
|
+
text4 = readFileSync13(path3, "utf8");
|
|
26215
26487
|
} catch {
|
|
26216
|
-
|
|
26488
|
+
text4 = "";
|
|
26217
26489
|
}
|
|
26218
|
-
const original =
|
|
26490
|
+
const original = text4;
|
|
26219
26491
|
const providerHeading = `[providers.${inject.host}]`;
|
|
26220
26492
|
const modelHeading = `[models.${quoteTomlKey(alias)}]`;
|
|
26221
26493
|
const blocks = [];
|
|
26222
|
-
if (!hasTomlTable(
|
|
26494
|
+
if (!hasTomlTable(text4, providerHeading)) {
|
|
26223
26495
|
blocks.push(
|
|
26224
26496
|
[
|
|
26225
26497
|
providerHeading,
|
|
@@ -26230,8 +26502,8 @@ function ensureKimiInjectAlias(modelId, env = process.env) {
|
|
|
26230
26502
|
].join("\n")
|
|
26231
26503
|
);
|
|
26232
26504
|
}
|
|
26233
|
-
if (hasTomlTable(
|
|
26234
|
-
|
|
26505
|
+
if (hasTomlTable(text4, modelHeading)) {
|
|
26506
|
+
text4 = patchTomlTable(text4, modelHeading, [`protocol = "openai"`, `max_context_size = 262144`]);
|
|
26235
26507
|
} else {
|
|
26236
26508
|
blocks.push(
|
|
26237
26509
|
[
|
|
@@ -26245,13 +26517,13 @@ function ensureKimiInjectAlias(modelId, env = process.env) {
|
|
|
26245
26517
|
);
|
|
26246
26518
|
}
|
|
26247
26519
|
if (blocks.length) {
|
|
26248
|
-
const prefix =
|
|
26520
|
+
const prefix = text4 && !text4.endsWith("\n") ? `${text4}
|
|
26249
26521
|
|
|
26250
|
-
` :
|
|
26522
|
+
` : text4 ? `${text4}
|
|
26251
26523
|
` : "";
|
|
26252
26524
|
writeFileSync8(path3, `${prefix}${blocks.join("\n")}`);
|
|
26253
|
-
} else if (
|
|
26254
|
-
writeFileSync8(path3,
|
|
26525
|
+
} else if (text4 !== original) {
|
|
26526
|
+
writeFileSync8(path3, text4);
|
|
26255
26527
|
}
|
|
26256
26528
|
return alias;
|
|
26257
26529
|
}
|
|
@@ -26271,9 +26543,9 @@ function stripKimiModelEnv(env) {
|
|
|
26271
26543
|
}
|
|
26272
26544
|
function readKimiModelCatalog(env) {
|
|
26273
26545
|
const dataRoot = kimiDataRoot(env);
|
|
26274
|
-
let
|
|
26546
|
+
let text4 = "";
|
|
26275
26547
|
try {
|
|
26276
|
-
|
|
26548
|
+
text4 = readFileSync13(join27(dataRoot, "config.toml"), "utf8");
|
|
26277
26549
|
} catch {
|
|
26278
26550
|
return STATIC_KIMI_MODELS;
|
|
26279
26551
|
}
|
|
@@ -26289,7 +26561,7 @@ function readKimiModelCatalog(env) {
|
|
|
26289
26561
|
options.push({ id: current.slug, label: current.name || current.slug, custom: true });
|
|
26290
26562
|
current = null;
|
|
26291
26563
|
};
|
|
26292
|
-
for (const line of
|
|
26564
|
+
for (const line of text4.split(/\r?\n/)) {
|
|
26293
26565
|
const stripped = line.trim();
|
|
26294
26566
|
if ((stripped.startsWith("[model.") || stripped.startsWith("[models.")) && stripped.endsWith("]")) {
|
|
26295
26567
|
flush();
|
|
@@ -26582,8 +26854,8 @@ function resolveCursorAcpModelId(available, wanted) {
|
|
|
26582
26854
|
}
|
|
26583
26855
|
return null;
|
|
26584
26856
|
}
|
|
26585
|
-
function firstJsonValue(
|
|
26586
|
-
const trimmed =
|
|
26857
|
+
function firstJsonValue(text4) {
|
|
26858
|
+
const trimmed = text4.trim();
|
|
26587
26859
|
if (!trimmed) return null;
|
|
26588
26860
|
try {
|
|
26589
26861
|
return JSON.parse(trimmed);
|
|
@@ -26657,12 +26929,12 @@ function stripModelMarkers(label) {
|
|
|
26657
26929
|
}
|
|
26658
26930
|
return { label: cleaned, isDefault, isCurrent };
|
|
26659
26931
|
}
|
|
26660
|
-
function decodeCursorModelText(
|
|
26932
|
+
function decodeCursorModelText(text4) {
|
|
26661
26933
|
const options = [];
|
|
26662
26934
|
const seen = /* @__PURE__ */ new Set();
|
|
26663
26935
|
let markedDefault;
|
|
26664
26936
|
let markedCurrent;
|
|
26665
|
-
for (const raw of
|
|
26937
|
+
for (const raw of text4.split(/\r?\n/)) {
|
|
26666
26938
|
const line = raw.trim();
|
|
26667
26939
|
if (!line || line.startsWith("#") || /^available\s+models?\b/i.test(line) || /^models?\b/i.test(line)) continue;
|
|
26668
26940
|
const stripped = line.replace(/^[\s*•-]+\s*/, "");
|
|
@@ -26715,8 +26987,8 @@ function decodeCursorAuthStatus(payload) {
|
|
|
26715
26987
|
}
|
|
26716
26988
|
return null;
|
|
26717
26989
|
}
|
|
26718
|
-
function decodeCursorAuthText(
|
|
26719
|
-
const normalized =
|
|
26990
|
+
function decodeCursorAuthText(text4) {
|
|
26991
|
+
const normalized = text4.trim().toLowerCase();
|
|
26720
26992
|
if (!normalized) return null;
|
|
26721
26993
|
if (/not (?:logged|signed) in|not authenticated|unauthenticated|logged out/.test(normalized)) return false;
|
|
26722
26994
|
if (/login successful|logged in|signed in|authenticated/.test(normalized)) return true;
|
|
@@ -27136,7 +27408,7 @@ function qwenHome(env) {
|
|
|
27136
27408
|
const home = process.platform === "win32" ? env.USERPROFILE || env.HOME || homedir19() : env.HOME || env.USERPROFILE || homedir19();
|
|
27137
27409
|
return join30(home, ".qwen");
|
|
27138
27410
|
}
|
|
27139
|
-
function
|
|
27411
|
+
function isRecord2(value) {
|
|
27140
27412
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
27141
27413
|
}
|
|
27142
27414
|
function qwenModelLabel(id, name) {
|
|
@@ -27150,15 +27422,15 @@ function readQwenRoutes(env) {
|
|
|
27150
27422
|
} catch {
|
|
27151
27423
|
return [];
|
|
27152
27424
|
}
|
|
27153
|
-
if (!
|
|
27425
|
+
if (!isRecord2(settings2) || !isRecord2(settings2.modelProviders)) return [];
|
|
27154
27426
|
const routes = [];
|
|
27155
27427
|
const seen = /* @__PURE__ */ new Set();
|
|
27156
|
-
const mappings =
|
|
27428
|
+
const mappings = isRecord2(settings2.providerProtocol) ? settings2.providerProtocol : {};
|
|
27157
27429
|
for (const [provider, rows] of Object.entries(settings2.modelProviders)) {
|
|
27158
27430
|
const protocol = Object.hasOwn(mappings, provider) ? mappings[provider] : provider;
|
|
27159
27431
|
if (typeof protocol !== "string" || !PROTOCOLS.has(protocol) || !Array.isArray(rows)) continue;
|
|
27160
27432
|
for (const row of rows) {
|
|
27161
|
-
if (!
|
|
27433
|
+
if (!isRecord2(row) || typeof row.id !== "string") continue;
|
|
27162
27434
|
const model = row.id;
|
|
27163
27435
|
if (!model.trim()) continue;
|
|
27164
27436
|
if (row.baseUrl !== void 0 && typeof row.baseUrl !== "string") continue;
|
|
@@ -28304,14 +28576,14 @@ var init_stringifyComment = __esm({
|
|
|
28304
28576
|
});
|
|
28305
28577
|
|
|
28306
28578
|
// node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/browser/dist/stringify/foldFlowLines.js
|
|
28307
|
-
function foldFlowLines(
|
|
28579
|
+
function foldFlowLines(text4, indent, mode = "flow", { indentAtStart, lineWidth = 80, minContentWidth = 20, onFold, onOverflow } = {}) {
|
|
28308
28580
|
if (!lineWidth || lineWidth < 0)
|
|
28309
|
-
return
|
|
28581
|
+
return text4;
|
|
28310
28582
|
if (lineWidth < minContentWidth)
|
|
28311
28583
|
minContentWidth = 0;
|
|
28312
28584
|
const endStep = Math.max(1 + minContentWidth, 1 + lineWidth - indent.length);
|
|
28313
|
-
if (
|
|
28314
|
-
return
|
|
28585
|
+
if (text4.length <= endStep)
|
|
28586
|
+
return text4;
|
|
28315
28587
|
const folds = [];
|
|
28316
28588
|
const escapedFolds = {};
|
|
28317
28589
|
let end = lineWidth - indent.length;
|
|
@@ -28328,14 +28600,14 @@ function foldFlowLines(text3, indent, mode = "flow", { indentAtStart, lineWidth
|
|
|
28328
28600
|
let escStart = -1;
|
|
28329
28601
|
let escEnd = -1;
|
|
28330
28602
|
if (mode === FOLD_BLOCK) {
|
|
28331
|
-
i2 = consumeMoreIndentedLines(
|
|
28603
|
+
i2 = consumeMoreIndentedLines(text4, i2, indent.length);
|
|
28332
28604
|
if (i2 !== -1)
|
|
28333
28605
|
end = i2 + endStep;
|
|
28334
28606
|
}
|
|
28335
|
-
for (let ch; ch =
|
|
28607
|
+
for (let ch; ch = text4[i2 += 1]; ) {
|
|
28336
28608
|
if (mode === FOLD_QUOTED && ch === "\\") {
|
|
28337
28609
|
escStart = i2;
|
|
28338
|
-
switch (
|
|
28610
|
+
switch (text4[i2 + 1]) {
|
|
28339
28611
|
case "x":
|
|
28340
28612
|
i2 += 3;
|
|
28341
28613
|
break;
|
|
@@ -28352,12 +28624,12 @@ function foldFlowLines(text3, indent, mode = "flow", { indentAtStart, lineWidth
|
|
|
28352
28624
|
}
|
|
28353
28625
|
if (ch === "\n") {
|
|
28354
28626
|
if (mode === FOLD_BLOCK)
|
|
28355
|
-
i2 = consumeMoreIndentedLines(
|
|
28627
|
+
i2 = consumeMoreIndentedLines(text4, i2, indent.length);
|
|
28356
28628
|
end = i2 + indent.length + endStep;
|
|
28357
28629
|
split = void 0;
|
|
28358
28630
|
} else {
|
|
28359
28631
|
if (ch === " " && prev && prev !== " " && prev !== "\n" && prev !== " ") {
|
|
28360
|
-
const next =
|
|
28632
|
+
const next = text4[i2 + 1];
|
|
28361
28633
|
if (next && next !== " " && next !== "\n" && next !== " ")
|
|
28362
28634
|
split = i2;
|
|
28363
28635
|
}
|
|
@@ -28369,12 +28641,12 @@ function foldFlowLines(text3, indent, mode = "flow", { indentAtStart, lineWidth
|
|
|
28369
28641
|
} else if (mode === FOLD_QUOTED) {
|
|
28370
28642
|
while (prev === " " || prev === " ") {
|
|
28371
28643
|
prev = ch;
|
|
28372
|
-
ch =
|
|
28644
|
+
ch = text4[i2 += 1];
|
|
28373
28645
|
overflow = true;
|
|
28374
28646
|
}
|
|
28375
28647
|
const j = i2 > escEnd + 1 ? i2 - 2 : escStart - 1;
|
|
28376
28648
|
if (escapedFolds[j])
|
|
28377
|
-
return
|
|
28649
|
+
return text4;
|
|
28378
28650
|
folds.push(j);
|
|
28379
28651
|
escapedFolds[j] = true;
|
|
28380
28652
|
end = j + endStep;
|
|
@@ -28389,39 +28661,39 @@ function foldFlowLines(text3, indent, mode = "flow", { indentAtStart, lineWidth
|
|
|
28389
28661
|
if (overflow && onOverflow)
|
|
28390
28662
|
onOverflow();
|
|
28391
28663
|
if (folds.length === 0)
|
|
28392
|
-
return
|
|
28664
|
+
return text4;
|
|
28393
28665
|
if (onFold)
|
|
28394
28666
|
onFold();
|
|
28395
|
-
let res =
|
|
28667
|
+
let res = text4.slice(0, folds[0]);
|
|
28396
28668
|
for (let i3 = 0; i3 < folds.length; ++i3) {
|
|
28397
28669
|
const fold = folds[i3];
|
|
28398
|
-
const end2 = folds[i3 + 1] ||
|
|
28670
|
+
const end2 = folds[i3 + 1] || text4.length;
|
|
28399
28671
|
if (fold === 0)
|
|
28400
28672
|
res = `
|
|
28401
|
-
${indent}${
|
|
28673
|
+
${indent}${text4.slice(0, end2)}`;
|
|
28402
28674
|
else {
|
|
28403
28675
|
if (mode === FOLD_QUOTED && escapedFolds[fold])
|
|
28404
|
-
res += `${
|
|
28676
|
+
res += `${text4[fold]}\\`;
|
|
28405
28677
|
res += `
|
|
28406
|
-
${indent}${
|
|
28678
|
+
${indent}${text4.slice(fold + 1, end2)}`;
|
|
28407
28679
|
}
|
|
28408
28680
|
}
|
|
28409
28681
|
return res;
|
|
28410
28682
|
}
|
|
28411
|
-
function consumeMoreIndentedLines(
|
|
28683
|
+
function consumeMoreIndentedLines(text4, i2, indent) {
|
|
28412
28684
|
let end = i2;
|
|
28413
28685
|
let start = i2 + 1;
|
|
28414
|
-
let ch =
|
|
28686
|
+
let ch = text4[start];
|
|
28415
28687
|
while (ch === " " || ch === " ") {
|
|
28416
28688
|
if (i2 < start + indent) {
|
|
28417
|
-
ch =
|
|
28689
|
+
ch = text4[++i2];
|
|
28418
28690
|
} else {
|
|
28419
28691
|
do {
|
|
28420
|
-
ch =
|
|
28692
|
+
ch = text4[++i2];
|
|
28421
28693
|
} while (ch && ch !== "\n");
|
|
28422
28694
|
end = i2;
|
|
28423
28695
|
start = i2 + 1;
|
|
28424
|
-
ch =
|
|
28696
|
+
ch = text4[start];
|
|
28425
28697
|
}
|
|
28426
28698
|
}
|
|
28427
28699
|
return end;
|
|
@@ -34247,24 +34519,24 @@ function quoteYaml(value) {
|
|
|
34247
34519
|
if (/^[\w./:+-]+$/.test(value)) return value;
|
|
34248
34520
|
return JSON.stringify(value);
|
|
34249
34521
|
}
|
|
34250
|
-
function upsertHermesProvider(
|
|
34522
|
+
function upsertHermesProvider(text4, hostId, baseUrl, apiKey) {
|
|
34251
34523
|
const block2 = [` ${hostId}:`, ` base_url: ${quoteYaml(baseUrl)}`, ` api_key: ${quoteYaml(apiKey)}`, ""].join(
|
|
34252
34524
|
"\n"
|
|
34253
34525
|
);
|
|
34254
|
-
if (/^providers:\s*$/m.test(
|
|
34255
|
-
const replaced = replaceHermesHostBlock(
|
|
34526
|
+
if (/^providers:\s*$/m.test(text4)) {
|
|
34527
|
+
const replaced = replaceHermesHostBlock(text4, hostId, block2);
|
|
34256
34528
|
if (replaced !== null) return replaced;
|
|
34257
|
-
return
|
|
34529
|
+
return text4.replace(/^providers:\s*$/m, `providers:
|
|
34258
34530
|
${block2.trimEnd()}`);
|
|
34259
34531
|
}
|
|
34260
|
-
const prefix =
|
|
34261
|
-
` :
|
|
34532
|
+
const prefix = text4 && !text4.endsWith("\n") ? `${text4}
|
|
34533
|
+
` : text4;
|
|
34262
34534
|
return `${prefix}
|
|
34263
34535
|
providers:
|
|
34264
34536
|
${block2}`;
|
|
34265
34537
|
}
|
|
34266
|
-
function replaceHermesHostBlock(
|
|
34267
|
-
const lines =
|
|
34538
|
+
function replaceHermesHostBlock(text4, hostId, block2) {
|
|
34539
|
+
const lines = text4.split("\n");
|
|
34268
34540
|
const start = lines.findIndex((line) => line === ` ${hostId}:`);
|
|
34269
34541
|
if (start < 0) return null;
|
|
34270
34542
|
let end = start + 1;
|
|
@@ -34284,14 +34556,14 @@ function ensureHermesInjectProvider(modelId, env = process.env) {
|
|
|
34284
34556
|
const dir = hermesHome(env);
|
|
34285
34557
|
mkdirSync14(dir, { recursive: true });
|
|
34286
34558
|
const path3 = join31(dir, "config.yaml");
|
|
34287
|
-
let
|
|
34559
|
+
let text4 = "";
|
|
34288
34560
|
try {
|
|
34289
|
-
|
|
34561
|
+
text4 = readFileSync17(path3, "utf8");
|
|
34290
34562
|
} catch {
|
|
34291
|
-
|
|
34563
|
+
text4 = "";
|
|
34292
34564
|
}
|
|
34293
|
-
const next = upsertHermesProvider(
|
|
34294
|
-
if (next !==
|
|
34565
|
+
const next = upsertHermesProvider(text4, inject.host, host.baseUrl, hostApiKey(host, env));
|
|
34566
|
+
if (next !== text4) writeFileSync12(path3, next);
|
|
34295
34567
|
return hermesAcpModelId(modelId) ?? modelId;
|
|
34296
34568
|
}
|
|
34297
34569
|
function hermesAcpModelId(modelId) {
|
|
@@ -34301,8 +34573,8 @@ function hermesAcpModelId(modelId) {
|
|
|
34301
34573
|
if (native && !native.includes(INJECT_SEP) && /^[a-z0-9_-]+:[\w./:-]+$/i.test(native)) return native;
|
|
34302
34574
|
return null;
|
|
34303
34575
|
}
|
|
34304
|
-
function nonEmptyDotenvValue(
|
|
34305
|
-
const match = new RegExp(`^[ \\t]*(?:export[ \\t]+)?${name}[ \\t]*=[ \\t]*([^\\r\\n]*)$`, "m").exec(
|
|
34576
|
+
function nonEmptyDotenvValue(text4, name) {
|
|
34577
|
+
const match = new RegExp(`^[ \\t]*(?:export[ \\t]+)?${name}[ \\t]*=[ \\t]*([^\\r\\n]*)$`, "m").exec(text4);
|
|
34306
34578
|
if (!match) return null;
|
|
34307
34579
|
const raw = match[1].trim();
|
|
34308
34580
|
if (!raw || raw.startsWith("#")) return null;
|
|
@@ -34319,10 +34591,10 @@ function nonEmptyDotenvValue(text3, name) {
|
|
|
34319
34591
|
function yamlString(value) {
|
|
34320
34592
|
return typeof value === "string" ? value.trim() : "";
|
|
34321
34593
|
}
|
|
34322
|
-
function hermesConfigDefault(
|
|
34594
|
+
function hermesConfigDefault(text4) {
|
|
34323
34595
|
let raw;
|
|
34324
34596
|
try {
|
|
34325
|
-
raw = parse3(
|
|
34597
|
+
raw = parse3(text4);
|
|
34326
34598
|
} catch {
|
|
34327
34599
|
return null;
|
|
34328
34600
|
}
|
|
@@ -34667,8 +34939,8 @@ var init_openai_compat = __esm({
|
|
|
34667
34939
|
nativeLog: {
|
|
34668
34940
|
source: "openai-compat.chat.completions",
|
|
34669
34941
|
outgoing: (_turn, messages, model) => ({ model, messageCount: messages.length }),
|
|
34670
|
-
incoming: ({ text:
|
|
34671
|
-
textLength:
|
|
34942
|
+
incoming: ({ text: text4, reasoning, usage }) => ({
|
|
34943
|
+
textLength: text4.length,
|
|
34672
34944
|
reasoningLength: reasoning.length,
|
|
34673
34945
|
usage
|
|
34674
34946
|
})
|
|
@@ -35059,10 +35331,10 @@ var init_pi = __esm({
|
|
|
35059
35331
|
child.stdin.write(JSON.stringify(obj) + "\n");
|
|
35060
35332
|
};
|
|
35061
35333
|
const flushAssistantText = () => {
|
|
35062
|
-
const
|
|
35334
|
+
const text4 = assistantText;
|
|
35063
35335
|
assistantText = "";
|
|
35064
|
-
if (!
|
|
35065
|
-
emit({ ...base2(threadId, turnId), type: "item.completed", itemType: "assistant_text", text:
|
|
35336
|
+
if (!text4.trim()) return;
|
|
35337
|
+
emit({ ...base2(threadId, turnId), type: "item.completed", itemType: "assistant_text", text: text4 });
|
|
35066
35338
|
};
|
|
35067
35339
|
const settle = (ok, stopReason, usage) => {
|
|
35068
35340
|
if (settled) return;
|
|
@@ -35455,7 +35727,7 @@ var init_minimax = __esm({
|
|
|
35455
35727
|
nativeLog: {
|
|
35456
35728
|
source: "minimax.chat.completions",
|
|
35457
35729
|
outgoing: (_turn, messages, model) => ({ model, messageCount: messages.length }),
|
|
35458
|
-
incoming: ({ text:
|
|
35730
|
+
incoming: ({ text: text4, usage }) => ({ textLength: text4.length, usage })
|
|
35459
35731
|
}
|
|
35460
35732
|
});
|
|
35461
35733
|
}
|
|
@@ -37122,10 +37394,10 @@ async function verifyHostedEndpoint(endpoint, { fetchImpl, timeoutSignal, timeou
|
|
|
37122
37394
|
signal: cancellationSignal ? AbortSignal.any([requestSignal, cancellationSignal]) : requestSignal
|
|
37123
37395
|
});
|
|
37124
37396
|
if (!response.ok) return false;
|
|
37125
|
-
const
|
|
37126
|
-
if (Buffer.byteLength(
|
|
37397
|
+
const text4 = await response.text();
|
|
37398
|
+
if (Buffer.byteLength(text4) > 4096) return false;
|
|
37127
37399
|
try {
|
|
37128
|
-
return JSON.parse(
|
|
37400
|
+
return JSON.parse(text4)?.app === "openmausbot";
|
|
37129
37401
|
} catch {
|
|
37130
37402
|
return false;
|
|
37131
37403
|
}
|
|
@@ -38046,9 +38318,9 @@ async function startCaddy(options) {
|
|
|
38046
38318
|
});
|
|
38047
38319
|
let output = "";
|
|
38048
38320
|
const receive = (chunk) => {
|
|
38049
|
-
const
|
|
38050
|
-
if (output.length < 16384) output +=
|
|
38051
|
-
for (const line of
|
|
38321
|
+
const text4 = chunk.toString("utf8");
|
|
38322
|
+
if (output.length < 16384) output += text4;
|
|
38323
|
+
for (const line of text4.split(/\r?\n/)) {
|
|
38052
38324
|
if (!line.trim()) continue;
|
|
38053
38325
|
if (/"level":"(warn|error)"/.test(line) || /^\S+\s+(WARN|ERROR)/.test(line) || !line.startsWith("{")) options.log?.(`caddy: ${line.slice(0, 400)}`);
|
|
38054
38326
|
}
|
|
@@ -38315,8 +38587,8 @@ function agentUnit(spec) {
|
|
|
38315
38587
|
function emptyRegistry(domain2) {
|
|
38316
38588
|
return { version: 1, domain: domain2, nextPort: FLEET_FIRST_PORT, workspaces: {} };
|
|
38317
38589
|
}
|
|
38318
|
-
function parseRegistry(
|
|
38319
|
-
const value = JSON.parse(
|
|
38590
|
+
function parseRegistry(text4) {
|
|
38591
|
+
const value = JSON.parse(text4);
|
|
38320
38592
|
const record3 = value && typeof value === "object" ? value : null;
|
|
38321
38593
|
if (!record3 || record3.version !== 1 || typeof record3.domain !== "string" || typeof record3.nextPort !== "number" || !record3.workspaces || typeof record3.workspaces !== "object") {
|
|
38322
38594
|
throw new Error("fleet.json is not a fleet registry this version understands");
|
|
@@ -38740,9 +39012,9 @@ function failed(io, what, output) {
|
|
|
38740
39012
|
return 1;
|
|
38741
39013
|
}
|
|
38742
39014
|
function loadRegistry(layout, deps) {
|
|
38743
|
-
const
|
|
38744
|
-
if (
|
|
38745
|
-
return parseRegistry(
|
|
39015
|
+
const text4 = deps.readText(layout.registryFile);
|
|
39016
|
+
if (text4 === null) throw new Error(`no fleet on this server yet: run \`openmausbot fleet init --domain your.domain\` first`);
|
|
39017
|
+
return parseRegistry(text4);
|
|
38746
39018
|
}
|
|
38747
39019
|
function planFleetAction(input, deps) {
|
|
38748
39020
|
const layout = fleetLayout(input.root ?? "/");
|
|
@@ -38889,13 +39161,13 @@ function readUsage(dataDir, range) {
|
|
|
38889
39161
|
const from = range.from.getTime();
|
|
38890
39162
|
const to = range.to.getTime();
|
|
38891
39163
|
for (const key of monthsBetween(range.from, range.to)) {
|
|
38892
|
-
let
|
|
39164
|
+
let text4;
|
|
38893
39165
|
try {
|
|
38894
|
-
|
|
39166
|
+
text4 = readFileSync2(join4(dataDir, DIR, `${key}.jsonl`), "utf8");
|
|
38895
39167
|
} catch {
|
|
38896
39168
|
continue;
|
|
38897
39169
|
}
|
|
38898
|
-
for (const line of
|
|
39170
|
+
for (const line of text4.split("\n")) {
|
|
38899
39171
|
if (!line) continue;
|
|
38900
39172
|
try {
|
|
38901
39173
|
const value = JSON.parse(line);
|
|
@@ -38989,15 +39261,15 @@ function summarizeUsage(rows, groupBy, prices = null) {
|
|
|
38989
39261
|
var MAX_BODY = 256 * 1024;
|
|
38990
39262
|
function readBody(req) {
|
|
38991
39263
|
return new Promise((resolve13, reject) => {
|
|
38992
|
-
let
|
|
39264
|
+
let text4 = "";
|
|
38993
39265
|
req.on("data", (chunk) => {
|
|
38994
|
-
|
|
38995
|
-
if (
|
|
39266
|
+
text4 += chunk.toString("utf8");
|
|
39267
|
+
if (text4.length > MAX_BODY) reject(Object.assign(new Error("request too large"), { status: 413 }));
|
|
38996
39268
|
});
|
|
38997
39269
|
req.on("end", () => {
|
|
38998
|
-
if (!
|
|
39270
|
+
if (!text4.trim()) return resolve13({});
|
|
38999
39271
|
try {
|
|
39000
|
-
const value = JSON.parse(
|
|
39272
|
+
const value = JSON.parse(text4);
|
|
39001
39273
|
resolve13(value && typeof value === "object" && !Array.isArray(value) ? value : {});
|
|
39002
39274
|
} catch {
|
|
39003
39275
|
reject(Object.assign(new Error("body must be JSON"), { status: 400 }));
|
|
@@ -39168,8 +39440,8 @@ var tailscaleEnvironment = () => ({
|
|
|
39168
39440
|
});
|
|
39169
39441
|
|
|
39170
39442
|
// server/tailscale.ts
|
|
39171
|
-
function classifyTailscaleStderr(
|
|
39172
|
-
const t2 =
|
|
39443
|
+
function classifyTailscaleStderr(text4) {
|
|
39444
|
+
const t2 = text4.toLowerCase();
|
|
39173
39445
|
if (/not logged in|logged out|needs login|please log in/.test(t2)) return "not-logged-in";
|
|
39174
39446
|
if (/is tailscale running|tailscaled is not running|connection refused|failed to connect to local tailscaled/.test(t2)) return "not-running";
|
|
39175
39447
|
if (/access denied|permission denied|operator|must be root|not permitted/.test(t2)) return "needs-operator";
|
|
@@ -39900,9 +40172,9 @@ function pairingBlock(input) {
|
|
|
39900
40172
|
}
|
|
39901
40173
|
return lines.join("\n");
|
|
39902
40174
|
}
|
|
39903
|
-
function qrToString(
|
|
40175
|
+
function qrToString(text4) {
|
|
39904
40176
|
let out = "";
|
|
39905
|
-
import_qrcode_terminal.default.generate(
|
|
40177
|
+
import_qrcode_terminal.default.generate(text4, { small: true }, (rendered) => {
|
|
39906
40178
|
out = rendered;
|
|
39907
40179
|
});
|
|
39908
40180
|
return out;
|
|
@@ -40317,9 +40589,9 @@ async function runServe(options, log = console.log) {
|
|
|
40317
40589
|
});
|
|
40318
40590
|
let tunnel = null;
|
|
40319
40591
|
let caddy = null;
|
|
40320
|
-
let
|
|
40592
|
+
let stopping2 = null;
|
|
40321
40593
|
const stop = () => {
|
|
40322
|
-
|
|
40594
|
+
stopping2 ??= (async () => {
|
|
40323
40595
|
if (tunnel) await tunnel.stop().catch(() => void 0);
|
|
40324
40596
|
if (caddy) await caddy.stop().catch(() => void 0);
|
|
40325
40597
|
if (tailscaleServing && tailscale) await tailscaleServeOff(tailscale).catch(() => void 0);
|
|
@@ -40332,7 +40604,7 @@ async function runServe(options, log = console.log) {
|
|
|
40332
40604
|
}
|
|
40333
40605
|
if (plan) cleanupTunnelOrigin(plan.origin);
|
|
40334
40606
|
})();
|
|
40335
|
-
return
|
|
40607
|
+
return stopping2;
|
|
40336
40608
|
};
|
|
40337
40609
|
const onSignal = () => {
|
|
40338
40610
|
void stop();
|
|
@@ -40341,7 +40613,7 @@ async function runServe(options, log = console.log) {
|
|
|
40341
40613
|
process.on("SIGTERM", onSignal);
|
|
40342
40614
|
try {
|
|
40343
40615
|
const deadline = Date.now() + 6e4;
|
|
40344
|
-
while (Date.now() < deadline && exited === null && !
|
|
40616
|
+
while (Date.now() < deadline && exited === null && !stopping2) {
|
|
40345
40617
|
if (await serverUp(options.port, child.pid)) break;
|
|
40346
40618
|
await new Promise((r2) => setTimeout(r2, 250));
|
|
40347
40619
|
}
|
|
@@ -40349,19 +40621,19 @@ async function runServe(options, log = console.log) {
|
|
|
40349
40621
|
if (exited !== 0) log(`OpenMausBot could not start.${logPath ? ` Details: ${logPath}` : " See the output above."}`);
|
|
40350
40622
|
return exited;
|
|
40351
40623
|
}
|
|
40352
|
-
if (
|
|
40624
|
+
if (stopping2) return await childExit;
|
|
40353
40625
|
if (!await serverUp(options.port, child.pid)) {
|
|
40354
40626
|
console.error(`OpenMausBot did not become ready within a minute.${logPath ? ` Details: ${logPath}` : " See its output above."}`);
|
|
40355
40627
|
await stop();
|
|
40356
40628
|
return 1;
|
|
40357
40629
|
}
|
|
40358
|
-
if (
|
|
40630
|
+
if (stopping2 || exited !== null) return await childExit;
|
|
40359
40631
|
if (options.domain && caddyBinary) {
|
|
40360
40632
|
try {
|
|
40361
40633
|
caddy = await startCaddy({ binary: caddyBinary, dataDir: options.dataDir, domain: options.domain, appPort: options.port, webhookPort: Number(env.OMB_WEBHOOK_PORT), log });
|
|
40362
40634
|
log(`https: Caddy serves ${publicUrl} \u2192 http://127.0.0.1:${options.port}; it gets the certificate from Let's Encrypt once DNS for ${options.domain} points at this machine`);
|
|
40363
40635
|
void caddy.exited.then((code) => {
|
|
40364
|
-
if (!
|
|
40636
|
+
if (!stopping2) log(`caddy: stopped (exit ${code ?? "signal"}); ${publicUrl} is no longer served. Stop and start the server again.`);
|
|
40365
40637
|
});
|
|
40366
40638
|
} catch (error51) {
|
|
40367
40639
|
console.error(`--domain: ${message(error51)}`);
|
|
@@ -40404,7 +40676,7 @@ async function runServe(options, log = console.log) {
|
|
|
40404
40676
|
]);
|
|
40405
40677
|
if (timer) clearTimeout(timer);
|
|
40406
40678
|
}
|
|
40407
|
-
if (!
|
|
40679
|
+
if (!stopping2 && exited === null) await showPhonePairing(options, publicUrl, log);
|
|
40408
40680
|
} else if (options.pair && !options.guided) {
|
|
40409
40681
|
log("");
|
|
40410
40682
|
log(await mintPairing(options.port, { label: options.label ? `${options.label} owner` : void 0, client: options.client, publicUrl: publicUrl ?? void 0 }));
|