@probelabs/visor 0.1.173 → 0.1.174-ee

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 (105) hide show
  1. package/dist/docs/dashboards/README.md +73 -26
  2. package/dist/docs/dashboards/grafana-visor-overview.json +435 -15
  3. package/dist/docs/telemetry-reference.md +387 -0
  4. package/dist/docs/telemetry-setup.md +2 -0
  5. package/dist/generated/config-schema.d.ts +277 -7
  6. package/dist/generated/config-schema.d.ts.map +1 -1
  7. package/dist/generated/config-schema.json +3803 -0
  8. package/dist/index.js +2202 -51
  9. package/dist/sdk/{a2a-frontend-VHOQ45CR.mjs → a2a-frontend-FUJRKHJB.mjs} +3 -3
  10. package/dist/sdk/{check-provider-registry-65GO3SCO.mjs → check-provider-registry-53C2ZIXJ.mjs} +7 -7
  11. package/dist/sdk/{check-provider-registry-75O5XJMA.mjs → check-provider-registry-UPQNHHFF.mjs} +7 -7
  12. package/dist/sdk/{chunk-Y5MEQW2W.mjs → chunk-2PL2YH3B.mjs} +19 -19
  13. package/dist/sdk/{chunk-4TV2CVVI.mjs → chunk-34QX63WK.mjs} +16 -14
  14. package/dist/sdk/chunk-34QX63WK.mjs.map +1 -0
  15. package/dist/sdk/{chunk-2HXOGRAS.mjs → chunk-65SHRIQF.mjs} +3 -3
  16. package/dist/sdk/{chunk-2HXOGRAS.mjs.map → chunk-65SHRIQF.mjs.map} +1 -1
  17. package/dist/sdk/{chunk-VVHALCWV.mjs → chunk-EFNNJIMY.mjs} +3 -3
  18. package/dist/sdk/{chunk-7CWJNSL2.mjs → chunk-GKSSG5IM.mjs} +20 -20
  19. package/dist/sdk/{chunk-7CWJNSL2.mjs.map → chunk-GKSSG5IM.mjs.map} +1 -1
  20. package/dist/sdk/{chunk-HZEXCJGA.mjs → chunk-W4KCJM6J.mjs} +282 -8
  21. package/dist/sdk/chunk-W4KCJM6J.mjs.map +1 -0
  22. package/dist/sdk/{chunk-GVPMO6QD.mjs → chunk-WJIV7MKY.mjs} +3 -3
  23. package/dist/sdk/{config-UXRHADSE.mjs → config-BVL3KFMB.mjs} +2 -2
  24. package/dist/sdk/{failure-condition-evaluator-Q4KNMX6F.mjs → failure-condition-evaluator-DL6H57NX.mjs} +4 -4
  25. package/dist/sdk/{github-frontend-56UQTA47.mjs → github-frontend-F2YCPK6H.mjs} +4 -4
  26. package/dist/sdk/{host-QRGXXRDA.mjs → host-6TBS44ER.mjs} +3 -3
  27. package/dist/sdk/{host-VYPJ2UGQ.mjs → host-LRWIKURZ.mjs} +3 -3
  28. package/dist/sdk/knex-store-QCEW4I4R.mjs +527 -0
  29. package/dist/sdk/knex-store-QCEW4I4R.mjs.map +1 -0
  30. package/dist/sdk/loader-Q7K76ZIY.mjs +89 -0
  31. package/dist/sdk/loader-Q7K76ZIY.mjs.map +1 -0
  32. package/dist/sdk/{metrics-FU2G5SZ2.mjs → metrics-JTOG2HNO.mjs} +2 -2
  33. package/dist/sdk/opa-policy-engine-QCSSIMUF.mjs +655 -0
  34. package/dist/sdk/opa-policy-engine-QCSSIMUF.mjs.map +1 -0
  35. package/dist/sdk/{routing-DBQHPP2O.mjs → routing-GF2CF3JT.mjs} +5 -5
  36. package/dist/sdk/{schedule-tool-MHICRNCI.mjs → schedule-tool-5KDBDCFO.mjs} +7 -7
  37. package/dist/sdk/{schedule-tool-VRLX54J5.mjs → schedule-tool-UMDRCNO5.mjs} +7 -7
  38. package/dist/sdk/{schedule-tool-handler-3ES4WON7.mjs → schedule-tool-handler-5EPTHBLS.mjs} +7 -7
  39. package/dist/sdk/{schedule-tool-handler-FQGAWC5N.mjs → schedule-tool-handler-MUF5V36L.mjs} +7 -7
  40. package/dist/sdk/sdk.d.mts +137 -133
  41. package/dist/sdk/sdk.d.ts +137 -133
  42. package/dist/sdk/sdk.js +1952 -302
  43. package/dist/sdk/sdk.js.map +1 -1
  44. package/dist/sdk/sdk.mjs +6 -6
  45. package/dist/sdk/{trace-helpers-UKMYHQIK.mjs → trace-helpers-FKM2MEDW.mjs} +3 -3
  46. package/dist/sdk/validator-XTZJZZJH.mjs +134 -0
  47. package/dist/sdk/validator-XTZJZZJH.mjs.map +1 -0
  48. package/dist/sdk/{workflow-check-provider-F5DTEX6E.mjs → workflow-check-provider-EWMZEEES.mjs} +7 -7
  49. package/dist/sdk/{workflow-check-provider-VEOVTCVU.mjs → workflow-check-provider-RQUCBAYY.mjs} +7 -7
  50. package/dist/telemetry/metrics.d.ts.map +1 -1
  51. package/dist/types/config.d.ts +5 -4
  52. package/dist/types/config.d.ts.map +1 -1
  53. package/package.json +2 -2
  54. package/dist/output/traces/run-2026-03-09T15-21-25-122Z.ndjson +0 -138
  55. package/dist/output/traces/run-2026-03-09T15-22-05-255Z.ndjson +0 -2280
  56. package/dist/sdk/a2a-frontend-7CYN3X7M.mjs +0 -1658
  57. package/dist/sdk/a2a-frontend-VHOQ45CR.mjs.map +0 -1
  58. package/dist/sdk/check-provider-registry-DBTS7OXY.mjs +0 -30
  59. package/dist/sdk/chunk-4TV2CVVI.mjs.map +0 -1
  60. package/dist/sdk/chunk-AV6KML52.mjs +0 -45016
  61. package/dist/sdk/chunk-AV6KML52.mjs.map +0 -1
  62. package/dist/sdk/chunk-HZEXCJGA.mjs.map +0 -1
  63. package/dist/sdk/chunk-LTHHE6Z5.mjs +0 -516
  64. package/dist/sdk/chunk-LTHHE6Z5.mjs.map +0 -1
  65. package/dist/sdk/chunk-VK7FUBBU.mjs +0 -739
  66. package/dist/sdk/chunk-VVHALCWV.mjs.map +0 -1
  67. package/dist/sdk/chunk-WYFQQ445.mjs +0 -1502
  68. package/dist/sdk/chunk-WYFQQ445.mjs.map +0 -1
  69. package/dist/sdk/failure-condition-evaluator-SNR5XLGN.mjs +0 -18
  70. package/dist/sdk/github-frontend-OOP26667.mjs +0 -1386
  71. package/dist/sdk/github-frontend-OOP26667.mjs.map +0 -1
  72. package/dist/sdk/routing-ZAUCS3HJ.mjs +0 -26
  73. package/dist/sdk/schedule-tool-2FIVKPVJ.mjs +0 -36
  74. package/dist/sdk/schedule-tool-handler-FQGAWC5N.mjs.map +0 -1
  75. package/dist/sdk/schedule-tool-handler-KYUHU4JR.mjs +0 -40
  76. package/dist/sdk/schedule-tool-handler-KYUHU4JR.mjs.map +0 -1
  77. package/dist/sdk/trace-helpers-UKMYHQIK.mjs.map +0 -1
  78. package/dist/sdk/trace-helpers-ZFDJ55SH.mjs +0 -29
  79. package/dist/sdk/trace-helpers-ZFDJ55SH.mjs.map +0 -1
  80. package/dist/sdk/workflow-check-provider-5KQTXKWS.mjs +0 -30
  81. package/dist/sdk/workflow-check-provider-5KQTXKWS.mjs.map +0 -1
  82. package/dist/sdk/workflow-check-provider-F5DTEX6E.mjs.map +0 -1
  83. package/dist/sdk/workflow-check-provider-VEOVTCVU.mjs.map +0 -1
  84. package/dist/traces/run-2026-03-09T15-21-25-122Z.ndjson +0 -138
  85. package/dist/traces/run-2026-03-09T15-22-05-255Z.ndjson +0 -2280
  86. /package/dist/sdk/{a2a-frontend-7CYN3X7M.mjs.map → a2a-frontend-FUJRKHJB.mjs.map} +0 -0
  87. /package/dist/sdk/{check-provider-registry-65GO3SCO.mjs.map → check-provider-registry-53C2ZIXJ.mjs.map} +0 -0
  88. /package/dist/sdk/{check-provider-registry-75O5XJMA.mjs.map → check-provider-registry-UPQNHHFF.mjs.map} +0 -0
  89. /package/dist/sdk/{chunk-Y5MEQW2W.mjs.map → chunk-2PL2YH3B.mjs.map} +0 -0
  90. /package/dist/sdk/{chunk-VK7FUBBU.mjs.map → chunk-EFNNJIMY.mjs.map} +0 -0
  91. /package/dist/sdk/{chunk-GVPMO6QD.mjs.map → chunk-WJIV7MKY.mjs.map} +0 -0
  92. /package/dist/sdk/{check-provider-registry-DBTS7OXY.mjs.map → config-BVL3KFMB.mjs.map} +0 -0
  93. /package/dist/sdk/{config-UXRHADSE.mjs.map → failure-condition-evaluator-DL6H57NX.mjs.map} +0 -0
  94. /package/dist/sdk/{github-frontend-56UQTA47.mjs.map → github-frontend-F2YCPK6H.mjs.map} +0 -0
  95. /package/dist/sdk/{host-QRGXXRDA.mjs.map → host-6TBS44ER.mjs.map} +0 -0
  96. /package/dist/sdk/{host-VYPJ2UGQ.mjs.map → host-LRWIKURZ.mjs.map} +0 -0
  97. /package/dist/sdk/{failure-condition-evaluator-Q4KNMX6F.mjs.map → metrics-JTOG2HNO.mjs.map} +0 -0
  98. /package/dist/sdk/{failure-condition-evaluator-SNR5XLGN.mjs.map → routing-GF2CF3JT.mjs.map} +0 -0
  99. /package/dist/sdk/{metrics-FU2G5SZ2.mjs.map → schedule-tool-5KDBDCFO.mjs.map} +0 -0
  100. /package/dist/sdk/{routing-DBQHPP2O.mjs.map → schedule-tool-UMDRCNO5.mjs.map} +0 -0
  101. /package/dist/sdk/{routing-ZAUCS3HJ.mjs.map → schedule-tool-handler-5EPTHBLS.mjs.map} +0 -0
  102. /package/dist/sdk/{schedule-tool-2FIVKPVJ.mjs.map → schedule-tool-handler-MUF5V36L.mjs.map} +0 -0
  103. /package/dist/sdk/{schedule-tool-MHICRNCI.mjs.map → trace-helpers-FKM2MEDW.mjs.map} +0 -0
  104. /package/dist/sdk/{schedule-tool-VRLX54J5.mjs.map → workflow-check-provider-EWMZEEES.mjs.map} +0 -0
  105. /package/dist/sdk/{schedule-tool-handler-3ES4WON7.mjs.map → workflow-check-provider-RQUCBAYY.mjs.map} +0 -0
