@probelabs/visor 0.1.96 → 0.1.98

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 (88) hide show
  1. package/README.md +20 -19
  2. package/defaults/.visor.yaml +3 -2
  3. package/dist/{168.index.js → 136.index.js} +5 -5
  4. package/dist/{272.index.js → 146.index.js} +5 -5
  5. package/dist/{13.index.js → 160.index.js} +5 -5
  6. package/dist/{421.index.js → 179.index.js} +3 -3
  7. package/dist/{85.index.js → 191.index.js} +5 -5
  8. package/dist/{544.index.js → 384.index.js} +3 -3
  9. package/dist/{861.index.js → 405.index.js} +3 -3
  10. package/dist/{320.index.js → 42.index.js} +3 -3
  11. package/dist/448.index.js +48 -0
  12. package/dist/{878.index.js → 491.index.js} +5 -5
  13. package/dist/663.index.js +321 -0
  14. package/dist/69.index.js +38 -0
  15. package/dist/{54.index.js → 760.index.js} +5 -5
  16. package/dist/80.index.js +263 -0
  17. package/dist/886.index.js +81 -0
  18. package/dist/917.index.js +82 -0
  19. package/dist/955.index.js +82 -0
  20. package/dist/ai-review-service.d.ts +2 -3
  21. package/dist/ai-review-service.d.ts.map +1 -1
  22. package/dist/check-execution-engine.d.ts.map +1 -1
  23. package/dist/cli.d.ts.map +1 -1
  24. package/dist/config.d.ts +5 -0
  25. package/dist/config.d.ts.map +1 -1
  26. package/dist/defaults/.visor.yaml +3 -2
  27. package/dist/generated/config-schema.d.ts +24 -3
  28. package/dist/generated/config-schema.d.ts.map +1 -1
  29. package/dist/generated/config-schema.json +28 -3
  30. package/dist/index.js +198171 -161819
  31. package/dist/proto/protoc-gen-validate/LICENSE +202 -0
  32. package/dist/proto/protoc-gen-validate/validate/validate.proto +797 -0
  33. package/dist/proto/xds/LICENSE +201 -0
  34. package/dist/proto/xds/xds/data/orca/v3/orca_load_report.proto +58 -0
  35. package/dist/proto/xds/xds/service/orca/v3/orca.proto +36 -0
  36. package/dist/protoc-gen-validate/LICENSE +202 -0
  37. package/dist/protoc-gen-validate/validate/validate.proto +797 -0
  38. package/dist/providers/check-provider-registry.d.ts.map +1 -1
  39. package/dist/providers/index.d.ts +1 -0
  40. package/dist/providers/index.d.ts.map +1 -1
  41. package/dist/providers/mcp-check-provider.d.ts +102 -0
  42. package/dist/providers/mcp-check-provider.d.ts.map +1 -0
  43. package/dist/sdk/check-execution-engine-W5FLIWZL.mjs +11 -0
  44. package/dist/sdk/chunk-IG3BFIIN.mjs +174 -0
  45. package/dist/sdk/chunk-IG3BFIIN.mjs.map +1 -0
  46. package/dist/sdk/{chunk-Q4S5A5TO.mjs → chunk-POYXI3MQ.mjs} +610 -21
  47. package/dist/sdk/chunk-POYXI3MQ.mjs.map +1 -0
  48. package/dist/sdk/chunk-YXOWIDEF.mjs +60 -0
  49. package/dist/sdk/chunk-YXOWIDEF.mjs.map +1 -0
  50. package/dist/sdk/{mermaid-telemetry-LZGDD35I.mjs → mermaid-telemetry-4DUEYCLE.mjs} +2 -2
  51. package/dist/sdk/sdk.d.mts +16 -3
  52. package/dist/sdk/sdk.d.ts +16 -3
  53. package/dist/sdk/sdk.js +994 -1513
  54. package/dist/sdk/sdk.js.map +1 -1
  55. package/dist/sdk/sdk.mjs +70 -13
  56. package/dist/sdk/sdk.mjs.map +1 -1
  57. package/dist/sdk/{tracer-init-O7RLXMJ3.mjs → tracer-init-RJGAIOBP.mjs} +2 -2
  58. package/dist/session-registry.d.ts +2 -3
  59. package/dist/session-registry.d.ts.map +1 -1
  60. package/dist/traces/run-2025-10-19T19-05-29-328Z.ndjson +40 -0
  61. package/dist/traces/run-2025-10-19T19-05-42-253Z.ndjson +40 -0
  62. package/dist/traces/run-2025-10-19T19-05-42-805Z.ndjson +40 -0
  63. package/dist/traces/run-2025-10-19T19-05-43-323Z.ndjson +40 -0
  64. package/dist/traces/run-2025-10-19T19-05-43-841Z.ndjson +12 -0
  65. package/dist/types/config.d.ts +16 -3
  66. package/dist/types/config.d.ts.map +1 -1
  67. package/dist/utils/config-loader.d.ts +5 -0
  68. package/dist/utils/config-loader.d.ts.map +1 -1
  69. package/dist/utils/tracer-init.d.ts +3 -4
  70. package/dist/utils/tracer-init.d.ts.map +1 -1
  71. package/dist/xds/LICENSE +201 -0
  72. package/dist/xds/xds/data/orca/v3/orca_load_report.proto +58 -0
  73. package/dist/xds/xds/service/orca/v3/orca.proto +36 -0
  74. package/package.json +15 -8
  75. package/dist/sdk/check-execution-engine-NMPXJ7FQ.mjs +0 -11
  76. package/dist/sdk/chunk-KVHVCGY6.mjs +0 -103
  77. package/dist/sdk/chunk-KVHVCGY6.mjs.map +0 -1
  78. package/dist/sdk/chunk-Q4S5A5TO.mjs.map +0 -1
  79. package/dist/sdk/chunk-TWJKAYT6.mjs +0 -1124
  80. package/dist/sdk/chunk-TWJKAYT6.mjs.map +0 -1
  81. /package/dist/{traces/run-2025-10-18T20-24-27-886Z.ndjson → output/traces/run-2025-10-19T19-05-29-328Z.ndjson} +0 -0
  82. /package/dist/{traces/run-2025-10-18T20-24-38-817Z.ndjson → output/traces/run-2025-10-19T19-05-42-253Z.ndjson} +0 -0
  83. /package/dist/{traces/run-2025-10-18T20-24-39-361Z.ndjson → output/traces/run-2025-10-19T19-05-42-805Z.ndjson} +0 -0
  84. /package/dist/{traces/run-2025-10-18T20-24-39-852Z.ndjson → output/traces/run-2025-10-19T19-05-43-323Z.ndjson} +0 -0
  85. /package/dist/{traces/run-2025-10-18T20-24-40-335Z.ndjson → output/traces/run-2025-10-19T19-05-43-841Z.ndjson} +0 -0
  86. /package/dist/sdk/{check-execution-engine-NMPXJ7FQ.mjs.map → check-execution-engine-W5FLIWZL.mjs.map} +0 -0
  87. /package/dist/sdk/{mermaid-telemetry-LZGDD35I.mjs.map → mermaid-telemetry-4DUEYCLE.mjs.map} +0 -0
  88. /package/dist/sdk/{tracer-init-O7RLXMJ3.mjs.map → tracer-init-RJGAIOBP.mjs.map} +0 -0
package/dist/sdk/sdk.js CHANGED
@@ -468,50 +468,7 @@ __export(tracer_init_exports, {
468
468
  });
