context-compress 2026.3.20 → 2026.3.21
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/executor.d.ts +3 -1
- package/dist/executor.d.ts.map +1 -1
- package/dist/executor.js +23 -10
- package/dist/executor.js.map +1 -1
- package/dist/network.d.ts.map +1 -1
- package/dist/network.js +17 -21
- package/dist/network.js.map +1 -1
- package/dist/server.bundle.mjs +186 -81
- package/dist/server.bundle.mjs.map +3 -3
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +97 -56
- package/dist/server.js.map +1 -1
- package/dist/stats.d.ts.map +1 -1
- package/dist/stats.js +1 -1
- package/dist/stats.js.map +1 -1
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +11 -4
- package/dist/store.js.map +1 -1
- package/dist/utils.d.ts +10 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +54 -0
- package/dist/utils.js.map +1 -0
- package/package.json +1 -1
package/dist/server.bundle.mjs
CHANGED
|
@@ -21216,6 +21216,54 @@ import { execFileSync, spawn } from "node:child_process";
|
|
|
21216
21216
|
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
21217
21217
|
import { tmpdir } from "node:os";
|
|
21218
21218
|
import { join as join2 } from "node:path";
|
|
21219
|
+
|
|
21220
|
+
// src/utils.ts
|
|
21221
|
+
function detectInjectionPatterns(content) {
|
|
21222
|
+
const warnings = [];
|
|
21223
|
+
const patterns = [
|
|
21224
|
+
{ re: /ignore\s+(all\s+)?previous\s+instructions/i, label: "instruction override" },
|
|
21225
|
+
{ re: /you\s+are\s+now\s+/i, label: "role reassignment" },
|
|
21226
|
+
{
|
|
21227
|
+
re: /(?:^|\n)\s*system\s*:\s*(?:you are|you're|as an? )/im,
|
|
21228
|
+
label: "system prompt injection"
|
|
21229
|
+
},
|
|
21230
|
+
{ re: /\[INST\]|\[\/INST\]|<\|im_start\|>|<\|im_end\|>/i, label: "chat template injection" },
|
|
21231
|
+
{ re: /\n\n(?:Human|Assistant):/m, label: "chat delimiter injection" },
|
|
21232
|
+
{ re: /reveal\s+(your|the)\s+(system|secret|confidential)/i, label: "data exfiltration" },
|
|
21233
|
+
{ re: /act\s+as\s+(if\s+you\s+are|a)\s+/i, label: "role manipulation" }
|
|
21234
|
+
];
|
|
21235
|
+
for (const { re, label } of patterns) {
|
|
21236
|
+
if (re.test(content)) {
|
|
21237
|
+
warnings.push(label);
|
|
21238
|
+
}
|
|
21239
|
+
}
|
|
21240
|
+
return warnings;
|
|
21241
|
+
}
|
|
21242
|
+
async function limitConcurrency(tasks, limit) {
|
|
21243
|
+
const results = new Array(tasks.length);
|
|
21244
|
+
let nextIndex = 0;
|
|
21245
|
+
async function runNext() {
|
|
21246
|
+
while (nextIndex < tasks.length) {
|
|
21247
|
+
const index = nextIndex++;
|
|
21248
|
+
try {
|
|
21249
|
+
const value = await tasks[index]();
|
|
21250
|
+
results[index] = { status: "fulfilled", value };
|
|
21251
|
+
} catch (reason) {
|
|
21252
|
+
results[index] = { status: "rejected", reason };
|
|
21253
|
+
}
|
|
21254
|
+
}
|
|
21255
|
+
}
|
|
21256
|
+
const workers = Array.from({ length: Math.min(limit, tasks.length) }, () => runNext());
|
|
21257
|
+
await Promise.all(workers);
|
|
21258
|
+
return results;
|
|
21259
|
+
}
|
|
21260
|
+
function formatBytes(bytes) {
|
|
21261
|
+
if (bytes < 1024) return `${bytes}B`;
|
|
21262
|
+
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)}KB`;
|
|
21263
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
|
|
21264
|
+
}
|
|
21265
|
+
|
|
21266
|
+
// src/executor.ts
|
|
21219
21267
|
var DEFAULT_TIMEOUT = 3e4;
|
|
21220
21268
|
var SAFE_ENV_KEYS = [
|
|
21221
21269
|
"PATH",
|
|
@@ -21380,20 +21428,26 @@ function smartTruncate(output, maxBytes) {
|
|
|
21380
21428
|
`;
|
|
21381
21429
|
return headLines.join("\n") + separator + tailLines.join("\n");
|
|
21382
21430
|
}
|
|
21383
|
-
function formatBytes(bytes) {
|
|
21384
|
-
if (bytes < 1024) return `${bytes}B`;
|
|
21385
|
-
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)}KB`;
|
|
21386
|
-
return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
|
|
21387
|
-
}
|
|
21388
21431
|
var SubprocessExecutor = class {
|
|
21389
21432
|
runtimes;
|
|
21390
21433
|
config;
|
|
21391
21434
|
env;
|
|
21435
|
+
activeProcesses = /* @__PURE__ */ new Set();
|
|
21392
21436
|
constructor(runtimes, config3) {
|
|
21393
21437
|
this.runtimes = runtimes;
|
|
21394
21438
|
this.config = config3;
|
|
21395
21439
|
this.env = buildEnv(config3);
|
|
21396
21440
|
}
|
|
21441
|
+
/** Kill all active child processes and their process trees. */
|
|
21442
|
+
shutdown() {
|
|
21443
|
+
for (const proc of this.activeProcesses) {
|
|
21444
|
+
try {
|
|
21445
|
+
if (proc.pid) killProcessTree(proc.pid);
|
|
21446
|
+
} catch {
|
|
21447
|
+
}
|
|
21448
|
+
}
|
|
21449
|
+
this.activeProcesses.clear();
|
|
21450
|
+
}
|
|
21397
21451
|
/**
|
|
21398
21452
|
* Execute code in a subprocess.
|
|
21399
21453
|
*/
|
|
@@ -21495,6 +21549,7 @@ var SubprocessExecutor = class {
|
|
|
21495
21549
|
shell: useShell,
|
|
21496
21550
|
detached: process.platform !== "win32"
|
|
21497
21551
|
});
|
|
21552
|
+
this.activeProcesses.add(proc);
|
|
21498
21553
|
proc.stdout?.on("data", (chunk) => {
|
|
21499
21554
|
totalBytes += chunk.length;
|
|
21500
21555
|
if (totalBytes > hardCap) {
|
|
@@ -21515,6 +21570,7 @@ var SubprocessExecutor = class {
|
|
|
21515
21570
|
});
|
|
21516
21571
|
proc.on("error", (err) => {
|
|
21517
21572
|
debug("Process error:", err.message);
|
|
21573
|
+
this.activeProcesses.delete(proc);
|
|
21518
21574
|
if (!resolved) {
|
|
21519
21575
|
resolved = true;
|
|
21520
21576
|
resolve2({
|
|
@@ -21527,6 +21583,7 @@ var SubprocessExecutor = class {
|
|
|
21527
21583
|
}
|
|
21528
21584
|
});
|
|
21529
21585
|
proc.on("close", (code) => {
|
|
21586
|
+
this.activeProcesses.delete(proc);
|
|
21530
21587
|
if (resolved) return;
|
|
21531
21588
|
resolved = true;
|
|
21532
21589
|
let stdout = Buffer.concat(stdoutChunks).toString("utf-8");
|
|
@@ -21540,8 +21597,10 @@ var SubprocessExecutor = class {
|
|
|
21540
21597
|
stdout += `
|
|
21541
21598
|
[output capped at ${formatBytes(hardCap)} \u2014 process killed]`;
|
|
21542
21599
|
}
|
|
21543
|
-
stdout
|
|
21544
|
-
|
|
21600
|
+
if (stdout.length > 1e4) {
|
|
21601
|
+
stdout = deduplicateLines(stdout);
|
|
21602
|
+
stdout = groupErrorLines(stdout);
|
|
21603
|
+
}
|
|
21545
21604
|
const truncated = Buffer.byteLength(stdout) > maxOutput;
|
|
21546
21605
|
if (truncated) {
|
|
21547
21606
|
stdout = smartTruncate(stdout, maxOutput);
|
|
@@ -21612,24 +21671,24 @@ async function resolveAndValidate(url) {
|
|
|
21612
21671
|
let resolvedIp = null;
|
|
21613
21672
|
let v4Error = false;
|
|
21614
21673
|
let v6Error = false;
|
|
21615
|
-
|
|
21616
|
-
|
|
21617
|
-
|
|
21618
|
-
|
|
21619
|
-
|
|
21620
|
-
|
|
21621
|
-
|
|
21622
|
-
|
|
21674
|
+
const [v4Result, v6Result] = await Promise.allSettled([
|
|
21675
|
+
dns.promises.lookup(hostname2, { family: 4 }),
|
|
21676
|
+
dns.promises.lookup(hostname2, { family: 6 })
|
|
21677
|
+
]);
|
|
21678
|
+
if (v4Result.status === "fulfilled") {
|
|
21679
|
+
if (isPrivateHost(v4Result.value.address)) {
|
|
21680
|
+
throw new Error(`Blocked: ${hostname2} resolved to private IP ${v4Result.value.address}`);
|
|
21681
|
+
}
|
|
21682
|
+
resolvedIp = v4Result.value.address;
|
|
21683
|
+
} else {
|
|
21623
21684
|
v4Error = true;
|
|
21624
21685
|
}
|
|
21625
|
-
|
|
21626
|
-
|
|
21627
|
-
|
|
21628
|
-
throw new Error(`Blocked: ${hostname2} resolved to private IPv6 ${address}`);
|
|
21686
|
+
if (v6Result.status === "fulfilled") {
|
|
21687
|
+
if (isPrivateHost(v6Result.value.address)) {
|
|
21688
|
+
throw new Error(`Blocked: ${hostname2} resolved to private IPv6 ${v6Result.value.address}`);
|
|
21629
21689
|
}
|
|
21630
|
-
if (!resolvedIp) resolvedIp = address;
|
|
21631
|
-
}
|
|
21632
|
-
if (err instanceof Error && err.message.startsWith("Blocked:")) throw err;
|
|
21690
|
+
if (!resolvedIp) resolvedIp = v6Result.value.address;
|
|
21691
|
+
} else {
|
|
21633
21692
|
v6Error = true;
|
|
21634
21693
|
}
|
|
21635
21694
|
if (v4Error && v6Error) {
|
|
@@ -22216,17 +22275,20 @@ function sanitizeQuery(raw) {
|
|
|
22216
22275
|
const words = q.split(/\s+/).filter((w) => w.length >= 2).map((w) => `"${w}"`);
|
|
22217
22276
|
return words.length > 0 ? words.join(" OR ") : "";
|
|
22218
22277
|
}
|
|
22219
|
-
function levenshtein(a, b) {
|
|
22278
|
+
function levenshtein(a, b, maxDist) {
|
|
22220
22279
|
if (a.length === 0) return b.length;
|
|
22221
22280
|
if (b.length === 0) return a.length;
|
|
22222
22281
|
let prev = Array.from({ length: b.length + 1 }, (_, i) => i);
|
|
22223
22282
|
let curr = new Array(b.length + 1);
|
|
22224
22283
|
for (let i = 1; i <= a.length; i++) {
|
|
22225
22284
|
curr[0] = i;
|
|
22285
|
+
let rowMin = curr[0];
|
|
22226
22286
|
for (let j = 1; j <= b.length; j++) {
|
|
22227
22287
|
const cost = a[i - 1] === b[j - 1] ? 0 : 1;
|
|
22228
22288
|
curr[j] = Math.min(prev[j] + 1, curr[j - 1] + 1, prev[j - 1] + cost);
|
|
22289
|
+
if (curr[j] < rowMin) rowMin = curr[j];
|
|
22229
22290
|
}
|
|
22291
|
+
if (maxDist !== void 0 && rowMin > maxDist) return maxDist + 1;
|
|
22230
22292
|
[prev, curr] = [curr, prev];
|
|
22231
22293
|
}
|
|
22232
22294
|
return prev[b.length];
|
|
@@ -22422,7 +22484,7 @@ var ContentStore = class {
|
|
|
22422
22484
|
let bestWord = word;
|
|
22423
22485
|
let bestDist = maxDist + 1;
|
|
22424
22486
|
for (const { word: candidate } of candidates) {
|
|
22425
|
-
const dist = levenshtein(word.toLowerCase(), candidate.toLowerCase());
|
|
22487
|
+
const dist = levenshtein(word.toLowerCase(), candidate.toLowerCase(), maxDist);
|
|
22426
22488
|
if (dist < bestDist && dist <= maxDist) {
|
|
22427
22489
|
bestDist = dist;
|
|
22428
22490
|
bestWord = candidate;
|
|
@@ -22439,7 +22501,8 @@ var ContentStore = class {
|
|
|
22439
22501
|
updateVocabulary(content) {
|
|
22440
22502
|
const currentCount = this.vocabCountStmt.get().cnt;
|
|
22441
22503
|
if (currentCount >= MAX_VOCABULARY) return;
|
|
22442
|
-
const
|
|
22504
|
+
const sample = content.length > 51200 ? content.slice(0, 51200) : content;
|
|
22505
|
+
const words = sample.split(WORD_SPLIT_RE).filter((w) => w.length >= 3 && !STOPWORDS.has(w.toLowerCase()));
|
|
22443
22506
|
const unique = new Set(words.map((w) => w.toLowerCase()));
|
|
22444
22507
|
const insert = this.vocabInsertStmt;
|
|
22445
22508
|
let added = 0;
|
|
@@ -22677,45 +22740,6 @@ function compactLabel(normal, level) {
|
|
|
22677
22740
|
}
|
|
22678
22741
|
return normal;
|
|
22679
22742
|
}
|
|
22680
|
-
async function limitConcurrency(tasks, limit) {
|
|
22681
|
-
const results = new Array(tasks.length);
|
|
22682
|
-
let nextIndex = 0;
|
|
22683
|
-
async function runNext() {
|
|
22684
|
-
while (nextIndex < tasks.length) {
|
|
22685
|
-
const index = nextIndex++;
|
|
22686
|
-
try {
|
|
22687
|
-
const value = await tasks[index]();
|
|
22688
|
-
results[index] = { status: "fulfilled", value };
|
|
22689
|
-
} catch (reason) {
|
|
22690
|
-
results[index] = { status: "rejected", reason };
|
|
22691
|
-
}
|
|
22692
|
-
}
|
|
22693
|
-
}
|
|
22694
|
-
const workers = Array.from({ length: Math.min(limit, tasks.length) }, () => runNext());
|
|
22695
|
-
await Promise.all(workers);
|
|
22696
|
-
return results;
|
|
22697
|
-
}
|
|
22698
|
-
function detectInjectionPatterns(content) {
|
|
22699
|
-
const warnings = [];
|
|
22700
|
-
const patterns = [
|
|
22701
|
-
{ re: /ignore\s+(all\s+)?previous\s+instructions/i, label: "instruction override" },
|
|
22702
|
-
{ re: /you\s+are\s+now\s+/i, label: "role reassignment" },
|
|
22703
|
-
{
|
|
22704
|
-
re: /(?:^|\n)\s*system\s*:\s*(?:you are|you're|as an? )/im,
|
|
22705
|
-
label: "system prompt injection"
|
|
22706
|
-
},
|
|
22707
|
-
{ re: /\[INST\]|\[\/INST\]|<\|im_start\|>|<\|im_end\|>/i, label: "chat template injection" },
|
|
22708
|
-
{ re: /\n\n(?:Human|Assistant):/m, label: "chat delimiter injection" },
|
|
22709
|
-
{ re: /reveal\s+(your|the)\s+(system|secret|confidential)/i, label: "data exfiltration" },
|
|
22710
|
-
{ re: /act\s+as\s+(if\s+you\s+are|a)\s+/i, label: "role manipulation" }
|
|
22711
|
-
];
|
|
22712
|
-
for (const { re, label } of patterns) {
|
|
22713
|
-
if (re.test(content)) {
|
|
22714
|
-
warnings.push(label);
|
|
22715
|
-
}
|
|
22716
|
-
}
|
|
22717
|
-
return warnings;
|
|
22718
|
-
}
|
|
22719
22743
|
async function createServer(config3) {
|
|
22720
22744
|
const version2 = getVersion();
|
|
22721
22745
|
debug("Version:", version2);
|
|
@@ -22734,6 +22758,20 @@ async function createServer(config3) {
|
|
|
22734
22758
|
dbFallback = true;
|
|
22735
22759
|
}
|
|
22736
22760
|
const tracker = new SessionTracker();
|
|
22761
|
+
let activeExecutions = 0;
|
|
22762
|
+
const MAX_CONCURRENT_EXECUTIONS = 8;
|
|
22763
|
+
const EXECUTION_LIMIT_ERROR = "Error: too many concurrent executions. Try again shortly.";
|
|
22764
|
+
async function withExecutionLimit(fn) {
|
|
22765
|
+
if (activeExecutions >= MAX_CONCURRENT_EXECUTIONS) {
|
|
22766
|
+
throw new Error(EXECUTION_LIMIT_ERROR);
|
|
22767
|
+
}
|
|
22768
|
+
activeExecutions++;
|
|
22769
|
+
try {
|
|
22770
|
+
return await fn();
|
|
22771
|
+
} finally {
|
|
22772
|
+
activeExecutions--;
|
|
22773
|
+
}
|
|
22774
|
+
}
|
|
22737
22775
|
function applyIntentFilter(output, intent, sourceLabel) {
|
|
22738
22776
|
if (Buffer.byteLength(output) <= config3.intentSearchThreshold) return output;
|
|
22739
22777
|
const indexed = store.index(output, sourceLabel);
|
|
@@ -22758,6 +22796,10 @@ Searchable terms: ${terms.join(", ")}
|
|
|
22758
22796
|
return compactLabel(filtered, config3.compressionLevel);
|
|
22759
22797
|
}
|
|
22760
22798
|
const shutdown = () => {
|
|
22799
|
+
try {
|
|
22800
|
+
executor.shutdown();
|
|
22801
|
+
} catch {
|
|
22802
|
+
}
|
|
22761
22803
|
try {
|
|
22762
22804
|
store.close();
|
|
22763
22805
|
} catch {
|
|
@@ -22766,6 +22808,16 @@ Searchable terms: ${terms.join(", ")}
|
|
|
22766
22808
|
process.on("SIGINT", shutdown);
|
|
22767
22809
|
process.on("SIGTERM", shutdown);
|
|
22768
22810
|
process.on("beforeExit", shutdown);
|
|
22811
|
+
process.on("uncaughtException", (err) => {
|
|
22812
|
+
debug("Uncaught exception:", err);
|
|
22813
|
+
shutdown();
|
|
22814
|
+
process.exit(1);
|
|
22815
|
+
});
|
|
22816
|
+
process.on("unhandledRejection", (err) => {
|
|
22817
|
+
debug("Unhandled rejection:", err);
|
|
22818
|
+
shutdown();
|
|
22819
|
+
process.exit(1);
|
|
22820
|
+
});
|
|
22769
22821
|
const searchCalls = [];
|
|
22770
22822
|
const server2 = new McpServer({
|
|
22771
22823
|
name: "context-compress",
|
|
@@ -22787,7 +22839,24 @@ PREFER THIS OVER BASH for: API calls (gh, curl, aws), test runners (npm test, py
|
|
|
22787
22839
|
timeout: external_exports.number().default(3e4).describe("Max execution time in ms")
|
|
22788
22840
|
},
|
|
22789
22841
|
async ({ language, code, intent, timeout }) => {
|
|
22790
|
-
const
|
|
22842
|
+
const codeBytes = Buffer.byteLength(code);
|
|
22843
|
+
if (codeBytes > 1024e3) {
|
|
22844
|
+
return {
|
|
22845
|
+
content: [
|
|
22846
|
+
{
|
|
22847
|
+
type: "text",
|
|
22848
|
+
text: `Error: code too large (${(codeBytes / 1024).toFixed(0)}KB). Max 1MB.`
|
|
22849
|
+
}
|
|
22850
|
+
]
|
|
22851
|
+
};
|
|
22852
|
+
}
|
|
22853
|
+
let result;
|
|
22854
|
+
try {
|
|
22855
|
+
result = await withExecutionLimit(() => executor.execute({ language, code, timeout }));
|
|
22856
|
+
} catch (e) {
|
|
22857
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
22858
|
+
return { content: [{ type: "text", text: msg }] };
|
|
22859
|
+
}
|
|
22791
22860
|
if (result.networkBytes) {
|
|
22792
22861
|
tracker.trackSandboxed(result.networkBytes);
|
|
22793
22862
|
}
|
|
@@ -22819,6 +22888,17 @@ ${result.stderr}`;
|
|
|
22819
22888
|
timeout: external_exports.number().default(3e4).describe("Max execution time in ms")
|
|
22820
22889
|
},
|
|
22821
22890
|
async ({ path: filePath, language, code, intent, timeout }) => {
|
|
22891
|
+
const codeBytes = Buffer.byteLength(code);
|
|
22892
|
+
if (codeBytes > 1024e3) {
|
|
22893
|
+
return {
|
|
22894
|
+
content: [
|
|
22895
|
+
{
|
|
22896
|
+
type: "text",
|
|
22897
|
+
text: `Error: code too large (${(codeBytes / 1024).toFixed(0)}KB). Max 1MB.`
|
|
22898
|
+
}
|
|
22899
|
+
]
|
|
22900
|
+
};
|
|
22901
|
+
}
|
|
22822
22902
|
const absPath = resolve(projectDir, filePath);
|
|
22823
22903
|
if (!isWithinProject(absPath)) {
|
|
22824
22904
|
return {
|
|
@@ -22830,12 +22910,20 @@ ${result.stderr}`;
|
|
|
22830
22910
|
]
|
|
22831
22911
|
};
|
|
22832
22912
|
}
|
|
22833
|
-
|
|
22834
|
-
|
|
22835
|
-
|
|
22836
|
-
|
|
22837
|
-
|
|
22838
|
-
|
|
22913
|
+
let result;
|
|
22914
|
+
try {
|
|
22915
|
+
result = await withExecutionLimit(
|
|
22916
|
+
() => executor.executeFile({
|
|
22917
|
+
language,
|
|
22918
|
+
code,
|
|
22919
|
+
filePath: absPath,
|
|
22920
|
+
timeout
|
|
22921
|
+
})
|
|
22922
|
+
);
|
|
22923
|
+
} catch (e) {
|
|
22924
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
22925
|
+
return { content: [{ type: "text", text: msg }] };
|
|
22926
|
+
}
|
|
22839
22927
|
let output = result.stdout;
|
|
22840
22928
|
if (result.stderr && result.exitCode !== 0) {
|
|
22841
22929
|
output += `
|
|
@@ -23020,11 +23108,19 @@ ${hit.snippet}
|
|
|
23020
23108
|
}
|
|
23021
23109
|
const label = source ?? url;
|
|
23022
23110
|
const fetchCode = buildFetchCode(url, resolvedIp);
|
|
23023
|
-
|
|
23024
|
-
|
|
23025
|
-
|
|
23026
|
-
|
|
23027
|
-
|
|
23111
|
+
let result;
|
|
23112
|
+
try {
|
|
23113
|
+
result = await withExecutionLimit(
|
|
23114
|
+
() => executor.execute({
|
|
23115
|
+
language: "javascript",
|
|
23116
|
+
code: fetchCode,
|
|
23117
|
+
timeout: 3e4
|
|
23118
|
+
})
|
|
23119
|
+
);
|
|
23120
|
+
} catch (e) {
|
|
23121
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
23122
|
+
return { content: [{ type: "text", text: msg }] };
|
|
23123
|
+
}
|
|
23028
23124
|
if (result.exitCode !== 0 || !result.stdout.trim()) {
|
|
23029
23125
|
const errMsg = `Failed to fetch ${url}: ${result.stderr || "empty response"}`;
|
|
23030
23126
|
tracker.trackCall("fetch_and_index", Buffer.byteLength(errMsg));
|
|
@@ -23076,11 +23172,13 @@ Searchable terms: ${terms.join(", ")}`;
|
|
|
23076
23172
|
async ({ commands, queries, timeout }) => {
|
|
23077
23173
|
const commandResults = await limitConcurrency(
|
|
23078
23174
|
commands.map((cmd) => async () => {
|
|
23079
|
-
const result = await
|
|
23080
|
-
|
|
23081
|
-
|
|
23082
|
-
|
|
23083
|
-
|
|
23175
|
+
const result = await withExecutionLimit(
|
|
23176
|
+
() => executor.execute({
|
|
23177
|
+
language: "shell",
|
|
23178
|
+
code: cmd.command,
|
|
23179
|
+
timeout
|
|
23180
|
+
})
|
|
23181
|
+
);
|
|
23084
23182
|
return { label: cmd.label, result };
|
|
23085
23183
|
}),
|
|
23086
23184
|
4
|
|
@@ -23262,7 +23360,14 @@ const resp = await fetch(url, { redirect: 'error' });`;
|
|
|
23262
23360
|
}
|
|
23263
23361
|
return `${fetchSetup}
|
|
23264
23362
|
if (!resp.ok) { console.error("HTTP " + resp.status); process.exit(1); }
|
|
23363
|
+
const cl = resp.headers.get('content-length');
|
|
23364
|
+
if (cl && parseInt(cl, 10) > 10 * 1024 * 1024) {
|
|
23365
|
+
console.error("Response too large: " + cl + " bytes"); process.exit(1);
|
|
23366
|
+
}
|
|
23265
23367
|
const html = await resp.text();
|
|
23368
|
+
if (html.length > 10 * 1024 * 1024) {
|
|
23369
|
+
console.error("Response body too large: " + html.length + " chars"); process.exit(1);
|
|
23370
|
+
}
|
|
23266
23371
|
|
|
23267
23372
|
// Strip unwanted tags
|
|
23268
23373
|
let md = html
|