openmausbot 0.1.97 → 0.1.98
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/ActivityPanel-H6D3SD39.js +1 -0
- package/dist/assets/BotSettingsDialog-Dqz_AiBZ.js +7 -0
- package/dist/assets/CloudBackendPicker-iezpJFpF.js +1 -0
- package/dist/assets/ComputerPanel-DZPj-IWu.js +1 -0
- package/dist/assets/DesktopViewer-utONms1p.js +5 -0
- package/dist/assets/InspectorPanel-OVaBVrzC.js +5 -0
- package/dist/assets/KeyboardShortcutsModal-gk9mvHj_.js +1 -0
- package/dist/assets/LocalVmWorkspace-DLIvd2kC.js +1 -0
- package/dist/assets/MacLocalControl-bJv8yiPB.js +1 -0
- package/dist/assets/NewBotDialog-1qGOAdUM.js +2 -0
- package/dist/assets/RemoteAgentSettingsPanel-DqKr0HkO.js +1 -0
- package/dist/assets/RoutinesPage-BM2D4qGi.js +1 -0
- package/dist/assets/RoutinesSection-Dny9ra-c.js +1 -0
- package/dist/assets/SettingsModal-gC6XJJmt.js +11 -0
- package/dist/assets/TeamMapPage-B6fuu4r_.js +8 -0
- package/dist/assets/TriggersPanel-j0qTP2CO.js +1 -0
- package/dist/assets/VisibilitySection-DT0FqPvu.js +12 -0
- package/dist/assets/WebhooksPanel--YQyCjKO.js +3 -0
- package/dist/assets/{abnfDiagram-O67JEVCF-k1UCNXb7.js → abnfDiagram-O67JEVCF-BsjcFX0-.js} +1 -1
- package/dist/assets/activity-BxOkayvD.js +1 -0
- package/dist/assets/{arc-BUWGa9UU.js → arc-CJNA94c6.js} +1 -1
- package/dist/assets/architectureDiagram-NJMV4G6O-dz2ud7lP.js +36 -0
- package/dist/assets/{blockDiagram-BEXU5L5S-Ag9nLW4H.js → blockDiagram-BEXU5L5S-ChBEALoR.js} +1 -1
- package/dist/assets/brain-CFZ7PEXc.js +1 -0
- package/dist/assets/{c4Diagram-YGBWAQC7-Bh0sjgUa.js → c4Diagram-YGBWAQC7-KZNRKDQe.js} +1 -1
- package/dist/assets/channel-WhFyujhZ.js +1 -0
- package/dist/assets/{chunk-2Q5K7J3B-BFBcIIqu.js → chunk-2Q5K7J3B-BLLwmCET.js} +1 -1
- package/dist/assets/{chunk-3FUC2YCW-Dvfpex-f.js → chunk-3FUC2YCW-CQxyreBZ.js} +2 -2
- package/dist/assets/{chunk-5VM5RSS4-CMjP2YZW.js → chunk-5VM5RSS4-D6sFMW0u.js} +1 -1
- package/dist/assets/{chunk-GTNCS2PH-BryoeTc7.js → chunk-GTNCS2PH-BaZ1YgLF.js} +1 -1
- package/dist/assets/{chunk-GWA4HPMP-BhfvcchO.js → chunk-GWA4HPMP-CcalphmC.js} +1 -1
- package/dist/assets/{chunk-JWPE2WC7-bcCVp8rp.js → chunk-JWPE2WC7-CSk8R3ve.js} +1 -1
- package/dist/assets/{chunk-NETBCI7D-yKIjIlkQ.js → chunk-NETBCI7D-CTmLjA57.js} +1 -1
- package/dist/assets/{chunk-WEXAMYUT-D3Zqbmup.js → chunk-WEXAMYUT-CM9Z77Ne.js} +1 -1
- package/dist/assets/{chunk-XXDRQBXY-CjVoIMG6.js → chunk-XXDRQBXY-B1fxpMS2.js} +1 -1
- package/dist/assets/{classDiagram-v2-NBCMYWYE-mUCWdVyH.js → classDiagram-v2-NBCMYWYE-DCCyoLpj.js} +1 -1
- package/dist/assets/computer-control-NLov352p.js +1 -0
- package/dist/assets/cose-bilkent-JH36ORCC-KyImBKvE.js +1 -0
- package/dist/assets/{cynefin-OW5HDTMX-BpRrxoO4.js → cynefin-OW5HDTMX-fsZc6MGa.js} +1 -1
- package/dist/assets/{cynefinDiagram-VND7K2PF-D3VBWCPK.js → cynefinDiagram-VND7K2PF-CGmHsShB.js} +1 -1
- package/dist/assets/{dagre-6A5THRUB-DxEIACOO.js → dagre-6A5THRUB-Dah1h-CH.js} +1 -1
- package/dist/assets/{diagram-22UHCM2B-BANgZEOS.js → diagram-22UHCM2B-BIu71OyV.js} +1 -1
- package/dist/assets/{diagram-3UASUU5V-Cnq7nJir.js → diagram-3UASUU5V-gxhUB_Mu.js} +1 -1
- package/dist/assets/{diagram-ATOU4E4O-4TBDIWnz.js → diagram-ATOU4E4O-CBhusUBn.js} +1 -1
- package/dist/assets/{diagram-CDSNMT55-CD_B39D4.js → diagram-CDSNMT55-BdPrc86x.js} +1 -1
- package/dist/assets/{diagram-MLGK6HIB-CzvnFhEC.js → diagram-MLGK6HIB-Clp110R_.js} +1 -1
- package/dist/assets/{diagram-MPIPVDR6-C4w2SNml.js → diagram-MPIPVDR6-DJKfbugw.js} +1 -1
- package/dist/assets/{ebnfDiagram-ZINNZB2B-gkUEBm2s.js → ebnfDiagram-ZINNZB2B-DnsltoBu.js} +1 -1
- package/dist/assets/{elk-276RUBZZ-B_56X6mw.js → elk-276RUBZZ-jWdq6gqH.js} +1 -1
- package/dist/assets/{erDiagram-OPXOYQCR-C_oByoDS.js → erDiagram-OPXOYQCR-DArPVf8u.js} +1 -1
- package/dist/assets/{flowDiagram-KWPJA3E3-CR9xXJkC.js → flowDiagram-KWPJA3E3-D2HZ-2f7.js} +1 -1
- package/dist/assets/ganttDiagram-FUAMR5RP--o0KIxEo.js +292 -0
- package/dist/assets/{gitGraphDiagram-X574FWY7-VJ6-Tp_p.js → gitGraphDiagram-X574FWY7-CsoXr2D7.js} +1 -1
- package/dist/assets/image-plus-BbVjGHin.js +1 -0
- package/dist/assets/index-BrPW5HDO.css +1 -0
- package/dist/assets/index-C3NqfdVU.js +585 -0
- package/dist/assets/{index-Cp4S4NOL.js → index-CJTp9JEp.js} +1 -1
- package/dist/assets/{infoDiagram-VRGFBTTK-2Lu9te4D.js → infoDiagram-VRGFBTTK-g-6lNp7r.js} +1 -1
- package/dist/assets/{ishikawaDiagram-OU5B5YK6-DR49XY-e.js → ishikawaDiagram-OU5B5YK6-B1d6qVTV.js} +1 -1
- package/dist/assets/{journeyDiagram-ZHPQQLJL-ZoR0M305.js → journeyDiagram-ZHPQQLJL-BTPuiU6T.js} +1 -1
- package/dist/assets/{kanban-definition-PNTS6WVX-DLKHxrO-.js → kanban-definition-PNTS6WVX-bDDuRJvP.js} +1 -1
- package/dist/assets/{linear-BASsfWly.js → linear-BVVKbEMy.js} +1 -1
- package/dist/assets/{mermaid.core-BVidiPkk.js → mermaid.core-JJdoKyKB.js} +5 -5
- package/dist/assets/{mindmap-definition-NLK3R4M7-g_Qx0U5C.js → mindmap-definition-NLK3R4M7-B4aE3T0q.js} +1 -1
- package/dist/assets/module-DCUsy2BQ.js +3 -0
- package/dist/assets/page-visible-BBo_Zm8g.js +1 -0
- package/dist/assets/{pegDiagram-GJSIUBJH-DI9Cjs8w.js → pegDiagram-GJSIUBJH-DFKQWpR7.js} +1 -1
- package/dist/assets/{pieDiagram-5QR66LMP-sRI0Uhr5.js → pieDiagram-5QR66LMP-Iv7OKVJi.js} +1 -1
- package/dist/assets/{quadrantDiagram-O4NWA36T-CamKTby3.js → quadrantDiagram-O4NWA36T-U2YnfwBk.js} +1 -1
- package/dist/assets/{railroadDiagram-XR7U4H2S-DOLlkbf3.js → railroadDiagram-XR7U4H2S-CuPy6RqM.js} +1 -1
- package/dist/assets/remote-desktop-panel-BNEj7tUx.js +1 -0
- package/dist/assets/{requirementDiagram-PLB6GJNP-DrRQ5r97.js → requirementDiagram-PLB6GJNP-bMI5AK7T.js} +1 -1
- package/dist/assets/{sankeyDiagram-IPEJSGJF-DGS_lXcX.js → sankeyDiagram-IPEJSGJF-BKcFE2WQ.js} +1 -1
- package/dist/assets/{sequenceDiagram-PO4LG4MO-CkjWqwtf.js → sequenceDiagram-PO4LG4MO-Bn9q88kl.js} +1 -1
- package/dist/assets/{sizeCapture-INFHLROL-CepRgful.js → sizeCapture-INFHLROL-Cvmdq9HD.js} +1 -1
- package/dist/assets/{stateDiagram-v2-GCMORJYK-hykr-9RS.js → stateDiagram-v2-GCMORJYK-JJQYw3eQ.js} +1 -1
- package/dist/assets/{swimlanes-2SLR337P-CKOHEZbI.js → swimlanes-2SLR337P-BkSCBEwp.js} +1 -1
- package/dist/assets/swimlanesDiagram-TC7HE7FX-CmTirbVT.js +8 -0
- package/dist/assets/table-file.worker-KkMx-SNx.js +10 -0
- package/dist/assets/{timeline-definition-EJHVYXUP-CB8pJ6AC.js → timeline-definition-EJHVYXUP-DsaM4GHr.js} +1 -1
- package/dist/assets/{usecaseDiagram-POWQR4AR-DrclJHdl.js → usecaseDiagram-POWQR4AR-3FOwLq7B.js} +1 -1
- package/dist/assets/user-DcZBnAuv.js +1 -0
- package/dist/assets/{vennDiagram-UO4OBE2U-zS23qjv8.js → vennDiagram-UO4OBE2U-DyNjJsKt.js} +1 -1
- package/dist/assets/{wardleyDiagram-VNRHLVJA-52jgeKxz.js → wardleyDiagram-VNRHLVJA-Y4ZMcnBC.js} +1 -1
- package/dist/assets/{xychartDiagram-PMCCYNJV-DSdl9rQ8.js → xychartDiagram-PMCCYNJV-BXZpg955.js} +1 -1
- package/dist/index.html +2 -2
- package/dist-server/cloud-home-start.js +19 -8
- package/dist-server/container-mcp.js +8 -0
- package/dist-server/desktop-entry.mjs +54 -0
- package/dist-server/drivers/agents-proxy.js +21 -4
- package/dist-server/index.js +1412 -821
- package/dist-server/openmausbot.js +837 -571
- package/dist-server/pair-cli.js +837 -571
- package/dist-server/permission-proxy.js +2 -0
- package/dist-server/server/atomic.js +70 -2
- package/dist-server/server/cloud-home-start.js +3 -3
- package/dist-server/server/config.js +22 -1
- package/dist-server/server/connector-card-text.js +15 -0
- package/dist-server/server/default-model-selection.js +7 -4
- package/dist-server/server/drivers/acp/core.js +10 -0
- package/dist-server/server/drivers/acp/grok.js +47 -5
- package/dist-server/server/drivers/agents-catalog.js +24 -4
- package/dist-server/server/drivers/agents-proxy.js +1 -0
- package/dist-server/server/drivers/chat-mcp-tools.js +5 -3
- package/dist-server/server/drivers/claude-login-auth.js +1 -1
- package/dist-server/server/drivers/claude.js +35 -11
- package/dist-server/server/drivers/codex-device-auth.js +27 -319
- package/dist-server/server/drivers/device-auth.js +342 -0
- package/dist-server/server/drivers/openai-chat.js +12 -4
- package/dist-server/server/fleet-agent.js +18 -5
- package/dist-server/server/harness/http.js +5 -2
- package/dist-server/server/harness/registry.js +19 -0
- package/dist-server/server/harness-capabilities.js +7 -4
- package/dist-server/server/hosted-models.js +3 -1
- package/dist-server/server/index.js +268 -54
- package/dist-server/server/key-rejections.js +57 -0
- package/dist-server/server/message-file.js +7 -4
- package/dist-server/server/permission-proxy.js +4 -0
- package/dist-server/server/provider-key-check.js +5 -1
- package/dist-server/server/request-auth.js +1 -1
- package/dist-server/server/room-turn-timeout.js +28 -0
- package/dist-server/server/routes/thread-models.js +36 -0
- package/dist-server/server/routines.js +2 -2
- package/dist-server/server/skills.js +3 -2
- package/dist-server/server/store.js +148 -60
- package/dist-server/server/team-backup.js +19 -4
- package/dist-server/server/thread-model.js +25 -0
- package/dist-server/server/turn-continuation.js +8 -2
- package/dist-server/server/webhook-ingress.js +8 -3
- package/dist-server/server/webhooks.js +40 -5
- package/dist-server/shared/device-sign-in.js +57 -0
- package/dist-server/shared/team-backup.js +2 -0
- package/dist-server/shared/thread-model.js +13 -0
- package/dist-server/vps-container-mcp.js +8 -0
- package/dist-server/workspace-backup.worker.js +41 -22
- package/package.json +1 -1
- package/dist/assets/DesktopViewer-CPidMCtt.js +0 -5
- package/dist/assets/architectureDiagram-NJMV4G6O-DiPor3UT.js +0 -36
- package/dist/assets/channel-DR8eD6QW.js +0 -1
- package/dist/assets/cose-bilkent-JH36ORCC-BBmR1bbX.js +0 -1
- package/dist/assets/ganttDiagram-FUAMR5RP-gtYBTu0B.js +0 -292
- package/dist/assets/index-CpaIXRLp.js +0 -614
- package/dist/assets/index-Z81SMsgR.css +0 -1
- package/dist/assets/swimlanesDiagram-TC7HE7FX-D-8vqZ4-.js +0 -8
|
@@ -16344,7 +16344,18 @@ var init_enterprise = __esm({
|
|
|
16344
16344
|
|
|
16345
16345
|
// server/atomic.ts
|
|
16346
16346
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
16347
|
-
import {
|
|
16347
|
+
import {
|
|
16348
|
+
closeSync,
|
|
16349
|
+
constants,
|
|
16350
|
+
fstatSync,
|
|
16351
|
+
fsyncSync,
|
|
16352
|
+
lstatSync,
|
|
16353
|
+
openSync,
|
|
16354
|
+
readFileSync,
|
|
16355
|
+
renameSync,
|
|
16356
|
+
unlinkSync,
|
|
16357
|
+
writeFileSync
|
|
16358
|
+
} from "node:fs";
|
|
16348
16359
|
function sleepSync(ms) {
|
|
16349
16360
|
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
|
|
16350
16361
|
}
|
|
@@ -16366,7 +16377,7 @@ function writeFileAtomic(path3, data, options = {}) {
|
|
|
16366
16377
|
try {
|
|
16367
16378
|
fd = openSync(tmp, "w", options.mode);
|
|
16368
16379
|
writeFileSync(fd, data);
|
|
16369
|
-
fsyncSync(fd);
|
|
16380
|
+
if (options.durable !== false) fsyncSync(fd);
|
|
16370
16381
|
closeSync(fd);
|
|
16371
16382
|
fd = null;
|
|
16372
16383
|
renameWithRetry(tmp, path3);
|
|
@@ -16384,6 +16395,37 @@ function writeFileAtomic(path3, data, options = {}) {
|
|
|
16384
16395
|
throw e;
|
|
16385
16396
|
}
|
|
16386
16397
|
}
|
|
16398
|
+
function holdsExactly(path3, data, mode) {
|
|
16399
|
+
let fd = null;
|
|
16400
|
+
try {
|
|
16401
|
+
if (process.platform === "win32") {
|
|
16402
|
+
if (!lstatSync(path3).isFile()) return false;
|
|
16403
|
+
fd = openSync(path3, "r");
|
|
16404
|
+
} else {
|
|
16405
|
+
fd = openSync(path3, constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK);
|
|
16406
|
+
}
|
|
16407
|
+
const stat5 = fstatSync(fd);
|
|
16408
|
+
if (!stat5.isFile() || stat5.size !== Buffer.byteLength(data)) return false;
|
|
16409
|
+
const uid = process.getuid?.();
|
|
16410
|
+
if (uid !== void 0 && stat5.uid !== uid) return false;
|
|
16411
|
+
if (mode !== void 0 && process.platform !== "win32" && (stat5.mode & 511 & ~mode) !== 0) return false;
|
|
16412
|
+
return readFileSync(fd).equals(Buffer.from(data));
|
|
16413
|
+
} catch {
|
|
16414
|
+
return false;
|
|
16415
|
+
} finally {
|
|
16416
|
+
if (fd !== null) {
|
|
16417
|
+
try {
|
|
16418
|
+
closeSync(fd);
|
|
16419
|
+
} catch {
|
|
16420
|
+
}
|
|
16421
|
+
}
|
|
16422
|
+
}
|
|
16423
|
+
}
|
|
16424
|
+
function writeFileAtomicIfChanged(path3, data, options = {}) {
|
|
16425
|
+
if (holdsExactly(path3, data, options.mode)) return false;
|
|
16426
|
+
writeFileAtomic(path3, data, options);
|
|
16427
|
+
return true;
|
|
16428
|
+
}
|
|
16387
16429
|
var RENAME_RETRY_DELAYS_MS, RETRYABLE_RENAME_CODES;
|
|
16388
16430
|
var init_atomic = __esm({
|
|
16389
16431
|
"server/atomic.ts"() {
|
|
@@ -18935,7 +18977,7 @@ var init_schema = __esm({
|
|
|
18935
18977
|
});
|
|
18936
18978
|
|
|
18937
18979
|
// server/config.ts
|
|
18938
|
-
import { readFileSync as
|
|
18980
|
+
import { readFileSync as readFileSync4, mkdirSync as mkdirSync6, existsSync as existsSync6, renameSync as renameSync3, statSync as statSync2 } from "node:fs";
|
|
18939
18981
|
import { homedir as homedir4 } from "node:os";
|
|
18940
18982
|
import { join as join9 } from "node:path";
|
|
18941
18983
|
function isValidSshAlias(value) {
|
|
@@ -19078,7 +19120,7 @@ function parseStoredConfig(value) {
|
|
|
19078
19120
|
function loadConfig() {
|
|
19079
19121
|
let cfg = {};
|
|
19080
19122
|
try {
|
|
19081
|
-
cfg = parseStoredConfig(parseJson(
|
|
19123
|
+
cfg = parseStoredConfig(parseJson(readFileSync4(join9(DATA_DIR, "config.json"), "utf8")));
|
|
19082
19124
|
lastIgnoredConfigWarning = "";
|
|
19083
19125
|
} catch (error51) {
|
|
19084
19126
|
if (error51?.code !== "ENOENT") {
|
|
@@ -19161,7 +19203,7 @@ function saveConfig(patch, options = {}) {
|
|
|
19161
19203
|
const p2 = join9(DATA_DIR, "config.json");
|
|
19162
19204
|
let disk = {};
|
|
19163
19205
|
try {
|
|
19164
|
-
const parsed = jsonObjectSchema.safeParse(parseJson(
|
|
19206
|
+
const parsed = jsonObjectSchema.safeParse(parseJson(readFileSync4(p2, "utf8")));
|
|
19165
19207
|
if (parsed.success) disk = parsed.data;
|
|
19166
19208
|
} catch {
|
|
19167
19209
|
}
|
|
@@ -19169,7 +19211,7 @@ function saveConfig(patch, options = {}) {
|
|
|
19169
19211
|
const before = configSaveListeners.size ? structuredClone(disk) : disk;
|
|
19170
19212
|
const storedProfiles = storedBrowserProfilesSchema.safeParse(disk.browserProfiles);
|
|
19171
19213
|
if (storedProfiles.success) disk.browserProfiles = storedProfiles.data;
|
|
19172
|
-
for (const key of ["xai", "anthropic", "mistral", "cerebras", "openai", "openrouter", "openaiCompat", "composio", "box", "opencodeGo", "tts", "decider", "imageGen", "live", "profile", "rooms", "threads", "context", "memory", "localVm", "features", "budgets", "billing", "decisions", "onboarding", "browserEngine", "newBots"]) {
|
|
19214
|
+
for (const key of ["xai", "anthropic", "mistral", "cerebras", "openai", "openrouter", "openaiCompat", "composio", "box", "opencodeGo", "tts", "decider", "imageGen", "live", "profile", "rooms", "mcp", "threads", "context", "memory", "localVm", "features", "budgets", "billing", "decisions", "onboarding", "browserEngine", "newBots"]) {
|
|
19173
19215
|
const section = checkedPatch[key];
|
|
19174
19216
|
if (!section) continue;
|
|
19175
19217
|
const current = jsonObjectSchema.safeParse(disk[key]);
|
|
@@ -19394,7 +19436,7 @@ function instanceConfigs(cfg) {
|
|
|
19394
19436
|
}
|
|
19395
19437
|
return map3;
|
|
19396
19438
|
}
|
|
19397
|
-
var optionalText, SSH_ALIAS, LEGACY_BROWSER_PROFILE_ID, BROWSER_PROFILE_ID, FISH_TTS_MODELS, MIN_ROOM_TURN_TIMEOUT_MINUTES, MAX_ROOM_TURN_TIMEOUT_MINUTES, DEFAULT_ROOM_HANDOFF_LIFETIME_MINUTES, DEFAULT_ROOM_HANDOFF_MIN_RUNWAY_MINUTES, DEFAULT_ROOM_HANDOFF_HARD_CAP_MINUTES, DEFAULT_MAX_CONCURRENT_BOT_THREADS, MAX_CONCURRENT_BOT_THREADS, MIN_THREAD_EVENT_LOG_BYTES, MAX_THREAD_EVENT_LOG_BYTES, MIN_LOCAL_VM_MAX_INSTANCES, MAX_LOCAL_VM_MAX_INSTANCES, MIN_LOCAL_VM_IDLE_TIMEOUT_MINUTES, MAX_LOCAL_VM_IDLE_TIMEOUT_MINUTES, CDP_PORT, CDP_URL, vpsConfigSchema, browserEngineConfigSchema, roomConfigSchema, localVmConfigSchema, browserProfileSchema, legacyBrowserProfileSchema, legacyBrowserProfilesSchema, storedBrowserProfilesSchema, browserProfilesSchema, featureConfigSchema, onboardingConfigSchema, instanceConfigSchema, instanceConfigMapSchema, defaultModelSelectionSchema, automaticRecoverySchema, threadsConfigSchema, newBotsConfigSchema, newBotsPatchSchema, threadsPatchSchema, appConfigSchema, storedAppConfigSchema, appConfigPatchSchema, jsonObjectSchema, DEFAULT_CAPTURE_QUIET_MS, DATA_DIR, LEGACY_DATA_DIR, EVENTS_DIR, NATIVE_DIR, lastIgnoredConfigWarning, WORKSPACE_CREDENTIAL_ENV, CONTROL_PLANE_ENV, CONTROL_PLANE_ENV_PREFIX, PROVIDER_CREDENTIAL_ENV, OPENCODE_PROVIDER_ENV, OPENCODE_PROVIDER_KEY_LIMIT, OPENCODE_PROVIDER_KEY_NAME, OPENCODE_PROVIDER_KEY_VALUE, configSaveListeners, CLAUDE_ROUTING_ENV, sameUrl, OPENAI_API_INSTANCE, OPENROUTER_API_INSTANCE, XAI_API_INSTANCE, CLAUDE_API_INSTANCE, API_KEY_FLEET;
|
|
19439
|
+
var optionalText, SSH_ALIAS, LEGACY_BROWSER_PROFILE_ID, BROWSER_PROFILE_ID, FISH_TTS_MODELS, MIN_ROOM_TURN_TIMEOUT_MINUTES, MAX_ROOM_TURN_TIMEOUT_MINUTES, MIN_MCP_CALL_TIMEOUT_MINUTES, MAX_MCP_CALL_TIMEOUT_MINUTES, DEFAULT_ROOM_HANDOFF_LIFETIME_MINUTES, DEFAULT_ROOM_HANDOFF_MIN_RUNWAY_MINUTES, DEFAULT_ROOM_HANDOFF_HARD_CAP_MINUTES, DEFAULT_MAX_CONCURRENT_BOT_THREADS, MAX_CONCURRENT_BOT_THREADS, MIN_THREAD_EVENT_LOG_BYTES, MAX_THREAD_EVENT_LOG_BYTES, MIN_LOCAL_VM_MAX_INSTANCES, MAX_LOCAL_VM_MAX_INSTANCES, MIN_LOCAL_VM_IDLE_TIMEOUT_MINUTES, MAX_LOCAL_VM_IDLE_TIMEOUT_MINUTES, CDP_PORT, CDP_URL, vpsConfigSchema, browserEngineConfigSchema, roomConfigSchema, mcpConfigSchema, localVmConfigSchema, browserProfileSchema, legacyBrowserProfileSchema, legacyBrowserProfilesSchema, storedBrowserProfilesSchema, browserProfilesSchema, featureConfigSchema, onboardingConfigSchema, instanceConfigSchema, instanceConfigMapSchema, defaultModelSelectionSchema, automaticRecoverySchema, threadsConfigSchema, newBotsConfigSchema, newBotsPatchSchema, threadsPatchSchema, appConfigSchema, storedAppConfigSchema, appConfigPatchSchema, jsonObjectSchema, DEFAULT_CAPTURE_QUIET_MS, DATA_DIR, LEGACY_DATA_DIR, EVENTS_DIR, NATIVE_DIR, lastIgnoredConfigWarning, WORKSPACE_CREDENTIAL_ENV, CONTROL_PLANE_ENV, CONTROL_PLANE_ENV_PREFIX, PROVIDER_CREDENTIAL_ENV, OPENCODE_PROVIDER_ENV, OPENCODE_PROVIDER_KEY_LIMIT, OPENCODE_PROVIDER_KEY_NAME, OPENCODE_PROVIDER_KEY_VALUE, configSaveListeners, CLAUDE_ROUTING_ENV, sameUrl, OPENAI_API_INSTANCE, OPENROUTER_API_INSTANCE, XAI_API_INSTANCE, CLAUDE_API_INSTANCE, API_KEY_FLEET;
|
|
19398
19440
|
var init_config = __esm({
|
|
19399
19441
|
"server/config.ts"() {
|
|
19400
19442
|
"use strict";
|
|
@@ -19415,6 +19457,8 @@ var init_config = __esm({
|
|
|
19415
19457
|
FISH_TTS_MODELS = ["s2.1-pro", "s2.1-pro-free"];
|
|
19416
19458
|
MIN_ROOM_TURN_TIMEOUT_MINUTES = 1;
|
|
19417
19459
|
MAX_ROOM_TURN_TIMEOUT_MINUTES = 1440;
|
|
19460
|
+
MIN_MCP_CALL_TIMEOUT_MINUTES = 1;
|
|
19461
|
+
MAX_MCP_CALL_TIMEOUT_MINUTES = 60;
|
|
19418
19462
|
DEFAULT_ROOM_HANDOFF_LIFETIME_MINUTES = 30;
|
|
19419
19463
|
DEFAULT_ROOM_HANDOFF_MIN_RUNWAY_MINUTES = 10;
|
|
19420
19464
|
DEFAULT_ROOM_HANDOFF_HARD_CAP_MINUTES = 240;
|
|
@@ -19450,6 +19494,11 @@ var init_config = __esm({
|
|
|
19450
19494
|
(rooms) => (rooms.handoffMinRunwayMinutes ?? DEFAULT_ROOM_HANDOFF_MIN_RUNWAY_MINUTES) <= (rooms.handoffLifetimeMinutes ?? DEFAULT_ROOM_HANDOFF_LIFETIME_MINUTES) && (rooms.handoffLifetimeMinutes ?? DEFAULT_ROOM_HANDOFF_LIFETIME_MINUTES) <= (rooms.handoffHardCapMinutes ?? DEFAULT_ROOM_HANDOFF_HARD_CAP_MINUTES),
|
|
19451
19495
|
{ message: "rooms handoff bounds must satisfy handoffMinRunwayMinutes <= handoffLifetimeMinutes <= handoffHardCapMinutes" }
|
|
19452
19496
|
);
|
|
19497
|
+
mcpConfigSchema = external_exports.object({
|
|
19498
|
+
/** Ceiling (minutes) for one bot MCP tool call. Missing values resolve to
|
|
19499
|
+
* 10, preserving the historic chat-mcp-tools constant. */
|
|
19500
|
+
callTimeoutMinutes: external_exports.number().int().min(MIN_MCP_CALL_TIMEOUT_MINUTES).max(MAX_MCP_CALL_TIMEOUT_MINUTES).optional()
|
|
19501
|
+
}).strict();
|
|
19453
19502
|
localVmConfigSchema = external_exports.object({
|
|
19454
19503
|
mode: external_exports.enum(["shared", "per-bot", "pool"]).optional(),
|
|
19455
19504
|
maxInstances: external_exports.number().int().min(MIN_LOCAL_VM_MAX_INSTANCES).max(MAX_LOCAL_VM_MAX_INSTANCES).optional(),
|
|
@@ -19711,6 +19760,7 @@ var init_config = __esm({
|
|
|
19711
19760
|
* system language. Unknown tags degrade to English in the renderer. */
|
|
19712
19761
|
language: optionalText,
|
|
19713
19762
|
rooms: roomConfigSchema.optional(),
|
|
19763
|
+
mcp: mcpConfigSchema.optional(),
|
|
19714
19764
|
context: external_exports.object({
|
|
19715
19765
|
rebuildBytes: external_exports.number().int().min(1024).max(1e6).optional(),
|
|
19716
19766
|
compactAt: external_exports.number().positive().max(1e7).optional(),
|
|
@@ -19867,7 +19917,7 @@ var init_config = __esm({
|
|
|
19867
19917
|
// electron/data-dir-lease.mjs
|
|
19868
19918
|
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
19869
19919
|
import { createHash as createHash2, randomUUID as randomUUID5 } from "node:crypto";
|
|
19870
|
-
import { existsSync as existsSync7, linkSync, mkdirSync as mkdirSync7, readFileSync as
|
|
19920
|
+
import { existsSync as existsSync7, linkSync, mkdirSync as mkdirSync7, readFileSync as readFileSync5, renameSync as renameSync4, unlinkSync as unlinkSync2, writeFileSync as writeFileSync4 } from "node:fs";
|
|
19871
19921
|
import { hostname as hostname4, uptime } from "node:os";
|
|
19872
19922
|
import { join as join10 } from "node:path";
|
|
19873
19923
|
function leaseError(message3, cause) {
|
|
@@ -19879,7 +19929,7 @@ function isPid(value) {
|
|
|
19879
19929
|
function readBootSession() {
|
|
19880
19930
|
try {
|
|
19881
19931
|
if (process.platform === "linux") {
|
|
19882
|
-
return normalizeBootId(
|
|
19932
|
+
return normalizeBootId(readFileSync5("/proc/sys/kernel/random/boot_id", "utf8"));
|
|
19883
19933
|
}
|
|
19884
19934
|
if (process.platform === "darwin") {
|
|
19885
19935
|
return normalizeBootId(execFileSync2("/usr/sbin/sysctl", ["-n", "kern.bootsessionuuid"], {
|
|
@@ -19934,7 +19984,7 @@ function isReaperOwner(value, targetToken) {
|
|
|
19934
19984
|
function parseRecord(path3, invalidMessage, validate) {
|
|
19935
19985
|
let raw;
|
|
19936
19986
|
try {
|
|
19937
|
-
raw =
|
|
19987
|
+
raw = readFileSync5(path3, "utf8");
|
|
19938
19988
|
} catch (error51) {
|
|
19939
19989
|
if (error51?.code === "ENOENT") return null;
|
|
19940
19990
|
throw leaseError("OpenMausBot cannot read the data-directory lease; refusing to start to protect its state.", error51);
|
|
@@ -20240,7 +20290,7 @@ var init_data_dir_lease2 = __esm({
|
|
|
20240
20290
|
|
|
20241
20291
|
// server/env-path.ts
|
|
20242
20292
|
import { execFile as execFile2 } from "node:child_process";
|
|
20243
|
-
import { closeSync as closeSync3, existsSync as existsSync8, openSync as openSync3, readFileSync as
|
|
20293
|
+
import { closeSync as closeSync3, existsSync as existsSync8, openSync as openSync3, readFileSync as readFileSync6, readSync, statSync as statSync3, readdirSync } from "node:fs";
|
|
20244
20294
|
import { homedir as homedir5 } from "node:os";
|
|
20245
20295
|
import { basename as basename4, delimiter as delimiter3, dirname as dirname5, extname, join as join11 } from "node:path";
|
|
20246
20296
|
function nvmBinDirs() {
|
|
@@ -20435,7 +20485,7 @@ function nodeExe(near, env) {
|
|
|
20435
20485
|
function parseCmdShim(shim, env) {
|
|
20436
20486
|
let text4;
|
|
20437
20487
|
try {
|
|
20438
|
-
text4 =
|
|
20488
|
+
text4 = readFileSync6(shim, "utf8");
|
|
20439
20489
|
} catch {
|
|
20440
20490
|
return null;
|
|
20441
20491
|
}
|
|
@@ -20834,6 +20884,9 @@ var init_registry = __esm({
|
|
|
20834
20884
|
/** decoded per-instance `cli` overrides, for describe() — drivers spawn
|
|
20835
20885
|
* from their own config; this map only reports what was configured */
|
|
20836
20886
|
cliByInstance = /* @__PURE__ */ new Map();
|
|
20887
|
+
/** What describe() last read of each live instance. A turn's start checks
|
|
20888
|
+
* a thread's own engine against it without waiting on that engine's CLI. */
|
|
20889
|
+
lastSnapshots = /* @__PURE__ */ new Map();
|
|
20837
20890
|
driversByKind;
|
|
20838
20891
|
/** Where Settings-driven npm installs go; the data directory by default. */
|
|
20839
20892
|
enginesBaseDir;
|
|
@@ -20893,6 +20946,16 @@ var init_registry = __esm({
|
|
|
20893
20946
|
get(instanceId) {
|
|
20894
20947
|
return this.byId.get(instanceId)?.live ?? null;
|
|
20895
20948
|
}
|
|
20949
|
+
/** The snapshot describe() last read of this live instance; absent before
|
|
20950
|
+
* the first read, or for an instance that is not live. */
|
|
20951
|
+
lastSnapshot(instanceId) {
|
|
20952
|
+
return this.byId.get(instanceId)?.live ? this.lastSnapshots.get(instanceId) : void 0;
|
|
20953
|
+
}
|
|
20954
|
+
/** How the instance's driver is presented and paid for (EngineAccess). */
|
|
20955
|
+
access(instanceId) {
|
|
20956
|
+
const entry = this.byId.get(instanceId);
|
|
20957
|
+
return entry ? this.driversByKind.get(entry.shadow?.driverKind ?? entry.live.driverKind)?.metadata.access ?? "subscription" : void 0;
|
|
20958
|
+
}
|
|
20896
20959
|
/** The configured executable for instance-scoped maintenance actions.
|
|
20897
20960
|
* This deliberately comes from the registry/config, never an HTTP body. */
|
|
20898
20961
|
cliTarget(instanceId) {
|
|
@@ -20994,6 +21057,7 @@ var init_registry = __esm({
|
|
|
20994
21057
|
} catch (e) {
|
|
20995
21058
|
snapshot = { state: "unavailable", reason: e instanceof Error ? e.message : String(e) };
|
|
20996
21059
|
}
|
|
21060
|
+
if (this.byId.get(inst.instanceId)?.live === inst) this.lastSnapshots.set(inst.instanceId, snapshot);
|
|
20997
21061
|
return {
|
|
20998
21062
|
instanceId: inst.instanceId,
|
|
20999
21063
|
driverKind: inst.driverKind,
|
|
@@ -21035,11 +21099,13 @@ var init_registry = __esm({
|
|
|
21035
21099
|
await Promise.allSettled(this.instances().map((i2) => i2.dispose()));
|
|
21036
21100
|
this.byId.clear();
|
|
21037
21101
|
this.cliByInstance.clear();
|
|
21102
|
+
this.lastSnapshots.clear();
|
|
21038
21103
|
}
|
|
21039
21104
|
async dispose(instanceId) {
|
|
21040
21105
|
const entry = this.byId.get(instanceId);
|
|
21041
21106
|
this.byId.delete(instanceId);
|
|
21042
21107
|
this.cliByInstance.delete(instanceId);
|
|
21108
|
+
this.lastSnapshots.delete(instanceId);
|
|
21043
21109
|
await entry?.live?.dispose();
|
|
21044
21110
|
}
|
|
21045
21111
|
};
|
|
@@ -21047,7 +21113,7 @@ var init_registry = __esm({
|
|
|
21047
21113
|
});
|
|
21048
21114
|
|
|
21049
21115
|
// server/drivers/local-inject.ts
|
|
21050
|
-
import { readFileSync as
|
|
21116
|
+
import { readFileSync as readFileSync7 } from "node:fs";
|
|
21051
21117
|
import { homedir as homedir6 } from "node:os";
|
|
21052
21118
|
import { join as join14 } from "node:path";
|
|
21053
21119
|
function contextWindowsFromPs(extra) {
|
|
@@ -21134,7 +21200,7 @@ function firstUnslothToken(row) {
|
|
|
21134
21200
|
function readUnslothKey(env) {
|
|
21135
21201
|
const home = env.HOME || env.USERPROFILE || homedir6();
|
|
21136
21202
|
try {
|
|
21137
|
-
const raw = JSON.parse(
|
|
21203
|
+
const raw = JSON.parse(readFileSync7(join14(home, ".unsloth", "studio", "auth", "agent_api_key.json"), "utf8"));
|
|
21138
21204
|
if (raw.servers && typeof raw.servers === "object") {
|
|
21139
21205
|
const servers = raw.servers;
|
|
21140
21206
|
for (const url2 of ["http://127.0.0.1:8888", "http://localhost:8888"]) {
|
|
@@ -21334,10 +21400,364 @@ var init_local_inject = __esm({
|
|
|
21334
21400
|
}
|
|
21335
21401
|
});
|
|
21336
21402
|
|
|
21403
|
+
// shared/device-sign-in.ts
|
|
21404
|
+
function deviceSignInLink(provider, value, userCode) {
|
|
21405
|
+
const page = value ? RULES[provider].page(value) : null;
|
|
21406
|
+
if (!page) return null;
|
|
21407
|
+
return [...new URL(page).searchParams.values()].every((carried) => carried === userCode) ? page : null;
|
|
21408
|
+
}
|
|
21409
|
+
function isDeviceSignInCode(provider, value) {
|
|
21410
|
+
return typeof value === "string" && RULES[provider].code.test(value);
|
|
21411
|
+
}
|
|
21412
|
+
function deviceSignInPrompt(provider, text4) {
|
|
21413
|
+
const lines = text4.split(/\r?\n/).slice(0, -1).map((line) => line.trim());
|
|
21414
|
+
const at = lines.findIndex((line) => RULES[provider].page(line) !== null);
|
|
21415
|
+
if (at < 0) return null;
|
|
21416
|
+
const userCode = lines.slice(at + 1).map((line) => line.replace(/^code:\s*/i, "")).find((line) => isDeviceSignInCode(provider, line));
|
|
21417
|
+
const authorizationUrl = userCode ? deviceSignInLink(provider, lines[at], userCode) : null;
|
|
21418
|
+
return authorizationUrl && userCode ? { authorizationUrl, userCode } : null;
|
|
21419
|
+
}
|
|
21420
|
+
var CODEX_PAGE, RULES;
|
|
21421
|
+
var init_device_sign_in = __esm({
|
|
21422
|
+
"shared/device-sign-in.ts"() {
|
|
21423
|
+
"use strict";
|
|
21424
|
+
CODEX_PAGE = "https://auth.openai.com/codex/device";
|
|
21425
|
+
RULES = {
|
|
21426
|
+
codex: {
|
|
21427
|
+
page: (value) => /^https:\/\/auth\.openai\.com\/codex\/device\/?$/.test(value) ? CODEX_PAGE : null,
|
|
21428
|
+
code: /^[A-Z0-9]{4,8}-[A-Z0-9]{4,8}$/
|
|
21429
|
+
},
|
|
21430
|
+
grok: {
|
|
21431
|
+
// xAI's own sign-in hosts. The page may carry the code itself (the
|
|
21432
|
+
// provider's "complete" link); nothing else may ride in its query.
|
|
21433
|
+
page: (value) => {
|
|
21434
|
+
if (!/^https:\/\/[^\s#]+$/.test(value)) return null;
|
|
21435
|
+
let url2;
|
|
21436
|
+
try {
|
|
21437
|
+
url2 = new URL(value);
|
|
21438
|
+
} catch {
|
|
21439
|
+
return null;
|
|
21440
|
+
}
|
|
21441
|
+
if (url2.username || url2.password || url2.port || !/(^|\.)(x\.ai|grok\.com)$/.test(url2.hostname)) return null;
|
|
21442
|
+
return [...url2.searchParams.keys()].every((key) => key === "user_code") ? url2.href : null;
|
|
21443
|
+
},
|
|
21444
|
+
code: /^[A-Z0-9]{4,12}(?:-[A-Z0-9]{2,12}){0,3}$/
|
|
21445
|
+
}
|
|
21446
|
+
};
|
|
21447
|
+
}
|
|
21448
|
+
});
|
|
21449
|
+
|
|
21450
|
+
// server/drivers/device-auth.ts
|
|
21451
|
+
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
21452
|
+
import { realpathSync } from "node:fs";
|
|
21453
|
+
import { homedir as homedir7 } from "node:os";
|
|
21454
|
+
import { basename as basename5, dirname as dirname6, isAbsolute, join as join15, resolve as resolve3 } from "node:path";
|
|
21455
|
+
import { stripVTControlCharacters as stripVTControlCharacters4 } from "node:util";
|
|
21456
|
+
function canonicalPath(path3) {
|
|
21457
|
+
try {
|
|
21458
|
+
return realpathSync(path3);
|
|
21459
|
+
} catch {
|
|
21460
|
+
const parent = dirname6(path3);
|
|
21461
|
+
return parent === path3 ? path3 : join15(canonicalPath(parent), basename5(path3));
|
|
21462
|
+
}
|
|
21463
|
+
}
|
|
21464
|
+
var MAX_OUTPUT2, authenticatingHomes, DeviceAuthController;
|
|
21465
|
+
var init_device_auth = __esm({
|
|
21466
|
+
"server/drivers/device-auth.ts"() {
|
|
21467
|
+
"use strict";
|
|
21468
|
+
init_device_sign_in();
|
|
21469
|
+
init_procs();
|
|
21470
|
+
MAX_OUTPUT2 = 16384;
|
|
21471
|
+
authenticatingHomes = /* @__PURE__ */ new Set();
|
|
21472
|
+
DeviceAuthController = class {
|
|
21473
|
+
flow = null;
|
|
21474
|
+
command = null;
|
|
21475
|
+
disposed = false;
|
|
21476
|
+
spec;
|
|
21477
|
+
options;
|
|
21478
|
+
constructor(spec, options) {
|
|
21479
|
+
this.spec = spec;
|
|
21480
|
+
this.options = options;
|
|
21481
|
+
}
|
|
21482
|
+
/** The credential home the lock is held on, for this environment. */
|
|
21483
|
+
home(env, action) {
|
|
21484
|
+
const { homeEnv, homeDir, product } = this.spec;
|
|
21485
|
+
const home = env.HOME || env.USERPROFILE || homedir7();
|
|
21486
|
+
const named = env[homeEnv];
|
|
21487
|
+
if (!isAbsolute(home) || named && !isAbsolute(named)) {
|
|
21488
|
+
throw new Error(`Use an absolute HOME and ${homeEnv} path for this server's ${product} provider before ${action}.`);
|
|
21489
|
+
}
|
|
21490
|
+
return { home, homeKey: canonicalPath(resolve3(named || join15(home, homeDir))) };
|
|
21491
|
+
}
|
|
21492
|
+
async start() {
|
|
21493
|
+
const { product, account, status } = this.spec;
|
|
21494
|
+
if (this.disposed) throw new Error("This provider was removed. Refresh Settings before signing in.");
|
|
21495
|
+
if (this.flow?.status.phase === "waiting") {
|
|
21496
|
+
if (this.flow.ready) return { ...this.flow.status, phase: "waiting" };
|
|
21497
|
+
throw new Error(`A ${account} sign-in is already starting. Please wait for the code.`);
|
|
21498
|
+
}
|
|
21499
|
+
await this.flow?.stopping;
|
|
21500
|
+
if (this.disposed) throw new Error("This provider was removed. Refresh Settings before signing in.");
|
|
21501
|
+
const env = this.options.environment();
|
|
21502
|
+
const { home, homeKey } = this.home(env, "signing in");
|
|
21503
|
+
if (authenticatingHomes.has(homeKey)) {
|
|
21504
|
+
throw new Error(`A ${account} sign-in is already running for this server account. Finish or cancel it before starting another.`);
|
|
21505
|
+
}
|
|
21506
|
+
authenticatingHomes.add(homeKey);
|
|
21507
|
+
return new Promise((resolveStart, reject) => {
|
|
21508
|
+
const flow = {
|
|
21509
|
+
status: {
|
|
21510
|
+
phase: "waiting",
|
|
21511
|
+
flowId: randomUUID6(),
|
|
21512
|
+
authorizationUrl: null,
|
|
21513
|
+
expiresAt: new Date(Date.now() + (this.options.lifetimeMs ?? 15 * 6e4)).toISOString()
|
|
21514
|
+
},
|
|
21515
|
+
child: null,
|
|
21516
|
+
ready: false,
|
|
21517
|
+
resolve: resolveStart,
|
|
21518
|
+
reject,
|
|
21519
|
+
homeKey,
|
|
21520
|
+
startupTimer: setTimeout(() => this.finish(flow, "failed", `${product} did not provide a sign-in code in time. Check the server connection and update ${product}, then try again.`), this.options.startupTimeoutMs ?? 3e4),
|
|
21521
|
+
expiryTimer: setTimeout(() => this.finish(flow, "expired", `The ${account} sign-in code expired. Start sign-in again.`), this.options.lifetimeMs ?? 15 * 6e4)
|
|
21522
|
+
};
|
|
21523
|
+
flow.startupTimer.unref();
|
|
21524
|
+
flow.expiryTimer.unref();
|
|
21525
|
+
this.flow = flow;
|
|
21526
|
+
const login = () => this.run(flow, [...this.spec.loginArgs], env, home, (loginCode, loginOutput) => {
|
|
21527
|
+
if (loginCode !== 0 || !flow.ready) {
|
|
21528
|
+
this.finish(flow, "failed", this.spec.failure(loginOutput));
|
|
21529
|
+
return;
|
|
21530
|
+
}
|
|
21531
|
+
flow.startupTimer = setTimeout(() => this.finish(flow, "failed", `${product} finished sign-in but could not confirm the account. Refresh Settings and try again.`), this.options.startupTimeoutMs ?? 3e4);
|
|
21532
|
+
flow.startupTimer.unref();
|
|
21533
|
+
this.confirm(flow, env, home, (signedIn) => this.finish(
|
|
21534
|
+
flow,
|
|
21535
|
+
signedIn ? "succeeded" : "failed",
|
|
21536
|
+
`${product} finished sign-in but did not confirm a ${account} account. Refresh Settings and try again.`
|
|
21537
|
+
));
|
|
21538
|
+
}, true);
|
|
21539
|
+
if (!status) {
|
|
21540
|
+
login();
|
|
21541
|
+
return;
|
|
21542
|
+
}
|
|
21543
|
+
this.run(flow, [...status.args], env, home, (code, output) => {
|
|
21544
|
+
const state = status.read(code, output);
|
|
21545
|
+
if (state === "signed-in") this.finish(flow, "succeeded");
|
|
21546
|
+
else if (state === "other") this.finish(flow, "failed", `${product} already has a different sign-in method on this server. Ask the server administrator to review it before changing accounts.`);
|
|
21547
|
+
else if (state === "signed-out") login();
|
|
21548
|
+
else this.finish(flow, "failed", `${product} could not confirm the existing sign-in on this server. Update ${product} and check its login status before trying again.`);
|
|
21549
|
+
});
|
|
21550
|
+
});
|
|
21551
|
+
}
|
|
21552
|
+
async get(flowId) {
|
|
21553
|
+
if (!flowId || this.flow?.status.flowId !== flowId) throw new Error("This sign-in is no longer available. Start sign-in again.");
|
|
21554
|
+
return { ...this.flow.status };
|
|
21555
|
+
}
|
|
21556
|
+
async cancel() {
|
|
21557
|
+
if (this.flow?.status.phase === "waiting") this.finish(this.flow, "cancelled", `${this.spec.account} sign-in cancelled.`);
|
|
21558
|
+
await this.flow?.stopping;
|
|
21559
|
+
if (this.flow?.terminationFailed) throw new Error(this.flow.status.message);
|
|
21560
|
+
if (this.command && !await this.stopChild(this.command)) {
|
|
21561
|
+
throw new Error(`${this.spec.product} could not be stopped on this server. Ask the server administrator to stop the account command before trying again.`);
|
|
21562
|
+
}
|
|
21563
|
+
}
|
|
21564
|
+
async dispose() {
|
|
21565
|
+
this.disposed = true;
|
|
21566
|
+
await this.cancel();
|
|
21567
|
+
this.flow = null;
|
|
21568
|
+
}
|
|
21569
|
+
/** Remove the sign-in the CLI stores for this server account so a
|
|
21570
|
+
* different account can connect. A sign-in in progress is never pulled
|
|
21571
|
+
* away underneath the browser completing it. */
|
|
21572
|
+
async signOut() {
|
|
21573
|
+
const { product, account, status, logoutArgs } = this.spec;
|
|
21574
|
+
if (!status || !logoutArgs) throw new Error(`Signing out of ${account} is not available from here.`);
|
|
21575
|
+
if (this.disposed) throw new Error("This provider was removed. Refresh Settings before signing out.");
|
|
21576
|
+
if (this.flow?.status.phase === "waiting") throw new Error(`Finish or cancel the ${account} sign-in in progress before signing out.`);
|
|
21577
|
+
await this.flow?.stopping;
|
|
21578
|
+
if (this.disposed) throw new Error("This provider was removed. Refresh Settings before signing out.");
|
|
21579
|
+
const env = this.options.environment();
|
|
21580
|
+
const { home, homeKey } = this.home(env, "signing out");
|
|
21581
|
+
if (authenticatingHomes.has(homeKey)) {
|
|
21582
|
+
throw new Error(`A ${account} sign-in is running for this server account. Finish or cancel it before signing out.`);
|
|
21583
|
+
}
|
|
21584
|
+
authenticatingHomes.add(homeKey);
|
|
21585
|
+
try {
|
|
21586
|
+
const before = await this.exec([...status.args], env, home);
|
|
21587
|
+
const state = status.read(before.code, before.output);
|
|
21588
|
+
if (state === "signed-out") return;
|
|
21589
|
+
if (state !== "signed-in") {
|
|
21590
|
+
throw new Error(`${product} did not confirm a ${account} sign-in. Other authentication methods will not be removed; ask the server administrator to check the account.`);
|
|
21591
|
+
}
|
|
21592
|
+
const logout = await this.exec([...logoutArgs], env, home);
|
|
21593
|
+
if (logout.code !== 0) throw new Error(`${product} could not remove the sign-in on this server. Check the server's ${product} installation and try again.`);
|
|
21594
|
+
const after = await this.exec([...status.args], env, home);
|
|
21595
|
+
if (status.read(after.code, after.output) !== "signed-out") {
|
|
21596
|
+
throw new Error(`${product} still reports a sign-in on this server. Update ${product} and check its login status before trying again.`);
|
|
21597
|
+
}
|
|
21598
|
+
} finally {
|
|
21599
|
+
const child = this.command;
|
|
21600
|
+
if (child && child.exitCode === null && child.signalCode === null) {
|
|
21601
|
+
child.once("close", () => authenticatingHomes.delete(homeKey));
|
|
21602
|
+
} else authenticatingHomes.delete(homeKey);
|
|
21603
|
+
}
|
|
21604
|
+
}
|
|
21605
|
+
/** After a login command succeeded: the status command when the CLI has
|
|
21606
|
+
* one, else the stored sign-in a turn checks for. */
|
|
21607
|
+
confirm(flow, env, home, done) {
|
|
21608
|
+
const status = this.spec.status;
|
|
21609
|
+
if (status) {
|
|
21610
|
+
this.run(flow, [...status.args], env, home, (code, output) => done(status.read(code, output) === "signed-in"));
|
|
21611
|
+
return;
|
|
21612
|
+
}
|
|
21613
|
+
let signedIn = false;
|
|
21614
|
+
try {
|
|
21615
|
+
signedIn = this.spec.signedIn?.(env) === true;
|
|
21616
|
+
} catch {
|
|
21617
|
+
}
|
|
21618
|
+
done(signedIn);
|
|
21619
|
+
}
|
|
21620
|
+
startFailure(error51) {
|
|
21621
|
+
const { product, install } = this.spec;
|
|
21622
|
+
return error51.code === "ENOENT" ? `${product} is not installed on this server. ${install}` : `${product} could not start on this server. Check the configured CLI path and its executable permissions.`;
|
|
21623
|
+
}
|
|
21624
|
+
/** One bounded, non-interactive command. Its output stays here; callers
|
|
21625
|
+
* see an exit code and a status-line match, never the text. */
|
|
21626
|
+
exec(args, env, cwd) {
|
|
21627
|
+
const { product } = this.spec;
|
|
21628
|
+
return new Promise((resolveExec, rejectExec) => {
|
|
21629
|
+
if (this.disposed) {
|
|
21630
|
+
rejectExec(new Error("This provider was removed. Refresh Settings before signing out."));
|
|
21631
|
+
return;
|
|
21632
|
+
}
|
|
21633
|
+
let child;
|
|
21634
|
+
try {
|
|
21635
|
+
child = spawnCli(this.options.cli, args, { env: { ...env, NO_COLOR: "1" }, cwd, stdio: ["pipe", "pipe", "pipe"] });
|
|
21636
|
+
} catch {
|
|
21637
|
+
rejectExec(new Error(`${product} could not start on this server. Install or update the configured ${product} CLI, then try again.`));
|
|
21638
|
+
return;
|
|
21639
|
+
}
|
|
21640
|
+
this.command = child;
|
|
21641
|
+
child.stdin.end();
|
|
21642
|
+
let output = "";
|
|
21643
|
+
const receive = (chunk) => {
|
|
21644
|
+
if (output.length < MAX_OUTPUT2) output += chunk.toString("utf8").slice(0, MAX_OUTPUT2 - output.length);
|
|
21645
|
+
};
|
|
21646
|
+
child.stdout.on("data", receive);
|
|
21647
|
+
child.stderr.on("data", receive);
|
|
21648
|
+
const timer = setTimeout(() => {
|
|
21649
|
+
void this.stopChild(child).catch(() => false).then((stopped) => {
|
|
21650
|
+
if (!stopped) rejectExec(new Error(`${product} could not be stopped on this server. Ask the server administrator to stop the account command before trying again.`));
|
|
21651
|
+
});
|
|
21652
|
+
}, this.options.startupTimeoutMs ?? 3e4);
|
|
21653
|
+
timer.unref();
|
|
21654
|
+
child.once("error", (error51) => {
|
|
21655
|
+
clearTimeout(timer);
|
|
21656
|
+
rejectExec(new Error(this.startFailure(error51)));
|
|
21657
|
+
});
|
|
21658
|
+
child.once("close", (code) => {
|
|
21659
|
+
clearTimeout(timer);
|
|
21660
|
+
if (this.command === child) this.command = null;
|
|
21661
|
+
resolveExec({ code, output: stripVTControlCharacters4(output) });
|
|
21662
|
+
});
|
|
21663
|
+
});
|
|
21664
|
+
}
|
|
21665
|
+
run(flow, args, env, cwd, done, parsePrompt = false) {
|
|
21666
|
+
const { product, provider } = this.spec;
|
|
21667
|
+
if (flow.status.phase !== "waiting") return;
|
|
21668
|
+
let child;
|
|
21669
|
+
try {
|
|
21670
|
+
child = spawnCli(this.options.cli, args, { env: { ...env, NO_COLOR: "1" }, cwd, stdio: ["pipe", "pipe", "pipe"] });
|
|
21671
|
+
} catch {
|
|
21672
|
+
this.finish(flow, "failed", `${product} could not start on this server. Install or update the configured ${product} CLI, then try again.`);
|
|
21673
|
+
return;
|
|
21674
|
+
}
|
|
21675
|
+
flow.child = child;
|
|
21676
|
+
child.stdin.end();
|
|
21677
|
+
let output = "";
|
|
21678
|
+
const receive = (chunk) => {
|
|
21679
|
+
if (flow.status.phase !== "waiting") return;
|
|
21680
|
+
if (output.length + chunk.length > MAX_OUTPUT2) {
|
|
21681
|
+
this.finish(flow, "failed", `${product} returned an unexpected sign-in response. Update the server's ${product} CLI and try again.`);
|
|
21682
|
+
return;
|
|
21683
|
+
}
|
|
21684
|
+
output += chunk.toString("utf8");
|
|
21685
|
+
const prompt = parsePrompt && !flow.ready ? deviceSignInPrompt(provider, stripVTControlCharacters4(output)) : null;
|
|
21686
|
+
if (prompt) {
|
|
21687
|
+
flow.status = { ...flow.status, ...prompt };
|
|
21688
|
+
flow.ready = true;
|
|
21689
|
+
clearTimeout(flow.startupTimer);
|
|
21690
|
+
flow.resolve({ ...flow.status, phase: "waiting" });
|
|
21691
|
+
}
|
|
21692
|
+
};
|
|
21693
|
+
child.stdout.on("data", receive);
|
|
21694
|
+
child.stderr.on("data", receive);
|
|
21695
|
+
child.once("error", (error51) => this.finish(flow, "failed", this.startFailure(error51)));
|
|
21696
|
+
child.once("close", (code) => {
|
|
21697
|
+
if (flow.child === child) flow.child = null;
|
|
21698
|
+
if (flow.status.phase === "waiting") done(code, stripVTControlCharacters4(output));
|
|
21699
|
+
output = "";
|
|
21700
|
+
});
|
|
21701
|
+
}
|
|
21702
|
+
finish(flow, phase, message3) {
|
|
21703
|
+
const { product, account } = this.spec;
|
|
21704
|
+
if (flow.status.phase !== "waiting") return;
|
|
21705
|
+
clearTimeout(flow.startupTimer);
|
|
21706
|
+
clearTimeout(flow.expiryTimer);
|
|
21707
|
+
flow.status = {
|
|
21708
|
+
phase,
|
|
21709
|
+
flowId: flow.status.flowId,
|
|
21710
|
+
authorizationUrl: null,
|
|
21711
|
+
expiresAt: null,
|
|
21712
|
+
...phase !== "succeeded" && message3 ? { message: message3 } : {}
|
|
21713
|
+
};
|
|
21714
|
+
if (!flow.ready) {
|
|
21715
|
+
if (phase === "succeeded") flow.resolve({ ...flow.status, phase });
|
|
21716
|
+
else flow.reject(new Error(message3 ?? `${account} sign-in did not finish.`));
|
|
21717
|
+
}
|
|
21718
|
+
flow.stopping = this.stopChild(flow.child).catch(() => false).then((stopped) => {
|
|
21719
|
+
const release = () => authenticatingHomes.delete(flow.homeKey);
|
|
21720
|
+
if (stopped) {
|
|
21721
|
+
release();
|
|
21722
|
+
return;
|
|
21723
|
+
}
|
|
21724
|
+
flow.terminationFailed = true;
|
|
21725
|
+
flow.status = { ...flow.status, phase: "failed", message: `${product} could not be stopped on this server. Ask the server administrator to stop the login process before trying again.` };
|
|
21726
|
+
const child = flow.child;
|
|
21727
|
+
if (!child || child.exitCode !== null || child.signalCode !== null) release();
|
|
21728
|
+
else child.once("close", release);
|
|
21729
|
+
});
|
|
21730
|
+
if (phase === "succeeded") void this.options.onAuthenticated?.().catch(() => {
|
|
21731
|
+
});
|
|
21732
|
+
}
|
|
21733
|
+
async stopChild(child) {
|
|
21734
|
+
if (!child || await killCliTree(child, this.options.terminateTimeoutMs ?? 1500)) return true;
|
|
21735
|
+
if (process.platform !== "win32" && child.pid) {
|
|
21736
|
+
try {
|
|
21737
|
+
process.kill(-child.pid, "SIGKILL");
|
|
21738
|
+
} catch {
|
|
21739
|
+
child.kill("SIGKILL");
|
|
21740
|
+
}
|
|
21741
|
+
} else child.kill("SIGKILL");
|
|
21742
|
+
await new Promise((resolveStop) => {
|
|
21743
|
+
if (child.exitCode !== null || child.signalCode !== null) return resolveStop();
|
|
21744
|
+
const timer = setTimeout(resolveStop, 1500);
|
|
21745
|
+
timer.unref();
|
|
21746
|
+
child.once("close", () => {
|
|
21747
|
+
clearTimeout(timer);
|
|
21748
|
+
resolveStop();
|
|
21749
|
+
});
|
|
21750
|
+
});
|
|
21751
|
+
return child.exitCode !== null || child.signalCode !== null;
|
|
21752
|
+
}
|
|
21753
|
+
};
|
|
21754
|
+
}
|
|
21755
|
+
});
|
|
21756
|
+
|
|
21337
21757
|
// server/drivers/prompt-split.ts
|
|
21338
21758
|
import { createHash as createHash3 } from "node:crypto";
|
|
21339
|
-
import { mkdirSync as mkdirSync9, readFileSync as
|
|
21340
|
-
import { join as
|
|
21759
|
+
import { mkdirSync as mkdirSync9, readFileSync as readFileSync8, rmSync as rmSync4 } from "node:fs";
|
|
21760
|
+
import { join as join16 } from "node:path";
|
|
21341
21761
|
function promptHalves(turn) {
|
|
21342
21762
|
const { systemStable, systemVolatile } = turn;
|
|
21343
21763
|
if (typeof systemStable !== "string" || typeof systemVolatile !== "string") {
|
|
@@ -21359,7 +21779,7 @@ function promptSplitFingerprints(stable, volatile) {
|
|
|
21359
21779
|
}
|
|
21360
21780
|
function readPromptSplitReceipt(scope, key) {
|
|
21361
21781
|
try {
|
|
21362
|
-
const raw = JSON.parse(
|
|
21782
|
+
const raw = JSON.parse(readFileSync8(receiptPath(scope, key), "utf8"));
|
|
21363
21783
|
if (raw && typeof raw === "object" && !Array.isArray(raw)) {
|
|
21364
21784
|
const record3 = raw;
|
|
21365
21785
|
if (typeof record3.stable === "string" && typeof record3.volatile === "string") {
|
|
@@ -21377,7 +21797,7 @@ function readPromptSplitReceipt(scope, key) {
|
|
|
21377
21797
|
return null;
|
|
21378
21798
|
}
|
|
21379
21799
|
function writePromptSplitReceipt(scope, key, receipt) {
|
|
21380
|
-
mkdirSync9(
|
|
21800
|
+
mkdirSync9(join16(DATA_DIR, "prompt-split"), { recursive: true });
|
|
21381
21801
|
writeFileAtomic(receiptPath(scope, key), JSON.stringify(receipt), { mode: 384 });
|
|
21382
21802
|
}
|
|
21383
21803
|
function deletePromptSplitReceipt(scope, key) {
|
|
@@ -21406,13 +21826,13 @@ var init_prompt_split = __esm({
|
|
|
21406
21826
|
VOLATILE_CONTEXT_CLEARED_NOTE = "The OpenMausBot context notes from earlier in this conversation have been cleared; the standing instructions still apply.";
|
|
21407
21827
|
digest = (value) => createHash3("sha256").update(value).digest("hex");
|
|
21408
21828
|
EMPTY_FINGERPRINT = digest("");
|
|
21409
|
-
receiptPath = (scope, key) =>
|
|
21829
|
+
receiptPath = (scope, key) => join16(DATA_DIR, "prompt-split", digest(JSON.stringify([scope, key])) + ".json");
|
|
21410
21830
|
}
|
|
21411
21831
|
});
|
|
21412
21832
|
|
|
21413
21833
|
// server/drivers/acp/quiet-status.ts
|
|
21414
21834
|
import { execFile as execFile4 } from "node:child_process";
|
|
21415
|
-
import { closeSync as closeSync4, fstatSync, openSync as openSync4, readSync as readSync2 } from "node:fs";
|
|
21835
|
+
import { closeSync as closeSync4, fstatSync as fstatSync2, openSync as openSync4, readSync as readSync2 } from "node:fs";
|
|
21416
21836
|
function parseQwenLogLine(line) {
|
|
21417
21837
|
if (line.includes("[RETRY]") && /\bAttempt \d+ failed\b/.test(line)) {
|
|
21418
21838
|
const attempt = /\bAttempt (\d+) failed/.exec(line);
|
|
@@ -21566,7 +21986,7 @@ var init_quiet_status = __esm({
|
|
|
21566
21986
|
return [];
|
|
21567
21987
|
}
|
|
21568
21988
|
try {
|
|
21569
|
-
const size =
|
|
21989
|
+
const size = fstatSync2(fd).size;
|
|
21570
21990
|
if (this.offset === null) {
|
|
21571
21991
|
this.offset = size;
|
|
21572
21992
|
return [];
|
|
@@ -21818,7 +22238,7 @@ var init_ask_question = __esm({
|
|
|
21818
22238
|
});
|
|
21819
22239
|
|
|
21820
22240
|
// server/thread-log-rotation.ts
|
|
21821
|
-
import { closeSync as closeSync5, fstatSync as
|
|
22241
|
+
import { closeSync as closeSync5, fstatSync as fstatSync3, openSync as openSync5, readSync as readSync3, renameSync as renameSync5, rmSync as rmSync5, statSync as statSync4, writeSync } from "node:fs";
|
|
21822
22242
|
function currentThreadLogCap() {
|
|
21823
22243
|
try {
|
|
21824
22244
|
return capProvider();
|
|
@@ -21842,7 +22262,7 @@ function trimToTail(file2, keepBytes) {
|
|
|
21842
22262
|
try {
|
|
21843
22263
|
const source = openSync5(file2, "r");
|
|
21844
22264
|
try {
|
|
21845
|
-
const size =
|
|
22265
|
+
const size = fstatSync3(source).size;
|
|
21846
22266
|
const start = Math.max(0, size - keepBytes);
|
|
21847
22267
|
const window = Buffer.allocUnsafe(size - start);
|
|
21848
22268
|
let filled = 0;
|
|
@@ -21885,9 +22305,9 @@ var init_thread_log_rotation = __esm({
|
|
|
21885
22305
|
|
|
21886
22306
|
// server/drivers/native.ts
|
|
21887
22307
|
import { appendFileSync as appendFileSync3 } from "node:fs";
|
|
21888
|
-
import { join as
|
|
22308
|
+
import { join as join17 } from "node:path";
|
|
21889
22309
|
function appendNative(threadId, entry) {
|
|
21890
|
-
const file2 =
|
|
22310
|
+
const file2 = join17(NATIVE_DIR, `${threadId}.ndjson`);
|
|
21891
22311
|
try {
|
|
21892
22312
|
appendFileSync3(
|
|
21893
22313
|
file2,
|
|
@@ -21908,16 +22328,16 @@ var init_native = __esm({
|
|
|
21908
22328
|
});
|
|
21909
22329
|
|
|
21910
22330
|
// server/drivers/permission-command.ts
|
|
21911
|
-
import { realpathSync } from "node:fs";
|
|
21912
|
-
import { isAbsolute } from "node:path";
|
|
22331
|
+
import { realpathSync as realpathSync2 } from "node:fs";
|
|
22332
|
+
import { isAbsolute as isAbsolute2 } from "node:path";
|
|
21913
22333
|
function permissionCommand(command, cwd) {
|
|
21914
22334
|
if (typeof command !== "string" || !command.trim() || command.includes("\0")) return void 0;
|
|
21915
|
-
if (typeof cwd !== "string" || !
|
|
22335
|
+
if (typeof cwd !== "string" || !isAbsolute2(cwd) || cwd.includes("\0")) return void 0;
|
|
21916
22336
|
return { command, cwd };
|
|
21917
22337
|
}
|
|
21918
22338
|
function permissionLaunchCwd(cwd) {
|
|
21919
22339
|
try {
|
|
21920
|
-
return
|
|
22340
|
+
return realpathSync2(cwd);
|
|
21921
22341
|
} catch {
|
|
21922
22342
|
return void 0;
|
|
21923
22343
|
}
|
|
@@ -21926,7 +22346,7 @@ function acpPermissionCommand(rawInput, launchCwd) {
|
|
|
21926
22346
|
if (!rawInput || typeof rawInput !== "object" || Array.isArray(rawInput)) return void 0;
|
|
21927
22347
|
const input = rawInput;
|
|
21928
22348
|
const directories = ["cwd", "workdir", "working_directory", "directory", "dir"].filter((key) => input[key] !== void 0).map((key) => input[key]);
|
|
21929
|
-
if (directories.some((value) => typeof value !== "string" || !
|
|
22349
|
+
if (directories.some((value) => typeof value !== "string" || !isAbsolute2(value) || value.includes("\0"))) return void 0;
|
|
21930
22350
|
if (new Set(directories).size > 1) return void 0;
|
|
21931
22351
|
return permissionCommand(input.command, directories[0] ?? launchCwd);
|
|
21932
22352
|
}
|
|
@@ -22201,7 +22621,7 @@ var init_mcp_http = __esm({
|
|
|
22201
22621
|
});
|
|
22202
22622
|
|
|
22203
22623
|
// server/mcp-gate-config.ts
|
|
22204
|
-
import { join as
|
|
22624
|
+
import { join as join18 } from "node:path";
|
|
22205
22625
|
function resultBudget(env = process.env) {
|
|
22206
22626
|
const raw = env.OMB_MCP_RESULT_BUDGET;
|
|
22207
22627
|
if (raw === void 0 || raw === "") return DEFAULT_RESULT_BUDGET;
|
|
@@ -22209,7 +22629,7 @@ function resultBudget(env = process.env) {
|
|
|
22209
22629
|
return Number.isFinite(parsed) && parsed >= 0 ? Math.floor(parsed) : DEFAULT_RESULT_BUDGET;
|
|
22210
22630
|
}
|
|
22211
22631
|
function spillDir(threadId) {
|
|
22212
|
-
return
|
|
22632
|
+
return join18(DATA_DIR, "tool-results", threadId.replace(/[^A-Za-z0-9_-]/g, "-").slice(0, 80) || "thread");
|
|
22213
22633
|
}
|
|
22214
22634
|
function mcpStdioServer(server, options = {}) {
|
|
22215
22635
|
if (!server || typeof server !== "object" || Array.isArray(server)) return null;
|
|
@@ -22266,9 +22686,9 @@ var init_mcp_gate_config = __esm({
|
|
|
22266
22686
|
});
|
|
22267
22687
|
|
|
22268
22688
|
// server/drivers/acp/core.ts
|
|
22269
|
-
import { homedir as
|
|
22689
|
+
import { homedir as homedir8 } from "node:os";
|
|
22270
22690
|
import { lstat, mkdir as mkdir3, readFile, realpath, stat as stat2, writeFile } from "node:fs/promises";
|
|
22271
|
-
import { basename as
|
|
22691
|
+
import { basename as basename6, dirname as dirname7, isAbsolute as isAbsolute3, relative, resolve as resolve4 } from "node:path";
|
|
22272
22692
|
import { createHash as createHash4 } from "node:crypto";
|
|
22273
22693
|
function skipSubscriptionAuthForLocalInject(model) {
|
|
22274
22694
|
return Boolean(decodeInjectId(model));
|
|
@@ -22474,7 +22894,8 @@ function createAcpDriver(support11) {
|
|
|
22474
22894
|
}
|
|
22475
22895
|
};
|
|
22476
22896
|
if (support11.resolveModelsOnCreate !== false) await refreshModels();
|
|
22477
|
-
const
|
|
22897
|
+
const deviceSignIn = support11.deviceSignIn ? new DeviceAuthController(support11.deviceSignIn, { cli: config2.cli, environment: () => childEnv(), onAuthenticated: refreshModels }) : null;
|
|
22898
|
+
const listeners2 = /* @__PURE__ */ new Set();
|
|
22478
22899
|
const active = /* @__PURE__ */ new Map();
|
|
22479
22900
|
const sessions = /* @__PURE__ */ new Map();
|
|
22480
22901
|
const retiring = /* @__PURE__ */ new Map();
|
|
@@ -22519,7 +22940,7 @@ function createAcpDriver(support11) {
|
|
|
22519
22940
|
};
|
|
22520
22941
|
const sessionAllows = /* @__PURE__ */ new Map();
|
|
22521
22942
|
const emit = (event) => {
|
|
22522
|
-
for (const listener of
|
|
22943
|
+
for (const listener of listeners2) listener(event);
|
|
22523
22944
|
};
|
|
22524
22945
|
const nativeLogMessage = (msg) => {
|
|
22525
22946
|
let redacted = msg;
|
|
@@ -22801,26 +23222,26 @@ function createAcpDriver(support11) {
|
|
|
22801
23222
|
}
|
|
22802
23223
|
};
|
|
22803
23224
|
const resolveClientPath = async (requestPath) => {
|
|
22804
|
-
if (typeof requestPath !== "string" || !
|
|
23225
|
+
if (typeof requestPath !== "string" || !isAbsolute3(requestPath)) {
|
|
22805
23226
|
throw new Error("ACP file paths must be absolute.");
|
|
22806
23227
|
}
|
|
22807
|
-
const workspace = await realpath(cwd).catch(() =>
|
|
22808
|
-
const requested =
|
|
22809
|
-
const lexical = relative(
|
|
22810
|
-
if (lexical === ".." || lexical.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`) ||
|
|
23228
|
+
const workspace = await realpath(cwd).catch(() => resolve4(cwd));
|
|
23229
|
+
const requested = resolve4(requestPath);
|
|
23230
|
+
const lexical = relative(resolve4(cwd), requested);
|
|
23231
|
+
if (lexical === ".." || lexical.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`) || isAbsolute3(lexical)) {
|
|
22811
23232
|
throw new Error("ACP file path is outside the session workspace.");
|
|
22812
23233
|
}
|
|
22813
|
-
const suffix = [
|
|
22814
|
-
let ancestor =
|
|
23234
|
+
const suffix = [basename6(requested)];
|
|
23235
|
+
let ancestor = dirname7(requested);
|
|
22815
23236
|
while (!await lstat(ancestor).catch(() => null)) {
|
|
22816
|
-
const parent =
|
|
23237
|
+
const parent = dirname7(ancestor);
|
|
22817
23238
|
if (parent === ancestor) throw new Error("ACP file path has no accessible parent.");
|
|
22818
|
-
suffix.unshift(
|
|
23239
|
+
suffix.unshift(basename6(ancestor));
|
|
22819
23240
|
ancestor = parent;
|
|
22820
23241
|
}
|
|
22821
|
-
const candidate =
|
|
23242
|
+
const candidate = resolve4(await realpath(ancestor), ...suffix);
|
|
22822
23243
|
const rel = relative(workspace, candidate);
|
|
22823
|
-
if (rel === ".." || rel.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`) ||
|
|
23244
|
+
if (rel === ".." || rel.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`) || isAbsolute3(rel)) {
|
|
22824
23245
|
throw new Error("ACP file path is outside the session workspace.");
|
|
22825
23246
|
}
|
|
22826
23247
|
const existing = await lstat(candidate).catch(() => null);
|
|
@@ -22861,7 +23282,7 @@ function createAcpDriver(support11) {
|
|
|
22861
23282
|
if (typeof params.content !== "string" || Buffer.byteLength(params.content) > CLIENT_FILE_MAX_BYTES) {
|
|
22862
23283
|
throw new Error(`ACP can only write text files under ${CLIENT_FILE_MAX_BYTES} bytes.`);
|
|
22863
23284
|
}
|
|
22864
|
-
await mkdir3(
|
|
23285
|
+
await mkdir3(dirname7(path3), { recursive: true });
|
|
22865
23286
|
await writeFile(path3, params.content, "utf8");
|
|
22866
23287
|
send({ jsonrpc: "2.0", id: msg.id, result: {} });
|
|
22867
23288
|
} catch (error51) {
|
|
@@ -23152,7 +23573,7 @@ function createAcpDriver(support11) {
|
|
|
23152
23573
|
throw new Error("local computer control requires interactive provider approvals");
|
|
23153
23574
|
}
|
|
23154
23575
|
const turnId = newId();
|
|
23155
|
-
const cwd = turn.cwd ?? turnConfig.workspace ??
|
|
23576
|
+
const cwd = turn.cwd ?? turnConfig.workspace ?? homedir8();
|
|
23156
23577
|
const env = childEnv(turnConfig);
|
|
23157
23578
|
if (support11.requireAuthenticationBeforeSpawn && !skipSubscriptionAuthForLocalInject(turn.model) && !await support11.isAuthenticated(env, turnConfig, instanceId)) {
|
|
23158
23579
|
emit({ ...base2(threadId, turnId), type: "turn.started" });
|
|
@@ -23684,6 +24105,11 @@ ${promptInput.text}` : promptInput.text;
|
|
|
23684
24105
|
return models2;
|
|
23685
24106
|
},
|
|
23686
24107
|
refreshModels: support11.resolveModels ? refreshModels : void 0,
|
|
24108
|
+
...deviceSignIn ? {
|
|
24109
|
+
startAuthentication: () => deviceSignIn.start(),
|
|
24110
|
+
getAuthentication: (flowId) => deviceSignIn.get(flowId),
|
|
24111
|
+
cancelAuthentication: () => deviceSignIn.cancel()
|
|
24112
|
+
} : {},
|
|
23687
24113
|
snapshot,
|
|
23688
24114
|
adapter: {
|
|
23689
24115
|
provider: DRIVER_KIND7,
|
|
@@ -23720,17 +24146,18 @@ ${promptInput.text}` : promptInput.text;
|
|
|
23720
24146
|
}
|
|
23721
24147
|
},
|
|
23722
24148
|
onEvent: (listener) => {
|
|
23723
|
-
|
|
23724
|
-
return () =>
|
|
24149
|
+
listeners2.add(listener);
|
|
24150
|
+
return () => listeners2.delete(listener);
|
|
23725
24151
|
}
|
|
23726
24152
|
},
|
|
23727
24153
|
dispose: async () => {
|
|
24154
|
+
await deviceSignIn?.dispose();
|
|
23728
24155
|
for (const { stop } of active.values()) stop();
|
|
23729
24156
|
for (const threadId of Array.from(sessions.keys())) closeSession(threadId, "dispose");
|
|
23730
24157
|
for (const [threadId, children] of retiring) {
|
|
23731
24158
|
for (const child of children) void retireChild(threadId, child);
|
|
23732
24159
|
}
|
|
23733
|
-
|
|
24160
|
+
listeners2.clear();
|
|
23734
24161
|
}
|
|
23735
24162
|
};
|
|
23736
24163
|
}
|
|
@@ -23742,6 +24169,7 @@ var init_core3 = __esm({
|
|
|
23742
24169
|
"use strict";
|
|
23743
24170
|
init_config();
|
|
23744
24171
|
init_local_inject();
|
|
24172
|
+
init_device_auth();
|
|
23745
24173
|
init_prompt_split();
|
|
23746
24174
|
init_procs();
|
|
23747
24175
|
init_quiet_status();
|
|
@@ -23789,15 +24217,15 @@ var init_core3 = __esm({
|
|
|
23789
24217
|
});
|
|
23790
24218
|
|
|
23791
24219
|
// server/drivers/antigravity-temp.ts
|
|
23792
|
-
import { createHash as createHash5, randomUUID as
|
|
24220
|
+
import { createHash as createHash5, randomUUID as randomUUID7 } from "node:crypto";
|
|
23793
24221
|
import { lstat as lstat2, readdir as readdir2, realpath as realpath2, rename, rm } from "node:fs/promises";
|
|
23794
|
-
import { basename as
|
|
24222
|
+
import { basename as basename7, dirname as dirname8, join as join19, resolve as resolve5 } from "node:path";
|
|
23795
24223
|
function antigravityTempRoot(dataDir = DATA_DIR) {
|
|
23796
|
-
return
|
|
24224
|
+
return join19(dataDir, "tmp", "agy");
|
|
23797
24225
|
}
|
|
23798
24226
|
function antigravityTempDir(dataDir, instanceId) {
|
|
23799
24227
|
const key = createHash5("sha256").update(instanceId).digest("hex").slice(0, 12);
|
|
23800
|
-
return
|
|
24228
|
+
return join19(antigravityTempRoot(dataDir), key);
|
|
23801
24229
|
}
|
|
23802
24230
|
function setAntigravityTempEnvironment(environment, directory, platform = process.platform) {
|
|
23803
24231
|
if (platform !== "win32") return;
|
|
@@ -23849,12 +24277,12 @@ async function listDirectory(path3) {
|
|
|
23849
24277
|
}
|
|
23850
24278
|
}
|
|
23851
24279
|
async function ownedTempDirectories(dataDir, only) {
|
|
23852
|
-
const root =
|
|
24280
|
+
const root = resolve5(antigravityTempRoot(dataDir));
|
|
23853
24281
|
let realRoot;
|
|
23854
24282
|
try {
|
|
23855
|
-
const realData = await realpath2(
|
|
24283
|
+
const realData = await realpath2(resolve5(dataDir));
|
|
23856
24284
|
realRoot = await realpath2(root);
|
|
23857
|
-
if (realRoot !==
|
|
24285
|
+
if (realRoot !== join19(realData, "tmp", "agy")) return [];
|
|
23858
24286
|
} catch {
|
|
23859
24287
|
return [];
|
|
23860
24288
|
}
|
|
@@ -23862,9 +24290,9 @@ async function ownedTempDirectories(dataDir, only) {
|
|
|
23862
24290
|
const owned = [];
|
|
23863
24291
|
for (const name of names) {
|
|
23864
24292
|
if (!INSTANCE_FOLDER.test(name)) continue;
|
|
23865
|
-
const directory =
|
|
24293
|
+
const directory = join19(root, name);
|
|
23866
24294
|
try {
|
|
23867
|
-
if (await realpath2(directory) !==
|
|
24295
|
+
if (await realpath2(directory) !== join19(realRoot, name)) continue;
|
|
23868
24296
|
} catch {
|
|
23869
24297
|
continue;
|
|
23870
24298
|
}
|
|
@@ -23877,7 +24305,7 @@ async function abandonedIn(directory, isAlive) {
|
|
|
23877
24305
|
for (const entry of await listDirectory(directory)) {
|
|
23878
24306
|
if (!entry.isDirectory()) continue;
|
|
23879
24307
|
if (entry.name.startsWith(CLAIM_PREFIX) || ownedByDeadProcess(entry.name, isAlive)) {
|
|
23880
|
-
found.push(
|
|
24308
|
+
found.push(join19(directory, entry.name));
|
|
23881
24309
|
}
|
|
23882
24310
|
}
|
|
23883
24311
|
return found;
|
|
@@ -23889,7 +24317,7 @@ async function folderBytes(directory, deadline = Infinity) {
|
|
|
23889
24317
|
if (Date.now() > deadline) return { bytes, complete: false };
|
|
23890
24318
|
const current = pending.pop();
|
|
23891
24319
|
for (const entry of await listDirectory(current)) {
|
|
23892
|
-
const path3 =
|
|
24320
|
+
const path3 = join19(current, entry.name);
|
|
23893
24321
|
if (entry.isDirectory()) pending.push(path3);
|
|
23894
24322
|
else if (entry.isFile()) {
|
|
23895
24323
|
try {
|
|
@@ -23902,12 +24330,12 @@ async function folderBytes(directory, deadline = Infinity) {
|
|
|
23902
24330
|
return { bytes, complete: true };
|
|
23903
24331
|
}
|
|
23904
24332
|
async function claimAndRemove(directory, countBytes) {
|
|
23905
|
-
const name =
|
|
24333
|
+
const name = basename7(directory);
|
|
23906
24334
|
const kind = await entryKind(directory);
|
|
23907
24335
|
if (kind !== "directory") return kind === "gone" ? "gone" : null;
|
|
23908
24336
|
let claimed = directory;
|
|
23909
24337
|
if (!name.startsWith(CLAIM_PREFIX)) {
|
|
23910
|
-
claimed =
|
|
24338
|
+
claimed = join19(dirname8(directory), `${CLAIM_PREFIX}${name}-${randomUUID7().slice(0, 8)}`);
|
|
23911
24339
|
try {
|
|
23912
24340
|
await rename(directory, claimed);
|
|
23913
24341
|
} catch (error51) {
|
|
@@ -23931,7 +24359,7 @@ function sweepAntigravityTemp(instanceId, options = {}) {
|
|
|
23931
24359
|
const sweep = (async () => {
|
|
23932
24360
|
const isAlive = options.isAlive ?? processIsAlive3;
|
|
23933
24361
|
let removed = 0;
|
|
23934
|
-
for (const directory of await ownedTempDirectories(dataDir,
|
|
24362
|
+
for (const directory of await ownedTempDirectories(dataDir, basename7(key))) {
|
|
23935
24363
|
for (const folder of await abandonedIn(directory, isAlive)) {
|
|
23936
24364
|
if (typeof await claimAndRemove(folder, false) === "number") removed++;
|
|
23937
24365
|
}
|
|
@@ -23961,11 +24389,11 @@ var init_antigravity_temp = __esm({
|
|
|
23961
24389
|
});
|
|
23962
24390
|
|
|
23963
24391
|
// server/drivers/antigravity-acp.ts
|
|
23964
|
-
import { createHash as createHash6, randomUUID as
|
|
24392
|
+
import { createHash as createHash6, randomUUID as randomUUID8 } from "node:crypto";
|
|
23965
24393
|
import { mkdir as mkdir4, mkdtemp, readFile as readFile2, rm as rm2, stat as stat3 } from "node:fs/promises";
|
|
23966
24394
|
import { request as httpRequest } from "node:http";
|
|
23967
24395
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
23968
|
-
import { delimiter as delimiter4, join as
|
|
24396
|
+
import { delimiter as delimiter4, join as join20, resolve as resolve6 } from "node:path";
|
|
23969
24397
|
function quoteBrowserArgument(value) {
|
|
23970
24398
|
return `'${value.replaceAll("'", `'"'"'`)}'`;
|
|
23971
24399
|
}
|
|
@@ -24000,11 +24428,11 @@ function authorizationUrlFromLine(line) {
|
|
|
24000
24428
|
}
|
|
24001
24429
|
}
|
|
24002
24430
|
function antigravityProfileDirectory(instanceId, baseDir = DATA_DIR) {
|
|
24003
|
-
return
|
|
24431
|
+
return join20(baseDir, "providers", "antigravity", createHash6("sha256").update(instanceId).digest("hex"));
|
|
24004
24432
|
}
|
|
24005
24433
|
async function prepareAntigravityProfile(input) {
|
|
24006
|
-
const directory =
|
|
24007
|
-
const acpDirectory =
|
|
24434
|
+
const directory = resolve6(input.profileDirectory ?? antigravityProfileDirectory(input.instanceId, input.baseDir));
|
|
24435
|
+
const acpDirectory = join20(directory, "antigravity-acp");
|
|
24008
24436
|
await mkdir4(acpDirectory, { recursive: true, mode: 448 });
|
|
24009
24437
|
if (process.platform !== "win32") {
|
|
24010
24438
|
const { chmod: chmod2 } = await import("node:fs/promises");
|
|
@@ -24012,7 +24440,7 @@ async function prepareAntigravityProfile(input) {
|
|
|
24012
24440
|
await chmod2(acpDirectory, 448);
|
|
24013
24441
|
}
|
|
24014
24442
|
writeFileAtomic(
|
|
24015
|
-
|
|
24443
|
+
join20(acpDirectory, "settings.json"),
|
|
24016
24444
|
`${JSON.stringify({ auth: { type: "oauth-personal" } })}
|
|
24017
24445
|
`,
|
|
24018
24446
|
{ mode: 384 }
|
|
@@ -24037,13 +24465,13 @@ async function prepareAntigravityProfile(input) {
|
|
|
24037
24465
|
});
|
|
24038
24466
|
let tempDirectory;
|
|
24039
24467
|
if ((input.platform ?? process.platform) === "win32") {
|
|
24040
|
-
tempDirectory =
|
|
24468
|
+
tempDirectory = resolve6(input.tempDirectory ?? antigravityTempDir(input.baseDir ?? DATA_DIR, input.instanceId));
|
|
24041
24469
|
await mkdir4(tempDirectory, { recursive: true });
|
|
24042
24470
|
setAntigravityTempEnvironment(environment, tempDirectory, "win32");
|
|
24043
24471
|
}
|
|
24044
24472
|
return {
|
|
24045
24473
|
directory,
|
|
24046
|
-
tokenPath:
|
|
24474
|
+
tokenPath: join20(acpDirectory, "acp_token.json"),
|
|
24047
24475
|
environment,
|
|
24048
24476
|
...tempDirectory ? { tempDirectory } : {}
|
|
24049
24477
|
};
|
|
@@ -24175,14 +24603,14 @@ function isValidAntigravityInitializeResult(initialized, expectedVersion) {
|
|
|
24175
24603
|
return true;
|
|
24176
24604
|
}
|
|
24177
24605
|
async function validateAntigravityRuntime(runtime, expectedVersion) {
|
|
24178
|
-
const profileDirectory = await mkdtemp(
|
|
24606
|
+
const profileDirectory = await mkdtemp(join20(tmpdir2(), "openmaus-antigravity-verify-"));
|
|
24179
24607
|
let client;
|
|
24180
24608
|
let tempDirectory;
|
|
24181
24609
|
let failed2 = false;
|
|
24182
24610
|
let failure;
|
|
24183
24611
|
try {
|
|
24184
24612
|
const profile = await prepareAntigravityProfile({
|
|
24185
|
-
instanceId: `verify-${
|
|
24613
|
+
instanceId: `verify-${randomUUID8()}`,
|
|
24186
24614
|
runtime,
|
|
24187
24615
|
profileDirectory,
|
|
24188
24616
|
tempDirectory: antigravityTempDir(DATA_DIR, VERIFICATION_TEMP_KEY)
|
|
@@ -24472,7 +24900,7 @@ var init_antigravity_acp = __esm({
|
|
|
24472
24900
|
return { phase: "succeeded", flowId: null, authorizationUrl: null, expiresAt: null };
|
|
24473
24901
|
}
|
|
24474
24902
|
const flow = {
|
|
24475
|
-
id:
|
|
24903
|
+
id: randomUUID8(),
|
|
24476
24904
|
client,
|
|
24477
24905
|
completed: authenticated,
|
|
24478
24906
|
pending: { redirectUri: outcome.request.redirectUri, state: outcome.request.state },
|
|
@@ -24581,7 +25009,7 @@ var init_antigravity_release = __esm({
|
|
|
24581
25009
|
});
|
|
24582
25010
|
|
|
24583
25011
|
// server/drivers/antigravity-runtime.ts
|
|
24584
|
-
import { createHash as createHash7, randomUUID as
|
|
25012
|
+
import { createHash as createHash7, randomUUID as randomUUID9 } from "node:crypto";
|
|
24585
25013
|
import { createReadStream, createWriteStream } from "node:fs";
|
|
24586
25014
|
import {
|
|
24587
25015
|
access,
|
|
@@ -24596,8 +25024,8 @@ import {
|
|
|
24596
25024
|
statfs,
|
|
24597
25025
|
writeFile as writeFile2
|
|
24598
25026
|
} from "node:fs/promises";
|
|
24599
|
-
import { constants } from "node:fs";
|
|
24600
|
-
import { delimiter as delimiter5, dirname as
|
|
25027
|
+
import { constants as constants2 } from "node:fs";
|
|
25028
|
+
import { delimiter as delimiter5, dirname as dirname9, isAbsolute as isAbsolute4, join as join21, resolve as resolve7 } from "node:path";
|
|
24601
25029
|
import { Transform } from "node:stream";
|
|
24602
25030
|
import { pipeline } from "node:stream/promises";
|
|
24603
25031
|
import { createInflateRaw } from "node:zlib";
|
|
@@ -24618,7 +25046,7 @@ async function retryOnWindowsFileLock(step, options = {}) {
|
|
|
24618
25046
|
}
|
|
24619
25047
|
}
|
|
24620
25048
|
function runtimeRoot(baseDir = DATA_DIR) {
|
|
24621
|
-
return
|
|
25049
|
+
return join21(baseDir, "tools", "antigravity-acp", `${process.platform}-${process.arch}`);
|
|
24622
25050
|
}
|
|
24623
25051
|
function executableNames(platform = process.platform) {
|
|
24624
25052
|
return platform === "win32" ? { executable: "agy_acp_server.exe", harness: "localharness_external.exe" } : { executable: "agy_acp_server.par", harness: "localharness_external" };
|
|
@@ -24627,7 +25055,7 @@ async function executableFile(path3, bytes) {
|
|
|
24627
25055
|
try {
|
|
24628
25056
|
const info = await stat4(path3);
|
|
24629
25057
|
if (!info.isFile() || bytes !== void 0 && info.size !== bytes) return false;
|
|
24630
|
-
if (process.platform !== "win32") await access(path3,
|
|
25058
|
+
if (process.platform !== "win32") await access(path3, constants2.X_OK);
|
|
24631
25059
|
return true;
|
|
24632
25060
|
} catch {
|
|
24633
25061
|
return false;
|
|
@@ -24635,10 +25063,10 @@ async function executableFile(path3, bytes) {
|
|
|
24635
25063
|
}
|
|
24636
25064
|
async function completedRelease(directory, asset) {
|
|
24637
25065
|
try {
|
|
24638
|
-
const record3 = JSON.parse(await readFile3(
|
|
25066
|
+
const record3 = JSON.parse(await readFile3(join21(directory, INSTALL_RECORD), "utf8"));
|
|
24639
25067
|
if (record3.sha256 !== asset.sha256 || record3.version !== asset.version || record3.executable.name !== asset.executable.name || record3.executable.bytes !== asset.executable.bytes || record3.harness.name !== asset.harness.name || record3.harness.bytes !== asset.harness.bytes) return null;
|
|
24640
|
-
const executablePath =
|
|
24641
|
-
const harnessPath =
|
|
25068
|
+
const executablePath = join21(directory, asset.executable.name);
|
|
25069
|
+
const harnessPath = join21(directory, asset.harness.name);
|
|
24642
25070
|
if (!await executableFile(executablePath, asset.executable.bytes)) return null;
|
|
24643
25071
|
if (!await executableFile(harnessPath, asset.harness.bytes)) return null;
|
|
24644
25072
|
return { executablePath, harnessPath, source: "managed", version: asset.version };
|
|
@@ -24647,14 +25075,14 @@ async function completedRelease(directory, asset) {
|
|
|
24647
25075
|
}
|
|
24648
25076
|
}
|
|
24649
25077
|
function pathCandidates(binary2, env) {
|
|
24650
|
-
if (
|
|
25078
|
+
if (isAbsolute4(binary2) || binary2.includes("/") || binary2.includes("\\")) return [resolve7(binary2)];
|
|
24651
25079
|
const pathValue = process.platform === "win32" ? Object.entries(env).findLast(([key]) => key.toUpperCase() === "PATH")?.[1] : env.PATH;
|
|
24652
|
-
return (pathValue ?? augmentedPath()).split(delimiter5).map((part) => part.trim().replace(/^"|"$/gu, "")).filter(Boolean).map((part) =>
|
|
25080
|
+
return (pathValue ?? augmentedPath()).split(delimiter5).map((part) => part.trim().replace(/^"|"$/gu, "")).filter(Boolean).map((part) => resolve7(part, binary2));
|
|
24653
25081
|
}
|
|
24654
25082
|
async function externalRuntime(candidate, source) {
|
|
24655
25083
|
const names = executableNames();
|
|
24656
|
-
const executablePath =
|
|
24657
|
-
const harnessPath =
|
|
25084
|
+
const executablePath = resolve7(candidate);
|
|
25085
|
+
const harnessPath = join21(dirname9(executablePath), names.harness);
|
|
24658
25086
|
if (!await executableFile(executablePath) || !await executableFile(harnessPath)) return null;
|
|
24659
25087
|
return { executablePath, harnessPath, source, version: null };
|
|
24660
25088
|
}
|
|
@@ -24674,7 +25102,7 @@ async function resolveAntigravityRuntime(binaryPath, env = process.env, baseDir
|
|
|
24674
25102
|
}
|
|
24675
25103
|
const asset = resolveAntigravityReleaseAsset();
|
|
24676
25104
|
if (asset) {
|
|
24677
|
-
const managed = await completedRelease(
|
|
25105
|
+
const managed = await completedRelease(join21(runtimeRoot(baseDir), "versions", asset.sha256), asset);
|
|
24678
25106
|
if (managed) return managed;
|
|
24679
25107
|
}
|
|
24680
25108
|
const names = executableNames();
|
|
@@ -24796,7 +25224,7 @@ async function extractPinnedArchive(archivePath, outputDirectory, asset) {
|
|
|
24796
25224
|
start: dataOffset,
|
|
24797
25225
|
end: dataOffset + entry.compressedBytes - 1
|
|
24798
25226
|
});
|
|
24799
|
-
const destination = createWriteStream(
|
|
25227
|
+
const destination = createWriteStream(join21(outputDirectory, entry.name), { flags: "wx", mode: 448 });
|
|
24800
25228
|
if (entry.compression === 8) await pipeline(source, createInflateRaw(), counter, destination);
|
|
24801
25229
|
else await pipeline(source, counter, destination);
|
|
24802
25230
|
if (bytes !== expectedBytes) throw new Error("An extracted file was truncated.");
|
|
@@ -24807,8 +25235,8 @@ async function installOnce2(options) {
|
|
|
24807
25235
|
const asset = options.asset === void 0 ? resolveAntigravityReleaseAsset() : options.asset;
|
|
24808
25236
|
if (!asset) throw new Error(`Google does not publish an Antigravity runtime for ${process.platform}-${process.arch}.`);
|
|
24809
25237
|
const root = runtimeRoot(options.baseDir);
|
|
24810
|
-
const versions =
|
|
24811
|
-
const destination =
|
|
25238
|
+
const versions = join21(root, "versions");
|
|
25239
|
+
const destination = join21(versions, asset.sha256);
|
|
24812
25240
|
await mkdir5(versions, { recursive: true, mode: 448 });
|
|
24813
25241
|
const existing = await completedRelease(destination, asset);
|
|
24814
25242
|
if (existing) {
|
|
@@ -24824,11 +25252,11 @@ async function installOnce2(options) {
|
|
|
24824
25252
|
} catch (error51) {
|
|
24825
25253
|
if (error51 instanceof Error && error51.message.includes("Antigravity needs")) throw error51;
|
|
24826
25254
|
}
|
|
24827
|
-
const staging = await mkdtemp2(
|
|
25255
|
+
const staging = await mkdtemp2(join21(versions, `${STAGING_PREFIX}${randomUUID9()}-`));
|
|
24828
25256
|
let failed2 = false;
|
|
24829
25257
|
try {
|
|
24830
|
-
const archivePath =
|
|
24831
|
-
const runtimeDirectory =
|
|
25258
|
+
const archivePath = join21(staging, "download.zip");
|
|
25259
|
+
const runtimeDirectory = join21(staging, "runtime");
|
|
24832
25260
|
await mkdir5(runtimeDirectory, { mode: 448 });
|
|
24833
25261
|
const controller = new AbortController();
|
|
24834
25262
|
const timeout = setTimeout(() => controller.abort(), DOWNLOAD_TIMEOUT_MS2);
|
|
@@ -24874,12 +25302,12 @@ async function installOnce2(options) {
|
|
|
24874
25302
|
}
|
|
24875
25303
|
await extractPinnedArchive(archivePath, runtimeDirectory, asset);
|
|
24876
25304
|
if (process.platform !== "win32") {
|
|
24877
|
-
await chmod(
|
|
24878
|
-
await chmod(
|
|
25305
|
+
await chmod(join21(runtimeDirectory, asset.executable.name), 493);
|
|
25306
|
+
await chmod(join21(runtimeDirectory, asset.harness.name), 493);
|
|
24879
25307
|
}
|
|
24880
25308
|
const candidate = {
|
|
24881
|
-
executablePath:
|
|
24882
|
-
harnessPath:
|
|
25309
|
+
executablePath: join21(runtimeDirectory, asset.executable.name),
|
|
25310
|
+
harnessPath: join21(runtimeDirectory, asset.harness.name),
|
|
24883
25311
|
source: "managed",
|
|
24884
25312
|
version: asset.version
|
|
24885
25313
|
};
|
|
@@ -24890,7 +25318,7 @@ async function installOnce2(options) {
|
|
|
24890
25318
|
executable: asset.executable,
|
|
24891
25319
|
harness: asset.harness
|
|
24892
25320
|
};
|
|
24893
|
-
await writeFile2(
|
|
25321
|
+
await writeFile2(join21(runtimeDirectory, INSTALL_RECORD), `${JSON.stringify(record3)}
|
|
24894
25322
|
`, { flag: "wx", mode: 384 });
|
|
24895
25323
|
try {
|
|
24896
25324
|
await retryOnWindowsFileLock(() => rename2(runtimeDirectory, destination));
|
|
@@ -25115,304 +25543,6 @@ var init_antigravity = __esm({
|
|
|
25115
25543
|
}
|
|
25116
25544
|
});
|
|
25117
25545
|
|
|
25118
|
-
// server/drivers/codex-device-auth.ts
|
|
25119
|
-
import { randomUUID as randomUUID9 } from "node:crypto";
|
|
25120
|
-
import { realpathSync as realpathSync2 } from "node:fs";
|
|
25121
|
-
import { homedir as homedir8 } from "node:os";
|
|
25122
|
-
import { basename as basename7, dirname as dirname9, isAbsolute as isAbsolute4, join as join21, resolve as resolve7 } from "node:path";
|
|
25123
|
-
import { stripVTControlCharacters as stripVTControlCharacters4 } from "node:util";
|
|
25124
|
-
function canonicalPath(path3) {
|
|
25125
|
-
try {
|
|
25126
|
-
return realpathSync2(path3);
|
|
25127
|
-
} catch {
|
|
25128
|
-
const parent = dirname9(path3);
|
|
25129
|
-
return parent === path3 ? path3 : join21(canonicalPath(parent), basename7(path3));
|
|
25130
|
-
}
|
|
25131
|
-
}
|
|
25132
|
-
function codexDevicePrompt(output) {
|
|
25133
|
-
const clean = stripVTControlCharacters4(output);
|
|
25134
|
-
const lines = clean.split(/\r?\n/).slice(0, -1).map((line) => line.trim());
|
|
25135
|
-
if (!lines.some((line) => /^https:\/\/auth\.openai\.com\/codex\/device\/?$/.test(line))) return null;
|
|
25136
|
-
const userCode = lines.find((line) => /^[A-Z0-9]{4,8}-[A-Z0-9]{4,8}$/.test(line));
|
|
25137
|
-
return userCode ? { authorizationUrl: DEVICE_URL, userCode } : null;
|
|
25138
|
-
}
|
|
25139
|
-
function loginFailure(output) {
|
|
25140
|
-
if (/(unexpected argument|unrecognized (argument|option)|unknown option).*device-auth/i.test(output)) {
|
|
25141
|
-
return "This server's Codex CLI needs updating for browser sign-in. Run npm install -g @openai/codex@latest on the server, then try again.";
|
|
25142
|
-
}
|
|
25143
|
-
if (/device.{0,40}(disabled|not enabled|not allowed)|enable.{0,40}device/i.test(output)) {
|
|
25144
|
-
return "Enable device-code login in your ChatGPT security settings or ask your workspace admin to allow it, then try again.";
|
|
25145
|
-
}
|
|
25146
|
-
if (/expired|expiration|timed out/i.test(output)) {
|
|
25147
|
-
return "The ChatGPT sign-in code expired. Start sign-in again for a new code.";
|
|
25148
|
-
}
|
|
25149
|
-
return "ChatGPT sign-in did not finish. Check the server's connection and that device-code login is enabled in ChatGPT, then try again.";
|
|
25150
|
-
}
|
|
25151
|
-
var DEVICE_URL, MAX_OUTPUT2, authenticatingHomes, CodexDeviceAuthController;
|
|
25152
|
-
var init_codex_device_auth = __esm({
|
|
25153
|
-
"server/drivers/codex-device-auth.ts"() {
|
|
25154
|
-
"use strict";
|
|
25155
|
-
init_procs();
|
|
25156
|
-
DEVICE_URL = "https://auth.openai.com/codex/device";
|
|
25157
|
-
MAX_OUTPUT2 = 16384;
|
|
25158
|
-
authenticatingHomes = /* @__PURE__ */ new Set();
|
|
25159
|
-
CodexDeviceAuthController = class {
|
|
25160
|
-
flow = null;
|
|
25161
|
-
command = null;
|
|
25162
|
-
disposed = false;
|
|
25163
|
-
options;
|
|
25164
|
-
constructor(options) {
|
|
25165
|
-
this.options = options;
|
|
25166
|
-
}
|
|
25167
|
-
async start() {
|
|
25168
|
-
if (this.disposed) throw new Error("This provider was removed. Refresh Settings before signing in.");
|
|
25169
|
-
if (this.flow?.status.phase === "waiting") {
|
|
25170
|
-
if (this.flow.ready) return { ...this.flow.status, phase: "waiting" };
|
|
25171
|
-
throw new Error("A ChatGPT sign-in is already starting. Please wait for the code.");
|
|
25172
|
-
}
|
|
25173
|
-
await this.flow?.stopping;
|
|
25174
|
-
if (this.disposed) throw new Error("This provider was removed. Refresh Settings before signing in.");
|
|
25175
|
-
const env = this.options.environment();
|
|
25176
|
-
const home = env.HOME || env.USERPROFILE || homedir8();
|
|
25177
|
-
if (!isAbsolute4(home) || env.CODEX_HOME && !isAbsolute4(env.CODEX_HOME)) {
|
|
25178
|
-
throw new Error("Use an absolute HOME and CODEX_HOME path for this server's Codex provider before signing in.");
|
|
25179
|
-
}
|
|
25180
|
-
const homeKey = canonicalPath(resolve7(env.CODEX_HOME || join21(home, ".codex")));
|
|
25181
|
-
if (authenticatingHomes.has(homeKey)) {
|
|
25182
|
-
throw new Error("A ChatGPT sign-in is already running for this server account. Finish or cancel it before starting another.");
|
|
25183
|
-
}
|
|
25184
|
-
authenticatingHomes.add(homeKey);
|
|
25185
|
-
return new Promise((resolveStart, reject) => {
|
|
25186
|
-
const flow = {
|
|
25187
|
-
status: {
|
|
25188
|
-
phase: "waiting",
|
|
25189
|
-
flowId: randomUUID9(),
|
|
25190
|
-
authorizationUrl: null,
|
|
25191
|
-
expiresAt: new Date(Date.now() + (this.options.lifetimeMs ?? 15 * 6e4)).toISOString()
|
|
25192
|
-
},
|
|
25193
|
-
child: null,
|
|
25194
|
-
ready: false,
|
|
25195
|
-
resolve: resolveStart,
|
|
25196
|
-
reject,
|
|
25197
|
-
homeKey,
|
|
25198
|
-
startupTimer: setTimeout(() => this.finish(flow, "failed", "Codex did not provide a sign-in code in time. Check the server connection and update Codex, then try again."), this.options.startupTimeoutMs ?? 3e4),
|
|
25199
|
-
expiryTimer: setTimeout(() => this.finish(flow, "expired", "The ChatGPT sign-in code expired. Start sign-in again."), this.options.lifetimeMs ?? 15 * 6e4)
|
|
25200
|
-
};
|
|
25201
|
-
flow.startupTimer.unref();
|
|
25202
|
-
flow.expiryTimer.unref();
|
|
25203
|
-
this.flow = flow;
|
|
25204
|
-
this.run(flow, ["login", "status"], env, home, (code, output) => {
|
|
25205
|
-
if (code === 0 && /^logged in.*chatgpt\b/im.test(output)) {
|
|
25206
|
-
this.finish(flow, "succeeded");
|
|
25207
|
-
} else if (code === 0 && /^logged in\b/im.test(output)) {
|
|
25208
|
-
this.finish(flow, "failed", "Codex already has a different sign-in method on this server. Ask the server administrator to review it before changing accounts.");
|
|
25209
|
-
} else if (code !== 0 && /^not logged in\b/im.test(output)) {
|
|
25210
|
-
this.run(flow, ["login", "--device-auth"], env, home, (loginCode, loginOutput) => {
|
|
25211
|
-
if (loginCode !== 0 || !flow.ready) {
|
|
25212
|
-
this.finish(flow, "failed", loginFailure(loginOutput));
|
|
25213
|
-
return;
|
|
25214
|
-
}
|
|
25215
|
-
flow.startupTimer = setTimeout(() => this.finish(flow, "failed", "Codex finished sign-in but could not confirm the account. Refresh Settings and try again."), this.options.startupTimeoutMs ?? 3e4);
|
|
25216
|
-
flow.startupTimer.unref();
|
|
25217
|
-
this.run(flow, ["login", "status"], env, home, (statusCode, statusOutput) => {
|
|
25218
|
-
this.finish(
|
|
25219
|
-
flow,
|
|
25220
|
-
statusCode === 0 && /^logged in.*chatgpt\b/im.test(statusOutput) ? "succeeded" : "failed",
|
|
25221
|
-
"Codex finished sign-in but did not confirm a ChatGPT account. Refresh Settings and try again."
|
|
25222
|
-
);
|
|
25223
|
-
});
|
|
25224
|
-
}, true);
|
|
25225
|
-
} else this.finish(flow, "failed", "Codex could not confirm the existing sign-in on this server. Update Codex and check its login status before trying again.");
|
|
25226
|
-
});
|
|
25227
|
-
});
|
|
25228
|
-
}
|
|
25229
|
-
async get(flowId) {
|
|
25230
|
-
if (!flowId || this.flow?.status.flowId !== flowId) throw new Error("This sign-in is no longer available. Start sign-in again.");
|
|
25231
|
-
return { ...this.flow.status };
|
|
25232
|
-
}
|
|
25233
|
-
async cancel() {
|
|
25234
|
-
if (this.flow?.status.phase === "waiting") this.finish(this.flow, "cancelled", "ChatGPT sign-in cancelled.");
|
|
25235
|
-
await this.flow?.stopping;
|
|
25236
|
-
if (this.flow?.terminationFailed) throw new Error(this.flow.status.message);
|
|
25237
|
-
if (this.command && !await this.stopChild(this.command)) {
|
|
25238
|
-
throw new Error("Codex could not be stopped on this server. Ask the server administrator to stop the account command before trying again.");
|
|
25239
|
-
}
|
|
25240
|
-
}
|
|
25241
|
-
async dispose() {
|
|
25242
|
-
this.disposed = true;
|
|
25243
|
-
await this.cancel();
|
|
25244
|
-
this.flow = null;
|
|
25245
|
-
}
|
|
25246
|
-
/** Remove the ChatGPT sign-in Codex stores for this server account so a
|
|
25247
|
-
* different account can connect. A sign-in in progress is never pulled
|
|
25248
|
-
* away underneath the browser completing it. */
|
|
25249
|
-
async signOut() {
|
|
25250
|
-
if (this.disposed) throw new Error("This provider was removed. Refresh Settings before signing out.");
|
|
25251
|
-
if (this.flow?.status.phase === "waiting") throw new Error("Finish or cancel the ChatGPT sign-in in progress before signing out.");
|
|
25252
|
-
await this.flow?.stopping;
|
|
25253
|
-
if (this.disposed) throw new Error("This provider was removed. Refresh Settings before signing out.");
|
|
25254
|
-
const env = this.options.environment();
|
|
25255
|
-
const home = env.HOME || env.USERPROFILE || homedir8();
|
|
25256
|
-
if (!isAbsolute4(home) || env.CODEX_HOME && !isAbsolute4(env.CODEX_HOME)) {
|
|
25257
|
-
throw new Error("Use an absolute HOME and CODEX_HOME path for this server's Codex provider before signing out.");
|
|
25258
|
-
}
|
|
25259
|
-
const homeKey = canonicalPath(resolve7(env.CODEX_HOME || join21(home, ".codex")));
|
|
25260
|
-
if (authenticatingHomes.has(homeKey)) {
|
|
25261
|
-
throw new Error("A ChatGPT sign-in is running for this server account. Finish or cancel it before signing out.");
|
|
25262
|
-
}
|
|
25263
|
-
authenticatingHomes.add(homeKey);
|
|
25264
|
-
try {
|
|
25265
|
-
const before = await this.exec(["login", "status"], env, home);
|
|
25266
|
-
if (before.code === 1 && /^not logged in\b/im.test(before.output)) return;
|
|
25267
|
-
if (before.code !== 0 || !/^logged in.*chatgpt\b/im.test(before.output)) {
|
|
25268
|
-
throw new Error("Codex did not confirm a ChatGPT sign-in. Other authentication methods will not be removed; ask the server administrator to check the account.");
|
|
25269
|
-
}
|
|
25270
|
-
const logout = await this.exec(["logout"], env, home);
|
|
25271
|
-
if (logout.code !== 0) throw new Error("Codex could not remove the sign-in on this server. Check the server's Codex installation and try again.");
|
|
25272
|
-
const status = await this.exec(["login", "status"], env, home);
|
|
25273
|
-
if (status.code !== 1 || !/^not logged in\b/im.test(status.output)) {
|
|
25274
|
-
throw new Error("Codex still reports a sign-in on this server. Update Codex and check its login status before trying again.");
|
|
25275
|
-
}
|
|
25276
|
-
} finally {
|
|
25277
|
-
const child = this.command;
|
|
25278
|
-
if (child && child.exitCode === null && child.signalCode === null) {
|
|
25279
|
-
child.once("close", () => authenticatingHomes.delete(homeKey));
|
|
25280
|
-
} else authenticatingHomes.delete(homeKey);
|
|
25281
|
-
}
|
|
25282
|
-
}
|
|
25283
|
-
/** One bounded, non-interactive Codex command. Its output stays here;
|
|
25284
|
-
* callers see an exit code and a status-line match, never the text. */
|
|
25285
|
-
exec(args, env, cwd) {
|
|
25286
|
-
return new Promise((resolveExec, rejectExec) => {
|
|
25287
|
-
if (this.disposed) {
|
|
25288
|
-
rejectExec(new Error("This provider was removed. Refresh Settings before signing out."));
|
|
25289
|
-
return;
|
|
25290
|
-
}
|
|
25291
|
-
let child;
|
|
25292
|
-
try {
|
|
25293
|
-
child = spawnCli(this.options.cli, args, { env: { ...env, NO_COLOR: "1" }, cwd, stdio: ["pipe", "pipe", "pipe"] });
|
|
25294
|
-
} catch {
|
|
25295
|
-
rejectExec(new Error("Codex could not start on this server. Install or update the configured Codex CLI, then try again."));
|
|
25296
|
-
return;
|
|
25297
|
-
}
|
|
25298
|
-
this.command = child;
|
|
25299
|
-
child.stdin.end();
|
|
25300
|
-
let output = "";
|
|
25301
|
-
const receive = (chunk) => {
|
|
25302
|
-
if (output.length < MAX_OUTPUT2) output += chunk.toString("utf8").slice(0, MAX_OUTPUT2 - output.length);
|
|
25303
|
-
};
|
|
25304
|
-
child.stdout.on("data", receive);
|
|
25305
|
-
child.stderr.on("data", receive);
|
|
25306
|
-
const timer = setTimeout(() => {
|
|
25307
|
-
void this.stopChild(child).catch(() => false).then((stopped) => {
|
|
25308
|
-
if (!stopped) rejectExec(new Error("Codex could not be stopped on this server. Ask the server administrator to stop the account command before trying again."));
|
|
25309
|
-
});
|
|
25310
|
-
}, this.options.startupTimeoutMs ?? 3e4);
|
|
25311
|
-
timer.unref();
|
|
25312
|
-
child.once("error", (error51) => {
|
|
25313
|
-
clearTimeout(timer);
|
|
25314
|
-
rejectExec(new Error(error51.code === "ENOENT" ? "Codex is not installed on this server. Run npm install -g @openai/codex@latest on the server, then try again." : "Codex could not start on this server. Check the configured CLI path and its executable permissions."));
|
|
25315
|
-
});
|
|
25316
|
-
child.once("close", (code) => {
|
|
25317
|
-
clearTimeout(timer);
|
|
25318
|
-
if (this.command === child) this.command = null;
|
|
25319
|
-
resolveExec({ code, output: stripVTControlCharacters4(output) });
|
|
25320
|
-
});
|
|
25321
|
-
});
|
|
25322
|
-
}
|
|
25323
|
-
run(flow, args, env, cwd, done, parsePrompt = false) {
|
|
25324
|
-
if (flow.status.phase !== "waiting") return;
|
|
25325
|
-
let child;
|
|
25326
|
-
try {
|
|
25327
|
-
child = spawnCli(this.options.cli, args, { env: { ...env, NO_COLOR: "1" }, cwd, stdio: ["pipe", "pipe", "pipe"] });
|
|
25328
|
-
} catch {
|
|
25329
|
-
this.finish(flow, "failed", "Codex could not start on this server. Install or update the configured Codex CLI, then try again.");
|
|
25330
|
-
return;
|
|
25331
|
-
}
|
|
25332
|
-
flow.child = child;
|
|
25333
|
-
child.stdin.end();
|
|
25334
|
-
let output = "";
|
|
25335
|
-
const receive = (chunk) => {
|
|
25336
|
-
if (flow.status.phase !== "waiting") return;
|
|
25337
|
-
if (output.length + chunk.length > MAX_OUTPUT2) {
|
|
25338
|
-
this.finish(flow, "failed", "Codex returned an unexpected sign-in response. Update the server's Codex CLI and try again.");
|
|
25339
|
-
return;
|
|
25340
|
-
}
|
|
25341
|
-
output += chunk.toString("utf8");
|
|
25342
|
-
const prompt = parsePrompt && !flow.ready ? codexDevicePrompt(output) : null;
|
|
25343
|
-
if (prompt) {
|
|
25344
|
-
flow.status = { ...flow.status, ...prompt };
|
|
25345
|
-
flow.ready = true;
|
|
25346
|
-
clearTimeout(flow.startupTimer);
|
|
25347
|
-
flow.resolve({ ...flow.status, phase: "waiting" });
|
|
25348
|
-
}
|
|
25349
|
-
};
|
|
25350
|
-
child.stdout.on("data", receive);
|
|
25351
|
-
child.stderr.on("data", receive);
|
|
25352
|
-
child.once("error", (error51) => {
|
|
25353
|
-
const message3 = error51.code === "ENOENT" ? "Codex is not installed on this server. Run npm install -g @openai/codex@latest on the server, then try again." : "Codex could not start on this server. Check the configured CLI path and its executable permissions.";
|
|
25354
|
-
this.finish(flow, "failed", message3);
|
|
25355
|
-
});
|
|
25356
|
-
child.once("close", (code) => {
|
|
25357
|
-
if (flow.child === child) flow.child = null;
|
|
25358
|
-
if (flow.status.phase === "waiting") done(code, stripVTControlCharacters4(output));
|
|
25359
|
-
output = "";
|
|
25360
|
-
});
|
|
25361
|
-
}
|
|
25362
|
-
finish(flow, phase, message3) {
|
|
25363
|
-
if (flow.status.phase !== "waiting") return;
|
|
25364
|
-
clearTimeout(flow.startupTimer);
|
|
25365
|
-
clearTimeout(flow.expiryTimer);
|
|
25366
|
-
flow.status = {
|
|
25367
|
-
phase,
|
|
25368
|
-
flowId: flow.status.flowId,
|
|
25369
|
-
authorizationUrl: null,
|
|
25370
|
-
expiresAt: null,
|
|
25371
|
-
...phase !== "succeeded" && message3 ? { message: message3 } : {}
|
|
25372
|
-
};
|
|
25373
|
-
if (!flow.ready) {
|
|
25374
|
-
if (phase === "succeeded") flow.resolve({ ...flow.status, phase });
|
|
25375
|
-
else flow.reject(new Error(message3 ?? "ChatGPT sign-in did not finish."));
|
|
25376
|
-
}
|
|
25377
|
-
flow.stopping = this.stopChild(flow.child).catch(() => false).then((stopped) => {
|
|
25378
|
-
const release = () => authenticatingHomes.delete(flow.homeKey);
|
|
25379
|
-
if (stopped) {
|
|
25380
|
-
release();
|
|
25381
|
-
return;
|
|
25382
|
-
}
|
|
25383
|
-
flow.terminationFailed = true;
|
|
25384
|
-
flow.status = { ...flow.status, phase: "failed", message: "Codex could not be stopped on this server. Ask the server administrator to stop the login process before trying again." };
|
|
25385
|
-
const child = flow.child;
|
|
25386
|
-
if (!child || child.exitCode !== null || child.signalCode !== null) release();
|
|
25387
|
-
else child.once("close", release);
|
|
25388
|
-
});
|
|
25389
|
-
if (phase === "succeeded") void this.options.onAuthenticated?.().catch(() => {
|
|
25390
|
-
});
|
|
25391
|
-
}
|
|
25392
|
-
async stopChild(child) {
|
|
25393
|
-
if (!child || await killCliTree(child, this.options.terminateTimeoutMs ?? 1500)) return true;
|
|
25394
|
-
if (process.platform !== "win32" && child.pid) {
|
|
25395
|
-
try {
|
|
25396
|
-
process.kill(-child.pid, "SIGKILL");
|
|
25397
|
-
} catch {
|
|
25398
|
-
child.kill("SIGKILL");
|
|
25399
|
-
}
|
|
25400
|
-
} else child.kill("SIGKILL");
|
|
25401
|
-
await new Promise((resolveStop) => {
|
|
25402
|
-
if (child.exitCode !== null || child.signalCode !== null) return resolveStop();
|
|
25403
|
-
const timer = setTimeout(resolveStop, 1500);
|
|
25404
|
-
timer.unref();
|
|
25405
|
-
child.once("close", () => {
|
|
25406
|
-
clearTimeout(timer);
|
|
25407
|
-
resolveStop();
|
|
25408
|
-
});
|
|
25409
|
-
});
|
|
25410
|
-
return child.exitCode !== null || child.signalCode !== null;
|
|
25411
|
-
}
|
|
25412
|
-
};
|
|
25413
|
-
}
|
|
25414
|
-
});
|
|
25415
|
-
|
|
25416
25546
|
// server/drivers/claude-login-auth.ts
|
|
25417
25547
|
import { randomUUID as randomUUID10 } from "node:crypto";
|
|
25418
25548
|
import { homedir as homedir9 } from "node:os";
|
|
@@ -25447,7 +25577,7 @@ var init_claude_login_auth = __esm({
|
|
|
25447
25577
|
"server/drivers/claude-login-auth.ts"() {
|
|
25448
25578
|
"use strict";
|
|
25449
25579
|
init_procs();
|
|
25450
|
-
|
|
25580
|
+
init_device_auth();
|
|
25451
25581
|
MAX_OUTPUT3 = 32768;
|
|
25452
25582
|
SIGN_IN_HOSTS = ["claude.com", "claude.ai", "console.anthropic.com", "platform.claude.com"];
|
|
25453
25583
|
authenticatingHomes2 = /* @__PURE__ */ new Set();
|
|
@@ -25819,7 +25949,7 @@ var init_tool_scope_support = __esm({
|
|
|
25819
25949
|
|
|
25820
25950
|
// server/drivers/claude.ts
|
|
25821
25951
|
import { createHash as createHash8, randomBytes as randomBytes2, randomUUID as randomUUID11 } from "node:crypto";
|
|
25822
|
-
import { chmodSync as chmodSync4, mkdirSync as mkdirSync10, mkdtempSync as mkdtempSync2, readFileSync as
|
|
25952
|
+
import { chmodSync as chmodSync4, mkdirSync as mkdirSync10, mkdtempSync as mkdtempSync2, readFileSync as readFileSync9, rmSync as rmSync6, unlinkSync as unlinkSync3, writeFileSync as writeFileSync5 } from "node:fs";
|
|
25823
25953
|
import { createServer as createNetServer } from "node:net";
|
|
25824
25954
|
import { homedir as homedir10, tmpdir as tmpdir3 } from "node:os";
|
|
25825
25955
|
import { join as join23, dirname as dirname10, isAbsolute as isAbsolute6, normalize } from "node:path";
|
|
@@ -25897,7 +26027,7 @@ function claudeInheritWarning(env) {
|
|
|
25897
26027
|
function readClaudeAuthSettings(env, instanceEnvironment = {}) {
|
|
25898
26028
|
if (CLAUDE_ACCOUNT_ENV_KEYS.some((key) => instanceEnvironment[key])) return {};
|
|
25899
26029
|
try {
|
|
25900
|
-
const settings2 = JSON.parse(
|
|
26030
|
+
const settings2 = JSON.parse(readFileSync9(join23(resolveClaudeConfigDir(void 0, env), "settings.json"), "utf8"));
|
|
25901
26031
|
const authEnv = {};
|
|
25902
26032
|
for (const key of CLAUDE_ACCOUNT_ENV_KEYS) {
|
|
25903
26033
|
if (!key.endsWith("_FILE_DESCRIPTOR") && typeof settings2?.env?.[key] === "string") {
|
|
@@ -25915,7 +26045,7 @@ function readClaudeAuthSettings(env, instanceEnvironment = {}) {
|
|
|
25915
26045
|
function projectMcpServers(cwd) {
|
|
25916
26046
|
let parsed;
|
|
25917
26047
|
try {
|
|
25918
|
-
parsed = JSON.parse(
|
|
26048
|
+
parsed = JSON.parse(readFileSync9(join23(cwd, ".mcp.json"), "utf8"));
|
|
25919
26049
|
} catch {
|
|
25920
26050
|
return {};
|
|
25921
26051
|
}
|
|
@@ -25980,7 +26110,7 @@ function extrasFromUnknown(value) {
|
|
|
25980
26110
|
function readClaudeModelCatalog(env = process.env) {
|
|
25981
26111
|
let settings2 = {};
|
|
25982
26112
|
try {
|
|
25983
|
-
settings2 = JSON.parse(
|
|
26113
|
+
settings2 = JSON.parse(readFileSync9(join23(resolveClaudeConfigDir(void 0, env), "settings.json"), "utf8"));
|
|
25984
26114
|
} catch {
|
|
25985
26115
|
settings2 = {};
|
|
25986
26116
|
}
|
|
@@ -26070,6 +26200,7 @@ async function createPermissionBroker(opts) {
|
|
|
26070
26200
|
const connectionHandler = (conn) => {
|
|
26071
26201
|
conn.on("error", () => {
|
|
26072
26202
|
});
|
|
26203
|
+
conn.setEncoding("utf8");
|
|
26073
26204
|
let buf = "";
|
|
26074
26205
|
conn.on("data", (chunk) => {
|
|
26075
26206
|
buf += chunk;
|
|
@@ -26299,7 +26430,7 @@ function isCostSnapshot(value) {
|
|
|
26299
26430
|
}
|
|
26300
26431
|
function readCostHistory() {
|
|
26301
26432
|
try {
|
|
26302
|
-
const parsed = JSON.parse(
|
|
26433
|
+
const parsed = JSON.parse(readFileSync9(COST_HISTORY_FILE, "utf8"));
|
|
26303
26434
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return {};
|
|
26304
26435
|
return Object.fromEntries(Object.entries(parsed).map(([id, states]) => [id, Array.isArray(states) ? states.filter(isCostSnapshot) : []]));
|
|
26305
26436
|
} catch {
|
|
@@ -26314,7 +26445,7 @@ function recordCostState(sessionId, state) {
|
|
|
26314
26445
|
const ids = Object.keys(history);
|
|
26315
26446
|
for (const id of ids.slice(0, Math.max(0, ids.length - COST_HISTORY_SESSIONS))) delete history[id];
|
|
26316
26447
|
try {
|
|
26317
|
-
writeFileAtomic(COST_HISTORY_FILE, JSON.stringify(history), { mode: 384 });
|
|
26448
|
+
writeFileAtomic(COST_HISTORY_FILE, JSON.stringify(history), { mode: 384, durable: false });
|
|
26318
26449
|
} catch {
|
|
26319
26450
|
}
|
|
26320
26451
|
}
|
|
@@ -26336,7 +26467,7 @@ function claudeUserMessage(text4, images) {
|
|
|
26336
26467
|
source: {
|
|
26337
26468
|
type: "base64",
|
|
26338
26469
|
media_type: image.mime,
|
|
26339
|
-
data:
|
|
26470
|
+
data: readFileSync9(image.path).toString("base64")
|
|
26340
26471
|
}
|
|
26341
26472
|
}));
|
|
26342
26473
|
if (text4) content.push({ type: "text", text: text4 });
|
|
@@ -26497,7 +26628,23 @@ var init_claude = __esm({
|
|
|
26497
26628
|
(err, stdout2) => resolve14(err ? null : stdout2.trim() || null)
|
|
26498
26629
|
);
|
|
26499
26630
|
});
|
|
26500
|
-
|
|
26631
|
+
let helpRead = null;
|
|
26632
|
+
const readCliHelp = (version2, env) => {
|
|
26633
|
+
if (helpRead?.version === version2) return helpRead.done;
|
|
26634
|
+
const read = {
|
|
26635
|
+
version: version2,
|
|
26636
|
+
done: new Promise((resolve14) => {
|
|
26637
|
+
execCli(config2.cli, ["--help"], { timeout: 8e3, env }, (err, stdout2) => resolve14(err ? null : stdout2));
|
|
26638
|
+
}).then((help) => {
|
|
26639
|
+
cliHasAutocompact = help === null ? null : /^\s*--autocompact\b/m.test(help);
|
|
26640
|
+
cliHelpVersion = version2;
|
|
26641
|
+
if (helpRead === read) helpRead = null;
|
|
26642
|
+
})
|
|
26643
|
+
};
|
|
26644
|
+
helpRead = read;
|
|
26645
|
+
return read.done;
|
|
26646
|
+
};
|
|
26647
|
+
const listeners2 = /* @__PURE__ */ new Set();
|
|
26501
26648
|
const active = /* @__PURE__ */ new Map();
|
|
26502
26649
|
const sessions = /* @__PURE__ */ new Map();
|
|
26503
26650
|
const { idleMs: SESSION_IDLE_MS } = sessionIdlePolicy("CLAUDE");
|
|
@@ -26550,7 +26697,7 @@ var init_claude = __esm({
|
|
|
26550
26697
|
});
|
|
26551
26698
|
};
|
|
26552
26699
|
const emit = (event) => {
|
|
26553
|
-
for (const l of Array.from(
|
|
26700
|
+
for (const l of Array.from(listeners2)) l(event);
|
|
26554
26701
|
};
|
|
26555
26702
|
const base2 = (threadId, turnId) => ({
|
|
26556
26703
|
eventId: newEventId(),
|
|
@@ -26728,7 +26875,7 @@ var init_claude = __esm({
|
|
|
26728
26875
|
const hookTokenPath = hooks ? hookTokenFile(threadId, botId) : null;
|
|
26729
26876
|
if (hooks && hookTokenPath) {
|
|
26730
26877
|
mkdirSync10(dirname10(hookTokenPath), { recursive: true, mode: 448 });
|
|
26731
|
-
|
|
26878
|
+
writeFileAtomicIfChanged(hookTokenPath, hooks.token, { mode: 384, durable: false });
|
|
26732
26879
|
env.OMB_HOOK_URL = hooks.url;
|
|
26733
26880
|
env.OMB_HOOK_TOKEN_FILE = hookTokenPath;
|
|
26734
26881
|
env.OMB_HOOK_NODE = process.execPath;
|
|
@@ -27360,13 +27507,7 @@ var init_claude = __esm({
|
|
|
27360
27507
|
if (!version2) return { state: "unavailable", reason: `\`${config2.cli}\` CLI not found` };
|
|
27361
27508
|
cliVersion = parseClaudeCliVersion(version2);
|
|
27362
27509
|
cliVersionChecked = true;
|
|
27363
|
-
if (version2 !== cliHelpVersion)
|
|
27364
|
-
const help = await new Promise((resolve14) => {
|
|
27365
|
-
execCli(config2.cli, ["--help"], { timeout: 8e3, env }, (err, stdout2) => resolve14(err ? null : stdout2));
|
|
27366
|
-
});
|
|
27367
|
-
cliHasAutocompact = help === null ? null : /^\s*--autocompact\b/m.test(help);
|
|
27368
|
-
cliHelpVersion = version2;
|
|
27369
|
-
}
|
|
27510
|
+
if (version2 !== cliHelpVersion) await readCliHelp(version2, env);
|
|
27370
27511
|
const update = claudeCliUpdate(version2, config2.cli);
|
|
27371
27512
|
const warning = claudeInheritWarning(env);
|
|
27372
27513
|
if (config2.requireApiKey) {
|
|
@@ -27519,8 +27660,8 @@ var init_claude = __esm({
|
|
|
27519
27660
|
for (const threadId of Array.from(sessions.keys())) closeSession(threadId, "stopAll");
|
|
27520
27661
|
},
|
|
27521
27662
|
onEvent: (listener) => {
|
|
27522
|
-
|
|
27523
|
-
return () =>
|
|
27663
|
+
listeners2.add(listener);
|
|
27664
|
+
return () => listeners2.delete(listener);
|
|
27524
27665
|
}
|
|
27525
27666
|
},
|
|
27526
27667
|
generateText: (prompt, options) => generateReview(prompt, options?.signal, options?.onUsage),
|
|
@@ -27531,7 +27672,7 @@ var init_claude = __esm({
|
|
|
27531
27672
|
} finally {
|
|
27532
27673
|
for (const { stop } of active.values()) stop();
|
|
27533
27674
|
for (const threadId of Array.from(sessions.keys())) closeSession(threadId, "dispose");
|
|
27534
|
-
|
|
27675
|
+
listeners2.clear();
|
|
27535
27676
|
}
|
|
27536
27677
|
}
|
|
27537
27678
|
};
|
|
@@ -27565,7 +27706,7 @@ var init_codex_tool_surface = __esm({
|
|
|
27565
27706
|
});
|
|
27566
27707
|
|
|
27567
27708
|
// server/drivers/codex-mcp-names.ts
|
|
27568
|
-
import { readFileSync as
|
|
27709
|
+
import { readFileSync as readFileSync10 } from "node:fs";
|
|
27569
27710
|
import { homedir as homedir11 } from "node:os";
|
|
27570
27711
|
import { join as join24 } from "node:path";
|
|
27571
27712
|
function mcpServerNamesInToml(toml) {
|
|
@@ -27579,7 +27720,7 @@ function mcpServerNamesInToml(toml) {
|
|
|
27579
27720
|
function codexConfigMcpServerNames(env) {
|
|
27580
27721
|
const codexHome2 = env.CODEX_HOME || join24(env.HOME || env.USERPROFILE || homedir11(), ".codex");
|
|
27581
27722
|
try {
|
|
27582
|
-
return mcpServerNamesInToml(
|
|
27723
|
+
return mcpServerNamesInToml(readFileSync10(join24(codexHome2, "config.toml"), "utf8"));
|
|
27583
27724
|
} catch {
|
|
27584
27725
|
return /* @__PURE__ */ new Set();
|
|
27585
27726
|
}
|
|
@@ -27677,7 +27818,7 @@ import {
|
|
|
27677
27818
|
linkSync as linkSync2,
|
|
27678
27819
|
mkdirSync as mkdirSync11,
|
|
27679
27820
|
openSync as openSync6,
|
|
27680
|
-
readFileSync as
|
|
27821
|
+
readFileSync as readFileSync11,
|
|
27681
27822
|
unlinkSync as unlinkSync4,
|
|
27682
27823
|
writeFileSync as writeFileSync6
|
|
27683
27824
|
} from "node:fs";
|
|
@@ -27686,7 +27827,7 @@ function serverVersion() {
|
|
|
27686
27827
|
const fromEnv = process.env.OMB_APP_VERSION?.trim();
|
|
27687
27828
|
if (fromEnv) return fromEnv;
|
|
27688
27829
|
try {
|
|
27689
|
-
const pkg = JSON.parse(
|
|
27830
|
+
const pkg = JSON.parse(readFileSync11(join25(SERVER_ROOT, "..", "package.json"), "utf8"));
|
|
27690
27831
|
const version2 = Reflect.get(Object(pkg), "version");
|
|
27691
27832
|
if (typeof version2 === "string" && version2) return version2;
|
|
27692
27833
|
} catch {
|
|
@@ -28669,7 +28810,7 @@ var init_webapi = __esm({
|
|
|
28669
28810
|
|
|
28670
28811
|
// server/drivers/chatgpt-plan-auth.ts
|
|
28671
28812
|
import { createHash as createHash9, randomBytes as randomBytes3, randomUUID as randomUUID12, timingSafeEqual } from "node:crypto";
|
|
28672
|
-
import { chmodSync as chmodSync5, closeSync as closeSync7, lstatSync as
|
|
28813
|
+
import { chmodSync as chmodSync5, closeSync as closeSync7, lstatSync as lstatSync3, mkdirSync as mkdirSync12, openSync as openSync7, readFileSync as readFileSync12, unlinkSync as unlinkSync5, writeFileSync as writeFileSync7 } from "node:fs";
|
|
28673
28814
|
import { createServer as createServer2 } from "node:http";
|
|
28674
28815
|
import { dirname as dirname12, isAbsolute as isAbsolute7, join as join26 } from "node:path";
|
|
28675
28816
|
import { setTimeout as delay } from "node:timers/promises";
|
|
@@ -28682,15 +28823,15 @@ function string4(value, max = 65536) {
|
|
|
28682
28823
|
}
|
|
28683
28824
|
function privateDirectory(path3) {
|
|
28684
28825
|
mkdirSync12(path3, { recursive: true, mode: 448 });
|
|
28685
|
-
if (!
|
|
28826
|
+
if (!lstatSync3(path3).isDirectory() || lstatSync3(path3).isSymbolicLink()) throw new Error("ChatGPT credential storage must be a private directory.");
|
|
28686
28827
|
chmodSync5(path3, 448);
|
|
28687
28828
|
}
|
|
28688
28829
|
function readJson(path3) {
|
|
28689
28830
|
try {
|
|
28690
|
-
const stat5 =
|
|
28831
|
+
const stat5 = lstatSync3(path3);
|
|
28691
28832
|
if (!stat5.isFile() || stat5.isSymbolicLink() || stat5.size > 512e3) throw new Error("Invalid credential storage.");
|
|
28692
28833
|
chmodSync5(path3, 384);
|
|
28693
|
-
return JSON.parse(
|
|
28834
|
+
return JSON.parse(readFileSync12(path3, "utf8"));
|
|
28694
28835
|
} catch (error51) {
|
|
28695
28836
|
if (error51.code === "ENOENT") return null;
|
|
28696
28837
|
throw new Error("ChatGPT credential storage could not be read safely. Check its permissions before signing in.");
|
|
@@ -29234,7 +29375,7 @@ var init_codex_identity = __esm({
|
|
|
29234
29375
|
});
|
|
29235
29376
|
|
|
29236
29377
|
// server/drivers/codex-catalog.ts
|
|
29237
|
-
import { readdirSync as readdirSync2, readFileSync as
|
|
29378
|
+
import { readdirSync as readdirSync2, readFileSync as readFileSync13 } from "node:fs";
|
|
29238
29379
|
import { homedir as homedir13 } from "node:os";
|
|
29239
29380
|
import { basename as basename8, join as join28 } from "node:path";
|
|
29240
29381
|
function encodeCodexSelection(provider, model) {
|
|
@@ -29411,7 +29552,7 @@ function parseCodexToml(text4) {
|
|
|
29411
29552
|
}
|
|
29412
29553
|
function readText(path3) {
|
|
29413
29554
|
try {
|
|
29414
|
-
return
|
|
29555
|
+
return readFileSync13(path3, "utf8");
|
|
29415
29556
|
} catch {
|
|
29416
29557
|
return null;
|
|
29417
29558
|
}
|
|
@@ -29581,7 +29722,7 @@ var init_codex_catalog = __esm({
|
|
|
29581
29722
|
|
|
29582
29723
|
// server/drivers/codex-instructions.ts
|
|
29583
29724
|
import { createHash as createHash10 } from "node:crypto";
|
|
29584
|
-
import { mkdirSync as mkdirSync13, readFileSync as
|
|
29725
|
+
import { mkdirSync as mkdirSync13, readFileSync as readFileSync14 } from "node:fs";
|
|
29585
29726
|
import { join as join29 } from "node:path";
|
|
29586
29727
|
function parseReceipt(raw) {
|
|
29587
29728
|
if (!raw) return null;
|
|
@@ -29617,16 +29758,16 @@ ${configured}` : botInstructions;
|
|
|
29617
29758
|
async function syncCodexInstructions(key, nativeThreadId, instructions, volatile, resumed, request, mentionTurn = false) {
|
|
29618
29759
|
const directory = join29(DATA_DIR, "codex-instructions");
|
|
29619
29760
|
const path3 = join29(directory, `${digest2(JSON.stringify([key, nativeThreadId]))}.sha256`);
|
|
29620
|
-
const
|
|
29761
|
+
const fingerprint2 = digest2(instructions);
|
|
29621
29762
|
const volatileFingerprint = digest2(volatile);
|
|
29622
29763
|
let previous;
|
|
29623
29764
|
try {
|
|
29624
|
-
previous = parseReceipt(
|
|
29765
|
+
previous = parseReceipt(readFileSync14(path3, "utf8"));
|
|
29625
29766
|
} catch (error51) {
|
|
29626
29767
|
if (error51.code !== "ENOENT") throw error51;
|
|
29627
29768
|
previous = null;
|
|
29628
29769
|
}
|
|
29629
|
-
if (resumed && previous?.instructions !==
|
|
29770
|
+
if (resumed && previous?.instructions !== fingerprint2) {
|
|
29630
29771
|
try {
|
|
29631
29772
|
await request("thread/inject_items", {
|
|
29632
29773
|
threadId: nativeThreadId,
|
|
@@ -29648,13 +29789,13 @@ async function syncCodexInstructions(key, nativeThreadId, instructions, volatile
|
|
|
29648
29789
|
}
|
|
29649
29790
|
const deliverVolatile = !resumed || previous?.volatile !== volatileFingerprint || mentionTurn;
|
|
29650
29791
|
const hadVolatile = typeof previous?.volatile === "string" && previous.volatile !== digest2("");
|
|
29651
|
-
if (!resumed || previous?.instructions !==
|
|
29792
|
+
if (!resumed || previous?.instructions !== fingerprint2) {
|
|
29652
29793
|
mkdirSync13(directory, { recursive: true });
|
|
29653
|
-
writeFileAtomic(path3, JSON.stringify({ instructions:
|
|
29794
|
+
writeFileAtomic(path3, JSON.stringify({ instructions: fingerprint2 }), { mode: 384 });
|
|
29654
29795
|
}
|
|
29655
|
-
const commitVolatile = previous?.instructions ===
|
|
29796
|
+
const commitVolatile = previous?.instructions === fingerprint2 && previous?.volatile === volatileFingerprint ? null : () => {
|
|
29656
29797
|
mkdirSync13(directory, { recursive: true });
|
|
29657
|
-
writeFileAtomic(path3, JSON.stringify({ instructions:
|
|
29798
|
+
writeFileAtomic(path3, JSON.stringify({ instructions: fingerprint2, volatile: volatileFingerprint }), { mode: 384 });
|
|
29658
29799
|
};
|
|
29659
29800
|
return { deliverVolatile, hadVolatile, commitVolatile };
|
|
29660
29801
|
}
|
|
@@ -29669,6 +29810,48 @@ var init_codex_instructions = __esm({
|
|
|
29669
29810
|
}
|
|
29670
29811
|
});
|
|
29671
29812
|
|
|
29813
|
+
// server/drivers/codex-device-auth.ts
|
|
29814
|
+
function loginFailure(output) {
|
|
29815
|
+
if (/(unexpected argument|unrecognized (argument|option)|unknown option).*device-auth/i.test(output)) {
|
|
29816
|
+
return "This server's Codex CLI needs updating for browser sign-in. Run npm install -g @openai/codex@latest on the server, then try again.";
|
|
29817
|
+
}
|
|
29818
|
+
if (/device.{0,40}(disabled|not enabled|not allowed)|enable.{0,40}device/i.test(output)) {
|
|
29819
|
+
return "Enable device-code login in your ChatGPT security settings or ask your workspace admin to allow it, then try again.";
|
|
29820
|
+
}
|
|
29821
|
+
if (/expired|expiration|timed out/i.test(output)) {
|
|
29822
|
+
return "The ChatGPT sign-in code expired. Start sign-in again for a new code.";
|
|
29823
|
+
}
|
|
29824
|
+
return "ChatGPT sign-in did not finish. Check the server's connection and that device-code login is enabled in ChatGPT, then try again.";
|
|
29825
|
+
}
|
|
29826
|
+
var CODEX_DEVICE_SIGN_IN, CodexDeviceAuthController;
|
|
29827
|
+
var init_codex_device_auth = __esm({
|
|
29828
|
+
"server/drivers/codex-device-auth.ts"() {
|
|
29829
|
+
"use strict";
|
|
29830
|
+
init_device_sign_in();
|
|
29831
|
+
init_device_auth();
|
|
29832
|
+
CODEX_DEVICE_SIGN_IN = {
|
|
29833
|
+
provider: "codex",
|
|
29834
|
+
product: "Codex",
|
|
29835
|
+
account: "ChatGPT",
|
|
29836
|
+
homeEnv: "CODEX_HOME",
|
|
29837
|
+
homeDir: ".codex",
|
|
29838
|
+
loginArgs: ["login", "--device-auth"],
|
|
29839
|
+
install: "Run npm install -g @openai/codex@latest on the server, then try again.",
|
|
29840
|
+
failure: loginFailure,
|
|
29841
|
+
status: {
|
|
29842
|
+
args: ["login", "status"],
|
|
29843
|
+
read: (code, output) => code === 0 && /^logged in.*chatgpt\b/im.test(output) ? "signed-in" : code === 0 && /^logged in\b/im.test(output) ? "other" : code !== 0 && /^not logged in\b/im.test(output) ? "signed-out" : "unknown"
|
|
29844
|
+
},
|
|
29845
|
+
logoutArgs: ["logout"]
|
|
29846
|
+
};
|
|
29847
|
+
CodexDeviceAuthController = class extends DeviceAuthController {
|
|
29848
|
+
constructor(options) {
|
|
29849
|
+
super(CODEX_DEVICE_SIGN_IN, options);
|
|
29850
|
+
}
|
|
29851
|
+
};
|
|
29852
|
+
}
|
|
29853
|
+
});
|
|
29854
|
+
|
|
29672
29855
|
// server/drivers/codex-release.ts
|
|
29673
29856
|
function parseCodexReleaseVersion(value) {
|
|
29674
29857
|
const match = /^(?:.*\bcodex-cli\s+)?v?(\d+)\.(\d+)\.(\d+)(-[0-9a-z.-]+)?(?:\+[0-9a-z.-]+)?$/i.exec(value.trim());
|
|
@@ -30213,10 +30396,10 @@ var init_codex = __esm({
|
|
|
30213
30396
|
environment: childEnv,
|
|
30214
30397
|
onAuthenticated: refreshModels
|
|
30215
30398
|
});
|
|
30216
|
-
const
|
|
30399
|
+
const listeners2 = /* @__PURE__ */ new Set();
|
|
30217
30400
|
const active = /* @__PURE__ */ new Map();
|
|
30218
30401
|
const emit = (event) => {
|
|
30219
|
-
for (const l of Array.from(
|
|
30402
|
+
for (const l of Array.from(listeners2)) l(event);
|
|
30220
30403
|
};
|
|
30221
30404
|
const base2 = (threadId, turnId) => ({
|
|
30222
30405
|
eventId: newEventId(),
|
|
@@ -31223,8 +31406,8 @@ ${stderr ?? ""}`))
|
|
|
31223
31406
|
await Promise.all([...active.values()].map(({ stop }) => stop()));
|
|
31224
31407
|
},
|
|
31225
31408
|
onEvent: (listener) => {
|
|
31226
|
-
|
|
31227
|
-
return () =>
|
|
31409
|
+
listeners2.add(listener);
|
|
31410
|
+
return () => listeners2.delete(listener);
|
|
31228
31411
|
}
|
|
31229
31412
|
},
|
|
31230
31413
|
dispose: async () => {
|
|
@@ -31233,7 +31416,7 @@ ${stderr ?? ""}`))
|
|
|
31233
31416
|
await authentication.dispose();
|
|
31234
31417
|
await planAuth?.dispose();
|
|
31235
31418
|
await Promise.all([...active.values()].map(({ stop }) => stop()));
|
|
31236
|
-
|
|
31419
|
+
listeners2.clear();
|
|
31237
31420
|
}
|
|
31238
31421
|
};
|
|
31239
31422
|
}
|
|
@@ -31618,11 +31801,11 @@ var require_codegen = __commonJS({
|
|
|
31618
31801
|
const rhs = this.rhs === void 0 ? "" : ` = ${this.rhs}`;
|
|
31619
31802
|
return `${varKind} ${this.name}${rhs};` + _n;
|
|
31620
31803
|
}
|
|
31621
|
-
optimizeNames(names,
|
|
31804
|
+
optimizeNames(names, constants4) {
|
|
31622
31805
|
if (!names[this.name.str])
|
|
31623
31806
|
return;
|
|
31624
31807
|
if (this.rhs)
|
|
31625
|
-
this.rhs = optimizeExpr(this.rhs, names,
|
|
31808
|
+
this.rhs = optimizeExpr(this.rhs, names, constants4);
|
|
31626
31809
|
return this;
|
|
31627
31810
|
}
|
|
31628
31811
|
get names() {
|
|
@@ -31639,10 +31822,10 @@ var require_codegen = __commonJS({
|
|
|
31639
31822
|
render({ _n }) {
|
|
31640
31823
|
return `${this.lhs} = ${this.rhs};` + _n;
|
|
31641
31824
|
}
|
|
31642
|
-
optimizeNames(names,
|
|
31825
|
+
optimizeNames(names, constants4) {
|
|
31643
31826
|
if (this.lhs instanceof code_1.Name && !names[this.lhs.str] && !this.sideEffects)
|
|
31644
31827
|
return;
|
|
31645
|
-
this.rhs = optimizeExpr(this.rhs, names,
|
|
31828
|
+
this.rhs = optimizeExpr(this.rhs, names, constants4);
|
|
31646
31829
|
return this;
|
|
31647
31830
|
}
|
|
31648
31831
|
get names() {
|
|
@@ -31703,8 +31886,8 @@ var require_codegen = __commonJS({
|
|
|
31703
31886
|
optimizeNodes() {
|
|
31704
31887
|
return `${this.code}` ? this : void 0;
|
|
31705
31888
|
}
|
|
31706
|
-
optimizeNames(names,
|
|
31707
|
-
this.code = optimizeExpr(this.code, names,
|
|
31889
|
+
optimizeNames(names, constants4) {
|
|
31890
|
+
this.code = optimizeExpr(this.code, names, constants4);
|
|
31708
31891
|
return this;
|
|
31709
31892
|
}
|
|
31710
31893
|
get names() {
|
|
@@ -31733,12 +31916,12 @@ var require_codegen = __commonJS({
|
|
|
31733
31916
|
}
|
|
31734
31917
|
return nodes.length > 0 ? this : void 0;
|
|
31735
31918
|
}
|
|
31736
|
-
optimizeNames(names,
|
|
31919
|
+
optimizeNames(names, constants4) {
|
|
31737
31920
|
const { nodes } = this;
|
|
31738
31921
|
let i2 = nodes.length;
|
|
31739
31922
|
while (i2--) {
|
|
31740
31923
|
const n3 = nodes[i2];
|
|
31741
|
-
if (n3.optimizeNames(names,
|
|
31924
|
+
if (n3.optimizeNames(names, constants4))
|
|
31742
31925
|
continue;
|
|
31743
31926
|
subtractNames(names, n3.names);
|
|
31744
31927
|
nodes.splice(i2, 1);
|
|
@@ -31791,12 +31974,12 @@ var require_codegen = __commonJS({
|
|
|
31791
31974
|
return void 0;
|
|
31792
31975
|
return this;
|
|
31793
31976
|
}
|
|
31794
|
-
optimizeNames(names,
|
|
31977
|
+
optimizeNames(names, constants4) {
|
|
31795
31978
|
var _a3;
|
|
31796
|
-
this.else = (_a3 = this.else) === null || _a3 === void 0 ? void 0 : _a3.optimizeNames(names,
|
|
31797
|
-
if (!(super.optimizeNames(names,
|
|
31979
|
+
this.else = (_a3 = this.else) === null || _a3 === void 0 ? void 0 : _a3.optimizeNames(names, constants4);
|
|
31980
|
+
if (!(super.optimizeNames(names, constants4) || this.else))
|
|
31798
31981
|
return;
|
|
31799
|
-
this.condition = optimizeExpr(this.condition, names,
|
|
31982
|
+
this.condition = optimizeExpr(this.condition, names, constants4);
|
|
31800
31983
|
return this;
|
|
31801
31984
|
}
|
|
31802
31985
|
get names() {
|
|
@@ -31819,10 +32002,10 @@ var require_codegen = __commonJS({
|
|
|
31819
32002
|
render(opts) {
|
|
31820
32003
|
return `for(${this.iteration})` + super.render(opts);
|
|
31821
32004
|
}
|
|
31822
|
-
optimizeNames(names,
|
|
31823
|
-
if (!super.optimizeNames(names,
|
|
32005
|
+
optimizeNames(names, constants4) {
|
|
32006
|
+
if (!super.optimizeNames(names, constants4))
|
|
31824
32007
|
return;
|
|
31825
|
-
this.iteration = optimizeExpr(this.iteration, names,
|
|
32008
|
+
this.iteration = optimizeExpr(this.iteration, names, constants4);
|
|
31826
32009
|
return this;
|
|
31827
32010
|
}
|
|
31828
32011
|
get names() {
|
|
@@ -31858,10 +32041,10 @@ var require_codegen = __commonJS({
|
|
|
31858
32041
|
render(opts) {
|
|
31859
32042
|
return `for(${this.varKind} ${this.name} ${this.loop} ${this.iterable})` + super.render(opts);
|
|
31860
32043
|
}
|
|
31861
|
-
optimizeNames(names,
|
|
31862
|
-
if (!super.optimizeNames(names,
|
|
32044
|
+
optimizeNames(names, constants4) {
|
|
32045
|
+
if (!super.optimizeNames(names, constants4))
|
|
31863
32046
|
return;
|
|
31864
|
-
this.iterable = optimizeExpr(this.iterable, names,
|
|
32047
|
+
this.iterable = optimizeExpr(this.iterable, names, constants4);
|
|
31865
32048
|
return this;
|
|
31866
32049
|
}
|
|
31867
32050
|
get names() {
|
|
@@ -31903,11 +32086,11 @@ var require_codegen = __commonJS({
|
|
|
31903
32086
|
(_b = this.finally) === null || _b === void 0 ? void 0 : _b.optimizeNodes();
|
|
31904
32087
|
return this;
|
|
31905
32088
|
}
|
|
31906
|
-
optimizeNames(names,
|
|
32089
|
+
optimizeNames(names, constants4) {
|
|
31907
32090
|
var _a3, _b;
|
|
31908
|
-
super.optimizeNames(names,
|
|
31909
|
-
(_a3 = this.catch) === null || _a3 === void 0 ? void 0 : _a3.optimizeNames(names,
|
|
31910
|
-
(_b = this.finally) === null || _b === void 0 ? void 0 : _b.optimizeNames(names,
|
|
32091
|
+
super.optimizeNames(names, constants4);
|
|
32092
|
+
(_a3 = this.catch) === null || _a3 === void 0 ? void 0 : _a3.optimizeNames(names, constants4);
|
|
32093
|
+
(_b = this.finally) === null || _b === void 0 ? void 0 : _b.optimizeNames(names, constants4);
|
|
31911
32094
|
return this;
|
|
31912
32095
|
}
|
|
31913
32096
|
get names() {
|
|
@@ -32208,7 +32391,7 @@ var require_codegen = __commonJS({
|
|
|
32208
32391
|
function addExprNames(names, from) {
|
|
32209
32392
|
return from instanceof code_1._CodeOrName ? addNames(names, from.names) : names;
|
|
32210
32393
|
}
|
|
32211
|
-
function optimizeExpr(expr, names,
|
|
32394
|
+
function optimizeExpr(expr, names, constants4) {
|
|
32212
32395
|
if (expr instanceof code_1.Name)
|
|
32213
32396
|
return replaceName(expr);
|
|
32214
32397
|
if (!canOptimize(expr))
|
|
@@ -32223,14 +32406,14 @@ var require_codegen = __commonJS({
|
|
|
32223
32406
|
return items;
|
|
32224
32407
|
}, []));
|
|
32225
32408
|
function replaceName(n3) {
|
|
32226
|
-
const c2 =
|
|
32409
|
+
const c2 = constants4[n3.str];
|
|
32227
32410
|
if (c2 === void 0 || names[n3.str] !== 1)
|
|
32228
32411
|
return n3;
|
|
32229
32412
|
delete names[n3.str];
|
|
32230
32413
|
return c2;
|
|
32231
32414
|
}
|
|
32232
32415
|
function canOptimize(e) {
|
|
32233
|
-
return e instanceof code_1._Code && e._items.some((c2) => c2 instanceof code_1.Name && names[c2.str] === 1 &&
|
|
32416
|
+
return e instanceof code_1._Code && e._items.some((c2) => c2 instanceof code_1.Name && names[c2.str] === 1 && constants4[c2.str] !== void 0);
|
|
32234
32417
|
}
|
|
32235
32418
|
}
|
|
32236
32419
|
function subtractNames(names, from) {
|
|
@@ -32306,11 +32489,11 @@ var require_util = __commonJS({
|
|
|
32306
32489
|
return false;
|
|
32307
32490
|
}
|
|
32308
32491
|
exports.schemaHasRules = schemaHasRules;
|
|
32309
|
-
function schemaHasRulesButRef(schema4,
|
|
32492
|
+
function schemaHasRulesButRef(schema4, RULES2) {
|
|
32310
32493
|
if (typeof schema4 == "boolean")
|
|
32311
32494
|
return !schema4;
|
|
32312
32495
|
for (const key in schema4)
|
|
32313
|
-
if (key !== "$ref" &&
|
|
32496
|
+
if (key !== "$ref" && RULES2.all[key])
|
|
32314
32497
|
return true;
|
|
32315
32498
|
return false;
|
|
32316
32499
|
}
|
|
@@ -33704,17 +33887,17 @@ var require_validate = __commonJS({
|
|
|
33704
33887
|
}
|
|
33705
33888
|
function schemaKeywords(it, types, typeErrors, errsCount) {
|
|
33706
33889
|
const { gen, schema: schema4, data, allErrors, opts, self } = it;
|
|
33707
|
-
const { RULES } = self;
|
|
33708
|
-
if (schema4.$ref && (opts.ignoreKeywordsWithRef || !(0, util_1.schemaHasRulesButRef)(schema4,
|
|
33709
|
-
gen.block(() => keywordCode(it, "$ref",
|
|
33890
|
+
const { RULES: RULES2 } = self;
|
|
33891
|
+
if (schema4.$ref && (opts.ignoreKeywordsWithRef || !(0, util_1.schemaHasRulesButRef)(schema4, RULES2))) {
|
|
33892
|
+
gen.block(() => keywordCode(it, "$ref", RULES2.all.$ref.definition));
|
|
33710
33893
|
return;
|
|
33711
33894
|
}
|
|
33712
33895
|
if (!opts.jtd)
|
|
33713
33896
|
checkStrictTypes(it, types);
|
|
33714
33897
|
gen.block(() => {
|
|
33715
|
-
for (const group of
|
|
33898
|
+
for (const group of RULES2.rules)
|
|
33716
33899
|
groupKeywords(group);
|
|
33717
|
-
groupKeywords(
|
|
33900
|
+
groupKeywords(RULES2.post);
|
|
33718
33901
|
});
|
|
33719
33902
|
function groupKeywords(group) {
|
|
33720
33903
|
if (!(0, applicability_1.shouldUseGroup)(schema4, group))
|
|
@@ -35529,10 +35712,10 @@ var require_core = __commonJS({
|
|
|
35529
35712
|
}
|
|
35530
35713
|
// Remove keyword
|
|
35531
35714
|
removeKeyword(keyword) {
|
|
35532
|
-
const { RULES } = this;
|
|
35533
|
-
delete
|
|
35534
|
-
delete
|
|
35535
|
-
for (const group of
|
|
35715
|
+
const { RULES: RULES2 } = this;
|
|
35716
|
+
delete RULES2.keywords[keyword];
|
|
35717
|
+
delete RULES2.all[keyword];
|
|
35718
|
+
for (const group of RULES2.rules) {
|
|
35536
35719
|
const i2 = group.rules.findIndex((rule) => rule.keyword === keyword);
|
|
35537
35720
|
if (i2 >= 0)
|
|
35538
35721
|
group.rules.splice(i2, 1);
|
|
@@ -35700,9 +35883,9 @@ var require_core = __commonJS({
|
|
|
35700
35883
|
}
|
|
35701
35884
|
var KEYWORD_NAME = /^[a-z_$][a-z0-9_$:-]*$/i;
|
|
35702
35885
|
function checkKeyword(keyword, def) {
|
|
35703
|
-
const { RULES } = this;
|
|
35886
|
+
const { RULES: RULES2 } = this;
|
|
35704
35887
|
(0, util_1.eachItem)(keyword, (kwd) => {
|
|
35705
|
-
if (
|
|
35888
|
+
if (RULES2.keywords[kwd])
|
|
35706
35889
|
throw new Error(`Keyword ${kwd} is already defined`);
|
|
35707
35890
|
if (!KEYWORD_NAME.test(kwd))
|
|
35708
35891
|
throw new Error(`Keyword ${kwd} has invalid name`);
|
|
@@ -35718,13 +35901,13 @@ var require_core = __commonJS({
|
|
|
35718
35901
|
const post = definition === null || definition === void 0 ? void 0 : definition.post;
|
|
35719
35902
|
if (dataType && post)
|
|
35720
35903
|
throw new Error('keyword with "post" flag cannot have "type"');
|
|
35721
|
-
const { RULES } = this;
|
|
35722
|
-
let ruleGroup = post ?
|
|
35904
|
+
const { RULES: RULES2 } = this;
|
|
35905
|
+
let ruleGroup = post ? RULES2.post : RULES2.rules.find(({ type: t2 }) => t2 === dataType);
|
|
35723
35906
|
if (!ruleGroup) {
|
|
35724
35907
|
ruleGroup = { type: dataType, rules: [] };
|
|
35725
|
-
|
|
35908
|
+
RULES2.rules.push(ruleGroup);
|
|
35726
35909
|
}
|
|
35727
|
-
|
|
35910
|
+
RULES2.keywords[keyword] = true;
|
|
35728
35911
|
if (!definition)
|
|
35729
35912
|
return;
|
|
35730
35913
|
const rule = {
|
|
@@ -35739,7 +35922,7 @@ var require_core = __commonJS({
|
|
|
35739
35922
|
addBeforeRule.call(this, ruleGroup, rule, definition.before);
|
|
35740
35923
|
else
|
|
35741
35924
|
ruleGroup.rules.push(rule);
|
|
35742
|
-
|
|
35925
|
+
RULES2.all[keyword] = rule;
|
|
35743
35926
|
(_a3 = definition.implements) === null || _a3 === void 0 ? void 0 : _a3.forEach((kwd) => this.addKeyword(kwd));
|
|
35744
35927
|
}
|
|
35745
35928
|
function addBeforeRule(ruleGroup, rule, before) {
|
|
@@ -38939,7 +39122,7 @@ var require_dist = __commonJS({
|
|
|
38939
39122
|
});
|
|
38940
39123
|
|
|
38941
39124
|
// server/drivers/chat-images.ts
|
|
38942
|
-
import { readFileSync as
|
|
39125
|
+
import { readFileSync as readFileSync15, statSync as statSync5 } from "node:fs";
|
|
38943
39126
|
function chatImageBudget() {
|
|
38944
39127
|
let used = 0;
|
|
38945
39128
|
return (parts) => {
|
|
@@ -38971,7 +39154,7 @@ function chatUserContent(turn) {
|
|
|
38971
39154
|
const budget = chatImageBudget();
|
|
38972
39155
|
return [{ type: "text", text: turn.text }, ...turn.images.map((image) => {
|
|
38973
39156
|
if (statSync5(image.path).size > IMAGE_BYTES) throw new Error("Image exceeds 20 MB");
|
|
38974
|
-
const part = chatImage({ mimeType: image.mime, data:
|
|
39157
|
+
const part = chatImage({ mimeType: image.mime, data: readFileSync15(image.path).toString("base64") });
|
|
38975
39158
|
budget([part]);
|
|
38976
39159
|
return part;
|
|
38977
39160
|
})];
|
|
@@ -39031,7 +39214,7 @@ function omitBlankDefaults(builtInBrowser, tool, args) {
|
|
|
39031
39214
|
if (typeof value === "string" && !value.trim()) delete args[field];
|
|
39032
39215
|
}
|
|
39033
39216
|
}
|
|
39034
|
-
async function mountChatTools(integrations, signal, computerUse = false, toolScope) {
|
|
39217
|
+
async function mountChatTools(integrations, signal, computerUse = false, toolScope, callTimeoutMs = DEFAULT_CALL_MS) {
|
|
39035
39218
|
const parsed = parseToolScope(toolScope);
|
|
39036
39219
|
if (!parsed.ok) throw new Error(parsed.error);
|
|
39037
39220
|
const scope = parsed.scope;
|
|
@@ -39135,7 +39318,7 @@ async function mountChatTools(integrations, signal, computerUse = false, toolSco
|
|
|
39135
39318
|
}
|
|
39136
39319
|
const tool = registered.get(name);
|
|
39137
39320
|
try {
|
|
39138
|
-
const result = await tool.client.call("tools/call", { name: tool.name, arguments: args }, AbortSignal.any([signal, callSignal]),
|
|
39321
|
+
const result = await tool.client.call("tools/call", { name: tool.name, arguments: args }, AbortSignal.any([signal, callSignal]), callTimeoutMs);
|
|
39139
39322
|
if (signal.aborted || callSignal.aborted) throw aborted2();
|
|
39140
39323
|
if (!object3(result) || !Array.isArray(result.content) || result.isError !== void 0 && typeof result.isError !== "boolean") throw new Error("MCP tool returned an invalid result; execution outcome may be uncertain");
|
|
39141
39324
|
const parts = [];
|
|
@@ -39161,7 +39344,7 @@ async function mountChatTools(integrations, signal, computerUse = false, toolSco
|
|
|
39161
39344
|
}
|
|
39162
39345
|
};
|
|
39163
39346
|
}
|
|
39164
|
-
var import_ajv, import__, import_ajv_formats, ChatToolSessionError, STARTUP_MS,
|
|
39347
|
+
var import_ajv, import__, import_ajv_formats, ChatToolSessionError, STARTUP_MS, DEFAULT_CALL_MS, FRAME_BYTES, OUTPUT_BYTES, TOOL_COUNT, MAX_PAGES, SCHEMA_BYTES, CATALOG_BYTES, MAX_FRAMES, ChatMcpClient, validatorOptions, BUILT_IN_BROWSER_BLANK_MEANS_OMITTED;
|
|
39165
39348
|
var init_chat_mcp_tools = __esm({
|
|
39166
39349
|
"server/drivers/chat-mcp-tools.ts"() {
|
|
39167
39350
|
"use strict";
|
|
@@ -39177,7 +39360,7 @@ var init_chat_mcp_tools = __esm({
|
|
|
39177
39360
|
ChatToolSessionError = class extends Error {
|
|
39178
39361
|
};
|
|
39179
39362
|
STARTUP_MS = 8e3;
|
|
39180
|
-
|
|
39363
|
+
DEFAULT_CALL_MS = 10 * 6e4;
|
|
39181
39364
|
FRAME_BYTES = 2 * 1024 * 1024;
|
|
39182
39365
|
OUTPUT_BYTES = 50 * 1024;
|
|
39183
39366
|
TOOL_COUNT = 128;
|
|
@@ -39603,7 +39786,7 @@ function writeTurnHandoff(input) {
|
|
|
39603
39786
|
function classifyContinuable(_stopReason, failure) {
|
|
39604
39787
|
if (!failure) return null;
|
|
39605
39788
|
if (NOT_RESUMABLE.test(failure)) return null;
|
|
39606
|
-
if (/
|
|
39789
|
+
if (/stopped after \d+ steps without a final answer|model-call limit reached/i.test(failure)) return "cap";
|
|
39607
39790
|
return null;
|
|
39608
39791
|
}
|
|
39609
39792
|
var NOT_RESUMABLE;
|
|
@@ -39614,6 +39797,41 @@ var init_turn_continuation = __esm({
|
|
|
39614
39797
|
}
|
|
39615
39798
|
});
|
|
39616
39799
|
|
|
39800
|
+
// server/key-rejections.ts
|
|
39801
|
+
import { createHash as createHash12 } from "node:crypto";
|
|
39802
|
+
function keyRejected(url2, key) {
|
|
39803
|
+
return rejected.size > 0 && rejected.has(markOf(url2, key));
|
|
39804
|
+
}
|
|
39805
|
+
function noteKeyRejected(url2, key) {
|
|
39806
|
+
const mark = markOf(url2, key);
|
|
39807
|
+
if (rejected.has(mark)) return;
|
|
39808
|
+
rejected.add(mark);
|
|
39809
|
+
changed();
|
|
39810
|
+
}
|
|
39811
|
+
function noteKeyAccepted(url2, key) {
|
|
39812
|
+
if (rejected.size > 0 && rejected.delete(markOf(url2, key))) changed();
|
|
39813
|
+
}
|
|
39814
|
+
function rejectsKey(status, body) {
|
|
39815
|
+
if (/\b(?:quota|billing|credits?|rate.?limit|insufficient.?(?:balance|funds))\b/i.test(body)) return false;
|
|
39816
|
+
if (status === 401) return true;
|
|
39817
|
+
if (status !== 400 && status !== 403) return false;
|
|
39818
|
+
return /\binvalid_api_key\b|\b(?:invalid|incorrect|revoked|expired|disabled|deactivated)[ _-]?(?:api[ _-]?)?key\b|\bapi[ _-]?key (?:is |was |has been )?(?:invalid|incorrect|revoked|expired|disabled|not valid)\b/i.test(body);
|
|
39819
|
+
}
|
|
39820
|
+
var KEY_REJECTED_REASON, rejected, listeners, fingerprint, markOf, changed;
|
|
39821
|
+
var init_key_rejections = __esm({
|
|
39822
|
+
"server/key-rejections.ts"() {
|
|
39823
|
+
"use strict";
|
|
39824
|
+
KEY_REJECTED_REASON = "The provider rejected this key. Change it in Settings \u2192 API keys.";
|
|
39825
|
+
rejected = /* @__PURE__ */ new Set();
|
|
39826
|
+
listeners = /* @__PURE__ */ new Set();
|
|
39827
|
+
fingerprint = (key) => createHash12("sha256").update(key.trim()).digest("hex").slice(0, 32);
|
|
39828
|
+
markOf = (url2, key) => `${url2.trim().replace(/\/+$/, "")} ${fingerprint(key)}`;
|
|
39829
|
+
changed = () => {
|
|
39830
|
+
for (const listener of listeners) listener();
|
|
39831
|
+
};
|
|
39832
|
+
}
|
|
39833
|
+
});
|
|
39834
|
+
|
|
39617
39835
|
// server/drivers/openai-chat.ts
|
|
39618
39836
|
function providerError(json2) {
|
|
39619
39837
|
if (typeof json2.error === "string") return json2.error;
|
|
@@ -39679,11 +39897,11 @@ function refusedToolCallFailure(error51, earlierSteps) {
|
|
|
39679
39897
|
}
|
|
39680
39898
|
function createOpenAIChatRuntime(options) {
|
|
39681
39899
|
const { input } = options;
|
|
39682
|
-
const
|
|
39900
|
+
const listeners2 = /* @__PURE__ */ new Set();
|
|
39683
39901
|
const active = /* @__PURE__ */ new Map();
|
|
39684
39902
|
const reasoningReplayRejected = /* @__PURE__ */ new Set();
|
|
39685
39903
|
const emit = (event) => {
|
|
39686
|
-
for (const listener of Array.from(
|
|
39904
|
+
for (const listener of Array.from(listeners2)) listener(event);
|
|
39687
39905
|
};
|
|
39688
39906
|
const base2 = (threadId, turnId) => ({
|
|
39689
39907
|
eventId: newEventId(),
|
|
@@ -39716,6 +39934,7 @@ function createOpenAIChatRuntime(options) {
|
|
|
39716
39934
|
});
|
|
39717
39935
|
if (!response.ok) {
|
|
39718
39936
|
const body = await response.text().catch(() => "");
|
|
39937
|
+
if (rejectsKey(response.status, body)) noteKeyRejected(options.apiUrl, options.apiKey);
|
|
39719
39938
|
const message3 = `${options.httpErrorLabel} HTTP ${response.status}${body ? `: ${body.slice(0, 200)}` : ""}`;
|
|
39720
39939
|
if (rejectsToolsParameter(response.status, body)) throw new UnsupportedChatToolsError(message3);
|
|
39721
39940
|
const refusal = refusedToolCall(response.status, body);
|
|
@@ -39725,6 +39944,7 @@ function createOpenAIChatRuntime(options) {
|
|
|
39725
39944
|
}
|
|
39726
39945
|
throw new Error(message3);
|
|
39727
39946
|
}
|
|
39947
|
+
noteKeyAccepted(options.apiUrl, options.apiKey);
|
|
39728
39948
|
if (!stream || response.headers.get("content-type")?.includes("application/json")) {
|
|
39729
39949
|
const json2 = await response.json();
|
|
39730
39950
|
if (onUsage) {
|
|
@@ -39963,7 +40183,7 @@ ${TEXT_ONLY_ATTACHMENT_NOTE}` : userTurn.text }
|
|
|
39963
40183
|
const parsed = parseToolScope(turn.toolScope);
|
|
39964
40184
|
if (!parsed.ok) throw new Error(parsed.error);
|
|
39965
40185
|
const scope = parsed.scope;
|
|
39966
|
-
tools = await mountChatTools(options.tools === false ? void 0 : turn.integrations, abort.signal, options.computerUse, scope);
|
|
40186
|
+
tools = await mountChatTools(options.tools === false ? void 0 : turn.integrations, abort.signal, options.computerUse, scope, turn.mcpCallTimeoutMs);
|
|
39967
40187
|
const questionAllowed = options.tools !== false && allowsTool(scope, { kind: "native", name: ASK_USER_TOOL });
|
|
39968
40188
|
let optionalQuestionOnly = questionAllowed && tools.definitions.length === 0;
|
|
39969
40189
|
if (questionAllowed && !tools.definitions.some((definition) => definition.function.name === ASK_USER_TOOL)) {
|
|
@@ -40225,7 +40445,11 @@ ${TEXT_ONLY_SCREENSHOT_NOTE}` };
|
|
|
40225
40445
|
return options.models();
|
|
40226
40446
|
},
|
|
40227
40447
|
...options.refreshModels ? { refreshModels: options.refreshModels } : {},
|
|
40228
|
-
snapshot: async () =>
|
|
40448
|
+
snapshot: async () => {
|
|
40449
|
+
if (!options.apiKey) return { state: "unavailable", reason: options.unavailableReason };
|
|
40450
|
+
if (keyRejected(options.apiUrl, options.apiKey)) return { state: "available", authenticated: false, reason: KEY_REJECTED_REASON, version: null };
|
|
40451
|
+
return { state: "available", authenticated: true, version: null, ...options.billing ? { billing: options.billing } : {} };
|
|
40452
|
+
},
|
|
40229
40453
|
adapter: {
|
|
40230
40454
|
provider: options.driverKind,
|
|
40231
40455
|
capabilities: {
|
|
@@ -40269,8 +40493,8 @@ ${TEXT_ONLY_SCREENSHOT_NOTE}` };
|
|
|
40269
40493
|
await Promise.all(turns.map((turn) => turn.done));
|
|
40270
40494
|
},
|
|
40271
40495
|
onEvent: (listener) => {
|
|
40272
|
-
|
|
40273
|
-
return () =>
|
|
40496
|
+
listeners2.add(listener);
|
|
40497
|
+
return () => listeners2.delete(listener);
|
|
40274
40498
|
}
|
|
40275
40499
|
},
|
|
40276
40500
|
generateText: async (prompt, { signal, onUsage } = {}) => {
|
|
@@ -40283,7 +40507,7 @@ ${TEXT_ONLY_SCREENSHOT_NOTE}` };
|
|
|
40283
40507
|
const turns = [...active.values()];
|
|
40284
40508
|
for (const turn of turns) turn.abort.abort();
|
|
40285
40509
|
await Promise.all(turns.map((turn) => turn.done));
|
|
40286
|
-
|
|
40510
|
+
listeners2.clear();
|
|
40287
40511
|
}
|
|
40288
40512
|
};
|
|
40289
40513
|
}
|
|
@@ -40304,6 +40528,7 @@ var init_openai_chat = __esm({
|
|
|
40304
40528
|
init_native();
|
|
40305
40529
|
init_retry();
|
|
40306
40530
|
init_turn_continuation();
|
|
40531
|
+
init_key_rejections();
|
|
40307
40532
|
usageFrom = (usage) => usage ? { input: usage.prompt_tokens ?? 0, output: usage.completion_tokens ?? 0 } : null;
|
|
40308
40533
|
asError = (value) => value instanceof Error ? value : new Error(String(value));
|
|
40309
40534
|
UnsupportedChatToolsError = class extends Error {
|
|
@@ -47234,9 +47459,26 @@ var init_browser = __esm({
|
|
|
47234
47459
|
});
|
|
47235
47460
|
|
|
47236
47461
|
// server/drivers/acp/grok.ts
|
|
47237
|
-
import { existsSync as existsSync10, readFileSync as
|
|
47462
|
+
import { existsSync as existsSync10, readFileSync as readFileSync16, writeFileSync as writeFileSync9 } from "node:fs";
|
|
47238
47463
|
import { dirname as dirname13, join as join32, resolve as resolve10 } from "node:path";
|
|
47239
47464
|
import { setTimeout as delay2 } from "node:timers/promises";
|
|
47465
|
+
function grokHome(env = process.env) {
|
|
47466
|
+
return env.GROK_HOME || harnessHome("grok", env);
|
|
47467
|
+
}
|
|
47468
|
+
function grokSignedIn(env) {
|
|
47469
|
+
return existsSync10(join32(grokHome(env), "auth.json"));
|
|
47470
|
+
}
|
|
47471
|
+
function grokLoginFailure(output) {
|
|
47472
|
+
if (/(unexpected argument|unrecognized (argument|option)|unknown option).*device-(auth|code)/i.test(output)) {
|
|
47473
|
+
return "This server's Grok is too old to sign in with a code. Update Grok on the server, then try again.";
|
|
47474
|
+
}
|
|
47475
|
+
if (/device-code login is not available/i.test(output)) {
|
|
47476
|
+
return "This Grok account can't sign in with a code. Use an xAI API key instead.";
|
|
47477
|
+
}
|
|
47478
|
+
if (/expired/i.test(output)) return "The Grok sign-in code expired. Start sign-in again for a new code.";
|
|
47479
|
+
if (/denied|rejected/i.test(output)) return "Grok sign-in was declined in the browser. Start sign-in again to try once more.";
|
|
47480
|
+
return "Grok sign-in did not finish. Check the server's connection, then try again.";
|
|
47481
|
+
}
|
|
47240
47482
|
function unquote2(raw) {
|
|
47241
47483
|
const value = raw.trim();
|
|
47242
47484
|
if (value.length >= 2 && value.startsWith('"') && value.endsWith('"')) {
|
|
@@ -47245,10 +47487,10 @@ function unquote2(raw) {
|
|
|
47245
47487
|
return value;
|
|
47246
47488
|
}
|
|
47247
47489
|
function readGrokModelCatalog(env = process.env) {
|
|
47248
|
-
const path3 = join32(
|
|
47490
|
+
const path3 = join32(grokHome(env), "config.toml");
|
|
47249
47491
|
let text4 = "";
|
|
47250
47492
|
try {
|
|
47251
|
-
text4 =
|
|
47493
|
+
text4 = readFileSync16(path3, "utf8");
|
|
47252
47494
|
} catch {
|
|
47253
47495
|
return STATIC_GROK_MODELS;
|
|
47254
47496
|
}
|
|
@@ -47318,10 +47560,10 @@ function ensureGrokInjectSlug(modelId, env = process.env) {
|
|
|
47318
47560
|
if (!inject) return modelId;
|
|
47319
47561
|
const host = localHost(inject.host);
|
|
47320
47562
|
if (!host) return modelId;
|
|
47321
|
-
const path3 = join32(
|
|
47563
|
+
const path3 = join32(grokHome(env), "config.toml");
|
|
47322
47564
|
let text4 = "";
|
|
47323
47565
|
try {
|
|
47324
|
-
text4 =
|
|
47566
|
+
text4 = readFileSync16(path3, "utf8");
|
|
47325
47567
|
} catch {
|
|
47326
47568
|
text4 = "";
|
|
47327
47569
|
}
|
|
@@ -47393,7 +47635,7 @@ function grokInheritedProfile(cli, env, cwd) {
|
|
|
47393
47635
|
const flag = flags[0] ?? -1;
|
|
47394
47636
|
let path3 = flag >= 0 ? args[flag].includes("=") ? args[flag].slice(args[flag].indexOf("=") + 1) : args[flag + 1] : void 0;
|
|
47395
47637
|
if (flag >= 0 && (!path3 || path3.startsWith("-"))) return unsupported();
|
|
47396
|
-
const files = [join32(
|
|
47638
|
+
const files = [join32(grokHome(env), "config.toml")];
|
|
47397
47639
|
for (let directory = resolve10(cwd); ; ) {
|
|
47398
47640
|
const file2 = join32(directory, ".grok", "config.toml");
|
|
47399
47641
|
if (!files.includes(file2)) files.push(file2);
|
|
@@ -47403,7 +47645,7 @@ function grokInheritedProfile(cli, env, cwd) {
|
|
|
47403
47645
|
}
|
|
47404
47646
|
for (const file2 of files) {
|
|
47405
47647
|
if (!existsSync10(file2)) continue;
|
|
47406
|
-
const text5 =
|
|
47648
|
+
const text5 = readFileSync16(file2, "utf8");
|
|
47407
47649
|
if (text5.length > 262144) return unsupported();
|
|
47408
47650
|
let section = "";
|
|
47409
47651
|
for (const line of text5.split(/\r?\n/).map((line2) => line2.trim()).filter((line2) => line2 && !line2.startsWith("#"))) {
|
|
@@ -47433,7 +47675,7 @@ function grokInheritedProfile(cli, env, cwd) {
|
|
|
47433
47675
|
}
|
|
47434
47676
|
}
|
|
47435
47677
|
if (!path3) return;
|
|
47436
|
-
const text4 =
|
|
47678
|
+
const text4 = readFileSync16(resolve10(cwd, path3), "utf8");
|
|
47437
47679
|
if (text4.length > 262144) return unsupported();
|
|
47438
47680
|
const match = /^\s*---\r?\n([\s\S]*?)\r?\n---(?:\r?\n([\s\S]*))?$/.exec(text4);
|
|
47439
47681
|
if (!match) return unsupported();
|
|
@@ -47469,7 +47711,7 @@ function grokToolScopeProfile(scope, init, inherited, hasMcp = false) {
|
|
|
47469
47711
|
disallowedTools: [.../* @__PURE__ */ new Set([...inherited?.disallowedTools ?? [], ...selected.length ? [] : ["read_file"]])]
|
|
47470
47712
|
};
|
|
47471
47713
|
}
|
|
47472
|
-
var STATIC_GROK_MODELS, SLUG, GROK_NATIVE_TOOLS, support2, GrokAgentDriver;
|
|
47714
|
+
var STATIC_GROK_MODELS, SLUG, GROK_DEVICE_SIGN_IN, GROK_NATIVE_TOOLS, support2, GrokAgentDriver;
|
|
47473
47715
|
var init_grok2 = __esm({
|
|
47474
47716
|
"server/drivers/acp/grok.ts"() {
|
|
47475
47717
|
"use strict";
|
|
@@ -47487,6 +47729,17 @@ var init_grok2 = __esm({
|
|
|
47487
47729
|
]
|
|
47488
47730
|
};
|
|
47489
47731
|
SLUG = /^[a-z0-9][a-z0-9._-]*$/i;
|
|
47732
|
+
GROK_DEVICE_SIGN_IN = {
|
|
47733
|
+
provider: "grok",
|
|
47734
|
+
product: "Grok",
|
|
47735
|
+
account: "Grok",
|
|
47736
|
+
homeEnv: "GROK_HOME",
|
|
47737
|
+
homeDir: ".grok",
|
|
47738
|
+
loginArgs: ["login", "--device-auth"],
|
|
47739
|
+
install: "Install it with xAI's installer (https://x.ai/cli), then try again.",
|
|
47740
|
+
failure: grokLoginFailure,
|
|
47741
|
+
signedIn: grokSignedIn
|
|
47742
|
+
};
|
|
47490
47743
|
GROK_NATIVE_TOOLS = [
|
|
47491
47744
|
["read_file", "GrokBuild:read_file"],
|
|
47492
47745
|
["search_replace", "GrokBuild:search_replace"],
|
|
@@ -47527,7 +47780,7 @@ var init_grok2 = __esm({
|
|
|
47527
47780
|
effortLevels: ["low", "medium", "high"],
|
|
47528
47781
|
defaultCli: "grok",
|
|
47529
47782
|
nativeSource: "grok.acp",
|
|
47530
|
-
loginNote: "Grok
|
|
47783
|
+
loginNote: "Grok is not signed in to your grok.com account \u2014 choose Sign in to Grok in engine setup",
|
|
47531
47784
|
// No Windows one-liner: the installer is a POSIX shell script, and offering
|
|
47532
47785
|
// `curl … | bash` there would be advice that cannot run. Windows falls back
|
|
47533
47786
|
// to docsUrl, which is honest rather than broken.
|
|
@@ -47537,8 +47790,11 @@ var init_grok2 = __esm({
|
|
|
47537
47790
|
linux: "curl -fsSL https://x.ai/cli/install.sh | bash"
|
|
47538
47791
|
},
|
|
47539
47792
|
docsUrl: "https://x.ai/cli",
|
|
47793
|
+
// The terminal route, for people who prefer it; the app's own sign-in
|
|
47794
|
+
// is the device code below, which needs no terminal.
|
|
47540
47795
|
signInCommand: "grok login"
|
|
47541
47796
|
},
|
|
47797
|
+
deviceSignIn: GROK_DEVICE_SIGN_IN,
|
|
47542
47798
|
// Write the [model.slug] block with the instance HOME/GROK_HOME, then pass
|
|
47543
47799
|
// the slug on argv. spawnArgs must not call ensureGrokInjectSlug itself —
|
|
47544
47800
|
// that helper defaults to process.env and would miss the instance override.
|
|
@@ -47639,7 +47895,7 @@ var init_grok2 = __esm({
|
|
|
47639
47895
|
// an unauthenticated CLI is a user action, not something to paper over.
|
|
47640
47896
|
pickAuthMethod: (methods) => methods.some((m2) => m2.id === "cached_token") ? "cached_token" : null,
|
|
47641
47897
|
authFailure: "fail",
|
|
47642
|
-
isAuthenticated: (env) =>
|
|
47898
|
+
isAuthenticated: (env) => grokSignedIn(env),
|
|
47643
47899
|
// `--append-system-prompt`/`--rules` are accepted by the CLI but do NOT
|
|
47644
47900
|
// reach the agent-stdio system prompt (verified against 1.0.0), so the
|
|
47645
47901
|
// persona is prepended codex-style.
|
|
@@ -47652,11 +47908,11 @@ ${turn.text}` : turn.text
|
|
|
47652
47908
|
});
|
|
47653
47909
|
|
|
47654
47910
|
// server/drivers/acp/gemini.ts
|
|
47655
|
-
import { existsSync as existsSync11, readFileSync as
|
|
47911
|
+
import { existsSync as existsSync11, readFileSync as readFileSync17 } from "node:fs";
|
|
47656
47912
|
import { join as join33 } from "node:path";
|
|
47657
47913
|
function liveOauthCredential(env) {
|
|
47658
47914
|
try {
|
|
47659
|
-
const creds = JSON.parse(
|
|
47915
|
+
const creds = JSON.parse(readFileSync17(join33(userHome(env), ".gemini", "oauth_creds.json"), "utf8"));
|
|
47660
47916
|
if (typeof creds.access_token !== "string" || creds.access_token.trim().length === 0) return false;
|
|
47661
47917
|
const hasRefresh = typeof creds.refresh_token === "string" && creds.refresh_token.trim().length > 0;
|
|
47662
47918
|
if (creds.expiry_date !== void 0) {
|
|
@@ -47717,7 +47973,7 @@ ${turn.text}` : turn.text
|
|
|
47717
47973
|
});
|
|
47718
47974
|
|
|
47719
47975
|
// server/drivers/acp/kimi.ts
|
|
47720
|
-
import { existsSync as existsSync12, mkdirSync as mkdirSync16, readFileSync as
|
|
47976
|
+
import { existsSync as existsSync12, mkdirSync as mkdirSync16, readFileSync as readFileSync18, writeFileSync as writeFileSync10 } from "node:fs";
|
|
47721
47977
|
import { homedir as homedir16 } from "node:os";
|
|
47722
47978
|
import { join as join34 } from "node:path";
|
|
47723
47979
|
function isLocalInjectAlias(slug) {
|
|
@@ -48018,7 +48274,7 @@ function ensureKimiInjectAlias(modelId, env = process.env) {
|
|
|
48018
48274
|
const path3 = join34(dataRoot, "config.toml");
|
|
48019
48275
|
let text4 = "";
|
|
48020
48276
|
try {
|
|
48021
|
-
text4 =
|
|
48277
|
+
text4 = readFileSync18(path3, "utf8");
|
|
48022
48278
|
} catch {
|
|
48023
48279
|
text4 = "";
|
|
48024
48280
|
}
|
|
@@ -48080,7 +48336,7 @@ function readKimiModelCatalog(env) {
|
|
|
48080
48336
|
const dataRoot = kimiDataRoot(env);
|
|
48081
48337
|
let text4 = "";
|
|
48082
48338
|
try {
|
|
48083
|
-
text4 =
|
|
48339
|
+
text4 = readFileSync18(join34(dataRoot, "config.toml"), "utf8");
|
|
48084
48340
|
} catch {
|
|
48085
48341
|
return STATIC_KIMI_MODELS;
|
|
48086
48342
|
}
|
|
@@ -48199,7 +48455,7 @@ ${turn.text}` : turn.text
|
|
|
48199
48455
|
});
|
|
48200
48456
|
|
|
48201
48457
|
// server/drivers/acp/droid.ts
|
|
48202
|
-
import { existsSync as existsSync13, mkdirSync as mkdirSync17, readFileSync as
|
|
48458
|
+
import { existsSync as existsSync13, mkdirSync as mkdirSync17, readFileSync as readFileSync19, writeFileSync as writeFileSync11 } from "node:fs";
|
|
48203
48459
|
import { join as join35 } from "node:path";
|
|
48204
48460
|
function authFilePaths(env) {
|
|
48205
48461
|
const home = env.FACTORY_HOME_OVERRIDE || userHome(env);
|
|
@@ -48220,7 +48476,7 @@ function ensureDroidInjectModel(modelId, env = process.env) {
|
|
|
48220
48476
|
const path3 = join35(dir, "settings.json");
|
|
48221
48477
|
let settings2 = {};
|
|
48222
48478
|
try {
|
|
48223
|
-
settings2 = JSON.parse(
|
|
48479
|
+
settings2 = JSON.parse(readFileSync19(path3, "utf8"));
|
|
48224
48480
|
} catch (error51) {
|
|
48225
48481
|
if (existsSync13(path3)) throw error51;
|
|
48226
48482
|
}
|
|
@@ -48257,7 +48513,7 @@ function applyDroidLocalAuthEnv(env, modelId) {
|
|
|
48257
48513
|
env.FACTORY_API_KEY = "openmausbot-local";
|
|
48258
48514
|
}
|
|
48259
48515
|
function readSettings(env) {
|
|
48260
|
-
return JSON.parse(
|
|
48516
|
+
return JSON.parse(readFileSync19(join35(env.FACTORY_HOME_OVERRIDE || userHome(env), ".factory", "settings.json"), "utf8"));
|
|
48261
48517
|
}
|
|
48262
48518
|
async function resolveModels(env) {
|
|
48263
48519
|
let catalog = MODELS2;
|
|
@@ -48716,7 +48972,7 @@ var init_attachments = __esm({
|
|
|
48716
48972
|
|
|
48717
48973
|
// server/drivers/acp/opencode-go.ts
|
|
48718
48974
|
import { execFile as execFile5 } from "node:child_process";
|
|
48719
|
-
import { existsSync as existsSync14, mkdirSync as mkdirSync18, readFileSync as
|
|
48975
|
+
import { existsSync as existsSync14, mkdirSync as mkdirSync18, readFileSync as readFileSync20, statSync as statSync6, writeFileSync as writeFileSync12 } from "node:fs";
|
|
48720
48976
|
import { homedir as homedir17 } from "node:os";
|
|
48721
48977
|
import { dirname as dirname14, isAbsolute as isAbsolute9, join as join37, relative as relative2, resolve as resolvePath, sep } from "node:path";
|
|
48722
48978
|
function labelForModel(id) {
|
|
@@ -49035,7 +49291,7 @@ function ensureOpenCodeInjectModel(modelId, env = process.env) {
|
|
|
49035
49291
|
let config2 = { $schema: "https://opencode.ai/config.json" };
|
|
49036
49292
|
if (existsSync14(path3)) {
|
|
49037
49293
|
try {
|
|
49038
|
-
config2 = JSON.parse(
|
|
49294
|
+
config2 = JSON.parse(readFileSync20(path3, "utf8"));
|
|
49039
49295
|
} catch {
|
|
49040
49296
|
}
|
|
49041
49297
|
}
|
|
@@ -49086,7 +49342,7 @@ function hasStoredOpenCodeAuth(env) {
|
|
|
49086
49342
|
if (env.OPENCODE_AUTH_CONTENT) candidates.push(env.OPENCODE_AUTH_CONTENT);
|
|
49087
49343
|
for (const path3 of storedAuthPaths(env)) {
|
|
49088
49344
|
try {
|
|
49089
|
-
candidates.push(
|
|
49345
|
+
candidates.push(readFileSync20(path3, "utf8"));
|
|
49090
49346
|
} catch {
|
|
49091
49347
|
}
|
|
49092
49348
|
}
|
|
@@ -49139,7 +49395,7 @@ function parseJsonc(text4) {
|
|
|
49139
49395
|
}
|
|
49140
49396
|
function readText2(path3) {
|
|
49141
49397
|
try {
|
|
49142
|
-
return
|
|
49398
|
+
return readFileSync20(path3, "utf8");
|
|
49143
49399
|
} catch {
|
|
49144
49400
|
return void 0;
|
|
49145
49401
|
}
|
|
@@ -49371,8 +49627,8 @@ ${turn.text}` : turn.text
|
|
|
49371
49627
|
});
|
|
49372
49628
|
|
|
49373
49629
|
// server/drivers/acp/qwen.ts
|
|
49374
|
-
import { chmodSync as chmodSync6, existsSync as existsSync15, mkdirSync as mkdirSync19, readFileSync as
|
|
49375
|
-
import { createHash as
|
|
49630
|
+
import { chmodSync as chmodSync6, existsSync as existsSync15, mkdirSync as mkdirSync19, readFileSync as readFileSync21, writeFileSync as writeFileSync13 } from "node:fs";
|
|
49631
|
+
import { createHash as createHash13 } from "node:crypto";
|
|
49376
49632
|
import { join as join38 } from "node:path";
|
|
49377
49633
|
function isRecord3(value) {
|
|
49378
49634
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
@@ -49380,7 +49636,7 @@ function isRecord3(value) {
|
|
|
49380
49636
|
function readQwenRoutes(env) {
|
|
49381
49637
|
let settings2;
|
|
49382
49638
|
try {
|
|
49383
|
-
settings2 = JSON.parse(
|
|
49639
|
+
settings2 = JSON.parse(readFileSync21(join38(harnessHome("qwen", env), "settings.json"), "utf8"));
|
|
49384
49640
|
} catch {
|
|
49385
49641
|
return [];
|
|
49386
49642
|
}
|
|
@@ -49438,7 +49694,7 @@ function readQwenRoutes(env) {
|
|
|
49438
49694
|
}
|
|
49439
49695
|
}
|
|
49440
49696
|
const identity = [route.id, route.label, route.envKey ?? null, route.baseUrl === void 0, publicEndpoint];
|
|
49441
|
-
route.id = `qwen-route:v1:${
|
|
49697
|
+
route.id = `qwen-route:v1:${createHash13("sha256").update(JSON.stringify(identity)).digest("base64url").slice(0, 16)}`;
|
|
49442
49698
|
}
|
|
49443
49699
|
if (new Set(routes.map((route) => route.id)).size !== routes.length) {
|
|
49444
49700
|
throw new Error("Qwen has indistinguishable model routes. Give them distinct names, envKey values, or public endpoints in Qwen settings.");
|
|
@@ -49470,7 +49726,7 @@ function ensureQwenInjectModel(modelId, env = process.env) {
|
|
|
49470
49726
|
let settings2 = {};
|
|
49471
49727
|
if (existsSync15(path3)) {
|
|
49472
49728
|
try {
|
|
49473
|
-
settings2 = JSON.parse(
|
|
49729
|
+
settings2 = JSON.parse(readFileSync21(path3, "utf8"));
|
|
49474
49730
|
} catch {
|
|
49475
49731
|
}
|
|
49476
49732
|
}
|
|
@@ -49647,7 +49903,7 @@ var init_custom = __esm({
|
|
|
49647
49903
|
|
|
49648
49904
|
// server/drivers/acp/hermes.ts
|
|
49649
49905
|
import { spawn as spawn6 } from "node:child_process";
|
|
49650
|
-
import { mkdirSync as mkdirSync20, readFileSync as
|
|
49906
|
+
import { mkdirSync as mkdirSync20, readFileSync as readFileSync22, writeFileSync as writeFileSync14 } from "node:fs";
|
|
49651
49907
|
import { homedir as homedir18 } from "node:os";
|
|
49652
49908
|
import { join as join39 } from "node:path";
|
|
49653
49909
|
function bindHermesScreenshotCompat(env, modelId) {
|
|
@@ -49701,7 +49957,7 @@ function ensureHermesInjectProvider(modelId, env = process.env) {
|
|
|
49701
49957
|
const path3 = join39(dir, "config.yaml");
|
|
49702
49958
|
let text4 = "";
|
|
49703
49959
|
try {
|
|
49704
|
-
text4 =
|
|
49960
|
+
text4 = readFileSync22(path3, "utf8");
|
|
49705
49961
|
} catch {
|
|
49706
49962
|
text4 = "";
|
|
49707
49963
|
}
|
|
@@ -49769,13 +50025,13 @@ function hermesConfiguredModel(env = process.env) {
|
|
|
49769
50025
|
const dir = env.HERMES_HOME || harnessHome("hermes", env);
|
|
49770
50026
|
let secrets = "";
|
|
49771
50027
|
try {
|
|
49772
|
-
secrets =
|
|
50028
|
+
secrets = readFileSync22(join39(dir, ".env"), "utf8");
|
|
49773
50029
|
} catch {
|
|
49774
50030
|
}
|
|
49775
50031
|
const hasHostedProviderKey = HERMES_HOSTED_PROVIDER_KEYS.some((name) => nonEmptyDotenvValue(secrets, name));
|
|
49776
50032
|
let configuredDefault = null;
|
|
49777
50033
|
try {
|
|
49778
|
-
configuredDefault = hermesConfigDefault(
|
|
50034
|
+
configuredDefault = hermesConfigDefault(readFileSync22(join39(dir, "config.yaml"), "utf8"));
|
|
49779
50035
|
} catch {
|
|
49780
50036
|
}
|
|
49781
50037
|
const configuredProvider = configuredDefault?.provider.toLowerCase() ?? "";
|
|
@@ -50150,13 +50406,13 @@ var init_openai_compat = __esm({
|
|
|
50150
50406
|
});
|
|
50151
50407
|
|
|
50152
50408
|
// server/drivers/pi.ts
|
|
50153
|
-
import { chmodSync as chmodSync7, existsSync as existsSync16, mkdirSync as mkdirSync21, mkdtempSync as mkdtempSync3, readFileSync as
|
|
50409
|
+
import { chmodSync as chmodSync7, existsSync as existsSync16, mkdirSync as mkdirSync21, mkdtempSync as mkdtempSync3, readFileSync as readFileSync23, rmSync as rmSync7, writeFileSync as writeFileSync15 } from "node:fs";
|
|
50154
50410
|
import { homedir as homedir19, tmpdir as tmpdir4 } from "node:os";
|
|
50155
50411
|
import { join as join40 } from "node:path";
|
|
50156
50412
|
function readPiPromptImages(turn) {
|
|
50157
50413
|
return (turn.images ?? []).map((image) => ({
|
|
50158
50414
|
type: "image",
|
|
50159
|
-
data:
|
|
50415
|
+
data: readFileSync23(image.path).toString("base64"),
|
|
50160
50416
|
mimeType: image.mime
|
|
50161
50417
|
}));
|
|
50162
50418
|
}
|
|
@@ -50304,7 +50560,7 @@ function ensurePiInjectModel(modelId, env = process.env) {
|
|
|
50304
50560
|
let root = { providers: {} };
|
|
50305
50561
|
if (existsSync16(path3)) {
|
|
50306
50562
|
try {
|
|
50307
|
-
const parsed = JSON.parse(
|
|
50563
|
+
const parsed = JSON.parse(readFileSync23(path3, "utf8"));
|
|
50308
50564
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
50309
50565
|
root = parsed;
|
|
50310
50566
|
} else {
|
|
@@ -50356,7 +50612,7 @@ function ensurePiInjectModel(modelId, env = process.env) {
|
|
|
50356
50612
|
function readPiDefaultModel(env) {
|
|
50357
50613
|
const home = env.HOME || env.USERPROFILE || homedir19();
|
|
50358
50614
|
try {
|
|
50359
|
-
const s2 = JSON.parse(
|
|
50615
|
+
const s2 = JSON.parse(readFileSync23(`${home}/.pi/agent/settings.json`, "utf8"));
|
|
50360
50616
|
return s2.defaultProvider && s2.defaultModel ? `${s2.defaultProvider}/${s2.defaultModel}` : "";
|
|
50361
50617
|
} catch {
|
|
50362
50618
|
return "";
|
|
@@ -50553,10 +50809,10 @@ var init_pi = __esm({
|
|
|
50553
50809
|
await readModels();
|
|
50554
50810
|
};
|
|
50555
50811
|
await readModels();
|
|
50556
|
-
const
|
|
50812
|
+
const listeners2 = /* @__PURE__ */ new Set();
|
|
50557
50813
|
const active = /* @__PURE__ */ new Map();
|
|
50558
50814
|
const emit = (event) => {
|
|
50559
|
-
for (const l of Array.from(
|
|
50815
|
+
for (const l of Array.from(listeners2)) l(event);
|
|
50560
50816
|
};
|
|
50561
50817
|
const base2 = (threadId, turnId) => ({
|
|
50562
50818
|
eventId: newEventId(),
|
|
@@ -50937,7 +51193,7 @@ var init_pi = __esm({
|
|
|
50937
51193
|
if (scopeReadyPath) {
|
|
50938
51194
|
let ready = false;
|
|
50939
51195
|
try {
|
|
50940
|
-
const receipt = JSON.parse(
|
|
51196
|
+
const receipt = JSON.parse(readFileSync23(scopeReadyPath, "utf8"));
|
|
50941
51197
|
ready = receipt.ok === true && JSON.stringify(receipt.toolScope) === JSON.stringify(toolScope);
|
|
50942
51198
|
} catch {
|
|
50943
51199
|
}
|
|
@@ -51095,13 +51351,13 @@ ${turn.text}` : turn.text;
|
|
|
51095
51351
|
for (const { stop } of active.values()) stop();
|
|
51096
51352
|
},
|
|
51097
51353
|
onEvent: (listener) => {
|
|
51098
|
-
|
|
51099
|
-
return () =>
|
|
51354
|
+
listeners2.add(listener);
|
|
51355
|
+
return () => listeners2.delete(listener);
|
|
51100
51356
|
}
|
|
51101
51357
|
},
|
|
51102
51358
|
dispose: async () => {
|
|
51103
51359
|
for (const { stop } of active.values()) stop();
|
|
51104
|
-
|
|
51360
|
+
listeners2.clear();
|
|
51105
51361
|
}
|
|
51106
51362
|
};
|
|
51107
51363
|
}
|
|
@@ -51347,7 +51603,7 @@ var init_cerebras = __esm({
|
|
|
51347
51603
|
});
|
|
51348
51604
|
|
|
51349
51605
|
// server/drivers/minimax.ts
|
|
51350
|
-
import { readFileSync as
|
|
51606
|
+
import { readFileSync as readFileSync24 } from "node:fs";
|
|
51351
51607
|
import { homedir as homedir20 } from "node:os";
|
|
51352
51608
|
import { join as join41 } from "node:path";
|
|
51353
51609
|
function normalizedApiUrl(value) {
|
|
@@ -51356,7 +51612,7 @@ function normalizedApiUrl(value) {
|
|
|
51356
51612
|
}
|
|
51357
51613
|
function loadLocalMiniMaxConfig(home = homedir20()) {
|
|
51358
51614
|
try {
|
|
51359
|
-
const raw = localConfigSchema.parse(JSON.parse(
|
|
51615
|
+
const raw = localConfigSchema.parse(JSON.parse(readFileSync24(join41(home, ".mmx", "config.json"), "utf8")));
|
|
51360
51616
|
const configuredUrl = raw.base_url?.trim() ? raw.base_url : raw.region === "cn" ? CN_URL : DEFAULT_URL4;
|
|
51361
51617
|
return {
|
|
51362
51618
|
apiKey: raw.api_key?.trim() ?? "",
|
|
@@ -51632,7 +51888,7 @@ __export(cli_setup_exports, {
|
|
|
51632
51888
|
saveCliStartup: () => saveCliStartup
|
|
51633
51889
|
});
|
|
51634
51890
|
import { spawn as spawn7 } from "node:child_process";
|
|
51635
|
-
import { readFileSync as
|
|
51891
|
+
import { readFileSync as readFileSync25 } from "node:fs";
|
|
51636
51892
|
import { join as join42, resolve as resolve11 } from "node:path";
|
|
51637
51893
|
import { randomUUID as randomUUID13 } from "node:crypto";
|
|
51638
51894
|
async function inspect(id, entry) {
|
|
@@ -51670,7 +51926,7 @@ function assertDataDir(dataDir) {
|
|
|
51670
51926
|
}
|
|
51671
51927
|
function checkStoredConfig(dataDir) {
|
|
51672
51928
|
try {
|
|
51673
|
-
parseStoredConfig(JSON.parse(
|
|
51929
|
+
parseStoredConfig(JSON.parse(readFileSync25(join42(dataDir, "config.json"), "utf8")));
|
|
51674
51930
|
} catch (error51) {
|
|
51675
51931
|
if (error51.code === "ENOENT") return;
|
|
51676
51932
|
throw new Error("Existing config.json could not be read or validated. Setup has not changed it; repair it before continuing.");
|
|
@@ -52106,13 +52362,13 @@ __export(browser_engine_exports, {
|
|
|
52106
52362
|
setBrowserViewport: () => setBrowserViewport
|
|
52107
52363
|
});
|
|
52108
52364
|
import { spawn as spawn8 } from "node:child_process";
|
|
52109
|
-
import { createHash as
|
|
52110
|
-
import { chmodSync as chmodSync8, constants as
|
|
52365
|
+
import { createHash as createHash14, randomBytes as randomBytes4, randomUUID as randomUUID14 } from "node:crypto";
|
|
52366
|
+
import { chmodSync as chmodSync8, constants as constants3, copyFileSync, existsSync as existsSync17, mkdirSync as mkdirSync22, readFileSync as readFileSync26, readdirSync as readdirSync3, renameSync as renameSync6, rmSync as rmSync8, statSync as statSync7, unlinkSync as unlinkSync6, writeFileSync as writeFileSync16 } from "node:fs";
|
|
52111
52367
|
import { homedir as homedir21, tmpdir as tmpdir5 } from "node:os";
|
|
52112
52368
|
import { delimiter as delimiter6, dirname as dirname15, join as join45, resolve as resolve12 } from "node:path";
|
|
52113
52369
|
function browserRestoreKey(session) {
|
|
52114
52370
|
if (!/^[A-Za-z0-9_.-]{1,96}$/.test(session)) throw new Error("Invalid browser session.");
|
|
52115
|
-
return `omb-${
|
|
52371
|
+
return `omb-${createHash14("sha256").update(session).digest("hex")}`;
|
|
52116
52372
|
}
|
|
52117
52373
|
function browserSessionsDirectory(env) {
|
|
52118
52374
|
const namespace = env.AGENT_BROWSER_NAMESPACE;
|
|
@@ -52131,7 +52387,7 @@ function ensureManagedBrowserConfig(env) {
|
|
|
52131
52387
|
writeFileSync16(path3, "{}\n", { flag: "wx", mode: 384 });
|
|
52132
52388
|
} catch (error51) {
|
|
52133
52389
|
if (error51.code !== "EEXIST") throw error51;
|
|
52134
|
-
if (
|
|
52390
|
+
if (readFileSync26(path3, "utf8").trim() !== "{}") throw new Error("The managed browser configuration was changed. Restore it to an empty JSON object before connecting.");
|
|
52135
52391
|
}
|
|
52136
52392
|
return path3;
|
|
52137
52393
|
}
|
|
@@ -52246,7 +52502,7 @@ async function prepareBrowserSessionState(binaryPath, session, options = {}) {
|
|
|
52246
52502
|
const source = candidates[0];
|
|
52247
52503
|
if (!source) return;
|
|
52248
52504
|
try {
|
|
52249
|
-
copyFileSync(source.path, targetBase + source.suffix,
|
|
52505
|
+
copyFileSync(source.path, targetBase + source.suffix, constants3.COPYFILE_EXCL);
|
|
52250
52506
|
chmodSync8(targetBase + source.suffix, 384);
|
|
52251
52507
|
} catch (error51) {
|
|
52252
52508
|
if (error51.code !== "EEXIST") throw error51;
|
|
@@ -52347,7 +52603,7 @@ async function installAgentBrowserBinary(options = {}) {
|
|
|
52347
52603
|
clearTimeout(timer);
|
|
52348
52604
|
}
|
|
52349
52605
|
if (body.length !== asset.bytes) throw new Error("the agent-browser download did not match its pinned size; nothing was installed");
|
|
52350
|
-
const digest3 =
|
|
52606
|
+
const digest3 = createHash14("sha256").update(body).digest("hex");
|
|
52351
52607
|
if (digest3 !== asset.sha256) throw new Error("the agent-browser download failed its SHA-256 check; nothing was installed");
|
|
52352
52608
|
try {
|
|
52353
52609
|
for (const name of readdirSync3(directory)) {
|
|
@@ -52414,7 +52670,7 @@ function ensureChrome(binaryPath, options = {}) {
|
|
|
52414
52670
|
function browserEngineEncryptionKey(dataDir = DATA_DIR) {
|
|
52415
52671
|
const file2 = join45(dataDir, KEY_FILE);
|
|
52416
52672
|
try {
|
|
52417
|
-
const existing =
|
|
52673
|
+
const existing = readFileSync26(file2, "utf8").trim();
|
|
52418
52674
|
if (/^[0-9a-f]{64}$/u.test(existing)) return existing;
|
|
52419
52675
|
} catch {
|
|
52420
52676
|
}
|
|
@@ -52536,7 +52792,7 @@ function agentBrowserFrame(input) {
|
|
|
52536
52792
|
fail(error51);
|
|
52537
52793
|
return;
|
|
52538
52794
|
}
|
|
52539
|
-
settle({ png:
|
|
52795
|
+
settle({ png: readFileSync26(file2).toString("base64"), format: "png" });
|
|
52540
52796
|
} catch {
|
|
52541
52797
|
fail(new Error("the browser reported a picture it did not write"));
|
|
52542
52798
|
} finally {
|
|
@@ -52623,7 +52879,7 @@ var init_browser_engine = __esm({
|
|
|
52623
52879
|
var import_qrcode_terminal = __toESM(require_main(), 1);
|
|
52624
52880
|
import { spawn as spawn9 } from "node:child_process";
|
|
52625
52881
|
import { randomBytes as randomBytes5 } from "node:crypto";
|
|
52626
|
-
import { closeSync as closeSync8, existsSync as existsSync18, mkdirSync as mkdirSync23, openSync as openSync8, readFileSync as
|
|
52882
|
+
import { closeSync as closeSync8, existsSync as existsSync18, mkdirSync as mkdirSync23, openSync as openSync8, readFileSync as readFileSync27 } from "node:fs";
|
|
52627
52883
|
import { homedir as homedir22 } from "node:os";
|
|
52628
52884
|
import { dirname as dirname16, join as join46, resolve as resolve13 } from "node:path";
|
|
52629
52885
|
import { createInterface as createInterface2 } from "node:readline/promises";
|
|
@@ -54882,7 +55138,7 @@ function runServiceCommand(input, io) {
|
|
|
54882
55138
|
// server/fleet-cli.ts
|
|
54883
55139
|
init_atomic();
|
|
54884
55140
|
import { execFileSync, spawn as spawn3 } from "node:child_process";
|
|
54885
|
-
import { appendFileSync, closeSync as closeSync2, existsSync as existsSync3, fsyncSync as fsyncSync2, lstatSync, mkdirSync as mkdirSync3, openSync as openSync2, readFileSync, rmSync as rmSync2 } from "node:fs";
|
|
55141
|
+
import { appendFileSync, closeSync as closeSync2, existsSync as existsSync3, fsyncSync as fsyncSync2, lstatSync as lstatSync2, mkdirSync as mkdirSync3, openSync as openSync2, readFileSync as readFileSync2, rmSync as rmSync2 } from "node:fs";
|
|
54886
55142
|
import { posix as posix3 } from "node:path";
|
|
54887
55143
|
|
|
54888
55144
|
// server/fleet.ts
|
|
@@ -55458,14 +55714,14 @@ function defaultFleetDeps() {
|
|
|
55458
55714
|
}),
|
|
55459
55715
|
pathExists: (path3) => {
|
|
55460
55716
|
try {
|
|
55461
|
-
|
|
55717
|
+
lstatSync2(path3);
|
|
55462
55718
|
return true;
|
|
55463
55719
|
} catch (error51) {
|
|
55464
55720
|
if (error51.code === "ENOENT") return false;
|
|
55465
55721
|
throw error51;
|
|
55466
55722
|
}
|
|
55467
55723
|
},
|
|
55468
|
-
readText: (path3, owner) => owner ? tenantIo(owner, path3, "read") : existsSync3(path3) ?
|
|
55724
|
+
readText: (path3, owner) => owner ? tenantIo(owner, path3, "read") : existsSync3(path3) ? readFileSync2(path3, "utf8") : null,
|
|
55469
55725
|
usage: (dataDir, owner, now) => {
|
|
55470
55726
|
const at = now.toISOString();
|
|
55471
55727
|
return tenantIo(owner, posix3.join(dataDir, "usage", `${at.slice(0, 7)}.jsonl`), "usage", at);
|
|
@@ -55488,7 +55744,7 @@ function defaultFleetDeps() {
|
|
|
55488
55744
|
else mkdirSync3(path3, { recursive: true, mode });
|
|
55489
55745
|
},
|
|
55490
55746
|
appendOnce: (path3, line) => {
|
|
55491
|
-
const current = existsSync3(path3) ?
|
|
55747
|
+
const current = existsSync3(path3) ? readFileSync2(path3, "utf8") : "";
|
|
55492
55748
|
if (!current.split("\n").some((existing) => existing.trim() === line)) appendFileSync(path3, `${current.endsWith("\n") || !current ? "" : "\n"}
|
|
55493
55749
|
${line}
|
|
55494
55750
|
`);
|
|
@@ -55722,12 +55978,22 @@ import { dirname as dirname3 } from "node:path";
|
|
|
55722
55978
|
var MAX_BODY = 256 * 1024;
|
|
55723
55979
|
function readBody(req) {
|
|
55724
55980
|
return new Promise((resolve14, reject) => {
|
|
55725
|
-
|
|
55981
|
+
const chunks = [];
|
|
55982
|
+
let bytes = 0;
|
|
55983
|
+
let tooLarge = false;
|
|
55726
55984
|
req.on("data", (chunk) => {
|
|
55727
|
-
|
|
55728
|
-
|
|
55985
|
+
if (tooLarge) return;
|
|
55986
|
+
bytes += chunk.length;
|
|
55987
|
+
if (bytes > MAX_BODY) {
|
|
55988
|
+
tooLarge = true;
|
|
55989
|
+
chunks.length = 0;
|
|
55990
|
+
return reject(Object.assign(new Error("request too large"), { status: 413 }));
|
|
55991
|
+
}
|
|
55992
|
+
chunks.push(chunk);
|
|
55729
55993
|
});
|
|
55730
55994
|
req.on("end", () => {
|
|
55995
|
+
if (tooLarge) return;
|
|
55996
|
+
const text4 = Buffer.concat(chunks).toString("utf8");
|
|
55731
55997
|
if (!text4.trim()) return resolve14({});
|
|
55732
55998
|
try {
|
|
55733
55999
|
const value = JSON.parse(text4);
|
|
@@ -56142,7 +56408,7 @@ function phonePairingInstructions(phone, input) {
|
|
|
56142
56408
|
// server/tunnel.ts
|
|
56143
56409
|
import { spawn as spawn4 } from "node:child_process";
|
|
56144
56410
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
56145
|
-
import { chmodSync as chmodSync3, existsSync as existsSync5, mkdirSync as mkdirSync5, readFileSync as
|
|
56411
|
+
import { chmodSync as chmodSync3, existsSync as existsSync5, mkdirSync as mkdirSync5, readFileSync as readFileSync3, statSync } from "node:fs";
|
|
56146
56412
|
import { hostname as hostname3 } from "node:os";
|
|
56147
56413
|
import { dirname as dirname4, join as join8, resolve as resolve2 } from "node:path";
|
|
56148
56414
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
@@ -56233,7 +56499,7 @@ function openTunnelCredentials(dataDir) {
|
|
|
56233
56499
|
if (existsSync5(file2)) {
|
|
56234
56500
|
try {
|
|
56235
56501
|
if (process.platform !== "win32" && (statSync(file2).mode & 63) !== 0) chmodSync3(file2, 384);
|
|
56236
|
-
const parsed = plainDocument(JSON.parse(
|
|
56502
|
+
const parsed = plainDocument(JSON.parse(readFileSync3(file2, "utf8")));
|
|
56237
56503
|
if (!parsed) throw new Error("not a JSON object");
|
|
56238
56504
|
initial = parsed;
|
|
56239
56505
|
status = "ok";
|
|
@@ -56583,7 +56849,7 @@ function defaultIo() {
|
|
|
56583
56849
|
}
|
|
56584
56850
|
function serverVersion2(here = HERE2) {
|
|
56585
56851
|
try {
|
|
56586
|
-
const parsed = JSON.parse(
|
|
56852
|
+
const parsed = JSON.parse(readFileSync27(resolve13(here, "..", "package.json"), "utf8"));
|
|
56587
56853
|
const version2 = typeof parsed === "object" && parsed !== null ? Reflect.get(parsed, "version") : void 0;
|
|
56588
56854
|
return typeof version2 === "string" && version2 ? version2 : "0.0.0";
|
|
56589
56855
|
} catch {
|
|
@@ -56614,7 +56880,7 @@ async function isWorkspaceRunning(options) {
|
|
|
56614
56880
|
try {
|
|
56615
56881
|
const { status, body } = await api(options.port, "/api/health");
|
|
56616
56882
|
if (status !== 200 || body?.app !== "openmausbot") return false;
|
|
56617
|
-
const expected =
|
|
56883
|
+
const expected = readFileSync27(join46(options.dataDir, "environment-id"), "utf8").trim();
|
|
56618
56884
|
const descriptor = await api(options.port, "/.well-known/openmausbot/environment");
|
|
56619
56885
|
return /^[0-9a-f-]{36}$/i.test(expected) && descriptor.status === 200 && descriptor.body?.environmentId === expected;
|
|
56620
56886
|
} catch {
|
|
@@ -56849,7 +57115,7 @@ async function runAccess(options, io = defaultIo()) {
|
|
|
56849
57115
|
let raw = {};
|
|
56850
57116
|
if (existsSync18(file2)) {
|
|
56851
57117
|
try {
|
|
56852
|
-
const parsed = JSON.parse(
|
|
57118
|
+
const parsed = JSON.parse(readFileSync27(file2, "utf8"));
|
|
56853
57119
|
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) throw new Error("not an object");
|
|
56854
57120
|
raw = Object.fromEntries(Object.entries(parsed));
|
|
56855
57121
|
} catch (error51) {
|
|
@@ -56869,15 +57135,15 @@ async function runAccess(options, io = defaultIo()) {
|
|
|
56869
57135
|
if (!sharedSignIn({ admins, members }) && !sharedSignIn(next) && !hostedWorkspaceConfigured()) return;
|
|
56870
57136
|
const decisions = raw.decisions && typeof raw.decisions === "object" ? raw.decisions.retentionDays : void 0;
|
|
56871
57137
|
bindDecisionRetention(() => decisionRetentionDays(typeof decisions === "number" ? decisions : void 0));
|
|
56872
|
-
const
|
|
57138
|
+
const changed2 = ["admins", "members"].filter((key) => next[key].join(",") !== (key === "admins" ? admins : members).join(","));
|
|
56873
57139
|
appendAdminAction(options.dataDir, {
|
|
56874
57140
|
category: "people",
|
|
56875
57141
|
action: "people.update",
|
|
56876
57142
|
target: { kind: "settings" },
|
|
56877
57143
|
actor: { kind: "cli" },
|
|
56878
|
-
changed:
|
|
56879
|
-
before: Object.fromEntries(
|
|
56880
|
-
after: Object.fromEntries(
|
|
57144
|
+
changed: changed2.map((key) => `signIn.${key}`),
|
|
57145
|
+
before: Object.fromEntries(changed2.map((key) => [`signIn.${key}`, key === "admins" ? admins : members])),
|
|
57146
|
+
after: Object.fromEntries(changed2.map((key) => [`signIn.${key}`, next[key]]))
|
|
56881
57147
|
});
|
|
56882
57148
|
await flushAdminActivity(options.dataDir);
|
|
56883
57149
|
};
|