package/dist/sdk/sdk.js CHANGED
@@ -704,7 +704,7 @@ var require_package = __commonJS({
704
704
  "package.json"(exports2, module2) {
705
705
  module2.exports = {
706
706
  name: "@probelabs/visor",
707
- version: "0.1.173",
707
+ version: "0.1.42",
708
708
  main: "dist/index.js",
709
709
  bin: {
710
710
  visor: "./dist/index.js"
@@ -823,7 +823,7 @@ var require_package = __commonJS({
823
823
  "@opentelemetry/sdk-node": "^0.203.0",
824
824
  "@opentelemetry/sdk-trace-base": "^1.30.1",
825
825
  "@opentelemetry/semantic-conventions": "^1.30.1",
826
- "@probelabs/probe": "^0.6.0-rc290",
826
+ "@probelabs/probe": "^0.6.0-rc291",
827
827
  "@types/commander": "^2.12.0",
828
828
  "@types/uuid": "^10.0.0",
829
829
  acorn: "^8.16.0",
@@ -939,50 +939,53 @@ __export(metrics_exports, {
939
939
  resetRunAiCalls: () => resetRunAiCalls,
940
940
  resetTestMetricsSnapshot: () => resetTestMetricsSnapshot
941
941
  });
942
+ function getMeter() {
943
+ return metrics.getMeter("visor");
944
+ }
942
945
  function ensureInstruments() {
943
946
  if (initialized) return;
944
947
  try {
945
- checkDurationHist = meter.createHistogram("visor.check.duration_ms", {
948
+ checkDurationHist = getMeter().createHistogram("visor.check.duration_ms", {
946
949
  description: "Duration of a check execution in milliseconds",
947
950
  unit: "ms"
948
951
  });
949
- providerDurationHist = meter.createHistogram("visor.provider.duration_ms", {
952
+ providerDurationHist = getMeter().createHistogram("visor.provider.duration_ms", {
950
953
  description: "Duration of provider execution in milliseconds",
951
954
  unit: "ms"
952
955
  });
953
- foreachDurationHist = meter.createHistogram("visor.foreach.item.duration_ms", {
956
+ foreachDurationHist = getMeter().createHistogram("visor.foreach.item.duration_ms", {
954
957
  description: "Duration of a forEach item execution in milliseconds",
955
958
  unit: "ms"
956
959
  });
957
- issuesCounter = meter.createCounter("visor.check.issues", {
960
+ issuesCounter = getMeter().createCounter("visor.check.issues", {
958
961
  description: "Number of issues produced by checks",
959
962
  unit: "1"
960
963
  });
961
- activeChecks = meter.createUpDownCounter("visor.run.active_checks", {
964
+ activeChecks = getMeter().createUpDownCounter("visor.run.active_checks", {
962
965
  description: "Number of checks actively running",
963
966
  unit: "1"
964
967
  });
965
- failIfCounter = meter.createCounter("visor.fail_if.triggered", {
968
+ failIfCounter = getMeter().createCounter("visor.fail_if.triggered", {
966
969
  description: "Number of times fail_if condition triggered",
967
970
  unit: "1"
968
971
  });
969
- diagramBlocks = meter.createCounter("visor.diagram.blocks", {
972
+ diagramBlocks = getMeter().createCounter("visor.diagram.blocks", {
970
973
  description: "Number of Mermaid diagram blocks emitted",
971
974
  unit: "1"
972
975
  });
973
- runCounter = meter.createCounter("visor.run.total", {
976
+ runCounter = getMeter().createCounter("visor.run.total", {
974
977
  description: "Total number of visor runs (workflow executions)",
975
978
  unit: "1"
976
979
  });
977
- runDurationHist = meter.createHistogram("visor.run.duration_ms", {
980
+ runDurationHist = getMeter().createHistogram("visor.run.duration_ms", {
978
981
  description: "Duration of a complete visor run in milliseconds",
979
982
  unit: "ms"
980
983
  });
981
- aiCallCounter = meter.createCounter("visor.ai_call.total", {
984
+ aiCallCounter = getMeter().createCounter("visor.ai_call.total", {
982
985
  description: "Total number of AI provider calls",
983
986
  unit: "1"
984
987
  });
985
- runAiCallsHist = meter.createHistogram("visor.run.ai_calls", {
988
+ runAiCallsHist = getMeter().createHistogram("visor.run.ai_calls", {
986
989
  description: "Number of AI calls per visor run",
987
990
  unit: "1"
988
991
  });
@@ -1119,13 +1122,12 @@ function getTestMetricsSnapshot() {
1119
1122
  function resetTestMetricsSnapshot() {
1120
1123
  Object.keys(TEST_SNAPSHOT).forEach((k) => TEST_SNAPSHOT[k] = 0);
1121
1124
  }
1122
- var initialized, meter, TEST_ENABLED, TEST_SNAPSHOT, checkDurationHist, providerDurationHist, foreachDurationHist, issuesCounter, activeChecks, failIfCounter, diagramBlocks, runCounter, runDurationHist, aiCallCounter, runAiCallsHist, _currentRunAiCalls;
1125
+ var initialized, TEST_ENABLED, TEST_SNAPSHOT, checkDurationHist, providerDurationHist, foreachDurationHist, issuesCounter, activeChecks, failIfCounter, diagramBlocks, runCounter, runDurationHist, aiCallCounter, runAiCallsHist, _currentRunAiCalls;
1123
1126
  var init_metrics = __esm({
1124
1127
  "src/telemetry/metrics.ts"() {
1125
1128
  "use strict";
1126
1129
  init_lazy_otel();
1127
1130
  initialized = false;
1128
- meter = metrics.getMeter("visor");
1129
1131
  TEST_ENABLED = process.env.VISOR_TEST_METRICS === "true";
1130
1132
  TEST_SNAPSHOT = { fail_if_triggered: 0 };
1131
1133
  _currentRunAiCalls = 0;
@@ -1150,11 +1152,11 @@ function getTracer() {
1150
1152
  }
1151
1153
  async function withActiveSpan(name, attrs, fn) {
1152
1154
  const tracer = getTracer();
1153
- return await new Promise((resolve15, reject) => {
1155
+ return await new Promise((resolve19, reject) => {
1154
1156
  const callback = async (span) => {
1155
1157
  try {
1156
1158
  const res = await fn(span);
1157
- resolve15(res);
1159
+ resolve19(res);
1158
1160
  } catch (err) {
1159
1161
  try {
1160
1162
  if (err instanceof Error) span.recordException(err);
@@ -1279,19 +1281,19 @@ function __getOrCreateNdjsonPath() {
1279
1281
  try {
1280
1282
  if (process.env.VISOR_TELEMETRY_SINK && process.env.VISOR_TELEMETRY_SINK !== "file")
1281
1283
  return null;
1282
- const path29 = require("path");
1283
- const fs25 = require("fs");
1284
+ const path33 = require("path");
1285
+ const fs29 = require("fs");
1284
1286
  if (process.env.VISOR_FALLBACK_TRACE_FILE) {
1285
1287
  __ndjsonPath = process.env.VISOR_FALLBACK_TRACE_FILE;
1286
- const dir = path29.dirname(__ndjsonPath);
1287
- if (!fs25.existsSync(dir)) fs25.mkdirSync(dir, { recursive: true });
1288
+ const dir = path33.dirname(__ndjsonPath);
1289
+ if (!fs29.existsSync(dir)) fs29.mkdirSync(dir, { recursive: true });
1288
1290
  return __ndjsonPath;
1289
1291
  }
1290
- const outDir = process.env.VISOR_TRACE_DIR || path29.join(process.cwd(), "output", "traces");
1291
- if (!fs25.existsSync(outDir)) fs25.mkdirSync(outDir, { recursive: true });
1292
+ const outDir = process.env.VISOR_TRACE_DIR || path33.join(process.cwd(), "output", "traces");
1293
+ if (!fs29.existsSync(outDir)) fs29.mkdirSync(outDir, { recursive: true });
1292
1294
  if (!__ndjsonPath) {
1293
1295
  const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
1294
- __ndjsonPath = path29.join(outDir, `${ts}.ndjson`);
1296
+ __ndjsonPath = path33.join(outDir, `${ts}.ndjson`);
1295
1297
  }
1296
1298
  return __ndjsonPath;
1297
1299
  } catch {
@@ -1300,11 +1302,11 @@ function __getOrCreateNdjsonPath() {
1300
1302
  }
1301
1303
  function _appendRunMarker() {
1302
1304
  try {
1303
- const fs25 = require("fs");
1305
+ const fs29 = require("fs");
1304
1306
  const p = __getOrCreateNdjsonPath();
1305
1307
  if (!p) return;
1306
1308
  const line = { name: "visor.run", attributes: { started: true } };
1307
- fs25.appendFileSync(p, JSON.stringify(line) + "\n", "utf8");
1309
+ fs29.appendFileSync(p, JSON.stringify(line) + "\n", "utf8");
1308
1310
  } catch {
1309
1311
  }
1310
1312
  }
@@ -3391,7 +3393,7 @@ var init_failure_condition_evaluator = __esm({
3391
3393
  */
3392
3394
  evaluateExpression(condition, context2) {
3393
3395
  try {
3394
- const normalize4 = (expr) => {
3396
+ const normalize8 = (expr) => {
3395
3397
  const trimmed = expr.trim();
3396
3398
  if (!/[\n;]/.test(trimmed)) return trimmed;
3397
3399
  const parts = trimmed.split(/[\n;]+/).map((s) => s.trim()).filter((s) => s.length > 0 && !s.startsWith("//"));
@@ -3549,7 +3551,7 @@ var init_failure_condition_evaluator = __esm({
3549
3551
  try {
3550
3552
  exec2 = this.sandbox.compile(`return (${raw});`);
3551
3553
  } catch {
3552
- const normalizedExpr = normalize4(condition);
3554
+ const normalizedExpr = normalize8(condition);
3553
3555
  exec2 = this.sandbox.compile(`return (${normalizedExpr});`);
3554
3556
  }
3555
3557
  const result = exec2(scope).run();
@@ -3932,9 +3934,9 @@ function configureLiquidWithExtensions(liquid) {
3932
3934
  });
3933
3935
  liquid.registerFilter("get", (obj, pathExpr) => {
3934
3936
  if (obj == null) return void 0;
3935
- const path29 = typeof pathExpr === "string" ? pathExpr : String(pathExpr || "");
3936
- if (!path29) return obj;
3937
- const parts = path29.split(".");
3937
+ const path33 = typeof pathExpr === "string" ? pathExpr : String(pathExpr || "");
3938
+ if (!path33) return obj;
3939
+ const parts = path33.split(".");
3938
3940
  let cur = obj;
3939
3941
  for (const p of parts) {
3940
3942
  if (cur == null) return void 0;
@@ -4053,9 +4055,9 @@ function configureLiquidWithExtensions(liquid) {
4053
4055
  }
4054
4056
  }
4055
4057
  const defaultRole = typeof rolesCfg.default === "string" && rolesCfg.default.trim() ? rolesCfg.default.trim() : void 0;
4056
- const getNested = (obj, path29) => {
4057
- if (!obj || !path29) return void 0;
4058
- const parts = path29.split(".");
4058
+ const getNested = (obj, path33) => {
4059
+ if (!obj || !path33) return void 0;
4060
+ const parts = path33.split(".");
4059
4061
  let cur = obj;
4060
4062
  for (const p of parts) {
4061
4063
  if (cur == null) return void 0;
@@ -6607,8 +6609,8 @@ var init_dependency_gating = __esm({
6607
6609
  async function renderTemplateContent(checkId, checkConfig, reviewSummary) {
6608
6610
  try {
6609
6611
  const { createExtendedLiquid: createExtendedLiquid2 } = await Promise.resolve().then(() => (init_liquid_extensions(), liquid_extensions_exports));
6610
- const fs25 = await import("fs/promises");
6611
- const path29 = await import("path");
6612
+ const fs29 = await import("fs/promises");
6613
+ const path33 = await import("path");
6612
6614
  const schemaRaw = checkConfig.schema || "plain";
6613
6615
  const schema = typeof schemaRaw === "string" ? schemaRaw : "code-review";
6614
6616
  let templateContent;
@@ -6616,24 +6618,24 @@ async function renderTemplateContent(checkId, checkConfig, reviewSummary) {
6616
6618
  templateContent = String(checkConfig.template.content);
6617
6619
  } else if (checkConfig.template && checkConfig.template.file) {
6618
6620
  const file = String(checkConfig.template.file);
6619
- const resolved = path29.resolve(process.cwd(), file);
6620
- templateContent = await fs25.readFile(resolved, "utf-8");
6621
+ const resolved = path33.resolve(process.cwd(), file);
6622
+ templateContent = await fs29.readFile(resolved, "utf-8");
6621
6623
  } else if (schema && schema !== "plain") {
6622
6624
  const sanitized = String(schema).replace(/[^a-zA-Z0-9-]/g, "");
6623
6625
  if (sanitized) {
6624
6626
  const candidatePaths = [
6625
- path29.join(__dirname, "output", sanitized, "template.liquid"),
6627
+ path33.join(__dirname, "output", sanitized, "template.liquid"),
6626
6628
  // bundled: dist/output/
6627
- path29.join(__dirname, "..", "..", "output", sanitized, "template.liquid"),
6629
+ path33.join(__dirname, "..", "..", "output", sanitized, "template.liquid"),
6628
6630
  // source: output/
6629
- path29.join(process.cwd(), "output", sanitized, "template.liquid"),
6631
+ path33.join(process.cwd(), "output", sanitized, "template.liquid"),
6630
6632
  // fallback: cwd/output/
6631
- path29.join(process.cwd(), "dist", "output", sanitized, "template.liquid")
6633
+ path33.join(process.cwd(), "dist", "output", sanitized, "template.liquid")
6632
6634
  // fallback: cwd/dist/output/
6633
6635
  ];
6634
6636
  for (const p of candidatePaths) {
6635
6637
  try {
6636
- templateContent = await fs25.readFile(p, "utf-8");
6638
+ templateContent = await fs29.readFile(p, "utf-8");
6637
6639
  if (templateContent) break;
6638
6640
  } catch {
6639
6641
  }
@@ -7038,7 +7040,7 @@ async function processDiffWithOutline(diffContent) {
7038
7040
  }
7039
7041
  try {
7040
7042
  const originalProbePath = process.env.PROBE_PATH;
7041
- const fs25 = require("fs");
7043
+ const fs29 = require("fs");
7042
7044
  const possiblePaths = [
7043
7045
  // Relative to current working directory (most common in production)
7044
7046
  path6.join(process.cwd(), "node_modules/@probelabs/probe/bin/probe-binary"),
@@ -7049,7 +7051,7 @@ async function processDiffWithOutline(diffContent) {
7049
7051
  ];
7050
7052
  let probeBinaryPath;
7051
7053
  for (const candidatePath of possiblePaths) {
7052
- if (fs25.existsSync(candidatePath)) {
7054
+ if (fs29.existsSync(candidatePath)) {
7053
7055
  probeBinaryPath = candidatePath;
7054
7056
  break;
7055
7057
  }
@@ -7156,7 +7158,7 @@ async function renderMermaidToPng(mermaidCode) {
7156
7158
  if (chromiumPath) {
7157
7159
  env.PUPPETEER_EXECUTABLE_PATH = chromiumPath;
7158
7160
  }
7159
- const result = await new Promise((resolve15) => {
7161
+ const result = await new Promise((resolve19) => {
7160
7162
  const proc = (0, import_child_process.spawn)(
7161
7163
  "npx",
7162
7164
  [
@@ -7186,13 +7188,13 @@ async function renderMermaidToPng(mermaidCode) {
7186
7188
  });
7187
7189
  proc.on("close", (code) => {
7188
7190
  if (code === 0) {
7189
- resolve15({ success: true });
7191
+ resolve19({ success: true });
7190
7192
  } else {
7191
- resolve15({ success: false, error: stderr || `Exit code ${code}` });
7193
+ resolve19({ success: false, error: stderr || `Exit code ${code}` });
7192
7194
  }
7193
7195
  });
7194
7196
  proc.on("error", (err) => {
7195
- resolve15({ success: false, error: err.message });
7197
+ resolve19({ success: false, error: err.message });
7196
7198
  });
7197
7199
  });
7198
7200
  if (!result.success) {
@@ -8354,8 +8356,8 @@ ${schemaString}`);
8354
8356
  }
8355
8357
  if (process.env.VISOR_DEBUG_AI_SESSIONS === "true") {
8356
8358
  try {
8357
- const fs25 = require("fs");
8358
- const path29 = require("path");
8359
+ const fs29 = require("fs");
8360
+ const path33 = require("path");
8359
8361
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
8360
8362
  const provider = this.config.provider || "auto";
8361
8363
  const model = this.config.model || "default";
@@ -8469,20 +8471,20 @@ ${"=".repeat(60)}
8469
8471
  `;
8470
8472
  readableVersion += `${"=".repeat(60)}
8471
8473
  `;
8472
- const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path29.join(process.cwd(), "debug-artifacts");
8473
- if (!fs25.existsSync(debugArtifactsDir)) {
8474
- fs25.mkdirSync(debugArtifactsDir, { recursive: true });
8474
+ const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path33.join(process.cwd(), "debug-artifacts");
8475
+ if (!fs29.existsSync(debugArtifactsDir)) {
8476
+ fs29.mkdirSync(debugArtifactsDir, { recursive: true });
8475
8477
  }
8476
- const debugFile = path29.join(
8478
+ const debugFile = path33.join(
8477
8479
  debugArtifactsDir,
8478
8480
  `prompt-${_checkName || "unknown"}-${timestamp}.json`
8479
8481
  );
8480
- fs25.writeFileSync(debugFile, debugJson, "utf-8");
8481
- const readableFile = path29.join(
8482
+ fs29.writeFileSync(debugFile, debugJson, "utf-8");
8483
+ const readableFile = path33.join(
8482
8484
  debugArtifactsDir,
8483
8485
  `prompt-${_checkName || "unknown"}-${timestamp}.txt`
8484
8486
  );
8485
- fs25.writeFileSync(readableFile, readableVersion, "utf-8");
8487
+ fs29.writeFileSync(readableFile, readableVersion, "utf-8");
8486
8488
  log(`
8487
8489
  \u{1F4BE} Full debug info saved to:`);
8488
8490
  log(` JSON: ${debugFile}`);
@@ -8520,8 +8522,8 @@ ${"=".repeat(60)}
8520
8522
  log(`\u{1F4E4} Response length: ${response.length} characters`);
8521
8523
  if (process.env.VISOR_DEBUG_AI_SESSIONS === "true") {
8522
8524
  try {
8523
- const fs25 = require("fs");
8524
- const path29 = require("path");
8525
+ const fs29 = require("fs");
8526
+ const path33 = require("path");
8525
8527
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
8526
8528
  const agentAny2 = agent;
8527
8529
  let fullHistory = [];
@@ -8532,8 +8534,8 @@ ${"=".repeat(60)}
8532
8534
  } else if (agentAny2._messages) {
8533
8535
  fullHistory = agentAny2._messages;
8534
8536
  }
8535
- const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path29.join(process.cwd(), "debug-artifacts");
8536
- const sessionBase = path29.join(
8537
+ const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path33.join(process.cwd(), "debug-artifacts");
8538
+ const sessionBase = path33.join(
8537
8539
  debugArtifactsDir,
8538
8540
  `session-${_checkName || "unknown"}-${timestamp}`
8539
8541
  );
@@ -8545,7 +8547,7 @@ ${"=".repeat(60)}
8545
8547
  schema: effectiveSchema,
8546
8548
  totalMessages: fullHistory.length
8547
8549
  };
8548
- fs25.writeFileSync(sessionBase + ".json", JSON.stringify(sessionData, null, 2), "utf-8");
8550
+ fs29.writeFileSync(sessionBase + ".json", JSON.stringify(sessionData, null, 2), "utf-8");
8549
8551
  let readable = `=============================================================
8550
8552
  `;
8551
8553
  readable += `COMPLETE AI SESSION HISTORY (AFTER RESPONSE)
@@ -8572,7 +8574,7 @@ ${"=".repeat(60)}
8572
8574
  `;
8573
8575
  readable += content + "\n";
8574
8576
  });
8575
- fs25.writeFileSync(sessionBase + ".summary.txt", readable, "utf-8");
8577
+ fs29.writeFileSync(sessionBase + ".summary.txt", readable, "utf-8");
8576
8578
  log(`\u{1F4BE} Complete session history saved:`);
8577
8579
  log(` - Contains ALL ${fullHistory.length} messages (prompts + responses)`);
8578
8580
  } catch (error) {
@@ -8581,11 +8583,11 @@ ${"=".repeat(60)}
8581
8583
  }
8582
8584
  if (process.env.VISOR_DEBUG_AI_SESSIONS === "true") {
8583
8585
  try {
8584
- const fs25 = require("fs");
8585
- const path29 = require("path");
8586
+ const fs29 = require("fs");
8587
+ const path33 = require("path");
8586
8588
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
8587
- const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path29.join(process.cwd(), "debug-artifacts");
8588
- const responseFile = path29.join(
8589
+ const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path33.join(process.cwd(), "debug-artifacts");
8590
+ const responseFile = path33.join(
8589
8591
  debugArtifactsDir,
8590
8592
  `response-${_checkName || "unknown"}-${timestamp}.txt`
8591
8593
  );
@@ -8618,7 +8620,7 @@ ${"=".repeat(60)}
8618
8620
  `;
8619
8621
  responseContent += `${"=".repeat(60)}
8620
8622
  `;
8621
- fs25.writeFileSync(responseFile, responseContent, "utf-8");
8623
+ fs29.writeFileSync(responseFile, responseContent, "utf-8");
8622
8624
  log(`\u{1F4BE} Response saved to: ${responseFile}`);
8623
8625
  } catch (error) {
8624
8626
  log(`\u26A0\uFE0F Could not save response file: ${error}`);
@@ -8634,9 +8636,9 @@ ${"=".repeat(60)}
8634
8636
  await agentAny._telemetryConfig.shutdown();
8635
8637
  log(`\u{1F4CA} OpenTelemetry trace saved to: ${agentAny._traceFilePath}`);
8636
8638
  if (process.env.GITHUB_ACTIONS) {
8637
- const fs25 = require("fs");
8638
- if (fs25.existsSync(agentAny._traceFilePath)) {
8639
- const stats = fs25.statSync(agentAny._traceFilePath);
8639
+ const fs29 = require("fs");
8640
+ if (fs29.existsSync(agentAny._traceFilePath)) {
8641
+ const stats = fs29.statSync(agentAny._traceFilePath);
8640
8642
  console.log(
8641
8643
  `::notice title=AI Trace Saved::${agentAny._traceFilePath} (${stats.size} bytes)`
8642
8644
  );
@@ -8849,9 +8851,9 @@ ${schemaString}`);
8849
8851
  const model = this.config.model || "default";
8850
8852
  if (process.env.VISOR_DEBUG_AI_SESSIONS === "true") {
8851
8853
  try {
8852
- const fs25 = require("fs");
8853
- const path29 = require("path");
8854
- const os2 = require("os");
8854
+ const fs29 = require("fs");
8855
+ const path33 = require("path");
8856
+ const os3 = require("os");
8855
8857
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
8856
8858
  const debugData = {
8857
8859
  timestamp,
@@ -8923,19 +8925,19 @@ ${"=".repeat(60)}
8923
8925
  `;
8924
8926
  readableVersion += `${"=".repeat(60)}
8925
8927
  `;
8926
- const tempDir = os2.tmpdir();
8927
- const promptFile = path29.join(tempDir, `visor-prompt-${timestamp}.txt`);
8928
- fs25.writeFileSync(promptFile, prompt, "utf-8");
8928
+ const tempDir = os3.tmpdir();
8929
+ const promptFile = path33.join(tempDir, `visor-prompt-${timestamp}.txt`);
8930
+ fs29.writeFileSync(promptFile, prompt, "utf-8");
8929
8931
  log(`
8930
8932
  \u{1F4BE} Prompt saved to: ${promptFile}`);
8931
- const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path29.join(process.cwd(), "debug-artifacts");
8933
+ const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path33.join(process.cwd(), "debug-artifacts");
8932
8934
  try {
8933
- const base = path29.join(
8935
+ const base = path33.join(
8934
8936
  debugArtifactsDir,
8935
8937
  `prompt-${_checkName || "unknown"}-${timestamp}`
8936
8938
  );
8937
- fs25.writeFileSync(base + ".json", debugJson, "utf-8");
8938
- fs25.writeFileSync(base + ".summary.txt", readableVersion, "utf-8");
8939
+ fs29.writeFileSync(base + ".json", debugJson, "utf-8");
8940
+ fs29.writeFileSync(base + ".summary.txt", readableVersion, "utf-8");
8939
8941
  log(`
8940
8942
  \u{1F4BE} Full debug info saved to directory: ${debugArtifactsDir}`);
8941
8943
  } catch {
@@ -8985,8 +8987,8 @@ $ ${cliCommand}
8985
8987
  log(`\u{1F4E4} Response length: ${response.length} characters`);
8986
8988
  if (process.env.VISOR_DEBUG_AI_SESSIONS === "true") {
8987
8989
  try {
8988
- const fs25 = require("fs");
8989
- const path29 = require("path");
8990
+ const fs29 = require("fs");
8991
+ const path33 = require("path");
8990
8992
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
8991
8993
  const agentAny = agent;
8992
8994
  let fullHistory = [];
@@ -8997,8 +8999,8 @@ $ ${cliCommand}
8997
8999
  } else if (agentAny._messages) {
8998
9000
  fullHistory = agentAny._messages;
8999
9001
  }
9000
- const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path29.join(process.cwd(), "debug-artifacts");
9001
- const sessionBase = path29.join(
9002
+ const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path33.join(process.cwd(), "debug-artifacts");
9003
+ const sessionBase = path33.join(
9002
9004
  debugArtifactsDir,
9003
9005
  `session-${_checkName || "unknown"}-${timestamp}`
9004
9006
  );
@@ -9010,7 +9012,7 @@ $ ${cliCommand}
9010
9012
  schema: effectiveSchema,
9011
9013
  totalMessages: fullHistory.length
9012
9014
  };
9013
- fs25.writeFileSync(sessionBase + ".json", JSON.stringify(sessionData, null, 2), "utf-8");
9015
+ fs29.writeFileSync(sessionBase + ".json", JSON.stringify(sessionData, null, 2), "utf-8");
9014
9016
  let readable = `=============================================================
9015
9017
  `;
9016
9018
  readable += `COMPLETE AI SESSION HISTORY (AFTER RESPONSE)
@@ -9037,7 +9039,7 @@ ${"=".repeat(60)}
9037
9039
  `;
9038
9040
  readable += content + "\n";
9039
9041
  });
9040
- fs25.writeFileSync(sessionBase + ".summary.txt", readable, "utf-8");
9042
+ fs29.writeFileSync(sessionBase + ".summary.txt", readable, "utf-8");
9041
9043
  log(`\u{1F4BE} Complete session history saved:`);
9042
9044
  log(` - Contains ALL ${fullHistory.length} messages (prompts + responses)`);
9043
9045
  } catch (error) {
@@ -9046,11 +9048,11 @@ ${"=".repeat(60)}
9046
9048
  }
9047
9049
  if (process.env.VISOR_DEBUG_AI_SESSIONS === "true") {
9048
9050
  try {
9049
- const fs25 = require("fs");
9050
- const path29 = require("path");
9051
+ const fs29 = require("fs");
9052
+ const path33 = require("path");
9051
9053
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
9052
- const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path29.join(process.cwd(), "debug-artifacts");
9053
- const responseFile = path29.join(
9054
+ const debugArtifactsDir = process.env.VISOR_DEBUG_ARTIFACTS || path33.join(process.cwd(), "debug-artifacts");
9055
+ const responseFile = path33.join(
9054
9056
  debugArtifactsDir,
9055
9057
  `response-${_checkName || "unknown"}-${timestamp}.txt`
9056
9058
  );
@@ -9083,7 +9085,7 @@ ${"=".repeat(60)}
9083
9085
  `;
9084
9086
  responseContent += `${"=".repeat(60)}
9085
9087
  `;
9086
- fs25.writeFileSync(responseFile, responseContent, "utf-8");
9088
+ fs29.writeFileSync(responseFile, responseContent, "utf-8");
9087
9089
  log(`\u{1F4BE} Response saved to: ${responseFile}`);
9088
9090
  } catch (error) {
9089
9091
  log(`\u26A0\uFE0F Could not save response file: ${error}`);
@@ -9101,9 +9103,9 @@ ${"=".repeat(60)}
9101
9103
  await telemetry.shutdown();
9102
9104
  log(`\u{1F4CA} OpenTelemetry trace saved to: ${traceFilePath}`);
9103
9105
  if (process.env.GITHUB_ACTIONS) {
9104
- const fs25 = require("fs");
9105
- if (fs25.existsSync(traceFilePath)) {
9106
- const stats = fs25.statSync(traceFilePath);
9106
+ const fs29 = require("fs");
9107
+ if (fs29.existsSync(traceFilePath)) {
9108
+ const stats = fs29.statSync(traceFilePath);
9107
9109
  console.log(
9108
9110
  `::notice title=AI Trace Saved::OpenTelemetry trace file size: ${stats.size} bytes`
9109
9111
  );
@@ -9141,8 +9143,8 @@ ${"=".repeat(60)}
9141
9143
  * Load schema content from schema files or inline definitions
9142
9144
  */
9143
9145
  async loadSchemaContent(schema) {
9144
- const fs25 = require("fs").promises;
9145
- const path29 = require("path");
9146
+ const fs29 = require("fs").promises;
9147
+ const path33 = require("path");
9146
9148
  if (typeof schema === "object" && schema !== null) {
9147
9149
  log("\u{1F4CB} Using inline schema object from configuration");
9148
9150
  return JSON.stringify(schema);
@@ -9155,14 +9157,14 @@ ${"=".repeat(60)}
9155
9157
  }
9156
9158
  } catch {
9157
9159
  }
9158
- if ((schema.startsWith("./") || schema.includes(".json")) && !path29.isAbsolute(schema)) {
9160
+ if ((schema.startsWith("./") || schema.includes(".json")) && !path33.isAbsolute(schema)) {
9159
9161
  if (schema.includes("..") || schema.includes("\0")) {
9160
9162
  throw new Error("Invalid schema path: path traversal not allowed");
9161
9163
  }
9162
9164
  try {
9163
- const schemaPath = path29.resolve(process.cwd(), schema);
9165
+ const schemaPath = path33.resolve(process.cwd(), schema);
9164
9166
  log(`\u{1F4CB} Loading custom schema from file: ${schemaPath}`);
9165
- const schemaContent = await fs25.readFile(schemaPath, "utf-8");
9167
+ const schemaContent = await fs29.readFile(schemaPath, "utf-8");
9166
9168
  return schemaContent.trim();
9167
9169
  } catch (error) {
9168
9170
  throw new Error(
@@ -9176,22 +9178,22 @@ ${"=".repeat(60)}
9176
9178
  }
9177
9179
  const candidatePaths = [
9178
9180
  // GitHub Action bundle location
9179
- path29.join(__dirname, "output", sanitizedSchemaName, "schema.json"),
9181
+ path33.join(__dirname, "output", sanitizedSchemaName, "schema.json"),
9180
9182
  // Historical fallback when src/output was inadvertently bundled as output1/
9181
- path29.join(__dirname, "output1", sanitizedSchemaName, "schema.json"),
9183
+ path33.join(__dirname, "output1", sanitizedSchemaName, "schema.json"),
9182
9184
  // Local dev (repo root)
9183
- path29.join(process.cwd(), "output", sanitizedSchemaName, "schema.json")
9185
+ path33.join(process.cwd(), "output", sanitizedSchemaName, "schema.json")
9184
9186
  ];
9185
9187
  for (const schemaPath of candidatePaths) {
9186
9188
  try {
9187
- const schemaContent = await fs25.readFile(schemaPath, "utf-8");
9189
+ const schemaContent = await fs29.readFile(schemaPath, "utf-8");
9188
9190
  return schemaContent.trim();
9189
9191
  } catch {
9190
9192
  }
9191
9193
  }
9192
- const distPath = path29.join(__dirname, "output", sanitizedSchemaName, "schema.json");
9193
- const distAltPath = path29.join(__dirname, "output1", sanitizedSchemaName, "schema.json");
9194
- const cwdPath = path29.join(process.cwd(), "output", sanitizedSchemaName, "schema.json");
9194
+ const distPath = path33.join(__dirname, "output", sanitizedSchemaName, "schema.json");
9195
+ const distAltPath = path33.join(__dirname, "output1", sanitizedSchemaName, "schema.json");
9196
+ const cwdPath = path33.join(process.cwd(), "output", sanitizedSchemaName, "schema.json");
9195
9197
  throw new Error(
9196
9198
  `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.`
9197
9199
  );
@@ -9433,7 +9435,7 @@ ${"=".repeat(60)}
9433
9435
  * Generate mock response for testing
9434
9436
  */
9435
9437
  async generateMockResponse(_prompt, _checkName, _schema) {
9436
- await new Promise((resolve15) => setTimeout(resolve15, 500));
9438
+ await new Promise((resolve19) => setTimeout(resolve19, 500));
9437
9439
  const name = (_checkName || "").toLowerCase();
9438
9440
  if (name.includes("extract-facts")) {
9439
9441
  const arr = Array.from({ length: 6 }, (_, i) => ({
@@ -9794,7 +9796,7 @@ var init_command_executor = __esm({
9794
9796
  * Execute command with stdin input
9795
9797
  */
9796
9798
  executeWithStdin(command, options) {
9797
- return new Promise((resolve15, reject) => {
9799
+ return new Promise((resolve19, reject) => {
9798
9800
  const childProcess = (0, import_child_process2.exec)(
9799
9801
  command,
9800
9802
  {
@@ -9806,7 +9808,7 @@ var init_command_executor = __esm({
9806
9808
  if (error && error.killed && (error.code === "ETIMEDOUT" || error.signal === "SIGTERM")) {
9807
9809
  reject(new Error(`Command timed out after ${options.timeout || 3e4}ms`));
9808
9810
  } else {
9809
- resolve15({
9811
+ resolve19({
9810
9812
  stdout: stdout || "",
9811
9813
  stderr: stderr || "",
9812
9814
  exitCode: error ? error.code || 1 : 0
@@ -12669,6 +12671,22 @@ var init_config_schema = __esm({
12669
12671
  $ref: "#/definitions/SlackConfig",
12670
12672
  description: "Slack configuration"
12671
12673
  },
12674
+ telegram: {
12675
+ $ref: "#/definitions/TelegramConfig",
12676
+ description: "Telegram bot configuration"
12677
+ },
12678
+ email: {
12679
+ $ref: "#/definitions/EmailConfig",
12680
+ description: "Email integration configuration"
12681
+ },
12682
+ whatsapp: {
12683
+ $ref: "#/definitions/WhatsAppConfig",
12684
+ description: "WhatsApp bot configuration"
12685
+ },
12686
+ teams: {
12687
+ $ref: "#/definitions/TeamsConfig",
12688
+ description: "Microsoft Teams bot configuration"
12689
+ },
12672
12690
  scheduler: {
12673
12691
  $ref: "#/definitions/SchedulerConfig",
12674
12692
  description: "Scheduler configuration for scheduled workflow execution"
@@ -13442,7 +13460,7 @@ var init_config_schema = __esm({
13442
13460
  description: "Arguments/inputs for the workflow"
13443
13461
  },
13444
13462
  overrides: {
13445
- $ref: "#/definitions/Record%3Cstring%2CPartial%3Cinterface-src_types_config.ts-13844-28438-src_types_config.ts-0-56400%3E%3E",
13463
+ $ref: "#/definitions/Record%3Cstring%2CPartial%3Cinterface-src_types_config.ts-14017-28611-src_types_config.ts-0-56833%3E%3E",
13446
13464
  description: "Override specific step configurations in the workflow"
13447
13465
  },
13448
13466
  output_mapping: {
@@ -13458,7 +13476,7 @@ var init_config_schema = __esm({
13458
13476
  description: "Config file path - alternative to workflow ID (loads a Visor config file as workflow)"
13459
13477
  },
13460
13478
  workflow_overrides: {
13461
- $ref: "#/definitions/Record%3Cstring%2CPartial%3Cinterface-src_types_config.ts-13844-28438-src_types_config.ts-0-56400%3E%3E",
13479
+ $ref: "#/definitions/Record%3Cstring%2CPartial%3Cinterface-src_types_config.ts-14017-28611-src_types_config.ts-0-56833%3E%3E",
13462
13480
  description: "Alias for overrides - workflow step overrides (backward compatibility)"
13463
13481
  },
13464
13482
  ref: {
@@ -13642,7 +13660,11 @@ var init_config_schema = __esm({
13642
13660
  "manual",
13643
13661
  "schedule",
13644
13662
  "webhook_received",
13645
- "slack_message"
13663
+ "slack_message",
13664
+ "telegram_message",
13665
+ "email_message",
13666
+ "whatsapp_message",
13667
+ "teams_message"
13646
13668
  ],
13647
13669
  description: "Valid event triggers for checks"
13648
13670
  },
@@ -14156,7 +14178,7 @@ var init_config_schema = __esm({
14156
14178
  description: "Custom output name (defaults to workflow name)"
14157
14179
  },
14158
14180
  overrides: {
14159
- $ref: "#/definitions/Record%3Cstring%2CPartial%3Cinterface-src_types_config.ts-13844-28438-src_types_config.ts-0-56400%3E%3E",
14181
+ $ref: "#/definitions/Record%3Cstring%2CPartial%3Cinterface-src_types_config.ts-14017-28611-src_types_config.ts-0-56833%3E%3E",
14160
14182
  description: "Step overrides"
14161
14183
  },
14162
14184
  output_mapping: {
@@ -14171,13 +14193,13 @@ var init_config_schema = __esm({
14171
14193
  "^x-": {}
14172
14194
  }
14173
14195
  },
14174
- "Record<string,Partial<interface-src_types_config.ts-13844-28438-src_types_config.ts-0-56400>>": {
14196
+ "Record<string,Partial<interface-src_types_config.ts-14017-28611-src_types_config.ts-0-56833>>": {
14175
14197
  type: "object",
14176
14198
  additionalProperties: {
14177
- $ref: "#/definitions/Partial%3Cinterface-src_types_config.ts-13844-28438-src_types_config.ts-0-56400%3E"
14199
+ $ref: "#/definitions/Partial%3Cinterface-src_types_config.ts-14017-28611-src_types_config.ts-0-56833%3E"
14178
14200
  }
14179
14201
  },
14180
- "Partial<interface-src_types_config.ts-13844-28438-src_types_config.ts-0-56400>": {
14202
+ "Partial<interface-src_types_config.ts-14017-28611-src_types_config.ts-0-56833>": {
14181
14203
  type: "object",
14182
14204
  additionalProperties: false
14183
14205
  },
@@ -15036,6 +15058,260 @@ var init_config_schema = __esm({
15036
15058
  "^x-": {}
15037
15059
  }
15038
15060
  },
15061
+ TelegramConfig: {
15062
+ type: "object",
15063
+ properties: {
15064
+ bot_token: {
15065
+ type: "string",
15066
+ description: "Bot token from"
15067
+ },
15068
+ polling_timeout: {
15069
+ type: "number",
15070
+ description: "Polling timeout in seconds for getUpdates (default: 30)"
15071
+ },
15072
+ chat_allowlist: {
15073
+ type: "array",
15074
+ items: {
15075
+ type: ["string", "number"]
15076
+ },
15077
+ description: "Chat/group allowlist - numeric chat IDs that the bot responds in"
15078
+ },
15079
+ require_mention: {
15080
+ type: "boolean",
15081
+ description: "In groups, only respond when"
15082
+ },
15083
+ workflow: {
15084
+ type: "string",
15085
+ description: "Workflow to run when a message is received"
15086
+ }
15087
+ },
15088
+ additionalProperties: false,
15089
+ patternProperties: {
15090
+ "^x-": {}
15091
+ }
15092
+ },
15093
+ EmailConfig: {
15094
+ type: "object",
15095
+ properties: {
15096
+ receive: {
15097
+ type: "object",
15098
+ properties: {
15099
+ type: {
15100
+ type: "string",
15101
+ enum: ["imap", "resend"],
15102
+ description: "Backend type: 'imap' (universal) or 'resend' (managed webhook)"
15103
+ },
15104
+ host: {
15105
+ type: "string",
15106
+ description: "IMAP server hostname"
15107
+ },
15108
+ port: {
15109
+ type: "number",
15110
+ description: "IMAP server port (default: 993)"
15111
+ },
15112
+ auth: {
15113
+ type: "object",
15114
+ properties: {
15115
+ user: {
15116
+ type: "string"
15117
+ },
15118
+ pass: {
15119
+ type: "string"
15120
+ }
15121
+ },
15122
+ additionalProperties: false,
15123
+ description: "IMAP auth credentials",
15124
+ patternProperties: {
15125
+ "^x-": {}
15126
+ }
15127
+ },
15128
+ secure: {
15129
+ type: "boolean",
15130
+ description: "Use TLS (default: true)"
15131
+ },
15132
+ poll_interval: {
15133
+ type: "number",
15134
+ description: "Polling interval in seconds when IDLE not available (default: 30)"
15135
+ },
15136
+ folder: {
15137
+ type: "string",
15138
+ description: "IMAP folder to monitor (default: 'INBOX')"
15139
+ },
15140
+ mark_read: {
15141
+ type: "boolean",
15142
+ description: "Mark processed messages as read (default: true)"
15143
+ },
15144
+ api_key: {
15145
+ type: "string",
15146
+ description: "Resend API key (for type: 'resend')"
15147
+ },
15148
+ webhook_secret: {
15149
+ type: "string",
15150
+ description: "Resend webhook secret for signature verification"
15151
+ }
15152
+ },
15153
+ additionalProperties: false,
15154
+ description: "Receive backend configuration",
15155
+ patternProperties: {
15156
+ "^x-": {}
15157
+ }
15158
+ },
15159
+ send: {
15160
+ type: "object",
15161
+ properties: {
15162
+ type: {
15163
+ type: "string",
15164
+ enum: ["smtp", "resend"],
15165
+ description: "Backend type: 'smtp' (universal) or 'resend' (managed API)"
15166
+ },
15167
+ host: {
15168
+ type: "string",
15169
+ description: "SMTP server hostname"
15170
+ },
15171
+ port: {
15172
+ type: "number",
15173
+ description: "SMTP server port (default: 587)"
15174
+ },
15175
+ auth: {
15176
+ type: "object",
15177
+ properties: {
15178
+ user: {
15179
+ type: "string"
15180
+ },
15181
+ pass: {
15182
+ type: "string"
15183
+ }
15184
+ },
15185
+ additionalProperties: false,
15186
+ description: "SMTP auth credentials",
15187
+ patternProperties: {
15188
+ "^x-": {}
15189
+ }
15190
+ },
15191
+ secure: {
15192
+ type: "boolean",
15193
+ description: "Use TLS (default: true)"
15194
+ },
15195
+ from: {
15196
+ type: "string",
15197
+ description: 'Default sender address (e.g., "Bot <bot@example.com>")'
15198
+ },
15199
+ api_key: {
15200
+ type: "string",
15201
+ description: "Resend API key (for type: 'resend')"
15202
+ }
15203
+ },
15204
+ additionalProperties: false,
15205
+ description: "Send backend configuration",
15206
+ patternProperties: {
15207
+ "^x-": {}
15208
+ }
15209
+ },
15210
+ allowlist: {
15211
+ type: "array",
15212
+ items: {
15213
+ type: "string"
15214
+ },
15215
+ description: "Only process emails from these senders"
15216
+ },
15217
+ workflow: {
15218
+ type: "string",
15219
+ description: "Workflow to run when an email is received"
15220
+ }
15221
+ },
15222
+ additionalProperties: false,
15223
+ patternProperties: {
15224
+ "^x-": {}
15225
+ }
15226
+ },
15227
+ WhatsAppConfig: {
15228
+ type: "object",
15229
+ properties: {
15230
+ access_token: {
15231
+ type: "string",
15232
+ description: "WhatsApp Cloud API access token (or WHATSAPP_ACCESS_TOKEN env var)"
15233
+ },
15234
+ phone_number_id: {
15235
+ type: "string",
15236
+ description: "Phone Number ID from Meta Business Suite (or WHATSAPP_PHONE_NUMBER_ID env var)"
15237
+ },
15238
+ app_secret: {
15239
+ type: "string",
15240
+ description: "Meta App Secret for webhook signature verification (or WHATSAPP_APP_SECRET env var)"
15241
+ },
15242
+ verify_token: {
15243
+ type: "string",
15244
+ description: "Verify token for webhook subscription challenge (or WHATSAPP_VERIFY_TOKEN env var)"
15245
+ },
15246
+ api_version: {
15247
+ type: "string",
15248
+ description: "Graph API version (default: 'v21.0')"
15249
+ },
15250
+ port: {
15251
+ type: "number",
15252
+ description: "Port for webhook HTTP server (default: 8443)"
15253
+ },
15254
+ host: {
15255
+ type: "string",
15256
+ description: "Host for webhook HTTP server (default: '0.0.0.0')"
15257
+ },
15258
+ phone_allowlist: {
15259
+ type: "array",
15260
+ items: {
15261
+ type: "string"
15262
+ },
15263
+ description: "Phone number allowlist \u2014 only respond to these numbers"
15264
+ },
15265
+ workflow: {
15266
+ type: "string",
15267
+ description: "Workflow to run when a message is received"
15268
+ }
15269
+ },
15270
+ additionalProperties: false,
15271
+ patternProperties: {
15272
+ "^x-": {}
15273
+ }
15274
+ },
15275
+ TeamsConfig: {
15276
+ type: "object",
15277
+ properties: {
15278
+ app_id: {
15279
+ type: "string",
15280
+ description: "Azure AD App (client) ID (or TEAMS_APP_ID env var)"
15281
+ },
15282
+ app_password: {
15283
+ type: "string",
15284
+ description: "Azure AD App client secret (or TEAMS_APP_PASSWORD env var)"
15285
+ },
15286
+ tenant_id: {
15287
+ type: "string",
15288
+ description: "Azure AD Tenant ID for single-tenant apps (or TEAMS_TENANT_ID env var)"
15289
+ },
15290
+ port: {
15291
+ type: "number",
15292
+ description: "Port for webhook HTTP server (default: 3978)"
15293
+ },
15294
+ host: {
15295
+ type: "string",
15296
+ description: "Host for webhook HTTP server (default: '0.0.0.0')"
15297
+ },
15298
+ user_allowlist: {
15299
+ type: "array",
15300
+ items: {
15301
+ type: "string"
15302
+ },
15303
+ description: "User ID allowlist \u2014 only respond to these AAD user IDs"
15304
+ },
15305
+ workflow: {
15306
+ type: "string",
15307
+ description: "Workflow to run when a message is received"
15308
+ }
15309
+ },
15310
+ additionalProperties: false,
15311
+ patternProperties: {
15312
+ "^x-": {}
15313
+ }
15314
+ },
15039
15315
  SchedulerConfig: {
15040
15316
  type: "object",
15041
15317
  properties: {
@@ -18299,17 +18575,17 @@ var init_workflow_check_provider = __esm({
18299
18575
  * so it can be executed by the state machine as a nested workflow.
18300
18576
  */
18301
18577
  async loadWorkflowFromConfigPath(sourcePath, baseDir) {
18302
- const path29 = require("path");
18303
- const fs25 = require("fs");
18578
+ const path33 = require("path");
18579
+ const fs29 = require("fs");
18304
18580
  const yaml5 = require("js-yaml");
18305
- const resolved = path29.isAbsolute(sourcePath) ? sourcePath : path29.resolve(baseDir, sourcePath);
18306
- if (!fs25.existsSync(resolved)) {
18581
+ const resolved = path33.isAbsolute(sourcePath) ? sourcePath : path33.resolve(baseDir, sourcePath);
18582
+ if (!fs29.existsSync(resolved)) {
18307
18583
  throw new Error(`Workflow config not found at: ${resolved}`);
18308
18584
  }
18309
- const rawContent = fs25.readFileSync(resolved, "utf8");
18585
+ const rawContent = fs29.readFileSync(resolved, "utf8");
18310
18586
  const rawData = yaml5.load(rawContent);
18311
18587
  if (rawData.imports && Array.isArray(rawData.imports)) {
18312
- const configDir = path29.dirname(resolved);
18588
+ const configDir = path33.dirname(resolved);
18313
18589
  for (const source of rawData.imports) {
18314
18590
  const results = await this.registry.import(source, {
18315
18591
  basePath: configDir,
@@ -18339,8 +18615,8 @@ ${errors}`);
18339
18615
  if (!steps || Object.keys(steps).length === 0) {
18340
18616
  throw new Error(`Config '${resolved}' does not contain any steps to execute as a workflow`);
18341
18617
  }
18342
- const id = path29.basename(resolved).replace(/\.(ya?ml)$/i, "");
18343
- const name = loaded.name || `Workflow from ${path29.basename(resolved)}`;
18618
+ const id = path33.basename(resolved).replace(/\.(ya?ml)$/i, "");
18619
+ const name = loaded.name || `Workflow from ${path33.basename(resolved)}`;
18344
18620
  const workflowDef = {
18345
18621
  id,
18346
18622
  name,
@@ -19149,8 +19425,8 @@ async function createStoreBackend(storageConfig, haConfig) {
19149
19425
  case "mssql": {
19150
19426
  try {
19151
19427
  const loaderPath = "../../enterprise/loader";
19152
- const { loadEnterpriseStoreBackend } = await import(loaderPath);
19153
- return await loadEnterpriseStoreBackend(driver, storageConfig, haConfig);
19428
+ const { loadEnterpriseStoreBackend: loadEnterpriseStoreBackend2 } = await import(loaderPath);
19429
+ return await loadEnterpriseStoreBackend2(driver, storageConfig, haConfig);
19154
19430
  } catch (err) {
19155
19431
  const msg = err instanceof Error ? err.message : String(err);
19156
19432
  logger.error(`[StoreFactory] Failed to load enterprise ${driver} backend: ${msg}`);
@@ -21838,7 +22114,7 @@ var init_mcp_custom_sse_server = __esm({
21838
22114
  * Returns the actual bound port number
21839
22115
  */
21840
22116
  async start() {
21841
- return new Promise((resolve15, reject) => {
22117
+ return new Promise((resolve19, reject) => {
21842
22118
  try {
21843
22119
  this.server = import_http.default.createServer((req, res) => {
21844
22120
  this.handleRequest(req, res).catch((error) => {
@@ -21872,7 +22148,7 @@ var init_mcp_custom_sse_server = __esm({
21872
22148
  );
21873
22149
  }
21874
22150
  this.startKeepalive();
21875
- resolve15(this.port);
22151
+ resolve19(this.port);
21876
22152
  });
21877
22153
  } catch (error) {
21878
22154
  reject(error);
@@ -21935,7 +22211,7 @@ var init_mcp_custom_sse_server = __esm({
21935
22211
  logger.debug(
21936
22212
  `[CustomToolsSSEServer:${this.sessionId}] Grace period before stop: ${waitMs}ms (activeToolCalls=${this.activeToolCalls})`
21937
22213
  );
21938
- await new Promise((resolve15) => setTimeout(resolve15, waitMs));
22214
+ await new Promise((resolve19) => setTimeout(resolve19, waitMs));
21939
22215
  }
21940
22216
  }
21941
22217
  if (this.activeToolCalls > 0) {
@@ -21944,7 +22220,7 @@ var init_mcp_custom_sse_server = __esm({
21944
22220
  `[CustomToolsSSEServer:${this.sessionId}] Waiting for ${this.activeToolCalls} active tool call(s) before stop`
21945
22221
  );
21946
22222
  while (this.activeToolCalls > 0 && Date.now() - startedAt < effectiveDrainTimeoutMs) {
21947
- await new Promise((resolve15) => setTimeout(resolve15, 250));
22223
+ await new Promise((resolve19) => setTimeout(resolve19, 250));
21948
22224
  }
21949
22225
  if (this.activeToolCalls > 0) {
21950
22226
  logger.warn(
@@ -21969,21 +22245,21 @@ var init_mcp_custom_sse_server = __esm({
21969
22245
  }
21970
22246
  this.connections.clear();
21971
22247
  if (this.server) {
21972
- await new Promise((resolve15, reject) => {
22248
+ await new Promise((resolve19, reject) => {
21973
22249
  const timeout = setTimeout(() => {
21974
22250
  if (this.debug) {
21975
22251
  logger.debug(
21976
22252
  `[CustomToolsSSEServer:${this.sessionId}] Force closing server after timeout`
21977
22253
  );
21978
22254
  }
21979
- this.server?.close(() => resolve15());
22255
+ this.server?.close(() => resolve19());
21980
22256
  }, 5e3);
21981
22257
  this.server.close((error) => {
21982
22258
  clearTimeout(timeout);
21983
22259
  if (error) {
21984
22260
  reject(error);
21985
22261
  } else {
21986
- resolve15();
22262
+ resolve19();
21987
22263
  }
21988
22264
  });
21989
22265
  });
@@ -22433,7 +22709,7 @@ var init_mcp_custom_sse_server = __esm({
22433
22709
  logger.warn(
22434
22710
  `[CustomToolsSSEServer:${this.sessionId}] Tool ${toolName} failed (attempt ${attempt + 1}/${retryCount + 1}): ${errorMsg}. Retrying in ${delay}ms`
22435
22711
  );
22436
- await new Promise((resolve15) => setTimeout(resolve15, delay));
22712
+ await new Promise((resolve19) => setTimeout(resolve19, delay));
22437
22713
  attempt++;
22438
22714
  }
22439
22715
  }
@@ -22825,9 +23101,9 @@ var init_ai_check_provider = __esm({
22825
23101
  } else {
22826
23102
  resolvedPath = import_path8.default.resolve(process.cwd(), str);
22827
23103
  }
22828
- const fs25 = require("fs").promises;
23104
+ const fs29 = require("fs").promises;
22829
23105
  try {
22830
- const stat2 = await fs25.stat(resolvedPath);
23106
+ const stat2 = await fs29.stat(resolvedPath);
22831
23107
  return stat2.isFile();
22832
23108
  } catch {
22833
23109
  return hasFileExtension && (isRelativePath || isAbsolutePath || hasPathSeparators);
@@ -28929,14 +29205,14 @@ var require_util = __commonJS({
28929
29205
  }
28930
29206
  const port = url.port != null ? url.port : url.protocol === "https:" ? 443 : 80;
28931
29207
  let origin = url.origin != null ? url.origin : `${url.protocol}//${url.hostname}:${port}`;
28932
- let path29 = url.path != null ? url.path : `${url.pathname || ""}${url.search || ""}`;
29208
+ let path33 = url.path != null ? url.path : `${url.pathname || ""}${url.search || ""}`;
28933
29209
  if (origin.endsWith("/")) {
28934
29210
  origin = origin.substring(0, origin.length - 1);
28935
29211
  }
28936
- if (path29 && !path29.startsWith("/")) {
28937
- path29 = `/${path29}`;
29212
+ if (path33 && !path33.startsWith("/")) {
29213
+ path33 = `/${path33}`;
28938
29214
  }
28939
- url = new URL(origin + path29);
29215
+ url = new URL(origin + path33);
28940
29216
  }
28941
29217
  return url;
28942
29218
  }
@@ -30550,20 +30826,20 @@ var require_parseParams = __commonJS({
30550
30826
  var require_basename = __commonJS({
30551
30827
  "node_modules/@fastify/busboy/lib/utils/basename.js"(exports2, module2) {
30552
30828
  "use strict";
30553
- module2.exports = function basename4(path29) {
30554
- if (typeof path29 !== "string") {
30829
+ module2.exports = function basename4(path33) {
30830
+ if (typeof path33 !== "string") {
30555
30831
  return "";
30556
30832
  }
30557
- for (var i = path29.length - 1; i >= 0; --i) {
30558
- switch (path29.charCodeAt(i)) {
30833
+ for (var i = path33.length - 1; i >= 0; --i) {
30834
+ switch (path33.charCodeAt(i)) {
30559
30835
  case 47:
30560
30836
  // '/'
30561
30837
  case 92:
30562
- path29 = path29.slice(i + 1);
30563
- return path29 === ".." || path29 === "." ? "" : path29;
30838
+ path33 = path33.slice(i + 1);
30839
+ return path33 === ".." || path33 === "." ? "" : path33;
30564
30840
  }
30565
30841
  }
30566
- return path29 === ".." || path29 === "." ? "" : path29;
30842
+ return path33 === ".." || path33 === "." ? "" : path33;
30567
30843
  };
30568
30844
  }
30569
30845
  });
@@ -31567,11 +31843,11 @@ var require_util2 = __commonJS({
31567
31843
  var assert = require("assert");
31568
31844
  var { isUint8Array } = require("util/types");
31569
31845
  var supportedHashes = [];
31570
- var crypto7;
31846
+ var crypto9;
31571
31847
  try {
31572
- crypto7 = require("crypto");
31848
+ crypto9 = require("crypto");
31573
31849
  const possibleRelevantHashes = ["sha256", "sha384", "sha512"];
31574
- supportedHashes = crypto7.getHashes().filter((hash) => possibleRelevantHashes.includes(hash));
31850
+ supportedHashes = crypto9.getHashes().filter((hash) => possibleRelevantHashes.includes(hash));
31575
31851
  } catch {
31576
31852
  }
31577
31853
  function responseURL(response) {
@@ -31848,7 +32124,7 @@ var require_util2 = __commonJS({
31848
32124
  }
31849
32125
  }
31850
32126
  function bytesMatch(bytes, metadataList) {
31851
- if (crypto7 === void 0) {
32127
+ if (crypto9 === void 0) {
31852
32128
  return true;
31853
32129
  }
31854
32130
  const parsedMetadata = parseMetadata(metadataList);
@@ -31863,7 +32139,7 @@ var require_util2 = __commonJS({
31863
32139
  for (const item of metadata) {
31864
32140
  const algorithm = item.algo;
31865
32141
  const expectedValue = item.hash;
31866
- let actualValue = crypto7.createHash(algorithm).update(bytes).digest("base64");
32142
+ let actualValue = crypto9.createHash(algorithm).update(bytes).digest("base64");
31867
32143
  if (actualValue[actualValue.length - 1] === "=") {
31868
32144
  if (actualValue[actualValue.length - 2] === "=") {
31869
32145
  actualValue = actualValue.slice(0, -2);
@@ -31956,8 +32232,8 @@ var require_util2 = __commonJS({
31956
32232
  function createDeferredPromise() {
31957
32233
  let res;
31958
32234
  let rej;
31959
- const promise = new Promise((resolve15, reject) => {
31960
- res = resolve15;
32235
+ const promise = new Promise((resolve19, reject) => {
32236
+ res = resolve19;
31961
32237
  rej = reject;
31962
32238
  });
31963
32239
  return { promise, resolve: res, reject: rej };
@@ -33210,8 +33486,8 @@ var require_body = __commonJS({
33210
33486
  var { parseMIMEType, serializeAMimeType } = require_dataURL();
33211
33487
  var random;
33212
33488
  try {
33213
- const crypto7 = require("crypto");
33214
- random = (max) => crypto7.randomInt(0, max);
33489
+ const crypto9 = require("crypto");
33490
+ random = (max) => crypto9.randomInt(0, max);
33215
33491
  } catch {
33216
33492
  random = (max) => Math.floor(Math.random(max));
33217
33493
  }
@@ -33462,8 +33738,8 @@ Content-Type: ${value.type || "application/octet-stream"}\r
33462
33738
  });
33463
33739
  }
33464
33740
  });
33465
- const busboyResolve = new Promise((resolve15, reject) => {
33466
- busboy.on("finish", resolve15);
33741
+ const busboyResolve = new Promise((resolve19, reject) => {
33742
+ busboy.on("finish", resolve19);
33467
33743
  busboy.on("error", (err) => reject(new TypeError(err)));
33468
33744
  });
33469
33745
  if (this.body !== null) for await (const chunk of consumeBody(this[kState].body)) busboy.write(chunk);
@@ -33594,7 +33870,7 @@ var require_request = __commonJS({
33594
33870
  }
33595
33871
  var Request2 = class _Request {
33596
33872
  constructor(origin, {
33597
- path: path29,
33873
+ path: path33,
33598
33874
  method,
33599
33875
  body,
33600
33876
  headers,
@@ -33608,11 +33884,11 @@ var require_request = __commonJS({
33608
33884
  throwOnError,
33609
33885
  expectContinue
33610
33886
  }, handler) {
33611
- if (typeof path29 !== "string") {
33887
+ if (typeof path33 !== "string") {
33612
33888
  throw new InvalidArgumentError("path must be a string");
33613
- } else if (path29[0] !== "/" && !(path29.startsWith("http://") || path29.startsWith("https://")) && method !== "CONNECT") {
33889
+ } else if (path33[0] !== "/" && !(path33.startsWith("http://") || path33.startsWith("https://")) && method !== "CONNECT") {
33614
33890
  throw new InvalidArgumentError("path must be an absolute URL or start with a slash");
33615
- } else if (invalidPathRegex.exec(path29) !== null) {
33891
+ } else if (invalidPathRegex.exec(path33) !== null) {
33616
33892
  throw new InvalidArgumentError("invalid request path");
33617
33893
  }
33618
33894
  if (typeof method !== "string") {
@@ -33675,7 +33951,7 @@ var require_request = __commonJS({
33675
33951
  this.completed = false;
33676
33952
  this.aborted = false;
33677
33953
  this.upgrade = upgrade || null;
33678
- this.path = query ? util.buildURL(path29, query) : path29;
33954
+ this.path = query ? util.buildURL(path33, query) : path33;
33679
33955
  this.origin = origin;
33680
33956
  this.idempotent = idempotent == null ? method === "HEAD" || method === "GET" : idempotent;
33681
33957
  this.blocking = blocking == null ? false : blocking;
@@ -33997,9 +34273,9 @@ var require_dispatcher_base = __commonJS({
33997
34273
  }
33998
34274
  close(callback) {
33999
34275
  if (callback === void 0) {
34000
- return new Promise((resolve15, reject) => {
34276
+ return new Promise((resolve19, reject) => {
34001
34277
  this.close((err, data) => {
34002
- return err ? reject(err) : resolve15(data);
34278
+ return err ? reject(err) : resolve19(data);
34003
34279
  });
34004
34280
  });
34005
34281
  }
@@ -34037,12 +34313,12 @@ var require_dispatcher_base = __commonJS({
34037
34313
  err = null;
34038
34314
  }
34039
34315
  if (callback === void 0) {
34040
- return new Promise((resolve15, reject) => {
34316
+ return new Promise((resolve19, reject) => {
34041
34317
  this.destroy(err, (err2, data) => {
34042
34318
  return err2 ? (
34043
34319
  /* istanbul ignore next: should never error */
34044
34320
  reject(err2)
34045
- ) : resolve15(data);
34321
+ ) : resolve19(data);
34046
34322
  });
34047
34323
  });
34048
34324
  }
@@ -34683,9 +34959,9 @@ var require_RedirectHandler = __commonJS({
34683
34959
  return this.handler.onHeaders(statusCode, headers, resume, statusText);
34684
34960
  }
34685
34961
  const { origin, pathname, search } = util.parseURL(new URL(this.location, this.opts.origin && new URL(this.opts.path, this.opts.origin)));
34686
- const path29 = search ? `${pathname}${search}` : pathname;
34962
+ const path33 = search ? `${pathname}${search}` : pathname;
34687
34963
  this.opts.headers = cleanRequestHeaders(this.opts.headers, statusCode === 303, this.opts.origin !== origin);
34688
- this.opts.path = path29;
34964
+ this.opts.path = path33;
34689
34965
  this.opts.origin = origin;
34690
34966
  this.opts.maxRedirections = 0;
34691
34967
  this.opts.query = null;
@@ -35104,16 +35380,16 @@ var require_client = __commonJS({
35104
35380
  return this[kNeedDrain] < 2;
35105
35381
  }
35106
35382
  async [kClose]() {
35107
- return new Promise((resolve15) => {
35383
+ return new Promise((resolve19) => {
35108
35384
  if (!this[kSize]) {
35109
- resolve15(null);
35385
+ resolve19(null);
35110
35386
  } else {
35111
- this[kClosedResolve] = resolve15;
35387
+ this[kClosedResolve] = resolve19;
35112
35388
  }
35113
35389
  });
35114
35390
  }
35115
35391
  async [kDestroy](err) {
35116
- return new Promise((resolve15) => {
35392
+ return new Promise((resolve19) => {
35117
35393
  const requests = this[kQueue].splice(this[kPendingIdx]);
35118
35394
  for (let i = 0; i < requests.length; i++) {
35119
35395
  const request = requests[i];
@@ -35124,7 +35400,7 @@ var require_client = __commonJS({
35124
35400
  this[kClosedResolve]();
35125
35401
  this[kClosedResolve] = null;
35126
35402
  }
35127
- resolve15();
35403
+ resolve19();
35128
35404
  };
35129
35405
  if (this[kHTTP2Session] != null) {
35130
35406
  util.destroy(this[kHTTP2Session], err);
@@ -35704,7 +35980,7 @@ var require_client = __commonJS({
35704
35980
  });
35705
35981
  }
35706
35982
  try {
35707
- const socket = await new Promise((resolve15, reject) => {
35983
+ const socket = await new Promise((resolve19, reject) => {
35708
35984
  client[kConnector]({
35709
35985
  host,
35710
35986
  hostname,
@@ -35716,7 +35992,7 @@ var require_client = __commonJS({
35716
35992
  if (err) {
35717
35993
  reject(err);
35718
35994
  } else {
35719
- resolve15(socket2);
35995
+ resolve19(socket2);
35720
35996
  }
35721
35997
  });
35722
35998
  });
@@ -35927,7 +36203,7 @@ var require_client = __commonJS({
35927
36203
  writeH2(client, client[kHTTP2Session], request);
35928
36204
  return;
35929
36205
  }
35930
- const { body, method, path: path29, host, upgrade, headers, blocking, reset } = request;
36206
+ const { body, method, path: path33, host, upgrade, headers, blocking, reset } = request;
35931
36207
  const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH";
35932
36208
  if (body && typeof body.read === "function") {
35933
36209
  body.read(0);
@@ -35977,7 +36253,7 @@ var require_client = __commonJS({
35977
36253
  if (blocking) {
35978
36254
  socket[kBlocking] = true;
35979
36255
  }
35980
- let header = `${method} ${path29} HTTP/1.1\r
36256
+ let header = `${method} ${path33} HTTP/1.1\r
35981
36257
  `;
35982
36258
  if (typeof host === "string") {
35983
36259
  header += `host: ${host}\r
@@ -36040,7 +36316,7 @@ upgrade: ${upgrade}\r
36040
36316
  return true;
36041
36317
  }
36042
36318
  function writeH2(client, session, request) {
36043
- const { body, method, path: path29, host, upgrade, expectContinue, signal, headers: reqHeaders } = request;
36319
+ const { body, method, path: path33, host, upgrade, expectContinue, signal, headers: reqHeaders } = request;
36044
36320
  let headers;
36045
36321
  if (typeof reqHeaders === "string") headers = Request2[kHTTP2CopyHeaders](reqHeaders.trim());
36046
36322
  else headers = reqHeaders;
@@ -36083,7 +36359,7 @@ upgrade: ${upgrade}\r
36083
36359
  });
36084
36360
  return true;
36085
36361
  }
36086
- headers[HTTP2_HEADER_PATH] = path29;
36362
+ headers[HTTP2_HEADER_PATH] = path33;
36087
36363
  headers[HTTP2_HEADER_SCHEME] = "https";
36088
36364
  const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH";
36089
36365
  if (body && typeof body.read === "function") {
@@ -36340,12 +36616,12 @@ upgrade: ${upgrade}\r
36340
36616
  cb();
36341
36617
  }
36342
36618
  }
36343
- const waitForDrain = () => new Promise((resolve15, reject) => {
36619
+ const waitForDrain = () => new Promise((resolve19, reject) => {
36344
36620
  assert(callback === null);
36345
36621
  if (socket[kError]) {
36346
36622
  reject(socket[kError]);
36347
36623
  } else {
36348
- callback = resolve15;
36624
+ callback = resolve19;
36349
36625
  }
36350
36626
  });
36351
36627
  if (client[kHTTPConnVersion] === "h2") {
@@ -36691,8 +36967,8 @@ var require_pool_base = __commonJS({
36691
36967
  if (this[kQueue].isEmpty()) {
36692
36968
  return Promise.all(this[kClients].map((c) => c.close()));
36693
36969
  } else {
36694
- return new Promise((resolve15) => {
36695
- this[kClosedResolve] = resolve15;
36970
+ return new Promise((resolve19) => {
36971
+ this[kClosedResolve] = resolve19;
36696
36972
  });
36697
36973
  }
36698
36974
  }
@@ -37270,7 +37546,7 @@ var require_readable = __commonJS({
37270
37546
  if (this.closed) {
37271
37547
  return Promise.resolve(null);
37272
37548
  }
37273
- return new Promise((resolve15, reject) => {
37549
+ return new Promise((resolve19, reject) => {
37274
37550
  const signalListenerCleanup = signal ? util.addAbortListener(signal, () => {
37275
37551
  this.destroy();
37276
37552
  }) : noop;
@@ -37279,7 +37555,7 @@ var require_readable = __commonJS({
37279
37555
  if (signal && signal.aborted) {
37280
37556
  reject(signal.reason || Object.assign(new Error("The operation was aborted"), { name: "AbortError" }));
37281
37557
  } else {
37282
- resolve15(null);
37558
+ resolve19(null);
37283
37559
  }
37284
37560
  }).on("error", noop).on("data", function(chunk) {
37285
37561
  limit -= chunk.length;
@@ -37301,11 +37577,11 @@ var require_readable = __commonJS({
37301
37577
  throw new TypeError("unusable");
37302
37578
  }
37303
37579
  assert(!stream[kConsume]);
37304
- return new Promise((resolve15, reject) => {
37580
+ return new Promise((resolve19, reject) => {
37305
37581
  stream[kConsume] = {
37306
37582
  type,
37307
37583
  stream,
37308
- resolve: resolve15,
37584
+ resolve: resolve19,
37309
37585
  reject,
37310
37586
  length: 0,
37311
37587
  body: []
@@ -37340,12 +37616,12 @@ var require_readable = __commonJS({
37340
37616
  }
37341
37617
  }
37342
37618
  function consumeEnd(consume2) {
37343
- const { type, body, resolve: resolve15, stream, length } = consume2;
37619
+ const { type, body, resolve: resolve19, stream, length } = consume2;
37344
37620
  try {
37345
37621
  if (type === "text") {
37346
- resolve15(toUSVString(Buffer.concat(body)));
37622
+ resolve19(toUSVString(Buffer.concat(body)));
37347
37623
  } else if (type === "json") {
37348
- resolve15(JSON.parse(Buffer.concat(body)));
37624
+ resolve19(JSON.parse(Buffer.concat(body)));
37349
37625
  } else if (type === "arrayBuffer") {
37350
37626
  const dst = new Uint8Array(length);
37351
37627
  let pos = 0;
@@ -37353,12 +37629,12 @@ var require_readable = __commonJS({
37353
37629
  dst.set(buf, pos);
37354
37630
  pos += buf.byteLength;
37355
37631
  }
37356
- resolve15(dst.buffer);
37632
+ resolve19(dst.buffer);
37357
37633
  } else if (type === "blob") {
37358
37634
  if (!Blob2) {
37359
37635
  Blob2 = require("buffer").Blob;
37360
37636
  }
37361
- resolve15(new Blob2(body, { type: stream[kContentType] }));
37637
+ resolve19(new Blob2(body, { type: stream[kContentType] }));
37362
37638
  }
37363
37639
  consumeFinish(consume2);
37364
37640
  } catch (err) {
@@ -37615,9 +37891,9 @@ var require_api_request = __commonJS({
37615
37891
  };
37616
37892
  function request(opts, callback) {
37617
37893
  if (callback === void 0) {
37618
- return new Promise((resolve15, reject) => {
37894
+ return new Promise((resolve19, reject) => {
37619
37895
  request.call(this, opts, (err, data) => {
37620
- return err ? reject(err) : resolve15(data);
37896
+ return err ? reject(err) : resolve19(data);
37621
37897
  });
37622
37898
  });
37623
37899
  }
@@ -37790,9 +38066,9 @@ var require_api_stream = __commonJS({
37790
38066
  };
37791
38067
  function stream(opts, factory, callback) {
37792
38068
  if (callback === void 0) {
37793
- return new Promise((resolve15, reject) => {
38069
+ return new Promise((resolve19, reject) => {
37794
38070
  stream.call(this, opts, factory, (err, data) => {
37795
- return err ? reject(err) : resolve15(data);
38071
+ return err ? reject(err) : resolve19(data);
37796
38072
  });
37797
38073
  });
37798
38074
  }
@@ -38073,9 +38349,9 @@ var require_api_upgrade = __commonJS({
38073
38349
  };
38074
38350
  function upgrade(opts, callback) {
38075
38351
  if (callback === void 0) {
38076
- return new Promise((resolve15, reject) => {
38352
+ return new Promise((resolve19, reject) => {
38077
38353
  upgrade.call(this, opts, (err, data) => {
38078
- return err ? reject(err) : resolve15(data);
38354
+ return err ? reject(err) : resolve19(data);
38079
38355
  });
38080
38356
  });
38081
38357
  }
@@ -38164,9 +38440,9 @@ var require_api_connect = __commonJS({
38164
38440
  };
38165
38441
  function connect(opts, callback) {
38166
38442
  if (callback === void 0) {
38167
- return new Promise((resolve15, reject) => {
38443
+ return new Promise((resolve19, reject) => {
38168
38444
  connect.call(this, opts, (err, data) => {
38169
- return err ? reject(err) : resolve15(data);
38445
+ return err ? reject(err) : resolve19(data);
38170
38446
  });
38171
38447
  });
38172
38448
  }
@@ -38326,20 +38602,20 @@ var require_mock_utils = __commonJS({
38326
38602
  }
38327
38603
  return true;
38328
38604
  }
38329
- function safeUrl(path29) {
38330
- if (typeof path29 !== "string") {
38331
- return path29;
38605
+ function safeUrl(path33) {
38606
+ if (typeof path33 !== "string") {
38607
+ return path33;
38332
38608
  }
38333
- const pathSegments = path29.split("?");
38609
+ const pathSegments = path33.split("?");
38334
38610
  if (pathSegments.length !== 2) {
38335
- return path29;
38611
+ return path33;
38336
38612
  }
38337
38613
  const qp = new URLSearchParams(pathSegments.pop());
38338
38614
  qp.sort();
38339
38615
  return [...pathSegments, qp.toString()].join("?");
38340
38616
  }
38341
- function matchKey(mockDispatch2, { path: path29, method, body, headers }) {
38342
- const pathMatch = matchValue(mockDispatch2.path, path29);
38617
+ function matchKey(mockDispatch2, { path: path33, method, body, headers }) {
38618
+ const pathMatch = matchValue(mockDispatch2.path, path33);
38343
38619
  const methodMatch = matchValue(mockDispatch2.method, method);
38344
38620
  const bodyMatch = typeof mockDispatch2.body !== "undefined" ? matchValue(mockDispatch2.body, body) : true;
38345
38621
  const headersMatch = matchHeaders(mockDispatch2, headers);
@@ -38357,7 +38633,7 @@ var require_mock_utils = __commonJS({
38357
38633
  function getMockDispatch(mockDispatches, key) {
38358
38634
  const basePath = key.query ? buildURL(key.path, key.query) : key.path;
38359
38635
  const resolvedPath = typeof basePath === "string" ? safeUrl(basePath) : basePath;
38360
- let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path: path29 }) => matchValue(safeUrl(path29), resolvedPath));
38636
+ let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path: path33 }) => matchValue(safeUrl(path33), resolvedPath));
38361
38637
  if (matchedMockDispatches.length === 0) {
38362
38638
  throw new MockNotMatchedError(`Mock dispatch not matched for path '${resolvedPath}'`);
38363
38639
  }
@@ -38394,9 +38670,9 @@ var require_mock_utils = __commonJS({
38394
38670
  }
38395
38671
  }
38396
38672
  function buildKey(opts) {
38397
- const { path: path29, method, body, headers, query } = opts;
38673
+ const { path: path33, method, body, headers, query } = opts;
38398
38674
  return {
38399
- path: path29,
38675
+ path: path33,
38400
38676
  method,
38401
38677
  body,
38402
38678
  headers,
@@ -38845,10 +39121,10 @@ var require_pending_interceptors_formatter = __commonJS({
38845
39121
  }
38846
39122
  format(pendingInterceptors) {
38847
39123
  const withPrettyHeaders = pendingInterceptors.map(
38848
- ({ method, path: path29, data: { statusCode }, persist, times, timesInvoked, origin }) => ({
39124
+ ({ method, path: path33, data: { statusCode }, persist, times, timesInvoked, origin }) => ({
38849
39125
  Method: method,
38850
39126
  Origin: origin,
38851
- Path: path29,
39127
+ Path: path33,
38852
39128
  "Status code": statusCode,
38853
39129
  Persistent: persist ? "\u2705" : "\u274C",
38854
39130
  Invocations: timesInvoked,
@@ -41789,7 +42065,7 @@ var require_fetch = __commonJS({
41789
42065
  async function dispatch({ body }) {
41790
42066
  const url = requestCurrentURL(request);
41791
42067
  const agent = fetchParams.controller.dispatcher;
41792
- return new Promise((resolve15, reject) => agent.dispatch(
42068
+ return new Promise((resolve19, reject) => agent.dispatch(
41793
42069
  {
41794
42070
  path: url.pathname + url.search,
41795
42071
  origin: url.origin,
@@ -41865,7 +42141,7 @@ var require_fetch = __commonJS({
41865
42141
  }
41866
42142
  }
41867
42143
  }
41868
- resolve15({
42144
+ resolve19({
41869
42145
  status,
41870
42146
  statusText,
41871
42147
  headersList: headers[kHeadersList],
@@ -41908,7 +42184,7 @@ var require_fetch = __commonJS({
41908
42184
  const val = headersList[n + 1].toString("latin1");
41909
42185
  headers[kHeadersList].append(key, val);
41910
42186
  }
41911
- resolve15({
42187
+ resolve19({
41912
42188
  status,
41913
42189
  statusText: STATUS_CODES[status],
41914
42190
  headersList: headers[kHeadersList],
@@ -43469,8 +43745,8 @@ var require_util6 = __commonJS({
43469
43745
  }
43470
43746
  }
43471
43747
  }
43472
- function validateCookiePath(path29) {
43473
- for (const char of path29) {
43748
+ function validateCookiePath(path33) {
43749
+ for (const char of path33) {
43474
43750
  const code = char.charCodeAt(0);
43475
43751
  if (code < 33 || char === ";") {
43476
43752
  throw new Error("Invalid cookie path");
@@ -44267,9 +44543,9 @@ var require_connection = __commonJS({
44267
44543
  channels.open = diagnosticsChannel.channel("undici:websocket:open");
44268
44544
  channels.close = diagnosticsChannel.channel("undici:websocket:close");
44269
44545
  channels.socketError = diagnosticsChannel.channel("undici:websocket:socket_error");
44270
- var crypto7;
44546
+ var crypto9;
44271
44547
  try {
44272
- crypto7 = require("crypto");
44548
+ crypto9 = require("crypto");
44273
44549
  } catch {
44274
44550
  }
44275
44551
  function establishWebSocketConnection(url, protocols, ws, onEstablish, options) {
@@ -44288,7 +44564,7 @@ var require_connection = __commonJS({
44288
44564
  const headersList = new Headers(options.headers)[kHeadersList];
44289
44565
  request.headersList = headersList;
44290
44566
  }
44291
- const keyValue = crypto7.randomBytes(16).toString("base64");
44567
+ const keyValue = crypto9.randomBytes(16).toString("base64");
44292
44568
  request.headersList.append("sec-websocket-key", keyValue);
44293
44569
  request.headersList.append("sec-websocket-version", "13");
44294
44570
  for (const protocol of protocols) {
@@ -44317,7 +44593,7 @@ var require_connection = __commonJS({
44317
44593
  return;
44318
44594
  }
44319
44595
  const secWSAccept = response.headersList.get("Sec-WebSocket-Accept");
44320
- const digest = crypto7.createHash("sha1").update(keyValue + uid).digest("base64");
44596
+ const digest = crypto9.createHash("sha1").update(keyValue + uid).digest("base64");
44321
44597
  if (secWSAccept !== digest) {
44322
44598
  failWebsocketConnection(ws, "Incorrect hash received in Sec-WebSocket-Accept header.");
44323
44599
  return;
@@ -44397,9 +44673,9 @@ var require_frame = __commonJS({
44397
44673
  "node_modules/undici/lib/websocket/frame.js"(exports2, module2) {
44398
44674
  "use strict";
44399
44675
  var { maxUnsigned16Bit } = require_constants5();
44400
- var crypto7;
44676
+ var crypto9;
44401
44677
  try {
44402
- crypto7 = require("crypto");
44678
+ crypto9 = require("crypto");
44403
44679
  } catch {
44404
44680
  }
44405
44681
  var WebsocketFrameSend = class {
@@ -44408,7 +44684,7 @@ var require_frame = __commonJS({
44408
44684
  */
44409
44685
  constructor(data) {
44410
44686
  this.frameData = data;
44411
- this.maskKey = crypto7.randomBytes(4);
44687
+ this.maskKey = crypto9.randomBytes(4);
44412
44688
  }
44413
44689
  createFrame(opcode) {
44414
44690
  const bodyLength = this.frameData?.byteLength ?? 0;
@@ -45150,11 +45426,11 @@ var require_undici = __commonJS({
45150
45426
  if (typeof opts.path !== "string") {
45151
45427
  throw new InvalidArgumentError("invalid opts.path");
45152
45428
  }
45153
- let path29 = opts.path;
45429
+ let path33 = opts.path;
45154
45430
  if (!opts.path.startsWith("/")) {
45155
- path29 = `/${path29}`;
45431
+ path33 = `/${path33}`;
45156
45432
  }
45157
- url = new URL(util.parseOrigin(url).origin + path29);
45433
+ url = new URL(util.parseOrigin(url).origin + path33);
45158
45434
  } else {
45159
45435
  if (!opts) {
45160
45436
  opts = typeof url === "object" ? url : {};
@@ -45723,7 +45999,7 @@ var init_mcp_check_provider = __esm({
45723
45999
  logger.warn(
45724
46000
  `MCP ${transportName} failed (attempt ${attempt + 1}/${maxRetries + 1}), retrying in ${delay}ms: ${error instanceof Error ? error.message : String(error)}`
45725
46001
  );
45726
- await new Promise((resolve15) => setTimeout(resolve15, delay));
46002
+ await new Promise((resolve19) => setTimeout(resolve19, delay));
45727
46003
  attempt += 1;
45728
46004
  } finally {
45729
46005
  try {
@@ -46016,7 +46292,7 @@ async function acquirePromptLock() {
46016
46292
  );
46017
46293
  }, 1e4);
46018
46294
  try {
46019
- await new Promise((resolve15) => waiters.push(resolve15));
46295
+ await new Promise((resolve19) => waiters.push(resolve19));
46020
46296
  } finally {
46021
46297
  clearInterval(reminder);
46022
46298
  const waitedMs = Date.now() - queuedAt;
@@ -46035,7 +46311,7 @@ function releasePromptLock() {
46035
46311
  }
46036
46312
  async function interactivePrompt(options) {
46037
46313
  await acquirePromptLock();
46038
- return new Promise((resolve15, reject) => {
46314
+ return new Promise((resolve19, reject) => {
46039
46315
  const dbg = process.env.VISOR_DEBUG === "true";
46040
46316
  try {
46041
46317
  if (dbg) {
@@ -46122,12 +46398,12 @@ async function interactivePrompt(options) {
46122
46398
  };
46123
46399
  const finish = (value) => {
46124
46400
  cleanup();
46125
- resolve15(value);
46401
+ resolve19(value);
46126
46402
  };
46127
46403
  if (options.timeout && options.timeout > 0) {
46128
46404
  timeoutId = setTimeout(() => {
46129
46405
  cleanup();
46130
- if (defaultValue !== void 0) return resolve15(defaultValue);
46406
+ if (defaultValue !== void 0) return resolve19(defaultValue);
46131
46407
  return reject(new Error("Input timeout"));
46132
46408
  }, options.timeout);
46133
46409
  }
@@ -46259,7 +46535,7 @@ async function interactivePrompt(options) {
46259
46535
  });
46260
46536
  }
46261
46537
  async function simplePrompt(prompt) {
46262
- return new Promise((resolve15) => {
46538
+ return new Promise((resolve19) => {
46263
46539
  const rl = readline.createInterface({
46264
46540
  input: process.stdin,
46265
46541
  output: process.stdout
@@ -46275,7 +46551,7 @@ async function simplePrompt(prompt) {
46275
46551
  rl.question(`${prompt}
46276
46552
  > `, (answer) => {
46277
46553
  rl.close();
46278
- resolve15(answer.trim());
46554
+ resolve19(answer.trim());
46279
46555
  });
46280
46556
  });
46281
46557
  }
@@ -46443,7 +46719,7 @@ function isStdinAvailable() {
46443
46719
  return !process.stdin.isTTY;
46444
46720
  }
46445
46721
  async function readStdin(timeout, maxSize = 1024 * 1024) {
46446
- return new Promise((resolve15, reject) => {
46722
+ return new Promise((resolve19, reject) => {
46447
46723
  let data = "";
46448
46724
  let timeoutId;
46449
46725
  if (timeout) {
@@ -46470,7 +46746,7 @@ async function readStdin(timeout, maxSize = 1024 * 1024) {
46470
46746
  };
46471
46747
  const onEnd = () => {
46472
46748
  cleanup();
46473
- resolve15(data.trim());
46749
+ resolve19(data.trim());
46474
46750
  };
46475
46751
  const onError = (err) => {
46476
46752
  cleanup();
@@ -51170,23 +51446,23 @@ __export(renderer_schema_exports, {
51170
51446
  });
51171
51447
  async function loadRendererSchema(name) {
51172
51448
  try {
51173
- const fs25 = await import("fs/promises");
51174
- const path29 = await import("path");
51449
+ const fs29 = await import("fs/promises");
51450
+ const path33 = await import("path");
51175
51451
  const sanitized = String(name).replace(/[^a-zA-Z0-9-]/g, "");
51176
51452
  if (!sanitized) return void 0;
51177
51453
  const candidates = [
51178
51454
  // When bundled with ncc, __dirname is dist/ and output/ is at dist/output/
51179
- path29.join(__dirname, "output", sanitized, "schema.json"),
51455
+ path33.join(__dirname, "output", sanitized, "schema.json"),
51180
51456
  // When running from source, __dirname is src/state-machine/dispatch/ and output/ is at output/
51181
- path29.join(__dirname, "..", "..", "output", sanitized, "schema.json"),
51457
+ path33.join(__dirname, "..", "..", "output", sanitized, "schema.json"),
51182
51458
  // When running from a checkout with output/ folder copied to CWD
51183
- path29.join(process.cwd(), "output", sanitized, "schema.json"),
51459
+ path33.join(process.cwd(), "output", sanitized, "schema.json"),
51184
51460
  // Fallback: cwd/dist/output/
51185
- path29.join(process.cwd(), "dist", "output", sanitized, "schema.json")
51461
+ path33.join(process.cwd(), "dist", "output", sanitized, "schema.json")
51186
51462
  ];
51187
51463
  for (const p of candidates) {
51188
51464
  try {
51189
- const raw = await fs25.readFile(p, "utf-8");
51465
+ const raw = await fs29.readFile(p, "utf-8");
51190
51466
  return JSON.parse(raw);
51191
51467
  } catch {
51192
51468
  }
@@ -53631,8 +53907,8 @@ function updateStats2(results, state, isForEachIteration = false) {
53631
53907
  async function renderTemplateContent2(checkId, checkConfig, reviewSummary) {
53632
53908
  try {
53633
53909
  const { createExtendedLiquid: createExtendedLiquid2 } = await Promise.resolve().then(() => (init_liquid_extensions(), liquid_extensions_exports));
53634
- const fs25 = await import("fs/promises");
53635
- const path29 = await import("path");
53910
+ const fs29 = await import("fs/promises");
53911
+ const path33 = await import("path");
53636
53912
  const schemaRaw = checkConfig.schema || "plain";
53637
53913
  const schema = typeof schemaRaw === "string" && !schemaRaw.includes("{{") && !schemaRaw.includes("{%") ? schemaRaw : typeof schemaRaw === "object" ? "code-review" : "plain";
53638
53914
  let templateContent;
@@ -53641,27 +53917,27 @@ async function renderTemplateContent2(checkId, checkConfig, reviewSummary) {
53641
53917
  logger.debug(`[LevelDispatch] Using inline template for ${checkId}`);
53642
53918
  } else if (checkConfig.template && checkConfig.template.file) {
53643
53919
  const file = String(checkConfig.template.file);
53644
- const resolved = path29.resolve(process.cwd(), file);
53645
- templateContent = await fs25.readFile(resolved, "utf-8");
53920
+ const resolved = path33.resolve(process.cwd(), file);
53921
+ templateContent = await fs29.readFile(resolved, "utf-8");
53646
53922
  logger.debug(`[LevelDispatch] Using template file for ${checkId}: ${resolved}`);
53647
53923
  } else if (schema && schema !== "plain") {
53648
53924
  const sanitized = String(schema).replace(/[^a-zA-Z0-9-]/g, "");
53649
53925
  if (sanitized) {
53650
53926
  const candidatePaths = [
53651
- path29.join(__dirname, "output", sanitized, "template.liquid"),
53927
+ path33.join(__dirname, "output", sanitized, "template.liquid"),
53652
53928
  // bundled: dist/output/
53653
- path29.join(__dirname, "..", "..", "output", sanitized, "template.liquid"),
53929
+ path33.join(__dirname, "..", "..", "output", sanitized, "template.liquid"),
53654
53930
  // source (from state-machine/states)
53655
- path29.join(__dirname, "..", "..", "..", "output", sanitized, "template.liquid"),
53931
+ path33.join(__dirname, "..", "..", "..", "output", sanitized, "template.liquid"),
53656
53932
  // source (alternate)
53657
- path29.join(process.cwd(), "output", sanitized, "template.liquid"),
53933
+ path33.join(process.cwd(), "output", sanitized, "template.liquid"),
53658
53934
  // fallback: cwd/output/
53659
- path29.join(process.cwd(), "dist", "output", sanitized, "template.liquid")
53935
+ path33.join(process.cwd(), "dist", "output", sanitized, "template.liquid")
53660
53936
  // fallback: cwd/dist/output/
53661
53937
  ];
53662
53938
  for (const p of candidatePaths) {
53663
53939
  try {
53664
- templateContent = await fs25.readFile(p, "utf-8");
53940
+ templateContent = await fs29.readFile(p, "utf-8");
53665
53941
  if (templateContent) {
53666
53942
  logger.debug(`[LevelDispatch] Using schema template for ${checkId}: ${p}`);
53667
53943
  break;
@@ -55801,8 +56077,8 @@ var init_workspace_manager = __esm({
55801
56077
  );
55802
56078
  if (this.cleanupRequested && this.activeOperations === 0) {
55803
56079
  logger.debug(`[Workspace] All references released, proceeding with deferred cleanup`);
55804
- for (const resolve15 of this.cleanupResolvers) {
55805
- resolve15();
56080
+ for (const resolve19 of this.cleanupResolvers) {
56081
+ resolve19();
55806
56082
  }
55807
56083
  this.cleanupResolvers = [];
55808
56084
  }
@@ -55981,19 +56257,19 @@ var init_workspace_manager = __esm({
55981
56257
  );
55982
56258
  this.cleanupRequested = true;
55983
56259
  await Promise.race([
55984
- new Promise((resolve15) => {
56260
+ new Promise((resolve19) => {
55985
56261
  if (this.activeOperations === 0) {
55986
- resolve15();
56262
+ resolve19();
55987
56263
  } else {
55988
- this.cleanupResolvers.push(resolve15);
56264
+ this.cleanupResolvers.push(resolve19);
55989
56265
  }
55990
56266
  }),
55991
- new Promise((resolve15) => {
56267
+ new Promise((resolve19) => {
55992
56268
  setTimeout(() => {
55993
56269
  logger.warn(
55994
56270
  `[Workspace] Cleanup timeout after ${timeout}ms, proceeding anyway (${this.activeOperations} operations still active)`
55995
56271
  );
55996
- resolve15();
56272
+ resolve19();
55997
56273
  }, timeout);
55998
56274
  })
55999
56275
  ]);
@@ -56387,8 +56663,8 @@ var init_fair_concurrency_limiter = __esm({
56387
56663
  );
56388
56664
  const queuedAt = Date.now();
56389
56665
  const effectiveTimeout = queueTimeout ?? 12e4;
56390
- return new Promise((resolve15, reject) => {
56391
- const entry = { resolve: resolve15, reject, queuedAt };
56666
+ return new Promise((resolve19, reject) => {
56667
+ const entry = { resolve: resolve19, reject, queuedAt };
56392
56668
  entry.reminder = setInterval(() => {
56393
56669
  const waited = Math.round((Date.now() - queuedAt) / 1e3);
56394
56670
  const curQueued = this._totalQueued();
@@ -56695,6 +56971,1380 @@ var init_build_engine_context = __esm({
56695
56971
  }
56696
56972
  });
56697
56973
 
56974
+ // src/policy/default-engine.ts
56975
+ var DefaultPolicyEngine;
56976
+ var init_default_engine = __esm({
56977
+ "src/policy/default-engine.ts"() {
56978
+ "use strict";
56979
+ DefaultPolicyEngine = class {
56980
+ async initialize(_config) {
56981
+ }
56982
+ async evaluateCheckExecution(_checkId, _checkConfig) {
56983
+ return { allowed: true };
56984
+ }
56985
+ async evaluateToolInvocation(_serverName, _methodName, _transport) {
56986
+ return { allowed: true };
56987
+ }
56988
+ async evaluateCapabilities(_checkId, _capabilities) {
56989
+ return { allowed: true };
56990
+ }
56991
+ async shutdown() {
56992
+ }
56993
+ };
56994
+ }
56995
+ });
56996
+
56997
+ // src/enterprise/license/validator.ts
56998
+ var validator_exports = {};
56999
+ __export(validator_exports, {
57000
+ LicenseValidator: () => LicenseValidator
57001
+ });
57002
+ var crypto3, fs21, path26, LicenseValidator;
57003
+ var init_validator = __esm({
57004
+ "src/enterprise/license/validator.ts"() {
57005
+ "use strict";
57006
+ crypto3 = __toESM(require("crypto"));
57007
+ fs21 = __toESM(require("fs"));
57008
+ path26 = __toESM(require("path"));
57009
+ LicenseValidator = class _LicenseValidator {
57010
+ /** Ed25519 public key for license verification (PEM format). */
57011
+ static PUBLIC_KEY = "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAI/Zd08EFmgIdrDm/HXd0l3/5GBt7R1PrdvhdmEXhJlU=\n-----END PUBLIC KEY-----\n";
57012
+ cache = null;
57013
+ static CACHE_TTL = 5 * 60 * 1e3;
57014
+ // 5 minutes
57015
+ static GRACE_PERIOD = 72 * 3600 * 1e3;
57016
+ // 72 hours after expiry
57017
+ /**
57018
+ * Load and validate license from environment or file.
57019
+ *
57020
+ * Resolution order:
57021
+ * 1. VISOR_LICENSE env var (JWT string)
57022
+ * 2. VISOR_LICENSE_FILE env var (path to file)
57023
+ * 3. .visor-license in project root (cwd)
57024
+ * 4. .visor-license in ~/.config/visor/
57025
+ */
57026
+ async loadAndValidate() {
57027
+ if (this.cache && Date.now() - this.cache.validatedAt < _LicenseValidator.CACHE_TTL) {
57028
+ return this.cache.payload;
57029
+ }
57030
+ const token = this.resolveToken();
57031
+ if (!token) return null;
57032
+ const payload = this.verifyAndDecode(token);
57033
+ if (!payload) return null;
57034
+ this.cache = { payload, validatedAt: Date.now() };
57035
+ return payload;
57036
+ }
57037
+ /** Check if a specific feature is licensed */
57038
+ hasFeature(feature) {
57039
+ if (!this.cache) return false;
57040
+ return this.cache.payload.features.includes(feature);
57041
+ }
57042
+ /** Check if license is valid (with grace period) */
57043
+ isValid() {
57044
+ if (!this.cache) return false;
57045
+ const now = Date.now();
57046
+ const expiryMs = this.cache.payload.exp * 1e3;
57047
+ return now < expiryMs + _LicenseValidator.GRACE_PERIOD;
57048
+ }
57049
+ /** Check if the license is within its grace period (expired but still valid) */
57050
+ isInGracePeriod() {
57051
+ if (!this.cache) return false;
57052
+ const now = Date.now();
57053
+ const expiryMs = this.cache.payload.exp * 1e3;
57054
+ return now >= expiryMs && now < expiryMs + _LicenseValidator.GRACE_PERIOD;
57055
+ }
57056
+ resolveToken() {
57057
+ if (process.env.VISOR_LICENSE) {
57058
+ return process.env.VISOR_LICENSE.trim();
57059
+ }
57060
+ if (process.env.VISOR_LICENSE_FILE) {
57061
+ const resolved = path26.resolve(process.env.VISOR_LICENSE_FILE);
57062
+ const home2 = process.env.HOME || process.env.USERPROFILE || "";
57063
+ const allowedPrefixes = [path26.normalize(process.cwd())];
57064
+ if (home2) allowedPrefixes.push(path26.normalize(path26.join(home2, ".config", "visor")));
57065
+ let realPath;
57066
+ try {
57067
+ realPath = fs21.realpathSync(resolved);
57068
+ } catch {
57069
+ return null;
57070
+ }
57071
+ const isSafe = allowedPrefixes.some(
57072
+ (prefix) => realPath === prefix || realPath.startsWith(prefix + path26.sep)
57073
+ );
57074
+ if (!isSafe) return null;
57075
+ return this.readFile(realPath);
57076
+ }
57077
+ const cwdPath = path26.join(process.cwd(), ".visor-license");
57078
+ const cwdToken = this.readFile(cwdPath);
57079
+ if (cwdToken) return cwdToken;
57080
+ const home = process.env.HOME || process.env.USERPROFILE || "";
57081
+ if (home) {
57082
+ const configPath = path26.join(home, ".config", "visor", ".visor-license");
57083
+ const configToken = this.readFile(configPath);
57084
+ if (configToken) return configToken;
57085
+ }
57086
+ return null;
57087
+ }
57088
+ readFile(filePath) {
57089
+ try {
57090
+ return fs21.readFileSync(filePath, "utf-8").trim();
57091
+ } catch {
57092
+ return null;
57093
+ }
57094
+ }
57095
+ verifyAndDecode(token) {
57096
+ try {
57097
+ const parts = token.split(".");
57098
+ if (parts.length !== 3) return null;
57099
+ const [headerB64, payloadB64, signatureB64] = parts;
57100
+ const header = JSON.parse(Buffer.from(headerB64, "base64url").toString());
57101
+ if (header.alg !== "EdDSA") return null;
57102
+ const data = `${headerB64}.${payloadB64}`;
57103
+ const signature = Buffer.from(signatureB64, "base64url");
57104
+ const publicKey = crypto3.createPublicKey(_LicenseValidator.PUBLIC_KEY);
57105
+ if (publicKey.asymmetricKeyType !== "ed25519") {
57106
+ return null;
57107
+ }
57108
+ const isValid = crypto3.verify(null, Buffer.from(data), publicKey, signature);
57109
+ if (!isValid) return null;
57110
+ const payload = JSON.parse(Buffer.from(payloadB64, "base64url").toString());
57111
+ if (!payload.org || !Array.isArray(payload.features) || typeof payload.exp !== "number" || typeof payload.iat !== "number" || !payload.sub) {
57112
+ return null;
57113
+ }
57114
+ const now = Date.now();
57115
+ const expiryMs = payload.exp * 1e3;
57116
+ if (now >= expiryMs + _LicenseValidator.GRACE_PERIOD) {
57117
+ return null;
57118
+ }
57119
+ return payload;
57120
+ } catch {
57121
+ return null;
57122
+ }
57123
+ }
57124
+ };
57125
+ }
57126
+ });
57127
+
57128
+ // src/enterprise/policy/opa-compiler.ts
57129
+ var fs22, path27, os2, crypto4, import_child_process8, OpaCompiler;
57130
+ var init_opa_compiler = __esm({
57131
+ "src/enterprise/policy/opa-compiler.ts"() {
57132
+ "use strict";
57133
+ fs22 = __toESM(require("fs"));
57134
+ path27 = __toESM(require("path"));
57135
+ os2 = __toESM(require("os"));
57136
+ crypto4 = __toESM(require("crypto"));
57137
+ import_child_process8 = require("child_process");
57138
+ OpaCompiler = class _OpaCompiler {
57139
+ static CACHE_DIR = path27.join(os2.tmpdir(), "visor-opa-cache");
57140
+ /**
57141
+ * Resolve the input paths to WASM bytes.
57142
+ *
57143
+ * Strategy:
57144
+ * 1. If any path is a .wasm file, read it directly
57145
+ * 2. If a directory contains policy.wasm, read it
57146
+ * 3. Otherwise, collect all .rego files and auto-compile via `opa build`
57147
+ */
57148
+ async resolveWasmBytes(paths) {
57149
+ const regoFiles = [];
57150
+ for (const p of paths) {
57151
+ const resolved = path27.resolve(p);
57152
+ if (path27.normalize(resolved).includes("..")) {
57153
+ throw new Error(`Policy path contains traversal sequences: ${p}`);
57154
+ }
57155
+ if (resolved.endsWith(".wasm") && fs22.existsSync(resolved)) {
57156
+ return fs22.readFileSync(resolved);
57157
+ }
57158
+ if (!fs22.existsSync(resolved)) continue;
57159
+ const stat2 = fs22.statSync(resolved);
57160
+ if (stat2.isDirectory()) {
57161
+ const wasmCandidate = path27.join(resolved, "policy.wasm");
57162
+ if (fs22.existsSync(wasmCandidate)) {
57163
+ return fs22.readFileSync(wasmCandidate);
57164
+ }
57165
+ const files = fs22.readdirSync(resolved);
57166
+ for (const f of files) {
57167
+ if (f.endsWith(".rego")) {
57168
+ regoFiles.push(path27.join(resolved, f));
57169
+ }
57170
+ }
57171
+ } else if (resolved.endsWith(".rego")) {
57172
+ regoFiles.push(resolved);
57173
+ }
57174
+ }
57175
+ if (regoFiles.length === 0) {
57176
+ throw new Error(
57177
+ `OPA WASM evaluator: no .wasm bundle or .rego files found in: ${paths.join(", ")}`
57178
+ );
57179
+ }
57180
+ return this.compileRego(regoFiles);
57181
+ }
57182
+ /**
57183
+ * Auto-compile .rego files to a WASM bundle using the `opa` CLI.
57184
+ *
57185
+ * Caches the compiled bundle based on a content hash of all input .rego files
57186
+ * so subsequent runs skip compilation if policies haven't changed.
57187
+ */
57188
+ compileRego(regoFiles) {
57189
+ try {
57190
+ (0, import_child_process8.execFileSync)("opa", ["version"], { stdio: "pipe" });
57191
+ } catch {
57192
+ throw new Error(
57193
+ "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(" ")
57194
+ );
57195
+ }
57196
+ const hash = crypto4.createHash("sha256");
57197
+ for (const f of regoFiles.sort()) {
57198
+ hash.update(fs22.readFileSync(f));
57199
+ hash.update(f);
57200
+ }
57201
+ const cacheKey = hash.digest("hex").slice(0, 16);
57202
+ const cacheDir = _OpaCompiler.CACHE_DIR;
57203
+ const cachedWasm = path27.join(cacheDir, `${cacheKey}.wasm`);
57204
+ if (fs22.existsSync(cachedWasm)) {
57205
+ return fs22.readFileSync(cachedWasm);
57206
+ }
57207
+ fs22.mkdirSync(cacheDir, { recursive: true });
57208
+ const bundleTar = path27.join(cacheDir, `${cacheKey}-bundle.tar.gz`);
57209
+ try {
57210
+ const args = [
57211
+ "build",
57212
+ "-t",
57213
+ "wasm",
57214
+ "-e",
57215
+ "visor",
57216
+ // entrypoint: the visor package tree
57217
+ "-o",
57218
+ bundleTar,
57219
+ ...regoFiles
57220
+ ];
57221
+ (0, import_child_process8.execFileSync)("opa", args, {
57222
+ stdio: "pipe",
57223
+ timeout: 3e4
57224
+ });
57225
+ } catch (err) {
57226
+ const stderr = err?.stderr?.toString() || "";
57227
+ throw new Error(
57228
+ `Failed to compile .rego files to WASM:
57229
+ ${stderr}
57230
+ Ensure your .rego files are valid and the \`opa\` CLI is installed.`
57231
+ );
57232
+ }
57233
+ try {
57234
+ (0, import_child_process8.execFileSync)("tar", ["-xzf", bundleTar, "-C", cacheDir, "/policy.wasm"], {
57235
+ stdio: "pipe"
57236
+ });
57237
+ const extractedWasm = path27.join(cacheDir, "policy.wasm");
57238
+ if (fs22.existsSync(extractedWasm)) {
57239
+ fs22.renameSync(extractedWasm, cachedWasm);
57240
+ }
57241
+ } catch {
57242
+ try {
57243
+ (0, import_child_process8.execFileSync)("tar", ["-xzf", bundleTar, "-C", cacheDir, "policy.wasm"], {
57244
+ stdio: "pipe"
57245
+ });
57246
+ const extractedWasm = path27.join(cacheDir, "policy.wasm");
57247
+ if (fs22.existsSync(extractedWasm)) {
57248
+ fs22.renameSync(extractedWasm, cachedWasm);
57249
+ }
57250
+ } catch (err2) {
57251
+ throw new Error(`Failed to extract policy.wasm from OPA bundle: ${err2?.message || err2}`);
57252
+ }
57253
+ }
57254
+ try {
57255
+ fs22.unlinkSync(bundleTar);
57256
+ } catch {
57257
+ }
57258
+ if (!fs22.existsSync(cachedWasm)) {
57259
+ throw new Error("OPA build succeeded but policy.wasm was not found in the bundle");
57260
+ }
57261
+ return fs22.readFileSync(cachedWasm);
57262
+ }
57263
+ };
57264
+ }
57265
+ });
57266
+
57267
+ // src/enterprise/policy/opa-wasm-evaluator.ts
57268
+ var fs23, path28, OpaWasmEvaluator;
57269
+ var init_opa_wasm_evaluator = __esm({
57270
+ "src/enterprise/policy/opa-wasm-evaluator.ts"() {
57271
+ "use strict";
57272
+ fs23 = __toESM(require("fs"));
57273
+ path28 = __toESM(require("path"));
57274
+ init_opa_compiler();
57275
+ OpaWasmEvaluator = class {
57276
+ policy = null;
57277
+ dataDocument = {};
57278
+ compiler = new OpaCompiler();
57279
+ async initialize(rulesPath) {
57280
+ const paths = Array.isArray(rulesPath) ? rulesPath : [rulesPath];
57281
+ const wasmBytes = await this.compiler.resolveWasmBytes(paths);
57282
+ try {
57283
+ const { createRequire } = require("module");
57284
+ const runtimeRequire = createRequire(__filename);
57285
+ const opaWasm = runtimeRequire("@open-policy-agent/opa-wasm");
57286
+ const loadPolicy = opaWasm.loadPolicy || opaWasm.default?.loadPolicy;
57287
+ if (!loadPolicy) {
57288
+ throw new Error("loadPolicy not found in @open-policy-agent/opa-wasm");
57289
+ }
57290
+ this.policy = await loadPolicy(wasmBytes);
57291
+ } catch (err) {
57292
+ if (err?.code === "MODULE_NOT_FOUND" || err?.code === "ERR_MODULE_NOT_FOUND") {
57293
+ throw new Error(
57294
+ "OPA WASM evaluator requires @open-policy-agent/opa-wasm. Install it with: npm install @open-policy-agent/opa-wasm"
57295
+ );
57296
+ }
57297
+ throw err;
57298
+ }
57299
+ }
57300
+ /**
57301
+ * Load external data from a JSON file to use as the OPA data document.
57302
+ * The loaded data will be passed to `policy.setData()` during evaluation,
57303
+ * making it available in Rego via `data.<key>`.
57304
+ */
57305
+ loadData(dataPath) {
57306
+ const resolved = path28.resolve(dataPath);
57307
+ if (path28.normalize(resolved).includes("..")) {
57308
+ throw new Error(`Data path contains traversal sequences: ${dataPath}`);
57309
+ }
57310
+ if (!fs23.existsSync(resolved)) {
57311
+ throw new Error(`OPA data file not found: ${resolved}`);
57312
+ }
57313
+ const stat2 = fs23.statSync(resolved);
57314
+ if (stat2.size > 10 * 1024 * 1024) {
57315
+ throw new Error(`OPA data file exceeds 10MB limit: ${resolved} (${stat2.size} bytes)`);
57316
+ }
57317
+ const raw = fs23.readFileSync(resolved, "utf-8");
57318
+ try {
57319
+ const parsed = JSON.parse(raw);
57320
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
57321
+ throw new Error("OPA data file must contain a JSON object (not an array or primitive)");
57322
+ }
57323
+ this.dataDocument = parsed;
57324
+ } catch (err) {
57325
+ if (err.message.startsWith("OPA data file must")) {
57326
+ throw err;
57327
+ }
57328
+ throw new Error(`Failed to parse OPA data file ${resolved}: ${err.message}`);
57329
+ }
57330
+ }
57331
+ async evaluate(input) {
57332
+ if (!this.policy) {
57333
+ throw new Error("OPA WASM evaluator not initialized");
57334
+ }
57335
+ this.policy.setData(this.dataDocument);
57336
+ const resultSet = this.policy.evaluate(input);
57337
+ if (Array.isArray(resultSet) && resultSet.length > 0) {
57338
+ return resultSet[0].result;
57339
+ }
57340
+ return void 0;
57341
+ }
57342
+ async shutdown() {
57343
+ if (this.policy) {
57344
+ if (typeof this.policy.close === "function") {
57345
+ try {
57346
+ this.policy.close();
57347
+ } catch {
57348
+ }
57349
+ } else if (typeof this.policy.free === "function") {
57350
+ try {
57351
+ this.policy.free();
57352
+ } catch {
57353
+ }
57354
+ }
57355
+ }
57356
+ this.policy = null;
57357
+ }
57358
+ };
57359
+ }
57360
+ });
57361
+
57362
+ // src/enterprise/policy/opa-http-evaluator.ts
57363
+ var OpaHttpEvaluator;
57364
+ var init_opa_http_evaluator = __esm({
57365
+ "src/enterprise/policy/opa-http-evaluator.ts"() {
57366
+ "use strict";
57367
+ OpaHttpEvaluator = class {
57368
+ baseUrl;
57369
+ timeout;
57370
+ constructor(baseUrl, timeout = 5e3) {
57371
+ let parsed;
57372
+ try {
57373
+ parsed = new URL(baseUrl);
57374
+ } catch {
57375
+ throw new Error(`OPA HTTP evaluator: invalid URL: ${baseUrl}`);
57376
+ }
57377
+ if (!["http:", "https:"].includes(parsed.protocol)) {
57378
+ throw new Error(
57379
+ `OPA HTTP evaluator: url must use http:// or https:// protocol, got: ${baseUrl}`
57380
+ );
57381
+ }
57382
+ const hostname = parsed.hostname;
57383
+ if (this.isBlockedHostname(hostname)) {
57384
+ throw new Error(
57385
+ `OPA HTTP evaluator: url must not point to internal, loopback, or private network addresses`
57386
+ );
57387
+ }
57388
+ this.baseUrl = baseUrl.replace(/\/+$/, "");
57389
+ this.timeout = timeout;
57390
+ }
57391
+ /**
57392
+ * Check if a hostname is blocked due to SSRF concerns.
57393
+ *
57394
+ * Blocks:
57395
+ * - Loopback addresses (127.x.x.x, localhost, 0.0.0.0, ::1)
57396
+ * - Link-local addresses (169.254.x.x)
57397
+ * - Private networks (10.x.x.x, 172.16-31.x.x, 192.168.x.x)
57398
+ * - IPv6 unique local addresses (fd00::/8)
57399
+ * - Cloud metadata services (*.internal)
57400
+ */
57401
+ isBlockedHostname(hostname) {
57402
+ if (!hostname) return true;
57403
+ const normalized = hostname.toLowerCase().replace(/^\[|\]$/g, "");
57404
+ if (normalized === "metadata.google.internal" || normalized.endsWith(".internal")) {
57405
+ return true;
57406
+ }
57407
+ if (normalized === "localhost" || normalized === "localhost.localdomain") {
57408
+ return true;
57409
+ }
57410
+ if (normalized === "::1" || normalized === "0:0:0:0:0:0:0:1") {
57411
+ return true;
57412
+ }
57413
+ const ipv4Pattern = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/;
57414
+ const ipv4Match = normalized.match(ipv4Pattern);
57415
+ if (ipv4Match) {
57416
+ const octets = ipv4Match.slice(1, 5).map(Number);
57417
+ if (octets.some((octet) => octet > 255)) {
57418
+ return false;
57419
+ }
57420
+ const [a, b] = octets;
57421
+ if (a === 127) {
57422
+ return true;
57423
+ }
57424
+ if (a === 0) {
57425
+ return true;
57426
+ }
57427
+ if (a === 169 && b === 254) {
57428
+ return true;
57429
+ }
57430
+ if (a === 10) {
57431
+ return true;
57432
+ }
57433
+ if (a === 172 && b >= 16 && b <= 31) {
57434
+ return true;
57435
+ }
57436
+ if (a === 192 && b === 168) {
57437
+ return true;
57438
+ }
57439
+ }
57440
+ if (normalized.startsWith("fd") || normalized.startsWith("fc")) {
57441
+ return true;
57442
+ }
57443
+ if (normalized.startsWith("fe80:")) {
57444
+ return true;
57445
+ }
57446
+ return false;
57447
+ }
57448
+ /**
57449
+ * Evaluate a policy rule against an input document via OPA REST API.
57450
+ *
57451
+ * @param input - The input document to evaluate
57452
+ * @param rulePath - OPA rule path (e.g., 'visor/check/execute')
57453
+ * @returns The result object from OPA, or undefined on error
57454
+ */
57455
+ async evaluate(input, rulePath) {
57456
+ const encodedPath = rulePath.split("/").map((s) => encodeURIComponent(s)).join("/");
57457
+ const url = `${this.baseUrl}/v1/data/${encodedPath}`;
57458
+ const controller = new AbortController();
57459
+ const timer = setTimeout(() => controller.abort(), this.timeout);
57460
+ try {
57461
+ const response = await fetch(url, {
57462
+ method: "POST",
57463
+ headers: { "Content-Type": "application/json" },
57464
+ body: JSON.stringify({ input }),
57465
+ signal: controller.signal
57466
+ });
57467
+ if (!response.ok) {
57468
+ throw new Error(`OPA HTTP ${response.status}: ${response.statusText}`);
57469
+ }
57470
+ let body;
57471
+ try {
57472
+ body = await response.json();
57473
+ } catch (jsonErr) {
57474
+ throw new Error(
57475
+ `OPA HTTP evaluator: failed to parse JSON response: ${jsonErr instanceof Error ? jsonErr.message : String(jsonErr)}`
57476
+ );
57477
+ }
57478
+ return body?.result;
57479
+ } finally {
57480
+ clearTimeout(timer);
57481
+ }
57482
+ }
57483
+ async shutdown() {
57484
+ }
57485
+ };
57486
+ }
57487
+ });
57488
+
57489
+ // src/enterprise/policy/policy-input-builder.ts
57490
+ var PolicyInputBuilder;
57491
+ var init_policy_input_builder = __esm({
57492
+ "src/enterprise/policy/policy-input-builder.ts"() {
57493
+ "use strict";
57494
+ PolicyInputBuilder = class {
57495
+ roles;
57496
+ actor;
57497
+ repository;
57498
+ pullRequest;
57499
+ constructor(policyConfig, actor, repository, pullRequest) {
57500
+ this.roles = policyConfig.roles || {};
57501
+ this.actor = actor;
57502
+ this.repository = repository;
57503
+ this.pullRequest = pullRequest;
57504
+ }
57505
+ /** Resolve which roles apply to the current actor. */
57506
+ resolveRoles() {
57507
+ const matched = [];
57508
+ for (const [roleName, roleConfig] of Object.entries(this.roles)) {
57509
+ let identityMatch = false;
57510
+ if (roleConfig.author_association && this.actor.authorAssociation && roleConfig.author_association.includes(this.actor.authorAssociation)) {
57511
+ identityMatch = true;
57512
+ }
57513
+ if (!identityMatch && roleConfig.users && this.actor.login && roleConfig.users.includes(this.actor.login)) {
57514
+ identityMatch = true;
57515
+ }
57516
+ if (!identityMatch && roleConfig.slack_users && this.actor.slack?.userId && roleConfig.slack_users.includes(this.actor.slack.userId)) {
57517
+ identityMatch = true;
57518
+ }
57519
+ if (!identityMatch && roleConfig.emails && this.actor.slack?.email) {
57520
+ const actorEmail = this.actor.slack.email.toLowerCase();
57521
+ if (roleConfig.emails.some((e) => e.toLowerCase() === actorEmail)) {
57522
+ identityMatch = true;
57523
+ }
57524
+ }
57525
+ if (!identityMatch) continue;
57526
+ if (roleConfig.slack_channels && roleConfig.slack_channels.length > 0) {
57527
+ if (!this.actor.slack?.channelId || !roleConfig.slack_channels.includes(this.actor.slack.channelId)) {
57528
+ continue;
57529
+ }
57530
+ }
57531
+ matched.push(roleName);
57532
+ }
57533
+ return matched;
57534
+ }
57535
+ buildActor() {
57536
+ return {
57537
+ authorAssociation: this.actor.authorAssociation,
57538
+ login: this.actor.login,
57539
+ roles: this.resolveRoles(),
57540
+ isLocalMode: this.actor.isLocalMode,
57541
+ ...this.actor.slack && { slack: this.actor.slack }
57542
+ };
57543
+ }
57544
+ forCheckExecution(check) {
57545
+ return {
57546
+ scope: "check.execute",
57547
+ check: {
57548
+ id: check.id,
57549
+ type: check.type,
57550
+ group: check.group,
57551
+ tags: check.tags,
57552
+ criticality: check.criticality,
57553
+ sandbox: check.sandbox,
57554
+ policy: check.policy
57555
+ },
57556
+ actor: this.buildActor(),
57557
+ repository: this.repository,
57558
+ pullRequest: this.pullRequest
57559
+ };
57560
+ }
57561
+ forToolInvocation(serverName, methodName, transport) {
57562
+ return {
57563
+ scope: "tool.invoke",
57564
+ tool: { serverName, methodName, transport },
57565
+ actor: this.buildActor(),
57566
+ repository: this.repository,
57567
+ pullRequest: this.pullRequest
57568
+ };
57569
+ }
57570
+ forCapabilityResolve(checkId, capabilities) {
57571
+ return {
57572
+ scope: "capability.resolve",
57573
+ check: { id: checkId, type: "ai" },
57574
+ capability: capabilities,
57575
+ actor: this.buildActor(),
57576
+ repository: this.repository,
57577
+ pullRequest: this.pullRequest
57578
+ };
57579
+ }
57580
+ };
57581
+ }
57582
+ });
57583
+
57584
+ // src/enterprise/policy/opa-policy-engine.ts
57585
+ var opa_policy_engine_exports = {};
57586
+ __export(opa_policy_engine_exports, {
57587
+ OpaPolicyEngine: () => OpaPolicyEngine
57588
+ });
57589
+ var OpaPolicyEngine;
57590
+ var init_opa_policy_engine = __esm({
57591
+ "src/enterprise/policy/opa-policy-engine.ts"() {
57592
+ "use strict";
57593
+ init_opa_wasm_evaluator();
57594
+ init_opa_http_evaluator();
57595
+ init_policy_input_builder();
57596
+ OpaPolicyEngine = class {
57597
+ evaluator = null;
57598
+ fallback;
57599
+ timeout;
57600
+ config;
57601
+ inputBuilder = null;
57602
+ logger = null;
57603
+ constructor(config) {
57604
+ this.config = config;
57605
+ this.fallback = config.fallback || "deny";
57606
+ this.timeout = config.timeout || 5e3;
57607
+ }
57608
+ async initialize(config) {
57609
+ try {
57610
+ this.logger = (init_logger(), __toCommonJS(logger_exports)).logger;
57611
+ } catch {
57612
+ }
57613
+ const actor = {
57614
+ authorAssociation: process.env.VISOR_AUTHOR_ASSOCIATION,
57615
+ login: process.env.VISOR_AUTHOR_LOGIN || process.env.GITHUB_ACTOR,
57616
+ isLocalMode: !process.env.GITHUB_ACTIONS
57617
+ };
57618
+ const repo = {
57619
+ owner: process.env.GITHUB_REPOSITORY_OWNER,
57620
+ name: process.env.GITHUB_REPOSITORY?.split("/")[1],
57621
+ branch: process.env.GITHUB_HEAD_REF,
57622
+ baseBranch: process.env.GITHUB_BASE_REF,
57623
+ event: process.env.GITHUB_EVENT_NAME
57624
+ };
57625
+ const prNum = process.env.GITHUB_PR_NUMBER ? parseInt(process.env.GITHUB_PR_NUMBER, 10) : void 0;
57626
+ const pullRequest = {
57627
+ number: prNum !== void 0 && Number.isFinite(prNum) ? prNum : void 0
57628
+ };
57629
+ this.inputBuilder = new PolicyInputBuilder(config, actor, repo, pullRequest);
57630
+ if (config.engine === "local") {
57631
+ if (!config.rules) {
57632
+ throw new Error("OPA local mode requires `policy.rules` path to .wasm or .rego files");
57633
+ }
57634
+ const wasm = new OpaWasmEvaluator();
57635
+ await wasm.initialize(config.rules);
57636
+ if (config.data) {
57637
+ wasm.loadData(config.data);
57638
+ }
57639
+ this.evaluator = wasm;
57640
+ } else if (config.engine === "remote") {
57641
+ if (!config.url) {
57642
+ throw new Error("OPA remote mode requires `policy.url` pointing to OPA server");
57643
+ }
57644
+ this.evaluator = new OpaHttpEvaluator(config.url, this.timeout);
57645
+ } else {
57646
+ this.evaluator = null;
57647
+ }
57648
+ }
57649
+ /**
57650
+ * Update actor/repo/PR context (e.g., after PR info becomes available).
57651
+ * Called by the enterprise loader when engine context is enriched.
57652
+ */
57653
+ setActorContext(actor, repo, pullRequest) {
57654
+ this.inputBuilder = new PolicyInputBuilder(this.config, actor, repo, pullRequest);
57655
+ }
57656
+ async evaluateCheckExecution(checkId, checkConfig) {
57657
+ if (!this.evaluator || !this.inputBuilder) return { allowed: true };
57658
+ const cfg = checkConfig && typeof checkConfig === "object" ? checkConfig : {};
57659
+ const policyOverride = cfg.policy;
57660
+ const input = this.inputBuilder.forCheckExecution({
57661
+ id: checkId,
57662
+ type: cfg.type || "ai",
57663
+ group: cfg.group,
57664
+ tags: cfg.tags,
57665
+ criticality: cfg.criticality,
57666
+ sandbox: cfg.sandbox,
57667
+ policy: policyOverride
57668
+ });
57669
+ return this.doEvaluate(input, this.resolveRulePath("check.execute", policyOverride?.rule));
57670
+ }
57671
+ async evaluateToolInvocation(serverName, methodName, transport) {
57672
+ if (!this.evaluator || !this.inputBuilder) return { allowed: true };
57673
+ const input = this.inputBuilder.forToolInvocation(serverName, methodName, transport);
57674
+ return this.doEvaluate(input, "visor/tool/invoke");
57675
+ }
57676
+ async evaluateCapabilities(checkId, capabilities) {
57677
+ if (!this.evaluator || !this.inputBuilder) return { allowed: true };
57678
+ const input = this.inputBuilder.forCapabilityResolve(checkId, capabilities);
57679
+ return this.doEvaluate(input, "visor/capability/resolve");
57680
+ }
57681
+ async shutdown() {
57682
+ if (this.evaluator && "shutdown" in this.evaluator) {
57683
+ await this.evaluator.shutdown();
57684
+ }
57685
+ this.evaluator = null;
57686
+ this.inputBuilder = null;
57687
+ }
57688
+ resolveRulePath(defaultScope, override) {
57689
+ if (override) {
57690
+ return override.startsWith("visor/") ? override : `visor/${override}`;
57691
+ }
57692
+ return `visor/${defaultScope.replace(/\./g, "/")}`;
57693
+ }
57694
+ async doEvaluate(input, rulePath) {
57695
+ try {
57696
+ this.logger?.debug(`[PolicyEngine] Evaluating ${rulePath}`, JSON.stringify(input));
57697
+ let timer;
57698
+ const timeoutPromise = new Promise((_resolve, reject) => {
57699
+ timer = setTimeout(() => reject(new Error("policy evaluation timeout")), this.timeout);
57700
+ });
57701
+ try {
57702
+ const result = await Promise.race([this.rawEvaluate(input, rulePath), timeoutPromise]);
57703
+ const decision = this.parseDecision(result);
57704
+ if (!decision.allowed && this.fallback === "warn") {
57705
+ decision.allowed = true;
57706
+ decision.warn = true;
57707
+ decision.reason = `audit: ${decision.reason || "policy denied"}`;
57708
+ }
57709
+ this.logger?.debug(
57710
+ `[PolicyEngine] Decision for ${rulePath}: allowed=${decision.allowed}, warn=${decision.warn || false}, reason=${decision.reason || "none"}`
57711
+ );
57712
+ return decision;
57713
+ } finally {
57714
+ if (timer) clearTimeout(timer);
57715
+ }
57716
+ } catch (err) {
57717
+ const msg = err instanceof Error ? err.message : String(err);
57718
+ this.logger?.warn(`[PolicyEngine] Evaluation failed for ${rulePath}: ${msg}`);
57719
+ return {
57720
+ allowed: this.fallback === "allow" || this.fallback === "warn",
57721
+ warn: this.fallback === "warn" ? true : void 0,
57722
+ reason: `policy evaluation failed, fallback=${this.fallback}`
57723
+ };
57724
+ }
57725
+ }
57726
+ async rawEvaluate(input, rulePath) {
57727
+ if (this.evaluator instanceof OpaWasmEvaluator) {
57728
+ const result = await this.evaluator.evaluate(input);
57729
+ return this.navigateWasmResult(result, rulePath);
57730
+ }
57731
+ return this.evaluator.evaluate(input, rulePath);
57732
+ }
57733
+ /**
57734
+ * Navigate nested OPA WASM result tree to reach the specific rule's output.
57735
+ * The WASM entrypoint `-e visor` means the result root IS the visor package,
57736
+ * so we strip the `visor/` prefix and walk the remaining segments.
57737
+ */
57738
+ navigateWasmResult(result, rulePath) {
57739
+ if (!result || typeof result !== "object") return result;
57740
+ const segments = rulePath.replace(/^visor\//, "").split("/");
57741
+ let current = result;
57742
+ for (const seg of segments) {
57743
+ if (current && typeof current === "object" && seg in current) {
57744
+ current = current[seg];
57745
+ } else {
57746
+ return void 0;
57747
+ }
57748
+ }
57749
+ return current;
57750
+ }
57751
+ parseDecision(result) {
57752
+ if (result === void 0 || result === null) {
57753
+ return {
57754
+ allowed: this.fallback === "allow" || this.fallback === "warn",
57755
+ warn: this.fallback === "warn" ? true : void 0,
57756
+ reason: this.fallback === "warn" ? "audit: no policy result" : "no policy result"
57757
+ };
57758
+ }
57759
+ const allowed = result.allowed !== false;
57760
+ const decision = {
57761
+ allowed,
57762
+ reason: result.reason
57763
+ };
57764
+ if (result.capabilities) {
57765
+ decision.capabilities = result.capabilities;
57766
+ }
57767
+ return decision;
57768
+ }
57769
+ };
57770
+ }
57771
+ });
57772
+
57773
+ // src/enterprise/scheduler/knex-store.ts
57774
+ var knex_store_exports = {};
57775
+ __export(knex_store_exports, {
57776
+ KnexStoreBackend: () => KnexStoreBackend
57777
+ });
57778
+ function toNum(val) {
57779
+ if (val === null || val === void 0) return void 0;
57780
+ return typeof val === "string" ? parseInt(val, 10) : val;
57781
+ }
57782
+ function safeJsonParse2(value) {
57783
+ if (!value) return void 0;
57784
+ try {
57785
+ return JSON.parse(value);
57786
+ } catch {
57787
+ return void 0;
57788
+ }
57789
+ }
57790
+ function fromTriggerRow2(row) {
57791
+ return {
57792
+ id: row.id,
57793
+ creatorId: row.creator_id,
57794
+ creatorContext: row.creator_context ?? void 0,
57795
+ creatorName: row.creator_name ?? void 0,
57796
+ description: row.description ?? void 0,
57797
+ channels: safeJsonParse2(row.channels),
57798
+ fromUsers: safeJsonParse2(row.from_users),
57799
+ fromBots: row.from_bots === true || row.from_bots === 1,
57800
+ contains: safeJsonParse2(row.contains),
57801
+ matchPattern: row.match_pattern ?? void 0,
57802
+ threads: row.threads,
57803
+ workflow: row.workflow,
57804
+ inputs: safeJsonParse2(row.inputs),
57805
+ outputContext: safeJsonParse2(row.output_context),
57806
+ status: row.status,
57807
+ enabled: row.enabled === true || row.enabled === 1,
57808
+ createdAt: toNum(row.created_at)
57809
+ };
57810
+ }
57811
+ function toTriggerInsertRow(trigger) {
57812
+ return {
57813
+ id: trigger.id,
57814
+ creator_id: trigger.creatorId,
57815
+ creator_context: trigger.creatorContext ?? null,
57816
+ creator_name: trigger.creatorName ?? null,
57817
+ description: trigger.description ?? null,
57818
+ channels: trigger.channels ? JSON.stringify(trigger.channels) : null,
57819
+ from_users: trigger.fromUsers ? JSON.stringify(trigger.fromUsers) : null,
57820
+ from_bots: trigger.fromBots,
57821
+ contains: trigger.contains ? JSON.stringify(trigger.contains) : null,
57822
+ match_pattern: trigger.matchPattern ?? null,
57823
+ threads: trigger.threads,
57824
+ workflow: trigger.workflow,
57825
+ inputs: trigger.inputs ? JSON.stringify(trigger.inputs) : null,
57826
+ output_context: trigger.outputContext ? JSON.stringify(trigger.outputContext) : null,
57827
+ status: trigger.status,
57828
+ enabled: trigger.enabled,
57829
+ created_at: trigger.createdAt
57830
+ };
57831
+ }
57832
+ function fromDbRow2(row) {
57833
+ return {
57834
+ id: row.id,
57835
+ creatorId: row.creator_id,
57836
+ creatorContext: row.creator_context ?? void 0,
57837
+ creatorName: row.creator_name ?? void 0,
57838
+ timezone: row.timezone,
57839
+ schedule: row.schedule_expr,
57840
+ runAt: toNum(row.run_at),
57841
+ isRecurring: row.is_recurring === true || row.is_recurring === 1,
57842
+ originalExpression: row.original_expression,
57843
+ workflow: row.workflow ?? void 0,
57844
+ workflowInputs: safeJsonParse2(row.workflow_inputs),
57845
+ outputContext: safeJsonParse2(row.output_context),
57846
+ status: row.status,
57847
+ createdAt: toNum(row.created_at),
57848
+ lastRunAt: toNum(row.last_run_at),
57849
+ nextRunAt: toNum(row.next_run_at),
57850
+ runCount: row.run_count,
57851
+ failureCount: row.failure_count,
57852
+ lastError: row.last_error ?? void 0,
57853
+ previousResponse: row.previous_response ?? void 0
57854
+ };
57855
+ }
57856
+ function toInsertRow(schedule) {
57857
+ return {
57858
+ id: schedule.id,
57859
+ creator_id: schedule.creatorId,
57860
+ creator_context: schedule.creatorContext ?? null,
57861
+ creator_name: schedule.creatorName ?? null,
57862
+ timezone: schedule.timezone,
57863
+ schedule_expr: schedule.schedule,
57864
+ run_at: schedule.runAt ?? null,
57865
+ is_recurring: schedule.isRecurring,
57866
+ original_expression: schedule.originalExpression,
57867
+ workflow: schedule.workflow ?? null,
57868
+ workflow_inputs: schedule.workflowInputs ? JSON.stringify(schedule.workflowInputs) : null,
57869
+ output_context: schedule.outputContext ? JSON.stringify(schedule.outputContext) : null,
57870
+ status: schedule.status,
57871
+ created_at: schedule.createdAt,
57872
+ last_run_at: schedule.lastRunAt ?? null,
57873
+ next_run_at: schedule.nextRunAt ?? null,
57874
+ run_count: schedule.runCount,
57875
+ failure_count: schedule.failureCount,
57876
+ last_error: schedule.lastError ?? null,
57877
+ previous_response: schedule.previousResponse ?? null
57878
+ };
57879
+ }
57880
+ var fs24, path29, import_uuid2, KnexStoreBackend;
57881
+ var init_knex_store = __esm({
57882
+ "src/enterprise/scheduler/knex-store.ts"() {
57883
+ "use strict";
57884
+ fs24 = __toESM(require("fs"));
57885
+ path29 = __toESM(require("path"));
57886
+ import_uuid2 = require("uuid");
57887
+ init_logger();
57888
+ KnexStoreBackend = class {
57889
+ knex = null;
57890
+ driver;
57891
+ connection;
57892
+ constructor(driver, storageConfig, _haConfig) {
57893
+ this.driver = driver;
57894
+ this.connection = storageConfig.connection || {};
57895
+ }
57896
+ async initialize() {
57897
+ const { createRequire } = require("module");
57898
+ const runtimeRequire = createRequire(__filename);
57899
+ let knexFactory;
57900
+ try {
57901
+ knexFactory = runtimeRequire("knex");
57902
+ } catch (err) {
57903
+ const code = err?.code;
57904
+ if (code === "MODULE_NOT_FOUND" || code === "ERR_MODULE_NOT_FOUND") {
57905
+ throw new Error(
57906
+ "knex is required for PostgreSQL/MySQL/MSSQL schedule storage. Install it with: npm install knex"
57907
+ );
57908
+ }
57909
+ throw err;
57910
+ }
57911
+ const clientMap = {
57912
+ postgresql: "pg",
57913
+ mysql: "mysql2",
57914
+ mssql: "tedious"
57915
+ };
57916
+ const client = clientMap[this.driver];
57917
+ let connection;
57918
+ if (this.connection.connection_string) {
57919
+ connection = this.connection.connection_string;
57920
+ } else if (this.driver === "mssql") {
57921
+ connection = this.buildMssqlConnection();
57922
+ } else {
57923
+ connection = this.buildStandardConnection();
57924
+ }
57925
+ this.knex = knexFactory({
57926
+ client,
57927
+ connection,
57928
+ pool: {
57929
+ min: this.connection.pool?.min ?? 0,
57930
+ max: this.connection.pool?.max ?? 10
57931
+ }
57932
+ });
57933
+ await this.migrateSchema();
57934
+ logger.info(`[KnexStore] Initialized (${this.driver})`);
57935
+ }
57936
+ buildStandardConnection() {
57937
+ return {
57938
+ host: this.connection.host || "localhost",
57939
+ port: this.connection.port,
57940
+ database: this.connection.database || "visor",
57941
+ user: this.connection.user,
57942
+ password: this.connection.password,
57943
+ ssl: this.resolveSslConfig()
57944
+ };
57945
+ }
57946
+ buildMssqlConnection() {
57947
+ const ssl = this.connection.ssl;
57948
+ const sslEnabled = ssl === true || typeof ssl === "object" && ssl.enabled !== false;
57949
+ return {
57950
+ server: this.connection.host || "localhost",
57951
+ port: this.connection.port,
57952
+ database: this.connection.database || "visor",
57953
+ user: this.connection.user,
57954
+ password: this.connection.password,
57955
+ options: {
57956
+ encrypt: sslEnabled,
57957
+ trustServerCertificate: typeof ssl === "object" ? ssl.reject_unauthorized === false : !sslEnabled
57958
+ }
57959
+ };
57960
+ }
57961
+ resolveSslConfig() {
57962
+ const ssl = this.connection.ssl;
57963
+ if (ssl === false || ssl === void 0) return false;
57964
+ if (ssl === true) return { rejectUnauthorized: true };
57965
+ if (ssl.enabled === false) return false;
57966
+ const result = {
57967
+ rejectUnauthorized: ssl.reject_unauthorized !== false
57968
+ };
57969
+ if (ssl.ca) {
57970
+ const caPath = this.validateSslPath(ssl.ca, "CA certificate");
57971
+ result.ca = fs24.readFileSync(caPath, "utf8");
57972
+ }
57973
+ if (ssl.cert) {
57974
+ const certPath = this.validateSslPath(ssl.cert, "client certificate");
57975
+ result.cert = fs24.readFileSync(certPath, "utf8");
57976
+ }
57977
+ if (ssl.key) {
57978
+ const keyPath = this.validateSslPath(ssl.key, "client key");
57979
+ result.key = fs24.readFileSync(keyPath, "utf8");
57980
+ }
57981
+ return result;
57982
+ }
57983
+ validateSslPath(filePath, label) {
57984
+ const resolved = path29.resolve(filePath);
57985
+ if (resolved !== path29.normalize(resolved)) {
57986
+ throw new Error(`SSL ${label} path contains invalid sequences: ${filePath}`);
57987
+ }
57988
+ if (!fs24.existsSync(resolved)) {
57989
+ throw new Error(`SSL ${label} not found: ${filePath}`);
57990
+ }
57991
+ return resolved;
57992
+ }
57993
+ async shutdown() {
57994
+ if (this.knex) {
57995
+ await this.knex.destroy();
57996
+ this.knex = null;
57997
+ }
57998
+ }
57999
+ async migrateSchema() {
58000
+ const knex = this.getKnex();
58001
+ const exists = await knex.schema.hasTable("schedules");
58002
+ if (!exists) {
58003
+ await knex.schema.createTable("schedules", (table) => {
58004
+ table.string("id", 36).primary();
58005
+ table.string("creator_id", 255).notNullable().index();
58006
+ table.string("creator_context", 255);
58007
+ table.string("creator_name", 255);
58008
+ table.string("timezone", 64).notNullable().defaultTo("UTC");
58009
+ table.string("schedule_expr", 255);
58010
+ table.bigInteger("run_at");
58011
+ table.boolean("is_recurring").notNullable();
58012
+ table.text("original_expression");
58013
+ table.string("workflow", 255);
58014
+ table.text("workflow_inputs");
58015
+ table.text("output_context");
58016
+ table.string("status", 20).notNullable().index();
58017
+ table.bigInteger("created_at").notNullable();
58018
+ table.bigInteger("last_run_at");
58019
+ table.bigInteger("next_run_at");
58020
+ table.integer("run_count").notNullable().defaultTo(0);
58021
+ table.integer("failure_count").notNullable().defaultTo(0);
58022
+ table.text("last_error");
58023
+ table.text("previous_response");
58024
+ table.index(["status", "next_run_at"]);
58025
+ });
58026
+ }
58027
+ const triggersExist = await knex.schema.hasTable("message_triggers");
58028
+ if (!triggersExist) {
58029
+ await knex.schema.createTable("message_triggers", (table) => {
58030
+ table.string("id", 36).primary();
58031
+ table.string("creator_id", 255).notNullable().index();
58032
+ table.string("creator_context", 255);
58033
+ table.string("creator_name", 255);
58034
+ table.text("description");
58035
+ table.text("channels");
58036
+ table.text("from_users");
58037
+ table.boolean("from_bots").notNullable().defaultTo(false);
58038
+ table.text("contains");
58039
+ table.text("match_pattern");
58040
+ table.string("threads", 20).notNullable().defaultTo("any");
58041
+ table.string("workflow", 255).notNullable();
58042
+ table.text("inputs");
58043
+ table.text("output_context");
58044
+ table.string("status", 20).notNullable().defaultTo("active").index();
58045
+ table.boolean("enabled").notNullable().defaultTo(true);
58046
+ table.bigInteger("created_at").notNullable();
58047
+ });
58048
+ }
58049
+ const locksExist = await knex.schema.hasTable("scheduler_locks");
58050
+ if (!locksExist) {
58051
+ await knex.schema.createTable("scheduler_locks", (table) => {
58052
+ table.string("lock_id", 255).primary();
58053
+ table.string("node_id", 255).notNullable();
58054
+ table.string("lock_token", 36).notNullable();
58055
+ table.bigInteger("acquired_at").notNullable();
58056
+ table.bigInteger("expires_at").notNullable();
58057
+ });
58058
+ }
58059
+ }
58060
+ getKnex() {
58061
+ if (!this.knex) {
58062
+ throw new Error("[KnexStore] Not initialized. Call initialize() first.");
58063
+ }
58064
+ return this.knex;
58065
+ }
58066
+ // --- CRUD ---
58067
+ async create(schedule) {
58068
+ const knex = this.getKnex();
58069
+ const newSchedule = {
58070
+ ...schedule,
58071
+ id: (0, import_uuid2.v4)(),
58072
+ createdAt: Date.now(),
58073
+ runCount: 0,
58074
+ failureCount: 0,
58075
+ status: "active"
58076
+ };
58077
+ await knex("schedules").insert(toInsertRow(newSchedule));
58078
+ logger.info(`[KnexStore] Created schedule ${newSchedule.id} for user ${newSchedule.creatorId}`);
58079
+ return newSchedule;
58080
+ }
58081
+ async importSchedule(schedule) {
58082
+ const knex = this.getKnex();
58083
+ const existing = await knex("schedules").where("id", schedule.id).first();
58084
+ if (existing) return;
58085
+ await knex("schedules").insert(toInsertRow(schedule));
58086
+ }
58087
+ async get(id) {
58088
+ const knex = this.getKnex();
58089
+ const row = await knex("schedules").where("id", id).first();
58090
+ return row ? fromDbRow2(row) : void 0;
58091
+ }
58092
+ async update(id, patch) {
58093
+ const knex = this.getKnex();
58094
+ const existing = await knex("schedules").where("id", id).first();
58095
+ if (!existing) return void 0;
58096
+ const current = fromDbRow2(existing);
58097
+ const updated = { ...current, ...patch, id: current.id };
58098
+ const row = toInsertRow(updated);
58099
+ delete row.id;
58100
+ await knex("schedules").where("id", id).update(row);
58101
+ return updated;
58102
+ }
58103
+ async delete(id) {
58104
+ const knex = this.getKnex();
58105
+ const deleted = await knex("schedules").where("id", id).del();
58106
+ if (deleted > 0) {
58107
+ logger.info(`[KnexStore] Deleted schedule ${id}`);
58108
+ return true;
58109
+ }
58110
+ return false;
58111
+ }
58112
+ // --- Queries ---
58113
+ async getByCreator(creatorId) {
58114
+ const knex = this.getKnex();
58115
+ const rows = await knex("schedules").where("creator_id", creatorId);
58116
+ return rows.map((r) => fromDbRow2(r));
58117
+ }
58118
+ async getActiveSchedules() {
58119
+ const knex = this.getKnex();
58120
+ const rows = await knex("schedules").where("status", "active");
58121
+ return rows.map((r) => fromDbRow2(r));
58122
+ }
58123
+ async getDueSchedules(now) {
58124
+ const ts = now ?? Date.now();
58125
+ const knex = this.getKnex();
58126
+ const bFalse = this.driver === "mssql" ? 0 : false;
58127
+ const bTrue = this.driver === "mssql" ? 1 : true;
58128
+ const rows = await knex("schedules").where("status", "active").andWhere(function() {
58129
+ this.where(function() {
58130
+ this.where("is_recurring", bFalse).whereNotNull("run_at").where("run_at", "<=", ts);
58131
+ }).orWhere(function() {
58132
+ this.where("is_recurring", bTrue).whereNotNull("next_run_at").where("next_run_at", "<=", ts);
58133
+ });
58134
+ });
58135
+ return rows.map((r) => fromDbRow2(r));
58136
+ }
58137
+ async findByWorkflow(creatorId, workflowName) {
58138
+ const knex = this.getKnex();
58139
+ const escaped = workflowName.toLowerCase().replace(/[%_\\]/g, "\\$&");
58140
+ const pattern = `%${escaped}%`;
58141
+ const rows = await knex("schedules").where("creator_id", creatorId).where("status", "active").whereRaw("LOWER(workflow) LIKE ? ESCAPE '\\'", [pattern]);
58142
+ return rows.map((r) => fromDbRow2(r));
58143
+ }
58144
+ async getAll() {
58145
+ const knex = this.getKnex();
58146
+ const rows = await knex("schedules");
58147
+ return rows.map((r) => fromDbRow2(r));
58148
+ }
58149
+ async getStats() {
58150
+ const knex = this.getKnex();
58151
+ const boolTrue = this.driver === "mssql" ? "1" : "true";
58152
+ const boolFalse = this.driver === "mssql" ? "0" : "false";
58153
+ const result = await knex("schedules").select(
58154
+ knex.raw("COUNT(*) as total"),
58155
+ knex.raw("SUM(CASE WHEN status = 'active' THEN 1 ELSE 0 END) as active"),
58156
+ knex.raw("SUM(CASE WHEN status = 'paused' THEN 1 ELSE 0 END) as paused"),
58157
+ knex.raw("SUM(CASE WHEN status = 'completed' THEN 1 ELSE 0 END) as completed"),
58158
+ knex.raw("SUM(CASE WHEN status = 'failed' THEN 1 ELSE 0 END) as failed"),
58159
+ knex.raw(`SUM(CASE WHEN is_recurring = ${boolTrue} THEN 1 ELSE 0 END) as recurring`),
58160
+ knex.raw(`SUM(CASE WHEN is_recurring = ${boolFalse} THEN 1 ELSE 0 END) as one_time`)
58161
+ ).first();
58162
+ return {
58163
+ total: Number(result.total) || 0,
58164
+ active: Number(result.active) || 0,
58165
+ paused: Number(result.paused) || 0,
58166
+ completed: Number(result.completed) || 0,
58167
+ failed: Number(result.failed) || 0,
58168
+ recurring: Number(result.recurring) || 0,
58169
+ oneTime: Number(result.one_time) || 0
58170
+ };
58171
+ }
58172
+ async validateLimits(creatorId, isRecurring, limits) {
58173
+ const knex = this.getKnex();
58174
+ if (limits.maxGlobal) {
58175
+ const result = await knex("schedules").count("* as cnt").first();
58176
+ if (Number(result?.cnt) >= limits.maxGlobal) {
58177
+ throw new Error(`Global schedule limit reached (${limits.maxGlobal})`);
58178
+ }
58179
+ }
58180
+ if (limits.maxPerUser) {
58181
+ const result = await knex("schedules").where("creator_id", creatorId).count("* as cnt").first();
58182
+ if (Number(result?.cnt) >= limits.maxPerUser) {
58183
+ throw new Error(`You have reached the maximum number of schedules (${limits.maxPerUser})`);
58184
+ }
58185
+ }
58186
+ if (isRecurring && limits.maxRecurringPerUser) {
58187
+ const bTrue = this.driver === "mssql" ? 1 : true;
58188
+ const result = await knex("schedules").where("creator_id", creatorId).where("is_recurring", bTrue).count("* as cnt").first();
58189
+ if (Number(result?.cnt) >= limits.maxRecurringPerUser) {
58190
+ throw new Error(
58191
+ `You have reached the maximum number of recurring schedules (${limits.maxRecurringPerUser})`
58192
+ );
58193
+ }
58194
+ }
58195
+ }
58196
+ // --- HA Distributed Locking (via scheduler_locks table) ---
58197
+ async tryAcquireLock(lockId, nodeId, ttlSeconds) {
58198
+ const knex = this.getKnex();
58199
+ const now = Date.now();
58200
+ const expiresAt = now + ttlSeconds * 1e3;
58201
+ const token = (0, import_uuid2.v4)();
58202
+ const updated = await knex("scheduler_locks").where("lock_id", lockId).where("expires_at", "<", now).update({
58203
+ node_id: nodeId,
58204
+ lock_token: token,
58205
+ acquired_at: now,
58206
+ expires_at: expiresAt
58207
+ });
58208
+ if (updated > 0) return token;
58209
+ try {
58210
+ await knex("scheduler_locks").insert({
58211
+ lock_id: lockId,
58212
+ node_id: nodeId,
58213
+ lock_token: token,
58214
+ acquired_at: now,
58215
+ expires_at: expiresAt
58216
+ });
58217
+ return token;
58218
+ } catch {
58219
+ return null;
58220
+ }
58221
+ }
58222
+ async releaseLock(lockId, lockToken) {
58223
+ const knex = this.getKnex();
58224
+ await knex("scheduler_locks").where("lock_id", lockId).where("lock_token", lockToken).del();
58225
+ }
58226
+ async renewLock(lockId, lockToken, ttlSeconds) {
58227
+ const knex = this.getKnex();
58228
+ const now = Date.now();
58229
+ const expiresAt = now + ttlSeconds * 1e3;
58230
+ const updated = await knex("scheduler_locks").where("lock_id", lockId).where("lock_token", lockToken).update({ acquired_at: now, expires_at: expiresAt });
58231
+ return updated > 0;
58232
+ }
58233
+ async flush() {
58234
+ }
58235
+ // --- Message Trigger CRUD ---
58236
+ async createTrigger(trigger) {
58237
+ const knex = this.getKnex();
58238
+ const newTrigger = {
58239
+ ...trigger,
58240
+ id: (0, import_uuid2.v4)(),
58241
+ createdAt: Date.now()
58242
+ };
58243
+ await knex("message_triggers").insert(toTriggerInsertRow(newTrigger));
58244
+ logger.info(`[KnexStore] Created trigger ${newTrigger.id} for user ${newTrigger.creatorId}`);
58245
+ return newTrigger;
58246
+ }
58247
+ async getTrigger(id) {
58248
+ const knex = this.getKnex();
58249
+ const row = await knex("message_triggers").where("id", id).first();
58250
+ return row ? fromTriggerRow2(row) : void 0;
58251
+ }
58252
+ async updateTrigger(id, patch) {
58253
+ const knex = this.getKnex();
58254
+ const existing = await knex("message_triggers").where("id", id).first();
58255
+ if (!existing) return void 0;
58256
+ const current = fromTriggerRow2(existing);
58257
+ const updated = {
58258
+ ...current,
58259
+ ...patch,
58260
+ id: current.id,
58261
+ createdAt: current.createdAt
58262
+ };
58263
+ const row = toTriggerInsertRow(updated);
58264
+ delete row.id;
58265
+ await knex("message_triggers").where("id", id).update(row);
58266
+ return updated;
58267
+ }
58268
+ async deleteTrigger(id) {
58269
+ const knex = this.getKnex();
58270
+ const deleted = await knex("message_triggers").where("id", id).del();
58271
+ if (deleted > 0) {
58272
+ logger.info(`[KnexStore] Deleted trigger ${id}`);
58273
+ return true;
58274
+ }
58275
+ return false;
58276
+ }
58277
+ async getTriggersByCreator(creatorId) {
58278
+ const knex = this.getKnex();
58279
+ const rows = await knex("message_triggers").where("creator_id", creatorId);
58280
+ return rows.map((r) => fromTriggerRow2(r));
58281
+ }
58282
+ async getActiveTriggers() {
58283
+ const knex = this.getKnex();
58284
+ const rows = await knex("message_triggers").where("status", "active").where("enabled", this.driver === "mssql" ? 1 : true);
58285
+ return rows.map((r) => fromTriggerRow2(r));
58286
+ }
58287
+ };
58288
+ }
58289
+ });
58290
+
58291
+ // src/enterprise/loader.ts
58292
+ var loader_exports = {};
58293
+ __export(loader_exports, {
58294
+ loadEnterprisePolicyEngine: () => loadEnterprisePolicyEngine,
58295
+ loadEnterpriseStoreBackend: () => loadEnterpriseStoreBackend
58296
+ });
58297
+ async function loadEnterprisePolicyEngine(config) {
58298
+ try {
58299
+ const { LicenseValidator: LicenseValidator2 } = await Promise.resolve().then(() => (init_validator(), validator_exports));
58300
+ const validator = new LicenseValidator2();
58301
+ const license = await validator.loadAndValidate();
58302
+ if (!license || !validator.hasFeature("policy")) {
58303
+ return new DefaultPolicyEngine();
58304
+ }
58305
+ if (validator.isInGracePeriod()) {
58306
+ console.warn(
58307
+ "[visor:enterprise] License has expired but is within the 72-hour grace period. Please renew your license."
58308
+ );
58309
+ }
58310
+ const { OpaPolicyEngine: OpaPolicyEngine2 } = await Promise.resolve().then(() => (init_opa_policy_engine(), opa_policy_engine_exports));
58311
+ const engine = new OpaPolicyEngine2(config);
58312
+ await engine.initialize(config);
58313
+ return engine;
58314
+ } catch (err) {
58315
+ const msg = err instanceof Error ? err.message : String(err);
58316
+ try {
58317
+ const { logger: logger2 } = (init_logger(), __toCommonJS(logger_exports));
58318
+ logger2.warn(`[PolicyEngine] Enterprise policy init failed, falling back to default: ${msg}`);
58319
+ } catch {
58320
+ }
58321
+ return new DefaultPolicyEngine();
58322
+ }
58323
+ }
58324
+ async function loadEnterpriseStoreBackend(driver, storageConfig, haConfig) {
58325
+ const { LicenseValidator: LicenseValidator2 } = await Promise.resolve().then(() => (init_validator(), validator_exports));
58326
+ const validator = new LicenseValidator2();
58327
+ const license = await validator.loadAndValidate();
58328
+ if (!license || !validator.hasFeature("scheduler-sql")) {
58329
+ throw new Error(
58330
+ `The ${driver} schedule storage driver requires a Visor Enterprise license with the 'scheduler-sql' feature. Please upgrade or use driver: 'sqlite' (default).`
58331
+ );
58332
+ }
58333
+ if (validator.isInGracePeriod()) {
58334
+ console.warn(
58335
+ "[visor:enterprise] License has expired but is within the 72-hour grace period. Please renew your license."
58336
+ );
58337
+ }
58338
+ const { KnexStoreBackend: KnexStoreBackend2 } = await Promise.resolve().then(() => (init_knex_store(), knex_store_exports));
58339
+ return new KnexStoreBackend2(driver, storageConfig, haConfig);
58340
+ }
58341
+ var init_loader = __esm({
58342
+ "src/enterprise/loader.ts"() {
58343
+ "use strict";
58344
+ init_default_engine();
58345
+ }
58346
+ });
58347
+
56698
58348
  // src/event-bus/event-bus.ts
56699
58349
  var event_bus_exports = {};
56700
58350
  __export(event_bus_exports, {
@@ -57601,8 +59251,8 @@ ${content}
57601
59251
  * Sleep utility
57602
59252
  */
57603
59253
  sleep(ms) {
57604
- return new Promise((resolve15) => {
57605
- const t = setTimeout(resolve15, ms);
59254
+ return new Promise((resolve19) => {
59255
+ const t = setTimeout(resolve19, ms);
57606
59256
  if (typeof t.unref === "function") {
57607
59257
  try {
57608
59258
  t.unref();
@@ -57887,8 +59537,8 @@ ${end}`);
57887
59537
  async updateGroupedComment(ctx, comments, group, changedIds) {
57888
59538
  const existingLock = this.updateLocks.get(group);
57889
59539
  let resolveLock;
57890
- const ourLock = new Promise((resolve15) => {
57891
- resolveLock = resolve15;
59540
+ const ourLock = new Promise((resolve19) => {
59541
+ resolveLock = resolve19;
57892
59542
  });
57893
59543
  this.updateLocks.set(group, ourLock);
57894
59544
  try {
@@ -58219,7 +59869,7 @@ ${blocks}
58219
59869
  * Sleep utility for enforcing delays
58220
59870
  */
58221
59871
  sleep(ms) {
58222
- return new Promise((resolve15) => setTimeout(resolve15, ms));
59872
+ return new Promise((resolve19) => setTimeout(resolve19, ms));
58223
59873
  }
58224
59874
  };
58225
59875
  }
@@ -60066,11 +61716,11 @@ var require_request3 = __commonJS({
60066
61716
  "use strict";
60067
61717
  var __awaiter = exports2 && exports2.__awaiter || function(thisArg, _arguments, P, generator) {
60068
61718
  function adopt(value) {
60069
- return value instanceof P ? value : new P(function(resolve15) {
60070
- resolve15(value);
61719
+ return value instanceof P ? value : new P(function(resolve19) {
61720
+ resolve19(value);
60071
61721
  });
60072
61722
  }
60073
- return new (P || (P = Promise))(function(resolve15, reject) {
61723
+ return new (P || (P = Promise))(function(resolve19, reject) {
60074
61724
  function fulfilled(value) {
60075
61725
  try {
60076
61726
  step(generator.next(value));
@@ -60086,7 +61736,7 @@ var require_request3 = __commonJS({
60086
61736
  }
60087
61737
  }
60088
61738
  function step(result) {
60089
- result.done ? resolve15(result.value) : adopt(result.value).then(fulfilled, rejected);
61739
+ result.done ? resolve19(result.value) : adopt(result.value).then(fulfilled, rejected);
60090
61740
  }
60091
61741
  step((generator = generator.apply(thisArg, _arguments || [])).next());
60092
61742
  });
@@ -60110,9 +61760,9 @@ var require_request3 = __commonJS({
60110
61760
  HttpMethod2["PATCH"] = "PATCH";
60111
61761
  })(HttpMethod = exports2.HttpMethod || (exports2.HttpMethod = {}));
60112
61762
  var SvixRequest = class {
60113
- constructor(method, path29) {
61763
+ constructor(method, path33) {
60114
61764
  this.method = method;
60115
- this.path = path29;
61765
+ this.path = path33;
60116
61766
  this.queryParams = {};
60117
61767
  this.headerParams = {};
60118
61768
  }
@@ -60215,7 +61865,7 @@ var require_request3 = __commonJS({
60215
61865
  }
60216
61866
  function sendWithRetry(url, init, retryScheduleInMs, nextInterval = 50, triesLeft = 2, fetchImpl = fetch, retryCount = 1) {
60217
61867
  return __awaiter(this, void 0, void 0, function* () {
60218
- const sleep = (interval) => new Promise((resolve15) => setTimeout(resolve15, interval));
61868
+ const sleep = (interval) => new Promise((resolve19) => setTimeout(resolve19, interval));
60219
61869
  try {
60220
61870
  const response = yield fetchImpl(url, init);
60221
61871
  if (triesLeft <= 0 || response.status < 500) {
@@ -69289,7 +70939,7 @@ ${message}`;
69289
70939
  });
69290
70940
 
69291
70941
  // src/agent-protocol/task-store.ts
69292
- function safeJsonParse2(value) {
70942
+ function safeJsonParse3(value) {
69293
70943
  if (!value) return void 0;
69294
70944
  try {
69295
70945
  return JSON.parse(value);
@@ -69306,12 +70956,12 @@ function taskRowToAgentTask(row) {
69306
70956
  context_id: row.context_id,
69307
70957
  status: {
69308
70958
  state: row.state,
69309
- message: safeJsonParse2(row.status_message),
70959
+ message: safeJsonParse3(row.status_message),
69310
70960
  timestamp: row.updated_at
69311
70961
  },
69312
- artifacts: safeJsonParse2(row.artifacts) ?? [],
69313
- history: safeJsonParse2(row.history) ?? [],
69314
- metadata: safeJsonParse2(row.request_metadata),
70962
+ artifacts: safeJsonParse3(row.artifacts) ?? [],
70963
+ history: safeJsonParse3(row.history) ?? [],
70964
+ metadata: safeJsonParse3(row.request_metadata),
69315
70965
  workflow_id: row.workflow_id ?? void 0
69316
70966
  };
69317
70967
  }
@@ -69548,7 +71198,7 @@ var init_task_store = __esm({
69548
71198
  const db = this.getDb();
69549
71199
  const row = db.prepare("SELECT artifacts FROM agent_tasks WHERE id = ?").get(taskId);
69550
71200
  if (!row) throw new TaskNotFoundError(taskId);
69551
- const artifacts = safeJsonParse2(row.artifacts) ?? [];
71201
+ const artifacts = safeJsonParse3(row.artifacts) ?? [];
69552
71202
  artifacts.push(artifact);
69553
71203
  db.prepare("UPDATE agent_tasks SET artifacts = ?, updated_at = ? WHERE id = ?").run(
69554
71204
  JSON.stringify(artifacts),
@@ -69560,7 +71210,7 @@ var init_task_store = __esm({
69560
71210
  const db = this.getDb();
69561
71211
  const row = db.prepare("SELECT history FROM agent_tasks WHERE id = ?").get(taskId);
69562
71212
  if (!row) throw new TaskNotFoundError(taskId);
69563
- const history = safeJsonParse2(row.history) ?? [];
71213
+ const history = safeJsonParse3(row.history) ?? [];
69564
71214
  history.push(message);
69565
71215
  db.prepare("UPDATE agent_tasks SET history = ?, updated_at = ? WHERE id = ?").run(
69566
71216
  JSON.stringify(history),
@@ -70072,13 +71722,13 @@ __export(a2a_frontend_exports, {
70072
71722
  resultToArtifacts: () => resultToArtifacts
70073
71723
  });
70074
71724
  function readJsonBody(req) {
70075
- return new Promise((resolve15, reject) => {
71725
+ return new Promise((resolve19, reject) => {
70076
71726
  const chunks = [];
70077
71727
  req.on("data", (chunk) => chunks.push(chunk));
70078
71728
  req.on("end", () => {
70079
71729
  try {
70080
71730
  const body = Buffer.concat(chunks).toString("utf8");
70081
- resolve15(body ? JSON.parse(body) : {});
71731
+ resolve19(body ? JSON.parse(body) : {});
70082
71732
  } catch {
70083
71733
  reject(new ParseError("Malformed JSON body"));
70084
71734
  }
@@ -70321,12 +71971,12 @@ var init_a2a_frontend = __esm({
70321
71971
  }
70322
71972
  const port = this.config.port ?? 9e3;
70323
71973
  const host = this.config.host ?? "0.0.0.0";
70324
- await new Promise((resolve15) => {
71974
+ await new Promise((resolve19) => {
70325
71975
  this.server.listen(port, host, () => {
70326
71976
  const addr = this.server.address();
70327
71977
  this._boundPort = typeof addr === "object" && addr ? addr.port : port;
70328
71978
  logger.info(`A2A server listening on ${host}:${this._boundPort}`);
70329
- resolve15();
71979
+ resolve19();
70330
71980
  });
70331
71981
  });
70332
71982
  if (this.agentCard) {
@@ -70350,8 +72000,8 @@ var init_a2a_frontend = __esm({
70350
72000
  }
70351
72001
  this.streamManager.shutdown();
70352
72002
  if (this.server) {
70353
- await new Promise((resolve15, reject) => {
70354
- this.server.close((err) => err ? reject(err) : resolve15());
72003
+ await new Promise((resolve19, reject) => {
72004
+ this.server.close((err) => err ? reject(err) : resolve19());
70355
72005
  });
70356
72006
  this.server = null;
70357
72007
  }
@@ -71068,15 +72718,15 @@ function serializeRunState(state) {
71068
72718
  ])
71069
72719
  };
71070
72720
  }
71071
- var path28, fs24, StateMachineExecutionEngine;
72721
+ var path32, fs28, StateMachineExecutionEngine;
71072
72722
  var init_state_machine_execution_engine = __esm({
71073
72723
  "src/state-machine-execution-engine.ts"() {
71074
72724
  "use strict";
71075
72725
  init_runner();
71076
72726
  init_logger();
71077
72727
  init_sandbox_manager();
71078
- path28 = __toESM(require("path"));
71079
- fs24 = __toESM(require("fs"));
72728
+ path32 = __toESM(require("path"));
72729
+ fs28 = __toESM(require("fs"));
71080
72730
  StateMachineExecutionEngine = class _StateMachineExecutionEngine {
71081
72731
  workingDirectory;
71082
72732
  executionContext;
@@ -71308,8 +72958,8 @@ var init_state_machine_execution_engine = __esm({
71308
72958
  logger.debug(
71309
72959
  `[PolicyEngine] Loading enterprise policy engine (engine=${configWithTagFilter.policy.engine})`
71310
72960
  );
71311
- const { loadEnterprisePolicyEngine } = await import("./enterprise/loader");
71312
- context2.policyEngine = await loadEnterprisePolicyEngine(configWithTagFilter.policy);
72961
+ const { loadEnterprisePolicyEngine: loadEnterprisePolicyEngine2 } = await Promise.resolve().then(() => (init_loader(), loader_exports));
72962
+ context2.policyEngine = await loadEnterprisePolicyEngine2(configWithTagFilter.policy);
71313
72963
  logger.debug(
71314
72964
  `[PolicyEngine] Initialized: ${context2.policyEngine?.constructor?.name || "unknown"}`
71315
72965
  );
@@ -71463,9 +73113,9 @@ var init_state_machine_execution_engine = __esm({
71463
73113
  }
71464
73114
  const checkId = String(ev?.checkId || "unknown");
71465
73115
  const threadKey = ev?.threadKey || (channel && threadTs ? `${channel}:${threadTs}` : "session");
71466
- const baseDir = process.env.VISOR_SNAPSHOT_DIR || path28.resolve(process.cwd(), ".visor", "snapshots");
71467
- fs24.mkdirSync(baseDir, { recursive: true });
71468
- const filePath = path28.join(baseDir, `${threadKey}-${checkId}.json`);
73116
+ const baseDir = process.env.VISOR_SNAPSHOT_DIR || path32.resolve(process.cwd(), ".visor", "snapshots");
73117
+ fs28.mkdirSync(baseDir, { recursive: true });
73118
+ const filePath = path32.join(baseDir, `${threadKey}-${checkId}.json`);
71469
73119
  await this.saveSnapshotToFile(filePath);
71470
73120
  logger.info(`[Snapshot] Saved run snapshot: ${filePath}`);
71471
73121
  try {
@@ -71606,7 +73256,7 @@ var init_state_machine_execution_engine = __esm({
71606
73256
  * Does not include secrets. Intended for debugging and future resume support.
71607
73257
  */
71608
73258
  async saveSnapshotToFile(filePath) {
71609
- const fs25 = await import("fs/promises");
73259
+ const fs29 = await import("fs/promises");
71610
73260
  const ctx = this._lastContext;
71611
73261
  const runner = this._lastRunner;
71612
73262
  if (!ctx || !runner) {
@@ -71626,14 +73276,14 @@ var init_state_machine_execution_engine = __esm({
71626
73276
  journal: entries,
71627
73277
  requestedChecks: ctx.requestedChecks || []
71628
73278
  };
71629
- await fs25.writeFile(filePath, JSON.stringify(payload, null, 2), "utf8");
73279
+ await fs29.writeFile(filePath, JSON.stringify(payload, null, 2), "utf8");
71630
73280
  }
71631
73281
  /**
71632
73282
  * Load a snapshot JSON from file and return it. Resume support can build on this.
71633
73283
  */
71634
73284
  async loadSnapshotFromFile(filePath) {
71635
- const fs25 = await import("fs/promises");
71636
- const raw = await fs25.readFile(filePath, "utf8");
73285
+ const fs29 = await import("fs/promises");
73286
+ const raw = await fs29.readFile(filePath, "utf8");
71637
73287
  return JSON.parse(raw);
71638
73288
  }
71639
73289
  /**