@probelabs/visor 0.1.159-ee → 0.1.159
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-05T15-45-37-714Z.ndjson +138 -0
- package/dist/output/traces/run-2026-03-05T15-46-23-118Z.ndjson +2197 -0
- package/dist/sdk/check-provider-registry-74VLAETF.mjs +29 -0
- package/dist/sdk/{check-provider-registry-A32RRIIF.mjs → check-provider-registry-UVLGKORU.mjs} +2 -2
- package/dist/sdk/chunk-5N33URMM.mjs +1502 -0
- package/dist/sdk/chunk-5N33URMM.mjs.map +1 -0
- package/dist/sdk/{chunk-RHAKGIBI.mjs → chunk-AW3IHBCI.mjs} +9 -9
- package/dist/sdk/{chunk-RHAKGIBI.mjs.map → chunk-AW3IHBCI.mjs.map} +1 -1
- package/dist/sdk/chunk-IVTSD7ZW.mjs +43780 -0
- package/dist/sdk/chunk-IVTSD7ZW.mjs.map +1 -0
- package/dist/sdk/chunk-PSZI5NZL.mjs +739 -0
- package/dist/sdk/chunk-PSZI5NZL.mjs.map +1 -0
- package/dist/sdk/chunk-PZONH3RK.mjs +443 -0
- package/dist/sdk/chunk-PZONH3RK.mjs.map +1 -0
- package/dist/sdk/failure-condition-evaluator-LQ5NUFZN.mjs +17 -0
- package/dist/sdk/github-frontend-YSRVB5FS.mjs +1368 -0
- package/dist/sdk/github-frontend-YSRVB5FS.mjs.map +1 -0
- package/dist/sdk/{host-KO3WVPVP.mjs → host-YG6LPL6H.mjs} +2 -2
- package/dist/sdk/routing-ZJSROSUU.mjs +25 -0
- package/dist/sdk/schedule-tool-2GSWLIWA.mjs +35 -0
- package/dist/sdk/schedule-tool-2GSWLIWA.mjs.map +1 -0
- package/dist/sdk/{schedule-tool-RF3GRKMG.mjs → schedule-tool-QCJWLYS3.mjs} +2 -2
- package/dist/sdk/schedule-tool-QCJWLYS3.mjs.map +1 -0
- package/dist/sdk/{schedule-tool-handler-JRSULLPY.mjs → schedule-tool-handler-HWHHAHJD.mjs} +2 -2
- package/dist/sdk/schedule-tool-handler-HWHHAHJD.mjs.map +1 -0
- package/dist/sdk/schedule-tool-handler-K2LO33KU.mjs +39 -0
- package/dist/sdk/schedule-tool-handler-K2LO33KU.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-23KC3NGK.mjs +25 -0
- package/dist/sdk/trace-helpers-23KC3NGK.mjs.map +1 -0
- package/dist/sdk/{workflow-check-provider-LWJTZ5AI.mjs → workflow-check-provider-DHNWJKYK.mjs} +2 -2
- package/dist/sdk/workflow-check-provider-DHNWJKYK.mjs.map +1 -0
- package/dist/sdk/workflow-check-provider-OUREVWAI.mjs +29 -0
- package/dist/sdk/workflow-check-provider-OUREVWAI.mjs.map +1 -0
- package/dist/traces/run-2026-03-05T15-45-37-714Z.ndjson +138 -0
- package/dist/traces/run-2026-03-05T15-46-23-118Z.ndjson +2197 -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-A32RRIIF.mjs.map → check-provider-registry-74VLAETF.mjs.map} +0 -0
- /package/dist/sdk/{schedule-tool-RF3GRKMG.mjs.map → check-provider-registry-UVLGKORU.mjs.map} +0 -0
- /package/dist/sdk/{schedule-tool-handler-JRSULLPY.mjs.map → failure-condition-evaluator-LQ5NUFZN.mjs.map} +0 -0
- /package/dist/sdk/{host-KO3WVPVP.mjs.map → host-YG6LPL6H.mjs.map} +0 -0
- /package/dist/sdk/{workflow-check-provider-LWJTZ5AI.mjs.map → routing-ZJSROSUU.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.159",
|
|
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
|
);
|
|
@@ -8640,9 +8640,9 @@ ${schemaString}`);
|
|
|
8640
8640
|
const model = this.config.model || "default";
|
|
8641
8641
|
if (process.env.VISOR_DEBUG_AI_SESSIONS === "true") {
|
|
8642
8642
|
try {
|
|
8643
|
-
const
|
|
8644
|
-
const
|
|
8645
|
-
const
|
|
8643
|
+
const fs23 = require("fs");
|
|
8644
|
+
const path27 = require("path");
|
|
8645
|
+
const os2 = require("os");
|
|
8646
8646
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
8647
8647
|
const debugData = {
|
|
8648
8648
|
timestamp,
|
|
@@ -8714,19 +8714,19 @@ ${"=".repeat(60)}
|
|
|
8714
8714
|
`;
|
|
8715
8715
|
readableVersion += `${"=".repeat(60)}
|
|
8716
8716
|
`;
|
|
8717
|
-
const tempDir =
|
|
8718
|
-
const promptFile =
|
|
8719
|
-
|
|
8717
|
+
const tempDir = os2.tmpdir();
|
|
8718
|
+
const promptFile = path27.join(tempDir, `visor-prompt-${timestamp}.txt`);
|
|
8719
|
+
fs23.writeFileSync(promptFile, prompt, "utf-8");
|
|
8720
8720
|
log(`
|
|
8721
8721
|
\u{1F4BE} Prompt saved to: ${promptFile}`);
|
|
8722
|
-
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS ||
|
|
8722
|
+
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path27.join(process.cwd(), "debug-artifacts");
|
|
8723
8723
|
try {
|
|
8724
|
-
const base =
|
|
8724
|
+
const base = path27.join(
|
|
8725
8725
|
debugArtifactsDir,
|
|
8726
8726
|
`prompt-${_checkName || "unknown"}-${timestamp}`
|
|
8727
8727
|
);
|
|
8728
|
-
|
|
8729
|
-
|
|
8728
|
+
fs23.writeFileSync(base + ".json", debugJson, "utf-8");
|
|
8729
|
+
fs23.writeFileSync(base + ".summary.txt", readableVersion, "utf-8");
|
|
8730
8730
|
log(`
|
|
8731
8731
|
\u{1F4BE} Full debug info saved to directory: ${debugArtifactsDir}`);
|
|
8732
8732
|
} catch {
|
|
@@ -8771,8 +8771,8 @@ $ ${cliCommand}
|
|
|
8771
8771
|
log(`\u{1F4E4} Response length: ${response.length} characters`);
|
|
8772
8772
|
if (process.env.VISOR_DEBUG_AI_SESSIONS === "true") {
|
|
8773
8773
|
try {
|
|
8774
|
-
const
|
|
8775
|
-
const
|
|
8774
|
+
const fs23 = require("fs");
|
|
8775
|
+
const path27 = require("path");
|
|
8776
8776
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
8777
8777
|
const agentAny = agent;
|
|
8778
8778
|
let fullHistory = [];
|
|
@@ -8783,8 +8783,8 @@ $ ${cliCommand}
|
|
|
8783
8783
|
} else if (agentAny._messages) {
|
|
8784
8784
|
fullHistory = agentAny._messages;
|
|
8785
8785
|
}
|
|
8786
|
-
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS ||
|
|
8787
|
-
const sessionBase =
|
|
8786
|
+
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path27.join(process.cwd(), "debug-artifacts");
|
|
8787
|
+
const sessionBase = path27.join(
|
|
8788
8788
|
debugArtifactsDir,
|
|
8789
8789
|
`session-${_checkName || "unknown"}-${timestamp}`
|
|
8790
8790
|
);
|
|
@@ -8796,7 +8796,7 @@ $ ${cliCommand}
|
|
|
8796
8796
|
schema: effectiveSchema,
|
|
8797
8797
|
totalMessages: fullHistory.length
|
|
8798
8798
|
};
|
|
8799
|
-
|
|
8799
|
+
fs23.writeFileSync(sessionBase + ".json", JSON.stringify(sessionData, null, 2), "utf-8");
|
|
8800
8800
|
let readable = `=============================================================
|
|
8801
8801
|
`;
|
|
8802
8802
|
readable += `COMPLETE AI SESSION HISTORY (AFTER RESPONSE)
|
|
@@ -8823,7 +8823,7 @@ ${"=".repeat(60)}
|
|
|
8823
8823
|
`;
|
|
8824
8824
|
readable += content + "\n";
|
|
8825
8825
|
});
|
|
8826
|
-
|
|
8826
|
+
fs23.writeFileSync(sessionBase + ".summary.txt", readable, "utf-8");
|
|
8827
8827
|
log(`\u{1F4BE} Complete session history saved:`);
|
|
8828
8828
|
log(` - Contains ALL ${fullHistory.length} messages (prompts + responses)`);
|
|
8829
8829
|
} catch (error) {
|
|
@@ -8832,11 +8832,11 @@ ${"=".repeat(60)}
|
|
|
8832
8832
|
}
|
|
8833
8833
|
if (process.env.VISOR_DEBUG_AI_SESSIONS === "true") {
|
|
8834
8834
|
try {
|
|
8835
|
-
const
|
|
8836
|
-
const
|
|
8835
|
+
const fs23 = require("fs");
|
|
8836
|
+
const path27 = require("path");
|
|
8837
8837
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
8838
|
-
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS ||
|
|
8839
|
-
const responseFile =
|
|
8838
|
+
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path27.join(process.cwd(), "debug-artifacts");
|
|
8839
|
+
const responseFile = path27.join(
|
|
8840
8840
|
debugArtifactsDir,
|
|
8841
8841
|
`response-${_checkName || "unknown"}-${timestamp}.txt`
|
|
8842
8842
|
);
|
|
@@ -8869,7 +8869,7 @@ ${"=".repeat(60)}
|
|
|
8869
8869
|
`;
|
|
8870
8870
|
responseContent += `${"=".repeat(60)}
|
|
8871
8871
|
`;
|
|
8872
|
-
|
|
8872
|
+
fs23.writeFileSync(responseFile, responseContent, "utf-8");
|
|
8873
8873
|
log(`\u{1F4BE} Response saved to: ${responseFile}`);
|
|
8874
8874
|
} catch (error) {
|
|
8875
8875
|
log(`\u26A0\uFE0F Could not save response file: ${error}`);
|
|
@@ -8887,9 +8887,9 @@ ${"=".repeat(60)}
|
|
|
8887
8887
|
await telemetry.shutdown();
|
|
8888
8888
|
log(`\u{1F4CA} OpenTelemetry trace saved to: ${traceFilePath}`);
|
|
8889
8889
|
if (process.env.GITHUB_ACTIONS) {
|
|
8890
|
-
const
|
|
8891
|
-
if (
|
|
8892
|
-
const stats =
|
|
8890
|
+
const fs23 = require("fs");
|
|
8891
|
+
if (fs23.existsSync(traceFilePath)) {
|
|
8892
|
+
const stats = fs23.statSync(traceFilePath);
|
|
8893
8893
|
console.log(
|
|
8894
8894
|
`::notice title=AI Trace Saved::OpenTelemetry trace file size: ${stats.size} bytes`
|
|
8895
8895
|
);
|
|
@@ -8927,8 +8927,8 @@ ${"=".repeat(60)}
|
|
|
8927
8927
|
* Load schema content from schema files or inline definitions
|
|
8928
8928
|
*/
|
|
8929
8929
|
async loadSchemaContent(schema) {
|
|
8930
|
-
const
|
|
8931
|
-
const
|
|
8930
|
+
const fs23 = require("fs").promises;
|
|
8931
|
+
const path27 = require("path");
|
|
8932
8932
|
if (typeof schema === "object" && schema !== null) {
|
|
8933
8933
|
log("\u{1F4CB} Using inline schema object from configuration");
|
|
8934
8934
|
return JSON.stringify(schema);
|
|
@@ -8941,14 +8941,14 @@ ${"=".repeat(60)}
|
|
|
8941
8941
|
}
|
|
8942
8942
|
} catch {
|
|
8943
8943
|
}
|
|
8944
|
-
if ((schema.startsWith("./") || schema.includes(".json")) && !
|
|
8944
|
+
if ((schema.startsWith("./") || schema.includes(".json")) && !path27.isAbsolute(schema)) {
|
|
8945
8945
|
if (schema.includes("..") || schema.includes("\0")) {
|
|
8946
8946
|
throw new Error("Invalid schema path: path traversal not allowed");
|
|
8947
8947
|
}
|
|
8948
8948
|
try {
|
|
8949
|
-
const schemaPath =
|
|
8949
|
+
const schemaPath = path27.resolve(process.cwd(), schema);
|
|
8950
8950
|
log(`\u{1F4CB} Loading custom schema from file: ${schemaPath}`);
|
|
8951
|
-
const schemaContent = await
|
|
8951
|
+
const schemaContent = await fs23.readFile(schemaPath, "utf-8");
|
|
8952
8952
|
return schemaContent.trim();
|
|
8953
8953
|
} catch (error) {
|
|
8954
8954
|
throw new Error(
|
|
@@ -8962,22 +8962,22 @@ ${"=".repeat(60)}
|
|
|
8962
8962
|
}
|
|
8963
8963
|
const candidatePaths = [
|
|
8964
8964
|
// GitHub Action bundle location
|
|
8965
|
-
|
|
8965
|
+
path27.join(__dirname, "output", sanitizedSchemaName, "schema.json"),
|
|
8966
8966
|
// Historical fallback when src/output was inadvertently bundled as output1/
|
|
8967
|
-
|
|
8967
|
+
path27.join(__dirname, "output1", sanitizedSchemaName, "schema.json"),
|
|
8968
8968
|
// Local dev (repo root)
|
|
8969
|
-
|
|
8969
|
+
path27.join(process.cwd(), "output", sanitizedSchemaName, "schema.json")
|
|
8970
8970
|
];
|
|
8971
8971
|
for (const schemaPath of candidatePaths) {
|
|
8972
8972
|
try {
|
|
8973
|
-
const schemaContent = await
|
|
8973
|
+
const schemaContent = await fs23.readFile(schemaPath, "utf-8");
|
|
8974
8974
|
return schemaContent.trim();
|
|
8975
8975
|
} catch {
|
|
8976
8976
|
}
|
|
8977
8977
|
}
|
|
8978
|
-
const distPath =
|
|
8979
|
-
const distAltPath =
|
|
8980
|
-
const cwdPath =
|
|
8978
|
+
const distPath = path27.join(__dirname, "output", sanitizedSchemaName, "schema.json");
|
|
8979
|
+
const distAltPath = path27.join(__dirname, "output1", sanitizedSchemaName, "schema.json");
|
|
8980
|
+
const cwdPath = path27.join(process.cwd(), "output", sanitizedSchemaName, "schema.json");
|
|
8981
8981
|
throw new Error(
|
|
8982
8982
|
`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.`
|
|
8983
8983
|
);
|
|
@@ -9222,7 +9222,7 @@ ${"=".repeat(60)}
|
|
|
9222
9222
|
* Generate mock response for testing
|
|
9223
9223
|
*/
|
|
9224
9224
|
async generateMockResponse(_prompt, _checkName, _schema) {
|
|
9225
|
-
await new Promise((
|
|
9225
|
+
await new Promise((resolve15) => setTimeout(resolve15, 500));
|
|
9226
9226
|
const name = (_checkName || "").toLowerCase();
|
|
9227
9227
|
if (name.includes("extract-facts")) {
|
|
9228
9228
|
const arr = Array.from({ length: 6 }, (_, i) => ({
|
|
@@ -9583,7 +9583,7 @@ var init_command_executor = __esm({
|
|
|
9583
9583
|
* Execute command with stdin input
|
|
9584
9584
|
*/
|
|
9585
9585
|
executeWithStdin(command, options) {
|
|
9586
|
-
return new Promise((
|
|
9586
|
+
return new Promise((resolve15, reject) => {
|
|
9587
9587
|
const childProcess = (0, import_child_process2.exec)(
|
|
9588
9588
|
command,
|
|
9589
9589
|
{
|
|
@@ -9595,7 +9595,7 @@ var init_command_executor = __esm({
|
|
|
9595
9595
|
if (error && error.killed && (error.code === "ETIMEDOUT" || error.signal === "SIGTERM")) {
|
|
9596
9596
|
reject(new Error(`Command timed out after ${options.timeout || 3e4}ms`));
|
|
9597
9597
|
} else {
|
|
9598
|
-
|
|
9598
|
+
resolve15({
|
|
9599
9599
|
stdout: stdout || "",
|
|
9600
9600
|
stderr: stderr || "",
|
|
9601
9601
|
exitCode: error ? error.code || 1 : 0
|
|
@@ -17601,17 +17601,17 @@ var init_workflow_check_provider = __esm({
|
|
|
17601
17601
|
* so it can be executed by the state machine as a nested workflow.
|
|
17602
17602
|
*/
|
|
17603
17603
|
async loadWorkflowFromConfigPath(sourcePath, baseDir) {
|
|
17604
|
-
const
|
|
17605
|
-
const
|
|
17604
|
+
const path27 = require("path");
|
|
17605
|
+
const fs23 = require("fs");
|
|
17606
17606
|
const yaml5 = require("js-yaml");
|
|
17607
|
-
const resolved =
|
|
17608
|
-
if (!
|
|
17607
|
+
const resolved = path27.isAbsolute(sourcePath) ? sourcePath : path27.resolve(baseDir, sourcePath);
|
|
17608
|
+
if (!fs23.existsSync(resolved)) {
|
|
17609
17609
|
throw new Error(`Workflow config not found at: ${resolved}`);
|
|
17610
17610
|
}
|
|
17611
|
-
const rawContent =
|
|
17611
|
+
const rawContent = fs23.readFileSync(resolved, "utf8");
|
|
17612
17612
|
const rawData = yaml5.load(rawContent);
|
|
17613
17613
|
if (rawData.imports && Array.isArray(rawData.imports)) {
|
|
17614
|
-
const configDir =
|
|
17614
|
+
const configDir = path27.dirname(resolved);
|
|
17615
17615
|
for (const source of rawData.imports) {
|
|
17616
17616
|
const results = await this.registry.import(source, {
|
|
17617
17617
|
basePath: configDir,
|
|
@@ -17641,8 +17641,8 @@ ${errors}`);
|
|
|
17641
17641
|
if (!steps || Object.keys(steps).length === 0) {
|
|
17642
17642
|
throw new Error(`Config '${resolved}' does not contain any steps to execute as a workflow`);
|
|
17643
17643
|
}
|
|
17644
|
-
const id =
|
|
17645
|
-
const name = loaded.name || `Workflow from ${
|
|
17644
|
+
const id = path27.basename(resolved).replace(/\.(ya?ml)$/i, "");
|
|
17645
|
+
const name = loaded.name || `Workflow from ${path27.basename(resolved)}`;
|
|
17646
17646
|
const workflowDef = {
|
|
17647
17647
|
id,
|
|
17648
17648
|
name,
|
|
@@ -18448,8 +18448,8 @@ async function createStoreBackend(storageConfig, haConfig) {
|
|
|
18448
18448
|
case "mssql": {
|
|
18449
18449
|
try {
|
|
18450
18450
|
const loaderPath = "../../enterprise/loader";
|
|
18451
|
-
const { loadEnterpriseStoreBackend
|
|
18452
|
-
return await
|
|
18451
|
+
const { loadEnterpriseStoreBackend } = await import(loaderPath);
|
|
18452
|
+
return await loadEnterpriseStoreBackend(driver, storageConfig, haConfig);
|
|
18453
18453
|
} catch (err) {
|
|
18454
18454
|
const msg = err instanceof Error ? err.message : String(err);
|
|
18455
18455
|
logger.error(`[StoreFactory] Failed to load enterprise ${driver} backend: ${msg}`);
|
|
@@ -21020,7 +21020,7 @@ var init_mcp_custom_sse_server = __esm({
|
|
|
21020
21020
|
* Returns the actual bound port number
|
|
21021
21021
|
*/
|
|
21022
21022
|
async start() {
|
|
21023
|
-
return new Promise((
|
|
21023
|
+
return new Promise((resolve15, reject) => {
|
|
21024
21024
|
try {
|
|
21025
21025
|
this.server = import_http.default.createServer((req, res) => {
|
|
21026
21026
|
this.handleRequest(req, res).catch((error) => {
|
|
@@ -21054,7 +21054,7 @@ var init_mcp_custom_sse_server = __esm({
|
|
|
21054
21054
|
);
|
|
21055
21055
|
}
|
|
21056
21056
|
this.startKeepalive();
|
|
21057
|
-
|
|
21057
|
+
resolve15(this.port);
|
|
21058
21058
|
});
|
|
21059
21059
|
} catch (error) {
|
|
21060
21060
|
reject(error);
|
|
@@ -21117,7 +21117,7 @@ var init_mcp_custom_sse_server = __esm({
|
|
|
21117
21117
|
logger.debug(
|
|
21118
21118
|
`[CustomToolsSSEServer:${this.sessionId}] Grace period before stop: ${waitMs}ms (activeToolCalls=${this.activeToolCalls})`
|
|
21119
21119
|
);
|
|
21120
|
-
await new Promise((
|
|
21120
|
+
await new Promise((resolve15) => setTimeout(resolve15, waitMs));
|
|
21121
21121
|
}
|
|
21122
21122
|
}
|
|
21123
21123
|
if (this.activeToolCalls > 0) {
|
|
@@ -21126,7 +21126,7 @@ var init_mcp_custom_sse_server = __esm({
|
|
|
21126
21126
|
`[CustomToolsSSEServer:${this.sessionId}] Waiting for ${this.activeToolCalls} active tool call(s) before stop`
|
|
21127
21127
|
);
|
|
21128
21128
|
while (this.activeToolCalls > 0 && Date.now() - startedAt < effectiveDrainTimeoutMs) {
|
|
21129
|
-
await new Promise((
|
|
21129
|
+
await new Promise((resolve15) => setTimeout(resolve15, 250));
|
|
21130
21130
|
}
|
|
21131
21131
|
if (this.activeToolCalls > 0) {
|
|
21132
21132
|
logger.warn(
|
|
@@ -21151,21 +21151,21 @@ var init_mcp_custom_sse_server = __esm({
|
|
|
21151
21151
|
}
|
|
21152
21152
|
this.connections.clear();
|
|
21153
21153
|
if (this.server) {
|
|
21154
|
-
await new Promise((
|
|
21154
|
+
await new Promise((resolve15, reject) => {
|
|
21155
21155
|
const timeout = setTimeout(() => {
|
|
21156
21156
|
if (this.debug) {
|
|
21157
21157
|
logger.debug(
|
|
21158
21158
|
`[CustomToolsSSEServer:${this.sessionId}] Force closing server after timeout`
|
|
21159
21159
|
);
|
|
21160
21160
|
}
|
|
21161
|
-
this.server?.close(() =>
|
|
21161
|
+
this.server?.close(() => resolve15());
|
|
21162
21162
|
}, 5e3);
|
|
21163
21163
|
this.server.close((error) => {
|
|
21164
21164
|
clearTimeout(timeout);
|
|
21165
21165
|
if (error) {
|
|
21166
21166
|
reject(error);
|
|
21167
21167
|
} else {
|
|
21168
|
-
|
|
21168
|
+
resolve15();
|
|
21169
21169
|
}
|
|
21170
21170
|
});
|
|
21171
21171
|
});
|
|
@@ -21600,7 +21600,7 @@ var init_mcp_custom_sse_server = __esm({
|
|
|
21600
21600
|
logger.warn(
|
|
21601
21601
|
`[CustomToolsSSEServer:${this.sessionId}] Tool ${toolName} failed (attempt ${attempt + 1}/${retryCount + 1}): ${errorMsg}. Retrying in ${delay}ms`
|
|
21602
21602
|
);
|
|
21603
|
-
await new Promise((
|
|
21603
|
+
await new Promise((resolve15) => setTimeout(resolve15, delay));
|
|
21604
21604
|
attempt++;
|
|
21605
21605
|
}
|
|
21606
21606
|
}
|
|
@@ -21913,9 +21913,9 @@ var init_ai_check_provider = __esm({
|
|
|
21913
21913
|
} else {
|
|
21914
21914
|
resolvedPath = import_path7.default.resolve(process.cwd(), str);
|
|
21915
21915
|
}
|
|
21916
|
-
const
|
|
21916
|
+
const fs23 = require("fs").promises;
|
|
21917
21917
|
try {
|
|
21918
|
-
const stat2 = await
|
|
21918
|
+
const stat2 = await fs23.stat(resolvedPath);
|
|
21919
21919
|
return stat2.isFile();
|
|
21920
21920
|
} catch {
|
|
21921
21921
|
return hasFileExtension && (isRelativePath || isAbsolutePath || hasPathSeparators);
|
|
@@ -27843,14 +27843,14 @@ var require_util = __commonJS({
|
|
|
27843
27843
|
}
|
|
27844
27844
|
const port = url.port != null ? url.port : url.protocol === "https:" ? 443 : 80;
|
|
27845
27845
|
let origin = url.origin != null ? url.origin : `${url.protocol}//${url.hostname}:${port}`;
|
|
27846
|
-
let
|
|
27846
|
+
let path27 = url.path != null ? url.path : `${url.pathname || ""}${url.search || ""}`;
|
|
27847
27847
|
if (origin.endsWith("/")) {
|
|
27848
27848
|
origin = origin.substring(0, origin.length - 1);
|
|
27849
27849
|
}
|
|
27850
|
-
if (
|
|
27851
|
-
|
|
27850
|
+
if (path27 && !path27.startsWith("/")) {
|
|
27851
|
+
path27 = `/${path27}`;
|
|
27852
27852
|
}
|
|
27853
|
-
url = new URL(origin +
|
|
27853
|
+
url = new URL(origin + path27);
|
|
27854
27854
|
}
|
|
27855
27855
|
return url;
|
|
27856
27856
|
}
|
|
@@ -29464,20 +29464,20 @@ var require_parseParams = __commonJS({
|
|
|
29464
29464
|
var require_basename = __commonJS({
|
|
29465
29465
|
"node_modules/@fastify/busboy/lib/utils/basename.js"(exports2, module2) {
|
|
29466
29466
|
"use strict";
|
|
29467
|
-
module2.exports = function basename4(
|
|
29468
|
-
if (typeof
|
|
29467
|
+
module2.exports = function basename4(path27) {
|
|
29468
|
+
if (typeof path27 !== "string") {
|
|
29469
29469
|
return "";
|
|
29470
29470
|
}
|
|
29471
|
-
for (var i =
|
|
29472
|
-
switch (
|
|
29471
|
+
for (var i = path27.length - 1; i >= 0; --i) {
|
|
29472
|
+
switch (path27.charCodeAt(i)) {
|
|
29473
29473
|
case 47:
|
|
29474
29474
|
// '/'
|
|
29475
29475
|
case 92:
|
|
29476
|
-
|
|
29477
|
-
return
|
|
29476
|
+
path27 = path27.slice(i + 1);
|
|
29477
|
+
return path27 === ".." || path27 === "." ? "" : path27;
|
|
29478
29478
|
}
|
|
29479
29479
|
}
|
|
29480
|
-
return
|
|
29480
|
+
return path27 === ".." || path27 === "." ? "" : path27;
|
|
29481
29481
|
};
|
|
29482
29482
|
}
|
|
29483
29483
|
});
|
|
@@ -30481,11 +30481,11 @@ var require_util2 = __commonJS({
|
|
|
30481
30481
|
var assert = require("assert");
|
|
30482
30482
|
var { isUint8Array } = require("util/types");
|
|
30483
30483
|
var supportedHashes = [];
|
|
30484
|
-
var
|
|
30484
|
+
var crypto2;
|
|
30485
30485
|
try {
|
|
30486
|
-
|
|
30486
|
+
crypto2 = require("crypto");
|
|
30487
30487
|
const possibleRelevantHashes = ["sha256", "sha384", "sha512"];
|
|
30488
|
-
supportedHashes =
|
|
30488
|
+
supportedHashes = crypto2.getHashes().filter((hash) => possibleRelevantHashes.includes(hash));
|
|
30489
30489
|
} catch {
|
|
30490
30490
|
}
|
|
30491
30491
|
function responseURL(response) {
|
|
@@ -30762,7 +30762,7 @@ var require_util2 = __commonJS({
|
|
|
30762
30762
|
}
|
|
30763
30763
|
}
|
|
30764
30764
|
function bytesMatch(bytes, metadataList) {
|
|
30765
|
-
if (
|
|
30765
|
+
if (crypto2 === void 0) {
|
|
30766
30766
|
return true;
|
|
30767
30767
|
}
|
|
30768
30768
|
const parsedMetadata = parseMetadata(metadataList);
|
|
@@ -30777,7 +30777,7 @@ var require_util2 = __commonJS({
|
|
|
30777
30777
|
for (const item of metadata) {
|
|
30778
30778
|
const algorithm = item.algo;
|
|
30779
30779
|
const expectedValue = item.hash;
|
|
30780
|
-
let actualValue =
|
|
30780
|
+
let actualValue = crypto2.createHash(algorithm).update(bytes).digest("base64");
|
|
30781
30781
|
if (actualValue[actualValue.length - 1] === "=") {
|
|
30782
30782
|
if (actualValue[actualValue.length - 2] === "=") {
|
|
30783
30783
|
actualValue = actualValue.slice(0, -2);
|
|
@@ -30870,8 +30870,8 @@ var require_util2 = __commonJS({
|
|
|
30870
30870
|
function createDeferredPromise() {
|
|
30871
30871
|
let res;
|
|
30872
30872
|
let rej;
|
|
30873
|
-
const promise = new Promise((
|
|
30874
|
-
res =
|
|
30873
|
+
const promise = new Promise((resolve15, reject) => {
|
|
30874
|
+
res = resolve15;
|
|
30875
30875
|
rej = reject;
|
|
30876
30876
|
});
|
|
30877
30877
|
return { promise, resolve: res, reject: rej };
|
|
@@ -32124,8 +32124,8 @@ var require_body = __commonJS({
|
|
|
32124
32124
|
var { parseMIMEType, serializeAMimeType } = require_dataURL();
|
|
32125
32125
|
var random;
|
|
32126
32126
|
try {
|
|
32127
|
-
const
|
|
32128
|
-
random = (max) =>
|
|
32127
|
+
const crypto2 = require("crypto");
|
|
32128
|
+
random = (max) => crypto2.randomInt(0, max);
|
|
32129
32129
|
} catch {
|
|
32130
32130
|
random = (max) => Math.floor(Math.random(max));
|
|
32131
32131
|
}
|
|
@@ -32376,8 +32376,8 @@ Content-Type: ${value.type || "application/octet-stream"}\r
|
|
|
32376
32376
|
});
|
|
32377
32377
|
}
|
|
32378
32378
|
});
|
|
32379
|
-
const busboyResolve = new Promise((
|
|
32380
|
-
busboy.on("finish",
|
|
32379
|
+
const busboyResolve = new Promise((resolve15, reject) => {
|
|
32380
|
+
busboy.on("finish", resolve15);
|
|
32381
32381
|
busboy.on("error", (err) => reject(new TypeError(err)));
|
|
32382
32382
|
});
|
|
32383
32383
|
if (this.body !== null) for await (const chunk of consumeBody(this[kState].body)) busboy.write(chunk);
|
|
@@ -32508,7 +32508,7 @@ var require_request = __commonJS({
|
|
|
32508
32508
|
}
|
|
32509
32509
|
var Request = class _Request {
|
|
32510
32510
|
constructor(origin, {
|
|
32511
|
-
path:
|
|
32511
|
+
path: path27,
|
|
32512
32512
|
method,
|
|
32513
32513
|
body,
|
|
32514
32514
|
headers,
|
|
@@ -32522,11 +32522,11 @@ var require_request = __commonJS({
|
|
|
32522
32522
|
throwOnError,
|
|
32523
32523
|
expectContinue
|
|
32524
32524
|
}, handler) {
|
|
32525
|
-
if (typeof
|
|
32525
|
+
if (typeof path27 !== "string") {
|
|
32526
32526
|
throw new InvalidArgumentError("path must be a string");
|
|
32527
|
-
} else if (
|
|
32527
|
+
} else if (path27[0] !== "/" && !(path27.startsWith("http://") || path27.startsWith("https://")) && method !== "CONNECT") {
|
|
32528
32528
|
throw new InvalidArgumentError("path must be an absolute URL or start with a slash");
|
|
32529
|
-
} else if (invalidPathRegex.exec(
|
|
32529
|
+
} else if (invalidPathRegex.exec(path27) !== null) {
|
|
32530
32530
|
throw new InvalidArgumentError("invalid request path");
|
|
32531
32531
|
}
|
|
32532
32532
|
if (typeof method !== "string") {
|
|
@@ -32589,7 +32589,7 @@ var require_request = __commonJS({
|
|
|
32589
32589
|
this.completed = false;
|
|
32590
32590
|
this.aborted = false;
|
|
32591
32591
|
this.upgrade = upgrade || null;
|
|
32592
|
-
this.path = query ? util.buildURL(
|
|
32592
|
+
this.path = query ? util.buildURL(path27, query) : path27;
|
|
32593
32593
|
this.origin = origin;
|
|
32594
32594
|
this.idempotent = idempotent == null ? method === "HEAD" || method === "GET" : idempotent;
|
|
32595
32595
|
this.blocking = blocking == null ? false : blocking;
|
|
@@ -32911,9 +32911,9 @@ var require_dispatcher_base = __commonJS({
|
|
|
32911
32911
|
}
|
|
32912
32912
|
close(callback) {
|
|
32913
32913
|
if (callback === void 0) {
|
|
32914
|
-
return new Promise((
|
|
32914
|
+
return new Promise((resolve15, reject) => {
|
|
32915
32915
|
this.close((err, data) => {
|
|
32916
|
-
return err ? reject(err) :
|
|
32916
|
+
return err ? reject(err) : resolve15(data);
|
|
32917
32917
|
});
|
|
32918
32918
|
});
|
|
32919
32919
|
}
|
|
@@ -32951,12 +32951,12 @@ var require_dispatcher_base = __commonJS({
|
|
|
32951
32951
|
err = null;
|
|
32952
32952
|
}
|
|
32953
32953
|
if (callback === void 0) {
|
|
32954
|
-
return new Promise((
|
|
32954
|
+
return new Promise((resolve15, reject) => {
|
|
32955
32955
|
this.destroy(err, (err2, data) => {
|
|
32956
32956
|
return err2 ? (
|
|
32957
32957
|
/* istanbul ignore next: should never error */
|
|
32958
32958
|
reject(err2)
|
|
32959
|
-
) :
|
|
32959
|
+
) : resolve15(data);
|
|
32960
32960
|
});
|
|
32961
32961
|
});
|
|
32962
32962
|
}
|
|
@@ -33597,9 +33597,9 @@ var require_RedirectHandler = __commonJS({
|
|
|
33597
33597
|
return this.handler.onHeaders(statusCode, headers, resume, statusText);
|
|
33598
33598
|
}
|
|
33599
33599
|
const { origin, pathname, search } = util.parseURL(new URL(this.location, this.opts.origin && new URL(this.opts.path, this.opts.origin)));
|
|
33600
|
-
const
|
|
33600
|
+
const path27 = search ? `${pathname}${search}` : pathname;
|
|
33601
33601
|
this.opts.headers = cleanRequestHeaders(this.opts.headers, statusCode === 303, this.opts.origin !== origin);
|
|
33602
|
-
this.opts.path =
|
|
33602
|
+
this.opts.path = path27;
|
|
33603
33603
|
this.opts.origin = origin;
|
|
33604
33604
|
this.opts.maxRedirections = 0;
|
|
33605
33605
|
this.opts.query = null;
|
|
@@ -34018,16 +34018,16 @@ var require_client = __commonJS({
|
|
|
34018
34018
|
return this[kNeedDrain] < 2;
|
|
34019
34019
|
}
|
|
34020
34020
|
async [kClose]() {
|
|
34021
|
-
return new Promise((
|
|
34021
|
+
return new Promise((resolve15) => {
|
|
34022
34022
|
if (!this[kSize]) {
|
|
34023
|
-
|
|
34023
|
+
resolve15(null);
|
|
34024
34024
|
} else {
|
|
34025
|
-
this[kClosedResolve] =
|
|
34025
|
+
this[kClosedResolve] = resolve15;
|
|
34026
34026
|
}
|
|
34027
34027
|
});
|
|
34028
34028
|
}
|
|
34029
34029
|
async [kDestroy](err) {
|
|
34030
|
-
return new Promise((
|
|
34030
|
+
return new Promise((resolve15) => {
|
|
34031
34031
|
const requests = this[kQueue].splice(this[kPendingIdx]);
|
|
34032
34032
|
for (let i = 0; i < requests.length; i++) {
|
|
34033
34033
|
const request = requests[i];
|
|
@@ -34038,7 +34038,7 @@ var require_client = __commonJS({
|
|
|
34038
34038
|
this[kClosedResolve]();
|
|
34039
34039
|
this[kClosedResolve] = null;
|
|
34040
34040
|
}
|
|
34041
|
-
|
|
34041
|
+
resolve15();
|
|
34042
34042
|
};
|
|
34043
34043
|
if (this[kHTTP2Session] != null) {
|
|
34044
34044
|
util.destroy(this[kHTTP2Session], err);
|
|
@@ -34618,7 +34618,7 @@ var require_client = __commonJS({
|
|
|
34618
34618
|
});
|
|
34619
34619
|
}
|
|
34620
34620
|
try {
|
|
34621
|
-
const socket = await new Promise((
|
|
34621
|
+
const socket = await new Promise((resolve15, reject) => {
|
|
34622
34622
|
client[kConnector]({
|
|
34623
34623
|
host,
|
|
34624
34624
|
hostname,
|
|
@@ -34630,7 +34630,7 @@ var require_client = __commonJS({
|
|
|
34630
34630
|
if (err) {
|
|
34631
34631
|
reject(err);
|
|
34632
34632
|
} else {
|
|
34633
|
-
|
|
34633
|
+
resolve15(socket2);
|
|
34634
34634
|
}
|
|
34635
34635
|
});
|
|
34636
34636
|
});
|
|
@@ -34841,7 +34841,7 @@ var require_client = __commonJS({
|
|
|
34841
34841
|
writeH2(client, client[kHTTP2Session], request);
|
|
34842
34842
|
return;
|
|
34843
34843
|
}
|
|
34844
|
-
const { body, method, path:
|
|
34844
|
+
const { body, method, path: path27, host, upgrade, headers, blocking, reset } = request;
|
|
34845
34845
|
const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH";
|
|
34846
34846
|
if (body && typeof body.read === "function") {
|
|
34847
34847
|
body.read(0);
|
|
@@ -34891,7 +34891,7 @@ var require_client = __commonJS({
|
|
|
34891
34891
|
if (blocking) {
|
|
34892
34892
|
socket[kBlocking] = true;
|
|
34893
34893
|
}
|
|
34894
|
-
let header = `${method} ${
|
|
34894
|
+
let header = `${method} ${path27} HTTP/1.1\r
|
|
34895
34895
|
`;
|
|
34896
34896
|
if (typeof host === "string") {
|
|
34897
34897
|
header += `host: ${host}\r
|
|
@@ -34954,7 +34954,7 @@ upgrade: ${upgrade}\r
|
|
|
34954
34954
|
return true;
|
|
34955
34955
|
}
|
|
34956
34956
|
function writeH2(client, session, request) {
|
|
34957
|
-
const { body, method, path:
|
|
34957
|
+
const { body, method, path: path27, host, upgrade, expectContinue, signal, headers: reqHeaders } = request;
|
|
34958
34958
|
let headers;
|
|
34959
34959
|
if (typeof reqHeaders === "string") headers = Request[kHTTP2CopyHeaders](reqHeaders.trim());
|
|
34960
34960
|
else headers = reqHeaders;
|
|
@@ -34997,7 +34997,7 @@ upgrade: ${upgrade}\r
|
|
|
34997
34997
|
});
|
|
34998
34998
|
return true;
|
|
34999
34999
|
}
|
|
35000
|
-
headers[HTTP2_HEADER_PATH] =
|
|
35000
|
+
headers[HTTP2_HEADER_PATH] = path27;
|
|
35001
35001
|
headers[HTTP2_HEADER_SCHEME] = "https";
|
|
35002
35002
|
const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH";
|
|
35003
35003
|
if (body && typeof body.read === "function") {
|
|
@@ -35254,12 +35254,12 @@ upgrade: ${upgrade}\r
|
|
|
35254
35254
|
cb();
|
|
35255
35255
|
}
|
|
35256
35256
|
}
|
|
35257
|
-
const waitForDrain = () => new Promise((
|
|
35257
|
+
const waitForDrain = () => new Promise((resolve15, reject) => {
|
|
35258
35258
|
assert(callback === null);
|
|
35259
35259
|
if (socket[kError]) {
|
|
35260
35260
|
reject(socket[kError]);
|
|
35261
35261
|
} else {
|
|
35262
|
-
callback =
|
|
35262
|
+
callback = resolve15;
|
|
35263
35263
|
}
|
|
35264
35264
|
});
|
|
35265
35265
|
if (client[kHTTPConnVersion] === "h2") {
|
|
@@ -35605,8 +35605,8 @@ var require_pool_base = __commonJS({
|
|
|
35605
35605
|
if (this[kQueue].isEmpty()) {
|
|
35606
35606
|
return Promise.all(this[kClients].map((c) => c.close()));
|
|
35607
35607
|
} else {
|
|
35608
|
-
return new Promise((
|
|
35609
|
-
this[kClosedResolve] =
|
|
35608
|
+
return new Promise((resolve15) => {
|
|
35609
|
+
this[kClosedResolve] = resolve15;
|
|
35610
35610
|
});
|
|
35611
35611
|
}
|
|
35612
35612
|
}
|
|
@@ -36184,7 +36184,7 @@ var require_readable = __commonJS({
|
|
|
36184
36184
|
if (this.closed) {
|
|
36185
36185
|
return Promise.resolve(null);
|
|
36186
36186
|
}
|
|
36187
|
-
return new Promise((
|
|
36187
|
+
return new Promise((resolve15, reject) => {
|
|
36188
36188
|
const signalListenerCleanup = signal ? util.addAbortListener(signal, () => {
|
|
36189
36189
|
this.destroy();
|
|
36190
36190
|
}) : noop;
|
|
@@ -36193,7 +36193,7 @@ var require_readable = __commonJS({
|
|
|
36193
36193
|
if (signal && signal.aborted) {
|
|
36194
36194
|
reject(signal.reason || Object.assign(new Error("The operation was aborted"), { name: "AbortError" }));
|
|
36195
36195
|
} else {
|
|
36196
|
-
|
|
36196
|
+
resolve15(null);
|
|
36197
36197
|
}
|
|
36198
36198
|
}).on("error", noop).on("data", function(chunk) {
|
|
36199
36199
|
limit -= chunk.length;
|
|
@@ -36215,11 +36215,11 @@ var require_readable = __commonJS({
|
|
|
36215
36215
|
throw new TypeError("unusable");
|
|
36216
36216
|
}
|
|
36217
36217
|
assert(!stream[kConsume]);
|
|
36218
|
-
return new Promise((
|
|
36218
|
+
return new Promise((resolve15, reject) => {
|
|
36219
36219
|
stream[kConsume] = {
|
|
36220
36220
|
type,
|
|
36221
36221
|
stream,
|
|
36222
|
-
resolve:
|
|
36222
|
+
resolve: resolve15,
|
|
36223
36223
|
reject,
|
|
36224
36224
|
length: 0,
|
|
36225
36225
|
body: []
|
|
@@ -36254,12 +36254,12 @@ var require_readable = __commonJS({
|
|
|
36254
36254
|
}
|
|
36255
36255
|
}
|
|
36256
36256
|
function consumeEnd(consume2) {
|
|
36257
|
-
const { type, body, resolve:
|
|
36257
|
+
const { type, body, resolve: resolve15, stream, length } = consume2;
|
|
36258
36258
|
try {
|
|
36259
36259
|
if (type === "text") {
|
|
36260
|
-
|
|
36260
|
+
resolve15(toUSVString(Buffer.concat(body)));
|
|
36261
36261
|
} else if (type === "json") {
|
|
36262
|
-
|
|
36262
|
+
resolve15(JSON.parse(Buffer.concat(body)));
|
|
36263
36263
|
} else if (type === "arrayBuffer") {
|
|
36264
36264
|
const dst = new Uint8Array(length);
|
|
36265
36265
|
let pos = 0;
|
|
@@ -36267,12 +36267,12 @@ var require_readable = __commonJS({
|
|
|
36267
36267
|
dst.set(buf, pos);
|
|
36268
36268
|
pos += buf.byteLength;
|
|
36269
36269
|
}
|
|
36270
|
-
|
|
36270
|
+
resolve15(dst.buffer);
|
|
36271
36271
|
} else if (type === "blob") {
|
|
36272
36272
|
if (!Blob2) {
|
|
36273
36273
|
Blob2 = require("buffer").Blob;
|
|
36274
36274
|
}
|
|
36275
|
-
|
|
36275
|
+
resolve15(new Blob2(body, { type: stream[kContentType] }));
|
|
36276
36276
|
}
|
|
36277
36277
|
consumeFinish(consume2);
|
|
36278
36278
|
} catch (err) {
|
|
@@ -36529,9 +36529,9 @@ var require_api_request = __commonJS({
|
|
|
36529
36529
|
};
|
|
36530
36530
|
function request(opts, callback) {
|
|
36531
36531
|
if (callback === void 0) {
|
|
36532
|
-
return new Promise((
|
|
36532
|
+
return new Promise((resolve15, reject) => {
|
|
36533
36533
|
request.call(this, opts, (err, data) => {
|
|
36534
|
-
return err ? reject(err) :
|
|
36534
|
+
return err ? reject(err) : resolve15(data);
|
|
36535
36535
|
});
|
|
36536
36536
|
});
|
|
36537
36537
|
}
|
|
@@ -36704,9 +36704,9 @@ var require_api_stream = __commonJS({
|
|
|
36704
36704
|
};
|
|
36705
36705
|
function stream(opts, factory, callback) {
|
|
36706
36706
|
if (callback === void 0) {
|
|
36707
|
-
return new Promise((
|
|
36707
|
+
return new Promise((resolve15, reject) => {
|
|
36708
36708
|
stream.call(this, opts, factory, (err, data) => {
|
|
36709
|
-
return err ? reject(err) :
|
|
36709
|
+
return err ? reject(err) : resolve15(data);
|
|
36710
36710
|
});
|
|
36711
36711
|
});
|
|
36712
36712
|
}
|
|
@@ -36987,9 +36987,9 @@ var require_api_upgrade = __commonJS({
|
|
|
36987
36987
|
};
|
|
36988
36988
|
function upgrade(opts, callback) {
|
|
36989
36989
|
if (callback === void 0) {
|
|
36990
|
-
return new Promise((
|
|
36990
|
+
return new Promise((resolve15, reject) => {
|
|
36991
36991
|
upgrade.call(this, opts, (err, data) => {
|
|
36992
|
-
return err ? reject(err) :
|
|
36992
|
+
return err ? reject(err) : resolve15(data);
|
|
36993
36993
|
});
|
|
36994
36994
|
});
|
|
36995
36995
|
}
|
|
@@ -37078,9 +37078,9 @@ var require_api_connect = __commonJS({
|
|
|
37078
37078
|
};
|
|
37079
37079
|
function connect(opts, callback) {
|
|
37080
37080
|
if (callback === void 0) {
|
|
37081
|
-
return new Promise((
|
|
37081
|
+
return new Promise((resolve15, reject) => {
|
|
37082
37082
|
connect.call(this, opts, (err, data) => {
|
|
37083
|
-
return err ? reject(err) :
|
|
37083
|
+
return err ? reject(err) : resolve15(data);
|
|
37084
37084
|
});
|
|
37085
37085
|
});
|
|
37086
37086
|
}
|
|
@@ -37240,20 +37240,20 @@ var require_mock_utils = __commonJS({
|
|
|
37240
37240
|
}
|
|
37241
37241
|
return true;
|
|
37242
37242
|
}
|
|
37243
|
-
function safeUrl(
|
|
37244
|
-
if (typeof
|
|
37245
|
-
return
|
|
37243
|
+
function safeUrl(path27) {
|
|
37244
|
+
if (typeof path27 !== "string") {
|
|
37245
|
+
return path27;
|
|
37246
37246
|
}
|
|
37247
|
-
const pathSegments =
|
|
37247
|
+
const pathSegments = path27.split("?");
|
|
37248
37248
|
if (pathSegments.length !== 2) {
|
|
37249
|
-
return
|
|
37249
|
+
return path27;
|
|
37250
37250
|
}
|
|
37251
37251
|
const qp = new URLSearchParams(pathSegments.pop());
|
|
37252
37252
|
qp.sort();
|
|
37253
37253
|
return [...pathSegments, qp.toString()].join("?");
|
|
37254
37254
|
}
|
|
37255
|
-
function matchKey(mockDispatch2, { path:
|
|
37256
|
-
const pathMatch = matchValue(mockDispatch2.path,
|
|
37255
|
+
function matchKey(mockDispatch2, { path: path27, method, body, headers }) {
|
|
37256
|
+
const pathMatch = matchValue(mockDispatch2.path, path27);
|
|
37257
37257
|
const methodMatch = matchValue(mockDispatch2.method, method);
|
|
37258
37258
|
const bodyMatch = typeof mockDispatch2.body !== "undefined" ? matchValue(mockDispatch2.body, body) : true;
|
|
37259
37259
|
const headersMatch = matchHeaders(mockDispatch2, headers);
|
|
@@ -37271,7 +37271,7 @@ var require_mock_utils = __commonJS({
|
|
|
37271
37271
|
function getMockDispatch(mockDispatches, key) {
|
|
37272
37272
|
const basePath = key.query ? buildURL(key.path, key.query) : key.path;
|
|
37273
37273
|
const resolvedPath = typeof basePath === "string" ? safeUrl(basePath) : basePath;
|
|
37274
|
-
let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path:
|
|
37274
|
+
let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path: path27 }) => matchValue(safeUrl(path27), resolvedPath));
|
|
37275
37275
|
if (matchedMockDispatches.length === 0) {
|
|
37276
37276
|
throw new MockNotMatchedError(`Mock dispatch not matched for path '${resolvedPath}'`);
|
|
37277
37277
|
}
|
|
@@ -37308,9 +37308,9 @@ var require_mock_utils = __commonJS({
|
|
|
37308
37308
|
}
|
|
37309
37309
|
}
|
|
37310
37310
|
function buildKey(opts) {
|
|
37311
|
-
const { path:
|
|
37311
|
+
const { path: path27, method, body, headers, query } = opts;
|
|
37312
37312
|
return {
|
|
37313
|
-
path:
|
|
37313
|
+
path: path27,
|
|
37314
37314
|
method,
|
|
37315
37315
|
body,
|
|
37316
37316
|
headers,
|
|
@@ -37759,10 +37759,10 @@ var require_pending_interceptors_formatter = __commonJS({
|
|
|
37759
37759
|
}
|
|
37760
37760
|
format(pendingInterceptors) {
|
|
37761
37761
|
const withPrettyHeaders = pendingInterceptors.map(
|
|
37762
|
-
({ method, path:
|
|
37762
|
+
({ method, path: path27, data: { statusCode }, persist, times, timesInvoked, origin }) => ({
|
|
37763
37763
|
Method: method,
|
|
37764
37764
|
Origin: origin,
|
|
37765
|
-
Path:
|
|
37765
|
+
Path: path27,
|
|
37766
37766
|
"Status code": statusCode,
|
|
37767
37767
|
Persistent: persist ? "\u2705" : "\u274C",
|
|
37768
37768
|
Invocations: timesInvoked,
|
|
@@ -40703,7 +40703,7 @@ var require_fetch = __commonJS({
|
|
|
40703
40703
|
async function dispatch({ body }) {
|
|
40704
40704
|
const url = requestCurrentURL(request);
|
|
40705
40705
|
const agent = fetchParams.controller.dispatcher;
|
|
40706
|
-
return new Promise((
|
|
40706
|
+
return new Promise((resolve15, reject) => agent.dispatch(
|
|
40707
40707
|
{
|
|
40708
40708
|
path: url.pathname + url.search,
|
|
40709
40709
|
origin: url.origin,
|
|
@@ -40779,7 +40779,7 @@ var require_fetch = __commonJS({
|
|
|
40779
40779
|
}
|
|
40780
40780
|
}
|
|
40781
40781
|
}
|
|
40782
|
-
|
|
40782
|
+
resolve15({
|
|
40783
40783
|
status,
|
|
40784
40784
|
statusText,
|
|
40785
40785
|
headersList: headers[kHeadersList],
|
|
@@ -40822,7 +40822,7 @@ var require_fetch = __commonJS({
|
|
|
40822
40822
|
const val = headersList[n + 1].toString("latin1");
|
|
40823
40823
|
headers[kHeadersList].append(key, val);
|
|
40824
40824
|
}
|
|
40825
|
-
|
|
40825
|
+
resolve15({
|
|
40826
40826
|
status,
|
|
40827
40827
|
statusText: STATUS_CODES[status],
|
|
40828
40828
|
headersList: headers[kHeadersList],
|
|
@@ -42383,8 +42383,8 @@ var require_util6 = __commonJS({
|
|
|
42383
42383
|
}
|
|
42384
42384
|
}
|
|
42385
42385
|
}
|
|
42386
|
-
function validateCookiePath(
|
|
42387
|
-
for (const char of
|
|
42386
|
+
function validateCookiePath(path27) {
|
|
42387
|
+
for (const char of path27) {
|
|
42388
42388
|
const code = char.charCodeAt(0);
|
|
42389
42389
|
if (code < 33 || char === ";") {
|
|
42390
42390
|
throw new Error("Invalid cookie path");
|
|
@@ -43181,9 +43181,9 @@ var require_connection = __commonJS({
|
|
|
43181
43181
|
channels.open = diagnosticsChannel.channel("undici:websocket:open");
|
|
43182
43182
|
channels.close = diagnosticsChannel.channel("undici:websocket:close");
|
|
43183
43183
|
channels.socketError = diagnosticsChannel.channel("undici:websocket:socket_error");
|
|
43184
|
-
var
|
|
43184
|
+
var crypto2;
|
|
43185
43185
|
try {
|
|
43186
|
-
|
|
43186
|
+
crypto2 = require("crypto");
|
|
43187
43187
|
} catch {
|
|
43188
43188
|
}
|
|
43189
43189
|
function establishWebSocketConnection(url, protocols, ws, onEstablish, options) {
|
|
@@ -43202,7 +43202,7 @@ var require_connection = __commonJS({
|
|
|
43202
43202
|
const headersList = new Headers(options.headers)[kHeadersList];
|
|
43203
43203
|
request.headersList = headersList;
|
|
43204
43204
|
}
|
|
43205
|
-
const keyValue =
|
|
43205
|
+
const keyValue = crypto2.randomBytes(16).toString("base64");
|
|
43206
43206
|
request.headersList.append("sec-websocket-key", keyValue);
|
|
43207
43207
|
request.headersList.append("sec-websocket-version", "13");
|
|
43208
43208
|
for (const protocol of protocols) {
|
|
@@ -43231,7 +43231,7 @@ var require_connection = __commonJS({
|
|
|
43231
43231
|
return;
|
|
43232
43232
|
}
|
|
43233
43233
|
const secWSAccept = response.headersList.get("Sec-WebSocket-Accept");
|
|
43234
|
-
const digest =
|
|
43234
|
+
const digest = crypto2.createHash("sha1").update(keyValue + uid).digest("base64");
|
|
43235
43235
|
if (secWSAccept !== digest) {
|
|
43236
43236
|
failWebsocketConnection(ws, "Incorrect hash received in Sec-WebSocket-Accept header.");
|
|
43237
43237
|
return;
|
|
@@ -43311,9 +43311,9 @@ var require_frame = __commonJS({
|
|
|
43311
43311
|
"node_modules/undici/lib/websocket/frame.js"(exports2, module2) {
|
|
43312
43312
|
"use strict";
|
|
43313
43313
|
var { maxUnsigned16Bit } = require_constants5();
|
|
43314
|
-
var
|
|
43314
|
+
var crypto2;
|
|
43315
43315
|
try {
|
|
43316
|
-
|
|
43316
|
+
crypto2 = require("crypto");
|
|
43317
43317
|
} catch {
|
|
43318
43318
|
}
|
|
43319
43319
|
var WebsocketFrameSend = class {
|
|
@@ -43322,7 +43322,7 @@ var require_frame = __commonJS({
|
|
|
43322
43322
|
*/
|
|
43323
43323
|
constructor(data) {
|
|
43324
43324
|
this.frameData = data;
|
|
43325
|
-
this.maskKey =
|
|
43325
|
+
this.maskKey = crypto2.randomBytes(4);
|
|
43326
43326
|
}
|
|
43327
43327
|
createFrame(opcode) {
|
|
43328
43328
|
const bodyLength = this.frameData?.byteLength ?? 0;
|
|
@@ -44064,11 +44064,11 @@ var require_undici = __commonJS({
|
|
|
44064
44064
|
if (typeof opts.path !== "string") {
|
|
44065
44065
|
throw new InvalidArgumentError("invalid opts.path");
|
|
44066
44066
|
}
|
|
44067
|
-
let
|
|
44067
|
+
let path27 = opts.path;
|
|
44068
44068
|
if (!opts.path.startsWith("/")) {
|
|
44069
|
-
|
|
44069
|
+
path27 = `/${path27}`;
|
|
44070
44070
|
}
|
|
44071
|
-
url = new URL(util.parseOrigin(url).origin +
|
|
44071
|
+
url = new URL(util.parseOrigin(url).origin + path27);
|
|
44072
44072
|
} else {
|
|
44073
44073
|
if (!opts) {
|
|
44074
44074
|
opts = typeof url === "object" ? url : {};
|
|
@@ -44617,7 +44617,7 @@ var init_mcp_check_provider = __esm({
|
|
|
44617
44617
|
logger.warn(
|
|
44618
44618
|
`MCP ${transportName} failed (attempt ${attempt + 1}/${maxRetries + 1}), retrying in ${delay}ms: ${error instanceof Error ? error.message : String(error)}`
|
|
44619
44619
|
);
|
|
44620
|
-
await new Promise((
|
|
44620
|
+
await new Promise((resolve15) => setTimeout(resolve15, delay));
|
|
44621
44621
|
attempt += 1;
|
|
44622
44622
|
} finally {
|
|
44623
44623
|
try {
|
|
@@ -44899,7 +44899,7 @@ async function acquirePromptLock() {
|
|
|
44899
44899
|
activePrompt = true;
|
|
44900
44900
|
return;
|
|
44901
44901
|
}
|
|
44902
|
-
await new Promise((
|
|
44902
|
+
await new Promise((resolve15) => waiters.push(resolve15));
|
|
44903
44903
|
activePrompt = true;
|
|
44904
44904
|
}
|
|
44905
44905
|
function releasePromptLock() {
|
|
@@ -44909,7 +44909,7 @@ function releasePromptLock() {
|
|
|
44909
44909
|
}
|
|
44910
44910
|
async function interactivePrompt(options) {
|
|
44911
44911
|
await acquirePromptLock();
|
|
44912
|
-
return new Promise((
|
|
44912
|
+
return new Promise((resolve15, reject) => {
|
|
44913
44913
|
const dbg = process.env.VISOR_DEBUG === "true";
|
|
44914
44914
|
try {
|
|
44915
44915
|
if (dbg) {
|
|
@@ -44996,12 +44996,12 @@ async function interactivePrompt(options) {
|
|
|
44996
44996
|
};
|
|
44997
44997
|
const finish = (value) => {
|
|
44998
44998
|
cleanup();
|
|
44999
|
-
|
|
44999
|
+
resolve15(value);
|
|
45000
45000
|
};
|
|
45001
45001
|
if (options.timeout && options.timeout > 0) {
|
|
45002
45002
|
timeoutId = setTimeout(() => {
|
|
45003
45003
|
cleanup();
|
|
45004
|
-
if (defaultValue !== void 0) return
|
|
45004
|
+
if (defaultValue !== void 0) return resolve15(defaultValue);
|
|
45005
45005
|
return reject(new Error("Input timeout"));
|
|
45006
45006
|
}, options.timeout);
|
|
45007
45007
|
}
|
|
@@ -45133,7 +45133,7 @@ async function interactivePrompt(options) {
|
|
|
45133
45133
|
});
|
|
45134
45134
|
}
|
|
45135
45135
|
async function simplePrompt(prompt) {
|
|
45136
|
-
return new Promise((
|
|
45136
|
+
return new Promise((resolve15) => {
|
|
45137
45137
|
const rl = readline.createInterface({
|
|
45138
45138
|
input: process.stdin,
|
|
45139
45139
|
output: process.stdout
|
|
@@ -45149,7 +45149,7 @@ async function simplePrompt(prompt) {
|
|
|
45149
45149
|
rl.question(`${prompt}
|
|
45150
45150
|
> `, (answer) => {
|
|
45151
45151
|
rl.close();
|
|
45152
|
-
|
|
45152
|
+
resolve15(answer.trim());
|
|
45153
45153
|
});
|
|
45154
45154
|
});
|
|
45155
45155
|
}
|
|
@@ -45317,7 +45317,7 @@ function isStdinAvailable() {
|
|
|
45317
45317
|
return !process.stdin.isTTY;
|
|
45318
45318
|
}
|
|
45319
45319
|
async function readStdin(timeout, maxSize = 1024 * 1024) {
|
|
45320
|
-
return new Promise((
|
|
45320
|
+
return new Promise((resolve15, reject) => {
|
|
45321
45321
|
let data = "";
|
|
45322
45322
|
let timeoutId;
|
|
45323
45323
|
if (timeout) {
|
|
@@ -45344,7 +45344,7 @@ async function readStdin(timeout, maxSize = 1024 * 1024) {
|
|
|
45344
45344
|
};
|
|
45345
45345
|
const onEnd = () => {
|
|
45346
45346
|
cleanup();
|
|
45347
|
-
|
|
45347
|
+
resolve15(data.trim());
|
|
45348
45348
|
};
|
|
45349
45349
|
const onError = (err) => {
|
|
45350
45350
|
cleanup();
|
|
@@ -49462,23 +49462,23 @@ __export(renderer_schema_exports, {
|
|
|
49462
49462
|
});
|
|
49463
49463
|
async function loadRendererSchema(name) {
|
|
49464
49464
|
try {
|
|
49465
|
-
const
|
|
49466
|
-
const
|
|
49465
|
+
const fs23 = await import("fs/promises");
|
|
49466
|
+
const path27 = await import("path");
|
|
49467
49467
|
const sanitized = String(name).replace(/[^a-zA-Z0-9-]/g, "");
|
|
49468
49468
|
if (!sanitized) return void 0;
|
|
49469
49469
|
const candidates = [
|
|
49470
49470
|
// When bundled with ncc, __dirname is dist/ and output/ is at dist/output/
|
|
49471
|
-
|
|
49471
|
+
path27.join(__dirname, "output", sanitized, "schema.json"),
|
|
49472
49472
|
// When running from source, __dirname is src/state-machine/dispatch/ and output/ is at output/
|
|
49473
|
-
|
|
49473
|
+
path27.join(__dirname, "..", "..", "output", sanitized, "schema.json"),
|
|
49474
49474
|
// When running from a checkout with output/ folder copied to CWD
|
|
49475
|
-
|
|
49475
|
+
path27.join(process.cwd(), "output", sanitized, "schema.json"),
|
|
49476
49476
|
// Fallback: cwd/dist/output/
|
|
49477
|
-
|
|
49477
|
+
path27.join(process.cwd(), "dist", "output", sanitized, "schema.json")
|
|
49478
49478
|
];
|
|
49479
49479
|
for (const p of candidates) {
|
|
49480
49480
|
try {
|
|
49481
|
-
const raw = await
|
|
49481
|
+
const raw = await fs23.readFile(p, "utf-8");
|
|
49482
49482
|
return JSON.parse(raw);
|
|
49483
49483
|
} catch {
|
|
49484
49484
|
}
|
|
@@ -51897,8 +51897,8 @@ function updateStats2(results, state, isForEachIteration = false) {
|
|
|
51897
51897
|
async function renderTemplateContent2(checkId, checkConfig, reviewSummary) {
|
|
51898
51898
|
try {
|
|
51899
51899
|
const { createExtendedLiquid: createExtendedLiquid2 } = await Promise.resolve().then(() => (init_liquid_extensions(), liquid_extensions_exports));
|
|
51900
|
-
const
|
|
51901
|
-
const
|
|
51900
|
+
const fs23 = await import("fs/promises");
|
|
51901
|
+
const path27 = await import("path");
|
|
51902
51902
|
const schemaRaw = checkConfig.schema || "plain";
|
|
51903
51903
|
const schema = typeof schemaRaw === "string" && !schemaRaw.includes("{{") && !schemaRaw.includes("{%") ? schemaRaw : typeof schemaRaw === "object" ? "code-review" : "plain";
|
|
51904
51904
|
let templateContent;
|
|
@@ -51907,27 +51907,27 @@ async function renderTemplateContent2(checkId, checkConfig, reviewSummary) {
|
|
|
51907
51907
|
logger.debug(`[LevelDispatch] Using inline template for ${checkId}`);
|
|
51908
51908
|
} else if (checkConfig.template && checkConfig.template.file) {
|
|
51909
51909
|
const file = String(checkConfig.template.file);
|
|
51910
|
-
const resolved =
|
|
51911
|
-
templateContent = await
|
|
51910
|
+
const resolved = path27.resolve(process.cwd(), file);
|
|
51911
|
+
templateContent = await fs23.readFile(resolved, "utf-8");
|
|
51912
51912
|
logger.debug(`[LevelDispatch] Using template file for ${checkId}: ${resolved}`);
|
|
51913
51913
|
} else if (schema && schema !== "plain") {
|
|
51914
51914
|
const sanitized = String(schema).replace(/[^a-zA-Z0-9-]/g, "");
|
|
51915
51915
|
if (sanitized) {
|
|
51916
51916
|
const candidatePaths = [
|
|
51917
|
-
|
|
51917
|
+
path27.join(__dirname, "output", sanitized, "template.liquid"),
|
|
51918
51918
|
// bundled: dist/output/
|
|
51919
|
-
|
|
51919
|
+
path27.join(__dirname, "..", "..", "output", sanitized, "template.liquid"),
|
|
51920
51920
|
// source (from state-machine/states)
|
|
51921
|
-
|
|
51921
|
+
path27.join(__dirname, "..", "..", "..", "output", sanitized, "template.liquid"),
|
|
51922
51922
|
// source (alternate)
|
|
51923
|
-
|
|
51923
|
+
path27.join(process.cwd(), "output", sanitized, "template.liquid"),
|
|
51924
51924
|
// fallback: cwd/output/
|
|
51925
|
-
|
|
51925
|
+
path27.join(process.cwd(), "dist", "output", sanitized, "template.liquid")
|
|
51926
51926
|
// fallback: cwd/dist/output/
|
|
51927
51927
|
];
|
|
51928
51928
|
for (const p of candidatePaths) {
|
|
51929
51929
|
try {
|
|
51930
|
-
templateContent = await
|
|
51930
|
+
templateContent = await fs23.readFile(p, "utf-8");
|
|
51931
51931
|
if (templateContent) {
|
|
51932
51932
|
logger.debug(`[LevelDispatch] Using schema template for ${checkId}: ${p}`);
|
|
51933
51933
|
break;
|
|
@@ -54067,8 +54067,8 @@ var init_workspace_manager = __esm({
|
|
|
54067
54067
|
);
|
|
54068
54068
|
if (this.cleanupRequested && this.activeOperations === 0) {
|
|
54069
54069
|
logger.debug(`[Workspace] All references released, proceeding with deferred cleanup`);
|
|
54070
|
-
for (const
|
|
54071
|
-
|
|
54070
|
+
for (const resolve15 of this.cleanupResolvers) {
|
|
54071
|
+
resolve15();
|
|
54072
54072
|
}
|
|
54073
54073
|
this.cleanupResolvers = [];
|
|
54074
54074
|
}
|
|
@@ -54225,19 +54225,19 @@ var init_workspace_manager = __esm({
|
|
|
54225
54225
|
);
|
|
54226
54226
|
this.cleanupRequested = true;
|
|
54227
54227
|
await Promise.race([
|
|
54228
|
-
new Promise((
|
|
54228
|
+
new Promise((resolve15) => {
|
|
54229
54229
|
if (this.activeOperations === 0) {
|
|
54230
|
-
|
|
54230
|
+
resolve15();
|
|
54231
54231
|
} else {
|
|
54232
|
-
this.cleanupResolvers.push(
|
|
54232
|
+
this.cleanupResolvers.push(resolve15);
|
|
54233
54233
|
}
|
|
54234
54234
|
}),
|
|
54235
|
-
new Promise((
|
|
54235
|
+
new Promise((resolve15) => {
|
|
54236
54236
|
setTimeout(() => {
|
|
54237
54237
|
logger.warn(
|
|
54238
54238
|
`[Workspace] Cleanup timeout after ${timeout}ms, proceeding anyway (${this.activeOperations} operations still active)`
|
|
54239
54239
|
);
|
|
54240
|
-
|
|
54240
|
+
resolve15();
|
|
54241
54241
|
}, timeout);
|
|
54242
54242
|
})
|
|
54243
54243
|
]);
|
|
@@ -54715,1380 +54715,6 @@ var init_build_engine_context = __esm({
|
|
|
54715
54715
|
}
|
|
54716
54716
|
});
|
|
54717
54717
|
|
|
54718
|
-
// src/policy/default-engine.ts
|
|
54719
|
-
var DefaultPolicyEngine;
|
|
54720
|
-
var init_default_engine = __esm({
|
|
54721
|
-
"src/policy/default-engine.ts"() {
|
|
54722
|
-
"use strict";
|
|
54723
|
-
DefaultPolicyEngine = class {
|
|
54724
|
-
async initialize(_config) {
|
|
54725
|
-
}
|
|
54726
|
-
async evaluateCheckExecution(_checkId, _checkConfig) {
|
|
54727
|
-
return { allowed: true };
|
|
54728
|
-
}
|
|
54729
|
-
async evaluateToolInvocation(_serverName, _methodName, _transport) {
|
|
54730
|
-
return { allowed: true };
|
|
54731
|
-
}
|
|
54732
|
-
async evaluateCapabilities(_checkId, _capabilities) {
|
|
54733
|
-
return { allowed: true };
|
|
54734
|
-
}
|
|
54735
|
-
async shutdown() {
|
|
54736
|
-
}
|
|
54737
|
-
};
|
|
54738
|
-
}
|
|
54739
|
-
});
|
|
54740
|
-
|
|
54741
|
-
// src/enterprise/license/validator.ts
|
|
54742
|
-
var validator_exports = {};
|
|
54743
|
-
__export(validator_exports, {
|
|
54744
|
-
LicenseValidator: () => LicenseValidator
|
|
54745
|
-
});
|
|
54746
|
-
var crypto2, fs21, path25, LicenseValidator;
|
|
54747
|
-
var init_validator = __esm({
|
|
54748
|
-
"src/enterprise/license/validator.ts"() {
|
|
54749
|
-
"use strict";
|
|
54750
|
-
crypto2 = __toESM(require("crypto"));
|
|
54751
|
-
fs21 = __toESM(require("fs"));
|
|
54752
|
-
path25 = __toESM(require("path"));
|
|
54753
|
-
LicenseValidator = class _LicenseValidator {
|
|
54754
|
-
/** Ed25519 public key for license verification (PEM format). */
|
|
54755
|
-
static PUBLIC_KEY = "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAI/Zd08EFmgIdrDm/HXd0l3/5GBt7R1PrdvhdmEXhJlU=\n-----END PUBLIC KEY-----\n";
|
|
54756
|
-
cache = null;
|
|
54757
|
-
static CACHE_TTL = 5 * 60 * 1e3;
|
|
54758
|
-
// 5 minutes
|
|
54759
|
-
static GRACE_PERIOD = 72 * 3600 * 1e3;
|
|
54760
|
-
// 72 hours after expiry
|
|
54761
|
-
/**
|
|
54762
|
-
* Load and validate license from environment or file.
|
|
54763
|
-
*
|
|
54764
|
-
* Resolution order:
|
|
54765
|
-
* 1. VISOR_LICENSE env var (JWT string)
|
|
54766
|
-
* 2. VISOR_LICENSE_FILE env var (path to file)
|
|
54767
|
-
* 3. .visor-license in project root (cwd)
|
|
54768
|
-
* 4. .visor-license in ~/.config/visor/
|
|
54769
|
-
*/
|
|
54770
|
-
async loadAndValidate() {
|
|
54771
|
-
if (this.cache && Date.now() - this.cache.validatedAt < _LicenseValidator.CACHE_TTL) {
|
|
54772
|
-
return this.cache.payload;
|
|
54773
|
-
}
|
|
54774
|
-
const token = this.resolveToken();
|
|
54775
|
-
if (!token) return null;
|
|
54776
|
-
const payload = this.verifyAndDecode(token);
|
|
54777
|
-
if (!payload) return null;
|
|
54778
|
-
this.cache = { payload, validatedAt: Date.now() };
|
|
54779
|
-
return payload;
|
|
54780
|
-
}
|
|
54781
|
-
/** Check if a specific feature is licensed */
|
|
54782
|
-
hasFeature(feature) {
|
|
54783
|
-
if (!this.cache) return false;
|
|
54784
|
-
return this.cache.payload.features.includes(feature);
|
|
54785
|
-
}
|
|
54786
|
-
/** Check if license is valid (with grace period) */
|
|
54787
|
-
isValid() {
|
|
54788
|
-
if (!this.cache) return false;
|
|
54789
|
-
const now = Date.now();
|
|
54790
|
-
const expiryMs = this.cache.payload.exp * 1e3;
|
|
54791
|
-
return now < expiryMs + _LicenseValidator.GRACE_PERIOD;
|
|
54792
|
-
}
|
|
54793
|
-
/** Check if the license is within its grace period (expired but still valid) */
|
|
54794
|
-
isInGracePeriod() {
|
|
54795
|
-
if (!this.cache) return false;
|
|
54796
|
-
const now = Date.now();
|
|
54797
|
-
const expiryMs = this.cache.payload.exp * 1e3;
|
|
54798
|
-
return now >= expiryMs && now < expiryMs + _LicenseValidator.GRACE_PERIOD;
|
|
54799
|
-
}
|
|
54800
|
-
resolveToken() {
|
|
54801
|
-
if (process.env.VISOR_LICENSE) {
|
|
54802
|
-
return process.env.VISOR_LICENSE.trim();
|
|
54803
|
-
}
|
|
54804
|
-
if (process.env.VISOR_LICENSE_FILE) {
|
|
54805
|
-
const resolved = path25.resolve(process.env.VISOR_LICENSE_FILE);
|
|
54806
|
-
const home2 = process.env.HOME || process.env.USERPROFILE || "";
|
|
54807
|
-
const allowedPrefixes = [path25.normalize(process.cwd())];
|
|
54808
|
-
if (home2) allowedPrefixes.push(path25.normalize(path25.join(home2, ".config", "visor")));
|
|
54809
|
-
let realPath;
|
|
54810
|
-
try {
|
|
54811
|
-
realPath = fs21.realpathSync(resolved);
|
|
54812
|
-
} catch {
|
|
54813
|
-
return null;
|
|
54814
|
-
}
|
|
54815
|
-
const isSafe = allowedPrefixes.some(
|
|
54816
|
-
(prefix) => realPath === prefix || realPath.startsWith(prefix + path25.sep)
|
|
54817
|
-
);
|
|
54818
|
-
if (!isSafe) return null;
|
|
54819
|
-
return this.readFile(realPath);
|
|
54820
|
-
}
|
|
54821
|
-
const cwdPath = path25.join(process.cwd(), ".visor-license");
|
|
54822
|
-
const cwdToken = this.readFile(cwdPath);
|
|
54823
|
-
if (cwdToken) return cwdToken;
|
|
54824
|
-
const home = process.env.HOME || process.env.USERPROFILE || "";
|
|
54825
|
-
if (home) {
|
|
54826
|
-
const configPath = path25.join(home, ".config", "visor", ".visor-license");
|
|
54827
|
-
const configToken = this.readFile(configPath);
|
|
54828
|
-
if (configToken) return configToken;
|
|
54829
|
-
}
|
|
54830
|
-
return null;
|
|
54831
|
-
}
|
|
54832
|
-
readFile(filePath) {
|
|
54833
|
-
try {
|
|
54834
|
-
return fs21.readFileSync(filePath, "utf-8").trim();
|
|
54835
|
-
} catch {
|
|
54836
|
-
return null;
|
|
54837
|
-
}
|
|
54838
|
-
}
|
|
54839
|
-
verifyAndDecode(token) {
|
|
54840
|
-
try {
|
|
54841
|
-
const parts = token.split(".");
|
|
54842
|
-
if (parts.length !== 3) return null;
|
|
54843
|
-
const [headerB64, payloadB64, signatureB64] = parts;
|
|
54844
|
-
const header = JSON.parse(Buffer.from(headerB64, "base64url").toString());
|
|
54845
|
-
if (header.alg !== "EdDSA") return null;
|
|
54846
|
-
const data = `${headerB64}.${payloadB64}`;
|
|
54847
|
-
const signature = Buffer.from(signatureB64, "base64url");
|
|
54848
|
-
const publicKey = crypto2.createPublicKey(_LicenseValidator.PUBLIC_KEY);
|
|
54849
|
-
if (publicKey.asymmetricKeyType !== "ed25519") {
|
|
54850
|
-
return null;
|
|
54851
|
-
}
|
|
54852
|
-
const isValid = crypto2.verify(null, Buffer.from(data), publicKey, signature);
|
|
54853
|
-
if (!isValid) return null;
|
|
54854
|
-
const payload = JSON.parse(Buffer.from(payloadB64, "base64url").toString());
|
|
54855
|
-
if (!payload.org || !Array.isArray(payload.features) || typeof payload.exp !== "number" || typeof payload.iat !== "number" || !payload.sub) {
|
|
54856
|
-
return null;
|
|
54857
|
-
}
|
|
54858
|
-
const now = Date.now();
|
|
54859
|
-
const expiryMs = payload.exp * 1e3;
|
|
54860
|
-
if (now >= expiryMs + _LicenseValidator.GRACE_PERIOD) {
|
|
54861
|
-
return null;
|
|
54862
|
-
}
|
|
54863
|
-
return payload;
|
|
54864
|
-
} catch {
|
|
54865
|
-
return null;
|
|
54866
|
-
}
|
|
54867
|
-
}
|
|
54868
|
-
};
|
|
54869
|
-
}
|
|
54870
|
-
});
|
|
54871
|
-
|
|
54872
|
-
// src/enterprise/policy/opa-compiler.ts
|
|
54873
|
-
var fs22, path26, os2, crypto3, import_child_process8, OpaCompiler;
|
|
54874
|
-
var init_opa_compiler = __esm({
|
|
54875
|
-
"src/enterprise/policy/opa-compiler.ts"() {
|
|
54876
|
-
"use strict";
|
|
54877
|
-
fs22 = __toESM(require("fs"));
|
|
54878
|
-
path26 = __toESM(require("path"));
|
|
54879
|
-
os2 = __toESM(require("os"));
|
|
54880
|
-
crypto3 = __toESM(require("crypto"));
|
|
54881
|
-
import_child_process8 = require("child_process");
|
|
54882
|
-
OpaCompiler = class _OpaCompiler {
|
|
54883
|
-
static CACHE_DIR = path26.join(os2.tmpdir(), "visor-opa-cache");
|
|
54884
|
-
/**
|
|
54885
|
-
* Resolve the input paths to WASM bytes.
|
|
54886
|
-
*
|
|
54887
|
-
* Strategy:
|
|
54888
|
-
* 1. If any path is a .wasm file, read it directly
|
|
54889
|
-
* 2. If a directory contains policy.wasm, read it
|
|
54890
|
-
* 3. Otherwise, collect all .rego files and auto-compile via `opa build`
|
|
54891
|
-
*/
|
|
54892
|
-
async resolveWasmBytes(paths) {
|
|
54893
|
-
const regoFiles = [];
|
|
54894
|
-
for (const p of paths) {
|
|
54895
|
-
const resolved = path26.resolve(p);
|
|
54896
|
-
if (path26.normalize(resolved).includes("..")) {
|
|
54897
|
-
throw new Error(`Policy path contains traversal sequences: ${p}`);
|
|
54898
|
-
}
|
|
54899
|
-
if (resolved.endsWith(".wasm") && fs22.existsSync(resolved)) {
|
|
54900
|
-
return fs22.readFileSync(resolved);
|
|
54901
|
-
}
|
|
54902
|
-
if (!fs22.existsSync(resolved)) continue;
|
|
54903
|
-
const stat2 = fs22.statSync(resolved);
|
|
54904
|
-
if (stat2.isDirectory()) {
|
|
54905
|
-
const wasmCandidate = path26.join(resolved, "policy.wasm");
|
|
54906
|
-
if (fs22.existsSync(wasmCandidate)) {
|
|
54907
|
-
return fs22.readFileSync(wasmCandidate);
|
|
54908
|
-
}
|
|
54909
|
-
const files = fs22.readdirSync(resolved);
|
|
54910
|
-
for (const f of files) {
|
|
54911
|
-
if (f.endsWith(".rego")) {
|
|
54912
|
-
regoFiles.push(path26.join(resolved, f));
|
|
54913
|
-
}
|
|
54914
|
-
}
|
|
54915
|
-
} else if (resolved.endsWith(".rego")) {
|
|
54916
|
-
regoFiles.push(resolved);
|
|
54917
|
-
}
|
|
54918
|
-
}
|
|
54919
|
-
if (regoFiles.length === 0) {
|
|
54920
|
-
throw new Error(
|
|
54921
|
-
`OPA WASM evaluator: no .wasm bundle or .rego files found in: ${paths.join(", ")}`
|
|
54922
|
-
);
|
|
54923
|
-
}
|
|
54924
|
-
return this.compileRego(regoFiles);
|
|
54925
|
-
}
|
|
54926
|
-
/**
|
|
54927
|
-
* Auto-compile .rego files to a WASM bundle using the `opa` CLI.
|
|
54928
|
-
*
|
|
54929
|
-
* Caches the compiled bundle based on a content hash of all input .rego files
|
|
54930
|
-
* so subsequent runs skip compilation if policies haven't changed.
|
|
54931
|
-
*/
|
|
54932
|
-
compileRego(regoFiles) {
|
|
54933
|
-
try {
|
|
54934
|
-
(0, import_child_process8.execFileSync)("opa", ["version"], { stdio: "pipe" });
|
|
54935
|
-
} catch {
|
|
54936
|
-
throw new Error(
|
|
54937
|
-
"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(" ")
|
|
54938
|
-
);
|
|
54939
|
-
}
|
|
54940
|
-
const hash = crypto3.createHash("sha256");
|
|
54941
|
-
for (const f of regoFiles.sort()) {
|
|
54942
|
-
hash.update(fs22.readFileSync(f));
|
|
54943
|
-
hash.update(f);
|
|
54944
|
-
}
|
|
54945
|
-
const cacheKey = hash.digest("hex").slice(0, 16);
|
|
54946
|
-
const cacheDir = _OpaCompiler.CACHE_DIR;
|
|
54947
|
-
const cachedWasm = path26.join(cacheDir, `${cacheKey}.wasm`);
|
|
54948
|
-
if (fs22.existsSync(cachedWasm)) {
|
|
54949
|
-
return fs22.readFileSync(cachedWasm);
|
|
54950
|
-
}
|
|
54951
|
-
fs22.mkdirSync(cacheDir, { recursive: true });
|
|
54952
|
-
const bundleTar = path26.join(cacheDir, `${cacheKey}-bundle.tar.gz`);
|
|
54953
|
-
try {
|
|
54954
|
-
const args = [
|
|
54955
|
-
"build",
|
|
54956
|
-
"-t",
|
|
54957
|
-
"wasm",
|
|
54958
|
-
"-e",
|
|
54959
|
-
"visor",
|
|
54960
|
-
// entrypoint: the visor package tree
|
|
54961
|
-
"-o",
|
|
54962
|
-
bundleTar,
|
|
54963
|
-
...regoFiles
|
|
54964
|
-
];
|
|
54965
|
-
(0, import_child_process8.execFileSync)("opa", args, {
|
|
54966
|
-
stdio: "pipe",
|
|
54967
|
-
timeout: 3e4
|
|
54968
|
-
});
|
|
54969
|
-
} catch (err) {
|
|
54970
|
-
const stderr = err?.stderr?.toString() || "";
|
|
54971
|
-
throw new Error(
|
|
54972
|
-
`Failed to compile .rego files to WASM:
|
|
54973
|
-
${stderr}
|
|
54974
|
-
Ensure your .rego files are valid and the \`opa\` CLI is installed.`
|
|
54975
|
-
);
|
|
54976
|
-
}
|
|
54977
|
-
try {
|
|
54978
|
-
(0, import_child_process8.execFileSync)("tar", ["-xzf", bundleTar, "-C", cacheDir, "/policy.wasm"], {
|
|
54979
|
-
stdio: "pipe"
|
|
54980
|
-
});
|
|
54981
|
-
const extractedWasm = path26.join(cacheDir, "policy.wasm");
|
|
54982
|
-
if (fs22.existsSync(extractedWasm)) {
|
|
54983
|
-
fs22.renameSync(extractedWasm, cachedWasm);
|
|
54984
|
-
}
|
|
54985
|
-
} catch {
|
|
54986
|
-
try {
|
|
54987
|
-
(0, import_child_process8.execFileSync)("tar", ["-xzf", bundleTar, "-C", cacheDir, "policy.wasm"], {
|
|
54988
|
-
stdio: "pipe"
|
|
54989
|
-
});
|
|
54990
|
-
const extractedWasm = path26.join(cacheDir, "policy.wasm");
|
|
54991
|
-
if (fs22.existsSync(extractedWasm)) {
|
|
54992
|
-
fs22.renameSync(extractedWasm, cachedWasm);
|
|
54993
|
-
}
|
|
54994
|
-
} catch (err2) {
|
|
54995
|
-
throw new Error(`Failed to extract policy.wasm from OPA bundle: ${err2?.message || err2}`);
|
|
54996
|
-
}
|
|
54997
|
-
}
|
|
54998
|
-
try {
|
|
54999
|
-
fs22.unlinkSync(bundleTar);
|
|
55000
|
-
} catch {
|
|
55001
|
-
}
|
|
55002
|
-
if (!fs22.existsSync(cachedWasm)) {
|
|
55003
|
-
throw new Error("OPA build succeeded but policy.wasm was not found in the bundle");
|
|
55004
|
-
}
|
|
55005
|
-
return fs22.readFileSync(cachedWasm);
|
|
55006
|
-
}
|
|
55007
|
-
};
|
|
55008
|
-
}
|
|
55009
|
-
});
|
|
55010
|
-
|
|
55011
|
-
// src/enterprise/policy/opa-wasm-evaluator.ts
|
|
55012
|
-
var fs23, path27, OpaWasmEvaluator;
|
|
55013
|
-
var init_opa_wasm_evaluator = __esm({
|
|
55014
|
-
"src/enterprise/policy/opa-wasm-evaluator.ts"() {
|
|
55015
|
-
"use strict";
|
|
55016
|
-
fs23 = __toESM(require("fs"));
|
|
55017
|
-
path27 = __toESM(require("path"));
|
|
55018
|
-
init_opa_compiler();
|
|
55019
|
-
OpaWasmEvaluator = class {
|
|
55020
|
-
policy = null;
|
|
55021
|
-
dataDocument = {};
|
|
55022
|
-
compiler = new OpaCompiler();
|
|
55023
|
-
async initialize(rulesPath) {
|
|
55024
|
-
const paths = Array.isArray(rulesPath) ? rulesPath : [rulesPath];
|
|
55025
|
-
const wasmBytes = await this.compiler.resolveWasmBytes(paths);
|
|
55026
|
-
try {
|
|
55027
|
-
const { createRequire } = require("module");
|
|
55028
|
-
const runtimeRequire = createRequire(__filename);
|
|
55029
|
-
const opaWasm = runtimeRequire("@open-policy-agent/opa-wasm");
|
|
55030
|
-
const loadPolicy = opaWasm.loadPolicy || opaWasm.default?.loadPolicy;
|
|
55031
|
-
if (!loadPolicy) {
|
|
55032
|
-
throw new Error("loadPolicy not found in @open-policy-agent/opa-wasm");
|
|
55033
|
-
}
|
|
55034
|
-
this.policy = await loadPolicy(wasmBytes);
|
|
55035
|
-
} catch (err) {
|
|
55036
|
-
if (err?.code === "MODULE_NOT_FOUND" || err?.code === "ERR_MODULE_NOT_FOUND") {
|
|
55037
|
-
throw new Error(
|
|
55038
|
-
"OPA WASM evaluator requires @open-policy-agent/opa-wasm. Install it with: npm install @open-policy-agent/opa-wasm"
|
|
55039
|
-
);
|
|
55040
|
-
}
|
|
55041
|
-
throw err;
|
|
55042
|
-
}
|
|
55043
|
-
}
|
|
55044
|
-
/**
|
|
55045
|
-
* Load external data from a JSON file to use as the OPA data document.
|
|
55046
|
-
* The loaded data will be passed to `policy.setData()` during evaluation,
|
|
55047
|
-
* making it available in Rego via `data.<key>`.
|
|
55048
|
-
*/
|
|
55049
|
-
loadData(dataPath) {
|
|
55050
|
-
const resolved = path27.resolve(dataPath);
|
|
55051
|
-
if (path27.normalize(resolved).includes("..")) {
|
|
55052
|
-
throw new Error(`Data path contains traversal sequences: ${dataPath}`);
|
|
55053
|
-
}
|
|
55054
|
-
if (!fs23.existsSync(resolved)) {
|
|
55055
|
-
throw new Error(`OPA data file not found: ${resolved}`);
|
|
55056
|
-
}
|
|
55057
|
-
const stat2 = fs23.statSync(resolved);
|
|
55058
|
-
if (stat2.size > 10 * 1024 * 1024) {
|
|
55059
|
-
throw new Error(`OPA data file exceeds 10MB limit: ${resolved} (${stat2.size} bytes)`);
|
|
55060
|
-
}
|
|
55061
|
-
const raw = fs23.readFileSync(resolved, "utf-8");
|
|
55062
|
-
try {
|
|
55063
|
-
const parsed = JSON.parse(raw);
|
|
55064
|
-
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
55065
|
-
throw new Error("OPA data file must contain a JSON object (not an array or primitive)");
|
|
55066
|
-
}
|
|
55067
|
-
this.dataDocument = parsed;
|
|
55068
|
-
} catch (err) {
|
|
55069
|
-
if (err.message.startsWith("OPA data file must")) {
|
|
55070
|
-
throw err;
|
|
55071
|
-
}
|
|
55072
|
-
throw new Error(`Failed to parse OPA data file ${resolved}: ${err.message}`);
|
|
55073
|
-
}
|
|
55074
|
-
}
|
|
55075
|
-
async evaluate(input) {
|
|
55076
|
-
if (!this.policy) {
|
|
55077
|
-
throw new Error("OPA WASM evaluator not initialized");
|
|
55078
|
-
}
|
|
55079
|
-
this.policy.setData(this.dataDocument);
|
|
55080
|
-
const resultSet = this.policy.evaluate(input);
|
|
55081
|
-
if (Array.isArray(resultSet) && resultSet.length > 0) {
|
|
55082
|
-
return resultSet[0].result;
|
|
55083
|
-
}
|
|
55084
|
-
return void 0;
|
|
55085
|
-
}
|
|
55086
|
-
async shutdown() {
|
|
55087
|
-
if (this.policy) {
|
|
55088
|
-
if (typeof this.policy.close === "function") {
|
|
55089
|
-
try {
|
|
55090
|
-
this.policy.close();
|
|
55091
|
-
} catch {
|
|
55092
|
-
}
|
|
55093
|
-
} else if (typeof this.policy.free === "function") {
|
|
55094
|
-
try {
|
|
55095
|
-
this.policy.free();
|
|
55096
|
-
} catch {
|
|
55097
|
-
}
|
|
55098
|
-
}
|
|
55099
|
-
}
|
|
55100
|
-
this.policy = null;
|
|
55101
|
-
}
|
|
55102
|
-
};
|
|
55103
|
-
}
|
|
55104
|
-
});
|
|
55105
|
-
|
|
55106
|
-
// src/enterprise/policy/opa-http-evaluator.ts
|
|
55107
|
-
var OpaHttpEvaluator;
|
|
55108
|
-
var init_opa_http_evaluator = __esm({
|
|
55109
|
-
"src/enterprise/policy/opa-http-evaluator.ts"() {
|
|
55110
|
-
"use strict";
|
|
55111
|
-
OpaHttpEvaluator = class {
|
|
55112
|
-
baseUrl;
|
|
55113
|
-
timeout;
|
|
55114
|
-
constructor(baseUrl, timeout = 5e3) {
|
|
55115
|
-
let parsed;
|
|
55116
|
-
try {
|
|
55117
|
-
parsed = new URL(baseUrl);
|
|
55118
|
-
} catch {
|
|
55119
|
-
throw new Error(`OPA HTTP evaluator: invalid URL: ${baseUrl}`);
|
|
55120
|
-
}
|
|
55121
|
-
if (!["http:", "https:"].includes(parsed.protocol)) {
|
|
55122
|
-
throw new Error(
|
|
55123
|
-
`OPA HTTP evaluator: url must use http:// or https:// protocol, got: ${baseUrl}`
|
|
55124
|
-
);
|
|
55125
|
-
}
|
|
55126
|
-
const hostname = parsed.hostname;
|
|
55127
|
-
if (this.isBlockedHostname(hostname)) {
|
|
55128
|
-
throw new Error(
|
|
55129
|
-
`OPA HTTP evaluator: url must not point to internal, loopback, or private network addresses`
|
|
55130
|
-
);
|
|
55131
|
-
}
|
|
55132
|
-
this.baseUrl = baseUrl.replace(/\/+$/, "");
|
|
55133
|
-
this.timeout = timeout;
|
|
55134
|
-
}
|
|
55135
|
-
/**
|
|
55136
|
-
* Check if a hostname is blocked due to SSRF concerns.
|
|
55137
|
-
*
|
|
55138
|
-
* Blocks:
|
|
55139
|
-
* - Loopback addresses (127.x.x.x, localhost, 0.0.0.0, ::1)
|
|
55140
|
-
* - Link-local addresses (169.254.x.x)
|
|
55141
|
-
* - Private networks (10.x.x.x, 172.16-31.x.x, 192.168.x.x)
|
|
55142
|
-
* - IPv6 unique local addresses (fd00::/8)
|
|
55143
|
-
* - Cloud metadata services (*.internal)
|
|
55144
|
-
*/
|
|
55145
|
-
isBlockedHostname(hostname) {
|
|
55146
|
-
if (!hostname) return true;
|
|
55147
|
-
const normalized = hostname.toLowerCase().replace(/^\[|\]$/g, "");
|
|
55148
|
-
if (normalized === "metadata.google.internal" || normalized.endsWith(".internal")) {
|
|
55149
|
-
return true;
|
|
55150
|
-
}
|
|
55151
|
-
if (normalized === "localhost" || normalized === "localhost.localdomain") {
|
|
55152
|
-
return true;
|
|
55153
|
-
}
|
|
55154
|
-
if (normalized === "::1" || normalized === "0:0:0:0:0:0:0:1") {
|
|
55155
|
-
return true;
|
|
55156
|
-
}
|
|
55157
|
-
const ipv4Pattern = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/;
|
|
55158
|
-
const ipv4Match = normalized.match(ipv4Pattern);
|
|
55159
|
-
if (ipv4Match) {
|
|
55160
|
-
const octets = ipv4Match.slice(1, 5).map(Number);
|
|
55161
|
-
if (octets.some((octet) => octet > 255)) {
|
|
55162
|
-
return false;
|
|
55163
|
-
}
|
|
55164
|
-
const [a, b] = octets;
|
|
55165
|
-
if (a === 127) {
|
|
55166
|
-
return true;
|
|
55167
|
-
}
|
|
55168
|
-
if (a === 0) {
|
|
55169
|
-
return true;
|
|
55170
|
-
}
|
|
55171
|
-
if (a === 169 && b === 254) {
|
|
55172
|
-
return true;
|
|
55173
|
-
}
|
|
55174
|
-
if (a === 10) {
|
|
55175
|
-
return true;
|
|
55176
|
-
}
|
|
55177
|
-
if (a === 172 && b >= 16 && b <= 31) {
|
|
55178
|
-
return true;
|
|
55179
|
-
}
|
|
55180
|
-
if (a === 192 && b === 168) {
|
|
55181
|
-
return true;
|
|
55182
|
-
}
|
|
55183
|
-
}
|
|
55184
|
-
if (normalized.startsWith("fd") || normalized.startsWith("fc")) {
|
|
55185
|
-
return true;
|
|
55186
|
-
}
|
|
55187
|
-
if (normalized.startsWith("fe80:")) {
|
|
55188
|
-
return true;
|
|
55189
|
-
}
|
|
55190
|
-
return false;
|
|
55191
|
-
}
|
|
55192
|
-
/**
|
|
55193
|
-
* Evaluate a policy rule against an input document via OPA REST API.
|
|
55194
|
-
*
|
|
55195
|
-
* @param input - The input document to evaluate
|
|
55196
|
-
* @param rulePath - OPA rule path (e.g., 'visor/check/execute')
|
|
55197
|
-
* @returns The result object from OPA, or undefined on error
|
|
55198
|
-
*/
|
|
55199
|
-
async evaluate(input, rulePath) {
|
|
55200
|
-
const encodedPath = rulePath.split("/").map((s) => encodeURIComponent(s)).join("/");
|
|
55201
|
-
const url = `${this.baseUrl}/v1/data/${encodedPath}`;
|
|
55202
|
-
const controller = new AbortController();
|
|
55203
|
-
const timer = setTimeout(() => controller.abort(), this.timeout);
|
|
55204
|
-
try {
|
|
55205
|
-
const response = await fetch(url, {
|
|
55206
|
-
method: "POST",
|
|
55207
|
-
headers: { "Content-Type": "application/json" },
|
|
55208
|
-
body: JSON.stringify({ input }),
|
|
55209
|
-
signal: controller.signal
|
|
55210
|
-
});
|
|
55211
|
-
if (!response.ok) {
|
|
55212
|
-
throw new Error(`OPA HTTP ${response.status}: ${response.statusText}`);
|
|
55213
|
-
}
|
|
55214
|
-
let body;
|
|
55215
|
-
try {
|
|
55216
|
-
body = await response.json();
|
|
55217
|
-
} catch (jsonErr) {
|
|
55218
|
-
throw new Error(
|
|
55219
|
-
`OPA HTTP evaluator: failed to parse JSON response: ${jsonErr instanceof Error ? jsonErr.message : String(jsonErr)}`
|
|
55220
|
-
);
|
|
55221
|
-
}
|
|
55222
|
-
return body?.result;
|
|
55223
|
-
} finally {
|
|
55224
|
-
clearTimeout(timer);
|
|
55225
|
-
}
|
|
55226
|
-
}
|
|
55227
|
-
async shutdown() {
|
|
55228
|
-
}
|
|
55229
|
-
};
|
|
55230
|
-
}
|
|
55231
|
-
});
|
|
55232
|
-
|
|
55233
|
-
// src/enterprise/policy/policy-input-builder.ts
|
|
55234
|
-
var PolicyInputBuilder;
|
|
55235
|
-
var init_policy_input_builder = __esm({
|
|
55236
|
-
"src/enterprise/policy/policy-input-builder.ts"() {
|
|
55237
|
-
"use strict";
|
|
55238
|
-
PolicyInputBuilder = class {
|
|
55239
|
-
roles;
|
|
55240
|
-
actor;
|
|
55241
|
-
repository;
|
|
55242
|
-
pullRequest;
|
|
55243
|
-
constructor(policyConfig, actor, repository, pullRequest) {
|
|
55244
|
-
this.roles = policyConfig.roles || {};
|
|
55245
|
-
this.actor = actor;
|
|
55246
|
-
this.repository = repository;
|
|
55247
|
-
this.pullRequest = pullRequest;
|
|
55248
|
-
}
|
|
55249
|
-
/** Resolve which roles apply to the current actor. */
|
|
55250
|
-
resolveRoles() {
|
|
55251
|
-
const matched = [];
|
|
55252
|
-
for (const [roleName, roleConfig] of Object.entries(this.roles)) {
|
|
55253
|
-
let identityMatch = false;
|
|
55254
|
-
if (roleConfig.author_association && this.actor.authorAssociation && roleConfig.author_association.includes(this.actor.authorAssociation)) {
|
|
55255
|
-
identityMatch = true;
|
|
55256
|
-
}
|
|
55257
|
-
if (!identityMatch && roleConfig.users && this.actor.login && roleConfig.users.includes(this.actor.login)) {
|
|
55258
|
-
identityMatch = true;
|
|
55259
|
-
}
|
|
55260
|
-
if (!identityMatch && roleConfig.slack_users && this.actor.slack?.userId && roleConfig.slack_users.includes(this.actor.slack.userId)) {
|
|
55261
|
-
identityMatch = true;
|
|
55262
|
-
}
|
|
55263
|
-
if (!identityMatch && roleConfig.emails && this.actor.slack?.email) {
|
|
55264
|
-
const actorEmail = this.actor.slack.email.toLowerCase();
|
|
55265
|
-
if (roleConfig.emails.some((e) => e.toLowerCase() === actorEmail)) {
|
|
55266
|
-
identityMatch = true;
|
|
55267
|
-
}
|
|
55268
|
-
}
|
|
55269
|
-
if (!identityMatch) continue;
|
|
55270
|
-
if (roleConfig.slack_channels && roleConfig.slack_channels.length > 0) {
|
|
55271
|
-
if (!this.actor.slack?.channelId || !roleConfig.slack_channels.includes(this.actor.slack.channelId)) {
|
|
55272
|
-
continue;
|
|
55273
|
-
}
|
|
55274
|
-
}
|
|
55275
|
-
matched.push(roleName);
|
|
55276
|
-
}
|
|
55277
|
-
return matched;
|
|
55278
|
-
}
|
|
55279
|
-
buildActor() {
|
|
55280
|
-
return {
|
|
55281
|
-
authorAssociation: this.actor.authorAssociation,
|
|
55282
|
-
login: this.actor.login,
|
|
55283
|
-
roles: this.resolveRoles(),
|
|
55284
|
-
isLocalMode: this.actor.isLocalMode,
|
|
55285
|
-
...this.actor.slack && { slack: this.actor.slack }
|
|
55286
|
-
};
|
|
55287
|
-
}
|
|
55288
|
-
forCheckExecution(check) {
|
|
55289
|
-
return {
|
|
55290
|
-
scope: "check.execute",
|
|
55291
|
-
check: {
|
|
55292
|
-
id: check.id,
|
|
55293
|
-
type: check.type,
|
|
55294
|
-
group: check.group,
|
|
55295
|
-
tags: check.tags,
|
|
55296
|
-
criticality: check.criticality,
|
|
55297
|
-
sandbox: check.sandbox,
|
|
55298
|
-
policy: check.policy
|
|
55299
|
-
},
|
|
55300
|
-
actor: this.buildActor(),
|
|
55301
|
-
repository: this.repository,
|
|
55302
|
-
pullRequest: this.pullRequest
|
|
55303
|
-
};
|
|
55304
|
-
}
|
|
55305
|
-
forToolInvocation(serverName, methodName, transport) {
|
|
55306
|
-
return {
|
|
55307
|
-
scope: "tool.invoke",
|
|
55308
|
-
tool: { serverName, methodName, transport },
|
|
55309
|
-
actor: this.buildActor(),
|
|
55310
|
-
repository: this.repository,
|
|
55311
|
-
pullRequest: this.pullRequest
|
|
55312
|
-
};
|
|
55313
|
-
}
|
|
55314
|
-
forCapabilityResolve(checkId, capabilities) {
|
|
55315
|
-
return {
|
|
55316
|
-
scope: "capability.resolve",
|
|
55317
|
-
check: { id: checkId, type: "ai" },
|
|
55318
|
-
capability: capabilities,
|
|
55319
|
-
actor: this.buildActor(),
|
|
55320
|
-
repository: this.repository,
|
|
55321
|
-
pullRequest: this.pullRequest
|
|
55322
|
-
};
|
|
55323
|
-
}
|
|
55324
|
-
};
|
|
55325
|
-
}
|
|
55326
|
-
});
|
|
55327
|
-
|
|
55328
|
-
// src/enterprise/policy/opa-policy-engine.ts
|
|
55329
|
-
var opa_policy_engine_exports = {};
|
|
55330
|
-
__export(opa_policy_engine_exports, {
|
|
55331
|
-
OpaPolicyEngine: () => OpaPolicyEngine
|
|
55332
|
-
});
|
|
55333
|
-
var OpaPolicyEngine;
|
|
55334
|
-
var init_opa_policy_engine = __esm({
|
|
55335
|
-
"src/enterprise/policy/opa-policy-engine.ts"() {
|
|
55336
|
-
"use strict";
|
|
55337
|
-
init_opa_wasm_evaluator();
|
|
55338
|
-
init_opa_http_evaluator();
|
|
55339
|
-
init_policy_input_builder();
|
|
55340
|
-
OpaPolicyEngine = class {
|
|
55341
|
-
evaluator = null;
|
|
55342
|
-
fallback;
|
|
55343
|
-
timeout;
|
|
55344
|
-
config;
|
|
55345
|
-
inputBuilder = null;
|
|
55346
|
-
logger = null;
|
|
55347
|
-
constructor(config) {
|
|
55348
|
-
this.config = config;
|
|
55349
|
-
this.fallback = config.fallback || "deny";
|
|
55350
|
-
this.timeout = config.timeout || 5e3;
|
|
55351
|
-
}
|
|
55352
|
-
async initialize(config) {
|
|
55353
|
-
try {
|
|
55354
|
-
this.logger = (init_logger(), __toCommonJS(logger_exports)).logger;
|
|
55355
|
-
} catch {
|
|
55356
|
-
}
|
|
55357
|
-
const actor = {
|
|
55358
|
-
authorAssociation: process.env.VISOR_AUTHOR_ASSOCIATION,
|
|
55359
|
-
login: process.env.VISOR_AUTHOR_LOGIN || process.env.GITHUB_ACTOR,
|
|
55360
|
-
isLocalMode: !process.env.GITHUB_ACTIONS
|
|
55361
|
-
};
|
|
55362
|
-
const repo = {
|
|
55363
|
-
owner: process.env.GITHUB_REPOSITORY_OWNER,
|
|
55364
|
-
name: process.env.GITHUB_REPOSITORY?.split("/")[1],
|
|
55365
|
-
branch: process.env.GITHUB_HEAD_REF,
|
|
55366
|
-
baseBranch: process.env.GITHUB_BASE_REF,
|
|
55367
|
-
event: process.env.GITHUB_EVENT_NAME
|
|
55368
|
-
};
|
|
55369
|
-
const prNum = process.env.GITHUB_PR_NUMBER ? parseInt(process.env.GITHUB_PR_NUMBER, 10) : void 0;
|
|
55370
|
-
const pullRequest = {
|
|
55371
|
-
number: prNum !== void 0 && Number.isFinite(prNum) ? prNum : void 0
|
|
55372
|
-
};
|
|
55373
|
-
this.inputBuilder = new PolicyInputBuilder(config, actor, repo, pullRequest);
|
|
55374
|
-
if (config.engine === "local") {
|
|
55375
|
-
if (!config.rules) {
|
|
55376
|
-
throw new Error("OPA local mode requires `policy.rules` path to .wasm or .rego files");
|
|
55377
|
-
}
|
|
55378
|
-
const wasm = new OpaWasmEvaluator();
|
|
55379
|
-
await wasm.initialize(config.rules);
|
|
55380
|
-
if (config.data) {
|
|
55381
|
-
wasm.loadData(config.data);
|
|
55382
|
-
}
|
|
55383
|
-
this.evaluator = wasm;
|
|
55384
|
-
} else if (config.engine === "remote") {
|
|
55385
|
-
if (!config.url) {
|
|
55386
|
-
throw new Error("OPA remote mode requires `policy.url` pointing to OPA server");
|
|
55387
|
-
}
|
|
55388
|
-
this.evaluator = new OpaHttpEvaluator(config.url, this.timeout);
|
|
55389
|
-
} else {
|
|
55390
|
-
this.evaluator = null;
|
|
55391
|
-
}
|
|
55392
|
-
}
|
|
55393
|
-
/**
|
|
55394
|
-
* Update actor/repo/PR context (e.g., after PR info becomes available).
|
|
55395
|
-
* Called by the enterprise loader when engine context is enriched.
|
|
55396
|
-
*/
|
|
55397
|
-
setActorContext(actor, repo, pullRequest) {
|
|
55398
|
-
this.inputBuilder = new PolicyInputBuilder(this.config, actor, repo, pullRequest);
|
|
55399
|
-
}
|
|
55400
|
-
async evaluateCheckExecution(checkId, checkConfig) {
|
|
55401
|
-
if (!this.evaluator || !this.inputBuilder) return { allowed: true };
|
|
55402
|
-
const cfg = checkConfig && typeof checkConfig === "object" ? checkConfig : {};
|
|
55403
|
-
const policyOverride = cfg.policy;
|
|
55404
|
-
const input = this.inputBuilder.forCheckExecution({
|
|
55405
|
-
id: checkId,
|
|
55406
|
-
type: cfg.type || "ai",
|
|
55407
|
-
group: cfg.group,
|
|
55408
|
-
tags: cfg.tags,
|
|
55409
|
-
criticality: cfg.criticality,
|
|
55410
|
-
sandbox: cfg.sandbox,
|
|
55411
|
-
policy: policyOverride
|
|
55412
|
-
});
|
|
55413
|
-
return this.doEvaluate(input, this.resolveRulePath("check.execute", policyOverride?.rule));
|
|
55414
|
-
}
|
|
55415
|
-
async evaluateToolInvocation(serverName, methodName, transport) {
|
|
55416
|
-
if (!this.evaluator || !this.inputBuilder) return { allowed: true };
|
|
55417
|
-
const input = this.inputBuilder.forToolInvocation(serverName, methodName, transport);
|
|
55418
|
-
return this.doEvaluate(input, "visor/tool/invoke");
|
|
55419
|
-
}
|
|
55420
|
-
async evaluateCapabilities(checkId, capabilities) {
|
|
55421
|
-
if (!this.evaluator || !this.inputBuilder) return { allowed: true };
|
|
55422
|
-
const input = this.inputBuilder.forCapabilityResolve(checkId, capabilities);
|
|
55423
|
-
return this.doEvaluate(input, "visor/capability/resolve");
|
|
55424
|
-
}
|
|
55425
|
-
async shutdown() {
|
|
55426
|
-
if (this.evaluator && "shutdown" in this.evaluator) {
|
|
55427
|
-
await this.evaluator.shutdown();
|
|
55428
|
-
}
|
|
55429
|
-
this.evaluator = null;
|
|
55430
|
-
this.inputBuilder = null;
|
|
55431
|
-
}
|
|
55432
|
-
resolveRulePath(defaultScope, override) {
|
|
55433
|
-
if (override) {
|
|
55434
|
-
return override.startsWith("visor/") ? override : `visor/${override}`;
|
|
55435
|
-
}
|
|
55436
|
-
return `visor/${defaultScope.replace(/\./g, "/")}`;
|
|
55437
|
-
}
|
|
55438
|
-
async doEvaluate(input, rulePath) {
|
|
55439
|
-
try {
|
|
55440
|
-
this.logger?.debug(`[PolicyEngine] Evaluating ${rulePath}`, JSON.stringify(input));
|
|
55441
|
-
let timer;
|
|
55442
|
-
const timeoutPromise = new Promise((_resolve, reject) => {
|
|
55443
|
-
timer = setTimeout(() => reject(new Error("policy evaluation timeout")), this.timeout);
|
|
55444
|
-
});
|
|
55445
|
-
try {
|
|
55446
|
-
const result = await Promise.race([this.rawEvaluate(input, rulePath), timeoutPromise]);
|
|
55447
|
-
const decision = this.parseDecision(result);
|
|
55448
|
-
if (!decision.allowed && this.fallback === "warn") {
|
|
55449
|
-
decision.allowed = true;
|
|
55450
|
-
decision.warn = true;
|
|
55451
|
-
decision.reason = `audit: ${decision.reason || "policy denied"}`;
|
|
55452
|
-
}
|
|
55453
|
-
this.logger?.debug(
|
|
55454
|
-
`[PolicyEngine] Decision for ${rulePath}: allowed=${decision.allowed}, warn=${decision.warn || false}, reason=${decision.reason || "none"}`
|
|
55455
|
-
);
|
|
55456
|
-
return decision;
|
|
55457
|
-
} finally {
|
|
55458
|
-
if (timer) clearTimeout(timer);
|
|
55459
|
-
}
|
|
55460
|
-
} catch (err) {
|
|
55461
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
55462
|
-
this.logger?.warn(`[PolicyEngine] Evaluation failed for ${rulePath}: ${msg}`);
|
|
55463
|
-
return {
|
|
55464
|
-
allowed: this.fallback === "allow" || this.fallback === "warn",
|
|
55465
|
-
warn: this.fallback === "warn" ? true : void 0,
|
|
55466
|
-
reason: `policy evaluation failed, fallback=${this.fallback}`
|
|
55467
|
-
};
|
|
55468
|
-
}
|
|
55469
|
-
}
|
|
55470
|
-
async rawEvaluate(input, rulePath) {
|
|
55471
|
-
if (this.evaluator instanceof OpaWasmEvaluator) {
|
|
55472
|
-
const result = await this.evaluator.evaluate(input);
|
|
55473
|
-
return this.navigateWasmResult(result, rulePath);
|
|
55474
|
-
}
|
|
55475
|
-
return this.evaluator.evaluate(input, rulePath);
|
|
55476
|
-
}
|
|
55477
|
-
/**
|
|
55478
|
-
* Navigate nested OPA WASM result tree to reach the specific rule's output.
|
|
55479
|
-
* The WASM entrypoint `-e visor` means the result root IS the visor package,
|
|
55480
|
-
* so we strip the `visor/` prefix and walk the remaining segments.
|
|
55481
|
-
*/
|
|
55482
|
-
navigateWasmResult(result, rulePath) {
|
|
55483
|
-
if (!result || typeof result !== "object") return result;
|
|
55484
|
-
const segments = rulePath.replace(/^visor\//, "").split("/");
|
|
55485
|
-
let current = result;
|
|
55486
|
-
for (const seg of segments) {
|
|
55487
|
-
if (current && typeof current === "object" && seg in current) {
|
|
55488
|
-
current = current[seg];
|
|
55489
|
-
} else {
|
|
55490
|
-
return void 0;
|
|
55491
|
-
}
|
|
55492
|
-
}
|
|
55493
|
-
return current;
|
|
55494
|
-
}
|
|
55495
|
-
parseDecision(result) {
|
|
55496
|
-
if (result === void 0 || result === null) {
|
|
55497
|
-
return {
|
|
55498
|
-
allowed: this.fallback === "allow" || this.fallback === "warn",
|
|
55499
|
-
warn: this.fallback === "warn" ? true : void 0,
|
|
55500
|
-
reason: this.fallback === "warn" ? "audit: no policy result" : "no policy result"
|
|
55501
|
-
};
|
|
55502
|
-
}
|
|
55503
|
-
const allowed = result.allowed !== false;
|
|
55504
|
-
const decision = {
|
|
55505
|
-
allowed,
|
|
55506
|
-
reason: result.reason
|
|
55507
|
-
};
|
|
55508
|
-
if (result.capabilities) {
|
|
55509
|
-
decision.capabilities = result.capabilities;
|
|
55510
|
-
}
|
|
55511
|
-
return decision;
|
|
55512
|
-
}
|
|
55513
|
-
};
|
|
55514
|
-
}
|
|
55515
|
-
});
|
|
55516
|
-
|
|
55517
|
-
// src/enterprise/scheduler/knex-store.ts
|
|
55518
|
-
var knex_store_exports = {};
|
|
55519
|
-
__export(knex_store_exports, {
|
|
55520
|
-
KnexStoreBackend: () => KnexStoreBackend
|
|
55521
|
-
});
|
|
55522
|
-
function toNum(val) {
|
|
55523
|
-
if (val === null || val === void 0) return void 0;
|
|
55524
|
-
return typeof val === "string" ? parseInt(val, 10) : val;
|
|
55525
|
-
}
|
|
55526
|
-
function safeJsonParse2(value) {
|
|
55527
|
-
if (!value) return void 0;
|
|
55528
|
-
try {
|
|
55529
|
-
return JSON.parse(value);
|
|
55530
|
-
} catch {
|
|
55531
|
-
return void 0;
|
|
55532
|
-
}
|
|
55533
|
-
}
|
|
55534
|
-
function fromTriggerRow2(row) {
|
|
55535
|
-
return {
|
|
55536
|
-
id: row.id,
|
|
55537
|
-
creatorId: row.creator_id,
|
|
55538
|
-
creatorContext: row.creator_context ?? void 0,
|
|
55539
|
-
creatorName: row.creator_name ?? void 0,
|
|
55540
|
-
description: row.description ?? void 0,
|
|
55541
|
-
channels: safeJsonParse2(row.channels),
|
|
55542
|
-
fromUsers: safeJsonParse2(row.from_users),
|
|
55543
|
-
fromBots: row.from_bots === true || row.from_bots === 1,
|
|
55544
|
-
contains: safeJsonParse2(row.contains),
|
|
55545
|
-
matchPattern: row.match_pattern ?? void 0,
|
|
55546
|
-
threads: row.threads,
|
|
55547
|
-
workflow: row.workflow,
|
|
55548
|
-
inputs: safeJsonParse2(row.inputs),
|
|
55549
|
-
outputContext: safeJsonParse2(row.output_context),
|
|
55550
|
-
status: row.status,
|
|
55551
|
-
enabled: row.enabled === true || row.enabled === 1,
|
|
55552
|
-
createdAt: toNum(row.created_at)
|
|
55553
|
-
};
|
|
55554
|
-
}
|
|
55555
|
-
function toTriggerInsertRow(trigger) {
|
|
55556
|
-
return {
|
|
55557
|
-
id: trigger.id,
|
|
55558
|
-
creator_id: trigger.creatorId,
|
|
55559
|
-
creator_context: trigger.creatorContext ?? null,
|
|
55560
|
-
creator_name: trigger.creatorName ?? null,
|
|
55561
|
-
description: trigger.description ?? null,
|
|
55562
|
-
channels: trigger.channels ? JSON.stringify(trigger.channels) : null,
|
|
55563
|
-
from_users: trigger.fromUsers ? JSON.stringify(trigger.fromUsers) : null,
|
|
55564
|
-
from_bots: trigger.fromBots,
|
|
55565
|
-
contains: trigger.contains ? JSON.stringify(trigger.contains) : null,
|
|
55566
|
-
match_pattern: trigger.matchPattern ?? null,
|
|
55567
|
-
threads: trigger.threads,
|
|
55568
|
-
workflow: trigger.workflow,
|
|
55569
|
-
inputs: trigger.inputs ? JSON.stringify(trigger.inputs) : null,
|
|
55570
|
-
output_context: trigger.outputContext ? JSON.stringify(trigger.outputContext) : null,
|
|
55571
|
-
status: trigger.status,
|
|
55572
|
-
enabled: trigger.enabled,
|
|
55573
|
-
created_at: trigger.createdAt
|
|
55574
|
-
};
|
|
55575
|
-
}
|
|
55576
|
-
function fromDbRow2(row) {
|
|
55577
|
-
return {
|
|
55578
|
-
id: row.id,
|
|
55579
|
-
creatorId: row.creator_id,
|
|
55580
|
-
creatorContext: row.creator_context ?? void 0,
|
|
55581
|
-
creatorName: row.creator_name ?? void 0,
|
|
55582
|
-
timezone: row.timezone,
|
|
55583
|
-
schedule: row.schedule_expr,
|
|
55584
|
-
runAt: toNum(row.run_at),
|
|
55585
|
-
isRecurring: row.is_recurring === true || row.is_recurring === 1,
|
|
55586
|
-
originalExpression: row.original_expression,
|
|
55587
|
-
workflow: row.workflow ?? void 0,
|
|
55588
|
-
workflowInputs: safeJsonParse2(row.workflow_inputs),
|
|
55589
|
-
outputContext: safeJsonParse2(row.output_context),
|
|
55590
|
-
status: row.status,
|
|
55591
|
-
createdAt: toNum(row.created_at),
|
|
55592
|
-
lastRunAt: toNum(row.last_run_at),
|
|
55593
|
-
nextRunAt: toNum(row.next_run_at),
|
|
55594
|
-
runCount: row.run_count,
|
|
55595
|
-
failureCount: row.failure_count,
|
|
55596
|
-
lastError: row.last_error ?? void 0,
|
|
55597
|
-
previousResponse: row.previous_response ?? void 0
|
|
55598
|
-
};
|
|
55599
|
-
}
|
|
55600
|
-
function toInsertRow(schedule) {
|
|
55601
|
-
return {
|
|
55602
|
-
id: schedule.id,
|
|
55603
|
-
creator_id: schedule.creatorId,
|
|
55604
|
-
creator_context: schedule.creatorContext ?? null,
|
|
55605
|
-
creator_name: schedule.creatorName ?? null,
|
|
55606
|
-
timezone: schedule.timezone,
|
|
55607
|
-
schedule_expr: schedule.schedule,
|
|
55608
|
-
run_at: schedule.runAt ?? null,
|
|
55609
|
-
is_recurring: schedule.isRecurring,
|
|
55610
|
-
original_expression: schedule.originalExpression,
|
|
55611
|
-
workflow: schedule.workflow ?? null,
|
|
55612
|
-
workflow_inputs: schedule.workflowInputs ? JSON.stringify(schedule.workflowInputs) : null,
|
|
55613
|
-
output_context: schedule.outputContext ? JSON.stringify(schedule.outputContext) : null,
|
|
55614
|
-
status: schedule.status,
|
|
55615
|
-
created_at: schedule.createdAt,
|
|
55616
|
-
last_run_at: schedule.lastRunAt ?? null,
|
|
55617
|
-
next_run_at: schedule.nextRunAt ?? null,
|
|
55618
|
-
run_count: schedule.runCount,
|
|
55619
|
-
failure_count: schedule.failureCount,
|
|
55620
|
-
last_error: schedule.lastError ?? null,
|
|
55621
|
-
previous_response: schedule.previousResponse ?? null
|
|
55622
|
-
};
|
|
55623
|
-
}
|
|
55624
|
-
var fs24, path28, import_uuid2, KnexStoreBackend;
|
|
55625
|
-
var init_knex_store = __esm({
|
|
55626
|
-
"src/enterprise/scheduler/knex-store.ts"() {
|
|
55627
|
-
"use strict";
|
|
55628
|
-
fs24 = __toESM(require("fs"));
|
|
55629
|
-
path28 = __toESM(require("path"));
|
|
55630
|
-
import_uuid2 = require("uuid");
|
|
55631
|
-
init_logger();
|
|
55632
|
-
KnexStoreBackend = class {
|
|
55633
|
-
knex = null;
|
|
55634
|
-
driver;
|
|
55635
|
-
connection;
|
|
55636
|
-
constructor(driver, storageConfig, _haConfig) {
|
|
55637
|
-
this.driver = driver;
|
|
55638
|
-
this.connection = storageConfig.connection || {};
|
|
55639
|
-
}
|
|
55640
|
-
async initialize() {
|
|
55641
|
-
const { createRequire } = require("module");
|
|
55642
|
-
const runtimeRequire = createRequire(__filename);
|
|
55643
|
-
let knexFactory;
|
|
55644
|
-
try {
|
|
55645
|
-
knexFactory = runtimeRequire("knex");
|
|
55646
|
-
} catch (err) {
|
|
55647
|
-
const code = err?.code;
|
|
55648
|
-
if (code === "MODULE_NOT_FOUND" || code === "ERR_MODULE_NOT_FOUND") {
|
|
55649
|
-
throw new Error(
|
|
55650
|
-
"knex is required for PostgreSQL/MySQL/MSSQL schedule storage. Install it with: npm install knex"
|
|
55651
|
-
);
|
|
55652
|
-
}
|
|
55653
|
-
throw err;
|
|
55654
|
-
}
|
|
55655
|
-
const clientMap = {
|
|
55656
|
-
postgresql: "pg",
|
|
55657
|
-
mysql: "mysql2",
|
|
55658
|
-
mssql: "tedious"
|
|
55659
|
-
};
|
|
55660
|
-
const client = clientMap[this.driver];
|
|
55661
|
-
let connection;
|
|
55662
|
-
if (this.connection.connection_string) {
|
|
55663
|
-
connection = this.connection.connection_string;
|
|
55664
|
-
} else if (this.driver === "mssql") {
|
|
55665
|
-
connection = this.buildMssqlConnection();
|
|
55666
|
-
} else {
|
|
55667
|
-
connection = this.buildStandardConnection();
|
|
55668
|
-
}
|
|
55669
|
-
this.knex = knexFactory({
|
|
55670
|
-
client,
|
|
55671
|
-
connection,
|
|
55672
|
-
pool: {
|
|
55673
|
-
min: this.connection.pool?.min ?? 0,
|
|
55674
|
-
max: this.connection.pool?.max ?? 10
|
|
55675
|
-
}
|
|
55676
|
-
});
|
|
55677
|
-
await this.migrateSchema();
|
|
55678
|
-
logger.info(`[KnexStore] Initialized (${this.driver})`);
|
|
55679
|
-
}
|
|
55680
|
-
buildStandardConnection() {
|
|
55681
|
-
return {
|
|
55682
|
-
host: this.connection.host || "localhost",
|
|
55683
|
-
port: this.connection.port,
|
|
55684
|
-
database: this.connection.database || "visor",
|
|
55685
|
-
user: this.connection.user,
|
|
55686
|
-
password: this.connection.password,
|
|
55687
|
-
ssl: this.resolveSslConfig()
|
|
55688
|
-
};
|
|
55689
|
-
}
|
|
55690
|
-
buildMssqlConnection() {
|
|
55691
|
-
const ssl = this.connection.ssl;
|
|
55692
|
-
const sslEnabled = ssl === true || typeof ssl === "object" && ssl.enabled !== false;
|
|
55693
|
-
return {
|
|
55694
|
-
server: this.connection.host || "localhost",
|
|
55695
|
-
port: this.connection.port,
|
|
55696
|
-
database: this.connection.database || "visor",
|
|
55697
|
-
user: this.connection.user,
|
|
55698
|
-
password: this.connection.password,
|
|
55699
|
-
options: {
|
|
55700
|
-
encrypt: sslEnabled,
|
|
55701
|
-
trustServerCertificate: typeof ssl === "object" ? ssl.reject_unauthorized === false : !sslEnabled
|
|
55702
|
-
}
|
|
55703
|
-
};
|
|
55704
|
-
}
|
|
55705
|
-
resolveSslConfig() {
|
|
55706
|
-
const ssl = this.connection.ssl;
|
|
55707
|
-
if (ssl === false || ssl === void 0) return false;
|
|
55708
|
-
if (ssl === true) return { rejectUnauthorized: true };
|
|
55709
|
-
if (ssl.enabled === false) return false;
|
|
55710
|
-
const result = {
|
|
55711
|
-
rejectUnauthorized: ssl.reject_unauthorized !== false
|
|
55712
|
-
};
|
|
55713
|
-
if (ssl.ca) {
|
|
55714
|
-
const caPath = this.validateSslPath(ssl.ca, "CA certificate");
|
|
55715
|
-
result.ca = fs24.readFileSync(caPath, "utf8");
|
|
55716
|
-
}
|
|
55717
|
-
if (ssl.cert) {
|
|
55718
|
-
const certPath = this.validateSslPath(ssl.cert, "client certificate");
|
|
55719
|
-
result.cert = fs24.readFileSync(certPath, "utf8");
|
|
55720
|
-
}
|
|
55721
|
-
if (ssl.key) {
|
|
55722
|
-
const keyPath = this.validateSslPath(ssl.key, "client key");
|
|
55723
|
-
result.key = fs24.readFileSync(keyPath, "utf8");
|
|
55724
|
-
}
|
|
55725
|
-
return result;
|
|
55726
|
-
}
|
|
55727
|
-
validateSslPath(filePath, label) {
|
|
55728
|
-
const resolved = path28.resolve(filePath);
|
|
55729
|
-
if (resolved !== path28.normalize(resolved)) {
|
|
55730
|
-
throw new Error(`SSL ${label} path contains invalid sequences: ${filePath}`);
|
|
55731
|
-
}
|
|
55732
|
-
if (!fs24.existsSync(resolved)) {
|
|
55733
|
-
throw new Error(`SSL ${label} not found: ${filePath}`);
|
|
55734
|
-
}
|
|
55735
|
-
return resolved;
|
|
55736
|
-
}
|
|
55737
|
-
async shutdown() {
|
|
55738
|
-
if (this.knex) {
|
|
55739
|
-
await this.knex.destroy();
|
|
55740
|
-
this.knex = null;
|
|
55741
|
-
}
|
|
55742
|
-
}
|
|
55743
|
-
async migrateSchema() {
|
|
55744
|
-
const knex = this.getKnex();
|
|
55745
|
-
const exists = await knex.schema.hasTable("schedules");
|
|
55746
|
-
if (!exists) {
|
|
55747
|
-
await knex.schema.createTable("schedules", (table) => {
|
|
55748
|
-
table.string("id", 36).primary();
|
|
55749
|
-
table.string("creator_id", 255).notNullable().index();
|
|
55750
|
-
table.string("creator_context", 255);
|
|
55751
|
-
table.string("creator_name", 255);
|
|
55752
|
-
table.string("timezone", 64).notNullable().defaultTo("UTC");
|
|
55753
|
-
table.string("schedule_expr", 255);
|
|
55754
|
-
table.bigInteger("run_at");
|
|
55755
|
-
table.boolean("is_recurring").notNullable();
|
|
55756
|
-
table.text("original_expression");
|
|
55757
|
-
table.string("workflow", 255);
|
|
55758
|
-
table.text("workflow_inputs");
|
|
55759
|
-
table.text("output_context");
|
|
55760
|
-
table.string("status", 20).notNullable().index();
|
|
55761
|
-
table.bigInteger("created_at").notNullable();
|
|
55762
|
-
table.bigInteger("last_run_at");
|
|
55763
|
-
table.bigInteger("next_run_at");
|
|
55764
|
-
table.integer("run_count").notNullable().defaultTo(0);
|
|
55765
|
-
table.integer("failure_count").notNullable().defaultTo(0);
|
|
55766
|
-
table.text("last_error");
|
|
55767
|
-
table.text("previous_response");
|
|
55768
|
-
table.index(["status", "next_run_at"]);
|
|
55769
|
-
});
|
|
55770
|
-
}
|
|
55771
|
-
const triggersExist = await knex.schema.hasTable("message_triggers");
|
|
55772
|
-
if (!triggersExist) {
|
|
55773
|
-
await knex.schema.createTable("message_triggers", (table) => {
|
|
55774
|
-
table.string("id", 36).primary();
|
|
55775
|
-
table.string("creator_id", 255).notNullable().index();
|
|
55776
|
-
table.string("creator_context", 255);
|
|
55777
|
-
table.string("creator_name", 255);
|
|
55778
|
-
table.text("description");
|
|
55779
|
-
table.text("channels");
|
|
55780
|
-
table.text("from_users");
|
|
55781
|
-
table.boolean("from_bots").notNullable().defaultTo(false);
|
|
55782
|
-
table.text("contains");
|
|
55783
|
-
table.text("match_pattern");
|
|
55784
|
-
table.string("threads", 20).notNullable().defaultTo("any");
|
|
55785
|
-
table.string("workflow", 255).notNullable();
|
|
55786
|
-
table.text("inputs");
|
|
55787
|
-
table.text("output_context");
|
|
55788
|
-
table.string("status", 20).notNullable().defaultTo("active").index();
|
|
55789
|
-
table.boolean("enabled").notNullable().defaultTo(true);
|
|
55790
|
-
table.bigInteger("created_at").notNullable();
|
|
55791
|
-
});
|
|
55792
|
-
}
|
|
55793
|
-
const locksExist = await knex.schema.hasTable("scheduler_locks");
|
|
55794
|
-
if (!locksExist) {
|
|
55795
|
-
await knex.schema.createTable("scheduler_locks", (table) => {
|
|
55796
|
-
table.string("lock_id", 255).primary();
|
|
55797
|
-
table.string("node_id", 255).notNullable();
|
|
55798
|
-
table.string("lock_token", 36).notNullable();
|
|
55799
|
-
table.bigInteger("acquired_at").notNullable();
|
|
55800
|
-
table.bigInteger("expires_at").notNullable();
|
|
55801
|
-
});
|
|
55802
|
-
}
|
|
55803
|
-
}
|
|
55804
|
-
getKnex() {
|
|
55805
|
-
if (!this.knex) {
|
|
55806
|
-
throw new Error("[KnexStore] Not initialized. Call initialize() first.");
|
|
55807
|
-
}
|
|
55808
|
-
return this.knex;
|
|
55809
|
-
}
|
|
55810
|
-
// --- CRUD ---
|
|
55811
|
-
async create(schedule) {
|
|
55812
|
-
const knex = this.getKnex();
|
|
55813
|
-
const newSchedule = {
|
|
55814
|
-
...schedule,
|
|
55815
|
-
id: (0, import_uuid2.v4)(),
|
|
55816
|
-
createdAt: Date.now(),
|
|
55817
|
-
runCount: 0,
|
|
55818
|
-
failureCount: 0,
|
|
55819
|
-
status: "active"
|
|
55820
|
-
};
|
|
55821
|
-
await knex("schedules").insert(toInsertRow(newSchedule));
|
|
55822
|
-
logger.info(`[KnexStore] Created schedule ${newSchedule.id} for user ${newSchedule.creatorId}`);
|
|
55823
|
-
return newSchedule;
|
|
55824
|
-
}
|
|
55825
|
-
async importSchedule(schedule) {
|
|
55826
|
-
const knex = this.getKnex();
|
|
55827
|
-
const existing = await knex("schedules").where("id", schedule.id).first();
|
|
55828
|
-
if (existing) return;
|
|
55829
|
-
await knex("schedules").insert(toInsertRow(schedule));
|
|
55830
|
-
}
|
|
55831
|
-
async get(id) {
|
|
55832
|
-
const knex = this.getKnex();
|
|
55833
|
-
const row = await knex("schedules").where("id", id).first();
|
|
55834
|
-
return row ? fromDbRow2(row) : void 0;
|
|
55835
|
-
}
|
|
55836
|
-
async update(id, patch) {
|
|
55837
|
-
const knex = this.getKnex();
|
|
55838
|
-
const existing = await knex("schedules").where("id", id).first();
|
|
55839
|
-
if (!existing) return void 0;
|
|
55840
|
-
const current = fromDbRow2(existing);
|
|
55841
|
-
const updated = { ...current, ...patch, id: current.id };
|
|
55842
|
-
const row = toInsertRow(updated);
|
|
55843
|
-
delete row.id;
|
|
55844
|
-
await knex("schedules").where("id", id).update(row);
|
|
55845
|
-
return updated;
|
|
55846
|
-
}
|
|
55847
|
-
async delete(id) {
|
|
55848
|
-
const knex = this.getKnex();
|
|
55849
|
-
const deleted = await knex("schedules").where("id", id).del();
|
|
55850
|
-
if (deleted > 0) {
|
|
55851
|
-
logger.info(`[KnexStore] Deleted schedule ${id}`);
|
|
55852
|
-
return true;
|
|
55853
|
-
}
|
|
55854
|
-
return false;
|
|
55855
|
-
}
|
|
55856
|
-
// --- Queries ---
|
|
55857
|
-
async getByCreator(creatorId) {
|
|
55858
|
-
const knex = this.getKnex();
|
|
55859
|
-
const rows = await knex("schedules").where("creator_id", creatorId);
|
|
55860
|
-
return rows.map((r) => fromDbRow2(r));
|
|
55861
|
-
}
|
|
55862
|
-
async getActiveSchedules() {
|
|
55863
|
-
const knex = this.getKnex();
|
|
55864
|
-
const rows = await knex("schedules").where("status", "active");
|
|
55865
|
-
return rows.map((r) => fromDbRow2(r));
|
|
55866
|
-
}
|
|
55867
|
-
async getDueSchedules(now) {
|
|
55868
|
-
const ts = now ?? Date.now();
|
|
55869
|
-
const knex = this.getKnex();
|
|
55870
|
-
const bFalse = this.driver === "mssql" ? 0 : false;
|
|
55871
|
-
const bTrue = this.driver === "mssql" ? 1 : true;
|
|
55872
|
-
const rows = await knex("schedules").where("status", "active").andWhere(function() {
|
|
55873
|
-
this.where(function() {
|
|
55874
|
-
this.where("is_recurring", bFalse).whereNotNull("run_at").where("run_at", "<=", ts);
|
|
55875
|
-
}).orWhere(function() {
|
|
55876
|
-
this.where("is_recurring", bTrue).whereNotNull("next_run_at").where("next_run_at", "<=", ts);
|
|
55877
|
-
});
|
|
55878
|
-
});
|
|
55879
|
-
return rows.map((r) => fromDbRow2(r));
|
|
55880
|
-
}
|
|
55881
|
-
async findByWorkflow(creatorId, workflowName) {
|
|
55882
|
-
const knex = this.getKnex();
|
|
55883
|
-
const escaped = workflowName.toLowerCase().replace(/[%_\\]/g, "\\$&");
|
|
55884
|
-
const pattern = `%${escaped}%`;
|
|
55885
|
-
const rows = await knex("schedules").where("creator_id", creatorId).where("status", "active").whereRaw("LOWER(workflow) LIKE ? ESCAPE '\\'", [pattern]);
|
|
55886
|
-
return rows.map((r) => fromDbRow2(r));
|
|
55887
|
-
}
|
|
55888
|
-
async getAll() {
|
|
55889
|
-
const knex = this.getKnex();
|
|
55890
|
-
const rows = await knex("schedules");
|
|
55891
|
-
return rows.map((r) => fromDbRow2(r));
|
|
55892
|
-
}
|
|
55893
|
-
async getStats() {
|
|
55894
|
-
const knex = this.getKnex();
|
|
55895
|
-
const boolTrue = this.driver === "mssql" ? "1" : "true";
|
|
55896
|
-
const boolFalse = this.driver === "mssql" ? "0" : "false";
|
|
55897
|
-
const result = await knex("schedules").select(
|
|
55898
|
-
knex.raw("COUNT(*) as total"),
|
|
55899
|
-
knex.raw("SUM(CASE WHEN status = 'active' THEN 1 ELSE 0 END) as active"),
|
|
55900
|
-
knex.raw("SUM(CASE WHEN status = 'paused' THEN 1 ELSE 0 END) as paused"),
|
|
55901
|
-
knex.raw("SUM(CASE WHEN status = 'completed' THEN 1 ELSE 0 END) as completed"),
|
|
55902
|
-
knex.raw("SUM(CASE WHEN status = 'failed' THEN 1 ELSE 0 END) as failed"),
|
|
55903
|
-
knex.raw(`SUM(CASE WHEN is_recurring = ${boolTrue} THEN 1 ELSE 0 END) as recurring`),
|
|
55904
|
-
knex.raw(`SUM(CASE WHEN is_recurring = ${boolFalse} THEN 1 ELSE 0 END) as one_time`)
|
|
55905
|
-
).first();
|
|
55906
|
-
return {
|
|
55907
|
-
total: Number(result.total) || 0,
|
|
55908
|
-
active: Number(result.active) || 0,
|
|
55909
|
-
paused: Number(result.paused) || 0,
|
|
55910
|
-
completed: Number(result.completed) || 0,
|
|
55911
|
-
failed: Number(result.failed) || 0,
|
|
55912
|
-
recurring: Number(result.recurring) || 0,
|
|
55913
|
-
oneTime: Number(result.one_time) || 0
|
|
55914
|
-
};
|
|
55915
|
-
}
|
|
55916
|
-
async validateLimits(creatorId, isRecurring, limits) {
|
|
55917
|
-
const knex = this.getKnex();
|
|
55918
|
-
if (limits.maxGlobal) {
|
|
55919
|
-
const result = await knex("schedules").count("* as cnt").first();
|
|
55920
|
-
if (Number(result?.cnt) >= limits.maxGlobal) {
|
|
55921
|
-
throw new Error(`Global schedule limit reached (${limits.maxGlobal})`);
|
|
55922
|
-
}
|
|
55923
|
-
}
|
|
55924
|
-
if (limits.maxPerUser) {
|
|
55925
|
-
const result = await knex("schedules").where("creator_id", creatorId).count("* as cnt").first();
|
|
55926
|
-
if (Number(result?.cnt) >= limits.maxPerUser) {
|
|
55927
|
-
throw new Error(`You have reached the maximum number of schedules (${limits.maxPerUser})`);
|
|
55928
|
-
}
|
|
55929
|
-
}
|
|
55930
|
-
if (isRecurring && limits.maxRecurringPerUser) {
|
|
55931
|
-
const bTrue = this.driver === "mssql" ? 1 : true;
|
|
55932
|
-
const result = await knex("schedules").where("creator_id", creatorId).where("is_recurring", bTrue).count("* as cnt").first();
|
|
55933
|
-
if (Number(result?.cnt) >= limits.maxRecurringPerUser) {
|
|
55934
|
-
throw new Error(
|
|
55935
|
-
`You have reached the maximum number of recurring schedules (${limits.maxRecurringPerUser})`
|
|
55936
|
-
);
|
|
55937
|
-
}
|
|
55938
|
-
}
|
|
55939
|
-
}
|
|
55940
|
-
// --- HA Distributed Locking (via scheduler_locks table) ---
|
|
55941
|
-
async tryAcquireLock(lockId, nodeId, ttlSeconds) {
|
|
55942
|
-
const knex = this.getKnex();
|
|
55943
|
-
const now = Date.now();
|
|
55944
|
-
const expiresAt = now + ttlSeconds * 1e3;
|
|
55945
|
-
const token = (0, import_uuid2.v4)();
|
|
55946
|
-
const updated = await knex("scheduler_locks").where("lock_id", lockId).where("expires_at", "<", now).update({
|
|
55947
|
-
node_id: nodeId,
|
|
55948
|
-
lock_token: token,
|
|
55949
|
-
acquired_at: now,
|
|
55950
|
-
expires_at: expiresAt
|
|
55951
|
-
});
|
|
55952
|
-
if (updated > 0) return token;
|
|
55953
|
-
try {
|
|
55954
|
-
await knex("scheduler_locks").insert({
|
|
55955
|
-
lock_id: lockId,
|
|
55956
|
-
node_id: nodeId,
|
|
55957
|
-
lock_token: token,
|
|
55958
|
-
acquired_at: now,
|
|
55959
|
-
expires_at: expiresAt
|
|
55960
|
-
});
|
|
55961
|
-
return token;
|
|
55962
|
-
} catch {
|
|
55963
|
-
return null;
|
|
55964
|
-
}
|
|
55965
|
-
}
|
|
55966
|
-
async releaseLock(lockId, lockToken) {
|
|
55967
|
-
const knex = this.getKnex();
|
|
55968
|
-
await knex("scheduler_locks").where("lock_id", lockId).where("lock_token", lockToken).del();
|
|
55969
|
-
}
|
|
55970
|
-
async renewLock(lockId, lockToken, ttlSeconds) {
|
|
55971
|
-
const knex = this.getKnex();
|
|
55972
|
-
const now = Date.now();
|
|
55973
|
-
const expiresAt = now + ttlSeconds * 1e3;
|
|
55974
|
-
const updated = await knex("scheduler_locks").where("lock_id", lockId).where("lock_token", lockToken).update({ acquired_at: now, expires_at: expiresAt });
|
|
55975
|
-
return updated > 0;
|
|
55976
|
-
}
|
|
55977
|
-
async flush() {
|
|
55978
|
-
}
|
|
55979
|
-
// --- Message Trigger CRUD ---
|
|
55980
|
-
async createTrigger(trigger) {
|
|
55981
|
-
const knex = this.getKnex();
|
|
55982
|
-
const newTrigger = {
|
|
55983
|
-
...trigger,
|
|
55984
|
-
id: (0, import_uuid2.v4)(),
|
|
55985
|
-
createdAt: Date.now()
|
|
55986
|
-
};
|
|
55987
|
-
await knex("message_triggers").insert(toTriggerInsertRow(newTrigger));
|
|
55988
|
-
logger.info(`[KnexStore] Created trigger ${newTrigger.id} for user ${newTrigger.creatorId}`);
|
|
55989
|
-
return newTrigger;
|
|
55990
|
-
}
|
|
55991
|
-
async getTrigger(id) {
|
|
55992
|
-
const knex = this.getKnex();
|
|
55993
|
-
const row = await knex("message_triggers").where("id", id).first();
|
|
55994
|
-
return row ? fromTriggerRow2(row) : void 0;
|
|
55995
|
-
}
|
|
55996
|
-
async updateTrigger(id, patch) {
|
|
55997
|
-
const knex = this.getKnex();
|
|
55998
|
-
const existing = await knex("message_triggers").where("id", id).first();
|
|
55999
|
-
if (!existing) return void 0;
|
|
56000
|
-
const current = fromTriggerRow2(existing);
|
|
56001
|
-
const updated = {
|
|
56002
|
-
...current,
|
|
56003
|
-
...patch,
|
|
56004
|
-
id: current.id,
|
|
56005
|
-
createdAt: current.createdAt
|
|
56006
|
-
};
|
|
56007
|
-
const row = toTriggerInsertRow(updated);
|
|
56008
|
-
delete row.id;
|
|
56009
|
-
await knex("message_triggers").where("id", id).update(row);
|
|
56010
|
-
return updated;
|
|
56011
|
-
}
|
|
56012
|
-
async deleteTrigger(id) {
|
|
56013
|
-
const knex = this.getKnex();
|
|
56014
|
-
const deleted = await knex("message_triggers").where("id", id).del();
|
|
56015
|
-
if (deleted > 0) {
|
|
56016
|
-
logger.info(`[KnexStore] Deleted trigger ${id}`);
|
|
56017
|
-
return true;
|
|
56018
|
-
}
|
|
56019
|
-
return false;
|
|
56020
|
-
}
|
|
56021
|
-
async getTriggersByCreator(creatorId) {
|
|
56022
|
-
const knex = this.getKnex();
|
|
56023
|
-
const rows = await knex("message_triggers").where("creator_id", creatorId);
|
|
56024
|
-
return rows.map((r) => fromTriggerRow2(r));
|
|
56025
|
-
}
|
|
56026
|
-
async getActiveTriggers() {
|
|
56027
|
-
const knex = this.getKnex();
|
|
56028
|
-
const rows = await knex("message_triggers").where("status", "active").where("enabled", this.driver === "mssql" ? 1 : true);
|
|
56029
|
-
return rows.map((r) => fromTriggerRow2(r));
|
|
56030
|
-
}
|
|
56031
|
-
};
|
|
56032
|
-
}
|
|
56033
|
-
});
|
|
56034
|
-
|
|
56035
|
-
// src/enterprise/loader.ts
|
|
56036
|
-
var loader_exports = {};
|
|
56037
|
-
__export(loader_exports, {
|
|
56038
|
-
loadEnterprisePolicyEngine: () => loadEnterprisePolicyEngine,
|
|
56039
|
-
loadEnterpriseStoreBackend: () => loadEnterpriseStoreBackend
|
|
56040
|
-
});
|
|
56041
|
-
async function loadEnterprisePolicyEngine(config) {
|
|
56042
|
-
try {
|
|
56043
|
-
const { LicenseValidator: LicenseValidator2 } = await Promise.resolve().then(() => (init_validator(), validator_exports));
|
|
56044
|
-
const validator = new LicenseValidator2();
|
|
56045
|
-
const license = await validator.loadAndValidate();
|
|
56046
|
-
if (!license || !validator.hasFeature("policy")) {
|
|
56047
|
-
return new DefaultPolicyEngine();
|
|
56048
|
-
}
|
|
56049
|
-
if (validator.isInGracePeriod()) {
|
|
56050
|
-
console.warn(
|
|
56051
|
-
"[visor:enterprise] License has expired but is within the 72-hour grace period. Please renew your license."
|
|
56052
|
-
);
|
|
56053
|
-
}
|
|
56054
|
-
const { OpaPolicyEngine: OpaPolicyEngine2 } = await Promise.resolve().then(() => (init_opa_policy_engine(), opa_policy_engine_exports));
|
|
56055
|
-
const engine = new OpaPolicyEngine2(config);
|
|
56056
|
-
await engine.initialize(config);
|
|
56057
|
-
return engine;
|
|
56058
|
-
} catch (err) {
|
|
56059
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
56060
|
-
try {
|
|
56061
|
-
const { logger: logger2 } = (init_logger(), __toCommonJS(logger_exports));
|
|
56062
|
-
logger2.warn(`[PolicyEngine] Enterprise policy init failed, falling back to default: ${msg}`);
|
|
56063
|
-
} catch {
|
|
56064
|
-
}
|
|
56065
|
-
return new DefaultPolicyEngine();
|
|
56066
|
-
}
|
|
56067
|
-
}
|
|
56068
|
-
async function loadEnterpriseStoreBackend(driver, storageConfig, haConfig) {
|
|
56069
|
-
const { LicenseValidator: LicenseValidator2 } = await Promise.resolve().then(() => (init_validator(), validator_exports));
|
|
56070
|
-
const validator = new LicenseValidator2();
|
|
56071
|
-
const license = await validator.loadAndValidate();
|
|
56072
|
-
if (!license || !validator.hasFeature("scheduler-sql")) {
|
|
56073
|
-
throw new Error(
|
|
56074
|
-
`The ${driver} schedule storage driver requires a Visor Enterprise license with the 'scheduler-sql' feature. Please upgrade or use driver: 'sqlite' (default).`
|
|
56075
|
-
);
|
|
56076
|
-
}
|
|
56077
|
-
if (validator.isInGracePeriod()) {
|
|
56078
|
-
console.warn(
|
|
56079
|
-
"[visor:enterprise] License has expired but is within the 72-hour grace period. Please renew your license."
|
|
56080
|
-
);
|
|
56081
|
-
}
|
|
56082
|
-
const { KnexStoreBackend: KnexStoreBackend2 } = await Promise.resolve().then(() => (init_knex_store(), knex_store_exports));
|
|
56083
|
-
return new KnexStoreBackend2(driver, storageConfig, haConfig);
|
|
56084
|
-
}
|
|
56085
|
-
var init_loader = __esm({
|
|
56086
|
-
"src/enterprise/loader.ts"() {
|
|
56087
|
-
"use strict";
|
|
56088
|
-
init_default_engine();
|
|
56089
|
-
}
|
|
56090
|
-
});
|
|
56091
|
-
|
|
56092
54718
|
// src/event-bus/event-bus.ts
|
|
56093
54719
|
var event_bus_exports = {};
|
|
56094
54720
|
__export(event_bus_exports, {
|
|
@@ -56995,8 +55621,8 @@ ${content}
|
|
|
56995
55621
|
* Sleep utility
|
|
56996
55622
|
*/
|
|
56997
55623
|
sleep(ms) {
|
|
56998
|
-
return new Promise((
|
|
56999
|
-
const t = setTimeout(
|
|
55624
|
+
return new Promise((resolve15) => {
|
|
55625
|
+
const t = setTimeout(resolve15, ms);
|
|
57000
55626
|
if (typeof t.unref === "function") {
|
|
57001
55627
|
try {
|
|
57002
55628
|
t.unref();
|
|
@@ -57281,8 +55907,8 @@ ${end}`);
|
|
|
57281
55907
|
async updateGroupedComment(ctx, comments, group, changedIds) {
|
|
57282
55908
|
const existingLock = this.updateLocks.get(group);
|
|
57283
55909
|
let resolveLock;
|
|
57284
|
-
const ourLock = new Promise((
|
|
57285
|
-
resolveLock =
|
|
55910
|
+
const ourLock = new Promise((resolve15) => {
|
|
55911
|
+
resolveLock = resolve15;
|
|
57286
55912
|
});
|
|
57287
55913
|
this.updateLocks.set(group, ourLock);
|
|
57288
55914
|
try {
|
|
@@ -57595,7 +56221,7 @@ ${blocks}
|
|
|
57595
56221
|
* Sleep utility for enforcing delays
|
|
57596
56222
|
*/
|
|
57597
56223
|
sleep(ms) {
|
|
57598
|
-
return new Promise((
|
|
56224
|
+
return new Promise((resolve15) => setTimeout(resolve15, ms));
|
|
57599
56225
|
}
|
|
57600
56226
|
};
|
|
57601
56227
|
}
|
|
@@ -58887,15 +57513,15 @@ function serializeRunState(state) {
|
|
|
58887
57513
|
])
|
|
58888
57514
|
};
|
|
58889
57515
|
}
|
|
58890
|
-
var
|
|
57516
|
+
var path26, fs22, StateMachineExecutionEngine;
|
|
58891
57517
|
var init_state_machine_execution_engine = __esm({
|
|
58892
57518
|
"src/state-machine-execution-engine.ts"() {
|
|
58893
57519
|
"use strict";
|
|
58894
57520
|
init_runner();
|
|
58895
57521
|
init_logger();
|
|
58896
57522
|
init_sandbox_manager();
|
|
58897
|
-
|
|
58898
|
-
|
|
57523
|
+
path26 = __toESM(require("path"));
|
|
57524
|
+
fs22 = __toESM(require("fs"));
|
|
58899
57525
|
StateMachineExecutionEngine = class _StateMachineExecutionEngine {
|
|
58900
57526
|
workingDirectory;
|
|
58901
57527
|
executionContext;
|
|
@@ -59127,8 +57753,8 @@ var init_state_machine_execution_engine = __esm({
|
|
|
59127
57753
|
logger.debug(
|
|
59128
57754
|
`[PolicyEngine] Loading enterprise policy engine (engine=${configWithTagFilter.policy.engine})`
|
|
59129
57755
|
);
|
|
59130
|
-
const { loadEnterprisePolicyEngine
|
|
59131
|
-
context2.policyEngine = await
|
|
57756
|
+
const { loadEnterprisePolicyEngine } = await import("./enterprise/loader");
|
|
57757
|
+
context2.policyEngine = await loadEnterprisePolicyEngine(configWithTagFilter.policy);
|
|
59132
57758
|
logger.debug(
|
|
59133
57759
|
`[PolicyEngine] Initialized: ${context2.policyEngine?.constructor?.name || "unknown"}`
|
|
59134
57760
|
);
|
|
@@ -59280,9 +57906,9 @@ var init_state_machine_execution_engine = __esm({
|
|
|
59280
57906
|
}
|
|
59281
57907
|
const checkId = String(ev?.checkId || "unknown");
|
|
59282
57908
|
const threadKey = ev?.threadKey || (channel && threadTs ? `${channel}:${threadTs}` : "session");
|
|
59283
|
-
const baseDir = process.env.VISOR_SNAPSHOT_DIR ||
|
|
59284
|
-
|
|
59285
|
-
const filePath =
|
|
57909
|
+
const baseDir = process.env.VISOR_SNAPSHOT_DIR || path26.resolve(process.cwd(), ".visor", "snapshots");
|
|
57910
|
+
fs22.mkdirSync(baseDir, { recursive: true });
|
|
57911
|
+
const filePath = path26.join(baseDir, `${threadKey}-${checkId}.json`);
|
|
59286
57912
|
await this.saveSnapshotToFile(filePath);
|
|
59287
57913
|
logger.info(`[Snapshot] Saved run snapshot: ${filePath}`);
|
|
59288
57914
|
try {
|
|
@@ -59423,7 +58049,7 @@ var init_state_machine_execution_engine = __esm({
|
|
|
59423
58049
|
* Does not include secrets. Intended for debugging and future resume support.
|
|
59424
58050
|
*/
|
|
59425
58051
|
async saveSnapshotToFile(filePath) {
|
|
59426
|
-
const
|
|
58052
|
+
const fs23 = await import("fs/promises");
|
|
59427
58053
|
const ctx = this._lastContext;
|
|
59428
58054
|
const runner = this._lastRunner;
|
|
59429
58055
|
if (!ctx || !runner) {
|
|
@@ -59443,14 +58069,14 @@ var init_state_machine_execution_engine = __esm({
|
|
|
59443
58069
|
journal: entries,
|
|
59444
58070
|
requestedChecks: ctx.requestedChecks || []
|
|
59445
58071
|
};
|
|
59446
|
-
await
|
|
58072
|
+
await fs23.writeFile(filePath, JSON.stringify(payload, null, 2), "utf8");
|
|
59447
58073
|
}
|
|
59448
58074
|
/**
|
|
59449
58075
|
* Load a snapshot JSON from file and return it. Resume support can build on this.
|
|
59450
58076
|
*/
|
|
59451
58077
|
async loadSnapshotFromFile(filePath) {
|
|
59452
|
-
const
|
|
59453
|
-
const raw = await
|
|
58078
|
+
const fs23 = await import("fs/promises");
|
|
58079
|
+
const raw = await fs23.readFile(filePath, "utf8");
|
|
59454
58080
|
return JSON.parse(raw);
|
|
59455
58081
|
}
|
|
59456
58082
|
/**
|