@probelabs/visor 0.1.181-ee → 0.1.181
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 +23 -1840
- package/dist/output/traces/run-2026-03-17T13-58-29-402Z.ndjson +157 -0
- package/dist/output/traces/run-2026-03-17T13-59-10-403Z.ndjson +2333 -0
- package/dist/sdk/a2a-frontend-IWOUJOIZ.mjs +1676 -0
- package/dist/sdk/a2a-frontend-IWOUJOIZ.mjs.map +1 -0
- package/dist/sdk/{check-provider-registry-Z7EHECLC.mjs → check-provider-registry-4YFVBGYU.mjs} +2 -2
- package/dist/sdk/check-provider-registry-67ZLGDDQ.mjs +31 -0
- package/dist/sdk/{chunk-6HLDM4OB.mjs → chunk-4DVP6KVC.mjs} +9 -9
- package/dist/sdk/{chunk-6HLDM4OB.mjs.map → chunk-4DVP6KVC.mjs.map} +1 -1
- package/dist/sdk/chunk-DGIH6EX3.mjs +520 -0
- package/dist/sdk/chunk-DGIH6EX3.mjs.map +1 -0
- package/dist/sdk/chunk-J73GEFPT.mjs +739 -0
- package/dist/sdk/chunk-J73GEFPT.mjs.map +1 -0
- package/dist/sdk/chunk-QGBASDYP.mjs +46153 -0
- package/dist/sdk/chunk-QGBASDYP.mjs.map +1 -0
- package/dist/sdk/chunk-VXC2XNQJ.mjs +1502 -0
- package/dist/sdk/chunk-VXC2XNQJ.mjs.map +1 -0
- package/dist/sdk/failure-condition-evaluator-HTPB5FYW.mjs +18 -0
- package/dist/sdk/github-frontend-3SDFCCKI.mjs +1394 -0
- package/dist/sdk/github-frontend-3SDFCCKI.mjs.map +1 -0
- package/dist/sdk/{host-6QBBL3QW.mjs → host-QE4L7UXE.mjs} +1 -1
- package/dist/sdk/host-VBBSLUWG.mjs +87 -0
- package/dist/sdk/host-VBBSLUWG.mjs.map +1 -0
- package/dist/sdk/routing-YVMTKFDZ.mjs +26 -0
- package/dist/sdk/schedule-tool-Z5VG67JK.mjs +37 -0
- package/dist/sdk/schedule-tool-Z5VG67JK.mjs.map +1 -0
- package/dist/sdk/{schedule-tool-5XBASQVY.mjs → schedule-tool-ZMX3Y7LF.mjs} +2 -2
- package/dist/sdk/schedule-tool-ZMX3Y7LF.mjs.map +1 -0
- package/dist/sdk/{schedule-tool-handler-GBIJS376.mjs → schedule-tool-handler-PCERK6ZZ.mjs} +2 -2
- package/dist/sdk/schedule-tool-handler-PCERK6ZZ.mjs.map +1 -0
- package/dist/sdk/schedule-tool-handler-QOJVFRB4.mjs +41 -0
- package/dist/sdk/schedule-tool-handler-QOJVFRB4.mjs.map +1 -0
- package/dist/sdk/sdk.js +289 -1663
- package/dist/sdk/sdk.js.map +1 -1
- package/dist/sdk/sdk.mjs +4 -4
- package/dist/sdk/trace-helpers-KXDOJWBL.mjs +29 -0
- package/dist/sdk/trace-helpers-KXDOJWBL.mjs.map +1 -0
- package/dist/sdk/{workflow-check-provider-3IXIADSV.mjs → workflow-check-provider-CJXW2Z4F.mjs} +2 -2
- package/dist/sdk/workflow-check-provider-CJXW2Z4F.mjs.map +1 -0
- package/dist/sdk/workflow-check-provider-NTHC5ZBF.mjs +31 -0
- package/dist/sdk/workflow-check-provider-NTHC5ZBF.mjs.map +1 -0
- package/dist/traces/run-2026-03-17T13-58-29-402Z.ndjson +157 -0
- package/dist/traces/run-2026-03-17T13-59-10-403Z.ndjson +2333 -0
- package/package.json +1 -1
- package/dist/sdk/knex-store-QCEW4I4R.mjs +0 -527
- package/dist/sdk/knex-store-QCEW4I4R.mjs.map +0 -1
- package/dist/sdk/loader-ZNKKJEZ3.mjs +0 -89
- package/dist/sdk/loader-ZNKKJEZ3.mjs.map +0 -1
- package/dist/sdk/opa-policy-engine-QCSSIMUF.mjs +0 -655
- package/dist/sdk/opa-policy-engine-QCSSIMUF.mjs.map +0 -1
- package/dist/sdk/validator-XTZJZZJH.mjs +0 -134
- package/dist/sdk/validator-XTZJZZJH.mjs.map +0 -1
- /package/dist/sdk/{check-provider-registry-Z7EHECLC.mjs.map → check-provider-registry-4YFVBGYU.mjs.map} +0 -0
- /package/dist/sdk/{schedule-tool-5XBASQVY.mjs.map → check-provider-registry-67ZLGDDQ.mjs.map} +0 -0
- /package/dist/sdk/{schedule-tool-handler-GBIJS376.mjs.map → failure-condition-evaluator-HTPB5FYW.mjs.map} +0 -0
- /package/dist/sdk/{host-6QBBL3QW.mjs.map → host-QE4L7UXE.mjs.map} +0 -0
- /package/dist/sdk/{workflow-check-provider-3IXIADSV.mjs.map → routing-YVMTKFDZ.mjs.map} +0 -0
package/dist/sdk/sdk.js
CHANGED
|
@@ -704,7 +704,7 @@ var require_package = __commonJS({
|
|
|
704
704
|
"package.json"(exports2, module2) {
|
|
705
705
|
module2.exports = {
|
|
706
706
|
name: "@probelabs/visor",
|
|
707
|
-
version: "0.1.
|
|
707
|
+
version: "0.1.181",
|
|
708
708
|
main: "dist/index.js",
|
|
709
709
|
bin: {
|
|
710
710
|
visor: "./dist/index.js"
|
|
@@ -1156,11 +1156,11 @@ function getTracer() {
|
|
|
1156
1156
|
}
|
|
1157
1157
|
async function withActiveSpan(name, attrs, fn) {
|
|
1158
1158
|
const tracer = getTracer();
|
|
1159
|
-
return await new Promise((
|
|
1159
|
+
return await new Promise((resolve17, reject) => {
|
|
1160
1160
|
const callback = async (span) => {
|
|
1161
1161
|
try {
|
|
1162
1162
|
const res = await fn(span);
|
|
1163
|
-
|
|
1163
|
+
resolve17(res);
|
|
1164
1164
|
} catch (err) {
|
|
1165
1165
|
try {
|
|
1166
1166
|
if (err instanceof Error) span.recordException(err);
|
|
@@ -1285,19 +1285,19 @@ function __getOrCreateNdjsonPath() {
|
|
|
1285
1285
|
try {
|
|
1286
1286
|
if (process.env.VISOR_TELEMETRY_SINK && process.env.VISOR_TELEMETRY_SINK !== "file")
|
|
1287
1287
|
return null;
|
|
1288
|
-
const
|
|
1289
|
-
const
|
|
1288
|
+
const path30 = require("path");
|
|
1289
|
+
const fs27 = require("fs");
|
|
1290
1290
|
if (process.env.VISOR_FALLBACK_TRACE_FILE) {
|
|
1291
1291
|
__ndjsonPath = process.env.VISOR_FALLBACK_TRACE_FILE;
|
|
1292
|
-
const dir =
|
|
1293
|
-
if (!
|
|
1292
|
+
const dir = path30.dirname(__ndjsonPath);
|
|
1293
|
+
if (!fs27.existsSync(dir)) fs27.mkdirSync(dir, { recursive: true });
|
|
1294
1294
|
return __ndjsonPath;
|
|
1295
1295
|
}
|
|
1296
|
-
const outDir = process.env.VISOR_TRACE_DIR ||
|
|
1297
|
-
if (!
|
|
1296
|
+
const outDir = process.env.VISOR_TRACE_DIR || path30.join(process.cwd(), "output", "traces");
|
|
1297
|
+
if (!fs27.existsSync(outDir)) fs27.mkdirSync(outDir, { recursive: true });
|
|
1298
1298
|
if (!__ndjsonPath) {
|
|
1299
1299
|
const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
1300
|
-
__ndjsonPath =
|
|
1300
|
+
__ndjsonPath = path30.join(outDir, `${ts}.ndjson`);
|
|
1301
1301
|
}
|
|
1302
1302
|
return __ndjsonPath;
|
|
1303
1303
|
} catch {
|
|
@@ -1306,11 +1306,11 @@ function __getOrCreateNdjsonPath() {
|
|
|
1306
1306
|
}
|
|
1307
1307
|
function _appendRunMarker() {
|
|
1308
1308
|
try {
|
|
1309
|
-
const
|
|
1309
|
+
const fs27 = require("fs");
|
|
1310
1310
|
const p = __getOrCreateNdjsonPath();
|
|
1311
1311
|
if (!p) return;
|
|
1312
1312
|
const line = { name: "visor.run", attributes: { started: true } };
|
|
1313
|
-
|
|
1313
|
+
fs27.appendFileSync(p, JSON.stringify(line) + "\n", "utf8");
|
|
1314
1314
|
} catch {
|
|
1315
1315
|
}
|
|
1316
1316
|
}
|
|
@@ -3397,7 +3397,7 @@ var init_failure_condition_evaluator = __esm({
|
|
|
3397
3397
|
*/
|
|
3398
3398
|
evaluateExpression(condition, context2) {
|
|
3399
3399
|
try {
|
|
3400
|
-
const
|
|
3400
|
+
const normalize5 = (expr) => {
|
|
3401
3401
|
const trimmed = expr.trim();
|
|
3402
3402
|
if (!/[\n;]/.test(trimmed)) return trimmed;
|
|
3403
3403
|
const parts = trimmed.split(/[\n;]+/).map((s) => s.trim()).filter((s) => s.length > 0 && !s.startsWith("//"));
|
|
@@ -3555,7 +3555,7 @@ var init_failure_condition_evaluator = __esm({
|
|
|
3555
3555
|
try {
|
|
3556
3556
|
exec2 = this.sandbox.compile(`return (${raw});`);
|
|
3557
3557
|
} catch {
|
|
3558
|
-
const normalizedExpr =
|
|
3558
|
+
const normalizedExpr = normalize5(condition);
|
|
3559
3559
|
exec2 = this.sandbox.compile(`return (${normalizedExpr});`);
|
|
3560
3560
|
}
|
|
3561
3561
|
const result = exec2(scope).run();
|
|
@@ -3938,9 +3938,9 @@ function configureLiquidWithExtensions(liquid) {
|
|
|
3938
3938
|
});
|
|
3939
3939
|
liquid.registerFilter("get", (obj, pathExpr) => {
|
|
3940
3940
|
if (obj == null) return void 0;
|
|
3941
|
-
const
|
|
3942
|
-
if (!
|
|
3943
|
-
const parts =
|
|
3941
|
+
const path30 = typeof pathExpr === "string" ? pathExpr : String(pathExpr || "");
|
|
3942
|
+
if (!path30) return obj;
|
|
3943
|
+
const parts = path30.split(".");
|
|
3944
3944
|
let cur = obj;
|
|
3945
3945
|
for (const p of parts) {
|
|
3946
3946
|
if (cur == null) return void 0;
|
|
@@ -4059,9 +4059,9 @@ function configureLiquidWithExtensions(liquid) {
|
|
|
4059
4059
|
}
|
|
4060
4060
|
}
|
|
4061
4061
|
const defaultRole = typeof rolesCfg.default === "string" && rolesCfg.default.trim() ? rolesCfg.default.trim() : void 0;
|
|
4062
|
-
const getNested = (obj,
|
|
4063
|
-
if (!obj || !
|
|
4064
|
-
const parts =
|
|
4062
|
+
const getNested = (obj, path30) => {
|
|
4063
|
+
if (!obj || !path30) return void 0;
|
|
4064
|
+
const parts = path30.split(".");
|
|
4065
4065
|
let cur = obj;
|
|
4066
4066
|
for (const p of parts) {
|
|
4067
4067
|
if (cur == null) return void 0;
|
|
@@ -7834,8 +7834,8 @@ var init_dependency_gating = __esm({
|
|
|
7834
7834
|
async function renderTemplateContent(checkId, checkConfig, reviewSummary) {
|
|
7835
7835
|
try {
|
|
7836
7836
|
const { createExtendedLiquid: createExtendedLiquid2 } = await Promise.resolve().then(() => (init_liquid_extensions(), liquid_extensions_exports));
|
|
7837
|
-
const
|
|
7838
|
-
const
|
|
7837
|
+
const fs27 = await import("fs/promises");
|
|
7838
|
+
const path30 = await import("path");
|
|
7839
7839
|
const schemaRaw = checkConfig.schema || "plain";
|
|
7840
7840
|
const schema = typeof schemaRaw === "string" ? schemaRaw : "code-review";
|
|
7841
7841
|
let templateContent;
|
|
@@ -7844,25 +7844,25 @@ async function renderTemplateContent(checkId, checkConfig, reviewSummary) {
|
|
|
7844
7844
|
logger.debug(`[TemplateRenderer] Using inline template for ${checkId}`);
|
|
7845
7845
|
} else if (checkConfig.template && checkConfig.template.file) {
|
|
7846
7846
|
const file = String(checkConfig.template.file);
|
|
7847
|
-
const resolved =
|
|
7848
|
-
templateContent = await
|
|
7847
|
+
const resolved = path30.resolve(process.cwd(), file);
|
|
7848
|
+
templateContent = await fs27.readFile(resolved, "utf-8");
|
|
7849
7849
|
logger.debug(`[TemplateRenderer] Using template file for ${checkId}: ${resolved}`);
|
|
7850
7850
|
} else if (schema && schema !== "plain") {
|
|
7851
7851
|
const sanitized = String(schema).replace(/[^a-zA-Z0-9-]/g, "");
|
|
7852
7852
|
if (sanitized) {
|
|
7853
7853
|
const candidatePaths = [
|
|
7854
|
-
|
|
7854
|
+
path30.join(__dirname, "output", sanitized, "template.liquid"),
|
|
7855
7855
|
// bundled: dist/output/
|
|
7856
|
-
|
|
7856
|
+
path30.join(__dirname, "..", "..", "output", sanitized, "template.liquid"),
|
|
7857
7857
|
// source: output/
|
|
7858
|
-
|
|
7858
|
+
path30.join(process.cwd(), "output", sanitized, "template.liquid"),
|
|
7859
7859
|
// fallback: cwd/output/
|
|
7860
|
-
|
|
7860
|
+
path30.join(process.cwd(), "dist", "output", sanitized, "template.liquid")
|
|
7861
7861
|
// fallback: cwd/dist/output/
|
|
7862
7862
|
];
|
|
7863
7863
|
for (const p of candidatePaths) {
|
|
7864
7864
|
try {
|
|
7865
|
-
templateContent = await
|
|
7865
|
+
templateContent = await fs27.readFile(p, "utf-8");
|
|
7866
7866
|
if (templateContent) {
|
|
7867
7867
|
logger.debug(`[TemplateRenderer] Using schema template for ${checkId}: ${p}`);
|
|
7868
7868
|
break;
|
|
@@ -8284,7 +8284,7 @@ async function processDiffWithOutline(diffContent) {
|
|
|
8284
8284
|
}
|
|
8285
8285
|
try {
|
|
8286
8286
|
const originalProbePath = process.env.PROBE_PATH;
|
|
8287
|
-
const
|
|
8287
|
+
const fs27 = require("fs");
|
|
8288
8288
|
const possiblePaths = [
|
|
8289
8289
|
// Relative to current working directory (most common in production)
|
|
8290
8290
|
path6.join(process.cwd(), "node_modules/@probelabs/probe/bin/probe-binary"),
|
|
@@ -8295,7 +8295,7 @@ async function processDiffWithOutline(diffContent) {
|
|
|
8295
8295
|
];
|
|
8296
8296
|
let probeBinaryPath;
|
|
8297
8297
|
for (const candidatePath of possiblePaths) {
|
|
8298
|
-
if (
|
|
8298
|
+
if (fs27.existsSync(candidatePath)) {
|
|
8299
8299
|
probeBinaryPath = candidatePath;
|
|
8300
8300
|
break;
|
|
8301
8301
|
}
|
|
@@ -8402,7 +8402,7 @@ async function renderMermaidToPng(mermaidCode) {
|
|
|
8402
8402
|
if (chromiumPath) {
|
|
8403
8403
|
env.PUPPETEER_EXECUTABLE_PATH = chromiumPath;
|
|
8404
8404
|
}
|
|
8405
|
-
const result = await new Promise((
|
|
8405
|
+
const result = await new Promise((resolve17) => {
|
|
8406
8406
|
const proc = (0, import_child_process6.spawn)(
|
|
8407
8407
|
"npx",
|
|
8408
8408
|
[
|
|
@@ -8432,13 +8432,13 @@ async function renderMermaidToPng(mermaidCode) {
|
|
|
8432
8432
|
});
|
|
8433
8433
|
proc.on("close", (code) => {
|
|
8434
8434
|
if (code === 0) {
|
|
8435
|
-
|
|
8435
|
+
resolve17({ success: true });
|
|
8436
8436
|
} else {
|
|
8437
|
-
|
|
8437
|
+
resolve17({ success: false, error: stderr || `Exit code ${code}` });
|
|
8438
8438
|
}
|
|
8439
8439
|
});
|
|
8440
8440
|
proc.on("error", (err) => {
|
|
8441
|
-
|
|
8441
|
+
resolve17({ success: false, error: err.message });
|
|
8442
8442
|
});
|
|
8443
8443
|
});
|
|
8444
8444
|
if (!result.success) {
|
|
@@ -9810,8 +9810,8 @@ ${schemaString}`);
|
|
|
9810
9810
|
}
|
|
9811
9811
|
if (process.env.VISOR_DEBUG_AI_SESSIONS === "true") {
|
|
9812
9812
|
try {
|
|
9813
|
-
const
|
|
9814
|
-
const
|
|
9813
|
+
const fs27 = require("fs");
|
|
9814
|
+
const path30 = require("path");
|
|
9815
9815
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
9816
9816
|
const provider = this.config.provider || "auto";
|
|
9817
9817
|
const model = this.config.model || "default";
|
|
@@ -9925,20 +9925,20 @@ ${"=".repeat(60)}
|
|
|
9925
9925
|
`;
|
|
9926
9926
|
readableVersion += `${"=".repeat(60)}
|
|
9927
9927
|
`;
|
|
9928
|
-
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS ||
|
|
9929
|
-
if (!
|
|
9930
|
-
|
|
9928
|
+
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path30.join(process.cwd(), "debug-artifacts");
|
|
9929
|
+
if (!fs27.existsSync(debugArtifactsDir)) {
|
|
9930
|
+
fs27.mkdirSync(debugArtifactsDir, { recursive: true });
|
|
9931
9931
|
}
|
|
9932
|
-
const debugFile =
|
|
9932
|
+
const debugFile = path30.join(
|
|
9933
9933
|
debugArtifactsDir,
|
|
9934
9934
|
`prompt-${_checkName || "unknown"}-${timestamp}.json`
|
|
9935
9935
|
);
|
|
9936
|
-
|
|
9937
|
-
const readableFile =
|
|
9936
|
+
fs27.writeFileSync(debugFile, debugJson, "utf-8");
|
|
9937
|
+
const readableFile = path30.join(
|
|
9938
9938
|
debugArtifactsDir,
|
|
9939
9939
|
`prompt-${_checkName || "unknown"}-${timestamp}.txt`
|
|
9940
9940
|
);
|
|
9941
|
-
|
|
9941
|
+
fs27.writeFileSync(readableFile, readableVersion, "utf-8");
|
|
9942
9942
|
log(`
|
|
9943
9943
|
\u{1F4BE} Full debug info saved to:`);
|
|
9944
9944
|
log(` JSON: ${debugFile}`);
|
|
@@ -9976,8 +9976,8 @@ ${"=".repeat(60)}
|
|
|
9976
9976
|
log(`\u{1F4E4} Response length: ${response.length} characters`);
|
|
9977
9977
|
if (process.env.VISOR_DEBUG_AI_SESSIONS === "true") {
|
|
9978
9978
|
try {
|
|
9979
|
-
const
|
|
9980
|
-
const
|
|
9979
|
+
const fs27 = require("fs");
|
|
9980
|
+
const path30 = require("path");
|
|
9981
9981
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
9982
9982
|
const agentAny2 = agent;
|
|
9983
9983
|
let fullHistory = [];
|
|
@@ -9988,8 +9988,8 @@ ${"=".repeat(60)}
|
|
|
9988
9988
|
} else if (agentAny2._messages) {
|
|
9989
9989
|
fullHistory = agentAny2._messages;
|
|
9990
9990
|
}
|
|
9991
|
-
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS ||
|
|
9992
|
-
const sessionBase =
|
|
9991
|
+
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path30.join(process.cwd(), "debug-artifacts");
|
|
9992
|
+
const sessionBase = path30.join(
|
|
9993
9993
|
debugArtifactsDir,
|
|
9994
9994
|
`session-${_checkName || "unknown"}-${timestamp}`
|
|
9995
9995
|
);
|
|
@@ -10001,7 +10001,7 @@ ${"=".repeat(60)}
|
|
|
10001
10001
|
schema: effectiveSchema,
|
|
10002
10002
|
totalMessages: fullHistory.length
|
|
10003
10003
|
};
|
|
10004
|
-
|
|
10004
|
+
fs27.writeFileSync(sessionBase + ".json", JSON.stringify(sessionData, null, 2), "utf-8");
|
|
10005
10005
|
let readable = `=============================================================
|
|
10006
10006
|
`;
|
|
10007
10007
|
readable += `COMPLETE AI SESSION HISTORY (AFTER RESPONSE)
|
|
@@ -10028,7 +10028,7 @@ ${"=".repeat(60)}
|
|
|
10028
10028
|
`;
|
|
10029
10029
|
readable += content + "\n";
|
|
10030
10030
|
});
|
|
10031
|
-
|
|
10031
|
+
fs27.writeFileSync(sessionBase + ".summary.txt", readable, "utf-8");
|
|
10032
10032
|
log(`\u{1F4BE} Complete session history saved:`);
|
|
10033
10033
|
log(` - Contains ALL ${fullHistory.length} messages (prompts + responses)`);
|
|
10034
10034
|
} catch (error) {
|
|
@@ -10037,11 +10037,11 @@ ${"=".repeat(60)}
|
|
|
10037
10037
|
}
|
|
10038
10038
|
if (process.env.VISOR_DEBUG_AI_SESSIONS === "true") {
|
|
10039
10039
|
try {
|
|
10040
|
-
const
|
|
10041
|
-
const
|
|
10040
|
+
const fs27 = require("fs");
|
|
10041
|
+
const path30 = require("path");
|
|
10042
10042
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
10043
|
-
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS ||
|
|
10044
|
-
const responseFile =
|
|
10043
|
+
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path30.join(process.cwd(), "debug-artifacts");
|
|
10044
|
+
const responseFile = path30.join(
|
|
10045
10045
|
debugArtifactsDir,
|
|
10046
10046
|
`response-${_checkName || "unknown"}-${timestamp}.txt`
|
|
10047
10047
|
);
|
|
@@ -10074,7 +10074,7 @@ ${"=".repeat(60)}
|
|
|
10074
10074
|
`;
|
|
10075
10075
|
responseContent += `${"=".repeat(60)}
|
|
10076
10076
|
`;
|
|
10077
|
-
|
|
10077
|
+
fs27.writeFileSync(responseFile, responseContent, "utf-8");
|
|
10078
10078
|
log(`\u{1F4BE} Response saved to: ${responseFile}`);
|
|
10079
10079
|
} catch (error) {
|
|
10080
10080
|
log(`\u26A0\uFE0F Could not save response file: ${error}`);
|
|
@@ -10090,9 +10090,9 @@ ${"=".repeat(60)}
|
|
|
10090
10090
|
await agentAny._telemetryConfig.shutdown();
|
|
10091
10091
|
log(`\u{1F4CA} OpenTelemetry trace saved to: ${agentAny._traceFilePath}`);
|
|
10092
10092
|
if (process.env.GITHUB_ACTIONS) {
|
|
10093
|
-
const
|
|
10094
|
-
if (
|
|
10095
|
-
const stats =
|
|
10093
|
+
const fs27 = require("fs");
|
|
10094
|
+
if (fs27.existsSync(agentAny._traceFilePath)) {
|
|
10095
|
+
const stats = fs27.statSync(agentAny._traceFilePath);
|
|
10096
10096
|
console.log(
|
|
10097
10097
|
`::notice title=AI Trace Saved::${agentAny._traceFilePath} (${stats.size} bytes)`
|
|
10098
10098
|
);
|
|
@@ -10353,9 +10353,9 @@ ${schemaString}`);
|
|
|
10353
10353
|
const model = this.config.model || "default";
|
|
10354
10354
|
if (process.env.VISOR_DEBUG_AI_SESSIONS === "true") {
|
|
10355
10355
|
try {
|
|
10356
|
-
const
|
|
10357
|
-
const
|
|
10358
|
-
const
|
|
10356
|
+
const fs27 = require("fs");
|
|
10357
|
+
const path30 = require("path");
|
|
10358
|
+
const os2 = require("os");
|
|
10359
10359
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
10360
10360
|
const debugData = {
|
|
10361
10361
|
timestamp,
|
|
@@ -10427,19 +10427,19 @@ ${"=".repeat(60)}
|
|
|
10427
10427
|
`;
|
|
10428
10428
|
readableVersion += `${"=".repeat(60)}
|
|
10429
10429
|
`;
|
|
10430
|
-
const tempDir =
|
|
10431
|
-
const promptFile =
|
|
10432
|
-
|
|
10430
|
+
const tempDir = os2.tmpdir();
|
|
10431
|
+
const promptFile = path30.join(tempDir, `visor-prompt-${timestamp}.txt`);
|
|
10432
|
+
fs27.writeFileSync(promptFile, prompt, "utf-8");
|
|
10433
10433
|
log(`
|
|
10434
10434
|
\u{1F4BE} Prompt saved to: ${promptFile}`);
|
|
10435
|
-
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS ||
|
|
10435
|
+
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path30.join(process.cwd(), "debug-artifacts");
|
|
10436
10436
|
try {
|
|
10437
|
-
const base =
|
|
10437
|
+
const base = path30.join(
|
|
10438
10438
|
debugArtifactsDir,
|
|
10439
10439
|
`prompt-${_checkName || "unknown"}-${timestamp}`
|
|
10440
10440
|
);
|
|
10441
|
-
|
|
10442
|
-
|
|
10441
|
+
fs27.writeFileSync(base + ".json", debugJson, "utf-8");
|
|
10442
|
+
fs27.writeFileSync(base + ".summary.txt", readableVersion, "utf-8");
|
|
10443
10443
|
log(`
|
|
10444
10444
|
\u{1F4BE} Full debug info saved to directory: ${debugArtifactsDir}`);
|
|
10445
10445
|
} catch {
|
|
@@ -10489,8 +10489,8 @@ $ ${cliCommand}
|
|
|
10489
10489
|
log(`\u{1F4E4} Response length: ${response.length} characters`);
|
|
10490
10490
|
if (process.env.VISOR_DEBUG_AI_SESSIONS === "true") {
|
|
10491
10491
|
try {
|
|
10492
|
-
const
|
|
10493
|
-
const
|
|
10492
|
+
const fs27 = require("fs");
|
|
10493
|
+
const path30 = require("path");
|
|
10494
10494
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
10495
10495
|
const agentAny = agent;
|
|
10496
10496
|
let fullHistory = [];
|
|
@@ -10501,8 +10501,8 @@ $ ${cliCommand}
|
|
|
10501
10501
|
} else if (agentAny._messages) {
|
|
10502
10502
|
fullHistory = agentAny._messages;
|
|
10503
10503
|
}
|
|
10504
|
-
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS ||
|
|
10505
|
-
const sessionBase =
|
|
10504
|
+
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path30.join(process.cwd(), "debug-artifacts");
|
|
10505
|
+
const sessionBase = path30.join(
|
|
10506
10506
|
debugArtifactsDir,
|
|
10507
10507
|
`session-${_checkName || "unknown"}-${timestamp}`
|
|
10508
10508
|
);
|
|
@@ -10514,7 +10514,7 @@ $ ${cliCommand}
|
|
|
10514
10514
|
schema: effectiveSchema,
|
|
10515
10515
|
totalMessages: fullHistory.length
|
|
10516
10516
|
};
|
|
10517
|
-
|
|
10517
|
+
fs27.writeFileSync(sessionBase + ".json", JSON.stringify(sessionData, null, 2), "utf-8");
|
|
10518
10518
|
let readable = `=============================================================
|
|
10519
10519
|
`;
|
|
10520
10520
|
readable += `COMPLETE AI SESSION HISTORY (AFTER RESPONSE)
|
|
@@ -10541,7 +10541,7 @@ ${"=".repeat(60)}
|
|
|
10541
10541
|
`;
|
|
10542
10542
|
readable += content + "\n";
|
|
10543
10543
|
});
|
|
10544
|
-
|
|
10544
|
+
fs27.writeFileSync(sessionBase + ".summary.txt", readable, "utf-8");
|
|
10545
10545
|
log(`\u{1F4BE} Complete session history saved:`);
|
|
10546
10546
|
log(` - Contains ALL ${fullHistory.length} messages (prompts + responses)`);
|
|
10547
10547
|
} catch (error) {
|
|
@@ -10550,11 +10550,11 @@ ${"=".repeat(60)}
|
|
|
10550
10550
|
}
|
|
10551
10551
|
if (process.env.VISOR_DEBUG_AI_SESSIONS === "true") {
|
|
10552
10552
|
try {
|
|
10553
|
-
const
|
|
10554
|
-
const
|
|
10553
|
+
const fs27 = require("fs");
|
|
10554
|
+
const path30 = require("path");
|
|
10555
10555
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
10556
|
-
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS ||
|
|
10557
|
-
const responseFile =
|
|
10556
|
+
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path30.join(process.cwd(), "debug-artifacts");
|
|
10557
|
+
const responseFile = path30.join(
|
|
10558
10558
|
debugArtifactsDir,
|
|
10559
10559
|
`response-${_checkName || "unknown"}-${timestamp}.txt`
|
|
10560
10560
|
);
|
|
@@ -10587,7 +10587,7 @@ ${"=".repeat(60)}
|
|
|
10587
10587
|
`;
|
|
10588
10588
|
responseContent += `${"=".repeat(60)}
|
|
10589
10589
|
`;
|
|
10590
|
-
|
|
10590
|
+
fs27.writeFileSync(responseFile, responseContent, "utf-8");
|
|
10591
10591
|
log(`\u{1F4BE} Response saved to: ${responseFile}`);
|
|
10592
10592
|
} catch (error) {
|
|
10593
10593
|
log(`\u26A0\uFE0F Could not save response file: ${error}`);
|
|
@@ -10605,9 +10605,9 @@ ${"=".repeat(60)}
|
|
|
10605
10605
|
await telemetry.shutdown();
|
|
10606
10606
|
log(`\u{1F4CA} OpenTelemetry trace saved to: ${traceFilePath}`);
|
|
10607
10607
|
if (process.env.GITHUB_ACTIONS) {
|
|
10608
|
-
const
|
|
10609
|
-
if (
|
|
10610
|
-
const stats =
|
|
10608
|
+
const fs27 = require("fs");
|
|
10609
|
+
if (fs27.existsSync(traceFilePath)) {
|
|
10610
|
+
const stats = fs27.statSync(traceFilePath);
|
|
10611
10611
|
console.log(
|
|
10612
10612
|
`::notice title=AI Trace Saved::OpenTelemetry trace file size: ${stats.size} bytes`
|
|
10613
10613
|
);
|
|
@@ -10645,8 +10645,8 @@ ${"=".repeat(60)}
|
|
|
10645
10645
|
* Load schema content from schema files or inline definitions
|
|
10646
10646
|
*/
|
|
10647
10647
|
async loadSchemaContent(schema) {
|
|
10648
|
-
const
|
|
10649
|
-
const
|
|
10648
|
+
const fs27 = require("fs").promises;
|
|
10649
|
+
const path30 = require("path");
|
|
10650
10650
|
if (typeof schema === "object" && schema !== null) {
|
|
10651
10651
|
log("\u{1F4CB} Using inline schema object from configuration");
|
|
10652
10652
|
return JSON.stringify(schema);
|
|
@@ -10659,14 +10659,14 @@ ${"=".repeat(60)}
|
|
|
10659
10659
|
}
|
|
10660
10660
|
} catch {
|
|
10661
10661
|
}
|
|
10662
|
-
if ((schema.startsWith("./") || schema.includes(".json")) && !
|
|
10662
|
+
if ((schema.startsWith("./") || schema.includes(".json")) && !path30.isAbsolute(schema)) {
|
|
10663
10663
|
if (schema.includes("..") || schema.includes("\0")) {
|
|
10664
10664
|
throw new Error("Invalid schema path: path traversal not allowed");
|
|
10665
10665
|
}
|
|
10666
10666
|
try {
|
|
10667
|
-
const schemaPath =
|
|
10667
|
+
const schemaPath = path30.resolve(process.cwd(), schema);
|
|
10668
10668
|
log(`\u{1F4CB} Loading custom schema from file: ${schemaPath}`);
|
|
10669
|
-
const schemaContent = await
|
|
10669
|
+
const schemaContent = await fs27.readFile(schemaPath, "utf-8");
|
|
10670
10670
|
return schemaContent.trim();
|
|
10671
10671
|
} catch (error) {
|
|
10672
10672
|
throw new Error(
|
|
@@ -10680,22 +10680,22 @@ ${"=".repeat(60)}
|
|
|
10680
10680
|
}
|
|
10681
10681
|
const candidatePaths = [
|
|
10682
10682
|
// GitHub Action bundle location
|
|
10683
|
-
|
|
10683
|
+
path30.join(__dirname, "output", sanitizedSchemaName, "schema.json"),
|
|
10684
10684
|
// Historical fallback when src/output was inadvertently bundled as output1/
|
|
10685
|
-
|
|
10685
|
+
path30.join(__dirname, "output1", sanitizedSchemaName, "schema.json"),
|
|
10686
10686
|
// Local dev (repo root)
|
|
10687
|
-
|
|
10687
|
+
path30.join(process.cwd(), "output", sanitizedSchemaName, "schema.json")
|
|
10688
10688
|
];
|
|
10689
10689
|
for (const schemaPath of candidatePaths) {
|
|
10690
10690
|
try {
|
|
10691
|
-
const schemaContent = await
|
|
10691
|
+
const schemaContent = await fs27.readFile(schemaPath, "utf-8");
|
|
10692
10692
|
return schemaContent.trim();
|
|
10693
10693
|
} catch {
|
|
10694
10694
|
}
|
|
10695
10695
|
}
|
|
10696
|
-
const distPath =
|
|
10697
|
-
const distAltPath =
|
|
10698
|
-
const cwdPath =
|
|
10696
|
+
const distPath = path30.join(__dirname, "output", sanitizedSchemaName, "schema.json");
|
|
10697
|
+
const distAltPath = path30.join(__dirname, "output1", sanitizedSchemaName, "schema.json");
|
|
10698
|
+
const cwdPath = path30.join(process.cwd(), "output", sanitizedSchemaName, "schema.json");
|
|
10699
10699
|
throw new Error(
|
|
10700
10700
|
`Failed to load schema '${sanitizedSchemaName}'. Tried: ${distPath}, ${distAltPath}, and ${cwdPath}. Ensure build copies 'output/' into dist (build:cli), or provide a custom schema file/path.`
|
|
10701
10701
|
);
|
|
@@ -10937,7 +10937,7 @@ ${"=".repeat(60)}
|
|
|
10937
10937
|
* Generate mock response for testing
|
|
10938
10938
|
*/
|
|
10939
10939
|
async generateMockResponse(_prompt, _checkName, _schema) {
|
|
10940
|
-
await new Promise((
|
|
10940
|
+
await new Promise((resolve17) => setTimeout(resolve17, 500));
|
|
10941
10941
|
const name = (_checkName || "").toLowerCase();
|
|
10942
10942
|
if (name.includes("extract-facts")) {
|
|
10943
10943
|
const arr = Array.from({ length: 6 }, (_, i) => ({
|
|
@@ -11298,7 +11298,7 @@ var init_command_executor = __esm({
|
|
|
11298
11298
|
* Execute command with stdin input
|
|
11299
11299
|
*/
|
|
11300
11300
|
executeWithStdin(command, options) {
|
|
11301
|
-
return new Promise((
|
|
11301
|
+
return new Promise((resolve17, reject) => {
|
|
11302
11302
|
const childProcess = (0, import_child_process7.exec)(
|
|
11303
11303
|
command,
|
|
11304
11304
|
{
|
|
@@ -11310,7 +11310,7 @@ var init_command_executor = __esm({
|
|
|
11310
11310
|
if (error && error.killed && (error.code === "ETIMEDOUT" || error.signal === "SIGTERM")) {
|
|
11311
11311
|
reject(new Error(`Command timed out after ${options.timeout || 3e4}ms`));
|
|
11312
11312
|
} else {
|
|
11313
|
-
|
|
11313
|
+
resolve17({
|
|
11314
11314
|
stdout: stdout || "",
|
|
11315
11315
|
stderr: stderr || "",
|
|
11316
11316
|
exitCode: error ? error.code || 1 : 0
|
|
@@ -11439,7 +11439,7 @@ async function rateLimitedFetch(url, options, rateLimitConfig) {
|
|
|
11439
11439
|
logger.verbose(
|
|
11440
11440
|
`[rate-limiter] 429 on ${url} (bucket: ${key}), retry ${attempt + 1}/${maxRetries} in ${delayMs}ms`
|
|
11441
11441
|
);
|
|
11442
|
-
await new Promise((
|
|
11442
|
+
await new Promise((resolve17) => setTimeout(resolve17, delayMs));
|
|
11443
11443
|
}
|
|
11444
11444
|
return fetch(url, options);
|
|
11445
11445
|
}
|
|
@@ -11488,8 +11488,8 @@ var init_rate_limiter = __esm({
|
|
|
11488
11488
|
return;
|
|
11489
11489
|
}
|
|
11490
11490
|
const waitMs = Math.ceil((1 - this.tokens) / this.refillRate);
|
|
11491
|
-
return new Promise((
|
|
11492
|
-
const entry = { resolve:
|
|
11491
|
+
return new Promise((resolve17) => {
|
|
11492
|
+
const entry = { resolve: resolve17 };
|
|
11493
11493
|
this.waitQueue.push(entry);
|
|
11494
11494
|
setTimeout(() => {
|
|
11495
11495
|
const idx = this.waitQueue.indexOf(entry);
|
|
@@ -11500,7 +11500,7 @@ var init_rate_limiter = __esm({
|
|
|
11500
11500
|
if (this.tokens >= 1) {
|
|
11501
11501
|
this.tokens -= 1;
|
|
11502
11502
|
}
|
|
11503
|
-
|
|
11503
|
+
resolve17();
|
|
11504
11504
|
}, waitMs);
|
|
11505
11505
|
});
|
|
11506
11506
|
}
|
|
@@ -20466,17 +20466,17 @@ var init_workflow_check_provider = __esm({
|
|
|
20466
20466
|
* so it can be executed by the state machine as a nested workflow.
|
|
20467
20467
|
*/
|
|
20468
20468
|
async loadWorkflowFromConfigPath(sourcePath, baseDir) {
|
|
20469
|
-
const
|
|
20470
|
-
const
|
|
20469
|
+
const path30 = require("path");
|
|
20470
|
+
const fs27 = require("fs");
|
|
20471
20471
|
const yaml6 = require("js-yaml");
|
|
20472
|
-
const resolved =
|
|
20473
|
-
if (!
|
|
20472
|
+
const resolved = path30.isAbsolute(sourcePath) ? sourcePath : path30.resolve(baseDir, sourcePath);
|
|
20473
|
+
if (!fs27.existsSync(resolved)) {
|
|
20474
20474
|
throw new Error(`Workflow config not found at: ${resolved}`);
|
|
20475
20475
|
}
|
|
20476
|
-
const rawContent =
|
|
20476
|
+
const rawContent = fs27.readFileSync(resolved, "utf8");
|
|
20477
20477
|
const rawData = yaml6.load(rawContent);
|
|
20478
20478
|
if (rawData.imports && Array.isArray(rawData.imports)) {
|
|
20479
|
-
const configDir =
|
|
20479
|
+
const configDir = path30.dirname(resolved);
|
|
20480
20480
|
for (const source of rawData.imports) {
|
|
20481
20481
|
const results = await this.registry.import(source, {
|
|
20482
20482
|
basePath: configDir,
|
|
@@ -20506,8 +20506,8 @@ ${errors}`);
|
|
|
20506
20506
|
if (!steps || Object.keys(steps).length === 0) {
|
|
20507
20507
|
throw new Error(`Config '${resolved}' does not contain any steps to execute as a workflow`);
|
|
20508
20508
|
}
|
|
20509
|
-
const id =
|
|
20510
|
-
const name = loaded.name || `Workflow from ${
|
|
20509
|
+
const id = path30.basename(resolved).replace(/\.(ya?ml)$/i, "");
|
|
20510
|
+
const name = loaded.name || `Workflow from ${path30.basename(resolved)}`;
|
|
20511
20511
|
const workflowDef = {
|
|
20512
20512
|
id,
|
|
20513
20513
|
name,
|
|
@@ -21316,8 +21316,8 @@ async function createStoreBackend(storageConfig, haConfig) {
|
|
|
21316
21316
|
case "mssql": {
|
|
21317
21317
|
try {
|
|
21318
21318
|
const loaderPath = "../../enterprise/loader";
|
|
21319
|
-
const { loadEnterpriseStoreBackend
|
|
21320
|
-
return await
|
|
21319
|
+
const { loadEnterpriseStoreBackend } = await import(loaderPath);
|
|
21320
|
+
return await loadEnterpriseStoreBackend(driver, storageConfig, haConfig);
|
|
21321
21321
|
} catch (err) {
|
|
21322
21322
|
const msg = err instanceof Error ? err.message : String(err);
|
|
21323
21323
|
logger.error(`[StoreFactory] Failed to load enterprise ${driver} backend: ${msg}`);
|
|
@@ -24686,7 +24686,7 @@ var init_mcp_custom_sse_server = __esm({
|
|
|
24686
24686
|
* Returns the actual bound port number
|
|
24687
24687
|
*/
|
|
24688
24688
|
async start() {
|
|
24689
|
-
return new Promise((
|
|
24689
|
+
return new Promise((resolve17, reject) => {
|
|
24690
24690
|
try {
|
|
24691
24691
|
this.server = import_http.default.createServer((req, res) => {
|
|
24692
24692
|
this.handleRequest(req, res).catch((error) => {
|
|
@@ -24720,7 +24720,7 @@ var init_mcp_custom_sse_server = __esm({
|
|
|
24720
24720
|
);
|
|
24721
24721
|
}
|
|
24722
24722
|
this.startKeepalive();
|
|
24723
|
-
|
|
24723
|
+
resolve17(this.port);
|
|
24724
24724
|
});
|
|
24725
24725
|
} catch (error) {
|
|
24726
24726
|
reject(error);
|
|
@@ -24783,7 +24783,7 @@ var init_mcp_custom_sse_server = __esm({
|
|
|
24783
24783
|
logger.debug(
|
|
24784
24784
|
`[CustomToolsSSEServer:${this.sessionId}] Grace period before stop: ${waitMs}ms (activeToolCalls=${this.activeToolCalls})`
|
|
24785
24785
|
);
|
|
24786
|
-
await new Promise((
|
|
24786
|
+
await new Promise((resolve17) => setTimeout(resolve17, waitMs));
|
|
24787
24787
|
}
|
|
24788
24788
|
}
|
|
24789
24789
|
if (this.activeToolCalls > 0) {
|
|
@@ -24792,7 +24792,7 @@ var init_mcp_custom_sse_server = __esm({
|
|
|
24792
24792
|
`[CustomToolsSSEServer:${this.sessionId}] Waiting for ${this.activeToolCalls} active tool call(s) before stop`
|
|
24793
24793
|
);
|
|
24794
24794
|
while (this.activeToolCalls > 0 && Date.now() - startedAt < effectiveDrainTimeoutMs) {
|
|
24795
|
-
await new Promise((
|
|
24795
|
+
await new Promise((resolve17) => setTimeout(resolve17, 250));
|
|
24796
24796
|
}
|
|
24797
24797
|
if (this.activeToolCalls > 0) {
|
|
24798
24798
|
logger.warn(
|
|
@@ -24817,21 +24817,21 @@ var init_mcp_custom_sse_server = __esm({
|
|
|
24817
24817
|
}
|
|
24818
24818
|
this.connections.clear();
|
|
24819
24819
|
if (this.server) {
|
|
24820
|
-
await new Promise((
|
|
24820
|
+
await new Promise((resolve17, reject) => {
|
|
24821
24821
|
const timeout = setTimeout(() => {
|
|
24822
24822
|
if (this.debug) {
|
|
24823
24823
|
logger.debug(
|
|
24824
24824
|
`[CustomToolsSSEServer:${this.sessionId}] Force closing server after timeout`
|
|
24825
24825
|
);
|
|
24826
24826
|
}
|
|
24827
|
-
this.server?.close(() =>
|
|
24827
|
+
this.server?.close(() => resolve17());
|
|
24828
24828
|
}, 5e3);
|
|
24829
24829
|
this.server.close((error) => {
|
|
24830
24830
|
clearTimeout(timeout);
|
|
24831
24831
|
if (error) {
|
|
24832
24832
|
reject(error);
|
|
24833
24833
|
} else {
|
|
24834
|
-
|
|
24834
|
+
resolve17();
|
|
24835
24835
|
}
|
|
24836
24836
|
});
|
|
24837
24837
|
});
|
|
@@ -25385,7 +25385,7 @@ var init_mcp_custom_sse_server = __esm({
|
|
|
25385
25385
|
logger.warn(
|
|
25386
25386
|
`[CustomToolsSSEServer:${this.sessionId}] Tool ${toolName} failed (attempt ${attempt + 1}/${retryCount + 1}): ${errorMsg}. Retrying in ${delay}ms`
|
|
25387
25387
|
);
|
|
25388
|
-
await new Promise((
|
|
25388
|
+
await new Promise((resolve17) => setTimeout(resolve17, delay));
|
|
25389
25389
|
attempt++;
|
|
25390
25390
|
}
|
|
25391
25391
|
}
|
|
@@ -25926,9 +25926,9 @@ var init_ai_check_provider = __esm({
|
|
|
25926
25926
|
} else {
|
|
25927
25927
|
resolvedPath = import_path13.default.resolve(process.cwd(), str);
|
|
25928
25928
|
}
|
|
25929
|
-
const
|
|
25929
|
+
const fs27 = require("fs").promises;
|
|
25930
25930
|
try {
|
|
25931
|
-
const stat2 = await
|
|
25931
|
+
const stat2 = await fs27.stat(resolvedPath);
|
|
25932
25932
|
return stat2.isFile();
|
|
25933
25933
|
} catch {
|
|
25934
25934
|
return hasFileExtension && (isRelativePath || isAbsolutePath || hasPathSeparators);
|
|
@@ -32200,14 +32200,14 @@ var require_util = __commonJS({
|
|
|
32200
32200
|
}
|
|
32201
32201
|
const port = url.port != null ? url.port : url.protocol === "https:" ? 443 : 80;
|
|
32202
32202
|
let origin = url.origin != null ? url.origin : `${url.protocol}//${url.hostname}:${port}`;
|
|
32203
|
-
let
|
|
32203
|
+
let path30 = url.path != null ? url.path : `${url.pathname || ""}${url.search || ""}`;
|
|
32204
32204
|
if (origin.endsWith("/")) {
|
|
32205
32205
|
origin = origin.substring(0, origin.length - 1);
|
|
32206
32206
|
}
|
|
32207
|
-
if (
|
|
32208
|
-
|
|
32207
|
+
if (path30 && !path30.startsWith("/")) {
|
|
32208
|
+
path30 = `/${path30}`;
|
|
32209
32209
|
}
|
|
32210
|
-
url = new URL(origin +
|
|
32210
|
+
url = new URL(origin + path30);
|
|
32211
32211
|
}
|
|
32212
32212
|
return url;
|
|
32213
32213
|
}
|
|
@@ -33821,20 +33821,20 @@ var require_parseParams = __commonJS({
|
|
|
33821
33821
|
var require_basename = __commonJS({
|
|
33822
33822
|
"node_modules/@fastify/busboy/lib/utils/basename.js"(exports2, module2) {
|
|
33823
33823
|
"use strict";
|
|
33824
|
-
module2.exports = function basename5(
|
|
33825
|
-
if (typeof
|
|
33824
|
+
module2.exports = function basename5(path30) {
|
|
33825
|
+
if (typeof path30 !== "string") {
|
|
33826
33826
|
return "";
|
|
33827
33827
|
}
|
|
33828
|
-
for (var i =
|
|
33829
|
-
switch (
|
|
33828
|
+
for (var i = path30.length - 1; i >= 0; --i) {
|
|
33829
|
+
switch (path30.charCodeAt(i)) {
|
|
33830
33830
|
case 47:
|
|
33831
33831
|
// '/'
|
|
33832
33832
|
case 92:
|
|
33833
|
-
|
|
33834
|
-
return
|
|
33833
|
+
path30 = path30.slice(i + 1);
|
|
33834
|
+
return path30 === ".." || path30 === "." ? "" : path30;
|
|
33835
33835
|
}
|
|
33836
33836
|
}
|
|
33837
|
-
return
|
|
33837
|
+
return path30 === ".." || path30 === "." ? "" : path30;
|
|
33838
33838
|
};
|
|
33839
33839
|
}
|
|
33840
33840
|
});
|
|
@@ -34838,11 +34838,11 @@ var require_util2 = __commonJS({
|
|
|
34838
34838
|
var assert = require("assert");
|
|
34839
34839
|
var { isUint8Array } = require("util/types");
|
|
34840
34840
|
var supportedHashes = [];
|
|
34841
|
-
var
|
|
34841
|
+
var crypto7;
|
|
34842
34842
|
try {
|
|
34843
|
-
|
|
34843
|
+
crypto7 = require("crypto");
|
|
34844
34844
|
const possibleRelevantHashes = ["sha256", "sha384", "sha512"];
|
|
34845
|
-
supportedHashes =
|
|
34845
|
+
supportedHashes = crypto7.getHashes().filter((hash) => possibleRelevantHashes.includes(hash));
|
|
34846
34846
|
} catch {
|
|
34847
34847
|
}
|
|
34848
34848
|
function responseURL(response) {
|
|
@@ -35119,7 +35119,7 @@ var require_util2 = __commonJS({
|
|
|
35119
35119
|
}
|
|
35120
35120
|
}
|
|
35121
35121
|
function bytesMatch(bytes, metadataList) {
|
|
35122
|
-
if (
|
|
35122
|
+
if (crypto7 === void 0) {
|
|
35123
35123
|
return true;
|
|
35124
35124
|
}
|
|
35125
35125
|
const parsedMetadata = parseMetadata(metadataList);
|
|
@@ -35134,7 +35134,7 @@ var require_util2 = __commonJS({
|
|
|
35134
35134
|
for (const item of metadata) {
|
|
35135
35135
|
const algorithm = item.algo;
|
|
35136
35136
|
const expectedValue = item.hash;
|
|
35137
|
-
let actualValue =
|
|
35137
|
+
let actualValue = crypto7.createHash(algorithm).update(bytes).digest("base64");
|
|
35138
35138
|
if (actualValue[actualValue.length - 1] === "=") {
|
|
35139
35139
|
if (actualValue[actualValue.length - 2] === "=") {
|
|
35140
35140
|
actualValue = actualValue.slice(0, -2);
|
|
@@ -35227,8 +35227,8 @@ var require_util2 = __commonJS({
|
|
|
35227
35227
|
function createDeferredPromise() {
|
|
35228
35228
|
let res;
|
|
35229
35229
|
let rej;
|
|
35230
|
-
const promise = new Promise((
|
|
35231
|
-
res =
|
|
35230
|
+
const promise = new Promise((resolve17, reject) => {
|
|
35231
|
+
res = resolve17;
|
|
35232
35232
|
rej = reject;
|
|
35233
35233
|
});
|
|
35234
35234
|
return { promise, resolve: res, reject: rej };
|
|
@@ -36481,8 +36481,8 @@ var require_body = __commonJS({
|
|
|
36481
36481
|
var { parseMIMEType, serializeAMimeType } = require_dataURL();
|
|
36482
36482
|
var random;
|
|
36483
36483
|
try {
|
|
36484
|
-
const
|
|
36485
|
-
random = (max) =>
|
|
36484
|
+
const crypto7 = require("crypto");
|
|
36485
|
+
random = (max) => crypto7.randomInt(0, max);
|
|
36486
36486
|
} catch {
|
|
36487
36487
|
random = (max) => Math.floor(Math.random(max));
|
|
36488
36488
|
}
|
|
@@ -36733,8 +36733,8 @@ Content-Type: ${value.type || "application/octet-stream"}\r
|
|
|
36733
36733
|
});
|
|
36734
36734
|
}
|
|
36735
36735
|
});
|
|
36736
|
-
const busboyResolve = new Promise((
|
|
36737
|
-
busboy.on("finish",
|
|
36736
|
+
const busboyResolve = new Promise((resolve17, reject) => {
|
|
36737
|
+
busboy.on("finish", resolve17);
|
|
36738
36738
|
busboy.on("error", (err) => reject(new TypeError(err)));
|
|
36739
36739
|
});
|
|
36740
36740
|
if (this.body !== null) for await (const chunk of consumeBody(this[kState].body)) busboy.write(chunk);
|
|
@@ -36865,7 +36865,7 @@ var require_request = __commonJS({
|
|
|
36865
36865
|
}
|
|
36866
36866
|
var Request2 = class _Request {
|
|
36867
36867
|
constructor(origin, {
|
|
36868
|
-
path:
|
|
36868
|
+
path: path30,
|
|
36869
36869
|
method,
|
|
36870
36870
|
body,
|
|
36871
36871
|
headers,
|
|
@@ -36879,11 +36879,11 @@ var require_request = __commonJS({
|
|
|
36879
36879
|
throwOnError,
|
|
36880
36880
|
expectContinue
|
|
36881
36881
|
}, handler) {
|
|
36882
|
-
if (typeof
|
|
36882
|
+
if (typeof path30 !== "string") {
|
|
36883
36883
|
throw new InvalidArgumentError("path must be a string");
|
|
36884
|
-
} else if (
|
|
36884
|
+
} else if (path30[0] !== "/" && !(path30.startsWith("http://") || path30.startsWith("https://")) && method !== "CONNECT") {
|
|
36885
36885
|
throw new InvalidArgumentError("path must be an absolute URL or start with a slash");
|
|
36886
|
-
} else if (invalidPathRegex.exec(
|
|
36886
|
+
} else if (invalidPathRegex.exec(path30) !== null) {
|
|
36887
36887
|
throw new InvalidArgumentError("invalid request path");
|
|
36888
36888
|
}
|
|
36889
36889
|
if (typeof method !== "string") {
|
|
@@ -36946,7 +36946,7 @@ var require_request = __commonJS({
|
|
|
36946
36946
|
this.completed = false;
|
|
36947
36947
|
this.aborted = false;
|
|
36948
36948
|
this.upgrade = upgrade || null;
|
|
36949
|
-
this.path = query ? util.buildURL(
|
|
36949
|
+
this.path = query ? util.buildURL(path30, query) : path30;
|
|
36950
36950
|
this.origin = origin;
|
|
36951
36951
|
this.idempotent = idempotent == null ? method === "HEAD" || method === "GET" : idempotent;
|
|
36952
36952
|
this.blocking = blocking == null ? false : blocking;
|
|
@@ -37268,9 +37268,9 @@ var require_dispatcher_base = __commonJS({
|
|
|
37268
37268
|
}
|
|
37269
37269
|
close(callback) {
|
|
37270
37270
|
if (callback === void 0) {
|
|
37271
|
-
return new Promise((
|
|
37271
|
+
return new Promise((resolve17, reject) => {
|
|
37272
37272
|
this.close((err, data) => {
|
|
37273
|
-
return err ? reject(err) :
|
|
37273
|
+
return err ? reject(err) : resolve17(data);
|
|
37274
37274
|
});
|
|
37275
37275
|
});
|
|
37276
37276
|
}
|
|
@@ -37308,12 +37308,12 @@ var require_dispatcher_base = __commonJS({
|
|
|
37308
37308
|
err = null;
|
|
37309
37309
|
}
|
|
37310
37310
|
if (callback === void 0) {
|
|
37311
|
-
return new Promise((
|
|
37311
|
+
return new Promise((resolve17, reject) => {
|
|
37312
37312
|
this.destroy(err, (err2, data) => {
|
|
37313
37313
|
return err2 ? (
|
|
37314
37314
|
/* istanbul ignore next: should never error */
|
|
37315
37315
|
reject(err2)
|
|
37316
|
-
) :
|
|
37316
|
+
) : resolve17(data);
|
|
37317
37317
|
});
|
|
37318
37318
|
});
|
|
37319
37319
|
}
|
|
@@ -37954,9 +37954,9 @@ var require_RedirectHandler = __commonJS({
|
|
|
37954
37954
|
return this.handler.onHeaders(statusCode, headers, resume, statusText);
|
|
37955
37955
|
}
|
|
37956
37956
|
const { origin, pathname, search } = util.parseURL(new URL(this.location, this.opts.origin && new URL(this.opts.path, this.opts.origin)));
|
|
37957
|
-
const
|
|
37957
|
+
const path30 = search ? `${pathname}${search}` : pathname;
|
|
37958
37958
|
this.opts.headers = cleanRequestHeaders(this.opts.headers, statusCode === 303, this.opts.origin !== origin);
|
|
37959
|
-
this.opts.path =
|
|
37959
|
+
this.opts.path = path30;
|
|
37960
37960
|
this.opts.origin = origin;
|
|
37961
37961
|
this.opts.maxRedirections = 0;
|
|
37962
37962
|
this.opts.query = null;
|
|
@@ -38375,16 +38375,16 @@ var require_client = __commonJS({
|
|
|
38375
38375
|
return this[kNeedDrain] < 2;
|
|
38376
38376
|
}
|
|
38377
38377
|
async [kClose]() {
|
|
38378
|
-
return new Promise((
|
|
38378
|
+
return new Promise((resolve17) => {
|
|
38379
38379
|
if (!this[kSize]) {
|
|
38380
|
-
|
|
38380
|
+
resolve17(null);
|
|
38381
38381
|
} else {
|
|
38382
|
-
this[kClosedResolve] =
|
|
38382
|
+
this[kClosedResolve] = resolve17;
|
|
38383
38383
|
}
|
|
38384
38384
|
});
|
|
38385
38385
|
}
|
|
38386
38386
|
async [kDestroy](err) {
|
|
38387
|
-
return new Promise((
|
|
38387
|
+
return new Promise((resolve17) => {
|
|
38388
38388
|
const requests = this[kQueue].splice(this[kPendingIdx]);
|
|
38389
38389
|
for (let i = 0; i < requests.length; i++) {
|
|
38390
38390
|
const request = requests[i];
|
|
@@ -38395,7 +38395,7 @@ var require_client = __commonJS({
|
|
|
38395
38395
|
this[kClosedResolve]();
|
|
38396
38396
|
this[kClosedResolve] = null;
|
|
38397
38397
|
}
|
|
38398
|
-
|
|
38398
|
+
resolve17();
|
|
38399
38399
|
};
|
|
38400
38400
|
if (this[kHTTP2Session] != null) {
|
|
38401
38401
|
util.destroy(this[kHTTP2Session], err);
|
|
@@ -38975,7 +38975,7 @@ var require_client = __commonJS({
|
|
|
38975
38975
|
});
|
|
38976
38976
|
}
|
|
38977
38977
|
try {
|
|
38978
|
-
const socket = await new Promise((
|
|
38978
|
+
const socket = await new Promise((resolve17, reject) => {
|
|
38979
38979
|
client[kConnector]({
|
|
38980
38980
|
host,
|
|
38981
38981
|
hostname,
|
|
@@ -38987,7 +38987,7 @@ var require_client = __commonJS({
|
|
|
38987
38987
|
if (err) {
|
|
38988
38988
|
reject(err);
|
|
38989
38989
|
} else {
|
|
38990
|
-
|
|
38990
|
+
resolve17(socket2);
|
|
38991
38991
|
}
|
|
38992
38992
|
});
|
|
38993
38993
|
});
|
|
@@ -39198,7 +39198,7 @@ var require_client = __commonJS({
|
|
|
39198
39198
|
writeH2(client, client[kHTTP2Session], request);
|
|
39199
39199
|
return;
|
|
39200
39200
|
}
|
|
39201
|
-
const { body, method, path:
|
|
39201
|
+
const { body, method, path: path30, host, upgrade, headers, blocking, reset } = request;
|
|
39202
39202
|
const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH";
|
|
39203
39203
|
if (body && typeof body.read === "function") {
|
|
39204
39204
|
body.read(0);
|
|
@@ -39248,7 +39248,7 @@ var require_client = __commonJS({
|
|
|
39248
39248
|
if (blocking) {
|
|
39249
39249
|
socket[kBlocking] = true;
|
|
39250
39250
|
}
|
|
39251
|
-
let header = `${method} ${
|
|
39251
|
+
let header = `${method} ${path30} HTTP/1.1\r
|
|
39252
39252
|
`;
|
|
39253
39253
|
if (typeof host === "string") {
|
|
39254
39254
|
header += `host: ${host}\r
|
|
@@ -39311,7 +39311,7 @@ upgrade: ${upgrade}\r
|
|
|
39311
39311
|
return true;
|
|
39312
39312
|
}
|
|
39313
39313
|
function writeH2(client, session, request) {
|
|
39314
|
-
const { body, method, path:
|
|
39314
|
+
const { body, method, path: path30, host, upgrade, expectContinue, signal, headers: reqHeaders } = request;
|
|
39315
39315
|
let headers;
|
|
39316
39316
|
if (typeof reqHeaders === "string") headers = Request2[kHTTP2CopyHeaders](reqHeaders.trim());
|
|
39317
39317
|
else headers = reqHeaders;
|
|
@@ -39354,7 +39354,7 @@ upgrade: ${upgrade}\r
|
|
|
39354
39354
|
});
|
|
39355
39355
|
return true;
|
|
39356
39356
|
}
|
|
39357
|
-
headers[HTTP2_HEADER_PATH] =
|
|
39357
|
+
headers[HTTP2_HEADER_PATH] = path30;
|
|
39358
39358
|
headers[HTTP2_HEADER_SCHEME] = "https";
|
|
39359
39359
|
const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH";
|
|
39360
39360
|
if (body && typeof body.read === "function") {
|
|
@@ -39611,12 +39611,12 @@ upgrade: ${upgrade}\r
|
|
|
39611
39611
|
cb();
|
|
39612
39612
|
}
|
|
39613
39613
|
}
|
|
39614
|
-
const waitForDrain = () => new Promise((
|
|
39614
|
+
const waitForDrain = () => new Promise((resolve17, reject) => {
|
|
39615
39615
|
assert(callback === null);
|
|
39616
39616
|
if (socket[kError]) {
|
|
39617
39617
|
reject(socket[kError]);
|
|
39618
39618
|
} else {
|
|
39619
|
-
callback =
|
|
39619
|
+
callback = resolve17;
|
|
39620
39620
|
}
|
|
39621
39621
|
});
|
|
39622
39622
|
if (client[kHTTPConnVersion] === "h2") {
|
|
@@ -39962,8 +39962,8 @@ var require_pool_base = __commonJS({
|
|
|
39962
39962
|
if (this[kQueue].isEmpty()) {
|
|
39963
39963
|
return Promise.all(this[kClients].map((c) => c.close()));
|
|
39964
39964
|
} else {
|
|
39965
|
-
return new Promise((
|
|
39966
|
-
this[kClosedResolve] =
|
|
39965
|
+
return new Promise((resolve17) => {
|
|
39966
|
+
this[kClosedResolve] = resolve17;
|
|
39967
39967
|
});
|
|
39968
39968
|
}
|
|
39969
39969
|
}
|
|
@@ -40541,7 +40541,7 @@ var require_readable = __commonJS({
|
|
|
40541
40541
|
if (this.closed) {
|
|
40542
40542
|
return Promise.resolve(null);
|
|
40543
40543
|
}
|
|
40544
|
-
return new Promise((
|
|
40544
|
+
return new Promise((resolve17, reject) => {
|
|
40545
40545
|
const signalListenerCleanup = signal ? util.addAbortListener(signal, () => {
|
|
40546
40546
|
this.destroy();
|
|
40547
40547
|
}) : noop;
|
|
@@ -40550,7 +40550,7 @@ var require_readable = __commonJS({
|
|
|
40550
40550
|
if (signal && signal.aborted) {
|
|
40551
40551
|
reject(signal.reason || Object.assign(new Error("The operation was aborted"), { name: "AbortError" }));
|
|
40552
40552
|
} else {
|
|
40553
|
-
|
|
40553
|
+
resolve17(null);
|
|
40554
40554
|
}
|
|
40555
40555
|
}).on("error", noop).on("data", function(chunk) {
|
|
40556
40556
|
limit -= chunk.length;
|
|
@@ -40572,11 +40572,11 @@ var require_readable = __commonJS({
|
|
|
40572
40572
|
throw new TypeError("unusable");
|
|
40573
40573
|
}
|
|
40574
40574
|
assert(!stream[kConsume]);
|
|
40575
|
-
return new Promise((
|
|
40575
|
+
return new Promise((resolve17, reject) => {
|
|
40576
40576
|
stream[kConsume] = {
|
|
40577
40577
|
type,
|
|
40578
40578
|
stream,
|
|
40579
|
-
resolve:
|
|
40579
|
+
resolve: resolve17,
|
|
40580
40580
|
reject,
|
|
40581
40581
|
length: 0,
|
|
40582
40582
|
body: []
|
|
@@ -40611,12 +40611,12 @@ var require_readable = __commonJS({
|
|
|
40611
40611
|
}
|
|
40612
40612
|
}
|
|
40613
40613
|
function consumeEnd(consume2) {
|
|
40614
|
-
const { type, body, resolve:
|
|
40614
|
+
const { type, body, resolve: resolve17, stream, length } = consume2;
|
|
40615
40615
|
try {
|
|
40616
40616
|
if (type === "text") {
|
|
40617
|
-
|
|
40617
|
+
resolve17(toUSVString(Buffer.concat(body)));
|
|
40618
40618
|
} else if (type === "json") {
|
|
40619
|
-
|
|
40619
|
+
resolve17(JSON.parse(Buffer.concat(body)));
|
|
40620
40620
|
} else if (type === "arrayBuffer") {
|
|
40621
40621
|
const dst = new Uint8Array(length);
|
|
40622
40622
|
let pos = 0;
|
|
@@ -40624,12 +40624,12 @@ var require_readable = __commonJS({
|
|
|
40624
40624
|
dst.set(buf, pos);
|
|
40625
40625
|
pos += buf.byteLength;
|
|
40626
40626
|
}
|
|
40627
|
-
|
|
40627
|
+
resolve17(dst.buffer);
|
|
40628
40628
|
} else if (type === "blob") {
|
|
40629
40629
|
if (!Blob2) {
|
|
40630
40630
|
Blob2 = require("buffer").Blob;
|
|
40631
40631
|
}
|
|
40632
|
-
|
|
40632
|
+
resolve17(new Blob2(body, { type: stream[kContentType] }));
|
|
40633
40633
|
}
|
|
40634
40634
|
consumeFinish(consume2);
|
|
40635
40635
|
} catch (err) {
|
|
@@ -40886,9 +40886,9 @@ var require_api_request = __commonJS({
|
|
|
40886
40886
|
};
|
|
40887
40887
|
function request(opts, callback) {
|
|
40888
40888
|
if (callback === void 0) {
|
|
40889
|
-
return new Promise((
|
|
40889
|
+
return new Promise((resolve17, reject) => {
|
|
40890
40890
|
request.call(this, opts, (err, data) => {
|
|
40891
|
-
return err ? reject(err) :
|
|
40891
|
+
return err ? reject(err) : resolve17(data);
|
|
40892
40892
|
});
|
|
40893
40893
|
});
|
|
40894
40894
|
}
|
|
@@ -41061,9 +41061,9 @@ var require_api_stream = __commonJS({
|
|
|
41061
41061
|
};
|
|
41062
41062
|
function stream(opts, factory, callback) {
|
|
41063
41063
|
if (callback === void 0) {
|
|
41064
|
-
return new Promise((
|
|
41064
|
+
return new Promise((resolve17, reject) => {
|
|
41065
41065
|
stream.call(this, opts, factory, (err, data) => {
|
|
41066
|
-
return err ? reject(err) :
|
|
41066
|
+
return err ? reject(err) : resolve17(data);
|
|
41067
41067
|
});
|
|
41068
41068
|
});
|
|
41069
41069
|
}
|
|
@@ -41344,9 +41344,9 @@ var require_api_upgrade = __commonJS({
|
|
|
41344
41344
|
};
|
|
41345
41345
|
function upgrade(opts, callback) {
|
|
41346
41346
|
if (callback === void 0) {
|
|
41347
|
-
return new Promise((
|
|
41347
|
+
return new Promise((resolve17, reject) => {
|
|
41348
41348
|
upgrade.call(this, opts, (err, data) => {
|
|
41349
|
-
return err ? reject(err) :
|
|
41349
|
+
return err ? reject(err) : resolve17(data);
|
|
41350
41350
|
});
|
|
41351
41351
|
});
|
|
41352
41352
|
}
|
|
@@ -41435,9 +41435,9 @@ var require_api_connect = __commonJS({
|
|
|
41435
41435
|
};
|
|
41436
41436
|
function connect(opts, callback) {
|
|
41437
41437
|
if (callback === void 0) {
|
|
41438
|
-
return new Promise((
|
|
41438
|
+
return new Promise((resolve17, reject) => {
|
|
41439
41439
|
connect.call(this, opts, (err, data) => {
|
|
41440
|
-
return err ? reject(err) :
|
|
41440
|
+
return err ? reject(err) : resolve17(data);
|
|
41441
41441
|
});
|
|
41442
41442
|
});
|
|
41443
41443
|
}
|
|
@@ -41597,20 +41597,20 @@ var require_mock_utils = __commonJS({
|
|
|
41597
41597
|
}
|
|
41598
41598
|
return true;
|
|
41599
41599
|
}
|
|
41600
|
-
function safeUrl(
|
|
41601
|
-
if (typeof
|
|
41602
|
-
return
|
|
41600
|
+
function safeUrl(path30) {
|
|
41601
|
+
if (typeof path30 !== "string") {
|
|
41602
|
+
return path30;
|
|
41603
41603
|
}
|
|
41604
|
-
const pathSegments =
|
|
41604
|
+
const pathSegments = path30.split("?");
|
|
41605
41605
|
if (pathSegments.length !== 2) {
|
|
41606
|
-
return
|
|
41606
|
+
return path30;
|
|
41607
41607
|
}
|
|
41608
41608
|
const qp = new URLSearchParams(pathSegments.pop());
|
|
41609
41609
|
qp.sort();
|
|
41610
41610
|
return [...pathSegments, qp.toString()].join("?");
|
|
41611
41611
|
}
|
|
41612
|
-
function matchKey(mockDispatch2, { path:
|
|
41613
|
-
const pathMatch = matchValue(mockDispatch2.path,
|
|
41612
|
+
function matchKey(mockDispatch2, { path: path30, method, body, headers }) {
|
|
41613
|
+
const pathMatch = matchValue(mockDispatch2.path, path30);
|
|
41614
41614
|
const methodMatch = matchValue(mockDispatch2.method, method);
|
|
41615
41615
|
const bodyMatch = typeof mockDispatch2.body !== "undefined" ? matchValue(mockDispatch2.body, body) : true;
|
|
41616
41616
|
const headersMatch = matchHeaders(mockDispatch2, headers);
|
|
@@ -41628,7 +41628,7 @@ var require_mock_utils = __commonJS({
|
|
|
41628
41628
|
function getMockDispatch(mockDispatches, key) {
|
|
41629
41629
|
const basePath = key.query ? buildURL(key.path, key.query) : key.path;
|
|
41630
41630
|
const resolvedPath = typeof basePath === "string" ? safeUrl(basePath) : basePath;
|
|
41631
|
-
let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path:
|
|
41631
|
+
let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path: path30 }) => matchValue(safeUrl(path30), resolvedPath));
|
|
41632
41632
|
if (matchedMockDispatches.length === 0) {
|
|
41633
41633
|
throw new MockNotMatchedError(`Mock dispatch not matched for path '${resolvedPath}'`);
|
|
41634
41634
|
}
|
|
@@ -41665,9 +41665,9 @@ var require_mock_utils = __commonJS({
|
|
|
41665
41665
|
}
|
|
41666
41666
|
}
|
|
41667
41667
|
function buildKey(opts) {
|
|
41668
|
-
const { path:
|
|
41668
|
+
const { path: path30, method, body, headers, query } = opts;
|
|
41669
41669
|
return {
|
|
41670
|
-
path:
|
|
41670
|
+
path: path30,
|
|
41671
41671
|
method,
|
|
41672
41672
|
body,
|
|
41673
41673
|
headers,
|
|
@@ -42116,10 +42116,10 @@ var require_pending_interceptors_formatter = __commonJS({
|
|
|
42116
42116
|
}
|
|
42117
42117
|
format(pendingInterceptors) {
|
|
42118
42118
|
const withPrettyHeaders = pendingInterceptors.map(
|
|
42119
|
-
({ method, path:
|
|
42119
|
+
({ method, path: path30, data: { statusCode }, persist, times, timesInvoked, origin }) => ({
|
|
42120
42120
|
Method: method,
|
|
42121
42121
|
Origin: origin,
|
|
42122
|
-
Path:
|
|
42122
|
+
Path: path30,
|
|
42123
42123
|
"Status code": statusCode,
|
|
42124
42124
|
Persistent: persist ? "\u2705" : "\u274C",
|
|
42125
42125
|
Invocations: timesInvoked,
|
|
@@ -45060,7 +45060,7 @@ var require_fetch = __commonJS({
|
|
|
45060
45060
|
async function dispatch({ body }) {
|
|
45061
45061
|
const url = requestCurrentURL(request);
|
|
45062
45062
|
const agent = fetchParams.controller.dispatcher;
|
|
45063
|
-
return new Promise((
|
|
45063
|
+
return new Promise((resolve17, reject) => agent.dispatch(
|
|
45064
45064
|
{
|
|
45065
45065
|
path: url.pathname + url.search,
|
|
45066
45066
|
origin: url.origin,
|
|
@@ -45136,7 +45136,7 @@ var require_fetch = __commonJS({
|
|
|
45136
45136
|
}
|
|
45137
45137
|
}
|
|
45138
45138
|
}
|
|
45139
|
-
|
|
45139
|
+
resolve17({
|
|
45140
45140
|
status,
|
|
45141
45141
|
statusText,
|
|
45142
45142
|
headersList: headers[kHeadersList],
|
|
@@ -45179,7 +45179,7 @@ var require_fetch = __commonJS({
|
|
|
45179
45179
|
const val = headersList[n + 1].toString("latin1");
|
|
45180
45180
|
headers[kHeadersList].append(key, val);
|
|
45181
45181
|
}
|
|
45182
|
-
|
|
45182
|
+
resolve17({
|
|
45183
45183
|
status,
|
|
45184
45184
|
statusText: STATUS_CODES[status],
|
|
45185
45185
|
headersList: headers[kHeadersList],
|
|
@@ -46740,8 +46740,8 @@ var require_util6 = __commonJS({
|
|
|
46740
46740
|
}
|
|
46741
46741
|
}
|
|
46742
46742
|
}
|
|
46743
|
-
function validateCookiePath(
|
|
46744
|
-
for (const char of
|
|
46743
|
+
function validateCookiePath(path30) {
|
|
46744
|
+
for (const char of path30) {
|
|
46745
46745
|
const code = char.charCodeAt(0);
|
|
46746
46746
|
if (code < 33 || char === ";") {
|
|
46747
46747
|
throw new Error("Invalid cookie path");
|
|
@@ -47538,9 +47538,9 @@ var require_connection = __commonJS({
|
|
|
47538
47538
|
channels.open = diagnosticsChannel.channel("undici:websocket:open");
|
|
47539
47539
|
channels.close = diagnosticsChannel.channel("undici:websocket:close");
|
|
47540
47540
|
channels.socketError = diagnosticsChannel.channel("undici:websocket:socket_error");
|
|
47541
|
-
var
|
|
47541
|
+
var crypto7;
|
|
47542
47542
|
try {
|
|
47543
|
-
|
|
47543
|
+
crypto7 = require("crypto");
|
|
47544
47544
|
} catch {
|
|
47545
47545
|
}
|
|
47546
47546
|
function establishWebSocketConnection(url, protocols, ws, onEstablish, options) {
|
|
@@ -47559,7 +47559,7 @@ var require_connection = __commonJS({
|
|
|
47559
47559
|
const headersList = new Headers(options.headers)[kHeadersList];
|
|
47560
47560
|
request.headersList = headersList;
|
|
47561
47561
|
}
|
|
47562
|
-
const keyValue =
|
|
47562
|
+
const keyValue = crypto7.randomBytes(16).toString("base64");
|
|
47563
47563
|
request.headersList.append("sec-websocket-key", keyValue);
|
|
47564
47564
|
request.headersList.append("sec-websocket-version", "13");
|
|
47565
47565
|
for (const protocol of protocols) {
|
|
@@ -47588,7 +47588,7 @@ var require_connection = __commonJS({
|
|
|
47588
47588
|
return;
|
|
47589
47589
|
}
|
|
47590
47590
|
const secWSAccept = response.headersList.get("Sec-WebSocket-Accept");
|
|
47591
|
-
const digest =
|
|
47591
|
+
const digest = crypto7.createHash("sha1").update(keyValue + uid).digest("base64");
|
|
47592
47592
|
if (secWSAccept !== digest) {
|
|
47593
47593
|
failWebsocketConnection(ws, "Incorrect hash received in Sec-WebSocket-Accept header.");
|
|
47594
47594
|
return;
|
|
@@ -47668,9 +47668,9 @@ var require_frame = __commonJS({
|
|
|
47668
47668
|
"node_modules/undici/lib/websocket/frame.js"(exports2, module2) {
|
|
47669
47669
|
"use strict";
|
|
47670
47670
|
var { maxUnsigned16Bit } = require_constants5();
|
|
47671
|
-
var
|
|
47671
|
+
var crypto7;
|
|
47672
47672
|
try {
|
|
47673
|
-
|
|
47673
|
+
crypto7 = require("crypto");
|
|
47674
47674
|
} catch {
|
|
47675
47675
|
}
|
|
47676
47676
|
var WebsocketFrameSend = class {
|
|
@@ -47679,7 +47679,7 @@ var require_frame = __commonJS({
|
|
|
47679
47679
|
*/
|
|
47680
47680
|
constructor(data) {
|
|
47681
47681
|
this.frameData = data;
|
|
47682
|
-
this.maskKey =
|
|
47682
|
+
this.maskKey = crypto7.randomBytes(4);
|
|
47683
47683
|
}
|
|
47684
47684
|
createFrame(opcode) {
|
|
47685
47685
|
const bodyLength = this.frameData?.byteLength ?? 0;
|
|
@@ -48421,11 +48421,11 @@ var require_undici = __commonJS({
|
|
|
48421
48421
|
if (typeof opts.path !== "string") {
|
|
48422
48422
|
throw new InvalidArgumentError("invalid opts.path");
|
|
48423
48423
|
}
|
|
48424
|
-
let
|
|
48424
|
+
let path30 = opts.path;
|
|
48425
48425
|
if (!opts.path.startsWith("/")) {
|
|
48426
|
-
|
|
48426
|
+
path30 = `/${path30}`;
|
|
48427
48427
|
}
|
|
48428
|
-
url = new URL(util.parseOrigin(url).origin +
|
|
48428
|
+
url = new URL(util.parseOrigin(url).origin + path30);
|
|
48429
48429
|
} else {
|
|
48430
48430
|
if (!opts) {
|
|
48431
48431
|
opts = typeof url === "object" ? url : {};
|
|
@@ -48995,7 +48995,7 @@ var init_mcp_check_provider = __esm({
|
|
|
48995
48995
|
logger.warn(
|
|
48996
48996
|
`MCP ${transportName} failed (attempt ${attempt + 1}/${maxRetries + 1}), retrying in ${delay}ms: ${error instanceof Error ? error.message : String(error)}`
|
|
48997
48997
|
);
|
|
48998
|
-
await new Promise((
|
|
48998
|
+
await new Promise((resolve17) => setTimeout(resolve17, delay));
|
|
48999
48999
|
attempt += 1;
|
|
49000
49000
|
} finally {
|
|
49001
49001
|
try {
|
|
@@ -49169,7 +49169,7 @@ async function acquirePromptLock() {
|
|
|
49169
49169
|
);
|
|
49170
49170
|
}, 1e4);
|
|
49171
49171
|
try {
|
|
49172
|
-
await new Promise((
|
|
49172
|
+
await new Promise((resolve17) => waiters.push(resolve17));
|
|
49173
49173
|
} finally {
|
|
49174
49174
|
clearInterval(reminder);
|
|
49175
49175
|
const waitedMs = Date.now() - queuedAt;
|
|
@@ -49188,7 +49188,7 @@ function releasePromptLock() {
|
|
|
49188
49188
|
}
|
|
49189
49189
|
async function interactivePrompt(options) {
|
|
49190
49190
|
await acquirePromptLock();
|
|
49191
|
-
return new Promise((
|
|
49191
|
+
return new Promise((resolve17, reject) => {
|
|
49192
49192
|
const dbg = process.env.VISOR_DEBUG === "true";
|
|
49193
49193
|
try {
|
|
49194
49194
|
if (dbg) {
|
|
@@ -49275,12 +49275,12 @@ async function interactivePrompt(options) {
|
|
|
49275
49275
|
};
|
|
49276
49276
|
const finish = (value) => {
|
|
49277
49277
|
cleanup();
|
|
49278
|
-
|
|
49278
|
+
resolve17(value);
|
|
49279
49279
|
};
|
|
49280
49280
|
if (options.timeout && options.timeout > 0) {
|
|
49281
49281
|
timeoutId = setTimeout(() => {
|
|
49282
49282
|
cleanup();
|
|
49283
|
-
if (defaultValue !== void 0) return
|
|
49283
|
+
if (defaultValue !== void 0) return resolve17(defaultValue);
|
|
49284
49284
|
return reject(new Error("Input timeout"));
|
|
49285
49285
|
}, options.timeout);
|
|
49286
49286
|
}
|
|
@@ -49412,7 +49412,7 @@ async function interactivePrompt(options) {
|
|
|
49412
49412
|
});
|
|
49413
49413
|
}
|
|
49414
49414
|
async function simplePrompt(prompt) {
|
|
49415
|
-
return new Promise((
|
|
49415
|
+
return new Promise((resolve17) => {
|
|
49416
49416
|
const rl = readline.createInterface({
|
|
49417
49417
|
input: process.stdin,
|
|
49418
49418
|
output: process.stdout
|
|
@@ -49428,7 +49428,7 @@ async function simplePrompt(prompt) {
|
|
|
49428
49428
|
rl.question(`${prompt}
|
|
49429
49429
|
> `, (answer) => {
|
|
49430
49430
|
rl.close();
|
|
49431
|
-
|
|
49431
|
+
resolve17(answer.trim());
|
|
49432
49432
|
});
|
|
49433
49433
|
});
|
|
49434
49434
|
}
|
|
@@ -49596,7 +49596,7 @@ function isStdinAvailable() {
|
|
|
49596
49596
|
return !process.stdin.isTTY;
|
|
49597
49597
|
}
|
|
49598
49598
|
async function readStdin(timeout, maxSize = 1024 * 1024) {
|
|
49599
|
-
return new Promise((
|
|
49599
|
+
return new Promise((resolve17, reject) => {
|
|
49600
49600
|
let data = "";
|
|
49601
49601
|
let timeoutId;
|
|
49602
49602
|
if (timeout) {
|
|
@@ -49623,7 +49623,7 @@ async function readStdin(timeout, maxSize = 1024 * 1024) {
|
|
|
49623
49623
|
};
|
|
49624
49624
|
const onEnd = () => {
|
|
49625
49625
|
cleanup();
|
|
49626
|
-
|
|
49626
|
+
resolve17(data.trim());
|
|
49627
49627
|
};
|
|
49628
49628
|
const onError = (err) => {
|
|
49629
49629
|
cleanup();
|
|
@@ -51177,7 +51177,7 @@ var init_worktree_manager = __esm({
|
|
|
51177
51177
|
logger.warn(`Bare repo update attempt ${attempt}/2 error: ${errorMessage}`);
|
|
51178
51178
|
}
|
|
51179
51179
|
if (attempt < 2) {
|
|
51180
|
-
await new Promise((
|
|
51180
|
+
await new Promise((resolve17) => setTimeout(resolve17, 2e3));
|
|
51181
51181
|
}
|
|
51182
51182
|
}
|
|
51183
51183
|
logger.warn(`Failed to update bare repository after 2 attempts (will rely on per-ref fetch)`);
|
|
@@ -51488,7 +51488,7 @@ var init_worktree_manager = __esm({
|
|
|
51488
51488
|
`Failed to fetch ref ${ref} (attempt ${attempt}/2): ${result.stderr || result.stdout}`
|
|
51489
51489
|
);
|
|
51490
51490
|
if (attempt < 2) {
|
|
51491
|
-
await new Promise((
|
|
51491
|
+
await new Promise((resolve17) => setTimeout(resolve17, 1e3));
|
|
51492
51492
|
}
|
|
51493
51493
|
}
|
|
51494
51494
|
return false;
|
|
@@ -54441,23 +54441,23 @@ __export(renderer_schema_exports, {
|
|
|
54441
54441
|
});
|
|
54442
54442
|
async function loadRendererSchema(name) {
|
|
54443
54443
|
try {
|
|
54444
|
-
const
|
|
54445
|
-
const
|
|
54444
|
+
const fs27 = await import("fs/promises");
|
|
54445
|
+
const path30 = await import("path");
|
|
54446
54446
|
const sanitized = String(name).replace(/[^a-zA-Z0-9-]/g, "");
|
|
54447
54447
|
if (!sanitized) return void 0;
|
|
54448
54448
|
const candidates = [
|
|
54449
54449
|
// When bundled with ncc, __dirname is dist/ and output/ is at dist/output/
|
|
54450
|
-
|
|
54450
|
+
path30.join(__dirname, "output", sanitized, "schema.json"),
|
|
54451
54451
|
// When running from source, __dirname is src/state-machine/dispatch/ and output/ is at output/
|
|
54452
|
-
|
|
54452
|
+
path30.join(__dirname, "..", "..", "output", sanitized, "schema.json"),
|
|
54453
54453
|
// When running from a checkout with output/ folder copied to CWD
|
|
54454
|
-
|
|
54454
|
+
path30.join(process.cwd(), "output", sanitized, "schema.json"),
|
|
54455
54455
|
// Fallback: cwd/dist/output/
|
|
54456
|
-
|
|
54456
|
+
path30.join(process.cwd(), "dist", "output", sanitized, "schema.json")
|
|
54457
54457
|
];
|
|
54458
54458
|
for (const p of candidates) {
|
|
54459
54459
|
try {
|
|
54460
|
-
const raw = await
|
|
54460
|
+
const raw = await fs27.readFile(p, "utf-8");
|
|
54461
54461
|
return JSON.parse(raw);
|
|
54462
54462
|
} catch {
|
|
54463
54463
|
}
|
|
@@ -56911,8 +56911,8 @@ function updateStats2(results, state, isForEachIteration = false) {
|
|
|
56911
56911
|
async function renderTemplateContent2(checkId, checkConfig, reviewSummary) {
|
|
56912
56912
|
try {
|
|
56913
56913
|
const { createExtendedLiquid: createExtendedLiquid2 } = await Promise.resolve().then(() => (init_liquid_extensions(), liquid_extensions_exports));
|
|
56914
|
-
const
|
|
56915
|
-
const
|
|
56914
|
+
const fs27 = await import("fs/promises");
|
|
56915
|
+
const path30 = await import("path");
|
|
56916
56916
|
const schemaRaw = checkConfig.schema || "plain";
|
|
56917
56917
|
const schema = typeof schemaRaw === "string" && !schemaRaw.includes("{{") && !schemaRaw.includes("{%") ? schemaRaw : typeof schemaRaw === "object" ? "code-review" : "plain";
|
|
56918
56918
|
let templateContent;
|
|
@@ -56921,27 +56921,27 @@ async function renderTemplateContent2(checkId, checkConfig, reviewSummary) {
|
|
|
56921
56921
|
logger.debug(`[LevelDispatch] Using inline template for ${checkId}`);
|
|
56922
56922
|
} else if (checkConfig.template && checkConfig.template.file) {
|
|
56923
56923
|
const file = String(checkConfig.template.file);
|
|
56924
|
-
const resolved =
|
|
56925
|
-
templateContent = await
|
|
56924
|
+
const resolved = path30.resolve(process.cwd(), file);
|
|
56925
|
+
templateContent = await fs27.readFile(resolved, "utf-8");
|
|
56926
56926
|
logger.debug(`[LevelDispatch] Using template file for ${checkId}: ${resolved}`);
|
|
56927
56927
|
} else if (schema && schema !== "plain") {
|
|
56928
56928
|
const sanitized = String(schema).replace(/[^a-zA-Z0-9-]/g, "");
|
|
56929
56929
|
if (sanitized) {
|
|
56930
56930
|
const candidatePaths = [
|
|
56931
|
-
|
|
56931
|
+
path30.join(__dirname, "output", sanitized, "template.liquid"),
|
|
56932
56932
|
// bundled: dist/output/
|
|
56933
|
-
|
|
56933
|
+
path30.join(__dirname, "..", "..", "output", sanitized, "template.liquid"),
|
|
56934
56934
|
// source (from state-machine/states)
|
|
56935
|
-
|
|
56935
|
+
path30.join(__dirname, "..", "..", "..", "output", sanitized, "template.liquid"),
|
|
56936
56936
|
// source (alternate)
|
|
56937
|
-
|
|
56937
|
+
path30.join(process.cwd(), "output", sanitized, "template.liquid"),
|
|
56938
56938
|
// fallback: cwd/output/
|
|
56939
|
-
|
|
56939
|
+
path30.join(process.cwd(), "dist", "output", sanitized, "template.liquid")
|
|
56940
56940
|
// fallback: cwd/dist/output/
|
|
56941
56941
|
];
|
|
56942
56942
|
for (const p of candidatePaths) {
|
|
56943
56943
|
try {
|
|
56944
|
-
templateContent = await
|
|
56944
|
+
templateContent = await fs27.readFile(p, "utf-8");
|
|
56945
56945
|
if (templateContent) {
|
|
56946
56946
|
logger.debug(`[LevelDispatch] Using schema template for ${checkId}: ${p}`);
|
|
56947
56947
|
break;
|
|
@@ -58147,8 +58147,8 @@ var init_workspace_manager = __esm({
|
|
|
58147
58147
|
);
|
|
58148
58148
|
if (this.cleanupRequested && this.activeOperations === 0) {
|
|
58149
58149
|
logger.debug(`[Workspace] All references released, proceeding with deferred cleanup`);
|
|
58150
|
-
for (const
|
|
58151
|
-
|
|
58150
|
+
for (const resolve17 of this.cleanupResolvers) {
|
|
58151
|
+
resolve17();
|
|
58152
58152
|
}
|
|
58153
58153
|
this.cleanupResolvers = [];
|
|
58154
58154
|
}
|
|
@@ -58364,19 +58364,19 @@ var init_workspace_manager = __esm({
|
|
|
58364
58364
|
);
|
|
58365
58365
|
this.cleanupRequested = true;
|
|
58366
58366
|
await Promise.race([
|
|
58367
|
-
new Promise((
|
|
58367
|
+
new Promise((resolve17) => {
|
|
58368
58368
|
if (this.activeOperations === 0) {
|
|
58369
|
-
|
|
58369
|
+
resolve17();
|
|
58370
58370
|
} else {
|
|
58371
|
-
this.cleanupResolvers.push(
|
|
58371
|
+
this.cleanupResolvers.push(resolve17);
|
|
58372
58372
|
}
|
|
58373
58373
|
}),
|
|
58374
|
-
new Promise((
|
|
58374
|
+
new Promise((resolve17) => {
|
|
58375
58375
|
setTimeout(() => {
|
|
58376
58376
|
logger.warn(
|
|
58377
58377
|
`[Workspace] Cleanup timeout after ${timeout}ms, proceeding anyway (${this.activeOperations} operations still active)`
|
|
58378
58378
|
);
|
|
58379
|
-
|
|
58379
|
+
resolve17();
|
|
58380
58380
|
}, timeout);
|
|
58381
58381
|
})
|
|
58382
58382
|
]);
|
|
@@ -58791,8 +58791,8 @@ var init_fair_concurrency_limiter = __esm({
|
|
|
58791
58791
|
);
|
|
58792
58792
|
const queuedAt = Date.now();
|
|
58793
58793
|
const effectiveTimeout = queueTimeout ?? 12e4;
|
|
58794
|
-
return new Promise((
|
|
58795
|
-
const entry = { resolve:
|
|
58794
|
+
return new Promise((resolve17, reject) => {
|
|
58795
|
+
const entry = { resolve: resolve17, reject, queuedAt };
|
|
58796
58796
|
entry.reminder = setInterval(() => {
|
|
58797
58797
|
const waited = Math.round((Date.now() - queuedAt) / 1e3);
|
|
58798
58798
|
const curQueued = this._totalQueued();
|
|
@@ -59100,1380 +59100,6 @@ var init_build_engine_context = __esm({
|
|
|
59100
59100
|
}
|
|
59101
59101
|
});
|
|
59102
59102
|
|
|
59103
|
-
// src/policy/default-engine.ts
|
|
59104
|
-
var DefaultPolicyEngine;
|
|
59105
|
-
var init_default_engine = __esm({
|
|
59106
|
-
"src/policy/default-engine.ts"() {
|
|
59107
|
-
"use strict";
|
|
59108
|
-
DefaultPolicyEngine = class {
|
|
59109
|
-
async initialize(_config) {
|
|
59110
|
-
}
|
|
59111
|
-
async evaluateCheckExecution(_checkId, _checkConfig) {
|
|
59112
|
-
return { allowed: true };
|
|
59113
|
-
}
|
|
59114
|
-
async evaluateToolInvocation(_serverName, _methodName, _transport) {
|
|
59115
|
-
return { allowed: true };
|
|
59116
|
-
}
|
|
59117
|
-
async evaluateCapabilities(_checkId, _capabilities) {
|
|
59118
|
-
return { allowed: true };
|
|
59119
|
-
}
|
|
59120
|
-
async shutdown() {
|
|
59121
|
-
}
|
|
59122
|
-
};
|
|
59123
|
-
}
|
|
59124
|
-
});
|
|
59125
|
-
|
|
59126
|
-
// src/enterprise/license/validator.ts
|
|
59127
|
-
var validator_exports = {};
|
|
59128
|
-
__export(validator_exports, {
|
|
59129
|
-
LicenseValidator: () => LicenseValidator
|
|
59130
|
-
});
|
|
59131
|
-
var crypto3, fs23, path27, LicenseValidator;
|
|
59132
|
-
var init_validator = __esm({
|
|
59133
|
-
"src/enterprise/license/validator.ts"() {
|
|
59134
|
-
"use strict";
|
|
59135
|
-
crypto3 = __toESM(require("crypto"));
|
|
59136
|
-
fs23 = __toESM(require("fs"));
|
|
59137
|
-
path27 = __toESM(require("path"));
|
|
59138
|
-
LicenseValidator = class _LicenseValidator {
|
|
59139
|
-
/** Ed25519 public key for license verification (PEM format). */
|
|
59140
|
-
static PUBLIC_KEY = "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAI/Zd08EFmgIdrDm/HXd0l3/5GBt7R1PrdvhdmEXhJlU=\n-----END PUBLIC KEY-----\n";
|
|
59141
|
-
cache = null;
|
|
59142
|
-
static CACHE_TTL = 5 * 60 * 1e3;
|
|
59143
|
-
// 5 minutes
|
|
59144
|
-
static GRACE_PERIOD = 72 * 3600 * 1e3;
|
|
59145
|
-
// 72 hours after expiry
|
|
59146
|
-
/**
|
|
59147
|
-
* Load and validate license from environment or file.
|
|
59148
|
-
*
|
|
59149
|
-
* Resolution order:
|
|
59150
|
-
* 1. VISOR_LICENSE env var (JWT string)
|
|
59151
|
-
* 2. VISOR_LICENSE_FILE env var (path to file)
|
|
59152
|
-
* 3. .visor-license in project root (cwd)
|
|
59153
|
-
* 4. .visor-license in ~/.config/visor/
|
|
59154
|
-
*/
|
|
59155
|
-
async loadAndValidate() {
|
|
59156
|
-
if (this.cache && Date.now() - this.cache.validatedAt < _LicenseValidator.CACHE_TTL) {
|
|
59157
|
-
return this.cache.payload;
|
|
59158
|
-
}
|
|
59159
|
-
const token = this.resolveToken();
|
|
59160
|
-
if (!token) return null;
|
|
59161
|
-
const payload = this.verifyAndDecode(token);
|
|
59162
|
-
if (!payload) return null;
|
|
59163
|
-
this.cache = { payload, validatedAt: Date.now() };
|
|
59164
|
-
return payload;
|
|
59165
|
-
}
|
|
59166
|
-
/** Check if a specific feature is licensed */
|
|
59167
|
-
hasFeature(feature) {
|
|
59168
|
-
if (!this.cache) return false;
|
|
59169
|
-
return this.cache.payload.features.includes(feature);
|
|
59170
|
-
}
|
|
59171
|
-
/** Check if license is valid (with grace period) */
|
|
59172
|
-
isValid() {
|
|
59173
|
-
if (!this.cache) return false;
|
|
59174
|
-
const now = Date.now();
|
|
59175
|
-
const expiryMs = this.cache.payload.exp * 1e3;
|
|
59176
|
-
return now < expiryMs + _LicenseValidator.GRACE_PERIOD;
|
|
59177
|
-
}
|
|
59178
|
-
/** Check if the license is within its grace period (expired but still valid) */
|
|
59179
|
-
isInGracePeriod() {
|
|
59180
|
-
if (!this.cache) return false;
|
|
59181
|
-
const now = Date.now();
|
|
59182
|
-
const expiryMs = this.cache.payload.exp * 1e3;
|
|
59183
|
-
return now >= expiryMs && now < expiryMs + _LicenseValidator.GRACE_PERIOD;
|
|
59184
|
-
}
|
|
59185
|
-
resolveToken() {
|
|
59186
|
-
if (process.env.VISOR_LICENSE) {
|
|
59187
|
-
return process.env.VISOR_LICENSE.trim();
|
|
59188
|
-
}
|
|
59189
|
-
if (process.env.VISOR_LICENSE_FILE) {
|
|
59190
|
-
const resolved = path27.resolve(process.env.VISOR_LICENSE_FILE);
|
|
59191
|
-
const home2 = process.env.HOME || process.env.USERPROFILE || "";
|
|
59192
|
-
const allowedPrefixes = [path27.normalize(process.cwd())];
|
|
59193
|
-
if (home2) allowedPrefixes.push(path27.normalize(path27.join(home2, ".config", "visor")));
|
|
59194
|
-
let realPath;
|
|
59195
|
-
try {
|
|
59196
|
-
realPath = fs23.realpathSync(resolved);
|
|
59197
|
-
} catch {
|
|
59198
|
-
return null;
|
|
59199
|
-
}
|
|
59200
|
-
const isSafe = allowedPrefixes.some(
|
|
59201
|
-
(prefix) => realPath === prefix || realPath.startsWith(prefix + path27.sep)
|
|
59202
|
-
);
|
|
59203
|
-
if (!isSafe) return null;
|
|
59204
|
-
return this.readFile(realPath);
|
|
59205
|
-
}
|
|
59206
|
-
const cwdPath = path27.join(process.cwd(), ".visor-license");
|
|
59207
|
-
const cwdToken = this.readFile(cwdPath);
|
|
59208
|
-
if (cwdToken) return cwdToken;
|
|
59209
|
-
const home = process.env.HOME || process.env.USERPROFILE || "";
|
|
59210
|
-
if (home) {
|
|
59211
|
-
const configPath = path27.join(home, ".config", "visor", ".visor-license");
|
|
59212
|
-
const configToken = this.readFile(configPath);
|
|
59213
|
-
if (configToken) return configToken;
|
|
59214
|
-
}
|
|
59215
|
-
return null;
|
|
59216
|
-
}
|
|
59217
|
-
readFile(filePath) {
|
|
59218
|
-
try {
|
|
59219
|
-
return fs23.readFileSync(filePath, "utf-8").trim();
|
|
59220
|
-
} catch {
|
|
59221
|
-
return null;
|
|
59222
|
-
}
|
|
59223
|
-
}
|
|
59224
|
-
verifyAndDecode(token) {
|
|
59225
|
-
try {
|
|
59226
|
-
const parts = token.split(".");
|
|
59227
|
-
if (parts.length !== 3) return null;
|
|
59228
|
-
const [headerB64, payloadB64, signatureB64] = parts;
|
|
59229
|
-
const header = JSON.parse(Buffer.from(headerB64, "base64url").toString());
|
|
59230
|
-
if (header.alg !== "EdDSA") return null;
|
|
59231
|
-
const data = `${headerB64}.${payloadB64}`;
|
|
59232
|
-
const signature = Buffer.from(signatureB64, "base64url");
|
|
59233
|
-
const publicKey = crypto3.createPublicKey(_LicenseValidator.PUBLIC_KEY);
|
|
59234
|
-
if (publicKey.asymmetricKeyType !== "ed25519") {
|
|
59235
|
-
return null;
|
|
59236
|
-
}
|
|
59237
|
-
const isValid = crypto3.verify(null, Buffer.from(data), publicKey, signature);
|
|
59238
|
-
if (!isValid) return null;
|
|
59239
|
-
const payload = JSON.parse(Buffer.from(payloadB64, "base64url").toString());
|
|
59240
|
-
if (!payload.org || !Array.isArray(payload.features) || typeof payload.exp !== "number" || typeof payload.iat !== "number" || !payload.sub) {
|
|
59241
|
-
return null;
|
|
59242
|
-
}
|
|
59243
|
-
const now = Date.now();
|
|
59244
|
-
const expiryMs = payload.exp * 1e3;
|
|
59245
|
-
if (now >= expiryMs + _LicenseValidator.GRACE_PERIOD) {
|
|
59246
|
-
return null;
|
|
59247
|
-
}
|
|
59248
|
-
return payload;
|
|
59249
|
-
} catch {
|
|
59250
|
-
return null;
|
|
59251
|
-
}
|
|
59252
|
-
}
|
|
59253
|
-
};
|
|
59254
|
-
}
|
|
59255
|
-
});
|
|
59256
|
-
|
|
59257
|
-
// src/enterprise/policy/opa-compiler.ts
|
|
59258
|
-
var fs24, path28, os2, crypto4, import_child_process8, OpaCompiler;
|
|
59259
|
-
var init_opa_compiler = __esm({
|
|
59260
|
-
"src/enterprise/policy/opa-compiler.ts"() {
|
|
59261
|
-
"use strict";
|
|
59262
|
-
fs24 = __toESM(require("fs"));
|
|
59263
|
-
path28 = __toESM(require("path"));
|
|
59264
|
-
os2 = __toESM(require("os"));
|
|
59265
|
-
crypto4 = __toESM(require("crypto"));
|
|
59266
|
-
import_child_process8 = require("child_process");
|
|
59267
|
-
OpaCompiler = class _OpaCompiler {
|
|
59268
|
-
static CACHE_DIR = path28.join(os2.tmpdir(), "visor-opa-cache");
|
|
59269
|
-
/**
|
|
59270
|
-
* Resolve the input paths to WASM bytes.
|
|
59271
|
-
*
|
|
59272
|
-
* Strategy:
|
|
59273
|
-
* 1. If any path is a .wasm file, read it directly
|
|
59274
|
-
* 2. If a directory contains policy.wasm, read it
|
|
59275
|
-
* 3. Otherwise, collect all .rego files and auto-compile via `opa build`
|
|
59276
|
-
*/
|
|
59277
|
-
async resolveWasmBytes(paths) {
|
|
59278
|
-
const regoFiles = [];
|
|
59279
|
-
for (const p of paths) {
|
|
59280
|
-
const resolved = path28.resolve(p);
|
|
59281
|
-
if (path28.normalize(resolved).includes("..")) {
|
|
59282
|
-
throw new Error(`Policy path contains traversal sequences: ${p}`);
|
|
59283
|
-
}
|
|
59284
|
-
if (resolved.endsWith(".wasm") && fs24.existsSync(resolved)) {
|
|
59285
|
-
return fs24.readFileSync(resolved);
|
|
59286
|
-
}
|
|
59287
|
-
if (!fs24.existsSync(resolved)) continue;
|
|
59288
|
-
const stat2 = fs24.statSync(resolved);
|
|
59289
|
-
if (stat2.isDirectory()) {
|
|
59290
|
-
const wasmCandidate = path28.join(resolved, "policy.wasm");
|
|
59291
|
-
if (fs24.existsSync(wasmCandidate)) {
|
|
59292
|
-
return fs24.readFileSync(wasmCandidate);
|
|
59293
|
-
}
|
|
59294
|
-
const files = fs24.readdirSync(resolved);
|
|
59295
|
-
for (const f of files) {
|
|
59296
|
-
if (f.endsWith(".rego")) {
|
|
59297
|
-
regoFiles.push(path28.join(resolved, f));
|
|
59298
|
-
}
|
|
59299
|
-
}
|
|
59300
|
-
} else if (resolved.endsWith(".rego")) {
|
|
59301
|
-
regoFiles.push(resolved);
|
|
59302
|
-
}
|
|
59303
|
-
}
|
|
59304
|
-
if (regoFiles.length === 0) {
|
|
59305
|
-
throw new Error(
|
|
59306
|
-
`OPA WASM evaluator: no .wasm bundle or .rego files found in: ${paths.join(", ")}`
|
|
59307
|
-
);
|
|
59308
|
-
}
|
|
59309
|
-
return this.compileRego(regoFiles);
|
|
59310
|
-
}
|
|
59311
|
-
/**
|
|
59312
|
-
* Auto-compile .rego files to a WASM bundle using the `opa` CLI.
|
|
59313
|
-
*
|
|
59314
|
-
* Caches the compiled bundle based on a content hash of all input .rego files
|
|
59315
|
-
* so subsequent runs skip compilation if policies haven't changed.
|
|
59316
|
-
*/
|
|
59317
|
-
compileRego(regoFiles) {
|
|
59318
|
-
try {
|
|
59319
|
-
(0, import_child_process8.execFileSync)("opa", ["version"], { stdio: "pipe" });
|
|
59320
|
-
} catch {
|
|
59321
|
-
throw new Error(
|
|
59322
|
-
"OPA CLI (`opa`) not found on PATH. Install it from https://www.openpolicyagent.org/docs/latest/#running-opa\nOr pre-compile your .rego files: opa build -t wasm -e visor -o bundle.tar.gz " + regoFiles.join(" ")
|
|
59323
|
-
);
|
|
59324
|
-
}
|
|
59325
|
-
const hash = crypto4.createHash("sha256");
|
|
59326
|
-
for (const f of regoFiles.sort()) {
|
|
59327
|
-
hash.update(fs24.readFileSync(f));
|
|
59328
|
-
hash.update(f);
|
|
59329
|
-
}
|
|
59330
|
-
const cacheKey = hash.digest("hex").slice(0, 16);
|
|
59331
|
-
const cacheDir = _OpaCompiler.CACHE_DIR;
|
|
59332
|
-
const cachedWasm = path28.join(cacheDir, `${cacheKey}.wasm`);
|
|
59333
|
-
if (fs24.existsSync(cachedWasm)) {
|
|
59334
|
-
return fs24.readFileSync(cachedWasm);
|
|
59335
|
-
}
|
|
59336
|
-
fs24.mkdirSync(cacheDir, { recursive: true });
|
|
59337
|
-
const bundleTar = path28.join(cacheDir, `${cacheKey}-bundle.tar.gz`);
|
|
59338
|
-
try {
|
|
59339
|
-
const args = [
|
|
59340
|
-
"build",
|
|
59341
|
-
"-t",
|
|
59342
|
-
"wasm",
|
|
59343
|
-
"-e",
|
|
59344
|
-
"visor",
|
|
59345
|
-
// entrypoint: the visor package tree
|
|
59346
|
-
"-o",
|
|
59347
|
-
bundleTar,
|
|
59348
|
-
...regoFiles
|
|
59349
|
-
];
|
|
59350
|
-
(0, import_child_process8.execFileSync)("opa", args, {
|
|
59351
|
-
stdio: "pipe",
|
|
59352
|
-
timeout: 3e4
|
|
59353
|
-
});
|
|
59354
|
-
} catch (err) {
|
|
59355
|
-
const stderr = err?.stderr?.toString() || "";
|
|
59356
|
-
throw new Error(
|
|
59357
|
-
`Failed to compile .rego files to WASM:
|
|
59358
|
-
${stderr}
|
|
59359
|
-
Ensure your .rego files are valid and the \`opa\` CLI is installed.`
|
|
59360
|
-
);
|
|
59361
|
-
}
|
|
59362
|
-
try {
|
|
59363
|
-
(0, import_child_process8.execFileSync)("tar", ["-xzf", bundleTar, "-C", cacheDir, "/policy.wasm"], {
|
|
59364
|
-
stdio: "pipe"
|
|
59365
|
-
});
|
|
59366
|
-
const extractedWasm = path28.join(cacheDir, "policy.wasm");
|
|
59367
|
-
if (fs24.existsSync(extractedWasm)) {
|
|
59368
|
-
fs24.renameSync(extractedWasm, cachedWasm);
|
|
59369
|
-
}
|
|
59370
|
-
} catch {
|
|
59371
|
-
try {
|
|
59372
|
-
(0, import_child_process8.execFileSync)("tar", ["-xzf", bundleTar, "-C", cacheDir, "policy.wasm"], {
|
|
59373
|
-
stdio: "pipe"
|
|
59374
|
-
});
|
|
59375
|
-
const extractedWasm = path28.join(cacheDir, "policy.wasm");
|
|
59376
|
-
if (fs24.existsSync(extractedWasm)) {
|
|
59377
|
-
fs24.renameSync(extractedWasm, cachedWasm);
|
|
59378
|
-
}
|
|
59379
|
-
} catch (err2) {
|
|
59380
|
-
throw new Error(`Failed to extract policy.wasm from OPA bundle: ${err2?.message || err2}`);
|
|
59381
|
-
}
|
|
59382
|
-
}
|
|
59383
|
-
try {
|
|
59384
|
-
fs24.unlinkSync(bundleTar);
|
|
59385
|
-
} catch {
|
|
59386
|
-
}
|
|
59387
|
-
if (!fs24.existsSync(cachedWasm)) {
|
|
59388
|
-
throw new Error("OPA build succeeded but policy.wasm was not found in the bundle");
|
|
59389
|
-
}
|
|
59390
|
-
return fs24.readFileSync(cachedWasm);
|
|
59391
|
-
}
|
|
59392
|
-
};
|
|
59393
|
-
}
|
|
59394
|
-
});
|
|
59395
|
-
|
|
59396
|
-
// src/enterprise/policy/opa-wasm-evaluator.ts
|
|
59397
|
-
var fs25, path29, OpaWasmEvaluator;
|
|
59398
|
-
var init_opa_wasm_evaluator = __esm({
|
|
59399
|
-
"src/enterprise/policy/opa-wasm-evaluator.ts"() {
|
|
59400
|
-
"use strict";
|
|
59401
|
-
fs25 = __toESM(require("fs"));
|
|
59402
|
-
path29 = __toESM(require("path"));
|
|
59403
|
-
init_opa_compiler();
|
|
59404
|
-
OpaWasmEvaluator = class {
|
|
59405
|
-
policy = null;
|
|
59406
|
-
dataDocument = {};
|
|
59407
|
-
compiler = new OpaCompiler();
|
|
59408
|
-
async initialize(rulesPath) {
|
|
59409
|
-
const paths = Array.isArray(rulesPath) ? rulesPath : [rulesPath];
|
|
59410
|
-
const wasmBytes = await this.compiler.resolveWasmBytes(paths);
|
|
59411
|
-
try {
|
|
59412
|
-
const { createRequire } = require("module");
|
|
59413
|
-
const runtimeRequire = createRequire(__filename);
|
|
59414
|
-
const opaWasm = runtimeRequire("@open-policy-agent/opa-wasm");
|
|
59415
|
-
const loadPolicy = opaWasm.loadPolicy || opaWasm.default?.loadPolicy;
|
|
59416
|
-
if (!loadPolicy) {
|
|
59417
|
-
throw new Error("loadPolicy not found in @open-policy-agent/opa-wasm");
|
|
59418
|
-
}
|
|
59419
|
-
this.policy = await loadPolicy(wasmBytes);
|
|
59420
|
-
} catch (err) {
|
|
59421
|
-
if (err?.code === "MODULE_NOT_FOUND" || err?.code === "ERR_MODULE_NOT_FOUND") {
|
|
59422
|
-
throw new Error(
|
|
59423
|
-
"OPA WASM evaluator requires @open-policy-agent/opa-wasm. Install it with: npm install @open-policy-agent/opa-wasm"
|
|
59424
|
-
);
|
|
59425
|
-
}
|
|
59426
|
-
throw err;
|
|
59427
|
-
}
|
|
59428
|
-
}
|
|
59429
|
-
/**
|
|
59430
|
-
* Load external data from a JSON file to use as the OPA data document.
|
|
59431
|
-
* The loaded data will be passed to `policy.setData()` during evaluation,
|
|
59432
|
-
* making it available in Rego via `data.<key>`.
|
|
59433
|
-
*/
|
|
59434
|
-
loadData(dataPath) {
|
|
59435
|
-
const resolved = path29.resolve(dataPath);
|
|
59436
|
-
if (path29.normalize(resolved).includes("..")) {
|
|
59437
|
-
throw new Error(`Data path contains traversal sequences: ${dataPath}`);
|
|
59438
|
-
}
|
|
59439
|
-
if (!fs25.existsSync(resolved)) {
|
|
59440
|
-
throw new Error(`OPA data file not found: ${resolved}`);
|
|
59441
|
-
}
|
|
59442
|
-
const stat2 = fs25.statSync(resolved);
|
|
59443
|
-
if (stat2.size > 10 * 1024 * 1024) {
|
|
59444
|
-
throw new Error(`OPA data file exceeds 10MB limit: ${resolved} (${stat2.size} bytes)`);
|
|
59445
|
-
}
|
|
59446
|
-
const raw = fs25.readFileSync(resolved, "utf-8");
|
|
59447
|
-
try {
|
|
59448
|
-
const parsed = JSON.parse(raw);
|
|
59449
|
-
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
59450
|
-
throw new Error("OPA data file must contain a JSON object (not an array or primitive)");
|
|
59451
|
-
}
|
|
59452
|
-
this.dataDocument = parsed;
|
|
59453
|
-
} catch (err) {
|
|
59454
|
-
if (err.message.startsWith("OPA data file must")) {
|
|
59455
|
-
throw err;
|
|
59456
|
-
}
|
|
59457
|
-
throw new Error(`Failed to parse OPA data file ${resolved}: ${err.message}`);
|
|
59458
|
-
}
|
|
59459
|
-
}
|
|
59460
|
-
async evaluate(input) {
|
|
59461
|
-
if (!this.policy) {
|
|
59462
|
-
throw new Error("OPA WASM evaluator not initialized");
|
|
59463
|
-
}
|
|
59464
|
-
this.policy.setData(this.dataDocument);
|
|
59465
|
-
const resultSet = this.policy.evaluate(input);
|
|
59466
|
-
if (Array.isArray(resultSet) && resultSet.length > 0) {
|
|
59467
|
-
return resultSet[0].result;
|
|
59468
|
-
}
|
|
59469
|
-
return void 0;
|
|
59470
|
-
}
|
|
59471
|
-
async shutdown() {
|
|
59472
|
-
if (this.policy) {
|
|
59473
|
-
if (typeof this.policy.close === "function") {
|
|
59474
|
-
try {
|
|
59475
|
-
this.policy.close();
|
|
59476
|
-
} catch {
|
|
59477
|
-
}
|
|
59478
|
-
} else if (typeof this.policy.free === "function") {
|
|
59479
|
-
try {
|
|
59480
|
-
this.policy.free();
|
|
59481
|
-
} catch {
|
|
59482
|
-
}
|
|
59483
|
-
}
|
|
59484
|
-
}
|
|
59485
|
-
this.policy = null;
|
|
59486
|
-
}
|
|
59487
|
-
};
|
|
59488
|
-
}
|
|
59489
|
-
});
|
|
59490
|
-
|
|
59491
|
-
// src/enterprise/policy/opa-http-evaluator.ts
|
|
59492
|
-
var OpaHttpEvaluator;
|
|
59493
|
-
var init_opa_http_evaluator = __esm({
|
|
59494
|
-
"src/enterprise/policy/opa-http-evaluator.ts"() {
|
|
59495
|
-
"use strict";
|
|
59496
|
-
OpaHttpEvaluator = class {
|
|
59497
|
-
baseUrl;
|
|
59498
|
-
timeout;
|
|
59499
|
-
constructor(baseUrl, timeout = 5e3) {
|
|
59500
|
-
let parsed;
|
|
59501
|
-
try {
|
|
59502
|
-
parsed = new URL(baseUrl);
|
|
59503
|
-
} catch {
|
|
59504
|
-
throw new Error(`OPA HTTP evaluator: invalid URL: ${baseUrl}`);
|
|
59505
|
-
}
|
|
59506
|
-
if (!["http:", "https:"].includes(parsed.protocol)) {
|
|
59507
|
-
throw new Error(
|
|
59508
|
-
`OPA HTTP evaluator: url must use http:// or https:// protocol, got: ${baseUrl}`
|
|
59509
|
-
);
|
|
59510
|
-
}
|
|
59511
|
-
const hostname = parsed.hostname;
|
|
59512
|
-
if (this.isBlockedHostname(hostname)) {
|
|
59513
|
-
throw new Error(
|
|
59514
|
-
`OPA HTTP evaluator: url must not point to internal, loopback, or private network addresses`
|
|
59515
|
-
);
|
|
59516
|
-
}
|
|
59517
|
-
this.baseUrl = baseUrl.replace(/\/+$/, "");
|
|
59518
|
-
this.timeout = timeout;
|
|
59519
|
-
}
|
|
59520
|
-
/**
|
|
59521
|
-
* Check if a hostname is blocked due to SSRF concerns.
|
|
59522
|
-
*
|
|
59523
|
-
* Blocks:
|
|
59524
|
-
* - Loopback addresses (127.x.x.x, localhost, 0.0.0.0, ::1)
|
|
59525
|
-
* - Link-local addresses (169.254.x.x)
|
|
59526
|
-
* - Private networks (10.x.x.x, 172.16-31.x.x, 192.168.x.x)
|
|
59527
|
-
* - IPv6 unique local addresses (fd00::/8)
|
|
59528
|
-
* - Cloud metadata services (*.internal)
|
|
59529
|
-
*/
|
|
59530
|
-
isBlockedHostname(hostname) {
|
|
59531
|
-
if (!hostname) return true;
|
|
59532
|
-
const normalized = hostname.toLowerCase().replace(/^\[|\]$/g, "");
|
|
59533
|
-
if (normalized === "metadata.google.internal" || normalized.endsWith(".internal")) {
|
|
59534
|
-
return true;
|
|
59535
|
-
}
|
|
59536
|
-
if (normalized === "localhost" || normalized === "localhost.localdomain") {
|
|
59537
|
-
return true;
|
|
59538
|
-
}
|
|
59539
|
-
if (normalized === "::1" || normalized === "0:0:0:0:0:0:0:1") {
|
|
59540
|
-
return true;
|
|
59541
|
-
}
|
|
59542
|
-
const ipv4Pattern = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/;
|
|
59543
|
-
const ipv4Match = normalized.match(ipv4Pattern);
|
|
59544
|
-
if (ipv4Match) {
|
|
59545
|
-
const octets = ipv4Match.slice(1, 5).map(Number);
|
|
59546
|
-
if (octets.some((octet) => octet > 255)) {
|
|
59547
|
-
return false;
|
|
59548
|
-
}
|
|
59549
|
-
const [a, b] = octets;
|
|
59550
|
-
if (a === 127) {
|
|
59551
|
-
return true;
|
|
59552
|
-
}
|
|
59553
|
-
if (a === 0) {
|
|
59554
|
-
return true;
|
|
59555
|
-
}
|
|
59556
|
-
if (a === 169 && b === 254) {
|
|
59557
|
-
return true;
|
|
59558
|
-
}
|
|
59559
|
-
if (a === 10) {
|
|
59560
|
-
return true;
|
|
59561
|
-
}
|
|
59562
|
-
if (a === 172 && b >= 16 && b <= 31) {
|
|
59563
|
-
return true;
|
|
59564
|
-
}
|
|
59565
|
-
if (a === 192 && b === 168) {
|
|
59566
|
-
return true;
|
|
59567
|
-
}
|
|
59568
|
-
}
|
|
59569
|
-
if (normalized.startsWith("fd") || normalized.startsWith("fc")) {
|
|
59570
|
-
return true;
|
|
59571
|
-
}
|
|
59572
|
-
if (normalized.startsWith("fe80:")) {
|
|
59573
|
-
return true;
|
|
59574
|
-
}
|
|
59575
|
-
return false;
|
|
59576
|
-
}
|
|
59577
|
-
/**
|
|
59578
|
-
* Evaluate a policy rule against an input document via OPA REST API.
|
|
59579
|
-
*
|
|
59580
|
-
* @param input - The input document to evaluate
|
|
59581
|
-
* @param rulePath - OPA rule path (e.g., 'visor/check/execute')
|
|
59582
|
-
* @returns The result object from OPA, or undefined on error
|
|
59583
|
-
*/
|
|
59584
|
-
async evaluate(input, rulePath) {
|
|
59585
|
-
const encodedPath = rulePath.split("/").map((s) => encodeURIComponent(s)).join("/");
|
|
59586
|
-
const url = `${this.baseUrl}/v1/data/${encodedPath}`;
|
|
59587
|
-
const controller = new AbortController();
|
|
59588
|
-
const timer = setTimeout(() => controller.abort(), this.timeout);
|
|
59589
|
-
try {
|
|
59590
|
-
const response = await fetch(url, {
|
|
59591
|
-
method: "POST",
|
|
59592
|
-
headers: { "Content-Type": "application/json" },
|
|
59593
|
-
body: JSON.stringify({ input }),
|
|
59594
|
-
signal: controller.signal
|
|
59595
|
-
});
|
|
59596
|
-
if (!response.ok) {
|
|
59597
|
-
throw new Error(`OPA HTTP ${response.status}: ${response.statusText}`);
|
|
59598
|
-
}
|
|
59599
|
-
let body;
|
|
59600
|
-
try {
|
|
59601
|
-
body = await response.json();
|
|
59602
|
-
} catch (jsonErr) {
|
|
59603
|
-
throw new Error(
|
|
59604
|
-
`OPA HTTP evaluator: failed to parse JSON response: ${jsonErr instanceof Error ? jsonErr.message : String(jsonErr)}`
|
|
59605
|
-
);
|
|
59606
|
-
}
|
|
59607
|
-
return body?.result;
|
|
59608
|
-
} finally {
|
|
59609
|
-
clearTimeout(timer);
|
|
59610
|
-
}
|
|
59611
|
-
}
|
|
59612
|
-
async shutdown() {
|
|
59613
|
-
}
|
|
59614
|
-
};
|
|
59615
|
-
}
|
|
59616
|
-
});
|
|
59617
|
-
|
|
59618
|
-
// src/enterprise/policy/policy-input-builder.ts
|
|
59619
|
-
var PolicyInputBuilder;
|
|
59620
|
-
var init_policy_input_builder = __esm({
|
|
59621
|
-
"src/enterprise/policy/policy-input-builder.ts"() {
|
|
59622
|
-
"use strict";
|
|
59623
|
-
PolicyInputBuilder = class {
|
|
59624
|
-
roles;
|
|
59625
|
-
actor;
|
|
59626
|
-
repository;
|
|
59627
|
-
pullRequest;
|
|
59628
|
-
constructor(policyConfig, actor, repository, pullRequest) {
|
|
59629
|
-
this.roles = policyConfig.roles || {};
|
|
59630
|
-
this.actor = actor;
|
|
59631
|
-
this.repository = repository;
|
|
59632
|
-
this.pullRequest = pullRequest;
|
|
59633
|
-
}
|
|
59634
|
-
/** Resolve which roles apply to the current actor. */
|
|
59635
|
-
resolveRoles() {
|
|
59636
|
-
const matched = [];
|
|
59637
|
-
for (const [roleName, roleConfig] of Object.entries(this.roles)) {
|
|
59638
|
-
let identityMatch = false;
|
|
59639
|
-
if (roleConfig.author_association && this.actor.authorAssociation && roleConfig.author_association.includes(this.actor.authorAssociation)) {
|
|
59640
|
-
identityMatch = true;
|
|
59641
|
-
}
|
|
59642
|
-
if (!identityMatch && roleConfig.users && this.actor.login && roleConfig.users.includes(this.actor.login)) {
|
|
59643
|
-
identityMatch = true;
|
|
59644
|
-
}
|
|
59645
|
-
if (!identityMatch && roleConfig.slack_users && this.actor.slack?.userId && roleConfig.slack_users.includes(this.actor.slack.userId)) {
|
|
59646
|
-
identityMatch = true;
|
|
59647
|
-
}
|
|
59648
|
-
if (!identityMatch && roleConfig.emails && this.actor.slack?.email) {
|
|
59649
|
-
const actorEmail = this.actor.slack.email.toLowerCase();
|
|
59650
|
-
if (roleConfig.emails.some((e) => e.toLowerCase() === actorEmail)) {
|
|
59651
|
-
identityMatch = true;
|
|
59652
|
-
}
|
|
59653
|
-
}
|
|
59654
|
-
if (!identityMatch) continue;
|
|
59655
|
-
if (roleConfig.slack_channels && roleConfig.slack_channels.length > 0) {
|
|
59656
|
-
if (!this.actor.slack?.channelId || !roleConfig.slack_channels.includes(this.actor.slack.channelId)) {
|
|
59657
|
-
continue;
|
|
59658
|
-
}
|
|
59659
|
-
}
|
|
59660
|
-
matched.push(roleName);
|
|
59661
|
-
}
|
|
59662
|
-
return matched;
|
|
59663
|
-
}
|
|
59664
|
-
buildActor() {
|
|
59665
|
-
return {
|
|
59666
|
-
authorAssociation: this.actor.authorAssociation,
|
|
59667
|
-
login: this.actor.login,
|
|
59668
|
-
roles: this.resolveRoles(),
|
|
59669
|
-
isLocalMode: this.actor.isLocalMode,
|
|
59670
|
-
...this.actor.slack && { slack: this.actor.slack }
|
|
59671
|
-
};
|
|
59672
|
-
}
|
|
59673
|
-
forCheckExecution(check) {
|
|
59674
|
-
return {
|
|
59675
|
-
scope: "check.execute",
|
|
59676
|
-
check: {
|
|
59677
|
-
id: check.id,
|
|
59678
|
-
type: check.type,
|
|
59679
|
-
group: check.group,
|
|
59680
|
-
tags: check.tags,
|
|
59681
|
-
criticality: check.criticality,
|
|
59682
|
-
sandbox: check.sandbox,
|
|
59683
|
-
policy: check.policy
|
|
59684
|
-
},
|
|
59685
|
-
actor: this.buildActor(),
|
|
59686
|
-
repository: this.repository,
|
|
59687
|
-
pullRequest: this.pullRequest
|
|
59688
|
-
};
|
|
59689
|
-
}
|
|
59690
|
-
forToolInvocation(serverName, methodName, transport) {
|
|
59691
|
-
return {
|
|
59692
|
-
scope: "tool.invoke",
|
|
59693
|
-
tool: { serverName, methodName, transport },
|
|
59694
|
-
actor: this.buildActor(),
|
|
59695
|
-
repository: this.repository,
|
|
59696
|
-
pullRequest: this.pullRequest
|
|
59697
|
-
};
|
|
59698
|
-
}
|
|
59699
|
-
forCapabilityResolve(checkId, capabilities) {
|
|
59700
|
-
return {
|
|
59701
|
-
scope: "capability.resolve",
|
|
59702
|
-
check: { id: checkId, type: "ai" },
|
|
59703
|
-
capability: capabilities,
|
|
59704
|
-
actor: this.buildActor(),
|
|
59705
|
-
repository: this.repository,
|
|
59706
|
-
pullRequest: this.pullRequest
|
|
59707
|
-
};
|
|
59708
|
-
}
|
|
59709
|
-
};
|
|
59710
|
-
}
|
|
59711
|
-
});
|
|
59712
|
-
|
|
59713
|
-
// src/enterprise/policy/opa-policy-engine.ts
|
|
59714
|
-
var opa_policy_engine_exports = {};
|
|
59715
|
-
__export(opa_policy_engine_exports, {
|
|
59716
|
-
OpaPolicyEngine: () => OpaPolicyEngine
|
|
59717
|
-
});
|
|
59718
|
-
var OpaPolicyEngine;
|
|
59719
|
-
var init_opa_policy_engine = __esm({
|
|
59720
|
-
"src/enterprise/policy/opa-policy-engine.ts"() {
|
|
59721
|
-
"use strict";
|
|
59722
|
-
init_opa_wasm_evaluator();
|
|
59723
|
-
init_opa_http_evaluator();
|
|
59724
|
-
init_policy_input_builder();
|
|
59725
|
-
OpaPolicyEngine = class {
|
|
59726
|
-
evaluator = null;
|
|
59727
|
-
fallback;
|
|
59728
|
-
timeout;
|
|
59729
|
-
config;
|
|
59730
|
-
inputBuilder = null;
|
|
59731
|
-
logger = null;
|
|
59732
|
-
constructor(config) {
|
|
59733
|
-
this.config = config;
|
|
59734
|
-
this.fallback = config.fallback || "deny";
|
|
59735
|
-
this.timeout = config.timeout || 5e3;
|
|
59736
|
-
}
|
|
59737
|
-
async initialize(config) {
|
|
59738
|
-
try {
|
|
59739
|
-
this.logger = (init_logger(), __toCommonJS(logger_exports)).logger;
|
|
59740
|
-
} catch {
|
|
59741
|
-
}
|
|
59742
|
-
const actor = {
|
|
59743
|
-
authorAssociation: process.env.VISOR_AUTHOR_ASSOCIATION,
|
|
59744
|
-
login: process.env.VISOR_AUTHOR_LOGIN || process.env.GITHUB_ACTOR,
|
|
59745
|
-
isLocalMode: !process.env.GITHUB_ACTIONS
|
|
59746
|
-
};
|
|
59747
|
-
const repo = {
|
|
59748
|
-
owner: process.env.GITHUB_REPOSITORY_OWNER,
|
|
59749
|
-
name: process.env.GITHUB_REPOSITORY?.split("/")[1],
|
|
59750
|
-
branch: process.env.GITHUB_HEAD_REF,
|
|
59751
|
-
baseBranch: process.env.GITHUB_BASE_REF,
|
|
59752
|
-
event: process.env.GITHUB_EVENT_NAME
|
|
59753
|
-
};
|
|
59754
|
-
const prNum = process.env.GITHUB_PR_NUMBER ? parseInt(process.env.GITHUB_PR_NUMBER, 10) : void 0;
|
|
59755
|
-
const pullRequest = {
|
|
59756
|
-
number: prNum !== void 0 && Number.isFinite(prNum) ? prNum : void 0
|
|
59757
|
-
};
|
|
59758
|
-
this.inputBuilder = new PolicyInputBuilder(config, actor, repo, pullRequest);
|
|
59759
|
-
if (config.engine === "local") {
|
|
59760
|
-
if (!config.rules) {
|
|
59761
|
-
throw new Error("OPA local mode requires `policy.rules` path to .wasm or .rego files");
|
|
59762
|
-
}
|
|
59763
|
-
const wasm = new OpaWasmEvaluator();
|
|
59764
|
-
await wasm.initialize(config.rules);
|
|
59765
|
-
if (config.data) {
|
|
59766
|
-
wasm.loadData(config.data);
|
|
59767
|
-
}
|
|
59768
|
-
this.evaluator = wasm;
|
|
59769
|
-
} else if (config.engine === "remote") {
|
|
59770
|
-
if (!config.url) {
|
|
59771
|
-
throw new Error("OPA remote mode requires `policy.url` pointing to OPA server");
|
|
59772
|
-
}
|
|
59773
|
-
this.evaluator = new OpaHttpEvaluator(config.url, this.timeout);
|
|
59774
|
-
} else {
|
|
59775
|
-
this.evaluator = null;
|
|
59776
|
-
}
|
|
59777
|
-
}
|
|
59778
|
-
/**
|
|
59779
|
-
* Update actor/repo/PR context (e.g., after PR info becomes available).
|
|
59780
|
-
* Called by the enterprise loader when engine context is enriched.
|
|
59781
|
-
*/
|
|
59782
|
-
setActorContext(actor, repo, pullRequest) {
|
|
59783
|
-
this.inputBuilder = new PolicyInputBuilder(this.config, actor, repo, pullRequest);
|
|
59784
|
-
}
|
|
59785
|
-
async evaluateCheckExecution(checkId, checkConfig) {
|
|
59786
|
-
if (!this.evaluator || !this.inputBuilder) return { allowed: true };
|
|
59787
|
-
const cfg = checkConfig && typeof checkConfig === "object" ? checkConfig : {};
|
|
59788
|
-
const policyOverride = cfg.policy;
|
|
59789
|
-
const input = this.inputBuilder.forCheckExecution({
|
|
59790
|
-
id: checkId,
|
|
59791
|
-
type: cfg.type || "ai",
|
|
59792
|
-
group: cfg.group,
|
|
59793
|
-
tags: cfg.tags,
|
|
59794
|
-
criticality: cfg.criticality,
|
|
59795
|
-
sandbox: cfg.sandbox,
|
|
59796
|
-
policy: policyOverride
|
|
59797
|
-
});
|
|
59798
|
-
return this.doEvaluate(input, this.resolveRulePath("check.execute", policyOverride?.rule));
|
|
59799
|
-
}
|
|
59800
|
-
async evaluateToolInvocation(serverName, methodName, transport) {
|
|
59801
|
-
if (!this.evaluator || !this.inputBuilder) return { allowed: true };
|
|
59802
|
-
const input = this.inputBuilder.forToolInvocation(serverName, methodName, transport);
|
|
59803
|
-
return this.doEvaluate(input, "visor/tool/invoke");
|
|
59804
|
-
}
|
|
59805
|
-
async evaluateCapabilities(checkId, capabilities) {
|
|
59806
|
-
if (!this.evaluator || !this.inputBuilder) return { allowed: true };
|
|
59807
|
-
const input = this.inputBuilder.forCapabilityResolve(checkId, capabilities);
|
|
59808
|
-
return this.doEvaluate(input, "visor/capability/resolve");
|
|
59809
|
-
}
|
|
59810
|
-
async shutdown() {
|
|
59811
|
-
if (this.evaluator && "shutdown" in this.evaluator) {
|
|
59812
|
-
await this.evaluator.shutdown();
|
|
59813
|
-
}
|
|
59814
|
-
this.evaluator = null;
|
|
59815
|
-
this.inputBuilder = null;
|
|
59816
|
-
}
|
|
59817
|
-
resolveRulePath(defaultScope, override) {
|
|
59818
|
-
if (override) {
|
|
59819
|
-
return override.startsWith("visor/") ? override : `visor/${override}`;
|
|
59820
|
-
}
|
|
59821
|
-
return `visor/${defaultScope.replace(/\./g, "/")}`;
|
|
59822
|
-
}
|
|
59823
|
-
async doEvaluate(input, rulePath) {
|
|
59824
|
-
try {
|
|
59825
|
-
this.logger?.debug(`[PolicyEngine] Evaluating ${rulePath}`, JSON.stringify(input));
|
|
59826
|
-
let timer;
|
|
59827
|
-
const timeoutPromise = new Promise((_resolve, reject) => {
|
|
59828
|
-
timer = setTimeout(() => reject(new Error("policy evaluation timeout")), this.timeout);
|
|
59829
|
-
});
|
|
59830
|
-
try {
|
|
59831
|
-
const result = await Promise.race([this.rawEvaluate(input, rulePath), timeoutPromise]);
|
|
59832
|
-
const decision = this.parseDecision(result);
|
|
59833
|
-
if (!decision.allowed && this.fallback === "warn") {
|
|
59834
|
-
decision.allowed = true;
|
|
59835
|
-
decision.warn = true;
|
|
59836
|
-
decision.reason = `audit: ${decision.reason || "policy denied"}`;
|
|
59837
|
-
}
|
|
59838
|
-
this.logger?.debug(
|
|
59839
|
-
`[PolicyEngine] Decision for ${rulePath}: allowed=${decision.allowed}, warn=${decision.warn || false}, reason=${decision.reason || "none"}`
|
|
59840
|
-
);
|
|
59841
|
-
return decision;
|
|
59842
|
-
} finally {
|
|
59843
|
-
if (timer) clearTimeout(timer);
|
|
59844
|
-
}
|
|
59845
|
-
} catch (err) {
|
|
59846
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
59847
|
-
this.logger?.warn(`[PolicyEngine] Evaluation failed for ${rulePath}: ${msg}`);
|
|
59848
|
-
return {
|
|
59849
|
-
allowed: this.fallback === "allow" || this.fallback === "warn",
|
|
59850
|
-
warn: this.fallback === "warn" ? true : void 0,
|
|
59851
|
-
reason: `policy evaluation failed, fallback=${this.fallback}`
|
|
59852
|
-
};
|
|
59853
|
-
}
|
|
59854
|
-
}
|
|
59855
|
-
async rawEvaluate(input, rulePath) {
|
|
59856
|
-
if (this.evaluator instanceof OpaWasmEvaluator) {
|
|
59857
|
-
const result = await this.evaluator.evaluate(input);
|
|
59858
|
-
return this.navigateWasmResult(result, rulePath);
|
|
59859
|
-
}
|
|
59860
|
-
return this.evaluator.evaluate(input, rulePath);
|
|
59861
|
-
}
|
|
59862
|
-
/**
|
|
59863
|
-
* Navigate nested OPA WASM result tree to reach the specific rule's output.
|
|
59864
|
-
* The WASM entrypoint `-e visor` means the result root IS the visor package,
|
|
59865
|
-
* so we strip the `visor/` prefix and walk the remaining segments.
|
|
59866
|
-
*/
|
|
59867
|
-
navigateWasmResult(result, rulePath) {
|
|
59868
|
-
if (!result || typeof result !== "object") return result;
|
|
59869
|
-
const segments = rulePath.replace(/^visor\//, "").split("/");
|
|
59870
|
-
let current = result;
|
|
59871
|
-
for (const seg of segments) {
|
|
59872
|
-
if (current && typeof current === "object" && seg in current) {
|
|
59873
|
-
current = current[seg];
|
|
59874
|
-
} else {
|
|
59875
|
-
return void 0;
|
|
59876
|
-
}
|
|
59877
|
-
}
|
|
59878
|
-
return current;
|
|
59879
|
-
}
|
|
59880
|
-
parseDecision(result) {
|
|
59881
|
-
if (result === void 0 || result === null) {
|
|
59882
|
-
return {
|
|
59883
|
-
allowed: this.fallback === "allow" || this.fallback === "warn",
|
|
59884
|
-
warn: this.fallback === "warn" ? true : void 0,
|
|
59885
|
-
reason: this.fallback === "warn" ? "audit: no policy result" : "no policy result"
|
|
59886
|
-
};
|
|
59887
|
-
}
|
|
59888
|
-
const allowed = result.allowed !== false;
|
|
59889
|
-
const decision = {
|
|
59890
|
-
allowed,
|
|
59891
|
-
reason: result.reason
|
|
59892
|
-
};
|
|
59893
|
-
if (result.capabilities) {
|
|
59894
|
-
decision.capabilities = result.capabilities;
|
|
59895
|
-
}
|
|
59896
|
-
return decision;
|
|
59897
|
-
}
|
|
59898
|
-
};
|
|
59899
|
-
}
|
|
59900
|
-
});
|
|
59901
|
-
|
|
59902
|
-
// src/enterprise/scheduler/knex-store.ts
|
|
59903
|
-
var knex_store_exports = {};
|
|
59904
|
-
__export(knex_store_exports, {
|
|
59905
|
-
KnexStoreBackend: () => KnexStoreBackend
|
|
59906
|
-
});
|
|
59907
|
-
function toNum(val) {
|
|
59908
|
-
if (val === null || val === void 0) return void 0;
|
|
59909
|
-
return typeof val === "string" ? parseInt(val, 10) : val;
|
|
59910
|
-
}
|
|
59911
|
-
function safeJsonParse2(value) {
|
|
59912
|
-
if (!value) return void 0;
|
|
59913
|
-
try {
|
|
59914
|
-
return JSON.parse(value);
|
|
59915
|
-
} catch {
|
|
59916
|
-
return void 0;
|
|
59917
|
-
}
|
|
59918
|
-
}
|
|
59919
|
-
function fromTriggerRow2(row) {
|
|
59920
|
-
return {
|
|
59921
|
-
id: row.id,
|
|
59922
|
-
creatorId: row.creator_id,
|
|
59923
|
-
creatorContext: row.creator_context ?? void 0,
|
|
59924
|
-
creatorName: row.creator_name ?? void 0,
|
|
59925
|
-
description: row.description ?? void 0,
|
|
59926
|
-
channels: safeJsonParse2(row.channels),
|
|
59927
|
-
fromUsers: safeJsonParse2(row.from_users),
|
|
59928
|
-
fromBots: row.from_bots === true || row.from_bots === 1,
|
|
59929
|
-
contains: safeJsonParse2(row.contains),
|
|
59930
|
-
matchPattern: row.match_pattern ?? void 0,
|
|
59931
|
-
threads: row.threads,
|
|
59932
|
-
workflow: row.workflow,
|
|
59933
|
-
inputs: safeJsonParse2(row.inputs),
|
|
59934
|
-
outputContext: safeJsonParse2(row.output_context),
|
|
59935
|
-
status: row.status,
|
|
59936
|
-
enabled: row.enabled === true || row.enabled === 1,
|
|
59937
|
-
createdAt: toNum(row.created_at)
|
|
59938
|
-
};
|
|
59939
|
-
}
|
|
59940
|
-
function toTriggerInsertRow(trigger) {
|
|
59941
|
-
return {
|
|
59942
|
-
id: trigger.id,
|
|
59943
|
-
creator_id: trigger.creatorId,
|
|
59944
|
-
creator_context: trigger.creatorContext ?? null,
|
|
59945
|
-
creator_name: trigger.creatorName ?? null,
|
|
59946
|
-
description: trigger.description ?? null,
|
|
59947
|
-
channels: trigger.channels ? JSON.stringify(trigger.channels) : null,
|
|
59948
|
-
from_users: trigger.fromUsers ? JSON.stringify(trigger.fromUsers) : null,
|
|
59949
|
-
from_bots: trigger.fromBots,
|
|
59950
|
-
contains: trigger.contains ? JSON.stringify(trigger.contains) : null,
|
|
59951
|
-
match_pattern: trigger.matchPattern ?? null,
|
|
59952
|
-
threads: trigger.threads,
|
|
59953
|
-
workflow: trigger.workflow,
|
|
59954
|
-
inputs: trigger.inputs ? JSON.stringify(trigger.inputs) : null,
|
|
59955
|
-
output_context: trigger.outputContext ? JSON.stringify(trigger.outputContext) : null,
|
|
59956
|
-
status: trigger.status,
|
|
59957
|
-
enabled: trigger.enabled,
|
|
59958
|
-
created_at: trigger.createdAt
|
|
59959
|
-
};
|
|
59960
|
-
}
|
|
59961
|
-
function fromDbRow2(row) {
|
|
59962
|
-
return {
|
|
59963
|
-
id: row.id,
|
|
59964
|
-
creatorId: row.creator_id,
|
|
59965
|
-
creatorContext: row.creator_context ?? void 0,
|
|
59966
|
-
creatorName: row.creator_name ?? void 0,
|
|
59967
|
-
timezone: row.timezone,
|
|
59968
|
-
schedule: row.schedule_expr,
|
|
59969
|
-
runAt: toNum(row.run_at),
|
|
59970
|
-
isRecurring: row.is_recurring === true || row.is_recurring === 1,
|
|
59971
|
-
originalExpression: row.original_expression,
|
|
59972
|
-
workflow: row.workflow ?? void 0,
|
|
59973
|
-
workflowInputs: safeJsonParse2(row.workflow_inputs),
|
|
59974
|
-
outputContext: safeJsonParse2(row.output_context),
|
|
59975
|
-
status: row.status,
|
|
59976
|
-
createdAt: toNum(row.created_at),
|
|
59977
|
-
lastRunAt: toNum(row.last_run_at),
|
|
59978
|
-
nextRunAt: toNum(row.next_run_at),
|
|
59979
|
-
runCount: row.run_count,
|
|
59980
|
-
failureCount: row.failure_count,
|
|
59981
|
-
lastError: row.last_error ?? void 0,
|
|
59982
|
-
previousResponse: row.previous_response ?? void 0
|
|
59983
|
-
};
|
|
59984
|
-
}
|
|
59985
|
-
function toInsertRow(schedule) {
|
|
59986
|
-
return {
|
|
59987
|
-
id: schedule.id,
|
|
59988
|
-
creator_id: schedule.creatorId,
|
|
59989
|
-
creator_context: schedule.creatorContext ?? null,
|
|
59990
|
-
creator_name: schedule.creatorName ?? null,
|
|
59991
|
-
timezone: schedule.timezone,
|
|
59992
|
-
schedule_expr: schedule.schedule,
|
|
59993
|
-
run_at: schedule.runAt ?? null,
|
|
59994
|
-
is_recurring: schedule.isRecurring,
|
|
59995
|
-
original_expression: schedule.originalExpression,
|
|
59996
|
-
workflow: schedule.workflow ?? null,
|
|
59997
|
-
workflow_inputs: schedule.workflowInputs ? JSON.stringify(schedule.workflowInputs) : null,
|
|
59998
|
-
output_context: schedule.outputContext ? JSON.stringify(schedule.outputContext) : null,
|
|
59999
|
-
status: schedule.status,
|
|
60000
|
-
created_at: schedule.createdAt,
|
|
60001
|
-
last_run_at: schedule.lastRunAt ?? null,
|
|
60002
|
-
next_run_at: schedule.nextRunAt ?? null,
|
|
60003
|
-
run_count: schedule.runCount,
|
|
60004
|
-
failure_count: schedule.failureCount,
|
|
60005
|
-
last_error: schedule.lastError ?? null,
|
|
60006
|
-
previous_response: schedule.previousResponse ?? null
|
|
60007
|
-
};
|
|
60008
|
-
}
|
|
60009
|
-
var fs26, path30, import_uuid2, KnexStoreBackend;
|
|
60010
|
-
var init_knex_store = __esm({
|
|
60011
|
-
"src/enterprise/scheduler/knex-store.ts"() {
|
|
60012
|
-
"use strict";
|
|
60013
|
-
fs26 = __toESM(require("fs"));
|
|
60014
|
-
path30 = __toESM(require("path"));
|
|
60015
|
-
import_uuid2 = require("uuid");
|
|
60016
|
-
init_logger();
|
|
60017
|
-
KnexStoreBackend = class {
|
|
60018
|
-
knex = null;
|
|
60019
|
-
driver;
|
|
60020
|
-
connection;
|
|
60021
|
-
constructor(driver, storageConfig, _haConfig) {
|
|
60022
|
-
this.driver = driver;
|
|
60023
|
-
this.connection = storageConfig.connection || {};
|
|
60024
|
-
}
|
|
60025
|
-
async initialize() {
|
|
60026
|
-
const { createRequire } = require("module");
|
|
60027
|
-
const runtimeRequire = createRequire(__filename);
|
|
60028
|
-
let knexFactory;
|
|
60029
|
-
try {
|
|
60030
|
-
knexFactory = runtimeRequire("knex");
|
|
60031
|
-
} catch (err) {
|
|
60032
|
-
const code = err?.code;
|
|
60033
|
-
if (code === "MODULE_NOT_FOUND" || code === "ERR_MODULE_NOT_FOUND") {
|
|
60034
|
-
throw new Error(
|
|
60035
|
-
"knex is required for PostgreSQL/MySQL/MSSQL schedule storage. Install it with: npm install knex"
|
|
60036
|
-
);
|
|
60037
|
-
}
|
|
60038
|
-
throw err;
|
|
60039
|
-
}
|
|
60040
|
-
const clientMap = {
|
|
60041
|
-
postgresql: "pg",
|
|
60042
|
-
mysql: "mysql2",
|
|
60043
|
-
mssql: "tedious"
|
|
60044
|
-
};
|
|
60045
|
-
const client = clientMap[this.driver];
|
|
60046
|
-
let connection;
|
|
60047
|
-
if (this.connection.connection_string) {
|
|
60048
|
-
connection = this.connection.connection_string;
|
|
60049
|
-
} else if (this.driver === "mssql") {
|
|
60050
|
-
connection = this.buildMssqlConnection();
|
|
60051
|
-
} else {
|
|
60052
|
-
connection = this.buildStandardConnection();
|
|
60053
|
-
}
|
|
60054
|
-
this.knex = knexFactory({
|
|
60055
|
-
client,
|
|
60056
|
-
connection,
|
|
60057
|
-
pool: {
|
|
60058
|
-
min: this.connection.pool?.min ?? 0,
|
|
60059
|
-
max: this.connection.pool?.max ?? 10
|
|
60060
|
-
}
|
|
60061
|
-
});
|
|
60062
|
-
await this.migrateSchema();
|
|
60063
|
-
logger.info(`[KnexStore] Initialized (${this.driver})`);
|
|
60064
|
-
}
|
|
60065
|
-
buildStandardConnection() {
|
|
60066
|
-
return {
|
|
60067
|
-
host: this.connection.host || "localhost",
|
|
60068
|
-
port: this.connection.port,
|
|
60069
|
-
database: this.connection.database || "visor",
|
|
60070
|
-
user: this.connection.user,
|
|
60071
|
-
password: this.connection.password,
|
|
60072
|
-
ssl: this.resolveSslConfig()
|
|
60073
|
-
};
|
|
60074
|
-
}
|
|
60075
|
-
buildMssqlConnection() {
|
|
60076
|
-
const ssl = this.connection.ssl;
|
|
60077
|
-
const sslEnabled = ssl === true || typeof ssl === "object" && ssl.enabled !== false;
|
|
60078
|
-
return {
|
|
60079
|
-
server: this.connection.host || "localhost",
|
|
60080
|
-
port: this.connection.port,
|
|
60081
|
-
database: this.connection.database || "visor",
|
|
60082
|
-
user: this.connection.user,
|
|
60083
|
-
password: this.connection.password,
|
|
60084
|
-
options: {
|
|
60085
|
-
encrypt: sslEnabled,
|
|
60086
|
-
trustServerCertificate: typeof ssl === "object" ? ssl.reject_unauthorized === false : !sslEnabled
|
|
60087
|
-
}
|
|
60088
|
-
};
|
|
60089
|
-
}
|
|
60090
|
-
resolveSslConfig() {
|
|
60091
|
-
const ssl = this.connection.ssl;
|
|
60092
|
-
if (ssl === false || ssl === void 0) return false;
|
|
60093
|
-
if (ssl === true) return { rejectUnauthorized: true };
|
|
60094
|
-
if (ssl.enabled === false) return false;
|
|
60095
|
-
const result = {
|
|
60096
|
-
rejectUnauthorized: ssl.reject_unauthorized !== false
|
|
60097
|
-
};
|
|
60098
|
-
if (ssl.ca) {
|
|
60099
|
-
const caPath = this.validateSslPath(ssl.ca, "CA certificate");
|
|
60100
|
-
result.ca = fs26.readFileSync(caPath, "utf8");
|
|
60101
|
-
}
|
|
60102
|
-
if (ssl.cert) {
|
|
60103
|
-
const certPath = this.validateSslPath(ssl.cert, "client certificate");
|
|
60104
|
-
result.cert = fs26.readFileSync(certPath, "utf8");
|
|
60105
|
-
}
|
|
60106
|
-
if (ssl.key) {
|
|
60107
|
-
const keyPath = this.validateSslPath(ssl.key, "client key");
|
|
60108
|
-
result.key = fs26.readFileSync(keyPath, "utf8");
|
|
60109
|
-
}
|
|
60110
|
-
return result;
|
|
60111
|
-
}
|
|
60112
|
-
validateSslPath(filePath, label) {
|
|
60113
|
-
const resolved = path30.resolve(filePath);
|
|
60114
|
-
if (resolved !== path30.normalize(resolved)) {
|
|
60115
|
-
throw new Error(`SSL ${label} path contains invalid sequences: ${filePath}`);
|
|
60116
|
-
}
|
|
60117
|
-
if (!fs26.existsSync(resolved)) {
|
|
60118
|
-
throw new Error(`SSL ${label} not found: ${filePath}`);
|
|
60119
|
-
}
|
|
60120
|
-
return resolved;
|
|
60121
|
-
}
|
|
60122
|
-
async shutdown() {
|
|
60123
|
-
if (this.knex) {
|
|
60124
|
-
await this.knex.destroy();
|
|
60125
|
-
this.knex = null;
|
|
60126
|
-
}
|
|
60127
|
-
}
|
|
60128
|
-
async migrateSchema() {
|
|
60129
|
-
const knex = this.getKnex();
|
|
60130
|
-
const exists = await knex.schema.hasTable("schedules");
|
|
60131
|
-
if (!exists) {
|
|
60132
|
-
await knex.schema.createTable("schedules", (table) => {
|
|
60133
|
-
table.string("id", 36).primary();
|
|
60134
|
-
table.string("creator_id", 255).notNullable().index();
|
|
60135
|
-
table.string("creator_context", 255);
|
|
60136
|
-
table.string("creator_name", 255);
|
|
60137
|
-
table.string("timezone", 64).notNullable().defaultTo("UTC");
|
|
60138
|
-
table.string("schedule_expr", 255);
|
|
60139
|
-
table.bigInteger("run_at");
|
|
60140
|
-
table.boolean("is_recurring").notNullable();
|
|
60141
|
-
table.text("original_expression");
|
|
60142
|
-
table.string("workflow", 255);
|
|
60143
|
-
table.text("workflow_inputs");
|
|
60144
|
-
table.text("output_context");
|
|
60145
|
-
table.string("status", 20).notNullable().index();
|
|
60146
|
-
table.bigInteger("created_at").notNullable();
|
|
60147
|
-
table.bigInteger("last_run_at");
|
|
60148
|
-
table.bigInteger("next_run_at");
|
|
60149
|
-
table.integer("run_count").notNullable().defaultTo(0);
|
|
60150
|
-
table.integer("failure_count").notNullable().defaultTo(0);
|
|
60151
|
-
table.text("last_error");
|
|
60152
|
-
table.text("previous_response");
|
|
60153
|
-
table.index(["status", "next_run_at"]);
|
|
60154
|
-
});
|
|
60155
|
-
}
|
|
60156
|
-
const triggersExist = await knex.schema.hasTable("message_triggers");
|
|
60157
|
-
if (!triggersExist) {
|
|
60158
|
-
await knex.schema.createTable("message_triggers", (table) => {
|
|
60159
|
-
table.string("id", 36).primary();
|
|
60160
|
-
table.string("creator_id", 255).notNullable().index();
|
|
60161
|
-
table.string("creator_context", 255);
|
|
60162
|
-
table.string("creator_name", 255);
|
|
60163
|
-
table.text("description");
|
|
60164
|
-
table.text("channels");
|
|
60165
|
-
table.text("from_users");
|
|
60166
|
-
table.boolean("from_bots").notNullable().defaultTo(false);
|
|
60167
|
-
table.text("contains");
|
|
60168
|
-
table.text("match_pattern");
|
|
60169
|
-
table.string("threads", 20).notNullable().defaultTo("any");
|
|
60170
|
-
table.string("workflow", 255).notNullable();
|
|
60171
|
-
table.text("inputs");
|
|
60172
|
-
table.text("output_context");
|
|
60173
|
-
table.string("status", 20).notNullable().defaultTo("active").index();
|
|
60174
|
-
table.boolean("enabled").notNullable().defaultTo(true);
|
|
60175
|
-
table.bigInteger("created_at").notNullable();
|
|
60176
|
-
});
|
|
60177
|
-
}
|
|
60178
|
-
const locksExist = await knex.schema.hasTable("scheduler_locks");
|
|
60179
|
-
if (!locksExist) {
|
|
60180
|
-
await knex.schema.createTable("scheduler_locks", (table) => {
|
|
60181
|
-
table.string("lock_id", 255).primary();
|
|
60182
|
-
table.string("node_id", 255).notNullable();
|
|
60183
|
-
table.string("lock_token", 36).notNullable();
|
|
60184
|
-
table.bigInteger("acquired_at").notNullable();
|
|
60185
|
-
table.bigInteger("expires_at").notNullable();
|
|
60186
|
-
});
|
|
60187
|
-
}
|
|
60188
|
-
}
|
|
60189
|
-
getKnex() {
|
|
60190
|
-
if (!this.knex) {
|
|
60191
|
-
throw new Error("[KnexStore] Not initialized. Call initialize() first.");
|
|
60192
|
-
}
|
|
60193
|
-
return this.knex;
|
|
60194
|
-
}
|
|
60195
|
-
// --- CRUD ---
|
|
60196
|
-
async create(schedule) {
|
|
60197
|
-
const knex = this.getKnex();
|
|
60198
|
-
const newSchedule = {
|
|
60199
|
-
...schedule,
|
|
60200
|
-
id: (0, import_uuid2.v4)(),
|
|
60201
|
-
createdAt: Date.now(),
|
|
60202
|
-
runCount: 0,
|
|
60203
|
-
failureCount: 0,
|
|
60204
|
-
status: "active"
|
|
60205
|
-
};
|
|
60206
|
-
await knex("schedules").insert(toInsertRow(newSchedule));
|
|
60207
|
-
logger.info(`[KnexStore] Created schedule ${newSchedule.id} for user ${newSchedule.creatorId}`);
|
|
60208
|
-
return newSchedule;
|
|
60209
|
-
}
|
|
60210
|
-
async importSchedule(schedule) {
|
|
60211
|
-
const knex = this.getKnex();
|
|
60212
|
-
const existing = await knex("schedules").where("id", schedule.id).first();
|
|
60213
|
-
if (existing) return;
|
|
60214
|
-
await knex("schedules").insert(toInsertRow(schedule));
|
|
60215
|
-
}
|
|
60216
|
-
async get(id) {
|
|
60217
|
-
const knex = this.getKnex();
|
|
60218
|
-
const row = await knex("schedules").where("id", id).first();
|
|
60219
|
-
return row ? fromDbRow2(row) : void 0;
|
|
60220
|
-
}
|
|
60221
|
-
async update(id, patch) {
|
|
60222
|
-
const knex = this.getKnex();
|
|
60223
|
-
const existing = await knex("schedules").where("id", id).first();
|
|
60224
|
-
if (!existing) return void 0;
|
|
60225
|
-
const current = fromDbRow2(existing);
|
|
60226
|
-
const updated = { ...current, ...patch, id: current.id };
|
|
60227
|
-
const row = toInsertRow(updated);
|
|
60228
|
-
delete row.id;
|
|
60229
|
-
await knex("schedules").where("id", id).update(row);
|
|
60230
|
-
return updated;
|
|
60231
|
-
}
|
|
60232
|
-
async delete(id) {
|
|
60233
|
-
const knex = this.getKnex();
|
|
60234
|
-
const deleted = await knex("schedules").where("id", id).del();
|
|
60235
|
-
if (deleted > 0) {
|
|
60236
|
-
logger.info(`[KnexStore] Deleted schedule ${id}`);
|
|
60237
|
-
return true;
|
|
60238
|
-
}
|
|
60239
|
-
return false;
|
|
60240
|
-
}
|
|
60241
|
-
// --- Queries ---
|
|
60242
|
-
async getByCreator(creatorId) {
|
|
60243
|
-
const knex = this.getKnex();
|
|
60244
|
-
const rows = await knex("schedules").where("creator_id", creatorId);
|
|
60245
|
-
return rows.map((r) => fromDbRow2(r));
|
|
60246
|
-
}
|
|
60247
|
-
async getActiveSchedules() {
|
|
60248
|
-
const knex = this.getKnex();
|
|
60249
|
-
const rows = await knex("schedules").where("status", "active");
|
|
60250
|
-
return rows.map((r) => fromDbRow2(r));
|
|
60251
|
-
}
|
|
60252
|
-
async getDueSchedules(now) {
|
|
60253
|
-
const ts = now ?? Date.now();
|
|
60254
|
-
const knex = this.getKnex();
|
|
60255
|
-
const bFalse = this.driver === "mssql" ? 0 : false;
|
|
60256
|
-
const bTrue = this.driver === "mssql" ? 1 : true;
|
|
60257
|
-
const rows = await knex("schedules").where("status", "active").andWhere(function() {
|
|
60258
|
-
this.where(function() {
|
|
60259
|
-
this.where("is_recurring", bFalse).whereNotNull("run_at").where("run_at", "<=", ts);
|
|
60260
|
-
}).orWhere(function() {
|
|
60261
|
-
this.where("is_recurring", bTrue).whereNotNull("next_run_at").where("next_run_at", "<=", ts);
|
|
60262
|
-
});
|
|
60263
|
-
});
|
|
60264
|
-
return rows.map((r) => fromDbRow2(r));
|
|
60265
|
-
}
|
|
60266
|
-
async findByWorkflow(creatorId, workflowName) {
|
|
60267
|
-
const knex = this.getKnex();
|
|
60268
|
-
const escaped = workflowName.toLowerCase().replace(/[%_\\]/g, "\\$&");
|
|
60269
|
-
const pattern = `%${escaped}%`;
|
|
60270
|
-
const rows = await knex("schedules").where("creator_id", creatorId).where("status", "active").whereRaw("LOWER(workflow) LIKE ? ESCAPE '\\'", [pattern]);
|
|
60271
|
-
return rows.map((r) => fromDbRow2(r));
|
|
60272
|
-
}
|
|
60273
|
-
async getAll() {
|
|
60274
|
-
const knex = this.getKnex();
|
|
60275
|
-
const rows = await knex("schedules");
|
|
60276
|
-
return rows.map((r) => fromDbRow2(r));
|
|
60277
|
-
}
|
|
60278
|
-
async getStats() {
|
|
60279
|
-
const knex = this.getKnex();
|
|
60280
|
-
const boolTrue = this.driver === "mssql" ? "1" : "true";
|
|
60281
|
-
const boolFalse = this.driver === "mssql" ? "0" : "false";
|
|
60282
|
-
const result = await knex("schedules").select(
|
|
60283
|
-
knex.raw("COUNT(*) as total"),
|
|
60284
|
-
knex.raw("SUM(CASE WHEN status = 'active' THEN 1 ELSE 0 END) as active"),
|
|
60285
|
-
knex.raw("SUM(CASE WHEN status = 'paused' THEN 1 ELSE 0 END) as paused"),
|
|
60286
|
-
knex.raw("SUM(CASE WHEN status = 'completed' THEN 1 ELSE 0 END) as completed"),
|
|
60287
|
-
knex.raw("SUM(CASE WHEN status = 'failed' THEN 1 ELSE 0 END) as failed"),
|
|
60288
|
-
knex.raw(`SUM(CASE WHEN is_recurring = ${boolTrue} THEN 1 ELSE 0 END) as recurring`),
|
|
60289
|
-
knex.raw(`SUM(CASE WHEN is_recurring = ${boolFalse} THEN 1 ELSE 0 END) as one_time`)
|
|
60290
|
-
).first();
|
|
60291
|
-
return {
|
|
60292
|
-
total: Number(result.total) || 0,
|
|
60293
|
-
active: Number(result.active) || 0,
|
|
60294
|
-
paused: Number(result.paused) || 0,
|
|
60295
|
-
completed: Number(result.completed) || 0,
|
|
60296
|
-
failed: Number(result.failed) || 0,
|
|
60297
|
-
recurring: Number(result.recurring) || 0,
|
|
60298
|
-
oneTime: Number(result.one_time) || 0
|
|
60299
|
-
};
|
|
60300
|
-
}
|
|
60301
|
-
async validateLimits(creatorId, isRecurring, limits) {
|
|
60302
|
-
const knex = this.getKnex();
|
|
60303
|
-
if (limits.maxGlobal) {
|
|
60304
|
-
const result = await knex("schedules").count("* as cnt").first();
|
|
60305
|
-
if (Number(result?.cnt) >= limits.maxGlobal) {
|
|
60306
|
-
throw new Error(`Global schedule limit reached (${limits.maxGlobal})`);
|
|
60307
|
-
}
|
|
60308
|
-
}
|
|
60309
|
-
if (limits.maxPerUser) {
|
|
60310
|
-
const result = await knex("schedules").where("creator_id", creatorId).count("* as cnt").first();
|
|
60311
|
-
if (Number(result?.cnt) >= limits.maxPerUser) {
|
|
60312
|
-
throw new Error(`You have reached the maximum number of schedules (${limits.maxPerUser})`);
|
|
60313
|
-
}
|
|
60314
|
-
}
|
|
60315
|
-
if (isRecurring && limits.maxRecurringPerUser) {
|
|
60316
|
-
const bTrue = this.driver === "mssql" ? 1 : true;
|
|
60317
|
-
const result = await knex("schedules").where("creator_id", creatorId).where("is_recurring", bTrue).count("* as cnt").first();
|
|
60318
|
-
if (Number(result?.cnt) >= limits.maxRecurringPerUser) {
|
|
60319
|
-
throw new Error(
|
|
60320
|
-
`You have reached the maximum number of recurring schedules (${limits.maxRecurringPerUser})`
|
|
60321
|
-
);
|
|
60322
|
-
}
|
|
60323
|
-
}
|
|
60324
|
-
}
|
|
60325
|
-
// --- HA Distributed Locking (via scheduler_locks table) ---
|
|
60326
|
-
async tryAcquireLock(lockId, nodeId, ttlSeconds) {
|
|
60327
|
-
const knex = this.getKnex();
|
|
60328
|
-
const now = Date.now();
|
|
60329
|
-
const expiresAt = now + ttlSeconds * 1e3;
|
|
60330
|
-
const token = (0, import_uuid2.v4)();
|
|
60331
|
-
const updated = await knex("scheduler_locks").where("lock_id", lockId).where("expires_at", "<", now).update({
|
|
60332
|
-
node_id: nodeId,
|
|
60333
|
-
lock_token: token,
|
|
60334
|
-
acquired_at: now,
|
|
60335
|
-
expires_at: expiresAt
|
|
60336
|
-
});
|
|
60337
|
-
if (updated > 0) return token;
|
|
60338
|
-
try {
|
|
60339
|
-
await knex("scheduler_locks").insert({
|
|
60340
|
-
lock_id: lockId,
|
|
60341
|
-
node_id: nodeId,
|
|
60342
|
-
lock_token: token,
|
|
60343
|
-
acquired_at: now,
|
|
60344
|
-
expires_at: expiresAt
|
|
60345
|
-
});
|
|
60346
|
-
return token;
|
|
60347
|
-
} catch {
|
|
60348
|
-
return null;
|
|
60349
|
-
}
|
|
60350
|
-
}
|
|
60351
|
-
async releaseLock(lockId, lockToken) {
|
|
60352
|
-
const knex = this.getKnex();
|
|
60353
|
-
await knex("scheduler_locks").where("lock_id", lockId).where("lock_token", lockToken).del();
|
|
60354
|
-
}
|
|
60355
|
-
async renewLock(lockId, lockToken, ttlSeconds) {
|
|
60356
|
-
const knex = this.getKnex();
|
|
60357
|
-
const now = Date.now();
|
|
60358
|
-
const expiresAt = now + ttlSeconds * 1e3;
|
|
60359
|
-
const updated = await knex("scheduler_locks").where("lock_id", lockId).where("lock_token", lockToken).update({ acquired_at: now, expires_at: expiresAt });
|
|
60360
|
-
return updated > 0;
|
|
60361
|
-
}
|
|
60362
|
-
async flush() {
|
|
60363
|
-
}
|
|
60364
|
-
// --- Message Trigger CRUD ---
|
|
60365
|
-
async createTrigger(trigger) {
|
|
60366
|
-
const knex = this.getKnex();
|
|
60367
|
-
const newTrigger = {
|
|
60368
|
-
...trigger,
|
|
60369
|
-
id: (0, import_uuid2.v4)(),
|
|
60370
|
-
createdAt: Date.now()
|
|
60371
|
-
};
|
|
60372
|
-
await knex("message_triggers").insert(toTriggerInsertRow(newTrigger));
|
|
60373
|
-
logger.info(`[KnexStore] Created trigger ${newTrigger.id} for user ${newTrigger.creatorId}`);
|
|
60374
|
-
return newTrigger;
|
|
60375
|
-
}
|
|
60376
|
-
async getTrigger(id) {
|
|
60377
|
-
const knex = this.getKnex();
|
|
60378
|
-
const row = await knex("message_triggers").where("id", id).first();
|
|
60379
|
-
return row ? fromTriggerRow2(row) : void 0;
|
|
60380
|
-
}
|
|
60381
|
-
async updateTrigger(id, patch) {
|
|
60382
|
-
const knex = this.getKnex();
|
|
60383
|
-
const existing = await knex("message_triggers").where("id", id).first();
|
|
60384
|
-
if (!existing) return void 0;
|
|
60385
|
-
const current = fromTriggerRow2(existing);
|
|
60386
|
-
const updated = {
|
|
60387
|
-
...current,
|
|
60388
|
-
...patch,
|
|
60389
|
-
id: current.id,
|
|
60390
|
-
createdAt: current.createdAt
|
|
60391
|
-
};
|
|
60392
|
-
const row = toTriggerInsertRow(updated);
|
|
60393
|
-
delete row.id;
|
|
60394
|
-
await knex("message_triggers").where("id", id).update(row);
|
|
60395
|
-
return updated;
|
|
60396
|
-
}
|
|
60397
|
-
async deleteTrigger(id) {
|
|
60398
|
-
const knex = this.getKnex();
|
|
60399
|
-
const deleted = await knex("message_triggers").where("id", id).del();
|
|
60400
|
-
if (deleted > 0) {
|
|
60401
|
-
logger.info(`[KnexStore] Deleted trigger ${id}`);
|
|
60402
|
-
return true;
|
|
60403
|
-
}
|
|
60404
|
-
return false;
|
|
60405
|
-
}
|
|
60406
|
-
async getTriggersByCreator(creatorId) {
|
|
60407
|
-
const knex = this.getKnex();
|
|
60408
|
-
const rows = await knex("message_triggers").where("creator_id", creatorId);
|
|
60409
|
-
return rows.map((r) => fromTriggerRow2(r));
|
|
60410
|
-
}
|
|
60411
|
-
async getActiveTriggers() {
|
|
60412
|
-
const knex = this.getKnex();
|
|
60413
|
-
const rows = await knex("message_triggers").where("status", "active").where("enabled", this.driver === "mssql" ? 1 : true);
|
|
60414
|
-
return rows.map((r) => fromTriggerRow2(r));
|
|
60415
|
-
}
|
|
60416
|
-
};
|
|
60417
|
-
}
|
|
60418
|
-
});
|
|
60419
|
-
|
|
60420
|
-
// src/enterprise/loader.ts
|
|
60421
|
-
var loader_exports = {};
|
|
60422
|
-
__export(loader_exports, {
|
|
60423
|
-
loadEnterprisePolicyEngine: () => loadEnterprisePolicyEngine,
|
|
60424
|
-
loadEnterpriseStoreBackend: () => loadEnterpriseStoreBackend
|
|
60425
|
-
});
|
|
60426
|
-
async function loadEnterprisePolicyEngine(config) {
|
|
60427
|
-
try {
|
|
60428
|
-
const { LicenseValidator: LicenseValidator2 } = await Promise.resolve().then(() => (init_validator(), validator_exports));
|
|
60429
|
-
const validator = new LicenseValidator2();
|
|
60430
|
-
const license = await validator.loadAndValidate();
|
|
60431
|
-
if (!license || !validator.hasFeature("policy")) {
|
|
60432
|
-
return new DefaultPolicyEngine();
|
|
60433
|
-
}
|
|
60434
|
-
if (validator.isInGracePeriod()) {
|
|
60435
|
-
console.warn(
|
|
60436
|
-
"[visor:enterprise] License has expired but is within the 72-hour grace period. Please renew your license."
|
|
60437
|
-
);
|
|
60438
|
-
}
|
|
60439
|
-
const { OpaPolicyEngine: OpaPolicyEngine2 } = await Promise.resolve().then(() => (init_opa_policy_engine(), opa_policy_engine_exports));
|
|
60440
|
-
const engine = new OpaPolicyEngine2(config);
|
|
60441
|
-
await engine.initialize(config);
|
|
60442
|
-
return engine;
|
|
60443
|
-
} catch (err) {
|
|
60444
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
60445
|
-
try {
|
|
60446
|
-
const { logger: logger2 } = (init_logger(), __toCommonJS(logger_exports));
|
|
60447
|
-
logger2.warn(`[PolicyEngine] Enterprise policy init failed, falling back to default: ${msg}`);
|
|
60448
|
-
} catch {
|
|
60449
|
-
}
|
|
60450
|
-
return new DefaultPolicyEngine();
|
|
60451
|
-
}
|
|
60452
|
-
}
|
|
60453
|
-
async function loadEnterpriseStoreBackend(driver, storageConfig, haConfig) {
|
|
60454
|
-
const { LicenseValidator: LicenseValidator2 } = await Promise.resolve().then(() => (init_validator(), validator_exports));
|
|
60455
|
-
const validator = new LicenseValidator2();
|
|
60456
|
-
const license = await validator.loadAndValidate();
|
|
60457
|
-
if (!license || !validator.hasFeature("scheduler-sql")) {
|
|
60458
|
-
throw new Error(
|
|
60459
|
-
`The ${driver} schedule storage driver requires a Visor Enterprise license with the 'scheduler-sql' feature. Please upgrade or use driver: 'sqlite' (default).`
|
|
60460
|
-
);
|
|
60461
|
-
}
|
|
60462
|
-
if (validator.isInGracePeriod()) {
|
|
60463
|
-
console.warn(
|
|
60464
|
-
"[visor:enterprise] License has expired but is within the 72-hour grace period. Please renew your license."
|
|
60465
|
-
);
|
|
60466
|
-
}
|
|
60467
|
-
const { KnexStoreBackend: KnexStoreBackend2 } = await Promise.resolve().then(() => (init_knex_store(), knex_store_exports));
|
|
60468
|
-
return new KnexStoreBackend2(driver, storageConfig, haConfig);
|
|
60469
|
-
}
|
|
60470
|
-
var init_loader = __esm({
|
|
60471
|
-
"src/enterprise/loader.ts"() {
|
|
60472
|
-
"use strict";
|
|
60473
|
-
init_default_engine();
|
|
60474
|
-
}
|
|
60475
|
-
});
|
|
60476
|
-
|
|
60477
59103
|
// src/event-bus/event-bus.ts
|
|
60478
59104
|
var event_bus_exports = {};
|
|
60479
59105
|
__export(event_bus_exports, {
|
|
@@ -61176,8 +59802,8 @@ var init_github_comments = __esm({
|
|
|
61176
59802
|
* Update existing comment or create new one with collision detection
|
|
61177
59803
|
*/
|
|
61178
59804
|
async updateOrCreateComment(owner, repo, prNumber, content, options = {}) {
|
|
61179
|
-
return new Promise((
|
|
61180
|
-
this._writeQueue = this._writeQueue.then(() => this._doUpdateOrCreate(owner, repo, prNumber, content, options)).then(
|
|
59805
|
+
return new Promise((resolve17, reject) => {
|
|
59806
|
+
this._writeQueue = this._writeQueue.then(() => this._doUpdateOrCreate(owner, repo, prNumber, content, options)).then(resolve17, reject);
|
|
61181
59807
|
});
|
|
61182
59808
|
}
|
|
61183
59809
|
async _doUpdateOrCreate(owner, repo, prNumber, content, options = {}) {
|
|
@@ -61388,8 +60014,8 @@ ${content}
|
|
|
61388
60014
|
* Sleep utility
|
|
61389
60015
|
*/
|
|
61390
60016
|
sleep(ms) {
|
|
61391
|
-
return new Promise((
|
|
61392
|
-
const t = setTimeout(
|
|
60017
|
+
return new Promise((resolve17) => {
|
|
60018
|
+
const t = setTimeout(resolve17, ms);
|
|
61393
60019
|
if (typeof t.unref === "function") {
|
|
61394
60020
|
try {
|
|
61395
60021
|
t.unref();
|
|
@@ -61674,8 +60300,8 @@ ${end}`);
|
|
|
61674
60300
|
async updateGroupedComment(ctx, comments, group, changedIds) {
|
|
61675
60301
|
const existingLock = this.updateLocks.get(group);
|
|
61676
60302
|
let resolveLock;
|
|
61677
|
-
const ourLock = new Promise((
|
|
61678
|
-
resolveLock =
|
|
60303
|
+
const ourLock = new Promise((resolve17) => {
|
|
60304
|
+
resolveLock = resolve17;
|
|
61679
60305
|
});
|
|
61680
60306
|
this.updateLocks.set(group, ourLock);
|
|
61681
60307
|
try {
|
|
@@ -62006,7 +60632,7 @@ ${blocks}
|
|
|
62006
60632
|
* Sleep utility for enforcing delays
|
|
62007
60633
|
*/
|
|
62008
60634
|
sleep(ms) {
|
|
62009
|
-
return new Promise((
|
|
60635
|
+
return new Promise((resolve17) => setTimeout(resolve17, ms));
|
|
62010
60636
|
}
|
|
62011
60637
|
};
|
|
62012
60638
|
}
|
|
@@ -63887,11 +62513,11 @@ var require_request3 = __commonJS({
|
|
|
63887
62513
|
"use strict";
|
|
63888
62514
|
var __awaiter = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) {
|
|
63889
62515
|
function adopt(value) {
|
|
63890
|
-
return value instanceof P ? value : new P(function(
|
|
63891
|
-
|
|
62516
|
+
return value instanceof P ? value : new P(function(resolve17) {
|
|
62517
|
+
resolve17(value);
|
|
63892
62518
|
});
|
|
63893
62519
|
}
|
|
63894
|
-
return new (P || (P = Promise))(function(
|
|
62520
|
+
return new (P || (P = Promise))(function(resolve17, reject) {
|
|
63895
62521
|
function fulfilled(value) {
|
|
63896
62522
|
try {
|
|
63897
62523
|
step(generator.next(value));
|
|
@@ -63907,7 +62533,7 @@ var require_request3 = __commonJS({
|
|
|
63907
62533
|
}
|
|
63908
62534
|
}
|
|
63909
62535
|
function step(result) {
|
|
63910
|
-
result.done ?
|
|
62536
|
+
result.done ? resolve17(result.value) : adopt(result.value).then(fulfilled, rejected);
|
|
63911
62537
|
}
|
|
63912
62538
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
63913
62539
|
});
|
|
@@ -63931,9 +62557,9 @@ var require_request3 = __commonJS({
|
|
|
63931
62557
|
HttpMethod2["PATCH"] = "PATCH";
|
|
63932
62558
|
})(HttpMethod = exports2.HttpMethod || (exports2.HttpMethod = {}));
|
|
63933
62559
|
var SvixRequest = class {
|
|
63934
|
-
constructor(method,
|
|
62560
|
+
constructor(method, path30) {
|
|
63935
62561
|
this.method = method;
|
|
63936
|
-
this.path =
|
|
62562
|
+
this.path = path30;
|
|
63937
62563
|
this.queryParams = {};
|
|
63938
62564
|
this.headerParams = {};
|
|
63939
62565
|
}
|
|
@@ -64036,7 +62662,7 @@ var require_request3 = __commonJS({
|
|
|
64036
62662
|
}
|
|
64037
62663
|
function sendWithRetry(url, init, retryScheduleInMs, nextInterval = 50, triesLeft = 2, fetchImpl = fetch, retryCount = 1) {
|
|
64038
62664
|
return __awaiter(this, void 0, void 0, function* () {
|
|
64039
|
-
const sleep = (interval) => new Promise((
|
|
62665
|
+
const sleep = (interval) => new Promise((resolve17) => setTimeout(resolve17, interval));
|
|
64040
62666
|
try {
|
|
64041
62667
|
const response = yield fetchImpl(url, init);
|
|
64042
62668
|
if (triesLeft <= 0 || response.status < 500) {
|
|
@@ -73110,7 +71736,7 @@ ${message}`;
|
|
|
73110
71736
|
});
|
|
73111
71737
|
|
|
73112
71738
|
// src/agent-protocol/task-store.ts
|
|
73113
|
-
function
|
|
71739
|
+
function safeJsonParse2(value) {
|
|
73114
71740
|
if (!value) return void 0;
|
|
73115
71741
|
try {
|
|
73116
71742
|
return JSON.parse(value);
|
|
@@ -73127,12 +71753,12 @@ function taskRowToAgentTask(row) {
|
|
|
73127
71753
|
context_id: row.context_id,
|
|
73128
71754
|
status: {
|
|
73129
71755
|
state: row.state,
|
|
73130
|
-
message:
|
|
71756
|
+
message: safeJsonParse2(row.status_message),
|
|
73131
71757
|
timestamp: row.updated_at
|
|
73132
71758
|
},
|
|
73133
|
-
artifacts:
|
|
73134
|
-
history:
|
|
73135
|
-
metadata:
|
|
71759
|
+
artifacts: safeJsonParse2(row.artifacts) ?? [],
|
|
71760
|
+
history: safeJsonParse2(row.history) ?? [],
|
|
71761
|
+
metadata: safeJsonParse2(row.request_metadata),
|
|
73136
71762
|
workflow_id: row.workflow_id ?? void 0
|
|
73137
71763
|
};
|
|
73138
71764
|
}
|
|
@@ -73369,7 +71995,7 @@ var init_task_store = __esm({
|
|
|
73369
71995
|
const db = this.getDb();
|
|
73370
71996
|
const row = db.prepare("SELECT artifacts FROM agent_tasks WHERE id = ?").get(taskId);
|
|
73371
71997
|
if (!row) throw new TaskNotFoundError(taskId);
|
|
73372
|
-
const artifacts =
|
|
71998
|
+
const artifacts = safeJsonParse2(row.artifacts) ?? [];
|
|
73373
71999
|
artifacts.push(artifact);
|
|
73374
72000
|
db.prepare("UPDATE agent_tasks SET artifacts = ?, updated_at = ? WHERE id = ?").run(
|
|
73375
72001
|
JSON.stringify(artifacts),
|
|
@@ -73381,7 +72007,7 @@ var init_task_store = __esm({
|
|
|
73381
72007
|
const db = this.getDb();
|
|
73382
72008
|
const row = db.prepare("SELECT history FROM agent_tasks WHERE id = ?").get(taskId);
|
|
73383
72009
|
if (!row) throw new TaskNotFoundError(taskId);
|
|
73384
|
-
const history =
|
|
72010
|
+
const history = safeJsonParse2(row.history) ?? [];
|
|
73385
72011
|
history.push(message);
|
|
73386
72012
|
db.prepare("UPDATE agent_tasks SET history = ?, updated_at = ? WHERE id = ?").run(
|
|
73387
72013
|
JSON.stringify(history),
|
|
@@ -73911,13 +72537,13 @@ __export(a2a_frontend_exports, {
|
|
|
73911
72537
|
resultToArtifacts: () => resultToArtifacts
|
|
73912
72538
|
});
|
|
73913
72539
|
function readJsonBody(req) {
|
|
73914
|
-
return new Promise((
|
|
72540
|
+
return new Promise((resolve17, reject) => {
|
|
73915
72541
|
const chunks = [];
|
|
73916
72542
|
req.on("data", (chunk) => chunks.push(chunk));
|
|
73917
72543
|
req.on("end", () => {
|
|
73918
72544
|
try {
|
|
73919
72545
|
const body = Buffer.concat(chunks).toString("utf8");
|
|
73920
|
-
|
|
72546
|
+
resolve17(body ? JSON.parse(body) : {});
|
|
73921
72547
|
} catch {
|
|
73922
72548
|
reject(new ParseError("Malformed JSON body"));
|
|
73923
72549
|
}
|
|
@@ -74160,12 +72786,12 @@ var init_a2a_frontend = __esm({
|
|
|
74160
72786
|
}
|
|
74161
72787
|
const port = this.config.port ?? 9e3;
|
|
74162
72788
|
const host = this.config.host ?? "0.0.0.0";
|
|
74163
|
-
await new Promise((
|
|
72789
|
+
await new Promise((resolve17) => {
|
|
74164
72790
|
this.server.listen(port, host, () => {
|
|
74165
72791
|
const addr = this.server.address();
|
|
74166
72792
|
this._boundPort = typeof addr === "object" && addr ? addr.port : port;
|
|
74167
72793
|
logger.info(`A2A server listening on ${host}:${this._boundPort}`);
|
|
74168
|
-
|
|
72794
|
+
resolve17();
|
|
74169
72795
|
});
|
|
74170
72796
|
});
|
|
74171
72797
|
if (this.agentCard) {
|
|
@@ -74189,8 +72815,8 @@ var init_a2a_frontend = __esm({
|
|
|
74189
72815
|
}
|
|
74190
72816
|
this.streamManager.shutdown();
|
|
74191
72817
|
if (this.server) {
|
|
74192
|
-
await new Promise((
|
|
74193
|
-
this.server.close((err) => err ? reject(err) :
|
|
72818
|
+
await new Promise((resolve17, reject) => {
|
|
72819
|
+
this.server.close((err) => err ? reject(err) : resolve17());
|
|
74194
72820
|
});
|
|
74195
72821
|
this.server = null;
|
|
74196
72822
|
}
|
|
@@ -74907,15 +73533,15 @@ function serializeRunState(state) {
|
|
|
74907
73533
|
])
|
|
74908
73534
|
};
|
|
74909
73535
|
}
|
|
74910
|
-
var
|
|
73536
|
+
var path29, fs26, StateMachineExecutionEngine;
|
|
74911
73537
|
var init_state_machine_execution_engine = __esm({
|
|
74912
73538
|
"src/state-machine-execution-engine.ts"() {
|
|
74913
73539
|
"use strict";
|
|
74914
73540
|
init_runner();
|
|
74915
73541
|
init_logger();
|
|
74916
73542
|
init_sandbox_manager();
|
|
74917
|
-
|
|
74918
|
-
|
|
73543
|
+
path29 = __toESM(require("path"));
|
|
73544
|
+
fs26 = __toESM(require("fs"));
|
|
74919
73545
|
StateMachineExecutionEngine = class _StateMachineExecutionEngine {
|
|
74920
73546
|
workingDirectory;
|
|
74921
73547
|
executionContext;
|
|
@@ -75148,8 +73774,8 @@ var init_state_machine_execution_engine = __esm({
|
|
|
75148
73774
|
logger.debug(
|
|
75149
73775
|
`[PolicyEngine] Loading enterprise policy engine (engine=${configWithTagFilter.policy.engine})`
|
|
75150
73776
|
);
|
|
75151
|
-
const { loadEnterprisePolicyEngine
|
|
75152
|
-
context2.policyEngine = await
|
|
73777
|
+
const { loadEnterprisePolicyEngine } = await import("./enterprise/loader");
|
|
73778
|
+
context2.policyEngine = await loadEnterprisePolicyEngine(configWithTagFilter.policy);
|
|
75153
73779
|
logger.debug(
|
|
75154
73780
|
`[PolicyEngine] Initialized: ${context2.policyEngine?.constructor?.name || "unknown"}`
|
|
75155
73781
|
);
|
|
@@ -75303,9 +73929,9 @@ var init_state_machine_execution_engine = __esm({
|
|
|
75303
73929
|
}
|
|
75304
73930
|
const checkId = String(ev?.checkId || "unknown");
|
|
75305
73931
|
const threadKey = ev?.threadKey || (channel && threadTs ? `${channel}:${threadTs}` : "session");
|
|
75306
|
-
const baseDir = process.env.VISOR_SNAPSHOT_DIR ||
|
|
75307
|
-
|
|
75308
|
-
const filePath =
|
|
73932
|
+
const baseDir = process.env.VISOR_SNAPSHOT_DIR || path29.resolve(process.cwd(), ".visor", "snapshots");
|
|
73933
|
+
fs26.mkdirSync(baseDir, { recursive: true });
|
|
73934
|
+
const filePath = path29.join(baseDir, `${threadKey}-${checkId}.json`);
|
|
75309
73935
|
await this.saveSnapshotToFile(filePath);
|
|
75310
73936
|
logger.info(`[Snapshot] Saved run snapshot: ${filePath}`);
|
|
75311
73937
|
try {
|
|
@@ -75446,7 +74072,7 @@ var init_state_machine_execution_engine = __esm({
|
|
|
75446
74072
|
* Does not include secrets. Intended for debugging and future resume support.
|
|
75447
74073
|
*/
|
|
75448
74074
|
async saveSnapshotToFile(filePath) {
|
|
75449
|
-
const
|
|
74075
|
+
const fs27 = await import("fs/promises");
|
|
75450
74076
|
const ctx = this._lastContext;
|
|
75451
74077
|
const runner = this._lastRunner;
|
|
75452
74078
|
if (!ctx || !runner) {
|
|
@@ -75466,14 +74092,14 @@ var init_state_machine_execution_engine = __esm({
|
|
|
75466
74092
|
journal: entries,
|
|
75467
74093
|
requestedChecks: ctx.requestedChecks || []
|
|
75468
74094
|
};
|
|
75469
|
-
await
|
|
74095
|
+
await fs27.writeFile(filePath, JSON.stringify(payload, null, 2), "utf8");
|
|
75470
74096
|
}
|
|
75471
74097
|
/**
|
|
75472
74098
|
* Load a snapshot JSON from file and return it. Resume support can build on this.
|
|
75473
74099
|
*/
|
|
75474
74100
|
async loadSnapshotFromFile(filePath) {
|
|
75475
|
-
const
|
|
75476
|
-
const raw = await
|
|
74101
|
+
const fs27 = await import("fs/promises");
|
|
74102
|
+
const raw = await fs27.readFile(filePath, "utf8");
|
|
75477
74103
|
return JSON.parse(raw);
|
|
75478
74104
|
}
|
|
75479
74105
|
/**
|