@probelabs/visor 0.1.138-ee → 0.1.138

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.
Files changed (49) hide show
  1. package/dist/index.js +22 -1719
  2. package/dist/output/traces/run-2026-02-23T15-25-03-052Z.ndjson +138 -0
  3. package/dist/output/traces/run-2026-02-23T15-25-53-483Z.ndjson +1442 -0
  4. package/dist/sdk/{check-provider-registry-B5X3AL4Z.mjs → check-provider-registry-JX7FK3MS.mjs} +3 -3
  5. package/dist/sdk/check-provider-registry-ZVPNBYEA.mjs +29 -0
  6. package/dist/sdk/chunk-GIGTDZHF.mjs +443 -0
  7. package/dist/sdk/chunk-GIGTDZHF.mjs.map +1 -0
  8. package/dist/sdk/chunk-HIRALSSN.mjs +40235 -0
  9. package/dist/sdk/{chunk-SUZCXRJ4.mjs.map → chunk-HIRALSSN.mjs.map} +1 -1
  10. package/dist/sdk/chunk-K7O7DMJU.mjs +1502 -0
  11. package/dist/sdk/chunk-K7O7DMJU.mjs.map +1 -0
  12. package/dist/sdk/{chunk-SUZCXRJ4.mjs → chunk-QSB2P6VY.mjs} +12 -12
  13. package/dist/sdk/chunk-QSB2P6VY.mjs.map +1 -0
  14. package/dist/sdk/chunk-ROCFDJFL.mjs +739 -0
  15. package/dist/sdk/chunk-ROCFDJFL.mjs.map +1 -0
  16. package/dist/sdk/failure-condition-evaluator-DPLWUGYG.mjs +17 -0
  17. package/dist/sdk/github-frontend-QSMW366Z.mjs +1356 -0
  18. package/dist/sdk/github-frontend-QSMW366Z.mjs.map +1 -0
  19. package/dist/sdk/{host-RF2UEKMG.mjs → host-FISPPQTH.mjs} +2 -2
  20. package/dist/sdk/routing-7QCNYAVE.mjs +25 -0
  21. package/dist/sdk/routing-7QCNYAVE.mjs.map +1 -0
  22. package/dist/sdk/{schedule-tool-handler-47KJUUJH.mjs → schedule-tool-handler-LBSAGK6P.mjs} +3 -3
  23. package/dist/sdk/schedule-tool-handler-LBSAGK6P.mjs.map +1 -0
  24. package/dist/sdk/schedule-tool-handler-RU76H4W5.mjs +39 -0
  25. package/dist/sdk/schedule-tool-handler-RU76H4W5.mjs.map +1 -0
  26. package/dist/sdk/sdk.js +274 -1532
  27. package/dist/sdk/sdk.js.map +1 -1
  28. package/dist/sdk/sdk.mjs +5 -5
  29. package/dist/sdk/trace-helpers-2ADE6X4I.mjs +25 -0
  30. package/dist/sdk/trace-helpers-2ADE6X4I.mjs.map +1 -0
  31. package/dist/sdk/{workflow-check-provider-D375GDQS.mjs → workflow-check-provider-I3SB5RG7.mjs} +3 -3
  32. package/dist/sdk/workflow-check-provider-I3SB5RG7.mjs.map +1 -0
  33. package/dist/sdk/workflow-check-provider-YDA7DL3O.mjs +29 -0
  34. package/dist/sdk/workflow-check-provider-YDA7DL3O.mjs.map +1 -0
  35. package/dist/traces/run-2026-02-23T15-25-03-052Z.ndjson +138 -0
  36. package/dist/traces/run-2026-02-23T15-25-53-483Z.ndjson +1442 -0
  37. package/package.json +1 -1
  38. package/dist/sdk/knex-store-HPXJILBL.mjs +0 -411
  39. package/dist/sdk/knex-store-HPXJILBL.mjs.map +0 -1
  40. package/dist/sdk/loader-ZC5G3JGJ.mjs +0 -89
  41. package/dist/sdk/loader-ZC5G3JGJ.mjs.map +0 -1
  42. package/dist/sdk/opa-policy-engine-S2S2ULEI.mjs +0 -655
  43. package/dist/sdk/opa-policy-engine-S2S2ULEI.mjs.map +0 -1
  44. package/dist/sdk/validator-XTZJZZJH.mjs +0 -134
  45. package/dist/sdk/validator-XTZJZZJH.mjs.map +0 -1
  46. /package/dist/sdk/{check-provider-registry-B5X3AL4Z.mjs.map → check-provider-registry-JX7FK3MS.mjs.map} +0 -0
  47. /package/dist/sdk/{schedule-tool-handler-47KJUUJH.mjs.map → check-provider-registry-ZVPNBYEA.mjs.map} +0 -0
  48. /package/dist/sdk/{workflow-check-provider-D375GDQS.mjs.map → failure-condition-evaluator-DPLWUGYG.mjs.map} +0 -0
  49. /package/dist/sdk/{host-RF2UEKMG.mjs.map → host-FISPPQTH.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.42",
649
+ version: "0.1.138",
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((resolve15, reject) => {
867
+ return await new Promise((resolve11, reject) => {
868
868
  const callback = async (span) => {
869
869
  try {
870
870
  const res = await fn(span);
871
- resolve15(res);
871
+ resolve11(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 path30 = require("path");
949
- const fs26 = require("fs");
948
+ const path26 = require("path");
949
+ const fs22 = require("fs");
950
950
  if (process.env.VISOR_FALLBACK_TRACE_FILE) {
951
951
  __ndjsonPath = process.env.VISOR_FALLBACK_TRACE_FILE;
952
- const dir = path30.dirname(__ndjsonPath);
953
- if (!fs26.existsSync(dir)) fs26.mkdirSync(dir, { recursive: true });
952
+ const dir = path26.dirname(__ndjsonPath);
953
+ if (!fs22.existsSync(dir)) fs22.mkdirSync(dir, { recursive: true });
954
954
  return __ndjsonPath;
955
955
  }
956
- const outDir = process.env.VISOR_TRACE_DIR || path30.join(process.cwd(), "output", "traces");
957
- if (!fs26.existsSync(outDir)) fs26.mkdirSync(outDir, { recursive: true });
956
+ const outDir = process.env.VISOR_TRACE_DIR || path26.join(process.cwd(), "output", "traces");
957
+ if (!fs22.existsSync(outDir)) fs22.mkdirSync(outDir, { recursive: true });
958
958
  if (!__ndjsonPath) {
959
959
  const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
960
- __ndjsonPath = path30.join(outDir, `${ts}.ndjson`);
960
+ __ndjsonPath = path26.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 fs26 = require("fs");
969
+ const fs22 = require("fs");
970
970
  const p = __getOrCreateNdjsonPath();
971
971
  if (!p) return;
972
972
  const line = { name: "visor.run", attributes: { started: true } };
973
- fs26.appendFileSync(p, JSON.stringify(line) + "\n", "utf8");
973
+ fs22.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 normalize8 = (expr) => {
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 = normalize8(condition);
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 path30 = typeof pathExpr === "string" ? pathExpr : String(pathExpr || "");
3738
- if (!path30) return obj;
3739
- const parts = path30.split(".");
3737
+ const path26 = typeof pathExpr === "string" ? pathExpr : String(pathExpr || "");
3738
+ if (!path26) return obj;
3739
+ const parts = path26.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, path30) => {
3859
- if (!obj || !path30) return void 0;
3860
- const parts = path30.split(".");
3858
+ const getNested = (obj, path26) => {
3859
+ if (!obj || !path26) return void 0;
3860
+ const parts = path26.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 fs26 = await import("fs/promises");
6413
- const path30 = await import("path");
6412
+ const fs22 = await import("fs/promises");
6413
+ const path26 = 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 = path30.resolve(process.cwd(), file);
6422
- templateContent = await fs26.readFile(resolved, "utf-8");
6421
+ const resolved = path26.resolve(process.cwd(), file);
6422
+ templateContent = await fs22.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
- path30.join(__dirname, "output", sanitized, "template.liquid"),
6427
+ path26.join(__dirname, "output", sanitized, "template.liquid"),
6428
6428
  // bundled: dist/output/
6429
- path30.join(__dirname, "..", "..", "output", sanitized, "template.liquid"),
6429
+ path26.join(__dirname, "..", "..", "output", sanitized, "template.liquid"),
6430
6430
  // source: output/
6431
- path30.join(process.cwd(), "output", sanitized, "template.liquid"),
6431
+ path26.join(process.cwd(), "output", sanitized, "template.liquid"),
6432
6432
  // fallback: cwd/output/
6433
- path30.join(process.cwd(), "dist", "output", sanitized, "template.liquid")
6433
+ path26.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 fs26.readFile(p, "utf-8");
6438
+ templateContent = await fs22.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 fs26 = require("fs");
6843
+ const fs22 = 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 (fs26.existsSync(candidatePath)) {
6854
+ if (fs22.existsSync(candidatePath)) {
6855
6855
  probeBinaryPath = candidatePath;
6856
6856
  break;
6857
6857
  }
@@ -7937,8 +7937,8 @@ ${schemaString}`);
7937
7937
  }
7938
7938
  if (process.env.VISOR_DEBUG_AI_SESSIONS === "true") {
7939
7939
  try {
7940
- const fs26 = require("fs");
7941
- const path30 = require("path");
7940
+ const fs22 = require("fs");
7941
+ const path26 = require("path");
7942
7942
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
7943
7943
  const provider = this.config.provider || "auto";
7944
7944
  const model = this.config.model || "default";
@@ -8052,20 +8052,20 @@ ${"=".repeat(60)}
8052
8052
  `;
8053
8053
  readableVersion += `${"=".repeat(60)}
8054
8054
  `;
8055
- const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path30.join(process.cwd(), "debug-artifacts");
8056
- if (!fs26.existsSync(debugArtifactsDir)) {
8057
- fs26.mkdirSync(debugArtifactsDir, { recursive: true });
8055
+ const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path26.join(process.cwd(), "debug-artifacts");
8056
+ if (!fs22.existsSync(debugArtifactsDir)) {
8057
+ fs22.mkdirSync(debugArtifactsDir, { recursive: true });
8058
8058
  }
8059
- const debugFile = path30.join(
8059
+ const debugFile = path26.join(
8060
8060
  debugArtifactsDir,
8061
8061
  `prompt-${_checkName || "unknown"}-${timestamp}.json`
8062
8062
  );
8063
- fs26.writeFileSync(debugFile, debugJson, "utf-8");
8064
- const readableFile = path30.join(
8063
+ fs22.writeFileSync(debugFile, debugJson, "utf-8");
8064
+ const readableFile = path26.join(
8065
8065
  debugArtifactsDir,
8066
8066
  `prompt-${_checkName || "unknown"}-${timestamp}.txt`
8067
8067
  );
8068
- fs26.writeFileSync(readableFile, readableVersion, "utf-8");
8068
+ fs22.writeFileSync(readableFile, readableVersion, "utf-8");
8069
8069
  log(`
8070
8070
  \u{1F4BE} Full debug info saved to:`);
8071
8071
  log(` JSON: ${debugFile}`);
@@ -8098,8 +8098,8 @@ ${"=".repeat(60)}
8098
8098
  log(`\u{1F4E4} Response length: ${response.length} characters`);
8099
8099
  if (process.env.VISOR_DEBUG_AI_SESSIONS === "true") {
8100
8100
  try {
8101
- const fs26 = require("fs");
8102
- const path30 = require("path");
8101
+ const fs22 = require("fs");
8102
+ const path26 = require("path");
8103
8103
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
8104
8104
  const agentAny2 = agent;
8105
8105
  let fullHistory = [];
@@ -8110,8 +8110,8 @@ ${"=".repeat(60)}
8110
8110
  } else if (agentAny2._messages) {
8111
8111
  fullHistory = agentAny2._messages;
8112
8112
  }
8113
- const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path30.join(process.cwd(), "debug-artifacts");
8114
- const sessionBase = path30.join(
8113
+ const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path26.join(process.cwd(), "debug-artifacts");
8114
+ const sessionBase = path26.join(
8115
8115
  debugArtifactsDir,
8116
8116
  `session-${_checkName || "unknown"}-${timestamp}`
8117
8117
  );
@@ -8123,7 +8123,7 @@ ${"=".repeat(60)}
8123
8123
  schema: effectiveSchema,
8124
8124
  totalMessages: fullHistory.length
8125
8125
  };
8126
- fs26.writeFileSync(sessionBase + ".json", JSON.stringify(sessionData, null, 2), "utf-8");
8126
+ fs22.writeFileSync(sessionBase + ".json", JSON.stringify(sessionData, null, 2), "utf-8");
8127
8127
  let readable = `=============================================================
8128
8128
  `;
8129
8129
  readable += `COMPLETE AI SESSION HISTORY (AFTER RESPONSE)
@@ -8150,7 +8150,7 @@ ${"=".repeat(60)}
8150
8150
  `;
8151
8151
  readable += content + "\n";
8152
8152
  });
8153
- fs26.writeFileSync(sessionBase + ".summary.txt", readable, "utf-8");
8153
+ fs22.writeFileSync(sessionBase + ".summary.txt", readable, "utf-8");
8154
8154
  log(`\u{1F4BE} Complete session history saved:`);
8155
8155
  log(` - Contains ALL ${fullHistory.length} messages (prompts + responses)`);
8156
8156
  } catch (error) {
@@ -8159,11 +8159,11 @@ ${"=".repeat(60)}
8159
8159
  }
8160
8160
  if (process.env.VISOR_DEBUG_AI_SESSIONS === "true") {
8161
8161
  try {
8162
- const fs26 = require("fs");
8163
- const path30 = require("path");
8162
+ const fs22 = require("fs");
8163
+ const path26 = require("path");
8164
8164
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
8165
- const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path30.join(process.cwd(), "debug-artifacts");
8166
- const responseFile = path30.join(
8165
+ const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path26.join(process.cwd(), "debug-artifacts");
8166
+ const responseFile = path26.join(
8167
8167
  debugArtifactsDir,
8168
8168
  `response-${_checkName || "unknown"}-${timestamp}.txt`
8169
8169
  );
@@ -8196,7 +8196,7 @@ ${"=".repeat(60)}
8196
8196
  `;
8197
8197
  responseContent += `${"=".repeat(60)}
8198
8198
  `;
8199
- fs26.writeFileSync(responseFile, responseContent, "utf-8");
8199
+ fs22.writeFileSync(responseFile, responseContent, "utf-8");
8200
8200
  log(`\u{1F4BE} Response saved to: ${responseFile}`);
8201
8201
  } catch (error) {
8202
8202
  log(`\u26A0\uFE0F Could not save response file: ${error}`);
@@ -8212,9 +8212,9 @@ ${"=".repeat(60)}
8212
8212
  await agentAny._telemetryConfig.shutdown();
8213
8213
  log(`\u{1F4CA} OpenTelemetry trace saved to: ${agentAny._traceFilePath}`);
8214
8214
  if (process.env.GITHUB_ACTIONS) {
8215
- const fs26 = require("fs");
8216
- if (fs26.existsSync(agentAny._traceFilePath)) {
8217
- const stats = fs26.statSync(agentAny._traceFilePath);
8215
+ const fs22 = require("fs");
8216
+ if (fs22.existsSync(agentAny._traceFilePath)) {
8217
+ const stats = fs22.statSync(agentAny._traceFilePath);
8218
8218
  console.log(
8219
8219
  `::notice title=AI Trace Saved::${agentAny._traceFilePath} (${stats.size} bytes)`
8220
8220
  );
@@ -8415,9 +8415,9 @@ ${schemaString}`);
8415
8415
  const model = this.config.model || "default";
8416
8416
  if (process.env.VISOR_DEBUG_AI_SESSIONS === "true") {
8417
8417
  try {
8418
- const fs26 = require("fs");
8419
- const path30 = require("path");
8420
- const os3 = require("os");
8418
+ const fs22 = require("fs");
8419
+ const path26 = require("path");
8420
+ const os2 = require("os");
8421
8421
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
8422
8422
  const debugData = {
8423
8423
  timestamp,
@@ -8489,19 +8489,19 @@ ${"=".repeat(60)}
8489
8489
  `;
8490
8490
  readableVersion += `${"=".repeat(60)}
8491
8491
  `;
8492
- const tempDir = os3.tmpdir();
8493
- const promptFile = path30.join(tempDir, `visor-prompt-${timestamp}.txt`);
8494
- fs26.writeFileSync(promptFile, prompt, "utf-8");
8492
+ const tempDir = os2.tmpdir();
8493
+ const promptFile = path26.join(tempDir, `visor-prompt-${timestamp}.txt`);
8494
+ fs22.writeFileSync(promptFile, prompt, "utf-8");
8495
8495
  log(`
8496
8496
  \u{1F4BE} Prompt saved to: ${promptFile}`);
8497
- const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path30.join(process.cwd(), "debug-artifacts");
8497
+ const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path26.join(process.cwd(), "debug-artifacts");
8498
8498
  try {
8499
- const base = path30.join(
8499
+ const base = path26.join(
8500
8500
  debugArtifactsDir,
8501
8501
  `prompt-${_checkName || "unknown"}-${timestamp}`
8502
8502
  );
8503
- fs26.writeFileSync(base + ".json", debugJson, "utf-8");
8504
- fs26.writeFileSync(base + ".summary.txt", readableVersion, "utf-8");
8503
+ fs22.writeFileSync(base + ".json", debugJson, "utf-8");
8504
+ fs22.writeFileSync(base + ".summary.txt", readableVersion, "utf-8");
8505
8505
  log(`
8506
8506
  \u{1F4BE} Full debug info saved to directory: ${debugArtifactsDir}`);
8507
8507
  } catch {
@@ -8546,8 +8546,8 @@ $ ${cliCommand}
8546
8546
  log(`\u{1F4E4} Response length: ${response.length} characters`);
8547
8547
  if (process.env.VISOR_DEBUG_AI_SESSIONS === "true") {
8548
8548
  try {
8549
- const fs26 = require("fs");
8550
- const path30 = require("path");
8549
+ const fs22 = require("fs");
8550
+ const path26 = require("path");
8551
8551
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
8552
8552
  const agentAny = agent;
8553
8553
  let fullHistory = [];
@@ -8558,8 +8558,8 @@ $ ${cliCommand}
8558
8558
  } else if (agentAny._messages) {
8559
8559
  fullHistory = agentAny._messages;
8560
8560
  }
8561
- const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path30.join(process.cwd(), "debug-artifacts");
8562
- const sessionBase = path30.join(
8561
+ const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path26.join(process.cwd(), "debug-artifacts");
8562
+ const sessionBase = path26.join(
8563
8563
  debugArtifactsDir,
8564
8564
  `session-${_checkName || "unknown"}-${timestamp}`
8565
8565
  );
@@ -8571,7 +8571,7 @@ $ ${cliCommand}
8571
8571
  schema: effectiveSchema,
8572
8572
  totalMessages: fullHistory.length
8573
8573
  };
8574
- fs26.writeFileSync(sessionBase + ".json", JSON.stringify(sessionData, null, 2), "utf-8");
8574
+ fs22.writeFileSync(sessionBase + ".json", JSON.stringify(sessionData, null, 2), "utf-8");
8575
8575
  let readable = `=============================================================
8576
8576
  `;
8577
8577
  readable += `COMPLETE AI SESSION HISTORY (AFTER RESPONSE)
@@ -8598,7 +8598,7 @@ ${"=".repeat(60)}
8598
8598
  `;
8599
8599
  readable += content + "\n";
8600
8600
  });
8601
- fs26.writeFileSync(sessionBase + ".summary.txt", readable, "utf-8");
8601
+ fs22.writeFileSync(sessionBase + ".summary.txt", readable, "utf-8");
8602
8602
  log(`\u{1F4BE} Complete session history saved:`);
8603
8603
  log(` - Contains ALL ${fullHistory.length} messages (prompts + responses)`);
8604
8604
  } catch (error) {
@@ -8607,11 +8607,11 @@ ${"=".repeat(60)}
8607
8607
  }
8608
8608
  if (process.env.VISOR_DEBUG_AI_SESSIONS === "true") {
8609
8609
  try {
8610
- const fs26 = require("fs");
8611
- const path30 = require("path");
8610
+ const fs22 = require("fs");
8611
+ const path26 = require("path");
8612
8612
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
8613
- const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path30.join(process.cwd(), "debug-artifacts");
8614
- const responseFile = path30.join(
8613
+ const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path26.join(process.cwd(), "debug-artifacts");
8614
+ const responseFile = path26.join(
8615
8615
  debugArtifactsDir,
8616
8616
  `response-${_checkName || "unknown"}-${timestamp}.txt`
8617
8617
  );
@@ -8644,7 +8644,7 @@ ${"=".repeat(60)}
8644
8644
  `;
8645
8645
  responseContent += `${"=".repeat(60)}
8646
8646
  `;
8647
- fs26.writeFileSync(responseFile, responseContent, "utf-8");
8647
+ fs22.writeFileSync(responseFile, responseContent, "utf-8");
8648
8648
  log(`\u{1F4BE} Response saved to: ${responseFile}`);
8649
8649
  } catch (error) {
8650
8650
  log(`\u26A0\uFE0F Could not save response file: ${error}`);
@@ -8662,9 +8662,9 @@ ${"=".repeat(60)}
8662
8662
  await telemetry.shutdown();
8663
8663
  log(`\u{1F4CA} OpenTelemetry trace saved to: ${traceFilePath}`);
8664
8664
  if (process.env.GITHUB_ACTIONS) {
8665
- const fs26 = require("fs");
8666
- if (fs26.existsSync(traceFilePath)) {
8667
- const stats = fs26.statSync(traceFilePath);
8665
+ const fs22 = require("fs");
8666
+ if (fs22.existsSync(traceFilePath)) {
8667
+ const stats = fs22.statSync(traceFilePath);
8668
8668
  console.log(
8669
8669
  `::notice title=AI Trace Saved::OpenTelemetry trace file size: ${stats.size} bytes`
8670
8670
  );
@@ -8702,8 +8702,8 @@ ${"=".repeat(60)}
8702
8702
  * Load schema content from schema files or inline definitions
8703
8703
  */
8704
8704
  async loadSchemaContent(schema) {
8705
- const fs26 = require("fs").promises;
8706
- const path30 = require("path");
8705
+ const fs22 = require("fs").promises;
8706
+ const path26 = require("path");
8707
8707
  if (typeof schema === "object" && schema !== null) {
8708
8708
  log("\u{1F4CB} Using inline schema object from configuration");
8709
8709
  return JSON.stringify(schema);
@@ -8716,14 +8716,14 @@ ${"=".repeat(60)}
8716
8716
  }
8717
8717
  } catch {
8718
8718
  }
8719
- if ((schema.startsWith("./") || schema.includes(".json")) && !path30.isAbsolute(schema)) {
8719
+ if ((schema.startsWith("./") || schema.includes(".json")) && !path26.isAbsolute(schema)) {
8720
8720
  if (schema.includes("..") || schema.includes("\0")) {
8721
8721
  throw new Error("Invalid schema path: path traversal not allowed");
8722
8722
  }
8723
8723
  try {
8724
- const schemaPath = path30.resolve(process.cwd(), schema);
8724
+ const schemaPath = path26.resolve(process.cwd(), schema);
8725
8725
  log(`\u{1F4CB} Loading custom schema from file: ${schemaPath}`);
8726
- const schemaContent = await fs26.readFile(schemaPath, "utf-8");
8726
+ const schemaContent = await fs22.readFile(schemaPath, "utf-8");
8727
8727
  return schemaContent.trim();
8728
8728
  } catch (error) {
8729
8729
  throw new Error(
@@ -8737,22 +8737,22 @@ ${"=".repeat(60)}
8737
8737
  }
8738
8738
  const candidatePaths = [
8739
8739
  // GitHub Action bundle location
8740
- path30.join(__dirname, "output", sanitizedSchemaName, "schema.json"),
8740
+ path26.join(__dirname, "output", sanitizedSchemaName, "schema.json"),
8741
8741
  // Historical fallback when src/output was inadvertently bundled as output1/
8742
- path30.join(__dirname, "output1", sanitizedSchemaName, "schema.json"),
8742
+ path26.join(__dirname, "output1", sanitizedSchemaName, "schema.json"),
8743
8743
  // Local dev (repo root)
8744
- path30.join(process.cwd(), "output", sanitizedSchemaName, "schema.json")
8744
+ path26.join(process.cwd(), "output", sanitizedSchemaName, "schema.json")
8745
8745
  ];
8746
8746
  for (const schemaPath of candidatePaths) {
8747
8747
  try {
8748
- const schemaContent = await fs26.readFile(schemaPath, "utf-8");
8748
+ const schemaContent = await fs22.readFile(schemaPath, "utf-8");
8749
8749
  return schemaContent.trim();
8750
8750
  } catch {
8751
8751
  }
8752
8752
  }
8753
- const distPath = path30.join(__dirname, "output", sanitizedSchemaName, "schema.json");
8754
- const distAltPath = path30.join(__dirname, "output1", sanitizedSchemaName, "schema.json");
8755
- const cwdPath = path30.join(process.cwd(), "output", sanitizedSchemaName, "schema.json");
8753
+ const distPath = path26.join(__dirname, "output", sanitizedSchemaName, "schema.json");
8754
+ const distAltPath = path26.join(__dirname, "output1", sanitizedSchemaName, "schema.json");
8755
+ const cwdPath = path26.join(process.cwd(), "output", sanitizedSchemaName, "schema.json");
8756
8756
  throw new Error(
8757
8757
  `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.`
8758
8758
  );
@@ -8987,7 +8987,7 @@ ${"=".repeat(60)}
8987
8987
  * Generate mock response for testing
8988
8988
  */
8989
8989
  async generateMockResponse(_prompt, _checkName, _schema) {
8990
- await new Promise((resolve15) => setTimeout(resolve15, 500));
8990
+ await new Promise((resolve11) => setTimeout(resolve11, 500));
8991
8991
  const name = (_checkName || "").toLowerCase();
8992
8992
  if (name.includes("extract-facts")) {
8993
8993
  const arr = Array.from({ length: 6 }, (_, i) => ({
@@ -9348,7 +9348,7 @@ var init_command_executor = __esm({
9348
9348
  * Execute command with stdin input
9349
9349
  */
9350
9350
  executeWithStdin(command, options) {
9351
- return new Promise((resolve15, reject) => {
9351
+ return new Promise((resolve11, reject) => {
9352
9352
  const childProcess = (0, import_child_process.exec)(
9353
9353
  command,
9354
9354
  {
@@ -9360,7 +9360,7 @@ var init_command_executor = __esm({
9360
9360
  if (error && error.killed && (error.code === "ETIMEDOUT" || error.signal === "SIGTERM")) {
9361
9361
  reject(new Error(`Command timed out after ${options.timeout || 3e4}ms`));
9362
9362
  } else {
9363
- resolve15({
9363
+ resolve11({
9364
9364
  stdout: stdout || "",
9365
9365
  stderr: stderr || "",
9366
9366
  exitCode: error ? error.code || 1 : 0
@@ -17137,17 +17137,17 @@ var init_workflow_check_provider = __esm({
17137
17137
  * so it can be executed by the state machine as a nested workflow.
17138
17138
  */
17139
17139
  async loadWorkflowFromConfigPath(sourcePath, baseDir) {
17140
- const path30 = require("path");
17141
- const fs26 = require("fs");
17140
+ const path26 = require("path");
17141
+ const fs22 = require("fs");
17142
17142
  const yaml5 = require("js-yaml");
17143
- const resolved = path30.isAbsolute(sourcePath) ? sourcePath : path30.resolve(baseDir, sourcePath);
17144
- if (!fs26.existsSync(resolved)) {
17143
+ const resolved = path26.isAbsolute(sourcePath) ? sourcePath : path26.resolve(baseDir, sourcePath);
17144
+ if (!fs22.existsSync(resolved)) {
17145
17145
  throw new Error(`Workflow config not found at: ${resolved}`);
17146
17146
  }
17147
- const rawContent = fs26.readFileSync(resolved, "utf8");
17147
+ const rawContent = fs22.readFileSync(resolved, "utf8");
17148
17148
  const rawData = yaml5.load(rawContent);
17149
17149
  if (rawData.imports && Array.isArray(rawData.imports)) {
17150
- const configDir = path30.dirname(resolved);
17150
+ const configDir = path26.dirname(resolved);
17151
17151
  for (const source of rawData.imports) {
17152
17152
  const results = await this.registry.import(source, {
17153
17153
  basePath: configDir,
@@ -17177,8 +17177,8 @@ ${errors}`);
17177
17177
  if (!steps || Object.keys(steps).length === 0) {
17178
17178
  throw new Error(`Config '${resolved}' does not contain any steps to execute as a workflow`);
17179
17179
  }
17180
- const id = path30.basename(resolved).replace(/\.(ya?ml)$/i, "");
17181
- const name = loaded.name || `Workflow from ${path30.basename(resolved)}`;
17180
+ const id = path26.basename(resolved).replace(/\.(ya?ml)$/i, "");
17181
+ const name = loaded.name || `Workflow from ${path26.basename(resolved)}`;
17182
17182
  const workflowDef = {
17183
17183
  id,
17184
17184
  name,
@@ -17807,8 +17807,8 @@ async function createStoreBackend(storageConfig, haConfig) {
17807
17807
  case "mssql": {
17808
17808
  try {
17809
17809
  const loaderPath = "../../enterprise/loader";
17810
- const { loadEnterpriseStoreBackend: loadEnterpriseStoreBackend2 } = await import(loaderPath);
17811
- return await loadEnterpriseStoreBackend2(driver, storageConfig, haConfig);
17810
+ const { loadEnterpriseStoreBackend } = await import(loaderPath);
17811
+ return await loadEnterpriseStoreBackend(driver, storageConfig, haConfig);
17812
17812
  } catch (err) {
17813
17813
  const msg = err instanceof Error ? err.message : String(err);
17814
17814
  logger.error(`[StoreFactory] Failed to load enterprise ${driver} backend: ${msg}`);
@@ -19082,7 +19082,7 @@ var init_mcp_custom_sse_server = __esm({
19082
19082
  * Returns the actual bound port number
19083
19083
  */
19084
19084
  async start() {
19085
- return new Promise((resolve15, reject) => {
19085
+ return new Promise((resolve11, reject) => {
19086
19086
  try {
19087
19087
  this.server = import_http.default.createServer((req, res) => {
19088
19088
  this.handleRequest(req, res).catch((error) => {
@@ -19116,7 +19116,7 @@ var init_mcp_custom_sse_server = __esm({
19116
19116
  );
19117
19117
  }
19118
19118
  this.startKeepalive();
19119
- resolve15(this.port);
19119
+ resolve11(this.port);
19120
19120
  });
19121
19121
  } catch (error) {
19122
19122
  reject(error);
@@ -19179,7 +19179,7 @@ var init_mcp_custom_sse_server = __esm({
19179
19179
  logger.debug(
19180
19180
  `[CustomToolsSSEServer:${this.sessionId}] Grace period before stop: ${waitMs}ms (activeToolCalls=${this.activeToolCalls})`
19181
19181
  );
19182
- await new Promise((resolve15) => setTimeout(resolve15, waitMs));
19182
+ await new Promise((resolve11) => setTimeout(resolve11, waitMs));
19183
19183
  }
19184
19184
  }
19185
19185
  if (this.activeToolCalls > 0) {
@@ -19188,7 +19188,7 @@ var init_mcp_custom_sse_server = __esm({
19188
19188
  `[CustomToolsSSEServer:${this.sessionId}] Waiting for ${this.activeToolCalls} active tool call(s) before stop`
19189
19189
  );
19190
19190
  while (this.activeToolCalls > 0 && Date.now() - startedAt < effectiveDrainTimeoutMs) {
19191
- await new Promise((resolve15) => setTimeout(resolve15, 250));
19191
+ await new Promise((resolve11) => setTimeout(resolve11, 250));
19192
19192
  }
19193
19193
  if (this.activeToolCalls > 0) {
19194
19194
  logger.warn(
@@ -19213,21 +19213,21 @@ var init_mcp_custom_sse_server = __esm({
19213
19213
  }
19214
19214
  this.connections.clear();
19215
19215
  if (this.server) {
19216
- await new Promise((resolve15, reject) => {
19216
+ await new Promise((resolve11, reject) => {
19217
19217
  const timeout = setTimeout(() => {
19218
19218
  if (this.debug) {
19219
19219
  logger.debug(
19220
19220
  `[CustomToolsSSEServer:${this.sessionId}] Force closing server after timeout`
19221
19221
  );
19222
19222
  }
19223
- this.server?.close(() => resolve15());
19223
+ this.server?.close(() => resolve11());
19224
19224
  }, 5e3);
19225
19225
  this.server.close((error) => {
19226
19226
  clearTimeout(timeout);
19227
19227
  if (error) {
19228
19228
  reject(error);
19229
19229
  } else {
19230
- resolve15();
19230
+ resolve11();
19231
19231
  }
19232
19232
  });
19233
19233
  });
@@ -19653,7 +19653,7 @@ var init_mcp_custom_sse_server = __esm({
19653
19653
  logger.warn(
19654
19654
  `[CustomToolsSSEServer:${this.sessionId}] Tool ${toolName} failed (attempt ${attempt + 1}/${retryCount + 1}): ${errorMsg}. Retrying in ${delay}ms`
19655
19655
  );
19656
- await new Promise((resolve15) => setTimeout(resolve15, delay));
19656
+ await new Promise((resolve11) => setTimeout(resolve11, delay));
19657
19657
  attempt++;
19658
19658
  }
19659
19659
  }
@@ -19956,9 +19956,9 @@ var init_ai_check_provider = __esm({
19956
19956
  } else {
19957
19957
  resolvedPath = import_path7.default.resolve(process.cwd(), str);
19958
19958
  }
19959
- const fs26 = require("fs").promises;
19959
+ const fs22 = require("fs").promises;
19960
19960
  try {
19961
- const stat = await fs26.stat(resolvedPath);
19961
+ const stat = await fs22.stat(resolvedPath);
19962
19962
  return stat.isFile();
19963
19963
  } catch {
19964
19964
  return hasFileExtension && (isRelativePath || isAbsolutePath || hasPathSeparators);
@@ -25810,14 +25810,14 @@ var require_util = __commonJS({
25810
25810
  }
25811
25811
  const port = url.port != null ? url.port : url.protocol === "https:" ? 443 : 80;
25812
25812
  let origin = url.origin != null ? url.origin : `${url.protocol}//${url.hostname}:${port}`;
25813
- let path30 = url.path != null ? url.path : `${url.pathname || ""}${url.search || ""}`;
25813
+ let path26 = url.path != null ? url.path : `${url.pathname || ""}${url.search || ""}`;
25814
25814
  if (origin.endsWith("/")) {
25815
25815
  origin = origin.substring(0, origin.length - 1);
25816
25816
  }
25817
- if (path30 && !path30.startsWith("/")) {
25818
- path30 = `/${path30}`;
25817
+ if (path26 && !path26.startsWith("/")) {
25818
+ path26 = `/${path26}`;
25819
25819
  }
25820
- url = new URL(origin + path30);
25820
+ url = new URL(origin + path26);
25821
25821
  }
25822
25822
  return url;
25823
25823
  }
@@ -27431,20 +27431,20 @@ var require_parseParams = __commonJS({
27431
27431
  var require_basename = __commonJS({
27432
27432
  "node_modules/@fastify/busboy/lib/utils/basename.js"(exports2, module2) {
27433
27433
  "use strict";
27434
- module2.exports = function basename4(path30) {
27435
- if (typeof path30 !== "string") {
27434
+ module2.exports = function basename4(path26) {
27435
+ if (typeof path26 !== "string") {
27436
27436
  return "";
27437
27437
  }
27438
- for (var i = path30.length - 1; i >= 0; --i) {
27439
- switch (path30.charCodeAt(i)) {
27438
+ for (var i = path26.length - 1; i >= 0; --i) {
27439
+ switch (path26.charCodeAt(i)) {
27440
27440
  case 47:
27441
27441
  // '/'
27442
27442
  case 92:
27443
- path30 = path30.slice(i + 1);
27444
- return path30 === ".." || path30 === "." ? "" : path30;
27443
+ path26 = path26.slice(i + 1);
27444
+ return path26 === ".." || path26 === "." ? "" : path26;
27445
27445
  }
27446
27446
  }
27447
- return path30 === ".." || path30 === "." ? "" : path30;
27447
+ return path26 === ".." || path26 === "." ? "" : path26;
27448
27448
  };
27449
27449
  }
27450
27450
  });
@@ -28448,11 +28448,11 @@ var require_util2 = __commonJS({
28448
28448
  var assert = require("assert");
28449
28449
  var { isUint8Array } = require("util/types");
28450
28450
  var supportedHashes = [];
28451
- var crypto4;
28451
+ var crypto2;
28452
28452
  try {
28453
- crypto4 = require("crypto");
28453
+ crypto2 = require("crypto");
28454
28454
  const possibleRelevantHashes = ["sha256", "sha384", "sha512"];
28455
- supportedHashes = crypto4.getHashes().filter((hash) => possibleRelevantHashes.includes(hash));
28455
+ supportedHashes = crypto2.getHashes().filter((hash) => possibleRelevantHashes.includes(hash));
28456
28456
  } catch {
28457
28457
  }
28458
28458
  function responseURL(response) {
@@ -28729,7 +28729,7 @@ var require_util2 = __commonJS({
28729
28729
  }
28730
28730
  }
28731
28731
  function bytesMatch(bytes, metadataList) {
28732
- if (crypto4 === void 0) {
28732
+ if (crypto2 === void 0) {
28733
28733
  return true;
28734
28734
  }
28735
28735
  const parsedMetadata = parseMetadata(metadataList);
@@ -28744,7 +28744,7 @@ var require_util2 = __commonJS({
28744
28744
  for (const item of metadata) {
28745
28745
  const algorithm = item.algo;
28746
28746
  const expectedValue = item.hash;
28747
- let actualValue = crypto4.createHash(algorithm).update(bytes).digest("base64");
28747
+ let actualValue = crypto2.createHash(algorithm).update(bytes).digest("base64");
28748
28748
  if (actualValue[actualValue.length - 1] === "=") {
28749
28749
  if (actualValue[actualValue.length - 2] === "=") {
28750
28750
  actualValue = actualValue.slice(0, -2);
@@ -28837,8 +28837,8 @@ var require_util2 = __commonJS({
28837
28837
  function createDeferredPromise() {
28838
28838
  let res;
28839
28839
  let rej;
28840
- const promise = new Promise((resolve15, reject) => {
28841
- res = resolve15;
28840
+ const promise = new Promise((resolve11, reject) => {
28841
+ res = resolve11;
28842
28842
  rej = reject;
28843
28843
  });
28844
28844
  return { promise, resolve: res, reject: rej };
@@ -30091,8 +30091,8 @@ var require_body = __commonJS({
30091
30091
  var { parseMIMEType, serializeAMimeType } = require_dataURL();
30092
30092
  var random;
30093
30093
  try {
30094
- const crypto4 = require("crypto");
30095
- random = (max) => crypto4.randomInt(0, max);
30094
+ const crypto2 = require("crypto");
30095
+ random = (max) => crypto2.randomInt(0, max);
30096
30096
  } catch {
30097
30097
  random = (max) => Math.floor(Math.random(max));
30098
30098
  }
@@ -30343,8 +30343,8 @@ Content-Type: ${value.type || "application/octet-stream"}\r
30343
30343
  });
30344
30344
  }
30345
30345
  });
30346
- const busboyResolve = new Promise((resolve15, reject) => {
30347
- busboy.on("finish", resolve15);
30346
+ const busboyResolve = new Promise((resolve11, reject) => {
30347
+ busboy.on("finish", resolve11);
30348
30348
  busboy.on("error", (err) => reject(new TypeError(err)));
30349
30349
  });
30350
30350
  if (this.body !== null) for await (const chunk of consumeBody(this[kState].body)) busboy.write(chunk);
@@ -30475,7 +30475,7 @@ var require_request = __commonJS({
30475
30475
  }
30476
30476
  var Request = class _Request {
30477
30477
  constructor(origin, {
30478
- path: path30,
30478
+ path: path26,
30479
30479
  method,
30480
30480
  body,
30481
30481
  headers,
@@ -30489,11 +30489,11 @@ var require_request = __commonJS({
30489
30489
  throwOnError,
30490
30490
  expectContinue
30491
30491
  }, handler) {
30492
- if (typeof path30 !== "string") {
30492
+ if (typeof path26 !== "string") {
30493
30493
  throw new InvalidArgumentError("path must be a string");
30494
- } else if (path30[0] !== "/" && !(path30.startsWith("http://") || path30.startsWith("https://")) && method !== "CONNECT") {
30494
+ } else if (path26[0] !== "/" && !(path26.startsWith("http://") || path26.startsWith("https://")) && method !== "CONNECT") {
30495
30495
  throw new InvalidArgumentError("path must be an absolute URL or start with a slash");
30496
- } else if (invalidPathRegex.exec(path30) !== null) {
30496
+ } else if (invalidPathRegex.exec(path26) !== null) {
30497
30497
  throw new InvalidArgumentError("invalid request path");
30498
30498
  }
30499
30499
  if (typeof method !== "string") {
@@ -30556,7 +30556,7 @@ var require_request = __commonJS({
30556
30556
  this.completed = false;
30557
30557
  this.aborted = false;
30558
30558
  this.upgrade = upgrade || null;
30559
- this.path = query ? util.buildURL(path30, query) : path30;
30559
+ this.path = query ? util.buildURL(path26, query) : path26;
30560
30560
  this.origin = origin;
30561
30561
  this.idempotent = idempotent == null ? method === "HEAD" || method === "GET" : idempotent;
30562
30562
  this.blocking = blocking == null ? false : blocking;
@@ -30878,9 +30878,9 @@ var require_dispatcher_base = __commonJS({
30878
30878
  }
30879
30879
  close(callback) {
30880
30880
  if (callback === void 0) {
30881
- return new Promise((resolve15, reject) => {
30881
+ return new Promise((resolve11, reject) => {
30882
30882
  this.close((err, data) => {
30883
- return err ? reject(err) : resolve15(data);
30883
+ return err ? reject(err) : resolve11(data);
30884
30884
  });
30885
30885
  });
30886
30886
  }
@@ -30918,12 +30918,12 @@ var require_dispatcher_base = __commonJS({
30918
30918
  err = null;
30919
30919
  }
30920
30920
  if (callback === void 0) {
30921
- return new Promise((resolve15, reject) => {
30921
+ return new Promise((resolve11, reject) => {
30922
30922
  this.destroy(err, (err2, data) => {
30923
30923
  return err2 ? (
30924
30924
  /* istanbul ignore next: should never error */
30925
30925
  reject(err2)
30926
- ) : resolve15(data);
30926
+ ) : resolve11(data);
30927
30927
  });
30928
30928
  });
30929
30929
  }
@@ -31564,9 +31564,9 @@ var require_RedirectHandler = __commonJS({
31564
31564
  return this.handler.onHeaders(statusCode, headers, resume, statusText);
31565
31565
  }
31566
31566
  const { origin, pathname, search } = util.parseURL(new URL(this.location, this.opts.origin && new URL(this.opts.path, this.opts.origin)));
31567
- const path30 = search ? `${pathname}${search}` : pathname;
31567
+ const path26 = search ? `${pathname}${search}` : pathname;
31568
31568
  this.opts.headers = cleanRequestHeaders(this.opts.headers, statusCode === 303, this.opts.origin !== origin);
31569
- this.opts.path = path30;
31569
+ this.opts.path = path26;
31570
31570
  this.opts.origin = origin;
31571
31571
  this.opts.maxRedirections = 0;
31572
31572
  this.opts.query = null;
@@ -31985,16 +31985,16 @@ var require_client = __commonJS({
31985
31985
  return this[kNeedDrain] < 2;
31986
31986
  }
31987
31987
  async [kClose]() {
31988
- return new Promise((resolve15) => {
31988
+ return new Promise((resolve11) => {
31989
31989
  if (!this[kSize]) {
31990
- resolve15(null);
31990
+ resolve11(null);
31991
31991
  } else {
31992
- this[kClosedResolve] = resolve15;
31992
+ this[kClosedResolve] = resolve11;
31993
31993
  }
31994
31994
  });
31995
31995
  }
31996
31996
  async [kDestroy](err) {
31997
- return new Promise((resolve15) => {
31997
+ return new Promise((resolve11) => {
31998
31998
  const requests = this[kQueue].splice(this[kPendingIdx]);
31999
31999
  for (let i = 0; i < requests.length; i++) {
32000
32000
  const request = requests[i];
@@ -32005,7 +32005,7 @@ var require_client = __commonJS({
32005
32005
  this[kClosedResolve]();
32006
32006
  this[kClosedResolve] = null;
32007
32007
  }
32008
- resolve15();
32008
+ resolve11();
32009
32009
  };
32010
32010
  if (this[kHTTP2Session] != null) {
32011
32011
  util.destroy(this[kHTTP2Session], err);
@@ -32585,7 +32585,7 @@ var require_client = __commonJS({
32585
32585
  });
32586
32586
  }
32587
32587
  try {
32588
- const socket = await new Promise((resolve15, reject) => {
32588
+ const socket = await new Promise((resolve11, reject) => {
32589
32589
  client[kConnector]({
32590
32590
  host,
32591
32591
  hostname,
@@ -32597,7 +32597,7 @@ var require_client = __commonJS({
32597
32597
  if (err) {
32598
32598
  reject(err);
32599
32599
  } else {
32600
- resolve15(socket2);
32600
+ resolve11(socket2);
32601
32601
  }
32602
32602
  });
32603
32603
  });
@@ -32808,7 +32808,7 @@ var require_client = __commonJS({
32808
32808
  writeH2(client, client[kHTTP2Session], request);
32809
32809
  return;
32810
32810
  }
32811
- const { body, method, path: path30, host, upgrade, headers, blocking, reset } = request;
32811
+ const { body, method, path: path26, host, upgrade, headers, blocking, reset } = request;
32812
32812
  const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH";
32813
32813
  if (body && typeof body.read === "function") {
32814
32814
  body.read(0);
@@ -32858,7 +32858,7 @@ var require_client = __commonJS({
32858
32858
  if (blocking) {
32859
32859
  socket[kBlocking] = true;
32860
32860
  }
32861
- let header = `${method} ${path30} HTTP/1.1\r
32861
+ let header = `${method} ${path26} HTTP/1.1\r
32862
32862
  `;
32863
32863
  if (typeof host === "string") {
32864
32864
  header += `host: ${host}\r
@@ -32921,7 +32921,7 @@ upgrade: ${upgrade}\r
32921
32921
  return true;
32922
32922
  }
32923
32923
  function writeH2(client, session, request) {
32924
- const { body, method, path: path30, host, upgrade, expectContinue, signal, headers: reqHeaders } = request;
32924
+ const { body, method, path: path26, host, upgrade, expectContinue, signal, headers: reqHeaders } = request;
32925
32925
  let headers;
32926
32926
  if (typeof reqHeaders === "string") headers = Request[kHTTP2CopyHeaders](reqHeaders.trim());
32927
32927
  else headers = reqHeaders;
@@ -32964,7 +32964,7 @@ upgrade: ${upgrade}\r
32964
32964
  });
32965
32965
  return true;
32966
32966
  }
32967
- headers[HTTP2_HEADER_PATH] = path30;
32967
+ headers[HTTP2_HEADER_PATH] = path26;
32968
32968
  headers[HTTP2_HEADER_SCHEME] = "https";
32969
32969
  const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH";
32970
32970
  if (body && typeof body.read === "function") {
@@ -33221,12 +33221,12 @@ upgrade: ${upgrade}\r
33221
33221
  cb();
33222
33222
  }
33223
33223
  }
33224
- const waitForDrain = () => new Promise((resolve15, reject) => {
33224
+ const waitForDrain = () => new Promise((resolve11, reject) => {
33225
33225
  assert(callback === null);
33226
33226
  if (socket[kError]) {
33227
33227
  reject(socket[kError]);
33228
33228
  } else {
33229
- callback = resolve15;
33229
+ callback = resolve11;
33230
33230
  }
33231
33231
  });
33232
33232
  if (client[kHTTPConnVersion] === "h2") {
@@ -33572,8 +33572,8 @@ var require_pool_base = __commonJS({
33572
33572
  if (this[kQueue].isEmpty()) {
33573
33573
  return Promise.all(this[kClients].map((c) => c.close()));
33574
33574
  } else {
33575
- return new Promise((resolve15) => {
33576
- this[kClosedResolve] = resolve15;
33575
+ return new Promise((resolve11) => {
33576
+ this[kClosedResolve] = resolve11;
33577
33577
  });
33578
33578
  }
33579
33579
  }
@@ -34151,7 +34151,7 @@ var require_readable = __commonJS({
34151
34151
  if (this.closed) {
34152
34152
  return Promise.resolve(null);
34153
34153
  }
34154
- return new Promise((resolve15, reject) => {
34154
+ return new Promise((resolve11, reject) => {
34155
34155
  const signalListenerCleanup = signal ? util.addAbortListener(signal, () => {
34156
34156
  this.destroy();
34157
34157
  }) : noop;
@@ -34160,7 +34160,7 @@ var require_readable = __commonJS({
34160
34160
  if (signal && signal.aborted) {
34161
34161
  reject(signal.reason || Object.assign(new Error("The operation was aborted"), { name: "AbortError" }));
34162
34162
  } else {
34163
- resolve15(null);
34163
+ resolve11(null);
34164
34164
  }
34165
34165
  }).on("error", noop).on("data", function(chunk) {
34166
34166
  limit -= chunk.length;
@@ -34182,11 +34182,11 @@ var require_readable = __commonJS({
34182
34182
  throw new TypeError("unusable");
34183
34183
  }
34184
34184
  assert(!stream[kConsume]);
34185
- return new Promise((resolve15, reject) => {
34185
+ return new Promise((resolve11, reject) => {
34186
34186
  stream[kConsume] = {
34187
34187
  type,
34188
34188
  stream,
34189
- resolve: resolve15,
34189
+ resolve: resolve11,
34190
34190
  reject,
34191
34191
  length: 0,
34192
34192
  body: []
@@ -34221,12 +34221,12 @@ var require_readable = __commonJS({
34221
34221
  }
34222
34222
  }
34223
34223
  function consumeEnd(consume2) {
34224
- const { type, body, resolve: resolve15, stream, length } = consume2;
34224
+ const { type, body, resolve: resolve11, stream, length } = consume2;
34225
34225
  try {
34226
34226
  if (type === "text") {
34227
- resolve15(toUSVString(Buffer.concat(body)));
34227
+ resolve11(toUSVString(Buffer.concat(body)));
34228
34228
  } else if (type === "json") {
34229
- resolve15(JSON.parse(Buffer.concat(body)));
34229
+ resolve11(JSON.parse(Buffer.concat(body)));
34230
34230
  } else if (type === "arrayBuffer") {
34231
34231
  const dst = new Uint8Array(length);
34232
34232
  let pos = 0;
@@ -34234,12 +34234,12 @@ var require_readable = __commonJS({
34234
34234
  dst.set(buf, pos);
34235
34235
  pos += buf.byteLength;
34236
34236
  }
34237
- resolve15(dst.buffer);
34237
+ resolve11(dst.buffer);
34238
34238
  } else if (type === "blob") {
34239
34239
  if (!Blob2) {
34240
34240
  Blob2 = require("buffer").Blob;
34241
34241
  }
34242
- resolve15(new Blob2(body, { type: stream[kContentType] }));
34242
+ resolve11(new Blob2(body, { type: stream[kContentType] }));
34243
34243
  }
34244
34244
  consumeFinish(consume2);
34245
34245
  } catch (err) {
@@ -34496,9 +34496,9 @@ var require_api_request = __commonJS({
34496
34496
  };
34497
34497
  function request(opts, callback) {
34498
34498
  if (callback === void 0) {
34499
- return new Promise((resolve15, reject) => {
34499
+ return new Promise((resolve11, reject) => {
34500
34500
  request.call(this, opts, (err, data) => {
34501
- return err ? reject(err) : resolve15(data);
34501
+ return err ? reject(err) : resolve11(data);
34502
34502
  });
34503
34503
  });
34504
34504
  }
@@ -34671,9 +34671,9 @@ var require_api_stream = __commonJS({
34671
34671
  };
34672
34672
  function stream(opts, factory, callback) {
34673
34673
  if (callback === void 0) {
34674
- return new Promise((resolve15, reject) => {
34674
+ return new Promise((resolve11, reject) => {
34675
34675
  stream.call(this, opts, factory, (err, data) => {
34676
- return err ? reject(err) : resolve15(data);
34676
+ return err ? reject(err) : resolve11(data);
34677
34677
  });
34678
34678
  });
34679
34679
  }
@@ -34954,9 +34954,9 @@ var require_api_upgrade = __commonJS({
34954
34954
  };
34955
34955
  function upgrade(opts, callback) {
34956
34956
  if (callback === void 0) {
34957
- return new Promise((resolve15, reject) => {
34957
+ return new Promise((resolve11, reject) => {
34958
34958
  upgrade.call(this, opts, (err, data) => {
34959
- return err ? reject(err) : resolve15(data);
34959
+ return err ? reject(err) : resolve11(data);
34960
34960
  });
34961
34961
  });
34962
34962
  }
@@ -35045,9 +35045,9 @@ var require_api_connect = __commonJS({
35045
35045
  };
35046
35046
  function connect(opts, callback) {
35047
35047
  if (callback === void 0) {
35048
- return new Promise((resolve15, reject) => {
35048
+ return new Promise((resolve11, reject) => {
35049
35049
  connect.call(this, opts, (err, data) => {
35050
- return err ? reject(err) : resolve15(data);
35050
+ return err ? reject(err) : resolve11(data);
35051
35051
  });
35052
35052
  });
35053
35053
  }
@@ -35207,20 +35207,20 @@ var require_mock_utils = __commonJS({
35207
35207
  }
35208
35208
  return true;
35209
35209
  }
35210
- function safeUrl(path30) {
35211
- if (typeof path30 !== "string") {
35212
- return path30;
35210
+ function safeUrl(path26) {
35211
+ if (typeof path26 !== "string") {
35212
+ return path26;
35213
35213
  }
35214
- const pathSegments = path30.split("?");
35214
+ const pathSegments = path26.split("?");
35215
35215
  if (pathSegments.length !== 2) {
35216
- return path30;
35216
+ return path26;
35217
35217
  }
35218
35218
  const qp = new URLSearchParams(pathSegments.pop());
35219
35219
  qp.sort();
35220
35220
  return [...pathSegments, qp.toString()].join("?");
35221
35221
  }
35222
- function matchKey(mockDispatch2, { path: path30, method, body, headers }) {
35223
- const pathMatch = matchValue(mockDispatch2.path, path30);
35222
+ function matchKey(mockDispatch2, { path: path26, method, body, headers }) {
35223
+ const pathMatch = matchValue(mockDispatch2.path, path26);
35224
35224
  const methodMatch = matchValue(mockDispatch2.method, method);
35225
35225
  const bodyMatch = typeof mockDispatch2.body !== "undefined" ? matchValue(mockDispatch2.body, body) : true;
35226
35226
  const headersMatch = matchHeaders(mockDispatch2, headers);
@@ -35238,7 +35238,7 @@ var require_mock_utils = __commonJS({
35238
35238
  function getMockDispatch(mockDispatches, key) {
35239
35239
  const basePath = key.query ? buildURL(key.path, key.query) : key.path;
35240
35240
  const resolvedPath = typeof basePath === "string" ? safeUrl(basePath) : basePath;
35241
- let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path: path30 }) => matchValue(safeUrl(path30), resolvedPath));
35241
+ let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path: path26 }) => matchValue(safeUrl(path26), resolvedPath));
35242
35242
  if (matchedMockDispatches.length === 0) {
35243
35243
  throw new MockNotMatchedError(`Mock dispatch not matched for path '${resolvedPath}'`);
35244
35244
  }
@@ -35275,9 +35275,9 @@ var require_mock_utils = __commonJS({
35275
35275
  }
35276
35276
  }
35277
35277
  function buildKey(opts) {
35278
- const { path: path30, method, body, headers, query } = opts;
35278
+ const { path: path26, method, body, headers, query } = opts;
35279
35279
  return {
35280
- path: path30,
35280
+ path: path26,
35281
35281
  method,
35282
35282
  body,
35283
35283
  headers,
@@ -35726,10 +35726,10 @@ var require_pending_interceptors_formatter = __commonJS({
35726
35726
  }
35727
35727
  format(pendingInterceptors) {
35728
35728
  const withPrettyHeaders = pendingInterceptors.map(
35729
- ({ method, path: path30, data: { statusCode }, persist, times, timesInvoked, origin }) => ({
35729
+ ({ method, path: path26, data: { statusCode }, persist, times, timesInvoked, origin }) => ({
35730
35730
  Method: method,
35731
35731
  Origin: origin,
35732
- Path: path30,
35732
+ Path: path26,
35733
35733
  "Status code": statusCode,
35734
35734
  Persistent: persist ? "\u2705" : "\u274C",
35735
35735
  Invocations: timesInvoked,
@@ -38670,7 +38670,7 @@ var require_fetch = __commonJS({
38670
38670
  async function dispatch({ body }) {
38671
38671
  const url = requestCurrentURL(request);
38672
38672
  const agent = fetchParams.controller.dispatcher;
38673
- return new Promise((resolve15, reject) => agent.dispatch(
38673
+ return new Promise((resolve11, reject) => agent.dispatch(
38674
38674
  {
38675
38675
  path: url.pathname + url.search,
38676
38676
  origin: url.origin,
@@ -38746,7 +38746,7 @@ var require_fetch = __commonJS({
38746
38746
  }
38747
38747
  }
38748
38748
  }
38749
- resolve15({
38749
+ resolve11({
38750
38750
  status,
38751
38751
  statusText,
38752
38752
  headersList: headers[kHeadersList],
@@ -38789,7 +38789,7 @@ var require_fetch = __commonJS({
38789
38789
  const val = headersList[n + 1].toString("latin1");
38790
38790
  headers[kHeadersList].append(key, val);
38791
38791
  }
38792
- resolve15({
38792
+ resolve11({
38793
38793
  status,
38794
38794
  statusText: STATUS_CODES[status],
38795
38795
  headersList: headers[kHeadersList],
@@ -40350,8 +40350,8 @@ var require_util6 = __commonJS({
40350
40350
  }
40351
40351
  }
40352
40352
  }
40353
- function validateCookiePath(path30) {
40354
- for (const char of path30) {
40353
+ function validateCookiePath(path26) {
40354
+ for (const char of path26) {
40355
40355
  const code = char.charCodeAt(0);
40356
40356
  if (code < 33 || char === ";") {
40357
40357
  throw new Error("Invalid cookie path");
@@ -41148,9 +41148,9 @@ var require_connection = __commonJS({
41148
41148
  channels.open = diagnosticsChannel.channel("undici:websocket:open");
41149
41149
  channels.close = diagnosticsChannel.channel("undici:websocket:close");
41150
41150
  channels.socketError = diagnosticsChannel.channel("undici:websocket:socket_error");
41151
- var crypto4;
41151
+ var crypto2;
41152
41152
  try {
41153
- crypto4 = require("crypto");
41153
+ crypto2 = require("crypto");
41154
41154
  } catch {
41155
41155
  }
41156
41156
  function establishWebSocketConnection(url, protocols, ws, onEstablish, options) {
@@ -41169,7 +41169,7 @@ var require_connection = __commonJS({
41169
41169
  const headersList = new Headers(options.headers)[kHeadersList];
41170
41170
  request.headersList = headersList;
41171
41171
  }
41172
- const keyValue = crypto4.randomBytes(16).toString("base64");
41172
+ const keyValue = crypto2.randomBytes(16).toString("base64");
41173
41173
  request.headersList.append("sec-websocket-key", keyValue);
41174
41174
  request.headersList.append("sec-websocket-version", "13");
41175
41175
  for (const protocol of protocols) {
@@ -41198,7 +41198,7 @@ var require_connection = __commonJS({
41198
41198
  return;
41199
41199
  }
41200
41200
  const secWSAccept = response.headersList.get("Sec-WebSocket-Accept");
41201
- const digest = crypto4.createHash("sha1").update(keyValue + uid).digest("base64");
41201
+ const digest = crypto2.createHash("sha1").update(keyValue + uid).digest("base64");
41202
41202
  if (secWSAccept !== digest) {
41203
41203
  failWebsocketConnection(ws, "Incorrect hash received in Sec-WebSocket-Accept header.");
41204
41204
  return;
@@ -41278,9 +41278,9 @@ var require_frame = __commonJS({
41278
41278
  "node_modules/undici/lib/websocket/frame.js"(exports2, module2) {
41279
41279
  "use strict";
41280
41280
  var { maxUnsigned16Bit } = require_constants5();
41281
- var crypto4;
41281
+ var crypto2;
41282
41282
  try {
41283
- crypto4 = require("crypto");
41283
+ crypto2 = require("crypto");
41284
41284
  } catch {
41285
41285
  }
41286
41286
  var WebsocketFrameSend = class {
@@ -41289,7 +41289,7 @@ var require_frame = __commonJS({
41289
41289
  */
41290
41290
  constructor(data) {
41291
41291
  this.frameData = data;
41292
- this.maskKey = crypto4.randomBytes(4);
41292
+ this.maskKey = crypto2.randomBytes(4);
41293
41293
  }
41294
41294
  createFrame(opcode) {
41295
41295
  const bodyLength = this.frameData?.byteLength ?? 0;
@@ -42031,11 +42031,11 @@ var require_undici = __commonJS({
42031
42031
  if (typeof opts.path !== "string") {
42032
42032
  throw new InvalidArgumentError("invalid opts.path");
42033
42033
  }
42034
- let path30 = opts.path;
42034
+ let path26 = opts.path;
42035
42035
  if (!opts.path.startsWith("/")) {
42036
- path30 = `/${path30}`;
42036
+ path26 = `/${path26}`;
42037
42037
  }
42038
- url = new URL(util.parseOrigin(url).origin + path30);
42038
+ url = new URL(util.parseOrigin(url).origin + path26);
42039
42039
  } else {
42040
42040
  if (!opts) {
42041
42041
  opts = typeof url === "object" ? url : {};
@@ -42563,7 +42563,7 @@ var init_mcp_check_provider = __esm({
42563
42563
  logger.warn(
42564
42564
  `MCP ${transportName} failed (attempt ${attempt + 1}/${maxRetries + 1}), retrying in ${delay}ms: ${error instanceof Error ? error.message : String(error)}`
42565
42565
  );
42566
- await new Promise((resolve15) => setTimeout(resolve15, delay));
42566
+ await new Promise((resolve11) => setTimeout(resolve11, delay));
42567
42567
  attempt += 1;
42568
42568
  } finally {
42569
42569
  try {
@@ -42845,7 +42845,7 @@ async function acquirePromptLock() {
42845
42845
  activePrompt = true;
42846
42846
  return;
42847
42847
  }
42848
- await new Promise((resolve15) => waiters.push(resolve15));
42848
+ await new Promise((resolve11) => waiters.push(resolve11));
42849
42849
  activePrompt = true;
42850
42850
  }
42851
42851
  function releasePromptLock() {
@@ -42855,7 +42855,7 @@ function releasePromptLock() {
42855
42855
  }
42856
42856
  async function interactivePrompt(options) {
42857
42857
  await acquirePromptLock();
42858
- return new Promise((resolve15, reject) => {
42858
+ return new Promise((resolve11, reject) => {
42859
42859
  const dbg = process.env.VISOR_DEBUG === "true";
42860
42860
  try {
42861
42861
  if (dbg) {
@@ -42942,12 +42942,12 @@ async function interactivePrompt(options) {
42942
42942
  };
42943
42943
  const finish = (value) => {
42944
42944
  cleanup();
42945
- resolve15(value);
42945
+ resolve11(value);
42946
42946
  };
42947
42947
  if (options.timeout && options.timeout > 0) {
42948
42948
  timeoutId = setTimeout(() => {
42949
42949
  cleanup();
42950
- if (defaultValue !== void 0) return resolve15(defaultValue);
42950
+ if (defaultValue !== void 0) return resolve11(defaultValue);
42951
42951
  return reject(new Error("Input timeout"));
42952
42952
  }, options.timeout);
42953
42953
  }
@@ -43079,7 +43079,7 @@ async function interactivePrompt(options) {
43079
43079
  });
43080
43080
  }
43081
43081
  async function simplePrompt(prompt) {
43082
- return new Promise((resolve15) => {
43082
+ return new Promise((resolve11) => {
43083
43083
  const rl = readline.createInterface({
43084
43084
  input: process.stdin,
43085
43085
  output: process.stdout
@@ -43095,7 +43095,7 @@ async function simplePrompt(prompt) {
43095
43095
  rl.question(`${prompt}
43096
43096
  > `, (answer) => {
43097
43097
  rl.close();
43098
- resolve15(answer.trim());
43098
+ resolve11(answer.trim());
43099
43099
  });
43100
43100
  });
43101
43101
  }
@@ -43263,7 +43263,7 @@ function isStdinAvailable() {
43263
43263
  return !process.stdin.isTTY;
43264
43264
  }
43265
43265
  async function readStdin(timeout, maxSize = 1024 * 1024) {
43266
- return new Promise((resolve15, reject) => {
43266
+ return new Promise((resolve11, reject) => {
43267
43267
  let data = "";
43268
43268
  let timeoutId;
43269
43269
  if (timeout) {
@@ -43290,7 +43290,7 @@ async function readStdin(timeout, maxSize = 1024 * 1024) {
43290
43290
  };
43291
43291
  const onEnd = () => {
43292
43292
  cleanup();
43293
- resolve15(data.trim());
43293
+ resolve11(data.trim());
43294
43294
  };
43295
43295
  const onError = (err) => {
43296
43296
  cleanup();
@@ -47320,23 +47320,23 @@ __export(renderer_schema_exports, {
47320
47320
  });
47321
47321
  async function loadRendererSchema(name) {
47322
47322
  try {
47323
- const fs26 = await import("fs/promises");
47324
- const path30 = await import("path");
47323
+ const fs22 = await import("fs/promises");
47324
+ const path26 = await import("path");
47325
47325
  const sanitized = String(name).replace(/[^a-zA-Z0-9-]/g, "");
47326
47326
  if (!sanitized) return void 0;
47327
47327
  const candidates = [
47328
47328
  // When bundled with ncc, __dirname is dist/ and output/ is at dist/output/
47329
- path30.join(__dirname, "output", sanitized, "schema.json"),
47329
+ path26.join(__dirname, "output", sanitized, "schema.json"),
47330
47330
  // When running from source, __dirname is src/state-machine/dispatch/ and output/ is at output/
47331
- path30.join(__dirname, "..", "..", "output", sanitized, "schema.json"),
47331
+ path26.join(__dirname, "..", "..", "output", sanitized, "schema.json"),
47332
47332
  // When running from a checkout with output/ folder copied to CWD
47333
- path30.join(process.cwd(), "output", sanitized, "schema.json"),
47333
+ path26.join(process.cwd(), "output", sanitized, "schema.json"),
47334
47334
  // Fallback: cwd/dist/output/
47335
- path30.join(process.cwd(), "dist", "output", sanitized, "schema.json")
47335
+ path26.join(process.cwd(), "dist", "output", sanitized, "schema.json")
47336
47336
  ];
47337
47337
  for (const p of candidates) {
47338
47338
  try {
47339
- const raw = await fs26.readFile(p, "utf-8");
47339
+ const raw = await fs22.readFile(p, "utf-8");
47340
47340
  return JSON.parse(raw);
47341
47341
  } catch {
47342
47342
  }
@@ -49755,8 +49755,8 @@ function updateStats2(results, state, isForEachIteration = false) {
49755
49755
  async function renderTemplateContent2(checkId, checkConfig, reviewSummary) {
49756
49756
  try {
49757
49757
  const { createExtendedLiquid: createExtendedLiquid2 } = await Promise.resolve().then(() => (init_liquid_extensions(), liquid_extensions_exports));
49758
- const fs26 = await import("fs/promises");
49759
- const path30 = await import("path");
49758
+ const fs22 = await import("fs/promises");
49759
+ const path26 = await import("path");
49760
49760
  const schemaRaw = checkConfig.schema || "plain";
49761
49761
  const schema = typeof schemaRaw === "string" && !schemaRaw.includes("{{") && !schemaRaw.includes("{%") ? schemaRaw : typeof schemaRaw === "object" ? "code-review" : "plain";
49762
49762
  let templateContent;
@@ -49765,27 +49765,27 @@ async function renderTemplateContent2(checkId, checkConfig, reviewSummary) {
49765
49765
  logger.debug(`[LevelDispatch] Using inline template for ${checkId}`);
49766
49766
  } else if (checkConfig.template && checkConfig.template.file) {
49767
49767
  const file = String(checkConfig.template.file);
49768
- const resolved = path30.resolve(process.cwd(), file);
49769
- templateContent = await fs26.readFile(resolved, "utf-8");
49768
+ const resolved = path26.resolve(process.cwd(), file);
49769
+ templateContent = await fs22.readFile(resolved, "utf-8");
49770
49770
  logger.debug(`[LevelDispatch] Using template file for ${checkId}: ${resolved}`);
49771
49771
  } else if (schema && schema !== "plain") {
49772
49772
  const sanitized = String(schema).replace(/[^a-zA-Z0-9-]/g, "");
49773
49773
  if (sanitized) {
49774
49774
  const candidatePaths = [
49775
- path30.join(__dirname, "output", sanitized, "template.liquid"),
49775
+ path26.join(__dirname, "output", sanitized, "template.liquid"),
49776
49776
  // bundled: dist/output/
49777
- path30.join(__dirname, "..", "..", "output", sanitized, "template.liquid"),
49777
+ path26.join(__dirname, "..", "..", "output", sanitized, "template.liquid"),
49778
49778
  // source (from state-machine/states)
49779
- path30.join(__dirname, "..", "..", "..", "output", sanitized, "template.liquid"),
49779
+ path26.join(__dirname, "..", "..", "..", "output", sanitized, "template.liquid"),
49780
49780
  // source (alternate)
49781
- path30.join(process.cwd(), "output", sanitized, "template.liquid"),
49781
+ path26.join(process.cwd(), "output", sanitized, "template.liquid"),
49782
49782
  // fallback: cwd/output/
49783
- path30.join(process.cwd(), "dist", "output", sanitized, "template.liquid")
49783
+ path26.join(process.cwd(), "dist", "output", sanitized, "template.liquid")
49784
49784
  // fallback: cwd/dist/output/
49785
49785
  ];
49786
49786
  for (const p of candidatePaths) {
49787
49787
  try {
49788
- templateContent = await fs26.readFile(p, "utf-8");
49788
+ templateContent = await fs22.readFile(p, "utf-8");
49789
49789
  if (templateContent) {
49790
49790
  logger.debug(`[LevelDispatch] Using schema template for ${checkId}: ${p}`);
49791
49791
  break;
@@ -51586,8 +51586,8 @@ var init_workspace_manager = __esm({
51586
51586
  );
51587
51587
  if (this.cleanupRequested && this.activeOperations === 0) {
51588
51588
  logger.debug(`[Workspace] All references released, proceeding with deferred cleanup`);
51589
- for (const resolve15 of this.cleanupResolvers) {
51590
- resolve15();
51589
+ for (const resolve11 of this.cleanupResolvers) {
51590
+ resolve11();
51591
51591
  }
51592
51592
  this.cleanupResolvers = [];
51593
51593
  }
@@ -51712,19 +51712,19 @@ var init_workspace_manager = __esm({
51712
51712
  );
51713
51713
  this.cleanupRequested = true;
51714
51714
  await Promise.race([
51715
- new Promise((resolve15) => {
51715
+ new Promise((resolve11) => {
51716
51716
  if (this.activeOperations === 0) {
51717
- resolve15();
51717
+ resolve11();
51718
51718
  } else {
51719
- this.cleanupResolvers.push(resolve15);
51719
+ this.cleanupResolvers.push(resolve11);
51720
51720
  }
51721
51721
  }),
51722
- new Promise((resolve15) => {
51722
+ new Promise((resolve11) => {
51723
51723
  setTimeout(() => {
51724
51724
  logger.warn(
51725
51725
  `[Workspace] Cleanup timeout after ${timeout}ms, proceeding anyway (${this.activeOperations} operations still active)`
51726
51726
  );
51727
- resolve15();
51727
+ resolve11();
51728
51728
  }, timeout);
51729
51729
  })
51730
51730
  ]);
@@ -52003,1264 +52003,6 @@ var init_build_engine_context = __esm({
52003
52003
  }
52004
52004
  });
52005
52005
 
52006
- // src/policy/default-engine.ts
52007
- var DefaultPolicyEngine;
52008
- var init_default_engine = __esm({
52009
- "src/policy/default-engine.ts"() {
52010
- "use strict";
52011
- DefaultPolicyEngine = class {
52012
- async initialize(_config) {
52013
- }
52014
- async evaluateCheckExecution(_checkId, _checkConfig) {
52015
- return { allowed: true };
52016
- }
52017
- async evaluateToolInvocation(_serverName, _methodName, _transport) {
52018
- return { allowed: true };
52019
- }
52020
- async evaluateCapabilities(_checkId, _capabilities) {
52021
- return { allowed: true };
52022
- }
52023
- async shutdown() {
52024
- }
52025
- };
52026
- }
52027
- });
52028
-
52029
- // src/enterprise/license/validator.ts
52030
- var validator_exports = {};
52031
- __export(validator_exports, {
52032
- LicenseValidator: () => LicenseValidator
52033
- });
52034
- var crypto2, fs19, path23, LicenseValidator;
52035
- var init_validator = __esm({
52036
- "src/enterprise/license/validator.ts"() {
52037
- "use strict";
52038
- crypto2 = __toESM(require("crypto"));
52039
- fs19 = __toESM(require("fs"));
52040
- path23 = __toESM(require("path"));
52041
- LicenseValidator = class _LicenseValidator {
52042
- /** Ed25519 public key for license verification (PEM format). */
52043
- static PUBLIC_KEY = "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAI/Zd08EFmgIdrDm/HXd0l3/5GBt7R1PrdvhdmEXhJlU=\n-----END PUBLIC KEY-----\n";
52044
- cache = null;
52045
- static CACHE_TTL = 5 * 60 * 1e3;
52046
- // 5 minutes
52047
- static GRACE_PERIOD = 72 * 3600 * 1e3;
52048
- // 72 hours after expiry
52049
- /**
52050
- * Load and validate license from environment or file.
52051
- *
52052
- * Resolution order:
52053
- * 1. VISOR_LICENSE env var (JWT string)
52054
- * 2. VISOR_LICENSE_FILE env var (path to file)
52055
- * 3. .visor-license in project root (cwd)
52056
- * 4. .visor-license in ~/.config/visor/
52057
- */
52058
- async loadAndValidate() {
52059
- if (this.cache && Date.now() - this.cache.validatedAt < _LicenseValidator.CACHE_TTL) {
52060
- return this.cache.payload;
52061
- }
52062
- const token = this.resolveToken();
52063
- if (!token) return null;
52064
- const payload = this.verifyAndDecode(token);
52065
- if (!payload) return null;
52066
- this.cache = { payload, validatedAt: Date.now() };
52067
- return payload;
52068
- }
52069
- /** Check if a specific feature is licensed */
52070
- hasFeature(feature) {
52071
- if (!this.cache) return false;
52072
- return this.cache.payload.features.includes(feature);
52073
- }
52074
- /** Check if license is valid (with grace period) */
52075
- isValid() {
52076
- if (!this.cache) return false;
52077
- const now = Date.now();
52078
- const expiryMs = this.cache.payload.exp * 1e3;
52079
- return now < expiryMs + _LicenseValidator.GRACE_PERIOD;
52080
- }
52081
- /** Check if the license is within its grace period (expired but still valid) */
52082
- isInGracePeriod() {
52083
- if (!this.cache) return false;
52084
- const now = Date.now();
52085
- const expiryMs = this.cache.payload.exp * 1e3;
52086
- return now >= expiryMs && now < expiryMs + _LicenseValidator.GRACE_PERIOD;
52087
- }
52088
- resolveToken() {
52089
- if (process.env.VISOR_LICENSE) {
52090
- return process.env.VISOR_LICENSE.trim();
52091
- }
52092
- if (process.env.VISOR_LICENSE_FILE) {
52093
- const resolved = path23.resolve(process.env.VISOR_LICENSE_FILE);
52094
- const home2 = process.env.HOME || process.env.USERPROFILE || "";
52095
- const allowedPrefixes = [path23.normalize(process.cwd())];
52096
- if (home2) allowedPrefixes.push(path23.normalize(path23.join(home2, ".config", "visor")));
52097
- let realPath;
52098
- try {
52099
- realPath = fs19.realpathSync(resolved);
52100
- } catch {
52101
- return null;
52102
- }
52103
- const isSafe = allowedPrefixes.some(
52104
- (prefix) => realPath === prefix || realPath.startsWith(prefix + path23.sep)
52105
- );
52106
- if (!isSafe) return null;
52107
- return this.readFile(realPath);
52108
- }
52109
- const cwdPath = path23.join(process.cwd(), ".visor-license");
52110
- const cwdToken = this.readFile(cwdPath);
52111
- if (cwdToken) return cwdToken;
52112
- const home = process.env.HOME || process.env.USERPROFILE || "";
52113
- if (home) {
52114
- const configPath = path23.join(home, ".config", "visor", ".visor-license");
52115
- const configToken = this.readFile(configPath);
52116
- if (configToken) return configToken;
52117
- }
52118
- return null;
52119
- }
52120
- readFile(filePath) {
52121
- try {
52122
- return fs19.readFileSync(filePath, "utf-8").trim();
52123
- } catch {
52124
- return null;
52125
- }
52126
- }
52127
- verifyAndDecode(token) {
52128
- try {
52129
- const parts = token.split(".");
52130
- if (parts.length !== 3) return null;
52131
- const [headerB64, payloadB64, signatureB64] = parts;
52132
- const header = JSON.parse(Buffer.from(headerB64, "base64url").toString());
52133
- if (header.alg !== "EdDSA") return null;
52134
- const data = `${headerB64}.${payloadB64}`;
52135
- const signature = Buffer.from(signatureB64, "base64url");
52136
- const publicKey = crypto2.createPublicKey(_LicenseValidator.PUBLIC_KEY);
52137
- if (publicKey.asymmetricKeyType !== "ed25519") {
52138
- return null;
52139
- }
52140
- const isValid = crypto2.verify(null, Buffer.from(data), publicKey, signature);
52141
- if (!isValid) return null;
52142
- const payload = JSON.parse(Buffer.from(payloadB64, "base64url").toString());
52143
- if (!payload.org || !Array.isArray(payload.features) || typeof payload.exp !== "number" || typeof payload.iat !== "number" || !payload.sub) {
52144
- return null;
52145
- }
52146
- const now = Date.now();
52147
- const expiryMs = payload.exp * 1e3;
52148
- if (now >= expiryMs + _LicenseValidator.GRACE_PERIOD) {
52149
- return null;
52150
- }
52151
- return payload;
52152
- } catch {
52153
- return null;
52154
- }
52155
- }
52156
- };
52157
- }
52158
- });
52159
-
52160
- // src/enterprise/policy/opa-compiler.ts
52161
- var fs20, path24, os, crypto3, import_child_process5, OpaCompiler;
52162
- var init_opa_compiler = __esm({
52163
- "src/enterprise/policy/opa-compiler.ts"() {
52164
- "use strict";
52165
- fs20 = __toESM(require("fs"));
52166
- path24 = __toESM(require("path"));
52167
- os = __toESM(require("os"));
52168
- crypto3 = __toESM(require("crypto"));
52169
- import_child_process5 = require("child_process");
52170
- OpaCompiler = class _OpaCompiler {
52171
- static CACHE_DIR = path24.join(os.tmpdir(), "visor-opa-cache");
52172
- /**
52173
- * Resolve the input paths to WASM bytes.
52174
- *
52175
- * Strategy:
52176
- * 1. If any path is a .wasm file, read it directly
52177
- * 2. If a directory contains policy.wasm, read it
52178
- * 3. Otherwise, collect all .rego files and auto-compile via `opa build`
52179
- */
52180
- async resolveWasmBytes(paths) {
52181
- const regoFiles = [];
52182
- for (const p of paths) {
52183
- const resolved = path24.resolve(p);
52184
- if (path24.normalize(resolved).includes("..")) {
52185
- throw new Error(`Policy path contains traversal sequences: ${p}`);
52186
- }
52187
- if (resolved.endsWith(".wasm") && fs20.existsSync(resolved)) {
52188
- return fs20.readFileSync(resolved);
52189
- }
52190
- if (!fs20.existsSync(resolved)) continue;
52191
- const stat = fs20.statSync(resolved);
52192
- if (stat.isDirectory()) {
52193
- const wasmCandidate = path24.join(resolved, "policy.wasm");
52194
- if (fs20.existsSync(wasmCandidate)) {
52195
- return fs20.readFileSync(wasmCandidate);
52196
- }
52197
- const files = fs20.readdirSync(resolved);
52198
- for (const f of files) {
52199
- if (f.endsWith(".rego")) {
52200
- regoFiles.push(path24.join(resolved, f));
52201
- }
52202
- }
52203
- } else if (resolved.endsWith(".rego")) {
52204
- regoFiles.push(resolved);
52205
- }
52206
- }
52207
- if (regoFiles.length === 0) {
52208
- throw new Error(
52209
- `OPA WASM evaluator: no .wasm bundle or .rego files found in: ${paths.join(", ")}`
52210
- );
52211
- }
52212
- return this.compileRego(regoFiles);
52213
- }
52214
- /**
52215
- * Auto-compile .rego files to a WASM bundle using the `opa` CLI.
52216
- *
52217
- * Caches the compiled bundle based on a content hash of all input .rego files
52218
- * so subsequent runs skip compilation if policies haven't changed.
52219
- */
52220
- compileRego(regoFiles) {
52221
- try {
52222
- (0, import_child_process5.execFileSync)("opa", ["version"], { stdio: "pipe" });
52223
- } catch {
52224
- throw new Error(
52225
- "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(" ")
52226
- );
52227
- }
52228
- const hash = crypto3.createHash("sha256");
52229
- for (const f of regoFiles.sort()) {
52230
- hash.update(fs20.readFileSync(f));
52231
- hash.update(f);
52232
- }
52233
- const cacheKey = hash.digest("hex").slice(0, 16);
52234
- const cacheDir = _OpaCompiler.CACHE_DIR;
52235
- const cachedWasm = path24.join(cacheDir, `${cacheKey}.wasm`);
52236
- if (fs20.existsSync(cachedWasm)) {
52237
- return fs20.readFileSync(cachedWasm);
52238
- }
52239
- fs20.mkdirSync(cacheDir, { recursive: true });
52240
- const bundleTar = path24.join(cacheDir, `${cacheKey}-bundle.tar.gz`);
52241
- try {
52242
- const args = [
52243
- "build",
52244
- "-t",
52245
- "wasm",
52246
- "-e",
52247
- "visor",
52248
- // entrypoint: the visor package tree
52249
- "-o",
52250
- bundleTar,
52251
- ...regoFiles
52252
- ];
52253
- (0, import_child_process5.execFileSync)("opa", args, {
52254
- stdio: "pipe",
52255
- timeout: 3e4
52256
- });
52257
- } catch (err) {
52258
- const stderr = err?.stderr?.toString() || "";
52259
- throw new Error(
52260
- `Failed to compile .rego files to WASM:
52261
- ${stderr}
52262
- Ensure your .rego files are valid and the \`opa\` CLI is installed.`
52263
- );
52264
- }
52265
- try {
52266
- (0, import_child_process5.execFileSync)("tar", ["-xzf", bundleTar, "-C", cacheDir, "/policy.wasm"], {
52267
- stdio: "pipe"
52268
- });
52269
- const extractedWasm = path24.join(cacheDir, "policy.wasm");
52270
- if (fs20.existsSync(extractedWasm)) {
52271
- fs20.renameSync(extractedWasm, cachedWasm);
52272
- }
52273
- } catch {
52274
- try {
52275
- (0, import_child_process5.execFileSync)("tar", ["-xzf", bundleTar, "-C", cacheDir, "policy.wasm"], {
52276
- stdio: "pipe"
52277
- });
52278
- const extractedWasm = path24.join(cacheDir, "policy.wasm");
52279
- if (fs20.existsSync(extractedWasm)) {
52280
- fs20.renameSync(extractedWasm, cachedWasm);
52281
- }
52282
- } catch (err2) {
52283
- throw new Error(`Failed to extract policy.wasm from OPA bundle: ${err2?.message || err2}`);
52284
- }
52285
- }
52286
- try {
52287
- fs20.unlinkSync(bundleTar);
52288
- } catch {
52289
- }
52290
- if (!fs20.existsSync(cachedWasm)) {
52291
- throw new Error("OPA build succeeded but policy.wasm was not found in the bundle");
52292
- }
52293
- return fs20.readFileSync(cachedWasm);
52294
- }
52295
- };
52296
- }
52297
- });
52298
-
52299
- // src/enterprise/policy/opa-wasm-evaluator.ts
52300
- var fs21, path25, OpaWasmEvaluator;
52301
- var init_opa_wasm_evaluator = __esm({
52302
- "src/enterprise/policy/opa-wasm-evaluator.ts"() {
52303
- "use strict";
52304
- fs21 = __toESM(require("fs"));
52305
- path25 = __toESM(require("path"));
52306
- init_opa_compiler();
52307
- OpaWasmEvaluator = class {
52308
- policy = null;
52309
- dataDocument = {};
52310
- compiler = new OpaCompiler();
52311
- async initialize(rulesPath) {
52312
- const paths = Array.isArray(rulesPath) ? rulesPath : [rulesPath];
52313
- const wasmBytes = await this.compiler.resolveWasmBytes(paths);
52314
- try {
52315
- const { createRequire } = require("module");
52316
- const runtimeRequire = createRequire(__filename);
52317
- const opaWasm = runtimeRequire("@open-policy-agent/opa-wasm");
52318
- const loadPolicy = opaWasm.loadPolicy || opaWasm.default?.loadPolicy;
52319
- if (!loadPolicy) {
52320
- throw new Error("loadPolicy not found in @open-policy-agent/opa-wasm");
52321
- }
52322
- this.policy = await loadPolicy(wasmBytes);
52323
- } catch (err) {
52324
- if (err?.code === "MODULE_NOT_FOUND" || err?.code === "ERR_MODULE_NOT_FOUND") {
52325
- throw new Error(
52326
- "OPA WASM evaluator requires @open-policy-agent/opa-wasm. Install it with: npm install @open-policy-agent/opa-wasm"
52327
- );
52328
- }
52329
- throw err;
52330
- }
52331
- }
52332
- /**
52333
- * Load external data from a JSON file to use as the OPA data document.
52334
- * The loaded data will be passed to `policy.setData()` during evaluation,
52335
- * making it available in Rego via `data.<key>`.
52336
- */
52337
- loadData(dataPath) {
52338
- const resolved = path25.resolve(dataPath);
52339
- if (path25.normalize(resolved).includes("..")) {
52340
- throw new Error(`Data path contains traversal sequences: ${dataPath}`);
52341
- }
52342
- if (!fs21.existsSync(resolved)) {
52343
- throw new Error(`OPA data file not found: ${resolved}`);
52344
- }
52345
- const stat = fs21.statSync(resolved);
52346
- if (stat.size > 10 * 1024 * 1024) {
52347
- throw new Error(`OPA data file exceeds 10MB limit: ${resolved} (${stat.size} bytes)`);
52348
- }
52349
- const raw = fs21.readFileSync(resolved, "utf-8");
52350
- try {
52351
- const parsed = JSON.parse(raw);
52352
- if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
52353
- throw new Error("OPA data file must contain a JSON object (not an array or primitive)");
52354
- }
52355
- this.dataDocument = parsed;
52356
- } catch (err) {
52357
- if (err.message.startsWith("OPA data file must")) {
52358
- throw err;
52359
- }
52360
- throw new Error(`Failed to parse OPA data file ${resolved}: ${err.message}`);
52361
- }
52362
- }
52363
- async evaluate(input) {
52364
- if (!this.policy) {
52365
- throw new Error("OPA WASM evaluator not initialized");
52366
- }
52367
- this.policy.setData(this.dataDocument);
52368
- const resultSet = this.policy.evaluate(input);
52369
- if (Array.isArray(resultSet) && resultSet.length > 0) {
52370
- return resultSet[0].result;
52371
- }
52372
- return void 0;
52373
- }
52374
- async shutdown() {
52375
- if (this.policy) {
52376
- if (typeof this.policy.close === "function") {
52377
- try {
52378
- this.policy.close();
52379
- } catch {
52380
- }
52381
- } else if (typeof this.policy.free === "function") {
52382
- try {
52383
- this.policy.free();
52384
- } catch {
52385
- }
52386
- }
52387
- }
52388
- this.policy = null;
52389
- }
52390
- };
52391
- }
52392
- });
52393
-
52394
- // src/enterprise/policy/opa-http-evaluator.ts
52395
- var OpaHttpEvaluator;
52396
- var init_opa_http_evaluator = __esm({
52397
- "src/enterprise/policy/opa-http-evaluator.ts"() {
52398
- "use strict";
52399
- OpaHttpEvaluator = class {
52400
- baseUrl;
52401
- timeout;
52402
- constructor(baseUrl, timeout = 5e3) {
52403
- let parsed;
52404
- try {
52405
- parsed = new URL(baseUrl);
52406
- } catch {
52407
- throw new Error(`OPA HTTP evaluator: invalid URL: ${baseUrl}`);
52408
- }
52409
- if (!["http:", "https:"].includes(parsed.protocol)) {
52410
- throw new Error(
52411
- `OPA HTTP evaluator: url must use http:// or https:// protocol, got: ${baseUrl}`
52412
- );
52413
- }
52414
- const hostname = parsed.hostname;
52415
- if (this.isBlockedHostname(hostname)) {
52416
- throw new Error(
52417
- `OPA HTTP evaluator: url must not point to internal, loopback, or private network addresses`
52418
- );
52419
- }
52420
- this.baseUrl = baseUrl.replace(/\/+$/, "");
52421
- this.timeout = timeout;
52422
- }
52423
- /**
52424
- * Check if a hostname is blocked due to SSRF concerns.
52425
- *
52426
- * Blocks:
52427
- * - Loopback addresses (127.x.x.x, localhost, 0.0.0.0, ::1)
52428
- * - Link-local addresses (169.254.x.x)
52429
- * - Private networks (10.x.x.x, 172.16-31.x.x, 192.168.x.x)
52430
- * - IPv6 unique local addresses (fd00::/8)
52431
- * - Cloud metadata services (*.internal)
52432
- */
52433
- isBlockedHostname(hostname) {
52434
- if (!hostname) return true;
52435
- const normalized = hostname.toLowerCase().replace(/^\[|\]$/g, "");
52436
- if (normalized === "metadata.google.internal" || normalized.endsWith(".internal")) {
52437
- return true;
52438
- }
52439
- if (normalized === "localhost" || normalized === "localhost.localdomain") {
52440
- return true;
52441
- }
52442
- if (normalized === "::1" || normalized === "0:0:0:0:0:0:0:1") {
52443
- return true;
52444
- }
52445
- const ipv4Pattern = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/;
52446
- const ipv4Match = normalized.match(ipv4Pattern);
52447
- if (ipv4Match) {
52448
- const octets = ipv4Match.slice(1, 5).map(Number);
52449
- if (octets.some((octet) => octet > 255)) {
52450
- return false;
52451
- }
52452
- const [a, b] = octets;
52453
- if (a === 127) {
52454
- return true;
52455
- }
52456
- if (a === 0) {
52457
- return true;
52458
- }
52459
- if (a === 169 && b === 254) {
52460
- return true;
52461
- }
52462
- if (a === 10) {
52463
- return true;
52464
- }
52465
- if (a === 172 && b >= 16 && b <= 31) {
52466
- return true;
52467
- }
52468
- if (a === 192 && b === 168) {
52469
- return true;
52470
- }
52471
- }
52472
- if (normalized.startsWith("fd") || normalized.startsWith("fc")) {
52473
- return true;
52474
- }
52475
- if (normalized.startsWith("fe80:")) {
52476
- return true;
52477
- }
52478
- return false;
52479
- }
52480
- /**
52481
- * Evaluate a policy rule against an input document via OPA REST API.
52482
- *
52483
- * @param input - The input document to evaluate
52484
- * @param rulePath - OPA rule path (e.g., 'visor/check/execute')
52485
- * @returns The result object from OPA, or undefined on error
52486
- */
52487
- async evaluate(input, rulePath) {
52488
- const encodedPath = rulePath.split("/").map((s) => encodeURIComponent(s)).join("/");
52489
- const url = `${this.baseUrl}/v1/data/${encodedPath}`;
52490
- const controller = new AbortController();
52491
- const timer = setTimeout(() => controller.abort(), this.timeout);
52492
- try {
52493
- const response = await fetch(url, {
52494
- method: "POST",
52495
- headers: { "Content-Type": "application/json" },
52496
- body: JSON.stringify({ input }),
52497
- signal: controller.signal
52498
- });
52499
- if (!response.ok) {
52500
- throw new Error(`OPA HTTP ${response.status}: ${response.statusText}`);
52501
- }
52502
- let body;
52503
- try {
52504
- body = await response.json();
52505
- } catch (jsonErr) {
52506
- throw new Error(
52507
- `OPA HTTP evaluator: failed to parse JSON response: ${jsonErr instanceof Error ? jsonErr.message : String(jsonErr)}`
52508
- );
52509
- }
52510
- return body?.result;
52511
- } finally {
52512
- clearTimeout(timer);
52513
- }
52514
- }
52515
- async shutdown() {
52516
- }
52517
- };
52518
- }
52519
- });
52520
-
52521
- // src/enterprise/policy/policy-input-builder.ts
52522
- var PolicyInputBuilder;
52523
- var init_policy_input_builder = __esm({
52524
- "src/enterprise/policy/policy-input-builder.ts"() {
52525
- "use strict";
52526
- PolicyInputBuilder = class {
52527
- roles;
52528
- actor;
52529
- repository;
52530
- pullRequest;
52531
- constructor(policyConfig, actor, repository, pullRequest) {
52532
- this.roles = policyConfig.roles || {};
52533
- this.actor = actor;
52534
- this.repository = repository;
52535
- this.pullRequest = pullRequest;
52536
- }
52537
- /** Resolve which roles apply to the current actor. */
52538
- resolveRoles() {
52539
- const matched = [];
52540
- for (const [roleName, roleConfig] of Object.entries(this.roles)) {
52541
- let identityMatch = false;
52542
- if (roleConfig.author_association && this.actor.authorAssociation && roleConfig.author_association.includes(this.actor.authorAssociation)) {
52543
- identityMatch = true;
52544
- }
52545
- if (!identityMatch && roleConfig.users && this.actor.login && roleConfig.users.includes(this.actor.login)) {
52546
- identityMatch = true;
52547
- }
52548
- if (!identityMatch && roleConfig.slack_users && this.actor.slack?.userId && roleConfig.slack_users.includes(this.actor.slack.userId)) {
52549
- identityMatch = true;
52550
- }
52551
- if (!identityMatch && roleConfig.emails && this.actor.slack?.email) {
52552
- const actorEmail = this.actor.slack.email.toLowerCase();
52553
- if (roleConfig.emails.some((e) => e.toLowerCase() === actorEmail)) {
52554
- identityMatch = true;
52555
- }
52556
- }
52557
- if (!identityMatch) continue;
52558
- if (roleConfig.slack_channels && roleConfig.slack_channels.length > 0) {
52559
- if (!this.actor.slack?.channelId || !roleConfig.slack_channels.includes(this.actor.slack.channelId)) {
52560
- continue;
52561
- }
52562
- }
52563
- matched.push(roleName);
52564
- }
52565
- return matched;
52566
- }
52567
- buildActor() {
52568
- return {
52569
- authorAssociation: this.actor.authorAssociation,
52570
- login: this.actor.login,
52571
- roles: this.resolveRoles(),
52572
- isLocalMode: this.actor.isLocalMode,
52573
- ...this.actor.slack && { slack: this.actor.slack }
52574
- };
52575
- }
52576
- forCheckExecution(check) {
52577
- return {
52578
- scope: "check.execute",
52579
- check: {
52580
- id: check.id,
52581
- type: check.type,
52582
- group: check.group,
52583
- tags: check.tags,
52584
- criticality: check.criticality,
52585
- sandbox: check.sandbox,
52586
- policy: check.policy
52587
- },
52588
- actor: this.buildActor(),
52589
- repository: this.repository,
52590
- pullRequest: this.pullRequest
52591
- };
52592
- }
52593
- forToolInvocation(serverName, methodName, transport) {
52594
- return {
52595
- scope: "tool.invoke",
52596
- tool: { serverName, methodName, transport },
52597
- actor: this.buildActor(),
52598
- repository: this.repository,
52599
- pullRequest: this.pullRequest
52600
- };
52601
- }
52602
- forCapabilityResolve(checkId, capabilities) {
52603
- return {
52604
- scope: "capability.resolve",
52605
- check: { id: checkId, type: "ai" },
52606
- capability: capabilities,
52607
- actor: this.buildActor(),
52608
- repository: this.repository,
52609
- pullRequest: this.pullRequest
52610
- };
52611
- }
52612
- };
52613
- }
52614
- });
52615
-
52616
- // src/enterprise/policy/opa-policy-engine.ts
52617
- var opa_policy_engine_exports = {};
52618
- __export(opa_policy_engine_exports, {
52619
- OpaPolicyEngine: () => OpaPolicyEngine
52620
- });
52621
- var OpaPolicyEngine;
52622
- var init_opa_policy_engine = __esm({
52623
- "src/enterprise/policy/opa-policy-engine.ts"() {
52624
- "use strict";
52625
- init_opa_wasm_evaluator();
52626
- init_opa_http_evaluator();
52627
- init_policy_input_builder();
52628
- OpaPolicyEngine = class {
52629
- evaluator = null;
52630
- fallback;
52631
- timeout;
52632
- config;
52633
- inputBuilder = null;
52634
- logger = null;
52635
- constructor(config) {
52636
- this.config = config;
52637
- this.fallback = config.fallback || "deny";
52638
- this.timeout = config.timeout || 5e3;
52639
- }
52640
- async initialize(config) {
52641
- try {
52642
- this.logger = (init_logger(), __toCommonJS(logger_exports)).logger;
52643
- } catch {
52644
- }
52645
- const actor = {
52646
- authorAssociation: process.env.VISOR_AUTHOR_ASSOCIATION,
52647
- login: process.env.VISOR_AUTHOR_LOGIN || process.env.GITHUB_ACTOR,
52648
- isLocalMode: !process.env.GITHUB_ACTIONS
52649
- };
52650
- const repo = {
52651
- owner: process.env.GITHUB_REPOSITORY_OWNER,
52652
- name: process.env.GITHUB_REPOSITORY?.split("/")[1],
52653
- branch: process.env.GITHUB_HEAD_REF,
52654
- baseBranch: process.env.GITHUB_BASE_REF,
52655
- event: process.env.GITHUB_EVENT_NAME
52656
- };
52657
- const prNum = process.env.GITHUB_PR_NUMBER ? parseInt(process.env.GITHUB_PR_NUMBER, 10) : void 0;
52658
- const pullRequest = {
52659
- number: prNum !== void 0 && Number.isFinite(prNum) ? prNum : void 0
52660
- };
52661
- this.inputBuilder = new PolicyInputBuilder(config, actor, repo, pullRequest);
52662
- if (config.engine === "local") {
52663
- if (!config.rules) {
52664
- throw new Error("OPA local mode requires `policy.rules` path to .wasm or .rego files");
52665
- }
52666
- const wasm = new OpaWasmEvaluator();
52667
- await wasm.initialize(config.rules);
52668
- if (config.data) {
52669
- wasm.loadData(config.data);
52670
- }
52671
- this.evaluator = wasm;
52672
- } else if (config.engine === "remote") {
52673
- if (!config.url) {
52674
- throw new Error("OPA remote mode requires `policy.url` pointing to OPA server");
52675
- }
52676
- this.evaluator = new OpaHttpEvaluator(config.url, this.timeout);
52677
- } else {
52678
- this.evaluator = null;
52679
- }
52680
- }
52681
- /**
52682
- * Update actor/repo/PR context (e.g., after PR info becomes available).
52683
- * Called by the enterprise loader when engine context is enriched.
52684
- */
52685
- setActorContext(actor, repo, pullRequest) {
52686
- this.inputBuilder = new PolicyInputBuilder(this.config, actor, repo, pullRequest);
52687
- }
52688
- async evaluateCheckExecution(checkId, checkConfig) {
52689
- if (!this.evaluator || !this.inputBuilder) return { allowed: true };
52690
- const cfg = checkConfig && typeof checkConfig === "object" ? checkConfig : {};
52691
- const policyOverride = cfg.policy;
52692
- const input = this.inputBuilder.forCheckExecution({
52693
- id: checkId,
52694
- type: cfg.type || "ai",
52695
- group: cfg.group,
52696
- tags: cfg.tags,
52697
- criticality: cfg.criticality,
52698
- sandbox: cfg.sandbox,
52699
- policy: policyOverride
52700
- });
52701
- return this.doEvaluate(input, this.resolveRulePath("check.execute", policyOverride?.rule));
52702
- }
52703
- async evaluateToolInvocation(serverName, methodName, transport) {
52704
- if (!this.evaluator || !this.inputBuilder) return { allowed: true };
52705
- const input = this.inputBuilder.forToolInvocation(serverName, methodName, transport);
52706
- return this.doEvaluate(input, "visor/tool/invoke");
52707
- }
52708
- async evaluateCapabilities(checkId, capabilities) {
52709
- if (!this.evaluator || !this.inputBuilder) return { allowed: true };
52710
- const input = this.inputBuilder.forCapabilityResolve(checkId, capabilities);
52711
- return this.doEvaluate(input, "visor/capability/resolve");
52712
- }
52713
- async shutdown() {
52714
- if (this.evaluator && "shutdown" in this.evaluator) {
52715
- await this.evaluator.shutdown();
52716
- }
52717
- this.evaluator = null;
52718
- this.inputBuilder = null;
52719
- }
52720
- resolveRulePath(defaultScope, override) {
52721
- if (override) {
52722
- return override.startsWith("visor/") ? override : `visor/${override}`;
52723
- }
52724
- return `visor/${defaultScope.replace(/\./g, "/")}`;
52725
- }
52726
- async doEvaluate(input, rulePath) {
52727
- try {
52728
- this.logger?.debug(`[PolicyEngine] Evaluating ${rulePath}`, JSON.stringify(input));
52729
- let timer;
52730
- const timeoutPromise = new Promise((_resolve, reject) => {
52731
- timer = setTimeout(() => reject(new Error("policy evaluation timeout")), this.timeout);
52732
- });
52733
- try {
52734
- const result = await Promise.race([this.rawEvaluate(input, rulePath), timeoutPromise]);
52735
- const decision = this.parseDecision(result);
52736
- if (!decision.allowed && this.fallback === "warn") {
52737
- decision.allowed = true;
52738
- decision.warn = true;
52739
- decision.reason = `audit: ${decision.reason || "policy denied"}`;
52740
- }
52741
- this.logger?.debug(
52742
- `[PolicyEngine] Decision for ${rulePath}: allowed=${decision.allowed}, warn=${decision.warn || false}, reason=${decision.reason || "none"}`
52743
- );
52744
- return decision;
52745
- } finally {
52746
- if (timer) clearTimeout(timer);
52747
- }
52748
- } catch (err) {
52749
- const msg = err instanceof Error ? err.message : String(err);
52750
- this.logger?.warn(`[PolicyEngine] Evaluation failed for ${rulePath}: ${msg}`);
52751
- return {
52752
- allowed: this.fallback === "allow" || this.fallback === "warn",
52753
- warn: this.fallback === "warn" ? true : void 0,
52754
- reason: `policy evaluation failed, fallback=${this.fallback}`
52755
- };
52756
- }
52757
- }
52758
- async rawEvaluate(input, rulePath) {
52759
- if (this.evaluator instanceof OpaWasmEvaluator) {
52760
- const result = await this.evaluator.evaluate(input);
52761
- return this.navigateWasmResult(result, rulePath);
52762
- }
52763
- return this.evaluator.evaluate(input, rulePath);
52764
- }
52765
- /**
52766
- * Navigate nested OPA WASM result tree to reach the specific rule's output.
52767
- * The WASM entrypoint `-e visor` means the result root IS the visor package,
52768
- * so we strip the `visor/` prefix and walk the remaining segments.
52769
- */
52770
- navigateWasmResult(result, rulePath) {
52771
- if (!result || typeof result !== "object") return result;
52772
- const segments = rulePath.replace(/^visor\//, "").split("/");
52773
- let current = result;
52774
- for (const seg of segments) {
52775
- if (current && typeof current === "object" && seg in current) {
52776
- current = current[seg];
52777
- } else {
52778
- return void 0;
52779
- }
52780
- }
52781
- return current;
52782
- }
52783
- parseDecision(result) {
52784
- if (result === void 0 || result === null) {
52785
- return {
52786
- allowed: this.fallback === "allow" || this.fallback === "warn",
52787
- warn: this.fallback === "warn" ? true : void 0,
52788
- reason: this.fallback === "warn" ? "audit: no policy result" : "no policy result"
52789
- };
52790
- }
52791
- const allowed = result.allowed !== false;
52792
- const decision = {
52793
- allowed,
52794
- reason: result.reason
52795
- };
52796
- if (result.capabilities) {
52797
- decision.capabilities = result.capabilities;
52798
- }
52799
- return decision;
52800
- }
52801
- };
52802
- }
52803
- });
52804
-
52805
- // src/enterprise/scheduler/knex-store.ts
52806
- var knex_store_exports = {};
52807
- __export(knex_store_exports, {
52808
- KnexStoreBackend: () => KnexStoreBackend
52809
- });
52810
- function toNum(val) {
52811
- if (val === null || val === void 0) return void 0;
52812
- return typeof val === "string" ? parseInt(val, 10) : val;
52813
- }
52814
- function safeJsonParse2(value) {
52815
- if (!value) return void 0;
52816
- try {
52817
- return JSON.parse(value);
52818
- } catch {
52819
- return void 0;
52820
- }
52821
- }
52822
- function fromDbRow2(row) {
52823
- return {
52824
- id: row.id,
52825
- creatorId: row.creator_id,
52826
- creatorContext: row.creator_context ?? void 0,
52827
- creatorName: row.creator_name ?? void 0,
52828
- timezone: row.timezone,
52829
- schedule: row.schedule_expr,
52830
- runAt: toNum(row.run_at),
52831
- isRecurring: row.is_recurring === true || row.is_recurring === 1,
52832
- originalExpression: row.original_expression,
52833
- workflow: row.workflow ?? void 0,
52834
- workflowInputs: safeJsonParse2(row.workflow_inputs),
52835
- outputContext: safeJsonParse2(row.output_context),
52836
- status: row.status,
52837
- createdAt: toNum(row.created_at),
52838
- lastRunAt: toNum(row.last_run_at),
52839
- nextRunAt: toNum(row.next_run_at),
52840
- runCount: row.run_count,
52841
- failureCount: row.failure_count,
52842
- lastError: row.last_error ?? void 0,
52843
- previousResponse: row.previous_response ?? void 0
52844
- };
52845
- }
52846
- function toInsertRow(schedule) {
52847
- return {
52848
- id: schedule.id,
52849
- creator_id: schedule.creatorId,
52850
- creator_context: schedule.creatorContext ?? null,
52851
- creator_name: schedule.creatorName ?? null,
52852
- timezone: schedule.timezone,
52853
- schedule_expr: schedule.schedule,
52854
- run_at: schedule.runAt ?? null,
52855
- is_recurring: schedule.isRecurring,
52856
- original_expression: schedule.originalExpression,
52857
- workflow: schedule.workflow ?? null,
52858
- workflow_inputs: schedule.workflowInputs ? JSON.stringify(schedule.workflowInputs) : null,
52859
- output_context: schedule.outputContext ? JSON.stringify(schedule.outputContext) : null,
52860
- status: schedule.status,
52861
- created_at: schedule.createdAt,
52862
- last_run_at: schedule.lastRunAt ?? null,
52863
- next_run_at: schedule.nextRunAt ?? null,
52864
- run_count: schedule.runCount,
52865
- failure_count: schedule.failureCount,
52866
- last_error: schedule.lastError ?? null,
52867
- previous_response: schedule.previousResponse ?? null
52868
- };
52869
- }
52870
- var fs22, path26, import_uuid2, KnexStoreBackend;
52871
- var init_knex_store = __esm({
52872
- "src/enterprise/scheduler/knex-store.ts"() {
52873
- "use strict";
52874
- fs22 = __toESM(require("fs"));
52875
- path26 = __toESM(require("path"));
52876
- import_uuid2 = require("uuid");
52877
- init_logger();
52878
- KnexStoreBackend = class {
52879
- knex = null;
52880
- driver;
52881
- connection;
52882
- constructor(driver, storageConfig, _haConfig) {
52883
- this.driver = driver;
52884
- this.connection = storageConfig.connection || {};
52885
- }
52886
- async initialize() {
52887
- const { createRequire } = require("module");
52888
- const runtimeRequire = createRequire(__filename);
52889
- let knexFactory;
52890
- try {
52891
- knexFactory = runtimeRequire("knex");
52892
- } catch (err) {
52893
- const code = err?.code;
52894
- if (code === "MODULE_NOT_FOUND" || code === "ERR_MODULE_NOT_FOUND") {
52895
- throw new Error(
52896
- "knex is required for PostgreSQL/MySQL/MSSQL schedule storage. Install it with: npm install knex"
52897
- );
52898
- }
52899
- throw err;
52900
- }
52901
- const clientMap = {
52902
- postgresql: "pg",
52903
- mysql: "mysql2",
52904
- mssql: "tedious"
52905
- };
52906
- const client = clientMap[this.driver];
52907
- let connection;
52908
- if (this.connection.connection_string) {
52909
- connection = this.connection.connection_string;
52910
- } else if (this.driver === "mssql") {
52911
- connection = this.buildMssqlConnection();
52912
- } else {
52913
- connection = this.buildStandardConnection();
52914
- }
52915
- this.knex = knexFactory({
52916
- client,
52917
- connection,
52918
- pool: {
52919
- min: this.connection.pool?.min ?? 0,
52920
- max: this.connection.pool?.max ?? 10
52921
- }
52922
- });
52923
- await this.migrateSchema();
52924
- logger.info(`[KnexStore] Initialized (${this.driver})`);
52925
- }
52926
- buildStandardConnection() {
52927
- return {
52928
- host: this.connection.host || "localhost",
52929
- port: this.connection.port,
52930
- database: this.connection.database || "visor",
52931
- user: this.connection.user,
52932
- password: this.connection.password,
52933
- ssl: this.resolveSslConfig()
52934
- };
52935
- }
52936
- buildMssqlConnection() {
52937
- const ssl = this.connection.ssl;
52938
- const sslEnabled = ssl === true || typeof ssl === "object" && ssl.enabled !== false;
52939
- return {
52940
- server: this.connection.host || "localhost",
52941
- port: this.connection.port,
52942
- database: this.connection.database || "visor",
52943
- user: this.connection.user,
52944
- password: this.connection.password,
52945
- options: {
52946
- encrypt: sslEnabled,
52947
- trustServerCertificate: typeof ssl === "object" ? ssl.reject_unauthorized === false : !sslEnabled
52948
- }
52949
- };
52950
- }
52951
- resolveSslConfig() {
52952
- const ssl = this.connection.ssl;
52953
- if (ssl === false || ssl === void 0) return false;
52954
- if (ssl === true) return { rejectUnauthorized: true };
52955
- if (ssl.enabled === false) return false;
52956
- const result = {
52957
- rejectUnauthorized: ssl.reject_unauthorized !== false
52958
- };
52959
- if (ssl.ca) {
52960
- const caPath = this.validateSslPath(ssl.ca, "CA certificate");
52961
- result.ca = fs22.readFileSync(caPath, "utf8");
52962
- }
52963
- if (ssl.cert) {
52964
- const certPath = this.validateSslPath(ssl.cert, "client certificate");
52965
- result.cert = fs22.readFileSync(certPath, "utf8");
52966
- }
52967
- if (ssl.key) {
52968
- const keyPath = this.validateSslPath(ssl.key, "client key");
52969
- result.key = fs22.readFileSync(keyPath, "utf8");
52970
- }
52971
- return result;
52972
- }
52973
- validateSslPath(filePath, label) {
52974
- const resolved = path26.resolve(filePath);
52975
- if (resolved !== path26.normalize(resolved)) {
52976
- throw new Error(`SSL ${label} path contains invalid sequences: ${filePath}`);
52977
- }
52978
- if (!fs22.existsSync(resolved)) {
52979
- throw new Error(`SSL ${label} not found: ${filePath}`);
52980
- }
52981
- return resolved;
52982
- }
52983
- async shutdown() {
52984
- if (this.knex) {
52985
- await this.knex.destroy();
52986
- this.knex = null;
52987
- }
52988
- }
52989
- async migrateSchema() {
52990
- const knex = this.getKnex();
52991
- const exists = await knex.schema.hasTable("schedules");
52992
- if (!exists) {
52993
- await knex.schema.createTable("schedules", (table) => {
52994
- table.string("id", 36).primary();
52995
- table.string("creator_id", 255).notNullable().index();
52996
- table.string("creator_context", 255);
52997
- table.string("creator_name", 255);
52998
- table.string("timezone", 64).notNullable().defaultTo("UTC");
52999
- table.string("schedule_expr", 255);
53000
- table.bigInteger("run_at");
53001
- table.boolean("is_recurring").notNullable();
53002
- table.text("original_expression");
53003
- table.string("workflow", 255);
53004
- table.text("workflow_inputs");
53005
- table.text("output_context");
53006
- table.string("status", 20).notNullable().index();
53007
- table.bigInteger("created_at").notNullable();
53008
- table.bigInteger("last_run_at");
53009
- table.bigInteger("next_run_at");
53010
- table.integer("run_count").notNullable().defaultTo(0);
53011
- table.integer("failure_count").notNullable().defaultTo(0);
53012
- table.text("last_error");
53013
- table.text("previous_response");
53014
- table.index(["status", "next_run_at"]);
53015
- });
53016
- }
53017
- const locksExist = await knex.schema.hasTable("scheduler_locks");
53018
- if (!locksExist) {
53019
- await knex.schema.createTable("scheduler_locks", (table) => {
53020
- table.string("lock_id", 255).primary();
53021
- table.string("node_id", 255).notNullable();
53022
- table.string("lock_token", 36).notNullable();
53023
- table.bigInteger("acquired_at").notNullable();
53024
- table.bigInteger("expires_at").notNullable();
53025
- });
53026
- }
53027
- }
53028
- getKnex() {
53029
- if (!this.knex) {
53030
- throw new Error("[KnexStore] Not initialized. Call initialize() first.");
53031
- }
53032
- return this.knex;
53033
- }
53034
- // --- CRUD ---
53035
- async create(schedule) {
53036
- const knex = this.getKnex();
53037
- const newSchedule = {
53038
- ...schedule,
53039
- id: (0, import_uuid2.v4)(),
53040
- createdAt: Date.now(),
53041
- runCount: 0,
53042
- failureCount: 0,
53043
- status: "active"
53044
- };
53045
- await knex("schedules").insert(toInsertRow(newSchedule));
53046
- logger.info(`[KnexStore] Created schedule ${newSchedule.id} for user ${newSchedule.creatorId}`);
53047
- return newSchedule;
53048
- }
53049
- async importSchedule(schedule) {
53050
- const knex = this.getKnex();
53051
- const existing = await knex("schedules").where("id", schedule.id).first();
53052
- if (existing) return;
53053
- await knex("schedules").insert(toInsertRow(schedule));
53054
- }
53055
- async get(id) {
53056
- const knex = this.getKnex();
53057
- const row = await knex("schedules").where("id", id).first();
53058
- return row ? fromDbRow2(row) : void 0;
53059
- }
53060
- async update(id, patch) {
53061
- const knex = this.getKnex();
53062
- const existing = await knex("schedules").where("id", id).first();
53063
- if (!existing) return void 0;
53064
- const current = fromDbRow2(existing);
53065
- const updated = { ...current, ...patch, id: current.id };
53066
- const row = toInsertRow(updated);
53067
- delete row.id;
53068
- await knex("schedules").where("id", id).update(row);
53069
- return updated;
53070
- }
53071
- async delete(id) {
53072
- const knex = this.getKnex();
53073
- const deleted = await knex("schedules").where("id", id).del();
53074
- if (deleted > 0) {
53075
- logger.info(`[KnexStore] Deleted schedule ${id}`);
53076
- return true;
53077
- }
53078
- return false;
53079
- }
53080
- // --- Queries ---
53081
- async getByCreator(creatorId) {
53082
- const knex = this.getKnex();
53083
- const rows = await knex("schedules").where("creator_id", creatorId);
53084
- return rows.map((r) => fromDbRow2(r));
53085
- }
53086
- async getActiveSchedules() {
53087
- const knex = this.getKnex();
53088
- const rows = await knex("schedules").where("status", "active");
53089
- return rows.map((r) => fromDbRow2(r));
53090
- }
53091
- async getDueSchedules(now) {
53092
- const ts = now ?? Date.now();
53093
- const knex = this.getKnex();
53094
- const bFalse = this.driver === "mssql" ? 0 : false;
53095
- const bTrue = this.driver === "mssql" ? 1 : true;
53096
- const rows = await knex("schedules").where("status", "active").andWhere(function() {
53097
- this.where(function() {
53098
- this.where("is_recurring", bFalse).whereNotNull("run_at").where("run_at", "<=", ts);
53099
- }).orWhere(function() {
53100
- this.where("is_recurring", bTrue).whereNotNull("next_run_at").where("next_run_at", "<=", ts);
53101
- });
53102
- });
53103
- return rows.map((r) => fromDbRow2(r));
53104
- }
53105
- async findByWorkflow(creatorId, workflowName) {
53106
- const knex = this.getKnex();
53107
- const escaped = workflowName.toLowerCase().replace(/[%_\\]/g, "\\$&");
53108
- const pattern = `%${escaped}%`;
53109
- const rows = await knex("schedules").where("creator_id", creatorId).where("status", "active").whereRaw("LOWER(workflow) LIKE ? ESCAPE '\\'", [pattern]);
53110
- return rows.map((r) => fromDbRow2(r));
53111
- }
53112
- async getAll() {
53113
- const knex = this.getKnex();
53114
- const rows = await knex("schedules");
53115
- return rows.map((r) => fromDbRow2(r));
53116
- }
53117
- async getStats() {
53118
- const knex = this.getKnex();
53119
- const boolTrue = this.driver === "mssql" ? "1" : "true";
53120
- const boolFalse = this.driver === "mssql" ? "0" : "false";
53121
- const result = await knex("schedules").select(
53122
- knex.raw("COUNT(*) as total"),
53123
- knex.raw("SUM(CASE WHEN status = 'active' THEN 1 ELSE 0 END) as active"),
53124
- knex.raw("SUM(CASE WHEN status = 'paused' THEN 1 ELSE 0 END) as paused"),
53125
- knex.raw("SUM(CASE WHEN status = 'completed' THEN 1 ELSE 0 END) as completed"),
53126
- knex.raw("SUM(CASE WHEN status = 'failed' THEN 1 ELSE 0 END) as failed"),
53127
- knex.raw(`SUM(CASE WHEN is_recurring = ${boolTrue} THEN 1 ELSE 0 END) as recurring`),
53128
- knex.raw(`SUM(CASE WHEN is_recurring = ${boolFalse} THEN 1 ELSE 0 END) as one_time`)
53129
- ).first();
53130
- return {
53131
- total: Number(result.total) || 0,
53132
- active: Number(result.active) || 0,
53133
- paused: Number(result.paused) || 0,
53134
- completed: Number(result.completed) || 0,
53135
- failed: Number(result.failed) || 0,
53136
- recurring: Number(result.recurring) || 0,
53137
- oneTime: Number(result.one_time) || 0
53138
- };
53139
- }
53140
- async validateLimits(creatorId, isRecurring, limits) {
53141
- const knex = this.getKnex();
53142
- if (limits.maxGlobal) {
53143
- const result = await knex("schedules").count("* as cnt").first();
53144
- if (Number(result?.cnt) >= limits.maxGlobal) {
53145
- throw new Error(`Global schedule limit reached (${limits.maxGlobal})`);
53146
- }
53147
- }
53148
- if (limits.maxPerUser) {
53149
- const result = await knex("schedules").where("creator_id", creatorId).count("* as cnt").first();
53150
- if (Number(result?.cnt) >= limits.maxPerUser) {
53151
- throw new Error(`You have reached the maximum number of schedules (${limits.maxPerUser})`);
53152
- }
53153
- }
53154
- if (isRecurring && limits.maxRecurringPerUser) {
53155
- const bTrue = this.driver === "mssql" ? 1 : true;
53156
- const result = await knex("schedules").where("creator_id", creatorId).where("is_recurring", bTrue).count("* as cnt").first();
53157
- if (Number(result?.cnt) >= limits.maxRecurringPerUser) {
53158
- throw new Error(
53159
- `You have reached the maximum number of recurring schedules (${limits.maxRecurringPerUser})`
53160
- );
53161
- }
53162
- }
53163
- }
53164
- // --- HA Distributed Locking (via scheduler_locks table) ---
53165
- async tryAcquireLock(lockId, nodeId, ttlSeconds) {
53166
- const knex = this.getKnex();
53167
- const now = Date.now();
53168
- const expiresAt = now + ttlSeconds * 1e3;
53169
- const token = (0, import_uuid2.v4)();
53170
- const updated = await knex("scheduler_locks").where("lock_id", lockId).where("expires_at", "<", now).update({
53171
- node_id: nodeId,
53172
- lock_token: token,
53173
- acquired_at: now,
53174
- expires_at: expiresAt
53175
- });
53176
- if (updated > 0) return token;
53177
- try {
53178
- await knex("scheduler_locks").insert({
53179
- lock_id: lockId,
53180
- node_id: nodeId,
53181
- lock_token: token,
53182
- acquired_at: now,
53183
- expires_at: expiresAt
53184
- });
53185
- return token;
53186
- } catch {
53187
- return null;
53188
- }
53189
- }
53190
- async releaseLock(lockId, lockToken) {
53191
- const knex = this.getKnex();
53192
- await knex("scheduler_locks").where("lock_id", lockId).where("lock_token", lockToken).del();
53193
- }
53194
- async renewLock(lockId, lockToken, ttlSeconds) {
53195
- const knex = this.getKnex();
53196
- const now = Date.now();
53197
- const expiresAt = now + ttlSeconds * 1e3;
53198
- const updated = await knex("scheduler_locks").where("lock_id", lockId).where("lock_token", lockToken).update({ acquired_at: now, expires_at: expiresAt });
53199
- return updated > 0;
53200
- }
53201
- async flush() {
53202
- }
53203
- };
53204
- }
53205
- });
53206
-
53207
- // src/enterprise/loader.ts
53208
- var loader_exports = {};
53209
- __export(loader_exports, {
53210
- loadEnterprisePolicyEngine: () => loadEnterprisePolicyEngine,
53211
- loadEnterpriseStoreBackend: () => loadEnterpriseStoreBackend
53212
- });
53213
- async function loadEnterprisePolicyEngine(config) {
53214
- try {
53215
- const { LicenseValidator: LicenseValidator2 } = await Promise.resolve().then(() => (init_validator(), validator_exports));
53216
- const validator = new LicenseValidator2();
53217
- const license = await validator.loadAndValidate();
53218
- if (!license || !validator.hasFeature("policy")) {
53219
- return new DefaultPolicyEngine();
53220
- }
53221
- if (validator.isInGracePeriod()) {
53222
- console.warn(
53223
- "[visor:enterprise] License has expired but is within the 72-hour grace period. Please renew your license."
53224
- );
53225
- }
53226
- const { OpaPolicyEngine: OpaPolicyEngine2 } = await Promise.resolve().then(() => (init_opa_policy_engine(), opa_policy_engine_exports));
53227
- const engine = new OpaPolicyEngine2(config);
53228
- await engine.initialize(config);
53229
- return engine;
53230
- } catch (err) {
53231
- const msg = err instanceof Error ? err.message : String(err);
53232
- try {
53233
- const { logger: logger2 } = (init_logger(), __toCommonJS(logger_exports));
53234
- logger2.warn(`[PolicyEngine] Enterprise policy init failed, falling back to default: ${msg}`);
53235
- } catch {
53236
- }
53237
- return new DefaultPolicyEngine();
53238
- }
53239
- }
53240
- async function loadEnterpriseStoreBackend(driver, storageConfig, haConfig) {
53241
- const { LicenseValidator: LicenseValidator2 } = await Promise.resolve().then(() => (init_validator(), validator_exports));
53242
- const validator = new LicenseValidator2();
53243
- const license = await validator.loadAndValidate();
53244
- if (!license || !validator.hasFeature("scheduler-sql")) {
53245
- throw new Error(
53246
- `The ${driver} schedule storage driver requires a Visor Enterprise license with the 'scheduler-sql' feature. Please upgrade or use driver: 'sqlite' (default).`
53247
- );
53248
- }
53249
- if (validator.isInGracePeriod()) {
53250
- console.warn(
53251
- "[visor:enterprise] License has expired but is within the 72-hour grace period. Please renew your license."
53252
- );
53253
- }
53254
- const { KnexStoreBackend: KnexStoreBackend2 } = await Promise.resolve().then(() => (init_knex_store(), knex_store_exports));
53255
- return new KnexStoreBackend2(driver, storageConfig, haConfig);
53256
- }
53257
- var init_loader = __esm({
53258
- "src/enterprise/loader.ts"() {
53259
- "use strict";
53260
- init_default_engine();
53261
- }
53262
- });
53263
-
53264
52006
  // src/event-bus/event-bus.ts
53265
52007
  var event_bus_exports = {};
53266
52008
  __export(event_bus_exports, {
@@ -54167,8 +52909,8 @@ ${content}
54167
52909
  * Sleep utility
54168
52910
  */
54169
52911
  sleep(ms) {
54170
- return new Promise((resolve15) => {
54171
- const t = setTimeout(resolve15, ms);
52912
+ return new Promise((resolve11) => {
52913
+ const t = setTimeout(resolve11, ms);
54172
52914
  if (typeof t.unref === "function") {
54173
52915
  try {
54174
52916
  t.unref();
@@ -54442,8 +53184,8 @@ ${end}`);
54442
53184
  async updateGroupedComment(ctx, comments, group, changedIds) {
54443
53185
  const existingLock = this.updateLocks.get(group);
54444
53186
  let resolveLock;
54445
- const ourLock = new Promise((resolve15) => {
54446
- resolveLock = resolve15;
53187
+ const ourLock = new Promise((resolve11) => {
53188
+ resolveLock = resolve11;
54447
53189
  });
54448
53190
  this.updateLocks.set(group, ourLock);
54449
53191
  try {
@@ -54755,7 +53497,7 @@ ${blocks}
54755
53497
  * Sleep utility for enforcing delays
54756
53498
  */
54757
53499
  sleep(ms) {
54758
- return new Promise((resolve15) => setTimeout(resolve15, ms));
53500
+ return new Promise((resolve11) => setTimeout(resolve11, ms));
54759
53501
  }
54760
53502
  };
54761
53503
  }
@@ -55070,17 +53812,17 @@ function extractMermaidDiagrams(text) {
55070
53812
  return diagrams;
55071
53813
  }
55072
53814
  async function renderMermaidToPng(mermaidCode) {
55073
- const tmpDir = os2.tmpdir();
55074
- const inputFile = path28.join(
53815
+ const tmpDir = os.tmpdir();
53816
+ const inputFile = path24.join(
55075
53817
  tmpDir,
55076
53818
  `mermaid-${Date.now()}-${Math.random().toString(36).slice(2)}.mmd`
55077
53819
  );
55078
- const outputFile = path28.join(
53820
+ const outputFile = path24.join(
55079
53821
  tmpDir,
55080
53822
  `mermaid-${Date.now()}-${Math.random().toString(36).slice(2)}.png`
55081
53823
  );
55082
53824
  try {
55083
- fs24.writeFileSync(inputFile, mermaidCode, "utf-8");
53825
+ fs20.writeFileSync(inputFile, mermaidCode, "utf-8");
55084
53826
  const chromiumPaths = [
55085
53827
  "/usr/bin/chromium",
55086
53828
  "/usr/bin/chromium-browser",
@@ -55089,7 +53831,7 @@ async function renderMermaidToPng(mermaidCode) {
55089
53831
  ];
55090
53832
  let chromiumPath;
55091
53833
  for (const p of chromiumPaths) {
55092
- if (fs24.existsSync(p)) {
53834
+ if (fs20.existsSync(p)) {
55093
53835
  chromiumPath = p;
55094
53836
  break;
55095
53837
  }
@@ -55098,8 +53840,8 @@ async function renderMermaidToPng(mermaidCode) {
55098
53840
  if (chromiumPath) {
55099
53841
  env.PUPPETEER_EXECUTABLE_PATH = chromiumPath;
55100
53842
  }
55101
- const result = await new Promise((resolve15) => {
55102
- const proc = (0, import_child_process6.spawn)(
53843
+ const result = await new Promise((resolve11) => {
53844
+ const proc = (0, import_child_process5.spawn)(
55103
53845
  "npx",
55104
53846
  [
55105
53847
  "--yes",
@@ -55128,32 +53870,32 @@ async function renderMermaidToPng(mermaidCode) {
55128
53870
  });
55129
53871
  proc.on("close", (code) => {
55130
53872
  if (code === 0) {
55131
- resolve15({ success: true });
53873
+ resolve11({ success: true });
55132
53874
  } else {
55133
- resolve15({ success: false, error: stderr || `Exit code ${code}` });
53875
+ resolve11({ success: false, error: stderr || `Exit code ${code}` });
55134
53876
  }
55135
53877
  });
55136
53878
  proc.on("error", (err) => {
55137
- resolve15({ success: false, error: err.message });
53879
+ resolve11({ success: false, error: err.message });
55138
53880
  });
55139
53881
  });
55140
53882
  if (!result.success) {
55141
53883
  console.warn(`Mermaid rendering failed: ${result.error}`);
55142
53884
  return null;
55143
53885
  }
55144
- if (!fs24.existsSync(outputFile)) {
53886
+ if (!fs20.existsSync(outputFile)) {
55145
53887
  console.warn("Mermaid output file not created");
55146
53888
  return null;
55147
53889
  }
55148
- const pngBuffer = fs24.readFileSync(outputFile);
53890
+ const pngBuffer = fs20.readFileSync(outputFile);
55149
53891
  return pngBuffer;
55150
53892
  } catch (e) {
55151
53893
  console.warn(`Mermaid rendering error: ${e instanceof Error ? e.message : String(e)}`);
55152
53894
  return null;
55153
53895
  } finally {
55154
53896
  try {
55155
- if (fs24.existsSync(inputFile)) fs24.unlinkSync(inputFile);
55156
- if (fs24.existsSync(outputFile)) fs24.unlinkSync(outputFile);
53897
+ if (fs20.existsSync(inputFile)) fs20.unlinkSync(inputFile);
53898
+ if (fs20.existsSync(outputFile)) fs20.unlinkSync(outputFile);
55157
53899
  } catch {
55158
53900
  }
55159
53901
  }
@@ -55258,14 +54000,14 @@ function replaceFileSections(text, sections, replacement = (idx) => `_(See file:
55258
54000
  function formatSlackText(text) {
55259
54001
  return markdownToSlack(text);
55260
54002
  }
55261
- var import_child_process6, fs24, path28, os2;
54003
+ var import_child_process5, fs20, path24, os;
55262
54004
  var init_markdown = __esm({
55263
54005
  "src/slack/markdown.ts"() {
55264
54006
  "use strict";
55265
- import_child_process6 = require("child_process");
55266
- fs24 = __toESM(require("fs"));
55267
- path28 = __toESM(require("path"));
55268
- os2 = __toESM(require("os"));
54007
+ import_child_process5 = require("child_process");
54008
+ fs20 = __toESM(require("fs"));
54009
+ path24 = __toESM(require("path"));
54010
+ os = __toESM(require("os"));
55269
54011
  }
55270
54012
  });
55271
54013
 
@@ -56241,15 +54983,15 @@ function serializeRunState(state) {
56241
54983
  ])
56242
54984
  };
56243
54985
  }
56244
- var path29, fs25, StateMachineExecutionEngine;
54986
+ var path25, fs21, StateMachineExecutionEngine;
56245
54987
  var init_state_machine_execution_engine = __esm({
56246
54988
  "src/state-machine-execution-engine.ts"() {
56247
54989
  "use strict";
56248
54990
  init_runner();
56249
54991
  init_logger();
56250
54992
  init_sandbox_manager();
56251
- path29 = __toESM(require("path"));
56252
- fs25 = __toESM(require("fs"));
54993
+ path25 = __toESM(require("path"));
54994
+ fs21 = __toESM(require("fs"));
56253
54995
  StateMachineExecutionEngine = class _StateMachineExecutionEngine {
56254
54996
  workingDirectory;
56255
54997
  executionContext;
@@ -56481,8 +55223,8 @@ var init_state_machine_execution_engine = __esm({
56481
55223
  logger.debug(
56482
55224
  `[PolicyEngine] Loading enterprise policy engine (engine=${configWithTagFilter.policy.engine})`
56483
55225
  );
56484
- const { loadEnterprisePolicyEngine: loadEnterprisePolicyEngine2 } = await Promise.resolve().then(() => (init_loader(), loader_exports));
56485
- context2.policyEngine = await loadEnterprisePolicyEngine2(configWithTagFilter.policy);
55226
+ const { loadEnterprisePolicyEngine } = await import("./enterprise/loader");
55227
+ context2.policyEngine = await loadEnterprisePolicyEngine(configWithTagFilter.policy);
56486
55228
  logger.debug(
56487
55229
  `[PolicyEngine] Initialized: ${context2.policyEngine?.constructor?.name || "unknown"}`
56488
55230
  );
@@ -56634,9 +55376,9 @@ var init_state_machine_execution_engine = __esm({
56634
55376
  }
56635
55377
  const checkId = String(ev?.checkId || "unknown");
56636
55378
  const threadKey = ev?.threadKey || (channel && threadTs ? `${channel}:${threadTs}` : "session");
56637
- const baseDir = process.env.VISOR_SNAPSHOT_DIR || path29.resolve(process.cwd(), ".visor", "snapshots");
56638
- fs25.mkdirSync(baseDir, { recursive: true });
56639
- const filePath = path29.join(baseDir, `${threadKey}-${checkId}.json`);
55379
+ const baseDir = process.env.VISOR_SNAPSHOT_DIR || path25.resolve(process.cwd(), ".visor", "snapshots");
55380
+ fs21.mkdirSync(baseDir, { recursive: true });
55381
+ const filePath = path25.join(baseDir, `${threadKey}-${checkId}.json`);
56640
55382
  await this.saveSnapshotToFile(filePath);
56641
55383
  logger.info(`[Snapshot] Saved run snapshot: ${filePath}`);
56642
55384
  try {
@@ -56777,7 +55519,7 @@ var init_state_machine_execution_engine = __esm({
56777
55519
  * Does not include secrets. Intended for debugging and future resume support.
56778
55520
  */
56779
55521
  async saveSnapshotToFile(filePath) {
56780
- const fs26 = await import("fs/promises");
55522
+ const fs22 = await import("fs/promises");
56781
55523
  const ctx = this._lastContext;
56782
55524
  const runner = this._lastRunner;
56783
55525
  if (!ctx || !runner) {
@@ -56797,14 +55539,14 @@ var init_state_machine_execution_engine = __esm({
56797
55539
  journal: entries,
56798
55540
  requestedChecks: ctx.requestedChecks || []
56799
55541
  };
56800
- await fs26.writeFile(filePath, JSON.stringify(payload, null, 2), "utf8");
55542
+ await fs22.writeFile(filePath, JSON.stringify(payload, null, 2), "utf8");
56801
55543
  }
56802
55544
  /**
56803
55545
  * Load a snapshot JSON from file and return it. Resume support can build on this.
56804
55546
  */
56805
55547
  async loadSnapshotFromFile(filePath) {
56806
- const fs26 = await import("fs/promises");
56807
- const raw = await fs26.readFile(filePath, "utf8");
55548
+ const fs22 = await import("fs/promises");
55549
+ const raw = await fs22.readFile(filePath, "utf8");
56808
55550
  return JSON.parse(raw);
56809
55551
  }
56810
55552
  /**