glimmervoid 0.36.0 → 0.38.0
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/README.md +86 -84
- package/dist/bin/glimmervoid.js +54 -115
- package/dist/chunks/{adapters-BdnLyJjf.js → adapters-B-IkWl-r.js} +37 -15
- package/dist/chunks/adapters-Dt3vwxwY.js +1 -0
- package/dist/chunks/{agent-api-cli-DIqRLvu3.js → agent-api-cli-3hryuewm.js} +1 -1
- package/dist/chunks/{agent-api-cli-d-Bgsshx.js → agent-api-cli-BcZ9DLCF.js} +41 -12
- package/dist/chunks/{agent-api-core-BUC9WND7.js → agent-api-core--8WtU1xU.js} +88 -6
- package/dist/chunks/{agent-setup-cli-CH7EHsAX.js → agent-setup-cli-BixDoCkF.js} +2 -2
- package/dist/chunks/{config-CuZ16F9W.js → config-BHBZsCBc.js} +22 -16
- package/dist/chunks/config-store-DYj3wYgw.js +1 -0
- package/dist/chunks/{config-store-LqQ7MuyV.js → config-store-DbfMbz4j.js} +46 -69
- package/dist/chunks/{contracts-BLZAOP57.js → contracts-u40eJhaf.js} +66 -21
- package/dist/chunks/git-version-BpnTd8sU.js +139 -0
- package/dist/chunks/{grok-Ch4-35_r.js → grok-xFs6zIu4.js} +5 -1
- package/dist/chunks/guardrails-deps-Cb-ki4EU.js +70 -0
- package/dist/chunks/{sandbox-proxy-core-hnQgKR0T.js → guardrails-proxy-core-BI3rdY-m.js} +4 -4
- package/dist/chunks/{json-file-BaxGcB2R.js → json-file-CIJf0Cel.js} +190 -9
- package/dist/chunks/{knowledge-graph-cli-DD7QvcFd.js → knowledge-graph-cli-DcspNqhz.js} +1 -1
- package/dist/chunks/{loopback-post-DepQfdcM.js → loopback-post-DZK7YibD.js} +10 -10
- package/dist/chunks/{main-Rmo83Ow-.js → main-w01-P1oZ.js} +15186 -13134
- package/dist/chunks/{pair-cli-DzFeAmq5.js → pair-cli-BdoyrDCr.js} +2 -2
- package/dist/chunks/{remote-config-CPdSF2Xi.js → remote-config-61zJ0hME.js} +2 -2
- package/dist/chunks/{session-B8RhqQJe.js → session-8Pv0y1vz.js} +55 -9
- package/dist/chunks/{session-routes-DB5aDKsx.js → session-routes-D-GZC-Sy.js} +9 -9
- package/dist/chunks/{settings-cli-C2TY6hl-.js → settings-cli-DKJsm3AP.js} +3 -3
- package/dist/chunks/{ssh-sign-cli-C2nUwJC-.js → ssh-sign-cli-Dc2gOCwE.js} +2 -2
- package/dist/client/assets/index-BfqmOGgc.js +275 -0
- package/dist/client/assets/index-DxABp5yJ.css +1 -0
- package/dist/client/index.html +10 -3
- package/dist/scripts/postinstall-path-check.js +4 -4
- package/dist/server/index.js +1 -1
- package/dist/session/command-hook-relay.js +1 -1
- package/dist/session/{sandbox-open-launcher.js → guardrails-open-launcher.js} +10 -10
- package/dist/session/hook-relay.js +1 -1
- package/dist/session/statusline-relay.js +1 -1
- package/dist/session/visions-relay.js +7 -7
- package/package.json +4 -3
- package/scripts/recover-handoff.mjs +1 -1
- package/dist/chunks/adapters-BVozg-Lg.js +0 -1
- package/dist/chunks/config-store-tVmt_nfm.js +0 -1
- package/dist/chunks/git-version-CUcDtF5k.js +0 -58
- package/dist/chunks/sandbox-deps-CWiH1d1w.js +0 -70
- package/dist/client/assets/index-BIaSyXwH.css +0 -1
- package/dist/client/assets/index-Ddu7M4Ad.js +0 -259
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { i as execSync } from "./child-process-safe-CbQnyh7D.js";
|
|
2
|
+
import { r as resolvePathCommandMatches } from "./spawn-command-Cc40FiZI.js";
|
|
3
|
+
//#region server/guardrails/core/guardrails-deps-core.ts
|
|
4
|
+
var LINUX_GUARDRAILS_BINARIES = Object.freeze([
|
|
5
|
+
"bwrap",
|
|
6
|
+
"socat",
|
|
7
|
+
"rg"
|
|
8
|
+
]);
|
|
9
|
+
var NO_GUARDRAILS_BINARIES = Object.freeze([]);
|
|
10
|
+
var GUARDRAILS_INSTALL_HINT = "Install bubblewrap, socat and ripgrep, for example: sudo apt install bubblewrap socat ripgrep";
|
|
11
|
+
var GUARDED_WORK = "guarded sessions and factory checks";
|
|
12
|
+
function requiredGuardrailsBinaries(platform) {
|
|
13
|
+
return platform === "linux" ? LINUX_GUARDRAILS_BINARIES : NO_GUARDRAILS_BINARIES;
|
|
14
|
+
}
|
|
15
|
+
function guardrailsDependencyReport({ platform, binariesOnPath }) {
|
|
16
|
+
const requiredBinaries = requiredGuardrailsBinaries(platform);
|
|
17
|
+
const missingBinaries = requiredBinaries.filter((binary) => !binariesOnPath.has(binary));
|
|
18
|
+
return {
|
|
19
|
+
platform,
|
|
20
|
+
requiredBinaries,
|
|
21
|
+
missingBinaries,
|
|
22
|
+
installHint: missingBinaries.length > 0 ? GUARDRAILS_INSTALL_HINT : null
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
function namesList(names) {
|
|
26
|
+
if (names.length <= 1) return names.join("");
|
|
27
|
+
return `${names.slice(0, -1).join(", ")} and ${names.at(-1)}`;
|
|
28
|
+
}
|
|
29
|
+
function missingBinariesPhrase(report) {
|
|
30
|
+
return `${namesList(report.missingBinaries)} ${report.missingBinaries.length === 1 ? "is" : "are"} not on PATH`;
|
|
31
|
+
}
|
|
32
|
+
function guardrailsSpawnRefusal(report) {
|
|
33
|
+
if (report.missingBinaries.length === 0) return null;
|
|
34
|
+
return `not started: the guardrails need ${namesList(report.requiredBinaries)}, and ${missingBinariesPhrase(report)}. ${report.installHint}`;
|
|
35
|
+
}
|
|
36
|
+
function guardrailsBootWarning(report) {
|
|
37
|
+
if (report.missingBinaries.length === 0) return null;
|
|
38
|
+
return `[guardrails] ${missingBinariesPhrase(report)}, so ${GUARDED_WORK} will refuse to start. ${report.installHint}`;
|
|
39
|
+
}
|
|
40
|
+
function guardrailsDoctorRows(report) {
|
|
41
|
+
if (report.requiredBinaries.length === 0) return [["guardrails", `nothing to check on ${report.platform}`]];
|
|
42
|
+
const binaryRows = report.requiredBinaries.map((binary) => [binary, report.missingBinaries.includes(binary) ? "MISSING" : "found"]);
|
|
43
|
+
if (report.installHint === null) return binaryRows;
|
|
44
|
+
return [...binaryRows, ["hint", report.installHint]];
|
|
45
|
+
}
|
|
46
|
+
function guardrailsInstallNotice(report) {
|
|
47
|
+
if (report.installHint === null) return null;
|
|
48
|
+
return `glimmervoid: ${missingBinariesPhrase(report)}; ${GUARDED_WORK} need ${namesList(report.requiredBinaries)}. ${report.installHint}`;
|
|
49
|
+
}
|
|
50
|
+
//#endregion
|
|
51
|
+
//#region server/guardrails/guardrails-deps.ts
|
|
52
|
+
function probeGuardrailsDependencies({ platform = process.platform, exec = execSync } = {}) {
|
|
53
|
+
return guardrailsDependencyReport({
|
|
54
|
+
platform,
|
|
55
|
+
binariesOnPath: new Set(requiredGuardrailsBinaries(platform).filter((binary) => resolvePathCommandMatches(binary, {
|
|
56
|
+
platform,
|
|
57
|
+
exec
|
|
58
|
+
}).length > 0))
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
function checkGuardrailsDependencies({ probe = probeGuardrailsDependencies, log = console } = {}) {
|
|
62
|
+
const report = probe();
|
|
63
|
+
const warning = guardrailsBootWarning(report);
|
|
64
|
+
if (warning !== null) log.warn(warning);
|
|
65
|
+
const refusal = guardrailsSpawnRefusal(report);
|
|
66
|
+
return () => refusal;
|
|
67
|
+
}
|
|
68
|
+
var allowGuardedSpawn = () => null;
|
|
69
|
+
//#endregion
|
|
70
|
+
export { guardrailsInstallNotice as a, guardrailsDoctorRows as i, checkGuardrailsDependencies as n, probeGuardrailsDependencies as r, allowGuardedSpawn as t };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { a as isLoopbackHostname } from "./hook-relay-core-DA_bz2KA.js";
|
|
2
|
-
//#region session/core/
|
|
3
|
-
var
|
|
2
|
+
//#region session/core/guardrails-proxy-core.ts
|
|
3
|
+
var HOOK_VIA_GUARDRAILS_PROXY_ENV = "GLIMMERVOID_HOOK_VIA_GUARDRAILS_PROXY";
|
|
4
4
|
function decodeProxyCredential(percentEncoded) {
|
|
5
5
|
try {
|
|
6
6
|
return decodeURIComponent(percentEncoded);
|
|
@@ -8,7 +8,7 @@ function decodeProxyCredential(percentEncoded) {
|
|
|
8
8
|
return null;
|
|
9
9
|
}
|
|
10
10
|
}
|
|
11
|
-
function
|
|
11
|
+
function decideGuardrailsProxy(env) {
|
|
12
12
|
if (env.SANDBOX_RUNTIME !== "1") return null;
|
|
13
13
|
const rawProxyUrl = env.HTTP_PROXY || env.http_proxy || "";
|
|
14
14
|
if (!URL.canParse(rawProxyUrl)) return null;
|
|
@@ -24,4 +24,4 @@ function decideSandboxProxy(env) {
|
|
|
24
24
|
};
|
|
25
25
|
}
|
|
26
26
|
//#endregion
|
|
27
|
-
export {
|
|
27
|
+
export { decideGuardrailsProxy as n, HOOK_VIA_GUARDRAILS_PROXY_ENV as t };
|
|
@@ -3,11 +3,60 @@ import { r as nextBackoffMs } from "./backoff-DjVpfHk7.js";
|
|
|
3
3
|
import fs from "node:fs";
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import crypto from "node:crypto";
|
|
6
|
+
//#region server/core/memory-admission-core.ts
|
|
7
|
+
var BYTES_PER_MEGABYTE$1 = 1048576;
|
|
8
|
+
var MEMORY_RECHECK_MS = 5e3;
|
|
9
|
+
var MEMORY_RESERVATION_SETTLE_MS = 3e4;
|
|
10
|
+
var DEFAULT_CHECK_MEMORY_RESERVE_MB = 1500;
|
|
11
|
+
function memoryReserveBytes(config, kind) {
|
|
12
|
+
return (kind === "session" ? config.sessionMemoryReserveMB ?? 600 : config.checkMemoryReserveMB ?? 1500) * BYTES_PER_MEGABYTE$1;
|
|
13
|
+
}
|
|
14
|
+
function parseCgroupV2Path(procSelfCgroupText) {
|
|
15
|
+
const unifiedLine = procSelfCgroupText.split("\n").find((line) => line.startsWith("0::"));
|
|
16
|
+
if (unifiedLine === void 0) return null;
|
|
17
|
+
const cgroupPath = unifiedLine.slice(3).trim();
|
|
18
|
+
return cgroupPath.startsWith("/") ? cgroupPath : null;
|
|
19
|
+
}
|
|
20
|
+
function cgroupAncestorPaths(cgroupPath) {
|
|
21
|
+
const segments = cgroupPath.split("/").filter((segment) => segment.length > 0);
|
|
22
|
+
return segments.map((_segment, depthFromLeaf) => `/${segments.slice(0, segments.length - depthFromLeaf).join("/")}`);
|
|
23
|
+
}
|
|
24
|
+
function parseCgroupBytes(text) {
|
|
25
|
+
if (text === null) return null;
|
|
26
|
+
const trimmed = text.trim();
|
|
27
|
+
return /^\d+$/.test(trimmed) ? Number(trimmed) : null;
|
|
28
|
+
}
|
|
29
|
+
function cgroupLimitBytes(memoryHighText, memoryMaxText) {
|
|
30
|
+
return parseCgroupBytes(memoryHighText) ?? parseCgroupBytes(memoryMaxText);
|
|
31
|
+
}
|
|
32
|
+
function parseMemAvailableBytes(meminfoText) {
|
|
33
|
+
const match = /^MemAvailable:\s+(\d+)\s+kB$/m.exec(meminfoText);
|
|
34
|
+
return match ? Number(match[1]) * 1024 : null;
|
|
35
|
+
}
|
|
36
|
+
function headroomFromReadings({ cgroupLevels, hostAvailableBytes }) {
|
|
37
|
+
const candidates = cgroupLevels.flatMap(({ limitBytes, currentBytes }) => limitBytes === null || currentBytes === null ? [] : [Math.max(0, limitBytes - currentBytes)]);
|
|
38
|
+
if (hostAvailableBytes !== null) candidates.push(hostAvailableBytes);
|
|
39
|
+
return candidates.length === 0 ? null : Math.min(...candidates);
|
|
40
|
+
}
|
|
41
|
+
function liveReservations(reservations, nowMs) {
|
|
42
|
+
return reservations.filter((reservation) => nowMs - reservation.admittedAtMs < MEMORY_RESERVATION_SETTLE_MS);
|
|
43
|
+
}
|
|
44
|
+
function shouldAdmitStart({ reading, reserveBytes, reservations, nowMs }) {
|
|
45
|
+
if (!reading.ok) return true;
|
|
46
|
+
const reservedBytes = liveReservations(reservations, nowMs).reduce((total, reservation) => total + reservation.bytes, 0);
|
|
47
|
+
return reading.headroomBytes - reservedBytes >= reserveBytes;
|
|
48
|
+
}
|
|
49
|
+
//#endregion
|
|
6
50
|
//#region server/spawn-gate.ts
|
|
51
|
+
var BYTES_PER_MEGABYTE = 1048576;
|
|
7
52
|
var QUEUE_ADMISSION_TIMED_OUT = "serial-queue-admission-timed-out";
|
|
53
|
+
var QUEUE_ADMISSION_ABANDONED = "serial-queue-admission-abandoned";
|
|
8
54
|
function isQueueAdmissionTimeout(error) {
|
|
9
55
|
return error instanceof Error && error.message === QUEUE_ADMISSION_TIMED_OUT;
|
|
10
56
|
}
|
|
57
|
+
function isQueueAdmissionAbandoned(error) {
|
|
58
|
+
return error instanceof Error && error.message === QUEUE_ADMISSION_ABANDONED;
|
|
59
|
+
}
|
|
11
60
|
function createSerialQueue() {
|
|
12
61
|
let tail = Promise.resolve();
|
|
13
62
|
function run(fn, options = {}) {
|
|
@@ -19,19 +68,27 @@ function createSerialQueue() {
|
|
|
19
68
|
return fn();
|
|
20
69
|
});
|
|
21
70
|
tail = result.then(() => void 0, () => void 0);
|
|
22
|
-
const admissionTimeoutMs = options
|
|
23
|
-
if (admissionTimeoutMs === void 0) return result;
|
|
71
|
+
const { admissionTimeoutMs, signal } = options;
|
|
72
|
+
if (admissionTimeoutMs === void 0 && signal === void 0) return result;
|
|
24
73
|
return new Promise((resolve, reject) => {
|
|
25
|
-
const
|
|
74
|
+
const leaveUnlessStarted = (reason) => {
|
|
26
75
|
if (started) return;
|
|
27
76
|
abandoned = true;
|
|
28
|
-
reject(
|
|
29
|
-
}
|
|
30
|
-
|
|
77
|
+
reject(new Error(reason));
|
|
78
|
+
};
|
|
79
|
+
const admissionTimer = admissionTimeoutMs === void 0 ? void 0 : setTimeout(() => leaveUnlessStarted(QUEUE_ADMISSION_TIMED_OUT), admissionTimeoutMs);
|
|
80
|
+
const leaveOnAbort = () => leaveUnlessStarted(QUEUE_ADMISSION_ABANDONED);
|
|
81
|
+
signal?.addEventListener("abort", leaveOnAbort, { once: true });
|
|
82
|
+
if (signal?.aborted) leaveOnAbort();
|
|
83
|
+
const stopWatching = () => {
|
|
31
84
|
clearTimeout(admissionTimer);
|
|
85
|
+
signal?.removeEventListener("abort", leaveOnAbort);
|
|
86
|
+
};
|
|
87
|
+
result.then((value) => {
|
|
88
|
+
stopWatching();
|
|
32
89
|
resolve(value);
|
|
33
90
|
}, (error) => {
|
|
34
|
-
|
|
91
|
+
stopWatching();
|
|
35
92
|
reject(error);
|
|
36
93
|
});
|
|
37
94
|
});
|
|
@@ -59,7 +116,131 @@ function createKeyedSerialQueue() {
|
|
|
59
116
|
}
|
|
60
117
|
return { run };
|
|
61
118
|
}
|
|
62
|
-
|
|
119
|
+
function toMegabytes(bytes) {
|
|
120
|
+
return Math.round(bytes / BYTES_PER_MEGABYTE);
|
|
121
|
+
}
|
|
122
|
+
function createMemoryAdmission({ readHeadroom, reserveBytesFor, nowMs = Date.now, sleep = (ms) => new Promise((resolve) => {
|
|
123
|
+
setTimeout(resolve, ms);
|
|
124
|
+
}), warn = (message) => console.warn(message) }) {
|
|
125
|
+
let reservations = [];
|
|
126
|
+
let isInProbeFailureStreak = false;
|
|
127
|
+
let heldStartCount = 0;
|
|
128
|
+
let latestHeadroomBytes = null;
|
|
129
|
+
let latestHeadroomReadAtMs = null;
|
|
130
|
+
function noteReading(reading, readAtMs) {
|
|
131
|
+
latestHeadroomReadAtMs = readAtMs;
|
|
132
|
+
latestHeadroomBytes = reading.ok ? reading.headroomBytes : null;
|
|
133
|
+
if (reading.ok) {
|
|
134
|
+
isInProbeFailureStreak = false;
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
if (isInProbeFailureStreak) return;
|
|
138
|
+
isInProbeFailureStreak = true;
|
|
139
|
+
warn(`[memory] could not read memory headroom, so starts go ahead unchecked: ${reading.reason}`);
|
|
140
|
+
}
|
|
141
|
+
async function admitOrDescribeShortfall(kind, { isDryRun = false } = {}) {
|
|
142
|
+
const reserveBytes = reserveBytesFor(kind);
|
|
143
|
+
if (reserveBytes <= 0) return null;
|
|
144
|
+
const reading = await readHeadroom();
|
|
145
|
+
const admittedAtMs = nowMs();
|
|
146
|
+
reservations = liveReservations(reservations, admittedAtMs);
|
|
147
|
+
noteReading(reading, admittedAtMs);
|
|
148
|
+
if (!(isDryRun && reading.ok && heldStartCount > 0) && shouldAdmitStart({
|
|
149
|
+
reading,
|
|
150
|
+
reserveBytes,
|
|
151
|
+
reservations,
|
|
152
|
+
nowMs: admittedAtMs
|
|
153
|
+
})) {
|
|
154
|
+
if (!isDryRun) reservations.push({
|
|
155
|
+
bytes: reserveBytes,
|
|
156
|
+
admittedAtMs
|
|
157
|
+
});
|
|
158
|
+
return null;
|
|
159
|
+
}
|
|
160
|
+
const heldBytes = reservations.reduce((total, reservation) => total + reservation.bytes, 0);
|
|
161
|
+
return {
|
|
162
|
+
headroomBytes: reading.ok ? reading.headroomBytes : 0,
|
|
163
|
+
heldBytes,
|
|
164
|
+
reserveBytes,
|
|
165
|
+
waitingStartCount: heldStartCount
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
async function recheckUntilAdmitted(kind, isStillWanted) {
|
|
169
|
+
do {
|
|
170
|
+
await sleep(MEMORY_RECHECK_MS);
|
|
171
|
+
if (!isStillWanted()) return false;
|
|
172
|
+
} while (await admitOrDescribeShortfall(kind) !== null);
|
|
173
|
+
return true;
|
|
174
|
+
}
|
|
175
|
+
async function waitForHeadroom(kind, { isStillWanted = () => true, onMemoryWait = () => {} } = {}) {
|
|
176
|
+
if (!isStillWanted()) return;
|
|
177
|
+
const shortfall = await admitOrDescribeShortfall(kind);
|
|
178
|
+
if (shortfall === null) return;
|
|
179
|
+
if (!isStillWanted()) return;
|
|
180
|
+
const waitStartedAtMs = nowMs();
|
|
181
|
+
warn(`[memory] holding a ${kind} start: ${toMegabytes(shortfall.headroomBytes)} MB headroom, ${toMegabytes(shortfall.heldBytes)} MB held for recent starts, ${toMegabytes(shortfall.reserveBytes)} MB reserve needed`);
|
|
182
|
+
onMemoryWait(true);
|
|
183
|
+
if (!await recheckUntilAdmitted(kind, isStillWanted).finally(() => onMemoryWait(false))) return;
|
|
184
|
+
warn(`[memory] admitted a ${kind} start after waiting ${Math.round((nowMs() - waitStartedAtMs) / 1e3)} s`);
|
|
185
|
+
}
|
|
186
|
+
return {
|
|
187
|
+
waitForHeadroom,
|
|
188
|
+
noteStartHeld: (isHeld) => {
|
|
189
|
+
heldStartCount += isHeld ? 1 : -1;
|
|
190
|
+
},
|
|
191
|
+
gateStatus: () => ({
|
|
192
|
+
headroomBytes: latestHeadroomBytes,
|
|
193
|
+
headroomReadAtMs: latestHeadroomReadAtMs,
|
|
194
|
+
heldStartCount
|
|
195
|
+
}),
|
|
196
|
+
describeShortfallNow: (kind) => admitOrDescribeShortfall(kind, { isDryRun: true })
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
function createSpawnGate({ memoryAdmission = null, kind = "session" } = {}) {
|
|
200
|
+
const queue = createSerialQueue();
|
|
201
|
+
if (!memoryAdmission) return queue;
|
|
202
|
+
const admission = memoryAdmission;
|
|
203
|
+
const queuedStarts = /* @__PURE__ */ new Set();
|
|
204
|
+
const flaggedStarts = /* @__PURE__ */ new Set();
|
|
205
|
+
let isHeadStartHeld = false;
|
|
206
|
+
function flagWaitingForMemory(queuedStart) {
|
|
207
|
+
if (flaggedStarts.has(queuedStart) || !queuedStart.isStillWanted()) return;
|
|
208
|
+
flaggedStarts.add(queuedStart);
|
|
209
|
+
admission.noteStartHeld(true);
|
|
210
|
+
queuedStart.onMemoryWait(true);
|
|
211
|
+
}
|
|
212
|
+
function leaveQueue(queuedStart) {
|
|
213
|
+
queuedStarts.delete(queuedStart);
|
|
214
|
+
if (!flaggedStarts.delete(queuedStart)) return;
|
|
215
|
+
admission.noteStartHeld(false);
|
|
216
|
+
queuedStart.onMemoryWait(false);
|
|
217
|
+
}
|
|
218
|
+
function noteHeadStartHeld(isHeld) {
|
|
219
|
+
isHeadStartHeld = isHeld;
|
|
220
|
+
if (!isHeld) return;
|
|
221
|
+
for (const queuedStart of queuedStarts) flagWaitingForMemory(queuedStart);
|
|
222
|
+
}
|
|
223
|
+
function run(fn, options = {}) {
|
|
224
|
+
const { isStillWanted = () => true, onMemoryWait = () => {} } = options;
|
|
225
|
+
const queuedStart = {
|
|
226
|
+
isStillWanted,
|
|
227
|
+
onMemoryWait
|
|
228
|
+
};
|
|
229
|
+
queuedStarts.add(queuedStart);
|
|
230
|
+
if (isHeadStartHeld) flagWaitingForMemory(queuedStart);
|
|
231
|
+
const release = () => leaveQueue(queuedStart);
|
|
232
|
+
const result = queue.run(() => admission.waitForHeadroom(kind, {
|
|
233
|
+
isStillWanted,
|
|
234
|
+
onMemoryWait: noteHeadStartHeld
|
|
235
|
+
}).finally(release).then(fn), options);
|
|
236
|
+
result.then(release, release);
|
|
237
|
+
return result;
|
|
238
|
+
}
|
|
239
|
+
return {
|
|
240
|
+
run,
|
|
241
|
+
idle: queue.idle
|
|
242
|
+
};
|
|
243
|
+
}
|
|
63
244
|
//#endregion
|
|
64
245
|
//#region server/json-file.ts
|
|
65
246
|
function tmpPathFor(filePath) {
|
|
@@ -349,4 +530,4 @@ function createJsonStateStore({ name, filePath, fsPromises = fs.promises, parse,
|
|
|
349
530
|
};
|
|
350
531
|
}
|
|
351
532
|
//#endregion
|
|
352
|
-
export {
|
|
533
|
+
export { headroomFromReadings as C, parseMemAvailableBytes as D, parseCgroupV2Path as E, cgroupLimitBytes as S, parseCgroupBytes as T, createSpawnGate as _, jsonStateLoadError as a, DEFAULT_CHECK_MEMORY_RESERVE_MB as b, loadedJsonValue as c, writeJsonAtomicSync as d, writeTextAtomic as f, createSerialQueue as g, createMemoryAdmission as h, createJsonStateWriter as i, sleepSync as l, createKeyedSerialQueue as m, appendJsonLines as n, loadJsonStateFile as o, writeTextAtomicSync as p, createJsonStateStore as r, loadJsonStateFileSync as s, appendJsonLine as t, writeJsonAtomic as u, isQueueAdmissionAbandoned as v, memoryReserveBytes as w, cgroupAncestorPaths as x, isQueueAdmissionTimeout as y };
|
|
@@ -2,7 +2,7 @@ import { r as errorMessage } from "./text-DoirglWV.js";
|
|
|
2
2
|
import { s as resolvePackageBin } from "./runtime-paths-BkeftE60.js";
|
|
3
3
|
import { r as execFileSync } from "./child-process-safe-CbQnyh7D.js";
|
|
4
4
|
import { n as glimmervoidHomeDir, t as decideConfigPath } from "./config-path-core-DFt-TemS.js";
|
|
5
|
-
import { r as BrowserConfig } from "./config-
|
|
5
|
+
import { r as BrowserConfig } from "./config-BHBZsCBc.js";
|
|
6
6
|
import fs, { closeSync, constants, existsSync, fstatSync, lstatSync, mkdirSync, openSync, readFileSync, readdirSync, realpathSync } from "node:fs";
|
|
7
7
|
import path, { dirname, join, posix, resolve, win32 } from "node:path";
|
|
8
8
|
import os from "node:os";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { a as isLoopbackHostname } from "./hook-relay-core-DA_bz2KA.js";
|
|
2
|
-
import { n as
|
|
3
|
-
import http from "node:http";
|
|
2
|
+
import { n as decideGuardrailsProxy } from "./guardrails-proxy-core-BI3rdY-m.js";
|
|
4
3
|
//#region session/loopback-post.ts
|
|
5
4
|
var POST_TIMEOUT_MS = 1500;
|
|
5
|
+
var http = process.getBuiltinModule("node:http");
|
|
6
6
|
function refusal(reason) {
|
|
7
7
|
return {
|
|
8
8
|
reason,
|
|
@@ -16,11 +16,11 @@ function directRoute(target) {
|
|
|
16
16
|
path: `${target.pathname}${target.search}`
|
|
17
17
|
};
|
|
18
18
|
}
|
|
19
|
-
function
|
|
20
|
-
const proxyHeaders =
|
|
19
|
+
function guardrailsProxyRoute(guardrailsProxy, target) {
|
|
20
|
+
const proxyHeaders = guardrailsProxy.authorization ? { "proxy-authorization": guardrailsProxy.authorization } : {};
|
|
21
21
|
return {
|
|
22
|
-
hostname:
|
|
23
|
-
port:
|
|
22
|
+
hostname: guardrailsProxy.hostname,
|
|
23
|
+
port: guardrailsProxy.port,
|
|
24
24
|
path: target.href,
|
|
25
25
|
headers: {
|
|
26
26
|
...proxyHeaders,
|
|
@@ -81,10 +81,10 @@ async function postToLoopback(url, body, env = process.env) {
|
|
|
81
81
|
const target = new URL(url);
|
|
82
82
|
if (target.protocol !== "http:") return refusal("not-http");
|
|
83
83
|
if (!isLoopbackHostname(target.hostname)) return refusal("not-loopback");
|
|
84
|
-
if (env["
|
|
85
|
-
const
|
|
86
|
-
if (!
|
|
87
|
-
return sendPost(
|
|
84
|
+
if (env["GLIMMERVOID_HOOK_VIA_GUARDRAILS_PROXY"] !== "1") return sendPost(directRoute(target), body);
|
|
85
|
+
const guardrailsProxy = decideGuardrailsProxy(env);
|
|
86
|
+
if (!guardrailsProxy) return refusal("guardrails-proxy-missing");
|
|
87
|
+
return sendPost(guardrailsProxyRoute(guardrailsProxy, target), body);
|
|
88
88
|
}
|
|
89
89
|
async function postPayload(url, body) {
|
|
90
90
|
return (await postToLoopback(url, body)).responseBody;
|