469
469
  async function initializeTracer(sessionId, checkName) {
470
470
  try {
471
- if (import_probe.TelemetryConfig && import_probe.AppTracer) {
472
- const sanitizedCheckName = checkName ? path.basename(checkName) : "check";
473
- const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
474
- const traceDir = process.env.GITHUB_WORKSPACE ? path.join(process.env.GITHUB_WORKSPACE, "debug-artifacts") : path.join(process.cwd(), "debug-artifacts");
475
- if (!fs.existsSync(traceDir)) {
476
- fs.mkdirSync(traceDir, { recursive: true });
477
- }
478
- const traceFilePath = path.join(traceDir, `trace-${sanitizedCheckName}-${timestamp}.jsonl`);
479
- const resolvedTracePath = path.resolve(traceFilePath);
480
- const resolvedTraceDir = path.resolve(traceDir);
481
- if (!resolvedTracePath.startsWith(resolvedTraceDir)) {
482
- console.error(
483
- `\u26A0\uFE0F Security: Attempted path traversal detected. Check name: ${checkName}, resolved path: ${resolvedTracePath}`
484
- );
485
- return null;
486
- }
487
- const telemetryConfig = new import_probe.TelemetryConfig({
488
- serviceName: "visor-ai",
489
- serviceVersion: "1.0.0",
490
- enableFile: true,
491
- filePath: traceFilePath,
492
- enableConsole: false,
493
- // Disable console to reduce noise
494
- enableRemote: false
495
- // Can be enabled via OTEL_EXPORTER_OTLP_ENDPOINT env var
496
- });
497
- telemetryConfig.initialize();
498
- const tracer = new import_probe.AppTracer(telemetryConfig, sessionId);
499
- console.error(`\u{1F4CA} OpenTelemetry tracing enabled for visor-ai, saving to: ${traceFilePath}`);
500
- console.error(
501
- `\u{1F332} Trace spans will show hierarchical relationships between visor checks and probe agent operations`
502
- );
503
- if (process.env.GITHUB_ACTIONS) {
504
- console.log(
505
- `::notice title=AI Trace::OpenTelemetry trace will be saved to ${traceFilePath}`
506
- );
507
- console.log(`::set-output name=trace-path::${traceFilePath}`);
508
- }
509
- return { tracer, telemetryConfig, filePath: traceFilePath };
510
- }
511
471
  if (import_probe.SimpleTelemetry && import_probe.SimpleAppTracer) {
512
- console.warn(
513
- "\u26A0\uFE0F Using SimpleTelemetry fallback - hierarchical span relationships may not be available"
514
- );
515
472
  const sanitizedCheckName = checkName ? path.basename(checkName) : "check";
516
473
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
517
474
  const traceDir = process.env.GITHUB_WORKSPACE ? path.join(process.env.GITHUB_WORKSPACE, "debug-artifacts") : path.join(process.cwd(), "debug-artifacts");
@@ -1184,7 +1141,7 @@ ${prContext}
1184
1141
  log2("\u{1F50D} Including code diffs in AI context");
1185
1142
  }
1186
1143
  if (isIssue) {
1187
- let context3 = `<issue>
1144
+ let context2 = `<issue>
1188
1145
  <!-- Core issue metadata including identification, status, and timeline information -->
1189
1146
  <metadata>
1190
1147
  <number>${prInfo.number}</number>
@@ -1196,7 +1153,7 @@ ${prContext}
1196
1153
  <comments_count>${prInfo.eventContext?.issue?.comments || 0}</comments_count>
1197
1154
  </metadata>`;
1198
1155
  if (prInfo.body) {
1199
- context3 += `
1156
+ context2 += `
1200
1157
  <!-- Full issue description and body text provided by the issue author -->
1201
1158
  <description>
1202
1159
  ${this.escapeXml(prInfo.body)}
@@ -1205,33 +1162,33 @@ ${this.escapeXml(prInfo.body)}
1205
1162
  const eventContext = prInfo;
1206
1163
  const labels = eventContext.eventContext?.issue?.labels;
1207
1164
  if (labels && labels.length > 0) {
1208
- context3 += `
1165
+ context2 += `
1209
1166
  <!-- Applied labels for issue categorization and organization -->
1210
1167
  <labels>`;
1211
1168
  labels.forEach((label) => {
1212
1169
  const labelName = typeof label === "string" ? label : label.name || "unknown";
1213
- context3 += `
1170
+ context2 += `
1214
1171
  <label>${this.escapeXml(labelName)}</label>`;
1215
1172
  });
1216
- context3 += `
1173
+ context2 += `
1217
1174
  </labels>`;
1218
1175
  }
1219
1176
  const assignees = prInfo.eventContext?.issue?.assignees;
1220
1177
  if (assignees && assignees.length > 0) {
1221
- context3 += `
1178
+ context2 += `
1222
1179
  <!-- Users assigned to work on this issue -->
1223
1180
  <assignees>`;
1224
1181
  assignees.forEach((assignee) => {
1225
1182
  const assigneeName = typeof assignee === "string" ? assignee : assignee.login || "unknown";
1226
- context3 += `
1183
+ context2 += `
1227
1184
  <assignee>${this.escapeXml(assigneeName)}</assignee>`;
1228
1185
  });
1229
- context3 += `
1186
+ context2 += `
1230
1187
  </assignees>`;
1231
1188
  }
1232
1189
  const milestone = prInfo.eventContext?.issue?.milestone;
1233
1190
  if (milestone) {
1234
- context3 += `
1191
+ context2 += `
1235
1192
  <!-- Associated project milestone information -->
1236
1193
  <milestone>
1237
1194
  <title>${this.escapeXml(milestone.title || "")}</title>
@@ -1241,7 +1198,7 @@ ${this.escapeXml(prInfo.body)}
1241
1198
  }
1242
1199
  const triggeringComment2 = prInfo.eventContext?.comment;
1243
1200
  if (triggeringComment2) {
1244
- context3 += `
1201
+ context2 += `
1245
1202
  <!-- The comment that triggered this analysis -->
1246
1203
  <triggering_comment>
1247
1204
  <author>${this.escapeXml(triggeringComment2.user?.login || "unknown")}</author>
@@ -1258,26 +1215,26 @@ ${this.escapeXml(prInfo.body)}
1258
1215
  );
1259
1216
  }
1260
1217
  if (historicalComments.length > 0) {
1261
- context3 += `
1218
+ context2 += `
1262
1219
  <!-- Previous comments in chronological order (excluding triggering comment) -->
1263
1220
  <comment_history>`;
1264
1221
  historicalComments.forEach((comment) => {
1265
- context3 += `
1222
+ context2 += `
1266
1223
  <comment>
1267
1224
  <author>${this.escapeXml(comment.author || "unknown")}</author>
1268
1225
  <created_at>${comment.createdAt || ""}</created_at>
1269
1226
  <body>${this.escapeXml(comment.body || "")}</body>
1270
1227
  </comment>`;
1271
1228
  });
1272
- context3 += `
1229
+ context2 += `
1273
1230
  </comment_history>`;
1274
1231
  }
1275
1232
  }
1276
- context3 += `
1233
+ context2 += `
1277
1234
  </issue>`;
1278
- return context3;
1235
+ return context2;
1279
1236
  }
1280
- let context2 = `<pull_request>
1237
+ let context = `<pull_request>
1281
1238
  <!-- Core pull request metadata including identification, branches, and change statistics -->
1282
1239
  <metadata>
1283
1240
  <number>${prInfo.number}</number>
@@ -1290,7 +1247,7 @@ ${this.escapeXml(prInfo.body)}
1290
1247
  <files_changed_count>${prInfo.files.length}</files_changed_count>
1291
1248
  </metadata>`;
1292
1249
  if (prInfo.body) {
1293
- context2 += `
1250
+ context += `
1294
1251
  <!-- Full pull request description provided by the author -->
1295
1252
  <description>
1296
1253
  ${this.escapeXml(prInfo.body)}
@@ -1299,7 +1256,7 @@ ${this.escapeXml(prInfo.body)}
1299
1256
  if (includeCodeContext) {
1300
1257
  if (prInfo.fullDiff) {
1301
1258
  const processedFullDiff = await processDiffWithOutline(prInfo.fullDiff);
1302
- context2 += `
1259
+ context += `
1303
1260
  <!-- Complete unified diff showing all changes in the pull request (processed with outline-diff) -->
1304
1261
  <full_diff>
1305
1262
  ${this.escapeXml(processedFullDiff)}
@@ -1308,14 +1265,14 @@ ${this.escapeXml(processedFullDiff)}
1308
1265
  if (prInfo.isIncremental) {
1309
1266
  if (prInfo.commitDiff && prInfo.commitDiff.length > 0) {
1310
1267
  const processedCommitDiff = await processDiffWithOutline(prInfo.commitDiff);
1311
- context2 += `
1268
+ context += `
1312
1269
  <!-- Diff of only the latest commit for incremental analysis (processed with outline-diff) -->
1313
1270
  <commit_diff>
1314
1271
  ${this.escapeXml(processedCommitDiff)}
1315
1272
  </commit_diff>`;
1316
1273
  } else {
1317
1274
  const processedFallbackDiff = prInfo.fullDiff ? await processDiffWithOutline(prInfo.fullDiff) : "";
1318
- context2 += `
1275
+ context += `
1319
1276
  <!-- Commit diff could not be retrieved - falling back to full diff analysis (processed with outline-diff) -->
1320
1277
  <commit_diff>
1321
1278
  ${this.escapeXml(processedFallbackDiff)}
@@ -1323,15 +1280,15 @@ ${this.escapeXml(processedFallbackDiff)}
1323
1280
  }
1324
1281
  }
1325
1282
  } else {
1326
- context2 += `
1283
+ context += `
1327
1284
  <!-- Code diffs excluded to reduce token usage (no code-review schema detected or disabled by flag) -->`;
1328
1285
  }
1329
1286
  if (prInfo.files.length > 0) {
1330
- context2 += `
1287
+ context += `
1331
1288
  <!-- Summary of all files changed with statistics -->
1332
1289
  <files_summary>`;
1333
1290
  prInfo.files.forEach((file) => {
1334
- context2 += `
1291
+ context += `
1335
1292
  <file>
1336
1293
  <filename>${this.escapeXml(file.filename)}</filename>
1337
1294
  <status>${file.status}</status>
@@ -1339,12 +1296,12 @@ ${this.escapeXml(processedFallbackDiff)}
1339
1296
  <deletions>${file.deletions}</deletions>
1340
1297
  </file>`;
1341
1298
  });
1342
- context2 += `
1299
+ context += `
1343
1300
  </files_summary>`;
1344
1301
  }
1345
1302
  const triggeringComment = prInfo.eventContext?.comment;
1346
1303
  if (triggeringComment) {
1347
- context2 += `
1304
+ context += `
1348
1305
  <!-- The comment that triggered this analysis -->
1349
1306
  <triggering_comment>
1350
1307
  <author>${this.escapeXml(triggeringComment.user?.login || "unknown")}</author>
@@ -1361,24 +1318,24 @@ ${this.escapeXml(processedFallbackDiff)}
1361
1318
  );
1362
1319
  }
1363
1320
  if (historicalComments.length > 0) {
1364
- context2 += `
1321
+ context += `
1365
1322
  <!-- Previous PR comments in chronological order (excluding triggering comment) -->
1366
1323
  <comment_history>`;
1367
1324
  historicalComments.forEach((comment) => {
1368
- context2 += `
1325
+ context += `
1369
1326
  <comment>
1370
1327
  <author>${this.escapeXml(comment.author || "unknown")}</author>
1371
1328
  <created_at>${comment.createdAt || ""}</created_at>
1372
1329
  <body>${this.escapeXml(comment.body || "")}</body>
1373
1330
  </comment>`;
1374
1331
  });
1375
- context2 += `
1332
+ context += `
1376
1333
  </comment_history>`;
1377
1334
  }
1378
1335
  }
1379
- context2 += `
1336
+ context += `
1380
1337
  </pull_request>`;
1381
- return context2;
1338
+ return context;
1382
1339
  }
1383
1340
  /**
1384
1341
  * No longer escaping XML - returning text as-is
@@ -2092,12 +2049,14 @@ ${"=".repeat(60)}
2092
2049
  }
2093
2050
  if (traceFilePath && telemetryConfig) {
2094
2051
  try {
2095
- if (tracer && typeof tracer.flush === "function") {
2096
- await tracer.flush();
2052
+ const telemetry = telemetryConfig;
2053
+ const tracerWithMethods = tracer;
2054
+ if (tracerWithMethods && typeof tracerWithMethods.flush === "function") {
2055
+ await tracerWithMethods.flush();
2097
2056
  log(`\u{1F504} Flushed tracer spans`);
2098
2057
  }
2099
- if (telemetryConfig && typeof telemetryConfig.shutdown === "function") {
2100
- await telemetryConfig.shutdown();
2058
+ if (telemetry && typeof telemetry.shutdown === "function") {
2059
+ await telemetry.shutdown();
2101
2060
  log(`\u{1F4CA} OpenTelemetry trace saved to: ${traceFilePath}`);
2102
2061
  if (process.env.GITHUB_ACTIONS) {
2103
2062
  const fs12 = require("fs");
@@ -2108,8 +2067,8 @@ ${"=".repeat(60)}
2108
2067
  );
2109
2068
  }
2110
2069
  }
2111
- } else if (tracer && typeof tracer.shutdown === "function") {
2112
- await tracer.shutdown();
2070
+ } else if (tracerWithMethods && typeof tracerWithMethods.shutdown === "function") {
2071
+ await tracerWithMethods.shutdown();
2113
2072
  log(`\u{1F4CA} Trace saved to: ${traceFilePath}`);
2114
2073
  }
2115
2074
  } catch (exportError) {
@@ -5308,8 +5267,8 @@ var init_log_check_provider = __esm({
5308
5267
  };
5309
5268
  }
5310
5269
  buildTemplateContext(prInfo, dependencyResults, _includePrContext = true, _includeDependencies = true, includeMetadata = true, outputHistory) {
5311
- const context2 = {};
5312
- context2.pr = {
5270
+ const context = {};
5271
+ context.pr = {
5313
5272
  number: prInfo.number,
5314
5273
  title: prInfo.title,
5315
5274
  body: prInfo.body,
@@ -5326,13 +5285,13 @@ var init_log_check_provider = __esm({
5326
5285
  changes: f.changes
5327
5286
  }))
5328
5287
  };
5329
- context2.filenames = prInfo.files.map((f) => f.filename);
5330
- context2.fileCount = prInfo.files.length;
5288
+ context.filenames = prInfo.files.map((f) => f.filename);
5289
+ context.fileCount = prInfo.files.length;
5331
5290
  if (dependencyResults) {
5332
5291
  const dependencies = {};
5333
5292
  const outputs = {};
5334
5293
  const history = {};
5335
- context2.dependencyCount = dependencyResults.size;
5294
+ context.dependencyCount = dependencyResults.size;
5336
5295
  for (const [checkName, result] of dependencyResults.entries()) {
5337
5296
  dependencies[checkName] = {
5338
5297
  issueCount: result.issues?.length || 0,
@@ -5348,11 +5307,11 @@ var init_log_check_provider = __esm({
5348
5307
  }
5349
5308
  }
5350
5309
  outputs.history = history;
5351
- context2.dependencies = dependencies;
5352
- context2.outputs = outputs;
5310
+ context.dependencies = dependencies;
5311
+ context.outputs = outputs;
5353
5312
  }
5354
5313
  if (includeMetadata) {
5355
- context2.metadata = {
5314
+ context.metadata = {
5356
5315
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
5357
5316
  executionTime: Date.now(),
5358
5317
  nodeVersion: process.version,
@@ -5360,7 +5319,7 @@ var init_log_check_provider = __esm({
5360
5319
  workingDirectory: process.cwd()
5361
5320
  };
5362
5321
  }
5363
- return context2;
5322
+ return context;
5364
5323
  }
5365
5324
  formatLogOutput(level, message, templateContext, includePrContext, includeDependencies, includeMetadata) {
5366
5325
  const sections = [];
@@ -6284,8 +6243,8 @@ var init_command_check_provider = __esm({
6284
6243
  const timeoutSeconds = config.timeout || 60;
6285
6244
  const timeoutMs = timeoutSeconds * 1e3;
6286
6245
  const normalizeNodeEval = (cmd) => {
6287
- const re2 = /^(?<prefix>\s*(?:\/usr\/bin\/env\s+)?node(?:\.exe)?\s+(?:-e|--eval)\s+)(['"])([\s\S]*?)\2(?<suffix>\s|$)/;
6288
- const m = cmd.match(re2);
6246
+ const re = /^(?<prefix>\s*(?:\/usr\/bin\/env\s+)?node(?:\.exe)?\s+(?:-e|--eval)\s+)(['"])([\s\S]*?)\2(?<suffix>\s|$)/;
6247
+ const m = cmd.match(re);
6289
6248
  if (!m || !m.groups) return cmd;
6290
6249
  const prefix = m.groups.prefix;
6291
6250
  const quote = m[2];
@@ -6293,7 +6252,7 @@ var init_command_check_provider = __esm({
6293
6252
  const suffix = m.groups.suffix || "";
6294
6253
  if (!code.includes("\n")) return cmd;
6295
6254
  const escaped = code.replace(/\n/g, "\\n");
6296
- return cmd.replace(re2, `${prefix}${quote}${escaped}${quote}${suffix}`);
6255
+ return cmd.replace(re, `${prefix}${quote}${escaped}${quote}${suffix}`);
6297
6256
  };
6298
6257
  const safeCommand = normalizeNodeEval(renderedCommand);
6299
6258
  const { stdout, stderr } = await execAsync(safeCommand, {
@@ -7371,7 +7330,7 @@ ${stderrOutput}` : `Command execution failed: ${errorMessage}`;
7371
7330
  }
7372
7331
  return null;
7373
7332
  }
7374
- async renderCommandTemplate(template, context2) {
7333
+ async renderCommandTemplate(template, context) {
7375
7334
  try {
7376
7335
  let tpl = template;
7377
7336
  if (tpl.includes("{{")) {
@@ -7380,10 +7339,10 @@ ${stderrOutput}` : `Command execution failed: ${errorMessage}`;
7380
7339
  return `{{ ${fixed} }}`;
7381
7340
  });
7382
7341
  }
7383
- let rendered = await this.liquid.parseAndRender(tpl, context2);
7342
+ let rendered = await this.liquid.parseAndRender(tpl, context);
7384
7343
  if (/\{\{[\s\S]*?\}\}/.test(rendered)) {
7385
7344
  try {
7386
- rendered = this.renderWithJsExpressions(rendered, context2);
7345
+ rendered = this.renderWithJsExpressions(rendered, context);
7387
7346
  } catch {
7388
7347
  }
7389
7348
  }
@@ -7391,18 +7350,18 @@ ${stderrOutput}` : `Command execution failed: ${errorMessage}`;
7391
7350
  } catch (error) {
7392
7351
  logger.debug(`\u{1F527} Debug: Liquid templating failed, trying JS-expression fallback: ${error}`);
7393
7352
  try {
7394
- return this.renderWithJsExpressions(template, context2);
7353
+ return this.renderWithJsExpressions(template, context);
7395
7354
  } catch {
7396
7355
  return template;
7397
7356
  }
7398
7357
  }
7399
7358
  }
7400
- renderWithJsExpressions(template, context2) {
7359
+ renderWithJsExpressions(template, context) {
7401
7360
  const scope = {
7402
- pr: context2.pr,
7403
- files: context2.files,
7404
- outputs: context2.outputs,
7405
- env: context2.env
7361
+ pr: context.pr,
7362
+ files: context.files,
7363
+ outputs: context.outputs,
7364
+ env: context.env
7406
7365
  };
7407
7366
  const expressionRegex = /\{\{\s*([^{}]+?)\s*\}\}/g;
7408
7367
  return template.replace(expressionRegex, (_match, expr) => {
@@ -7616,16 +7575,16 @@ var init_memory_check_provider = __esm({
7616
7575
  );
7617
7576
  return value;
7618
7577
  }
7619
- async handleSet(store, key, config, namespace, context2) {
7620
- const value = await this.computeValue(config, context2);
7578
+ async handleSet(store, key, config, namespace, context) {
7579
+ const value = await this.computeValue(config, context);
7621
7580
  await store.set(key, value, namespace);
7622
7581
  logger.debug(
7623
7582
  `Memory SET: ${namespace || store.getDefaultNamespace()}.${key} = ${JSON.stringify(value)}`
7624
7583
  );
7625
7584
  return value;
7626
7585
  }
7627
- async handleAppend(store, key, config, namespace, context2) {
7628
- const value = await this.computeValue(config, context2);
7586
+ async handleAppend(store, key, config, namespace, context) {
7587
+ const value = await this.computeValue(config, context);
7629
7588
  await store.append(key, value, namespace);
7630
7589
  const result = store.get(key, namespace);
7631
7590
  logger.debug(
@@ -7633,10 +7592,10 @@ var init_memory_check_provider = __esm({
7633
7592
  );
7634
7593
  return result;
7635
7594
  }
7636
- async handleIncrement(store, key, config, namespace, context2) {
7595
+ async handleIncrement(store, key, config, namespace, context) {
7637
7596
  let amount = 1;
7638
7597
  if (config.value !== void 0 || config.value_js) {
7639
- const computedValue = await this.computeValue(config, context2);
7598
+ const computedValue = await this.computeValue(config, context);
7640
7599
  if (typeof computedValue === "number") {
7641
7600
  amount = computedValue;
7642
7601
  } else {
@@ -7665,11 +7624,11 @@ var init_memory_check_provider = __esm({
7665
7624
  logger.debug(`Memory LIST: ${namespace || store.getDefaultNamespace()} (${keys.length} keys)`);
7666
7625
  return keys;
7667
7626
  }
7668
- async handleExecJs(store, config, context2) {
7627
+ async handleExecJs(store, config, context) {
7669
7628
  const script = config.memory_js;
7670
7629
  const pendingOps = [];
7671
7630
  const enhancedContext = {
7672
- ...context2,
7631
+ ...context,
7673
7632
  memory: {
7674
7633
  get: (key, ns) => store.get(key, ns),
7675
7634
  set: (key, value, ns) => {
@@ -7772,29 +7731,29 @@ var init_memory_check_provider = __esm({
7772
7731
  /**
7773
7732
  * Compute value from config using value, value_js, transform, or transform_js
7774
7733
  */
7775
- async computeValue(config, context2) {
7734
+ async computeValue(config, context) {
7776
7735
  let value;
7777
7736
  if (config.value_js && typeof config.value_js === "string") {
7778
- value = this.evaluateJavaScript(config.value_js, context2);
7737
+ value = this.evaluateJavaScript(config.value_js, context);
7779
7738
  } else {
7780
7739
  value = config.value;
7781
7740
  }
7782
7741
  if (config.transform && typeof config.transform === "string") {
7783
7742
  const rendered = await this.liquid.parseAndRender(config.transform, {
7784
- ...context2,
7743
+ ...context,
7785
7744
  value
7786
7745
  });
7787
7746
  value = rendered;
7788
7747
  }
7789
7748
  if (config.transform_js && typeof config.transform_js === "string") {
7790
- value = this.evaluateJavaScript(config.transform_js, { ...context2, value });
7749
+ value = this.evaluateJavaScript(config.transform_js, { ...context, value });
7791
7750
  }
7792
7751
  return value;
7793
7752
  }
7794
7753
  /**
7795
7754
  * Evaluate JavaScript expression in context using SandboxJS for secure execution
7796
7755
  */
7797
- evaluateJavaScript(expression, context2) {
7756
+ evaluateJavaScript(expression, context) {
7798
7757
  if (!this.sandbox) {
7799
7758
  this.sandbox = this.createSecureSandbox();
7800
7759
  }
@@ -7803,7 +7762,7 @@ var init_memory_check_provider = __esm({
7803
7762
  logger.info(`\u{1F50D} [memory-js] ${args.map((a) => JSON.stringify(a)).join(" ")}`);
7804
7763
  };
7805
7764
  const scope = {
7806
- ...context2,
7765
+ ...context,
7807
7766
  log: log2
7808
7767
  };
7809
7768
  const exec = this.sandbox.compile(`return (${expression});`);
@@ -7817,7 +7776,7 @@ var init_memory_check_provider = __esm({
7817
7776
  * Evaluate JavaScript block (multi-line script) using SandboxJS for secure execution
7818
7777
  * Unlike evaluateJavaScript, this supports full scripts with statements, not just expressions
7819
7778
  */
7820
- evaluateJavaScriptBlock(script, context2) {
7779
+ evaluateJavaScriptBlock(script, context) {
7821
7780
  if (!this.sandbox) {
7822
7781
  this.sandbox = this.createSecureSandbox();
7823
7782
  }
@@ -7826,7 +7785,7 @@ var init_memory_check_provider = __esm({
7826
7785
  logger.info(`\u{1F50D} [memory-js] ${args.map((a) => JSON.stringify(a)).join(" ")}`);
7827
7786
  };
7828
7787
  const scope = {
7829
- ...context2,
7788
+ ...context,
7830
7789
  log: log2
7831
7790
  };
7832
7791
  const exec = this.sandbox.compile(script);
@@ -7842,8 +7801,8 @@ var init_memory_check_provider = __esm({
7842
7801
  * Build template context for Liquid and JS evaluation
7843
7802
  */
7844
7803
  buildTemplateContext(prInfo, dependencyResults, memoryStore, outputHistory) {
7845
- const context2 = {};
7846
- context2.pr = {
7804
+ const context = {};
7805
+ context.pr = {
7847
7806
  number: prInfo.number,
7848
7807
  title: prInfo.title,
7849
7808
  body: prInfo.body,
@@ -7874,16 +7833,16 @@ var init_memory_check_provider = __esm({
7874
7833
  }
7875
7834
  }
7876
7835
  outputs.history = history;
7877
- context2.outputs = outputs;
7836
+ context.outputs = outputs;
7878
7837
  if (memoryStore) {
7879
- context2.memory = {
7838
+ context.memory = {
7880
7839
  get: (key, ns) => memoryStore.get(key, ns),
7881
7840
  has: (key, ns) => memoryStore.has(key, ns),
7882
7841
  list: (ns) => memoryStore.list(ns),
7883
7842
  getAll: (ns) => memoryStore.getAll(ns)
7884
7843
  };
7885
7844
  }
7886
- return context2;
7845
+ return context;
7887
7846
  }
7888
7847
  getSupportedConfigKeys() {
7889
7848
  return [
@@ -7919,134 +7878,730 @@ var init_memory_check_provider = __esm({
7919
7878
  }
7920
7879
  });
7921
7880
 
7922
- // src/providers/check-provider-registry.ts
7923
- var CheckProviderRegistry;
7924
- var init_check_provider_registry = __esm({
7925
- "src/providers/check-provider-registry.ts"() {
7881
+ // src/providers/mcp-check-provider.ts
7882
+ var import_client, import_stdio, import_sse, import_streamableHttp, import_sandboxjs4, McpCheckProvider;
7883
+ var init_mcp_check_provider = __esm({
7884
+ "src/providers/mcp-check-provider.ts"() {
7926
7885
  "use strict";
7927
- init_ai_check_provider();
7928
- init_http_check_provider();
7929
- init_http_input_provider();
7930
- init_http_client_provider();
7931
- init_noop_check_provider();
7932
- init_log_check_provider();
7933
- init_github_ops_provider();
7934
- init_claude_code_check_provider();
7935
- init_command_check_provider();
7936
- init_memory_check_provider();
7937
- CheckProviderRegistry = class _CheckProviderRegistry {
7938
- providers = /* @__PURE__ */ new Map();
7939
- static instance;
7886
+ init_check_provider_interface();
7887
+ init_logger();
7888
+ init_liquid_extensions();
7889
+ import_client = require("@modelcontextprotocol/sdk/client/index.js");
7890
+ import_stdio = require("@modelcontextprotocol/sdk/client/stdio.js");
7891
+ import_sse = require("@modelcontextprotocol/sdk/client/sse.js");
7892
+ import_streamableHttp = require("@modelcontextprotocol/sdk/client/streamableHttp.js");
7893
+ import_sandboxjs4 = __toESM(require("@nyariv/sandboxjs"));
7894
+ McpCheckProvider = class extends CheckProvider {
7895
+ liquid;
7896
+ sandbox;
7940
7897
  constructor() {
7941
- this.registerDefaultProviders();
7898
+ super();
7899
+ this.liquid = createExtendedLiquid({
7900
+ cache: false,
7901
+ strictFilters: false,
7902
+ strictVariables: false
7903
+ });
7942
7904
  }
7943
7905
  /**
7944
- * Get singleton instance
7906
+ * Create a secure sandbox for JavaScript execution
7907
+ * - Uses Sandbox.SAFE_GLOBALS which excludes: Function, eval, require, process, etc.
7908
+ * - Only allows explicitly whitelisted prototype methods
7909
+ * - No access to filesystem, network, or system resources
7945
7910
  */
7946
- static getInstance() {
7947
- if (!_CheckProviderRegistry.instance) {
7948
- _CheckProviderRegistry.instance = new _CheckProviderRegistry();
7949
- }
7950
- return _CheckProviderRegistry.instance;
7911
+ createSecureSandbox() {
7912
+ const log2 = (...args) => {
7913
+ logger.debug(`[transform_js] ${args.map((a) => JSON.stringify(a)).join(" ")}`);
7914
+ };
7915
+ const globals = {
7916
+ ...import_sandboxjs4.default.SAFE_GLOBALS,
7917
+ // Excludes Function, eval, require, process, etc.
7918
+ Math,
7919
+ JSON,
7920
+ console: {
7921
+ log: log2
7922
+ }
7923
+ };
7924
+ const prototypeWhitelist = new Map(import_sandboxjs4.default.SAFE_PROTOTYPES);
7925
+ const arrayMethods = /* @__PURE__ */ new Set([
7926
+ "some",
7927
+ "every",
7928
+ "filter",
7929
+ "map",
7930
+ "reduce",
7931
+ "find",
7932
+ "includes",
7933
+ "indexOf",
7934
+ "length",
7935
+ "slice",
7936
+ "concat",
7937
+ "join",
7938
+ "push",
7939
+ "pop",
7940
+ "shift",
7941
+ "unshift",
7942
+ "sort",
7943
+ "reverse",
7944
+ "flat",
7945
+ "flatMap"
7946
+ ]);
7947
+ prototypeWhitelist.set(Array.prototype, arrayMethods);
7948
+ const stringMethods = /* @__PURE__ */ new Set([
7949
+ "toLowerCase",
7950
+ "toUpperCase",
7951
+ "includes",
7952
+ "indexOf",
7953
+ "startsWith",
7954
+ "endsWith",
7955
+ "slice",
7956
+ "substring",
7957
+ "length",
7958
+ "trim",
7959
+ "split",
7960
+ "replace",
7961
+ // String.prototype.replace for text manipulation (e.g., "hello".replace("h", "H"))
7962
+ "match",
7963
+ "padStart",
7964
+ "padEnd"
7965
+ ]);
7966
+ prototypeWhitelist.set(String.prototype, stringMethods);
7967
+ const objectMethods = /* @__PURE__ */ new Set(["hasOwnProperty", "toString", "valueOf", "keys", "values"]);
7968
+ prototypeWhitelist.set(Object.prototype, objectMethods);
7969
+ return new import_sandboxjs4.default({
7970
+ globals,
7971
+ prototypeWhitelist
7972
+ });
7951
7973
  }
7952
- /**
7953
- * Register default built-in providers
7954
- */
7955
- registerDefaultProviders() {
7956
- this.register(new AICheckProvider());
7957
- this.register(new CommandCheckProvider());
7958
- this.register(new HttpCheckProvider());
7959
- this.register(new HttpInputProvider());
7960
- this.register(new HttpClientProvider());
7961
- this.register(new NoopCheckProvider());
7962
- this.register(new LogCheckProvider());
7963
- this.register(new MemoryCheckProvider());
7964
- this.register(new GitHubOpsProvider());
7965
- try {
7966
- this.register(new ClaudeCodeCheckProvider());
7967
- } catch (error) {
7968
- console.error(
7969
- `Warning: Failed to register ClaudeCodeCheckProvider: ${error instanceof Error ? error.message : "Unknown error"}`
7970
- );
7971
- }
7974
+ getName() {
7975
+ return "mcp";
7972
7976
  }
7973
- /**
7974
- * Register a check provider
7975
- */
7976
- register(provider) {
7977
- const name = provider.getName();
7978
- if (this.providers.has(name)) {
7979
- throw new Error(`Provider '${name}' is already registered`);
7980
- }
7981
- this.providers.set(name, provider);
7982
- if (process.env.VISOR_DEBUG === "true") {
7983
- console.error(`Registered check provider: ${name}`);
7984
- }
7977
+ getDescription() {
7978
+ return "Call MCP tools directly using stdio, SSE, or Streamable HTTP transport";
7985
7979
  }
7986
- /**
7987
- * Unregister a check provider
7988
- */
7989
- unregister(name) {
7990
- if (!this.providers.has(name)) {
7991
- throw new Error(`Provider '${name}' not found`);
7980
+ async validateConfig(config) {
7981
+ if (!config || typeof config !== "object") {
7982
+ return false;
7992
7983
  }
7993
- this.providers.delete(name);
7994
- console.error(`Unregistered check provider: ${name}`);
7995
- }
7996
- /**
7997
- * Get a provider by name
7998
- */
7999
- getProvider(name) {
8000
- return this.providers.get(name);
8001
- }
8002
- /**
8003
- * Get provider or throw if not found
8004
- */
8005
- getProviderOrThrow(name) {
8006
- const provider = this.providers.get(name);
8007
- if (!provider) {
8008
- throw new Error(
8009
- `Check provider '${name}' not found. Available providers: ${this.getAvailableProviders().join(", ")}`
8010
- );
7984
+ const cfg = config;
7985
+ if (!cfg.method || typeof cfg.method !== "string") {
7986
+ logger.error("MCP check requires a method name");
7987
+ return false;
8011
7988
  }
8012
- return provider;
8013
- }
8014
- /**
8015
- * Check if a provider exists
8016
- */
8017
- hasProvider(name) {
8018
- return this.providers.has(name);
8019
- }
8020
- /**
8021
- * Get all registered provider names
8022
- */
8023
- getAvailableProviders() {
8024
- return Array.from(this.providers.keys());
8025
- }
8026
- /**
8027
- * Get all providers
8028
- */
8029
- getAllProviders() {
8030
- return Array.from(this.providers.values());
8031
- }
8032
- /**
8033
- * Get providers that are currently available (have required dependencies)
8034
- */
8035
- async getActiveProviders() {
8036
- const providers = this.getAllProviders();
8037
- const activeProviders = [];
8038
- for (const provider of providers) {
8039
- if (await provider.isAvailable()) {
8040
- activeProviders.push(provider);
7989
+ const transport = cfg.transport || "stdio";
7990
+ if (transport === "stdio") {
7991
+ if (!cfg.command || typeof cfg.command !== "string") {
7992
+ logger.error("MCP stdio transport requires a command");
7993
+ return false;
7994
+ }
7995
+ if (/[;&|`$(){}[\]]/.test(cfg.command)) {
7996
+ logger.error("MCP stdio command contains potentially unsafe characters");
7997
+ return false;
7998
+ }
7999
+ } else if (transport === "sse" || transport === "http") {
8000
+ if (!cfg.url || typeof cfg.url !== "string") {
8001
+ logger.error(`MCP ${transport} transport requires a URL`);
8002
+ return false;
8003
+ }
8004
+ try {
8005
+ const parsedUrl = new URL(cfg.url);
8006
+ if (parsedUrl.protocol !== "http:" && parsedUrl.protocol !== "https:") {
8007
+ logger.error(
8008
+ `Invalid URL protocol for MCP ${transport} transport: ${parsedUrl.protocol}. Only http: and https: are allowed.`
8009
+ );
8010
+ return false;
8011
+ }
8012
+ } catch {
8013
+ logger.error(`Invalid URL format for MCP ${transport} transport: ${cfg.url}`);
8014
+ return false;
8041
8015
  }
8016
+ } else {
8017
+ logger.error(`Invalid MCP transport: ${transport}. Must be 'stdio', 'sse', or 'http'`);
8018
+ return false;
8042
8019
  }
8043
- return activeProviders;
8020
+ return true;
8044
8021
  }
8045
- /**
8046
- * List provider information
8047
- */
8048
- async listProviders() {
8049
- const providers = this.getAllProviders();
8022
+ async execute(prInfo, config, dependencyResults) {
8023
+ const cfg = config;
8024
+ try {
8025
+ const templateContext = {
8026
+ pr: {
8027
+ number: prInfo.number,
8028
+ title: prInfo.title,
8029
+ author: prInfo.author,
8030
+ branch: prInfo.head,
8031
+ base: prInfo.base
8032
+ },
8033
+ files: prInfo.files,
8034
+ fileCount: prInfo.files.length,
8035
+ outputs: this.buildOutputContext(dependencyResults),
8036
+ env: this.getSafeEnvironmentVariables()
8037
+ };
8038
+ let methodArgs = cfg.methodArgs || {};
8039
+ if (cfg.argsTransform) {
8040
+ const rendered = await this.liquid.parseAndRender(cfg.argsTransform, templateContext);
8041
+ try {
8042
+ methodArgs = JSON.parse(rendered);
8043
+ } catch (error) {
8044
+ logger.error(`Failed to parse argsTransform as JSON: ${error}`);
8045
+ return {
8046
+ issues: [
8047
+ {
8048
+ file: "mcp",
8049
+ line: 0,
8050
+ ruleId: "mcp/args_transform_error",
8051
+ message: `Failed to parse argsTransform: ${error instanceof Error ? error.message : "Unknown error"}`,
8052
+ severity: "error",
8053
+ category: "logic"
8054
+ }
8055
+ ]
8056
+ };
8057
+ }
8058
+ }
8059
+ const result = await this.executeMcpMethod(cfg, methodArgs);
8060
+ let finalOutput = result;
8061
+ if (cfg.transform) {
8062
+ try {
8063
+ const transformContext = {
8064
+ ...templateContext,
8065
+ output: result
8066
+ };
8067
+ const rendered = await this.liquid.parseAndRender(cfg.transform, transformContext);
8068
+ try {
8069
+ finalOutput = JSON.parse(rendered.trim());
8070
+ } catch {
8071
+ finalOutput = rendered.trim();
8072
+ }
8073
+ } catch (error) {
8074
+ logger.error(`Failed to apply Liquid transform: ${error}`);
8075
+ return {
8076
+ issues: [
8077
+ {
8078
+ file: "mcp",
8079
+ line: 0,
8080
+ ruleId: "mcp/transform_error",
8081
+ message: `Failed to apply transform: ${error instanceof Error ? error.message : "Unknown error"}`,
8082
+ severity: "error",
8083
+ category: "logic"
8084
+ }
8085
+ ]
8086
+ };
8087
+ }
8088
+ }
8089
+ if (cfg.transform_js) {
8090
+ try {
8091
+ if (!this.sandbox) {
8092
+ this.sandbox = this.createSecureSandbox();
8093
+ }
8094
+ const scope = {
8095
+ output: finalOutput,
8096
+ pr: templateContext.pr,
8097
+ files: templateContext.files,
8098
+ outputs: templateContext.outputs,
8099
+ env: templateContext.env
8100
+ };
8101
+ const exec = this.sandbox.compile(`return (${cfg.transform_js});`);
8102
+ finalOutput = exec(scope).run();
8103
+ } catch (error) {
8104
+ logger.error(`Failed to apply JavaScript transform: ${error}`);
8105
+ return {
8106
+ issues: [
8107
+ {
8108
+ file: "mcp",
8109
+ line: 0,
8110
+ ruleId: "mcp/transform_js_error",
8111
+ message: `Failed to apply JavaScript transform: ${error instanceof Error ? error.message : "Unknown error"}`,
8112
+ severity: "error",
8113
+ category: "logic"
8114
+ }
8115
+ ]
8116
+ };
8117
+ }
8118
+ }
8119
+ const extracted = this.extractIssuesFromOutput(finalOutput);
8120
+ if (extracted) {
8121
+ return {
8122
+ issues: extracted.issues,
8123
+ ...extracted.remainingOutput ? { output: extracted.remainingOutput } : {}
8124
+ };
8125
+ }
8126
+ return {
8127
+ issues: [],
8128
+ ...finalOutput ? { output: finalOutput } : {}
8129
+ };
8130
+ } catch (error) {
8131
+ const errorMessage = error instanceof Error ? error.message : "Unknown error";
8132
+ logger.error(`MCP check failed: ${errorMessage}`);
8133
+ return {
8134
+ issues: [
8135
+ {
8136
+ file: "mcp",
8137
+ line: 0,
8138
+ ruleId: "mcp/execution_error",
8139
+ message: `MCP check failed: ${errorMessage}`,
8140
+ severity: "error",
8141
+ category: "logic"
8142
+ }
8143
+ ]
8144
+ };
8145
+ }
8146
+ }
8147
+ /**
8148
+ * Execute an MCP method using the configured transport
8149
+ */
8150
+ async executeMcpMethod(config, methodArgs) {
8151
+ const transport = config.transport || "stdio";
8152
+ const timeout = (config.timeout || 60) * 1e3;
8153
+ if (transport === "stdio") {
8154
+ return await this.executeStdioMethod(config, methodArgs, timeout);
8155
+ } else if (transport === "sse") {
8156
+ return await this.executeSseMethod(config, methodArgs, timeout);
8157
+ } else if (transport === "http") {
8158
+ return await this.executeHttpMethod(config, methodArgs, timeout);
8159
+ } else {
8160
+ throw new Error(`Unsupported transport: ${transport}`);
8161
+ }
8162
+ }
8163
+ /**
8164
+ * Generic method to execute MCP method with any transport
8165
+ */
8166
+ async executeWithTransport(transport, config, methodArgs, timeout, transportName) {
8167
+ const client = new import_client.Client(
8168
+ {
8169
+ name: "visor-mcp-client",
8170
+ version: "1.0.0"
8171
+ },
8172
+ {
8173
+ capabilities: {}
8174
+ }
8175
+ );
8176
+ try {
8177
+ let timeoutId;
8178
+ try {
8179
+ await Promise.race([
8180
+ client.connect(transport),
8181
+ new Promise((_, reject) => {
8182
+ timeoutId = setTimeout(() => reject(new Error("Connection timeout")), timeout);
8183
+ })
8184
+ ]);
8185
+ } finally {
8186
+ if (timeoutId) {
8187
+ clearTimeout(timeoutId);
8188
+ }
8189
+ }
8190
+ logger.debug(`Connected to MCP server via ${transportName}`);
8191
+ if (transport instanceof import_streamableHttp.StreamableHTTPClientTransport && transport.sessionId) {
8192
+ logger.debug(`MCP Session ID: ${transport.sessionId}`);
8193
+ }
8194
+ try {
8195
+ const toolsResult = await client.listTools();
8196
+ logger.debug(`Available MCP tools: ${JSON.stringify(toolsResult?.tools || [])}`);
8197
+ } catch (error) {
8198
+ logger.debug(`Could not list MCP tools: ${error}`);
8199
+ }
8200
+ let callTimeoutId;
8201
+ try {
8202
+ const result = await Promise.race([
8203
+ client.callTool({
8204
+ name: config.method,
8205
+ arguments: methodArgs
8206
+ }),
8207
+ new Promise((_, reject) => {
8208
+ callTimeoutId = setTimeout(() => reject(new Error("Request timeout")), timeout);
8209
+ })
8210
+ ]);
8211
+ logger.debug(`MCP method result: ${JSON.stringify(result)}`);
8212
+ return result;
8213
+ } finally {
8214
+ if (callTimeoutId) {
8215
+ clearTimeout(callTimeoutId);
8216
+ }
8217
+ }
8218
+ } finally {
8219
+ try {
8220
+ await client.close();
8221
+ } catch (error) {
8222
+ logger.debug(`Error closing MCP client: ${error}`);
8223
+ }
8224
+ }
8225
+ }
8226
+ /**
8227
+ * Execute MCP method using stdio transport
8228
+ */
8229
+ async executeStdioMethod(config, methodArgs, timeout) {
8230
+ const transport = new import_stdio.StdioClientTransport({
8231
+ command: config.command,
8232
+ args: config.args,
8233
+ env: config.env,
8234
+ cwd: config.workingDirectory
8235
+ });
8236
+ return this.executeWithTransport(
8237
+ transport,
8238
+ config,
8239
+ methodArgs,
8240
+ timeout,
8241
+ `stdio: ${config.command}`
8242
+ );
8243
+ }
8244
+ /**
8245
+ * Execute MCP method using SSE transport
8246
+ */
8247
+ async executeSseMethod(config, methodArgs, timeout) {
8248
+ const requestInit = {};
8249
+ if (config.headers) {
8250
+ requestInit.headers = config.headers;
8251
+ }
8252
+ const transport = new import_sse.SSEClientTransport(new URL(config.url), {
8253
+ requestInit
8254
+ });
8255
+ return this.executeWithTransport(transport, config, methodArgs, timeout, `SSE: ${config.url}`);
8256
+ }
8257
+ /**
8258
+ * Execute MCP method using Streamable HTTP transport
8259
+ */
8260
+ async executeHttpMethod(config, methodArgs, timeout) {
8261
+ const requestInit = {};
8262
+ if (config.headers) {
8263
+ requestInit.headers = config.headers;
8264
+ }
8265
+ const transport = new import_streamableHttp.StreamableHTTPClientTransport(new URL(config.url), {
8266
+ requestInit,
8267
+ sessionId: config.sessionId
8268
+ });
8269
+ return this.executeWithTransport(
8270
+ transport,
8271
+ config,
8272
+ methodArgs,
8273
+ timeout,
8274
+ `Streamable HTTP: ${config.url}`
8275
+ );
8276
+ }
8277
+ /**
8278
+ * Build output context from dependency results
8279
+ */
8280
+ buildOutputContext(dependencyResults) {
8281
+ if (!dependencyResults) {
8282
+ return {};
8283
+ }
8284
+ const outputs = {};
8285
+ for (const [checkName, result] of dependencyResults) {
8286
+ const summary = result;
8287
+ outputs[checkName] = summary.output !== void 0 ? summary.output : summary;
8288
+ }
8289
+ return outputs;
8290
+ }
8291
+ /**
8292
+ * Get safe environment variables
8293
+ */
8294
+ getSafeEnvironmentVariables() {
8295
+ const safeVars = {};
8296
+ const allowedPrefixes = ["CI_", "GITHUB_", "RUNNER_", "NODE_", "npm_", "PATH", "HOME", "USER"];
8297
+ for (const [key, value] of Object.entries(process.env)) {
8298
+ if (value !== void 0 && allowedPrefixes.some((prefix) => key.startsWith(prefix))) {
8299
+ safeVars[key] = value;
8300
+ }
8301
+ }
8302
+ safeVars["PWD"] = process.cwd();
8303
+ return safeVars;
8304
+ }
8305
+ /**
8306
+ * Extract issues from MCP output
8307
+ */
8308
+ extractIssuesFromOutput(output) {
8309
+ if (output === null || output === void 0) {
8310
+ return null;
8311
+ }
8312
+ if (typeof output === "string") {
8313
+ try {
8314
+ const parsed = JSON.parse(output);
8315
+ return this.extractIssuesFromOutput(parsed);
8316
+ } catch {
8317
+ return null;
8318
+ }
8319
+ }
8320
+ if (Array.isArray(output)) {
8321
+ const issues = this.normalizeIssueArray(output);
8322
+ if (issues) {
8323
+ return { issues, remainingOutput: void 0 };
8324
+ }
8325
+ return null;
8326
+ }
8327
+ if (typeof output === "object") {
8328
+ const record = output;
8329
+ if (Array.isArray(record.issues)) {
8330
+ const issues = this.normalizeIssueArray(record.issues);
8331
+ if (!issues) {
8332
+ return null;
8333
+ }
8334
+ const remaining = { ...record };
8335
+ delete remaining.issues;
8336
+ return {
8337
+ issues,
8338
+ remainingOutput: Object.keys(remaining).length > 0 ? remaining : void 0
8339
+ };
8340
+ }
8341
+ const singleIssue = this.normalizeIssue(record);
8342
+ if (singleIssue) {
8343
+ return { issues: [singleIssue], remainingOutput: void 0 };
8344
+ }
8345
+ }
8346
+ return null;
8347
+ }
8348
+ /**
8349
+ * Normalize an array of issues
8350
+ */
8351
+ normalizeIssueArray(values) {
8352
+ const normalized = [];
8353
+ for (const value of values) {
8354
+ const issue = this.normalizeIssue(value);
8355
+ if (!issue) {
8356
+ return null;
8357
+ }
8358
+ normalized.push(issue);
8359
+ }
8360
+ return normalized;
8361
+ }
8362
+ /**
8363
+ * Normalize a single issue
8364
+ */
8365
+ normalizeIssue(raw) {
8366
+ if (!raw || typeof raw !== "object") {
8367
+ return null;
8368
+ }
8369
+ const data = raw;
8370
+ const message = this.toTrimmedString(
8371
+ data.message || data.text || data.description || data.summary
8372
+ );
8373
+ if (!message) {
8374
+ return null;
8375
+ }
8376
+ const allowedSeverities = /* @__PURE__ */ new Set(["info", "warning", "error", "critical"]);
8377
+ const severityRaw = this.toTrimmedString(data.severity || data.level || data.priority);
8378
+ let severity = "warning";
8379
+ if (severityRaw) {
8380
+ const lower = severityRaw.toLowerCase();
8381
+ if (allowedSeverities.has(lower)) {
8382
+ severity = lower;
8383
+ }
8384
+ }
8385
+ const allowedCategories = /* @__PURE__ */ new Set([
8386
+ "security",
8387
+ "performance",
8388
+ "style",
8389
+ "logic",
8390
+ "documentation"
8391
+ ]);
8392
+ const categoryRaw = this.toTrimmedString(data.category || data.type || data.group);
8393
+ let category = "logic";
8394
+ if (categoryRaw && allowedCategories.has(categoryRaw.toLowerCase())) {
8395
+ category = categoryRaw.toLowerCase();
8396
+ }
8397
+ const file = this.toTrimmedString(data.file || data.path || data.filename) || "system";
8398
+ const line = this.toNumber(data.line || data.startLine || data.lineNumber) ?? 0;
8399
+ const endLine = this.toNumber(data.endLine || data.end_line || data.stopLine);
8400
+ const suggestion = this.toTrimmedString(data.suggestion);
8401
+ const replacement = this.toTrimmedString(data.replacement);
8402
+ const ruleId = this.toTrimmedString(data.ruleId || data.rule || data.id || data.check) || "mcp";
8403
+ return {
8404
+ file,
8405
+ line,
8406
+ endLine: endLine ?? void 0,
8407
+ ruleId,
8408
+ message,
8409
+ severity,
8410
+ category,
8411
+ suggestion: suggestion || void 0,
8412
+ replacement: replacement || void 0
8413
+ };
8414
+ }
8415
+ toTrimmedString(value) {
8416
+ if (typeof value === "string") {
8417
+ const trimmed = value.trim();
8418
+ return trimmed.length > 0 ? trimmed : null;
8419
+ }
8420
+ if (value !== null && value !== void 0 && typeof value.toString === "function") {
8421
+ const converted = String(value).trim();
8422
+ return converted.length > 0 ? converted : null;
8423
+ }
8424
+ return null;
8425
+ }
8426
+ toNumber(value) {
8427
+ if (value === null || value === void 0) {
8428
+ return null;
8429
+ }
8430
+ const num = Number(value);
8431
+ if (Number.isFinite(num)) {
8432
+ return Math.trunc(num);
8433
+ }
8434
+ return null;
8435
+ }
8436
+ getSupportedConfigKeys() {
8437
+ return [
8438
+ "type",
8439
+ "transport",
8440
+ "command",
8441
+ "args",
8442
+ "env",
8443
+ "workingDirectory",
8444
+ "url",
8445
+ "headers",
8446
+ "sessionId",
8447
+ "method",
8448
+ "methodArgs",
8449
+ "argsTransform",
8450
+ "transform",
8451
+ "transform_js",
8452
+ "timeout",
8453
+ "depends_on",
8454
+ "on",
8455
+ "if",
8456
+ "group"
8457
+ ];
8458
+ }
8459
+ async isAvailable() {
8460
+ return true;
8461
+ }
8462
+ getRequirements() {
8463
+ return ["MCP method name specified", "Transport configuration (stdio: command, sse/http: url)"];
8464
+ }
8465
+ };
8466
+ }
8467
+ });
8468
+
8469
+ // src/providers/check-provider-registry.ts
8470
+ var CheckProviderRegistry;
8471
+ var init_check_provider_registry = __esm({
8472
+ "src/providers/check-provider-registry.ts"() {
8473
+ "use strict";
8474
+ init_ai_check_provider();
8475
+ init_http_check_provider();
8476
+ init_http_input_provider();
8477
+ init_http_client_provider();
8478
+ init_noop_check_provider();
8479
+ init_log_check_provider();
8480
+ init_github_ops_provider();
8481
+ init_claude_code_check_provider();
8482
+ init_command_check_provider();
8483
+ init_memory_check_provider();
8484
+ init_mcp_check_provider();
8485
+ CheckProviderRegistry = class _CheckProviderRegistry {
8486
+ providers = /* @__PURE__ */ new Map();
8487
+ static instance;
8488
+ constructor() {
8489
+ this.registerDefaultProviders();
8490
+ }
8491
+ /**
8492
+ * Get singleton instance
8493
+ */
8494
+ static getInstance() {
8495
+ if (!_CheckProviderRegistry.instance) {
8496
+ _CheckProviderRegistry.instance = new _CheckProviderRegistry();
8497
+ }
8498
+ return _CheckProviderRegistry.instance;
8499
+ }
8500
+ /**
8501
+ * Register default built-in providers
8502
+ */
8503
+ registerDefaultProviders() {
8504
+ this.register(new AICheckProvider());
8505
+ this.register(new CommandCheckProvider());
8506
+ this.register(new HttpCheckProvider());
8507
+ this.register(new HttpInputProvider());
8508
+ this.register(new HttpClientProvider());
8509
+ this.register(new NoopCheckProvider());
8510
+ this.register(new LogCheckProvider());
8511
+ this.register(new MemoryCheckProvider());
8512
+ this.register(new GitHubOpsProvider());
8513
+ try {
8514
+ this.register(new ClaudeCodeCheckProvider());
8515
+ } catch (error) {
8516
+ console.error(
8517
+ `Warning: Failed to register ClaudeCodeCheckProvider: ${error instanceof Error ? error.message : "Unknown error"}`
8518
+ );
8519
+ }
8520
+ try {
8521
+ this.register(new McpCheckProvider());
8522
+ } catch (error) {
8523
+ console.error(
8524
+ `Warning: Failed to register McpCheckProvider: ${error instanceof Error ? error.message : "Unknown error"}`
8525
+ );
8526
+ }
8527
+ }
8528
+ /**
8529
+ * Register a check provider
8530
+ */
8531
+ register(provider) {
8532
+ const name = provider.getName();
8533
+ if (this.providers.has(name)) {
8534
+ throw new Error(`Provider '${name}' is already registered`);
8535
+ }
8536
+ this.providers.set(name, provider);
8537
+ if (process.env.VISOR_DEBUG === "true") {
8538
+ console.error(`Registered check provider: ${name}`);
8539
+ }
8540
+ }
8541
+ /**
8542
+ * Unregister a check provider
8543
+ */
8544
+ unregister(name) {
8545
+ if (!this.providers.has(name)) {
8546
+ throw new Error(`Provider '${name}' not found`);
8547
+ }
8548
+ this.providers.delete(name);
8549
+ console.error(`Unregistered check provider: ${name}`);
8550
+ }
8551
+ /**
8552
+ * Get a provider by name
8553
+ */
8554
+ getProvider(name) {
8555
+ return this.providers.get(name);
8556
+ }
8557
+ /**
8558
+ * Get provider or throw if not found
8559
+ */
8560
+ getProviderOrThrow(name) {
8561
+ const provider = this.providers.get(name);
8562
+ if (!provider) {
8563
+ throw new Error(
8564
+ `Check provider '${name}' not found. Available providers: ${this.getAvailableProviders().join(", ")}`
8565
+ );
8566
+ }
8567
+ return provider;
8568
+ }
8569
+ /**
8570
+ * Check if a provider exists
8571
+ */
8572
+ hasProvider(name) {
8573
+ return this.providers.has(name);
8574
+ }
8575
+ /**
8576
+ * Get all registered provider names
8577
+ */
8578
+ getAvailableProviders() {
8579
+ return Array.from(this.providers.keys());
8580
+ }
8581
+ /**
8582
+ * Get all providers
8583
+ */
8584
+ getAllProviders() {
8585
+ return Array.from(this.providers.values());
8586
+ }
8587
+ /**
8588
+ * Get providers that are currently available (have required dependencies)
8589
+ */
8590
+ async getActiveProviders() {
8591
+ const providers = this.getAllProviders();
8592
+ const activeProviders = [];
8593
+ for (const provider of providers) {
8594
+ if (await provider.isAvailable()) {
8595
+ activeProviders.push(provider);
8596
+ }
8597
+ }
8598
+ return activeProviders;
8599
+ }
8600
+ /**
8601
+ * List provider information
8602
+ */
8603
+ async listProviders() {
8604
+ const providers = this.getAllProviders();
8050
8605
  const info = [];
8051
8606
  for (const provider of providers) {
8052
8607
  info.push({
@@ -8185,1219 +8740,87 @@ var init_dependency_resolver = __esm({
8185
8740
  }
8186
8741
  level++;
8187
8742
  }
8188
- return executionGroups;
8189
- }
8190
- /**
8191
- * Validate that all dependencies exist
8192
- */
8193
- static validateDependencies(checkIds, dependencies) {
8194
- const errors = [];
8195
- const checkIdSet = new Set(checkIds);
8196
- for (const [checkId, deps] of Object.entries(dependencies)) {
8197
- if (!checkIdSet.has(checkId)) {
8198
- errors.push(`Check "${checkId}" is not in the list of available checks`);
8199
- continue;
8200
- }
8201
- for (const depId of deps || []) {
8202
- if (!checkIdSet.has(depId)) {
8203
- errors.push(`Check "${checkId}" depends on "${depId}" which is not available`);
8204
- }
8205
- }
8206
- }
8207
- return {
8208
- valid: errors.length === 0,
8209
- errors
8210
- };
8211
- }
8212
- /**
8213
- * Get all transitive dependencies (ancestors) for a given check
8214
- * This returns all checks that must complete before the given check can run,
8215
- * not just the direct dependencies.
8216
- *
8217
- * For example, if A -> B -> C, then:
8218
- * - getAllDependencies(C) returns [A, B]
8219
- * - getAllDependencies(B) returns [A]
8220
- * - getAllDependencies(A) returns []
8221
- *
8222
- * @param checkId The check to find dependencies for
8223
- * @param nodes The dependency graph nodes
8224
- * @returns Array of all transitive dependency IDs
8225
- */
8226
- static getAllDependencies(checkId, nodes) {
8227
- const allDeps = /* @__PURE__ */ new Set();
8228
- const visited = /* @__PURE__ */ new Set();
8229
- const collectDependencies = (currentId) => {
8230
- if (visited.has(currentId)) {
8231
- return;
8232
- }
8233
- visited.add(currentId);
8234
- const node = nodes.get(currentId);
8235
- if (!node) {
8236
- return;
8237
- }
8238
- for (const depId of node.dependencies) {
8239
- allDeps.add(depId);
8240
- collectDependencies(depId);
8241
- }
8242
- };
8243
- collectDependencies(checkId);
8244
- return Array.from(allDeps);
8245
- }
8246
- /**
8247
- * Get execution statistics for debugging
8248
- */
8249
- static getExecutionStats(graph) {
8250
- const totalChecks = graph.nodes.size;
8251
- const parallelLevels = graph.executionOrder.length;
8252
- const maxParallelism = Math.max(...graph.executionOrder.map((group) => group.parallel.length));
8253
- const averageParallelism = totalChecks / parallelLevels;
8254
- const checksWithDependencies = Array.from(graph.nodes.values()).filter(
8255
- (node) => node.dependencies.length > 0
8256
- ).length;
8257
- return {
8258
- totalChecks,
8259
- parallelLevels,
8260
- maxParallelism,
8261
- averageParallelism,
8262
- checksWithDependencies
8263
- };
8264
- }
8265
- };
8266
- }
8267
- });
8268
-
8269
- // node_modules/@opentelemetry/api/build/esm/platform/node/globalThis.js
8270
- var _globalThis;
8271
- var init_globalThis = __esm({
8272
- "node_modules/@opentelemetry/api/build/esm/platform/node/globalThis.js"() {
8273
- "use strict";
8274
- _globalThis = typeof globalThis === "object" ? globalThis : global;
8275
- }
8276
- });
8277
-
8278
- // node_modules/@opentelemetry/api/build/esm/platform/node/index.js
8279
- var init_node = __esm({
8280
- "node_modules/@opentelemetry/api/build/esm/platform/node/index.js"() {
8281
- "use strict";
8282
- init_globalThis();
8283
- }
8284
- });
8285
-
8286
- // node_modules/@opentelemetry/api/build/esm/platform/index.js
8287
- var init_platform = __esm({
8288
- "node_modules/@opentelemetry/api/build/esm/platform/index.js"() {
8289
- "use strict";
8290
- init_node();
8291
- }
8292
- });
8293
-
8294
- // node_modules/@opentelemetry/api/build/esm/version.js
8295
- var VERSION;
8296
- var init_version = __esm({
8297
- "node_modules/@opentelemetry/api/build/esm/version.js"() {
8298
- "use strict";
8299
- VERSION = "1.9.0";
8300
- }
8301
- });
8302
-
8303
- // node_modules/@opentelemetry/api/build/esm/internal/semver.js
8304
- function _makeCompatibilityCheck(ownVersion) {
8305
- var acceptedVersions = /* @__PURE__ */ new Set([ownVersion]);
8306
- var rejectedVersions = /* @__PURE__ */ new Set();
8307
- var myVersionMatch = ownVersion.match(re);
8308
- if (!myVersionMatch) {
8309
- return function() {
8310
- return false;
8311
- };
8312
- }
8313
- var ownVersionParsed = {
8314
- major: +myVersionMatch[1],
8315
- minor: +myVersionMatch[2],
8316
- patch: +myVersionMatch[3],
8317
- prerelease: myVersionMatch[4]
8318
- };
8319
- if (ownVersionParsed.prerelease != null) {
8320
- return function isExactmatch(globalVersion) {
8321
- return globalVersion === ownVersion;
8322
- };
8323
- }
8324
- function _reject(v) {
8325
- rejectedVersions.add(v);
8326
- return false;
8327
- }
8328
- function _accept(v) {
8329
- acceptedVersions.add(v);
8330
- return true;
8331
- }
8332
- return function isCompatible2(globalVersion) {
8333
- if (acceptedVersions.has(globalVersion)) {
8334
- return true;
8335
- }
8336
- if (rejectedVersions.has(globalVersion)) {
8337
- return false;
8338
- }
8339
- var globalVersionMatch = globalVersion.match(re);
8340
- if (!globalVersionMatch) {
8341
- return _reject(globalVersion);
8342
- }
8343
- var globalVersionParsed = {
8344
- major: +globalVersionMatch[1],
8345
- minor: +globalVersionMatch[2],
8346
- patch: +globalVersionMatch[3],
8347
- prerelease: globalVersionMatch[4]
8348
- };
8349
- if (globalVersionParsed.prerelease != null) {
8350
- return _reject(globalVersion);
8351
- }
8352
- if (ownVersionParsed.major !== globalVersionParsed.major) {
8353
- return _reject(globalVersion);
8354
- }
8355
- if (ownVersionParsed.major === 0) {
8356
- if (ownVersionParsed.minor === globalVersionParsed.minor && ownVersionParsed.patch <= globalVersionParsed.patch) {
8357
- return _accept(globalVersion);
8358
- }
8359
- return _reject(globalVersion);
8360
- }
8361
- if (ownVersionParsed.minor <= globalVersionParsed.minor) {
8362
- return _accept(globalVersion);
8363
- }
8364
- return _reject(globalVersion);
8365
- };
8366
- }
8367
- var re, isCompatible;
8368
- var init_semver = __esm({
8369
- "node_modules/@opentelemetry/api/build/esm/internal/semver.js"() {
8370
- "use strict";
8371
- init_version();
8372
- re = /^(\d+)\.(\d+)\.(\d+)(-(.+))?$/;
8373
- isCompatible = _makeCompatibilityCheck(VERSION);
8374
- }
8375
- });
8376
-
8377
- // node_modules/@opentelemetry/api/build/esm/internal/global-utils.js
8378
- function registerGlobal(type, instance, diag, allowOverride) {
8379
- var _a;
8380
- if (allowOverride === void 0) {
8381
- allowOverride = false;
8382
- }
8383
- var api = _global[GLOBAL_OPENTELEMETRY_API_KEY] = (_a = _global[GLOBAL_OPENTELEMETRY_API_KEY]) !== null && _a !== void 0 ? _a : {
8384
- version: VERSION
8385
- };
8386
- if (!allowOverride && api[type]) {
8387
- var err = new Error("@opentelemetry/api: Attempted duplicate registration of API: " + type);
8388
- diag.error(err.stack || err.message);
8389
- return false;
8390
- }
8391
- if (api.version !== VERSION) {
8392
- var err = new Error("@opentelemetry/api: Registration of version v" + api.version + " for " + type + " does not match previously registered API v" + VERSION);
8393
- diag.error(err.stack || err.message);
8394
- return false;
8395
- }
8396
- api[type] = instance;
8397
- diag.debug("@opentelemetry/api: Registered a global for " + type + " v" + VERSION + ".");
8398
- return true;
8399
- }
8400
- function getGlobal(type) {
8401
- var _a, _b;
8402
- var globalVersion = (_a = _global[GLOBAL_OPENTELEMETRY_API_KEY]) === null || _a === void 0 ? void 0 : _a.version;
8403
- if (!globalVersion || !isCompatible(globalVersion)) {
8404
- return;
8405
- }
8406
- return (_b = _global[GLOBAL_OPENTELEMETRY_API_KEY]) === null || _b === void 0 ? void 0 : _b[type];
8407
- }
8408
- function unregisterGlobal(type, diag) {
8409
- diag.debug("@opentelemetry/api: Unregistering a global for " + type + " v" + VERSION + ".");
8410
- var api = _global[GLOBAL_OPENTELEMETRY_API_KEY];
8411
- if (api) {
8412
- delete api[type];
8413
- }
8414
- }
8415
- var major, GLOBAL_OPENTELEMETRY_API_KEY, _global;
8416
- var init_global_utils = __esm({
8417
- "node_modules/@opentelemetry/api/build/esm/internal/global-utils.js"() {
8418
- "use strict";
8419
- init_platform();
8420
- init_version();
8421
- init_semver();
8422
- major = VERSION.split(".")[0];
8423
- GLOBAL_OPENTELEMETRY_API_KEY = Symbol.for("opentelemetry.js.api." + major);
8424
- _global = _globalThis;
8425
- }
8426
- });
8427
-
8428
- // node_modules/@opentelemetry/api/build/esm/diag/ComponentLogger.js
8429
- function logProxy(funcName, namespace, args) {
8430
- var logger2 = getGlobal("diag");
8431
- if (!logger2) {
8432
- return;
8433
- }
8434
- args.unshift(namespace);
8435
- return logger2[funcName].apply(logger2, __spreadArray([], __read(args), false));
8436
- }
8437
- var __read, __spreadArray, DiagComponentLogger;
8438
- var init_ComponentLogger = __esm({
8439
- "node_modules/@opentelemetry/api/build/esm/diag/ComponentLogger.js"() {
8440
- "use strict";
8441
- init_global_utils();
8442
- __read = function(o, n) {
8443
- var m = typeof Symbol === "function" && o[Symbol.iterator];
8444
- if (!m) return o;
8445
- var i = m.call(o), r, ar = [], e;
8446
- try {
8447
- while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
8448
- } catch (error) {
8449
- e = { error };
8450
- } finally {
8451
- try {
8452
- if (r && !r.done && (m = i["return"])) m.call(i);
8453
- } finally {
8454
- if (e) throw e.error;
8455
- }
8456
- }
8457
- return ar;
8458
- };
8459
- __spreadArray = function(to, from, pack) {
8460
- if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
8461
- if (ar || !(i in from)) {
8462
- if (!ar) ar = Array.prototype.slice.call(from, 0, i);
8463
- ar[i] = from[i];
8464
- }
8465
- }
8466
- return to.concat(ar || Array.prototype.slice.call(from));
8467
- };
8468
- DiagComponentLogger = /** @class */
8469
- (function() {
8470
- function DiagComponentLogger2(props) {
8471
- this._namespace = props.namespace || "DiagComponentLogger";
8472
- }
8473
- DiagComponentLogger2.prototype.debug = function() {
8474
- var args = [];
8475
- for (var _i = 0; _i < arguments.length; _i++) {
8476
- args[_i] = arguments[_i];
8477
- }
8478
- return logProxy("debug", this._namespace, args);
8479
- };
8480
- DiagComponentLogger2.prototype.error = function() {
8481
- var args = [];
8482
- for (var _i = 0; _i < arguments.length; _i++) {
8483
- args[_i] = arguments[_i];
8484
- }
8485
- return logProxy("error", this._namespace, args);
8486
- };
8487
- DiagComponentLogger2.prototype.info = function() {
8488
- var args = [];
8489
- for (var _i = 0; _i < arguments.length; _i++) {
8490
- args[_i] = arguments[_i];
8491
- }
8492
- return logProxy("info", this._namespace, args);
8493
- };
8494
- DiagComponentLogger2.prototype.warn = function() {
8495
- var args = [];
8496
- for (var _i = 0; _i < arguments.length; _i++) {
8497
- args[_i] = arguments[_i];
8498
- }
8499
- return logProxy("warn", this._namespace, args);
8500
- };
8501
- DiagComponentLogger2.prototype.verbose = function() {
8502
- var args = [];
8503
- for (var _i = 0; _i < arguments.length; _i++) {
8504
- args[_i] = arguments[_i];
8505
- }
8506
- return logProxy("verbose", this._namespace, args);
8507
- };
8508
- return DiagComponentLogger2;
8509
- })();
8510
- }
8511
- });
8512
-
8513
- // node_modules/@opentelemetry/api/build/esm/diag/types.js
8514
- var DiagLogLevel;
8515
- var init_types = __esm({
8516
- "node_modules/@opentelemetry/api/build/esm/diag/types.js"() {
8517
- "use strict";
8518
- (function(DiagLogLevel2) {
8519
- DiagLogLevel2[DiagLogLevel2["NONE"] = 0] = "NONE";
8520
- DiagLogLevel2[DiagLogLevel2["ERROR"] = 30] = "ERROR";
8521
- DiagLogLevel2[DiagLogLevel2["WARN"] = 50] = "WARN";
8522
- DiagLogLevel2[DiagLogLevel2["INFO"] = 60] = "INFO";
8523
- DiagLogLevel2[DiagLogLevel2["DEBUG"] = 70] = "DEBUG";
8524
- DiagLogLevel2[DiagLogLevel2["VERBOSE"] = 80] = "VERBOSE";
8525
- DiagLogLevel2[DiagLogLevel2["ALL"] = 9999] = "ALL";
8526
- })(DiagLogLevel || (DiagLogLevel = {}));
8527
- }
8528
- });
8529
-
8530
- // node_modules/@opentelemetry/api/build/esm/diag/internal/logLevelLogger.js
8531
- function createLogLevelDiagLogger(maxLevel, logger2) {
8532
- if (maxLevel < DiagLogLevel.NONE) {
8533
- maxLevel = DiagLogLevel.NONE;
8534
- } else if (maxLevel > DiagLogLevel.ALL) {
8535
- maxLevel = DiagLogLevel.ALL;
8536
- }
8537
- logger2 = logger2 || {};
8538
- function _filterFunc(funcName, theLevel) {
8539
- var theFunc = logger2[funcName];
8540
- if (typeof theFunc === "function" && maxLevel >= theLevel) {
8541
- return theFunc.bind(logger2);
8542
- }
8543
- return function() {
8544
- };
8545
- }
8546
- return {
8547
- error: _filterFunc("error", DiagLogLevel.ERROR),
8548
- warn: _filterFunc("warn", DiagLogLevel.WARN),
8549
- info: _filterFunc("info", DiagLogLevel.INFO),
8550
- debug: _filterFunc("debug", DiagLogLevel.DEBUG),
8551
- verbose: _filterFunc("verbose", DiagLogLevel.VERBOSE)
8552
- };
8553
- }
8554
- var init_logLevelLogger = __esm({
8555
- "node_modules/@opentelemetry/api/build/esm/diag/internal/logLevelLogger.js"() {
8556
- "use strict";
8557
- init_types();
8558
- }
8559
- });
8560
-
8561
- // node_modules/@opentelemetry/api/build/esm/api/diag.js
8562
- var __read2, __spreadArray2, API_NAME, DiagAPI;
8563
- var init_diag = __esm({
8564
- "node_modules/@opentelemetry/api/build/esm/api/diag.js"() {
8565
- "use strict";
8566
- init_ComponentLogger();
8567
- init_logLevelLogger();
8568
- init_types();
8569
- init_global_utils();
8570
- __read2 = function(o, n) {
8571
- var m = typeof Symbol === "function" && o[Symbol.iterator];
8572
- if (!m) return o;
8573
- var i = m.call(o), r, ar = [], e;
8574
- try {
8575
- while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
8576
- } catch (error) {
8577
- e = { error };
8578
- } finally {
8579
- try {
8580
- if (r && !r.done && (m = i["return"])) m.call(i);
8581
- } finally {
8582
- if (e) throw e.error;
8583
- }
8584
- }
8585
- return ar;
8586
- };
8587
- __spreadArray2 = function(to, from, pack) {
8588
- if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
8589
- if (ar || !(i in from)) {
8590
- if (!ar) ar = Array.prototype.slice.call(from, 0, i);
8591
- ar[i] = from[i];
8592
- }
8593
- }
8594
- return to.concat(ar || Array.prototype.slice.call(from));
8595
- };
8596
- API_NAME = "diag";
8597
- DiagAPI = /** @class */
8598
- (function() {
8599
- function DiagAPI2() {
8600
- function _logProxy(funcName) {
8601
- return function() {
8602
- var args = [];
8603
- for (var _i = 0; _i < arguments.length; _i++) {
8604
- args[_i] = arguments[_i];
8605
- }
8606
- var logger2 = getGlobal("diag");
8607
- if (!logger2)
8608
- return;
8609
- return logger2[funcName].apply(logger2, __spreadArray2([], __read2(args), false));
8610
- };
8611
- }
8612
- var self = this;
8613
- var setLogger = function(logger2, optionsOrLogLevel) {
8614
- var _a, _b, _c;
8615
- if (optionsOrLogLevel === void 0) {
8616
- optionsOrLogLevel = { logLevel: DiagLogLevel.INFO };
8617
- }
8618
- if (logger2 === self) {
8619
- var err = new Error("Cannot use diag as the logger for itself. Please use a DiagLogger implementation like ConsoleDiagLogger or a custom implementation");
8620
- self.error((_a = err.stack) !== null && _a !== void 0 ? _a : err.message);
8621
- return false;
8622
- }
8623
- if (typeof optionsOrLogLevel === "number") {
8624
- optionsOrLogLevel = {
8625
- logLevel: optionsOrLogLevel
8626
- };
8627
- }
8628
- var oldLogger = getGlobal("diag");
8629
- var newLogger = createLogLevelDiagLogger((_b = optionsOrLogLevel.logLevel) !== null && _b !== void 0 ? _b : DiagLogLevel.INFO, logger2);
8630
- if (oldLogger && !optionsOrLogLevel.suppressOverrideMessage) {
8631
- var stack = (_c = new Error().stack) !== null && _c !== void 0 ? _c : "<failed to generate stacktrace>";
8632
- oldLogger.warn("Current logger will be overwritten from " + stack);
8633
- newLogger.warn("Current logger will overwrite one already registered from " + stack);
8634
- }
8635
- return registerGlobal("diag", newLogger, self, true);
8636
- };
8637
- self.setLogger = setLogger;
8638
- self.disable = function() {
8639
- unregisterGlobal(API_NAME, self);
8640
- };
8641
- self.createComponentLogger = function(options) {
8642
- return new DiagComponentLogger(options);
8643
- };
8644
- self.verbose = _logProxy("verbose");
8645
- self.debug = _logProxy("debug");
8646
- self.info = _logProxy("info");
8647
- self.warn = _logProxy("warn");
8648
- self.error = _logProxy("error");
8649
- }
8650
- DiagAPI2.instance = function() {
8651
- if (!this._instance) {
8652
- this._instance = new DiagAPI2();
8653
- }
8654
- return this._instance;
8655
- };
8656
- return DiagAPI2;
8657
- })();
8658
- }
8659
- });
8660
-
8661
- // node_modules/@opentelemetry/api/build/esm/context/context.js
8662
- function createContextKey(description) {
8663
- return Symbol.for(description);
8664
- }
8665
- var BaseContext, ROOT_CONTEXT;
8666
- var init_context = __esm({
8667
- "node_modules/@opentelemetry/api/build/esm/context/context.js"() {
8668
- "use strict";
8669
- BaseContext = /** @class */
8670
- /* @__PURE__ */ (function() {
8671
- function BaseContext2(parentContext) {
8672
- var self = this;
8673
- self._currentContext = parentContext ? new Map(parentContext) : /* @__PURE__ */ new Map();
8674
- self.getValue = function(key) {
8675
- return self._currentContext.get(key);
8676
- };
8677
- self.setValue = function(key, value) {
8678
- var context2 = new BaseContext2(self._currentContext);
8679
- context2._currentContext.set(key, value);
8680
- return context2;
8681
- };
8682
- self.deleteValue = function(key) {
8683
- var context2 = new BaseContext2(self._currentContext);
8684
- context2._currentContext.delete(key);
8685
- return context2;
8686
- };
8687
- }
8688
- return BaseContext2;
8689
- })();
8690
- ROOT_CONTEXT = new BaseContext();
8691
- }
8692
- });
8693
-
8694
- // node_modules/@opentelemetry/api/build/esm/metrics/NoopMeter.js
8695
- var __extends, NoopMeter, NoopMetric, NoopCounterMetric, NoopUpDownCounterMetric, NoopGaugeMetric, NoopHistogramMetric, NoopObservableMetric, NoopObservableCounterMetric, NoopObservableGaugeMetric, NoopObservableUpDownCounterMetric, NOOP_METER, NOOP_COUNTER_METRIC, NOOP_GAUGE_METRIC, NOOP_HISTOGRAM_METRIC, NOOP_UP_DOWN_COUNTER_METRIC, NOOP_OBSERVABLE_COUNTER_METRIC, NOOP_OBSERVABLE_GAUGE_METRIC, NOOP_OBSERVABLE_UP_DOWN_COUNTER_METRIC;
8696
- var init_NoopMeter = __esm({
8697
- "node_modules/@opentelemetry/api/build/esm/metrics/NoopMeter.js"() {
8698
- "use strict";
8699
- __extends = /* @__PURE__ */ (function() {
8700
- var extendStatics = function(d, b) {
8701
- extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(d2, b2) {
8702
- d2.__proto__ = b2;
8703
- } || function(d2, b2) {
8704
- for (var p in b2) if (Object.prototype.hasOwnProperty.call(b2, p)) d2[p] = b2[p];
8705
- };
8706
- return extendStatics(d, b);
8707
- };
8708
- return function(d, b) {
8709
- if (typeof b !== "function" && b !== null)
8710
- throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
8711
- extendStatics(d, b);
8712
- function __() {
8713
- this.constructor = d;
8714
- }
8715
- d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
8716
- };
8717
- })();
8718
- NoopMeter = /** @class */
8719
- (function() {
8720
- function NoopMeter2() {
8721
- }
8722
- NoopMeter2.prototype.createGauge = function(_name, _options) {
8723
- return NOOP_GAUGE_METRIC;
8724
- };
8725
- NoopMeter2.prototype.createHistogram = function(_name, _options) {
8726
- return NOOP_HISTOGRAM_METRIC;
8727
- };
8728
- NoopMeter2.prototype.createCounter = function(_name, _options) {
8729
- return NOOP_COUNTER_METRIC;
8730
- };
8731
- NoopMeter2.prototype.createUpDownCounter = function(_name, _options) {
8732
- return NOOP_UP_DOWN_COUNTER_METRIC;
8733
- };
8734
- NoopMeter2.prototype.createObservableGauge = function(_name, _options) {
8735
- return NOOP_OBSERVABLE_GAUGE_METRIC;
8736
- };
8737
- NoopMeter2.prototype.createObservableCounter = function(_name, _options) {
8738
- return NOOP_OBSERVABLE_COUNTER_METRIC;
8739
- };
8740
- NoopMeter2.prototype.createObservableUpDownCounter = function(_name, _options) {
8741
- return NOOP_OBSERVABLE_UP_DOWN_COUNTER_METRIC;
8742
- };
8743
- NoopMeter2.prototype.addBatchObservableCallback = function(_callback, _observables) {
8744
- };
8745
- NoopMeter2.prototype.removeBatchObservableCallback = function(_callback) {
8746
- };
8747
- return NoopMeter2;
8748
- })();
8749
- NoopMetric = /** @class */
8750
- /* @__PURE__ */ (function() {
8751
- function NoopMetric2() {
8752
- }
8753
- return NoopMetric2;
8754
- })();
8755
- NoopCounterMetric = /** @class */
8756
- (function(_super) {
8757
- __extends(NoopCounterMetric2, _super);
8758
- function NoopCounterMetric2() {
8759
- return _super !== null && _super.apply(this, arguments) || this;
8760
- }
8761
- NoopCounterMetric2.prototype.add = function(_value, _attributes) {
8762
- };
8763
- return NoopCounterMetric2;
8764
- })(NoopMetric);
8765
- NoopUpDownCounterMetric = /** @class */
8766
- (function(_super) {
8767
- __extends(NoopUpDownCounterMetric2, _super);
8768
- function NoopUpDownCounterMetric2() {
8769
- return _super !== null && _super.apply(this, arguments) || this;
8770
- }
8771
- NoopUpDownCounterMetric2.prototype.add = function(_value, _attributes) {
8772
- };
8773
- return NoopUpDownCounterMetric2;
8774
- })(NoopMetric);
8775
- NoopGaugeMetric = /** @class */
8776
- (function(_super) {
8777
- __extends(NoopGaugeMetric2, _super);
8778
- function NoopGaugeMetric2() {
8779
- return _super !== null && _super.apply(this, arguments) || this;
8780
- }
8781
- NoopGaugeMetric2.prototype.record = function(_value, _attributes) {
8782
- };
8783
- return NoopGaugeMetric2;
8784
- })(NoopMetric);
8785
- NoopHistogramMetric = /** @class */
8786
- (function(_super) {
8787
- __extends(NoopHistogramMetric2, _super);
8788
- function NoopHistogramMetric2() {
8789
- return _super !== null && _super.apply(this, arguments) || this;
8790
- }
8791
- NoopHistogramMetric2.prototype.record = function(_value, _attributes) {
8792
- };
8793
- return NoopHistogramMetric2;
8794
- })(NoopMetric);
8795
- NoopObservableMetric = /** @class */
8796
- (function() {
8797
- function NoopObservableMetric2() {
8798
- }
8799
- NoopObservableMetric2.prototype.addCallback = function(_callback) {
8800
- };
8801
- NoopObservableMetric2.prototype.removeCallback = function(_callback) {
8802
- };
8803
- return NoopObservableMetric2;
8804
- })();
8805
- NoopObservableCounterMetric = /** @class */
8806
- (function(_super) {
8807
- __extends(NoopObservableCounterMetric2, _super);
8808
- function NoopObservableCounterMetric2() {
8809
- return _super !== null && _super.apply(this, arguments) || this;
8810
- }
8811
- return NoopObservableCounterMetric2;
8812
- })(NoopObservableMetric);
8813
- NoopObservableGaugeMetric = /** @class */
8814
- (function(_super) {
8815
- __extends(NoopObservableGaugeMetric2, _super);
8816
- function NoopObservableGaugeMetric2() {
8817
- return _super !== null && _super.apply(this, arguments) || this;
8818
- }
8819
- return NoopObservableGaugeMetric2;
8820
- })(NoopObservableMetric);
8821
- NoopObservableUpDownCounterMetric = /** @class */
8822
- (function(_super) {
8823
- __extends(NoopObservableUpDownCounterMetric2, _super);
8824
- function NoopObservableUpDownCounterMetric2() {
8825
- return _super !== null && _super.apply(this, arguments) || this;
8826
- }
8827
- return NoopObservableUpDownCounterMetric2;
8828
- })(NoopObservableMetric);
8829
- NOOP_METER = new NoopMeter();
8830
- NOOP_COUNTER_METRIC = new NoopCounterMetric();
8831
- NOOP_GAUGE_METRIC = new NoopGaugeMetric();
8832
- NOOP_HISTOGRAM_METRIC = new NoopHistogramMetric();
8833
- NOOP_UP_DOWN_COUNTER_METRIC = new NoopUpDownCounterMetric();
8834
- NOOP_OBSERVABLE_COUNTER_METRIC = new NoopObservableCounterMetric();
8835
- NOOP_OBSERVABLE_GAUGE_METRIC = new NoopObservableGaugeMetric();
8836
- NOOP_OBSERVABLE_UP_DOWN_COUNTER_METRIC = new NoopObservableUpDownCounterMetric();
8837
- }
8838
- });
8839
-
8840
- // node_modules/@opentelemetry/api/build/esm/context/NoopContextManager.js
8841
- var __read3, __spreadArray3, NoopContextManager;
8842
- var init_NoopContextManager = __esm({
8843
- "node_modules/@opentelemetry/api/build/esm/context/NoopContextManager.js"() {
8844
- "use strict";
8845
- init_context();
8846
- __read3 = function(o, n) {
8847
- var m = typeof Symbol === "function" && o[Symbol.iterator];
8848
- if (!m) return o;
8849
- var i = m.call(o), r, ar = [], e;
8850
- try {
8851
- while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
8852
- } catch (error) {
8853
- e = { error };
8854
- } finally {
8855
- try {
8856
- if (r && !r.done && (m = i["return"])) m.call(i);
8857
- } finally {
8858
- if (e) throw e.error;
8859
- }
8860
- }
8861
- return ar;
8862
- };
8863
- __spreadArray3 = function(to, from, pack) {
8864
- if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
8865
- if (ar || !(i in from)) {
8866
- if (!ar) ar = Array.prototype.slice.call(from, 0, i);
8867
- ar[i] = from[i];
8868
- }
8869
- }
8870
- return to.concat(ar || Array.prototype.slice.call(from));
8871
- };
8872
- NoopContextManager = /** @class */
8873
- (function() {
8874
- function NoopContextManager2() {
8743
+ return executionGroups;
8875
8744
  }
8876
- NoopContextManager2.prototype.active = function() {
8877
- return ROOT_CONTEXT;
8878
- };
8879
- NoopContextManager2.prototype.with = function(_context, fn, thisArg) {
8880
- var args = [];
8881
- for (var _i = 3; _i < arguments.length; _i++) {
8882
- args[_i - 3] = arguments[_i];
8883
- }
8884
- return fn.call.apply(fn, __spreadArray3([thisArg], __read3(args), false));
8885
- };
8886
- NoopContextManager2.prototype.bind = function(_context, target) {
8887
- return target;
8888
- };
8889
- NoopContextManager2.prototype.enable = function() {
8890
- return this;
8891
- };
8892
- NoopContextManager2.prototype.disable = function() {
8893
- return this;
8894
- };
8895
- return NoopContextManager2;
8896
- })();
8897
- }
8898
- });
8899
-
8900
- // node_modules/@opentelemetry/api/build/esm/api/context.js
8901
- var __read4, __spreadArray4, API_NAME2, NOOP_CONTEXT_MANAGER, ContextAPI;
8902
- var init_context2 = __esm({
8903
- "node_modules/@opentelemetry/api/build/esm/api/context.js"() {
8904
- "use strict";
8905
- init_NoopContextManager();
8906
- init_global_utils();
8907
- init_diag();
8908
- __read4 = function(o, n) {
8909
- var m = typeof Symbol === "function" && o[Symbol.iterator];
8910
- if (!m) return o;
8911
- var i = m.call(o), r, ar = [], e;
8912
- try {
8913
- while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
8914
- } catch (error) {
8915
- e = { error };
8916
- } finally {
8917
- try {
8918
- if (r && !r.done && (m = i["return"])) m.call(i);
8919
- } finally {
8920
- if (e) throw e.error;
8745
+ /**
8746
+ * Validate that all dependencies exist
8747
+ */
8748
+ static validateDependencies(checkIds, dependencies) {
8749
+ const errors = [];
8750
+ const checkIdSet = new Set(checkIds);
8751
+ for (const [checkId, deps] of Object.entries(dependencies)) {
8752
+ if (!checkIdSet.has(checkId)) {
8753
+ errors.push(`Check "${checkId}" is not in the list of available checks`);
8754
+ continue;
8755
+ }
8756
+ for (const depId of deps || []) {
8757
+ if (!checkIdSet.has(depId)) {
8758
+ errors.push(`Check "${checkId}" depends on "${depId}" which is not available`);
8759
+ }
8760
+ }
8921
8761
  }
8762
+ return {
8763
+ valid: errors.length === 0,
8764
+ errors
8765
+ };
8922
8766
  }
8923
- return ar;
8924
- };
8925
- __spreadArray4 = function(to, from, pack) {
8926
- if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
8927
- if (ar || !(i in from)) {
8928
- if (!ar) ar = Array.prototype.slice.call(from, 0, i);
8929
- ar[i] = from[i];
8930
- }
8767
+ /**
8768
+ * Get all transitive dependencies (ancestors) for a given check
8769
+ * This returns all checks that must complete before the given check can run,
8770
+ * not just the direct dependencies.
8771
+ *
8772
+ * For example, if A -> B -> C, then:
8773
+ * - getAllDependencies(C) returns [A, B]
8774
+ * - getAllDependencies(B) returns [A]
8775
+ * - getAllDependencies(A) returns []
8776
+ *
8777
+ * @param checkId The check to find dependencies for
8778
+ * @param nodes The dependency graph nodes
8779
+ * @returns Array of all transitive dependency IDs
8780
+ */
8781
+ static getAllDependencies(checkId, nodes) {
8782
+ const allDeps = /* @__PURE__ */ new Set();
8783
+ const visited = /* @__PURE__ */ new Set();
8784
+ const collectDependencies = (currentId) => {
8785
+ if (visited.has(currentId)) {
8786
+ return;
8787
+ }
8788
+ visited.add(currentId);
8789
+ const node = nodes.get(currentId);
8790
+ if (!node) {
8791
+ return;
8792
+ }
8793
+ for (const depId of node.dependencies) {
8794
+ allDeps.add(depId);
8795
+ collectDependencies(depId);
8796
+ }
8797
+ };
8798
+ collectDependencies(checkId);
8799
+ return Array.from(allDeps);
8931
8800
  }
8932
- return to.concat(ar || Array.prototype.slice.call(from));
8933
- };
8934
- API_NAME2 = "context";
8935
- NOOP_CONTEXT_MANAGER = new NoopContextManager();
8936
- ContextAPI = /** @class */
8937
- (function() {
8938
- function ContextAPI2() {
8801
+ /**
8802
+ * Get execution statistics for debugging
8803
+ */
8804
+ static getExecutionStats(graph) {
8805
+ const totalChecks = graph.nodes.size;
8806
+ const parallelLevels = graph.executionOrder.length;
8807
+ const maxParallelism = Math.max(...graph.executionOrder.map((group) => group.parallel.length));
8808
+ const averageParallelism = totalChecks / parallelLevels;
8809
+ const checksWithDependencies = Array.from(graph.nodes.values()).filter(
8810
+ (node) => node.dependencies.length > 0
8811
+ ).length;
8812
+ return {
8813
+ totalChecks,
8814
+ parallelLevels,
8815
+ maxParallelism,
8816
+ averageParallelism,
8817
+ checksWithDependencies
8818
+ };
8939
8819
  }
8940
- ContextAPI2.getInstance = function() {
8941
- if (!this._instance) {
8942
- this._instance = new ContextAPI2();
8943
- }
8944
- return this._instance;
8945
- };
8946
- ContextAPI2.prototype.setGlobalContextManager = function(contextManager) {
8947
- return registerGlobal(API_NAME2, contextManager, DiagAPI.instance());
8948
- };
8949
- ContextAPI2.prototype.active = function() {
8950
- return this._getContextManager().active();
8951
- };
8952
- ContextAPI2.prototype.with = function(context2, fn, thisArg) {
8953
- var _a;
8954
- var args = [];
8955
- for (var _i = 3; _i < arguments.length; _i++) {
8956
- args[_i - 3] = arguments[_i];
8957
- }
8958
- return (_a = this._getContextManager()).with.apply(_a, __spreadArray4([context2, fn, thisArg], __read4(args), false));
8959
- };
8960
- ContextAPI2.prototype.bind = function(context2, target) {
8961
- return this._getContextManager().bind(context2, target);
8962
- };
8963
- ContextAPI2.prototype._getContextManager = function() {
8964
- return getGlobal(API_NAME2) || NOOP_CONTEXT_MANAGER;
8965
- };
8966
- ContextAPI2.prototype.disable = function() {
8967
- this._getContextManager().disable();
8968
- unregisterGlobal(API_NAME2, DiagAPI.instance());
8969
- };
8970
- return ContextAPI2;
8971
- })();
8972
- }
8973
- });
8974
-
8975
- // node_modules/@opentelemetry/api/build/esm/trace/trace_flags.js
8976
- var TraceFlags;
8977
- var init_trace_flags = __esm({
8978
- "node_modules/@opentelemetry/api/build/esm/trace/trace_flags.js"() {
8979
- "use strict";
8980
- (function(TraceFlags2) {
8981
- TraceFlags2[TraceFlags2["NONE"] = 0] = "NONE";
8982
- TraceFlags2[TraceFlags2["SAMPLED"] = 1] = "SAMPLED";
8983
- })(TraceFlags || (TraceFlags = {}));
8984
- }
8985
- });
8986
-
8987
- // node_modules/@opentelemetry/api/build/esm/trace/invalid-span-constants.js
8988
- var INVALID_SPANID, INVALID_TRACEID, INVALID_SPAN_CONTEXT;
8989
- var init_invalid_span_constants = __esm({
8990
- "node_modules/@opentelemetry/api/build/esm/trace/invalid-span-constants.js"() {
8991
- "use strict";
8992
- init_trace_flags();
8993
- INVALID_SPANID = "0000000000000000";
8994
- INVALID_TRACEID = "00000000000000000000000000000000";
8995
- INVALID_SPAN_CONTEXT = {
8996
- traceId: INVALID_TRACEID,
8997
- spanId: INVALID_SPANID,
8998
- traceFlags: TraceFlags.NONE
8999
8820
  };
9000
8821
  }
9001
8822
  });
9002
8823
 
9003
- // node_modules/@opentelemetry/api/build/esm/trace/NonRecordingSpan.js
9004
- var NonRecordingSpan;
9005
- var init_NonRecordingSpan = __esm({
9006
- "node_modules/@opentelemetry/api/build/esm/trace/NonRecordingSpan.js"() {
9007
- "use strict";
9008
- init_invalid_span_constants();
9009
- NonRecordingSpan = /** @class */
9010
- (function() {
9011
- function NonRecordingSpan2(_spanContext) {
9012
- if (_spanContext === void 0) {
9013
- _spanContext = INVALID_SPAN_CONTEXT;
9014
- }
9015
- this._spanContext = _spanContext;
9016
- }
9017
- NonRecordingSpan2.prototype.spanContext = function() {
9018
- return this._spanContext;
9019
- };
9020
- NonRecordingSpan2.prototype.setAttribute = function(_key, _value) {
9021
- return this;
9022
- };
9023
- NonRecordingSpan2.prototype.setAttributes = function(_attributes) {
9024
- return this;
9025
- };
9026
- NonRecordingSpan2.prototype.addEvent = function(_name, _attributes) {
9027
- return this;
9028
- };
9029
- NonRecordingSpan2.prototype.addLink = function(_link) {
9030
- return this;
9031
- };
9032
- NonRecordingSpan2.prototype.addLinks = function(_links) {
9033
- return this;
9034
- };
9035
- NonRecordingSpan2.prototype.setStatus = function(_status) {
9036
- return this;
9037
- };
9038
- NonRecordingSpan2.prototype.updateName = function(_name) {
9039
- return this;
9040
- };
9041
- NonRecordingSpan2.prototype.end = function(_endTime) {
9042
- };
9043
- NonRecordingSpan2.prototype.isRecording = function() {
9044
- return false;
9045
- };
9046
- NonRecordingSpan2.prototype.recordException = function(_exception, _time) {
9047
- };
9048
- return NonRecordingSpan2;
9049
- })();
9050
- }
9051
- });
9052
-
9053
- // node_modules/@opentelemetry/api/build/esm/trace/context-utils.js
9054
- function getSpan(context2) {
9055
- return context2.getValue(SPAN_KEY) || void 0;
9056
- }
9057
- function getActiveSpan() {
9058
- return getSpan(ContextAPI.getInstance().active());
9059
- }
9060
- function setSpan(context2, span) {
9061
- return context2.setValue(SPAN_KEY, span);
9062
- }
9063
- function deleteSpan(context2) {
9064
- return context2.deleteValue(SPAN_KEY);
9065
- }
9066
- function setSpanContext(context2, spanContext) {
9067
- return setSpan(context2, new NonRecordingSpan(spanContext));
9068
- }
9069
- function getSpanContext(context2) {
9070
- var _a;
9071
- return (_a = getSpan(context2)) === null || _a === void 0 ? void 0 : _a.spanContext();
9072
- }
9073
- var SPAN_KEY;
9074
- var init_context_utils = __esm({
9075
- "node_modules/@opentelemetry/api/build/esm/trace/context-utils.js"() {
9076
- "use strict";
9077
- init_context();
9078
- init_NonRecordingSpan();
9079
- init_context2();
9080
- SPAN_KEY = createContextKey("OpenTelemetry Context Key SPAN");
9081
- }
9082
- });
9083
-
9084
- // node_modules/@opentelemetry/api/build/esm/trace/spancontext-utils.js
9085
- function isValidTraceId(traceId) {
9086
- return VALID_TRACEID_REGEX.test(traceId) && traceId !== INVALID_TRACEID;
9087
- }
9088
- function isValidSpanId(spanId) {
9089
- return VALID_SPANID_REGEX.test(spanId) && spanId !== INVALID_SPANID;
9090
- }
9091
- function isSpanContextValid(spanContext) {
9092
- return isValidTraceId(spanContext.traceId) && isValidSpanId(spanContext.spanId);
9093
- }
9094
- function wrapSpanContext(spanContext) {
9095
- return new NonRecordingSpan(spanContext);
9096
- }
9097
- var VALID_TRACEID_REGEX, VALID_SPANID_REGEX;
9098
- var init_spancontext_utils = __esm({
9099
- "node_modules/@opentelemetry/api/build/esm/trace/spancontext-utils.js"() {
9100
- "use strict";
9101
- init_invalid_span_constants();
9102
- init_NonRecordingSpan();
9103
- VALID_TRACEID_REGEX = /^([0-9a-f]{32})$/i;
9104
- VALID_SPANID_REGEX = /^[0-9a-f]{16}$/i;
9105
- }
9106
- });
9107
-
9108
- // node_modules/@opentelemetry/api/build/esm/trace/NoopTracer.js
9109
- function isSpanContext(spanContext) {
9110
- return typeof spanContext === "object" && typeof spanContext["spanId"] === "string" && typeof spanContext["traceId"] === "string" && typeof spanContext["traceFlags"] === "number";
9111
- }
9112
- var contextApi, NoopTracer;
9113
- var init_NoopTracer = __esm({
9114
- "node_modules/@opentelemetry/api/build/esm/trace/NoopTracer.js"() {
9115
- "use strict";
9116
- init_context2();
9117
- init_context_utils();
9118
- init_NonRecordingSpan();
9119
- init_spancontext_utils();
9120
- contextApi = ContextAPI.getInstance();
9121
- NoopTracer = /** @class */
9122
- (function() {
9123
- function NoopTracer2() {
9124
- }
9125
- NoopTracer2.prototype.startSpan = function(name, options, context2) {
9126
- if (context2 === void 0) {
9127
- context2 = contextApi.active();
9128
- }
9129
- var root = Boolean(options === null || options === void 0 ? void 0 : options.root);
9130
- if (root) {
9131
- return new NonRecordingSpan();
9132
- }
9133
- var parentFromContext = context2 && getSpanContext(context2);
9134
- if (isSpanContext(parentFromContext) && isSpanContextValid(parentFromContext)) {
9135
- return new NonRecordingSpan(parentFromContext);
9136
- } else {
9137
- return new NonRecordingSpan();
9138
- }
9139
- };
9140
- NoopTracer2.prototype.startActiveSpan = function(name, arg2, arg3, arg4) {
9141
- var opts;
9142
- var ctx;
9143
- var fn;
9144
- if (arguments.length < 2) {
9145
- return;
9146
- } else if (arguments.length === 2) {
9147
- fn = arg2;
9148
- } else if (arguments.length === 3) {
9149
- opts = arg2;
9150
- fn = arg3;
9151
- } else {
9152
- opts = arg2;
9153
- ctx = arg3;
9154
- fn = arg4;
9155
- }
9156
- var parentContext = ctx !== null && ctx !== void 0 ? ctx : contextApi.active();
9157
- var span = this.startSpan(name, opts, parentContext);
9158
- var contextWithSpanSet = setSpan(parentContext, span);
9159
- return contextApi.with(contextWithSpanSet, fn, void 0, span);
9160
- };
9161
- return NoopTracer2;
9162
- })();
9163
- }
9164
- });
9165
-
9166
- // node_modules/@opentelemetry/api/build/esm/trace/ProxyTracer.js
9167
- var NOOP_TRACER, ProxyTracer;
9168
- var init_ProxyTracer = __esm({
9169
- "node_modules/@opentelemetry/api/build/esm/trace/ProxyTracer.js"() {
9170
- "use strict";
9171
- init_NoopTracer();
9172
- NOOP_TRACER = new NoopTracer();
9173
- ProxyTracer = /** @class */
9174
- (function() {
9175
- function ProxyTracer2(_provider, name, version, options) {
9176
- this._provider = _provider;
9177
- this.name = name;
9178
- this.version = version;
9179
- this.options = options;
9180
- }
9181
- ProxyTracer2.prototype.startSpan = function(name, options, context2) {
9182
- return this._getTracer().startSpan(name, options, context2);
9183
- };
9184
- ProxyTracer2.prototype.startActiveSpan = function(_name, _options, _context, _fn) {
9185
- var tracer = this._getTracer();
9186
- return Reflect.apply(tracer.startActiveSpan, tracer, arguments);
9187
- };
9188
- ProxyTracer2.prototype._getTracer = function() {
9189
- if (this._delegate) {
9190
- return this._delegate;
9191
- }
9192
- var tracer = this._provider.getDelegateTracer(this.name, this.version, this.options);
9193
- if (!tracer) {
9194
- return NOOP_TRACER;
9195
- }
9196
- this._delegate = tracer;
9197
- return this._delegate;
9198
- };
9199
- return ProxyTracer2;
9200
- })();
9201
- }
9202
- });
9203
-
9204
- // node_modules/@opentelemetry/api/build/esm/trace/NoopTracerProvider.js
9205
- var NoopTracerProvider;
9206
- var init_NoopTracerProvider = __esm({
9207
- "node_modules/@opentelemetry/api/build/esm/trace/NoopTracerProvider.js"() {
9208
- "use strict";
9209
- init_NoopTracer();
9210
- NoopTracerProvider = /** @class */
9211
- (function() {
9212
- function NoopTracerProvider2() {
9213
- }
9214
- NoopTracerProvider2.prototype.getTracer = function(_name, _version, _options) {
9215
- return new NoopTracer();
9216
- };
9217
- return NoopTracerProvider2;
9218
- })();
9219
- }
9220
- });
9221
-
9222
- // node_modules/@opentelemetry/api/build/esm/trace/ProxyTracerProvider.js
9223
- var NOOP_TRACER_PROVIDER, ProxyTracerProvider;
9224
- var init_ProxyTracerProvider = __esm({
9225
- "node_modules/@opentelemetry/api/build/esm/trace/ProxyTracerProvider.js"() {
9226
- "use strict";
9227
- init_ProxyTracer();
9228
- init_NoopTracerProvider();
9229
- NOOP_TRACER_PROVIDER = new NoopTracerProvider();
9230
- ProxyTracerProvider = /** @class */
9231
- (function() {
9232
- function ProxyTracerProvider2() {
9233
- }
9234
- ProxyTracerProvider2.prototype.getTracer = function(name, version, options) {
9235
- var _a;
9236
- return (_a = this.getDelegateTracer(name, version, options)) !== null && _a !== void 0 ? _a : new ProxyTracer(this, name, version, options);
9237
- };
9238
- ProxyTracerProvider2.prototype.getDelegate = function() {
9239
- var _a;
9240
- return (_a = this._delegate) !== null && _a !== void 0 ? _a : NOOP_TRACER_PROVIDER;
9241
- };
9242
- ProxyTracerProvider2.prototype.setDelegate = function(delegate) {
9243
- this._delegate = delegate;
9244
- };
9245
- ProxyTracerProvider2.prototype.getDelegateTracer = function(name, version, options) {
9246
- var _a;
9247
- return (_a = this._delegate) === null || _a === void 0 ? void 0 : _a.getTracer(name, version, options);
9248
- };
9249
- return ProxyTracerProvider2;
9250
- })();
9251
- }
9252
- });
9253
-
9254
- // node_modules/@opentelemetry/api/build/esm/context-api.js
9255
- var context;
9256
- var init_context_api = __esm({
9257
- "node_modules/@opentelemetry/api/build/esm/context-api.js"() {
9258
- "use strict";
9259
- init_context2();
9260
- context = ContextAPI.getInstance();
9261
- }
9262
- });
9263
-
9264
- // node_modules/@opentelemetry/api/build/esm/metrics/NoopMeterProvider.js
9265
- var NoopMeterProvider, NOOP_METER_PROVIDER;
9266
- var init_NoopMeterProvider = __esm({
9267
- "node_modules/@opentelemetry/api/build/esm/metrics/NoopMeterProvider.js"() {
9268
- "use strict";
9269
- init_NoopMeter();
9270
- NoopMeterProvider = /** @class */
9271
- (function() {
9272
- function NoopMeterProvider2() {
9273
- }
9274
- NoopMeterProvider2.prototype.getMeter = function(_name, _version, _options) {
9275
- return NOOP_METER;
9276
- };
9277
- return NoopMeterProvider2;
9278
- })();
9279
- NOOP_METER_PROVIDER = new NoopMeterProvider();
9280
- }
9281
- });
9282
-
9283
- // node_modules/@opentelemetry/api/build/esm/api/metrics.js
9284
- var API_NAME3, MetricsAPI;
9285
- var init_metrics = __esm({
9286
- "node_modules/@opentelemetry/api/build/esm/api/metrics.js"() {
9287
- "use strict";
9288
- init_NoopMeterProvider();
9289
- init_global_utils();
9290
- init_diag();
9291
- API_NAME3 = "metrics";
9292
- MetricsAPI = /** @class */
9293
- (function() {
9294
- function MetricsAPI2() {
9295
- }
9296
- MetricsAPI2.getInstance = function() {
9297
- if (!this._instance) {
9298
- this._instance = new MetricsAPI2();
9299
- }
9300
- return this._instance;
9301
- };
9302
- MetricsAPI2.prototype.setGlobalMeterProvider = function(provider) {
9303
- return registerGlobal(API_NAME3, provider, DiagAPI.instance());
9304
- };
9305
- MetricsAPI2.prototype.getMeterProvider = function() {
9306
- return getGlobal(API_NAME3) || NOOP_METER_PROVIDER;
9307
- };
9308
- MetricsAPI2.prototype.getMeter = function(name, version, options) {
9309
- return this.getMeterProvider().getMeter(name, version, options);
9310
- };
9311
- MetricsAPI2.prototype.disable = function() {
9312
- unregisterGlobal(API_NAME3, DiagAPI.instance());
9313
- };
9314
- return MetricsAPI2;
9315
- })();
9316
- }
9317
- });
9318
-
9319
- // node_modules/@opentelemetry/api/build/esm/metrics-api.js
9320
- var metrics;
9321
- var init_metrics_api = __esm({
9322
- "node_modules/@opentelemetry/api/build/esm/metrics-api.js"() {
9323
- "use strict";
9324
- init_metrics();
9325
- metrics = MetricsAPI.getInstance();
9326
- }
9327
- });
9328
-
9329
- // node_modules/@opentelemetry/api/build/esm/api/trace.js
9330
- var API_NAME4, TraceAPI;
9331
- var init_trace = __esm({
9332
- "node_modules/@opentelemetry/api/build/esm/api/trace.js"() {
9333
- "use strict";
9334
- init_global_utils();
9335
- init_ProxyTracerProvider();
9336
- init_spancontext_utils();
9337
- init_context_utils();
9338
- init_diag();
9339
- API_NAME4 = "trace";
9340
- TraceAPI = /** @class */
9341
- (function() {
9342
- function TraceAPI2() {
9343
- this._proxyTracerProvider = new ProxyTracerProvider();
9344
- this.wrapSpanContext = wrapSpanContext;
9345
- this.isSpanContextValid = isSpanContextValid;
9346
- this.deleteSpan = deleteSpan;
9347
- this.getSpan = getSpan;
9348
- this.getActiveSpan = getActiveSpan;
9349
- this.getSpanContext = getSpanContext;
9350
- this.setSpan = setSpan;
9351
- this.setSpanContext = setSpanContext;
9352
- }
9353
- TraceAPI2.getInstance = function() {
9354
- if (!this._instance) {
9355
- this._instance = new TraceAPI2();
9356
- }
9357
- return this._instance;
9358
- };
9359
- TraceAPI2.prototype.setGlobalTracerProvider = function(provider) {
9360
- var success = registerGlobal(API_NAME4, this._proxyTracerProvider, DiagAPI.instance());
9361
- if (success) {
9362
- this._proxyTracerProvider.setDelegate(provider);
9363
- }
9364
- return success;
9365
- };
9366
- TraceAPI2.prototype.getTracerProvider = function() {
9367
- return getGlobal(API_NAME4) || this._proxyTracerProvider;
9368
- };
9369
- TraceAPI2.prototype.getTracer = function(name, version) {
9370
- return this.getTracerProvider().getTracer(name, version);
9371
- };
9372
- TraceAPI2.prototype.disable = function() {
9373
- unregisterGlobal(API_NAME4, DiagAPI.instance());
9374
- this._proxyTracerProvider = new ProxyTracerProvider();
9375
- };
9376
- return TraceAPI2;
9377
- })();
9378
- }
9379
- });
9380
-
9381
- // node_modules/@opentelemetry/api/build/esm/trace-api.js
9382
- var trace;
9383
- var init_trace_api = __esm({
9384
- "node_modules/@opentelemetry/api/build/esm/trace-api.js"() {
9385
- "use strict";
9386
- init_trace();
9387
- trace = TraceAPI.getInstance();
9388
- }
9389
- });
9390
-
9391
- // node_modules/@opentelemetry/api/build/esm/index.js
9392
- var init_esm = __esm({
9393
- "node_modules/@opentelemetry/api/build/esm/index.js"() {
9394
- "use strict";
9395
- init_context_api();
9396
- init_metrics_api();
9397
- init_trace_api();
9398
- }
9399
- });
9400
-
9401
8824
  // src/telemetry/fallback-ndjson.ts
9402
8825
  var fallback_ndjson_exports = {};
9403
8826
  __export(fallback_ndjson_exports, {
@@ -9471,7 +8894,7 @@ var init_fallback_ndjson = __esm({
9471
8894
 
9472
8895
  // src/telemetry/trace-helpers.ts
9473
8896
  function addEvent(name, attrs) {
9474
- const span = trace.getSpan(context.active());
8897
+ const span = import_api.trace.getSpan(import_api.context.active());
9475
8898
  if (span) {
9476
8899
  try {
9477
8900
  span.addEvent(name, attrs);
@@ -9490,10 +8913,11 @@ function addEvent(name, attrs) {
9490
8913
  } catch {
9491
8914
  }
9492
8915
  }
8916
+ var import_api;
9493
8917
  var init_trace_helpers = __esm({
9494
8918
  "src/telemetry/trace-helpers.ts"() {
9495
8919
  "use strict";
9496
- init_esm();
8920
+ import_api = require("@opentelemetry/api");
9497
8921
  }
9498
8922
  });
9499
8923
 
@@ -9548,26 +8972,26 @@ function addDiagramBlock(origin) {
9548
8972
  } catch {
9549
8973
  }
9550
8974
  }
9551
- var initialized, meter, TEST_ENABLED, TEST_SNAPSHOT, checkDurationHist, providerDurationHist, foreachDurationHist, issuesCounter, activeChecks, failIfCounter, diagramBlocks;
9552
- var init_metrics2 = __esm({
8975
+ var import_api2, initialized, meter, TEST_ENABLED, TEST_SNAPSHOT, checkDurationHist, providerDurationHist, foreachDurationHist, issuesCounter, activeChecks, failIfCounter, diagramBlocks;
8976
+ var init_metrics = __esm({
9553
8977
  "src/telemetry/metrics.ts"() {
9554
8978
  "use strict";
9555
- init_esm();
8979
+ import_api2 = require("@opentelemetry/api");
9556
8980
  initialized = false;
9557
- meter = metrics.getMeter("visor");
8981
+ meter = import_api2.metrics.getMeter("visor");
9558
8982
  TEST_ENABLED = process.env.VISOR_TEST_METRICS === "true";
9559
8983
  TEST_SNAPSHOT = { fail_if_triggered: 0 };
9560
8984
  }
9561
8985
  });
9562
8986
 
9563
8987
  // src/failure-condition-evaluator.ts
9564
- var import_sandboxjs4, FailureConditionEvaluator;
8988
+ var import_sandboxjs5, FailureConditionEvaluator;
9565
8989
  var init_failure_condition_evaluator = __esm({
9566
8990
  "src/failure-condition-evaluator.ts"() {
9567
8991
  "use strict";
9568
8992
  init_trace_helpers();
9569
- init_metrics2();
9570
- import_sandboxjs4 = __toESM(require("@nyariv/sandboxjs"));
8993
+ init_metrics();
8994
+ import_sandboxjs5 = __toESM(require("@nyariv/sandboxjs"));
9571
8995
  init_author_permissions();
9572
8996
  init_memory_store();
9573
8997
  FailureConditionEvaluator = class _FailureConditionEvaluator {
@@ -9579,7 +9003,7 @@ var init_failure_condition_evaluator = __esm({
9579
9003
  */
9580
9004
  createSecureSandbox() {
9581
9005
  const globals = {
9582
- ...import_sandboxjs4.default.SAFE_GLOBALS,
9006
+ ...import_sandboxjs5.default.SAFE_GLOBALS,
9583
9007
  // Allow Math for calculations
9584
9008
  Math,
9585
9009
  // Allow console for debugging (in controlled environment)
@@ -9589,7 +9013,7 @@ var init_failure_condition_evaluator = __esm({
9589
9013
  error: console.error
9590
9014
  }
9591
9015
  };
9592
- const prototypeWhitelist = new Map(import_sandboxjs4.default.SAFE_PROTOTYPES);
9016
+ const prototypeWhitelist = new Map(import_sandboxjs5.default.SAFE_PROTOTYPES);
9593
9017
  const arrayMethods = /* @__PURE__ */ new Set([
9594
9018
  "some",
9595
9019
  "every",
@@ -9622,7 +9046,7 @@ var init_failure_condition_evaluator = __esm({
9622
9046
  prototypeWhitelist.set(String.prototype, stringMethods);
9623
9047
  const objectMethods = /* @__PURE__ */ new Set(["hasOwnProperty", "toString", "valueOf"]);
9624
9048
  prototypeWhitelist.set(Object.prototype, objectMethods);
9625
- return new import_sandboxjs4.default({
9049
+ return new import_sandboxjs5.default({
9626
9050
  globals,
9627
9051
  prototypeWhitelist
9628
9052
  });
@@ -9631,7 +9055,7 @@ var init_failure_condition_evaluator = __esm({
9631
9055
  * Evaluate simple fail_if condition
9632
9056
  */
9633
9057
  async evaluateSimpleCondition(checkName, checkSchema, checkGroup, reviewSummary, expression, previousOutputs, authorAssociation) {
9634
- const context2 = this.buildEvaluationContext(
9058
+ const context = this.buildEvaluationContext(
9635
9059
  checkName,
9636
9060
  checkSchema,
9637
9061
  checkGroup,
@@ -9641,17 +9065,17 @@ var init_failure_condition_evaluator = __esm({
9641
9065
  );
9642
9066
  try {
9643
9067
  try {
9644
- const isObj = context2.output && typeof context2.output === "object";
9645
- const keys = isObj ? Object.keys(context2.output).join(",") : typeof context2.output;
9068
+ const isObj = context.output && typeof context.output === "object";
9069
+ const keys = isObj ? Object.keys(context.output).join(",") : typeof context.output;
9646
9070
  let errorVal = void 0;
9647
- if (isObj && context2.output.error !== void 0)
9648
- errorVal = context2.output.error;
9071
+ if (isObj && context.output.error !== void 0)
9072
+ errorVal = context.output.error;
9649
9073
  (init_logger(), __toCommonJS(logger_exports)).logger.debug(
9650
9074
  ` fail_if: evaluating '${expression}' with output keys=${keys} error=${String(errorVal)}`
9651
9075
  );
9652
9076
  } catch {
9653
9077
  }
9654
- const res = this.evaluateExpression(expression, context2);
9078
+ const res = this.evaluateExpression(expression, context);
9655
9079
  if (res === true) {
9656
9080
  try {
9657
9081
  addEvent("fail_if.triggered", {
@@ -9710,7 +9134,7 @@ var init_failure_condition_evaluator = __esm({
9710
9134
  * Evaluate if condition to determine whether a check should run
9711
9135
  */
9712
9136
  async evaluateIfCondition(checkName, expression, contextData) {
9713
- const context2 = {
9137
+ const context = {
9714
9138
  // Check metadata
9715
9139
  checkName,
9716
9140
  // Git context
@@ -9759,7 +9183,7 @@ var init_failure_condition_evaluator = __esm({
9759
9183
  }
9760
9184
  };
9761
9185
  try {
9762
- return this.evaluateExpression(expression, context2);
9186
+ return this.evaluateExpression(expression, context);
9763
9187
  } catch (error) {
9764
9188
  console.warn(`Failed to evaluate if expression for check '${checkName}': ${error}`);
9765
9189
  return true;
@@ -9769,7 +9193,7 @@ var init_failure_condition_evaluator = __esm({
9769
9193
  * Evaluate all failure conditions for a check result
9770
9194
  */
9771
9195
  async evaluateConditions(checkName, checkSchema, checkGroup, reviewSummary, globalConditions, checkConditions, previousOutputs, authorAssociation) {
9772
- const context2 = this.buildEvaluationContext(
9196
+ const context = this.buildEvaluationContext(
9773
9197
  checkName,
9774
9198
  checkSchema,
9775
9199
  checkGroup,
@@ -9779,11 +9203,11 @@ var init_failure_condition_evaluator = __esm({
9779
9203
  );
9780
9204
  const results = [];
9781
9205
  if (globalConditions) {
9782
- const globalResults = await this.evaluateConditionSet(globalConditions, context2, "global");
9206
+ const globalResults = await this.evaluateConditionSet(globalConditions, context, "global");
9783
9207
  results.push(...globalResults);
9784
9208
  }
9785
9209
  if (checkConditions) {
9786
- const checkResults = await this.evaluateConditionSet(checkConditions, context2, "check");
9210
+ const checkResults = await this.evaluateConditionSet(checkConditions, context, "check");
9787
9211
  const overriddenConditions = new Set(Object.keys(checkConditions));
9788
9212
  const filteredResults = results.filter(
9789
9213
  (result) => !overriddenConditions.has(result.conditionName)
@@ -9795,7 +9219,7 @@ var init_failure_condition_evaluator = __esm({
9795
9219
  if (checkName === "B") {
9796
9220
  console.error(
9797
9221
  `\u{1F527} Debug: fail_if results for ${checkName}: ${JSON.stringify(results)} context.output=${JSON.stringify(
9798
- context2.output
9222
+ context.output
9799
9223
  )}`
9800
9224
  );
9801
9225
  }
@@ -9806,12 +9230,12 @@ var init_failure_condition_evaluator = __esm({
9806
9230
  /**
9807
9231
  * Evaluate a set of failure conditions
9808
9232
  */
9809
- async evaluateConditionSet(conditions, context2, source) {
9233
+ async evaluateConditionSet(conditions, context, source) {
9810
9234
  const results = [];
9811
9235
  for (const [conditionName, condition] of Object.entries(conditions)) {
9812
9236
  try {
9813
9237
  addEvent("fail_if.evaluated", {
9814
- check: context2.checkName,
9238
+ check: context.checkName,
9815
9239
  scope: source,
9816
9240
  name: conditionName,
9817
9241
  expression: this.extractExpression(condition)
@@ -9822,12 +9246,12 @@ var init_failure_condition_evaluator = __esm({
9822
9246
  const { emitNdjsonSpanWithEvents: emitNdjsonSpanWithEvents2 } = (init_fallback_ndjson(), __toCommonJS(fallback_ndjson_exports));
9823
9247
  emitNdjsonSpanWithEvents2(
9824
9248
  "visor.fail_if",
9825
- { check: context2.checkName || "unknown", scope: source, name: conditionName },
9249
+ { check: context.checkName || "unknown", scope: source, name: conditionName },
9826
9250
  [
9827
9251
  {
9828
9252
  name: "fail_if.evaluated",
9829
9253
  attrs: {
9830
- check: context2.checkName,
9254
+ check: context.checkName,
9831
9255
  scope: source,
9832
9256
  name: conditionName,
9833
9257
  expression: this.extractExpression(condition)
@@ -9838,12 +9262,12 @@ var init_failure_condition_evaluator = __esm({
9838
9262
  } catch {
9839
9263
  }
9840
9264
  try {
9841
- const result = await this.evaluateSingleCondition(conditionName, condition, context2);
9265
+ const result = await this.evaluateSingleCondition(conditionName, condition, context);
9842
9266
  results.push(result);
9843
9267
  if (result.failed) {
9844
9268
  try {
9845
9269
  addEvent("fail_if.triggered", {
9846
- check: context2.checkName,
9270
+ check: context.checkName,
9847
9271
  scope: source,
9848
9272
  name: conditionName,
9849
9273
  expression: result.expression,
@@ -9853,7 +9277,7 @@ var init_failure_condition_evaluator = __esm({
9853
9277
  } catch {
9854
9278
  }
9855
9279
  try {
9856
- addFailIfTriggered(context2.checkName || "unknown", source);
9280
+ addFailIfTriggered(context.checkName || "unknown", source);
9857
9281
  } catch {
9858
9282
  }
9859
9283
  }
@@ -9873,11 +9297,11 @@ var init_failure_condition_evaluator = __esm({
9873
9297
  /**
9874
9298
  * Evaluate a single failure condition
9875
9299
  */
9876
- async evaluateSingleCondition(conditionName, condition, context2) {
9300
+ async evaluateSingleCondition(conditionName, condition, context) {
9877
9301
  const expression = this.extractExpression(condition);
9878
9302
  const config = this.extractConditionConfig(condition);
9879
9303
  try {
9880
- const failed = this.evaluateExpression(expression, context2);
9304
+ const failed = this.evaluateExpression(expression, context);
9881
9305
  return {
9882
9306
  conditionName,
9883
9307
  failed,
@@ -9896,7 +9320,7 @@ var init_failure_condition_evaluator = __esm({
9896
9320
  * Secure expression evaluation using SandboxJS
9897
9321
  * Supports the same GitHub Actions-style functions as the previous implementation
9898
9322
  */
9899
- evaluateExpression(condition, context2) {
9323
+ evaluateExpression(condition, context) {
9900
9324
  try {
9901
9325
  const normalize2 = (expr) => {
9902
9326
  const trimmed = expr.trim();
@@ -9941,7 +9365,7 @@ var init_failure_condition_evaluator = __esm({
9941
9365
  const hasIssueWith = hasIssue;
9942
9366
  const hasFileWith = hasFileMatching;
9943
9367
  const permissionHelpers = createPermissionHelpers(
9944
- context2.authorAssociation,
9368
+ context.authorAssociation,
9945
9369
  detectLocalMode()
9946
9370
  );
9947
9371
  const hasMinPermission2 = permissionHelpers.hasMinPermission;
@@ -9950,35 +9374,35 @@ var init_failure_condition_evaluator = __esm({
9950
9374
  const isCollaborator2 = permissionHelpers.isCollaborator;
9951
9375
  const isContributor2 = permissionHelpers.isContributor;
9952
9376
  const isFirstTimer2 = permissionHelpers.isFirstTimer;
9953
- const output = context2.output || {};
9377
+ const output = context.output || {};
9954
9378
  const issues = output.issues || [];
9955
- const metadata = context2.metadata || {
9956
- checkName: context2.checkName || "",
9957
- schema: context2.schema || "",
9958
- group: context2.group || "",
9379
+ const metadata = context.metadata || {
9380
+ checkName: context.checkName || "",
9381
+ schema: context.schema || "",
9382
+ group: context.group || "",
9959
9383
  criticalIssues: issues.filter((i) => i.severity === "critical").length,
9960
9384
  errorIssues: issues.filter((i) => i.severity === "error").length,
9961
9385
  warningIssues: issues.filter((i) => i.severity === "warning").length,
9962
9386
  infoIssues: issues.filter((i) => i.severity === "info").length,
9963
9387
  totalIssues: issues.length,
9964
- hasChanges: context2.hasChanges || false
9388
+ hasChanges: context.hasChanges || false
9965
9389
  };
9966
9390
  const criticalIssues = metadata.criticalIssues;
9967
9391
  const errorIssues = metadata.errorIssues;
9968
9392
  const totalIssues = metadata.totalIssues;
9969
9393
  const warningIssues = metadata.warningIssues;
9970
9394
  const infoIssues = metadata.infoIssues;
9971
- const checkName = context2.checkName || "";
9972
- const schema = context2.schema || "";
9973
- const group = context2.group || "";
9974
- const branch = context2.branch || "unknown";
9975
- const baseBranch = context2.baseBranch || "main";
9976
- const filesChanged = context2.filesChanged || [];
9977
- const filesCount = context2.filesCount || 0;
9978
- const event = context2.event || "manual";
9979
- const env = context2.env || {};
9980
- const outputs = context2.outputs || {};
9981
- const debugData = context2.debug || null;
9395
+ const checkName = context.checkName || "";
9396
+ const schema = context.schema || "";
9397
+ const group = context.group || "";
9398
+ const branch = context.branch || "unknown";
9399
+ const baseBranch = context.baseBranch || "main";
9400
+ const filesChanged = context.filesChanged || [];
9401
+ const filesCount = context.filesCount || 0;
9402
+ const event = context.event || "manual";
9403
+ const env = context.env || {};
9404
+ const outputs = context.outputs || {};
9405
+ const debugData = context.debug || null;
9982
9406
  const memoryStore = MemoryStore.getInstance();
9983
9407
  const memoryAccessor = {
9984
9408
  get: (key, ns) => memoryStore.get(key, ns),
@@ -10179,7 +9603,7 @@ var init_failure_condition_evaluator = __esm({
10179
9603
  } catch {
10180
9604
  }
10181
9605
  const memoryStore = MemoryStore.getInstance();
10182
- const context2 = {
9606
+ const context = {
10183
9607
  output: aggregatedOutput,
10184
9608
  outputs: (() => {
10185
9609
  if (!previousOutputs) return {};
@@ -10204,14 +9628,14 @@ var init_failure_condition_evaluator = __esm({
10204
9628
  authorAssociation
10205
9629
  };
10206
9630
  if (debug) {
10207
- context2.debug = {
9631
+ context.debug = {
10208
9632
  errors: debug.errors || [],
10209
9633
  processingTime: debug.processingTime || 0,
10210
9634
  provider: debug.provider || "unknown",
10211
9635
  model: debug.model || "unknown"
10212
9636
  };
10213
9637
  }
10214
- return context2;
9638
+ return context;
10215
9639
  }
10216
9640
  // Minimal JSON-from-end extractor for fail_if context fallback
10217
9641
  tryExtractJsonFromEnd(text) {
@@ -10791,7 +10215,7 @@ var init_mermaid_telemetry = __esm({
10791
10215
  "src/utils/mermaid-telemetry.ts"() {
10792
10216
  "use strict";
10793
10217
  init_trace_helpers();
10794
- init_metrics2();
10218
+ init_metrics();
10795
10219
  fs9 = __toESM(require("fs"));
10796
10220
  path10 = __toESM(require("path"));
10797
10221
  MERMAID_RE = /```mermaid\s*\n([\s\S]*?)\n```/gi;
@@ -10826,7 +10250,7 @@ function getSafeEnvironmentVariables() {
10826
10250
  }
10827
10251
  return safeEnv;
10828
10252
  }
10829
- var import_sandboxjs5, CheckExecutionEngine;
10253
+ var import_sandboxjs6, CheckExecutionEngine;
10830
10254
  var init_check_execution_engine = __esm({
10831
10255
  "src/check-execution-engine.ts"() {
10832
10256
  "use strict";
@@ -10839,12 +10263,12 @@ var init_check_execution_engine = __esm({
10839
10263
  init_github_check_service();
10840
10264
  init_issue_filter();
10841
10265
  init_logger();
10842
- import_sandboxjs5 = __toESM(require("@nyariv/sandboxjs"));
10266
+ import_sandboxjs6 = __toESM(require("@nyariv/sandboxjs"));
10843
10267
  init_author_permissions();
10844
10268
  init_memory_store();
10845
10269
  init_fallback_ndjson();
10846
10270
  init_trace_helpers();
10847
- init_metrics2();
10271
+ init_metrics();
10848
10272
  CheckExecutionEngine = class _CheckExecutionEngine {
10849
10273
  gitAnalyzer;
10850
10274
  mockOctokit;
@@ -10898,13 +10322,13 @@ var init_check_execution_engine = __esm({
10898
10322
  getRoutingSandbox() {
10899
10323
  if (this.routingSandbox) return this.routingSandbox;
10900
10324
  const globals = {
10901
- ...import_sandboxjs5.default.SAFE_GLOBALS,
10325
+ ...import_sandboxjs6.default.SAFE_GLOBALS,
10902
10326
  Math,
10903
10327
  JSON,
10904
10328
  console: { log: console.log }
10905
10329
  };
10906
- const prototypeWhitelist = new Map(import_sandboxjs5.default.SAFE_PROTOTYPES);
10907
- this.routingSandbox = new import_sandboxjs5.default({ globals, prototypeWhitelist });
10330
+ const prototypeWhitelist = new Map(import_sandboxjs6.default.SAFE_PROTOTYPES);
10331
+ this.routingSandbox = new import_sandboxjs6.default({ globals, prototypeWhitelist });
10908
10332
  return this.routingSandbox;
10909
10333
  }
10910
10334
  redact(str, limit = 200) {
@@ -12269,7 +11693,7 @@ ${expr}
12269
11693
  if (!sanitizedSchema) {
12270
11694
  throw new Error("Invalid schema name");
12271
11695
  }
12272
- const templatePath = path13.join(__dirname, `../output/${sanitizedSchema}/template.liquid`);
11696
+ const templatePath = path13.join(__dirname, `output/${sanitizedSchema}/template.liquid`);
12273
11697
  templateContent = await fs12.readFile(templatePath, "utf-8");
12274
11698
  if (sanitizedSchema === "issue-assistant") {
12275
11699
  enrichAssistantContext = true;
@@ -15410,9 +14834,13 @@ var init_config_schema = __esm({
15410
14834
  ],
15411
14835
  description: 'Extends from other configurations - can be file path, HTTP(S) URL, or "default"'
15412
14836
  },
14837
+ steps: {
14838
+ $ref: "#/definitions/Record%3Cstring%2CCheckConfig%3E",
14839
+ description: "Step configurations (recommended)"
14840
+ },
15413
14841
  checks: {
15414
14842
  $ref: "#/definitions/Record%3Cstring%2CCheckConfig%3E",
15415
- description: "Check configurations"
14843
+ description: "Check configurations (legacy, use 'steps' instead) - always populated after normalization"
15416
14844
  },
15417
14845
  output: {
15418
14846
  $ref: "#/definitions/OutputConfig",
@@ -15467,7 +14895,7 @@ var init_config_schema = __esm({
15467
14895
  description: "Optional routing defaults for retry/goto/run policies"
15468
14896
  }
15469
14897
  },
15470
- required: ["version", "checks", "output"],
14898
+ required: ["version", "output"],
15471
14899
  additionalProperties: false,
15472
14900
  description: "Main Visor configuration",
15473
14901
  patternProperties: {
@@ -15713,6 +15141,23 @@ var init_config_schema = __esm({
15713
15141
  }
15714
15142
  ],
15715
15143
  description: "Values for GitHub operations (can be array or single value)"
15144
+ },
15145
+ transport: {
15146
+ type: "string",
15147
+ enum: ["stdio", "sse", "http"],
15148
+ description: "Transport type for MCP: stdio (default), sse (legacy), or http (streamable HTTP)"
15149
+ },
15150
+ methodArgs: {
15151
+ $ref: "#/definitions/Record%3Cstring%2Cunknown%3E",
15152
+ description: "Arguments to pass to the MCP method (supports Liquid templates)"
15153
+ },
15154
+ argsTransform: {
15155
+ type: "string",
15156
+ description: "Transform template for method arguments (Liquid)"
15157
+ },
15158
+ sessionId: {
15159
+ type: "string",
15160
+ description: "Session ID for HTTP transport (optional, server may generate one)"
15716
15161
  }
15717
15162
  },
15718
15163
  additionalProperties: false,
@@ -15733,7 +15178,8 @@ var init_config_schema = __esm({
15733
15178
  "log",
15734
15179
  "memory",
15735
15180
  "github",
15736
- "claude-code"
15181
+ "claude-code",
15182
+ "mcp"
15737
15183
  ],
15738
15184
  description: "Valid check types in configuration"
15739
15185
  },
@@ -16646,10 +16092,11 @@ var ConfigLoader = class {
16646
16092
  if (defaultConfigPath && fs10.existsSync(defaultConfigPath)) {
16647
16093
  console.error(`\u{1F4E6} Loading bundled default configuration from ${defaultConfigPath}`);
16648
16094
  const content = fs10.readFileSync(defaultConfigPath, "utf8");
16649
- const config = yaml.load(content);
16095
+ let config = yaml.load(content);
16650
16096
  if (!config || typeof config !== "object") {
16651
16097
  throw new Error("Invalid default configuration");
16652
16098
  }
16099
+ config = this.normalizeStepsAndChecks(config);
16653
16100
  if (config.extends) {
16654
16101
  return await this.processExtends(config);
16655
16102
  }
@@ -16780,6 +16227,20 @@ var ConfigLoader = class {
16780
16227
  this.loadedConfigs.clear();
16781
16228
  this.clearCache();
16782
16229
  }
16230
+ /**
16231
+ * Normalize 'checks' and 'steps' keys for backward compatibility
16232
+ * Ensures both keys are present and contain the same data
16233
+ */
16234
+ normalizeStepsAndChecks(config) {
16235
+ if (config.steps && config.checks) {
16236
+ config.checks = config.steps;
16237
+ } else if (config.steps && !config.checks) {
16238
+ config.checks = config.steps;
16239
+ } else if (config.checks && !config.steps) {
16240
+ config.steps = config.checks;
16241
+ }
16242
+ return config;
16243
+ }
16783
16244
  };
16784
16245
 
16785
16246
  // src/config.ts
@@ -16854,6 +16315,7 @@ var ConfigManager = class {
16854
16315
  parsedConfig = merger.merge(mergedConfig, configWithoutExtends);
16855
16316
  parsedConfig = merger.removeDisabledChecks(parsedConfig);
16856
16317
  }
16318
+ parsedConfig = this.normalizeStepsAndChecks(parsedConfig);
16857
16319
  if (validate) {
16858
16320
  this.validateConfig(parsedConfig);
16859
16321
  }
@@ -16920,7 +16382,9 @@ var ConfigManager = class {
16920
16382
  async getDefaultConfig() {
16921
16383
  return {
16922
16384
  version: "1.0",
16385
+ steps: {},
16923
16386
  checks: {},
16387
+ // Keep for backward compatibility
16924
16388
  max_parallelism: 3,
16925
16389
  output: {
16926
16390
  pr_comment: {
@@ -16963,10 +16427,11 @@ var ConfigManager = class {
16963
16427
  if (bundledConfigPath && fs11.existsSync(bundledConfigPath)) {
16964
16428
  console.error(`\u{1F4E6} Loading bundled default configuration from ${bundledConfigPath}`);
16965
16429
  const configContent = fs11.readFileSync(bundledConfigPath, "utf8");
16966
- const parsedConfig = yaml2.load(configContent);
16430
+ let parsedConfig = yaml2.load(configContent);
16967
16431
  if (!parsedConfig || typeof parsedConfig !== "object") {
16968
16432
  return null;
16969
16433
  }
16434
+ parsedConfig = this.normalizeStepsAndChecks(parsedConfig);
16970
16435
  this.validateConfig(parsedConfig);
16971
16436
  return this.mergeWithDefaults(parsedConfig);
16972
16437
  }
@@ -16998,6 +16463,20 @@ var ConfigManager = class {
16998
16463
  }
16999
16464
  return null;
17000
16465
  }
16466
+ /**
16467
+ * Normalize 'checks' and 'steps' keys for backward compatibility
16468
+ * Ensures both keys are present and contain the same data
16469
+ */
16470
+ normalizeStepsAndChecks(config) {
16471
+ if (config.steps && config.checks) {
16472
+ config.checks = config.steps;
16473
+ } else if (config.steps && !config.checks) {
16474
+ config.checks = config.steps;
16475
+ } else if (config.checks && !config.steps) {
16476
+ config.steps = config.checks;
16477
+ }
16478
+ return config;
16479
+ }
17001
16480
  /**
17002
16481
  * Merge configuration with CLI options
17003
16482
  */
@@ -17053,13 +16532,15 @@ var ConfigManager = class {
17053
16532
  message: "Missing required field: version"
17054
16533
  });
17055
16534
  }
17056
- if (!config.checks) {
16535
+ if (!config.checks && !config.steps) {
17057
16536
  errors.push({
17058
- field: "checks",
17059
- message: "Missing required field: checks"
16537
+ field: "checks/steps",
16538
+ message: 'Missing required field: either "checks" or "steps" must be defined. "steps" is recommended for new configurations.'
17060
16539
  });
17061
- } else {
17062
- for (const [checkName, checkConfig] of Object.entries(config.checks)) {
16540
+ }
16541
+ const checksToValidate = config.checks || config.steps;
16542
+ if (checksToValidate) {
16543
+ for (const [checkName, checkConfig] of Object.entries(checksToValidate)) {
17063
16544
  if (!checkConfig.type) {
17064
16545
  checkConfig.type = "ai";
17065
16546
  }