@probelabs/visor 0.1.151-ee → 0.1.152
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 +33 -1844
- package/dist/output/traces/run-2026-03-04T06-46-24-105Z.ndjson +138 -0
- package/dist/output/traces/run-2026-03-04T06-47-08-884Z.ndjson +2197 -0
- package/dist/sdk/{check-provider-registry-IGIIFX67.mjs → check-provider-registry-DCZR46KQ.mjs} +5 -5
- package/dist/sdk/{check-provider-registry-NEOLXMRW.mjs → check-provider-registry-QBURXJ6B.mjs} +5 -5
- package/dist/sdk/check-provider-registry-VY5ZZAEU.mjs +29 -0
- package/dist/sdk/chunk-6VQ73GYD.mjs +443 -0
- package/dist/sdk/chunk-6VQ73GYD.mjs.map +1 -0
- package/dist/sdk/{chunk-LH3PEGKM.mjs → chunk-FP3RZSLW.mjs} +2 -2
- package/dist/sdk/{chunk-CZOKADR7.mjs → chunk-LLVVHYIP.mjs} +3 -3
- package/dist/sdk/{chunk-GJN2HALW.mjs → chunk-PCI4FXAO.mjs} +16 -16
- package/dist/sdk/{chunk-GJN2HALW.mjs.map → chunk-PCI4FXAO.mjs.map} +1 -1
- package/dist/sdk/{chunk-U4ZJWL63.mjs → chunk-QRR6OJQN.mjs} +15 -15
- package/dist/sdk/chunk-WG7P66MJ.mjs +739 -0
- package/dist/sdk/chunk-WG7P66MJ.mjs.map +1 -0
- package/dist/sdk/chunk-XJZKNTKZ.mjs +43715 -0
- package/dist/sdk/chunk-XJZKNTKZ.mjs.map +1 -0
- package/dist/sdk/{chunk-NE3OOOB2.mjs → chunk-Y3XWPKFP.mjs} +2 -2
- package/dist/sdk/{chunk-NE3OOOB2.mjs.map → chunk-Y3XWPKFP.mjs.map} +1 -1
- package/dist/sdk/chunk-ZCUGMT7X.mjs +1502 -0
- package/dist/sdk/chunk-ZCUGMT7X.mjs.map +1 -0
- package/dist/sdk/{failure-condition-evaluator-XYC6LZAV.mjs → failure-condition-evaluator-R3UE4PE7.mjs} +3 -3
- package/dist/sdk/failure-condition-evaluator-TV227HAG.mjs +17 -0
- package/dist/sdk/{github-frontend-NWH4ZK77.mjs → github-frontend-6KZSVSPC.mjs} +3 -3
- package/dist/sdk/github-frontend-YLSS5NQ7.mjs +1368 -0
- package/dist/sdk/github-frontend-YLSS5NQ7.mjs.map +1 -0
- package/dist/sdk/{host-7WIF5HKA.mjs → host-A5HS6F6G.mjs} +2 -2
- package/dist/sdk/{host-ZWGHQS34.mjs → host-WNCX3MPT.mjs} +2 -2
- package/dist/sdk/{routing-ODVQHICC.mjs → routing-FKWK5BHS.mjs} +4 -4
- package/dist/sdk/routing-MMEOAH34.mjs +25 -0
- package/dist/sdk/{schedule-tool-HQFZLF4V.mjs → schedule-tool-62XTFB6K.mjs} +5 -5
- package/dist/sdk/{schedule-tool-SFHR3T3S.mjs → schedule-tool-IJC2TSKU.mjs} +5 -5
- package/dist/sdk/schedule-tool-VOZ536P4.mjs +35 -0
- package/dist/sdk/{schedule-tool-handler-C6B4SFCZ.mjs → schedule-tool-handler-5K275UT6.mjs} +5 -5
- package/dist/sdk/{schedule-tool-handler-JCOBGMRA.mjs → schedule-tool-handler-T4L2ECBA.mjs} +5 -5
- package/dist/sdk/schedule-tool-handler-T4L2ECBA.mjs.map +1 -0
- package/dist/sdk/schedule-tool-handler-WBIZSBGJ.mjs +39 -0
- package/dist/sdk/schedule-tool-handler-WBIZSBGJ.mjs.map +1 -0
- package/dist/sdk/sdk.js +260 -1634
- package/dist/sdk/sdk.js.map +1 -1
- package/dist/sdk/sdk.mjs +4 -4
- package/dist/sdk/{trace-helpers-LKAADSNB.mjs → trace-helpers-JJLVZ2RJ.mjs} +2 -2
- package/dist/sdk/trace-helpers-JJLVZ2RJ.mjs.map +1 -0
- package/dist/sdk/trace-helpers-W33WMBL7.mjs +25 -0
- package/dist/sdk/trace-helpers-W33WMBL7.mjs.map +1 -0
- package/dist/sdk/{workflow-check-provider-CH3ARLBE.mjs → workflow-check-provider-6TEZHBZJ.mjs} +5 -5
- package/dist/sdk/workflow-check-provider-6TEZHBZJ.mjs.map +1 -0
- package/dist/sdk/{workflow-check-provider-LMAKHSEZ.mjs → workflow-check-provider-FONJYRMR.mjs} +5 -5
- package/dist/sdk/workflow-check-provider-FONJYRMR.mjs.map +1 -0
- package/dist/sdk/workflow-check-provider-LREOGGTH.mjs +29 -0
- package/dist/sdk/workflow-check-provider-LREOGGTH.mjs.map +1 -0
- package/dist/traces/run-2026-03-04T06-46-24-105Z.ndjson +138 -0
- package/dist/traces/run-2026-03-04T06-47-08-884Z.ndjson +2197 -0
- package/package.json +2 -2
- 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-IGIIFX67.mjs.map → check-provider-registry-DCZR46KQ.mjs.map} +0 -0
- /package/dist/sdk/{check-provider-registry-NEOLXMRW.mjs.map → check-provider-registry-QBURXJ6B.mjs.map} +0 -0
- /package/dist/sdk/{failure-condition-evaluator-XYC6LZAV.mjs.map → check-provider-registry-VY5ZZAEU.mjs.map} +0 -0
- /package/dist/sdk/{chunk-LH3PEGKM.mjs.map → chunk-FP3RZSLW.mjs.map} +0 -0
- /package/dist/sdk/{chunk-CZOKADR7.mjs.map → chunk-LLVVHYIP.mjs.map} +0 -0
- /package/dist/sdk/{chunk-U4ZJWL63.mjs.map → chunk-QRR6OJQN.mjs.map} +0 -0
- /package/dist/sdk/{routing-ODVQHICC.mjs.map → failure-condition-evaluator-R3UE4PE7.mjs.map} +0 -0
- /package/dist/sdk/{schedule-tool-HQFZLF4V.mjs.map → failure-condition-evaluator-TV227HAG.mjs.map} +0 -0
- /package/dist/sdk/{github-frontend-NWH4ZK77.mjs.map → github-frontend-6KZSVSPC.mjs.map} +0 -0
- /package/dist/sdk/{host-7WIF5HKA.mjs.map → host-A5HS6F6G.mjs.map} +0 -0
- /package/dist/sdk/{host-ZWGHQS34.mjs.map → host-WNCX3MPT.mjs.map} +0 -0
- /package/dist/sdk/{schedule-tool-SFHR3T3S.mjs.map → routing-FKWK5BHS.mjs.map} +0 -0
- /package/dist/sdk/{schedule-tool-handler-C6B4SFCZ.mjs.map → routing-MMEOAH34.mjs.map} +0 -0
- /package/dist/sdk/{schedule-tool-handler-JCOBGMRA.mjs.map → schedule-tool-62XTFB6K.mjs.map} +0 -0
- /package/dist/sdk/{trace-helpers-LKAADSNB.mjs.map → schedule-tool-IJC2TSKU.mjs.map} +0 -0
- /package/dist/sdk/{workflow-check-provider-CH3ARLBE.mjs.map → schedule-tool-VOZ536P4.mjs.map} +0 -0
- /package/dist/sdk/{workflow-check-provider-LMAKHSEZ.mjs.map → schedule-tool-handler-5K275UT6.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.152",
|
|
650
650
|
main: "dist/index.js",
|
|
651
651
|
bin: {
|
|
652
652
|
visor: "./dist/index.js"
|
|
@@ -760,7 +760,7 @@ var require_package = __commonJS({
|
|
|
760
760
|
"@opentelemetry/sdk-node": "^0.203.0",
|
|
761
761
|
"@opentelemetry/sdk-trace-base": "^1.30.1",
|
|
762
762
|
"@opentelemetry/semantic-conventions": "^1.30.1",
|
|
763
|
-
"@probelabs/probe": "^0.6.0-
|
|
763
|
+
"@probelabs/probe": "^0.6.0-rc269",
|
|
764
764
|
"@types/commander": "^2.12.0",
|
|
765
765
|
"@types/uuid": "^10.0.0",
|
|
766
766
|
acorn: "^8.16.0",
|
|
@@ -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((resolve14, reject) => {
|
|
868
868
|
const callback = async (span) => {
|
|
869
869
|
try {
|
|
870
870
|
const res = await fn(span);
|
|
871
|
-
|
|
871
|
+
resolve14(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
|
}
|
|
@@ -6972,7 +6972,7 @@ async function renderMermaidToPng(mermaidCode) {
|
|
|
6972
6972
|
if (chromiumPath) {
|
|
6973
6973
|
env.PUPPETEER_EXECUTABLE_PATH = chromiumPath;
|
|
6974
6974
|
}
|
|
6975
|
-
const result = await new Promise((
|
|
6975
|
+
const result = await new Promise((resolve14) => {
|
|
6976
6976
|
const proc = (0, import_child_process.spawn)(
|
|
6977
6977
|
"npx",
|
|
6978
6978
|
[
|
|
@@ -7002,13 +7002,13 @@ async function renderMermaidToPng(mermaidCode) {
|
|
|
7002
7002
|
});
|
|
7003
7003
|
proc.on("close", (code) => {
|
|
7004
7004
|
if (code === 0) {
|
|
7005
|
-
|
|
7005
|
+
resolve14({ success: true });
|
|
7006
7006
|
} else {
|
|
7007
|
-
|
|
7007
|
+
resolve14({ success: false, error: stderr || `Exit code ${code}` });
|
|
7008
7008
|
}
|
|
7009
7009
|
});
|
|
7010
7010
|
proc.on("error", (err) => {
|
|
7011
|
-
|
|
7011
|
+
resolve14({ success: false, error: err.message });
|
|
7012
7012
|
});
|
|
7013
7013
|
});
|
|
7014
7014
|
if (!result.success) {
|
|
@@ -8170,8 +8170,8 @@ ${schemaString}`);
|
|
|
8170
8170
|
}
|
|
8171
8171
|
if (process.env.VISOR_DEBUG_AI_SESSIONS === "true") {
|
|
8172
8172
|
try {
|
|
8173
|
-
const
|
|
8174
|
-
const
|
|
8173
|
+
const fs23 = require("fs");
|
|
8174
|
+
const path27 = require("path");
|
|
8175
8175
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
8176
8176
|
const provider = this.config.provider || "auto";
|
|
8177
8177
|
const model = this.config.model || "default";
|
|
@@ -8285,20 +8285,20 @@ ${"=".repeat(60)}
|
|
|
8285
8285
|
`;
|
|
8286
8286
|
readableVersion += `${"=".repeat(60)}
|
|
8287
8287
|
`;
|
|
8288
|
-
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS ||
|
|
8289
|
-
if (!
|
|
8290
|
-
|
|
8288
|
+
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path27.join(process.cwd(), "debug-artifacts");
|
|
8289
|
+
if (!fs23.existsSync(debugArtifactsDir)) {
|
|
8290
|
+
fs23.mkdirSync(debugArtifactsDir, { recursive: true });
|
|
8291
8291
|
}
|
|
8292
|
-
const debugFile =
|
|
8292
|
+
const debugFile = path27.join(
|
|
8293
8293
|
debugArtifactsDir,
|
|
8294
8294
|
`prompt-${_checkName || "unknown"}-${timestamp}.json`
|
|
8295
8295
|
);
|
|
8296
|
-
|
|
8297
|
-
const readableFile =
|
|
8296
|
+
fs23.writeFileSync(debugFile, debugJson, "utf-8");
|
|
8297
|
+
const readableFile = path27.join(
|
|
8298
8298
|
debugArtifactsDir,
|
|
8299
8299
|
`prompt-${_checkName || "unknown"}-${timestamp}.txt`
|
|
8300
8300
|
);
|
|
8301
|
-
|
|
8301
|
+
fs23.writeFileSync(readableFile, readableVersion, "utf-8");
|
|
8302
8302
|
log(`
|
|
8303
8303
|
\u{1F4BE} Full debug info saved to:`);
|
|
8304
8304
|
log(` JSON: ${debugFile}`);
|
|
@@ -8331,8 +8331,8 @@ ${"=".repeat(60)}
|
|
|
8331
8331
|
log(`\u{1F4E4} Response length: ${response.length} characters`);
|
|
8332
8332
|
if (process.env.VISOR_DEBUG_AI_SESSIONS === "true") {
|
|
8333
8333
|
try {
|
|
8334
|
-
const
|
|
8335
|
-
const
|
|
8334
|
+
const fs23 = require("fs");
|
|
8335
|
+
const path27 = require("path");
|
|
8336
8336
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
8337
8337
|
const agentAny2 = agent;
|
|
8338
8338
|
let fullHistory = [];
|
|
@@ -8343,8 +8343,8 @@ ${"=".repeat(60)}
|
|
|
8343
8343
|
} else if (agentAny2._messages) {
|
|
8344
8344
|
fullHistory = agentAny2._messages;
|
|
8345
8345
|
}
|
|
8346
|
-
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS ||
|
|
8347
|
-
const sessionBase =
|
|
8346
|
+
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path27.join(process.cwd(), "debug-artifacts");
|
|
8347
|
+
const sessionBase = path27.join(
|
|
8348
8348
|
debugArtifactsDir,
|
|
8349
8349
|
`session-${_checkName || "unknown"}-${timestamp}`
|
|
8350
8350
|
);
|
|
@@ -8356,7 +8356,7 @@ ${"=".repeat(60)}
|
|
|
8356
8356
|
schema: effectiveSchema,
|
|
8357
8357
|
totalMessages: fullHistory.length
|
|
8358
8358
|
};
|
|
8359
|
-
|
|
8359
|
+
fs23.writeFileSync(sessionBase + ".json", JSON.stringify(sessionData, null, 2), "utf-8");
|
|
8360
8360
|
let readable = `=============================================================
|
|
8361
8361
|
`;
|
|
8362
8362
|
readable += `COMPLETE AI SESSION HISTORY (AFTER RESPONSE)
|
|
@@ -8383,7 +8383,7 @@ ${"=".repeat(60)}
|
|
|
8383
8383
|
`;
|
|
8384
8384
|
readable += content + "\n";
|
|
8385
8385
|
});
|
|
8386
|
-
|
|
8386
|
+
fs23.writeFileSync(sessionBase + ".summary.txt", readable, "utf-8");
|
|
8387
8387
|
log(`\u{1F4BE} Complete session history saved:`);
|
|
8388
8388
|
log(` - Contains ALL ${fullHistory.length} messages (prompts + responses)`);
|
|
8389
8389
|
} catch (error) {
|
|
@@ -8392,11 +8392,11 @@ ${"=".repeat(60)}
|
|
|
8392
8392
|
}
|
|
8393
8393
|
if (process.env.VISOR_DEBUG_AI_SESSIONS === "true") {
|
|
8394
8394
|
try {
|
|
8395
|
-
const
|
|
8396
|
-
const
|
|
8395
|
+
const fs23 = require("fs");
|
|
8396
|
+
const path27 = require("path");
|
|
8397
8397
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
8398
|
-
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS ||
|
|
8399
|
-
const responseFile =
|
|
8398
|
+
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path27.join(process.cwd(), "debug-artifacts");
|
|
8399
|
+
const responseFile = path27.join(
|
|
8400
8400
|
debugArtifactsDir,
|
|
8401
8401
|
`response-${_checkName || "unknown"}-${timestamp}.txt`
|
|
8402
8402
|
);
|
|
@@ -8429,7 +8429,7 @@ ${"=".repeat(60)}
|
|
|
8429
8429
|
`;
|
|
8430
8430
|
responseContent += `${"=".repeat(60)}
|
|
8431
8431
|
`;
|
|
8432
|
-
|
|
8432
|
+
fs23.writeFileSync(responseFile, responseContent, "utf-8");
|
|
8433
8433
|
log(`\u{1F4BE} Response saved to: ${responseFile}`);
|
|
8434
8434
|
} catch (error) {
|
|
8435
8435
|
log(`\u26A0\uFE0F Could not save response file: ${error}`);
|
|
@@ -8445,9 +8445,9 @@ ${"=".repeat(60)}
|
|
|
8445
8445
|
await agentAny._telemetryConfig.shutdown();
|
|
8446
8446
|
log(`\u{1F4CA} OpenTelemetry trace saved to: ${agentAny._traceFilePath}`);
|
|
8447
8447
|
if (process.env.GITHUB_ACTIONS) {
|
|
8448
|
-
const
|
|
8449
|
-
if (
|
|
8450
|
-
const stats =
|
|
8448
|
+
const fs23 = require("fs");
|
|
8449
|
+
if (fs23.existsSync(agentAny._traceFilePath)) {
|
|
8450
|
+
const stats = fs23.statSync(agentAny._traceFilePath);
|
|
8451
8451
|
console.log(
|
|
8452
8452
|
`::notice title=AI Trace Saved::${agentAny._traceFilePath} (${stats.size} bytes)`
|
|
8453
8453
|
);
|
|
@@ -8654,9 +8654,9 @@ ${schemaString}`);
|
|
|
8654
8654
|
const model = this.config.model || "default";
|
|
8655
8655
|
if (process.env.VISOR_DEBUG_AI_SESSIONS === "true") {
|
|
8656
8656
|
try {
|
|
8657
|
-
const
|
|
8658
|
-
const
|
|
8659
|
-
const
|
|
8657
|
+
const fs23 = require("fs");
|
|
8658
|
+
const path27 = require("path");
|
|
8659
|
+
const os2 = require("os");
|
|
8660
8660
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
8661
8661
|
const debugData = {
|
|
8662
8662
|
timestamp,
|
|
@@ -8728,19 +8728,19 @@ ${"=".repeat(60)}
|
|
|
8728
8728
|
`;
|
|
8729
8729
|
readableVersion += `${"=".repeat(60)}
|
|
8730
8730
|
`;
|
|
8731
|
-
const tempDir =
|
|
8732
|
-
const promptFile =
|
|
8733
|
-
|
|
8731
|
+
const tempDir = os2.tmpdir();
|
|
8732
|
+
const promptFile = path27.join(tempDir, `visor-prompt-${timestamp}.txt`);
|
|
8733
|
+
fs23.writeFileSync(promptFile, prompt, "utf-8");
|
|
8734
8734
|
log(`
|
|
8735
8735
|
\u{1F4BE} Prompt saved to: ${promptFile}`);
|
|
8736
|
-
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS ||
|
|
8736
|
+
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path27.join(process.cwd(), "debug-artifacts");
|
|
8737
8737
|
try {
|
|
8738
|
-
const base =
|
|
8738
|
+
const base = path27.join(
|
|
8739
8739
|
debugArtifactsDir,
|
|
8740
8740
|
`prompt-${_checkName || "unknown"}-${timestamp}`
|
|
8741
8741
|
);
|
|
8742
|
-
|
|
8743
|
-
|
|
8742
|
+
fs23.writeFileSync(base + ".json", debugJson, "utf-8");
|
|
8743
|
+
fs23.writeFileSync(base + ".summary.txt", readableVersion, "utf-8");
|
|
8744
8744
|
log(`
|
|
8745
8745
|
\u{1F4BE} Full debug info saved to directory: ${debugArtifactsDir}`);
|
|
8746
8746
|
} catch {
|
|
@@ -8785,8 +8785,8 @@ $ ${cliCommand}
|
|
|
8785
8785
|
log(`\u{1F4E4} Response length: ${response.length} characters`);
|
|
8786
8786
|
if (process.env.VISOR_DEBUG_AI_SESSIONS === "true") {
|
|
8787
8787
|
try {
|
|
8788
|
-
const
|
|
8789
|
-
const
|
|
8788
|
+
const fs23 = require("fs");
|
|
8789
|
+
const path27 = require("path");
|
|
8790
8790
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
8791
8791
|
const agentAny = agent;
|
|
8792
8792
|
let fullHistory = [];
|
|
@@ -8797,8 +8797,8 @@ $ ${cliCommand}
|
|
|
8797
8797
|
} else if (agentAny._messages) {
|
|
8798
8798
|
fullHistory = agentAny._messages;
|
|
8799
8799
|
}
|
|
8800
|
-
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS ||
|
|
8801
|
-
const sessionBase =
|
|
8800
|
+
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path27.join(process.cwd(), "debug-artifacts");
|
|
8801
|
+
const sessionBase = path27.join(
|
|
8802
8802
|
debugArtifactsDir,
|
|
8803
8803
|
`session-${_checkName || "unknown"}-${timestamp}`
|
|
8804
8804
|
);
|
|
@@ -8810,7 +8810,7 @@ $ ${cliCommand}
|
|
|
8810
8810
|
schema: effectiveSchema,
|
|
8811
8811
|
totalMessages: fullHistory.length
|
|
8812
8812
|
};
|
|
8813
|
-
|
|
8813
|
+
fs23.writeFileSync(sessionBase + ".json", JSON.stringify(sessionData, null, 2), "utf-8");
|
|
8814
8814
|
let readable = `=============================================================
|
|
8815
8815
|
`;
|
|
8816
8816
|
readable += `COMPLETE AI SESSION HISTORY (AFTER RESPONSE)
|
|
@@ -8837,7 +8837,7 @@ ${"=".repeat(60)}
|
|
|
8837
8837
|
`;
|
|
8838
8838
|
readable += content + "\n";
|
|
8839
8839
|
});
|
|
8840
|
-
|
|
8840
|
+
fs23.writeFileSync(sessionBase + ".summary.txt", readable, "utf-8");
|
|
8841
8841
|
log(`\u{1F4BE} Complete session history saved:`);
|
|
8842
8842
|
log(` - Contains ALL ${fullHistory.length} messages (prompts + responses)`);
|
|
8843
8843
|
} catch (error) {
|
|
@@ -8846,11 +8846,11 @@ ${"=".repeat(60)}
|
|
|
8846
8846
|
}
|
|
8847
8847
|
if (process.env.VISOR_DEBUG_AI_SESSIONS === "true") {
|
|
8848
8848
|
try {
|
|
8849
|
-
const
|
|
8850
|
-
const
|
|
8849
|
+
const fs23 = require("fs");
|
|
8850
|
+
const path27 = require("path");
|
|
8851
8851
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
8852
|
-
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS ||
|
|
8853
|
-
const responseFile =
|
|
8852
|
+
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path27.join(process.cwd(), "debug-artifacts");
|
|
8853
|
+
const responseFile = path27.join(
|
|
8854
8854
|
debugArtifactsDir,
|
|
8855
8855
|
`response-${_checkName || "unknown"}-${timestamp}.txt`
|
|
8856
8856
|
);
|
|
@@ -8883,7 +8883,7 @@ ${"=".repeat(60)}
|
|
|
8883
8883
|
`;
|
|
8884
8884
|
responseContent += `${"=".repeat(60)}
|
|
8885
8885
|
`;
|
|
8886
|
-
|
|
8886
|
+
fs23.writeFileSync(responseFile, responseContent, "utf-8");
|
|
8887
8887
|
log(`\u{1F4BE} Response saved to: ${responseFile}`);
|
|
8888
8888
|
} catch (error) {
|
|
8889
8889
|
log(`\u26A0\uFE0F Could not save response file: ${error}`);
|
|
@@ -8901,9 +8901,9 @@ ${"=".repeat(60)}
|
|
|
8901
8901
|
await telemetry.shutdown();
|
|
8902
8902
|
log(`\u{1F4CA} OpenTelemetry trace saved to: ${traceFilePath}`);
|
|
8903
8903
|
if (process.env.GITHUB_ACTIONS) {
|
|
8904
|
-
const
|
|
8905
|
-
if (
|
|
8906
|
-
const stats =
|
|
8904
|
+
const fs23 = require("fs");
|
|
8905
|
+
if (fs23.existsSync(traceFilePath)) {
|
|
8906
|
+
const stats = fs23.statSync(traceFilePath);
|
|
8907
8907
|
console.log(
|
|
8908
8908
|
`::notice title=AI Trace Saved::OpenTelemetry trace file size: ${stats.size} bytes`
|
|
8909
8909
|
);
|
|
@@ -8941,8 +8941,8 @@ ${"=".repeat(60)}
|
|
|
8941
8941
|
* Load schema content from schema files or inline definitions
|
|
8942
8942
|
*/
|
|
8943
8943
|
async loadSchemaContent(schema) {
|
|
8944
|
-
const
|
|
8945
|
-
const
|
|
8944
|
+
const fs23 = require("fs").promises;
|
|
8945
|
+
const path27 = require("path");
|
|
8946
8946
|
if (typeof schema === "object" && schema !== null) {
|
|
8947
8947
|
log("\u{1F4CB} Using inline schema object from configuration");
|
|
8948
8948
|
return JSON.stringify(schema);
|
|
@@ -8955,14 +8955,14 @@ ${"=".repeat(60)}
|
|
|
8955
8955
|
}
|
|
8956
8956
|
} catch {
|
|
8957
8957
|
}
|
|
8958
|
-
if ((schema.startsWith("./") || schema.includes(".json")) && !
|
|
8958
|
+
if ((schema.startsWith("./") || schema.includes(".json")) && !path27.isAbsolute(schema)) {
|
|
8959
8959
|
if (schema.includes("..") || schema.includes("\0")) {
|
|
8960
8960
|
throw new Error("Invalid schema path: path traversal not allowed");
|
|
8961
8961
|
}
|
|
8962
8962
|
try {
|
|
8963
|
-
const schemaPath =
|
|
8963
|
+
const schemaPath = path27.resolve(process.cwd(), schema);
|
|
8964
8964
|
log(`\u{1F4CB} Loading custom schema from file: ${schemaPath}`);
|
|
8965
|
-
const schemaContent = await
|
|
8965
|
+
const schemaContent = await fs23.readFile(schemaPath, "utf-8");
|
|
8966
8966
|
return schemaContent.trim();
|
|
8967
8967
|
} catch (error) {
|
|
8968
8968
|
throw new Error(
|
|
@@ -8976,22 +8976,22 @@ ${"=".repeat(60)}
|
|
|
8976
8976
|
}
|
|
8977
8977
|
const candidatePaths = [
|
|
8978
8978
|
// GitHub Action bundle location
|
|
8979
|
-
|
|
8979
|
+
path27.join(__dirname, "output", sanitizedSchemaName, "schema.json"),
|
|
8980
8980
|
// Historical fallback when src/output was inadvertently bundled as output1/
|
|
8981
|
-
|
|
8981
|
+
path27.join(__dirname, "output1", sanitizedSchemaName, "schema.json"),
|
|
8982
8982
|
// Local dev (repo root)
|
|
8983
|
-
|
|
8983
|
+
path27.join(process.cwd(), "output", sanitizedSchemaName, "schema.json")
|
|
8984
8984
|
];
|
|
8985
8985
|
for (const schemaPath of candidatePaths) {
|
|
8986
8986
|
try {
|
|
8987
|
-
const schemaContent = await
|
|
8987
|
+
const schemaContent = await fs23.readFile(schemaPath, "utf-8");
|
|
8988
8988
|
return schemaContent.trim();
|
|
8989
8989
|
} catch {
|
|
8990
8990
|
}
|
|
8991
8991
|
}
|
|
8992
|
-
const distPath =
|
|
8993
|
-
const distAltPath =
|
|
8994
|
-
const cwdPath =
|
|
8992
|
+
const distPath = path27.join(__dirname, "output", sanitizedSchemaName, "schema.json");
|
|
8993
|
+
const distAltPath = path27.join(__dirname, "output1", sanitizedSchemaName, "schema.json");
|
|
8994
|
+
const cwdPath = path27.join(process.cwd(), "output", sanitizedSchemaName, "schema.json");
|
|
8995
8995
|
throw new Error(
|
|
8996
8996
|
`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.`
|
|
8997
8997
|
);
|
|
@@ -9236,7 +9236,7 @@ ${"=".repeat(60)}
|
|
|
9236
9236
|
* Generate mock response for testing
|
|
9237
9237
|
*/
|
|
9238
9238
|
async generateMockResponse(_prompt, _checkName, _schema) {
|
|
9239
|
-
await new Promise((
|
|
9239
|
+
await new Promise((resolve14) => setTimeout(resolve14, 500));
|
|
9240
9240
|
const name = (_checkName || "").toLowerCase();
|
|
9241
9241
|
if (name.includes("extract-facts")) {
|
|
9242
9242
|
const arr = Array.from({ length: 6 }, (_, i) => ({
|
|
@@ -9597,7 +9597,7 @@ var init_command_executor = __esm({
|
|
|
9597
9597
|
* Execute command with stdin input
|
|
9598
9598
|
*/
|
|
9599
9599
|
executeWithStdin(command, options) {
|
|
9600
|
-
return new Promise((
|
|
9600
|
+
return new Promise((resolve14, reject) => {
|
|
9601
9601
|
const childProcess = (0, import_child_process2.exec)(
|
|
9602
9602
|
command,
|
|
9603
9603
|
{
|
|
@@ -9609,7 +9609,7 @@ var init_command_executor = __esm({
|
|
|
9609
9609
|
if (error && error.killed && (error.code === "ETIMEDOUT" || error.signal === "SIGTERM")) {
|
|
9610
9610
|
reject(new Error(`Command timed out after ${options.timeout || 3e4}ms`));
|
|
9611
9611
|
} else {
|
|
9612
|
-
|
|
9612
|
+
resolve14({
|
|
9613
9613
|
stdout: stdout || "",
|
|
9614
9614
|
stderr: stderr || "",
|
|
9615
9615
|
exitCode: error ? error.code || 1 : 0
|
|
@@ -17546,17 +17546,17 @@ var init_workflow_check_provider = __esm({
|
|
|
17546
17546
|
* so it can be executed by the state machine as a nested workflow.
|
|
17547
17547
|
*/
|
|
17548
17548
|
async loadWorkflowFromConfigPath(sourcePath, baseDir) {
|
|
17549
|
-
const
|
|
17550
|
-
const
|
|
17549
|
+
const path27 = require("path");
|
|
17550
|
+
const fs23 = require("fs");
|
|
17551
17551
|
const yaml5 = require("js-yaml");
|
|
17552
|
-
const resolved =
|
|
17553
|
-
if (!
|
|
17552
|
+
const resolved = path27.isAbsolute(sourcePath) ? sourcePath : path27.resolve(baseDir, sourcePath);
|
|
17553
|
+
if (!fs23.existsSync(resolved)) {
|
|
17554
17554
|
throw new Error(`Workflow config not found at: ${resolved}`);
|
|
17555
17555
|
}
|
|
17556
|
-
const rawContent =
|
|
17556
|
+
const rawContent = fs23.readFileSync(resolved, "utf8");
|
|
17557
17557
|
const rawData = yaml5.load(rawContent);
|
|
17558
17558
|
if (rawData.imports && Array.isArray(rawData.imports)) {
|
|
17559
|
-
const configDir =
|
|
17559
|
+
const configDir = path27.dirname(resolved);
|
|
17560
17560
|
for (const source of rawData.imports) {
|
|
17561
17561
|
const results = await this.registry.import(source, {
|
|
17562
17562
|
basePath: configDir,
|
|
@@ -17586,8 +17586,8 @@ ${errors}`);
|
|
|
17586
17586
|
if (!steps || Object.keys(steps).length === 0) {
|
|
17587
17587
|
throw new Error(`Config '${resolved}' does not contain any steps to execute as a workflow`);
|
|
17588
17588
|
}
|
|
17589
|
-
const id =
|
|
17590
|
-
const name = loaded.name || `Workflow from ${
|
|
17589
|
+
const id = path27.basename(resolved).replace(/\.(ya?ml)$/i, "");
|
|
17590
|
+
const name = loaded.name || `Workflow from ${path27.basename(resolved)}`;
|
|
17591
17591
|
const workflowDef = {
|
|
17592
17592
|
id,
|
|
17593
17593
|
name,
|
|
@@ -18393,8 +18393,8 @@ async function createStoreBackend(storageConfig, haConfig) {
|
|
|
18393
18393
|
case "mssql": {
|
|
18394
18394
|
try {
|
|
18395
18395
|
const loaderPath = "../../enterprise/loader";
|
|
18396
|
-
const { loadEnterpriseStoreBackend
|
|
18397
|
-
return await
|
|
18396
|
+
const { loadEnterpriseStoreBackend } = await import(loaderPath);
|
|
18397
|
+
return await loadEnterpriseStoreBackend(driver, storageConfig, haConfig);
|
|
18398
18398
|
} catch (err) {
|
|
18399
18399
|
const msg = err instanceof Error ? err.message : String(err);
|
|
18400
18400
|
logger.error(`[StoreFactory] Failed to load enterprise ${driver} backend: ${msg}`);
|
|
@@ -20938,7 +20938,7 @@ var init_mcp_custom_sse_server = __esm({
|
|
|
20938
20938
|
* Returns the actual bound port number
|
|
20939
20939
|
*/
|
|
20940
20940
|
async start() {
|
|
20941
|
-
return new Promise((
|
|
20941
|
+
return new Promise((resolve14, reject) => {
|
|
20942
20942
|
try {
|
|
20943
20943
|
this.server = import_http.default.createServer((req, res) => {
|
|
20944
20944
|
this.handleRequest(req, res).catch((error) => {
|
|
@@ -20972,7 +20972,7 @@ var init_mcp_custom_sse_server = __esm({
|
|
|
20972
20972
|
);
|
|
20973
20973
|
}
|
|
20974
20974
|
this.startKeepalive();
|
|
20975
|
-
|
|
20975
|
+
resolve14(this.port);
|
|
20976
20976
|
});
|
|
20977
20977
|
} catch (error) {
|
|
20978
20978
|
reject(error);
|
|
@@ -21035,7 +21035,7 @@ var init_mcp_custom_sse_server = __esm({
|
|
|
21035
21035
|
logger.debug(
|
|
21036
21036
|
`[CustomToolsSSEServer:${this.sessionId}] Grace period before stop: ${waitMs}ms (activeToolCalls=${this.activeToolCalls})`
|
|
21037
21037
|
);
|
|
21038
|
-
await new Promise((
|
|
21038
|
+
await new Promise((resolve14) => setTimeout(resolve14, waitMs));
|
|
21039
21039
|
}
|
|
21040
21040
|
}
|
|
21041
21041
|
if (this.activeToolCalls > 0) {
|
|
@@ -21044,7 +21044,7 @@ var init_mcp_custom_sse_server = __esm({
|
|
|
21044
21044
|
`[CustomToolsSSEServer:${this.sessionId}] Waiting for ${this.activeToolCalls} active tool call(s) before stop`
|
|
21045
21045
|
);
|
|
21046
21046
|
while (this.activeToolCalls > 0 && Date.now() - startedAt < effectiveDrainTimeoutMs) {
|
|
21047
|
-
await new Promise((
|
|
21047
|
+
await new Promise((resolve14) => setTimeout(resolve14, 250));
|
|
21048
21048
|
}
|
|
21049
21049
|
if (this.activeToolCalls > 0) {
|
|
21050
21050
|
logger.warn(
|
|
@@ -21069,21 +21069,21 @@ var init_mcp_custom_sse_server = __esm({
|
|
|
21069
21069
|
}
|
|
21070
21070
|
this.connections.clear();
|
|
21071
21071
|
if (this.server) {
|
|
21072
|
-
await new Promise((
|
|
21072
|
+
await new Promise((resolve14, reject) => {
|
|
21073
21073
|
const timeout = setTimeout(() => {
|
|
21074
21074
|
if (this.debug) {
|
|
21075
21075
|
logger.debug(
|
|
21076
21076
|
`[CustomToolsSSEServer:${this.sessionId}] Force closing server after timeout`
|
|
21077
21077
|
);
|
|
21078
21078
|
}
|
|
21079
|
-
this.server?.close(() =>
|
|
21079
|
+
this.server?.close(() => resolve14());
|
|
21080
21080
|
}, 5e3);
|
|
21081
21081
|
this.server.close((error) => {
|
|
21082
21082
|
clearTimeout(timeout);
|
|
21083
21083
|
if (error) {
|
|
21084
21084
|
reject(error);
|
|
21085
21085
|
} else {
|
|
21086
|
-
|
|
21086
|
+
resolve14();
|
|
21087
21087
|
}
|
|
21088
21088
|
});
|
|
21089
21089
|
});
|
|
@@ -21509,7 +21509,7 @@ var init_mcp_custom_sse_server = __esm({
|
|
|
21509
21509
|
logger.warn(
|
|
21510
21510
|
`[CustomToolsSSEServer:${this.sessionId}] Tool ${toolName} failed (attempt ${attempt + 1}/${retryCount + 1}): ${errorMsg}. Retrying in ${delay}ms`
|
|
21511
21511
|
);
|
|
21512
|
-
await new Promise((
|
|
21512
|
+
await new Promise((resolve14) => setTimeout(resolve14, delay));
|
|
21513
21513
|
attempt++;
|
|
21514
21514
|
}
|
|
21515
21515
|
}
|
|
@@ -21822,9 +21822,9 @@ var init_ai_check_provider = __esm({
|
|
|
21822
21822
|
} else {
|
|
21823
21823
|
resolvedPath = import_path7.default.resolve(process.cwd(), str);
|
|
21824
21824
|
}
|
|
21825
|
-
const
|
|
21825
|
+
const fs23 = require("fs").promises;
|
|
21826
21826
|
try {
|
|
21827
|
-
const stat2 = await
|
|
21827
|
+
const stat2 = await fs23.stat(resolvedPath);
|
|
21828
21828
|
return stat2.isFile();
|
|
21829
21829
|
} catch {
|
|
21830
21830
|
return hasFileExtension && (isRelativePath || isAbsolutePath || hasPathSeparators);
|
|
@@ -27752,14 +27752,14 @@ var require_util = __commonJS({
|
|
|
27752
27752
|
}
|
|
27753
27753
|
const port = url.port != null ? url.port : url.protocol === "https:" ? 443 : 80;
|
|
27754
27754
|
let origin = url.origin != null ? url.origin : `${url.protocol}//${url.hostname}:${port}`;
|
|
27755
|
-
let
|
|
27755
|
+
let path27 = url.path != null ? url.path : `${url.pathname || ""}${url.search || ""}`;
|
|
27756
27756
|
if (origin.endsWith("/")) {
|
|
27757
27757
|
origin = origin.substring(0, origin.length - 1);
|
|
27758
27758
|
}
|
|
27759
|
-
if (
|
|
27760
|
-
|
|
27759
|
+
if (path27 && !path27.startsWith("/")) {
|
|
27760
|
+
path27 = `/${path27}`;
|
|
27761
27761
|
}
|
|
27762
|
-
url = new URL(origin +
|
|
27762
|
+
url = new URL(origin + path27);
|
|
27763
27763
|
}
|
|
27764
27764
|
return url;
|
|
27765
27765
|
}
|
|
@@ -29373,20 +29373,20 @@ var require_parseParams = __commonJS({
|
|
|
29373
29373
|
var require_basename = __commonJS({
|
|
29374
29374
|
"node_modules/@fastify/busboy/lib/utils/basename.js"(exports2, module2) {
|
|
29375
29375
|
"use strict";
|
|
29376
|
-
module2.exports = function basename4(
|
|
29377
|
-
if (typeof
|
|
29376
|
+
module2.exports = function basename4(path27) {
|
|
29377
|
+
if (typeof path27 !== "string") {
|
|
29378
29378
|
return "";
|
|
29379
29379
|
}
|
|
29380
|
-
for (var i =
|
|
29381
|
-
switch (
|
|
29380
|
+
for (var i = path27.length - 1; i >= 0; --i) {
|
|
29381
|
+
switch (path27.charCodeAt(i)) {
|
|
29382
29382
|
case 47:
|
|
29383
29383
|
// '/'
|
|
29384
29384
|
case 92:
|
|
29385
|
-
|
|
29386
|
-
return
|
|
29385
|
+
path27 = path27.slice(i + 1);
|
|
29386
|
+
return path27 === ".." || path27 === "." ? "" : path27;
|
|
29387
29387
|
}
|
|
29388
29388
|
}
|
|
29389
|
-
return
|
|
29389
|
+
return path27 === ".." || path27 === "." ? "" : path27;
|
|
29390
29390
|
};
|
|
29391
29391
|
}
|
|
29392
29392
|
});
|
|
@@ -30390,11 +30390,11 @@ var require_util2 = __commonJS({
|
|
|
30390
30390
|
var assert = require("assert");
|
|
30391
30391
|
var { isUint8Array } = require("util/types");
|
|
30392
30392
|
var supportedHashes = [];
|
|
30393
|
-
var
|
|
30393
|
+
var crypto2;
|
|
30394
30394
|
try {
|
|
30395
|
-
|
|
30395
|
+
crypto2 = require("crypto");
|
|
30396
30396
|
const possibleRelevantHashes = ["sha256", "sha384", "sha512"];
|
|
30397
|
-
supportedHashes =
|
|
30397
|
+
supportedHashes = crypto2.getHashes().filter((hash) => possibleRelevantHashes.includes(hash));
|
|
30398
30398
|
} catch {
|
|
30399
30399
|
}
|
|
30400
30400
|
function responseURL(response) {
|
|
@@ -30671,7 +30671,7 @@ var require_util2 = __commonJS({
|
|
|
30671
30671
|
}
|
|
30672
30672
|
}
|
|
30673
30673
|
function bytesMatch(bytes, metadataList) {
|
|
30674
|
-
if (
|
|
30674
|
+
if (crypto2 === void 0) {
|
|
30675
30675
|
return true;
|
|
30676
30676
|
}
|
|
30677
30677
|
const parsedMetadata = parseMetadata(metadataList);
|
|
@@ -30686,7 +30686,7 @@ var require_util2 = __commonJS({
|
|
|
30686
30686
|
for (const item of metadata) {
|
|
30687
30687
|
const algorithm = item.algo;
|
|
30688
30688
|
const expectedValue = item.hash;
|
|
30689
|
-
let actualValue =
|
|
30689
|
+
let actualValue = crypto2.createHash(algorithm).update(bytes).digest("base64");
|
|
30690
30690
|
if (actualValue[actualValue.length - 1] === "=") {
|
|
30691
30691
|
if (actualValue[actualValue.length - 2] === "=") {
|
|
30692
30692
|
actualValue = actualValue.slice(0, -2);
|
|
@@ -30779,8 +30779,8 @@ var require_util2 = __commonJS({
|
|
|
30779
30779
|
function createDeferredPromise() {
|
|
30780
30780
|
let res;
|
|
30781
30781
|
let rej;
|
|
30782
|
-
const promise = new Promise((
|
|
30783
|
-
res =
|
|
30782
|
+
const promise = new Promise((resolve14, reject) => {
|
|
30783
|
+
res = resolve14;
|
|
30784
30784
|
rej = reject;
|
|
30785
30785
|
});
|
|
30786
30786
|
return { promise, resolve: res, reject: rej };
|
|
@@ -32033,8 +32033,8 @@ var require_body = __commonJS({
|
|
|
32033
32033
|
var { parseMIMEType, serializeAMimeType } = require_dataURL();
|
|
32034
32034
|
var random;
|
|
32035
32035
|
try {
|
|
32036
|
-
const
|
|
32037
|
-
random = (max) =>
|
|
32036
|
+
const crypto2 = require("crypto");
|
|
32037
|
+
random = (max) => crypto2.randomInt(0, max);
|
|
32038
32038
|
} catch {
|
|
32039
32039
|
random = (max) => Math.floor(Math.random(max));
|
|
32040
32040
|
}
|
|
@@ -32285,8 +32285,8 @@ Content-Type: ${value.type || "application/octet-stream"}\r
|
|
|
32285
32285
|
});
|
|
32286
32286
|
}
|
|
32287
32287
|
});
|
|
32288
|
-
const busboyResolve = new Promise((
|
|
32289
|
-
busboy.on("finish",
|
|
32288
|
+
const busboyResolve = new Promise((resolve14, reject) => {
|
|
32289
|
+
busboy.on("finish", resolve14);
|
|
32290
32290
|
busboy.on("error", (err) => reject(new TypeError(err)));
|
|
32291
32291
|
});
|
|
32292
32292
|
if (this.body !== null) for await (const chunk of consumeBody(this[kState].body)) busboy.write(chunk);
|
|
@@ -32417,7 +32417,7 @@ var require_request = __commonJS({
|
|
|
32417
32417
|
}
|
|
32418
32418
|
var Request = class _Request {
|
|
32419
32419
|
constructor(origin, {
|
|
32420
|
-
path:
|
|
32420
|
+
path: path27,
|
|
32421
32421
|
method,
|
|
32422
32422
|
body,
|
|
32423
32423
|
headers,
|
|
@@ -32431,11 +32431,11 @@ var require_request = __commonJS({
|
|
|
32431
32431
|
throwOnError,
|
|
32432
32432
|
expectContinue
|
|
32433
32433
|
}, handler) {
|
|
32434
|
-
if (typeof
|
|
32434
|
+
if (typeof path27 !== "string") {
|
|
32435
32435
|
throw new InvalidArgumentError("path must be a string");
|
|
32436
|
-
} else if (
|
|
32436
|
+
} else if (path27[0] !== "/" && !(path27.startsWith("http://") || path27.startsWith("https://")) && method !== "CONNECT") {
|
|
32437
32437
|
throw new InvalidArgumentError("path must be an absolute URL or start with a slash");
|
|
32438
|
-
} else if (invalidPathRegex.exec(
|
|
32438
|
+
} else if (invalidPathRegex.exec(path27) !== null) {
|
|
32439
32439
|
throw new InvalidArgumentError("invalid request path");
|
|
32440
32440
|
}
|
|
32441
32441
|
if (typeof method !== "string") {
|
|
@@ -32498,7 +32498,7 @@ var require_request = __commonJS({
|
|
|
32498
32498
|
this.completed = false;
|
|
32499
32499
|
this.aborted = false;
|
|
32500
32500
|
this.upgrade = upgrade || null;
|
|
32501
|
-
this.path = query ? util.buildURL(
|
|
32501
|
+
this.path = query ? util.buildURL(path27, query) : path27;
|
|
32502
32502
|
this.origin = origin;
|
|
32503
32503
|
this.idempotent = idempotent == null ? method === "HEAD" || method === "GET" : idempotent;
|
|
32504
32504
|
this.blocking = blocking == null ? false : blocking;
|
|
@@ -32820,9 +32820,9 @@ var require_dispatcher_base = __commonJS({
|
|
|
32820
32820
|
}
|
|
32821
32821
|
close(callback) {
|
|
32822
32822
|
if (callback === void 0) {
|
|
32823
|
-
return new Promise((
|
|
32823
|
+
return new Promise((resolve14, reject) => {
|
|
32824
32824
|
this.close((err, data) => {
|
|
32825
|
-
return err ? reject(err) :
|
|
32825
|
+
return err ? reject(err) : resolve14(data);
|
|
32826
32826
|
});
|
|
32827
32827
|
});
|
|
32828
32828
|
}
|
|
@@ -32860,12 +32860,12 @@ var require_dispatcher_base = __commonJS({
|
|
|
32860
32860
|
err = null;
|
|
32861
32861
|
}
|
|
32862
32862
|
if (callback === void 0) {
|
|
32863
|
-
return new Promise((
|
|
32863
|
+
return new Promise((resolve14, reject) => {
|
|
32864
32864
|
this.destroy(err, (err2, data) => {
|
|
32865
32865
|
return err2 ? (
|
|
32866
32866
|
/* istanbul ignore next: should never error */
|
|
32867
32867
|
reject(err2)
|
|
32868
|
-
) :
|
|
32868
|
+
) : resolve14(data);
|
|
32869
32869
|
});
|
|
32870
32870
|
});
|
|
32871
32871
|
}
|
|
@@ -33506,9 +33506,9 @@ var require_RedirectHandler = __commonJS({
|
|
|
33506
33506
|
return this.handler.onHeaders(statusCode, headers, resume, statusText);
|
|
33507
33507
|
}
|
|
33508
33508
|
const { origin, pathname, search } = util.parseURL(new URL(this.location, this.opts.origin && new URL(this.opts.path, this.opts.origin)));
|
|
33509
|
-
const
|
|
33509
|
+
const path27 = search ? `${pathname}${search}` : pathname;
|
|
33510
33510
|
this.opts.headers = cleanRequestHeaders(this.opts.headers, statusCode === 303, this.opts.origin !== origin);
|
|
33511
|
-
this.opts.path =
|
|
33511
|
+
this.opts.path = path27;
|
|
33512
33512
|
this.opts.origin = origin;
|
|
33513
33513
|
this.opts.maxRedirections = 0;
|
|
33514
33514
|
this.opts.query = null;
|
|
@@ -33927,16 +33927,16 @@ var require_client = __commonJS({
|
|
|
33927
33927
|
return this[kNeedDrain] < 2;
|
|
33928
33928
|
}
|
|
33929
33929
|
async [kClose]() {
|
|
33930
|
-
return new Promise((
|
|
33930
|
+
return new Promise((resolve14) => {
|
|
33931
33931
|
if (!this[kSize]) {
|
|
33932
|
-
|
|
33932
|
+
resolve14(null);
|
|
33933
33933
|
} else {
|
|
33934
|
-
this[kClosedResolve] =
|
|
33934
|
+
this[kClosedResolve] = resolve14;
|
|
33935
33935
|
}
|
|
33936
33936
|
});
|
|
33937
33937
|
}
|
|
33938
33938
|
async [kDestroy](err) {
|
|
33939
|
-
return new Promise((
|
|
33939
|
+
return new Promise((resolve14) => {
|
|
33940
33940
|
const requests = this[kQueue].splice(this[kPendingIdx]);
|
|
33941
33941
|
for (let i = 0; i < requests.length; i++) {
|
|
33942
33942
|
const request = requests[i];
|
|
@@ -33947,7 +33947,7 @@ var require_client = __commonJS({
|
|
|
33947
33947
|
this[kClosedResolve]();
|
|
33948
33948
|
this[kClosedResolve] = null;
|
|
33949
33949
|
}
|
|
33950
|
-
|
|
33950
|
+
resolve14();
|
|
33951
33951
|
};
|
|
33952
33952
|
if (this[kHTTP2Session] != null) {
|
|
33953
33953
|
util.destroy(this[kHTTP2Session], err);
|
|
@@ -34527,7 +34527,7 @@ var require_client = __commonJS({
|
|
|
34527
34527
|
});
|
|
34528
34528
|
}
|
|
34529
34529
|
try {
|
|
34530
|
-
const socket = await new Promise((
|
|
34530
|
+
const socket = await new Promise((resolve14, reject) => {
|
|
34531
34531
|
client[kConnector]({
|
|
34532
34532
|
host,
|
|
34533
34533
|
hostname,
|
|
@@ -34539,7 +34539,7 @@ var require_client = __commonJS({
|
|
|
34539
34539
|
if (err) {
|
|
34540
34540
|
reject(err);
|
|
34541
34541
|
} else {
|
|
34542
|
-
|
|
34542
|
+
resolve14(socket2);
|
|
34543
34543
|
}
|
|
34544
34544
|
});
|
|
34545
34545
|
});
|
|
@@ -34750,7 +34750,7 @@ var require_client = __commonJS({
|
|
|
34750
34750
|
writeH2(client, client[kHTTP2Session], request);
|
|
34751
34751
|
return;
|
|
34752
34752
|
}
|
|
34753
|
-
const { body, method, path:
|
|
34753
|
+
const { body, method, path: path27, host, upgrade, headers, blocking, reset } = request;
|
|
34754
34754
|
const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH";
|
|
34755
34755
|
if (body && typeof body.read === "function") {
|
|
34756
34756
|
body.read(0);
|
|
@@ -34800,7 +34800,7 @@ var require_client = __commonJS({
|
|
|
34800
34800
|
if (blocking) {
|
|
34801
34801
|
socket[kBlocking] = true;
|
|
34802
34802
|
}
|
|
34803
|
-
let header = `${method} ${
|
|
34803
|
+
let header = `${method} ${path27} HTTP/1.1\r
|
|
34804
34804
|
`;
|
|
34805
34805
|
if (typeof host === "string") {
|
|
34806
34806
|
header += `host: ${host}\r
|
|
@@ -34863,7 +34863,7 @@ upgrade: ${upgrade}\r
|
|
|
34863
34863
|
return true;
|
|
34864
34864
|
}
|
|
34865
34865
|
function writeH2(client, session, request) {
|
|
34866
|
-
const { body, method, path:
|
|
34866
|
+
const { body, method, path: path27, host, upgrade, expectContinue, signal, headers: reqHeaders } = request;
|
|
34867
34867
|
let headers;
|
|
34868
34868
|
if (typeof reqHeaders === "string") headers = Request[kHTTP2CopyHeaders](reqHeaders.trim());
|
|
34869
34869
|
else headers = reqHeaders;
|
|
@@ -34906,7 +34906,7 @@ upgrade: ${upgrade}\r
|
|
|
34906
34906
|
});
|
|
34907
34907
|
return true;
|
|
34908
34908
|
}
|
|
34909
|
-
headers[HTTP2_HEADER_PATH] =
|
|
34909
|
+
headers[HTTP2_HEADER_PATH] = path27;
|
|
34910
34910
|
headers[HTTP2_HEADER_SCHEME] = "https";
|
|
34911
34911
|
const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH";
|
|
34912
34912
|
if (body && typeof body.read === "function") {
|
|
@@ -35163,12 +35163,12 @@ upgrade: ${upgrade}\r
|
|
|
35163
35163
|
cb();
|
|
35164
35164
|
}
|
|
35165
35165
|
}
|
|
35166
|
-
const waitForDrain = () => new Promise((
|
|
35166
|
+
const waitForDrain = () => new Promise((resolve14, reject) => {
|
|
35167
35167
|
assert(callback === null);
|
|
35168
35168
|
if (socket[kError]) {
|
|
35169
35169
|
reject(socket[kError]);
|
|
35170
35170
|
} else {
|
|
35171
|
-
callback =
|
|
35171
|
+
callback = resolve14;
|
|
35172
35172
|
}
|
|
35173
35173
|
});
|
|
35174
35174
|
if (client[kHTTPConnVersion] === "h2") {
|
|
@@ -35514,8 +35514,8 @@ var require_pool_base = __commonJS({
|
|
|
35514
35514
|
if (this[kQueue].isEmpty()) {
|
|
35515
35515
|
return Promise.all(this[kClients].map((c) => c.close()));
|
|
35516
35516
|
} else {
|
|
35517
|
-
return new Promise((
|
|
35518
|
-
this[kClosedResolve] =
|
|
35517
|
+
return new Promise((resolve14) => {
|
|
35518
|
+
this[kClosedResolve] = resolve14;
|
|
35519
35519
|
});
|
|
35520
35520
|
}
|
|
35521
35521
|
}
|
|
@@ -36093,7 +36093,7 @@ var require_readable = __commonJS({
|
|
|
36093
36093
|
if (this.closed) {
|
|
36094
36094
|
return Promise.resolve(null);
|
|
36095
36095
|
}
|
|
36096
|
-
return new Promise((
|
|
36096
|
+
return new Promise((resolve14, reject) => {
|
|
36097
36097
|
const signalListenerCleanup = signal ? util.addAbortListener(signal, () => {
|
|
36098
36098
|
this.destroy();
|
|
36099
36099
|
}) : noop;
|
|
@@ -36102,7 +36102,7 @@ var require_readable = __commonJS({
|
|
|
36102
36102
|
if (signal && signal.aborted) {
|
|
36103
36103
|
reject(signal.reason || Object.assign(new Error("The operation was aborted"), { name: "AbortError" }));
|
|
36104
36104
|
} else {
|
|
36105
|
-
|
|
36105
|
+
resolve14(null);
|
|
36106
36106
|
}
|
|
36107
36107
|
}).on("error", noop).on("data", function(chunk) {
|
|
36108
36108
|
limit -= chunk.length;
|
|
@@ -36124,11 +36124,11 @@ var require_readable = __commonJS({
|
|
|
36124
36124
|
throw new TypeError("unusable");
|
|
36125
36125
|
}
|
|
36126
36126
|
assert(!stream[kConsume]);
|
|
36127
|
-
return new Promise((
|
|
36127
|
+
return new Promise((resolve14, reject) => {
|
|
36128
36128
|
stream[kConsume] = {
|
|
36129
36129
|
type,
|
|
36130
36130
|
stream,
|
|
36131
|
-
resolve:
|
|
36131
|
+
resolve: resolve14,
|
|
36132
36132
|
reject,
|
|
36133
36133
|
length: 0,
|
|
36134
36134
|
body: []
|
|
@@ -36163,12 +36163,12 @@ var require_readable = __commonJS({
|
|
|
36163
36163
|
}
|
|
36164
36164
|
}
|
|
36165
36165
|
function consumeEnd(consume2) {
|
|
36166
|
-
const { type, body, resolve:
|
|
36166
|
+
const { type, body, resolve: resolve14, stream, length } = consume2;
|
|
36167
36167
|
try {
|
|
36168
36168
|
if (type === "text") {
|
|
36169
|
-
|
|
36169
|
+
resolve14(toUSVString(Buffer.concat(body)));
|
|
36170
36170
|
} else if (type === "json") {
|
|
36171
|
-
|
|
36171
|
+
resolve14(JSON.parse(Buffer.concat(body)));
|
|
36172
36172
|
} else if (type === "arrayBuffer") {
|
|
36173
36173
|
const dst = new Uint8Array(length);
|
|
36174
36174
|
let pos = 0;
|
|
@@ -36176,12 +36176,12 @@ var require_readable = __commonJS({
|
|
|
36176
36176
|
dst.set(buf, pos);
|
|
36177
36177
|
pos += buf.byteLength;
|
|
36178
36178
|
}
|
|
36179
|
-
|
|
36179
|
+
resolve14(dst.buffer);
|
|
36180
36180
|
} else if (type === "blob") {
|
|
36181
36181
|
if (!Blob2) {
|
|
36182
36182
|
Blob2 = require("buffer").Blob;
|
|
36183
36183
|
}
|
|
36184
|
-
|
|
36184
|
+
resolve14(new Blob2(body, { type: stream[kContentType] }));
|
|
36185
36185
|
}
|
|
36186
36186
|
consumeFinish(consume2);
|
|
36187
36187
|
} catch (err) {
|
|
@@ -36438,9 +36438,9 @@ var require_api_request = __commonJS({
|
|
|
36438
36438
|
};
|
|
36439
36439
|
function request(opts, callback) {
|
|
36440
36440
|
if (callback === void 0) {
|
|
36441
|
-
return new Promise((
|
|
36441
|
+
return new Promise((resolve14, reject) => {
|
|
36442
36442
|
request.call(this, opts, (err, data) => {
|
|
36443
|
-
return err ? reject(err) :
|
|
36443
|
+
return err ? reject(err) : resolve14(data);
|
|
36444
36444
|
});
|
|
36445
36445
|
});
|
|
36446
36446
|
}
|
|
@@ -36613,9 +36613,9 @@ var require_api_stream = __commonJS({
|
|
|
36613
36613
|
};
|
|
36614
36614
|
function stream(opts, factory, callback) {
|
|
36615
36615
|
if (callback === void 0) {
|
|
36616
|
-
return new Promise((
|
|
36616
|
+
return new Promise((resolve14, reject) => {
|
|
36617
36617
|
stream.call(this, opts, factory, (err, data) => {
|
|
36618
|
-
return err ? reject(err) :
|
|
36618
|
+
return err ? reject(err) : resolve14(data);
|
|
36619
36619
|
});
|
|
36620
36620
|
});
|
|
36621
36621
|
}
|
|
@@ -36896,9 +36896,9 @@ var require_api_upgrade = __commonJS({
|
|
|
36896
36896
|
};
|
|
36897
36897
|
function upgrade(opts, callback) {
|
|
36898
36898
|
if (callback === void 0) {
|
|
36899
|
-
return new Promise((
|
|
36899
|
+
return new Promise((resolve14, reject) => {
|
|
36900
36900
|
upgrade.call(this, opts, (err, data) => {
|
|
36901
|
-
return err ? reject(err) :
|
|
36901
|
+
return err ? reject(err) : resolve14(data);
|
|
36902
36902
|
});
|
|
36903
36903
|
});
|
|
36904
36904
|
}
|
|
@@ -36987,9 +36987,9 @@ var require_api_connect = __commonJS({
|
|
|
36987
36987
|
};
|
|
36988
36988
|
function connect(opts, callback) {
|
|
36989
36989
|
if (callback === void 0) {
|
|
36990
|
-
return new Promise((
|
|
36990
|
+
return new Promise((resolve14, reject) => {
|
|
36991
36991
|
connect.call(this, opts, (err, data) => {
|
|
36992
|
-
return err ? reject(err) :
|
|
36992
|
+
return err ? reject(err) : resolve14(data);
|
|
36993
36993
|
});
|
|
36994
36994
|
});
|
|
36995
36995
|
}
|
|
@@ -37149,20 +37149,20 @@ var require_mock_utils = __commonJS({
|
|
|
37149
37149
|
}
|
|
37150
37150
|
return true;
|
|
37151
37151
|
}
|
|
37152
|
-
function safeUrl(
|
|
37153
|
-
if (typeof
|
|
37154
|
-
return
|
|
37152
|
+
function safeUrl(path27) {
|
|
37153
|
+
if (typeof path27 !== "string") {
|
|
37154
|
+
return path27;
|
|
37155
37155
|
}
|
|
37156
|
-
const pathSegments =
|
|
37156
|
+
const pathSegments = path27.split("?");
|
|
37157
37157
|
if (pathSegments.length !== 2) {
|
|
37158
|
-
return
|
|
37158
|
+
return path27;
|
|
37159
37159
|
}
|
|
37160
37160
|
const qp = new URLSearchParams(pathSegments.pop());
|
|
37161
37161
|
qp.sort();
|
|
37162
37162
|
return [...pathSegments, qp.toString()].join("?");
|
|
37163
37163
|
}
|
|
37164
|
-
function matchKey(mockDispatch2, { path:
|
|
37165
|
-
const pathMatch = matchValue(mockDispatch2.path,
|
|
37164
|
+
function matchKey(mockDispatch2, { path: path27, method, body, headers }) {
|
|
37165
|
+
const pathMatch = matchValue(mockDispatch2.path, path27);
|
|
37166
37166
|
const methodMatch = matchValue(mockDispatch2.method, method);
|
|
37167
37167
|
const bodyMatch = typeof mockDispatch2.body !== "undefined" ? matchValue(mockDispatch2.body, body) : true;
|
|
37168
37168
|
const headersMatch = matchHeaders(mockDispatch2, headers);
|
|
@@ -37180,7 +37180,7 @@ var require_mock_utils = __commonJS({
|
|
|
37180
37180
|
function getMockDispatch(mockDispatches, key) {
|
|
37181
37181
|
const basePath = key.query ? buildURL(key.path, key.query) : key.path;
|
|
37182
37182
|
const resolvedPath = typeof basePath === "string" ? safeUrl(basePath) : basePath;
|
|
37183
|
-
let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path:
|
|
37183
|
+
let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path: path27 }) => matchValue(safeUrl(path27), resolvedPath));
|
|
37184
37184
|
if (matchedMockDispatches.length === 0) {
|
|
37185
37185
|
throw new MockNotMatchedError(`Mock dispatch not matched for path '${resolvedPath}'`);
|
|
37186
37186
|
}
|
|
@@ -37217,9 +37217,9 @@ var require_mock_utils = __commonJS({
|
|
|
37217
37217
|
}
|
|
37218
37218
|
}
|
|
37219
37219
|
function buildKey(opts) {
|
|
37220
|
-
const { path:
|
|
37220
|
+
const { path: path27, method, body, headers, query } = opts;
|
|
37221
37221
|
return {
|
|
37222
|
-
path:
|
|
37222
|
+
path: path27,
|
|
37223
37223
|
method,
|
|
37224
37224
|
body,
|
|
37225
37225
|
headers,
|
|
@@ -37668,10 +37668,10 @@ var require_pending_interceptors_formatter = __commonJS({
|
|
|
37668
37668
|
}
|
|
37669
37669
|
format(pendingInterceptors) {
|
|
37670
37670
|
const withPrettyHeaders = pendingInterceptors.map(
|
|
37671
|
-
({ method, path:
|
|
37671
|
+
({ method, path: path27, data: { statusCode }, persist, times, timesInvoked, origin }) => ({
|
|
37672
37672
|
Method: method,
|
|
37673
37673
|
Origin: origin,
|
|
37674
|
-
Path:
|
|
37674
|
+
Path: path27,
|
|
37675
37675
|
"Status code": statusCode,
|
|
37676
37676
|
Persistent: persist ? "\u2705" : "\u274C",
|
|
37677
37677
|
Invocations: timesInvoked,
|
|
@@ -40612,7 +40612,7 @@ var require_fetch = __commonJS({
|
|
|
40612
40612
|
async function dispatch({ body }) {
|
|
40613
40613
|
const url = requestCurrentURL(request);
|
|
40614
40614
|
const agent = fetchParams.controller.dispatcher;
|
|
40615
|
-
return new Promise((
|
|
40615
|
+
return new Promise((resolve14, reject) => agent.dispatch(
|
|
40616
40616
|
{
|
|
40617
40617
|
path: url.pathname + url.search,
|
|
40618
40618
|
origin: url.origin,
|
|
@@ -40688,7 +40688,7 @@ var require_fetch = __commonJS({
|
|
|
40688
40688
|
}
|
|
40689
40689
|
}
|
|
40690
40690
|
}
|
|
40691
|
-
|
|
40691
|
+
resolve14({
|
|
40692
40692
|
status,
|
|
40693
40693
|
statusText,
|
|
40694
40694
|
headersList: headers[kHeadersList],
|
|
@@ -40731,7 +40731,7 @@ var require_fetch = __commonJS({
|
|
|
40731
40731
|
const val = headersList[n + 1].toString("latin1");
|
|
40732
40732
|
headers[kHeadersList].append(key, val);
|
|
40733
40733
|
}
|
|
40734
|
-
|
|
40734
|
+
resolve14({
|
|
40735
40735
|
status,
|
|
40736
40736
|
statusText: STATUS_CODES[status],
|
|
40737
40737
|
headersList: headers[kHeadersList],
|
|
@@ -42292,8 +42292,8 @@ var require_util6 = __commonJS({
|
|
|
42292
42292
|
}
|
|
42293
42293
|
}
|
|
42294
42294
|
}
|
|
42295
|
-
function validateCookiePath(
|
|
42296
|
-
for (const char of
|
|
42295
|
+
function validateCookiePath(path27) {
|
|
42296
|
+
for (const char of path27) {
|
|
42297
42297
|
const code = char.charCodeAt(0);
|
|
42298
42298
|
if (code < 33 || char === ";") {
|
|
42299
42299
|
throw new Error("Invalid cookie path");
|
|
@@ -43090,9 +43090,9 @@ var require_connection = __commonJS({
|
|
|
43090
43090
|
channels.open = diagnosticsChannel.channel("undici:websocket:open");
|
|
43091
43091
|
channels.close = diagnosticsChannel.channel("undici:websocket:close");
|
|
43092
43092
|
channels.socketError = diagnosticsChannel.channel("undici:websocket:socket_error");
|
|
43093
|
-
var
|
|
43093
|
+
var crypto2;
|
|
43094
43094
|
try {
|
|
43095
|
-
|
|
43095
|
+
crypto2 = require("crypto");
|
|
43096
43096
|
} catch {
|
|
43097
43097
|
}
|
|
43098
43098
|
function establishWebSocketConnection(url, protocols, ws, onEstablish, options) {
|
|
@@ -43111,7 +43111,7 @@ var require_connection = __commonJS({
|
|
|
43111
43111
|
const headersList = new Headers(options.headers)[kHeadersList];
|
|
43112
43112
|
request.headersList = headersList;
|
|
43113
43113
|
}
|
|
43114
|
-
const keyValue =
|
|
43114
|
+
const keyValue = crypto2.randomBytes(16).toString("base64");
|
|
43115
43115
|
request.headersList.append("sec-websocket-key", keyValue);
|
|
43116
43116
|
request.headersList.append("sec-websocket-version", "13");
|
|
43117
43117
|
for (const protocol of protocols) {
|
|
@@ -43140,7 +43140,7 @@ var require_connection = __commonJS({
|
|
|
43140
43140
|
return;
|
|
43141
43141
|
}
|
|
43142
43142
|
const secWSAccept = response.headersList.get("Sec-WebSocket-Accept");
|
|
43143
|
-
const digest =
|
|
43143
|
+
const digest = crypto2.createHash("sha1").update(keyValue + uid).digest("base64");
|
|
43144
43144
|
if (secWSAccept !== digest) {
|
|
43145
43145
|
failWebsocketConnection(ws, "Incorrect hash received in Sec-WebSocket-Accept header.");
|
|
43146
43146
|
return;
|
|
@@ -43220,9 +43220,9 @@ var require_frame = __commonJS({
|
|
|
43220
43220
|
"node_modules/undici/lib/websocket/frame.js"(exports2, module2) {
|
|
43221
43221
|
"use strict";
|
|
43222
43222
|
var { maxUnsigned16Bit } = require_constants5();
|
|
43223
|
-
var
|
|
43223
|
+
var crypto2;
|
|
43224
43224
|
try {
|
|
43225
|
-
|
|
43225
|
+
crypto2 = require("crypto");
|
|
43226
43226
|
} catch {
|
|
43227
43227
|
}
|
|
43228
43228
|
var WebsocketFrameSend = class {
|
|
@@ -43231,7 +43231,7 @@ var require_frame = __commonJS({
|
|
|
43231
43231
|
*/
|
|
43232
43232
|
constructor(data) {
|
|
43233
43233
|
this.frameData = data;
|
|
43234
|
-
this.maskKey =
|
|
43234
|
+
this.maskKey = crypto2.randomBytes(4);
|
|
43235
43235
|
}
|
|
43236
43236
|
createFrame(opcode) {
|
|
43237
43237
|
const bodyLength = this.frameData?.byteLength ?? 0;
|
|
@@ -43973,11 +43973,11 @@ var require_undici = __commonJS({
|
|
|
43973
43973
|
if (typeof opts.path !== "string") {
|
|
43974
43974
|
throw new InvalidArgumentError("invalid opts.path");
|
|
43975
43975
|
}
|
|
43976
|
-
let
|
|
43976
|
+
let path27 = opts.path;
|
|
43977
43977
|
if (!opts.path.startsWith("/")) {
|
|
43978
|
-
|
|
43978
|
+
path27 = `/${path27}`;
|
|
43979
43979
|
}
|
|
43980
|
-
url = new URL(util.parseOrigin(url).origin +
|
|
43980
|
+
url = new URL(util.parseOrigin(url).origin + path27);
|
|
43981
43981
|
} else {
|
|
43982
43982
|
if (!opts) {
|
|
43983
43983
|
opts = typeof url === "object" ? url : {};
|
|
@@ -44526,7 +44526,7 @@ var init_mcp_check_provider = __esm({
|
|
|
44526
44526
|
logger.warn(
|
|
44527
44527
|
`MCP ${transportName} failed (attempt ${attempt + 1}/${maxRetries + 1}), retrying in ${delay}ms: ${error instanceof Error ? error.message : String(error)}`
|
|
44528
44528
|
);
|
|
44529
|
-
await new Promise((
|
|
44529
|
+
await new Promise((resolve14) => setTimeout(resolve14, delay));
|
|
44530
44530
|
attempt += 1;
|
|
44531
44531
|
} finally {
|
|
44532
44532
|
try {
|
|
@@ -44808,7 +44808,7 @@ async function acquirePromptLock() {
|
|
|
44808
44808
|
activePrompt = true;
|
|
44809
44809
|
return;
|
|
44810
44810
|
}
|
|
44811
|
-
await new Promise((
|
|
44811
|
+
await new Promise((resolve14) => waiters.push(resolve14));
|
|
44812
44812
|
activePrompt = true;
|
|
44813
44813
|
}
|
|
44814
44814
|
function releasePromptLock() {
|
|
@@ -44818,7 +44818,7 @@ function releasePromptLock() {
|
|
|
44818
44818
|
}
|
|
44819
44819
|
async function interactivePrompt(options) {
|
|
44820
44820
|
await acquirePromptLock();
|
|
44821
|
-
return new Promise((
|
|
44821
|
+
return new Promise((resolve14, reject) => {
|
|
44822
44822
|
const dbg = process.env.VISOR_DEBUG === "true";
|
|
44823
44823
|
try {
|
|
44824
44824
|
if (dbg) {
|
|
@@ -44905,12 +44905,12 @@ async function interactivePrompt(options) {
|
|
|
44905
44905
|
};
|
|
44906
44906
|
const finish = (value) => {
|
|
44907
44907
|
cleanup();
|
|
44908
|
-
|
|
44908
|
+
resolve14(value);
|
|
44909
44909
|
};
|
|
44910
44910
|
if (options.timeout && options.timeout > 0) {
|
|
44911
44911
|
timeoutId = setTimeout(() => {
|
|
44912
44912
|
cleanup();
|
|
44913
|
-
if (defaultValue !== void 0) return
|
|
44913
|
+
if (defaultValue !== void 0) return resolve14(defaultValue);
|
|
44914
44914
|
return reject(new Error("Input timeout"));
|
|
44915
44915
|
}, options.timeout);
|
|
44916
44916
|
}
|
|
@@ -45042,7 +45042,7 @@ async function interactivePrompt(options) {
|
|
|
45042
45042
|
});
|
|
45043
45043
|
}
|
|
45044
45044
|
async function simplePrompt(prompt) {
|
|
45045
|
-
return new Promise((
|
|
45045
|
+
return new Promise((resolve14) => {
|
|
45046
45046
|
const rl = readline.createInterface({
|
|
45047
45047
|
input: process.stdin,
|
|
45048
45048
|
output: process.stdout
|
|
@@ -45058,7 +45058,7 @@ async function simplePrompt(prompt) {
|
|
|
45058
45058
|
rl.question(`${prompt}
|
|
45059
45059
|
> `, (answer) => {
|
|
45060
45060
|
rl.close();
|
|
45061
|
-
|
|
45061
|
+
resolve14(answer.trim());
|
|
45062
45062
|
});
|
|
45063
45063
|
});
|
|
45064
45064
|
}
|
|
@@ -45226,7 +45226,7 @@ function isStdinAvailable() {
|
|
|
45226
45226
|
return !process.stdin.isTTY;
|
|
45227
45227
|
}
|
|
45228
45228
|
async function readStdin(timeout, maxSize = 1024 * 1024) {
|
|
45229
|
-
return new Promise((
|
|
45229
|
+
return new Promise((resolve14, reject) => {
|
|
45230
45230
|
let data = "";
|
|
45231
45231
|
let timeoutId;
|
|
45232
45232
|
if (timeout) {
|
|
@@ -45253,7 +45253,7 @@ async function readStdin(timeout, maxSize = 1024 * 1024) {
|
|
|
45253
45253
|
};
|
|
45254
45254
|
const onEnd = () => {
|
|
45255
45255
|
cleanup();
|
|
45256
|
-
|
|
45256
|
+
resolve14(data.trim());
|
|
45257
45257
|
};
|
|
45258
45258
|
const onError = (err) => {
|
|
45259
45259
|
cleanup();
|
|
@@ -49371,23 +49371,23 @@ __export(renderer_schema_exports, {
|
|
|
49371
49371
|
});
|
|
49372
49372
|
async function loadRendererSchema(name) {
|
|
49373
49373
|
try {
|
|
49374
|
-
const
|
|
49375
|
-
const
|
|
49374
|
+
const fs23 = await import("fs/promises");
|
|
49375
|
+
const path27 = await import("path");
|
|
49376
49376
|
const sanitized = String(name).replace(/[^a-zA-Z0-9-]/g, "");
|
|
49377
49377
|
if (!sanitized) return void 0;
|
|
49378
49378
|
const candidates = [
|
|
49379
49379
|
// When bundled with ncc, __dirname is dist/ and output/ is at dist/output/
|
|
49380
|
-
|
|
49380
|
+
path27.join(__dirname, "output", sanitized, "schema.json"),
|
|
49381
49381
|
// When running from source, __dirname is src/state-machine/dispatch/ and output/ is at output/
|
|
49382
|
-
|
|
49382
|
+
path27.join(__dirname, "..", "..", "output", sanitized, "schema.json"),
|
|
49383
49383
|
// When running from a checkout with output/ folder copied to CWD
|
|
49384
|
-
|
|
49384
|
+
path27.join(process.cwd(), "output", sanitized, "schema.json"),
|
|
49385
49385
|
// Fallback: cwd/dist/output/
|
|
49386
|
-
|
|
49386
|
+
path27.join(process.cwd(), "dist", "output", sanitized, "schema.json")
|
|
49387
49387
|
];
|
|
49388
49388
|
for (const p of candidates) {
|
|
49389
49389
|
try {
|
|
49390
|
-
const raw = await
|
|
49390
|
+
const raw = await fs23.readFile(p, "utf-8");
|
|
49391
49391
|
return JSON.parse(raw);
|
|
49392
49392
|
} catch {
|
|
49393
49393
|
}
|
|
@@ -51806,8 +51806,8 @@ function updateStats2(results, state, isForEachIteration = false) {
|
|
|
51806
51806
|
async function renderTemplateContent2(checkId, checkConfig, reviewSummary) {
|
|
51807
51807
|
try {
|
|
51808
51808
|
const { createExtendedLiquid: createExtendedLiquid2 } = await Promise.resolve().then(() => (init_liquid_extensions(), liquid_extensions_exports));
|
|
51809
|
-
const
|
|
51810
|
-
const
|
|
51809
|
+
const fs23 = await import("fs/promises");
|
|
51810
|
+
const path27 = await import("path");
|
|
51811
51811
|
const schemaRaw = checkConfig.schema || "plain";
|
|
51812
51812
|
const schema = typeof schemaRaw === "string" && !schemaRaw.includes("{{") && !schemaRaw.includes("{%") ? schemaRaw : typeof schemaRaw === "object" ? "code-review" : "plain";
|
|
51813
51813
|
let templateContent;
|
|
@@ -51816,27 +51816,27 @@ async function renderTemplateContent2(checkId, checkConfig, reviewSummary) {
|
|
|
51816
51816
|
logger.debug(`[LevelDispatch] Using inline template for ${checkId}`);
|
|
51817
51817
|
} else if (checkConfig.template && checkConfig.template.file) {
|
|
51818
51818
|
const file = String(checkConfig.template.file);
|
|
51819
|
-
const resolved =
|
|
51820
|
-
templateContent = await
|
|
51819
|
+
const resolved = path27.resolve(process.cwd(), file);
|
|
51820
|
+
templateContent = await fs23.readFile(resolved, "utf-8");
|
|
51821
51821
|
logger.debug(`[LevelDispatch] Using template file for ${checkId}: ${resolved}`);
|
|
51822
51822
|
} else if (schema && schema !== "plain") {
|
|
51823
51823
|
const sanitized = String(schema).replace(/[^a-zA-Z0-9-]/g, "");
|
|
51824
51824
|
if (sanitized) {
|
|
51825
51825
|
const candidatePaths = [
|
|
51826
|
-
|
|
51826
|
+
path27.join(__dirname, "output", sanitized, "template.liquid"),
|
|
51827
51827
|
// bundled: dist/output/
|
|
51828
|
-
|
|
51828
|
+
path27.join(__dirname, "..", "..", "output", sanitized, "template.liquid"),
|
|
51829
51829
|
// source (from state-machine/states)
|
|
51830
|
-
|
|
51830
|
+
path27.join(__dirname, "..", "..", "..", "output", sanitized, "template.liquid"),
|
|
51831
51831
|
// source (alternate)
|
|
51832
|
-
|
|
51832
|
+
path27.join(process.cwd(), "output", sanitized, "template.liquid"),
|
|
51833
51833
|
// fallback: cwd/output/
|
|
51834
|
-
|
|
51834
|
+
path27.join(process.cwd(), "dist", "output", sanitized, "template.liquid")
|
|
51835
51835
|
// fallback: cwd/dist/output/
|
|
51836
51836
|
];
|
|
51837
51837
|
for (const p of candidatePaths) {
|
|
51838
51838
|
try {
|
|
51839
|
-
templateContent = await
|
|
51839
|
+
templateContent = await fs23.readFile(p, "utf-8");
|
|
51840
51840
|
if (templateContent) {
|
|
51841
51841
|
logger.debug(`[LevelDispatch] Using schema template for ${checkId}: ${p}`);
|
|
51842
51842
|
break;
|
|
@@ -53950,8 +53950,8 @@ var init_workspace_manager = __esm({
|
|
|
53950
53950
|
);
|
|
53951
53951
|
if (this.cleanupRequested && this.activeOperations === 0) {
|
|
53952
53952
|
logger.debug(`[Workspace] All references released, proceeding with deferred cleanup`);
|
|
53953
|
-
for (const
|
|
53954
|
-
|
|
53953
|
+
for (const resolve14 of this.cleanupResolvers) {
|
|
53954
|
+
resolve14();
|
|
53955
53955
|
}
|
|
53956
53956
|
this.cleanupResolvers = [];
|
|
53957
53957
|
}
|
|
@@ -54108,19 +54108,19 @@ var init_workspace_manager = __esm({
|
|
|
54108
54108
|
);
|
|
54109
54109
|
this.cleanupRequested = true;
|
|
54110
54110
|
await Promise.race([
|
|
54111
|
-
new Promise((
|
|
54111
|
+
new Promise((resolve14) => {
|
|
54112
54112
|
if (this.activeOperations === 0) {
|
|
54113
|
-
|
|
54113
|
+
resolve14();
|
|
54114
54114
|
} else {
|
|
54115
|
-
this.cleanupResolvers.push(
|
|
54115
|
+
this.cleanupResolvers.push(resolve14);
|
|
54116
54116
|
}
|
|
54117
54117
|
}),
|
|
54118
|
-
new Promise((
|
|
54118
|
+
new Promise((resolve14) => {
|
|
54119
54119
|
setTimeout(() => {
|
|
54120
54120
|
logger.warn(
|
|
54121
54121
|
`[Workspace] Cleanup timeout after ${timeout}ms, proceeding anyway (${this.activeOperations} operations still active)`
|
|
54122
54122
|
);
|
|
54123
|
-
|
|
54123
|
+
resolve14();
|
|
54124
54124
|
}, timeout);
|
|
54125
54125
|
})
|
|
54126
54126
|
]);
|
|
@@ -54598,1380 +54598,6 @@ var init_build_engine_context = __esm({
|
|
|
54598
54598
|
}
|
|
54599
54599
|
});
|
|
54600
54600
|
|
|
54601
|
-
// src/policy/default-engine.ts
|
|
54602
|
-
var DefaultPolicyEngine;
|
|
54603
|
-
var init_default_engine = __esm({
|
|
54604
|
-
"src/policy/default-engine.ts"() {
|
|
54605
|
-
"use strict";
|
|
54606
|
-
DefaultPolicyEngine = class {
|
|
54607
|
-
async initialize(_config) {
|
|
54608
|
-
}
|
|
54609
|
-
async evaluateCheckExecution(_checkId, _checkConfig) {
|
|
54610
|
-
return { allowed: true };
|
|
54611
|
-
}
|
|
54612
|
-
async evaluateToolInvocation(_serverName, _methodName, _transport) {
|
|
54613
|
-
return { allowed: true };
|
|
54614
|
-
}
|
|
54615
|
-
async evaluateCapabilities(_checkId, _capabilities) {
|
|
54616
|
-
return { allowed: true };
|
|
54617
|
-
}
|
|
54618
|
-
async shutdown() {
|
|
54619
|
-
}
|
|
54620
|
-
};
|
|
54621
|
-
}
|
|
54622
|
-
});
|
|
54623
|
-
|
|
54624
|
-
// src/enterprise/license/validator.ts
|
|
54625
|
-
var validator_exports = {};
|
|
54626
|
-
__export(validator_exports, {
|
|
54627
|
-
LicenseValidator: () => LicenseValidator
|
|
54628
|
-
});
|
|
54629
|
-
var crypto2, fs21, path25, LicenseValidator;
|
|
54630
|
-
var init_validator = __esm({
|
|
54631
|
-
"src/enterprise/license/validator.ts"() {
|
|
54632
|
-
"use strict";
|
|
54633
|
-
crypto2 = __toESM(require("crypto"));
|
|
54634
|
-
fs21 = __toESM(require("fs"));
|
|
54635
|
-
path25 = __toESM(require("path"));
|
|
54636
|
-
LicenseValidator = class _LicenseValidator {
|
|
54637
|
-
/** Ed25519 public key for license verification (PEM format). */
|
|
54638
|
-
static PUBLIC_KEY = "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAI/Zd08EFmgIdrDm/HXd0l3/5GBt7R1PrdvhdmEXhJlU=\n-----END PUBLIC KEY-----\n";
|
|
54639
|
-
cache = null;
|
|
54640
|
-
static CACHE_TTL = 5 * 60 * 1e3;
|
|
54641
|
-
// 5 minutes
|
|
54642
|
-
static GRACE_PERIOD = 72 * 3600 * 1e3;
|
|
54643
|
-
// 72 hours after expiry
|
|
54644
|
-
/**
|
|
54645
|
-
* Load and validate license from environment or file.
|
|
54646
|
-
*
|
|
54647
|
-
* Resolution order:
|
|
54648
|
-
* 1. VISOR_LICENSE env var (JWT string)
|
|
54649
|
-
* 2. VISOR_LICENSE_FILE env var (path to file)
|
|
54650
|
-
* 3. .visor-license in project root (cwd)
|
|
54651
|
-
* 4. .visor-license in ~/.config/visor/
|
|
54652
|
-
*/
|
|
54653
|
-
async loadAndValidate() {
|
|
54654
|
-
if (this.cache && Date.now() - this.cache.validatedAt < _LicenseValidator.CACHE_TTL) {
|
|
54655
|
-
return this.cache.payload;
|
|
54656
|
-
}
|
|
54657
|
-
const token = this.resolveToken();
|
|
54658
|
-
if (!token) return null;
|
|
54659
|
-
const payload = this.verifyAndDecode(token);
|
|
54660
|
-
if (!payload) return null;
|
|
54661
|
-
this.cache = { payload, validatedAt: Date.now() };
|
|
54662
|
-
return payload;
|
|
54663
|
-
}
|
|
54664
|
-
/** Check if a specific feature is licensed */
|
|
54665
|
-
hasFeature(feature) {
|
|
54666
|
-
if (!this.cache) return false;
|
|
54667
|
-
return this.cache.payload.features.includes(feature);
|
|
54668
|
-
}
|
|
54669
|
-
/** Check if license is valid (with grace period) */
|
|
54670
|
-
isValid() {
|
|
54671
|
-
if (!this.cache) return false;
|
|
54672
|
-
const now = Date.now();
|
|
54673
|
-
const expiryMs = this.cache.payload.exp * 1e3;
|
|
54674
|
-
return now < expiryMs + _LicenseValidator.GRACE_PERIOD;
|
|
54675
|
-
}
|
|
54676
|
-
/** Check if the license is within its grace period (expired but still valid) */
|
|
54677
|
-
isInGracePeriod() {
|
|
54678
|
-
if (!this.cache) return false;
|
|
54679
|
-
const now = Date.now();
|
|
54680
|
-
const expiryMs = this.cache.payload.exp * 1e3;
|
|
54681
|
-
return now >= expiryMs && now < expiryMs + _LicenseValidator.GRACE_PERIOD;
|
|
54682
|
-
}
|
|
54683
|
-
resolveToken() {
|
|
54684
|
-
if (process.env.VISOR_LICENSE) {
|
|
54685
|
-
return process.env.VISOR_LICENSE.trim();
|
|
54686
|
-
}
|
|
54687
|
-
if (process.env.VISOR_LICENSE_FILE) {
|
|
54688
|
-
const resolved = path25.resolve(process.env.VISOR_LICENSE_FILE);
|
|
54689
|
-
const home2 = process.env.HOME || process.env.USERPROFILE || "";
|
|
54690
|
-
const allowedPrefixes = [path25.normalize(process.cwd())];
|
|
54691
|
-
if (home2) allowedPrefixes.push(path25.normalize(path25.join(home2, ".config", "visor")));
|
|
54692
|
-
let realPath;
|
|
54693
|
-
try {
|
|
54694
|
-
realPath = fs21.realpathSync(resolved);
|
|
54695
|
-
} catch {
|
|
54696
|
-
return null;
|
|
54697
|
-
}
|
|
54698
|
-
const isSafe = allowedPrefixes.some(
|
|
54699
|
-
(prefix) => realPath === prefix || realPath.startsWith(prefix + path25.sep)
|
|
54700
|
-
);
|
|
54701
|
-
if (!isSafe) return null;
|
|
54702
|
-
return this.readFile(realPath);
|
|
54703
|
-
}
|
|
54704
|
-
const cwdPath = path25.join(process.cwd(), ".visor-license");
|
|
54705
|
-
const cwdToken = this.readFile(cwdPath);
|
|
54706
|
-
if (cwdToken) return cwdToken;
|
|
54707
|
-
const home = process.env.HOME || process.env.USERPROFILE || "";
|
|
54708
|
-
if (home) {
|
|
54709
|
-
const configPath = path25.join(home, ".config", "visor", ".visor-license");
|
|
54710
|
-
const configToken = this.readFile(configPath);
|
|
54711
|
-
if (configToken) return configToken;
|
|
54712
|
-
}
|
|
54713
|
-
return null;
|
|
54714
|
-
}
|
|
54715
|
-
readFile(filePath) {
|
|
54716
|
-
try {
|
|
54717
|
-
return fs21.readFileSync(filePath, "utf-8").trim();
|
|
54718
|
-
} catch {
|
|
54719
|
-
return null;
|
|
54720
|
-
}
|
|
54721
|
-
}
|
|
54722
|
-
verifyAndDecode(token) {
|
|
54723
|
-
try {
|
|
54724
|
-
const parts = token.split(".");
|
|
54725
|
-
if (parts.length !== 3) return null;
|
|
54726
|
-
const [headerB64, payloadB64, signatureB64] = parts;
|
|
54727
|
-
const header = JSON.parse(Buffer.from(headerB64, "base64url").toString());
|
|
54728
|
-
if (header.alg !== "EdDSA") return null;
|
|
54729
|
-
const data = `${headerB64}.${payloadB64}`;
|
|
54730
|
-
const signature = Buffer.from(signatureB64, "base64url");
|
|
54731
|
-
const publicKey = crypto2.createPublicKey(_LicenseValidator.PUBLIC_KEY);
|
|
54732
|
-
if (publicKey.asymmetricKeyType !== "ed25519") {
|
|
54733
|
-
return null;
|
|
54734
|
-
}
|
|
54735
|
-
const isValid = crypto2.verify(null, Buffer.from(data), publicKey, signature);
|
|
54736
|
-
if (!isValid) return null;
|
|
54737
|
-
const payload = JSON.parse(Buffer.from(payloadB64, "base64url").toString());
|
|
54738
|
-
if (!payload.org || !Array.isArray(payload.features) || typeof payload.exp !== "number" || typeof payload.iat !== "number" || !payload.sub) {
|
|
54739
|
-
return null;
|
|
54740
|
-
}
|
|
54741
|
-
const now = Date.now();
|
|
54742
|
-
const expiryMs = payload.exp * 1e3;
|
|
54743
|
-
if (now >= expiryMs + _LicenseValidator.GRACE_PERIOD) {
|
|
54744
|
-
return null;
|
|
54745
|
-
}
|
|
54746
|
-
return payload;
|
|
54747
|
-
} catch {
|
|
54748
|
-
return null;
|
|
54749
|
-
}
|
|
54750
|
-
}
|
|
54751
|
-
};
|
|
54752
|
-
}
|
|
54753
|
-
});
|
|
54754
|
-
|
|
54755
|
-
// src/enterprise/policy/opa-compiler.ts
|
|
54756
|
-
var fs22, path26, os2, crypto3, import_child_process8, OpaCompiler;
|
|
54757
|
-
var init_opa_compiler = __esm({
|
|
54758
|
-
"src/enterprise/policy/opa-compiler.ts"() {
|
|
54759
|
-
"use strict";
|
|
54760
|
-
fs22 = __toESM(require("fs"));
|
|
54761
|
-
path26 = __toESM(require("path"));
|
|
54762
|
-
os2 = __toESM(require("os"));
|
|
54763
|
-
crypto3 = __toESM(require("crypto"));
|
|
54764
|
-
import_child_process8 = require("child_process");
|
|
54765
|
-
OpaCompiler = class _OpaCompiler {
|
|
54766
|
-
static CACHE_DIR = path26.join(os2.tmpdir(), "visor-opa-cache");
|
|
54767
|
-
/**
|
|
54768
|
-
* Resolve the input paths to WASM bytes.
|
|
54769
|
-
*
|
|
54770
|
-
* Strategy:
|
|
54771
|
-
* 1. If any path is a .wasm file, read it directly
|
|
54772
|
-
* 2. If a directory contains policy.wasm, read it
|
|
54773
|
-
* 3. Otherwise, collect all .rego files and auto-compile via `opa build`
|
|
54774
|
-
*/
|
|
54775
|
-
async resolveWasmBytes(paths) {
|
|
54776
|
-
const regoFiles = [];
|
|
54777
|
-
for (const p of paths) {
|
|
54778
|
-
const resolved = path26.resolve(p);
|
|
54779
|
-
if (path26.normalize(resolved).includes("..")) {
|
|
54780
|
-
throw new Error(`Policy path contains traversal sequences: ${p}`);
|
|
54781
|
-
}
|
|
54782
|
-
if (resolved.endsWith(".wasm") && fs22.existsSync(resolved)) {
|
|
54783
|
-
return fs22.readFileSync(resolved);
|
|
54784
|
-
}
|
|
54785
|
-
if (!fs22.existsSync(resolved)) continue;
|
|
54786
|
-
const stat2 = fs22.statSync(resolved);
|
|
54787
|
-
if (stat2.isDirectory()) {
|
|
54788
|
-
const wasmCandidate = path26.join(resolved, "policy.wasm");
|
|
54789
|
-
if (fs22.existsSync(wasmCandidate)) {
|
|
54790
|
-
return fs22.readFileSync(wasmCandidate);
|
|
54791
|
-
}
|
|
54792
|
-
const files = fs22.readdirSync(resolved);
|
|
54793
|
-
for (const f of files) {
|
|
54794
|
-
if (f.endsWith(".rego")) {
|
|
54795
|
-
regoFiles.push(path26.join(resolved, f));
|
|
54796
|
-
}
|
|
54797
|
-
}
|
|
54798
|
-
} else if (resolved.endsWith(".rego")) {
|
|
54799
|
-
regoFiles.push(resolved);
|
|
54800
|
-
}
|
|
54801
|
-
}
|
|
54802
|
-
if (regoFiles.length === 0) {
|
|
54803
|
-
throw new Error(
|
|
54804
|
-
`OPA WASM evaluator: no .wasm bundle or .rego files found in: ${paths.join(", ")}`
|
|
54805
|
-
);
|
|
54806
|
-
}
|
|
54807
|
-
return this.compileRego(regoFiles);
|
|
54808
|
-
}
|
|
54809
|
-
/**
|
|
54810
|
-
* Auto-compile .rego files to a WASM bundle using the `opa` CLI.
|
|
54811
|
-
*
|
|
54812
|
-
* Caches the compiled bundle based on a content hash of all input .rego files
|
|
54813
|
-
* so subsequent runs skip compilation if policies haven't changed.
|
|
54814
|
-
*/
|
|
54815
|
-
compileRego(regoFiles) {
|
|
54816
|
-
try {
|
|
54817
|
-
(0, import_child_process8.execFileSync)("opa", ["version"], { stdio: "pipe" });
|
|
54818
|
-
} catch {
|
|
54819
|
-
throw new Error(
|
|
54820
|
-
"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(" ")
|
|
54821
|
-
);
|
|
54822
|
-
}
|
|
54823
|
-
const hash = crypto3.createHash("sha256");
|
|
54824
|
-
for (const f of regoFiles.sort()) {
|
|
54825
|
-
hash.update(fs22.readFileSync(f));
|
|
54826
|
-
hash.update(f);
|
|
54827
|
-
}
|
|
54828
|
-
const cacheKey = hash.digest("hex").slice(0, 16);
|
|
54829
|
-
const cacheDir = _OpaCompiler.CACHE_DIR;
|
|
54830
|
-
const cachedWasm = path26.join(cacheDir, `${cacheKey}.wasm`);
|
|
54831
|
-
if (fs22.existsSync(cachedWasm)) {
|
|
54832
|
-
return fs22.readFileSync(cachedWasm);
|
|
54833
|
-
}
|
|
54834
|
-
fs22.mkdirSync(cacheDir, { recursive: true });
|
|
54835
|
-
const bundleTar = path26.join(cacheDir, `${cacheKey}-bundle.tar.gz`);
|
|
54836
|
-
try {
|
|
54837
|
-
const args = [
|
|
54838
|
-
"build",
|
|
54839
|
-
"-t",
|
|
54840
|
-
"wasm",
|
|
54841
|
-
"-e",
|
|
54842
|
-
"visor",
|
|
54843
|
-
// entrypoint: the visor package tree
|
|
54844
|
-
"-o",
|
|
54845
|
-
bundleTar,
|
|
54846
|
-
...regoFiles
|
|
54847
|
-
];
|
|
54848
|
-
(0, import_child_process8.execFileSync)("opa", args, {
|
|
54849
|
-
stdio: "pipe",
|
|
54850
|
-
timeout: 3e4
|
|
54851
|
-
});
|
|
54852
|
-
} catch (err) {
|
|
54853
|
-
const stderr = err?.stderr?.toString() || "";
|
|
54854
|
-
throw new Error(
|
|
54855
|
-
`Failed to compile .rego files to WASM:
|
|
54856
|
-
${stderr}
|
|
54857
|
-
Ensure your .rego files are valid and the \`opa\` CLI is installed.`
|
|
54858
|
-
);
|
|
54859
|
-
}
|
|
54860
|
-
try {
|
|
54861
|
-
(0, import_child_process8.execFileSync)("tar", ["-xzf", bundleTar, "-C", cacheDir, "/policy.wasm"], {
|
|
54862
|
-
stdio: "pipe"
|
|
54863
|
-
});
|
|
54864
|
-
const extractedWasm = path26.join(cacheDir, "policy.wasm");
|
|
54865
|
-
if (fs22.existsSync(extractedWasm)) {
|
|
54866
|
-
fs22.renameSync(extractedWasm, cachedWasm);
|
|
54867
|
-
}
|
|
54868
|
-
} catch {
|
|
54869
|
-
try {
|
|
54870
|
-
(0, import_child_process8.execFileSync)("tar", ["-xzf", bundleTar, "-C", cacheDir, "policy.wasm"], {
|
|
54871
|
-
stdio: "pipe"
|
|
54872
|
-
});
|
|
54873
|
-
const extractedWasm = path26.join(cacheDir, "policy.wasm");
|
|
54874
|
-
if (fs22.existsSync(extractedWasm)) {
|
|
54875
|
-
fs22.renameSync(extractedWasm, cachedWasm);
|
|
54876
|
-
}
|
|
54877
|
-
} catch (err2) {
|
|
54878
|
-
throw new Error(`Failed to extract policy.wasm from OPA bundle: ${err2?.message || err2}`);
|
|
54879
|
-
}
|
|
54880
|
-
}
|
|
54881
|
-
try {
|
|
54882
|
-
fs22.unlinkSync(bundleTar);
|
|
54883
|
-
} catch {
|
|
54884
|
-
}
|
|
54885
|
-
if (!fs22.existsSync(cachedWasm)) {
|
|
54886
|
-
throw new Error("OPA build succeeded but policy.wasm was not found in the bundle");
|
|
54887
|
-
}
|
|
54888
|
-
return fs22.readFileSync(cachedWasm);
|
|
54889
|
-
}
|
|
54890
|
-
};
|
|
54891
|
-
}
|
|
54892
|
-
});
|
|
54893
|
-
|
|
54894
|
-
// src/enterprise/policy/opa-wasm-evaluator.ts
|
|
54895
|
-
var fs23, path27, OpaWasmEvaluator;
|
|
54896
|
-
var init_opa_wasm_evaluator = __esm({
|
|
54897
|
-
"src/enterprise/policy/opa-wasm-evaluator.ts"() {
|
|
54898
|
-
"use strict";
|
|
54899
|
-
fs23 = __toESM(require("fs"));
|
|
54900
|
-
path27 = __toESM(require("path"));
|
|
54901
|
-
init_opa_compiler();
|
|
54902
|
-
OpaWasmEvaluator = class {
|
|
54903
|
-
policy = null;
|
|
54904
|
-
dataDocument = {};
|
|
54905
|
-
compiler = new OpaCompiler();
|
|
54906
|
-
async initialize(rulesPath) {
|
|
54907
|
-
const paths = Array.isArray(rulesPath) ? rulesPath : [rulesPath];
|
|
54908
|
-
const wasmBytes = await this.compiler.resolveWasmBytes(paths);
|
|
54909
|
-
try {
|
|
54910
|
-
const { createRequire } = require("module");
|
|
54911
|
-
const runtimeRequire = createRequire(__filename);
|
|
54912
|
-
const opaWasm = runtimeRequire("@open-policy-agent/opa-wasm");
|
|
54913
|
-
const loadPolicy = opaWasm.loadPolicy || opaWasm.default?.loadPolicy;
|
|
54914
|
-
if (!loadPolicy) {
|
|
54915
|
-
throw new Error("loadPolicy not found in @open-policy-agent/opa-wasm");
|
|
54916
|
-
}
|
|
54917
|
-
this.policy = await loadPolicy(wasmBytes);
|
|
54918
|
-
} catch (err) {
|
|
54919
|
-
if (err?.code === "MODULE_NOT_FOUND" || err?.code === "ERR_MODULE_NOT_FOUND") {
|
|
54920
|
-
throw new Error(
|
|
54921
|
-
"OPA WASM evaluator requires @open-policy-agent/opa-wasm. Install it with: npm install @open-policy-agent/opa-wasm"
|
|
54922
|
-
);
|
|
54923
|
-
}
|
|
54924
|
-
throw err;
|
|
54925
|
-
}
|
|
54926
|
-
}
|
|
54927
|
-
/**
|
|
54928
|
-
* Load external data from a JSON file to use as the OPA data document.
|
|
54929
|
-
* The loaded data will be passed to `policy.setData()` during evaluation,
|
|
54930
|
-
* making it available in Rego via `data.<key>`.
|
|
54931
|
-
*/
|
|
54932
|
-
loadData(dataPath) {
|
|
54933
|
-
const resolved = path27.resolve(dataPath);
|
|
54934
|
-
if (path27.normalize(resolved).includes("..")) {
|
|
54935
|
-
throw new Error(`Data path contains traversal sequences: ${dataPath}`);
|
|
54936
|
-
}
|
|
54937
|
-
if (!fs23.existsSync(resolved)) {
|
|
54938
|
-
throw new Error(`OPA data file not found: ${resolved}`);
|
|
54939
|
-
}
|
|
54940
|
-
const stat2 = fs23.statSync(resolved);
|
|
54941
|
-
if (stat2.size > 10 * 1024 * 1024) {
|
|
54942
|
-
throw new Error(`OPA data file exceeds 10MB limit: ${resolved} (${stat2.size} bytes)`);
|
|
54943
|
-
}
|
|
54944
|
-
const raw = fs23.readFileSync(resolved, "utf-8");
|
|
54945
|
-
try {
|
|
54946
|
-
const parsed = JSON.parse(raw);
|
|
54947
|
-
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
54948
|
-
throw new Error("OPA data file must contain a JSON object (not an array or primitive)");
|
|
54949
|
-
}
|
|
54950
|
-
this.dataDocument = parsed;
|
|
54951
|
-
} catch (err) {
|
|
54952
|
-
if (err.message.startsWith("OPA data file must")) {
|
|
54953
|
-
throw err;
|
|
54954
|
-
}
|
|
54955
|
-
throw new Error(`Failed to parse OPA data file ${resolved}: ${err.message}`);
|
|
54956
|
-
}
|
|
54957
|
-
}
|
|
54958
|
-
async evaluate(input) {
|
|
54959
|
-
if (!this.policy) {
|
|
54960
|
-
throw new Error("OPA WASM evaluator not initialized");
|
|
54961
|
-
}
|
|
54962
|
-
this.policy.setData(this.dataDocument);
|
|
54963
|
-
const resultSet = this.policy.evaluate(input);
|
|
54964
|
-
if (Array.isArray(resultSet) && resultSet.length > 0) {
|
|
54965
|
-
return resultSet[0].result;
|
|
54966
|
-
}
|
|
54967
|
-
return void 0;
|
|
54968
|
-
}
|
|
54969
|
-
async shutdown() {
|
|
54970
|
-
if (this.policy) {
|
|
54971
|
-
if (typeof this.policy.close === "function") {
|
|
54972
|
-
try {
|
|
54973
|
-
this.policy.close();
|
|
54974
|
-
} catch {
|
|
54975
|
-
}
|
|
54976
|
-
} else if (typeof this.policy.free === "function") {
|
|
54977
|
-
try {
|
|
54978
|
-
this.policy.free();
|
|
54979
|
-
} catch {
|
|
54980
|
-
}
|
|
54981
|
-
}
|
|
54982
|
-
}
|
|
54983
|
-
this.policy = null;
|
|
54984
|
-
}
|
|
54985
|
-
};
|
|
54986
|
-
}
|
|
54987
|
-
});
|
|
54988
|
-
|
|
54989
|
-
// src/enterprise/policy/opa-http-evaluator.ts
|
|
54990
|
-
var OpaHttpEvaluator;
|
|
54991
|
-
var init_opa_http_evaluator = __esm({
|
|
54992
|
-
"src/enterprise/policy/opa-http-evaluator.ts"() {
|
|
54993
|
-
"use strict";
|
|
54994
|
-
OpaHttpEvaluator = class {
|
|
54995
|
-
baseUrl;
|
|
54996
|
-
timeout;
|
|
54997
|
-
constructor(baseUrl, timeout = 5e3) {
|
|
54998
|
-
let parsed;
|
|
54999
|
-
try {
|
|
55000
|
-
parsed = new URL(baseUrl);
|
|
55001
|
-
} catch {
|
|
55002
|
-
throw new Error(`OPA HTTP evaluator: invalid URL: ${baseUrl}`);
|
|
55003
|
-
}
|
|
55004
|
-
if (!["http:", "https:"].includes(parsed.protocol)) {
|
|
55005
|
-
throw new Error(
|
|
55006
|
-
`OPA HTTP evaluator: url must use http:// or https:// protocol, got: ${baseUrl}`
|
|
55007
|
-
);
|
|
55008
|
-
}
|
|
55009
|
-
const hostname = parsed.hostname;
|
|
55010
|
-
if (this.isBlockedHostname(hostname)) {
|
|
55011
|
-
throw new Error(
|
|
55012
|
-
`OPA HTTP evaluator: url must not point to internal, loopback, or private network addresses`
|
|
55013
|
-
);
|
|
55014
|
-
}
|
|
55015
|
-
this.baseUrl = baseUrl.replace(/\/+$/, "");
|
|
55016
|
-
this.timeout = timeout;
|
|
55017
|
-
}
|
|
55018
|
-
/**
|
|
55019
|
-
* Check if a hostname is blocked due to SSRF concerns.
|
|
55020
|
-
*
|
|
55021
|
-
* Blocks:
|
|
55022
|
-
* - Loopback addresses (127.x.x.x, localhost, 0.0.0.0, ::1)
|
|
55023
|
-
* - Link-local addresses (169.254.x.x)
|
|
55024
|
-
* - Private networks (10.x.x.x, 172.16-31.x.x, 192.168.x.x)
|
|
55025
|
-
* - IPv6 unique local addresses (fd00::/8)
|
|
55026
|
-
* - Cloud metadata services (*.internal)
|
|
55027
|
-
*/
|
|
55028
|
-
isBlockedHostname(hostname) {
|
|
55029
|
-
if (!hostname) return true;
|
|
55030
|
-
const normalized = hostname.toLowerCase().replace(/^\[|\]$/g, "");
|
|
55031
|
-
if (normalized === "metadata.google.internal" || normalized.endsWith(".internal")) {
|
|
55032
|
-
return true;
|
|
55033
|
-
}
|
|
55034
|
-
if (normalized === "localhost" || normalized === "localhost.localdomain") {
|
|
55035
|
-
return true;
|
|
55036
|
-
}
|
|
55037
|
-
if (normalized === "::1" || normalized === "0:0:0:0:0:0:0:1") {
|
|
55038
|
-
return true;
|
|
55039
|
-
}
|
|
55040
|
-
const ipv4Pattern = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/;
|
|
55041
|
-
const ipv4Match = normalized.match(ipv4Pattern);
|
|
55042
|
-
if (ipv4Match) {
|
|
55043
|
-
const octets = ipv4Match.slice(1, 5).map(Number);
|
|
55044
|
-
if (octets.some((octet) => octet > 255)) {
|
|
55045
|
-
return false;
|
|
55046
|
-
}
|
|
55047
|
-
const [a, b] = octets;
|
|
55048
|
-
if (a === 127) {
|
|
55049
|
-
return true;
|
|
55050
|
-
}
|
|
55051
|
-
if (a === 0) {
|
|
55052
|
-
return true;
|
|
55053
|
-
}
|
|
55054
|
-
if (a === 169 && b === 254) {
|
|
55055
|
-
return true;
|
|
55056
|
-
}
|
|
55057
|
-
if (a === 10) {
|
|
55058
|
-
return true;
|
|
55059
|
-
}
|
|
55060
|
-
if (a === 172 && b >= 16 && b <= 31) {
|
|
55061
|
-
return true;
|
|
55062
|
-
}
|
|
55063
|
-
if (a === 192 && b === 168) {
|
|
55064
|
-
return true;
|
|
55065
|
-
}
|
|
55066
|
-
}
|
|
55067
|
-
if (normalized.startsWith("fd") || normalized.startsWith("fc")) {
|
|
55068
|
-
return true;
|
|
55069
|
-
}
|
|
55070
|
-
if (normalized.startsWith("fe80:")) {
|
|
55071
|
-
return true;
|
|
55072
|
-
}
|
|
55073
|
-
return false;
|
|
55074
|
-
}
|
|
55075
|
-
/**
|
|
55076
|
-
* Evaluate a policy rule against an input document via OPA REST API.
|
|
55077
|
-
*
|
|
55078
|
-
* @param input - The input document to evaluate
|
|
55079
|
-
* @param rulePath - OPA rule path (e.g., 'visor/check/execute')
|
|
55080
|
-
* @returns The result object from OPA, or undefined on error
|
|
55081
|
-
*/
|
|
55082
|
-
async evaluate(input, rulePath) {
|
|
55083
|
-
const encodedPath = rulePath.split("/").map((s) => encodeURIComponent(s)).join("/");
|
|
55084
|
-
const url = `${this.baseUrl}/v1/data/${encodedPath}`;
|
|
55085
|
-
const controller = new AbortController();
|
|
55086
|
-
const timer = setTimeout(() => controller.abort(), this.timeout);
|
|
55087
|
-
try {
|
|
55088
|
-
const response = await fetch(url, {
|
|
55089
|
-
method: "POST",
|
|
55090
|
-
headers: { "Content-Type": "application/json" },
|
|
55091
|
-
body: JSON.stringify({ input }),
|
|
55092
|
-
signal: controller.signal
|
|
55093
|
-
});
|
|
55094
|
-
if (!response.ok) {
|
|
55095
|
-
throw new Error(`OPA HTTP ${response.status}: ${response.statusText}`);
|
|
55096
|
-
}
|
|
55097
|
-
let body;
|
|
55098
|
-
try {
|
|
55099
|
-
body = await response.json();
|
|
55100
|
-
} catch (jsonErr) {
|
|
55101
|
-
throw new Error(
|
|
55102
|
-
`OPA HTTP evaluator: failed to parse JSON response: ${jsonErr instanceof Error ? jsonErr.message : String(jsonErr)}`
|
|
55103
|
-
);
|
|
55104
|
-
}
|
|
55105
|
-
return body?.result;
|
|
55106
|
-
} finally {
|
|
55107
|
-
clearTimeout(timer);
|
|
55108
|
-
}
|
|
55109
|
-
}
|
|
55110
|
-
async shutdown() {
|
|
55111
|
-
}
|
|
55112
|
-
};
|
|
55113
|
-
}
|
|
55114
|
-
});
|
|
55115
|
-
|
|
55116
|
-
// src/enterprise/policy/policy-input-builder.ts
|
|
55117
|
-
var PolicyInputBuilder;
|
|
55118
|
-
var init_policy_input_builder = __esm({
|
|
55119
|
-
"src/enterprise/policy/policy-input-builder.ts"() {
|
|
55120
|
-
"use strict";
|
|
55121
|
-
PolicyInputBuilder = class {
|
|
55122
|
-
roles;
|
|
55123
|
-
actor;
|
|
55124
|
-
repository;
|
|
55125
|
-
pullRequest;
|
|
55126
|
-
constructor(policyConfig, actor, repository, pullRequest) {
|
|
55127
|
-
this.roles = policyConfig.roles || {};
|
|
55128
|
-
this.actor = actor;
|
|
55129
|
-
this.repository = repository;
|
|
55130
|
-
this.pullRequest = pullRequest;
|
|
55131
|
-
}
|
|
55132
|
-
/** Resolve which roles apply to the current actor. */
|
|
55133
|
-
resolveRoles() {
|
|
55134
|
-
const matched = [];
|
|
55135
|
-
for (const [roleName, roleConfig] of Object.entries(this.roles)) {
|
|
55136
|
-
let identityMatch = false;
|
|
55137
|
-
if (roleConfig.author_association && this.actor.authorAssociation && roleConfig.author_association.includes(this.actor.authorAssociation)) {
|
|
55138
|
-
identityMatch = true;
|
|
55139
|
-
}
|
|
55140
|
-
if (!identityMatch && roleConfig.users && this.actor.login && roleConfig.users.includes(this.actor.login)) {
|
|
55141
|
-
identityMatch = true;
|
|
55142
|
-
}
|
|
55143
|
-
if (!identityMatch && roleConfig.slack_users && this.actor.slack?.userId && roleConfig.slack_users.includes(this.actor.slack.userId)) {
|
|
55144
|
-
identityMatch = true;
|
|
55145
|
-
}
|
|
55146
|
-
if (!identityMatch && roleConfig.emails && this.actor.slack?.email) {
|
|
55147
|
-
const actorEmail = this.actor.slack.email.toLowerCase();
|
|
55148
|
-
if (roleConfig.emails.some((e) => e.toLowerCase() === actorEmail)) {
|
|
55149
|
-
identityMatch = true;
|
|
55150
|
-
}
|
|
55151
|
-
}
|
|
55152
|
-
if (!identityMatch) continue;
|
|
55153
|
-
if (roleConfig.slack_channels && roleConfig.slack_channels.length > 0) {
|
|
55154
|
-
if (!this.actor.slack?.channelId || !roleConfig.slack_channels.includes(this.actor.slack.channelId)) {
|
|
55155
|
-
continue;
|
|
55156
|
-
}
|
|
55157
|
-
}
|
|
55158
|
-
matched.push(roleName);
|
|
55159
|
-
}
|
|
55160
|
-
return matched;
|
|
55161
|
-
}
|
|
55162
|
-
buildActor() {
|
|
55163
|
-
return {
|
|
55164
|
-
authorAssociation: this.actor.authorAssociation,
|
|
55165
|
-
login: this.actor.login,
|
|
55166
|
-
roles: this.resolveRoles(),
|
|
55167
|
-
isLocalMode: this.actor.isLocalMode,
|
|
55168
|
-
...this.actor.slack && { slack: this.actor.slack }
|
|
55169
|
-
};
|
|
55170
|
-
}
|
|
55171
|
-
forCheckExecution(check) {
|
|
55172
|
-
return {
|
|
55173
|
-
scope: "check.execute",
|
|
55174
|
-
check: {
|
|
55175
|
-
id: check.id,
|
|
55176
|
-
type: check.type,
|
|
55177
|
-
group: check.group,
|
|
55178
|
-
tags: check.tags,
|
|
55179
|
-
criticality: check.criticality,
|
|
55180
|
-
sandbox: check.sandbox,
|
|
55181
|
-
policy: check.policy
|
|
55182
|
-
},
|
|
55183
|
-
actor: this.buildActor(),
|
|
55184
|
-
repository: this.repository,
|
|
55185
|
-
pullRequest: this.pullRequest
|
|
55186
|
-
};
|
|
55187
|
-
}
|
|
55188
|
-
forToolInvocation(serverName, methodName, transport) {
|
|
55189
|
-
return {
|
|
55190
|
-
scope: "tool.invoke",
|
|
55191
|
-
tool: { serverName, methodName, transport },
|
|
55192
|
-
actor: this.buildActor(),
|
|
55193
|
-
repository: this.repository,
|
|
55194
|
-
pullRequest: this.pullRequest
|
|
55195
|
-
};
|
|
55196
|
-
}
|
|
55197
|
-
forCapabilityResolve(checkId, capabilities) {
|
|
55198
|
-
return {
|
|
55199
|
-
scope: "capability.resolve",
|
|
55200
|
-
check: { id: checkId, type: "ai" },
|
|
55201
|
-
capability: capabilities,
|
|
55202
|
-
actor: this.buildActor(),
|
|
55203
|
-
repository: this.repository,
|
|
55204
|
-
pullRequest: this.pullRequest
|
|
55205
|
-
};
|
|
55206
|
-
}
|
|
55207
|
-
};
|
|
55208
|
-
}
|
|
55209
|
-
});
|
|
55210
|
-
|
|
55211
|
-
// src/enterprise/policy/opa-policy-engine.ts
|
|
55212
|
-
var opa_policy_engine_exports = {};
|
|
55213
|
-
__export(opa_policy_engine_exports, {
|
|
55214
|
-
OpaPolicyEngine: () => OpaPolicyEngine
|
|
55215
|
-
});
|
|
55216
|
-
var OpaPolicyEngine;
|
|
55217
|
-
var init_opa_policy_engine = __esm({
|
|
55218
|
-
"src/enterprise/policy/opa-policy-engine.ts"() {
|
|
55219
|
-
"use strict";
|
|
55220
|
-
init_opa_wasm_evaluator();
|
|
55221
|
-
init_opa_http_evaluator();
|
|
55222
|
-
init_policy_input_builder();
|
|
55223
|
-
OpaPolicyEngine = class {
|
|
55224
|
-
evaluator = null;
|
|
55225
|
-
fallback;
|
|
55226
|
-
timeout;
|
|
55227
|
-
config;
|
|
55228
|
-
inputBuilder = null;
|
|
55229
|
-
logger = null;
|
|
55230
|
-
constructor(config) {
|
|
55231
|
-
this.config = config;
|
|
55232
|
-
this.fallback = config.fallback || "deny";
|
|
55233
|
-
this.timeout = config.timeout || 5e3;
|
|
55234
|
-
}
|
|
55235
|
-
async initialize(config) {
|
|
55236
|
-
try {
|
|
55237
|
-
this.logger = (init_logger(), __toCommonJS(logger_exports)).logger;
|
|
55238
|
-
} catch {
|
|
55239
|
-
}
|
|
55240
|
-
const actor = {
|
|
55241
|
-
authorAssociation: process.env.VISOR_AUTHOR_ASSOCIATION,
|
|
55242
|
-
login: process.env.VISOR_AUTHOR_LOGIN || process.env.GITHUB_ACTOR,
|
|
55243
|
-
isLocalMode: !process.env.GITHUB_ACTIONS
|
|
55244
|
-
};
|
|
55245
|
-
const repo = {
|
|
55246
|
-
owner: process.env.GITHUB_REPOSITORY_OWNER,
|
|
55247
|
-
name: process.env.GITHUB_REPOSITORY?.split("/")[1],
|
|
55248
|
-
branch: process.env.GITHUB_HEAD_REF,
|
|
55249
|
-
baseBranch: process.env.GITHUB_BASE_REF,
|
|
55250
|
-
event: process.env.GITHUB_EVENT_NAME
|
|
55251
|
-
};
|
|
55252
|
-
const prNum = process.env.GITHUB_PR_NUMBER ? parseInt(process.env.GITHUB_PR_NUMBER, 10) : void 0;
|
|
55253
|
-
const pullRequest = {
|
|
55254
|
-
number: prNum !== void 0 && Number.isFinite(prNum) ? prNum : void 0
|
|
55255
|
-
};
|
|
55256
|
-
this.inputBuilder = new PolicyInputBuilder(config, actor, repo, pullRequest);
|
|
55257
|
-
if (config.engine === "local") {
|
|
55258
|
-
if (!config.rules) {
|
|
55259
|
-
throw new Error("OPA local mode requires `policy.rules` path to .wasm or .rego files");
|
|
55260
|
-
}
|
|
55261
|
-
const wasm = new OpaWasmEvaluator();
|
|
55262
|
-
await wasm.initialize(config.rules);
|
|
55263
|
-
if (config.data) {
|
|
55264
|
-
wasm.loadData(config.data);
|
|
55265
|
-
}
|
|
55266
|
-
this.evaluator = wasm;
|
|
55267
|
-
} else if (config.engine === "remote") {
|
|
55268
|
-
if (!config.url) {
|
|
55269
|
-
throw new Error("OPA remote mode requires `policy.url` pointing to OPA server");
|
|
55270
|
-
}
|
|
55271
|
-
this.evaluator = new OpaHttpEvaluator(config.url, this.timeout);
|
|
55272
|
-
} else {
|
|
55273
|
-
this.evaluator = null;
|
|
55274
|
-
}
|
|
55275
|
-
}
|
|
55276
|
-
/**
|
|
55277
|
-
* Update actor/repo/PR context (e.g., after PR info becomes available).
|
|
55278
|
-
* Called by the enterprise loader when engine context is enriched.
|
|
55279
|
-
*/
|
|
55280
|
-
setActorContext(actor, repo, pullRequest) {
|
|
55281
|
-
this.inputBuilder = new PolicyInputBuilder(this.config, actor, repo, pullRequest);
|
|
55282
|
-
}
|
|
55283
|
-
async evaluateCheckExecution(checkId, checkConfig) {
|
|
55284
|
-
if (!this.evaluator || !this.inputBuilder) return { allowed: true };
|
|
55285
|
-
const cfg = checkConfig && typeof checkConfig === "object" ? checkConfig : {};
|
|
55286
|
-
const policyOverride = cfg.policy;
|
|
55287
|
-
const input = this.inputBuilder.forCheckExecution({
|
|
55288
|
-
id: checkId,
|
|
55289
|
-
type: cfg.type || "ai",
|
|
55290
|
-
group: cfg.group,
|
|
55291
|
-
tags: cfg.tags,
|
|
55292
|
-
criticality: cfg.criticality,
|
|
55293
|
-
sandbox: cfg.sandbox,
|
|
55294
|
-
policy: policyOverride
|
|
55295
|
-
});
|
|
55296
|
-
return this.doEvaluate(input, this.resolveRulePath("check.execute", policyOverride?.rule));
|
|
55297
|
-
}
|
|
55298
|
-
async evaluateToolInvocation(serverName, methodName, transport) {
|
|
55299
|
-
if (!this.evaluator || !this.inputBuilder) return { allowed: true };
|
|
55300
|
-
const input = this.inputBuilder.forToolInvocation(serverName, methodName, transport);
|
|
55301
|
-
return this.doEvaluate(input, "visor/tool/invoke");
|
|
55302
|
-
}
|
|
55303
|
-
async evaluateCapabilities(checkId, capabilities) {
|
|
55304
|
-
if (!this.evaluator || !this.inputBuilder) return { allowed: true };
|
|
55305
|
-
const input = this.inputBuilder.forCapabilityResolve(checkId, capabilities);
|
|
55306
|
-
return this.doEvaluate(input, "visor/capability/resolve");
|
|
55307
|
-
}
|
|
55308
|
-
async shutdown() {
|
|
55309
|
-
if (this.evaluator && "shutdown" in this.evaluator) {
|
|
55310
|
-
await this.evaluator.shutdown();
|
|
55311
|
-
}
|
|
55312
|
-
this.evaluator = null;
|
|
55313
|
-
this.inputBuilder = null;
|
|
55314
|
-
}
|
|
55315
|
-
resolveRulePath(defaultScope, override) {
|
|
55316
|
-
if (override) {
|
|
55317
|
-
return override.startsWith("visor/") ? override : `visor/${override}`;
|
|
55318
|
-
}
|
|
55319
|
-
return `visor/${defaultScope.replace(/\./g, "/")}`;
|
|
55320
|
-
}
|
|
55321
|
-
async doEvaluate(input, rulePath) {
|
|
55322
|
-
try {
|
|
55323
|
-
this.logger?.debug(`[PolicyEngine] Evaluating ${rulePath}`, JSON.stringify(input));
|
|
55324
|
-
let timer;
|
|
55325
|
-
const timeoutPromise = new Promise((_resolve, reject) => {
|
|
55326
|
-
timer = setTimeout(() => reject(new Error("policy evaluation timeout")), this.timeout);
|
|
55327
|
-
});
|
|
55328
|
-
try {
|
|
55329
|
-
const result = await Promise.race([this.rawEvaluate(input, rulePath), timeoutPromise]);
|
|
55330
|
-
const decision = this.parseDecision(result);
|
|
55331
|
-
if (!decision.allowed && this.fallback === "warn") {
|
|
55332
|
-
decision.allowed = true;
|
|
55333
|
-
decision.warn = true;
|
|
55334
|
-
decision.reason = `audit: ${decision.reason || "policy denied"}`;
|
|
55335
|
-
}
|
|
55336
|
-
this.logger?.debug(
|
|
55337
|
-
`[PolicyEngine] Decision for ${rulePath}: allowed=${decision.allowed}, warn=${decision.warn || false}, reason=${decision.reason || "none"}`
|
|
55338
|
-
);
|
|
55339
|
-
return decision;
|
|
55340
|
-
} finally {
|
|
55341
|
-
if (timer) clearTimeout(timer);
|
|
55342
|
-
}
|
|
55343
|
-
} catch (err) {
|
|
55344
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
55345
|
-
this.logger?.warn(`[PolicyEngine] Evaluation failed for ${rulePath}: ${msg}`);
|
|
55346
|
-
return {
|
|
55347
|
-
allowed: this.fallback === "allow" || this.fallback === "warn",
|
|
55348
|
-
warn: this.fallback === "warn" ? true : void 0,
|
|
55349
|
-
reason: `policy evaluation failed, fallback=${this.fallback}`
|
|
55350
|
-
};
|
|
55351
|
-
}
|
|
55352
|
-
}
|
|
55353
|
-
async rawEvaluate(input, rulePath) {
|
|
55354
|
-
if (this.evaluator instanceof OpaWasmEvaluator) {
|
|
55355
|
-
const result = await this.evaluator.evaluate(input);
|
|
55356
|
-
return this.navigateWasmResult(result, rulePath);
|
|
55357
|
-
}
|
|
55358
|
-
return this.evaluator.evaluate(input, rulePath);
|
|
55359
|
-
}
|
|
55360
|
-
/**
|
|
55361
|
-
* Navigate nested OPA WASM result tree to reach the specific rule's output.
|
|
55362
|
-
* The WASM entrypoint `-e visor` means the result root IS the visor package,
|
|
55363
|
-
* so we strip the `visor/` prefix and walk the remaining segments.
|
|
55364
|
-
*/
|
|
55365
|
-
navigateWasmResult(result, rulePath) {
|
|
55366
|
-
if (!result || typeof result !== "object") return result;
|
|
55367
|
-
const segments = rulePath.replace(/^visor\//, "").split("/");
|
|
55368
|
-
let current = result;
|
|
55369
|
-
for (const seg of segments) {
|
|
55370
|
-
if (current && typeof current === "object" && seg in current) {
|
|
55371
|
-
current = current[seg];
|
|
55372
|
-
} else {
|
|
55373
|
-
return void 0;
|
|
55374
|
-
}
|
|
55375
|
-
}
|
|
55376
|
-
return current;
|
|
55377
|
-
}
|
|
55378
|
-
parseDecision(result) {
|
|
55379
|
-
if (result === void 0 || result === null) {
|
|
55380
|
-
return {
|
|
55381
|
-
allowed: this.fallback === "allow" || this.fallback === "warn",
|
|
55382
|
-
warn: this.fallback === "warn" ? true : void 0,
|
|
55383
|
-
reason: this.fallback === "warn" ? "audit: no policy result" : "no policy result"
|
|
55384
|
-
};
|
|
55385
|
-
}
|
|
55386
|
-
const allowed = result.allowed !== false;
|
|
55387
|
-
const decision = {
|
|
55388
|
-
allowed,
|
|
55389
|
-
reason: result.reason
|
|
55390
|
-
};
|
|
55391
|
-
if (result.capabilities) {
|
|
55392
|
-
decision.capabilities = result.capabilities;
|
|
55393
|
-
}
|
|
55394
|
-
return decision;
|
|
55395
|
-
}
|
|
55396
|
-
};
|
|
55397
|
-
}
|
|
55398
|
-
});
|
|
55399
|
-
|
|
55400
|
-
// src/enterprise/scheduler/knex-store.ts
|
|
55401
|
-
var knex_store_exports = {};
|
|
55402
|
-
__export(knex_store_exports, {
|
|
55403
|
-
KnexStoreBackend: () => KnexStoreBackend
|
|
55404
|
-
});
|
|
55405
|
-
function toNum(val) {
|
|
55406
|
-
if (val === null || val === void 0) return void 0;
|
|
55407
|
-
return typeof val === "string" ? parseInt(val, 10) : val;
|
|
55408
|
-
}
|
|
55409
|
-
function safeJsonParse2(value) {
|
|
55410
|
-
if (!value) return void 0;
|
|
55411
|
-
try {
|
|
55412
|
-
return JSON.parse(value);
|
|
55413
|
-
} catch {
|
|
55414
|
-
return void 0;
|
|
55415
|
-
}
|
|
55416
|
-
}
|
|
55417
|
-
function fromTriggerRow2(row) {
|
|
55418
|
-
return {
|
|
55419
|
-
id: row.id,
|
|
55420
|
-
creatorId: row.creator_id,
|
|
55421
|
-
creatorContext: row.creator_context ?? void 0,
|
|
55422
|
-
creatorName: row.creator_name ?? void 0,
|
|
55423
|
-
description: row.description ?? void 0,
|
|
55424
|
-
channels: safeJsonParse2(row.channels),
|
|
55425
|
-
fromUsers: safeJsonParse2(row.from_users),
|
|
55426
|
-
fromBots: row.from_bots === true || row.from_bots === 1,
|
|
55427
|
-
contains: safeJsonParse2(row.contains),
|
|
55428
|
-
matchPattern: row.match_pattern ?? void 0,
|
|
55429
|
-
threads: row.threads,
|
|
55430
|
-
workflow: row.workflow,
|
|
55431
|
-
inputs: safeJsonParse2(row.inputs),
|
|
55432
|
-
outputContext: safeJsonParse2(row.output_context),
|
|
55433
|
-
status: row.status,
|
|
55434
|
-
enabled: row.enabled === true || row.enabled === 1,
|
|
55435
|
-
createdAt: toNum(row.created_at)
|
|
55436
|
-
};
|
|
55437
|
-
}
|
|
55438
|
-
function toTriggerInsertRow(trigger) {
|
|
55439
|
-
return {
|
|
55440
|
-
id: trigger.id,
|
|
55441
|
-
creator_id: trigger.creatorId,
|
|
55442
|
-
creator_context: trigger.creatorContext ?? null,
|
|
55443
|
-
creator_name: trigger.creatorName ?? null,
|
|
55444
|
-
description: trigger.description ?? null,
|
|
55445
|
-
channels: trigger.channels ? JSON.stringify(trigger.channels) : null,
|
|
55446
|
-
from_users: trigger.fromUsers ? JSON.stringify(trigger.fromUsers) : null,
|
|
55447
|
-
from_bots: trigger.fromBots,
|
|
55448
|
-
contains: trigger.contains ? JSON.stringify(trigger.contains) : null,
|
|
55449
|
-
match_pattern: trigger.matchPattern ?? null,
|
|
55450
|
-
threads: trigger.threads,
|
|
55451
|
-
workflow: trigger.workflow,
|
|
55452
|
-
inputs: trigger.inputs ? JSON.stringify(trigger.inputs) : null,
|
|
55453
|
-
output_context: trigger.outputContext ? JSON.stringify(trigger.outputContext) : null,
|
|
55454
|
-
status: trigger.status,
|
|
55455
|
-
enabled: trigger.enabled,
|
|
55456
|
-
created_at: trigger.createdAt
|
|
55457
|
-
};
|
|
55458
|
-
}
|
|
55459
|
-
function fromDbRow2(row) {
|
|
55460
|
-
return {
|
|
55461
|
-
id: row.id,
|
|
55462
|
-
creatorId: row.creator_id,
|
|
55463
|
-
creatorContext: row.creator_context ?? void 0,
|
|
55464
|
-
creatorName: row.creator_name ?? void 0,
|
|
55465
|
-
timezone: row.timezone,
|
|
55466
|
-
schedule: row.schedule_expr,
|
|
55467
|
-
runAt: toNum(row.run_at),
|
|
55468
|
-
isRecurring: row.is_recurring === true || row.is_recurring === 1,
|
|
55469
|
-
originalExpression: row.original_expression,
|
|
55470
|
-
workflow: row.workflow ?? void 0,
|
|
55471
|
-
workflowInputs: safeJsonParse2(row.workflow_inputs),
|
|
55472
|
-
outputContext: safeJsonParse2(row.output_context),
|
|
55473
|
-
status: row.status,
|
|
55474
|
-
createdAt: toNum(row.created_at),
|
|
55475
|
-
lastRunAt: toNum(row.last_run_at),
|
|
55476
|
-
nextRunAt: toNum(row.next_run_at),
|
|
55477
|
-
runCount: row.run_count,
|
|
55478
|
-
failureCount: row.failure_count,
|
|
55479
|
-
lastError: row.last_error ?? void 0,
|
|
55480
|
-
previousResponse: row.previous_response ?? void 0
|
|
55481
|
-
};
|
|
55482
|
-
}
|
|
55483
|
-
function toInsertRow(schedule) {
|
|
55484
|
-
return {
|
|
55485
|
-
id: schedule.id,
|
|
55486
|
-
creator_id: schedule.creatorId,
|
|
55487
|
-
creator_context: schedule.creatorContext ?? null,
|
|
55488
|
-
creator_name: schedule.creatorName ?? null,
|
|
55489
|
-
timezone: schedule.timezone,
|
|
55490
|
-
schedule_expr: schedule.schedule,
|
|
55491
|
-
run_at: schedule.runAt ?? null,
|
|
55492
|
-
is_recurring: schedule.isRecurring,
|
|
55493
|
-
original_expression: schedule.originalExpression,
|
|
55494
|
-
workflow: schedule.workflow ?? null,
|
|
55495
|
-
workflow_inputs: schedule.workflowInputs ? JSON.stringify(schedule.workflowInputs) : null,
|
|
55496
|
-
output_context: schedule.outputContext ? JSON.stringify(schedule.outputContext) : null,
|
|
55497
|
-
status: schedule.status,
|
|
55498
|
-
created_at: schedule.createdAt,
|
|
55499
|
-
last_run_at: schedule.lastRunAt ?? null,
|
|
55500
|
-
next_run_at: schedule.nextRunAt ?? null,
|
|
55501
|
-
run_count: schedule.runCount,
|
|
55502
|
-
failure_count: schedule.failureCount,
|
|
55503
|
-
last_error: schedule.lastError ?? null,
|
|
55504
|
-
previous_response: schedule.previousResponse ?? null
|
|
55505
|
-
};
|
|
55506
|
-
}
|
|
55507
|
-
var fs24, path28, import_uuid2, KnexStoreBackend;
|
|
55508
|
-
var init_knex_store = __esm({
|
|
55509
|
-
"src/enterprise/scheduler/knex-store.ts"() {
|
|
55510
|
-
"use strict";
|
|
55511
|
-
fs24 = __toESM(require("fs"));
|
|
55512
|
-
path28 = __toESM(require("path"));
|
|
55513
|
-
import_uuid2 = require("uuid");
|
|
55514
|
-
init_logger();
|
|
55515
|
-
KnexStoreBackend = class {
|
|
55516
|
-
knex = null;
|
|
55517
|
-
driver;
|
|
55518
|
-
connection;
|
|
55519
|
-
constructor(driver, storageConfig, _haConfig) {
|
|
55520
|
-
this.driver = driver;
|
|
55521
|
-
this.connection = storageConfig.connection || {};
|
|
55522
|
-
}
|
|
55523
|
-
async initialize() {
|
|
55524
|
-
const { createRequire } = require("module");
|
|
55525
|
-
const runtimeRequire = createRequire(__filename);
|
|
55526
|
-
let knexFactory;
|
|
55527
|
-
try {
|
|
55528
|
-
knexFactory = runtimeRequire("knex");
|
|
55529
|
-
} catch (err) {
|
|
55530
|
-
const code = err?.code;
|
|
55531
|
-
if (code === "MODULE_NOT_FOUND" || code === "ERR_MODULE_NOT_FOUND") {
|
|
55532
|
-
throw new Error(
|
|
55533
|
-
"knex is required for PostgreSQL/MySQL/MSSQL schedule storage. Install it with: npm install knex"
|
|
55534
|
-
);
|
|
55535
|
-
}
|
|
55536
|
-
throw err;
|
|
55537
|
-
}
|
|
55538
|
-
const clientMap = {
|
|
55539
|
-
postgresql: "pg",
|
|
55540
|
-
mysql: "mysql2",
|
|
55541
|
-
mssql: "tedious"
|
|
55542
|
-
};
|
|
55543
|
-
const client = clientMap[this.driver];
|
|
55544
|
-
let connection;
|
|
55545
|
-
if (this.connection.connection_string) {
|
|
55546
|
-
connection = this.connection.connection_string;
|
|
55547
|
-
} else if (this.driver === "mssql") {
|
|
55548
|
-
connection = this.buildMssqlConnection();
|
|
55549
|
-
} else {
|
|
55550
|
-
connection = this.buildStandardConnection();
|
|
55551
|
-
}
|
|
55552
|
-
this.knex = knexFactory({
|
|
55553
|
-
client,
|
|
55554
|
-
connection,
|
|
55555
|
-
pool: {
|
|
55556
|
-
min: this.connection.pool?.min ?? 0,
|
|
55557
|
-
max: this.connection.pool?.max ?? 10
|
|
55558
|
-
}
|
|
55559
|
-
});
|
|
55560
|
-
await this.migrateSchema();
|
|
55561
|
-
logger.info(`[KnexStore] Initialized (${this.driver})`);
|
|
55562
|
-
}
|
|
55563
|
-
buildStandardConnection() {
|
|
55564
|
-
return {
|
|
55565
|
-
host: this.connection.host || "localhost",
|
|
55566
|
-
port: this.connection.port,
|
|
55567
|
-
database: this.connection.database || "visor",
|
|
55568
|
-
user: this.connection.user,
|
|
55569
|
-
password: this.connection.password,
|
|
55570
|
-
ssl: this.resolveSslConfig()
|
|
55571
|
-
};
|
|
55572
|
-
}
|
|
55573
|
-
buildMssqlConnection() {
|
|
55574
|
-
const ssl = this.connection.ssl;
|
|
55575
|
-
const sslEnabled = ssl === true || typeof ssl === "object" && ssl.enabled !== false;
|
|
55576
|
-
return {
|
|
55577
|
-
server: this.connection.host || "localhost",
|
|
55578
|
-
port: this.connection.port,
|
|
55579
|
-
database: this.connection.database || "visor",
|
|
55580
|
-
user: this.connection.user,
|
|
55581
|
-
password: this.connection.password,
|
|
55582
|
-
options: {
|
|
55583
|
-
encrypt: sslEnabled,
|
|
55584
|
-
trustServerCertificate: typeof ssl === "object" ? ssl.reject_unauthorized === false : !sslEnabled
|
|
55585
|
-
}
|
|
55586
|
-
};
|
|
55587
|
-
}
|
|
55588
|
-
resolveSslConfig() {
|
|
55589
|
-
const ssl = this.connection.ssl;
|
|
55590
|
-
if (ssl === false || ssl === void 0) return false;
|
|
55591
|
-
if (ssl === true) return { rejectUnauthorized: true };
|
|
55592
|
-
if (ssl.enabled === false) return false;
|
|
55593
|
-
const result = {
|
|
55594
|
-
rejectUnauthorized: ssl.reject_unauthorized !== false
|
|
55595
|
-
};
|
|
55596
|
-
if (ssl.ca) {
|
|
55597
|
-
const caPath = this.validateSslPath(ssl.ca, "CA certificate");
|
|
55598
|
-
result.ca = fs24.readFileSync(caPath, "utf8");
|
|
55599
|
-
}
|
|
55600
|
-
if (ssl.cert) {
|
|
55601
|
-
const certPath = this.validateSslPath(ssl.cert, "client certificate");
|
|
55602
|
-
result.cert = fs24.readFileSync(certPath, "utf8");
|
|
55603
|
-
}
|
|
55604
|
-
if (ssl.key) {
|
|
55605
|
-
const keyPath = this.validateSslPath(ssl.key, "client key");
|
|
55606
|
-
result.key = fs24.readFileSync(keyPath, "utf8");
|
|
55607
|
-
}
|
|
55608
|
-
return result;
|
|
55609
|
-
}
|
|
55610
|
-
validateSslPath(filePath, label) {
|
|
55611
|
-
const resolved = path28.resolve(filePath);
|
|
55612
|
-
if (resolved !== path28.normalize(resolved)) {
|
|
55613
|
-
throw new Error(`SSL ${label} path contains invalid sequences: ${filePath}`);
|
|
55614
|
-
}
|
|
55615
|
-
if (!fs24.existsSync(resolved)) {
|
|
55616
|
-
throw new Error(`SSL ${label} not found: ${filePath}`);
|
|
55617
|
-
}
|
|
55618
|
-
return resolved;
|
|
55619
|
-
}
|
|
55620
|
-
async shutdown() {
|
|
55621
|
-
if (this.knex) {
|
|
55622
|
-
await this.knex.destroy();
|
|
55623
|
-
this.knex = null;
|
|
55624
|
-
}
|
|
55625
|
-
}
|
|
55626
|
-
async migrateSchema() {
|
|
55627
|
-
const knex = this.getKnex();
|
|
55628
|
-
const exists = await knex.schema.hasTable("schedules");
|
|
55629
|
-
if (!exists) {
|
|
55630
|
-
await knex.schema.createTable("schedules", (table) => {
|
|
55631
|
-
table.string("id", 36).primary();
|
|
55632
|
-
table.string("creator_id", 255).notNullable().index();
|
|
55633
|
-
table.string("creator_context", 255);
|
|
55634
|
-
table.string("creator_name", 255);
|
|
55635
|
-
table.string("timezone", 64).notNullable().defaultTo("UTC");
|
|
55636
|
-
table.string("schedule_expr", 255);
|
|
55637
|
-
table.bigInteger("run_at");
|
|
55638
|
-
table.boolean("is_recurring").notNullable();
|
|
55639
|
-
table.text("original_expression");
|
|
55640
|
-
table.string("workflow", 255);
|
|
55641
|
-
table.text("workflow_inputs");
|
|
55642
|
-
table.text("output_context");
|
|
55643
|
-
table.string("status", 20).notNullable().index();
|
|
55644
|
-
table.bigInteger("created_at").notNullable();
|
|
55645
|
-
table.bigInteger("last_run_at");
|
|
55646
|
-
table.bigInteger("next_run_at");
|
|
55647
|
-
table.integer("run_count").notNullable().defaultTo(0);
|
|
55648
|
-
table.integer("failure_count").notNullable().defaultTo(0);
|
|
55649
|
-
table.text("last_error");
|
|
55650
|
-
table.text("previous_response");
|
|
55651
|
-
table.index(["status", "next_run_at"]);
|
|
55652
|
-
});
|
|
55653
|
-
}
|
|
55654
|
-
const triggersExist = await knex.schema.hasTable("message_triggers");
|
|
55655
|
-
if (!triggersExist) {
|
|
55656
|
-
await knex.schema.createTable("message_triggers", (table) => {
|
|
55657
|
-
table.string("id", 36).primary();
|
|
55658
|
-
table.string("creator_id", 255).notNullable().index();
|
|
55659
|
-
table.string("creator_context", 255);
|
|
55660
|
-
table.string("creator_name", 255);
|
|
55661
|
-
table.text("description");
|
|
55662
|
-
table.text("channels");
|
|
55663
|
-
table.text("from_users");
|
|
55664
|
-
table.boolean("from_bots").notNullable().defaultTo(false);
|
|
55665
|
-
table.text("contains");
|
|
55666
|
-
table.text("match_pattern");
|
|
55667
|
-
table.string("threads", 20).notNullable().defaultTo("any");
|
|
55668
|
-
table.string("workflow", 255).notNullable();
|
|
55669
|
-
table.text("inputs");
|
|
55670
|
-
table.text("output_context");
|
|
55671
|
-
table.string("status", 20).notNullable().defaultTo("active").index();
|
|
55672
|
-
table.boolean("enabled").notNullable().defaultTo(true);
|
|
55673
|
-
table.bigInteger("created_at").notNullable();
|
|
55674
|
-
});
|
|
55675
|
-
}
|
|
55676
|
-
const locksExist = await knex.schema.hasTable("scheduler_locks");
|
|
55677
|
-
if (!locksExist) {
|
|
55678
|
-
await knex.schema.createTable("scheduler_locks", (table) => {
|
|
55679
|
-
table.string("lock_id", 255).primary();
|
|
55680
|
-
table.string("node_id", 255).notNullable();
|
|
55681
|
-
table.string("lock_token", 36).notNullable();
|
|
55682
|
-
table.bigInteger("acquired_at").notNullable();
|
|
55683
|
-
table.bigInteger("expires_at").notNullable();
|
|
55684
|
-
});
|
|
55685
|
-
}
|
|
55686
|
-
}
|
|
55687
|
-
getKnex() {
|
|
55688
|
-
if (!this.knex) {
|
|
55689
|
-
throw new Error("[KnexStore] Not initialized. Call initialize() first.");
|
|
55690
|
-
}
|
|
55691
|
-
return this.knex;
|
|
55692
|
-
}
|
|
55693
|
-
// --- CRUD ---
|
|
55694
|
-
async create(schedule) {
|
|
55695
|
-
const knex = this.getKnex();
|
|
55696
|
-
const newSchedule = {
|
|
55697
|
-
...schedule,
|
|
55698
|
-
id: (0, import_uuid2.v4)(),
|
|
55699
|
-
createdAt: Date.now(),
|
|
55700
|
-
runCount: 0,
|
|
55701
|
-
failureCount: 0,
|
|
55702
|
-
status: "active"
|
|
55703
|
-
};
|
|
55704
|
-
await knex("schedules").insert(toInsertRow(newSchedule));
|
|
55705
|
-
logger.info(`[KnexStore] Created schedule ${newSchedule.id} for user ${newSchedule.creatorId}`);
|
|
55706
|
-
return newSchedule;
|
|
55707
|
-
}
|
|
55708
|
-
async importSchedule(schedule) {
|
|
55709
|
-
const knex = this.getKnex();
|
|
55710
|
-
const existing = await knex("schedules").where("id", schedule.id).first();
|
|
55711
|
-
if (existing) return;
|
|
55712
|
-
await knex("schedules").insert(toInsertRow(schedule));
|
|
55713
|
-
}
|
|
55714
|
-
async get(id) {
|
|
55715
|
-
const knex = this.getKnex();
|
|
55716
|
-
const row = await knex("schedules").where("id", id).first();
|
|
55717
|
-
return row ? fromDbRow2(row) : void 0;
|
|
55718
|
-
}
|
|
55719
|
-
async update(id, patch) {
|
|
55720
|
-
const knex = this.getKnex();
|
|
55721
|
-
const existing = await knex("schedules").where("id", id).first();
|
|
55722
|
-
if (!existing) return void 0;
|
|
55723
|
-
const current = fromDbRow2(existing);
|
|
55724
|
-
const updated = { ...current, ...patch, id: current.id };
|
|
55725
|
-
const row = toInsertRow(updated);
|
|
55726
|
-
delete row.id;
|
|
55727
|
-
await knex("schedules").where("id", id).update(row);
|
|
55728
|
-
return updated;
|
|
55729
|
-
}
|
|
55730
|
-
async delete(id) {
|
|
55731
|
-
const knex = this.getKnex();
|
|
55732
|
-
const deleted = await knex("schedules").where("id", id).del();
|
|
55733
|
-
if (deleted > 0) {
|
|
55734
|
-
logger.info(`[KnexStore] Deleted schedule ${id}`);
|
|
55735
|
-
return true;
|
|
55736
|
-
}
|
|
55737
|
-
return false;
|
|
55738
|
-
}
|
|
55739
|
-
// --- Queries ---
|
|
55740
|
-
async getByCreator(creatorId) {
|
|
55741
|
-
const knex = this.getKnex();
|
|
55742
|
-
const rows = await knex("schedules").where("creator_id", creatorId);
|
|
55743
|
-
return rows.map((r) => fromDbRow2(r));
|
|
55744
|
-
}
|
|
55745
|
-
async getActiveSchedules() {
|
|
55746
|
-
const knex = this.getKnex();
|
|
55747
|
-
const rows = await knex("schedules").where("status", "active");
|
|
55748
|
-
return rows.map((r) => fromDbRow2(r));
|
|
55749
|
-
}
|
|
55750
|
-
async getDueSchedules(now) {
|
|
55751
|
-
const ts = now ?? Date.now();
|
|
55752
|
-
const knex = this.getKnex();
|
|
55753
|
-
const bFalse = this.driver === "mssql" ? 0 : false;
|
|
55754
|
-
const bTrue = this.driver === "mssql" ? 1 : true;
|
|
55755
|
-
const rows = await knex("schedules").where("status", "active").andWhere(function() {
|
|
55756
|
-
this.where(function() {
|
|
55757
|
-
this.where("is_recurring", bFalse).whereNotNull("run_at").where("run_at", "<=", ts);
|
|
55758
|
-
}).orWhere(function() {
|
|
55759
|
-
this.where("is_recurring", bTrue).whereNotNull("next_run_at").where("next_run_at", "<=", ts);
|
|
55760
|
-
});
|
|
55761
|
-
});
|
|
55762
|
-
return rows.map((r) => fromDbRow2(r));
|
|
55763
|
-
}
|
|
55764
|
-
async findByWorkflow(creatorId, workflowName) {
|
|
55765
|
-
const knex = this.getKnex();
|
|
55766
|
-
const escaped = workflowName.toLowerCase().replace(/[%_\\]/g, "\\$&");
|
|
55767
|
-
const pattern = `%${escaped}%`;
|
|
55768
|
-
const rows = await knex("schedules").where("creator_id", creatorId).where("status", "active").whereRaw("LOWER(workflow) LIKE ? ESCAPE '\\'", [pattern]);
|
|
55769
|
-
return rows.map((r) => fromDbRow2(r));
|
|
55770
|
-
}
|
|
55771
|
-
async getAll() {
|
|
55772
|
-
const knex = this.getKnex();
|
|
55773
|
-
const rows = await knex("schedules");
|
|
55774
|
-
return rows.map((r) => fromDbRow2(r));
|
|
55775
|
-
}
|
|
55776
|
-
async getStats() {
|
|
55777
|
-
const knex = this.getKnex();
|
|
55778
|
-
const boolTrue = this.driver === "mssql" ? "1" : "true";
|
|
55779
|
-
const boolFalse = this.driver === "mssql" ? "0" : "false";
|
|
55780
|
-
const result = await knex("schedules").select(
|
|
55781
|
-
knex.raw("COUNT(*) as total"),
|
|
55782
|
-
knex.raw("SUM(CASE WHEN status = 'active' THEN 1 ELSE 0 END) as active"),
|
|
55783
|
-
knex.raw("SUM(CASE WHEN status = 'paused' THEN 1 ELSE 0 END) as paused"),
|
|
55784
|
-
knex.raw("SUM(CASE WHEN status = 'completed' THEN 1 ELSE 0 END) as completed"),
|
|
55785
|
-
knex.raw("SUM(CASE WHEN status = 'failed' THEN 1 ELSE 0 END) as failed"),
|
|
55786
|
-
knex.raw(`SUM(CASE WHEN is_recurring = ${boolTrue} THEN 1 ELSE 0 END) as recurring`),
|
|
55787
|
-
knex.raw(`SUM(CASE WHEN is_recurring = ${boolFalse} THEN 1 ELSE 0 END) as one_time`)
|
|
55788
|
-
).first();
|
|
55789
|
-
return {
|
|
55790
|
-
total: Number(result.total) || 0,
|
|
55791
|
-
active: Number(result.active) || 0,
|
|
55792
|
-
paused: Number(result.paused) || 0,
|
|
55793
|
-
completed: Number(result.completed) || 0,
|
|
55794
|
-
failed: Number(result.failed) || 0,
|
|
55795
|
-
recurring: Number(result.recurring) || 0,
|
|
55796
|
-
oneTime: Number(result.one_time) || 0
|
|
55797
|
-
};
|
|
55798
|
-
}
|
|
55799
|
-
async validateLimits(creatorId, isRecurring, limits) {
|
|
55800
|
-
const knex = this.getKnex();
|
|
55801
|
-
if (limits.maxGlobal) {
|
|
55802
|
-
const result = await knex("schedules").count("* as cnt").first();
|
|
55803
|
-
if (Number(result?.cnt) >= limits.maxGlobal) {
|
|
55804
|
-
throw new Error(`Global schedule limit reached (${limits.maxGlobal})`);
|
|
55805
|
-
}
|
|
55806
|
-
}
|
|
55807
|
-
if (limits.maxPerUser) {
|
|
55808
|
-
const result = await knex("schedules").where("creator_id", creatorId).count("* as cnt").first();
|
|
55809
|
-
if (Number(result?.cnt) >= limits.maxPerUser) {
|
|
55810
|
-
throw new Error(`You have reached the maximum number of schedules (${limits.maxPerUser})`);
|
|
55811
|
-
}
|
|
55812
|
-
}
|
|
55813
|
-
if (isRecurring && limits.maxRecurringPerUser) {
|
|
55814
|
-
const bTrue = this.driver === "mssql" ? 1 : true;
|
|
55815
|
-
const result = await knex("schedules").where("creator_id", creatorId).where("is_recurring", bTrue).count("* as cnt").first();
|
|
55816
|
-
if (Number(result?.cnt) >= limits.maxRecurringPerUser) {
|
|
55817
|
-
throw new Error(
|
|
55818
|
-
`You have reached the maximum number of recurring schedules (${limits.maxRecurringPerUser})`
|
|
55819
|
-
);
|
|
55820
|
-
}
|
|
55821
|
-
}
|
|
55822
|
-
}
|
|
55823
|
-
// --- HA Distributed Locking (via scheduler_locks table) ---
|
|
55824
|
-
async tryAcquireLock(lockId, nodeId, ttlSeconds) {
|
|
55825
|
-
const knex = this.getKnex();
|
|
55826
|
-
const now = Date.now();
|
|
55827
|
-
const expiresAt = now + ttlSeconds * 1e3;
|
|
55828
|
-
const token = (0, import_uuid2.v4)();
|
|
55829
|
-
const updated = await knex("scheduler_locks").where("lock_id", lockId).where("expires_at", "<", now).update({
|
|
55830
|
-
node_id: nodeId,
|
|
55831
|
-
lock_token: token,
|
|
55832
|
-
acquired_at: now,
|
|
55833
|
-
expires_at: expiresAt
|
|
55834
|
-
});
|
|
55835
|
-
if (updated > 0) return token;
|
|
55836
|
-
try {
|
|
55837
|
-
await knex("scheduler_locks").insert({
|
|
55838
|
-
lock_id: lockId,
|
|
55839
|
-
node_id: nodeId,
|
|
55840
|
-
lock_token: token,
|
|
55841
|
-
acquired_at: now,
|
|
55842
|
-
expires_at: expiresAt
|
|
55843
|
-
});
|
|
55844
|
-
return token;
|
|
55845
|
-
} catch {
|
|
55846
|
-
return null;
|
|
55847
|
-
}
|
|
55848
|
-
}
|
|
55849
|
-
async releaseLock(lockId, lockToken) {
|
|
55850
|
-
const knex = this.getKnex();
|
|
55851
|
-
await knex("scheduler_locks").where("lock_id", lockId).where("lock_token", lockToken).del();
|
|
55852
|
-
}
|
|
55853
|
-
async renewLock(lockId, lockToken, ttlSeconds) {
|
|
55854
|
-
const knex = this.getKnex();
|
|
55855
|
-
const now = Date.now();
|
|
55856
|
-
const expiresAt = now + ttlSeconds * 1e3;
|
|
55857
|
-
const updated = await knex("scheduler_locks").where("lock_id", lockId).where("lock_token", lockToken).update({ acquired_at: now, expires_at: expiresAt });
|
|
55858
|
-
return updated > 0;
|
|
55859
|
-
}
|
|
55860
|
-
async flush() {
|
|
55861
|
-
}
|
|
55862
|
-
// --- Message Trigger CRUD ---
|
|
55863
|
-
async createTrigger(trigger) {
|
|
55864
|
-
const knex = this.getKnex();
|
|
55865
|
-
const newTrigger = {
|
|
55866
|
-
...trigger,
|
|
55867
|
-
id: (0, import_uuid2.v4)(),
|
|
55868
|
-
createdAt: Date.now()
|
|
55869
|
-
};
|
|
55870
|
-
await knex("message_triggers").insert(toTriggerInsertRow(newTrigger));
|
|
55871
|
-
logger.info(`[KnexStore] Created trigger ${newTrigger.id} for user ${newTrigger.creatorId}`);
|
|
55872
|
-
return newTrigger;
|
|
55873
|
-
}
|
|
55874
|
-
async getTrigger(id) {
|
|
55875
|
-
const knex = this.getKnex();
|
|
55876
|
-
const row = await knex("message_triggers").where("id", id).first();
|
|
55877
|
-
return row ? fromTriggerRow2(row) : void 0;
|
|
55878
|
-
}
|
|
55879
|
-
async updateTrigger(id, patch) {
|
|
55880
|
-
const knex = this.getKnex();
|
|
55881
|
-
const existing = await knex("message_triggers").where("id", id).first();
|
|
55882
|
-
if (!existing) return void 0;
|
|
55883
|
-
const current = fromTriggerRow2(existing);
|
|
55884
|
-
const updated = {
|
|
55885
|
-
...current,
|
|
55886
|
-
...patch,
|
|
55887
|
-
id: current.id,
|
|
55888
|
-
createdAt: current.createdAt
|
|
55889
|
-
};
|
|
55890
|
-
const row = toTriggerInsertRow(updated);
|
|
55891
|
-
delete row.id;
|
|
55892
|
-
await knex("message_triggers").where("id", id).update(row);
|
|
55893
|
-
return updated;
|
|
55894
|
-
}
|
|
55895
|
-
async deleteTrigger(id) {
|
|
55896
|
-
const knex = this.getKnex();
|
|
55897
|
-
const deleted = await knex("message_triggers").where("id", id).del();
|
|
55898
|
-
if (deleted > 0) {
|
|
55899
|
-
logger.info(`[KnexStore] Deleted trigger ${id}`);
|
|
55900
|
-
return true;
|
|
55901
|
-
}
|
|
55902
|
-
return false;
|
|
55903
|
-
}
|
|
55904
|
-
async getTriggersByCreator(creatorId) {
|
|
55905
|
-
const knex = this.getKnex();
|
|
55906
|
-
const rows = await knex("message_triggers").where("creator_id", creatorId);
|
|
55907
|
-
return rows.map((r) => fromTriggerRow2(r));
|
|
55908
|
-
}
|
|
55909
|
-
async getActiveTriggers() {
|
|
55910
|
-
const knex = this.getKnex();
|
|
55911
|
-
const rows = await knex("message_triggers").where("status", "active").where("enabled", this.driver === "mssql" ? 1 : true);
|
|
55912
|
-
return rows.map((r) => fromTriggerRow2(r));
|
|
55913
|
-
}
|
|
55914
|
-
};
|
|
55915
|
-
}
|
|
55916
|
-
});
|
|
55917
|
-
|
|
55918
|
-
// src/enterprise/loader.ts
|
|
55919
|
-
var loader_exports = {};
|
|
55920
|
-
__export(loader_exports, {
|
|
55921
|
-
loadEnterprisePolicyEngine: () => loadEnterprisePolicyEngine,
|
|
55922
|
-
loadEnterpriseStoreBackend: () => loadEnterpriseStoreBackend
|
|
55923
|
-
});
|
|
55924
|
-
async function loadEnterprisePolicyEngine(config) {
|
|
55925
|
-
try {
|
|
55926
|
-
const { LicenseValidator: LicenseValidator2 } = await Promise.resolve().then(() => (init_validator(), validator_exports));
|
|
55927
|
-
const validator = new LicenseValidator2();
|
|
55928
|
-
const license = await validator.loadAndValidate();
|
|
55929
|
-
if (!license || !validator.hasFeature("policy")) {
|
|
55930
|
-
return new DefaultPolicyEngine();
|
|
55931
|
-
}
|
|
55932
|
-
if (validator.isInGracePeriod()) {
|
|
55933
|
-
console.warn(
|
|
55934
|
-
"[visor:enterprise] License has expired but is within the 72-hour grace period. Please renew your license."
|
|
55935
|
-
);
|
|
55936
|
-
}
|
|
55937
|
-
const { OpaPolicyEngine: OpaPolicyEngine2 } = await Promise.resolve().then(() => (init_opa_policy_engine(), opa_policy_engine_exports));
|
|
55938
|
-
const engine = new OpaPolicyEngine2(config);
|
|
55939
|
-
await engine.initialize(config);
|
|
55940
|
-
return engine;
|
|
55941
|
-
} catch (err) {
|
|
55942
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
55943
|
-
try {
|
|
55944
|
-
const { logger: logger2 } = (init_logger(), __toCommonJS(logger_exports));
|
|
55945
|
-
logger2.warn(`[PolicyEngine] Enterprise policy init failed, falling back to default: ${msg}`);
|
|
55946
|
-
} catch {
|
|
55947
|
-
}
|
|
55948
|
-
return new DefaultPolicyEngine();
|
|
55949
|
-
}
|
|
55950
|
-
}
|
|
55951
|
-
async function loadEnterpriseStoreBackend(driver, storageConfig, haConfig) {
|
|
55952
|
-
const { LicenseValidator: LicenseValidator2 } = await Promise.resolve().then(() => (init_validator(), validator_exports));
|
|
55953
|
-
const validator = new LicenseValidator2();
|
|
55954
|
-
const license = await validator.loadAndValidate();
|
|
55955
|
-
if (!license || !validator.hasFeature("scheduler-sql")) {
|
|
55956
|
-
throw new Error(
|
|
55957
|
-
`The ${driver} schedule storage driver requires a Visor Enterprise license with the 'scheduler-sql' feature. Please upgrade or use driver: 'sqlite' (default).`
|
|
55958
|
-
);
|
|
55959
|
-
}
|
|
55960
|
-
if (validator.isInGracePeriod()) {
|
|
55961
|
-
console.warn(
|
|
55962
|
-
"[visor:enterprise] License has expired but is within the 72-hour grace period. Please renew your license."
|
|
55963
|
-
);
|
|
55964
|
-
}
|
|
55965
|
-
const { KnexStoreBackend: KnexStoreBackend2 } = await Promise.resolve().then(() => (init_knex_store(), knex_store_exports));
|
|
55966
|
-
return new KnexStoreBackend2(driver, storageConfig, haConfig);
|
|
55967
|
-
}
|
|
55968
|
-
var init_loader = __esm({
|
|
55969
|
-
"src/enterprise/loader.ts"() {
|
|
55970
|
-
"use strict";
|
|
55971
|
-
init_default_engine();
|
|
55972
|
-
}
|
|
55973
|
-
});
|
|
55974
|
-
|
|
55975
54601
|
// src/event-bus/event-bus.ts
|
|
55976
54602
|
var event_bus_exports = {};
|
|
55977
54603
|
__export(event_bus_exports, {
|
|
@@ -56878,8 +55504,8 @@ ${content}
|
|
|
56878
55504
|
* Sleep utility
|
|
56879
55505
|
*/
|
|
56880
55506
|
sleep(ms) {
|
|
56881
|
-
return new Promise((
|
|
56882
|
-
const t = setTimeout(
|
|
55507
|
+
return new Promise((resolve14) => {
|
|
55508
|
+
const t = setTimeout(resolve14, ms);
|
|
56883
55509
|
if (typeof t.unref === "function") {
|
|
56884
55510
|
try {
|
|
56885
55511
|
t.unref();
|
|
@@ -57164,8 +55790,8 @@ ${end}`);
|
|
|
57164
55790
|
async updateGroupedComment(ctx, comments, group, changedIds) {
|
|
57165
55791
|
const existingLock = this.updateLocks.get(group);
|
|
57166
55792
|
let resolveLock;
|
|
57167
|
-
const ourLock = new Promise((
|
|
57168
|
-
resolveLock =
|
|
55793
|
+
const ourLock = new Promise((resolve14) => {
|
|
55794
|
+
resolveLock = resolve14;
|
|
57169
55795
|
});
|
|
57170
55796
|
this.updateLocks.set(group, ourLock);
|
|
57171
55797
|
try {
|
|
@@ -57478,7 +56104,7 @@ ${blocks}
|
|
|
57478
56104
|
* Sleep utility for enforcing delays
|
|
57479
56105
|
*/
|
|
57480
56106
|
sleep(ms) {
|
|
57481
|
-
return new Promise((
|
|
56107
|
+
return new Promise((resolve14) => setTimeout(resolve14, ms));
|
|
57482
56108
|
}
|
|
57483
56109
|
};
|
|
57484
56110
|
}
|
|
@@ -58749,15 +57375,15 @@ function serializeRunState(state) {
|
|
|
58749
57375
|
])
|
|
58750
57376
|
};
|
|
58751
57377
|
}
|
|
58752
|
-
var
|
|
57378
|
+
var path26, fs22, StateMachineExecutionEngine;
|
|
58753
57379
|
var init_state_machine_execution_engine = __esm({
|
|
58754
57380
|
"src/state-machine-execution-engine.ts"() {
|
|
58755
57381
|
"use strict";
|
|
58756
57382
|
init_runner();
|
|
58757
57383
|
init_logger();
|
|
58758
57384
|
init_sandbox_manager();
|
|
58759
|
-
|
|
58760
|
-
|
|
57385
|
+
path26 = __toESM(require("path"));
|
|
57386
|
+
fs22 = __toESM(require("fs"));
|
|
58761
57387
|
StateMachineExecutionEngine = class _StateMachineExecutionEngine {
|
|
58762
57388
|
workingDirectory;
|
|
58763
57389
|
executionContext;
|
|
@@ -58989,8 +57615,8 @@ var init_state_machine_execution_engine = __esm({
|
|
|
58989
57615
|
logger.debug(
|
|
58990
57616
|
`[PolicyEngine] Loading enterprise policy engine (engine=${configWithTagFilter.policy.engine})`
|
|
58991
57617
|
);
|
|
58992
|
-
const { loadEnterprisePolicyEngine
|
|
58993
|
-
context2.policyEngine = await
|
|
57618
|
+
const { loadEnterprisePolicyEngine } = await import("./enterprise/loader");
|
|
57619
|
+
context2.policyEngine = await loadEnterprisePolicyEngine(configWithTagFilter.policy);
|
|
58994
57620
|
logger.debug(
|
|
58995
57621
|
`[PolicyEngine] Initialized: ${context2.policyEngine?.constructor?.name || "unknown"}`
|
|
58996
57622
|
);
|
|
@@ -59142,9 +57768,9 @@ var init_state_machine_execution_engine = __esm({
|
|
|
59142
57768
|
}
|
|
59143
57769
|
const checkId = String(ev?.checkId || "unknown");
|
|
59144
57770
|
const threadKey = ev?.threadKey || (channel && threadTs ? `${channel}:${threadTs}` : "session");
|
|
59145
|
-
const baseDir = process.env.VISOR_SNAPSHOT_DIR ||
|
|
59146
|
-
|
|
59147
|
-
const filePath =
|
|
57771
|
+
const baseDir = process.env.VISOR_SNAPSHOT_DIR || path26.resolve(process.cwd(), ".visor", "snapshots");
|
|
57772
|
+
fs22.mkdirSync(baseDir, { recursive: true });
|
|
57773
|
+
const filePath = path26.join(baseDir, `${threadKey}-${checkId}.json`);
|
|
59148
57774
|
await this.saveSnapshotToFile(filePath);
|
|
59149
57775
|
logger.info(`[Snapshot] Saved run snapshot: ${filePath}`);
|
|
59150
57776
|
try {
|
|
@@ -59285,7 +57911,7 @@ var init_state_machine_execution_engine = __esm({
|
|
|
59285
57911
|
* Does not include secrets. Intended for debugging and future resume support.
|
|
59286
57912
|
*/
|
|
59287
57913
|
async saveSnapshotToFile(filePath) {
|
|
59288
|
-
const
|
|
57914
|
+
const fs23 = await import("fs/promises");
|
|
59289
57915
|
const ctx = this._lastContext;
|
|
59290
57916
|
const runner = this._lastRunner;
|
|
59291
57917
|
if (!ctx || !runner) {
|
|
@@ -59305,14 +57931,14 @@ var init_state_machine_execution_engine = __esm({
|
|
|
59305
57931
|
journal: entries,
|
|
59306
57932
|
requestedChecks: ctx.requestedChecks || []
|
|
59307
57933
|
};
|
|
59308
|
-
await
|
|
57934
|
+
await fs23.writeFile(filePath, JSON.stringify(payload, null, 2), "utf8");
|
|
59309
57935
|
}
|
|
59310
57936
|
/**
|
|
59311
57937
|
* Load a snapshot JSON from file and return it. Resume support can build on this.
|
|
59312
57938
|
*/
|
|
59313
57939
|
async loadSnapshotFromFile(filePath) {
|
|
59314
|
-
const
|
|
59315
|
-
const raw = await
|
|
57940
|
+
const fs23 = await import("fs/promises");
|
|
57941
|
+
const raw = await fs23.readFile(filePath, "utf8");
|
|
59316
57942
|
return JSON.parse(raw);
|
|
59317
57943
|
}
|
|
59318
57944
|
/**
|