@runsec/mcp 1.0.85 → 1.0.87
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/index.js +69 -21
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6129,7 +6129,8 @@ function buildHubComplianceBlock(result) {
|
|
|
6129
6129
|
// src/telemetryClient.ts
|
|
6130
6130
|
var HUB_UPLOAD_TIMEOUT_MS = 12e4;
|
|
6131
6131
|
var HUB_UPLOAD_MAX_RETRIES = 4;
|
|
6132
|
-
var
|
|
6132
|
+
var HUB_WRITE_CHUNK_BYTES = 16 * 1024;
|
|
6133
|
+
var HUB_HTTPS_AGENT = new import_node_https.default.Agent({ keepAlive: false, maxSockets: 2, timeout: HUB_UPLOAD_TIMEOUT_MS });
|
|
6133
6134
|
function sleepMs(ms) {
|
|
6134
6135
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
6135
6136
|
}
|
|
@@ -6206,13 +6207,51 @@ function slimFindingForHubUpload(finding) {
|
|
|
6206
6207
|
file_path: finding.file_path,
|
|
6207
6208
|
line: finding.line,
|
|
6208
6209
|
detector_name: finding.detector_name,
|
|
6209
|
-
description: finding.description?.slice(0,
|
|
6210
|
-
match_text: finding.match_text?.slice(0, 120),
|
|
6210
|
+
description: finding.description?.slice(0, 160),
|
|
6211
6211
|
confidence_score: finding.confidence_score,
|
|
6212
6212
|
suppressed: finding.suppressed,
|
|
6213
6213
|
suppression_reason: finding.suppression_reason
|
|
6214
6214
|
};
|
|
6215
6215
|
}
|
|
6216
|
+
function buildSuppressedSummaryForHub(findings) {
|
|
6217
|
+
const byReason = {};
|
|
6218
|
+
const locations = [];
|
|
6219
|
+
for (const f of findings) {
|
|
6220
|
+
const reason = String(f.suppression_reason ?? "cognitive_suppressed");
|
|
6221
|
+
byReason[reason] = (byReason[reason] ?? 0) + 1;
|
|
6222
|
+
locations.push({
|
|
6223
|
+
file_path: f.file_path,
|
|
6224
|
+
line: f.line ?? 0,
|
|
6225
|
+
rule_id: f.rule_id,
|
|
6226
|
+
detector_name: f.detector_name,
|
|
6227
|
+
suppression_reason: reason,
|
|
6228
|
+
severity: f.severity
|
|
6229
|
+
});
|
|
6230
|
+
}
|
|
6231
|
+
return { total: findings.length, by_reason: byReason, locations };
|
|
6232
|
+
}
|
|
6233
|
+
function slimEngineSummaryForHub(engineSummary) {
|
|
6234
|
+
if (!engineSummary) return void 0;
|
|
6235
|
+
const pick = (row) => row ? {
|
|
6236
|
+
engine: row.engine,
|
|
6237
|
+
status: row.status,
|
|
6238
|
+
finding_count: row.finding_count,
|
|
6239
|
+
duration_ms: row.duration_ms
|
|
6240
|
+
} : void 0;
|
|
6241
|
+
return {
|
|
6242
|
+
concurrent_duration_ms: engineSummary.concurrent_duration_ms,
|
|
6243
|
+
semgrep: pick(engineSummary.semgrep),
|
|
6244
|
+
trufflehog: pick(engineSummary.trufflehog),
|
|
6245
|
+
syft: pick(engineSummary.syft)
|
|
6246
|
+
};
|
|
6247
|
+
}
|
|
6248
|
+
function slimReportMetricsForHub(reportMetrics) {
|
|
6249
|
+
const { findings_suppressed: _fs, raw_engines: _raw, engine_summary, ...rest } = reportMetrics;
|
|
6250
|
+
return {
|
|
6251
|
+
...rest,
|
|
6252
|
+
engine_summary: slimEngineSummaryForHub(engine_summary)
|
|
6253
|
+
};
|
|
6254
|
+
}
|
|
6216
6255
|
function slimRunsecJsonForHubUpload(result, reportMetrics, workspacePath, verdict, metrics, compliance, complianceASVS) {
|
|
6217
6256
|
return {
|
|
6218
6257
|
source: "runsec_mcp",
|
|
@@ -6222,14 +6261,15 @@ function slimRunsecJsonForHubUpload(result, reportMetrics, workspacePath, verdic
|
|
|
6222
6261
|
metrics,
|
|
6223
6262
|
compliance,
|
|
6224
6263
|
complianceASVS,
|
|
6225
|
-
report_metrics: reportMetrics,
|
|
6264
|
+
report_metrics: slimReportMetricsForHub(reportMetrics),
|
|
6226
6265
|
findings: result.findings.map(slimFindingForHubUpload),
|
|
6227
|
-
|
|
6266
|
+
findings_suppressed_summary: buildSuppressedSummaryForHub(result.findings_suppressed),
|
|
6267
|
+
findings_suppressed_count: result.findings_suppressed.length,
|
|
6228
6268
|
duration_ms: result.duration_ms,
|
|
6229
6269
|
findings_count: result.findings_count,
|
|
6230
6270
|
cognitive_suppressed_count: result.cognitive_suppressed_count,
|
|
6231
6271
|
engines: result.engines,
|
|
6232
|
-
engine_summary: result.engine_summary,
|
|
6272
|
+
engine_summary: slimEngineSummaryForHub(result.engine_summary),
|
|
6233
6273
|
cognitive: result.cognitive,
|
|
6234
6274
|
verdict_detail: result.verdict
|
|
6235
6275
|
};
|
|
@@ -6250,9 +6290,11 @@ function postHubUploadNodeHttp(url, apiKey, payload) {
|
|
|
6250
6290
|
reject(err);
|
|
6251
6291
|
return;
|
|
6252
6292
|
}
|
|
6293
|
+
const bodyBuffer = Buffer.from(body, "utf8");
|
|
6253
6294
|
const headers = {
|
|
6254
6295
|
...hubAuthHeaders(apiKey),
|
|
6255
|
-
"Content-Length": String(
|
|
6296
|
+
"Content-Length": String(bodyBuffer.length),
|
|
6297
|
+
Connection: "close"
|
|
6256
6298
|
};
|
|
6257
6299
|
const lib = parsed.protocol === "https:" ? import_node_https.default : import_node_http.default;
|
|
6258
6300
|
const port = parsed.port !== "" ? Number(parsed.port) : parsed.protocol === "https:" ? 443 : 80;
|
|
@@ -6287,27 +6329,33 @@ function postHubUploadNodeHttp(url, apiKey, payload) {
|
|
|
6287
6329
|
req.destroy();
|
|
6288
6330
|
reject(Object.assign(new Error("Hub upload request timeout"), { code: "ETIMEDOUT" }));
|
|
6289
6331
|
});
|
|
6290
|
-
|
|
6332
|
+
for (let offset = 0; offset < bodyBuffer.length; offset += HUB_WRITE_CHUNK_BYTES) {
|
|
6333
|
+
req.write(bodyBuffer.subarray(offset, offset + HUB_WRITE_CHUNK_BYTES));
|
|
6334
|
+
}
|
|
6291
6335
|
req.end();
|
|
6292
6336
|
});
|
|
6293
6337
|
}
|
|
6294
|
-
function
|
|
6295
|
-
|
|
6296
|
-
|
|
6297
|
-
|
|
6298
|
-
|
|
6338
|
+
async function postHubUploadFetch(url, apiKey, payload) {
|
|
6339
|
+
return await fetch(url, {
|
|
6340
|
+
method: "POST",
|
|
6341
|
+
headers: hubAuthHeaders(apiKey),
|
|
6342
|
+
body: JSON.stringify(payload),
|
|
6343
|
+
signal: AbortSignal.timeout(HUB_UPLOAD_TIMEOUT_MS)
|
|
6344
|
+
});
|
|
6299
6345
|
}
|
|
6300
6346
|
async function postHubUploadOnce(url, apiKey, payload) {
|
|
6301
|
-
|
|
6302
|
-
|
|
6347
|
+
const useNodeFirst = process.env.RUNSEC_HUB_USE_NODE_HTTP === "1";
|
|
6348
|
+
if (useNodeFirst) {
|
|
6349
|
+
try {
|
|
6350
|
+
return await postHubUploadNodeHttp(url, apiKey, payload);
|
|
6351
|
+
} catch (nodeError) {
|
|
6352
|
+
console.error("[runsec] node:http(s) upload failed \u2014 retrying with fetch()");
|
|
6353
|
+
dumpHubNetworkError(nodeError, url);
|
|
6354
|
+
return postHubUploadFetch(url, apiKey, payload);
|
|
6355
|
+
}
|
|
6303
6356
|
}
|
|
6304
6357
|
try {
|
|
6305
|
-
return await
|
|
6306
|
-
method: "POST",
|
|
6307
|
-
headers: hubAuthHeaders(apiKey),
|
|
6308
|
-
body: JSON.stringify(payload),
|
|
6309
|
-
signal: AbortSignal.timeout(HUB_UPLOAD_TIMEOUT_MS)
|
|
6310
|
-
});
|
|
6358
|
+
return await postHubUploadFetch(url, apiKey, payload);
|
|
6311
6359
|
} catch (fetchError) {
|
|
6312
6360
|
console.error("[runsec] fetch() failed \u2014 retrying Hub upload via node:http(s)");
|
|
6313
6361
|
dumpHubNetworkError(fetchError, url);
|