@probelabs/visor 0.1.74 → 0.1.76
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/dist/check-execution-engine.d.ts.map +1 -1
- package/dist/config.d.ts +9 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/generated/config-schema.d.ts +883 -0
- package/dist/generated/config-schema.d.ts.map +1 -0
- package/dist/generated/config-schema.json +974 -0
- package/dist/index.js +11869 -682
- package/dist/sdk/{check-execution-engine-75SSXUBP.mjs → check-execution-engine-XBKOCBEK.mjs} +2 -2
- package/dist/sdk/{chunk-NINHE4RF.mjs → chunk-HDGNSOMS.mjs} +24 -2
- package/dist/sdk/{chunk-NINHE4RF.mjs.map → chunk-HDGNSOMS.mjs.map} +1 -1
- package/dist/sdk/sdk.js +1170 -3
- package/dist/sdk/sdk.js.map +1 -1
- package/dist/sdk/sdk.mjs +1152 -3
- package/dist/sdk/sdk.mjs.map +1 -1
- package/package.json +9 -5
- /package/dist/sdk/{check-execution-engine-75SSXUBP.mjs.map → check-execution-engine-XBKOCBEK.mjs.map} +0 -0
package/dist/sdk/sdk.mjs
CHANGED
|
@@ -1,14 +1,1006 @@
|
|
|
1
1
|
import {
|
|
2
|
-
CheckExecutionEngine
|
|
3
|
-
|
|
2
|
+
CheckExecutionEngine,
|
|
3
|
+
logger
|
|
4
|
+
} from "./chunk-HDGNSOMS.mjs";
|
|
4
5
|
import "./chunk-FIL2OGF6.mjs";
|
|
5
6
|
import {
|
|
6
7
|
ConfigMerger
|
|
7
8
|
} from "./chunk-U5D2LY66.mjs";
|
|
8
9
|
import {
|
|
9
|
-
|
|
10
|
+
__esm,
|
|
11
|
+
__export,
|
|
12
|
+
__require,
|
|
13
|
+
__toCommonJS
|
|
10
14
|
} from "./chunk-WMJKH4XE.mjs";
|
|
11
15
|
|
|
16
|
+
// src/generated/config-schema.ts
|
|
17
|
+
var config_schema_exports = {};
|
|
18
|
+
__export(config_schema_exports, {
|
|
19
|
+
configSchema: () => configSchema,
|
|
20
|
+
default: () => config_schema_default
|
|
21
|
+
});
|
|
22
|
+
var configSchema, config_schema_default;
|
|
23
|
+
var init_config_schema = __esm({
|
|
24
|
+
"src/generated/config-schema.ts"() {
|
|
25
|
+
"use strict";
|
|
26
|
+
configSchema = {
|
|
27
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
28
|
+
"$ref": "#/definitions/VisorConfig",
|
|
29
|
+
"definitions": {
|
|
30
|
+
"VisorConfig": {
|
|
31
|
+
"type": "object",
|
|
32
|
+
"properties": {
|
|
33
|
+
"version": {
|
|
34
|
+
"type": "string",
|
|
35
|
+
"description": "Configuration version"
|
|
36
|
+
},
|
|
37
|
+
"extends": {
|
|
38
|
+
"anyOf": [
|
|
39
|
+
{
|
|
40
|
+
"type": "string"
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"type": "array",
|
|
44
|
+
"items": {
|
|
45
|
+
"type": "string"
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
],
|
|
49
|
+
"description": 'Extends from other configurations - can be file path, HTTP(S) URL, or "default"'
|
|
50
|
+
},
|
|
51
|
+
"checks": {
|
|
52
|
+
"$ref": "#/definitions/Record%3Cstring%2CCheckConfig%3E",
|
|
53
|
+
"description": "Check configurations"
|
|
54
|
+
},
|
|
55
|
+
"output": {
|
|
56
|
+
"$ref": "#/definitions/OutputConfig",
|
|
57
|
+
"description": "Output configuration"
|
|
58
|
+
},
|
|
59
|
+
"http_server": {
|
|
60
|
+
"$ref": "#/definitions/HttpServerConfig",
|
|
61
|
+
"description": "HTTP server configuration for receiving webhooks"
|
|
62
|
+
},
|
|
63
|
+
"env": {
|
|
64
|
+
"$ref": "#/definitions/EnvConfig",
|
|
65
|
+
"description": "Global environment variables"
|
|
66
|
+
},
|
|
67
|
+
"ai_model": {
|
|
68
|
+
"type": "string",
|
|
69
|
+
"description": "Global AI model setting"
|
|
70
|
+
},
|
|
71
|
+
"ai_provider": {
|
|
72
|
+
"type": "string",
|
|
73
|
+
"description": "Global AI provider setting"
|
|
74
|
+
},
|
|
75
|
+
"ai_mcp_servers": {
|
|
76
|
+
"$ref": "#/definitions/Record%3Cstring%2CMcpServerConfig%3E",
|
|
77
|
+
"description": "Global MCP servers configuration for AI checks"
|
|
78
|
+
},
|
|
79
|
+
"max_parallelism": {
|
|
80
|
+
"type": "number",
|
|
81
|
+
"description": "Maximum number of checks to run in parallel (default: 3)"
|
|
82
|
+
},
|
|
83
|
+
"fail_fast": {
|
|
84
|
+
"type": "boolean",
|
|
85
|
+
"description": "Stop execution when any check fails (default: false)"
|
|
86
|
+
},
|
|
87
|
+
"fail_if": {
|
|
88
|
+
"type": "string",
|
|
89
|
+
"description": "Simple global fail condition - fails if expression evaluates to true"
|
|
90
|
+
},
|
|
91
|
+
"failure_conditions": {
|
|
92
|
+
"$ref": "#/definitions/FailureConditions",
|
|
93
|
+
"description": "Global failure conditions - optional (deprecated, use fail_if)"
|
|
94
|
+
},
|
|
95
|
+
"tag_filter": {
|
|
96
|
+
"$ref": "#/definitions/TagFilter",
|
|
97
|
+
"description": "Tag filter for selective check execution"
|
|
98
|
+
},
|
|
99
|
+
"routing": {
|
|
100
|
+
"$ref": "#/definitions/RoutingDefaults",
|
|
101
|
+
"description": "Optional routing defaults for retry/goto/run policies"
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
"required": [
|
|
105
|
+
"version",
|
|
106
|
+
"checks",
|
|
107
|
+
"output"
|
|
108
|
+
],
|
|
109
|
+
"additionalProperties": false,
|
|
110
|
+
"description": "Main Visor configuration",
|
|
111
|
+
"patternProperties": {
|
|
112
|
+
"^x-": {}
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
"Record<string,CheckConfig>": {
|
|
116
|
+
"type": "object",
|
|
117
|
+
"additionalProperties": {
|
|
118
|
+
"$ref": "#/definitions/CheckConfig"
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
"CheckConfig": {
|
|
122
|
+
"type": "object",
|
|
123
|
+
"properties": {
|
|
124
|
+
"type": {
|
|
125
|
+
"$ref": "#/definitions/ConfigCheckType",
|
|
126
|
+
"description": "Type of check to perform (defaults to 'ai' if not specified)"
|
|
127
|
+
},
|
|
128
|
+
"prompt": {
|
|
129
|
+
"type": "string",
|
|
130
|
+
"description": "AI prompt for the check - can be inline string or file path (auto-detected) - required for AI checks"
|
|
131
|
+
},
|
|
132
|
+
"appendPrompt": {
|
|
133
|
+
"type": "string",
|
|
134
|
+
"description": "Additional prompt to append when extending configurations - merged with parent prompt"
|
|
135
|
+
},
|
|
136
|
+
"exec": {
|
|
137
|
+
"type": "string",
|
|
138
|
+
"description": "Command execution with Liquid template support - required for command checks"
|
|
139
|
+
},
|
|
140
|
+
"stdin": {
|
|
141
|
+
"type": "string",
|
|
142
|
+
"description": "Stdin input for tools with Liquid template support - optional for tool checks"
|
|
143
|
+
},
|
|
144
|
+
"url": {
|
|
145
|
+
"type": "string",
|
|
146
|
+
"description": "HTTP URL - required for http output checks"
|
|
147
|
+
},
|
|
148
|
+
"body": {
|
|
149
|
+
"type": "string",
|
|
150
|
+
"description": "HTTP body template (Liquid) - required for http output checks"
|
|
151
|
+
},
|
|
152
|
+
"method": {
|
|
153
|
+
"type": "string",
|
|
154
|
+
"description": "HTTP method (defaults to POST)"
|
|
155
|
+
},
|
|
156
|
+
"headers": {
|
|
157
|
+
"$ref": "#/definitions/Record%3Cstring%2Cstring%3E",
|
|
158
|
+
"description": "HTTP headers"
|
|
159
|
+
},
|
|
160
|
+
"endpoint": {
|
|
161
|
+
"type": "string",
|
|
162
|
+
"description": "HTTP endpoint path - required for http_input checks"
|
|
163
|
+
},
|
|
164
|
+
"transform": {
|
|
165
|
+
"type": "string",
|
|
166
|
+
"description": "Transform template for http_input data (Liquid) - optional"
|
|
167
|
+
},
|
|
168
|
+
"transform_js": {
|
|
169
|
+
"type": "string",
|
|
170
|
+
"description": "Transform using JavaScript expressions (evaluated in secure sandbox) - optional"
|
|
171
|
+
},
|
|
172
|
+
"schedule": {
|
|
173
|
+
"type": "string",
|
|
174
|
+
"description": 'Cron schedule expression (e.g., "0 2 * * *") - optional for any check type'
|
|
175
|
+
},
|
|
176
|
+
"focus": {
|
|
177
|
+
"type": "string",
|
|
178
|
+
"description": "Focus area for the check (security/performance/style/architecture/all) - optional"
|
|
179
|
+
},
|
|
180
|
+
"command": {
|
|
181
|
+
"type": "string",
|
|
182
|
+
"description": 'Command that triggers this check (e.g., "review", "security-scan") - optional'
|
|
183
|
+
},
|
|
184
|
+
"on": {
|
|
185
|
+
"type": "array",
|
|
186
|
+
"items": {
|
|
187
|
+
"$ref": "#/definitions/EventTrigger"
|
|
188
|
+
},
|
|
189
|
+
"description": "Events that trigger this check (defaults to ['manual'] if not specified)"
|
|
190
|
+
},
|
|
191
|
+
"triggers": {
|
|
192
|
+
"type": "array",
|
|
193
|
+
"items": {
|
|
194
|
+
"type": "string"
|
|
195
|
+
},
|
|
196
|
+
"description": "File patterns that trigger this check (optional)"
|
|
197
|
+
},
|
|
198
|
+
"ai": {
|
|
199
|
+
"$ref": "#/definitions/AIProviderConfig",
|
|
200
|
+
"description": "AI provider configuration (optional)"
|
|
201
|
+
},
|
|
202
|
+
"ai_model": {
|
|
203
|
+
"type": "string",
|
|
204
|
+
"description": "AI model to use for this check - overrides global setting"
|
|
205
|
+
},
|
|
206
|
+
"ai_provider": {
|
|
207
|
+
"type": "string",
|
|
208
|
+
"description": "AI provider to use for this check - overrides global setting"
|
|
209
|
+
},
|
|
210
|
+
"ai_mcp_servers": {
|
|
211
|
+
"$ref": "#/definitions/Record%3Cstring%2CMcpServerConfig%3E",
|
|
212
|
+
"description": "MCP servers for this AI check - overrides global setting"
|
|
213
|
+
},
|
|
214
|
+
"claude_code": {
|
|
215
|
+
"$ref": "#/definitions/ClaudeCodeConfig",
|
|
216
|
+
"description": "Claude Code configuration (for claude-code type checks)"
|
|
217
|
+
},
|
|
218
|
+
"env": {
|
|
219
|
+
"$ref": "#/definitions/EnvConfig",
|
|
220
|
+
"description": "Environment variables for this check"
|
|
221
|
+
},
|
|
222
|
+
"depends_on": {
|
|
223
|
+
"type": "array",
|
|
224
|
+
"items": {
|
|
225
|
+
"type": "string"
|
|
226
|
+
},
|
|
227
|
+
"description": "Check IDs that this check depends on (optional)"
|
|
228
|
+
},
|
|
229
|
+
"group": {
|
|
230
|
+
"type": "string",
|
|
231
|
+
"description": 'Group name for comment separation (e.g., "code-review", "pr-overview") - optional'
|
|
232
|
+
},
|
|
233
|
+
"schema": {
|
|
234
|
+
"anyOf": [
|
|
235
|
+
{
|
|
236
|
+
"type": "string"
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
"$ref": "#/definitions/Record%3Cstring%2Cunknown%3E"
|
|
240
|
+
}
|
|
241
|
+
],
|
|
242
|
+
"description": 'Schema type for template rendering (e.g., "code-review", "markdown") or inline JSON schema object - optional'
|
|
243
|
+
},
|
|
244
|
+
"template": {
|
|
245
|
+
"$ref": "#/definitions/CustomTemplateConfig",
|
|
246
|
+
"description": "Custom template configuration - optional"
|
|
247
|
+
},
|
|
248
|
+
"if": {
|
|
249
|
+
"type": "string",
|
|
250
|
+
"description": "Condition to determine if check should run - runs if expression evaluates to true"
|
|
251
|
+
},
|
|
252
|
+
"reuse_ai_session": {
|
|
253
|
+
"type": "boolean",
|
|
254
|
+
"description": "Whether to reuse AI session from dependency checks (only works with depends_on)"
|
|
255
|
+
},
|
|
256
|
+
"fail_if": {
|
|
257
|
+
"type": "string",
|
|
258
|
+
"description": "Simple fail condition - fails check if expression evaluates to true"
|
|
259
|
+
},
|
|
260
|
+
"failure_conditions": {
|
|
261
|
+
"$ref": "#/definitions/FailureConditions",
|
|
262
|
+
"description": "Check-specific failure conditions - optional (deprecated, use fail_if)"
|
|
263
|
+
},
|
|
264
|
+
"tags": {
|
|
265
|
+
"type": "array",
|
|
266
|
+
"items": {
|
|
267
|
+
"type": "string"
|
|
268
|
+
},
|
|
269
|
+
"description": 'Tags for categorizing and filtering checks (e.g., ["local", "fast", "security"])'
|
|
270
|
+
},
|
|
271
|
+
"forEach": {
|
|
272
|
+
"type": "boolean",
|
|
273
|
+
"description": "Process output as array and run dependent checks for each item"
|
|
274
|
+
},
|
|
275
|
+
"on_fail": {
|
|
276
|
+
"$ref": "#/definitions/OnFailConfig",
|
|
277
|
+
"description": "Failure routing configuration for this check (retry/goto/run)"
|
|
278
|
+
},
|
|
279
|
+
"on_success": {
|
|
280
|
+
"$ref": "#/definitions/OnSuccessConfig",
|
|
281
|
+
"description": "Success routing configuration for this check (post-actions and optional goto)"
|
|
282
|
+
}
|
|
283
|
+
},
|
|
284
|
+
"additionalProperties": false,
|
|
285
|
+
"description": "Configuration for a single check",
|
|
286
|
+
"patternProperties": {
|
|
287
|
+
"^x-": {}
|
|
288
|
+
}
|
|
289
|
+
},
|
|
290
|
+
"ConfigCheckType": {
|
|
291
|
+
"type": "string",
|
|
292
|
+
"enum": [
|
|
293
|
+
"ai",
|
|
294
|
+
"command",
|
|
295
|
+
"http",
|
|
296
|
+
"http_input",
|
|
297
|
+
"http_client",
|
|
298
|
+
"noop",
|
|
299
|
+
"log",
|
|
300
|
+
"claude-code"
|
|
301
|
+
],
|
|
302
|
+
"description": "Valid check types in configuration"
|
|
303
|
+
},
|
|
304
|
+
"Record<string,string>": {
|
|
305
|
+
"type": "object",
|
|
306
|
+
"additionalProperties": {
|
|
307
|
+
"type": "string"
|
|
308
|
+
}
|
|
309
|
+
},
|
|
310
|
+
"EventTrigger": {
|
|
311
|
+
"type": "string",
|
|
312
|
+
"enum": [
|
|
313
|
+
"pr_opened",
|
|
314
|
+
"pr_updated",
|
|
315
|
+
"pr_closed",
|
|
316
|
+
"issue_opened",
|
|
317
|
+
"issue_comment",
|
|
318
|
+
"manual",
|
|
319
|
+
"schedule",
|
|
320
|
+
"webhook_received"
|
|
321
|
+
],
|
|
322
|
+
"description": "Valid event triggers for checks"
|
|
323
|
+
},
|
|
324
|
+
"AIProviderConfig": {
|
|
325
|
+
"type": "object",
|
|
326
|
+
"properties": {
|
|
327
|
+
"provider": {
|
|
328
|
+
"type": "string",
|
|
329
|
+
"enum": [
|
|
330
|
+
"google",
|
|
331
|
+
"anthropic",
|
|
332
|
+
"openai",
|
|
333
|
+
"bedrock",
|
|
334
|
+
"mock"
|
|
335
|
+
],
|
|
336
|
+
"description": "AI provider to use"
|
|
337
|
+
},
|
|
338
|
+
"model": {
|
|
339
|
+
"type": "string",
|
|
340
|
+
"description": "Model name to use"
|
|
341
|
+
},
|
|
342
|
+
"apiKey": {
|
|
343
|
+
"type": "string",
|
|
344
|
+
"description": "API key (usually from environment variables)"
|
|
345
|
+
},
|
|
346
|
+
"timeout": {
|
|
347
|
+
"type": "number",
|
|
348
|
+
"description": "Request timeout in milliseconds"
|
|
349
|
+
},
|
|
350
|
+
"debug": {
|
|
351
|
+
"type": "boolean",
|
|
352
|
+
"description": "Enable debug mode"
|
|
353
|
+
},
|
|
354
|
+
"mcpServers": {
|
|
355
|
+
"$ref": "#/definitions/Record%3Cstring%2CMcpServerConfig%3E",
|
|
356
|
+
"description": "MCP servers configuration"
|
|
357
|
+
}
|
|
358
|
+
},
|
|
359
|
+
"additionalProperties": false,
|
|
360
|
+
"description": "AI provider configuration",
|
|
361
|
+
"patternProperties": {
|
|
362
|
+
"^x-": {}
|
|
363
|
+
}
|
|
364
|
+
},
|
|
365
|
+
"Record<string,McpServerConfig>": {
|
|
366
|
+
"type": "object",
|
|
367
|
+
"additionalProperties": {
|
|
368
|
+
"$ref": "#/definitions/McpServerConfig"
|
|
369
|
+
}
|
|
370
|
+
},
|
|
371
|
+
"McpServerConfig": {
|
|
372
|
+
"type": "object",
|
|
373
|
+
"properties": {
|
|
374
|
+
"command": {
|
|
375
|
+
"type": "string",
|
|
376
|
+
"description": "Command to execute for the MCP server"
|
|
377
|
+
},
|
|
378
|
+
"args": {
|
|
379
|
+
"type": "array",
|
|
380
|
+
"items": {
|
|
381
|
+
"type": "string"
|
|
382
|
+
},
|
|
383
|
+
"description": "Arguments to pass to the command"
|
|
384
|
+
},
|
|
385
|
+
"env": {
|
|
386
|
+
"$ref": "#/definitions/Record%3Cstring%2Cstring%3E",
|
|
387
|
+
"description": "Environment variables for the MCP server"
|
|
388
|
+
}
|
|
389
|
+
},
|
|
390
|
+
"required": [
|
|
391
|
+
"command"
|
|
392
|
+
],
|
|
393
|
+
"additionalProperties": false,
|
|
394
|
+
"description": "MCP Server configuration",
|
|
395
|
+
"patternProperties": {
|
|
396
|
+
"^x-": {}
|
|
397
|
+
}
|
|
398
|
+
},
|
|
399
|
+
"ClaudeCodeConfig": {
|
|
400
|
+
"type": "object",
|
|
401
|
+
"properties": {
|
|
402
|
+
"allowedTools": {
|
|
403
|
+
"type": "array",
|
|
404
|
+
"items": {
|
|
405
|
+
"type": "string"
|
|
406
|
+
},
|
|
407
|
+
"description": "List of allowed tools for Claude Code to use"
|
|
408
|
+
},
|
|
409
|
+
"maxTurns": {
|
|
410
|
+
"type": "number",
|
|
411
|
+
"description": "Maximum number of turns in conversation"
|
|
412
|
+
},
|
|
413
|
+
"systemPrompt": {
|
|
414
|
+
"type": "string",
|
|
415
|
+
"description": "System prompt for Claude Code"
|
|
416
|
+
},
|
|
417
|
+
"mcpServers": {
|
|
418
|
+
"$ref": "#/definitions/Record%3Cstring%2CMcpServerConfig%3E",
|
|
419
|
+
"description": "MCP servers configuration"
|
|
420
|
+
},
|
|
421
|
+
"subagent": {
|
|
422
|
+
"type": "string",
|
|
423
|
+
"description": "Path to subagent script"
|
|
424
|
+
},
|
|
425
|
+
"hooks": {
|
|
426
|
+
"type": "object",
|
|
427
|
+
"properties": {
|
|
428
|
+
"onStart": {
|
|
429
|
+
"type": "string",
|
|
430
|
+
"description": "Called when check starts"
|
|
431
|
+
},
|
|
432
|
+
"onEnd": {
|
|
433
|
+
"type": "string",
|
|
434
|
+
"description": "Called when check ends"
|
|
435
|
+
},
|
|
436
|
+
"onError": {
|
|
437
|
+
"type": "string",
|
|
438
|
+
"description": "Called when check encounters an error"
|
|
439
|
+
}
|
|
440
|
+
},
|
|
441
|
+
"additionalProperties": false,
|
|
442
|
+
"description": "Event hooks for lifecycle management",
|
|
443
|
+
"patternProperties": {
|
|
444
|
+
"^x-": {}
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
},
|
|
448
|
+
"additionalProperties": false,
|
|
449
|
+
"description": "Claude Code configuration",
|
|
450
|
+
"patternProperties": {
|
|
451
|
+
"^x-": {}
|
|
452
|
+
}
|
|
453
|
+
},
|
|
454
|
+
"EnvConfig": {
|
|
455
|
+
"type": "object",
|
|
456
|
+
"additionalProperties": {
|
|
457
|
+
"type": [
|
|
458
|
+
"string",
|
|
459
|
+
"number",
|
|
460
|
+
"boolean"
|
|
461
|
+
]
|
|
462
|
+
},
|
|
463
|
+
"description": "Environment variable reference configuration"
|
|
464
|
+
},
|
|
465
|
+
"Record<string,unknown>": {
|
|
466
|
+
"type": "object",
|
|
467
|
+
"additionalProperties": {}
|
|
468
|
+
},
|
|
469
|
+
"CustomTemplateConfig": {
|
|
470
|
+
"type": "object",
|
|
471
|
+
"properties": {
|
|
472
|
+
"file": {
|
|
473
|
+
"type": "string",
|
|
474
|
+
"description": "Path to custom template file (relative to config file or absolute)"
|
|
475
|
+
},
|
|
476
|
+
"content": {
|
|
477
|
+
"type": "string",
|
|
478
|
+
"description": "Raw template content as string"
|
|
479
|
+
}
|
|
480
|
+
},
|
|
481
|
+
"additionalProperties": false,
|
|
482
|
+
"description": "Custom template configuration",
|
|
483
|
+
"patternProperties": {
|
|
484
|
+
"^x-": {}
|
|
485
|
+
}
|
|
486
|
+
},
|
|
487
|
+
"FailureConditions": {
|
|
488
|
+
"type": "object",
|
|
489
|
+
"additionalProperties": {
|
|
490
|
+
"$ref": "#/definitions/FailureCondition"
|
|
491
|
+
},
|
|
492
|
+
"description": "Collection of failure conditions"
|
|
493
|
+
},
|
|
494
|
+
"FailureCondition": {
|
|
495
|
+
"anyOf": [
|
|
496
|
+
{
|
|
497
|
+
"$ref": "#/definitions/SimpleFailureCondition"
|
|
498
|
+
},
|
|
499
|
+
{
|
|
500
|
+
"$ref": "#/definitions/ComplexFailureCondition"
|
|
501
|
+
}
|
|
502
|
+
],
|
|
503
|
+
"description": "Failure condition - can be a simple expression string or complex object"
|
|
504
|
+
},
|
|
505
|
+
"SimpleFailureCondition": {
|
|
506
|
+
"type": "string",
|
|
507
|
+
"description": "Simple failure condition - just an expression string"
|
|
508
|
+
},
|
|
509
|
+
"ComplexFailureCondition": {
|
|
510
|
+
"type": "object",
|
|
511
|
+
"properties": {
|
|
512
|
+
"condition": {
|
|
513
|
+
"type": "string",
|
|
514
|
+
"description": "Expression to evaluate using Function Constructor"
|
|
515
|
+
},
|
|
516
|
+
"message": {
|
|
517
|
+
"type": "string",
|
|
518
|
+
"description": "Human-readable message when condition is met"
|
|
519
|
+
},
|
|
520
|
+
"severity": {
|
|
521
|
+
"$ref": "#/definitions/FailureConditionSeverity",
|
|
522
|
+
"description": "Severity level of the failure"
|
|
523
|
+
},
|
|
524
|
+
"halt_execution": {
|
|
525
|
+
"type": "boolean",
|
|
526
|
+
"description": "Whether this condition should halt execution"
|
|
527
|
+
}
|
|
528
|
+
},
|
|
529
|
+
"required": [
|
|
530
|
+
"condition"
|
|
531
|
+
],
|
|
532
|
+
"additionalProperties": false,
|
|
533
|
+
"description": "Complex failure condition with additional metadata",
|
|
534
|
+
"patternProperties": {
|
|
535
|
+
"^x-": {}
|
|
536
|
+
}
|
|
537
|
+
},
|
|
538
|
+
"FailureConditionSeverity": {
|
|
539
|
+
"type": "string",
|
|
540
|
+
"enum": [
|
|
541
|
+
"error",
|
|
542
|
+
"warning",
|
|
543
|
+
"info"
|
|
544
|
+
],
|
|
545
|
+
"description": "Failure condition severity levels"
|
|
546
|
+
},
|
|
547
|
+
"OnFailConfig": {
|
|
548
|
+
"type": "object",
|
|
549
|
+
"properties": {
|
|
550
|
+
"retry": {
|
|
551
|
+
"$ref": "#/definitions/RetryPolicy",
|
|
552
|
+
"description": "Retry policy"
|
|
553
|
+
},
|
|
554
|
+
"run": {
|
|
555
|
+
"type": "array",
|
|
556
|
+
"items": {
|
|
557
|
+
"type": "string"
|
|
558
|
+
},
|
|
559
|
+
"description": "Remediation steps to run before reattempt"
|
|
560
|
+
},
|
|
561
|
+
"goto": {
|
|
562
|
+
"type": "string",
|
|
563
|
+
"description": "Jump back to an ancestor step (by id)"
|
|
564
|
+
},
|
|
565
|
+
"goto_js": {
|
|
566
|
+
"type": "string",
|
|
567
|
+
"description": "Dynamic goto: JS expression returning step id or null"
|
|
568
|
+
},
|
|
569
|
+
"run_js": {
|
|
570
|
+
"type": "string",
|
|
571
|
+
"description": "Dynamic remediation list: JS expression returning string[]"
|
|
572
|
+
}
|
|
573
|
+
},
|
|
574
|
+
"additionalProperties": false,
|
|
575
|
+
"description": "Failure routing configuration per check",
|
|
576
|
+
"patternProperties": {
|
|
577
|
+
"^x-": {}
|
|
578
|
+
}
|
|
579
|
+
},
|
|
580
|
+
"RetryPolicy": {
|
|
581
|
+
"type": "object",
|
|
582
|
+
"properties": {
|
|
583
|
+
"max": {
|
|
584
|
+
"type": "number",
|
|
585
|
+
"description": "Maximum retry attempts (excluding the first attempt)"
|
|
586
|
+
},
|
|
587
|
+
"backoff": {
|
|
588
|
+
"$ref": "#/definitions/BackoffPolicy",
|
|
589
|
+
"description": "Backoff policy"
|
|
590
|
+
}
|
|
591
|
+
},
|
|
592
|
+
"additionalProperties": false,
|
|
593
|
+
"description": "Retry policy for a step",
|
|
594
|
+
"patternProperties": {
|
|
595
|
+
"^x-": {}
|
|
596
|
+
}
|
|
597
|
+
},
|
|
598
|
+
"BackoffPolicy": {
|
|
599
|
+
"type": "object",
|
|
600
|
+
"properties": {
|
|
601
|
+
"mode": {
|
|
602
|
+
"type": "string",
|
|
603
|
+
"enum": [
|
|
604
|
+
"fixed",
|
|
605
|
+
"exponential"
|
|
606
|
+
],
|
|
607
|
+
"description": "Backoff mode"
|
|
608
|
+
},
|
|
609
|
+
"delay_ms": {
|
|
610
|
+
"type": "number",
|
|
611
|
+
"description": "Initial delay in milliseconds"
|
|
612
|
+
}
|
|
613
|
+
},
|
|
614
|
+
"additionalProperties": false,
|
|
615
|
+
"description": "Backoff policy for retries",
|
|
616
|
+
"patternProperties": {
|
|
617
|
+
"^x-": {}
|
|
618
|
+
}
|
|
619
|
+
},
|
|
620
|
+
"OnSuccessConfig": {
|
|
621
|
+
"type": "object",
|
|
622
|
+
"properties": {
|
|
623
|
+
"run": {
|
|
624
|
+
"type": "array",
|
|
625
|
+
"items": {
|
|
626
|
+
"type": "string"
|
|
627
|
+
},
|
|
628
|
+
"description": "Post-success steps to run"
|
|
629
|
+
},
|
|
630
|
+
"goto": {
|
|
631
|
+
"type": "string",
|
|
632
|
+
"description": "Optional jump back to ancestor step (by id)"
|
|
633
|
+
},
|
|
634
|
+
"goto_js": {
|
|
635
|
+
"type": "string",
|
|
636
|
+
"description": "Dynamic goto: JS expression returning step id or null"
|
|
637
|
+
},
|
|
638
|
+
"run_js": {
|
|
639
|
+
"type": "string",
|
|
640
|
+
"description": "Dynamic post-success steps: JS expression returning string[]"
|
|
641
|
+
}
|
|
642
|
+
},
|
|
643
|
+
"additionalProperties": false,
|
|
644
|
+
"description": "Success routing configuration per check",
|
|
645
|
+
"patternProperties": {
|
|
646
|
+
"^x-": {}
|
|
647
|
+
}
|
|
648
|
+
},
|
|
649
|
+
"OutputConfig": {
|
|
650
|
+
"type": "object",
|
|
651
|
+
"properties": {
|
|
652
|
+
"pr_comment": {
|
|
653
|
+
"$ref": "#/definitions/PrCommentOutput",
|
|
654
|
+
"description": "PR comment configuration"
|
|
655
|
+
},
|
|
656
|
+
"file_comment": {
|
|
657
|
+
"$ref": "#/definitions/FileCommentOutput",
|
|
658
|
+
"description": "File comment configuration (optional)"
|
|
659
|
+
},
|
|
660
|
+
"github_checks": {
|
|
661
|
+
"$ref": "#/definitions/GitHubCheckOutput",
|
|
662
|
+
"description": "GitHub check runs configuration (optional)"
|
|
663
|
+
},
|
|
664
|
+
"suppressionEnabled": {
|
|
665
|
+
"type": "boolean",
|
|
666
|
+
"description": "Whether to enable issue suppression via visor-disable comments (default: true)"
|
|
667
|
+
}
|
|
668
|
+
},
|
|
669
|
+
"required": [
|
|
670
|
+
"pr_comment"
|
|
671
|
+
],
|
|
672
|
+
"additionalProperties": false,
|
|
673
|
+
"description": "Output configuration",
|
|
674
|
+
"patternProperties": {
|
|
675
|
+
"^x-": {}
|
|
676
|
+
}
|
|
677
|
+
},
|
|
678
|
+
"PrCommentOutput": {
|
|
679
|
+
"type": "object",
|
|
680
|
+
"properties": {
|
|
681
|
+
"format": {
|
|
682
|
+
"$ref": "#/definitions/ConfigOutputFormat",
|
|
683
|
+
"description": "Format of the output"
|
|
684
|
+
},
|
|
685
|
+
"group_by": {
|
|
686
|
+
"$ref": "#/definitions/GroupByOption",
|
|
687
|
+
"description": "How to group the results"
|
|
688
|
+
},
|
|
689
|
+
"collapse": {
|
|
690
|
+
"type": "boolean",
|
|
691
|
+
"description": "Whether to collapse sections by default"
|
|
692
|
+
},
|
|
693
|
+
"debug": {
|
|
694
|
+
"$ref": "#/definitions/DebugConfig",
|
|
695
|
+
"description": "Debug mode configuration (optional)"
|
|
696
|
+
}
|
|
697
|
+
},
|
|
698
|
+
"required": [
|
|
699
|
+
"format",
|
|
700
|
+
"group_by",
|
|
701
|
+
"collapse"
|
|
702
|
+
],
|
|
703
|
+
"additionalProperties": false,
|
|
704
|
+
"description": "PR comment output configuration",
|
|
705
|
+
"patternProperties": {
|
|
706
|
+
"^x-": {}
|
|
707
|
+
}
|
|
708
|
+
},
|
|
709
|
+
"ConfigOutputFormat": {
|
|
710
|
+
"type": "string",
|
|
711
|
+
"enum": [
|
|
712
|
+
"table",
|
|
713
|
+
"json",
|
|
714
|
+
"markdown",
|
|
715
|
+
"sarif"
|
|
716
|
+
],
|
|
717
|
+
"description": "Valid output formats"
|
|
718
|
+
},
|
|
719
|
+
"GroupByOption": {
|
|
720
|
+
"type": "string",
|
|
721
|
+
"enum": [
|
|
722
|
+
"check",
|
|
723
|
+
"file",
|
|
724
|
+
"severity"
|
|
725
|
+
],
|
|
726
|
+
"description": "Valid grouping options"
|
|
727
|
+
},
|
|
728
|
+
"DebugConfig": {
|
|
729
|
+
"type": "object",
|
|
730
|
+
"properties": {
|
|
731
|
+
"enabled": {
|
|
732
|
+
"type": "boolean",
|
|
733
|
+
"description": "Enable debug mode"
|
|
734
|
+
},
|
|
735
|
+
"includePrompts": {
|
|
736
|
+
"type": "boolean",
|
|
737
|
+
"description": "Include AI prompts in debug output"
|
|
738
|
+
},
|
|
739
|
+
"includeRawResponses": {
|
|
740
|
+
"type": "boolean",
|
|
741
|
+
"description": "Include raw AI responses in debug output"
|
|
742
|
+
},
|
|
743
|
+
"includeTiming": {
|
|
744
|
+
"type": "boolean",
|
|
745
|
+
"description": "Include timing information"
|
|
746
|
+
},
|
|
747
|
+
"includeProviderInfo": {
|
|
748
|
+
"type": "boolean",
|
|
749
|
+
"description": "Include provider information"
|
|
750
|
+
}
|
|
751
|
+
},
|
|
752
|
+
"required": [
|
|
753
|
+
"enabled",
|
|
754
|
+
"includePrompts",
|
|
755
|
+
"includeRawResponses",
|
|
756
|
+
"includeTiming",
|
|
757
|
+
"includeProviderInfo"
|
|
758
|
+
],
|
|
759
|
+
"additionalProperties": false,
|
|
760
|
+
"description": "Debug mode configuration",
|
|
761
|
+
"patternProperties": {
|
|
762
|
+
"^x-": {}
|
|
763
|
+
}
|
|
764
|
+
},
|
|
765
|
+
"FileCommentOutput": {
|
|
766
|
+
"type": "object",
|
|
767
|
+
"properties": {
|
|
768
|
+
"enabled": {
|
|
769
|
+
"type": "boolean",
|
|
770
|
+
"description": "Whether file comments are enabled"
|
|
771
|
+
},
|
|
772
|
+
"inline": {
|
|
773
|
+
"type": "boolean",
|
|
774
|
+
"description": "Whether to show inline comments"
|
|
775
|
+
}
|
|
776
|
+
},
|
|
777
|
+
"required": [
|
|
778
|
+
"enabled",
|
|
779
|
+
"inline"
|
|
780
|
+
],
|
|
781
|
+
"additionalProperties": false,
|
|
782
|
+
"description": "File comment output configuration",
|
|
783
|
+
"patternProperties": {
|
|
784
|
+
"^x-": {}
|
|
785
|
+
}
|
|
786
|
+
},
|
|
787
|
+
"GitHubCheckOutput": {
|
|
788
|
+
"type": "object",
|
|
789
|
+
"properties": {
|
|
790
|
+
"enabled": {
|
|
791
|
+
"type": "boolean",
|
|
792
|
+
"description": "Whether GitHub check runs are enabled"
|
|
793
|
+
},
|
|
794
|
+
"per_check": {
|
|
795
|
+
"type": "boolean",
|
|
796
|
+
"description": "Whether to create individual check runs per configured check"
|
|
797
|
+
},
|
|
798
|
+
"name_prefix": {
|
|
799
|
+
"type": "string",
|
|
800
|
+
"description": "Custom name prefix for check runs"
|
|
801
|
+
}
|
|
802
|
+
},
|
|
803
|
+
"required": [
|
|
804
|
+
"enabled",
|
|
805
|
+
"per_check"
|
|
806
|
+
],
|
|
807
|
+
"additionalProperties": false,
|
|
808
|
+
"description": "GitHub Check Runs output configuration",
|
|
809
|
+
"patternProperties": {
|
|
810
|
+
"^x-": {}
|
|
811
|
+
}
|
|
812
|
+
},
|
|
813
|
+
"HttpServerConfig": {
|
|
814
|
+
"type": "object",
|
|
815
|
+
"properties": {
|
|
816
|
+
"enabled": {
|
|
817
|
+
"type": "boolean",
|
|
818
|
+
"description": "Whether HTTP server is enabled"
|
|
819
|
+
},
|
|
820
|
+
"port": {
|
|
821
|
+
"type": "number",
|
|
822
|
+
"description": "Port to listen on"
|
|
823
|
+
},
|
|
824
|
+
"host": {
|
|
825
|
+
"type": "string",
|
|
826
|
+
"description": "Host/IP to bind to (defaults to 0.0.0.0)"
|
|
827
|
+
},
|
|
828
|
+
"tls": {
|
|
829
|
+
"$ref": "#/definitions/TlsConfig",
|
|
830
|
+
"description": "TLS/SSL configuration for HTTPS"
|
|
831
|
+
},
|
|
832
|
+
"auth": {
|
|
833
|
+
"$ref": "#/definitions/HttpAuthConfig",
|
|
834
|
+
"description": "Authentication configuration"
|
|
835
|
+
},
|
|
836
|
+
"endpoints": {
|
|
837
|
+
"type": "array",
|
|
838
|
+
"items": {
|
|
839
|
+
"$ref": "#/definitions/HttpEndpointConfig"
|
|
840
|
+
},
|
|
841
|
+
"description": "HTTP endpoints configuration"
|
|
842
|
+
}
|
|
843
|
+
},
|
|
844
|
+
"required": [
|
|
845
|
+
"enabled",
|
|
846
|
+
"port"
|
|
847
|
+
],
|
|
848
|
+
"additionalProperties": false,
|
|
849
|
+
"description": "HTTP server configuration for receiving webhooks",
|
|
850
|
+
"patternProperties": {
|
|
851
|
+
"^x-": {}
|
|
852
|
+
}
|
|
853
|
+
},
|
|
854
|
+
"TlsConfig": {
|
|
855
|
+
"type": "object",
|
|
856
|
+
"properties": {
|
|
857
|
+
"enabled": {
|
|
858
|
+
"type": "boolean",
|
|
859
|
+
"description": "Enable TLS/HTTPS"
|
|
860
|
+
},
|
|
861
|
+
"cert": {
|
|
862
|
+
"type": "string",
|
|
863
|
+
"description": "Path to TLS certificate file or certificate content"
|
|
864
|
+
},
|
|
865
|
+
"key": {
|
|
866
|
+
"type": "string",
|
|
867
|
+
"description": "Path to TLS key file or key content"
|
|
868
|
+
},
|
|
869
|
+
"ca": {
|
|
870
|
+
"type": "string",
|
|
871
|
+
"description": "Path to CA certificate file or CA content (optional)"
|
|
872
|
+
},
|
|
873
|
+
"rejectUnauthorized": {
|
|
874
|
+
"type": "boolean",
|
|
875
|
+
"description": "Reject unauthorized connections (default: true)"
|
|
876
|
+
}
|
|
877
|
+
},
|
|
878
|
+
"required": [
|
|
879
|
+
"enabled"
|
|
880
|
+
],
|
|
881
|
+
"additionalProperties": false,
|
|
882
|
+
"description": "TLS/SSL configuration for HTTPS server",
|
|
883
|
+
"patternProperties": {
|
|
884
|
+
"^x-": {}
|
|
885
|
+
}
|
|
886
|
+
},
|
|
887
|
+
"HttpAuthConfig": {
|
|
888
|
+
"type": "object",
|
|
889
|
+
"properties": {
|
|
890
|
+
"type": {
|
|
891
|
+
"type": "string",
|
|
892
|
+
"enum": [
|
|
893
|
+
"bearer_token",
|
|
894
|
+
"hmac",
|
|
895
|
+
"basic",
|
|
896
|
+
"none"
|
|
897
|
+
],
|
|
898
|
+
"description": "Authentication type"
|
|
899
|
+
},
|
|
900
|
+
"secret": {
|
|
901
|
+
"type": "string",
|
|
902
|
+
"description": "Secret or token for authentication"
|
|
903
|
+
},
|
|
904
|
+
"username": {
|
|
905
|
+
"type": "string",
|
|
906
|
+
"description": "Username for basic auth"
|
|
907
|
+
},
|
|
908
|
+
"password": {
|
|
909
|
+
"type": "string",
|
|
910
|
+
"description": "Password for basic auth"
|
|
911
|
+
}
|
|
912
|
+
},
|
|
913
|
+
"required": [
|
|
914
|
+
"type"
|
|
915
|
+
],
|
|
916
|
+
"additionalProperties": false,
|
|
917
|
+
"description": "HTTP server authentication configuration",
|
|
918
|
+
"patternProperties": {
|
|
919
|
+
"^x-": {}
|
|
920
|
+
}
|
|
921
|
+
},
|
|
922
|
+
"HttpEndpointConfig": {
|
|
923
|
+
"type": "object",
|
|
924
|
+
"properties": {
|
|
925
|
+
"path": {
|
|
926
|
+
"type": "string",
|
|
927
|
+
"description": "Path for the webhook endpoint"
|
|
928
|
+
},
|
|
929
|
+
"transform": {
|
|
930
|
+
"type": "string",
|
|
931
|
+
"description": "Optional transform template (Liquid) for the received data"
|
|
932
|
+
},
|
|
933
|
+
"name": {
|
|
934
|
+
"type": "string",
|
|
935
|
+
"description": "Optional name/ID for this endpoint"
|
|
936
|
+
}
|
|
937
|
+
},
|
|
938
|
+
"required": [
|
|
939
|
+
"path"
|
|
940
|
+
],
|
|
941
|
+
"additionalProperties": false,
|
|
942
|
+
"description": "HTTP server endpoint configuration",
|
|
943
|
+
"patternProperties": {
|
|
944
|
+
"^x-": {}
|
|
945
|
+
}
|
|
946
|
+
},
|
|
947
|
+
"TagFilter": {
|
|
948
|
+
"type": "object",
|
|
949
|
+
"properties": {
|
|
950
|
+
"include": {
|
|
951
|
+
"type": "array",
|
|
952
|
+
"items": {
|
|
953
|
+
"type": "string"
|
|
954
|
+
},
|
|
955
|
+
"description": "Tags that checks must have to be included (ANY match)"
|
|
956
|
+
},
|
|
957
|
+
"exclude": {
|
|
958
|
+
"type": "array",
|
|
959
|
+
"items": {
|
|
960
|
+
"type": "string"
|
|
961
|
+
},
|
|
962
|
+
"description": "Tags that will exclude checks if present (ANY match)"
|
|
963
|
+
}
|
|
964
|
+
},
|
|
965
|
+
"additionalProperties": false,
|
|
966
|
+
"description": "Tag filter configuration for selective check execution",
|
|
967
|
+
"patternProperties": {
|
|
968
|
+
"^x-": {}
|
|
969
|
+
}
|
|
970
|
+
},
|
|
971
|
+
"RoutingDefaults": {
|
|
972
|
+
"type": "object",
|
|
973
|
+
"properties": {
|
|
974
|
+
"max_loops": {
|
|
975
|
+
"type": "number",
|
|
976
|
+
"description": "Per-scope cap on routing transitions (success + failure)"
|
|
977
|
+
},
|
|
978
|
+
"defaults": {
|
|
979
|
+
"type": "object",
|
|
980
|
+
"properties": {
|
|
981
|
+
"on_fail": {
|
|
982
|
+
"$ref": "#/definitions/OnFailConfig"
|
|
983
|
+
}
|
|
984
|
+
},
|
|
985
|
+
"additionalProperties": false,
|
|
986
|
+
"description": "Default policies applied to checks (step-level overrides take precedence)",
|
|
987
|
+
"patternProperties": {
|
|
988
|
+
"^x-": {}
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
},
|
|
992
|
+
"additionalProperties": false,
|
|
993
|
+
"description": "Global routing defaults",
|
|
994
|
+
"patternProperties": {
|
|
995
|
+
"^x-": {}
|
|
996
|
+
}
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
};
|
|
1000
|
+
config_schema_default = configSchema;
|
|
1001
|
+
}
|
|
1002
|
+
});
|
|
1003
|
+
|
|
12
1004
|
// src/config.ts
|
|
13
1005
|
import * as yaml2 from "js-yaml";
|
|
14
1006
|
import * as fs2 from "fs";
|
|
@@ -356,6 +1348,8 @@ var ConfigLoader = class {
|
|
|
356
1348
|
};
|
|
357
1349
|
|
|
358
1350
|
// src/config.ts
|
|
1351
|
+
import Ajv from "ajv";
|
|
1352
|
+
import addFormats from "ajv-formats";
|
|
359
1353
|
var ConfigManager = class {
|
|
360
1354
|
validCheckTypes = [
|
|
361
1355
|
"ai",
|
|
@@ -608,6 +1602,8 @@ var ConfigManager = class {
|
|
|
608
1602
|
*/
|
|
609
1603
|
validateConfig(config) {
|
|
610
1604
|
const errors = [];
|
|
1605
|
+
const warnings = [];
|
|
1606
|
+
this.validateWithAjvSchema(config, errors, warnings);
|
|
611
1607
|
if (!config.version) {
|
|
612
1608
|
errors.push({
|
|
613
1609
|
field: "version",
|
|
@@ -625,8 +1621,38 @@ var ConfigManager = class {
|
|
|
625
1621
|
checkConfig.type = "ai";
|
|
626
1622
|
}
|
|
627
1623
|
this.validateCheckConfig(checkName, checkConfig, errors);
|
|
1624
|
+
if (checkConfig.ai_mcp_servers) {
|
|
1625
|
+
this.validateMcpServersObject(
|
|
1626
|
+
checkConfig.ai_mcp_servers,
|
|
1627
|
+
`checks.${checkName}.ai_mcp_servers`,
|
|
1628
|
+
errors,
|
|
1629
|
+
warnings
|
|
1630
|
+
);
|
|
1631
|
+
}
|
|
1632
|
+
if (checkConfig.ai?.mcpServers) {
|
|
1633
|
+
this.validateMcpServersObject(
|
|
1634
|
+
checkConfig.ai.mcpServers,
|
|
1635
|
+
`checks.${checkName}.ai.mcpServers`,
|
|
1636
|
+
errors,
|
|
1637
|
+
warnings
|
|
1638
|
+
);
|
|
1639
|
+
}
|
|
1640
|
+
if (checkConfig.ai_mcp_servers && checkConfig.ai?.mcpServers) {
|
|
1641
|
+
const lower = Object.keys(checkConfig.ai_mcp_servers);
|
|
1642
|
+
const higher = Object.keys(checkConfig.ai.mcpServers);
|
|
1643
|
+
const overridden = lower.filter((k) => higher.includes(k));
|
|
1644
|
+
warnings.push({
|
|
1645
|
+
field: `checks.${checkName}.ai.mcpServers`,
|
|
1646
|
+
message: overridden.length > 0 ? `Both ai_mcp_servers and ai.mcpServers are set; ai.mcpServers overrides these servers: ${overridden.join(
|
|
1647
|
+
", "
|
|
1648
|
+
)}` : "Both ai_mcp_servers and ai.mcpServers are set; ai.mcpServers takes precedence for this check."
|
|
1649
|
+
});
|
|
1650
|
+
}
|
|
628
1651
|
}
|
|
629
1652
|
}
|
|
1653
|
+
if (config.ai_mcp_servers) {
|
|
1654
|
+
this.validateMcpServersObject(config.ai_mcp_servers, "ai_mcp_servers", errors, warnings);
|
|
1655
|
+
}
|
|
630
1656
|
if (config.output) {
|
|
631
1657
|
this.validateOutputConfig(config.output, errors);
|
|
632
1658
|
}
|
|
@@ -651,6 +1677,11 @@ var ConfigManager = class {
|
|
|
651
1677
|
if (errors.length > 0) {
|
|
652
1678
|
throw new Error(errors[0].message);
|
|
653
1679
|
}
|
|
1680
|
+
if (warnings.length > 0) {
|
|
1681
|
+
for (const w of warnings) {
|
|
1682
|
+
logger.warn(`\u26A0\uFE0F Config warning [${w.field}]: ${w.message}`);
|
|
1683
|
+
}
|
|
1684
|
+
}
|
|
654
1685
|
}
|
|
655
1686
|
/**
|
|
656
1687
|
* Validate individual check configuration
|
|
@@ -776,6 +1807,122 @@ var ConfigManager = class {
|
|
|
776
1807
|
}
|
|
777
1808
|
}
|
|
778
1809
|
}
|
|
1810
|
+
/**
|
|
1811
|
+
* Validate MCP servers object shape and values (basic shape only)
|
|
1812
|
+
*/
|
|
1813
|
+
validateMcpServersObject(mcpServers, fieldPrefix, errors, _warnings) {
|
|
1814
|
+
if (typeof mcpServers !== "object" || mcpServers === null) {
|
|
1815
|
+
errors.push({
|
|
1816
|
+
field: fieldPrefix,
|
|
1817
|
+
message: `${fieldPrefix} must be an object mapping server names to { command, args?, env? }`,
|
|
1818
|
+
value: mcpServers
|
|
1819
|
+
});
|
|
1820
|
+
return;
|
|
1821
|
+
}
|
|
1822
|
+
for (const [serverName, cfg] of Object.entries(mcpServers)) {
|
|
1823
|
+
const pathStr = `${fieldPrefix}.${serverName}`;
|
|
1824
|
+
if (!cfg || typeof cfg !== "object") {
|
|
1825
|
+
errors.push({ field: pathStr, message: `${pathStr} must be an object`, value: cfg });
|
|
1826
|
+
continue;
|
|
1827
|
+
}
|
|
1828
|
+
const { command, args, env } = cfg;
|
|
1829
|
+
if (typeof command !== "string" || command.trim() === "") {
|
|
1830
|
+
errors.push({
|
|
1831
|
+
field: `${pathStr}.command`,
|
|
1832
|
+
message: `${pathStr}.command must be a non-empty string`,
|
|
1833
|
+
value: command
|
|
1834
|
+
});
|
|
1835
|
+
}
|
|
1836
|
+
if (args !== void 0 && !Array.isArray(args)) {
|
|
1837
|
+
errors.push({
|
|
1838
|
+
field: `${pathStr}.args`,
|
|
1839
|
+
message: `${pathStr}.args must be an array of strings`,
|
|
1840
|
+
value: args
|
|
1841
|
+
});
|
|
1842
|
+
}
|
|
1843
|
+
if (env !== void 0) {
|
|
1844
|
+
if (typeof env !== "object" || env === null) {
|
|
1845
|
+
errors.push({
|
|
1846
|
+
field: `${pathStr}.env`,
|
|
1847
|
+
message: `${pathStr}.env must be an object of string values`,
|
|
1848
|
+
value: env
|
|
1849
|
+
});
|
|
1850
|
+
} else {
|
|
1851
|
+
for (const [k, v] of Object.entries(env)) {
|
|
1852
|
+
if (typeof v !== "string") {
|
|
1853
|
+
errors.push({
|
|
1854
|
+
field: `${pathStr}.env.${k}`,
|
|
1855
|
+
message: `${pathStr}.env.${k} must be a string`,
|
|
1856
|
+
value: v
|
|
1857
|
+
});
|
|
1858
|
+
}
|
|
1859
|
+
}
|
|
1860
|
+
}
|
|
1861
|
+
}
|
|
1862
|
+
}
|
|
1863
|
+
}
|
|
1864
|
+
/**
|
|
1865
|
+
* Validate configuration using generated JSON Schema via Ajv, if available.
|
|
1866
|
+
* Adds to errors/warnings but does not throw directly.
|
|
1867
|
+
*/
|
|
1868
|
+
validateWithAjvSchema(config, errors, warnings) {
|
|
1869
|
+
try {
|
|
1870
|
+
if (!__ajvValidate) {
|
|
1871
|
+
try {
|
|
1872
|
+
const jsonPath = path2.resolve(__dirname, "generated", "config-schema.json");
|
|
1873
|
+
const jsonSchema = __require(jsonPath);
|
|
1874
|
+
if (jsonSchema) {
|
|
1875
|
+
const ajv = new Ajv({ allErrors: true, allowUnionTypes: true, strict: false });
|
|
1876
|
+
addFormats(ajv);
|
|
1877
|
+
const validate = ajv.compile(jsonSchema);
|
|
1878
|
+
__ajvValidate = (data) => validate(data);
|
|
1879
|
+
__ajvErrors = () => validate.errors;
|
|
1880
|
+
}
|
|
1881
|
+
} catch {
|
|
1882
|
+
}
|
|
1883
|
+
if (!__ajvValidate) {
|
|
1884
|
+
try {
|
|
1885
|
+
const mod = (init_config_schema(), __toCommonJS(config_schema_exports));
|
|
1886
|
+
const schema = mod?.configSchema || mod?.default || mod;
|
|
1887
|
+
if (schema) {
|
|
1888
|
+
const ajv = new Ajv({ allErrors: true, allowUnionTypes: true, strict: false });
|
|
1889
|
+
addFormats(ajv);
|
|
1890
|
+
const validate = ajv.compile(schema);
|
|
1891
|
+
__ajvValidate = (data) => validate(data);
|
|
1892
|
+
__ajvErrors = () => validate.errors;
|
|
1893
|
+
} else {
|
|
1894
|
+
return;
|
|
1895
|
+
}
|
|
1896
|
+
} catch {
|
|
1897
|
+
return;
|
|
1898
|
+
}
|
|
1899
|
+
}
|
|
1900
|
+
}
|
|
1901
|
+
const ok = __ajvValidate(config);
|
|
1902
|
+
const errs = __ajvErrors ? __ajvErrors() : null;
|
|
1903
|
+
if (!ok && Array.isArray(errs)) {
|
|
1904
|
+
for (const e of errs) {
|
|
1905
|
+
const pathStr = e.instancePath ? e.instancePath.replace(/^\//, "").replace(/\//g, ".") : "";
|
|
1906
|
+
const msg = e.message || "Invalid configuration";
|
|
1907
|
+
if (e.keyword === "additionalProperties") {
|
|
1908
|
+
const addl = e.params && e.params.additionalProperty || "unknown";
|
|
1909
|
+
const fullField = pathStr ? `${pathStr}.${addl}` : addl;
|
|
1910
|
+
const topLevel = !pathStr;
|
|
1911
|
+
warnings.push({
|
|
1912
|
+
field: fullField || "config",
|
|
1913
|
+
message: topLevel ? `Unknown top-level key '${addl}' will be ignored.` : `Unknown key '${addl}' will be ignored`
|
|
1914
|
+
});
|
|
1915
|
+
} else {
|
|
1916
|
+
logger.debug(`Ajv note [${pathStr || "config"}]: ${msg}`);
|
|
1917
|
+
}
|
|
1918
|
+
}
|
|
1919
|
+
}
|
|
1920
|
+
} catch (err) {
|
|
1921
|
+
logger.debug(`Ajv validation skipped: ${err instanceof Error ? err.message : String(err)}`);
|
|
1922
|
+
}
|
|
1923
|
+
}
|
|
1924
|
+
// Unknown-key warnings are fully handled by Ajv using the generated schema
|
|
1925
|
+
// Unknown-key hints are produced by Ajv (additionalProperties=false)
|
|
779
1926
|
/**
|
|
780
1927
|
* Validate tag filter configuration
|
|
781
1928
|
*/
|
|
@@ -952,6 +2099,8 @@ var ConfigManager = class {
|
|
|
952
2099
|
return merged;
|
|
953
2100
|
}
|
|
954
2101
|
};
|
|
2102
|
+
var __ajvValidate = null;
|
|
2103
|
+
var __ajvErrors = null;
|
|
955
2104
|
|
|
956
2105
|
// src/sdk.ts
|
|
957
2106
|
async function loadConfig(configPath) {
|