@probelabs/visor 0.1.148-ee → 0.1.149
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/defaults/assistant.yaml +2141 -0
- package/defaults/code-talk.yaml +1250 -0
- package/defaults/intent-router.yaml +478 -0
- package/dist/defaults/assistant.yaml +2141 -0
- package/dist/defaults/code-talk.yaml +1250 -0
- package/dist/defaults/intent-router.yaml +478 -0
- package/dist/index.js +38 -1722
- package/dist/output/traces/run-2026-03-03T07-19-07-543Z.ndjson +138 -0
- package/dist/output/traces/run-2026-03-03T07-19-50-933Z.ndjson +2121 -0
- package/dist/sdk/check-provider-registry-IYSUDKPB.mjs +29 -0
- package/dist/sdk/{check-provider-registry-AMYY2ZJY.mjs → check-provider-registry-LVLC4EPF.mjs} +4 -4
- package/dist/sdk/{check-provider-registry-DVQDGTOE.mjs → check-provider-registry-X4OZJWPK.mjs} +4 -4
- package/dist/sdk/{chunk-75Q63UNX.mjs → chunk-6EXCUX7Y.mjs} +12 -12
- package/dist/sdk/{chunk-75Q63UNX.mjs.map → chunk-6EXCUX7Y.mjs.map} +1 -1
- package/dist/sdk/chunk-BR7DYA3S.mjs +739 -0
- package/dist/sdk/chunk-BR7DYA3S.mjs.map +1 -0
- package/dist/sdk/{chunk-DIND4ZCV.mjs → chunk-DNDS7R3N.mjs} +11 -1
- package/dist/sdk/{chunk-DIND4ZCV.mjs.map → chunk-DNDS7R3N.mjs.map} +1 -1
- package/dist/sdk/chunk-GFNXX64M.mjs +43159 -0
- package/dist/sdk/chunk-GFNXX64M.mjs.map +1 -0
- package/dist/sdk/chunk-Q6EPAJ6Z.mjs +1502 -0
- package/dist/sdk/chunk-Q6EPAJ6Z.mjs.map +1 -0
- package/dist/sdk/{chunk-H4AYMOAT.mjs → chunk-V6GI4U2M.mjs} +10 -10
- package/dist/sdk/chunk-VLUGLWLA.mjs +443 -0
- package/dist/sdk/chunk-VLUGLWLA.mjs.map +1 -0
- package/dist/sdk/{chunk-XNTBSV6M.mjs → chunk-YYZAN5NK.mjs} +3 -3
- package/dist/sdk/{config-G5UU4WXT.mjs → config-KQH254CA.mjs} +2 -2
- package/dist/sdk/failure-condition-evaluator-LZ2AG5PY.mjs +17 -0
- package/dist/sdk/github-frontend-S523EEJB.mjs +1368 -0
- package/dist/sdk/github-frontend-S523EEJB.mjs.map +1 -0
- package/dist/sdk/{host-NZXGBBJI.mjs → host-7YKRMOUJ.mjs} +2 -2
- package/dist/sdk/routing-ZMBKWMVI.mjs +25 -0
- package/dist/sdk/schedule-tool-CDVUSZEG.mjs +35 -0
- package/dist/sdk/{schedule-tool-4JMWZCCK.mjs → schedule-tool-EOMZFICZ.mjs} +4 -4
- package/dist/sdk/{schedule-tool-CONR4VW3.mjs → schedule-tool-NX75VKGA.mjs} +4 -4
- package/dist/sdk/schedule-tool-handler-3FJHDIPG.mjs +39 -0
- package/dist/sdk/{schedule-tool-handler-AXMR7NBI.mjs → schedule-tool-handler-KKN7XJYT.mjs} +4 -4
- package/dist/sdk/schedule-tool-handler-KKN7XJYT.mjs.map +1 -0
- package/dist/sdk/{schedule-tool-handler-YUC6CAXX.mjs → schedule-tool-handler-QNZG55DX.mjs} +4 -4
- package/dist/sdk/schedule-tool-handler-QNZG55DX.mjs.map +1 -0
- package/dist/sdk/sdk.js +269 -1517
- package/dist/sdk/sdk.js.map +1 -1
- package/dist/sdk/sdk.mjs +6 -6
- package/dist/sdk/trace-helpers-EJUIOP6L.mjs +25 -0
- package/dist/sdk/trace-helpers-EJUIOP6L.mjs.map +1 -0
- package/dist/sdk/workflow-check-provider-6ERNNCNA.mjs +29 -0
- package/dist/sdk/workflow-check-provider-6ERNNCNA.mjs.map +1 -0
- package/dist/sdk/{workflow-check-provider-DYSO3PML.mjs → workflow-check-provider-AGZ5JY2I.mjs} +4 -4
- package/dist/sdk/workflow-check-provider-AGZ5JY2I.mjs.map +1 -0
- package/dist/sdk/{workflow-check-provider-MMB7L3YG.mjs → workflow-check-provider-PTNUWM5W.mjs} +4 -4
- package/dist/sdk/workflow-check-provider-PTNUWM5W.mjs.map +1 -0
- package/dist/sdk/{workflow-registry-AAD37XKZ.mjs → workflow-registry-MHUSKSD6.mjs} +2 -2
- package/dist/sdk/workflow-registry-MHUSKSD6.mjs.map +1 -0
- package/dist/traces/run-2026-03-03T07-19-07-543Z.ndjson +138 -0
- package/dist/traces/run-2026-03-03T07-19-50-933Z.ndjson +2121 -0
- package/dist/workflow-registry.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/sdk/knex-store-HPXJILBL.mjs +0 -411
- package/dist/sdk/knex-store-HPXJILBL.mjs.map +0 -1
- package/dist/sdk/loader-YSRMVXC3.mjs +0 -89
- package/dist/sdk/loader-YSRMVXC3.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-AMYY2ZJY.mjs.map → check-provider-registry-IYSUDKPB.mjs.map} +0 -0
- /package/dist/sdk/{check-provider-registry-DVQDGTOE.mjs.map → check-provider-registry-LVLC4EPF.mjs.map} +0 -0
- /package/dist/sdk/{config-G5UU4WXT.mjs.map → check-provider-registry-X4OZJWPK.mjs.map} +0 -0
- /package/dist/sdk/{chunk-H4AYMOAT.mjs.map → chunk-V6GI4U2M.mjs.map} +0 -0
- /package/dist/sdk/{chunk-XNTBSV6M.mjs.map → chunk-YYZAN5NK.mjs.map} +0 -0
- /package/dist/sdk/{schedule-tool-4JMWZCCK.mjs.map → config-KQH254CA.mjs.map} +0 -0
- /package/dist/sdk/{schedule-tool-CONR4VW3.mjs.map → failure-condition-evaluator-LZ2AG5PY.mjs.map} +0 -0
- /package/dist/sdk/{host-NZXGBBJI.mjs.map → host-7YKRMOUJ.mjs.map} +0 -0
- /package/dist/sdk/{schedule-tool-handler-AXMR7NBI.mjs.map → routing-ZMBKWMVI.mjs.map} +0 -0
- /package/dist/sdk/{schedule-tool-handler-YUC6CAXX.mjs.map → schedule-tool-CDVUSZEG.mjs.map} +0 -0
- /package/dist/sdk/{workflow-check-provider-DYSO3PML.mjs.map → schedule-tool-EOMZFICZ.mjs.map} +0 -0
- /package/dist/sdk/{workflow-check-provider-MMB7L3YG.mjs.map → schedule-tool-NX75VKGA.mjs.map} +0 -0
- /package/dist/sdk/{workflow-registry-AAD37XKZ.mjs.map → schedule-tool-handler-3FJHDIPG.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.149",
|
|
650
650
|
main: "dist/index.js",
|
|
651
651
|
bin: {
|
|
652
652
|
visor: "./dist/index.js"
|
|
@@ -864,11 +864,11 @@ function getTracer() {
|
|
|
864
864
|
}
|
|
865
865
|
async function withActiveSpan(name, attrs, fn) {
|
|
866
866
|
const tracer = getTracer();
|
|
867
|
-
return await new Promise((
|
|
867
|
+
return await new Promise((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) {
|
|
@@ -8153,8 +8153,8 @@ ${schemaString}`);
|
|
|
8153
8153
|
}
|
|
8154
8154
|
if (process.env.VISOR_DEBUG_AI_SESSIONS === "true") {
|
|
8155
8155
|
try {
|
|
8156
|
-
const
|
|
8157
|
-
const
|
|
8156
|
+
const fs23 = require("fs");
|
|
8157
|
+
const path27 = require("path");
|
|
8158
8158
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
8159
8159
|
const provider = this.config.provider || "auto";
|
|
8160
8160
|
const model = this.config.model || "default";
|
|
@@ -8268,20 +8268,20 @@ ${"=".repeat(60)}
|
|
|
8268
8268
|
`;
|
|
8269
8269
|
readableVersion += `${"=".repeat(60)}
|
|
8270
8270
|
`;
|
|
8271
|
-
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS ||
|
|
8272
|
-
if (!
|
|
8273
|
-
|
|
8271
|
+
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path27.join(process.cwd(), "debug-artifacts");
|
|
8272
|
+
if (!fs23.existsSync(debugArtifactsDir)) {
|
|
8273
|
+
fs23.mkdirSync(debugArtifactsDir, { recursive: true });
|
|
8274
8274
|
}
|
|
8275
|
-
const debugFile =
|
|
8275
|
+
const debugFile = path27.join(
|
|
8276
8276
|
debugArtifactsDir,
|
|
8277
8277
|
`prompt-${_checkName || "unknown"}-${timestamp}.json`
|
|
8278
8278
|
);
|
|
8279
|
-
|
|
8280
|
-
const readableFile =
|
|
8279
|
+
fs23.writeFileSync(debugFile, debugJson, "utf-8");
|
|
8280
|
+
const readableFile = path27.join(
|
|
8281
8281
|
debugArtifactsDir,
|
|
8282
8282
|
`prompt-${_checkName || "unknown"}-${timestamp}.txt`
|
|
8283
8283
|
);
|
|
8284
|
-
|
|
8284
|
+
fs23.writeFileSync(readableFile, readableVersion, "utf-8");
|
|
8285
8285
|
log(`
|
|
8286
8286
|
\u{1F4BE} Full debug info saved to:`);
|
|
8287
8287
|
log(` JSON: ${debugFile}`);
|
|
@@ -8314,8 +8314,8 @@ ${"=".repeat(60)}
|
|
|
8314
8314
|
log(`\u{1F4E4} Response length: ${response.length} characters`);
|
|
8315
8315
|
if (process.env.VISOR_DEBUG_AI_SESSIONS === "true") {
|
|
8316
8316
|
try {
|
|
8317
|
-
const
|
|
8318
|
-
const
|
|
8317
|
+
const fs23 = require("fs");
|
|
8318
|
+
const path27 = require("path");
|
|
8319
8319
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
8320
8320
|
const agentAny2 = agent;
|
|
8321
8321
|
let fullHistory = [];
|
|
@@ -8326,8 +8326,8 @@ ${"=".repeat(60)}
|
|
|
8326
8326
|
} else if (agentAny2._messages) {
|
|
8327
8327
|
fullHistory = agentAny2._messages;
|
|
8328
8328
|
}
|
|
8329
|
-
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS ||
|
|
8330
|
-
const sessionBase =
|
|
8329
|
+
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path27.join(process.cwd(), "debug-artifacts");
|
|
8330
|
+
const sessionBase = path27.join(
|
|
8331
8331
|
debugArtifactsDir,
|
|
8332
8332
|
`session-${_checkName || "unknown"}-${timestamp}`
|
|
8333
8333
|
);
|
|
@@ -8339,7 +8339,7 @@ ${"=".repeat(60)}
|
|
|
8339
8339
|
schema: effectiveSchema,
|
|
8340
8340
|
totalMessages: fullHistory.length
|
|
8341
8341
|
};
|
|
8342
|
-
|
|
8342
|
+
fs23.writeFileSync(sessionBase + ".json", JSON.stringify(sessionData, null, 2), "utf-8");
|
|
8343
8343
|
let readable = `=============================================================
|
|
8344
8344
|
`;
|
|
8345
8345
|
readable += `COMPLETE AI SESSION HISTORY (AFTER RESPONSE)
|
|
@@ -8366,7 +8366,7 @@ ${"=".repeat(60)}
|
|
|
8366
8366
|
`;
|
|
8367
8367
|
readable += content + "\n";
|
|
8368
8368
|
});
|
|
8369
|
-
|
|
8369
|
+
fs23.writeFileSync(sessionBase + ".summary.txt", readable, "utf-8");
|
|
8370
8370
|
log(`\u{1F4BE} Complete session history saved:`);
|
|
8371
8371
|
log(` - Contains ALL ${fullHistory.length} messages (prompts + responses)`);
|
|
8372
8372
|
} catch (error) {
|
|
@@ -8375,11 +8375,11 @@ ${"=".repeat(60)}
|
|
|
8375
8375
|
}
|
|
8376
8376
|
if (process.env.VISOR_DEBUG_AI_SESSIONS === "true") {
|
|
8377
8377
|
try {
|
|
8378
|
-
const
|
|
8379
|
-
const
|
|
8378
|
+
const fs23 = require("fs");
|
|
8379
|
+
const path27 = require("path");
|
|
8380
8380
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
8381
|
-
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS ||
|
|
8382
|
-
const responseFile =
|
|
8381
|
+
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path27.join(process.cwd(), "debug-artifacts");
|
|
8382
|
+
const responseFile = path27.join(
|
|
8383
8383
|
debugArtifactsDir,
|
|
8384
8384
|
`response-${_checkName || "unknown"}-${timestamp}.txt`
|
|
8385
8385
|
);
|
|
@@ -8412,7 +8412,7 @@ ${"=".repeat(60)}
|
|
|
8412
8412
|
`;
|
|
8413
8413
|
responseContent += `${"=".repeat(60)}
|
|
8414
8414
|
`;
|
|
8415
|
-
|
|
8415
|
+
fs23.writeFileSync(responseFile, responseContent, "utf-8");
|
|
8416
8416
|
log(`\u{1F4BE} Response saved to: ${responseFile}`);
|
|
8417
8417
|
} catch (error) {
|
|
8418
8418
|
log(`\u26A0\uFE0F Could not save response file: ${error}`);
|
|
@@ -8428,9 +8428,9 @@ ${"=".repeat(60)}
|
|
|
8428
8428
|
await agentAny._telemetryConfig.shutdown();
|
|
8429
8429
|
log(`\u{1F4CA} OpenTelemetry trace saved to: ${agentAny._traceFilePath}`);
|
|
8430
8430
|
if (process.env.GITHUB_ACTIONS) {
|
|
8431
|
-
const
|
|
8432
|
-
if (
|
|
8433
|
-
const stats =
|
|
8431
|
+
const fs23 = require("fs");
|
|
8432
|
+
if (fs23.existsSync(agentAny._traceFilePath)) {
|
|
8433
|
+
const stats = fs23.statSync(agentAny._traceFilePath);
|
|
8434
8434
|
console.log(
|
|
8435
8435
|
`::notice title=AI Trace Saved::${agentAny._traceFilePath} (${stats.size} bytes)`
|
|
8436
8436
|
);
|
|
@@ -8637,9 +8637,9 @@ ${schemaString}`);
|
|
|
8637
8637
|
const model = this.config.model || "default";
|
|
8638
8638
|
if (process.env.VISOR_DEBUG_AI_SESSIONS === "true") {
|
|
8639
8639
|
try {
|
|
8640
|
-
const
|
|
8641
|
-
const
|
|
8642
|
-
const
|
|
8640
|
+
const fs23 = require("fs");
|
|
8641
|
+
const path27 = require("path");
|
|
8642
|
+
const os2 = require("os");
|
|
8643
8643
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
8644
8644
|
const debugData = {
|
|
8645
8645
|
timestamp,
|
|
@@ -8711,19 +8711,19 @@ ${"=".repeat(60)}
|
|
|
8711
8711
|
`;
|
|
8712
8712
|
readableVersion += `${"=".repeat(60)}
|
|
8713
8713
|
`;
|
|
8714
|
-
const tempDir =
|
|
8715
|
-
const promptFile =
|
|
8716
|
-
|
|
8714
|
+
const tempDir = os2.tmpdir();
|
|
8715
|
+
const promptFile = path27.join(tempDir, `visor-prompt-${timestamp}.txt`);
|
|
8716
|
+
fs23.writeFileSync(promptFile, prompt, "utf-8");
|
|
8717
8717
|
log(`
|
|
8718
8718
|
\u{1F4BE} Prompt saved to: ${promptFile}`);
|
|
8719
|
-
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS ||
|
|
8719
|
+
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path27.join(process.cwd(), "debug-artifacts");
|
|
8720
8720
|
try {
|
|
8721
|
-
const base =
|
|
8721
|
+
const base = path27.join(
|
|
8722
8722
|
debugArtifactsDir,
|
|
8723
8723
|
`prompt-${_checkName || "unknown"}-${timestamp}`
|
|
8724
8724
|
);
|
|
8725
|
-
|
|
8726
|
-
|
|
8725
|
+
fs23.writeFileSync(base + ".json", debugJson, "utf-8");
|
|
8726
|
+
fs23.writeFileSync(base + ".summary.txt", readableVersion, "utf-8");
|
|
8727
8727
|
log(`
|
|
8728
8728
|
\u{1F4BE} Full debug info saved to directory: ${debugArtifactsDir}`);
|
|
8729
8729
|
} catch {
|
|
@@ -8768,8 +8768,8 @@ $ ${cliCommand}
|
|
|
8768
8768
|
log(`\u{1F4E4} Response length: ${response.length} characters`);
|
|
8769
8769
|
if (process.env.VISOR_DEBUG_AI_SESSIONS === "true") {
|
|
8770
8770
|
try {
|
|
8771
|
-
const
|
|
8772
|
-
const
|
|
8771
|
+
const fs23 = require("fs");
|
|
8772
|
+
const path27 = require("path");
|
|
8773
8773
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
8774
8774
|
const agentAny = agent;
|
|
8775
8775
|
let fullHistory = [];
|
|
@@ -8780,8 +8780,8 @@ $ ${cliCommand}
|
|
|
8780
8780
|
} else if (agentAny._messages) {
|
|
8781
8781
|
fullHistory = agentAny._messages;
|
|
8782
8782
|
}
|
|
8783
|
-
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS ||
|
|
8784
|
-
const sessionBase =
|
|
8783
|
+
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path27.join(process.cwd(), "debug-artifacts");
|
|
8784
|
+
const sessionBase = path27.join(
|
|
8785
8785
|
debugArtifactsDir,
|
|
8786
8786
|
`session-${_checkName || "unknown"}-${timestamp}`
|
|
8787
8787
|
);
|
|
@@ -8793,7 +8793,7 @@ $ ${cliCommand}
|
|
|
8793
8793
|
schema: effectiveSchema,
|
|
8794
8794
|
totalMessages: fullHistory.length
|
|
8795
8795
|
};
|
|
8796
|
-
|
|
8796
|
+
fs23.writeFileSync(sessionBase + ".json", JSON.stringify(sessionData, null, 2), "utf-8");
|
|
8797
8797
|
let readable = `=============================================================
|
|
8798
8798
|
`;
|
|
8799
8799
|
readable += `COMPLETE AI SESSION HISTORY (AFTER RESPONSE)
|
|
@@ -8820,7 +8820,7 @@ ${"=".repeat(60)}
|
|
|
8820
8820
|
`;
|
|
8821
8821
|
readable += content + "\n";
|
|
8822
8822
|
});
|
|
8823
|
-
|
|
8823
|
+
fs23.writeFileSync(sessionBase + ".summary.txt", readable, "utf-8");
|
|
8824
8824
|
log(`\u{1F4BE} Complete session history saved:`);
|
|
8825
8825
|
log(` - Contains ALL ${fullHistory.length} messages (prompts + responses)`);
|
|
8826
8826
|
} catch (error) {
|
|
@@ -8829,11 +8829,11 @@ ${"=".repeat(60)}
|
|
|
8829
8829
|
}
|
|
8830
8830
|
if (process.env.VISOR_DEBUG_AI_SESSIONS === "true") {
|
|
8831
8831
|
try {
|
|
8832
|
-
const
|
|
8833
|
-
const
|
|
8832
|
+
const fs23 = require("fs");
|
|
8833
|
+
const path27 = require("path");
|
|
8834
8834
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
8835
|
-
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS ||
|
|
8836
|
-
const responseFile =
|
|
8835
|
+
const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path27.join(process.cwd(), "debug-artifacts");
|
|
8836
|
+
const responseFile = path27.join(
|
|
8837
8837
|
debugArtifactsDir,
|
|
8838
8838
|
`response-${_checkName || "unknown"}-${timestamp}.txt`
|
|
8839
8839
|
);
|
|
@@ -8866,7 +8866,7 @@ ${"=".repeat(60)}
|
|
|
8866
8866
|
`;
|
|
8867
8867
|
responseContent += `${"=".repeat(60)}
|
|
8868
8868
|
`;
|
|
8869
|
-
|
|
8869
|
+
fs23.writeFileSync(responseFile, responseContent, "utf-8");
|
|
8870
8870
|
log(`\u{1F4BE} Response saved to: ${responseFile}`);
|
|
8871
8871
|
} catch (error) {
|
|
8872
8872
|
log(`\u26A0\uFE0F Could not save response file: ${error}`);
|
|
@@ -8884,9 +8884,9 @@ ${"=".repeat(60)}
|
|
|
8884
8884
|
await telemetry.shutdown();
|
|
8885
8885
|
log(`\u{1F4CA} OpenTelemetry trace saved to: ${traceFilePath}`);
|
|
8886
8886
|
if (process.env.GITHUB_ACTIONS) {
|
|
8887
|
-
const
|
|
8888
|
-
if (
|
|
8889
|
-
const stats =
|
|
8887
|
+
const fs23 = require("fs");
|
|
8888
|
+
if (fs23.existsSync(traceFilePath)) {
|
|
8889
|
+
const stats = fs23.statSync(traceFilePath);
|
|
8890
8890
|
console.log(
|
|
8891
8891
|
`::notice title=AI Trace Saved::OpenTelemetry trace file size: ${stats.size} bytes`
|
|
8892
8892
|
);
|
|
@@ -8924,8 +8924,8 @@ ${"=".repeat(60)}
|
|
|
8924
8924
|
* Load schema content from schema files or inline definitions
|
|
8925
8925
|
*/
|
|
8926
8926
|
async loadSchemaContent(schema) {
|
|
8927
|
-
const
|
|
8928
|
-
const
|
|
8927
|
+
const fs23 = require("fs").promises;
|
|
8928
|
+
const path27 = require("path");
|
|
8929
8929
|
if (typeof schema === "object" && schema !== null) {
|
|
8930
8930
|
log("\u{1F4CB} Using inline schema object from configuration");
|
|
8931
8931
|
return JSON.stringify(schema);
|
|
@@ -8938,14 +8938,14 @@ ${"=".repeat(60)}
|
|
|
8938
8938
|
}
|
|
8939
8939
|
} catch {
|
|
8940
8940
|
}
|
|
8941
|
-
if ((schema.startsWith("./") || schema.includes(".json")) && !
|
|
8941
|
+
if ((schema.startsWith("./") || schema.includes(".json")) && !path27.isAbsolute(schema)) {
|
|
8942
8942
|
if (schema.includes("..") || schema.includes("\0")) {
|
|
8943
8943
|
throw new Error("Invalid schema path: path traversal not allowed");
|
|
8944
8944
|
}
|
|
8945
8945
|
try {
|
|
8946
|
-
const schemaPath =
|
|
8946
|
+
const schemaPath = path27.resolve(process.cwd(), schema);
|
|
8947
8947
|
log(`\u{1F4CB} Loading custom schema from file: ${schemaPath}`);
|
|
8948
|
-
const schemaContent = await
|
|
8948
|
+
const schemaContent = await fs23.readFile(schemaPath, "utf-8");
|
|
8949
8949
|
return schemaContent.trim();
|
|
8950
8950
|
} catch (error) {
|
|
8951
8951
|
throw new Error(
|
|
@@ -8959,22 +8959,22 @@ ${"=".repeat(60)}
|
|
|
8959
8959
|
}
|
|
8960
8960
|
const candidatePaths = [
|
|
8961
8961
|
// GitHub Action bundle location
|
|
8962
|
-
|
|
8962
|
+
path27.join(__dirname, "output", sanitizedSchemaName, "schema.json"),
|
|
8963
8963
|
// Historical fallback when src/output was inadvertently bundled as output1/
|
|
8964
|
-
|
|
8964
|
+
path27.join(__dirname, "output1", sanitizedSchemaName, "schema.json"),
|
|
8965
8965
|
// Local dev (repo root)
|
|
8966
|
-
|
|
8966
|
+
path27.join(process.cwd(), "output", sanitizedSchemaName, "schema.json")
|
|
8967
8967
|
];
|
|
8968
8968
|
for (const schemaPath of candidatePaths) {
|
|
8969
8969
|
try {
|
|
8970
|
-
const schemaContent = await
|
|
8970
|
+
const schemaContent = await fs23.readFile(schemaPath, "utf-8");
|
|
8971
8971
|
return schemaContent.trim();
|
|
8972
8972
|
} catch {
|
|
8973
8973
|
}
|
|
8974
8974
|
}
|
|
8975
|
-
const distPath =
|
|
8976
|
-
const distAltPath =
|
|
8977
|
-
const cwdPath =
|
|
8975
|
+
const distPath = path27.join(__dirname, "output", sanitizedSchemaName, "schema.json");
|
|
8976
|
+
const distAltPath = path27.join(__dirname, "output1", sanitizedSchemaName, "schema.json");
|
|
8977
|
+
const cwdPath = path27.join(process.cwd(), "output", sanitizedSchemaName, "schema.json");
|
|
8978
8978
|
throw new Error(
|
|
8979
8979
|
`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.`
|
|
8980
8980
|
);
|
|
@@ -9219,7 +9219,7 @@ ${"=".repeat(60)}
|
|
|
9219
9219
|
* Generate mock response for testing
|
|
9220
9220
|
*/
|
|
9221
9221
|
async generateMockResponse(_prompt, _checkName, _schema) {
|
|
9222
|
-
await new Promise((
|
|
9222
|
+
await new Promise((resolve14) => setTimeout(resolve14, 500));
|
|
9223
9223
|
const name = (_checkName || "").toLowerCase();
|
|
9224
9224
|
if (name.includes("extract-facts")) {
|
|
9225
9225
|
const arr = Array.from({ length: 6 }, (_, i) => ({
|
|
@@ -9580,7 +9580,7 @@ var init_command_executor = __esm({
|
|
|
9580
9580
|
* Execute command with stdin input
|
|
9581
9581
|
*/
|
|
9582
9582
|
executeWithStdin(command, options) {
|
|
9583
|
-
return new Promise((
|
|
9583
|
+
return new Promise((resolve14, reject) => {
|
|
9584
9584
|
const childProcess = (0, import_child_process2.exec)(
|
|
9585
9585
|
command,
|
|
9586
9586
|
{
|
|
@@ -9592,7 +9592,7 @@ var init_command_executor = __esm({
|
|
|
9592
9592
|
if (error && error.killed && (error.code === "ETIMEDOUT" || error.signal === "SIGTERM")) {
|
|
9593
9593
|
reject(new Error(`Command timed out after ${options.timeout || 3e4}ms`));
|
|
9594
9594
|
} else {
|
|
9595
|
-
|
|
9595
|
+
resolve14({
|
|
9596
9596
|
stdout: stdout || "",
|
|
9597
9597
|
stderr: stderr || "",
|
|
9598
9598
|
exitCode: error ? error.code || 1 : 0
|
|
@@ -11026,6 +11026,16 @@ var init_workflow_registry = __esm({
|
|
|
11026
11026
|
*/
|
|
11027
11027
|
async loadWorkflowContent(source, basePath) {
|
|
11028
11028
|
const baseIsUrl = basePath?.startsWith("http://") || basePath?.startsWith("https://");
|
|
11029
|
+
if (source.startsWith("visor://") || source.startsWith("visor-ee://")) {
|
|
11030
|
+
const relativePath = source.replace(/^visor(?:-ee)?:\/\//, "");
|
|
11031
|
+
const defaultsDir = path10.resolve(__dirname, "..", "defaults");
|
|
11032
|
+
const filePath2 = path10.resolve(defaultsDir, relativePath);
|
|
11033
|
+
if (!filePath2.startsWith(defaultsDir + path10.sep)) {
|
|
11034
|
+
throw new Error(`Invalid visor:// path: resolved path escapes defaults directory`);
|
|
11035
|
+
}
|
|
11036
|
+
const content2 = await import_fs3.promises.readFile(filePath2, "utf-8");
|
|
11037
|
+
return { content: content2, resolvedSource: filePath2, importBasePath: path10.dirname(filePath2) };
|
|
11038
|
+
}
|
|
11029
11039
|
if (source.startsWith("http://") || source.startsWith("https://")) {
|
|
11030
11040
|
const response = await fetch(source);
|
|
11031
11041
|
if (!response.ok) {
|
|
@@ -17422,17 +17432,17 @@ var init_workflow_check_provider = __esm({
|
|
|
17422
17432
|
* so it can be executed by the state machine as a nested workflow.
|
|
17423
17433
|
*/
|
|
17424
17434
|
async loadWorkflowFromConfigPath(sourcePath, baseDir) {
|
|
17425
|
-
const
|
|
17426
|
-
const
|
|
17435
|
+
const path27 = require("path");
|
|
17436
|
+
const fs23 = require("fs");
|
|
17427
17437
|
const yaml5 = require("js-yaml");
|
|
17428
|
-
const resolved =
|
|
17429
|
-
if (!
|
|
17438
|
+
const resolved = path27.isAbsolute(sourcePath) ? sourcePath : path27.resolve(baseDir, sourcePath);
|
|
17439
|
+
if (!fs23.existsSync(resolved)) {
|
|
17430
17440
|
throw new Error(`Workflow config not found at: ${resolved}`);
|
|
17431
17441
|
}
|
|
17432
|
-
const rawContent =
|
|
17442
|
+
const rawContent = fs23.readFileSync(resolved, "utf8");
|
|
17433
17443
|
const rawData = yaml5.load(rawContent);
|
|
17434
17444
|
if (rawData.imports && Array.isArray(rawData.imports)) {
|
|
17435
|
-
const configDir =
|
|
17445
|
+
const configDir = path27.dirname(resolved);
|
|
17436
17446
|
for (const source of rawData.imports) {
|
|
17437
17447
|
const results = await this.registry.import(source, {
|
|
17438
17448
|
basePath: configDir,
|
|
@@ -17462,8 +17472,8 @@ ${errors}`);
|
|
|
17462
17472
|
if (!steps || Object.keys(steps).length === 0) {
|
|
17463
17473
|
throw new Error(`Config '${resolved}' does not contain any steps to execute as a workflow`);
|
|
17464
17474
|
}
|
|
17465
|
-
const id =
|
|
17466
|
-
const name = loaded.name || `Workflow from ${
|
|
17475
|
+
const id = path27.basename(resolved).replace(/\.(ya?ml)$/i, "");
|
|
17476
|
+
const name = loaded.name || `Workflow from ${path27.basename(resolved)}`;
|
|
17467
17477
|
const workflowDef = {
|
|
17468
17478
|
id,
|
|
17469
17479
|
name,
|
|
@@ -18093,8 +18103,8 @@ async function createStoreBackend(storageConfig, haConfig) {
|
|
|
18093
18103
|
case "mssql": {
|
|
18094
18104
|
try {
|
|
18095
18105
|
const loaderPath = "../../enterprise/loader";
|
|
18096
|
-
const { loadEnterpriseStoreBackend
|
|
18097
|
-
return await
|
|
18106
|
+
const { loadEnterpriseStoreBackend } = await import(loaderPath);
|
|
18107
|
+
return await loadEnterpriseStoreBackend(driver, storageConfig, haConfig);
|
|
18098
18108
|
} catch (err) {
|
|
18099
18109
|
const msg = err instanceof Error ? err.message : String(err);
|
|
18100
18110
|
logger.error(`[StoreFactory] Failed to load enterprise ${driver} backend: ${msg}`);
|
|
@@ -20340,7 +20350,7 @@ var init_mcp_custom_sse_server = __esm({
|
|
|
20340
20350
|
* Returns the actual bound port number
|
|
20341
20351
|
*/
|
|
20342
20352
|
async start() {
|
|
20343
|
-
return new Promise((
|
|
20353
|
+
return new Promise((resolve14, reject) => {
|
|
20344
20354
|
try {
|
|
20345
20355
|
this.server = import_http.default.createServer((req, res) => {
|
|
20346
20356
|
this.handleRequest(req, res).catch((error) => {
|
|
@@ -20374,7 +20384,7 @@ var init_mcp_custom_sse_server = __esm({
|
|
|
20374
20384
|
);
|
|
20375
20385
|
}
|
|
20376
20386
|
this.startKeepalive();
|
|
20377
|
-
|
|
20387
|
+
resolve14(this.port);
|
|
20378
20388
|
});
|
|
20379
20389
|
} catch (error) {
|
|
20380
20390
|
reject(error);
|
|
@@ -20437,7 +20447,7 @@ var init_mcp_custom_sse_server = __esm({
|
|
|
20437
20447
|
logger.debug(
|
|
20438
20448
|
`[CustomToolsSSEServer:${this.sessionId}] Grace period before stop: ${waitMs}ms (activeToolCalls=${this.activeToolCalls})`
|
|
20439
20449
|
);
|
|
20440
|
-
await new Promise((
|
|
20450
|
+
await new Promise((resolve14) => setTimeout(resolve14, waitMs));
|
|
20441
20451
|
}
|
|
20442
20452
|
}
|
|
20443
20453
|
if (this.activeToolCalls > 0) {
|
|
@@ -20446,7 +20456,7 @@ var init_mcp_custom_sse_server = __esm({
|
|
|
20446
20456
|
`[CustomToolsSSEServer:${this.sessionId}] Waiting for ${this.activeToolCalls} active tool call(s) before stop`
|
|
20447
20457
|
);
|
|
20448
20458
|
while (this.activeToolCalls > 0 && Date.now() - startedAt < effectiveDrainTimeoutMs) {
|
|
20449
|
-
await new Promise((
|
|
20459
|
+
await new Promise((resolve14) => setTimeout(resolve14, 250));
|
|
20450
20460
|
}
|
|
20451
20461
|
if (this.activeToolCalls > 0) {
|
|
20452
20462
|
logger.warn(
|
|
@@ -20471,21 +20481,21 @@ var init_mcp_custom_sse_server = __esm({
|
|
|
20471
20481
|
}
|
|
20472
20482
|
this.connections.clear();
|
|
20473
20483
|
if (this.server) {
|
|
20474
|
-
await new Promise((
|
|
20484
|
+
await new Promise((resolve14, reject) => {
|
|
20475
20485
|
const timeout = setTimeout(() => {
|
|
20476
20486
|
if (this.debug) {
|
|
20477
20487
|
logger.debug(
|
|
20478
20488
|
`[CustomToolsSSEServer:${this.sessionId}] Force closing server after timeout`
|
|
20479
20489
|
);
|
|
20480
20490
|
}
|
|
20481
|
-
this.server?.close(() =>
|
|
20491
|
+
this.server?.close(() => resolve14());
|
|
20482
20492
|
}, 5e3);
|
|
20483
20493
|
this.server.close((error) => {
|
|
20484
20494
|
clearTimeout(timeout);
|
|
20485
20495
|
if (error) {
|
|
20486
20496
|
reject(error);
|
|
20487
20497
|
} else {
|
|
20488
|
-
|
|
20498
|
+
resolve14();
|
|
20489
20499
|
}
|
|
20490
20500
|
});
|
|
20491
20501
|
});
|
|
@@ -20911,7 +20921,7 @@ var init_mcp_custom_sse_server = __esm({
|
|
|
20911
20921
|
logger.warn(
|
|
20912
20922
|
`[CustomToolsSSEServer:${this.sessionId}] Tool ${toolName} failed (attempt ${attempt + 1}/${retryCount + 1}): ${errorMsg}. Retrying in ${delay}ms`
|
|
20913
20923
|
);
|
|
20914
|
-
await new Promise((
|
|
20924
|
+
await new Promise((resolve14) => setTimeout(resolve14, delay));
|
|
20915
20925
|
attempt++;
|
|
20916
20926
|
}
|
|
20917
20927
|
}
|
|
@@ -21224,9 +21234,9 @@ var init_ai_check_provider = __esm({
|
|
|
21224
21234
|
} else {
|
|
21225
21235
|
resolvedPath = import_path7.default.resolve(process.cwd(), str);
|
|
21226
21236
|
}
|
|
21227
|
-
const
|
|
21237
|
+
const fs23 = require("fs").promises;
|
|
21228
21238
|
try {
|
|
21229
|
-
const stat2 = await
|
|
21239
|
+
const stat2 = await fs23.stat(resolvedPath);
|
|
21230
21240
|
return stat2.isFile();
|
|
21231
21241
|
} catch {
|
|
21232
21242
|
return hasFileExtension && (isRelativePath || isAbsolutePath || hasPathSeparators);
|
|
@@ -27154,14 +27164,14 @@ var require_util = __commonJS({
|
|
|
27154
27164
|
}
|
|
27155
27165
|
const port = url.port != null ? url.port : url.protocol === "https:" ? 443 : 80;
|
|
27156
27166
|
let origin = url.origin != null ? url.origin : `${url.protocol}//${url.hostname}:${port}`;
|
|
27157
|
-
let
|
|
27167
|
+
let path27 = url.path != null ? url.path : `${url.pathname || ""}${url.search || ""}`;
|
|
27158
27168
|
if (origin.endsWith("/")) {
|
|
27159
27169
|
origin = origin.substring(0, origin.length - 1);
|
|
27160
27170
|
}
|
|
27161
|
-
if (
|
|
27162
|
-
|
|
27171
|
+
if (path27 && !path27.startsWith("/")) {
|
|
27172
|
+
path27 = `/${path27}`;
|
|
27163
27173
|
}
|
|
27164
|
-
url = new URL(origin +
|
|
27174
|
+
url = new URL(origin + path27);
|
|
27165
27175
|
}
|
|
27166
27176
|
return url;
|
|
27167
27177
|
}
|
|
@@ -28775,20 +28785,20 @@ var require_parseParams = __commonJS({
|
|
|
28775
28785
|
var require_basename = __commonJS({
|
|
28776
28786
|
"node_modules/@fastify/busboy/lib/utils/basename.js"(exports2, module2) {
|
|
28777
28787
|
"use strict";
|
|
28778
|
-
module2.exports = function basename4(
|
|
28779
|
-
if (typeof
|
|
28788
|
+
module2.exports = function basename4(path27) {
|
|
28789
|
+
if (typeof path27 !== "string") {
|
|
28780
28790
|
return "";
|
|
28781
28791
|
}
|
|
28782
|
-
for (var i =
|
|
28783
|
-
switch (
|
|
28792
|
+
for (var i = path27.length - 1; i >= 0; --i) {
|
|
28793
|
+
switch (path27.charCodeAt(i)) {
|
|
28784
28794
|
case 47:
|
|
28785
28795
|
// '/'
|
|
28786
28796
|
case 92:
|
|
28787
|
-
|
|
28788
|
-
return
|
|
28797
|
+
path27 = path27.slice(i + 1);
|
|
28798
|
+
return path27 === ".." || path27 === "." ? "" : path27;
|
|
28789
28799
|
}
|
|
28790
28800
|
}
|
|
28791
|
-
return
|
|
28801
|
+
return path27 === ".." || path27 === "." ? "" : path27;
|
|
28792
28802
|
};
|
|
28793
28803
|
}
|
|
28794
28804
|
});
|
|
@@ -29792,11 +29802,11 @@ var require_util2 = __commonJS({
|
|
|
29792
29802
|
var assert = require("assert");
|
|
29793
29803
|
var { isUint8Array } = require("util/types");
|
|
29794
29804
|
var supportedHashes = [];
|
|
29795
|
-
var
|
|
29805
|
+
var crypto2;
|
|
29796
29806
|
try {
|
|
29797
|
-
|
|
29807
|
+
crypto2 = require("crypto");
|
|
29798
29808
|
const possibleRelevantHashes = ["sha256", "sha384", "sha512"];
|
|
29799
|
-
supportedHashes =
|
|
29809
|
+
supportedHashes = crypto2.getHashes().filter((hash) => possibleRelevantHashes.includes(hash));
|
|
29800
29810
|
} catch {
|
|
29801
29811
|
}
|
|
29802
29812
|
function responseURL(response) {
|
|
@@ -30073,7 +30083,7 @@ var require_util2 = __commonJS({
|
|
|
30073
30083
|
}
|
|
30074
30084
|
}
|
|
30075
30085
|
function bytesMatch(bytes, metadataList) {
|
|
30076
|
-
if (
|
|
30086
|
+
if (crypto2 === void 0) {
|
|
30077
30087
|
return true;
|
|
30078
30088
|
}
|
|
30079
30089
|
const parsedMetadata = parseMetadata(metadataList);
|
|
@@ -30088,7 +30098,7 @@ var require_util2 = __commonJS({
|
|
|
30088
30098
|
for (const item of metadata) {
|
|
30089
30099
|
const algorithm = item.algo;
|
|
30090
30100
|
const expectedValue = item.hash;
|
|
30091
|
-
let actualValue =
|
|
30101
|
+
let actualValue = crypto2.createHash(algorithm).update(bytes).digest("base64");
|
|
30092
30102
|
if (actualValue[actualValue.length - 1] === "=") {
|
|
30093
30103
|
if (actualValue[actualValue.length - 2] === "=") {
|
|
30094
30104
|
actualValue = actualValue.slice(0, -2);
|
|
@@ -30181,8 +30191,8 @@ var require_util2 = __commonJS({
|
|
|
30181
30191
|
function createDeferredPromise() {
|
|
30182
30192
|
let res;
|
|
30183
30193
|
let rej;
|
|
30184
|
-
const promise = new Promise((
|
|
30185
|
-
res =
|
|
30194
|
+
const promise = new Promise((resolve14, reject) => {
|
|
30195
|
+
res = resolve14;
|
|
30186
30196
|
rej = reject;
|
|
30187
30197
|
});
|
|
30188
30198
|
return { promise, resolve: res, reject: rej };
|
|
@@ -31435,8 +31445,8 @@ var require_body = __commonJS({
|
|
|
31435
31445
|
var { parseMIMEType, serializeAMimeType } = require_dataURL();
|
|
31436
31446
|
var random;
|
|
31437
31447
|
try {
|
|
31438
|
-
const
|
|
31439
|
-
random = (max) =>
|
|
31448
|
+
const crypto2 = require("crypto");
|
|
31449
|
+
random = (max) => crypto2.randomInt(0, max);
|
|
31440
31450
|
} catch {
|
|
31441
31451
|
random = (max) => Math.floor(Math.random(max));
|
|
31442
31452
|
}
|
|
@@ -31687,8 +31697,8 @@ Content-Type: ${value.type || "application/octet-stream"}\r
|
|
|
31687
31697
|
});
|
|
31688
31698
|
}
|
|
31689
31699
|
});
|
|
31690
|
-
const busboyResolve = new Promise((
|
|
31691
|
-
busboy.on("finish",
|
|
31700
|
+
const busboyResolve = new Promise((resolve14, reject) => {
|
|
31701
|
+
busboy.on("finish", resolve14);
|
|
31692
31702
|
busboy.on("error", (err) => reject(new TypeError(err)));
|
|
31693
31703
|
});
|
|
31694
31704
|
if (this.body !== null) for await (const chunk of consumeBody(this[kState].body)) busboy.write(chunk);
|
|
@@ -31819,7 +31829,7 @@ var require_request = __commonJS({
|
|
|
31819
31829
|
}
|
|
31820
31830
|
var Request = class _Request {
|
|
31821
31831
|
constructor(origin, {
|
|
31822
|
-
path:
|
|
31832
|
+
path: path27,
|
|
31823
31833
|
method,
|
|
31824
31834
|
body,
|
|
31825
31835
|
headers,
|
|
@@ -31833,11 +31843,11 @@ var require_request = __commonJS({
|
|
|
31833
31843
|
throwOnError,
|
|
31834
31844
|
expectContinue
|
|
31835
31845
|
}, handler) {
|
|
31836
|
-
if (typeof
|
|
31846
|
+
if (typeof path27 !== "string") {
|
|
31837
31847
|
throw new InvalidArgumentError("path must be a string");
|
|
31838
|
-
} else if (
|
|
31848
|
+
} else if (path27[0] !== "/" && !(path27.startsWith("http://") || path27.startsWith("https://")) && method !== "CONNECT") {
|
|
31839
31849
|
throw new InvalidArgumentError("path must be an absolute URL or start with a slash");
|
|
31840
|
-
} else if (invalidPathRegex.exec(
|
|
31850
|
+
} else if (invalidPathRegex.exec(path27) !== null) {
|
|
31841
31851
|
throw new InvalidArgumentError("invalid request path");
|
|
31842
31852
|
}
|
|
31843
31853
|
if (typeof method !== "string") {
|
|
@@ -31900,7 +31910,7 @@ var require_request = __commonJS({
|
|
|
31900
31910
|
this.completed = false;
|
|
31901
31911
|
this.aborted = false;
|
|
31902
31912
|
this.upgrade = upgrade || null;
|
|
31903
|
-
this.path = query ? util.buildURL(
|
|
31913
|
+
this.path = query ? util.buildURL(path27, query) : path27;
|
|
31904
31914
|
this.origin = origin;
|
|
31905
31915
|
this.idempotent = idempotent == null ? method === "HEAD" || method === "GET" : idempotent;
|
|
31906
31916
|
this.blocking = blocking == null ? false : blocking;
|
|
@@ -32222,9 +32232,9 @@ var require_dispatcher_base = __commonJS({
|
|
|
32222
32232
|
}
|
|
32223
32233
|
close(callback) {
|
|
32224
32234
|
if (callback === void 0) {
|
|
32225
|
-
return new Promise((
|
|
32235
|
+
return new Promise((resolve14, reject) => {
|
|
32226
32236
|
this.close((err, data) => {
|
|
32227
|
-
return err ? reject(err) :
|
|
32237
|
+
return err ? reject(err) : resolve14(data);
|
|
32228
32238
|
});
|
|
32229
32239
|
});
|
|
32230
32240
|
}
|
|
@@ -32262,12 +32272,12 @@ var require_dispatcher_base = __commonJS({
|
|
|
32262
32272
|
err = null;
|
|
32263
32273
|
}
|
|
32264
32274
|
if (callback === void 0) {
|
|
32265
|
-
return new Promise((
|
|
32275
|
+
return new Promise((resolve14, reject) => {
|
|
32266
32276
|
this.destroy(err, (err2, data) => {
|
|
32267
32277
|
return err2 ? (
|
|
32268
32278
|
/* istanbul ignore next: should never error */
|
|
32269
32279
|
reject(err2)
|
|
32270
|
-
) :
|
|
32280
|
+
) : resolve14(data);
|
|
32271
32281
|
});
|
|
32272
32282
|
});
|
|
32273
32283
|
}
|
|
@@ -32908,9 +32918,9 @@ var require_RedirectHandler = __commonJS({
|
|
|
32908
32918
|
return this.handler.onHeaders(statusCode, headers, resume, statusText);
|
|
32909
32919
|
}
|
|
32910
32920
|
const { origin, pathname, search } = util.parseURL(new URL(this.location, this.opts.origin && new URL(this.opts.path, this.opts.origin)));
|
|
32911
|
-
const
|
|
32921
|
+
const path27 = search ? `${pathname}${search}` : pathname;
|
|
32912
32922
|
this.opts.headers = cleanRequestHeaders(this.opts.headers, statusCode === 303, this.opts.origin !== origin);
|
|
32913
|
-
this.opts.path =
|
|
32923
|
+
this.opts.path = path27;
|
|
32914
32924
|
this.opts.origin = origin;
|
|
32915
32925
|
this.opts.maxRedirections = 0;
|
|
32916
32926
|
this.opts.query = null;
|
|
@@ -33329,16 +33339,16 @@ var require_client = __commonJS({
|
|
|
33329
33339
|
return this[kNeedDrain] < 2;
|
|
33330
33340
|
}
|
|
33331
33341
|
async [kClose]() {
|
|
33332
|
-
return new Promise((
|
|
33342
|
+
return new Promise((resolve14) => {
|
|
33333
33343
|
if (!this[kSize]) {
|
|
33334
|
-
|
|
33344
|
+
resolve14(null);
|
|
33335
33345
|
} else {
|
|
33336
|
-
this[kClosedResolve] =
|
|
33346
|
+
this[kClosedResolve] = resolve14;
|
|
33337
33347
|
}
|
|
33338
33348
|
});
|
|
33339
33349
|
}
|
|
33340
33350
|
async [kDestroy](err) {
|
|
33341
|
-
return new Promise((
|
|
33351
|
+
return new Promise((resolve14) => {
|
|
33342
33352
|
const requests = this[kQueue].splice(this[kPendingIdx]);
|
|
33343
33353
|
for (let i = 0; i < requests.length; i++) {
|
|
33344
33354
|
const request = requests[i];
|
|
@@ -33349,7 +33359,7 @@ var require_client = __commonJS({
|
|
|
33349
33359
|
this[kClosedResolve]();
|
|
33350
33360
|
this[kClosedResolve] = null;
|
|
33351
33361
|
}
|
|
33352
|
-
|
|
33362
|
+
resolve14();
|
|
33353
33363
|
};
|
|
33354
33364
|
if (this[kHTTP2Session] != null) {
|
|
33355
33365
|
util.destroy(this[kHTTP2Session], err);
|
|
@@ -33929,7 +33939,7 @@ var require_client = __commonJS({
|
|
|
33929
33939
|
});
|
|
33930
33940
|
}
|
|
33931
33941
|
try {
|
|
33932
|
-
const socket = await new Promise((
|
|
33942
|
+
const socket = await new Promise((resolve14, reject) => {
|
|
33933
33943
|
client[kConnector]({
|
|
33934
33944
|
host,
|
|
33935
33945
|
hostname,
|
|
@@ -33941,7 +33951,7 @@ var require_client = __commonJS({
|
|
|
33941
33951
|
if (err) {
|
|
33942
33952
|
reject(err);
|
|
33943
33953
|
} else {
|
|
33944
|
-
|
|
33954
|
+
resolve14(socket2);
|
|
33945
33955
|
}
|
|
33946
33956
|
});
|
|
33947
33957
|
});
|
|
@@ -34152,7 +34162,7 @@ var require_client = __commonJS({
|
|
|
34152
34162
|
writeH2(client, client[kHTTP2Session], request);
|
|
34153
34163
|
return;
|
|
34154
34164
|
}
|
|
34155
|
-
const { body, method, path:
|
|
34165
|
+
const { body, method, path: path27, host, upgrade, headers, blocking, reset } = request;
|
|
34156
34166
|
const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH";
|
|
34157
34167
|
if (body && typeof body.read === "function") {
|
|
34158
34168
|
body.read(0);
|
|
@@ -34202,7 +34212,7 @@ var require_client = __commonJS({
|
|
|
34202
34212
|
if (blocking) {
|
|
34203
34213
|
socket[kBlocking] = true;
|
|
34204
34214
|
}
|
|
34205
|
-
let header = `${method} ${
|
|
34215
|
+
let header = `${method} ${path27} HTTP/1.1\r
|
|
34206
34216
|
`;
|
|
34207
34217
|
if (typeof host === "string") {
|
|
34208
34218
|
header += `host: ${host}\r
|
|
@@ -34265,7 +34275,7 @@ upgrade: ${upgrade}\r
|
|
|
34265
34275
|
return true;
|
|
34266
34276
|
}
|
|
34267
34277
|
function writeH2(client, session, request) {
|
|
34268
|
-
const { body, method, path:
|
|
34278
|
+
const { body, method, path: path27, host, upgrade, expectContinue, signal, headers: reqHeaders } = request;
|
|
34269
34279
|
let headers;
|
|
34270
34280
|
if (typeof reqHeaders === "string") headers = Request[kHTTP2CopyHeaders](reqHeaders.trim());
|
|
34271
34281
|
else headers = reqHeaders;
|
|
@@ -34308,7 +34318,7 @@ upgrade: ${upgrade}\r
|
|
|
34308
34318
|
});
|
|
34309
34319
|
return true;
|
|
34310
34320
|
}
|
|
34311
|
-
headers[HTTP2_HEADER_PATH] =
|
|
34321
|
+
headers[HTTP2_HEADER_PATH] = path27;
|
|
34312
34322
|
headers[HTTP2_HEADER_SCHEME] = "https";
|
|
34313
34323
|
const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH";
|
|
34314
34324
|
if (body && typeof body.read === "function") {
|
|
@@ -34565,12 +34575,12 @@ upgrade: ${upgrade}\r
|
|
|
34565
34575
|
cb();
|
|
34566
34576
|
}
|
|
34567
34577
|
}
|
|
34568
|
-
const waitForDrain = () => new Promise((
|
|
34578
|
+
const waitForDrain = () => new Promise((resolve14, reject) => {
|
|
34569
34579
|
assert(callback === null);
|
|
34570
34580
|
if (socket[kError]) {
|
|
34571
34581
|
reject(socket[kError]);
|
|
34572
34582
|
} else {
|
|
34573
|
-
callback =
|
|
34583
|
+
callback = resolve14;
|
|
34574
34584
|
}
|
|
34575
34585
|
});
|
|
34576
34586
|
if (client[kHTTPConnVersion] === "h2") {
|
|
@@ -34916,8 +34926,8 @@ var require_pool_base = __commonJS({
|
|
|
34916
34926
|
if (this[kQueue].isEmpty()) {
|
|
34917
34927
|
return Promise.all(this[kClients].map((c) => c.close()));
|
|
34918
34928
|
} else {
|
|
34919
|
-
return new Promise((
|
|
34920
|
-
this[kClosedResolve] =
|
|
34929
|
+
return new Promise((resolve14) => {
|
|
34930
|
+
this[kClosedResolve] = resolve14;
|
|
34921
34931
|
});
|
|
34922
34932
|
}
|
|
34923
34933
|
}
|
|
@@ -35495,7 +35505,7 @@ var require_readable = __commonJS({
|
|
|
35495
35505
|
if (this.closed) {
|
|
35496
35506
|
return Promise.resolve(null);
|
|
35497
35507
|
}
|
|
35498
|
-
return new Promise((
|
|
35508
|
+
return new Promise((resolve14, reject) => {
|
|
35499
35509
|
const signalListenerCleanup = signal ? util.addAbortListener(signal, () => {
|
|
35500
35510
|
this.destroy();
|
|
35501
35511
|
}) : noop;
|
|
@@ -35504,7 +35514,7 @@ var require_readable = __commonJS({
|
|
|
35504
35514
|
if (signal && signal.aborted) {
|
|
35505
35515
|
reject(signal.reason || Object.assign(new Error("The operation was aborted"), { name: "AbortError" }));
|
|
35506
35516
|
} else {
|
|
35507
|
-
|
|
35517
|
+
resolve14(null);
|
|
35508
35518
|
}
|
|
35509
35519
|
}).on("error", noop).on("data", function(chunk) {
|
|
35510
35520
|
limit -= chunk.length;
|
|
@@ -35526,11 +35536,11 @@ var require_readable = __commonJS({
|
|
|
35526
35536
|
throw new TypeError("unusable");
|
|
35527
35537
|
}
|
|
35528
35538
|
assert(!stream[kConsume]);
|
|
35529
|
-
return new Promise((
|
|
35539
|
+
return new Promise((resolve14, reject) => {
|
|
35530
35540
|
stream[kConsume] = {
|
|
35531
35541
|
type,
|
|
35532
35542
|
stream,
|
|
35533
|
-
resolve:
|
|
35543
|
+
resolve: resolve14,
|
|
35534
35544
|
reject,
|
|
35535
35545
|
length: 0,
|
|
35536
35546
|
body: []
|
|
@@ -35565,12 +35575,12 @@ var require_readable = __commonJS({
|
|
|
35565
35575
|
}
|
|
35566
35576
|
}
|
|
35567
35577
|
function consumeEnd(consume2) {
|
|
35568
|
-
const { type, body, resolve:
|
|
35578
|
+
const { type, body, resolve: resolve14, stream, length } = consume2;
|
|
35569
35579
|
try {
|
|
35570
35580
|
if (type === "text") {
|
|
35571
|
-
|
|
35581
|
+
resolve14(toUSVString(Buffer.concat(body)));
|
|
35572
35582
|
} else if (type === "json") {
|
|
35573
|
-
|
|
35583
|
+
resolve14(JSON.parse(Buffer.concat(body)));
|
|
35574
35584
|
} else if (type === "arrayBuffer") {
|
|
35575
35585
|
const dst = new Uint8Array(length);
|
|
35576
35586
|
let pos = 0;
|
|
@@ -35578,12 +35588,12 @@ var require_readable = __commonJS({
|
|
|
35578
35588
|
dst.set(buf, pos);
|
|
35579
35589
|
pos += buf.byteLength;
|
|
35580
35590
|
}
|
|
35581
|
-
|
|
35591
|
+
resolve14(dst.buffer);
|
|
35582
35592
|
} else if (type === "blob") {
|
|
35583
35593
|
if (!Blob2) {
|
|
35584
35594
|
Blob2 = require("buffer").Blob;
|
|
35585
35595
|
}
|
|
35586
|
-
|
|
35596
|
+
resolve14(new Blob2(body, { type: stream[kContentType] }));
|
|
35587
35597
|
}
|
|
35588
35598
|
consumeFinish(consume2);
|
|
35589
35599
|
} catch (err) {
|
|
@@ -35840,9 +35850,9 @@ var require_api_request = __commonJS({
|
|
|
35840
35850
|
};
|
|
35841
35851
|
function request(opts, callback) {
|
|
35842
35852
|
if (callback === void 0) {
|
|
35843
|
-
return new Promise((
|
|
35853
|
+
return new Promise((resolve14, reject) => {
|
|
35844
35854
|
request.call(this, opts, (err, data) => {
|
|
35845
|
-
return err ? reject(err) :
|
|
35855
|
+
return err ? reject(err) : resolve14(data);
|
|
35846
35856
|
});
|
|
35847
35857
|
});
|
|
35848
35858
|
}
|
|
@@ -36015,9 +36025,9 @@ var require_api_stream = __commonJS({
|
|
|
36015
36025
|
};
|
|
36016
36026
|
function stream(opts, factory, callback) {
|
|
36017
36027
|
if (callback === void 0) {
|
|
36018
|
-
return new Promise((
|
|
36028
|
+
return new Promise((resolve14, reject) => {
|
|
36019
36029
|
stream.call(this, opts, factory, (err, data) => {
|
|
36020
|
-
return err ? reject(err) :
|
|
36030
|
+
return err ? reject(err) : resolve14(data);
|
|
36021
36031
|
});
|
|
36022
36032
|
});
|
|
36023
36033
|
}
|
|
@@ -36298,9 +36308,9 @@ var require_api_upgrade = __commonJS({
|
|
|
36298
36308
|
};
|
|
36299
36309
|
function upgrade(opts, callback) {
|
|
36300
36310
|
if (callback === void 0) {
|
|
36301
|
-
return new Promise((
|
|
36311
|
+
return new Promise((resolve14, reject) => {
|
|
36302
36312
|
upgrade.call(this, opts, (err, data) => {
|
|
36303
|
-
return err ? reject(err) :
|
|
36313
|
+
return err ? reject(err) : resolve14(data);
|
|
36304
36314
|
});
|
|
36305
36315
|
});
|
|
36306
36316
|
}
|
|
@@ -36389,9 +36399,9 @@ var require_api_connect = __commonJS({
|
|
|
36389
36399
|
};
|
|
36390
36400
|
function connect(opts, callback) {
|
|
36391
36401
|
if (callback === void 0) {
|
|
36392
|
-
return new Promise((
|
|
36402
|
+
return new Promise((resolve14, reject) => {
|
|
36393
36403
|
connect.call(this, opts, (err, data) => {
|
|
36394
|
-
return err ? reject(err) :
|
|
36404
|
+
return err ? reject(err) : resolve14(data);
|
|
36395
36405
|
});
|
|
36396
36406
|
});
|
|
36397
36407
|
}
|
|
@@ -36551,20 +36561,20 @@ var require_mock_utils = __commonJS({
|
|
|
36551
36561
|
}
|
|
36552
36562
|
return true;
|
|
36553
36563
|
}
|
|
36554
|
-
function safeUrl(
|
|
36555
|
-
if (typeof
|
|
36556
|
-
return
|
|
36564
|
+
function safeUrl(path27) {
|
|
36565
|
+
if (typeof path27 !== "string") {
|
|
36566
|
+
return path27;
|
|
36557
36567
|
}
|
|
36558
|
-
const pathSegments =
|
|
36568
|
+
const pathSegments = path27.split("?");
|
|
36559
36569
|
if (pathSegments.length !== 2) {
|
|
36560
|
-
return
|
|
36570
|
+
return path27;
|
|
36561
36571
|
}
|
|
36562
36572
|
const qp = new URLSearchParams(pathSegments.pop());
|
|
36563
36573
|
qp.sort();
|
|
36564
36574
|
return [...pathSegments, qp.toString()].join("?");
|
|
36565
36575
|
}
|
|
36566
|
-
function matchKey(mockDispatch2, { path:
|
|
36567
|
-
const pathMatch = matchValue(mockDispatch2.path,
|
|
36576
|
+
function matchKey(mockDispatch2, { path: path27, method, body, headers }) {
|
|
36577
|
+
const pathMatch = matchValue(mockDispatch2.path, path27);
|
|
36568
36578
|
const methodMatch = matchValue(mockDispatch2.method, method);
|
|
36569
36579
|
const bodyMatch = typeof mockDispatch2.body !== "undefined" ? matchValue(mockDispatch2.body, body) : true;
|
|
36570
36580
|
const headersMatch = matchHeaders(mockDispatch2, headers);
|
|
@@ -36582,7 +36592,7 @@ var require_mock_utils = __commonJS({
|
|
|
36582
36592
|
function getMockDispatch(mockDispatches, key) {
|
|
36583
36593
|
const basePath = key.query ? buildURL(key.path, key.query) : key.path;
|
|
36584
36594
|
const resolvedPath = typeof basePath === "string" ? safeUrl(basePath) : basePath;
|
|
36585
|
-
let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path:
|
|
36595
|
+
let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path: path27 }) => matchValue(safeUrl(path27), resolvedPath));
|
|
36586
36596
|
if (matchedMockDispatches.length === 0) {
|
|
36587
36597
|
throw new MockNotMatchedError(`Mock dispatch not matched for path '${resolvedPath}'`);
|
|
36588
36598
|
}
|
|
@@ -36619,9 +36629,9 @@ var require_mock_utils = __commonJS({
|
|
|
36619
36629
|
}
|
|
36620
36630
|
}
|
|
36621
36631
|
function buildKey(opts) {
|
|
36622
|
-
const { path:
|
|
36632
|
+
const { path: path27, method, body, headers, query } = opts;
|
|
36623
36633
|
return {
|
|
36624
|
-
path:
|
|
36634
|
+
path: path27,
|
|
36625
36635
|
method,
|
|
36626
36636
|
body,
|
|
36627
36637
|
headers,
|
|
@@ -37070,10 +37080,10 @@ var require_pending_interceptors_formatter = __commonJS({
|
|
|
37070
37080
|
}
|
|
37071
37081
|
format(pendingInterceptors) {
|
|
37072
37082
|
const withPrettyHeaders = pendingInterceptors.map(
|
|
37073
|
-
({ method, path:
|
|
37083
|
+
({ method, path: path27, data: { statusCode }, persist, times, timesInvoked, origin }) => ({
|
|
37074
37084
|
Method: method,
|
|
37075
37085
|
Origin: origin,
|
|
37076
|
-
Path:
|
|
37086
|
+
Path: path27,
|
|
37077
37087
|
"Status code": statusCode,
|
|
37078
37088
|
Persistent: persist ? "\u2705" : "\u274C",
|
|
37079
37089
|
Invocations: timesInvoked,
|
|
@@ -40014,7 +40024,7 @@ var require_fetch = __commonJS({
|
|
|
40014
40024
|
async function dispatch({ body }) {
|
|
40015
40025
|
const url = requestCurrentURL(request);
|
|
40016
40026
|
const agent = fetchParams.controller.dispatcher;
|
|
40017
|
-
return new Promise((
|
|
40027
|
+
return new Promise((resolve14, reject) => agent.dispatch(
|
|
40018
40028
|
{
|
|
40019
40029
|
path: url.pathname + url.search,
|
|
40020
40030
|
origin: url.origin,
|
|
@@ -40090,7 +40100,7 @@ var require_fetch = __commonJS({
|
|
|
40090
40100
|
}
|
|
40091
40101
|
}
|
|
40092
40102
|
}
|
|
40093
|
-
|
|
40103
|
+
resolve14({
|
|
40094
40104
|
status,
|
|
40095
40105
|
statusText,
|
|
40096
40106
|
headersList: headers[kHeadersList],
|
|
@@ -40133,7 +40143,7 @@ var require_fetch = __commonJS({
|
|
|
40133
40143
|
const val = headersList[n + 1].toString("latin1");
|
|
40134
40144
|
headers[kHeadersList].append(key, val);
|
|
40135
40145
|
}
|
|
40136
|
-
|
|
40146
|
+
resolve14({
|
|
40137
40147
|
status,
|
|
40138
40148
|
statusText: STATUS_CODES[status],
|
|
40139
40149
|
headersList: headers[kHeadersList],
|
|
@@ -41694,8 +41704,8 @@ var require_util6 = __commonJS({
|
|
|
41694
41704
|
}
|
|
41695
41705
|
}
|
|
41696
41706
|
}
|
|
41697
|
-
function validateCookiePath(
|
|
41698
|
-
for (const char of
|
|
41707
|
+
function validateCookiePath(path27) {
|
|
41708
|
+
for (const char of path27) {
|
|
41699
41709
|
const code = char.charCodeAt(0);
|
|
41700
41710
|
if (code < 33 || char === ";") {
|
|
41701
41711
|
throw new Error("Invalid cookie path");
|
|
@@ -42492,9 +42502,9 @@ var require_connection = __commonJS({
|
|
|
42492
42502
|
channels.open = diagnosticsChannel.channel("undici:websocket:open");
|
|
42493
42503
|
channels.close = diagnosticsChannel.channel("undici:websocket:close");
|
|
42494
42504
|
channels.socketError = diagnosticsChannel.channel("undici:websocket:socket_error");
|
|
42495
|
-
var
|
|
42505
|
+
var crypto2;
|
|
42496
42506
|
try {
|
|
42497
|
-
|
|
42507
|
+
crypto2 = require("crypto");
|
|
42498
42508
|
} catch {
|
|
42499
42509
|
}
|
|
42500
42510
|
function establishWebSocketConnection(url, protocols, ws, onEstablish, options) {
|
|
@@ -42513,7 +42523,7 @@ var require_connection = __commonJS({
|
|
|
42513
42523
|
const headersList = new Headers(options.headers)[kHeadersList];
|
|
42514
42524
|
request.headersList = headersList;
|
|
42515
42525
|
}
|
|
42516
|
-
const keyValue =
|
|
42526
|
+
const keyValue = crypto2.randomBytes(16).toString("base64");
|
|
42517
42527
|
request.headersList.append("sec-websocket-key", keyValue);
|
|
42518
42528
|
request.headersList.append("sec-websocket-version", "13");
|
|
42519
42529
|
for (const protocol of protocols) {
|
|
@@ -42542,7 +42552,7 @@ var require_connection = __commonJS({
|
|
|
42542
42552
|
return;
|
|
42543
42553
|
}
|
|
42544
42554
|
const secWSAccept = response.headersList.get("Sec-WebSocket-Accept");
|
|
42545
|
-
const digest =
|
|
42555
|
+
const digest = crypto2.createHash("sha1").update(keyValue + uid).digest("base64");
|
|
42546
42556
|
if (secWSAccept !== digest) {
|
|
42547
42557
|
failWebsocketConnection(ws, "Incorrect hash received in Sec-WebSocket-Accept header.");
|
|
42548
42558
|
return;
|
|
@@ -42622,9 +42632,9 @@ var require_frame = __commonJS({
|
|
|
42622
42632
|
"node_modules/undici/lib/websocket/frame.js"(exports2, module2) {
|
|
42623
42633
|
"use strict";
|
|
42624
42634
|
var { maxUnsigned16Bit } = require_constants5();
|
|
42625
|
-
var
|
|
42635
|
+
var crypto2;
|
|
42626
42636
|
try {
|
|
42627
|
-
|
|
42637
|
+
crypto2 = require("crypto");
|
|
42628
42638
|
} catch {
|
|
42629
42639
|
}
|
|
42630
42640
|
var WebsocketFrameSend = class {
|
|
@@ -42633,7 +42643,7 @@ var require_frame = __commonJS({
|
|
|
42633
42643
|
*/
|
|
42634
42644
|
constructor(data) {
|
|
42635
42645
|
this.frameData = data;
|
|
42636
|
-
this.maskKey =
|
|
42646
|
+
this.maskKey = crypto2.randomBytes(4);
|
|
42637
42647
|
}
|
|
42638
42648
|
createFrame(opcode) {
|
|
42639
42649
|
const bodyLength = this.frameData?.byteLength ?? 0;
|
|
@@ -43375,11 +43385,11 @@ var require_undici = __commonJS({
|
|
|
43375
43385
|
if (typeof opts.path !== "string") {
|
|
43376
43386
|
throw new InvalidArgumentError("invalid opts.path");
|
|
43377
43387
|
}
|
|
43378
|
-
let
|
|
43388
|
+
let path27 = opts.path;
|
|
43379
43389
|
if (!opts.path.startsWith("/")) {
|
|
43380
|
-
|
|
43390
|
+
path27 = `/${path27}`;
|
|
43381
43391
|
}
|
|
43382
|
-
url = new URL(util.parseOrigin(url).origin +
|
|
43392
|
+
url = new URL(util.parseOrigin(url).origin + path27);
|
|
43383
43393
|
} else {
|
|
43384
43394
|
if (!opts) {
|
|
43385
43395
|
opts = typeof url === "object" ? url : {};
|
|
@@ -43928,7 +43938,7 @@ var init_mcp_check_provider = __esm({
|
|
|
43928
43938
|
logger.warn(
|
|
43929
43939
|
`MCP ${transportName} failed (attempt ${attempt + 1}/${maxRetries + 1}), retrying in ${delay}ms: ${error instanceof Error ? error.message : String(error)}`
|
|
43930
43940
|
);
|
|
43931
|
-
await new Promise((
|
|
43941
|
+
await new Promise((resolve14) => setTimeout(resolve14, delay));
|
|
43932
43942
|
attempt += 1;
|
|
43933
43943
|
} finally {
|
|
43934
43944
|
try {
|
|
@@ -44210,7 +44220,7 @@ async function acquirePromptLock() {
|
|
|
44210
44220
|
activePrompt = true;
|
|
44211
44221
|
return;
|
|
44212
44222
|
}
|
|
44213
|
-
await new Promise((
|
|
44223
|
+
await new Promise((resolve14) => waiters.push(resolve14));
|
|
44214
44224
|
activePrompt = true;
|
|
44215
44225
|
}
|
|
44216
44226
|
function releasePromptLock() {
|
|
@@ -44220,7 +44230,7 @@ function releasePromptLock() {
|
|
|
44220
44230
|
}
|
|
44221
44231
|
async function interactivePrompt(options) {
|
|
44222
44232
|
await acquirePromptLock();
|
|
44223
|
-
return new Promise((
|
|
44233
|
+
return new Promise((resolve14, reject) => {
|
|
44224
44234
|
const dbg = process.env.VISOR_DEBUG === "true";
|
|
44225
44235
|
try {
|
|
44226
44236
|
if (dbg) {
|
|
@@ -44307,12 +44317,12 @@ async function interactivePrompt(options) {
|
|
|
44307
44317
|
};
|
|
44308
44318
|
const finish = (value) => {
|
|
44309
44319
|
cleanup();
|
|
44310
|
-
|
|
44320
|
+
resolve14(value);
|
|
44311
44321
|
};
|
|
44312
44322
|
if (options.timeout && options.timeout > 0) {
|
|
44313
44323
|
timeoutId = setTimeout(() => {
|
|
44314
44324
|
cleanup();
|
|
44315
|
-
if (defaultValue !== void 0) return
|
|
44325
|
+
if (defaultValue !== void 0) return resolve14(defaultValue);
|
|
44316
44326
|
return reject(new Error("Input timeout"));
|
|
44317
44327
|
}, options.timeout);
|
|
44318
44328
|
}
|
|
@@ -44444,7 +44454,7 @@ async function interactivePrompt(options) {
|
|
|
44444
44454
|
});
|
|
44445
44455
|
}
|
|
44446
44456
|
async function simplePrompt(prompt) {
|
|
44447
|
-
return new Promise((
|
|
44457
|
+
return new Promise((resolve14) => {
|
|
44448
44458
|
const rl = readline.createInterface({
|
|
44449
44459
|
input: process.stdin,
|
|
44450
44460
|
output: process.stdout
|
|
@@ -44460,7 +44470,7 @@ async function simplePrompt(prompt) {
|
|
|
44460
44470
|
rl.question(`${prompt}
|
|
44461
44471
|
> `, (answer) => {
|
|
44462
44472
|
rl.close();
|
|
44463
|
-
|
|
44473
|
+
resolve14(answer.trim());
|
|
44464
44474
|
});
|
|
44465
44475
|
});
|
|
44466
44476
|
}
|
|
@@ -44628,7 +44638,7 @@ function isStdinAvailable() {
|
|
|
44628
44638
|
return !process.stdin.isTTY;
|
|
44629
44639
|
}
|
|
44630
44640
|
async function readStdin(timeout, maxSize = 1024 * 1024) {
|
|
44631
|
-
return new Promise((
|
|
44641
|
+
return new Promise((resolve14, reject) => {
|
|
44632
44642
|
let data = "";
|
|
44633
44643
|
let timeoutId;
|
|
44634
44644
|
if (timeout) {
|
|
@@ -44655,7 +44665,7 @@ async function readStdin(timeout, maxSize = 1024 * 1024) {
|
|
|
44655
44665
|
};
|
|
44656
44666
|
const onEnd = () => {
|
|
44657
44667
|
cleanup();
|
|
44658
|
-
|
|
44668
|
+
resolve14(data.trim());
|
|
44659
44669
|
};
|
|
44660
44670
|
const onError = (err) => {
|
|
44661
44671
|
cleanup();
|
|
@@ -48732,23 +48742,23 @@ __export(renderer_schema_exports, {
|
|
|
48732
48742
|
});
|
|
48733
48743
|
async function loadRendererSchema(name) {
|
|
48734
48744
|
try {
|
|
48735
|
-
const
|
|
48736
|
-
const
|
|
48745
|
+
const fs23 = await import("fs/promises");
|
|
48746
|
+
const path27 = await import("path");
|
|
48737
48747
|
const sanitized = String(name).replace(/[^a-zA-Z0-9-]/g, "");
|
|
48738
48748
|
if (!sanitized) return void 0;
|
|
48739
48749
|
const candidates = [
|
|
48740
48750
|
// When bundled with ncc, __dirname is dist/ and output/ is at dist/output/
|
|
48741
|
-
|
|
48751
|
+
path27.join(__dirname, "output", sanitized, "schema.json"),
|
|
48742
48752
|
// When running from source, __dirname is src/state-machine/dispatch/ and output/ is at output/
|
|
48743
|
-
|
|
48753
|
+
path27.join(__dirname, "..", "..", "output", sanitized, "schema.json"),
|
|
48744
48754
|
// When running from a checkout with output/ folder copied to CWD
|
|
48745
|
-
|
|
48755
|
+
path27.join(process.cwd(), "output", sanitized, "schema.json"),
|
|
48746
48756
|
// Fallback: cwd/dist/output/
|
|
48747
|
-
|
|
48757
|
+
path27.join(process.cwd(), "dist", "output", sanitized, "schema.json")
|
|
48748
48758
|
];
|
|
48749
48759
|
for (const p of candidates) {
|
|
48750
48760
|
try {
|
|
48751
|
-
const raw = await
|
|
48761
|
+
const raw = await fs23.readFile(p, "utf-8");
|
|
48752
48762
|
return JSON.parse(raw);
|
|
48753
48763
|
} catch {
|
|
48754
48764
|
}
|
|
@@ -51167,8 +51177,8 @@ function updateStats2(results, state, isForEachIteration = false) {
|
|
|
51167
51177
|
async function renderTemplateContent2(checkId, checkConfig, reviewSummary) {
|
|
51168
51178
|
try {
|
|
51169
51179
|
const { createExtendedLiquid: createExtendedLiquid2 } = await Promise.resolve().then(() => (init_liquid_extensions(), liquid_extensions_exports));
|
|
51170
|
-
const
|
|
51171
|
-
const
|
|
51180
|
+
const fs23 = await import("fs/promises");
|
|
51181
|
+
const path27 = await import("path");
|
|
51172
51182
|
const schemaRaw = checkConfig.schema || "plain";
|
|
51173
51183
|
const schema = typeof schemaRaw === "string" && !schemaRaw.includes("{{") && !schemaRaw.includes("{%") ? schemaRaw : typeof schemaRaw === "object" ? "code-review" : "plain";
|
|
51174
51184
|
let templateContent;
|
|
@@ -51177,27 +51187,27 @@ async function renderTemplateContent2(checkId, checkConfig, reviewSummary) {
|
|
|
51177
51187
|
logger.debug(`[LevelDispatch] Using inline template for ${checkId}`);
|
|
51178
51188
|
} else if (checkConfig.template && checkConfig.template.file) {
|
|
51179
51189
|
const file = String(checkConfig.template.file);
|
|
51180
|
-
const resolved =
|
|
51181
|
-
templateContent = await
|
|
51190
|
+
const resolved = path27.resolve(process.cwd(), file);
|
|
51191
|
+
templateContent = await fs23.readFile(resolved, "utf-8");
|
|
51182
51192
|
logger.debug(`[LevelDispatch] Using template file for ${checkId}: ${resolved}`);
|
|
51183
51193
|
} else if (schema && schema !== "plain") {
|
|
51184
51194
|
const sanitized = String(schema).replace(/[^a-zA-Z0-9-]/g, "");
|
|
51185
51195
|
if (sanitized) {
|
|
51186
51196
|
const candidatePaths = [
|
|
51187
|
-
|
|
51197
|
+
path27.join(__dirname, "output", sanitized, "template.liquid"),
|
|
51188
51198
|
// bundled: dist/output/
|
|
51189
|
-
|
|
51199
|
+
path27.join(__dirname, "..", "..", "output", sanitized, "template.liquid"),
|
|
51190
51200
|
// source (from state-machine/states)
|
|
51191
|
-
|
|
51201
|
+
path27.join(__dirname, "..", "..", "..", "output", sanitized, "template.liquid"),
|
|
51192
51202
|
// source (alternate)
|
|
51193
|
-
|
|
51203
|
+
path27.join(process.cwd(), "output", sanitized, "template.liquid"),
|
|
51194
51204
|
// fallback: cwd/output/
|
|
51195
|
-
|
|
51205
|
+
path27.join(process.cwd(), "dist", "output", sanitized, "template.liquid")
|
|
51196
51206
|
// fallback: cwd/dist/output/
|
|
51197
51207
|
];
|
|
51198
51208
|
for (const p of candidatePaths) {
|
|
51199
51209
|
try {
|
|
51200
|
-
templateContent = await
|
|
51210
|
+
templateContent = await fs23.readFile(p, "utf-8");
|
|
51201
51211
|
if (templateContent) {
|
|
51202
51212
|
logger.debug(`[LevelDispatch] Using schema template for ${checkId}: ${p}`);
|
|
51203
51213
|
break;
|
|
@@ -53280,8 +53290,8 @@ var init_workspace_manager = __esm({
|
|
|
53280
53290
|
);
|
|
53281
53291
|
if (this.cleanupRequested && this.activeOperations === 0) {
|
|
53282
53292
|
logger.debug(`[Workspace] All references released, proceeding with deferred cleanup`);
|
|
53283
|
-
for (const
|
|
53284
|
-
|
|
53293
|
+
for (const resolve14 of this.cleanupResolvers) {
|
|
53294
|
+
resolve14();
|
|
53285
53295
|
}
|
|
53286
53296
|
this.cleanupResolvers = [];
|
|
53287
53297
|
}
|
|
@@ -53438,19 +53448,19 @@ var init_workspace_manager = __esm({
|
|
|
53438
53448
|
);
|
|
53439
53449
|
this.cleanupRequested = true;
|
|
53440
53450
|
await Promise.race([
|
|
53441
|
-
new Promise((
|
|
53451
|
+
new Promise((resolve14) => {
|
|
53442
53452
|
if (this.activeOperations === 0) {
|
|
53443
|
-
|
|
53453
|
+
resolve14();
|
|
53444
53454
|
} else {
|
|
53445
|
-
this.cleanupResolvers.push(
|
|
53455
|
+
this.cleanupResolvers.push(resolve14);
|
|
53446
53456
|
}
|
|
53447
53457
|
}),
|
|
53448
|
-
new Promise((
|
|
53458
|
+
new Promise((resolve14) => {
|
|
53449
53459
|
setTimeout(() => {
|
|
53450
53460
|
logger.warn(
|
|
53451
53461
|
`[Workspace] Cleanup timeout after ${timeout}ms, proceeding anyway (${this.activeOperations} operations still active)`
|
|
53452
53462
|
);
|
|
53453
|
-
|
|
53463
|
+
resolve14();
|
|
53454
53464
|
}, timeout);
|
|
53455
53465
|
})
|
|
53456
53466
|
]);
|
|
@@ -53904,1264 +53914,6 @@ var init_build_engine_context = __esm({
|
|
|
53904
53914
|
}
|
|
53905
53915
|
});
|
|
53906
53916
|
|
|
53907
|
-
// src/policy/default-engine.ts
|
|
53908
|
-
var DefaultPolicyEngine;
|
|
53909
|
-
var init_default_engine = __esm({
|
|
53910
|
-
"src/policy/default-engine.ts"() {
|
|
53911
|
-
"use strict";
|
|
53912
|
-
DefaultPolicyEngine = class {
|
|
53913
|
-
async initialize(_config) {
|
|
53914
|
-
}
|
|
53915
|
-
async evaluateCheckExecution(_checkId, _checkConfig) {
|
|
53916
|
-
return { allowed: true };
|
|
53917
|
-
}
|
|
53918
|
-
async evaluateToolInvocation(_serverName, _methodName, _transport) {
|
|
53919
|
-
return { allowed: true };
|
|
53920
|
-
}
|
|
53921
|
-
async evaluateCapabilities(_checkId, _capabilities) {
|
|
53922
|
-
return { allowed: true };
|
|
53923
|
-
}
|
|
53924
|
-
async shutdown() {
|
|
53925
|
-
}
|
|
53926
|
-
};
|
|
53927
|
-
}
|
|
53928
|
-
});
|
|
53929
|
-
|
|
53930
|
-
// src/enterprise/license/validator.ts
|
|
53931
|
-
var validator_exports = {};
|
|
53932
|
-
__export(validator_exports, {
|
|
53933
|
-
LicenseValidator: () => LicenseValidator
|
|
53934
|
-
});
|
|
53935
|
-
var crypto2, fs21, path25, LicenseValidator;
|
|
53936
|
-
var init_validator = __esm({
|
|
53937
|
-
"src/enterprise/license/validator.ts"() {
|
|
53938
|
-
"use strict";
|
|
53939
|
-
crypto2 = __toESM(require("crypto"));
|
|
53940
|
-
fs21 = __toESM(require("fs"));
|
|
53941
|
-
path25 = __toESM(require("path"));
|
|
53942
|
-
LicenseValidator = class _LicenseValidator {
|
|
53943
|
-
/** Ed25519 public key for license verification (PEM format). */
|
|
53944
|
-
static PUBLIC_KEY = "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAI/Zd08EFmgIdrDm/HXd0l3/5GBt7R1PrdvhdmEXhJlU=\n-----END PUBLIC KEY-----\n";
|
|
53945
|
-
cache = null;
|
|
53946
|
-
static CACHE_TTL = 5 * 60 * 1e3;
|
|
53947
|
-
// 5 minutes
|
|
53948
|
-
static GRACE_PERIOD = 72 * 3600 * 1e3;
|
|
53949
|
-
// 72 hours after expiry
|
|
53950
|
-
/**
|
|
53951
|
-
* Load and validate license from environment or file.
|
|
53952
|
-
*
|
|
53953
|
-
* Resolution order:
|
|
53954
|
-
* 1. VISOR_LICENSE env var (JWT string)
|
|
53955
|
-
* 2. VISOR_LICENSE_FILE env var (path to file)
|
|
53956
|
-
* 3. .visor-license in project root (cwd)
|
|
53957
|
-
* 4. .visor-license in ~/.config/visor/
|
|
53958
|
-
*/
|
|
53959
|
-
async loadAndValidate() {
|
|
53960
|
-
if (this.cache && Date.now() - this.cache.validatedAt < _LicenseValidator.CACHE_TTL) {
|
|
53961
|
-
return this.cache.payload;
|
|
53962
|
-
}
|
|
53963
|
-
const token = this.resolveToken();
|
|
53964
|
-
if (!token) return null;
|
|
53965
|
-
const payload = this.verifyAndDecode(token);
|
|
53966
|
-
if (!payload) return null;
|
|
53967
|
-
this.cache = { payload, validatedAt: Date.now() };
|
|
53968
|
-
return payload;
|
|
53969
|
-
}
|
|
53970
|
-
/** Check if a specific feature is licensed */
|
|
53971
|
-
hasFeature(feature) {
|
|
53972
|
-
if (!this.cache) return false;
|
|
53973
|
-
return this.cache.payload.features.includes(feature);
|
|
53974
|
-
}
|
|
53975
|
-
/** Check if license is valid (with grace period) */
|
|
53976
|
-
isValid() {
|
|
53977
|
-
if (!this.cache) return false;
|
|
53978
|
-
const now = Date.now();
|
|
53979
|
-
const expiryMs = this.cache.payload.exp * 1e3;
|
|
53980
|
-
return now < expiryMs + _LicenseValidator.GRACE_PERIOD;
|
|
53981
|
-
}
|
|
53982
|
-
/** Check if the license is within its grace period (expired but still valid) */
|
|
53983
|
-
isInGracePeriod() {
|
|
53984
|
-
if (!this.cache) return false;
|
|
53985
|
-
const now = Date.now();
|
|
53986
|
-
const expiryMs = this.cache.payload.exp * 1e3;
|
|
53987
|
-
return now >= expiryMs && now < expiryMs + _LicenseValidator.GRACE_PERIOD;
|
|
53988
|
-
}
|
|
53989
|
-
resolveToken() {
|
|
53990
|
-
if (process.env.VISOR_LICENSE) {
|
|
53991
|
-
return process.env.VISOR_LICENSE.trim();
|
|
53992
|
-
}
|
|
53993
|
-
if (process.env.VISOR_LICENSE_FILE) {
|
|
53994
|
-
const resolved = path25.resolve(process.env.VISOR_LICENSE_FILE);
|
|
53995
|
-
const home2 = process.env.HOME || process.env.USERPROFILE || "";
|
|
53996
|
-
const allowedPrefixes = [path25.normalize(process.cwd())];
|
|
53997
|
-
if (home2) allowedPrefixes.push(path25.normalize(path25.join(home2, ".config", "visor")));
|
|
53998
|
-
let realPath;
|
|
53999
|
-
try {
|
|
54000
|
-
realPath = fs21.realpathSync(resolved);
|
|
54001
|
-
} catch {
|
|
54002
|
-
return null;
|
|
54003
|
-
}
|
|
54004
|
-
const isSafe = allowedPrefixes.some(
|
|
54005
|
-
(prefix) => realPath === prefix || realPath.startsWith(prefix + path25.sep)
|
|
54006
|
-
);
|
|
54007
|
-
if (!isSafe) return null;
|
|
54008
|
-
return this.readFile(realPath);
|
|
54009
|
-
}
|
|
54010
|
-
const cwdPath = path25.join(process.cwd(), ".visor-license");
|
|
54011
|
-
const cwdToken = this.readFile(cwdPath);
|
|
54012
|
-
if (cwdToken) return cwdToken;
|
|
54013
|
-
const home = process.env.HOME || process.env.USERPROFILE || "";
|
|
54014
|
-
if (home) {
|
|
54015
|
-
const configPath = path25.join(home, ".config", "visor", ".visor-license");
|
|
54016
|
-
const configToken = this.readFile(configPath);
|
|
54017
|
-
if (configToken) return configToken;
|
|
54018
|
-
}
|
|
54019
|
-
return null;
|
|
54020
|
-
}
|
|
54021
|
-
readFile(filePath) {
|
|
54022
|
-
try {
|
|
54023
|
-
return fs21.readFileSync(filePath, "utf-8").trim();
|
|
54024
|
-
} catch {
|
|
54025
|
-
return null;
|
|
54026
|
-
}
|
|
54027
|
-
}
|
|
54028
|
-
verifyAndDecode(token) {
|
|
54029
|
-
try {
|
|
54030
|
-
const parts = token.split(".");
|
|
54031
|
-
if (parts.length !== 3) return null;
|
|
54032
|
-
const [headerB64, payloadB64, signatureB64] = parts;
|
|
54033
|
-
const header = JSON.parse(Buffer.from(headerB64, "base64url").toString());
|
|
54034
|
-
if (header.alg !== "EdDSA") return null;
|
|
54035
|
-
const data = `${headerB64}.${payloadB64}`;
|
|
54036
|
-
const signature = Buffer.from(signatureB64, "base64url");
|
|
54037
|
-
const publicKey = crypto2.createPublicKey(_LicenseValidator.PUBLIC_KEY);
|
|
54038
|
-
if (publicKey.asymmetricKeyType !== "ed25519") {
|
|
54039
|
-
return null;
|
|
54040
|
-
}
|
|
54041
|
-
const isValid = crypto2.verify(null, Buffer.from(data), publicKey, signature);
|
|
54042
|
-
if (!isValid) return null;
|
|
54043
|
-
const payload = JSON.parse(Buffer.from(payloadB64, "base64url").toString());
|
|
54044
|
-
if (!payload.org || !Array.isArray(payload.features) || typeof payload.exp !== "number" || typeof payload.iat !== "number" || !payload.sub) {
|
|
54045
|
-
return null;
|
|
54046
|
-
}
|
|
54047
|
-
const now = Date.now();
|
|
54048
|
-
const expiryMs = payload.exp * 1e3;
|
|
54049
|
-
if (now >= expiryMs + _LicenseValidator.GRACE_PERIOD) {
|
|
54050
|
-
return null;
|
|
54051
|
-
}
|
|
54052
|
-
return payload;
|
|
54053
|
-
} catch {
|
|
54054
|
-
return null;
|
|
54055
|
-
}
|
|
54056
|
-
}
|
|
54057
|
-
};
|
|
54058
|
-
}
|
|
54059
|
-
});
|
|
54060
|
-
|
|
54061
|
-
// src/enterprise/policy/opa-compiler.ts
|
|
54062
|
-
var fs22, path26, os2, crypto3, import_child_process8, OpaCompiler;
|
|
54063
|
-
var init_opa_compiler = __esm({
|
|
54064
|
-
"src/enterprise/policy/opa-compiler.ts"() {
|
|
54065
|
-
"use strict";
|
|
54066
|
-
fs22 = __toESM(require("fs"));
|
|
54067
|
-
path26 = __toESM(require("path"));
|
|
54068
|
-
os2 = __toESM(require("os"));
|
|
54069
|
-
crypto3 = __toESM(require("crypto"));
|
|
54070
|
-
import_child_process8 = require("child_process");
|
|
54071
|
-
OpaCompiler = class _OpaCompiler {
|
|
54072
|
-
static CACHE_DIR = path26.join(os2.tmpdir(), "visor-opa-cache");
|
|
54073
|
-
/**
|
|
54074
|
-
* Resolve the input paths to WASM bytes.
|
|
54075
|
-
*
|
|
54076
|
-
* Strategy:
|
|
54077
|
-
* 1. If any path is a .wasm file, read it directly
|
|
54078
|
-
* 2. If a directory contains policy.wasm, read it
|
|
54079
|
-
* 3. Otherwise, collect all .rego files and auto-compile via `opa build`
|
|
54080
|
-
*/
|
|
54081
|
-
async resolveWasmBytes(paths) {
|
|
54082
|
-
const regoFiles = [];
|
|
54083
|
-
for (const p of paths) {
|
|
54084
|
-
const resolved = path26.resolve(p);
|
|
54085
|
-
if (path26.normalize(resolved).includes("..")) {
|
|
54086
|
-
throw new Error(`Policy path contains traversal sequences: ${p}`);
|
|
54087
|
-
}
|
|
54088
|
-
if (resolved.endsWith(".wasm") && fs22.existsSync(resolved)) {
|
|
54089
|
-
return fs22.readFileSync(resolved);
|
|
54090
|
-
}
|
|
54091
|
-
if (!fs22.existsSync(resolved)) continue;
|
|
54092
|
-
const stat2 = fs22.statSync(resolved);
|
|
54093
|
-
if (stat2.isDirectory()) {
|
|
54094
|
-
const wasmCandidate = path26.join(resolved, "policy.wasm");
|
|
54095
|
-
if (fs22.existsSync(wasmCandidate)) {
|
|
54096
|
-
return fs22.readFileSync(wasmCandidate);
|
|
54097
|
-
}
|
|
54098
|
-
const files = fs22.readdirSync(resolved);
|
|
54099
|
-
for (const f of files) {
|
|
54100
|
-
if (f.endsWith(".rego")) {
|
|
54101
|
-
regoFiles.push(path26.join(resolved, f));
|
|
54102
|
-
}
|
|
54103
|
-
}
|
|
54104
|
-
} else if (resolved.endsWith(".rego")) {
|
|
54105
|
-
regoFiles.push(resolved);
|
|
54106
|
-
}
|
|
54107
|
-
}
|
|
54108
|
-
if (regoFiles.length === 0) {
|
|
54109
|
-
throw new Error(
|
|
54110
|
-
`OPA WASM evaluator: no .wasm bundle or .rego files found in: ${paths.join(", ")}`
|
|
54111
|
-
);
|
|
54112
|
-
}
|
|
54113
|
-
return this.compileRego(regoFiles);
|
|
54114
|
-
}
|
|
54115
|
-
/**
|
|
54116
|
-
* Auto-compile .rego files to a WASM bundle using the `opa` CLI.
|
|
54117
|
-
*
|
|
54118
|
-
* Caches the compiled bundle based on a content hash of all input .rego files
|
|
54119
|
-
* so subsequent runs skip compilation if policies haven't changed.
|
|
54120
|
-
*/
|
|
54121
|
-
compileRego(regoFiles) {
|
|
54122
|
-
try {
|
|
54123
|
-
(0, import_child_process8.execFileSync)("opa", ["version"], { stdio: "pipe" });
|
|
54124
|
-
} catch {
|
|
54125
|
-
throw new Error(
|
|
54126
|
-
"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(" ")
|
|
54127
|
-
);
|
|
54128
|
-
}
|
|
54129
|
-
const hash = crypto3.createHash("sha256");
|
|
54130
|
-
for (const f of regoFiles.sort()) {
|
|
54131
|
-
hash.update(fs22.readFileSync(f));
|
|
54132
|
-
hash.update(f);
|
|
54133
|
-
}
|
|
54134
|
-
const cacheKey = hash.digest("hex").slice(0, 16);
|
|
54135
|
-
const cacheDir = _OpaCompiler.CACHE_DIR;
|
|
54136
|
-
const cachedWasm = path26.join(cacheDir, `${cacheKey}.wasm`);
|
|
54137
|
-
if (fs22.existsSync(cachedWasm)) {
|
|
54138
|
-
return fs22.readFileSync(cachedWasm);
|
|
54139
|
-
}
|
|
54140
|
-
fs22.mkdirSync(cacheDir, { recursive: true });
|
|
54141
|
-
const bundleTar = path26.join(cacheDir, `${cacheKey}-bundle.tar.gz`);
|
|
54142
|
-
try {
|
|
54143
|
-
const args = [
|
|
54144
|
-
"build",
|
|
54145
|
-
"-t",
|
|
54146
|
-
"wasm",
|
|
54147
|
-
"-e",
|
|
54148
|
-
"visor",
|
|
54149
|
-
// entrypoint: the visor package tree
|
|
54150
|
-
"-o",
|
|
54151
|
-
bundleTar,
|
|
54152
|
-
...regoFiles
|
|
54153
|
-
];
|
|
54154
|
-
(0, import_child_process8.execFileSync)("opa", args, {
|
|
54155
|
-
stdio: "pipe",
|
|
54156
|
-
timeout: 3e4
|
|
54157
|
-
});
|
|
54158
|
-
} catch (err) {
|
|
54159
|
-
const stderr = err?.stderr?.toString() || "";
|
|
54160
|
-
throw new Error(
|
|
54161
|
-
`Failed to compile .rego files to WASM:
|
|
54162
|
-
${stderr}
|
|
54163
|
-
Ensure your .rego files are valid and the \`opa\` CLI is installed.`
|
|
54164
|
-
);
|
|
54165
|
-
}
|
|
54166
|
-
try {
|
|
54167
|
-
(0, import_child_process8.execFileSync)("tar", ["-xzf", bundleTar, "-C", cacheDir, "/policy.wasm"], {
|
|
54168
|
-
stdio: "pipe"
|
|
54169
|
-
});
|
|
54170
|
-
const extractedWasm = path26.join(cacheDir, "policy.wasm");
|
|
54171
|
-
if (fs22.existsSync(extractedWasm)) {
|
|
54172
|
-
fs22.renameSync(extractedWasm, cachedWasm);
|
|
54173
|
-
}
|
|
54174
|
-
} catch {
|
|
54175
|
-
try {
|
|
54176
|
-
(0, import_child_process8.execFileSync)("tar", ["-xzf", bundleTar, "-C", cacheDir, "policy.wasm"], {
|
|
54177
|
-
stdio: "pipe"
|
|
54178
|
-
});
|
|
54179
|
-
const extractedWasm = path26.join(cacheDir, "policy.wasm");
|
|
54180
|
-
if (fs22.existsSync(extractedWasm)) {
|
|
54181
|
-
fs22.renameSync(extractedWasm, cachedWasm);
|
|
54182
|
-
}
|
|
54183
|
-
} catch (err2) {
|
|
54184
|
-
throw new Error(`Failed to extract policy.wasm from OPA bundle: ${err2?.message || err2}`);
|
|
54185
|
-
}
|
|
54186
|
-
}
|
|
54187
|
-
try {
|
|
54188
|
-
fs22.unlinkSync(bundleTar);
|
|
54189
|
-
} catch {
|
|
54190
|
-
}
|
|
54191
|
-
if (!fs22.existsSync(cachedWasm)) {
|
|
54192
|
-
throw new Error("OPA build succeeded but policy.wasm was not found in the bundle");
|
|
54193
|
-
}
|
|
54194
|
-
return fs22.readFileSync(cachedWasm);
|
|
54195
|
-
}
|
|
54196
|
-
};
|
|
54197
|
-
}
|
|
54198
|
-
});
|
|
54199
|
-
|
|
54200
|
-
// src/enterprise/policy/opa-wasm-evaluator.ts
|
|
54201
|
-
var fs23, path27, OpaWasmEvaluator;
|
|
54202
|
-
var init_opa_wasm_evaluator = __esm({
|
|
54203
|
-
"src/enterprise/policy/opa-wasm-evaluator.ts"() {
|
|
54204
|
-
"use strict";
|
|
54205
|
-
fs23 = __toESM(require("fs"));
|
|
54206
|
-
path27 = __toESM(require("path"));
|
|
54207
|
-
init_opa_compiler();
|
|
54208
|
-
OpaWasmEvaluator = class {
|
|
54209
|
-
policy = null;
|
|
54210
|
-
dataDocument = {};
|
|
54211
|
-
compiler = new OpaCompiler();
|
|
54212
|
-
async initialize(rulesPath) {
|
|
54213
|
-
const paths = Array.isArray(rulesPath) ? rulesPath : [rulesPath];
|
|
54214
|
-
const wasmBytes = await this.compiler.resolveWasmBytes(paths);
|
|
54215
|
-
try {
|
|
54216
|
-
const { createRequire } = require("module");
|
|
54217
|
-
const runtimeRequire = createRequire(__filename);
|
|
54218
|
-
const opaWasm = runtimeRequire("@open-policy-agent/opa-wasm");
|
|
54219
|
-
const loadPolicy = opaWasm.loadPolicy || opaWasm.default?.loadPolicy;
|
|
54220
|
-
if (!loadPolicy) {
|
|
54221
|
-
throw new Error("loadPolicy not found in @open-policy-agent/opa-wasm");
|
|
54222
|
-
}
|
|
54223
|
-
this.policy = await loadPolicy(wasmBytes);
|
|
54224
|
-
} catch (err) {
|
|
54225
|
-
if (err?.code === "MODULE_NOT_FOUND" || err?.code === "ERR_MODULE_NOT_FOUND") {
|
|
54226
|
-
throw new Error(
|
|
54227
|
-
"OPA WASM evaluator requires @open-policy-agent/opa-wasm. Install it with: npm install @open-policy-agent/opa-wasm"
|
|
54228
|
-
);
|
|
54229
|
-
}
|
|
54230
|
-
throw err;
|
|
54231
|
-
}
|
|
54232
|
-
}
|
|
54233
|
-
/**
|
|
54234
|
-
* Load external data from a JSON file to use as the OPA data document.
|
|
54235
|
-
* The loaded data will be passed to `policy.setData()` during evaluation,
|
|
54236
|
-
* making it available in Rego via `data.<key>`.
|
|
54237
|
-
*/
|
|
54238
|
-
loadData(dataPath) {
|
|
54239
|
-
const resolved = path27.resolve(dataPath);
|
|
54240
|
-
if (path27.normalize(resolved).includes("..")) {
|
|
54241
|
-
throw new Error(`Data path contains traversal sequences: ${dataPath}`);
|
|
54242
|
-
}
|
|
54243
|
-
if (!fs23.existsSync(resolved)) {
|
|
54244
|
-
throw new Error(`OPA data file not found: ${resolved}`);
|
|
54245
|
-
}
|
|
54246
|
-
const stat2 = fs23.statSync(resolved);
|
|
54247
|
-
if (stat2.size > 10 * 1024 * 1024) {
|
|
54248
|
-
throw new Error(`OPA data file exceeds 10MB limit: ${resolved} (${stat2.size} bytes)`);
|
|
54249
|
-
}
|
|
54250
|
-
const raw = fs23.readFileSync(resolved, "utf-8");
|
|
54251
|
-
try {
|
|
54252
|
-
const parsed = JSON.parse(raw);
|
|
54253
|
-
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
54254
|
-
throw new Error("OPA data file must contain a JSON object (not an array or primitive)");
|
|
54255
|
-
}
|
|
54256
|
-
this.dataDocument = parsed;
|
|
54257
|
-
} catch (err) {
|
|
54258
|
-
if (err.message.startsWith("OPA data file must")) {
|
|
54259
|
-
throw err;
|
|
54260
|
-
}
|
|
54261
|
-
throw new Error(`Failed to parse OPA data file ${resolved}: ${err.message}`);
|
|
54262
|
-
}
|
|
54263
|
-
}
|
|
54264
|
-
async evaluate(input) {
|
|
54265
|
-
if (!this.policy) {
|
|
54266
|
-
throw new Error("OPA WASM evaluator not initialized");
|
|
54267
|
-
}
|
|
54268
|
-
this.policy.setData(this.dataDocument);
|
|
54269
|
-
const resultSet = this.policy.evaluate(input);
|
|
54270
|
-
if (Array.isArray(resultSet) && resultSet.length > 0) {
|
|
54271
|
-
return resultSet[0].result;
|
|
54272
|
-
}
|
|
54273
|
-
return void 0;
|
|
54274
|
-
}
|
|
54275
|
-
async shutdown() {
|
|
54276
|
-
if (this.policy) {
|
|
54277
|
-
if (typeof this.policy.close === "function") {
|
|
54278
|
-
try {
|
|
54279
|
-
this.policy.close();
|
|
54280
|
-
} catch {
|
|
54281
|
-
}
|
|
54282
|
-
} else if (typeof this.policy.free === "function") {
|
|
54283
|
-
try {
|
|
54284
|
-
this.policy.free();
|
|
54285
|
-
} catch {
|
|
54286
|
-
}
|
|
54287
|
-
}
|
|
54288
|
-
}
|
|
54289
|
-
this.policy = null;
|
|
54290
|
-
}
|
|
54291
|
-
};
|
|
54292
|
-
}
|
|
54293
|
-
});
|
|
54294
|
-
|
|
54295
|
-
// src/enterprise/policy/opa-http-evaluator.ts
|
|
54296
|
-
var OpaHttpEvaluator;
|
|
54297
|
-
var init_opa_http_evaluator = __esm({
|
|
54298
|
-
"src/enterprise/policy/opa-http-evaluator.ts"() {
|
|
54299
|
-
"use strict";
|
|
54300
|
-
OpaHttpEvaluator = class {
|
|
54301
|
-
baseUrl;
|
|
54302
|
-
timeout;
|
|
54303
|
-
constructor(baseUrl, timeout = 5e3) {
|
|
54304
|
-
let parsed;
|
|
54305
|
-
try {
|
|
54306
|
-
parsed = new URL(baseUrl);
|
|
54307
|
-
} catch {
|
|
54308
|
-
throw new Error(`OPA HTTP evaluator: invalid URL: ${baseUrl}`);
|
|
54309
|
-
}
|
|
54310
|
-
if (!["http:", "https:"].includes(parsed.protocol)) {
|
|
54311
|
-
throw new Error(
|
|
54312
|
-
`OPA HTTP evaluator: url must use http:// or https:// protocol, got: ${baseUrl}`
|
|
54313
|
-
);
|
|
54314
|
-
}
|
|
54315
|
-
const hostname = parsed.hostname;
|
|
54316
|
-
if (this.isBlockedHostname(hostname)) {
|
|
54317
|
-
throw new Error(
|
|
54318
|
-
`OPA HTTP evaluator: url must not point to internal, loopback, or private network addresses`
|
|
54319
|
-
);
|
|
54320
|
-
}
|
|
54321
|
-
this.baseUrl = baseUrl.replace(/\/+$/, "");
|
|
54322
|
-
this.timeout = timeout;
|
|
54323
|
-
}
|
|
54324
|
-
/**
|
|
54325
|
-
* Check if a hostname is blocked due to SSRF concerns.
|
|
54326
|
-
*
|
|
54327
|
-
* Blocks:
|
|
54328
|
-
* - Loopback addresses (127.x.x.x, localhost, 0.0.0.0, ::1)
|
|
54329
|
-
* - Link-local addresses (169.254.x.x)
|
|
54330
|
-
* - Private networks (10.x.x.x, 172.16-31.x.x, 192.168.x.x)
|
|
54331
|
-
* - IPv6 unique local addresses (fd00::/8)
|
|
54332
|
-
* - Cloud metadata services (*.internal)
|
|
54333
|
-
*/
|
|
54334
|
-
isBlockedHostname(hostname) {
|
|
54335
|
-
if (!hostname) return true;
|
|
54336
|
-
const normalized = hostname.toLowerCase().replace(/^\[|\]$/g, "");
|
|
54337
|
-
if (normalized === "metadata.google.internal" || normalized.endsWith(".internal")) {
|
|
54338
|
-
return true;
|
|
54339
|
-
}
|
|
54340
|
-
if (normalized === "localhost" || normalized === "localhost.localdomain") {
|
|
54341
|
-
return true;
|
|
54342
|
-
}
|
|
54343
|
-
if (normalized === "::1" || normalized === "0:0:0:0:0:0:0:1") {
|
|
54344
|
-
return true;
|
|
54345
|
-
}
|
|
54346
|
-
const ipv4Pattern = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/;
|
|
54347
|
-
const ipv4Match = normalized.match(ipv4Pattern);
|
|
54348
|
-
if (ipv4Match) {
|
|
54349
|
-
const octets = ipv4Match.slice(1, 5).map(Number);
|
|
54350
|
-
if (octets.some((octet) => octet > 255)) {
|
|
54351
|
-
return false;
|
|
54352
|
-
}
|
|
54353
|
-
const [a, b] = octets;
|
|
54354
|
-
if (a === 127) {
|
|
54355
|
-
return true;
|
|
54356
|
-
}
|
|
54357
|
-
if (a === 0) {
|
|
54358
|
-
return true;
|
|
54359
|
-
}
|
|
54360
|
-
if (a === 169 && b === 254) {
|
|
54361
|
-
return true;
|
|
54362
|
-
}
|
|
54363
|
-
if (a === 10) {
|
|
54364
|
-
return true;
|
|
54365
|
-
}
|
|
54366
|
-
if (a === 172 && b >= 16 && b <= 31) {
|
|
54367
|
-
return true;
|
|
54368
|
-
}
|
|
54369
|
-
if (a === 192 && b === 168) {
|
|
54370
|
-
return true;
|
|
54371
|
-
}
|
|
54372
|
-
}
|
|
54373
|
-
if (normalized.startsWith("fd") || normalized.startsWith("fc")) {
|
|
54374
|
-
return true;
|
|
54375
|
-
}
|
|
54376
|
-
if (normalized.startsWith("fe80:")) {
|
|
54377
|
-
return true;
|
|
54378
|
-
}
|
|
54379
|
-
return false;
|
|
54380
|
-
}
|
|
54381
|
-
/**
|
|
54382
|
-
* Evaluate a policy rule against an input document via OPA REST API.
|
|
54383
|
-
*
|
|
54384
|
-
* @param input - The input document to evaluate
|
|
54385
|
-
* @param rulePath - OPA rule path (e.g., 'visor/check/execute')
|
|
54386
|
-
* @returns The result object from OPA, or undefined on error
|
|
54387
|
-
*/
|
|
54388
|
-
async evaluate(input, rulePath) {
|
|
54389
|
-
const encodedPath = rulePath.split("/").map((s) => encodeURIComponent(s)).join("/");
|
|
54390
|
-
const url = `${this.baseUrl}/v1/data/${encodedPath}`;
|
|
54391
|
-
const controller = new AbortController();
|
|
54392
|
-
const timer = setTimeout(() => controller.abort(), this.timeout);
|
|
54393
|
-
try {
|
|
54394
|
-
const response = await fetch(url, {
|
|
54395
|
-
method: "POST",
|
|
54396
|
-
headers: { "Content-Type": "application/json" },
|
|
54397
|
-
body: JSON.stringify({ input }),
|
|
54398
|
-
signal: controller.signal
|
|
54399
|
-
});
|
|
54400
|
-
if (!response.ok) {
|
|
54401
|
-
throw new Error(`OPA HTTP ${response.status}: ${response.statusText}`);
|
|
54402
|
-
}
|
|
54403
|
-
let body;
|
|
54404
|
-
try {
|
|
54405
|
-
body = await response.json();
|
|
54406
|
-
} catch (jsonErr) {
|
|
54407
|
-
throw new Error(
|
|
54408
|
-
`OPA HTTP evaluator: failed to parse JSON response: ${jsonErr instanceof Error ? jsonErr.message : String(jsonErr)}`
|
|
54409
|
-
);
|
|
54410
|
-
}
|
|
54411
|
-
return body?.result;
|
|
54412
|
-
} finally {
|
|
54413
|
-
clearTimeout(timer);
|
|
54414
|
-
}
|
|
54415
|
-
}
|
|
54416
|
-
async shutdown() {
|
|
54417
|
-
}
|
|
54418
|
-
};
|
|
54419
|
-
}
|
|
54420
|
-
});
|
|
54421
|
-
|
|
54422
|
-
// src/enterprise/policy/policy-input-builder.ts
|
|
54423
|
-
var PolicyInputBuilder;
|
|
54424
|
-
var init_policy_input_builder = __esm({
|
|
54425
|
-
"src/enterprise/policy/policy-input-builder.ts"() {
|
|
54426
|
-
"use strict";
|
|
54427
|
-
PolicyInputBuilder = class {
|
|
54428
|
-
roles;
|
|
54429
|
-
actor;
|
|
54430
|
-
repository;
|
|
54431
|
-
pullRequest;
|
|
54432
|
-
constructor(policyConfig, actor, repository, pullRequest) {
|
|
54433
|
-
this.roles = policyConfig.roles || {};
|
|
54434
|
-
this.actor = actor;
|
|
54435
|
-
this.repository = repository;
|
|
54436
|
-
this.pullRequest = pullRequest;
|
|
54437
|
-
}
|
|
54438
|
-
/** Resolve which roles apply to the current actor. */
|
|
54439
|
-
resolveRoles() {
|
|
54440
|
-
const matched = [];
|
|
54441
|
-
for (const [roleName, roleConfig] of Object.entries(this.roles)) {
|
|
54442
|
-
let identityMatch = false;
|
|
54443
|
-
if (roleConfig.author_association && this.actor.authorAssociation && roleConfig.author_association.includes(this.actor.authorAssociation)) {
|
|
54444
|
-
identityMatch = true;
|
|
54445
|
-
}
|
|
54446
|
-
if (!identityMatch && roleConfig.users && this.actor.login && roleConfig.users.includes(this.actor.login)) {
|
|
54447
|
-
identityMatch = true;
|
|
54448
|
-
}
|
|
54449
|
-
if (!identityMatch && roleConfig.slack_users && this.actor.slack?.userId && roleConfig.slack_users.includes(this.actor.slack.userId)) {
|
|
54450
|
-
identityMatch = true;
|
|
54451
|
-
}
|
|
54452
|
-
if (!identityMatch && roleConfig.emails && this.actor.slack?.email) {
|
|
54453
|
-
const actorEmail = this.actor.slack.email.toLowerCase();
|
|
54454
|
-
if (roleConfig.emails.some((e) => e.toLowerCase() === actorEmail)) {
|
|
54455
|
-
identityMatch = true;
|
|
54456
|
-
}
|
|
54457
|
-
}
|
|
54458
|
-
if (!identityMatch) continue;
|
|
54459
|
-
if (roleConfig.slack_channels && roleConfig.slack_channels.length > 0) {
|
|
54460
|
-
if (!this.actor.slack?.channelId || !roleConfig.slack_channels.includes(this.actor.slack.channelId)) {
|
|
54461
|
-
continue;
|
|
54462
|
-
}
|
|
54463
|
-
}
|
|
54464
|
-
matched.push(roleName);
|
|
54465
|
-
}
|
|
54466
|
-
return matched;
|
|
54467
|
-
}
|
|
54468
|
-
buildActor() {
|
|
54469
|
-
return {
|
|
54470
|
-
authorAssociation: this.actor.authorAssociation,
|
|
54471
|
-
login: this.actor.login,
|
|
54472
|
-
roles: this.resolveRoles(),
|
|
54473
|
-
isLocalMode: this.actor.isLocalMode,
|
|
54474
|
-
...this.actor.slack && { slack: this.actor.slack }
|
|
54475
|
-
};
|
|
54476
|
-
}
|
|
54477
|
-
forCheckExecution(check) {
|
|
54478
|
-
return {
|
|
54479
|
-
scope: "check.execute",
|
|
54480
|
-
check: {
|
|
54481
|
-
id: check.id,
|
|
54482
|
-
type: check.type,
|
|
54483
|
-
group: check.group,
|
|
54484
|
-
tags: check.tags,
|
|
54485
|
-
criticality: check.criticality,
|
|
54486
|
-
sandbox: check.sandbox,
|
|
54487
|
-
policy: check.policy
|
|
54488
|
-
},
|
|
54489
|
-
actor: this.buildActor(),
|
|
54490
|
-
repository: this.repository,
|
|
54491
|
-
pullRequest: this.pullRequest
|
|
54492
|
-
};
|
|
54493
|
-
}
|
|
54494
|
-
forToolInvocation(serverName, methodName, transport) {
|
|
54495
|
-
return {
|
|
54496
|
-
scope: "tool.invoke",
|
|
54497
|
-
tool: { serverName, methodName, transport },
|
|
54498
|
-
actor: this.buildActor(),
|
|
54499
|
-
repository: this.repository,
|
|
54500
|
-
pullRequest: this.pullRequest
|
|
54501
|
-
};
|
|
54502
|
-
}
|
|
54503
|
-
forCapabilityResolve(checkId, capabilities) {
|
|
54504
|
-
return {
|
|
54505
|
-
scope: "capability.resolve",
|
|
54506
|
-
check: { id: checkId, type: "ai" },
|
|
54507
|
-
capability: capabilities,
|
|
54508
|
-
actor: this.buildActor(),
|
|
54509
|
-
repository: this.repository,
|
|
54510
|
-
pullRequest: this.pullRequest
|
|
54511
|
-
};
|
|
54512
|
-
}
|
|
54513
|
-
};
|
|
54514
|
-
}
|
|
54515
|
-
});
|
|
54516
|
-
|
|
54517
|
-
// src/enterprise/policy/opa-policy-engine.ts
|
|
54518
|
-
var opa_policy_engine_exports = {};
|
|
54519
|
-
__export(opa_policy_engine_exports, {
|
|
54520
|
-
OpaPolicyEngine: () => OpaPolicyEngine
|
|
54521
|
-
});
|
|
54522
|
-
var OpaPolicyEngine;
|
|
54523
|
-
var init_opa_policy_engine = __esm({
|
|
54524
|
-
"src/enterprise/policy/opa-policy-engine.ts"() {
|
|
54525
|
-
"use strict";
|
|
54526
|
-
init_opa_wasm_evaluator();
|
|
54527
|
-
init_opa_http_evaluator();
|
|
54528
|
-
init_policy_input_builder();
|
|
54529
|
-
OpaPolicyEngine = class {
|
|
54530
|
-
evaluator = null;
|
|
54531
|
-
fallback;
|
|
54532
|
-
timeout;
|
|
54533
|
-
config;
|
|
54534
|
-
inputBuilder = null;
|
|
54535
|
-
logger = null;
|
|
54536
|
-
constructor(config) {
|
|
54537
|
-
this.config = config;
|
|
54538
|
-
this.fallback = config.fallback || "deny";
|
|
54539
|
-
this.timeout = config.timeout || 5e3;
|
|
54540
|
-
}
|
|
54541
|
-
async initialize(config) {
|
|
54542
|
-
try {
|
|
54543
|
-
this.logger = (init_logger(), __toCommonJS(logger_exports)).logger;
|
|
54544
|
-
} catch {
|
|
54545
|
-
}
|
|
54546
|
-
const actor = {
|
|
54547
|
-
authorAssociation: process.env.VISOR_AUTHOR_ASSOCIATION,
|
|
54548
|
-
login: process.env.VISOR_AUTHOR_LOGIN || process.env.GITHUB_ACTOR,
|
|
54549
|
-
isLocalMode: !process.env.GITHUB_ACTIONS
|
|
54550
|
-
};
|
|
54551
|
-
const repo = {
|
|
54552
|
-
owner: process.env.GITHUB_REPOSITORY_OWNER,
|
|
54553
|
-
name: process.env.GITHUB_REPOSITORY?.split("/")[1],
|
|
54554
|
-
branch: process.env.GITHUB_HEAD_REF,
|
|
54555
|
-
baseBranch: process.env.GITHUB_BASE_REF,
|
|
54556
|
-
event: process.env.GITHUB_EVENT_NAME
|
|
54557
|
-
};
|
|
54558
|
-
const prNum = process.env.GITHUB_PR_NUMBER ? parseInt(process.env.GITHUB_PR_NUMBER, 10) : void 0;
|
|
54559
|
-
const pullRequest = {
|
|
54560
|
-
number: prNum !== void 0 && Number.isFinite(prNum) ? prNum : void 0
|
|
54561
|
-
};
|
|
54562
|
-
this.inputBuilder = new PolicyInputBuilder(config, actor, repo, pullRequest);
|
|
54563
|
-
if (config.engine === "local") {
|
|
54564
|
-
if (!config.rules) {
|
|
54565
|
-
throw new Error("OPA local mode requires `policy.rules` path to .wasm or .rego files");
|
|
54566
|
-
}
|
|
54567
|
-
const wasm = new OpaWasmEvaluator();
|
|
54568
|
-
await wasm.initialize(config.rules);
|
|
54569
|
-
if (config.data) {
|
|
54570
|
-
wasm.loadData(config.data);
|
|
54571
|
-
}
|
|
54572
|
-
this.evaluator = wasm;
|
|
54573
|
-
} else if (config.engine === "remote") {
|
|
54574
|
-
if (!config.url) {
|
|
54575
|
-
throw new Error("OPA remote mode requires `policy.url` pointing to OPA server");
|
|
54576
|
-
}
|
|
54577
|
-
this.evaluator = new OpaHttpEvaluator(config.url, this.timeout);
|
|
54578
|
-
} else {
|
|
54579
|
-
this.evaluator = null;
|
|
54580
|
-
}
|
|
54581
|
-
}
|
|
54582
|
-
/**
|
|
54583
|
-
* Update actor/repo/PR context (e.g., after PR info becomes available).
|
|
54584
|
-
* Called by the enterprise loader when engine context is enriched.
|
|
54585
|
-
*/
|
|
54586
|
-
setActorContext(actor, repo, pullRequest) {
|
|
54587
|
-
this.inputBuilder = new PolicyInputBuilder(this.config, actor, repo, pullRequest);
|
|
54588
|
-
}
|
|
54589
|
-
async evaluateCheckExecution(checkId, checkConfig) {
|
|
54590
|
-
if (!this.evaluator || !this.inputBuilder) return { allowed: true };
|
|
54591
|
-
const cfg = checkConfig && typeof checkConfig === "object" ? checkConfig : {};
|
|
54592
|
-
const policyOverride = cfg.policy;
|
|
54593
|
-
const input = this.inputBuilder.forCheckExecution({
|
|
54594
|
-
id: checkId,
|
|
54595
|
-
type: cfg.type || "ai",
|
|
54596
|
-
group: cfg.group,
|
|
54597
|
-
tags: cfg.tags,
|
|
54598
|
-
criticality: cfg.criticality,
|
|
54599
|
-
sandbox: cfg.sandbox,
|
|
54600
|
-
policy: policyOverride
|
|
54601
|
-
});
|
|
54602
|
-
return this.doEvaluate(input, this.resolveRulePath("check.execute", policyOverride?.rule));
|
|
54603
|
-
}
|
|
54604
|
-
async evaluateToolInvocation(serverName, methodName, transport) {
|
|
54605
|
-
if (!this.evaluator || !this.inputBuilder) return { allowed: true };
|
|
54606
|
-
const input = this.inputBuilder.forToolInvocation(serverName, methodName, transport);
|
|
54607
|
-
return this.doEvaluate(input, "visor/tool/invoke");
|
|
54608
|
-
}
|
|
54609
|
-
async evaluateCapabilities(checkId, capabilities) {
|
|
54610
|
-
if (!this.evaluator || !this.inputBuilder) return { allowed: true };
|
|
54611
|
-
const input = this.inputBuilder.forCapabilityResolve(checkId, capabilities);
|
|
54612
|
-
return this.doEvaluate(input, "visor/capability/resolve");
|
|
54613
|
-
}
|
|
54614
|
-
async shutdown() {
|
|
54615
|
-
if (this.evaluator && "shutdown" in this.evaluator) {
|
|
54616
|
-
await this.evaluator.shutdown();
|
|
54617
|
-
}
|
|
54618
|
-
this.evaluator = null;
|
|
54619
|
-
this.inputBuilder = null;
|
|
54620
|
-
}
|
|
54621
|
-
resolveRulePath(defaultScope, override) {
|
|
54622
|
-
if (override) {
|
|
54623
|
-
return override.startsWith("visor/") ? override : `visor/${override}`;
|
|
54624
|
-
}
|
|
54625
|
-
return `visor/${defaultScope.replace(/\./g, "/")}`;
|
|
54626
|
-
}
|
|
54627
|
-
async doEvaluate(input, rulePath) {
|
|
54628
|
-
try {
|
|
54629
|
-
this.logger?.debug(`[PolicyEngine] Evaluating ${rulePath}`, JSON.stringify(input));
|
|
54630
|
-
let timer;
|
|
54631
|
-
const timeoutPromise = new Promise((_resolve, reject) => {
|
|
54632
|
-
timer = setTimeout(() => reject(new Error("policy evaluation timeout")), this.timeout);
|
|
54633
|
-
});
|
|
54634
|
-
try {
|
|
54635
|
-
const result = await Promise.race([this.rawEvaluate(input, rulePath), timeoutPromise]);
|
|
54636
|
-
const decision = this.parseDecision(result);
|
|
54637
|
-
if (!decision.allowed && this.fallback === "warn") {
|
|
54638
|
-
decision.allowed = true;
|
|
54639
|
-
decision.warn = true;
|
|
54640
|
-
decision.reason = `audit: ${decision.reason || "policy denied"}`;
|
|
54641
|
-
}
|
|
54642
|
-
this.logger?.debug(
|
|
54643
|
-
`[PolicyEngine] Decision for ${rulePath}: allowed=${decision.allowed}, warn=${decision.warn || false}, reason=${decision.reason || "none"}`
|
|
54644
|
-
);
|
|
54645
|
-
return decision;
|
|
54646
|
-
} finally {
|
|
54647
|
-
if (timer) clearTimeout(timer);
|
|
54648
|
-
}
|
|
54649
|
-
} catch (err) {
|
|
54650
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
54651
|
-
this.logger?.warn(`[PolicyEngine] Evaluation failed for ${rulePath}: ${msg}`);
|
|
54652
|
-
return {
|
|
54653
|
-
allowed: this.fallback === "allow" || this.fallback === "warn",
|
|
54654
|
-
warn: this.fallback === "warn" ? true : void 0,
|
|
54655
|
-
reason: `policy evaluation failed, fallback=${this.fallback}`
|
|
54656
|
-
};
|
|
54657
|
-
}
|
|
54658
|
-
}
|
|
54659
|
-
async rawEvaluate(input, rulePath) {
|
|
54660
|
-
if (this.evaluator instanceof OpaWasmEvaluator) {
|
|
54661
|
-
const result = await this.evaluator.evaluate(input);
|
|
54662
|
-
return this.navigateWasmResult(result, rulePath);
|
|
54663
|
-
}
|
|
54664
|
-
return this.evaluator.evaluate(input, rulePath);
|
|
54665
|
-
}
|
|
54666
|
-
/**
|
|
54667
|
-
* Navigate nested OPA WASM result tree to reach the specific rule's output.
|
|
54668
|
-
* The WASM entrypoint `-e visor` means the result root IS the visor package,
|
|
54669
|
-
* so we strip the `visor/` prefix and walk the remaining segments.
|
|
54670
|
-
*/
|
|
54671
|
-
navigateWasmResult(result, rulePath) {
|
|
54672
|
-
if (!result || typeof result !== "object") return result;
|
|
54673
|
-
const segments = rulePath.replace(/^visor\//, "").split("/");
|
|
54674
|
-
let current = result;
|
|
54675
|
-
for (const seg of segments) {
|
|
54676
|
-
if (current && typeof current === "object" && seg in current) {
|
|
54677
|
-
current = current[seg];
|
|
54678
|
-
} else {
|
|
54679
|
-
return void 0;
|
|
54680
|
-
}
|
|
54681
|
-
}
|
|
54682
|
-
return current;
|
|
54683
|
-
}
|
|
54684
|
-
parseDecision(result) {
|
|
54685
|
-
if (result === void 0 || result === null) {
|
|
54686
|
-
return {
|
|
54687
|
-
allowed: this.fallback === "allow" || this.fallback === "warn",
|
|
54688
|
-
warn: this.fallback === "warn" ? true : void 0,
|
|
54689
|
-
reason: this.fallback === "warn" ? "audit: no policy result" : "no policy result"
|
|
54690
|
-
};
|
|
54691
|
-
}
|
|
54692
|
-
const allowed = result.allowed !== false;
|
|
54693
|
-
const decision = {
|
|
54694
|
-
allowed,
|
|
54695
|
-
reason: result.reason
|
|
54696
|
-
};
|
|
54697
|
-
if (result.capabilities) {
|
|
54698
|
-
decision.capabilities = result.capabilities;
|
|
54699
|
-
}
|
|
54700
|
-
return decision;
|
|
54701
|
-
}
|
|
54702
|
-
};
|
|
54703
|
-
}
|
|
54704
|
-
});
|
|
54705
|
-
|
|
54706
|
-
// src/enterprise/scheduler/knex-store.ts
|
|
54707
|
-
var knex_store_exports = {};
|
|
54708
|
-
__export(knex_store_exports, {
|
|
54709
|
-
KnexStoreBackend: () => KnexStoreBackend
|
|
54710
|
-
});
|
|
54711
|
-
function toNum(val) {
|
|
54712
|
-
if (val === null || val === void 0) return void 0;
|
|
54713
|
-
return typeof val === "string" ? parseInt(val, 10) : val;
|
|
54714
|
-
}
|
|
54715
|
-
function safeJsonParse2(value) {
|
|
54716
|
-
if (!value) return void 0;
|
|
54717
|
-
try {
|
|
54718
|
-
return JSON.parse(value);
|
|
54719
|
-
} catch {
|
|
54720
|
-
return void 0;
|
|
54721
|
-
}
|
|
54722
|
-
}
|
|
54723
|
-
function fromDbRow2(row) {
|
|
54724
|
-
return {
|
|
54725
|
-
id: row.id,
|
|
54726
|
-
creatorId: row.creator_id,
|
|
54727
|
-
creatorContext: row.creator_context ?? void 0,
|
|
54728
|
-
creatorName: row.creator_name ?? void 0,
|
|
54729
|
-
timezone: row.timezone,
|
|
54730
|
-
schedule: row.schedule_expr,
|
|
54731
|
-
runAt: toNum(row.run_at),
|
|
54732
|
-
isRecurring: row.is_recurring === true || row.is_recurring === 1,
|
|
54733
|
-
originalExpression: row.original_expression,
|
|
54734
|
-
workflow: row.workflow ?? void 0,
|
|
54735
|
-
workflowInputs: safeJsonParse2(row.workflow_inputs),
|
|
54736
|
-
outputContext: safeJsonParse2(row.output_context),
|
|
54737
|
-
status: row.status,
|
|
54738
|
-
createdAt: toNum(row.created_at),
|
|
54739
|
-
lastRunAt: toNum(row.last_run_at),
|
|
54740
|
-
nextRunAt: toNum(row.next_run_at),
|
|
54741
|
-
runCount: row.run_count,
|
|
54742
|
-
failureCount: row.failure_count,
|
|
54743
|
-
lastError: row.last_error ?? void 0,
|
|
54744
|
-
previousResponse: row.previous_response ?? void 0
|
|
54745
|
-
};
|
|
54746
|
-
}
|
|
54747
|
-
function toInsertRow(schedule) {
|
|
54748
|
-
return {
|
|
54749
|
-
id: schedule.id,
|
|
54750
|
-
creator_id: schedule.creatorId,
|
|
54751
|
-
creator_context: schedule.creatorContext ?? null,
|
|
54752
|
-
creator_name: schedule.creatorName ?? null,
|
|
54753
|
-
timezone: schedule.timezone,
|
|
54754
|
-
schedule_expr: schedule.schedule,
|
|
54755
|
-
run_at: schedule.runAt ?? null,
|
|
54756
|
-
is_recurring: schedule.isRecurring,
|
|
54757
|
-
original_expression: schedule.originalExpression,
|
|
54758
|
-
workflow: schedule.workflow ?? null,
|
|
54759
|
-
workflow_inputs: schedule.workflowInputs ? JSON.stringify(schedule.workflowInputs) : null,
|
|
54760
|
-
output_context: schedule.outputContext ? JSON.stringify(schedule.outputContext) : null,
|
|
54761
|
-
status: schedule.status,
|
|
54762
|
-
created_at: schedule.createdAt,
|
|
54763
|
-
last_run_at: schedule.lastRunAt ?? null,
|
|
54764
|
-
next_run_at: schedule.nextRunAt ?? null,
|
|
54765
|
-
run_count: schedule.runCount,
|
|
54766
|
-
failure_count: schedule.failureCount,
|
|
54767
|
-
last_error: schedule.lastError ?? null,
|
|
54768
|
-
previous_response: schedule.previousResponse ?? null
|
|
54769
|
-
};
|
|
54770
|
-
}
|
|
54771
|
-
var fs24, path28, import_uuid2, KnexStoreBackend;
|
|
54772
|
-
var init_knex_store = __esm({
|
|
54773
|
-
"src/enterprise/scheduler/knex-store.ts"() {
|
|
54774
|
-
"use strict";
|
|
54775
|
-
fs24 = __toESM(require("fs"));
|
|
54776
|
-
path28 = __toESM(require("path"));
|
|
54777
|
-
import_uuid2 = require("uuid");
|
|
54778
|
-
init_logger();
|
|
54779
|
-
KnexStoreBackend = class {
|
|
54780
|
-
knex = null;
|
|
54781
|
-
driver;
|
|
54782
|
-
connection;
|
|
54783
|
-
constructor(driver, storageConfig, _haConfig) {
|
|
54784
|
-
this.driver = driver;
|
|
54785
|
-
this.connection = storageConfig.connection || {};
|
|
54786
|
-
}
|
|
54787
|
-
async initialize() {
|
|
54788
|
-
const { createRequire } = require("module");
|
|
54789
|
-
const runtimeRequire = createRequire(__filename);
|
|
54790
|
-
let knexFactory;
|
|
54791
|
-
try {
|
|
54792
|
-
knexFactory = runtimeRequire("knex");
|
|
54793
|
-
} catch (err) {
|
|
54794
|
-
const code = err?.code;
|
|
54795
|
-
if (code === "MODULE_NOT_FOUND" || code === "ERR_MODULE_NOT_FOUND") {
|
|
54796
|
-
throw new Error(
|
|
54797
|
-
"knex is required for PostgreSQL/MySQL/MSSQL schedule storage. Install it with: npm install knex"
|
|
54798
|
-
);
|
|
54799
|
-
}
|
|
54800
|
-
throw err;
|
|
54801
|
-
}
|
|
54802
|
-
const clientMap = {
|
|
54803
|
-
postgresql: "pg",
|
|
54804
|
-
mysql: "mysql2",
|
|
54805
|
-
mssql: "tedious"
|
|
54806
|
-
};
|
|
54807
|
-
const client = clientMap[this.driver];
|
|
54808
|
-
let connection;
|
|
54809
|
-
if (this.connection.connection_string) {
|
|
54810
|
-
connection = this.connection.connection_string;
|
|
54811
|
-
} else if (this.driver === "mssql") {
|
|
54812
|
-
connection = this.buildMssqlConnection();
|
|
54813
|
-
} else {
|
|
54814
|
-
connection = this.buildStandardConnection();
|
|
54815
|
-
}
|
|
54816
|
-
this.knex = knexFactory({
|
|
54817
|
-
client,
|
|
54818
|
-
connection,
|
|
54819
|
-
pool: {
|
|
54820
|
-
min: this.connection.pool?.min ?? 0,
|
|
54821
|
-
max: this.connection.pool?.max ?? 10
|
|
54822
|
-
}
|
|
54823
|
-
});
|
|
54824
|
-
await this.migrateSchema();
|
|
54825
|
-
logger.info(`[KnexStore] Initialized (${this.driver})`);
|
|
54826
|
-
}
|
|
54827
|
-
buildStandardConnection() {
|
|
54828
|
-
return {
|
|
54829
|
-
host: this.connection.host || "localhost",
|
|
54830
|
-
port: this.connection.port,
|
|
54831
|
-
database: this.connection.database || "visor",
|
|
54832
|
-
user: this.connection.user,
|
|
54833
|
-
password: this.connection.password,
|
|
54834
|
-
ssl: this.resolveSslConfig()
|
|
54835
|
-
};
|
|
54836
|
-
}
|
|
54837
|
-
buildMssqlConnection() {
|
|
54838
|
-
const ssl = this.connection.ssl;
|
|
54839
|
-
const sslEnabled = ssl === true || typeof ssl === "object" && ssl.enabled !== false;
|
|
54840
|
-
return {
|
|
54841
|
-
server: this.connection.host || "localhost",
|
|
54842
|
-
port: this.connection.port,
|
|
54843
|
-
database: this.connection.database || "visor",
|
|
54844
|
-
user: this.connection.user,
|
|
54845
|
-
password: this.connection.password,
|
|
54846
|
-
options: {
|
|
54847
|
-
encrypt: sslEnabled,
|
|
54848
|
-
trustServerCertificate: typeof ssl === "object" ? ssl.reject_unauthorized === false : !sslEnabled
|
|
54849
|
-
}
|
|
54850
|
-
};
|
|
54851
|
-
}
|
|
54852
|
-
resolveSslConfig() {
|
|
54853
|
-
const ssl = this.connection.ssl;
|
|
54854
|
-
if (ssl === false || ssl === void 0) return false;
|
|
54855
|
-
if (ssl === true) return { rejectUnauthorized: true };
|
|
54856
|
-
if (ssl.enabled === false) return false;
|
|
54857
|
-
const result = {
|
|
54858
|
-
rejectUnauthorized: ssl.reject_unauthorized !== false
|
|
54859
|
-
};
|
|
54860
|
-
if (ssl.ca) {
|
|
54861
|
-
const caPath = this.validateSslPath(ssl.ca, "CA certificate");
|
|
54862
|
-
result.ca = fs24.readFileSync(caPath, "utf8");
|
|
54863
|
-
}
|
|
54864
|
-
if (ssl.cert) {
|
|
54865
|
-
const certPath = this.validateSslPath(ssl.cert, "client certificate");
|
|
54866
|
-
result.cert = fs24.readFileSync(certPath, "utf8");
|
|
54867
|
-
}
|
|
54868
|
-
if (ssl.key) {
|
|
54869
|
-
const keyPath = this.validateSslPath(ssl.key, "client key");
|
|
54870
|
-
result.key = fs24.readFileSync(keyPath, "utf8");
|
|
54871
|
-
}
|
|
54872
|
-
return result;
|
|
54873
|
-
}
|
|
54874
|
-
validateSslPath(filePath, label) {
|
|
54875
|
-
const resolved = path28.resolve(filePath);
|
|
54876
|
-
if (resolved !== path28.normalize(resolved)) {
|
|
54877
|
-
throw new Error(`SSL ${label} path contains invalid sequences: ${filePath}`);
|
|
54878
|
-
}
|
|
54879
|
-
if (!fs24.existsSync(resolved)) {
|
|
54880
|
-
throw new Error(`SSL ${label} not found: ${filePath}`);
|
|
54881
|
-
}
|
|
54882
|
-
return resolved;
|
|
54883
|
-
}
|
|
54884
|
-
async shutdown() {
|
|
54885
|
-
if (this.knex) {
|
|
54886
|
-
await this.knex.destroy();
|
|
54887
|
-
this.knex = null;
|
|
54888
|
-
}
|
|
54889
|
-
}
|
|
54890
|
-
async migrateSchema() {
|
|
54891
|
-
const knex = this.getKnex();
|
|
54892
|
-
const exists = await knex.schema.hasTable("schedules");
|
|
54893
|
-
if (!exists) {
|
|
54894
|
-
await knex.schema.createTable("schedules", (table) => {
|
|
54895
|
-
table.string("id", 36).primary();
|
|
54896
|
-
table.string("creator_id", 255).notNullable().index();
|
|
54897
|
-
table.string("creator_context", 255);
|
|
54898
|
-
table.string("creator_name", 255);
|
|
54899
|
-
table.string("timezone", 64).notNullable().defaultTo("UTC");
|
|
54900
|
-
table.string("schedule_expr", 255);
|
|
54901
|
-
table.bigInteger("run_at");
|
|
54902
|
-
table.boolean("is_recurring").notNullable();
|
|
54903
|
-
table.text("original_expression");
|
|
54904
|
-
table.string("workflow", 255);
|
|
54905
|
-
table.text("workflow_inputs");
|
|
54906
|
-
table.text("output_context");
|
|
54907
|
-
table.string("status", 20).notNullable().index();
|
|
54908
|
-
table.bigInteger("created_at").notNullable();
|
|
54909
|
-
table.bigInteger("last_run_at");
|
|
54910
|
-
table.bigInteger("next_run_at");
|
|
54911
|
-
table.integer("run_count").notNullable().defaultTo(0);
|
|
54912
|
-
table.integer("failure_count").notNullable().defaultTo(0);
|
|
54913
|
-
table.text("last_error");
|
|
54914
|
-
table.text("previous_response");
|
|
54915
|
-
table.index(["status", "next_run_at"]);
|
|
54916
|
-
});
|
|
54917
|
-
}
|
|
54918
|
-
const locksExist = await knex.schema.hasTable("scheduler_locks");
|
|
54919
|
-
if (!locksExist) {
|
|
54920
|
-
await knex.schema.createTable("scheduler_locks", (table) => {
|
|
54921
|
-
table.string("lock_id", 255).primary();
|
|
54922
|
-
table.string("node_id", 255).notNullable();
|
|
54923
|
-
table.string("lock_token", 36).notNullable();
|
|
54924
|
-
table.bigInteger("acquired_at").notNullable();
|
|
54925
|
-
table.bigInteger("expires_at").notNullable();
|
|
54926
|
-
});
|
|
54927
|
-
}
|
|
54928
|
-
}
|
|
54929
|
-
getKnex() {
|
|
54930
|
-
if (!this.knex) {
|
|
54931
|
-
throw new Error("[KnexStore] Not initialized. Call initialize() first.");
|
|
54932
|
-
}
|
|
54933
|
-
return this.knex;
|
|
54934
|
-
}
|
|
54935
|
-
// --- CRUD ---
|
|
54936
|
-
async create(schedule) {
|
|
54937
|
-
const knex = this.getKnex();
|
|
54938
|
-
const newSchedule = {
|
|
54939
|
-
...schedule,
|
|
54940
|
-
id: (0, import_uuid2.v4)(),
|
|
54941
|
-
createdAt: Date.now(),
|
|
54942
|
-
runCount: 0,
|
|
54943
|
-
failureCount: 0,
|
|
54944
|
-
status: "active"
|
|
54945
|
-
};
|
|
54946
|
-
await knex("schedules").insert(toInsertRow(newSchedule));
|
|
54947
|
-
logger.info(`[KnexStore] Created schedule ${newSchedule.id} for user ${newSchedule.creatorId}`);
|
|
54948
|
-
return newSchedule;
|
|
54949
|
-
}
|
|
54950
|
-
async importSchedule(schedule) {
|
|
54951
|
-
const knex = this.getKnex();
|
|
54952
|
-
const existing = await knex("schedules").where("id", schedule.id).first();
|
|
54953
|
-
if (existing) return;
|
|
54954
|
-
await knex("schedules").insert(toInsertRow(schedule));
|
|
54955
|
-
}
|
|
54956
|
-
async get(id) {
|
|
54957
|
-
const knex = this.getKnex();
|
|
54958
|
-
const row = await knex("schedules").where("id", id).first();
|
|
54959
|
-
return row ? fromDbRow2(row) : void 0;
|
|
54960
|
-
}
|
|
54961
|
-
async update(id, patch) {
|
|
54962
|
-
const knex = this.getKnex();
|
|
54963
|
-
const existing = await knex("schedules").where("id", id).first();
|
|
54964
|
-
if (!existing) return void 0;
|
|
54965
|
-
const current = fromDbRow2(existing);
|
|
54966
|
-
const updated = { ...current, ...patch, id: current.id };
|
|
54967
|
-
const row = toInsertRow(updated);
|
|
54968
|
-
delete row.id;
|
|
54969
|
-
await knex("schedules").where("id", id).update(row);
|
|
54970
|
-
return updated;
|
|
54971
|
-
}
|
|
54972
|
-
async delete(id) {
|
|
54973
|
-
const knex = this.getKnex();
|
|
54974
|
-
const deleted = await knex("schedules").where("id", id).del();
|
|
54975
|
-
if (deleted > 0) {
|
|
54976
|
-
logger.info(`[KnexStore] Deleted schedule ${id}`);
|
|
54977
|
-
return true;
|
|
54978
|
-
}
|
|
54979
|
-
return false;
|
|
54980
|
-
}
|
|
54981
|
-
// --- Queries ---
|
|
54982
|
-
async getByCreator(creatorId) {
|
|
54983
|
-
const knex = this.getKnex();
|
|
54984
|
-
const rows = await knex("schedules").where("creator_id", creatorId);
|
|
54985
|
-
return rows.map((r) => fromDbRow2(r));
|
|
54986
|
-
}
|
|
54987
|
-
async getActiveSchedules() {
|
|
54988
|
-
const knex = this.getKnex();
|
|
54989
|
-
const rows = await knex("schedules").where("status", "active");
|
|
54990
|
-
return rows.map((r) => fromDbRow2(r));
|
|
54991
|
-
}
|
|
54992
|
-
async getDueSchedules(now) {
|
|
54993
|
-
const ts = now ?? Date.now();
|
|
54994
|
-
const knex = this.getKnex();
|
|
54995
|
-
const bFalse = this.driver === "mssql" ? 0 : false;
|
|
54996
|
-
const bTrue = this.driver === "mssql" ? 1 : true;
|
|
54997
|
-
const rows = await knex("schedules").where("status", "active").andWhere(function() {
|
|
54998
|
-
this.where(function() {
|
|
54999
|
-
this.where("is_recurring", bFalse).whereNotNull("run_at").where("run_at", "<=", ts);
|
|
55000
|
-
}).orWhere(function() {
|
|
55001
|
-
this.where("is_recurring", bTrue).whereNotNull("next_run_at").where("next_run_at", "<=", ts);
|
|
55002
|
-
});
|
|
55003
|
-
});
|
|
55004
|
-
return rows.map((r) => fromDbRow2(r));
|
|
55005
|
-
}
|
|
55006
|
-
async findByWorkflow(creatorId, workflowName) {
|
|
55007
|
-
const knex = this.getKnex();
|
|
55008
|
-
const escaped = workflowName.toLowerCase().replace(/[%_\\]/g, "\\$&");
|
|
55009
|
-
const pattern = `%${escaped}%`;
|
|
55010
|
-
const rows = await knex("schedules").where("creator_id", creatorId).where("status", "active").whereRaw("LOWER(workflow) LIKE ? ESCAPE '\\'", [pattern]);
|
|
55011
|
-
return rows.map((r) => fromDbRow2(r));
|
|
55012
|
-
}
|
|
55013
|
-
async getAll() {
|
|
55014
|
-
const knex = this.getKnex();
|
|
55015
|
-
const rows = await knex("schedules");
|
|
55016
|
-
return rows.map((r) => fromDbRow2(r));
|
|
55017
|
-
}
|
|
55018
|
-
async getStats() {
|
|
55019
|
-
const knex = this.getKnex();
|
|
55020
|
-
const boolTrue = this.driver === "mssql" ? "1" : "true";
|
|
55021
|
-
const boolFalse = this.driver === "mssql" ? "0" : "false";
|
|
55022
|
-
const result = await knex("schedules").select(
|
|
55023
|
-
knex.raw("COUNT(*) as total"),
|
|
55024
|
-
knex.raw("SUM(CASE WHEN status = 'active' THEN 1 ELSE 0 END) as active"),
|
|
55025
|
-
knex.raw("SUM(CASE WHEN status = 'paused' THEN 1 ELSE 0 END) as paused"),
|
|
55026
|
-
knex.raw("SUM(CASE WHEN status = 'completed' THEN 1 ELSE 0 END) as completed"),
|
|
55027
|
-
knex.raw("SUM(CASE WHEN status = 'failed' THEN 1 ELSE 0 END) as failed"),
|
|
55028
|
-
knex.raw(`SUM(CASE WHEN is_recurring = ${boolTrue} THEN 1 ELSE 0 END) as recurring`),
|
|
55029
|
-
knex.raw(`SUM(CASE WHEN is_recurring = ${boolFalse} THEN 1 ELSE 0 END) as one_time`)
|
|
55030
|
-
).first();
|
|
55031
|
-
return {
|
|
55032
|
-
total: Number(result.total) || 0,
|
|
55033
|
-
active: Number(result.active) || 0,
|
|
55034
|
-
paused: Number(result.paused) || 0,
|
|
55035
|
-
completed: Number(result.completed) || 0,
|
|
55036
|
-
failed: Number(result.failed) || 0,
|
|
55037
|
-
recurring: Number(result.recurring) || 0,
|
|
55038
|
-
oneTime: Number(result.one_time) || 0
|
|
55039
|
-
};
|
|
55040
|
-
}
|
|
55041
|
-
async validateLimits(creatorId, isRecurring, limits) {
|
|
55042
|
-
const knex = this.getKnex();
|
|
55043
|
-
if (limits.maxGlobal) {
|
|
55044
|
-
const result = await knex("schedules").count("* as cnt").first();
|
|
55045
|
-
if (Number(result?.cnt) >= limits.maxGlobal) {
|
|
55046
|
-
throw new Error(`Global schedule limit reached (${limits.maxGlobal})`);
|
|
55047
|
-
}
|
|
55048
|
-
}
|
|
55049
|
-
if (limits.maxPerUser) {
|
|
55050
|
-
const result = await knex("schedules").where("creator_id", creatorId).count("* as cnt").first();
|
|
55051
|
-
if (Number(result?.cnt) >= limits.maxPerUser) {
|
|
55052
|
-
throw new Error(`You have reached the maximum number of schedules (${limits.maxPerUser})`);
|
|
55053
|
-
}
|
|
55054
|
-
}
|
|
55055
|
-
if (isRecurring && limits.maxRecurringPerUser) {
|
|
55056
|
-
const bTrue = this.driver === "mssql" ? 1 : true;
|
|
55057
|
-
const result = await knex("schedules").where("creator_id", creatorId).where("is_recurring", bTrue).count("* as cnt").first();
|
|
55058
|
-
if (Number(result?.cnt) >= limits.maxRecurringPerUser) {
|
|
55059
|
-
throw new Error(
|
|
55060
|
-
`You have reached the maximum number of recurring schedules (${limits.maxRecurringPerUser})`
|
|
55061
|
-
);
|
|
55062
|
-
}
|
|
55063
|
-
}
|
|
55064
|
-
}
|
|
55065
|
-
// --- HA Distributed Locking (via scheduler_locks table) ---
|
|
55066
|
-
async tryAcquireLock(lockId, nodeId, ttlSeconds) {
|
|
55067
|
-
const knex = this.getKnex();
|
|
55068
|
-
const now = Date.now();
|
|
55069
|
-
const expiresAt = now + ttlSeconds * 1e3;
|
|
55070
|
-
const token = (0, import_uuid2.v4)();
|
|
55071
|
-
const updated = await knex("scheduler_locks").where("lock_id", lockId).where("expires_at", "<", now).update({
|
|
55072
|
-
node_id: nodeId,
|
|
55073
|
-
lock_token: token,
|
|
55074
|
-
acquired_at: now,
|
|
55075
|
-
expires_at: expiresAt
|
|
55076
|
-
});
|
|
55077
|
-
if (updated > 0) return token;
|
|
55078
|
-
try {
|
|
55079
|
-
await knex("scheduler_locks").insert({
|
|
55080
|
-
lock_id: lockId,
|
|
55081
|
-
node_id: nodeId,
|
|
55082
|
-
lock_token: token,
|
|
55083
|
-
acquired_at: now,
|
|
55084
|
-
expires_at: expiresAt
|
|
55085
|
-
});
|
|
55086
|
-
return token;
|
|
55087
|
-
} catch {
|
|
55088
|
-
return null;
|
|
55089
|
-
}
|
|
55090
|
-
}
|
|
55091
|
-
async releaseLock(lockId, lockToken) {
|
|
55092
|
-
const knex = this.getKnex();
|
|
55093
|
-
await knex("scheduler_locks").where("lock_id", lockId).where("lock_token", lockToken).del();
|
|
55094
|
-
}
|
|
55095
|
-
async renewLock(lockId, lockToken, ttlSeconds) {
|
|
55096
|
-
const knex = this.getKnex();
|
|
55097
|
-
const now = Date.now();
|
|
55098
|
-
const expiresAt = now + ttlSeconds * 1e3;
|
|
55099
|
-
const updated = await knex("scheduler_locks").where("lock_id", lockId).where("lock_token", lockToken).update({ acquired_at: now, expires_at: expiresAt });
|
|
55100
|
-
return updated > 0;
|
|
55101
|
-
}
|
|
55102
|
-
async flush() {
|
|
55103
|
-
}
|
|
55104
|
-
};
|
|
55105
|
-
}
|
|
55106
|
-
});
|
|
55107
|
-
|
|
55108
|
-
// src/enterprise/loader.ts
|
|
55109
|
-
var loader_exports = {};
|
|
55110
|
-
__export(loader_exports, {
|
|
55111
|
-
loadEnterprisePolicyEngine: () => loadEnterprisePolicyEngine,
|
|
55112
|
-
loadEnterpriseStoreBackend: () => loadEnterpriseStoreBackend
|
|
55113
|
-
});
|
|
55114
|
-
async function loadEnterprisePolicyEngine(config) {
|
|
55115
|
-
try {
|
|
55116
|
-
const { LicenseValidator: LicenseValidator2 } = await Promise.resolve().then(() => (init_validator(), validator_exports));
|
|
55117
|
-
const validator = new LicenseValidator2();
|
|
55118
|
-
const license = await validator.loadAndValidate();
|
|
55119
|
-
if (!license || !validator.hasFeature("policy")) {
|
|
55120
|
-
return new DefaultPolicyEngine();
|
|
55121
|
-
}
|
|
55122
|
-
if (validator.isInGracePeriod()) {
|
|
55123
|
-
console.warn(
|
|
55124
|
-
"[visor:enterprise] License has expired but is within the 72-hour grace period. Please renew your license."
|
|
55125
|
-
);
|
|
55126
|
-
}
|
|
55127
|
-
const { OpaPolicyEngine: OpaPolicyEngine2 } = await Promise.resolve().then(() => (init_opa_policy_engine(), opa_policy_engine_exports));
|
|
55128
|
-
const engine = new OpaPolicyEngine2(config);
|
|
55129
|
-
await engine.initialize(config);
|
|
55130
|
-
return engine;
|
|
55131
|
-
} catch (err) {
|
|
55132
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
55133
|
-
try {
|
|
55134
|
-
const { logger: logger2 } = (init_logger(), __toCommonJS(logger_exports));
|
|
55135
|
-
logger2.warn(`[PolicyEngine] Enterprise policy init failed, falling back to default: ${msg}`);
|
|
55136
|
-
} catch {
|
|
55137
|
-
}
|
|
55138
|
-
return new DefaultPolicyEngine();
|
|
55139
|
-
}
|
|
55140
|
-
}
|
|
55141
|
-
async function loadEnterpriseStoreBackend(driver, storageConfig, haConfig) {
|
|
55142
|
-
const { LicenseValidator: LicenseValidator2 } = await Promise.resolve().then(() => (init_validator(), validator_exports));
|
|
55143
|
-
const validator = new LicenseValidator2();
|
|
55144
|
-
const license = await validator.loadAndValidate();
|
|
55145
|
-
if (!license || !validator.hasFeature("scheduler-sql")) {
|
|
55146
|
-
throw new Error(
|
|
55147
|
-
`The ${driver} schedule storage driver requires a Visor Enterprise license with the 'scheduler-sql' feature. Please upgrade or use driver: 'sqlite' (default).`
|
|
55148
|
-
);
|
|
55149
|
-
}
|
|
55150
|
-
if (validator.isInGracePeriod()) {
|
|
55151
|
-
console.warn(
|
|
55152
|
-
"[visor:enterprise] License has expired but is within the 72-hour grace period. Please renew your license."
|
|
55153
|
-
);
|
|
55154
|
-
}
|
|
55155
|
-
const { KnexStoreBackend: KnexStoreBackend2 } = await Promise.resolve().then(() => (init_knex_store(), knex_store_exports));
|
|
55156
|
-
return new KnexStoreBackend2(driver, storageConfig, haConfig);
|
|
55157
|
-
}
|
|
55158
|
-
var init_loader = __esm({
|
|
55159
|
-
"src/enterprise/loader.ts"() {
|
|
55160
|
-
"use strict";
|
|
55161
|
-
init_default_engine();
|
|
55162
|
-
}
|
|
55163
|
-
});
|
|
55164
|
-
|
|
55165
53917
|
// src/event-bus/event-bus.ts
|
|
55166
53918
|
var event_bus_exports = {};
|
|
55167
53919
|
__export(event_bus_exports, {
|
|
@@ -56068,8 +54820,8 @@ ${content}
|
|
|
56068
54820
|
* Sleep utility
|
|
56069
54821
|
*/
|
|
56070
54822
|
sleep(ms) {
|
|
56071
|
-
return new Promise((
|
|
56072
|
-
const t = setTimeout(
|
|
54823
|
+
return new Promise((resolve14) => {
|
|
54824
|
+
const t = setTimeout(resolve14, ms);
|
|
56073
54825
|
if (typeof t.unref === "function") {
|
|
56074
54826
|
try {
|
|
56075
54827
|
t.unref();
|
|
@@ -56354,8 +55106,8 @@ ${end}`);
|
|
|
56354
55106
|
async updateGroupedComment(ctx, comments, group, changedIds) {
|
|
56355
55107
|
const existingLock = this.updateLocks.get(group);
|
|
56356
55108
|
let resolveLock;
|
|
56357
|
-
const ourLock = new Promise((
|
|
56358
|
-
resolveLock =
|
|
55109
|
+
const ourLock = new Promise((resolve14) => {
|
|
55110
|
+
resolveLock = resolve14;
|
|
56359
55111
|
});
|
|
56360
55112
|
this.updateLocks.set(group, ourLock);
|
|
56361
55113
|
try {
|
|
@@ -56668,7 +55420,7 @@ ${blocks}
|
|
|
56668
55420
|
* Sleep utility for enforcing delays
|
|
56669
55421
|
*/
|
|
56670
55422
|
sleep(ms) {
|
|
56671
|
-
return new Promise((
|
|
55423
|
+
return new Promise((resolve14) => setTimeout(resolve14, ms));
|
|
56672
55424
|
}
|
|
56673
55425
|
};
|
|
56674
55426
|
}
|
|
@@ -57939,15 +56691,15 @@ function serializeRunState(state) {
|
|
|
57939
56691
|
])
|
|
57940
56692
|
};
|
|
57941
56693
|
}
|
|
57942
|
-
var
|
|
56694
|
+
var path26, fs22, StateMachineExecutionEngine;
|
|
57943
56695
|
var init_state_machine_execution_engine = __esm({
|
|
57944
56696
|
"src/state-machine-execution-engine.ts"() {
|
|
57945
56697
|
"use strict";
|
|
57946
56698
|
init_runner();
|
|
57947
56699
|
init_logger();
|
|
57948
56700
|
init_sandbox_manager();
|
|
57949
|
-
|
|
57950
|
-
|
|
56701
|
+
path26 = __toESM(require("path"));
|
|
56702
|
+
fs22 = __toESM(require("fs"));
|
|
57951
56703
|
StateMachineExecutionEngine = class _StateMachineExecutionEngine {
|
|
57952
56704
|
workingDirectory;
|
|
57953
56705
|
executionContext;
|
|
@@ -58179,8 +56931,8 @@ var init_state_machine_execution_engine = __esm({
|
|
|
58179
56931
|
logger.debug(
|
|
58180
56932
|
`[PolicyEngine] Loading enterprise policy engine (engine=${configWithTagFilter.policy.engine})`
|
|
58181
56933
|
);
|
|
58182
|
-
const { loadEnterprisePolicyEngine
|
|
58183
|
-
context2.policyEngine = await
|
|
56934
|
+
const { loadEnterprisePolicyEngine } = await import("./enterprise/loader");
|
|
56935
|
+
context2.policyEngine = await loadEnterprisePolicyEngine(configWithTagFilter.policy);
|
|
58184
56936
|
logger.debug(
|
|
58185
56937
|
`[PolicyEngine] Initialized: ${context2.policyEngine?.constructor?.name || "unknown"}`
|
|
58186
56938
|
);
|
|
@@ -58332,9 +57084,9 @@ var init_state_machine_execution_engine = __esm({
|
|
|
58332
57084
|
}
|
|
58333
57085
|
const checkId = String(ev?.checkId || "unknown");
|
|
58334
57086
|
const threadKey = ev?.threadKey || (channel && threadTs ? `${channel}:${threadTs}` : "session");
|
|
58335
|
-
const baseDir = process.env.VISOR_SNAPSHOT_DIR ||
|
|
58336
|
-
|
|
58337
|
-
const filePath =
|
|
57087
|
+
const baseDir = process.env.VISOR_SNAPSHOT_DIR || path26.resolve(process.cwd(), ".visor", "snapshots");
|
|
57088
|
+
fs22.mkdirSync(baseDir, { recursive: true });
|
|
57089
|
+
const filePath = path26.join(baseDir, `${threadKey}-${checkId}.json`);
|
|
58338
57090
|
await this.saveSnapshotToFile(filePath);
|
|
58339
57091
|
logger.info(`[Snapshot] Saved run snapshot: ${filePath}`);
|
|
58340
57092
|
try {
|
|
@@ -58475,7 +57227,7 @@ var init_state_machine_execution_engine = __esm({
|
|
|
58475
57227
|
* Does not include secrets. Intended for debugging and future resume support.
|
|
58476
57228
|
*/
|
|
58477
57229
|
async saveSnapshotToFile(filePath) {
|
|
58478
|
-
const
|
|
57230
|
+
const fs23 = await import("fs/promises");
|
|
58479
57231
|
const ctx = this._lastContext;
|
|
58480
57232
|
const runner = this._lastRunner;
|
|
58481
57233
|
if (!ctx || !runner) {
|
|
@@ -58495,14 +57247,14 @@ var init_state_machine_execution_engine = __esm({
|
|
|
58495
57247
|
journal: entries,
|
|
58496
57248
|
requestedChecks: ctx.requestedChecks || []
|
|
58497
57249
|
};
|
|
58498
|
-
await
|
|
57250
|
+
await fs23.writeFile(filePath, JSON.stringify(payload, null, 2), "utf8");
|
|
58499
57251
|
}
|
|
58500
57252
|
/**
|
|
58501
57253
|
* Load a snapshot JSON from file and return it. Resume support can build on this.
|
|
58502
57254
|
*/
|
|
58503
57255
|
async loadSnapshotFromFile(filePath) {
|
|
58504
|
-
const
|
|
58505
|
-
const raw = await
|
|
57256
|
+
const fs23 = await import("fs/promises");
|
|
57257
|
+
const raw = await fs23.readFile(filePath, "utf8");
|
|
58506
57258
|
return JSON.parse(raw);
|
|
58507
57259
|
}
|
|
58508
57260
|
/**
|