@probelabs/visor 0.1.164-ee → 0.1.164
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-06T05-53-46-693Z.ndjson +138 -0
- package/dist/output/traces/run-2026-03-06T05-54-31-473Z.ndjson +2235 -0
- package/dist/sdk/check-provider-registry-WQX5DJ6P.mjs +29 -0
- package/dist/sdk/{check-provider-registry-AWFYHQAW.mjs → check-provider-registry-XSXGGCRA.mjs} +2 -2
- package/dist/sdk/chunk-2MK5U5QT.mjs +43891 -0
- package/dist/sdk/{chunk-N4SZPYA6.mjs.map → chunk-2MK5U5QT.mjs.map} +1 -1
- package/dist/sdk/chunk-GUV363XE.mjs +1502 -0
- package/dist/sdk/chunk-GUV363XE.mjs.map +1 -0
- package/dist/sdk/chunk-JB2Y4N46.mjs +739 -0
- package/dist/sdk/chunk-JB2Y4N46.mjs.map +1 -0
- package/dist/sdk/chunk-KY57Z7F4.mjs +443 -0
- package/dist/sdk/chunk-KY57Z7F4.mjs.map +1 -0
- package/dist/sdk/{chunk-N4SZPYA6.mjs → chunk-WFIAHEOV.mjs} +9 -9
- package/dist/sdk/chunk-WFIAHEOV.mjs.map +1 -0
- package/dist/sdk/failure-condition-evaluator-BDO4W6VW.mjs +17 -0
- package/dist/sdk/github-frontend-5AQQSJK6.mjs +1368 -0
- package/dist/sdk/github-frontend-5AQQSJK6.mjs.map +1 -0
- package/dist/sdk/{host-QFABFVSJ.mjs → host-MUK55QXE.mjs} +2 -2
- package/dist/sdk/routing-KMLDYFYT.mjs +25 -0
- package/dist/sdk/{schedule-tool-SPUM47DS.mjs → schedule-tool-2XUUYBGO.mjs} +2 -2
- package/dist/sdk/schedule-tool-2XUUYBGO.mjs.map +1 -0
- package/dist/sdk/schedule-tool-JXKWDQ4B.mjs +35 -0
- package/dist/sdk/schedule-tool-JXKWDQ4B.mjs.map +1 -0
- package/dist/sdk/{schedule-tool-handler-CT5DUQ32.mjs → schedule-tool-handler-ECXGDV6S.mjs} +2 -2
- package/dist/sdk/schedule-tool-handler-ECXGDV6S.mjs.map +1 -0
- package/dist/sdk/schedule-tool-handler-FQTIABDT.mjs +39 -0
- package/dist/sdk/schedule-tool-handler-FQTIABDT.mjs.map +1 -0
- package/dist/sdk/sdk.js +259 -1633
- package/dist/sdk/sdk.js.map +1 -1
- package/dist/sdk/sdk.mjs +4 -4
- package/dist/sdk/trace-helpers-AFW3FLL4.mjs +25 -0
- package/dist/sdk/trace-helpers-AFW3FLL4.mjs.map +1 -0
- package/dist/sdk/{workflow-check-provider-JORTTXVH.mjs → workflow-check-provider-4KEI4FO7.mjs} +2 -2
- package/dist/sdk/workflow-check-provider-4KEI4FO7.mjs.map +1 -0
- package/dist/sdk/workflow-check-provider-KLN6YN6F.mjs +29 -0
- package/dist/sdk/workflow-check-provider-KLN6YN6F.mjs.map +1 -0
- package/dist/traces/run-2026-03-06T05-53-46-693Z.ndjson +138 -0
- package/dist/traces/run-2026-03-06T05-54-31-473Z.ndjson +2235 -0
- package/package.json +1 -1
- package/dist/sdk/knex-store-CRORFJE6.mjs +0 -527
- package/dist/sdk/knex-store-CRORFJE6.mjs.map +0 -1
- package/dist/sdk/loader-NJCF7DUS.mjs +0 -89
- package/dist/sdk/loader-NJCF7DUS.mjs.map +0 -1
- package/dist/sdk/opa-policy-engine-S2S2ULEI.mjs +0 -655
- package/dist/sdk/opa-policy-engine-S2S2ULEI.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-AWFYHQAW.mjs.map → check-provider-registry-WQX5DJ6P.mjs.map} +0 -0
- /package/dist/sdk/{schedule-tool-SPUM47DS.mjs.map → check-provider-registry-XSXGGCRA.mjs.map} +0 -0
- /package/dist/sdk/{schedule-tool-handler-CT5DUQ32.mjs.map → failure-condition-evaluator-BDO4W6VW.mjs.map} +0 -0
- /package/dist/sdk/{host-QFABFVSJ.mjs.map → host-MUK55QXE.mjs.map} +0 -0
- /package/dist/sdk/{workflow-check-provider-JORTTXVH.mjs.map → routing-KMLDYFYT.mjs.map} +0 -0
package/dist/sdk/sdk.js
CHANGED
|
@@ -646,7 +646,7 @@ var require_package = __commonJS({
|
|
|
646
646
|
"package.json"(exports2, module2) {
|
|
647
647
|
module2.exports = {
|
|
648
648
|
name: "@probelabs/visor",
|
|
649
|
-
version: "0.1.
|
|
649
|
+
version: "0.1.164",
|
|
650
650
|
main: "dist/index.js",
|
|
651
651
|
bin: {
|
|
652
652
|
visor: "./dist/index.js"
|
|
@@ -864,11 +864,11 @@ function getTracer() {
|
|
|
864
864
|
}
|
|
865
865
|
async function withActiveSpan(name, attrs, fn) {
|
|
866
866
|
const tracer = getTracer();
|
|
867
|
-
return await new Promise((
|
|
867
|
+
return await new Promise((resolve15, reject) => {
|
|
868
868
|
const callback = async (span) => {
|
|
869
869
|
try {
|
|
870
870
|
const res = await fn(span);
|
|
871
|
-
|
|
871
|
+
resolve15(res);
|
|
872
872
|
} catch (err) {
|
|
873
873
|
try {
|
|
874
874
|
if (err instanceof Error) span.recordException(err);
|
|
@@ -945,19 +945,19 @@ function __getOrCreateNdjsonPath() {
|
|
|
945
945
|
try {
|
|
946
946
|
if (process.env.VISOR_TELEMETRY_SINK && process.env.VISOR_TELEMETRY_SINK !== "file")
|
|
947
947
|
return null;
|
|
948
|
-
const
|
|
949
|
-
const
|
|
948
|
+
const path27 = require("path");
|
|
949
|
+
const fs23 = require("fs");
|
|
950
950
|
if (process.env.VISOR_FALLBACK_TRACE_FILE) {
|
|
951
951
|
__ndjsonPath = process.env.VISOR_FALLBACK_TRACE_FILE;
|
|
952
|
-
const dir =
|
|
953
|
-
if (!
|
|
952
|
+
const dir = path27.dirname(__ndjsonPath);
|
|
953
|
+
if (!fs23.existsSync(dir)) fs23.mkdirSync(dir, { recursive: true });
|
|
954
954
|
return __ndjsonPath;
|
|
955
955
|
}
|
|
956
|
-
const outDir = process.env.VISOR_TRACE_DIR ||
|
|
957
|
-
if (!
|
|
956
|
+
const outDir = process.env.VISOR_TRACE_DIR || path27.join(process.cwd(), "output", "traces");
|
|
957
|
+
if (!fs23.existsSync(outDir)) fs23.mkdirSync(outDir, { recursive: true });
|
|
958
958
|
if (!__ndjsonPath) {
|
|
959
959
|
const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
960
|
-
__ndjsonPath =
|
|
960
|
+
__ndjsonPath = path27.join(outDir, `${ts}.ndjson`);
|
|
961
961
|
}
|
|
962
962
|
return __ndjsonPath;
|
|
963
963
|
} catch {
|
|
@@ -966,11 +966,11 @@ function __getOrCreateNdjsonPath() {
|
|
|
966
966
|
}
|
|
967
967
|
function _appendRunMarker() {
|
|
968
968
|
try {
|
|
969
|
-
const
|
|
969
|
+
const fs23 = require("fs");
|
|
970
970
|
const p = __getOrCreateNdjsonPath();
|
|
971
971
|
if (!p) return;
|
|
972
972
|
const line = { name: "visor.run", attributes: { started: true } };
|
|
973
|
-
|
|
973
|
+
fs23.appendFileSync(p, JSON.stringify(line) + "\n", "utf8");
|
|
974
974
|
} catch {
|
|
975
975
|
}
|
|
976
976
|
}
|
|
@@ -3193,7 +3193,7 @@ var init_failure_condition_evaluator = __esm({
|
|
|
3193
3193
|
*/
|
|
3194
3194
|
evaluateExpression(condition, context2) {
|
|
3195
3195
|
try {
|
|
3196
|
-
const
|
|
3196
|
+
const normalize4 = (expr) => {
|
|
3197
3197
|
const trimmed = expr.trim();
|
|
3198
3198
|
if (!/[\n;]/.test(trimmed)) return trimmed;
|
|
3199
3199
|
const parts = trimmed.split(/[\n;]+/).map((s) => s.trim()).filter((s) => s.length > 0 && !s.startsWith("//"));
|
|
@@ -3351,7 +3351,7 @@ var init_failure_condition_evaluator = __esm({
|
|
|
3351
3351
|
try {
|
|
3352
3352
|
exec2 = this.sandbox.compile(`return (${raw});`);
|
|
3353
3353
|
} catch {
|
|
3354
|
-
const normalizedExpr =
|
|
3354
|
+
const normalizedExpr = normalize4(condition);
|
|
3355
3355
|
exec2 = this.sandbox.compile(`return (${normalizedExpr});`);
|
|
3356
3356
|
}
|
|
3357
3357
|
const result = exec2(scope).run();
|
|
@@ -3734,9 +3734,9 @@ function configureLiquidWithExtensions(liquid) {
|
|
|
3734
3734
|
});
|
|
3735
3735
|
liquid.registerFilter("get", (obj, pathExpr) => {
|
|
3736
3736
|
if (obj == null) return void 0;
|
|
3737
|
-
const
|
|
3738
|
-
if (!
|
|
3739
|
-
const parts =
|
|
3737
|
+
const path27 = typeof pathExpr === "string" ? pathExpr : String(pathExpr || "");
|
|
3738
|
+
if (!path27) return obj;
|
|
3739
|
+
const parts = path27.split(".");
|
|
3740
3740
|
let cur = obj;
|
|
3741
3741
|
for (const p of parts) {
|
|
3742
3742
|
if (cur == null) return void 0;
|
|
@@ -3855,9 +3855,9 @@ function configureLiquidWithExtensions(liquid) {
|
|
|
3855
3855
|
}
|
|
3856
3856
|
}
|
|
3857
3857
|
const defaultRole = typeof rolesCfg.default === "string" && rolesCfg.default.trim() ? rolesCfg.default.trim() : void 0;
|
|
3858
|
-
const getNested = (obj,
|
|
3859
|
-
if (!obj || !
|
|
3860
|
-
const parts =
|
|
3858
|
+
const getNested = (obj, path27) => {
|
|
3859
|
+
if (!obj || !path27) return void 0;
|
|
3860
|
+
const parts = path27.split(".");
|
|
3861
3861
|
let cur = obj;
|
|
3862
3862
|
for (const p of parts) {
|
|
3863
3863
|
if (cur == null) return void 0;
|
|
@@ -6409,8 +6409,8 @@ var init_dependency_gating = __esm({
|
|
|
6409
6409
|
async function renderTemplateContent(checkId, checkConfig, reviewSummary) {
|
|
6410
6410
|
try {
|
|
6411
6411
|
const { createExtendedLiquid: createExtendedLiquid2 } = await Promise.resolve().then(() => (init_liquid_extensions(), liquid_extensions_exports));
|
|
6412
|
-
const
|
|
6413
|
-
const
|
|
6412
|
+
const fs23 = await import("fs/promises");
|
|
6413
|
+
const path27 = await import("path");
|
|
6414
6414
|
const schemaRaw = checkConfig.schema || "plain";
|
|
6415
6415
|
const schema = typeof schemaRaw === "string" ? schemaRaw : "code-review";
|
|
6416
6416
|
let templateContent;
|
|
@@ -6418,24 +6418,24 @@ async function renderTemplateContent(checkId, checkConfig, reviewSummary) {
|
|
|
6418
6418
|
templateContent = String(checkConfig.template.content);
|
|
6419
6419
|
} else if (checkConfig.template && checkConfig.template.file) {
|
|
6420
6420
|
const file = String(checkConfig.template.file);
|
|
6421
|
-
const resolved =
|
|
6422
|
-
templateContent = await
|
|
6421
|
+
const resolved = path27.resolve(process.cwd(), file);
|
|
6422
|
+
templateContent = await fs23.readFile(resolved, "utf-8");
|
|
6423
6423
|
} else if (schema && schema !== "plain") {
|
|
6424
6424
|
const sanitized = String(schema).replace(/[^a-zA-Z0-9-]/g, "");
|
|
6425
6425
|
if (sanitized) {
|
|
6426
6426
|
const candidatePaths = [
|
|
6427
|
-
|
|
6427
|
+
path27.join(__dirname, "output", sanitized, "template.liquid"),
|
|
6428
6428
|
// bundled: dist/output/
|
|
6429
|
-
|
|
6429
|
+
path27.join(__dirname, "..", "..", "output", sanitized, "template.liquid"),
|
|
6430
6430
|
// source: output/
|
|
6431
|
-
|
|
6431
|
+
path27.join(process.cwd(), "output", sanitized, "template.liquid"),
|
|
6432
6432
|
// fallback: cwd/output/
|
|
6433
|
-
|
|
6433
|
+
path27.join(process.cwd(), "dist", "output", sanitized, "template.liquid")
|
|
6434
6434
|
// fallback: cwd/dist/output/
|
|
6435
6435
|
];
|
|
6436
6436
|
for (const p of candidatePaths) {
|
|
6437
6437
|
try {
|
|
6438
|
-
templateContent = await
|
|
6438
|
+
templateContent = await fs23.readFile(p, "utf-8");
|
|
6439
6439
|
if (templateContent) break;
|
|
6440
6440
|
} catch {
|
|
6441
6441
|
}
|
|
@@ -6840,7 +6840,7 @@ async function processDiffWithOutline(diffContent) {
|
|
|
6840
6840
|
}
|
|
6841
6841
|
try {
|
|
6842
6842
|
const originalProbePath = process.env.PROBE_PATH;
|
|
6843
|
-
const
|
|
6843
|
+
const fs23 = require("fs");
|
|
6844
6844
|
const possiblePaths = [
|
|
6845
6845
|
// Relative to current working directory (most common in production)
|
|
6846
6846
|
path6.join(process.cwd(), "node_modules/@probelabs/probe/bin/probe-binary"),
|
|
@@ -6851,7 +6851,7 @@ async function processDiffWithOutline(diffContent) {
|
|
|
6851
6851
|
];
|
|
6852
6852
|
let probeBinaryPath;
|
|
6853
6853
|
for (const candidatePath of possiblePaths) {
|
|
6854
|
-
if (
|
|
6854
|
+
if (fs23.existsSync(candidatePath)) {
|
|
6855
6855
|
probeBinaryPath = candidatePath;
|
|
6856
6856
|
break;
|
|
6857
6857
|
}
|
|
@@ -6958,7 +6958,7 @@ async function renderMermaidToPng(mermaidCode) {
|
|
|
6958
6958
|
if (chromiumPath) {
|
|
6959
6959
|
env.PUPPETEER_EXECUTABLE_PATH = chromiumPath;
|
|
6960
6960
|
}
|
|
6961
|
-
const result = await new Promise((
|
|
6961
|
+
const result = await new Promise((resolve15) => {
|
|
6962
6962
|
const proc = (0, import_child_process.spawn)(
|
|
6963
6963
|
"npx",
|
|
6964
6964
|
[
|
|
@@ -6988,13 +6988,13 @@ async function renderMermaidToPng(mermaidCode) {
|
|
|
6988
6988
|
});
|
|
6989
6989
|
proc.on("close", (code) => {
|
|
6990
6990
|
if (code === 0) {
|
|
6991
|
-
|
|
6991
|
+
resolve15({ success: true });
|
|
6992
6992
|
} else {
|
|
6993
|
-
|
|
6993
|
+
resolve15({ success: false, error: stderr || `Exit code ${code}` });
|
|
6994
6994
|
}
|
|
6995
6995
|
});
|
|
6996
6996
|
proc.on("error", (err) => {
|
|
6997
|
-
|
|
6997
|
+
resolve15({ success: false, error: err.message });
|
|
6998
6998
|
});
|
|
6999
6999
|
});
|
|
7000
7000
|
if (!result.success) {
|
|
@@ -8156,8 +8156,8 @@ ${schemaString}`);
|
|
|
8156
8156
|
}
|
|
8157
8157
|
if (process.env.VISOR_DEBUG_AI_SESSIONS === "true") {
|
|
8158
8158
|
try {
|
|
8159
|
-
const
|
|
8160
|
-
const
|
|
8159
|
+
const fs23 = require("fs");
|
|
8160
|
+
const path27 = require("path");
|
|
8161
8161
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
8162
8162
|
const provider = this.config.provider || "auto";
|
|
8163
8163
|
const model = this.config.model || "default";
|
|
@@ -8271,20 +8271,20 @@ ${"=".repeat(60)}
|
|
|
8271
8271
|
`;
|
|
8272
8272
|
readableVersion += `${"=".repeat(60)}
|
|
8273
8273
|
`;
|
|
8274
|
-
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS ||
|
|
8275
|
-
if (!
|
|
8276
|
-
|
|
8274
|
+
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path27.join(process.cwd(), "debug-artifacts");
|
|
8275
|
+
if (!fs23.existsSync(debugArtifactsDir)) {
|
|
8276
|
+
fs23.mkdirSync(debugArtifactsDir, { recursive: true });
|
|
8277
8277
|
}
|
|
8278
|
-
const debugFile =
|
|
8278
|
+
const debugFile = path27.join(
|
|
8279
8279
|
debugArtifactsDir,
|
|
8280
8280
|
`prompt-${_checkName || "unknown"}-${timestamp}.json`
|
|
8281
8281
|
);
|
|
8282
|
-
|
|
8283
|
-
const readableFile =
|
|
8282
|
+
fs23.writeFileSync(debugFile, debugJson, "utf-8");
|
|
8283
|
+
const readableFile = path27.join(
|
|
8284
8284
|
debugArtifactsDir,
|
|
8285
8285
|
`prompt-${_checkName || "unknown"}-${timestamp}.txt`
|
|
8286
8286
|
);
|
|
8287
|
-
|
|
8287
|
+
fs23.writeFileSync(readableFile, readableVersion, "utf-8");
|
|
8288
8288
|
log(`
|
|
8289
8289
|
\u{1F4BE} Full debug info saved to:`);
|
|
8290
8290
|
log(` JSON: ${debugFile}`);
|
|
@@ -8317,8 +8317,8 @@ ${"=".repeat(60)}
|
|
|
8317
8317
|
log(`\u{1F4E4} Response length: ${response.length} characters`);
|
|
8318
8318
|
if (process.env.VISOR_DEBUG_AI_SESSIONS === "true") {
|
|
8319
8319
|
try {
|
|
8320
|
-
const
|
|
8321
|
-
const
|
|
8320
|
+
const fs23 = require("fs");
|
|
8321
|
+
const path27 = require("path");
|
|
8322
8322
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
8323
8323
|
const agentAny2 = agent;
|
|
8324
8324
|
let fullHistory = [];
|
|
@@ -8329,8 +8329,8 @@ ${"=".repeat(60)}
|
|
|
8329
8329
|
} else if (agentAny2._messages) {
|
|
8330
8330
|
fullHistory = agentAny2._messages;
|
|
8331
8331
|
}
|
|
8332
|
-
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS ||
|
|
8333
|
-
const sessionBase =
|
|
8332
|
+
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path27.join(process.cwd(), "debug-artifacts");
|
|
8333
|
+
const sessionBase = path27.join(
|
|
8334
8334
|
debugArtifactsDir,
|
|
8335
8335
|
`session-${_checkName || "unknown"}-${timestamp}`
|
|
8336
8336
|
);
|
|
@@ -8342,7 +8342,7 @@ ${"=".repeat(60)}
|
|
|
8342
8342
|
schema: effectiveSchema,
|
|
8343
8343
|
totalMessages: fullHistory.length
|
|
8344
8344
|
};
|
|
8345
|
-
|
|
8345
|
+
fs23.writeFileSync(sessionBase + ".json", JSON.stringify(sessionData, null, 2), "utf-8");
|
|
8346
8346
|
let readable = `=============================================================
|
|
8347
8347
|
`;
|
|
8348
8348
|
readable += `COMPLETE AI SESSION HISTORY (AFTER RESPONSE)
|
|
@@ -8369,7 +8369,7 @@ ${"=".repeat(60)}
|
|
|
8369
8369
|
`;
|
|
8370
8370
|
readable += content + "\n";
|
|
8371
8371
|
});
|
|
8372
|
-
|
|
8372
|
+
fs23.writeFileSync(sessionBase + ".summary.txt", readable, "utf-8");
|
|
8373
8373
|
log(`\u{1F4BE} Complete session history saved:`);
|
|
8374
8374
|
log(` - Contains ALL ${fullHistory.length} messages (prompts + responses)`);
|
|
8375
8375
|
} catch (error) {
|
|
@@ -8378,11 +8378,11 @@ ${"=".repeat(60)}
|
|
|
8378
8378
|
}
|
|
8379
8379
|
if (process.env.VISOR_DEBUG_AI_SESSIONS === "true") {
|
|
8380
8380
|
try {
|
|
8381
|
-
const
|
|
8382
|
-
const
|
|
8381
|
+
const fs23 = require("fs");
|
|
8382
|
+
const path27 = require("path");
|
|
8383
8383
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
8384
|
-
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS ||
|
|
8385
|
-
const responseFile =
|
|
8384
|
+
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path27.join(process.cwd(), "debug-artifacts");
|
|
8385
|
+
const responseFile = path27.join(
|
|
8386
8386
|
debugArtifactsDir,
|
|
8387
8387
|
`response-${_checkName || "unknown"}-${timestamp}.txt`
|
|
8388
8388
|
);
|
|
@@ -8415,7 +8415,7 @@ ${"=".repeat(60)}
|
|
|
8415
8415
|
`;
|
|
8416
8416
|
responseContent += `${"=".repeat(60)}
|
|
8417
8417
|
`;
|
|
8418
|
-
|
|
8418
|
+
fs23.writeFileSync(responseFile, responseContent, "utf-8");
|
|
8419
8419
|
log(`\u{1F4BE} Response saved to: ${responseFile}`);
|
|
8420
8420
|
} catch (error) {
|
|
8421
8421
|
log(`\u26A0\uFE0F Could not save response file: ${error}`);
|
|
@@ -8431,9 +8431,9 @@ ${"=".repeat(60)}
|
|
|
8431
8431
|
await agentAny._telemetryConfig.shutdown();
|
|
8432
8432
|
log(`\u{1F4CA} OpenTelemetry trace saved to: ${agentAny._traceFilePath}`);
|
|
8433
8433
|
if (process.env.GITHUB_ACTIONS) {
|
|
8434
|
-
const
|
|
8435
|
-
if (
|
|
8436
|
-
const stats =
|
|
8434
|
+
const fs23 = require("fs");
|
|
8435
|
+
if (fs23.existsSync(agentAny._traceFilePath)) {
|
|
8436
|
+
const stats = fs23.statSync(agentAny._traceFilePath);
|
|
8437
8437
|
console.log(
|
|
8438
8438
|
`::notice title=AI Trace Saved::${agentAny._traceFilePath} (${stats.size} bytes)`
|
|
8439
8439
|
);
|
|
@@ -8646,9 +8646,9 @@ ${schemaString}`);
|
|
|
8646
8646
|
const model = this.config.model || "default";
|
|
8647
8647
|
if (process.env.VISOR_DEBUG_AI_SESSIONS === "true") {
|
|
8648
8648
|
try {
|
|
8649
|
-
const
|
|
8650
|
-
const
|
|
8651
|
-
const
|
|
8649
|
+
const fs23 = require("fs");
|
|
8650
|
+
const path27 = require("path");
|
|
8651
|
+
const os2 = require("os");
|
|
8652
8652
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
8653
8653
|
const debugData = {
|
|
8654
8654
|
timestamp,
|
|
@@ -8720,19 +8720,19 @@ ${"=".repeat(60)}
|
|
|
8720
8720
|
`;
|
|
8721
8721
|
readableVersion += `${"=".repeat(60)}
|
|
8722
8722
|
`;
|
|
8723
|
-
const tempDir =
|
|
8724
|
-
const promptFile =
|
|
8725
|
-
|
|
8723
|
+
const tempDir = os2.tmpdir();
|
|
8724
|
+
const promptFile = path27.join(tempDir, `visor-prompt-${timestamp}.txt`);
|
|
8725
|
+
fs23.writeFileSync(promptFile, prompt, "utf-8");
|
|
8726
8726
|
log(`
|
|
8727
8727
|
\u{1F4BE} Prompt saved to: ${promptFile}`);
|
|
8728
|
-
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS ||
|
|
8728
|
+
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path27.join(process.cwd(), "debug-artifacts");
|
|
8729
8729
|
try {
|
|
8730
|
-
const base =
|
|
8730
|
+
const base = path27.join(
|
|
8731
8731
|
debugArtifactsDir,
|
|
8732
8732
|
`prompt-${_checkName || "unknown"}-${timestamp}`
|
|
8733
8733
|
);
|
|
8734
|
-
|
|
8735
|
-
|
|
8734
|
+
fs23.writeFileSync(base + ".json", debugJson, "utf-8");
|
|
8735
|
+
fs23.writeFileSync(base + ".summary.txt", readableVersion, "utf-8");
|
|
8736
8736
|
log(`
|
|
8737
8737
|
\u{1F4BE} Full debug info saved to directory: ${debugArtifactsDir}`);
|
|
8738
8738
|
} catch {
|
|
@@ -8777,8 +8777,8 @@ $ ${cliCommand}
|
|
|
8777
8777
|
log(`\u{1F4E4} Response length: ${response.length} characters`);
|
|
8778
8778
|
if (process.env.VISOR_DEBUG_AI_SESSIONS === "true") {
|
|
8779
8779
|
try {
|
|
8780
|
-
const
|
|
8781
|
-
const
|
|
8780
|
+
const fs23 = require("fs");
|
|
8781
|
+
const path27 = require("path");
|
|
8782
8782
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
8783
8783
|
const agentAny = agent;
|
|
8784
8784
|
let fullHistory = [];
|
|
@@ -8789,8 +8789,8 @@ $ ${cliCommand}
|
|
|
8789
8789
|
} else if (agentAny._messages) {
|
|
8790
8790
|
fullHistory = agentAny._messages;
|
|
8791
8791
|
}
|
|
8792
|
-
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS ||
|
|
8793
|
-
const sessionBase =
|
|
8792
|
+
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path27.join(process.cwd(), "debug-artifacts");
|
|
8793
|
+
const sessionBase = path27.join(
|
|
8794
8794
|
debugArtifactsDir,
|
|
8795
8795
|
`session-${_checkName || "unknown"}-${timestamp}`
|
|
8796
8796
|
);
|
|
@@ -8802,7 +8802,7 @@ $ ${cliCommand}
|
|
|
8802
8802
|
schema: effectiveSchema,
|
|
8803
8803
|
totalMessages: fullHistory.length
|
|
8804
8804
|
};
|
|
8805
|
-
|
|
8805
|
+
fs23.writeFileSync(sessionBase + ".json", JSON.stringify(sessionData, null, 2), "utf-8");
|
|
8806
8806
|
let readable = `=============================================================
|
|
8807
8807
|
`;
|
|
8808
8808
|
readable += `COMPLETE AI SESSION HISTORY (AFTER RESPONSE)
|
|
@@ -8829,7 +8829,7 @@ ${"=".repeat(60)}
|
|
|
8829
8829
|
`;
|
|
8830
8830
|
readable += content + "\n";
|
|
8831
8831
|
});
|
|
8832
|
-
|
|
8832
|
+
fs23.writeFileSync(sessionBase + ".summary.txt", readable, "utf-8");
|
|
8833
8833
|
log(`\u{1F4BE} Complete session history saved:`);
|
|
8834
8834
|
log(` - Contains ALL ${fullHistory.length} messages (prompts + responses)`);
|
|
8835
8835
|
} catch (error) {
|
|
@@ -8838,11 +8838,11 @@ ${"=".repeat(60)}
|
|
|
8838
8838
|
}
|
|
8839
8839
|
if (process.env.VISOR_DEBUG_AI_SESSIONS === "true") {
|
|
8840
8840
|
try {
|
|
8841
|
-
const
|
|
8842
|
-
const
|
|
8841
|
+
const fs23 = require("fs");
|
|
8842
|
+
const path27 = require("path");
|
|
8843
8843
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
8844
|
-
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS ||
|
|
8845
|
-
const responseFile =
|
|
8844
|
+
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path27.join(process.cwd(), "debug-artifacts");
|
|
8845
|
+
const responseFile = path27.join(
|
|
8846
8846
|
debugArtifactsDir,
|
|
8847
8847
|
`response-${_checkName || "unknown"}-${timestamp}.txt`
|
|
8848
8848
|
);
|
|
@@ -8875,7 +8875,7 @@ ${"=".repeat(60)}
|
|
|
8875
8875
|
`;
|
|
8876
8876
|
responseContent += `${"=".repeat(60)}
|
|
8877
8877
|
`;
|
|
8878
|
-
|
|
8878
|
+
fs23.writeFileSync(responseFile, responseContent, "utf-8");
|
|
8879
8879
|
log(`\u{1F4BE} Response saved to: ${responseFile}`);
|
|
8880
8880
|
} catch (error) {
|
|
8881
8881
|
log(`\u26A0\uFE0F Could not save response file: ${error}`);
|
|
@@ -8893,9 +8893,9 @@ ${"=".repeat(60)}
|
|
|
8893
8893
|
await telemetry.shutdown();
|
|
8894
8894
|
log(`\u{1F4CA} OpenTelemetry trace saved to: ${traceFilePath}`);
|
|
8895
8895
|
if (process.env.GITHUB_ACTIONS) {
|
|
8896
|
-
const
|
|
8897
|
-
if (
|
|
8898
|
-
const stats =
|
|
8896
|
+
const fs23 = require("fs");
|
|
8897
|
+
if (fs23.existsSync(traceFilePath)) {
|
|
8898
|
+
const stats = fs23.statSync(traceFilePath);
|
|
8899
8899
|
console.log(
|
|
8900
8900
|
`::notice title=AI Trace Saved::OpenTelemetry trace file size: ${stats.size} bytes`
|
|
8901
8901
|
);
|
|
@@ -8933,8 +8933,8 @@ ${"=".repeat(60)}
|
|
|
8933
8933
|
* Load schema content from schema files or inline definitions
|
|
8934
8934
|
*/
|
|
8935
8935
|
async loadSchemaContent(schema) {
|
|
8936
|
-
const
|
|
8937
|
-
const
|
|
8936
|
+
const fs23 = require("fs").promises;
|
|
8937
|
+
const path27 = require("path");
|
|
8938
8938
|
if (typeof schema === "object" && schema !== null) {
|
|
8939
8939
|
log("\u{1F4CB} Using inline schema object from configuration");
|
|
8940
8940
|
return JSON.stringify(schema);
|
|
@@ -8947,14 +8947,14 @@ ${"=".repeat(60)}
|
|
|
8947
8947
|
}
|
|
8948
8948
|
} catch {
|
|
8949
8949
|
}
|
|
8950
|
-
if ((schema.startsWith("./") || schema.includes(".json")) && !
|
|
8950
|
+
if ((schema.startsWith("./") || schema.includes(".json")) && !path27.isAbsolute(schema)) {
|
|
8951
8951
|
if (schema.includes("..") || schema.includes("\0")) {
|
|
8952
8952
|
throw new Error("Invalid schema path: path traversal not allowed");
|
|
8953
8953
|
}
|
|
8954
8954
|
try {
|
|
8955
|
-
const schemaPath =
|
|
8955
|
+
const schemaPath = path27.resolve(process.cwd(), schema);
|
|
8956
8956
|
log(`\u{1F4CB} Loading custom schema from file: ${schemaPath}`);
|
|
8957
|
-
const schemaContent = await
|
|
8957
|
+
const schemaContent = await fs23.readFile(schemaPath, "utf-8");
|
|
8958
8958
|
return schemaContent.trim();
|
|
8959
8959
|
} catch (error) {
|
|
8960
8960
|
throw new Error(
|
|
@@ -8968,22 +8968,22 @@ ${"=".repeat(60)}
|
|
|
8968
8968
|
}
|
|
8969
8969
|
const candidatePaths = [
|
|
8970
8970
|
// GitHub Action bundle location
|
|
8971
|
-
|
|
8971
|
+
path27.join(__dirname, "output", sanitizedSchemaName, "schema.json"),
|
|
8972
8972
|
// Historical fallback when src/output was inadvertently bundled as output1/
|
|
8973
|
-
|
|
8973
|
+
path27.join(__dirname, "output1", sanitizedSchemaName, "schema.json"),
|
|
8974
8974
|
// Local dev (repo root)
|
|
8975
|
-
|
|
8975
|
+
path27.join(process.cwd(), "output", sanitizedSchemaName, "schema.json")
|
|
8976
8976
|
];
|
|
8977
8977
|
for (const schemaPath of candidatePaths) {
|
|
8978
8978
|
try {
|
|
8979
|
-
const schemaContent = await
|
|
8979
|
+
const schemaContent = await fs23.readFile(schemaPath, "utf-8");
|
|
8980
8980
|
return schemaContent.trim();
|
|
8981
8981
|
} catch {
|
|
8982
8982
|
}
|
|
8983
8983
|
}
|
|
8984
|
-
const distPath =
|
|
8985
|
-
const distAltPath =
|
|
8986
|
-
const cwdPath =
|
|
8984
|
+
const distPath = path27.join(__dirname, "output", sanitizedSchemaName, "schema.json");
|
|
8985
|
+
const distAltPath = path27.join(__dirname, "output1", sanitizedSchemaName, "schema.json");
|
|
8986
|
+
const cwdPath = path27.join(process.cwd(), "output", sanitizedSchemaName, "schema.json");
|
|
8987
8987
|
throw new Error(
|
|
8988
8988
|
`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.`
|
|
8989
8989
|
);
|
|
@@ -9228,7 +9228,7 @@ ${"=".repeat(60)}
|
|
|
9228
9228
|
* Generate mock response for testing
|
|
9229
9229
|
*/
|
|
9230
9230
|
async generateMockResponse(_prompt, _checkName, _schema) {
|
|
9231
|
-
await new Promise((
|
|
9231
|
+
await new Promise((resolve15) => setTimeout(resolve15, 500));
|
|
9232
9232
|
const name = (_checkName || "").toLowerCase();
|
|
9233
9233
|
if (name.includes("extract-facts")) {
|
|
9234
9234
|
const arr = Array.from({ length: 6 }, (_, i) => ({
|
|
@@ -9589,7 +9589,7 @@ var init_command_executor = __esm({
|
|
|
9589
9589
|
* Execute command with stdin input
|
|
9590
9590
|
*/
|
|
9591
9591
|
executeWithStdin(command, options) {
|
|
9592
|
-
return new Promise((
|
|
9592
|
+
return new Promise((resolve15, reject) => {
|
|
9593
9593
|
const childProcess = (0, import_child_process2.exec)(
|
|
9594
9594
|
command,
|
|
9595
9595
|
{
|
|
@@ -9601,7 +9601,7 @@ var init_command_executor = __esm({
|
|
|
9601
9601
|
if (error && error.killed && (error.code === "ETIMEDOUT" || error.signal === "SIGTERM")) {
|
|
9602
9602
|
reject(new Error(`Command timed out after ${options.timeout || 3e4}ms`));
|
|
9603
9603
|
} else {
|
|
9604
|
-
|
|
9604
|
+
resolve15({
|
|
9605
9605
|
stdout: stdout || "",
|
|
9606
9606
|
stderr: stderr || "",
|
|
9607
9607
|
exitCode: error ? error.code || 1 : 0
|
|
@@ -17704,17 +17704,17 @@ var init_workflow_check_provider = __esm({
|
|
|
17704
17704
|
* so it can be executed by the state machine as a nested workflow.
|
|
17705
17705
|
*/
|
|
17706
17706
|
async loadWorkflowFromConfigPath(sourcePath, baseDir) {
|
|
17707
|
-
const
|
|
17708
|
-
const
|
|
17707
|
+
const path27 = require("path");
|
|
17708
|
+
const fs23 = require("fs");
|
|
17709
17709
|
const yaml5 = require("js-yaml");
|
|
17710
|
-
const resolved =
|
|
17711
|
-
if (!
|
|
17710
|
+
const resolved = path27.isAbsolute(sourcePath) ? sourcePath : path27.resolve(baseDir, sourcePath);
|
|
17711
|
+
if (!fs23.existsSync(resolved)) {
|
|
17712
17712
|
throw new Error(`Workflow config not found at: ${resolved}`);
|
|
17713
17713
|
}
|
|
17714
|
-
const rawContent =
|
|
17714
|
+
const rawContent = fs23.readFileSync(resolved, "utf8");
|
|
17715
17715
|
const rawData = yaml5.load(rawContent);
|
|
17716
17716
|
if (rawData.imports && Array.isArray(rawData.imports)) {
|
|
17717
|
-
const configDir =
|
|
17717
|
+
const configDir = path27.dirname(resolved);
|
|
17718
17718
|
for (const source of rawData.imports) {
|
|
17719
17719
|
const results = await this.registry.import(source, {
|
|
17720
17720
|
basePath: configDir,
|
|
@@ -17744,8 +17744,8 @@ ${errors}`);
|
|
|
17744
17744
|
if (!steps || Object.keys(steps).length === 0) {
|
|
17745
17745
|
throw new Error(`Config '${resolved}' does not contain any steps to execute as a workflow`);
|
|
17746
17746
|
}
|
|
17747
|
-
const id =
|
|
17748
|
-
const name = loaded.name || `Workflow from ${
|
|
17747
|
+
const id = path27.basename(resolved).replace(/\.(ya?ml)$/i, "");
|
|
17748
|
+
const name = loaded.name || `Workflow from ${path27.basename(resolved)}`;
|
|
17749
17749
|
const workflowDef = {
|
|
17750
17750
|
id,
|
|
17751
17751
|
name,
|
|
@@ -18551,8 +18551,8 @@ async function createStoreBackend(storageConfig, haConfig) {
|
|
|
18551
18551
|
case "mssql": {
|
|
18552
18552
|
try {
|
|
18553
18553
|
const loaderPath = "../../enterprise/loader";
|
|
18554
|
-
const { loadEnterpriseStoreBackend
|
|
18555
|
-
return await
|
|
18554
|
+
const { loadEnterpriseStoreBackend } = await import(loaderPath);
|
|
18555
|
+
return await loadEnterpriseStoreBackend(driver, storageConfig, haConfig);
|
|
18556
18556
|
} catch (err) {
|
|
18557
18557
|
const msg = err instanceof Error ? err.message : String(err);
|
|
18558
18558
|
logger.error(`[StoreFactory] Failed to load enterprise ${driver} backend: ${msg}`);
|
|
@@ -21123,7 +21123,7 @@ var init_mcp_custom_sse_server = __esm({
|
|
|
21123
21123
|
* Returns the actual bound port number
|
|
21124
21124
|
*/
|
|
21125
21125
|
async start() {
|
|
21126
|
-
return new Promise((
|
|
21126
|
+
return new Promise((resolve15, reject) => {
|
|
21127
21127
|
try {
|
|
21128
21128
|
this.server = import_http.default.createServer((req, res) => {
|
|
21129
21129
|
this.handleRequest(req, res).catch((error) => {
|
|
@@ -21157,7 +21157,7 @@ var init_mcp_custom_sse_server = __esm({
|
|
|
21157
21157
|
);
|
|
21158
21158
|
}
|
|
21159
21159
|
this.startKeepalive();
|
|
21160
|
-
|
|
21160
|
+
resolve15(this.port);
|
|
21161
21161
|
});
|
|
21162
21162
|
} catch (error) {
|
|
21163
21163
|
reject(error);
|
|
@@ -21220,7 +21220,7 @@ var init_mcp_custom_sse_server = __esm({
|
|
|
21220
21220
|
logger.debug(
|
|
21221
21221
|
`[CustomToolsSSEServer:${this.sessionId}] Grace period before stop: ${waitMs}ms (activeToolCalls=${this.activeToolCalls})`
|
|
21222
21222
|
);
|
|
21223
|
-
await new Promise((
|
|
21223
|
+
await new Promise((resolve15) => setTimeout(resolve15, waitMs));
|
|
21224
21224
|
}
|
|
21225
21225
|
}
|
|
21226
21226
|
if (this.activeToolCalls > 0) {
|
|
@@ -21229,7 +21229,7 @@ var init_mcp_custom_sse_server = __esm({
|
|
|
21229
21229
|
`[CustomToolsSSEServer:${this.sessionId}] Waiting for ${this.activeToolCalls} active tool call(s) before stop`
|
|
21230
21230
|
);
|
|
21231
21231
|
while (this.activeToolCalls > 0 && Date.now() - startedAt < effectiveDrainTimeoutMs) {
|
|
21232
|
-
await new Promise((
|
|
21232
|
+
await new Promise((resolve15) => setTimeout(resolve15, 250));
|
|
21233
21233
|
}
|
|
21234
21234
|
if (this.activeToolCalls > 0) {
|
|
21235
21235
|
logger.warn(
|
|
@@ -21254,21 +21254,21 @@ var init_mcp_custom_sse_server = __esm({
|
|
|
21254
21254
|
}
|
|
21255
21255
|
this.connections.clear();
|
|
21256
21256
|
if (this.server) {
|
|
21257
|
-
await new Promise((
|
|
21257
|
+
await new Promise((resolve15, reject) => {
|
|
21258
21258
|
const timeout = setTimeout(() => {
|
|
21259
21259
|
if (this.debug) {
|
|
21260
21260
|
logger.debug(
|
|
21261
21261
|
`[CustomToolsSSEServer:${this.sessionId}] Force closing server after timeout`
|
|
21262
21262
|
);
|
|
21263
21263
|
}
|
|
21264
|
-
this.server?.close(() =>
|
|
21264
|
+
this.server?.close(() => resolve15());
|
|
21265
21265
|
}, 5e3);
|
|
21266
21266
|
this.server.close((error) => {
|
|
21267
21267
|
clearTimeout(timeout);
|
|
21268
21268
|
if (error) {
|
|
21269
21269
|
reject(error);
|
|
21270
21270
|
} else {
|
|
21271
|
-
|
|
21271
|
+
resolve15();
|
|
21272
21272
|
}
|
|
21273
21273
|
});
|
|
21274
21274
|
});
|
|
@@ -21703,7 +21703,7 @@ var init_mcp_custom_sse_server = __esm({
|
|
|
21703
21703
|
logger.warn(
|
|
21704
21704
|
`[CustomToolsSSEServer:${this.sessionId}] Tool ${toolName} failed (attempt ${attempt + 1}/${retryCount + 1}): ${errorMsg}. Retrying in ${delay}ms`
|
|
21705
21705
|
);
|
|
21706
|
-
await new Promise((
|
|
21706
|
+
await new Promise((resolve15) => setTimeout(resolve15, delay));
|
|
21707
21707
|
attempt++;
|
|
21708
21708
|
}
|
|
21709
21709
|
}
|
|
@@ -22016,9 +22016,9 @@ var init_ai_check_provider = __esm({
|
|
|
22016
22016
|
} else {
|
|
22017
22017
|
resolvedPath = import_path7.default.resolve(process.cwd(), str);
|
|
22018
22018
|
}
|
|
22019
|
-
const
|
|
22019
|
+
const fs23 = require("fs").promises;
|
|
22020
22020
|
try {
|
|
22021
|
-
const stat2 = await
|
|
22021
|
+
const stat2 = await fs23.stat(resolvedPath);
|
|
22022
22022
|
return stat2.isFile();
|
|
22023
22023
|
} catch {
|
|
22024
22024
|
return hasFileExtension && (isRelativePath || isAbsolutePath || hasPathSeparators);
|
|
@@ -27954,14 +27954,14 @@ var require_util = __commonJS({
|
|
|
27954
27954
|
}
|
|
27955
27955
|
const port = url.port != null ? url.port : url.protocol === "https:" ? 443 : 80;
|
|
27956
27956
|
let origin = url.origin != null ? url.origin : `${url.protocol}//${url.hostname}:${port}`;
|
|
27957
|
-
let
|
|
27957
|
+
let path27 = url.path != null ? url.path : `${url.pathname || ""}${url.search || ""}`;
|
|
27958
27958
|
if (origin.endsWith("/")) {
|
|
27959
27959
|
origin = origin.substring(0, origin.length - 1);
|
|
27960
27960
|
}
|
|
27961
|
-
if (
|
|
27962
|
-
|
|
27961
|
+
if (path27 && !path27.startsWith("/")) {
|
|
27962
|
+
path27 = `/${path27}`;
|
|
27963
27963
|
}
|
|
27964
|
-
url = new URL(origin +
|
|
27964
|
+
url = new URL(origin + path27);
|
|
27965
27965
|
}
|
|
27966
27966
|
return url;
|
|
27967
27967
|
}
|
|
@@ -29575,20 +29575,20 @@ var require_parseParams = __commonJS({
|
|
|
29575
29575
|
var require_basename = __commonJS({
|
|
29576
29576
|
"node_modules/@fastify/busboy/lib/utils/basename.js"(exports2, module2) {
|
|
29577
29577
|
"use strict";
|
|
29578
|
-
module2.exports = function basename4(
|
|
29579
|
-
if (typeof
|
|
29578
|
+
module2.exports = function basename4(path27) {
|
|
29579
|
+
if (typeof path27 !== "string") {
|
|
29580
29580
|
return "";
|
|
29581
29581
|
}
|
|
29582
|
-
for (var i =
|
|
29583
|
-
switch (
|
|
29582
|
+
for (var i = path27.length - 1; i >= 0; --i) {
|
|
29583
|
+
switch (path27.charCodeAt(i)) {
|
|
29584
29584
|
case 47:
|
|
29585
29585
|
// '/'
|
|
29586
29586
|
case 92:
|
|
29587
|
-
|
|
29588
|
-
return
|
|
29587
|
+
path27 = path27.slice(i + 1);
|
|
29588
|
+
return path27 === ".." || path27 === "." ? "" : path27;
|
|
29589
29589
|
}
|
|
29590
29590
|
}
|
|
29591
|
-
return
|
|
29591
|
+
return path27 === ".." || path27 === "." ? "" : path27;
|
|
29592
29592
|
};
|
|
29593
29593
|
}
|
|
29594
29594
|
});
|
|
@@ -30592,11 +30592,11 @@ var require_util2 = __commonJS({
|
|
|
30592
30592
|
var assert = require("assert");
|
|
30593
30593
|
var { isUint8Array } = require("util/types");
|
|
30594
30594
|
var supportedHashes = [];
|
|
30595
|
-
var
|
|
30595
|
+
var crypto2;
|
|
30596
30596
|
try {
|
|
30597
|
-
|
|
30597
|
+
crypto2 = require("crypto");
|
|
30598
30598
|
const possibleRelevantHashes = ["sha256", "sha384", "sha512"];
|
|
30599
|
-
supportedHashes =
|
|
30599
|
+
supportedHashes = crypto2.getHashes().filter((hash) => possibleRelevantHashes.includes(hash));
|
|
30600
30600
|
} catch {
|
|
30601
30601
|
}
|
|
30602
30602
|
function responseURL(response) {
|
|
@@ -30873,7 +30873,7 @@ var require_util2 = __commonJS({
|
|
|
30873
30873
|
}
|
|
30874
30874
|
}
|
|
30875
30875
|
function bytesMatch(bytes, metadataList) {
|
|
30876
|
-
if (
|
|
30876
|
+
if (crypto2 === void 0) {
|
|
30877
30877
|
return true;
|
|
30878
30878
|
}
|
|
30879
30879
|
const parsedMetadata = parseMetadata(metadataList);
|
|
@@ -30888,7 +30888,7 @@ var require_util2 = __commonJS({
|
|
|
30888
30888
|
for (const item of metadata) {
|
|
30889
30889
|
const algorithm = item.algo;
|
|
30890
30890
|
const expectedValue = item.hash;
|
|
30891
|
-
let actualValue =
|
|
30891
|
+
let actualValue = crypto2.createHash(algorithm).update(bytes).digest("base64");
|
|
30892
30892
|
if (actualValue[actualValue.length - 1] === "=") {
|
|
30893
30893
|
if (actualValue[actualValue.length - 2] === "=") {
|
|
30894
30894
|
actualValue = actualValue.slice(0, -2);
|
|
@@ -30981,8 +30981,8 @@ var require_util2 = __commonJS({
|
|
|
30981
30981
|
function createDeferredPromise() {
|
|
30982
30982
|
let res;
|
|
30983
30983
|
let rej;
|
|
30984
|
-
const promise = new Promise((
|
|
30985
|
-
res =
|
|
30984
|
+
const promise = new Promise((resolve15, reject) => {
|
|
30985
|
+
res = resolve15;
|
|
30986
30986
|
rej = reject;
|
|
30987
30987
|
});
|
|
30988
30988
|
return { promise, resolve: res, reject: rej };
|
|
@@ -32235,8 +32235,8 @@ var require_body = __commonJS({
|
|
|
32235
32235
|
var { parseMIMEType, serializeAMimeType } = require_dataURL();
|
|
32236
32236
|
var random;
|
|
32237
32237
|
try {
|
|
32238
|
-
const
|
|
32239
|
-
random = (max) =>
|
|
32238
|
+
const crypto2 = require("crypto");
|
|
32239
|
+
random = (max) => crypto2.randomInt(0, max);
|
|
32240
32240
|
} catch {
|
|
32241
32241
|
random = (max) => Math.floor(Math.random(max));
|
|
32242
32242
|
}
|
|
@@ -32487,8 +32487,8 @@ Content-Type: ${value.type || "application/octet-stream"}\r
|
|
|
32487
32487
|
});
|
|
32488
32488
|
}
|
|
32489
32489
|
});
|
|
32490
|
-
const busboyResolve = new Promise((
|
|
32491
|
-
busboy.on("finish",
|
|
32490
|
+
const busboyResolve = new Promise((resolve15, reject) => {
|
|
32491
|
+
busboy.on("finish", resolve15);
|
|
32492
32492
|
busboy.on("error", (err) => reject(new TypeError(err)));
|
|
32493
32493
|
});
|
|
32494
32494
|
if (this.body !== null) for await (const chunk of consumeBody(this[kState].body)) busboy.write(chunk);
|
|
@@ -32619,7 +32619,7 @@ var require_request = __commonJS({
|
|
|
32619
32619
|
}
|
|
32620
32620
|
var Request = class _Request {
|
|
32621
32621
|
constructor(origin, {
|
|
32622
|
-
path:
|
|
32622
|
+
path: path27,
|
|
32623
32623
|
method,
|
|
32624
32624
|
body,
|
|
32625
32625
|
headers,
|
|
@@ -32633,11 +32633,11 @@ var require_request = __commonJS({
|
|
|
32633
32633
|
throwOnError,
|
|
32634
32634
|
expectContinue
|
|
32635
32635
|
}, handler) {
|
|
32636
|
-
if (typeof
|
|
32636
|
+
if (typeof path27 !== "string") {
|
|
32637
32637
|
throw new InvalidArgumentError("path must be a string");
|
|
32638
|
-
} else if (
|
|
32638
|
+
} else if (path27[0] !== "/" && !(path27.startsWith("http://") || path27.startsWith("https://")) && method !== "CONNECT") {
|
|
32639
32639
|
throw new InvalidArgumentError("path must be an absolute URL or start with a slash");
|
|
32640
|
-
} else if (invalidPathRegex.exec(
|
|
32640
|
+
} else if (invalidPathRegex.exec(path27) !== null) {
|
|
32641
32641
|
throw new InvalidArgumentError("invalid request path");
|
|
32642
32642
|
}
|
|
32643
32643
|
if (typeof method !== "string") {
|
|
@@ -32700,7 +32700,7 @@ var require_request = __commonJS({
|
|
|
32700
32700
|
this.completed = false;
|
|
32701
32701
|
this.aborted = false;
|
|
32702
32702
|
this.upgrade = upgrade || null;
|
|
32703
|
-
this.path = query ? util.buildURL(
|
|
32703
|
+
this.path = query ? util.buildURL(path27, query) : path27;
|
|
32704
32704
|
this.origin = origin;
|
|
32705
32705
|
this.idempotent = idempotent == null ? method === "HEAD" || method === "GET" : idempotent;
|
|
32706
32706
|
this.blocking = blocking == null ? false : blocking;
|
|
@@ -33022,9 +33022,9 @@ var require_dispatcher_base = __commonJS({
|
|
|
33022
33022
|
}
|
|
33023
33023
|
close(callback) {
|
|
33024
33024
|
if (callback === void 0) {
|
|
33025
|
-
return new Promise((
|
|
33025
|
+
return new Promise((resolve15, reject) => {
|
|
33026
33026
|
this.close((err, data) => {
|
|
33027
|
-
return err ? reject(err) :
|
|
33027
|
+
return err ? reject(err) : resolve15(data);
|
|
33028
33028
|
});
|
|
33029
33029
|
});
|
|
33030
33030
|
}
|
|
@@ -33062,12 +33062,12 @@ var require_dispatcher_base = __commonJS({
|
|
|
33062
33062
|
err = null;
|
|
33063
33063
|
}
|
|
33064
33064
|
if (callback === void 0) {
|
|
33065
|
-
return new Promise((
|
|
33065
|
+
return new Promise((resolve15, reject) => {
|
|
33066
33066
|
this.destroy(err, (err2, data) => {
|
|
33067
33067
|
return err2 ? (
|
|
33068
33068
|
/* istanbul ignore next: should never error */
|
|
33069
33069
|
reject(err2)
|
|
33070
|
-
) :
|
|
33070
|
+
) : resolve15(data);
|
|
33071
33071
|
});
|
|
33072
33072
|
});
|
|
33073
33073
|
}
|
|
@@ -33708,9 +33708,9 @@ var require_RedirectHandler = __commonJS({
|
|
|
33708
33708
|
return this.handler.onHeaders(statusCode, headers, resume, statusText);
|
|
33709
33709
|
}
|
|
33710
33710
|
const { origin, pathname, search } = util.parseURL(new URL(this.location, this.opts.origin && new URL(this.opts.path, this.opts.origin)));
|
|
33711
|
-
const
|
|
33711
|
+
const path27 = search ? `${pathname}${search}` : pathname;
|
|
33712
33712
|
this.opts.headers = cleanRequestHeaders(this.opts.headers, statusCode === 303, this.opts.origin !== origin);
|
|
33713
|
-
this.opts.path =
|
|
33713
|
+
this.opts.path = path27;
|
|
33714
33714
|
this.opts.origin = origin;
|
|
33715
33715
|
this.opts.maxRedirections = 0;
|
|
33716
33716
|
this.opts.query = null;
|
|
@@ -34129,16 +34129,16 @@ var require_client = __commonJS({
|
|
|
34129
34129
|
return this[kNeedDrain] < 2;
|
|
34130
34130
|
}
|
|
34131
34131
|
async [kClose]() {
|
|
34132
|
-
return new Promise((
|
|
34132
|
+
return new Promise((resolve15) => {
|
|
34133
34133
|
if (!this[kSize]) {
|
|
34134
|
-
|
|
34134
|
+
resolve15(null);
|
|
34135
34135
|
} else {
|
|
34136
|
-
this[kClosedResolve] =
|
|
34136
|
+
this[kClosedResolve] = resolve15;
|
|
34137
34137
|
}
|
|
34138
34138
|
});
|
|
34139
34139
|
}
|
|
34140
34140
|
async [kDestroy](err) {
|
|
34141
|
-
return new Promise((
|
|
34141
|
+
return new Promise((resolve15) => {
|
|
34142
34142
|
const requests = this[kQueue].splice(this[kPendingIdx]);
|
|
34143
34143
|
for (let i = 0; i < requests.length; i++) {
|
|
34144
34144
|
const request = requests[i];
|
|
@@ -34149,7 +34149,7 @@ var require_client = __commonJS({
|
|
|
34149
34149
|
this[kClosedResolve]();
|
|
34150
34150
|
this[kClosedResolve] = null;
|
|
34151
34151
|
}
|
|
34152
|
-
|
|
34152
|
+
resolve15();
|
|
34153
34153
|
};
|
|
34154
34154
|
if (this[kHTTP2Session] != null) {
|
|
34155
34155
|
util.destroy(this[kHTTP2Session], err);
|
|
@@ -34729,7 +34729,7 @@ var require_client = __commonJS({
|
|
|
34729
34729
|
});
|
|
34730
34730
|
}
|
|
34731
34731
|
try {
|
|
34732
|
-
const socket = await new Promise((
|
|
34732
|
+
const socket = await new Promise((resolve15, reject) => {
|
|
34733
34733
|
client[kConnector]({
|
|
34734
34734
|
host,
|
|
34735
34735
|
hostname,
|
|
@@ -34741,7 +34741,7 @@ var require_client = __commonJS({
|
|
|
34741
34741
|
if (err) {
|
|
34742
34742
|
reject(err);
|
|
34743
34743
|
} else {
|
|
34744
|
-
|
|
34744
|
+
resolve15(socket2);
|
|
34745
34745
|
}
|
|
34746
34746
|
});
|
|
34747
34747
|
});
|
|
@@ -34952,7 +34952,7 @@ var require_client = __commonJS({
|
|
|
34952
34952
|
writeH2(client, client[kHTTP2Session], request);
|
|
34953
34953
|
return;
|
|
34954
34954
|
}
|
|
34955
|
-
const { body, method, path:
|
|
34955
|
+
const { body, method, path: path27, host, upgrade, headers, blocking, reset } = request;
|
|
34956
34956
|
const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH";
|
|
34957
34957
|
if (body && typeof body.read === "function") {
|
|
34958
34958
|
body.read(0);
|
|
@@ -35002,7 +35002,7 @@ var require_client = __commonJS({
|
|
|
35002
35002
|
if (blocking) {
|
|
35003
35003
|
socket[kBlocking] = true;
|
|
35004
35004
|
}
|
|
35005
|
-
let header = `${method} ${
|
|
35005
|
+
let header = `${method} ${path27} HTTP/1.1\r
|
|
35006
35006
|
`;
|
|
35007
35007
|
if (typeof host === "string") {
|
|
35008
35008
|
header += `host: ${host}\r
|
|
@@ -35065,7 +35065,7 @@ upgrade: ${upgrade}\r
|
|
|
35065
35065
|
return true;
|
|
35066
35066
|
}
|
|
35067
35067
|
function writeH2(client, session, request) {
|
|
35068
|
-
const { body, method, path:
|
|
35068
|
+
const { body, method, path: path27, host, upgrade, expectContinue, signal, headers: reqHeaders } = request;
|
|
35069
35069
|
let headers;
|
|
35070
35070
|
if (typeof reqHeaders === "string") headers = Request[kHTTP2CopyHeaders](reqHeaders.trim());
|
|
35071
35071
|
else headers = reqHeaders;
|
|
@@ -35108,7 +35108,7 @@ upgrade: ${upgrade}\r
|
|
|
35108
35108
|
});
|
|
35109
35109
|
return true;
|
|
35110
35110
|
}
|
|
35111
|
-
headers[HTTP2_HEADER_PATH] =
|
|
35111
|
+
headers[HTTP2_HEADER_PATH] = path27;
|
|
35112
35112
|
headers[HTTP2_HEADER_SCHEME] = "https";
|
|
35113
35113
|
const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH";
|
|
35114
35114
|
if (body && typeof body.read === "function") {
|
|
@@ -35365,12 +35365,12 @@ upgrade: ${upgrade}\r
|
|
|
35365
35365
|
cb();
|
|
35366
35366
|
}
|
|
35367
35367
|
}
|
|
35368
|
-
const waitForDrain = () => new Promise((
|
|
35368
|
+
const waitForDrain = () => new Promise((resolve15, reject) => {
|
|
35369
35369
|
assert(callback === null);
|
|
35370
35370
|
if (socket[kError]) {
|
|
35371
35371
|
reject(socket[kError]);
|
|
35372
35372
|
} else {
|
|
35373
|
-
callback =
|
|
35373
|
+
callback = resolve15;
|
|
35374
35374
|
}
|
|
35375
35375
|
});
|
|
35376
35376
|
if (client[kHTTPConnVersion] === "h2") {
|
|
@@ -35716,8 +35716,8 @@ var require_pool_base = __commonJS({
|
|
|
35716
35716
|
if (this[kQueue].isEmpty()) {
|
|
35717
35717
|
return Promise.all(this[kClients].map((c) => c.close()));
|
|
35718
35718
|
} else {
|
|
35719
|
-
return new Promise((
|
|
35720
|
-
this[kClosedResolve] =
|
|
35719
|
+
return new Promise((resolve15) => {
|
|
35720
|
+
this[kClosedResolve] = resolve15;
|
|
35721
35721
|
});
|
|
35722
35722
|
}
|
|
35723
35723
|
}
|
|
@@ -36295,7 +36295,7 @@ var require_readable = __commonJS({
|
|
|
36295
36295
|
if (this.closed) {
|
|
36296
36296
|
return Promise.resolve(null);
|
|
36297
36297
|
}
|
|
36298
|
-
return new Promise((
|
|
36298
|
+
return new Promise((resolve15, reject) => {
|
|
36299
36299
|
const signalListenerCleanup = signal ? util.addAbortListener(signal, () => {
|
|
36300
36300
|
this.destroy();
|
|
36301
36301
|
}) : noop;
|
|
@@ -36304,7 +36304,7 @@ var require_readable = __commonJS({
|
|
|
36304
36304
|
if (signal && signal.aborted) {
|
|
36305
36305
|
reject(signal.reason || Object.assign(new Error("The operation was aborted"), { name: "AbortError" }));
|
|
36306
36306
|
} else {
|
|
36307
|
-
|
|
36307
|
+
resolve15(null);
|
|
36308
36308
|
}
|
|
36309
36309
|
}).on("error", noop).on("data", function(chunk) {
|
|
36310
36310
|
limit -= chunk.length;
|
|
@@ -36326,11 +36326,11 @@ var require_readable = __commonJS({
|
|
|
36326
36326
|
throw new TypeError("unusable");
|
|
36327
36327
|
}
|
|
36328
36328
|
assert(!stream[kConsume]);
|
|
36329
|
-
return new Promise((
|
|
36329
|
+
return new Promise((resolve15, reject) => {
|
|
36330
36330
|
stream[kConsume] = {
|
|
36331
36331
|
type,
|
|
36332
36332
|
stream,
|
|
36333
|
-
resolve:
|
|
36333
|
+
resolve: resolve15,
|
|
36334
36334
|
reject,
|
|
36335
36335
|
length: 0,
|
|
36336
36336
|
body: []
|
|
@@ -36365,12 +36365,12 @@ var require_readable = __commonJS({
|
|
|
36365
36365
|
}
|
|
36366
36366
|
}
|
|
36367
36367
|
function consumeEnd(consume2) {
|
|
36368
|
-
const { type, body, resolve:
|
|
36368
|
+
const { type, body, resolve: resolve15, stream, length } = consume2;
|
|
36369
36369
|
try {
|
|
36370
36370
|
if (type === "text") {
|
|
36371
|
-
|
|
36371
|
+
resolve15(toUSVString(Buffer.concat(body)));
|
|
36372
36372
|
} else if (type === "json") {
|
|
36373
|
-
|
|
36373
|
+
resolve15(JSON.parse(Buffer.concat(body)));
|
|
36374
36374
|
} else if (type === "arrayBuffer") {
|
|
36375
36375
|
const dst = new Uint8Array(length);
|
|
36376
36376
|
let pos = 0;
|
|
@@ -36378,12 +36378,12 @@ var require_readable = __commonJS({
|
|
|
36378
36378
|
dst.set(buf, pos);
|
|
36379
36379
|
pos += buf.byteLength;
|
|
36380
36380
|
}
|
|
36381
|
-
|
|
36381
|
+
resolve15(dst.buffer);
|
|
36382
36382
|
} else if (type === "blob") {
|
|
36383
36383
|
if (!Blob2) {
|
|
36384
36384
|
Blob2 = require("buffer").Blob;
|
|
36385
36385
|
}
|
|
36386
|
-
|
|
36386
|
+
resolve15(new Blob2(body, { type: stream[kContentType] }));
|
|
36387
36387
|
}
|
|
36388
36388
|
consumeFinish(consume2);
|
|
36389
36389
|
} catch (err) {
|
|
@@ -36640,9 +36640,9 @@ var require_api_request = __commonJS({
|
|
|
36640
36640
|
};
|
|
36641
36641
|
function request(opts, callback) {
|
|
36642
36642
|
if (callback === void 0) {
|
|
36643
|
-
return new Promise((
|
|
36643
|
+
return new Promise((resolve15, reject) => {
|
|
36644
36644
|
request.call(this, opts, (err, data) => {
|
|
36645
|
-
return err ? reject(err) :
|
|
36645
|
+
return err ? reject(err) : resolve15(data);
|
|
36646
36646
|
});
|
|
36647
36647
|
});
|
|
36648
36648
|
}
|
|
@@ -36815,9 +36815,9 @@ var require_api_stream = __commonJS({
|
|
|
36815
36815
|
};
|
|
36816
36816
|
function stream(opts, factory, callback) {
|
|
36817
36817
|
if (callback === void 0) {
|
|
36818
|
-
return new Promise((
|
|
36818
|
+
return new Promise((resolve15, reject) => {
|
|
36819
36819
|
stream.call(this, opts, factory, (err, data) => {
|
|
36820
|
-
return err ? reject(err) :
|
|
36820
|
+
return err ? reject(err) : resolve15(data);
|
|
36821
36821
|
});
|
|
36822
36822
|
});
|
|
36823
36823
|
}
|
|
@@ -37098,9 +37098,9 @@ var require_api_upgrade = __commonJS({
|
|
|
37098
37098
|
};
|
|
37099
37099
|
function upgrade(opts, callback) {
|
|
37100
37100
|
if (callback === void 0) {
|
|
37101
|
-
return new Promise((
|
|
37101
|
+
return new Promise((resolve15, reject) => {
|
|
37102
37102
|
upgrade.call(this, opts, (err, data) => {
|
|
37103
|
-
return err ? reject(err) :
|
|
37103
|
+
return err ? reject(err) : resolve15(data);
|
|
37104
37104
|
});
|
|
37105
37105
|
});
|
|
37106
37106
|
}
|
|
@@ -37189,9 +37189,9 @@ var require_api_connect = __commonJS({
|
|
|
37189
37189
|
};
|
|
37190
37190
|
function connect(opts, callback) {
|
|
37191
37191
|
if (callback === void 0) {
|
|
37192
|
-
return new Promise((
|
|
37192
|
+
return new Promise((resolve15, reject) => {
|
|
37193
37193
|
connect.call(this, opts, (err, data) => {
|
|
37194
|
-
return err ? reject(err) :
|
|
37194
|
+
return err ? reject(err) : resolve15(data);
|
|
37195
37195
|
});
|
|
37196
37196
|
});
|
|
37197
37197
|
}
|
|
@@ -37351,20 +37351,20 @@ var require_mock_utils = __commonJS({
|
|
|
37351
37351
|
}
|
|
37352
37352
|
return true;
|
|
37353
37353
|
}
|
|
37354
|
-
function safeUrl(
|
|
37355
|
-
if (typeof
|
|
37356
|
-
return
|
|
37354
|
+
function safeUrl(path27) {
|
|
37355
|
+
if (typeof path27 !== "string") {
|
|
37356
|
+
return path27;
|
|
37357
37357
|
}
|
|
37358
|
-
const pathSegments =
|
|
37358
|
+
const pathSegments = path27.split("?");
|
|
37359
37359
|
if (pathSegments.length !== 2) {
|
|
37360
|
-
return
|
|
37360
|
+
return path27;
|
|
37361
37361
|
}
|
|
37362
37362
|
const qp = new URLSearchParams(pathSegments.pop());
|
|
37363
37363
|
qp.sort();
|
|
37364
37364
|
return [...pathSegments, qp.toString()].join("?");
|
|
37365
37365
|
}
|
|
37366
|
-
function matchKey(mockDispatch2, { path:
|
|
37367
|
-
const pathMatch = matchValue(mockDispatch2.path,
|
|
37366
|
+
function matchKey(mockDispatch2, { path: path27, method, body, headers }) {
|
|
37367
|
+
const pathMatch = matchValue(mockDispatch2.path, path27);
|
|
37368
37368
|
const methodMatch = matchValue(mockDispatch2.method, method);
|
|
37369
37369
|
const bodyMatch = typeof mockDispatch2.body !== "undefined" ? matchValue(mockDispatch2.body, body) : true;
|
|
37370
37370
|
const headersMatch = matchHeaders(mockDispatch2, headers);
|
|
@@ -37382,7 +37382,7 @@ var require_mock_utils = __commonJS({
|
|
|
37382
37382
|
function getMockDispatch(mockDispatches, key) {
|
|
37383
37383
|
const basePath = key.query ? buildURL(key.path, key.query) : key.path;
|
|
37384
37384
|
const resolvedPath = typeof basePath === "string" ? safeUrl(basePath) : basePath;
|
|
37385
|
-
let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path:
|
|
37385
|
+
let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path: path27 }) => matchValue(safeUrl(path27), resolvedPath));
|
|
37386
37386
|
if (matchedMockDispatches.length === 0) {
|
|
37387
37387
|
throw new MockNotMatchedError(`Mock dispatch not matched for path '${resolvedPath}'`);
|
|
37388
37388
|
}
|
|
@@ -37419,9 +37419,9 @@ var require_mock_utils = __commonJS({
|
|
|
37419
37419
|
}
|
|
37420
37420
|
}
|
|
37421
37421
|
function buildKey(opts) {
|
|
37422
|
-
const { path:
|
|
37422
|
+
const { path: path27, method, body, headers, query } = opts;
|
|
37423
37423
|
return {
|
|
37424
|
-
path:
|
|
37424
|
+
path: path27,
|
|
37425
37425
|
method,
|
|
37426
37426
|
body,
|
|
37427
37427
|
headers,
|
|
@@ -37870,10 +37870,10 @@ var require_pending_interceptors_formatter = __commonJS({
|
|
|
37870
37870
|
}
|
|
37871
37871
|
format(pendingInterceptors) {
|
|
37872
37872
|
const withPrettyHeaders = pendingInterceptors.map(
|
|
37873
|
-
({ method, path:
|
|
37873
|
+
({ method, path: path27, data: { statusCode }, persist, times, timesInvoked, origin }) => ({
|
|
37874
37874
|
Method: method,
|
|
37875
37875
|
Origin: origin,
|
|
37876
|
-
Path:
|
|
37876
|
+
Path: path27,
|
|
37877
37877
|
"Status code": statusCode,
|
|
37878
37878
|
Persistent: persist ? "\u2705" : "\u274C",
|
|
37879
37879
|
Invocations: timesInvoked,
|
|
@@ -40814,7 +40814,7 @@ var require_fetch = __commonJS({
|
|
|
40814
40814
|
async function dispatch({ body }) {
|
|
40815
40815
|
const url = requestCurrentURL(request);
|
|
40816
40816
|
const agent = fetchParams.controller.dispatcher;
|
|
40817
|
-
return new Promise((
|
|
40817
|
+
return new Promise((resolve15, reject) => agent.dispatch(
|
|
40818
40818
|
{
|
|
40819
40819
|
path: url.pathname + url.search,
|
|
40820
40820
|
origin: url.origin,
|
|
@@ -40890,7 +40890,7 @@ var require_fetch = __commonJS({
|
|
|
40890
40890
|
}
|
|
40891
40891
|
}
|
|
40892
40892
|
}
|
|
40893
|
-
|
|
40893
|
+
resolve15({
|
|
40894
40894
|
status,
|
|
40895
40895
|
statusText,
|
|
40896
40896
|
headersList: headers[kHeadersList],
|
|
@@ -40933,7 +40933,7 @@ var require_fetch = __commonJS({
|
|
|
40933
40933
|
const val = headersList[n + 1].toString("latin1");
|
|
40934
40934
|
headers[kHeadersList].append(key, val);
|
|
40935
40935
|
}
|
|
40936
|
-
|
|
40936
|
+
resolve15({
|
|
40937
40937
|
status,
|
|
40938
40938
|
statusText: STATUS_CODES[status],
|
|
40939
40939
|
headersList: headers[kHeadersList],
|
|
@@ -42494,8 +42494,8 @@ var require_util6 = __commonJS({
|
|
|
42494
42494
|
}
|
|
42495
42495
|
}
|
|
42496
42496
|
}
|
|
42497
|
-
function validateCookiePath(
|
|
42498
|
-
for (const char of
|
|
42497
|
+
function validateCookiePath(path27) {
|
|
42498
|
+
for (const char of path27) {
|
|
42499
42499
|
const code = char.charCodeAt(0);
|
|
42500
42500
|
if (code < 33 || char === ";") {
|
|
42501
42501
|
throw new Error("Invalid cookie path");
|
|
@@ -43292,9 +43292,9 @@ var require_connection = __commonJS({
|
|
|
43292
43292
|
channels.open = diagnosticsChannel.channel("undici:websocket:open");
|
|
43293
43293
|
channels.close = diagnosticsChannel.channel("undici:websocket:close");
|
|
43294
43294
|
channels.socketError = diagnosticsChannel.channel("undici:websocket:socket_error");
|
|
43295
|
-
var
|
|
43295
|
+
var crypto2;
|
|
43296
43296
|
try {
|
|
43297
|
-
|
|
43297
|
+
crypto2 = require("crypto");
|
|
43298
43298
|
} catch {
|
|
43299
43299
|
}
|
|
43300
43300
|
function establishWebSocketConnection(url, protocols, ws, onEstablish, options) {
|
|
@@ -43313,7 +43313,7 @@ var require_connection = __commonJS({
|
|
|
43313
43313
|
const headersList = new Headers(options.headers)[kHeadersList];
|
|
43314
43314
|
request.headersList = headersList;
|
|
43315
43315
|
}
|
|
43316
|
-
const keyValue =
|
|
43316
|
+
const keyValue = crypto2.randomBytes(16).toString("base64");
|
|
43317
43317
|
request.headersList.append("sec-websocket-key", keyValue);
|
|
43318
43318
|
request.headersList.append("sec-websocket-version", "13");
|
|
43319
43319
|
for (const protocol of protocols) {
|
|
@@ -43342,7 +43342,7 @@ var require_connection = __commonJS({
|
|
|
43342
43342
|
return;
|
|
43343
43343
|
}
|
|
43344
43344
|
const secWSAccept = response.headersList.get("Sec-WebSocket-Accept");
|
|
43345
|
-
const digest =
|
|
43345
|
+
const digest = crypto2.createHash("sha1").update(keyValue + uid).digest("base64");
|
|
43346
43346
|
if (secWSAccept !== digest) {
|
|
43347
43347
|
failWebsocketConnection(ws, "Incorrect hash received in Sec-WebSocket-Accept header.");
|
|
43348
43348
|
return;
|
|
@@ -43422,9 +43422,9 @@ var require_frame = __commonJS({
|
|
|
43422
43422
|
"node_modules/undici/lib/websocket/frame.js"(exports2, module2) {
|
|
43423
43423
|
"use strict";
|
|
43424
43424
|
var { maxUnsigned16Bit } = require_constants5();
|
|
43425
|
-
var
|
|
43425
|
+
var crypto2;
|
|
43426
43426
|
try {
|
|
43427
|
-
|
|
43427
|
+
crypto2 = require("crypto");
|
|
43428
43428
|
} catch {
|
|
43429
43429
|
}
|
|
43430
43430
|
var WebsocketFrameSend = class {
|
|
@@ -43433,7 +43433,7 @@ var require_frame = __commonJS({
|
|
|
43433
43433
|
*/
|
|
43434
43434
|
constructor(data) {
|
|
43435
43435
|
this.frameData = data;
|
|
43436
|
-
this.maskKey =
|
|
43436
|
+
this.maskKey = crypto2.randomBytes(4);
|
|
43437
43437
|
}
|
|
43438
43438
|
createFrame(opcode) {
|
|
43439
43439
|
const bodyLength = this.frameData?.byteLength ?? 0;
|
|
@@ -44175,11 +44175,11 @@ var require_undici = __commonJS({
|
|
|
44175
44175
|
if (typeof opts.path !== "string") {
|
|
44176
44176
|
throw new InvalidArgumentError("invalid opts.path");
|
|
44177
44177
|
}
|
|
44178
|
-
let
|
|
44178
|
+
let path27 = opts.path;
|
|
44179
44179
|
if (!opts.path.startsWith("/")) {
|
|
44180
|
-
|
|
44180
|
+
path27 = `/${path27}`;
|
|
44181
44181
|
}
|
|
44182
|
-
url = new URL(util.parseOrigin(url).origin +
|
|
44182
|
+
url = new URL(util.parseOrigin(url).origin + path27);
|
|
44183
44183
|
} else {
|
|
44184
44184
|
if (!opts) {
|
|
44185
44185
|
opts = typeof url === "object" ? url : {};
|
|
@@ -44728,7 +44728,7 @@ var init_mcp_check_provider = __esm({
|
|
|
44728
44728
|
logger.warn(
|
|
44729
44729
|
`MCP ${transportName} failed (attempt ${attempt + 1}/${maxRetries + 1}), retrying in ${delay}ms: ${error instanceof Error ? error.message : String(error)}`
|
|
44730
44730
|
);
|
|
44731
|
-
await new Promise((
|
|
44731
|
+
await new Promise((resolve15) => setTimeout(resolve15, delay));
|
|
44732
44732
|
attempt += 1;
|
|
44733
44733
|
} finally {
|
|
44734
44734
|
try {
|
|
@@ -45010,7 +45010,7 @@ async function acquirePromptLock() {
|
|
|
45010
45010
|
activePrompt = true;
|
|
45011
45011
|
return;
|
|
45012
45012
|
}
|
|
45013
|
-
await new Promise((
|
|
45013
|
+
await new Promise((resolve15) => waiters.push(resolve15));
|
|
45014
45014
|
activePrompt = true;
|
|
45015
45015
|
}
|
|
45016
45016
|
function releasePromptLock() {
|
|
@@ -45020,7 +45020,7 @@ function releasePromptLock() {
|
|
|
45020
45020
|
}
|
|
45021
45021
|
async function interactivePrompt(options) {
|
|
45022
45022
|
await acquirePromptLock();
|
|
45023
|
-
return new Promise((
|
|
45023
|
+
return new Promise((resolve15, reject) => {
|
|
45024
45024
|
const dbg = process.env.VISOR_DEBUG === "true";
|
|
45025
45025
|
try {
|
|
45026
45026
|
if (dbg) {
|
|
@@ -45107,12 +45107,12 @@ async function interactivePrompt(options) {
|
|
|
45107
45107
|
};
|
|
45108
45108
|
const finish = (value) => {
|
|
45109
45109
|
cleanup();
|
|
45110
|
-
|
|
45110
|
+
resolve15(value);
|
|
45111
45111
|
};
|
|
45112
45112
|
if (options.timeout && options.timeout > 0) {
|
|
45113
45113
|
timeoutId = setTimeout(() => {
|
|
45114
45114
|
cleanup();
|
|
45115
|
-
if (defaultValue !== void 0) return
|
|
45115
|
+
if (defaultValue !== void 0) return resolve15(defaultValue);
|
|
45116
45116
|
return reject(new Error("Input timeout"));
|
|
45117
45117
|
}, options.timeout);
|
|
45118
45118
|
}
|
|
@@ -45244,7 +45244,7 @@ async function interactivePrompt(options) {
|
|
|
45244
45244
|
});
|
|
45245
45245
|
}
|
|
45246
45246
|
async function simplePrompt(prompt) {
|
|
45247
|
-
return new Promise((
|
|
45247
|
+
return new Promise((resolve15) => {
|
|
45248
45248
|
const rl = readline.createInterface({
|
|
45249
45249
|
input: process.stdin,
|
|
45250
45250
|
output: process.stdout
|
|
@@ -45260,7 +45260,7 @@ async function simplePrompt(prompt) {
|
|
|
45260
45260
|
rl.question(`${prompt}
|
|
45261
45261
|
> `, (answer) => {
|
|
45262
45262
|
rl.close();
|
|
45263
|
-
|
|
45263
|
+
resolve15(answer.trim());
|
|
45264
45264
|
});
|
|
45265
45265
|
});
|
|
45266
45266
|
}
|
|
@@ -45428,7 +45428,7 @@ function isStdinAvailable() {
|
|
|
45428
45428
|
return !process.stdin.isTTY;
|
|
45429
45429
|
}
|
|
45430
45430
|
async function readStdin(timeout, maxSize = 1024 * 1024) {
|
|
45431
|
-
return new Promise((
|
|
45431
|
+
return new Promise((resolve15, reject) => {
|
|
45432
45432
|
let data = "";
|
|
45433
45433
|
let timeoutId;
|
|
45434
45434
|
if (timeout) {
|
|
@@ -45455,7 +45455,7 @@ async function readStdin(timeout, maxSize = 1024 * 1024) {
|
|
|
45455
45455
|
};
|
|
45456
45456
|
const onEnd = () => {
|
|
45457
45457
|
cleanup();
|
|
45458
|
-
|
|
45458
|
+
resolve15(data.trim());
|
|
45459
45459
|
};
|
|
45460
45460
|
const onError = (err) => {
|
|
45461
45461
|
cleanup();
|
|
@@ -49581,23 +49581,23 @@ __export(renderer_schema_exports, {
|
|
|
49581
49581
|
});
|
|
49582
49582
|
async function loadRendererSchema(name) {
|
|
49583
49583
|
try {
|
|
49584
|
-
const
|
|
49585
|
-
const
|
|
49584
|
+
const fs23 = await import("fs/promises");
|
|
49585
|
+
const path27 = await import("path");
|
|
49586
49586
|
const sanitized = String(name).replace(/[^a-zA-Z0-9-]/g, "");
|
|
49587
49587
|
if (!sanitized) return void 0;
|
|
49588
49588
|
const candidates = [
|
|
49589
49589
|
// When bundled with ncc, __dirname is dist/ and output/ is at dist/output/
|
|
49590
|
-
|
|
49590
|
+
path27.join(__dirname, "output", sanitized, "schema.json"),
|
|
49591
49591
|
// When running from source, __dirname is src/state-machine/dispatch/ and output/ is at output/
|
|
49592
|
-
|
|
49592
|
+
path27.join(__dirname, "..", "..", "output", sanitized, "schema.json"),
|
|
49593
49593
|
// When running from a checkout with output/ folder copied to CWD
|
|
49594
|
-
|
|
49594
|
+
path27.join(process.cwd(), "output", sanitized, "schema.json"),
|
|
49595
49595
|
// Fallback: cwd/dist/output/
|
|
49596
|
-
|
|
49596
|
+
path27.join(process.cwd(), "dist", "output", sanitized, "schema.json")
|
|
49597
49597
|
];
|
|
49598
49598
|
for (const p of candidates) {
|
|
49599
49599
|
try {
|
|
49600
|
-
const raw = await
|
|
49600
|
+
const raw = await fs23.readFile(p, "utf-8");
|
|
49601
49601
|
return JSON.parse(raw);
|
|
49602
49602
|
} catch {
|
|
49603
49603
|
}
|
|
@@ -52016,8 +52016,8 @@ function updateStats2(results, state, isForEachIteration = false) {
|
|
|
52016
52016
|
async function renderTemplateContent2(checkId, checkConfig, reviewSummary) {
|
|
52017
52017
|
try {
|
|
52018
52018
|
const { createExtendedLiquid: createExtendedLiquid2 } = await Promise.resolve().then(() => (init_liquid_extensions(), liquid_extensions_exports));
|
|
52019
|
-
const
|
|
52020
|
-
const
|
|
52019
|
+
const fs23 = await import("fs/promises");
|
|
52020
|
+
const path27 = await import("path");
|
|
52021
52021
|
const schemaRaw = checkConfig.schema || "plain";
|
|
52022
52022
|
const schema = typeof schemaRaw === "string" && !schemaRaw.includes("{{") && !schemaRaw.includes("{%") ? schemaRaw : typeof schemaRaw === "object" ? "code-review" : "plain";
|
|
52023
52023
|
let templateContent;
|
|
@@ -52026,27 +52026,27 @@ async function renderTemplateContent2(checkId, checkConfig, reviewSummary) {
|
|
|
52026
52026
|
logger.debug(`[LevelDispatch] Using inline template for ${checkId}`);
|
|
52027
52027
|
} else if (checkConfig.template && checkConfig.template.file) {
|
|
52028
52028
|
const file = String(checkConfig.template.file);
|
|
52029
|
-
const resolved =
|
|
52030
|
-
templateContent = await
|
|
52029
|
+
const resolved = path27.resolve(process.cwd(), file);
|
|
52030
|
+
templateContent = await fs23.readFile(resolved, "utf-8");
|
|
52031
52031
|
logger.debug(`[LevelDispatch] Using template file for ${checkId}: ${resolved}`);
|
|
52032
52032
|
} else if (schema && schema !== "plain") {
|
|
52033
52033
|
const sanitized = String(schema).replace(/[^a-zA-Z0-9-]/g, "");
|
|
52034
52034
|
if (sanitized) {
|
|
52035
52035
|
const candidatePaths = [
|
|
52036
|
-
|
|
52036
|
+
path27.join(__dirname, "output", sanitized, "template.liquid"),
|
|
52037
52037
|
// bundled: dist/output/
|
|
52038
|
-
|
|
52038
|
+
path27.join(__dirname, "..", "..", "output", sanitized, "template.liquid"),
|
|
52039
52039
|
// source (from state-machine/states)
|
|
52040
|
-
|
|
52040
|
+
path27.join(__dirname, "..", "..", "..", "output", sanitized, "template.liquid"),
|
|
52041
52041
|
// source (alternate)
|
|
52042
|
-
|
|
52042
|
+
path27.join(process.cwd(), "output", sanitized, "template.liquid"),
|
|
52043
52043
|
// fallback: cwd/output/
|
|
52044
|
-
|
|
52044
|
+
path27.join(process.cwd(), "dist", "output", sanitized, "template.liquid")
|
|
52045
52045
|
// fallback: cwd/dist/output/
|
|
52046
52046
|
];
|
|
52047
52047
|
for (const p of candidatePaths) {
|
|
52048
52048
|
try {
|
|
52049
|
-
templateContent = await
|
|
52049
|
+
templateContent = await fs23.readFile(p, "utf-8");
|
|
52050
52050
|
if (templateContent) {
|
|
52051
52051
|
logger.debug(`[LevelDispatch] Using schema template for ${checkId}: ${p}`);
|
|
52052
52052
|
break;
|
|
@@ -54186,8 +54186,8 @@ var init_workspace_manager = __esm({
|
|
|
54186
54186
|
);
|
|
54187
54187
|
if (this.cleanupRequested && this.activeOperations === 0) {
|
|
54188
54188
|
logger.debug(`[Workspace] All references released, proceeding with deferred cleanup`);
|
|
54189
|
-
for (const
|
|
54190
|
-
|
|
54189
|
+
for (const resolve15 of this.cleanupResolvers) {
|
|
54190
|
+
resolve15();
|
|
54191
54191
|
}
|
|
54192
54192
|
this.cleanupResolvers = [];
|
|
54193
54193
|
}
|
|
@@ -54344,19 +54344,19 @@ var init_workspace_manager = __esm({
|
|
|
54344
54344
|
);
|
|
54345
54345
|
this.cleanupRequested = true;
|
|
54346
54346
|
await Promise.race([
|
|
54347
|
-
new Promise((
|
|
54347
|
+
new Promise((resolve15) => {
|
|
54348
54348
|
if (this.activeOperations === 0) {
|
|
54349
|
-
|
|
54349
|
+
resolve15();
|
|
54350
54350
|
} else {
|
|
54351
|
-
this.cleanupResolvers.push(
|
|
54351
|
+
this.cleanupResolvers.push(resolve15);
|
|
54352
54352
|
}
|
|
54353
54353
|
}),
|
|
54354
|
-
new Promise((
|
|
54354
|
+
new Promise((resolve15) => {
|
|
54355
54355
|
setTimeout(() => {
|
|
54356
54356
|
logger.warn(
|
|
54357
54357
|
`[Workspace] Cleanup timeout after ${timeout}ms, proceeding anyway (${this.activeOperations} operations still active)`
|
|
54358
54358
|
);
|
|
54359
|
-
|
|
54359
|
+
resolve15();
|
|
54360
54360
|
}, timeout);
|
|
54361
54361
|
})
|
|
54362
54362
|
]);
|
|
@@ -54834,1380 +54834,6 @@ var init_build_engine_context = __esm({
|
|
|
54834
54834
|
}
|
|
54835
54835
|
});
|
|
54836
54836
|
|
|
54837
|
-
// src/policy/default-engine.ts
|
|
54838
|
-
var DefaultPolicyEngine;
|
|
54839
|
-
var init_default_engine = __esm({
|
|
54840
|
-
"src/policy/default-engine.ts"() {
|
|
54841
|
-
"use strict";
|
|
54842
|
-
DefaultPolicyEngine = class {
|
|
54843
|
-
async initialize(_config) {
|
|
54844
|
-
}
|
|
54845
|
-
async evaluateCheckExecution(_checkId, _checkConfig) {
|
|
54846
|
-
return { allowed: true };
|
|
54847
|
-
}
|
|
54848
|
-
async evaluateToolInvocation(_serverName, _methodName, _transport) {
|
|
54849
|
-
return { allowed: true };
|
|
54850
|
-
}
|
|
54851
|
-
async evaluateCapabilities(_checkId, _capabilities) {
|
|
54852
|
-
return { allowed: true };
|
|
54853
|
-
}
|
|
54854
|
-
async shutdown() {
|
|
54855
|
-
}
|
|
54856
|
-
};
|
|
54857
|
-
}
|
|
54858
|
-
});
|
|
54859
|
-
|
|
54860
|
-
// src/enterprise/license/validator.ts
|
|
54861
|
-
var validator_exports = {};
|
|
54862
|
-
__export(validator_exports, {
|
|
54863
|
-
LicenseValidator: () => LicenseValidator
|
|
54864
|
-
});
|
|
54865
|
-
var crypto2, fs21, path25, LicenseValidator;
|
|
54866
|
-
var init_validator = __esm({
|
|
54867
|
-
"src/enterprise/license/validator.ts"() {
|
|
54868
|
-
"use strict";
|
|
54869
|
-
crypto2 = __toESM(require("crypto"));
|
|
54870
|
-
fs21 = __toESM(require("fs"));
|
|
54871
|
-
path25 = __toESM(require("path"));
|
|
54872
|
-
LicenseValidator = class _LicenseValidator {
|
|
54873
|
-
/** Ed25519 public key for license verification (PEM format). */
|
|
54874
|
-
static PUBLIC_KEY = "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAI/Zd08EFmgIdrDm/HXd0l3/5GBt7R1PrdvhdmEXhJlU=\n-----END PUBLIC KEY-----\n";
|
|
54875
|
-
cache = null;
|
|
54876
|
-
static CACHE_TTL = 5 * 60 * 1e3;
|
|
54877
|
-
// 5 minutes
|
|
54878
|
-
static GRACE_PERIOD = 72 * 3600 * 1e3;
|
|
54879
|
-
// 72 hours after expiry
|
|
54880
|
-
/**
|
|
54881
|
-
* Load and validate license from environment or file.
|
|
54882
|
-
*
|
|
54883
|
-
* Resolution order:
|
|
54884
|
-
* 1. VISOR_LICENSE env var (JWT string)
|
|
54885
|
-
* 2. VISOR_LICENSE_FILE env var (path to file)
|
|
54886
|
-
* 3. .visor-license in project root (cwd)
|
|
54887
|
-
* 4. .visor-license in ~/.config/visor/
|
|
54888
|
-
*/
|
|
54889
|
-
async loadAndValidate() {
|
|
54890
|
-
if (this.cache && Date.now() - this.cache.validatedAt < _LicenseValidator.CACHE_TTL) {
|
|
54891
|
-
return this.cache.payload;
|
|
54892
|
-
}
|
|
54893
|
-
const token = this.resolveToken();
|
|
54894
|
-
if (!token) return null;
|
|
54895
|
-
const payload = this.verifyAndDecode(token);
|
|
54896
|
-
if (!payload) return null;
|
|
54897
|
-
this.cache = { payload, validatedAt: Date.now() };
|
|
54898
|
-
return payload;
|
|
54899
|
-
}
|
|
54900
|
-
/** Check if a specific feature is licensed */
|
|
54901
|
-
hasFeature(feature) {
|
|
54902
|
-
if (!this.cache) return false;
|
|
54903
|
-
return this.cache.payload.features.includes(feature);
|
|
54904
|
-
}
|
|
54905
|
-
/** Check if license is valid (with grace period) */
|
|
54906
|
-
isValid() {
|
|
54907
|
-
if (!this.cache) return false;
|
|
54908
|
-
const now = Date.now();
|
|
54909
|
-
const expiryMs = this.cache.payload.exp * 1e3;
|
|
54910
|
-
return now < expiryMs + _LicenseValidator.GRACE_PERIOD;
|
|
54911
|
-
}
|
|
54912
|
-
/** Check if the license is within its grace period (expired but still valid) */
|
|
54913
|
-
isInGracePeriod() {
|
|
54914
|
-
if (!this.cache) return false;
|
|
54915
|
-
const now = Date.now();
|
|
54916
|
-
const expiryMs = this.cache.payload.exp * 1e3;
|
|
54917
|
-
return now >= expiryMs && now < expiryMs + _LicenseValidator.GRACE_PERIOD;
|
|
54918
|
-
}
|
|
54919
|
-
resolveToken() {
|
|
54920
|
-
if (process.env.VISOR_LICENSE) {
|
|
54921
|
-
return process.env.VISOR_LICENSE.trim();
|
|
54922
|
-
}
|
|
54923
|
-
if (process.env.VISOR_LICENSE_FILE) {
|
|
54924
|
-
const resolved = path25.resolve(process.env.VISOR_LICENSE_FILE);
|
|
54925
|
-
const home2 = process.env.HOME || process.env.USERPROFILE || "";
|
|
54926
|
-
const allowedPrefixes = [path25.normalize(process.cwd())];
|
|
54927
|
-
if (home2) allowedPrefixes.push(path25.normalize(path25.join(home2, ".config", "visor")));
|
|
54928
|
-
let realPath;
|
|
54929
|
-
try {
|
|
54930
|
-
realPath = fs21.realpathSync(resolved);
|
|
54931
|
-
} catch {
|
|
54932
|
-
return null;
|
|
54933
|
-
}
|
|
54934
|
-
const isSafe = allowedPrefixes.some(
|
|
54935
|
-
(prefix) => realPath === prefix || realPath.startsWith(prefix + path25.sep)
|
|
54936
|
-
);
|
|
54937
|
-
if (!isSafe) return null;
|
|
54938
|
-
return this.readFile(realPath);
|
|
54939
|
-
}
|
|
54940
|
-
const cwdPath = path25.join(process.cwd(), ".visor-license");
|
|
54941
|
-
const cwdToken = this.readFile(cwdPath);
|
|
54942
|
-
if (cwdToken) return cwdToken;
|
|
54943
|
-
const home = process.env.HOME || process.env.USERPROFILE || "";
|
|
54944
|
-
if (home) {
|
|
54945
|
-
const configPath = path25.join(home, ".config", "visor", ".visor-license");
|
|
54946
|
-
const configToken = this.readFile(configPath);
|
|
54947
|
-
if (configToken) return configToken;
|
|
54948
|
-
}
|
|
54949
|
-
return null;
|
|
54950
|
-
}
|
|
54951
|
-
readFile(filePath) {
|
|
54952
|
-
try {
|
|
54953
|
-
return fs21.readFileSync(filePath, "utf-8").trim();
|
|
54954
|
-
} catch {
|
|
54955
|
-
return null;
|
|
54956
|
-
}
|
|
54957
|
-
}
|
|
54958
|
-
verifyAndDecode(token) {
|
|
54959
|
-
try {
|
|
54960
|
-
const parts = token.split(".");
|
|
54961
|
-
if (parts.length !== 3) return null;
|
|
54962
|
-
const [headerB64, payloadB64, signatureB64] = parts;
|
|
54963
|
-
const header = JSON.parse(Buffer.from(headerB64, "base64url").toString());
|
|
54964
|
-
if (header.alg !== "EdDSA") return null;
|
|
54965
|
-
const data = `${headerB64}.${payloadB64}`;
|
|
54966
|
-
const signature = Buffer.from(signatureB64, "base64url");
|
|
54967
|
-
const publicKey = crypto2.createPublicKey(_LicenseValidator.PUBLIC_KEY);
|
|
54968
|
-
if (publicKey.asymmetricKeyType !== "ed25519") {
|
|
54969
|
-
return null;
|
|
54970
|
-
}
|
|
54971
|
-
const isValid = crypto2.verify(null, Buffer.from(data), publicKey, signature);
|
|
54972
|
-
if (!isValid) return null;
|
|
54973
|
-
const payload = JSON.parse(Buffer.from(payloadB64, "base64url").toString());
|
|
54974
|
-
if (!payload.org || !Array.isArray(payload.features) || typeof payload.exp !== "number" || typeof payload.iat !== "number" || !payload.sub) {
|
|
54975
|
-
return null;
|
|
54976
|
-
}
|
|
54977
|
-
const now = Date.now();
|
|
54978
|
-
const expiryMs = payload.exp * 1e3;
|
|
54979
|
-
if (now >= expiryMs + _LicenseValidator.GRACE_PERIOD) {
|
|
54980
|
-
return null;
|
|
54981
|
-
}
|
|
54982
|
-
return payload;
|
|
54983
|
-
} catch {
|
|
54984
|
-
return null;
|
|
54985
|
-
}
|
|
54986
|
-
}
|
|
54987
|
-
};
|
|
54988
|
-
}
|
|
54989
|
-
});
|
|
54990
|
-
|
|
54991
|
-
// src/enterprise/policy/opa-compiler.ts
|
|
54992
|
-
var fs22, path26, os2, crypto3, import_child_process8, OpaCompiler;
|
|
54993
|
-
var init_opa_compiler = __esm({
|
|
54994
|
-
"src/enterprise/policy/opa-compiler.ts"() {
|
|
54995
|
-
"use strict";
|
|
54996
|
-
fs22 = __toESM(require("fs"));
|
|
54997
|
-
path26 = __toESM(require("path"));
|
|
54998
|
-
os2 = __toESM(require("os"));
|
|
54999
|
-
crypto3 = __toESM(require("crypto"));
|
|
55000
|
-
import_child_process8 = require("child_process");
|
|
55001
|
-
OpaCompiler = class _OpaCompiler {
|
|
55002
|
-
static CACHE_DIR = path26.join(os2.tmpdir(), "visor-opa-cache");
|
|
55003
|
-
/**
|
|
55004
|
-
* Resolve the input paths to WASM bytes.
|
|
55005
|
-
*
|
|
55006
|
-
* Strategy:
|
|
55007
|
-
* 1. If any path is a .wasm file, read it directly
|
|
55008
|
-
* 2. If a directory contains policy.wasm, read it
|
|
55009
|
-
* 3. Otherwise, collect all .rego files and auto-compile via `opa build`
|
|
55010
|
-
*/
|
|
55011
|
-
async resolveWasmBytes(paths) {
|
|
55012
|
-
const regoFiles = [];
|
|
55013
|
-
for (const p of paths) {
|
|
55014
|
-
const resolved = path26.resolve(p);
|
|
55015
|
-
if (path26.normalize(resolved).includes("..")) {
|
|
55016
|
-
throw new Error(`Policy path contains traversal sequences: ${p}`);
|
|
55017
|
-
}
|
|
55018
|
-
if (resolved.endsWith(".wasm") && fs22.existsSync(resolved)) {
|
|
55019
|
-
return fs22.readFileSync(resolved);
|
|
55020
|
-
}
|
|
55021
|
-
if (!fs22.existsSync(resolved)) continue;
|
|
55022
|
-
const stat2 = fs22.statSync(resolved);
|
|
55023
|
-
if (stat2.isDirectory()) {
|
|
55024
|
-
const wasmCandidate = path26.join(resolved, "policy.wasm");
|
|
55025
|
-
if (fs22.existsSync(wasmCandidate)) {
|
|
55026
|
-
return fs22.readFileSync(wasmCandidate);
|
|
55027
|
-
}
|
|
55028
|
-
const files = fs22.readdirSync(resolved);
|
|
55029
|
-
for (const f of files) {
|
|
55030
|
-
if (f.endsWith(".rego")) {
|
|
55031
|
-
regoFiles.push(path26.join(resolved, f));
|
|
55032
|
-
}
|
|
55033
|
-
}
|
|
55034
|
-
} else if (resolved.endsWith(".rego")) {
|
|
55035
|
-
regoFiles.push(resolved);
|
|
55036
|
-
}
|
|
55037
|
-
}
|
|
55038
|
-
if (regoFiles.length === 0) {
|
|
55039
|
-
throw new Error(
|
|
55040
|
-
`OPA WASM evaluator: no .wasm bundle or .rego files found in: ${paths.join(", ")}`
|
|
55041
|
-
);
|
|
55042
|
-
}
|
|
55043
|
-
return this.compileRego(regoFiles);
|
|
55044
|
-
}
|
|
55045
|
-
/**
|
|
55046
|
-
* Auto-compile .rego files to a WASM bundle using the `opa` CLI.
|
|
55047
|
-
*
|
|
55048
|
-
* Caches the compiled bundle based on a content hash of all input .rego files
|
|
55049
|
-
* so subsequent runs skip compilation if policies haven't changed.
|
|
55050
|
-
*/
|
|
55051
|
-
compileRego(regoFiles) {
|
|
55052
|
-
try {
|
|
55053
|
-
(0, import_child_process8.execFileSync)("opa", ["version"], { stdio: "pipe" });
|
|
55054
|
-
} catch {
|
|
55055
|
-
throw new Error(
|
|
55056
|
-
"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(" ")
|
|
55057
|
-
);
|
|
55058
|
-
}
|
|
55059
|
-
const hash = crypto3.createHash("sha256");
|
|
55060
|
-
for (const f of regoFiles.sort()) {
|
|
55061
|
-
hash.update(fs22.readFileSync(f));
|
|
55062
|
-
hash.update(f);
|
|
55063
|
-
}
|
|
55064
|
-
const cacheKey = hash.digest("hex").slice(0, 16);
|
|
55065
|
-
const cacheDir = _OpaCompiler.CACHE_DIR;
|
|
55066
|
-
const cachedWasm = path26.join(cacheDir, `${cacheKey}.wasm`);
|
|
55067
|
-
if (fs22.existsSync(cachedWasm)) {
|
|
55068
|
-
return fs22.readFileSync(cachedWasm);
|
|
55069
|
-
}
|
|
55070
|
-
fs22.mkdirSync(cacheDir, { recursive: true });
|
|
55071
|
-
const bundleTar = path26.join(cacheDir, `${cacheKey}-bundle.tar.gz`);
|
|
55072
|
-
try {
|
|
55073
|
-
const args = [
|
|
55074
|
-
"build",
|
|
55075
|
-
"-t",
|
|
55076
|
-
"wasm",
|
|
55077
|
-
"-e",
|
|
55078
|
-
"visor",
|
|
55079
|
-
// entrypoint: the visor package tree
|
|
55080
|
-
"-o",
|
|
55081
|
-
bundleTar,
|
|
55082
|
-
...regoFiles
|
|
55083
|
-
];
|
|
55084
|
-
(0, import_child_process8.execFileSync)("opa", args, {
|
|
55085
|
-
stdio: "pipe",
|
|
55086
|
-
timeout: 3e4
|
|
55087
|
-
});
|
|
55088
|
-
} catch (err) {
|
|
55089
|
-
const stderr = err?.stderr?.toString() || "";
|
|
55090
|
-
throw new Error(
|
|
55091
|
-
`Failed to compile .rego files to WASM:
|
|
55092
|
-
${stderr}
|
|
55093
|
-
Ensure your .rego files are valid and the \`opa\` CLI is installed.`
|
|
55094
|
-
);
|
|
55095
|
-
}
|
|
55096
|
-
try {
|
|
55097
|
-
(0, import_child_process8.execFileSync)("tar", ["-xzf", bundleTar, "-C", cacheDir, "/policy.wasm"], {
|
|
55098
|
-
stdio: "pipe"
|
|
55099
|
-
});
|
|
55100
|
-
const extractedWasm = path26.join(cacheDir, "policy.wasm");
|
|
55101
|
-
if (fs22.existsSync(extractedWasm)) {
|
|
55102
|
-
fs22.renameSync(extractedWasm, cachedWasm);
|
|
55103
|
-
}
|
|
55104
|
-
} catch {
|
|
55105
|
-
try {
|
|
55106
|
-
(0, import_child_process8.execFileSync)("tar", ["-xzf", bundleTar, "-C", cacheDir, "policy.wasm"], {
|
|
55107
|
-
stdio: "pipe"
|
|
55108
|
-
});
|
|
55109
|
-
const extractedWasm = path26.join(cacheDir, "policy.wasm");
|
|
55110
|
-
if (fs22.existsSync(extractedWasm)) {
|
|
55111
|
-
fs22.renameSync(extractedWasm, cachedWasm);
|
|
55112
|
-
}
|
|
55113
|
-
} catch (err2) {
|
|
55114
|
-
throw new Error(`Failed to extract policy.wasm from OPA bundle: ${err2?.message || err2}`);
|
|
55115
|
-
}
|
|
55116
|
-
}
|
|
55117
|
-
try {
|
|
55118
|
-
fs22.unlinkSync(bundleTar);
|
|
55119
|
-
} catch {
|
|
55120
|
-
}
|
|
55121
|
-
if (!fs22.existsSync(cachedWasm)) {
|
|
55122
|
-
throw new Error("OPA build succeeded but policy.wasm was not found in the bundle");
|
|
55123
|
-
}
|
|
55124
|
-
return fs22.readFileSync(cachedWasm);
|
|
55125
|
-
}
|
|
55126
|
-
};
|
|
55127
|
-
}
|
|
55128
|
-
});
|
|
55129
|
-
|
|
55130
|
-
// src/enterprise/policy/opa-wasm-evaluator.ts
|
|
55131
|
-
var fs23, path27, OpaWasmEvaluator;
|
|
55132
|
-
var init_opa_wasm_evaluator = __esm({
|
|
55133
|
-
"src/enterprise/policy/opa-wasm-evaluator.ts"() {
|
|
55134
|
-
"use strict";
|
|
55135
|
-
fs23 = __toESM(require("fs"));
|
|
55136
|
-
path27 = __toESM(require("path"));
|
|
55137
|
-
init_opa_compiler();
|
|
55138
|
-
OpaWasmEvaluator = class {
|
|
55139
|
-
policy = null;
|
|
55140
|
-
dataDocument = {};
|
|
55141
|
-
compiler = new OpaCompiler();
|
|
55142
|
-
async initialize(rulesPath) {
|
|
55143
|
-
const paths = Array.isArray(rulesPath) ? rulesPath : [rulesPath];
|
|
55144
|
-
const wasmBytes = await this.compiler.resolveWasmBytes(paths);
|
|
55145
|
-
try {
|
|
55146
|
-
const { createRequire } = require("module");
|
|
55147
|
-
const runtimeRequire = createRequire(__filename);
|
|
55148
|
-
const opaWasm = runtimeRequire("@open-policy-agent/opa-wasm");
|
|
55149
|
-
const loadPolicy = opaWasm.loadPolicy || opaWasm.default?.loadPolicy;
|
|
55150
|
-
if (!loadPolicy) {
|
|
55151
|
-
throw new Error("loadPolicy not found in @open-policy-agent/opa-wasm");
|
|
55152
|
-
}
|
|
55153
|
-
this.policy = await loadPolicy(wasmBytes);
|
|
55154
|
-
} catch (err) {
|
|
55155
|
-
if (err?.code === "MODULE_NOT_FOUND" || err?.code === "ERR_MODULE_NOT_FOUND") {
|
|
55156
|
-
throw new Error(
|
|
55157
|
-
"OPA WASM evaluator requires @open-policy-agent/opa-wasm. Install it with: npm install @open-policy-agent/opa-wasm"
|
|
55158
|
-
);
|
|
55159
|
-
}
|
|
55160
|
-
throw err;
|
|
55161
|
-
}
|
|
55162
|
-
}
|
|
55163
|
-
/**
|
|
55164
|
-
* Load external data from a JSON file to use as the OPA data document.
|
|
55165
|
-
* The loaded data will be passed to `policy.setData()` during evaluation,
|
|
55166
|
-
* making it available in Rego via `data.<key>`.
|
|
55167
|
-
*/
|
|
55168
|
-
loadData(dataPath) {
|
|
55169
|
-
const resolved = path27.resolve(dataPath);
|
|
55170
|
-
if (path27.normalize(resolved).includes("..")) {
|
|
55171
|
-
throw new Error(`Data path contains traversal sequences: ${dataPath}`);
|
|
55172
|
-
}
|
|
55173
|
-
if (!fs23.existsSync(resolved)) {
|
|
55174
|
-
throw new Error(`OPA data file not found: ${resolved}`);
|
|
55175
|
-
}
|
|
55176
|
-
const stat2 = fs23.statSync(resolved);
|
|
55177
|
-
if (stat2.size > 10 * 1024 * 1024) {
|
|
55178
|
-
throw new Error(`OPA data file exceeds 10MB limit: ${resolved} (${stat2.size} bytes)`);
|
|
55179
|
-
}
|
|
55180
|
-
const raw = fs23.readFileSync(resolved, "utf-8");
|
|
55181
|
-
try {
|
|
55182
|
-
const parsed = JSON.parse(raw);
|
|
55183
|
-
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
55184
|
-
throw new Error("OPA data file must contain a JSON object (not an array or primitive)");
|
|
55185
|
-
}
|
|
55186
|
-
this.dataDocument = parsed;
|
|
55187
|
-
} catch (err) {
|
|
55188
|
-
if (err.message.startsWith("OPA data file must")) {
|
|
55189
|
-
throw err;
|
|
55190
|
-
}
|
|
55191
|
-
throw new Error(`Failed to parse OPA data file ${resolved}: ${err.message}`);
|
|
55192
|
-
}
|
|
55193
|
-
}
|
|
55194
|
-
async evaluate(input) {
|
|
55195
|
-
if (!this.policy) {
|
|
55196
|
-
throw new Error("OPA WASM evaluator not initialized");
|
|
55197
|
-
}
|
|
55198
|
-
this.policy.setData(this.dataDocument);
|
|
55199
|
-
const resultSet = this.policy.evaluate(input);
|
|
55200
|
-
if (Array.isArray(resultSet) && resultSet.length > 0) {
|
|
55201
|
-
return resultSet[0].result;
|
|
55202
|
-
}
|
|
55203
|
-
return void 0;
|
|
55204
|
-
}
|
|
55205
|
-
async shutdown() {
|
|
55206
|
-
if (this.policy) {
|
|
55207
|
-
if (typeof this.policy.close === "function") {
|
|
55208
|
-
try {
|
|
55209
|
-
this.policy.close();
|
|
55210
|
-
} catch {
|
|
55211
|
-
}
|
|
55212
|
-
} else if (typeof this.policy.free === "function") {
|
|
55213
|
-
try {
|
|
55214
|
-
this.policy.free();
|
|
55215
|
-
} catch {
|
|
55216
|
-
}
|
|
55217
|
-
}
|
|
55218
|
-
}
|
|
55219
|
-
this.policy = null;
|
|
55220
|
-
}
|
|
55221
|
-
};
|
|
55222
|
-
}
|
|
55223
|
-
});
|
|
55224
|
-
|
|
55225
|
-
// src/enterprise/policy/opa-http-evaluator.ts
|
|
55226
|
-
var OpaHttpEvaluator;
|
|
55227
|
-
var init_opa_http_evaluator = __esm({
|
|
55228
|
-
"src/enterprise/policy/opa-http-evaluator.ts"() {
|
|
55229
|
-
"use strict";
|
|
55230
|
-
OpaHttpEvaluator = class {
|
|
55231
|
-
baseUrl;
|
|
55232
|
-
timeout;
|
|
55233
|
-
constructor(baseUrl, timeout = 5e3) {
|
|
55234
|
-
let parsed;
|
|
55235
|
-
try {
|
|
55236
|
-
parsed = new URL(baseUrl);
|
|
55237
|
-
} catch {
|
|
55238
|
-
throw new Error(`OPA HTTP evaluator: invalid URL: ${baseUrl}`);
|
|
55239
|
-
}
|
|
55240
|
-
if (!["http:", "https:"].includes(parsed.protocol)) {
|
|
55241
|
-
throw new Error(
|
|
55242
|
-
`OPA HTTP evaluator: url must use http:// or https:// protocol, got: ${baseUrl}`
|
|
55243
|
-
);
|
|
55244
|
-
}
|
|
55245
|
-
const hostname = parsed.hostname;
|
|
55246
|
-
if (this.isBlockedHostname(hostname)) {
|
|
55247
|
-
throw new Error(
|
|
55248
|
-
`OPA HTTP evaluator: url must not point to internal, loopback, or private network addresses`
|
|
55249
|
-
);
|
|
55250
|
-
}
|
|
55251
|
-
this.baseUrl = baseUrl.replace(/\/+$/, "");
|
|
55252
|
-
this.timeout = timeout;
|
|
55253
|
-
}
|
|
55254
|
-
/**
|
|
55255
|
-
* Check if a hostname is blocked due to SSRF concerns.
|
|
55256
|
-
*
|
|
55257
|
-
* Blocks:
|
|
55258
|
-
* - Loopback addresses (127.x.x.x, localhost, 0.0.0.0, ::1)
|
|
55259
|
-
* - Link-local addresses (169.254.x.x)
|
|
55260
|
-
* - Private networks (10.x.x.x, 172.16-31.x.x, 192.168.x.x)
|
|
55261
|
-
* - IPv6 unique local addresses (fd00::/8)
|
|
55262
|
-
* - Cloud metadata services (*.internal)
|
|
55263
|
-
*/
|
|
55264
|
-
isBlockedHostname(hostname) {
|
|
55265
|
-
if (!hostname) return true;
|
|
55266
|
-
const normalized = hostname.toLowerCase().replace(/^\[|\]$/g, "");
|
|
55267
|
-
if (normalized === "metadata.google.internal" || normalized.endsWith(".internal")) {
|
|
55268
|
-
return true;
|
|
55269
|
-
}
|
|
55270
|
-
if (normalized === "localhost" || normalized === "localhost.localdomain") {
|
|
55271
|
-
return true;
|
|
55272
|
-
}
|
|
55273
|
-
if (normalized === "::1" || normalized === "0:0:0:0:0:0:0:1") {
|
|
55274
|
-
return true;
|
|
55275
|
-
}
|
|
55276
|
-
const ipv4Pattern = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/;
|
|
55277
|
-
const ipv4Match = normalized.match(ipv4Pattern);
|
|
55278
|
-
if (ipv4Match) {
|
|
55279
|
-
const octets = ipv4Match.slice(1, 5).map(Number);
|
|
55280
|
-
if (octets.some((octet) => octet > 255)) {
|
|
55281
|
-
return false;
|
|
55282
|
-
}
|
|
55283
|
-
const [a, b] = octets;
|
|
55284
|
-
if (a === 127) {
|
|
55285
|
-
return true;
|
|
55286
|
-
}
|
|
55287
|
-
if (a === 0) {
|
|
55288
|
-
return true;
|
|
55289
|
-
}
|
|
55290
|
-
if (a === 169 && b === 254) {
|
|
55291
|
-
return true;
|
|
55292
|
-
}
|
|
55293
|
-
if (a === 10) {
|
|
55294
|
-
return true;
|
|
55295
|
-
}
|
|
55296
|
-
if (a === 172 && b >= 16 && b <= 31) {
|
|
55297
|
-
return true;
|
|
55298
|
-
}
|
|
55299
|
-
if (a === 192 && b === 168) {
|
|
55300
|
-
return true;
|
|
55301
|
-
}
|
|
55302
|
-
}
|
|
55303
|
-
if (normalized.startsWith("fd") || normalized.startsWith("fc")) {
|
|
55304
|
-
return true;
|
|
55305
|
-
}
|
|
55306
|
-
if (normalized.startsWith("fe80:")) {
|
|
55307
|
-
return true;
|
|
55308
|
-
}
|
|
55309
|
-
return false;
|
|
55310
|
-
}
|
|
55311
|
-
/**
|
|
55312
|
-
* Evaluate a policy rule against an input document via OPA REST API.
|
|
55313
|
-
*
|
|
55314
|
-
* @param input - The input document to evaluate
|
|
55315
|
-
* @param rulePath - OPA rule path (e.g., 'visor/check/execute')
|
|
55316
|
-
* @returns The result object from OPA, or undefined on error
|
|
55317
|
-
*/
|
|
55318
|
-
async evaluate(input, rulePath) {
|
|
55319
|
-
const encodedPath = rulePath.split("/").map((s) => encodeURIComponent(s)).join("/");
|
|
55320
|
-
const url = `${this.baseUrl}/v1/data/${encodedPath}`;
|
|
55321
|
-
const controller = new AbortController();
|
|
55322
|
-
const timer = setTimeout(() => controller.abort(), this.timeout);
|
|
55323
|
-
try {
|
|
55324
|
-
const response = await fetch(url, {
|
|
55325
|
-
method: "POST",
|
|
55326
|
-
headers: { "Content-Type": "application/json" },
|
|
55327
|
-
body: JSON.stringify({ input }),
|
|
55328
|
-
signal: controller.signal
|
|
55329
|
-
});
|
|
55330
|
-
if (!response.ok) {
|
|
55331
|
-
throw new Error(`OPA HTTP ${response.status}: ${response.statusText}`);
|
|
55332
|
-
}
|
|
55333
|
-
let body;
|
|
55334
|
-
try {
|
|
55335
|
-
body = await response.json();
|
|
55336
|
-
} catch (jsonErr) {
|
|
55337
|
-
throw new Error(
|
|
55338
|
-
`OPA HTTP evaluator: failed to parse JSON response: ${jsonErr instanceof Error ? jsonErr.message : String(jsonErr)}`
|
|
55339
|
-
);
|
|
55340
|
-
}
|
|
55341
|
-
return body?.result;
|
|
55342
|
-
} finally {
|
|
55343
|
-
clearTimeout(timer);
|
|
55344
|
-
}
|
|
55345
|
-
}
|
|
55346
|
-
async shutdown() {
|
|
55347
|
-
}
|
|
55348
|
-
};
|
|
55349
|
-
}
|
|
55350
|
-
});
|
|
55351
|
-
|
|
55352
|
-
// src/enterprise/policy/policy-input-builder.ts
|
|
55353
|
-
var PolicyInputBuilder;
|
|
55354
|
-
var init_policy_input_builder = __esm({
|
|
55355
|
-
"src/enterprise/policy/policy-input-builder.ts"() {
|
|
55356
|
-
"use strict";
|
|
55357
|
-
PolicyInputBuilder = class {
|
|
55358
|
-
roles;
|
|
55359
|
-
actor;
|
|
55360
|
-
repository;
|
|
55361
|
-
pullRequest;
|
|
55362
|
-
constructor(policyConfig, actor, repository, pullRequest) {
|
|
55363
|
-
this.roles = policyConfig.roles || {};
|
|
55364
|
-
this.actor = actor;
|
|
55365
|
-
this.repository = repository;
|
|
55366
|
-
this.pullRequest = pullRequest;
|
|
55367
|
-
}
|
|
55368
|
-
/** Resolve which roles apply to the current actor. */
|
|
55369
|
-
resolveRoles() {
|
|
55370
|
-
const matched = [];
|
|
55371
|
-
for (const [roleName, roleConfig] of Object.entries(this.roles)) {
|
|
55372
|
-
let identityMatch = false;
|
|
55373
|
-
if (roleConfig.author_association && this.actor.authorAssociation && roleConfig.author_association.includes(this.actor.authorAssociation)) {
|
|
55374
|
-
identityMatch = true;
|
|
55375
|
-
}
|
|
55376
|
-
if (!identityMatch && roleConfig.users && this.actor.login && roleConfig.users.includes(this.actor.login)) {
|
|
55377
|
-
identityMatch = true;
|
|
55378
|
-
}
|
|
55379
|
-
if (!identityMatch && roleConfig.slack_users && this.actor.slack?.userId && roleConfig.slack_users.includes(this.actor.slack.userId)) {
|
|
55380
|
-
identityMatch = true;
|
|
55381
|
-
}
|
|
55382
|
-
if (!identityMatch && roleConfig.emails && this.actor.slack?.email) {
|
|
55383
|
-
const actorEmail = this.actor.slack.email.toLowerCase();
|
|
55384
|
-
if (roleConfig.emails.some((e) => e.toLowerCase() === actorEmail)) {
|
|
55385
|
-
identityMatch = true;
|
|
55386
|
-
}
|
|
55387
|
-
}
|
|
55388
|
-
if (!identityMatch) continue;
|
|
55389
|
-
if (roleConfig.slack_channels && roleConfig.slack_channels.length > 0) {
|
|
55390
|
-
if (!this.actor.slack?.channelId || !roleConfig.slack_channels.includes(this.actor.slack.channelId)) {
|
|
55391
|
-
continue;
|
|
55392
|
-
}
|
|
55393
|
-
}
|
|
55394
|
-
matched.push(roleName);
|
|
55395
|
-
}
|
|
55396
|
-
return matched;
|
|
55397
|
-
}
|
|
55398
|
-
buildActor() {
|
|
55399
|
-
return {
|
|
55400
|
-
authorAssociation: this.actor.authorAssociation,
|
|
55401
|
-
login: this.actor.login,
|
|
55402
|
-
roles: this.resolveRoles(),
|
|
55403
|
-
isLocalMode: this.actor.isLocalMode,
|
|
55404
|
-
...this.actor.slack && { slack: this.actor.slack }
|
|
55405
|
-
};
|
|
55406
|
-
}
|
|
55407
|
-
forCheckExecution(check) {
|
|
55408
|
-
return {
|
|
55409
|
-
scope: "check.execute",
|
|
55410
|
-
check: {
|
|
55411
|
-
id: check.id,
|
|
55412
|
-
type: check.type,
|
|
55413
|
-
group: check.group,
|
|
55414
|
-
tags: check.tags,
|
|
55415
|
-
criticality: check.criticality,
|
|
55416
|
-
sandbox: check.sandbox,
|
|
55417
|
-
policy: check.policy
|
|
55418
|
-
},
|
|
55419
|
-
actor: this.buildActor(),
|
|
55420
|
-
repository: this.repository,
|
|
55421
|
-
pullRequest: this.pullRequest
|
|
55422
|
-
};
|
|
55423
|
-
}
|
|
55424
|
-
forToolInvocation(serverName, methodName, transport) {
|
|
55425
|
-
return {
|
|
55426
|
-
scope: "tool.invoke",
|
|
55427
|
-
tool: { serverName, methodName, transport },
|
|
55428
|
-
actor: this.buildActor(),
|
|
55429
|
-
repository: this.repository,
|
|
55430
|
-
pullRequest: this.pullRequest
|
|
55431
|
-
};
|
|
55432
|
-
}
|
|
55433
|
-
forCapabilityResolve(checkId, capabilities) {
|
|
55434
|
-
return {
|
|
55435
|
-
scope: "capability.resolve",
|
|
55436
|
-
check: { id: checkId, type: "ai" },
|
|
55437
|
-
capability: capabilities,
|
|
55438
|
-
actor: this.buildActor(),
|
|
55439
|
-
repository: this.repository,
|
|
55440
|
-
pullRequest: this.pullRequest
|
|
55441
|
-
};
|
|
55442
|
-
}
|
|
55443
|
-
};
|
|
55444
|
-
}
|
|
55445
|
-
});
|
|
55446
|
-
|
|
55447
|
-
// src/enterprise/policy/opa-policy-engine.ts
|
|
55448
|
-
var opa_policy_engine_exports = {};
|
|
55449
|
-
__export(opa_policy_engine_exports, {
|
|
55450
|
-
OpaPolicyEngine: () => OpaPolicyEngine
|
|
55451
|
-
});
|
|
55452
|
-
var OpaPolicyEngine;
|
|
55453
|
-
var init_opa_policy_engine = __esm({
|
|
55454
|
-
"src/enterprise/policy/opa-policy-engine.ts"() {
|
|
55455
|
-
"use strict";
|
|
55456
|
-
init_opa_wasm_evaluator();
|
|
55457
|
-
init_opa_http_evaluator();
|
|
55458
|
-
init_policy_input_builder();
|
|
55459
|
-
OpaPolicyEngine = class {
|
|
55460
|
-
evaluator = null;
|
|
55461
|
-
fallback;
|
|
55462
|
-
timeout;
|
|
55463
|
-
config;
|
|
55464
|
-
inputBuilder = null;
|
|
55465
|
-
logger = null;
|
|
55466
|
-
constructor(config) {
|
|
55467
|
-
this.config = config;
|
|
55468
|
-
this.fallback = config.fallback || "deny";
|
|
55469
|
-
this.timeout = config.timeout || 5e3;
|
|
55470
|
-
}
|
|
55471
|
-
async initialize(config) {
|
|
55472
|
-
try {
|
|
55473
|
-
this.logger = (init_logger(), __toCommonJS(logger_exports)).logger;
|
|
55474
|
-
} catch {
|
|
55475
|
-
}
|
|
55476
|
-
const actor = {
|
|
55477
|
-
authorAssociation: process.env.VISOR_AUTHOR_ASSOCIATION,
|
|
55478
|
-
login: process.env.VISOR_AUTHOR_LOGIN || process.env.GITHUB_ACTOR,
|
|
55479
|
-
isLocalMode: !process.env.GITHUB_ACTIONS
|
|
55480
|
-
};
|
|
55481
|
-
const repo = {
|
|
55482
|
-
owner: process.env.GITHUB_REPOSITORY_OWNER,
|
|
55483
|
-
name: process.env.GITHUB_REPOSITORY?.split("/")[1],
|
|
55484
|
-
branch: process.env.GITHUB_HEAD_REF,
|
|
55485
|
-
baseBranch: process.env.GITHUB_BASE_REF,
|
|
55486
|
-
event: process.env.GITHUB_EVENT_NAME
|
|
55487
|
-
};
|
|
55488
|
-
const prNum = process.env.GITHUB_PR_NUMBER ? parseInt(process.env.GITHUB_PR_NUMBER, 10) : void 0;
|
|
55489
|
-
const pullRequest = {
|
|
55490
|
-
number: prNum !== void 0 && Number.isFinite(prNum) ? prNum : void 0
|
|
55491
|
-
};
|
|
55492
|
-
this.inputBuilder = new PolicyInputBuilder(config, actor, repo, pullRequest);
|
|
55493
|
-
if (config.engine === "local") {
|
|
55494
|
-
if (!config.rules) {
|
|
55495
|
-
throw new Error("OPA local mode requires `policy.rules` path to .wasm or .rego files");
|
|
55496
|
-
}
|
|
55497
|
-
const wasm = new OpaWasmEvaluator();
|
|
55498
|
-
await wasm.initialize(config.rules);
|
|
55499
|
-
if (config.data) {
|
|
55500
|
-
wasm.loadData(config.data);
|
|
55501
|
-
}
|
|
55502
|
-
this.evaluator = wasm;
|
|
55503
|
-
} else if (config.engine === "remote") {
|
|
55504
|
-
if (!config.url) {
|
|
55505
|
-
throw new Error("OPA remote mode requires `policy.url` pointing to OPA server");
|
|
55506
|
-
}
|
|
55507
|
-
this.evaluator = new OpaHttpEvaluator(config.url, this.timeout);
|
|
55508
|
-
} else {
|
|
55509
|
-
this.evaluator = null;
|
|
55510
|
-
}
|
|
55511
|
-
}
|
|
55512
|
-
/**
|
|
55513
|
-
* Update actor/repo/PR context (e.g., after PR info becomes available).
|
|
55514
|
-
* Called by the enterprise loader when engine context is enriched.
|
|
55515
|
-
*/
|
|
55516
|
-
setActorContext(actor, repo, pullRequest) {
|
|
55517
|
-
this.inputBuilder = new PolicyInputBuilder(this.config, actor, repo, pullRequest);
|
|
55518
|
-
}
|
|
55519
|
-
async evaluateCheckExecution(checkId, checkConfig) {
|
|
55520
|
-
if (!this.evaluator || !this.inputBuilder) return { allowed: true };
|
|
55521
|
-
const cfg = checkConfig && typeof checkConfig === "object" ? checkConfig : {};
|
|
55522
|
-
const policyOverride = cfg.policy;
|
|
55523
|
-
const input = this.inputBuilder.forCheckExecution({
|
|
55524
|
-
id: checkId,
|
|
55525
|
-
type: cfg.type || "ai",
|
|
55526
|
-
group: cfg.group,
|
|
55527
|
-
tags: cfg.tags,
|
|
55528
|
-
criticality: cfg.criticality,
|
|
55529
|
-
sandbox: cfg.sandbox,
|
|
55530
|
-
policy: policyOverride
|
|
55531
|
-
});
|
|
55532
|
-
return this.doEvaluate(input, this.resolveRulePath("check.execute", policyOverride?.rule));
|
|
55533
|
-
}
|
|
55534
|
-
async evaluateToolInvocation(serverName, methodName, transport) {
|
|
55535
|
-
if (!this.evaluator || !this.inputBuilder) return { allowed: true };
|
|
55536
|
-
const input = this.inputBuilder.forToolInvocation(serverName, methodName, transport);
|
|
55537
|
-
return this.doEvaluate(input, "visor/tool/invoke");
|
|
55538
|
-
}
|
|
55539
|
-
async evaluateCapabilities(checkId, capabilities) {
|
|
55540
|
-
if (!this.evaluator || !this.inputBuilder) return { allowed: true };
|
|
55541
|
-
const input = this.inputBuilder.forCapabilityResolve(checkId, capabilities);
|
|
55542
|
-
return this.doEvaluate(input, "visor/capability/resolve");
|
|
55543
|
-
}
|
|
55544
|
-
async shutdown() {
|
|
55545
|
-
if (this.evaluator && "shutdown" in this.evaluator) {
|
|
55546
|
-
await this.evaluator.shutdown();
|
|
55547
|
-
}
|
|
55548
|
-
this.evaluator = null;
|
|
55549
|
-
this.inputBuilder = null;
|
|
55550
|
-
}
|
|
55551
|
-
resolveRulePath(defaultScope, override) {
|
|
55552
|
-
if (override) {
|
|
55553
|
-
return override.startsWith("visor/") ? override : `visor/${override}`;
|
|
55554
|
-
}
|
|
55555
|
-
return `visor/${defaultScope.replace(/\./g, "/")}`;
|
|
55556
|
-
}
|
|
55557
|
-
async doEvaluate(input, rulePath) {
|
|
55558
|
-
try {
|
|
55559
|
-
this.logger?.debug(`[PolicyEngine] Evaluating ${rulePath}`, JSON.stringify(input));
|
|
55560
|
-
let timer;
|
|
55561
|
-
const timeoutPromise = new Promise((_resolve, reject) => {
|
|
55562
|
-
timer = setTimeout(() => reject(new Error("policy evaluation timeout")), this.timeout);
|
|
55563
|
-
});
|
|
55564
|
-
try {
|
|
55565
|
-
const result = await Promise.race([this.rawEvaluate(input, rulePath), timeoutPromise]);
|
|
55566
|
-
const decision = this.parseDecision(result);
|
|
55567
|
-
if (!decision.allowed && this.fallback === "warn") {
|
|
55568
|
-
decision.allowed = true;
|
|
55569
|
-
decision.warn = true;
|
|
55570
|
-
decision.reason = `audit: ${decision.reason || "policy denied"}`;
|
|
55571
|
-
}
|
|
55572
|
-
this.logger?.debug(
|
|
55573
|
-
`[PolicyEngine] Decision for ${rulePath}: allowed=${decision.allowed}, warn=${decision.warn || false}, reason=${decision.reason || "none"}`
|
|
55574
|
-
);
|
|
55575
|
-
return decision;
|
|
55576
|
-
} finally {
|
|
55577
|
-
if (timer) clearTimeout(timer);
|
|
55578
|
-
}
|
|
55579
|
-
} catch (err) {
|
|
55580
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
55581
|
-
this.logger?.warn(`[PolicyEngine] Evaluation failed for ${rulePath}: ${msg}`);
|
|
55582
|
-
return {
|
|
55583
|
-
allowed: this.fallback === "allow" || this.fallback === "warn",
|
|
55584
|
-
warn: this.fallback === "warn" ? true : void 0,
|
|
55585
|
-
reason: `policy evaluation failed, fallback=${this.fallback}`
|
|
55586
|
-
};
|
|
55587
|
-
}
|
|
55588
|
-
}
|
|
55589
|
-
async rawEvaluate(input, rulePath) {
|
|
55590
|
-
if (this.evaluator instanceof OpaWasmEvaluator) {
|
|
55591
|
-
const result = await this.evaluator.evaluate(input);
|
|
55592
|
-
return this.navigateWasmResult(result, rulePath);
|
|
55593
|
-
}
|
|
55594
|
-
return this.evaluator.evaluate(input, rulePath);
|
|
55595
|
-
}
|
|
55596
|
-
/**
|
|
55597
|
-
* Navigate nested OPA WASM result tree to reach the specific rule's output.
|
|
55598
|
-
* The WASM entrypoint `-e visor` means the result root IS the visor package,
|
|
55599
|
-
* so we strip the `visor/` prefix and walk the remaining segments.
|
|
55600
|
-
*/
|
|
55601
|
-
navigateWasmResult(result, rulePath) {
|
|
55602
|
-
if (!result || typeof result !== "object") return result;
|
|
55603
|
-
const segments = rulePath.replace(/^visor\//, "").split("/");
|
|
55604
|
-
let current = result;
|
|
55605
|
-
for (const seg of segments) {
|
|
55606
|
-
if (current && typeof current === "object" && seg in current) {
|
|
55607
|
-
current = current[seg];
|
|
55608
|
-
} else {
|
|
55609
|
-
return void 0;
|
|
55610
|
-
}
|
|
55611
|
-
}
|
|
55612
|
-
return current;
|
|
55613
|
-
}
|
|
55614
|
-
parseDecision(result) {
|
|
55615
|
-
if (result === void 0 || result === null) {
|
|
55616
|
-
return {
|
|
55617
|
-
allowed: this.fallback === "allow" || this.fallback === "warn",
|
|
55618
|
-
warn: this.fallback === "warn" ? true : void 0,
|
|
55619
|
-
reason: this.fallback === "warn" ? "audit: no policy result" : "no policy result"
|
|
55620
|
-
};
|
|
55621
|
-
}
|
|
55622
|
-
const allowed = result.allowed !== false;
|
|
55623
|
-
const decision = {
|
|
55624
|
-
allowed,
|
|
55625
|
-
reason: result.reason
|
|
55626
|
-
};
|
|
55627
|
-
if (result.capabilities) {
|
|
55628
|
-
decision.capabilities = result.capabilities;
|
|
55629
|
-
}
|
|
55630
|
-
return decision;
|
|
55631
|
-
}
|
|
55632
|
-
};
|
|
55633
|
-
}
|
|
55634
|
-
});
|
|
55635
|
-
|
|
55636
|
-
// src/enterprise/scheduler/knex-store.ts
|
|
55637
|
-
var knex_store_exports = {};
|
|
55638
|
-
__export(knex_store_exports, {
|
|
55639
|
-
KnexStoreBackend: () => KnexStoreBackend
|
|
55640
|
-
});
|
|
55641
|
-
function toNum(val) {
|
|
55642
|
-
if (val === null || val === void 0) return void 0;
|
|
55643
|
-
return typeof val === "string" ? parseInt(val, 10) : val;
|
|
55644
|
-
}
|
|
55645
|
-
function safeJsonParse2(value) {
|
|
55646
|
-
if (!value) return void 0;
|
|
55647
|
-
try {
|
|
55648
|
-
return JSON.parse(value);
|
|
55649
|
-
} catch {
|
|
55650
|
-
return void 0;
|
|
55651
|
-
}
|
|
55652
|
-
}
|
|
55653
|
-
function fromTriggerRow2(row) {
|
|
55654
|
-
return {
|
|
55655
|
-
id: row.id,
|
|
55656
|
-
creatorId: row.creator_id,
|
|
55657
|
-
creatorContext: row.creator_context ?? void 0,
|
|
55658
|
-
creatorName: row.creator_name ?? void 0,
|
|
55659
|
-
description: row.description ?? void 0,
|
|
55660
|
-
channels: safeJsonParse2(row.channels),
|
|
55661
|
-
fromUsers: safeJsonParse2(row.from_users),
|
|
55662
|
-
fromBots: row.from_bots === true || row.from_bots === 1,
|
|
55663
|
-
contains: safeJsonParse2(row.contains),
|
|
55664
|
-
matchPattern: row.match_pattern ?? void 0,
|
|
55665
|
-
threads: row.threads,
|
|
55666
|
-
workflow: row.workflow,
|
|
55667
|
-
inputs: safeJsonParse2(row.inputs),
|
|
55668
|
-
outputContext: safeJsonParse2(row.output_context),
|
|
55669
|
-
status: row.status,
|
|
55670
|
-
enabled: row.enabled === true || row.enabled === 1,
|
|
55671
|
-
createdAt: toNum(row.created_at)
|
|
55672
|
-
};
|
|
55673
|
-
}
|
|
55674
|
-
function toTriggerInsertRow(trigger) {
|
|
55675
|
-
return {
|
|
55676
|
-
id: trigger.id,
|
|
55677
|
-
creator_id: trigger.creatorId,
|
|
55678
|
-
creator_context: trigger.creatorContext ?? null,
|
|
55679
|
-
creator_name: trigger.creatorName ?? null,
|
|
55680
|
-
description: trigger.description ?? null,
|
|
55681
|
-
channels: trigger.channels ? JSON.stringify(trigger.channels) : null,
|
|
55682
|
-
from_users: trigger.fromUsers ? JSON.stringify(trigger.fromUsers) : null,
|
|
55683
|
-
from_bots: trigger.fromBots,
|
|
55684
|
-
contains: trigger.contains ? JSON.stringify(trigger.contains) : null,
|
|
55685
|
-
match_pattern: trigger.matchPattern ?? null,
|
|
55686
|
-
threads: trigger.threads,
|
|
55687
|
-
workflow: trigger.workflow,
|
|
55688
|
-
inputs: trigger.inputs ? JSON.stringify(trigger.inputs) : null,
|
|
55689
|
-
output_context: trigger.outputContext ? JSON.stringify(trigger.outputContext) : null,
|
|
55690
|
-
status: trigger.status,
|
|
55691
|
-
enabled: trigger.enabled,
|
|
55692
|
-
created_at: trigger.createdAt
|
|
55693
|
-
};
|
|
55694
|
-
}
|
|
55695
|
-
function fromDbRow2(row) {
|
|
55696
|
-
return {
|
|
55697
|
-
id: row.id,
|
|
55698
|
-
creatorId: row.creator_id,
|
|
55699
|
-
creatorContext: row.creator_context ?? void 0,
|
|
55700
|
-
creatorName: row.creator_name ?? void 0,
|
|
55701
|
-
timezone: row.timezone,
|
|
55702
|
-
schedule: row.schedule_expr,
|
|
55703
|
-
runAt: toNum(row.run_at),
|
|
55704
|
-
isRecurring: row.is_recurring === true || row.is_recurring === 1,
|
|
55705
|
-
originalExpression: row.original_expression,
|
|
55706
|
-
workflow: row.workflow ?? void 0,
|
|
55707
|
-
workflowInputs: safeJsonParse2(row.workflow_inputs),
|
|
55708
|
-
outputContext: safeJsonParse2(row.output_context),
|
|
55709
|
-
status: row.status,
|
|
55710
|
-
createdAt: toNum(row.created_at),
|
|
55711
|
-
lastRunAt: toNum(row.last_run_at),
|
|
55712
|
-
nextRunAt: toNum(row.next_run_at),
|
|
55713
|
-
runCount: row.run_count,
|
|
55714
|
-
failureCount: row.failure_count,
|
|
55715
|
-
lastError: row.last_error ?? void 0,
|
|
55716
|
-
previousResponse: row.previous_response ?? void 0
|
|
55717
|
-
};
|
|
55718
|
-
}
|
|
55719
|
-
function toInsertRow(schedule) {
|
|
55720
|
-
return {
|
|
55721
|
-
id: schedule.id,
|
|
55722
|
-
creator_id: schedule.creatorId,
|
|
55723
|
-
creator_context: schedule.creatorContext ?? null,
|
|
55724
|
-
creator_name: schedule.creatorName ?? null,
|
|
55725
|
-
timezone: schedule.timezone,
|
|
55726
|
-
schedule_expr: schedule.schedule,
|
|
55727
|
-
run_at: schedule.runAt ?? null,
|
|
55728
|
-
is_recurring: schedule.isRecurring,
|
|
55729
|
-
original_expression: schedule.originalExpression,
|
|
55730
|
-
workflow: schedule.workflow ?? null,
|
|
55731
|
-
workflow_inputs: schedule.workflowInputs ? JSON.stringify(schedule.workflowInputs) : null,
|
|
55732
|
-
output_context: schedule.outputContext ? JSON.stringify(schedule.outputContext) : null,
|
|
55733
|
-
status: schedule.status,
|
|
55734
|
-
created_at: schedule.createdAt,
|
|
55735
|
-
last_run_at: schedule.lastRunAt ?? null,
|
|
55736
|
-
next_run_at: schedule.nextRunAt ?? null,
|
|
55737
|
-
run_count: schedule.runCount,
|
|
55738
|
-
failure_count: schedule.failureCount,
|
|
55739
|
-
last_error: schedule.lastError ?? null,
|
|
55740
|
-
previous_response: schedule.previousResponse ?? null
|
|
55741
|
-
};
|
|
55742
|
-
}
|
|
55743
|
-
var fs24, path28, import_uuid2, KnexStoreBackend;
|
|
55744
|
-
var init_knex_store = __esm({
|
|
55745
|
-
"src/enterprise/scheduler/knex-store.ts"() {
|
|
55746
|
-
"use strict";
|
|
55747
|
-
fs24 = __toESM(require("fs"));
|
|
55748
|
-
path28 = __toESM(require("path"));
|
|
55749
|
-
import_uuid2 = require("uuid");
|
|
55750
|
-
init_logger();
|
|
55751
|
-
KnexStoreBackend = class {
|
|
55752
|
-
knex = null;
|
|
55753
|
-
driver;
|
|
55754
|
-
connection;
|
|
55755
|
-
constructor(driver, storageConfig, _haConfig) {
|
|
55756
|
-
this.driver = driver;
|
|
55757
|
-
this.connection = storageConfig.connection || {};
|
|
55758
|
-
}
|
|
55759
|
-
async initialize() {
|
|
55760
|
-
const { createRequire } = require("module");
|
|
55761
|
-
const runtimeRequire = createRequire(__filename);
|
|
55762
|
-
let knexFactory;
|
|
55763
|
-
try {
|
|
55764
|
-
knexFactory = runtimeRequire("knex");
|
|
55765
|
-
} catch (err) {
|
|
55766
|
-
const code = err?.code;
|
|
55767
|
-
if (code === "MODULE_NOT_FOUND" || code === "ERR_MODULE_NOT_FOUND") {
|
|
55768
|
-
throw new Error(
|
|
55769
|
-
"knex is required for PostgreSQL/MySQL/MSSQL schedule storage. Install it with: npm install knex"
|
|
55770
|
-
);
|
|
55771
|
-
}
|
|
55772
|
-
throw err;
|
|
55773
|
-
}
|
|
55774
|
-
const clientMap = {
|
|
55775
|
-
postgresql: "pg",
|
|
55776
|
-
mysql: "mysql2",
|
|
55777
|
-
mssql: "tedious"
|
|
55778
|
-
};
|
|
55779
|
-
const client = clientMap[this.driver];
|
|
55780
|
-
let connection;
|
|
55781
|
-
if (this.connection.connection_string) {
|
|
55782
|
-
connection = this.connection.connection_string;
|
|
55783
|
-
} else if (this.driver === "mssql") {
|
|
55784
|
-
connection = this.buildMssqlConnection();
|
|
55785
|
-
} else {
|
|
55786
|
-
connection = this.buildStandardConnection();
|
|
55787
|
-
}
|
|
55788
|
-
this.knex = knexFactory({
|
|
55789
|
-
client,
|
|
55790
|
-
connection,
|
|
55791
|
-
pool: {
|
|
55792
|
-
min: this.connection.pool?.min ?? 0,
|
|
55793
|
-
max: this.connection.pool?.max ?? 10
|
|
55794
|
-
}
|
|
55795
|
-
});
|
|
55796
|
-
await this.migrateSchema();
|
|
55797
|
-
logger.info(`[KnexStore] Initialized (${this.driver})`);
|
|
55798
|
-
}
|
|
55799
|
-
buildStandardConnection() {
|
|
55800
|
-
return {
|
|
55801
|
-
host: this.connection.host || "localhost",
|
|
55802
|
-
port: this.connection.port,
|
|
55803
|
-
database: this.connection.database || "visor",
|
|
55804
|
-
user: this.connection.user,
|
|
55805
|
-
password: this.connection.password,
|
|
55806
|
-
ssl: this.resolveSslConfig()
|
|
55807
|
-
};
|
|
55808
|
-
}
|
|
55809
|
-
buildMssqlConnection() {
|
|
55810
|
-
const ssl = this.connection.ssl;
|
|
55811
|
-
const sslEnabled = ssl === true || typeof ssl === "object" && ssl.enabled !== false;
|
|
55812
|
-
return {
|
|
55813
|
-
server: this.connection.host || "localhost",
|
|
55814
|
-
port: this.connection.port,
|
|
55815
|
-
database: this.connection.database || "visor",
|
|
55816
|
-
user: this.connection.user,
|
|
55817
|
-
password: this.connection.password,
|
|
55818
|
-
options: {
|
|
55819
|
-
encrypt: sslEnabled,
|
|
55820
|
-
trustServerCertificate: typeof ssl === "object" ? ssl.reject_unauthorized === false : !sslEnabled
|
|
55821
|
-
}
|
|
55822
|
-
};
|
|
55823
|
-
}
|
|
55824
|
-
resolveSslConfig() {
|
|
55825
|
-
const ssl = this.connection.ssl;
|
|
55826
|
-
if (ssl === false || ssl === void 0) return false;
|
|
55827
|
-
if (ssl === true) return { rejectUnauthorized: true };
|
|
55828
|
-
if (ssl.enabled === false) return false;
|
|
55829
|
-
const result = {
|
|
55830
|
-
rejectUnauthorized: ssl.reject_unauthorized !== false
|
|
55831
|
-
};
|
|
55832
|
-
if (ssl.ca) {
|
|
55833
|
-
const caPath = this.validateSslPath(ssl.ca, "CA certificate");
|
|
55834
|
-
result.ca = fs24.readFileSync(caPath, "utf8");
|
|
55835
|
-
}
|
|
55836
|
-
if (ssl.cert) {
|
|
55837
|
-
const certPath = this.validateSslPath(ssl.cert, "client certificate");
|
|
55838
|
-
result.cert = fs24.readFileSync(certPath, "utf8");
|
|
55839
|
-
}
|
|
55840
|
-
if (ssl.key) {
|
|
55841
|
-
const keyPath = this.validateSslPath(ssl.key, "client key");
|
|
55842
|
-
result.key = fs24.readFileSync(keyPath, "utf8");
|
|
55843
|
-
}
|
|
55844
|
-
return result;
|
|
55845
|
-
}
|
|
55846
|
-
validateSslPath(filePath, label) {
|
|
55847
|
-
const resolved = path28.resolve(filePath);
|
|
55848
|
-
if (resolved !== path28.normalize(resolved)) {
|
|
55849
|
-
throw new Error(`SSL ${label} path contains invalid sequences: ${filePath}`);
|
|
55850
|
-
}
|
|
55851
|
-
if (!fs24.existsSync(resolved)) {
|
|
55852
|
-
throw new Error(`SSL ${label} not found: ${filePath}`);
|
|
55853
|
-
}
|
|
55854
|
-
return resolved;
|
|
55855
|
-
}
|
|
55856
|
-
async shutdown() {
|
|
55857
|
-
if (this.knex) {
|
|
55858
|
-
await this.knex.destroy();
|
|
55859
|
-
this.knex = null;
|
|
55860
|
-
}
|
|
55861
|
-
}
|
|
55862
|
-
async migrateSchema() {
|
|
55863
|
-
const knex = this.getKnex();
|
|
55864
|
-
const exists = await knex.schema.hasTable("schedules");
|
|
55865
|
-
if (!exists) {
|
|
55866
|
-
await knex.schema.createTable("schedules", (table) => {
|
|
55867
|
-
table.string("id", 36).primary();
|
|
55868
|
-
table.string("creator_id", 255).notNullable().index();
|
|
55869
|
-
table.string("creator_context", 255);
|
|
55870
|
-
table.string("creator_name", 255);
|
|
55871
|
-
table.string("timezone", 64).notNullable().defaultTo("UTC");
|
|
55872
|
-
table.string("schedule_expr", 255);
|
|
55873
|
-
table.bigInteger("run_at");
|
|
55874
|
-
table.boolean("is_recurring").notNullable();
|
|
55875
|
-
table.text("original_expression");
|
|
55876
|
-
table.string("workflow", 255);
|
|
55877
|
-
table.text("workflow_inputs");
|
|
55878
|
-
table.text("output_context");
|
|
55879
|
-
table.string("status", 20).notNullable().index();
|
|
55880
|
-
table.bigInteger("created_at").notNullable();
|
|
55881
|
-
table.bigInteger("last_run_at");
|
|
55882
|
-
table.bigInteger("next_run_at");
|
|
55883
|
-
table.integer("run_count").notNullable().defaultTo(0);
|
|
55884
|
-
table.integer("failure_count").notNullable().defaultTo(0);
|
|
55885
|
-
table.text("last_error");
|
|
55886
|
-
table.text("previous_response");
|
|
55887
|
-
table.index(["status", "next_run_at"]);
|
|
55888
|
-
});
|
|
55889
|
-
}
|
|
55890
|
-
const triggersExist = await knex.schema.hasTable("message_triggers");
|
|
55891
|
-
if (!triggersExist) {
|
|
55892
|
-
await knex.schema.createTable("message_triggers", (table) => {
|
|
55893
|
-
table.string("id", 36).primary();
|
|
55894
|
-
table.string("creator_id", 255).notNullable().index();
|
|
55895
|
-
table.string("creator_context", 255);
|
|
55896
|
-
table.string("creator_name", 255);
|
|
55897
|
-
table.text("description");
|
|
55898
|
-
table.text("channels");
|
|
55899
|
-
table.text("from_users");
|
|
55900
|
-
table.boolean("from_bots").notNullable().defaultTo(false);
|
|
55901
|
-
table.text("contains");
|
|
55902
|
-
table.text("match_pattern");
|
|
55903
|
-
table.string("threads", 20).notNullable().defaultTo("any");
|
|
55904
|
-
table.string("workflow", 255).notNullable();
|
|
55905
|
-
table.text("inputs");
|
|
55906
|
-
table.text("output_context");
|
|
55907
|
-
table.string("status", 20).notNullable().defaultTo("active").index();
|
|
55908
|
-
table.boolean("enabled").notNullable().defaultTo(true);
|
|
55909
|
-
table.bigInteger("created_at").notNullable();
|
|
55910
|
-
});
|
|
55911
|
-
}
|
|
55912
|
-
const locksExist = await knex.schema.hasTable("scheduler_locks");
|
|
55913
|
-
if (!locksExist) {
|
|
55914
|
-
await knex.schema.createTable("scheduler_locks", (table) => {
|
|
55915
|
-
table.string("lock_id", 255).primary();
|
|
55916
|
-
table.string("node_id", 255).notNullable();
|
|
55917
|
-
table.string("lock_token", 36).notNullable();
|
|
55918
|
-
table.bigInteger("acquired_at").notNullable();
|
|
55919
|
-
table.bigInteger("expires_at").notNullable();
|
|
55920
|
-
});
|
|
55921
|
-
}
|
|
55922
|
-
}
|
|
55923
|
-
getKnex() {
|
|
55924
|
-
if (!this.knex) {
|
|
55925
|
-
throw new Error("[KnexStore] Not initialized. Call initialize() first.");
|
|
55926
|
-
}
|
|
55927
|
-
return this.knex;
|
|
55928
|
-
}
|
|
55929
|
-
// --- CRUD ---
|
|
55930
|
-
async create(schedule) {
|
|
55931
|
-
const knex = this.getKnex();
|
|
55932
|
-
const newSchedule = {
|
|
55933
|
-
...schedule,
|
|
55934
|
-
id: (0, import_uuid2.v4)(),
|
|
55935
|
-
createdAt: Date.now(),
|
|
55936
|
-
runCount: 0,
|
|
55937
|
-
failureCount: 0,
|
|
55938
|
-
status: "active"
|
|
55939
|
-
};
|
|
55940
|
-
await knex("schedules").insert(toInsertRow(newSchedule));
|
|
55941
|
-
logger.info(`[KnexStore] Created schedule ${newSchedule.id} for user ${newSchedule.creatorId}`);
|
|
55942
|
-
return newSchedule;
|
|
55943
|
-
}
|
|
55944
|
-
async importSchedule(schedule) {
|
|
55945
|
-
const knex = this.getKnex();
|
|
55946
|
-
const existing = await knex("schedules").where("id", schedule.id).first();
|
|
55947
|
-
if (existing) return;
|
|
55948
|
-
await knex("schedules").insert(toInsertRow(schedule));
|
|
55949
|
-
}
|
|
55950
|
-
async get(id) {
|
|
55951
|
-
const knex = this.getKnex();
|
|
55952
|
-
const row = await knex("schedules").where("id", id).first();
|
|
55953
|
-
return row ? fromDbRow2(row) : void 0;
|
|
55954
|
-
}
|
|
55955
|
-
async update(id, patch) {
|
|
55956
|
-
const knex = this.getKnex();
|
|
55957
|
-
const existing = await knex("schedules").where("id", id).first();
|
|
55958
|
-
if (!existing) return void 0;
|
|
55959
|
-
const current = fromDbRow2(existing);
|
|
55960
|
-
const updated = { ...current, ...patch, id: current.id };
|
|
55961
|
-
const row = toInsertRow(updated);
|
|
55962
|
-
delete row.id;
|
|
55963
|
-
await knex("schedules").where("id", id).update(row);
|
|
55964
|
-
return updated;
|
|
55965
|
-
}
|
|
55966
|
-
async delete(id) {
|
|
55967
|
-
const knex = this.getKnex();
|
|
55968
|
-
const deleted = await knex("schedules").where("id", id).del();
|
|
55969
|
-
if (deleted > 0) {
|
|
55970
|
-
logger.info(`[KnexStore] Deleted schedule ${id}`);
|
|
55971
|
-
return true;
|
|
55972
|
-
}
|
|
55973
|
-
return false;
|
|
55974
|
-
}
|
|
55975
|
-
// --- Queries ---
|
|
55976
|
-
async getByCreator(creatorId) {
|
|
55977
|
-
const knex = this.getKnex();
|
|
55978
|
-
const rows = await knex("schedules").where("creator_id", creatorId);
|
|
55979
|
-
return rows.map((r) => fromDbRow2(r));
|
|
55980
|
-
}
|
|
55981
|
-
async getActiveSchedules() {
|
|
55982
|
-
const knex = this.getKnex();
|
|
55983
|
-
const rows = await knex("schedules").where("status", "active");
|
|
55984
|
-
return rows.map((r) => fromDbRow2(r));
|
|
55985
|
-
}
|
|
55986
|
-
async getDueSchedules(now) {
|
|
55987
|
-
const ts = now ?? Date.now();
|
|
55988
|
-
const knex = this.getKnex();
|
|
55989
|
-
const bFalse = this.driver === "mssql" ? 0 : false;
|
|
55990
|
-
const bTrue = this.driver === "mssql" ? 1 : true;
|
|
55991
|
-
const rows = await knex("schedules").where("status", "active").andWhere(function() {
|
|
55992
|
-
this.where(function() {
|
|
55993
|
-
this.where("is_recurring", bFalse).whereNotNull("run_at").where("run_at", "<=", ts);
|
|
55994
|
-
}).orWhere(function() {
|
|
55995
|
-
this.where("is_recurring", bTrue).whereNotNull("next_run_at").where("next_run_at", "<=", ts);
|
|
55996
|
-
});
|
|
55997
|
-
});
|
|
55998
|
-
return rows.map((r) => fromDbRow2(r));
|
|
55999
|
-
}
|
|
56000
|
-
async findByWorkflow(creatorId, workflowName) {
|
|
56001
|
-
const knex = this.getKnex();
|
|
56002
|
-
const escaped = workflowName.toLowerCase().replace(/[%_\\]/g, "\\$&");
|
|
56003
|
-
const pattern = `%${escaped}%`;
|
|
56004
|
-
const rows = await knex("schedules").where("creator_id", creatorId).where("status", "active").whereRaw("LOWER(workflow) LIKE ? ESCAPE '\\'", [pattern]);
|
|
56005
|
-
return rows.map((r) => fromDbRow2(r));
|
|
56006
|
-
}
|
|
56007
|
-
async getAll() {
|
|
56008
|
-
const knex = this.getKnex();
|
|
56009
|
-
const rows = await knex("schedules");
|
|
56010
|
-
return rows.map((r) => fromDbRow2(r));
|
|
56011
|
-
}
|
|
56012
|
-
async getStats() {
|
|
56013
|
-
const knex = this.getKnex();
|
|
56014
|
-
const boolTrue = this.driver === "mssql" ? "1" : "true";
|
|
56015
|
-
const boolFalse = this.driver === "mssql" ? "0" : "false";
|
|
56016
|
-
const result = await knex("schedules").select(
|
|
56017
|
-
knex.raw("COUNT(*) as total"),
|
|
56018
|
-
knex.raw("SUM(CASE WHEN status = 'active' THEN 1 ELSE 0 END) as active"),
|
|
56019
|
-
knex.raw("SUM(CASE WHEN status = 'paused' THEN 1 ELSE 0 END) as paused"),
|
|
56020
|
-
knex.raw("SUM(CASE WHEN status = 'completed' THEN 1 ELSE 0 END) as completed"),
|
|
56021
|
-
knex.raw("SUM(CASE WHEN status = 'failed' THEN 1 ELSE 0 END) as failed"),
|
|
56022
|
-
knex.raw(`SUM(CASE WHEN is_recurring = ${boolTrue} THEN 1 ELSE 0 END) as recurring`),
|
|
56023
|
-
knex.raw(`SUM(CASE WHEN is_recurring = ${boolFalse} THEN 1 ELSE 0 END) as one_time`)
|
|
56024
|
-
).first();
|
|
56025
|
-
return {
|
|
56026
|
-
total: Number(result.total) || 0,
|
|
56027
|
-
active: Number(result.active) || 0,
|
|
56028
|
-
paused: Number(result.paused) || 0,
|
|
56029
|
-
completed: Number(result.completed) || 0,
|
|
56030
|
-
failed: Number(result.failed) || 0,
|
|
56031
|
-
recurring: Number(result.recurring) || 0,
|
|
56032
|
-
oneTime: Number(result.one_time) || 0
|
|
56033
|
-
};
|
|
56034
|
-
}
|
|
56035
|
-
async validateLimits(creatorId, isRecurring, limits) {
|
|
56036
|
-
const knex = this.getKnex();
|
|
56037
|
-
if (limits.maxGlobal) {
|
|
56038
|
-
const result = await knex("schedules").count("* as cnt").first();
|
|
56039
|
-
if (Number(result?.cnt) >= limits.maxGlobal) {
|
|
56040
|
-
throw new Error(`Global schedule limit reached (${limits.maxGlobal})`);
|
|
56041
|
-
}
|
|
56042
|
-
}
|
|
56043
|
-
if (limits.maxPerUser) {
|
|
56044
|
-
const result = await knex("schedules").where("creator_id", creatorId).count("* as cnt").first();
|
|
56045
|
-
if (Number(result?.cnt) >= limits.maxPerUser) {
|
|
56046
|
-
throw new Error(`You have reached the maximum number of schedules (${limits.maxPerUser})`);
|
|
56047
|
-
}
|
|
56048
|
-
}
|
|
56049
|
-
if (isRecurring && limits.maxRecurringPerUser) {
|
|
56050
|
-
const bTrue = this.driver === "mssql" ? 1 : true;
|
|
56051
|
-
const result = await knex("schedules").where("creator_id", creatorId).where("is_recurring", bTrue).count("* as cnt").first();
|
|
56052
|
-
if (Number(result?.cnt) >= limits.maxRecurringPerUser) {
|
|
56053
|
-
throw new Error(
|
|
56054
|
-
`You have reached the maximum number of recurring schedules (${limits.maxRecurringPerUser})`
|
|
56055
|
-
);
|
|
56056
|
-
}
|
|
56057
|
-
}
|
|
56058
|
-
}
|
|
56059
|
-
// --- HA Distributed Locking (via scheduler_locks table) ---
|
|
56060
|
-
async tryAcquireLock(lockId, nodeId, ttlSeconds) {
|
|
56061
|
-
const knex = this.getKnex();
|
|
56062
|
-
const now = Date.now();
|
|
56063
|
-
const expiresAt = now + ttlSeconds * 1e3;
|
|
56064
|
-
const token = (0, import_uuid2.v4)();
|
|
56065
|
-
const updated = await knex("scheduler_locks").where("lock_id", lockId).where("expires_at", "<", now).update({
|
|
56066
|
-
node_id: nodeId,
|
|
56067
|
-
lock_token: token,
|
|
56068
|
-
acquired_at: now,
|
|
56069
|
-
expires_at: expiresAt
|
|
56070
|
-
});
|
|
56071
|
-
if (updated > 0) return token;
|
|
56072
|
-
try {
|
|
56073
|
-
await knex("scheduler_locks").insert({
|
|
56074
|
-
lock_id: lockId,
|
|
56075
|
-
node_id: nodeId,
|
|
56076
|
-
lock_token: token,
|
|
56077
|
-
acquired_at: now,
|
|
56078
|
-
expires_at: expiresAt
|
|
56079
|
-
});
|
|
56080
|
-
return token;
|
|
56081
|
-
} catch {
|
|
56082
|
-
return null;
|
|
56083
|
-
}
|
|
56084
|
-
}
|
|
56085
|
-
async releaseLock(lockId, lockToken) {
|
|
56086
|
-
const knex = this.getKnex();
|
|
56087
|
-
await knex("scheduler_locks").where("lock_id", lockId).where("lock_token", lockToken).del();
|
|
56088
|
-
}
|
|
56089
|
-
async renewLock(lockId, lockToken, ttlSeconds) {
|
|
56090
|
-
const knex = this.getKnex();
|
|
56091
|
-
const now = Date.now();
|
|
56092
|
-
const expiresAt = now + ttlSeconds * 1e3;
|
|
56093
|
-
const updated = await knex("scheduler_locks").where("lock_id", lockId).where("lock_token", lockToken).update({ acquired_at: now, expires_at: expiresAt });
|
|
56094
|
-
return updated > 0;
|
|
56095
|
-
}
|
|
56096
|
-
async flush() {
|
|
56097
|
-
}
|
|
56098
|
-
// --- Message Trigger CRUD ---
|
|
56099
|
-
async createTrigger(trigger) {
|
|
56100
|
-
const knex = this.getKnex();
|
|
56101
|
-
const newTrigger = {
|
|
56102
|
-
...trigger,
|
|
56103
|
-
id: (0, import_uuid2.v4)(),
|
|
56104
|
-
createdAt: Date.now()
|
|
56105
|
-
};
|
|
56106
|
-
await knex("message_triggers").insert(toTriggerInsertRow(newTrigger));
|
|
56107
|
-
logger.info(`[KnexStore] Created trigger ${newTrigger.id} for user ${newTrigger.creatorId}`);
|
|
56108
|
-
return newTrigger;
|
|
56109
|
-
}
|
|
56110
|
-
async getTrigger(id) {
|
|
56111
|
-
const knex = this.getKnex();
|
|
56112
|
-
const row = await knex("message_triggers").where("id", id).first();
|
|
56113
|
-
return row ? fromTriggerRow2(row) : void 0;
|
|
56114
|
-
}
|
|
56115
|
-
async updateTrigger(id, patch) {
|
|
56116
|
-
const knex = this.getKnex();
|
|
56117
|
-
const existing = await knex("message_triggers").where("id", id).first();
|
|
56118
|
-
if (!existing) return void 0;
|
|
56119
|
-
const current = fromTriggerRow2(existing);
|
|
56120
|
-
const updated = {
|
|
56121
|
-
...current,
|
|
56122
|
-
...patch,
|
|
56123
|
-
id: current.id,
|
|
56124
|
-
createdAt: current.createdAt
|
|
56125
|
-
};
|
|
56126
|
-
const row = toTriggerInsertRow(updated);
|
|
56127
|
-
delete row.id;
|
|
56128
|
-
await knex("message_triggers").where("id", id).update(row);
|
|
56129
|
-
return updated;
|
|
56130
|
-
}
|
|
56131
|
-
async deleteTrigger(id) {
|
|
56132
|
-
const knex = this.getKnex();
|
|
56133
|
-
const deleted = await knex("message_triggers").where("id", id).del();
|
|
56134
|
-
if (deleted > 0) {
|
|
56135
|
-
logger.info(`[KnexStore] Deleted trigger ${id}`);
|
|
56136
|
-
return true;
|
|
56137
|
-
}
|
|
56138
|
-
return false;
|
|
56139
|
-
}
|
|
56140
|
-
async getTriggersByCreator(creatorId) {
|
|
56141
|
-
const knex = this.getKnex();
|
|
56142
|
-
const rows = await knex("message_triggers").where("creator_id", creatorId);
|
|
56143
|
-
return rows.map((r) => fromTriggerRow2(r));
|
|
56144
|
-
}
|
|
56145
|
-
async getActiveTriggers() {
|
|
56146
|
-
const knex = this.getKnex();
|
|
56147
|
-
const rows = await knex("message_triggers").where("status", "active").where("enabled", this.driver === "mssql" ? 1 : true);
|
|
56148
|
-
return rows.map((r) => fromTriggerRow2(r));
|
|
56149
|
-
}
|
|
56150
|
-
};
|
|
56151
|
-
}
|
|
56152
|
-
});
|
|
56153
|
-
|
|
56154
|
-
// src/enterprise/loader.ts
|
|
56155
|
-
var loader_exports = {};
|
|
56156
|
-
__export(loader_exports, {
|
|
56157
|
-
loadEnterprisePolicyEngine: () => loadEnterprisePolicyEngine,
|
|
56158
|
-
loadEnterpriseStoreBackend: () => loadEnterpriseStoreBackend
|
|
56159
|
-
});
|
|
56160
|
-
async function loadEnterprisePolicyEngine(config) {
|
|
56161
|
-
try {
|
|
56162
|
-
const { LicenseValidator: LicenseValidator2 } = await Promise.resolve().then(() => (init_validator(), validator_exports));
|
|
56163
|
-
const validator = new LicenseValidator2();
|
|
56164
|
-
const license = await validator.loadAndValidate();
|
|
56165
|
-
if (!license || !validator.hasFeature("policy")) {
|
|
56166
|
-
return new DefaultPolicyEngine();
|
|
56167
|
-
}
|
|
56168
|
-
if (validator.isInGracePeriod()) {
|
|
56169
|
-
console.warn(
|
|
56170
|
-
"[visor:enterprise] License has expired but is within the 72-hour grace period. Please renew your license."
|
|
56171
|
-
);
|
|
56172
|
-
}
|
|
56173
|
-
const { OpaPolicyEngine: OpaPolicyEngine2 } = await Promise.resolve().then(() => (init_opa_policy_engine(), opa_policy_engine_exports));
|
|
56174
|
-
const engine = new OpaPolicyEngine2(config);
|
|
56175
|
-
await engine.initialize(config);
|
|
56176
|
-
return engine;
|
|
56177
|
-
} catch (err) {
|
|
56178
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
56179
|
-
try {
|
|
56180
|
-
const { logger: logger2 } = (init_logger(), __toCommonJS(logger_exports));
|
|
56181
|
-
logger2.warn(`[PolicyEngine] Enterprise policy init failed, falling back to default: ${msg}`);
|
|
56182
|
-
} catch {
|
|
56183
|
-
}
|
|
56184
|
-
return new DefaultPolicyEngine();
|
|
56185
|
-
}
|
|
56186
|
-
}
|
|
56187
|
-
async function loadEnterpriseStoreBackend(driver, storageConfig, haConfig) {
|
|
56188
|
-
const { LicenseValidator: LicenseValidator2 } = await Promise.resolve().then(() => (init_validator(), validator_exports));
|
|
56189
|
-
const validator = new LicenseValidator2();
|
|
56190
|
-
const license = await validator.loadAndValidate();
|
|
56191
|
-
if (!license || !validator.hasFeature("scheduler-sql")) {
|
|
56192
|
-
throw new Error(
|
|
56193
|
-
`The ${driver} schedule storage driver requires a Visor Enterprise license with the 'scheduler-sql' feature. Please upgrade or use driver: 'sqlite' (default).`
|
|
56194
|
-
);
|
|
56195
|
-
}
|
|
56196
|
-
if (validator.isInGracePeriod()) {
|
|
56197
|
-
console.warn(
|
|
56198
|
-
"[visor:enterprise] License has expired but is within the 72-hour grace period. Please renew your license."
|
|
56199
|
-
);
|
|
56200
|
-
}
|
|
56201
|
-
const { KnexStoreBackend: KnexStoreBackend2 } = await Promise.resolve().then(() => (init_knex_store(), knex_store_exports));
|
|
56202
|
-
return new KnexStoreBackend2(driver, storageConfig, haConfig);
|
|
56203
|
-
}
|
|
56204
|
-
var init_loader = __esm({
|
|
56205
|
-
"src/enterprise/loader.ts"() {
|
|
56206
|
-
"use strict";
|
|
56207
|
-
init_default_engine();
|
|
56208
|
-
}
|
|
56209
|
-
});
|
|
56210
|
-
|
|
56211
54837
|
// src/event-bus/event-bus.ts
|
|
56212
54838
|
var event_bus_exports = {};
|
|
56213
54839
|
__export(event_bus_exports, {
|
|
@@ -57114,8 +55740,8 @@ ${content}
|
|
|
57114
55740
|
* Sleep utility
|
|
57115
55741
|
*/
|
|
57116
55742
|
sleep(ms) {
|
|
57117
|
-
return new Promise((
|
|
57118
|
-
const t = setTimeout(
|
|
55743
|
+
return new Promise((resolve15) => {
|
|
55744
|
+
const t = setTimeout(resolve15, ms);
|
|
57119
55745
|
if (typeof t.unref === "function") {
|
|
57120
55746
|
try {
|
|
57121
55747
|
t.unref();
|
|
@@ -57400,8 +56026,8 @@ ${end}`);
|
|
|
57400
56026
|
async updateGroupedComment(ctx, comments, group, changedIds) {
|
|
57401
56027
|
const existingLock = this.updateLocks.get(group);
|
|
57402
56028
|
let resolveLock;
|
|
57403
|
-
const ourLock = new Promise((
|
|
57404
|
-
resolveLock =
|
|
56029
|
+
const ourLock = new Promise((resolve15) => {
|
|
56030
|
+
resolveLock = resolve15;
|
|
57405
56031
|
});
|
|
57406
56032
|
this.updateLocks.set(group, ourLock);
|
|
57407
56033
|
try {
|
|
@@ -57714,7 +56340,7 @@ ${blocks}
|
|
|
57714
56340
|
* Sleep utility for enforcing delays
|
|
57715
56341
|
*/
|
|
57716
56342
|
sleep(ms) {
|
|
57717
|
-
return new Promise((
|
|
56343
|
+
return new Promise((resolve15) => setTimeout(resolve15, ms));
|
|
57718
56344
|
}
|
|
57719
56345
|
};
|
|
57720
56346
|
}
|
|
@@ -59006,15 +57632,15 @@ function serializeRunState(state) {
|
|
|
59006
57632
|
])
|
|
59007
57633
|
};
|
|
59008
57634
|
}
|
|
59009
|
-
var
|
|
57635
|
+
var path26, fs22, StateMachineExecutionEngine;
|
|
59010
57636
|
var init_state_machine_execution_engine = __esm({
|
|
59011
57637
|
"src/state-machine-execution-engine.ts"() {
|
|
59012
57638
|
"use strict";
|
|
59013
57639
|
init_runner();
|
|
59014
57640
|
init_logger();
|
|
59015
57641
|
init_sandbox_manager();
|
|
59016
|
-
|
|
59017
|
-
|
|
57642
|
+
path26 = __toESM(require("path"));
|
|
57643
|
+
fs22 = __toESM(require("fs"));
|
|
59018
57644
|
StateMachineExecutionEngine = class _StateMachineExecutionEngine {
|
|
59019
57645
|
workingDirectory;
|
|
59020
57646
|
executionContext;
|
|
@@ -59246,8 +57872,8 @@ var init_state_machine_execution_engine = __esm({
|
|
|
59246
57872
|
logger.debug(
|
|
59247
57873
|
`[PolicyEngine] Loading enterprise policy engine (engine=${configWithTagFilter.policy.engine})`
|
|
59248
57874
|
);
|
|
59249
|
-
const { loadEnterprisePolicyEngine
|
|
59250
|
-
context2.policyEngine = await
|
|
57875
|
+
const { loadEnterprisePolicyEngine } = await import("./enterprise/loader");
|
|
57876
|
+
context2.policyEngine = await loadEnterprisePolicyEngine(configWithTagFilter.policy);
|
|
59251
57877
|
logger.debug(
|
|
59252
57878
|
`[PolicyEngine] Initialized: ${context2.policyEngine?.constructor?.name || "unknown"}`
|
|
59253
57879
|
);
|
|
@@ -59399,9 +58025,9 @@ var init_state_machine_execution_engine = __esm({
|
|
|
59399
58025
|
}
|
|
59400
58026
|
const checkId = String(ev?.checkId || "unknown");
|
|
59401
58027
|
const threadKey = ev?.threadKey || (channel && threadTs ? `${channel}:${threadTs}` : "session");
|
|
59402
|
-
const baseDir = process.env.VISOR_SNAPSHOT_DIR ||
|
|
59403
|
-
|
|
59404
|
-
const filePath =
|
|
58028
|
+
const baseDir = process.env.VISOR_SNAPSHOT_DIR || path26.resolve(process.cwd(), ".visor", "snapshots");
|
|
58029
|
+
fs22.mkdirSync(baseDir, { recursive: true });
|
|
58030
|
+
const filePath = path26.join(baseDir, `${threadKey}-${checkId}.json`);
|
|
59405
58031
|
await this.saveSnapshotToFile(filePath);
|
|
59406
58032
|
logger.info(`[Snapshot] Saved run snapshot: ${filePath}`);
|
|
59407
58033
|
try {
|
|
@@ -59542,7 +58168,7 @@ var init_state_machine_execution_engine = __esm({
|
|
|
59542
58168
|
* Does not include secrets. Intended for debugging and future resume support.
|
|
59543
58169
|
*/
|
|
59544
58170
|
async saveSnapshotToFile(filePath) {
|
|
59545
|
-
const
|
|
58171
|
+
const fs23 = await import("fs/promises");
|
|
59546
58172
|
const ctx = this._lastContext;
|
|
59547
58173
|
const runner = this._lastRunner;
|
|
59548
58174
|
if (!ctx || !runner) {
|
|
@@ -59562,14 +58188,14 @@ var init_state_machine_execution_engine = __esm({
|
|
|
59562
58188
|
journal: entries,
|
|
59563
58189
|
requestedChecks: ctx.requestedChecks || []
|
|
59564
58190
|
};
|
|
59565
|
-
await
|
|
58191
|
+
await fs23.writeFile(filePath, JSON.stringify(payload, null, 2), "utf8");
|
|
59566
58192
|
}
|
|
59567
58193
|
/**
|
|
59568
58194
|
* Load a snapshot JSON from file and return it. Resume support can build on this.
|
|
59569
58195
|
*/
|
|
59570
58196
|
async loadSnapshotFromFile(filePath) {
|
|
59571
|
-
const
|
|
59572
|
-
const raw = await
|
|
58197
|
+
const fs23 = await import("fs/promises");
|
|
58198
|
+
const raw = await fs23.readFile(filePath, "utf8");
|
|
59573
58199
|
return JSON.parse(raw);
|
|
59574
58200
|
}
|
|
59575
58201
|
/**
|