@probelabs/visor 0.1.96 → 0.1.97
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -5
- package/dist/{168.index.js → 136.index.js} +5 -5
- package/dist/{272.index.js → 146.index.js} +5 -5
- package/dist/{13.index.js → 160.index.js} +5 -5
- package/dist/{421.index.js → 179.index.js} +3 -3
- package/dist/{85.index.js → 191.index.js} +5 -5
- package/dist/{544.index.js → 384.index.js} +3 -3
- package/dist/{861.index.js → 405.index.js} +3 -3
- package/dist/{320.index.js → 42.index.js} +3 -3
- package/dist/448.index.js +48 -0
- package/dist/{878.index.js → 491.index.js} +5 -5
- package/dist/663.index.js +321 -0
- package/dist/69.index.js +38 -0
- package/dist/{54.index.js → 760.index.js} +5 -5
- package/dist/80.index.js +263 -0
- package/dist/886.index.js +81 -0
- package/dist/917.index.js +82 -0
- package/dist/955.index.js +82 -0
- package/dist/ai-review-service.d.ts +2 -3
- package/dist/ai-review-service.d.ts.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/generated/config-schema.d.ts +18 -1
- package/dist/generated/config-schema.d.ts.map +1 -1
- package/dist/generated/config-schema.json +23 -1
- package/dist/index.js +191599 -155303
- package/dist/proto/protoc-gen-validate/LICENSE +202 -0
- package/dist/proto/protoc-gen-validate/validate/validate.proto +797 -0
- package/dist/proto/xds/LICENSE +201 -0
- package/dist/proto/xds/xds/data/orca/v3/orca_load_report.proto +58 -0
- package/dist/proto/xds/xds/service/orca/v3/orca.proto +36 -0
- package/dist/protoc-gen-validate/LICENSE +202 -0
- package/dist/protoc-gen-validate/validate/validate.proto +797 -0
- package/dist/providers/check-provider-registry.d.ts.map +1 -1
- package/dist/providers/index.d.ts +1 -0
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/mcp-check-provider.d.ts +102 -0
- package/dist/providers/mcp-check-provider.d.ts.map +1 -0
- package/dist/sdk/check-execution-engine-S7BFPVWA.mjs +11 -0
- package/dist/sdk/{chunk-Q4S5A5TO.mjs → chunk-4VK6WTYU.mjs} +610 -21
- package/dist/sdk/chunk-4VK6WTYU.mjs.map +1 -0
- package/dist/sdk/chunk-IG3BFIIN.mjs +174 -0
- package/dist/sdk/chunk-IG3BFIIN.mjs.map +1 -0
- package/dist/sdk/chunk-YXOWIDEF.mjs +60 -0
- package/dist/sdk/chunk-YXOWIDEF.mjs.map +1 -0
- package/dist/sdk/{mermaid-telemetry-LZGDD35I.mjs → mermaid-telemetry-4DUEYCLE.mjs} +2 -2
- package/dist/sdk/sdk.d.mts +12 -1
- package/dist/sdk/sdk.d.ts +12 -1
- package/dist/sdk/sdk.js +1019 -1577
- package/dist/sdk/sdk.js.map +1 -1
- package/dist/sdk/sdk.mjs +22 -4
- package/dist/sdk/sdk.mjs.map +1 -1
- package/dist/sdk/{tracer-init-O7RLXMJ3.mjs → tracer-init-RJGAIOBP.mjs} +2 -2
- package/dist/session-registry.d.ts +2 -3
- package/dist/session-registry.d.ts.map +1 -1
- package/dist/traces/run-2025-10-19T14-24-36-341Z.ndjson +40 -0
- package/dist/traces/run-2025-10-19T14-24-48-674Z.ndjson +40 -0
- package/dist/traces/run-2025-10-19T14-24-49-238Z.ndjson +40 -0
- package/dist/traces/run-2025-10-19T14-24-49-761Z.ndjson +40 -0
- package/dist/traces/run-2025-10-19T14-24-50-279Z.ndjson +12 -0
- package/dist/types/config.d.ts +12 -1
- package/dist/types/config.d.ts.map +1 -1
- package/dist/utils/tracer-init.d.ts +3 -4
- package/dist/utils/tracer-init.d.ts.map +1 -1
- package/dist/xds/LICENSE +201 -0
- package/dist/xds/xds/data/orca/v3/orca_load_report.proto +58 -0
- package/dist/xds/xds/service/orca/v3/orca.proto +36 -0
- package/package.json +15 -8
- package/dist/sdk/check-execution-engine-NMPXJ7FQ.mjs +0 -11
- package/dist/sdk/chunk-KVHVCGY6.mjs +0 -103
- package/dist/sdk/chunk-KVHVCGY6.mjs.map +0 -1
- package/dist/sdk/chunk-Q4S5A5TO.mjs.map +0 -1
- package/dist/sdk/chunk-TWJKAYT6.mjs +0 -1124
- package/dist/sdk/chunk-TWJKAYT6.mjs.map +0 -1
- /package/dist/{traces/run-2025-10-18T20-24-27-886Z.ndjson → output/traces/run-2025-10-19T14-24-36-341Z.ndjson} +0 -0
- /package/dist/{traces/run-2025-10-18T20-24-38-817Z.ndjson → output/traces/run-2025-10-19T14-24-48-674Z.ndjson} +0 -0
- /package/dist/{traces/run-2025-10-18T20-24-39-361Z.ndjson → output/traces/run-2025-10-19T14-24-49-238Z.ndjson} +0 -0
- /package/dist/{traces/run-2025-10-18T20-24-39-852Z.ndjson → output/traces/run-2025-10-19T14-24-49-761Z.ndjson} +0 -0
- /package/dist/{traces/run-2025-10-18T20-24-40-335Z.ndjson → output/traces/run-2025-10-19T14-24-50-279Z.ndjson} +0 -0
- /package/dist/sdk/{check-execution-engine-NMPXJ7FQ.mjs.map → check-execution-engine-S7BFPVWA.mjs.map} +0 -0
- /package/dist/sdk/{mermaid-telemetry-LZGDD35I.mjs.map → mermaid-telemetry-4DUEYCLE.mjs.map} +0 -0
- /package/dist/sdk/{tracer-init-O7RLXMJ3.mjs.map → tracer-init-RJGAIOBP.mjs.map} +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
init_tracer_init,
|
|
3
3
|
initializeTracer
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-YXOWIDEF.mjs";
|
|
5
5
|
import {
|
|
6
6
|
MemoryStore,
|
|
7
7
|
createExtendedLiquid,
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
emitNdjsonSpanWithEvents,
|
|
20
20
|
fallback_ndjson_exports,
|
|
21
21
|
init_fallback_ndjson
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-IG3BFIIN.mjs";
|
|
23
23
|
import {
|
|
24
24
|
__esm,
|
|
25
25
|
__export,
|
|
@@ -139,7 +139,7 @@ var init_session_registry = __esm({
|
|
|
139
139
|
});
|
|
140
140
|
if (sourceAgent.debug && checkName) {
|
|
141
141
|
try {
|
|
142
|
-
const { initializeTracer: initializeTracer2 } = await import("./tracer-init-
|
|
142
|
+
const { initializeTracer: initializeTracer2 } = await import("./tracer-init-RJGAIOBP.mjs");
|
|
143
143
|
const tracerResult = await initializeTracer2(newSessionId, checkName);
|
|
144
144
|
if (tracerResult) {
|
|
145
145
|
clonedAgent.tracer = tracerResult.tracer;
|
|
@@ -1864,12 +1864,14 @@ ${"=".repeat(60)}
|
|
|
1864
1864
|
}
|
|
1865
1865
|
if (traceFilePath && telemetryConfig) {
|
|
1866
1866
|
try {
|
|
1867
|
-
|
|
1868
|
-
|
|
1867
|
+
const telemetry = telemetryConfig;
|
|
1868
|
+
const tracerWithMethods = tracer;
|
|
1869
|
+
if (tracerWithMethods && typeof tracerWithMethods.flush === "function") {
|
|
1870
|
+
await tracerWithMethods.flush();
|
|
1869
1871
|
log(`\u{1F504} Flushed tracer spans`);
|
|
1870
1872
|
}
|
|
1871
|
-
if (
|
|
1872
|
-
await
|
|
1873
|
+
if (telemetry && typeof telemetry.shutdown === "function") {
|
|
1874
|
+
await telemetry.shutdown();
|
|
1873
1875
|
log(`\u{1F4CA} OpenTelemetry trace saved to: ${traceFilePath}`);
|
|
1874
1876
|
if (process.env.GITHUB_ACTIONS) {
|
|
1875
1877
|
const fs5 = __require("fs");
|
|
@@ -1880,8 +1882,8 @@ ${"=".repeat(60)}
|
|
|
1880
1882
|
);
|
|
1881
1883
|
}
|
|
1882
1884
|
}
|
|
1883
|
-
} else if (
|
|
1884
|
-
await
|
|
1885
|
+
} else if (tracerWithMethods && typeof tracerWithMethods.shutdown === "function") {
|
|
1886
|
+
await tracerWithMethods.shutdown();
|
|
1885
1887
|
log(`\u{1F4CA} Trace saved to: ${traceFilePath}`);
|
|
1886
1888
|
}
|
|
1887
1889
|
} catch (exportError) {
|
|
@@ -2275,7 +2277,7 @@ var PRReviewer = class {
|
|
|
2275
2277
|
async reviewPR(owner, repo, prNumber, prInfo, options = {}) {
|
|
2276
2278
|
const { debug = false, config, checks } = options;
|
|
2277
2279
|
if (config && checks && checks.length > 0) {
|
|
2278
|
-
const { CheckExecutionEngine: CheckExecutionEngine2 } = await import("./check-execution-engine-
|
|
2280
|
+
const { CheckExecutionEngine: CheckExecutionEngine2 } = await import("./check-execution-engine-S7BFPVWA.mjs");
|
|
2279
2281
|
const engine = new CheckExecutionEngine2();
|
|
2280
2282
|
const { results } = await engine.executeGroupedChecks(
|
|
2281
2283
|
prInfo,
|
|
@@ -6908,6 +6910,586 @@ var MemoryCheckProvider = class extends CheckProvider {
|
|
|
6908
6910
|
}
|
|
6909
6911
|
};
|
|
6910
6912
|
|
|
6913
|
+
// src/providers/mcp-check-provider.ts
|
|
6914
|
+
init_logger();
|
|
6915
|
+
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
6916
|
+
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
|
|
6917
|
+
import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
|
|
6918
|
+
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
|
|
6919
|
+
import Sandbox4 from "@nyariv/sandboxjs";
|
|
6920
|
+
var McpCheckProvider = class extends CheckProvider {
|
|
6921
|
+
liquid;
|
|
6922
|
+
sandbox;
|
|
6923
|
+
constructor() {
|
|
6924
|
+
super();
|
|
6925
|
+
this.liquid = createExtendedLiquid({
|
|
6926
|
+
cache: false,
|
|
6927
|
+
strictFilters: false,
|
|
6928
|
+
strictVariables: false
|
|
6929
|
+
});
|
|
6930
|
+
}
|
|
6931
|
+
/**
|
|
6932
|
+
* Create a secure sandbox for JavaScript execution
|
|
6933
|
+
* - Uses Sandbox.SAFE_GLOBALS which excludes: Function, eval, require, process, etc.
|
|
6934
|
+
* - Only allows explicitly whitelisted prototype methods
|
|
6935
|
+
* - No access to filesystem, network, or system resources
|
|
6936
|
+
*/
|
|
6937
|
+
createSecureSandbox() {
|
|
6938
|
+
const log2 = (...args) => {
|
|
6939
|
+
logger.debug(`[transform_js] ${args.map((a) => JSON.stringify(a)).join(" ")}`);
|
|
6940
|
+
};
|
|
6941
|
+
const globals = {
|
|
6942
|
+
...Sandbox4.SAFE_GLOBALS,
|
|
6943
|
+
// Excludes Function, eval, require, process, etc.
|
|
6944
|
+
Math,
|
|
6945
|
+
JSON,
|
|
6946
|
+
console: {
|
|
6947
|
+
log: log2
|
|
6948
|
+
}
|
|
6949
|
+
};
|
|
6950
|
+
const prototypeWhitelist = new Map(Sandbox4.SAFE_PROTOTYPES);
|
|
6951
|
+
const arrayMethods = /* @__PURE__ */ new Set([
|
|
6952
|
+
"some",
|
|
6953
|
+
"every",
|
|
6954
|
+
"filter",
|
|
6955
|
+
"map",
|
|
6956
|
+
"reduce",
|
|
6957
|
+
"find",
|
|
6958
|
+
"includes",
|
|
6959
|
+
"indexOf",
|
|
6960
|
+
"length",
|
|
6961
|
+
"slice",
|
|
6962
|
+
"concat",
|
|
6963
|
+
"join",
|
|
6964
|
+
"push",
|
|
6965
|
+
"pop",
|
|
6966
|
+
"shift",
|
|
6967
|
+
"unshift",
|
|
6968
|
+
"sort",
|
|
6969
|
+
"reverse",
|
|
6970
|
+
"flat",
|
|
6971
|
+
"flatMap"
|
|
6972
|
+
]);
|
|
6973
|
+
prototypeWhitelist.set(Array.prototype, arrayMethods);
|
|
6974
|
+
const stringMethods = /* @__PURE__ */ new Set([
|
|
6975
|
+
"toLowerCase",
|
|
6976
|
+
"toUpperCase",
|
|
6977
|
+
"includes",
|
|
6978
|
+
"indexOf",
|
|
6979
|
+
"startsWith",
|
|
6980
|
+
"endsWith",
|
|
6981
|
+
"slice",
|
|
6982
|
+
"substring",
|
|
6983
|
+
"length",
|
|
6984
|
+
"trim",
|
|
6985
|
+
"split",
|
|
6986
|
+
"replace",
|
|
6987
|
+
// String.prototype.replace for text manipulation (e.g., "hello".replace("h", "H"))
|
|
6988
|
+
"match",
|
|
6989
|
+
"padStart",
|
|
6990
|
+
"padEnd"
|
|
6991
|
+
]);
|
|
6992
|
+
prototypeWhitelist.set(String.prototype, stringMethods);
|
|
6993
|
+
const objectMethods = /* @__PURE__ */ new Set(["hasOwnProperty", "toString", "valueOf", "keys", "values"]);
|
|
6994
|
+
prototypeWhitelist.set(Object.prototype, objectMethods);
|
|
6995
|
+
return new Sandbox4({
|
|
6996
|
+
globals,
|
|
6997
|
+
prototypeWhitelist
|
|
6998
|
+
});
|
|
6999
|
+
}
|
|
7000
|
+
getName() {
|
|
7001
|
+
return "mcp";
|
|
7002
|
+
}
|
|
7003
|
+
getDescription() {
|
|
7004
|
+
return "Call MCP tools directly using stdio, SSE, or Streamable HTTP transport";
|
|
7005
|
+
}
|
|
7006
|
+
async validateConfig(config) {
|
|
7007
|
+
if (!config || typeof config !== "object") {
|
|
7008
|
+
return false;
|
|
7009
|
+
}
|
|
7010
|
+
const cfg = config;
|
|
7011
|
+
if (!cfg.method || typeof cfg.method !== "string") {
|
|
7012
|
+
logger.error("MCP check requires a method name");
|
|
7013
|
+
return false;
|
|
7014
|
+
}
|
|
7015
|
+
const transport = cfg.transport || "stdio";
|
|
7016
|
+
if (transport === "stdio") {
|
|
7017
|
+
if (!cfg.command || typeof cfg.command !== "string") {
|
|
7018
|
+
logger.error("MCP stdio transport requires a command");
|
|
7019
|
+
return false;
|
|
7020
|
+
}
|
|
7021
|
+
if (/[;&|`$(){}[\]]/.test(cfg.command)) {
|
|
7022
|
+
logger.error("MCP stdio command contains potentially unsafe characters");
|
|
7023
|
+
return false;
|
|
7024
|
+
}
|
|
7025
|
+
} else if (transport === "sse" || transport === "http") {
|
|
7026
|
+
if (!cfg.url || typeof cfg.url !== "string") {
|
|
7027
|
+
logger.error(`MCP ${transport} transport requires a URL`);
|
|
7028
|
+
return false;
|
|
7029
|
+
}
|
|
7030
|
+
try {
|
|
7031
|
+
const parsedUrl = new URL(cfg.url);
|
|
7032
|
+
if (parsedUrl.protocol !== "http:" && parsedUrl.protocol !== "https:") {
|
|
7033
|
+
logger.error(
|
|
7034
|
+
`Invalid URL protocol for MCP ${transport} transport: ${parsedUrl.protocol}. Only http: and https: are allowed.`
|
|
7035
|
+
);
|
|
7036
|
+
return false;
|
|
7037
|
+
}
|
|
7038
|
+
} catch {
|
|
7039
|
+
logger.error(`Invalid URL format for MCP ${transport} transport: ${cfg.url}`);
|
|
7040
|
+
return false;
|
|
7041
|
+
}
|
|
7042
|
+
} else {
|
|
7043
|
+
logger.error(`Invalid MCP transport: ${transport}. Must be 'stdio', 'sse', or 'http'`);
|
|
7044
|
+
return false;
|
|
7045
|
+
}
|
|
7046
|
+
return true;
|
|
7047
|
+
}
|
|
7048
|
+
async execute(prInfo, config, dependencyResults) {
|
|
7049
|
+
const cfg = config;
|
|
7050
|
+
try {
|
|
7051
|
+
const templateContext = {
|
|
7052
|
+
pr: {
|
|
7053
|
+
number: prInfo.number,
|
|
7054
|
+
title: prInfo.title,
|
|
7055
|
+
author: prInfo.author,
|
|
7056
|
+
branch: prInfo.head,
|
|
7057
|
+
base: prInfo.base
|
|
7058
|
+
},
|
|
7059
|
+
files: prInfo.files,
|
|
7060
|
+
fileCount: prInfo.files.length,
|
|
7061
|
+
outputs: this.buildOutputContext(dependencyResults),
|
|
7062
|
+
env: this.getSafeEnvironmentVariables()
|
|
7063
|
+
};
|
|
7064
|
+
let methodArgs = cfg.methodArgs || {};
|
|
7065
|
+
if (cfg.argsTransform) {
|
|
7066
|
+
const rendered = await this.liquid.parseAndRender(cfg.argsTransform, templateContext);
|
|
7067
|
+
try {
|
|
7068
|
+
methodArgs = JSON.parse(rendered);
|
|
7069
|
+
} catch (error) {
|
|
7070
|
+
logger.error(`Failed to parse argsTransform as JSON: ${error}`);
|
|
7071
|
+
return {
|
|
7072
|
+
issues: [
|
|
7073
|
+
{
|
|
7074
|
+
file: "mcp",
|
|
7075
|
+
line: 0,
|
|
7076
|
+
ruleId: "mcp/args_transform_error",
|
|
7077
|
+
message: `Failed to parse argsTransform: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
7078
|
+
severity: "error",
|
|
7079
|
+
category: "logic"
|
|
7080
|
+
}
|
|
7081
|
+
]
|
|
7082
|
+
};
|
|
7083
|
+
}
|
|
7084
|
+
}
|
|
7085
|
+
const result = await this.executeMcpMethod(cfg, methodArgs);
|
|
7086
|
+
let finalOutput = result;
|
|
7087
|
+
if (cfg.transform) {
|
|
7088
|
+
try {
|
|
7089
|
+
const transformContext = {
|
|
7090
|
+
...templateContext,
|
|
7091
|
+
output: result
|
|
7092
|
+
};
|
|
7093
|
+
const rendered = await this.liquid.parseAndRender(cfg.transform, transformContext);
|
|
7094
|
+
try {
|
|
7095
|
+
finalOutput = JSON.parse(rendered.trim());
|
|
7096
|
+
} catch {
|
|
7097
|
+
finalOutput = rendered.trim();
|
|
7098
|
+
}
|
|
7099
|
+
} catch (error) {
|
|
7100
|
+
logger.error(`Failed to apply Liquid transform: ${error}`);
|
|
7101
|
+
return {
|
|
7102
|
+
issues: [
|
|
7103
|
+
{
|
|
7104
|
+
file: "mcp",
|
|
7105
|
+
line: 0,
|
|
7106
|
+
ruleId: "mcp/transform_error",
|
|
7107
|
+
message: `Failed to apply transform: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
7108
|
+
severity: "error",
|
|
7109
|
+
category: "logic"
|
|
7110
|
+
}
|
|
7111
|
+
]
|
|
7112
|
+
};
|
|
7113
|
+
}
|
|
7114
|
+
}
|
|
7115
|
+
if (cfg.transform_js) {
|
|
7116
|
+
try {
|
|
7117
|
+
if (!this.sandbox) {
|
|
7118
|
+
this.sandbox = this.createSecureSandbox();
|
|
7119
|
+
}
|
|
7120
|
+
const scope = {
|
|
7121
|
+
output: finalOutput,
|
|
7122
|
+
pr: templateContext.pr,
|
|
7123
|
+
files: templateContext.files,
|
|
7124
|
+
outputs: templateContext.outputs,
|
|
7125
|
+
env: templateContext.env
|
|
7126
|
+
};
|
|
7127
|
+
const exec = this.sandbox.compile(`return (${cfg.transform_js});`);
|
|
7128
|
+
finalOutput = exec(scope).run();
|
|
7129
|
+
} catch (error) {
|
|
7130
|
+
logger.error(`Failed to apply JavaScript transform: ${error}`);
|
|
7131
|
+
return {
|
|
7132
|
+
issues: [
|
|
7133
|
+
{
|
|
7134
|
+
file: "mcp",
|
|
7135
|
+
line: 0,
|
|
7136
|
+
ruleId: "mcp/transform_js_error",
|
|
7137
|
+
message: `Failed to apply JavaScript transform: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
7138
|
+
severity: "error",
|
|
7139
|
+
category: "logic"
|
|
7140
|
+
}
|
|
7141
|
+
]
|
|
7142
|
+
};
|
|
7143
|
+
}
|
|
7144
|
+
}
|
|
7145
|
+
const extracted = this.extractIssuesFromOutput(finalOutput);
|
|
7146
|
+
if (extracted) {
|
|
7147
|
+
return {
|
|
7148
|
+
issues: extracted.issues,
|
|
7149
|
+
...extracted.remainingOutput ? { output: extracted.remainingOutput } : {}
|
|
7150
|
+
};
|
|
7151
|
+
}
|
|
7152
|
+
return {
|
|
7153
|
+
issues: [],
|
|
7154
|
+
...finalOutput ? { output: finalOutput } : {}
|
|
7155
|
+
};
|
|
7156
|
+
} catch (error) {
|
|
7157
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
7158
|
+
logger.error(`MCP check failed: ${errorMessage}`);
|
|
7159
|
+
return {
|
|
7160
|
+
issues: [
|
|
7161
|
+
{
|
|
7162
|
+
file: "mcp",
|
|
7163
|
+
line: 0,
|
|
7164
|
+
ruleId: "mcp/execution_error",
|
|
7165
|
+
message: `MCP check failed: ${errorMessage}`,
|
|
7166
|
+
severity: "error",
|
|
7167
|
+
category: "logic"
|
|
7168
|
+
}
|
|
7169
|
+
]
|
|
7170
|
+
};
|
|
7171
|
+
}
|
|
7172
|
+
}
|
|
7173
|
+
/**
|
|
7174
|
+
* Execute an MCP method using the configured transport
|
|
7175
|
+
*/
|
|
7176
|
+
async executeMcpMethod(config, methodArgs) {
|
|
7177
|
+
const transport = config.transport || "stdio";
|
|
7178
|
+
const timeout = (config.timeout || 60) * 1e3;
|
|
7179
|
+
if (transport === "stdio") {
|
|
7180
|
+
return await this.executeStdioMethod(config, methodArgs, timeout);
|
|
7181
|
+
} else if (transport === "sse") {
|
|
7182
|
+
return await this.executeSseMethod(config, methodArgs, timeout);
|
|
7183
|
+
} else if (transport === "http") {
|
|
7184
|
+
return await this.executeHttpMethod(config, methodArgs, timeout);
|
|
7185
|
+
} else {
|
|
7186
|
+
throw new Error(`Unsupported transport: ${transport}`);
|
|
7187
|
+
}
|
|
7188
|
+
}
|
|
7189
|
+
/**
|
|
7190
|
+
* Generic method to execute MCP method with any transport
|
|
7191
|
+
*/
|
|
7192
|
+
async executeWithTransport(transport, config, methodArgs, timeout, transportName) {
|
|
7193
|
+
const client = new Client(
|
|
7194
|
+
{
|
|
7195
|
+
name: "visor-mcp-client",
|
|
7196
|
+
version: "1.0.0"
|
|
7197
|
+
},
|
|
7198
|
+
{
|
|
7199
|
+
capabilities: {}
|
|
7200
|
+
}
|
|
7201
|
+
);
|
|
7202
|
+
try {
|
|
7203
|
+
let timeoutId;
|
|
7204
|
+
try {
|
|
7205
|
+
await Promise.race([
|
|
7206
|
+
client.connect(transport),
|
|
7207
|
+
new Promise((_, reject) => {
|
|
7208
|
+
timeoutId = setTimeout(() => reject(new Error("Connection timeout")), timeout);
|
|
7209
|
+
})
|
|
7210
|
+
]);
|
|
7211
|
+
} finally {
|
|
7212
|
+
if (timeoutId) {
|
|
7213
|
+
clearTimeout(timeoutId);
|
|
7214
|
+
}
|
|
7215
|
+
}
|
|
7216
|
+
logger.debug(`Connected to MCP server via ${transportName}`);
|
|
7217
|
+
if (transport instanceof StreamableHTTPClientTransport && transport.sessionId) {
|
|
7218
|
+
logger.debug(`MCP Session ID: ${transport.sessionId}`);
|
|
7219
|
+
}
|
|
7220
|
+
try {
|
|
7221
|
+
const toolsResult = await client.listTools();
|
|
7222
|
+
logger.debug(`Available MCP tools: ${JSON.stringify(toolsResult?.tools || [])}`);
|
|
7223
|
+
} catch (error) {
|
|
7224
|
+
logger.debug(`Could not list MCP tools: ${error}`);
|
|
7225
|
+
}
|
|
7226
|
+
let callTimeoutId;
|
|
7227
|
+
try {
|
|
7228
|
+
const result = await Promise.race([
|
|
7229
|
+
client.callTool({
|
|
7230
|
+
name: config.method,
|
|
7231
|
+
arguments: methodArgs
|
|
7232
|
+
}),
|
|
7233
|
+
new Promise((_, reject) => {
|
|
7234
|
+
callTimeoutId = setTimeout(() => reject(new Error("Request timeout")), timeout);
|
|
7235
|
+
})
|
|
7236
|
+
]);
|
|
7237
|
+
logger.debug(`MCP method result: ${JSON.stringify(result)}`);
|
|
7238
|
+
return result;
|
|
7239
|
+
} finally {
|
|
7240
|
+
if (callTimeoutId) {
|
|
7241
|
+
clearTimeout(callTimeoutId);
|
|
7242
|
+
}
|
|
7243
|
+
}
|
|
7244
|
+
} finally {
|
|
7245
|
+
try {
|
|
7246
|
+
await client.close();
|
|
7247
|
+
} catch (error) {
|
|
7248
|
+
logger.debug(`Error closing MCP client: ${error}`);
|
|
7249
|
+
}
|
|
7250
|
+
}
|
|
7251
|
+
}
|
|
7252
|
+
/**
|
|
7253
|
+
* Execute MCP method using stdio transport
|
|
7254
|
+
*/
|
|
7255
|
+
async executeStdioMethod(config, methodArgs, timeout) {
|
|
7256
|
+
const transport = new StdioClientTransport({
|
|
7257
|
+
command: config.command,
|
|
7258
|
+
args: config.args,
|
|
7259
|
+
env: config.env,
|
|
7260
|
+
cwd: config.workingDirectory
|
|
7261
|
+
});
|
|
7262
|
+
return this.executeWithTransport(
|
|
7263
|
+
transport,
|
|
7264
|
+
config,
|
|
7265
|
+
methodArgs,
|
|
7266
|
+
timeout,
|
|
7267
|
+
`stdio: ${config.command}`
|
|
7268
|
+
);
|
|
7269
|
+
}
|
|
7270
|
+
/**
|
|
7271
|
+
* Execute MCP method using SSE transport
|
|
7272
|
+
*/
|
|
7273
|
+
async executeSseMethod(config, methodArgs, timeout) {
|
|
7274
|
+
const requestInit = {};
|
|
7275
|
+
if (config.headers) {
|
|
7276
|
+
requestInit.headers = config.headers;
|
|
7277
|
+
}
|
|
7278
|
+
const transport = new SSEClientTransport(new URL(config.url), {
|
|
7279
|
+
requestInit
|
|
7280
|
+
});
|
|
7281
|
+
return this.executeWithTransport(transport, config, methodArgs, timeout, `SSE: ${config.url}`);
|
|
7282
|
+
}
|
|
7283
|
+
/**
|
|
7284
|
+
* Execute MCP method using Streamable HTTP transport
|
|
7285
|
+
*/
|
|
7286
|
+
async executeHttpMethod(config, methodArgs, timeout) {
|
|
7287
|
+
const requestInit = {};
|
|
7288
|
+
if (config.headers) {
|
|
7289
|
+
requestInit.headers = config.headers;
|
|
7290
|
+
}
|
|
7291
|
+
const transport = new StreamableHTTPClientTransport(new URL(config.url), {
|
|
7292
|
+
requestInit,
|
|
7293
|
+
sessionId: config.sessionId
|
|
7294
|
+
});
|
|
7295
|
+
return this.executeWithTransport(
|
|
7296
|
+
transport,
|
|
7297
|
+
config,
|
|
7298
|
+
methodArgs,
|
|
7299
|
+
timeout,
|
|
7300
|
+
`Streamable HTTP: ${config.url}`
|
|
7301
|
+
);
|
|
7302
|
+
}
|
|
7303
|
+
/**
|
|
7304
|
+
* Build output context from dependency results
|
|
7305
|
+
*/
|
|
7306
|
+
buildOutputContext(dependencyResults) {
|
|
7307
|
+
if (!dependencyResults) {
|
|
7308
|
+
return {};
|
|
7309
|
+
}
|
|
7310
|
+
const outputs = {};
|
|
7311
|
+
for (const [checkName, result] of dependencyResults) {
|
|
7312
|
+
const summary = result;
|
|
7313
|
+
outputs[checkName] = summary.output !== void 0 ? summary.output : summary;
|
|
7314
|
+
}
|
|
7315
|
+
return outputs;
|
|
7316
|
+
}
|
|
7317
|
+
/**
|
|
7318
|
+
* Get safe environment variables
|
|
7319
|
+
*/
|
|
7320
|
+
getSafeEnvironmentVariables() {
|
|
7321
|
+
const safeVars = {};
|
|
7322
|
+
const allowedPrefixes = ["CI_", "GITHUB_", "RUNNER_", "NODE_", "npm_", "PATH", "HOME", "USER"];
|
|
7323
|
+
for (const [key, value] of Object.entries(process.env)) {
|
|
7324
|
+
if (value !== void 0 && allowedPrefixes.some((prefix) => key.startsWith(prefix))) {
|
|
7325
|
+
safeVars[key] = value;
|
|
7326
|
+
}
|
|
7327
|
+
}
|
|
7328
|
+
safeVars["PWD"] = process.cwd();
|
|
7329
|
+
return safeVars;
|
|
7330
|
+
}
|
|
7331
|
+
/**
|
|
7332
|
+
* Extract issues from MCP output
|
|
7333
|
+
*/
|
|
7334
|
+
extractIssuesFromOutput(output) {
|
|
7335
|
+
if (output === null || output === void 0) {
|
|
7336
|
+
return null;
|
|
7337
|
+
}
|
|
7338
|
+
if (typeof output === "string") {
|
|
7339
|
+
try {
|
|
7340
|
+
const parsed = JSON.parse(output);
|
|
7341
|
+
return this.extractIssuesFromOutput(parsed);
|
|
7342
|
+
} catch {
|
|
7343
|
+
return null;
|
|
7344
|
+
}
|
|
7345
|
+
}
|
|
7346
|
+
if (Array.isArray(output)) {
|
|
7347
|
+
const issues = this.normalizeIssueArray(output);
|
|
7348
|
+
if (issues) {
|
|
7349
|
+
return { issues, remainingOutput: void 0 };
|
|
7350
|
+
}
|
|
7351
|
+
return null;
|
|
7352
|
+
}
|
|
7353
|
+
if (typeof output === "object") {
|
|
7354
|
+
const record = output;
|
|
7355
|
+
if (Array.isArray(record.issues)) {
|
|
7356
|
+
const issues = this.normalizeIssueArray(record.issues);
|
|
7357
|
+
if (!issues) {
|
|
7358
|
+
return null;
|
|
7359
|
+
}
|
|
7360
|
+
const remaining = { ...record };
|
|
7361
|
+
delete remaining.issues;
|
|
7362
|
+
return {
|
|
7363
|
+
issues,
|
|
7364
|
+
remainingOutput: Object.keys(remaining).length > 0 ? remaining : void 0
|
|
7365
|
+
};
|
|
7366
|
+
}
|
|
7367
|
+
const singleIssue = this.normalizeIssue(record);
|
|
7368
|
+
if (singleIssue) {
|
|
7369
|
+
return { issues: [singleIssue], remainingOutput: void 0 };
|
|
7370
|
+
}
|
|
7371
|
+
}
|
|
7372
|
+
return null;
|
|
7373
|
+
}
|
|
7374
|
+
/**
|
|
7375
|
+
* Normalize an array of issues
|
|
7376
|
+
*/
|
|
7377
|
+
normalizeIssueArray(values) {
|
|
7378
|
+
const normalized = [];
|
|
7379
|
+
for (const value of values) {
|
|
7380
|
+
const issue = this.normalizeIssue(value);
|
|
7381
|
+
if (!issue) {
|
|
7382
|
+
return null;
|
|
7383
|
+
}
|
|
7384
|
+
normalized.push(issue);
|
|
7385
|
+
}
|
|
7386
|
+
return normalized;
|
|
7387
|
+
}
|
|
7388
|
+
/**
|
|
7389
|
+
* Normalize a single issue
|
|
7390
|
+
*/
|
|
7391
|
+
normalizeIssue(raw) {
|
|
7392
|
+
if (!raw || typeof raw !== "object") {
|
|
7393
|
+
return null;
|
|
7394
|
+
}
|
|
7395
|
+
const data = raw;
|
|
7396
|
+
const message = this.toTrimmedString(
|
|
7397
|
+
data.message || data.text || data.description || data.summary
|
|
7398
|
+
);
|
|
7399
|
+
if (!message) {
|
|
7400
|
+
return null;
|
|
7401
|
+
}
|
|
7402
|
+
const allowedSeverities = /* @__PURE__ */ new Set(["info", "warning", "error", "critical"]);
|
|
7403
|
+
const severityRaw = this.toTrimmedString(data.severity || data.level || data.priority);
|
|
7404
|
+
let severity = "warning";
|
|
7405
|
+
if (severityRaw) {
|
|
7406
|
+
const lower = severityRaw.toLowerCase();
|
|
7407
|
+
if (allowedSeverities.has(lower)) {
|
|
7408
|
+
severity = lower;
|
|
7409
|
+
}
|
|
7410
|
+
}
|
|
7411
|
+
const allowedCategories = /* @__PURE__ */ new Set([
|
|
7412
|
+
"security",
|
|
7413
|
+
"performance",
|
|
7414
|
+
"style",
|
|
7415
|
+
"logic",
|
|
7416
|
+
"documentation"
|
|
7417
|
+
]);
|
|
7418
|
+
const categoryRaw = this.toTrimmedString(data.category || data.type || data.group);
|
|
7419
|
+
let category = "logic";
|
|
7420
|
+
if (categoryRaw && allowedCategories.has(categoryRaw.toLowerCase())) {
|
|
7421
|
+
category = categoryRaw.toLowerCase();
|
|
7422
|
+
}
|
|
7423
|
+
const file = this.toTrimmedString(data.file || data.path || data.filename) || "system";
|
|
7424
|
+
const line = this.toNumber(data.line || data.startLine || data.lineNumber) ?? 0;
|
|
7425
|
+
const endLine = this.toNumber(data.endLine || data.end_line || data.stopLine);
|
|
7426
|
+
const suggestion = this.toTrimmedString(data.suggestion);
|
|
7427
|
+
const replacement = this.toTrimmedString(data.replacement);
|
|
7428
|
+
const ruleId = this.toTrimmedString(data.ruleId || data.rule || data.id || data.check) || "mcp";
|
|
7429
|
+
return {
|
|
7430
|
+
file,
|
|
7431
|
+
line,
|
|
7432
|
+
endLine: endLine ?? void 0,
|
|
7433
|
+
ruleId,
|
|
7434
|
+
message,
|
|
7435
|
+
severity,
|
|
7436
|
+
category,
|
|
7437
|
+
suggestion: suggestion || void 0,
|
|
7438
|
+
replacement: replacement || void 0
|
|
7439
|
+
};
|
|
7440
|
+
}
|
|
7441
|
+
toTrimmedString(value) {
|
|
7442
|
+
if (typeof value === "string") {
|
|
7443
|
+
const trimmed = value.trim();
|
|
7444
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
7445
|
+
}
|
|
7446
|
+
if (value !== null && value !== void 0 && typeof value.toString === "function") {
|
|
7447
|
+
const converted = String(value).trim();
|
|
7448
|
+
return converted.length > 0 ? converted : null;
|
|
7449
|
+
}
|
|
7450
|
+
return null;
|
|
7451
|
+
}
|
|
7452
|
+
toNumber(value) {
|
|
7453
|
+
if (value === null || value === void 0) {
|
|
7454
|
+
return null;
|
|
7455
|
+
}
|
|
7456
|
+
const num = Number(value);
|
|
7457
|
+
if (Number.isFinite(num)) {
|
|
7458
|
+
return Math.trunc(num);
|
|
7459
|
+
}
|
|
7460
|
+
return null;
|
|
7461
|
+
}
|
|
7462
|
+
getSupportedConfigKeys() {
|
|
7463
|
+
return [
|
|
7464
|
+
"type",
|
|
7465
|
+
"transport",
|
|
7466
|
+
"command",
|
|
7467
|
+
"args",
|
|
7468
|
+
"env",
|
|
7469
|
+
"workingDirectory",
|
|
7470
|
+
"url",
|
|
7471
|
+
"headers",
|
|
7472
|
+
"sessionId",
|
|
7473
|
+
"method",
|
|
7474
|
+
"methodArgs",
|
|
7475
|
+
"argsTransform",
|
|
7476
|
+
"transform",
|
|
7477
|
+
"transform_js",
|
|
7478
|
+
"timeout",
|
|
7479
|
+
"depends_on",
|
|
7480
|
+
"on",
|
|
7481
|
+
"if",
|
|
7482
|
+
"group"
|
|
7483
|
+
];
|
|
7484
|
+
}
|
|
7485
|
+
async isAvailable() {
|
|
7486
|
+
return true;
|
|
7487
|
+
}
|
|
7488
|
+
getRequirements() {
|
|
7489
|
+
return ["MCP method name specified", "Transport configuration (stdio: command, sse/http: url)"];
|
|
7490
|
+
}
|
|
7491
|
+
};
|
|
7492
|
+
|
|
6911
7493
|
// src/providers/check-provider-registry.ts
|
|
6912
7494
|
var CheckProviderRegistry = class _CheckProviderRegistry {
|
|
6913
7495
|
providers = /* @__PURE__ */ new Map();
|
|
@@ -6944,6 +7526,13 @@ var CheckProviderRegistry = class _CheckProviderRegistry {
|
|
|
6944
7526
|
`Warning: Failed to register ClaudeCodeCheckProvider: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
6945
7527
|
);
|
|
6946
7528
|
}
|
|
7529
|
+
try {
|
|
7530
|
+
this.register(new McpCheckProvider());
|
|
7531
|
+
} catch (error) {
|
|
7532
|
+
console.error(
|
|
7533
|
+
`Warning: Failed to register McpCheckProvider: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
7534
|
+
);
|
|
7535
|
+
}
|
|
6947
7536
|
}
|
|
6948
7537
|
/**
|
|
6949
7538
|
* Register a check provider
|
|
@@ -7234,7 +7823,7 @@ var DependencyResolver = class {
|
|
|
7234
7823
|
};
|
|
7235
7824
|
|
|
7236
7825
|
// src/failure-condition-evaluator.ts
|
|
7237
|
-
import
|
|
7826
|
+
import Sandbox5 from "@nyariv/sandboxjs";
|
|
7238
7827
|
var FailureConditionEvaluator = class _FailureConditionEvaluator {
|
|
7239
7828
|
sandbox;
|
|
7240
7829
|
constructor() {
|
|
@@ -7244,7 +7833,7 @@ var FailureConditionEvaluator = class _FailureConditionEvaluator {
|
|
|
7244
7833
|
*/
|
|
7245
7834
|
createSecureSandbox() {
|
|
7246
7835
|
const globals = {
|
|
7247
|
-
...
|
|
7836
|
+
...Sandbox5.SAFE_GLOBALS,
|
|
7248
7837
|
// Allow Math for calculations
|
|
7249
7838
|
Math,
|
|
7250
7839
|
// Allow console for debugging (in controlled environment)
|
|
@@ -7254,7 +7843,7 @@ var FailureConditionEvaluator = class _FailureConditionEvaluator {
|
|
|
7254
7843
|
error: console.error
|
|
7255
7844
|
}
|
|
7256
7845
|
};
|
|
7257
|
-
const prototypeWhitelist = new Map(
|
|
7846
|
+
const prototypeWhitelist = new Map(Sandbox5.SAFE_PROTOTYPES);
|
|
7258
7847
|
const arrayMethods = /* @__PURE__ */ new Set([
|
|
7259
7848
|
"some",
|
|
7260
7849
|
"every",
|
|
@@ -7287,7 +7876,7 @@ var FailureConditionEvaluator = class _FailureConditionEvaluator {
|
|
|
7287
7876
|
prototypeWhitelist.set(String.prototype, stringMethods);
|
|
7288
7877
|
const objectMethods = /* @__PURE__ */ new Set(["hasOwnProperty", "toString", "valueOf"]);
|
|
7289
7878
|
prototypeWhitelist.set(Object.prototype, objectMethods);
|
|
7290
|
-
return new
|
|
7879
|
+
return new Sandbox5({
|
|
7291
7880
|
globals,
|
|
7292
7881
|
prototypeWhitelist
|
|
7293
7882
|
});
|
|
@@ -8392,7 +8981,7 @@ Please check your configuration and try again.`
|
|
|
8392
8981
|
|
|
8393
8982
|
// src/check-execution-engine.ts
|
|
8394
8983
|
init_logger();
|
|
8395
|
-
import
|
|
8984
|
+
import Sandbox6 from "@nyariv/sandboxjs";
|
|
8396
8985
|
init_fallback_ndjson();
|
|
8397
8986
|
function getSafeEnvironmentVariables() {
|
|
8398
8987
|
const safeEnvVars = [
|
|
@@ -8470,13 +9059,13 @@ var CheckExecutionEngine = class _CheckExecutionEngine {
|
|
|
8470
9059
|
getRoutingSandbox() {
|
|
8471
9060
|
if (this.routingSandbox) return this.routingSandbox;
|
|
8472
9061
|
const globals = {
|
|
8473
|
-
...
|
|
9062
|
+
...Sandbox6.SAFE_GLOBALS,
|
|
8474
9063
|
Math,
|
|
8475
9064
|
JSON,
|
|
8476
9065
|
console: { log: console.log }
|
|
8477
9066
|
};
|
|
8478
|
-
const prototypeWhitelist = new Map(
|
|
8479
|
-
this.routingSandbox = new
|
|
9067
|
+
const prototypeWhitelist = new Map(Sandbox6.SAFE_PROTOTYPES);
|
|
9068
|
+
this.routingSandbox = new Sandbox6({ globals, prototypeWhitelist });
|
|
8480
9069
|
return this.routingSandbox;
|
|
8481
9070
|
}
|
|
8482
9071
|
redact(str, limit = 200) {
|
|
@@ -9841,7 +10430,7 @@ ${expr}
|
|
|
9841
10430
|
if (!sanitizedSchema) {
|
|
9842
10431
|
throw new Error("Invalid schema name");
|
|
9843
10432
|
}
|
|
9844
|
-
const templatePath = path6.join(__dirname,
|
|
10433
|
+
const templatePath = path6.join(__dirname, `output/${sanitizedSchema}/template.liquid`);
|
|
9845
10434
|
templateContent = await fs5.readFile(templatePath, "utf-8");
|
|
9846
10435
|
if (sanitizedSchema === "issue-assistant") {
|
|
9847
10436
|
enrichAssistantContext = true;
|
|
@@ -9898,7 +10487,7 @@ ${expr}
|
|
|
9898
10487
|
}
|
|
9899
10488
|
const finalRendered = rendered.trim();
|
|
9900
10489
|
try {
|
|
9901
|
-
const { emitMermaidFromMarkdown } = await import("./mermaid-telemetry-
|
|
10490
|
+
const { emitMermaidFromMarkdown } = await import("./mermaid-telemetry-4DUEYCLE.mjs");
|
|
9902
10491
|
emitMermaidFromMarkdown(checkName, finalRendered, "content");
|
|
9903
10492
|
} catch {
|
|
9904
10493
|
}
|
|
@@ -12697,4 +13286,4 @@ ${result.value.result.debug.rawResponse}`;
|
|
|
12697
13286
|
export {
|
|
12698
13287
|
CheckExecutionEngine
|
|
12699
13288
|
};
|
|
12700
|
-
//# sourceMappingURL=chunk-
|
|
13289
|
+
//# sourceMappingURL=chunk-4VK6WTYU.mjs.map
|