@provartesting/provardx-cli 1.5.0-dev.2 → 1.5.1
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 +163 -12
- package/bin/mcp-start.js +74 -0
- package/lib/commands/provar/auth/clear.d.ts +7 -0
- package/lib/commands/provar/auth/clear.js +36 -0
- package/lib/commands/provar/auth/clear.js.map +1 -0
- package/lib/commands/provar/auth/login.d.ts +10 -0
- package/lib/commands/provar/auth/login.js +90 -0
- package/lib/commands/provar/auth/login.js.map +1 -0
- package/lib/commands/provar/auth/rotate.d.ts +7 -0
- package/lib/commands/provar/auth/rotate.js +42 -0
- package/lib/commands/provar/auth/rotate.js.map +1 -0
- package/lib/commands/provar/auth/status.d.ts +7 -0
- package/lib/commands/provar/auth/status.js +107 -0
- package/lib/commands/provar/auth/status.js.map +1 -0
- package/lib/commands/provar/mcp/start.d.ts +2 -0
- package/lib/commands/provar/mcp/start.js +14 -1
- package/lib/commands/provar/mcp/start.js.map +1 -1
- package/lib/mcp/docs/NITROX_CATALOG_SOURCE.json +6 -0
- package/lib/mcp/docs/NITROX_COMPONENT_CATALOG.md +2001 -0
- package/lib/mcp/docs/PROVAR_TEST_STEP_REFERENCE.md +1430 -0
- package/lib/mcp/docs/PROVAR_TOOL_GUIDE.md +187 -0
- package/lib/mcp/licensing/algasClient.js +14 -5
- package/lib/mcp/licensing/algasClient.js.map +1 -1
- package/lib/mcp/licensing/ideDetection.d.ts +0 -12
- package/lib/mcp/licensing/ideDetection.js +1 -73
- package/lib/mcp/licensing/ideDetection.js.map +1 -1
- package/lib/mcp/licensing/licenseCache.js +7 -1
- package/lib/mcp/licensing/licenseCache.js.map +1 -1
- package/lib/mcp/licensing/licenseValidator.d.ts +3 -3
- package/lib/mcp/licensing/licenseValidator.js +11 -4
- package/lib/mcp/licensing/licenseValidator.js.map +1 -1
- package/lib/mcp/prompts/guidePrompts.d.ts +4 -0
- package/lib/mcp/prompts/guidePrompts.js +334 -0
- package/lib/mcp/prompts/guidePrompts.js.map +1 -0
- package/lib/mcp/prompts/index.d.ts +2 -0
- package/lib/mcp/prompts/index.js +23 -0
- package/lib/mcp/prompts/index.js.map +1 -0
- package/lib/mcp/prompts/loopPrompts.d.ts +6 -0
- package/lib/mcp/prompts/loopPrompts.js +435 -0
- package/lib/mcp/prompts/loopPrompts.js.map +1 -0
- package/lib/mcp/prompts/migrationPrompts.d.ts +4 -0
- package/lib/mcp/prompts/migrationPrompts.js +207 -0
- package/lib/mcp/prompts/migrationPrompts.js.map +1 -0
- package/lib/mcp/rules/provar_best_practices_rules.json +256 -544
- package/lib/mcp/security/pathPolicy.d.ts +5 -0
- package/lib/mcp/security/pathPolicy.js +58 -3
- package/lib/mcp/security/pathPolicy.js.map +1 -1
- package/lib/mcp/server.d.ts +18 -0
- package/lib/mcp/server.js +232 -19
- package/lib/mcp/server.js.map +1 -1
- package/lib/mcp/tools/antTools.d.ts +15 -0
- package/lib/mcp/tools/antTools.js +369 -170
- package/lib/mcp/tools/antTools.js.map +1 -1
- package/lib/mcp/tools/automationTools.d.ts +18 -8
- package/lib/mcp/tools/automationTools.js +333 -176
- package/lib/mcp/tools/automationTools.js.map +1 -1
- package/lib/mcp/tools/bestPracticesEngine.js +161 -23
- package/lib/mcp/tools/bestPracticesEngine.js.map +1 -1
- package/lib/mcp/tools/connectionTools.d.ts +4 -0
- package/lib/mcp/tools/connectionTools.js +242 -0
- package/lib/mcp/tools/connectionTools.js.map +1 -0
- package/lib/mcp/tools/defectTools.d.ts +1 -1
- package/lib/mcp/tools/defectTools.js +61 -50
- package/lib/mcp/tools/defectTools.js.map +1 -1
- package/lib/mcp/tools/descHelper.d.ts +5 -0
- package/lib/mcp/tools/descHelper.js +14 -0
- package/lib/mcp/tools/descHelper.js.map +1 -0
- package/lib/mcp/tools/hierarchyValidate.d.ts +1 -1
- package/lib/mcp/tools/hierarchyValidate.js +127 -42
- package/lib/mcp/tools/hierarchyValidate.js.map +1 -1
- package/lib/mcp/tools/nitroXTools.d.ts +23 -0
- package/lib/mcp/tools/nitroXTools.js +863 -0
- package/lib/mcp/tools/nitroXTools.js.map +1 -0
- package/lib/mcp/tools/pageObjectGenerate.js +150 -57
- package/lib/mcp/tools/pageObjectGenerate.js.map +1 -1
- package/lib/mcp/tools/pageObjectValidate.js +143 -46
- package/lib/mcp/tools/pageObjectValidate.js.map +1 -1
- package/lib/mcp/tools/projectInspect.js +79 -32
- package/lib/mcp/tools/projectInspect.js.map +1 -1
- package/lib/mcp/tools/projectValidateFromPath.js +185 -58
- package/lib/mcp/tools/projectValidateFromPath.js.map +1 -1
- package/lib/mcp/tools/propertiesTools.d.ts +2 -0
- package/lib/mcp/tools/propertiesTools.js +358 -78
- package/lib/mcp/tools/propertiesTools.js.map +1 -1
- package/lib/mcp/tools/qualityHubApiTools.d.ts +3 -0
- package/lib/mcp/tools/qualityHubApiTools.js +139 -0
- package/lib/mcp/tools/qualityHubApiTools.js.map +1 -0
- package/lib/mcp/tools/qualityHubTools.js +292 -72
- package/lib/mcp/tools/qualityHubTools.js.map +1 -1
- package/lib/mcp/tools/rcaTools.d.ts +3 -2
- package/lib/mcp/tools/rcaTools.js +194 -56
- package/lib/mcp/tools/rcaTools.js.map +1 -1
- package/lib/mcp/tools/sfSpawn.d.ts +25 -3
- package/lib/mcp/tools/sfSpawn.js +154 -6
- package/lib/mcp/tools/sfSpawn.js.map +1 -1
- package/lib/mcp/tools/testCaseGenerate.js +285 -78
- package/lib/mcp/tools/testCaseGenerate.js.map +1 -1
- package/lib/mcp/tools/testCaseStepTools.d.ts +4 -0
- package/lib/mcp/tools/testCaseStepTools.js +244 -0
- package/lib/mcp/tools/testCaseStepTools.js.map +1 -0
- package/lib/mcp/tools/testCaseValidate.d.ts +11 -0
- package/lib/mcp/tools/testCaseValidate.js +381 -46
- package/lib/mcp/tools/testCaseValidate.js.map +1 -1
- package/lib/mcp/tools/testPlanTools.d.ts +1 -0
- package/lib/mcp/tools/testPlanTools.js +316 -59
- package/lib/mcp/tools/testPlanTools.js.map +1 -1
- package/lib/mcp/tools/testPlanValidate.js +114 -23
- package/lib/mcp/tools/testPlanValidate.js.map +1 -1
- package/lib/mcp/tools/testSuiteValidate.js +130 -15
- package/lib/mcp/tools/testSuiteValidate.js.map +1 -1
- package/lib/mcp/update/updateChecker.d.ts +14 -0
- package/lib/mcp/update/updateChecker.js +228 -0
- package/lib/mcp/update/updateChecker.js.map +1 -0
- package/lib/mcp/utils/detailLevel.d.ts +9 -0
- package/lib/mcp/utils/detailLevel.js +20 -0
- package/lib/mcp/utils/detailLevel.js.map +1 -0
- package/lib/mcp/utils/fieldMask.d.ts +17 -0
- package/lib/mcp/utils/fieldMask.js +75 -0
- package/lib/mcp/utils/fieldMask.js.map +1 -0
- package/lib/mcp/utils/tokenMeta.d.ts +40 -0
- package/lib/mcp/utils/tokenMeta.js +90 -0
- package/lib/mcp/utils/tokenMeta.js.map +1 -0
- package/lib/mcp/utils/validationDiff.d.ts +57 -0
- package/lib/mcp/utils/validationDiff.js +191 -0
- package/lib/mcp/utils/validationDiff.js.map +1 -0
- package/lib/mcp/utils/validationScore.d.ts +15 -0
- package/lib/mcp/utils/validationScore.js +31 -0
- package/lib/mcp/utils/validationScore.js.map +1 -0
- package/lib/services/auth/credentials.d.ts +21 -0
- package/lib/services/auth/credentials.js +75 -0
- package/lib/services/auth/credentials.js.map +1 -0
- package/lib/services/auth/loginFlow.d.ts +68 -0
- package/lib/services/auth/loginFlow.js +216 -0
- package/lib/services/auth/loginFlow.js.map +1 -0
- package/lib/services/projectValidation.d.ts +5 -2
- package/lib/services/projectValidation.js +83 -31
- package/lib/services/projectValidation.js.map +1 -1
- package/lib/services/qualityHub/client.d.ts +161 -0
- package/lib/services/qualityHub/client.js +226 -0
- package/lib/services/qualityHub/client.js.map +1 -0
- package/messages/sf.provar.auth.clear.md +16 -0
- package/messages/sf.provar.auth.login.md +31 -0
- package/messages/sf.provar.auth.rotate.md +23 -0
- package/messages/sf.provar.auth.status.md +16 -0
- package/messages/sf.provar.mcp.start.md +83 -48
- package/oclif.manifest.json +325 -28
- package/package.json +35 -12
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2024 Provar Limited.
|
|
3
|
+
* All rights reserved.
|
|
4
|
+
* Licensed under the BSD 3-Clause license.
|
|
5
|
+
* For full license text, see LICENSE.md file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
|
6
|
+
*/
|
|
7
|
+
import fs from 'node:fs';
|
|
8
|
+
import path from 'node:path';
|
|
9
|
+
import os from 'node:os';
|
|
10
|
+
import { fileURLToPath } from 'node:url';
|
|
11
|
+
import { spawnSync } from 'node:child_process';
|
|
12
|
+
import { createRequire } from 'node:module';
|
|
13
|
+
import { log } from '../logging/logger.js';
|
|
14
|
+
const requireJson = createRequire(import.meta.url);
|
|
15
|
+
const CURRENT_SERVER_VERSION = requireJson('../../../package.json').version;
|
|
16
|
+
const UPDATE_TTL_MS = 4 * 60 * 60 * 1000;
|
|
17
|
+
const UPDATE_GRACE_MS = 48 * 60 * 60 * 1000;
|
|
18
|
+
const SPAWN_OPTS = {
|
|
19
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
20
|
+
timeout: 30000,
|
|
21
|
+
shell: process.platform === 'win32',
|
|
22
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
23
|
+
};
|
|
24
|
+
const SEMVER_RE = /^\d+\.\d+\.\d+(-[a-zA-Z0-9.]+)?$/;
|
|
25
|
+
function cacheDir() {
|
|
26
|
+
const provarHome = process.env['PROVAR_HOME'] ?? path.join(os.homedir(), 'Provar');
|
|
27
|
+
return path.join(provarHome, '.cache');
|
|
28
|
+
}
|
|
29
|
+
function cacheFile() {
|
|
30
|
+
return path.join(cacheDir(), '.mcp-update-cache.json');
|
|
31
|
+
}
|
|
32
|
+
// Derives the dist-tag channel from the current version's prerelease identifier.
|
|
33
|
+
// '1.5.0-beta.10' → 'beta', '1.5.0' → 'latest'
|
|
34
|
+
// Same-channel assumption: we fetch dist-tags.{channel} and compare within that channel.
|
|
35
|
+
// Cross-label comparison (e.g. beta vs rc) is explicitly out of scope.
|
|
36
|
+
export function deriveChannel(version) {
|
|
37
|
+
const hyphen = version.indexOf('-');
|
|
38
|
+
if (hyphen === -1)
|
|
39
|
+
return 'latest';
|
|
40
|
+
return version.slice(hyphen + 1).split('.')[0] ?? 'latest';
|
|
41
|
+
}
|
|
42
|
+
export function isNewer(current, latest) {
|
|
43
|
+
if (current === latest)
|
|
44
|
+
return false;
|
|
45
|
+
if (!SEMVER_RE.test(latest))
|
|
46
|
+
return false;
|
|
47
|
+
const split = (v) => {
|
|
48
|
+
const [main, pre = ''] = v.split('-');
|
|
49
|
+
const [major, minor, patch] = (main ?? '').split('.').map(Number);
|
|
50
|
+
// Infinity for stable versions so stable is always newer than any prerelease
|
|
51
|
+
const preN = pre ? parseInt(pre.split('.').pop() ?? '0', 10) : Infinity;
|
|
52
|
+
return [major, minor, patch, preN];
|
|
53
|
+
};
|
|
54
|
+
const [cm, cn, cp, cpN] = split(current);
|
|
55
|
+
const [lm, ln, lp, lpN] = split(latest);
|
|
56
|
+
for (const [c, l] of [
|
|
57
|
+
[cm, lm],
|
|
58
|
+
[cn, ln],
|
|
59
|
+
[cp, lp],
|
|
60
|
+
[cpN, lpN],
|
|
61
|
+
]) {
|
|
62
|
+
if (l > c)
|
|
63
|
+
return true;
|
|
64
|
+
if (l < c)
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
export function detectInstallMethod() {
|
|
70
|
+
const modulePath = fileURLToPath(import.meta.url);
|
|
71
|
+
const sfDataDirs = [
|
|
72
|
+
path.join('.local', 'share', 'sf'),
|
|
73
|
+
path.join('AppData', 'Local', 'sf'),
|
|
74
|
+
path.join('AppData', 'Roaming', 'sf'),
|
|
75
|
+
path.join('.local', 'share', 'sfdx'),
|
|
76
|
+
];
|
|
77
|
+
if (sfDataDirs.some((d) => modulePath.includes(d)))
|
|
78
|
+
return 'sf-plugin';
|
|
79
|
+
if (modulePath.includes('node_modules'))
|
|
80
|
+
return 'npm-global';
|
|
81
|
+
return 'linked';
|
|
82
|
+
}
|
|
83
|
+
function readUpdateCache() {
|
|
84
|
+
try {
|
|
85
|
+
const raw = fs.readFileSync(cacheFile(), 'utf-8');
|
|
86
|
+
return JSON.parse(raw);
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
function writeUpdateCache(entry) {
|
|
93
|
+
try {
|
|
94
|
+
fs.mkdirSync(cacheDir(), { recursive: true });
|
|
95
|
+
const file = cacheFile();
|
|
96
|
+
fs.writeFileSync(file, JSON.stringify(entry, null, 2), { encoding: 'utf-8', mode: 0o600 });
|
|
97
|
+
try {
|
|
98
|
+
fs.chmodSync(file, 0o600);
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
// best effort
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
catch (err) {
|
|
105
|
+
log('warn', 'updateChecker: failed to write cache', { error: String(err) });
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
function buildUpdateCommand(latestVersion) {
|
|
109
|
+
const method = detectInstallMethod();
|
|
110
|
+
if (method === 'npm-global') {
|
|
111
|
+
return 'npm install -g @provartesting/provardx-cli@' + latestVersion;
|
|
112
|
+
}
|
|
113
|
+
return 'sf plugins install @provartesting/provardx-cli@' + latestVersion;
|
|
114
|
+
}
|
|
115
|
+
function resultFromCache(cached, currentVersion) {
|
|
116
|
+
const updateAvailable = cached.latestVersion ? isNewer(currentVersion, cached.latestVersion) : false;
|
|
117
|
+
const updateCommand = updateAvailable && cached.latestVersion ? buildUpdateCommand(cached.latestVersion) : null;
|
|
118
|
+
return { currentVersion, latestVersion: cached.latestVersion, updateAvailable, updateCommand, fromCache: true };
|
|
119
|
+
}
|
|
120
|
+
async function fetchLatestVersion(channel) {
|
|
121
|
+
const controller = new AbortController();
|
|
122
|
+
const timer = setTimeout(() => controller.abort(), 5000);
|
|
123
|
+
try {
|
|
124
|
+
const resp = await fetch('https://registry.npmjs.org/@provartesting/provardx-cli', {
|
|
125
|
+
signal: controller.signal,
|
|
126
|
+
headers: { Accept: 'application/json' },
|
|
127
|
+
});
|
|
128
|
+
if (!resp.ok) {
|
|
129
|
+
log('warn', 'updateChecker: registry returned non-200', { status: resp.status });
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
const data = (await resp.json());
|
|
133
|
+
const distTags = data['dist-tags'];
|
|
134
|
+
const candidate = distTags?.[channel];
|
|
135
|
+
if (!candidate) {
|
|
136
|
+
log('warn', 'updateChecker: dist-tag not found in registry', { channel });
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
if (!SEMVER_RE.test(candidate)) {
|
|
140
|
+
log('warn', 'updateChecker: registry returned invalid semver', { candidate });
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
143
|
+
return candidate;
|
|
144
|
+
}
|
|
145
|
+
finally {
|
|
146
|
+
clearTimeout(timer);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
function applyAutoUpdate(latestVersion) {
|
|
150
|
+
const method = detectInstallMethod();
|
|
151
|
+
if (method === 'linked') {
|
|
152
|
+
process.stderr.write('[provar-mcp] Auto-update skipped: running from development link. Install manually:\n' +
|
|
153
|
+
' sf plugins install @provartesting/provardx-cli@' +
|
|
154
|
+
latestVersion +
|
|
155
|
+
'\n');
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
const args = method === 'sf-plugin'
|
|
159
|
+
? ['plugins', 'install', '@provartesting/provardx-cli@' + latestVersion]
|
|
160
|
+
: ['install', '-g', '@provartesting/provardx-cli@' + latestVersion];
|
|
161
|
+
const cmd = method === 'sf-plugin' ? 'sf' : 'npm';
|
|
162
|
+
log('info', 'updateChecker: running auto-update', { cmd, args });
|
|
163
|
+
const result = spawnSync(cmd, args, SPAWN_OPTS);
|
|
164
|
+
if (result.error != null || result.status !== 0 || result.signal != null) {
|
|
165
|
+
const detail = result.stderr?.toString().trim() ?? '';
|
|
166
|
+
log('error', 'updateChecker: auto-update failed', { status: result.status, signal: result.signal, detail });
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
process.stderr.write('[provar-mcp] Updated to ' + latestVersion + '. Restart your MCP connection to use the new version.\n');
|
|
170
|
+
process.exit(0);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
export async function checkForUpdate(opts) {
|
|
174
|
+
const currentVersion = CURRENT_SERVER_VERSION;
|
|
175
|
+
const earlyExit = {
|
|
176
|
+
currentVersion,
|
|
177
|
+
latestVersion: null,
|
|
178
|
+
updateAvailable: false,
|
|
179
|
+
updateCommand: null,
|
|
180
|
+
fromCache: false,
|
|
181
|
+
};
|
|
182
|
+
if (process.env.NODE_ENV === 'test')
|
|
183
|
+
return earlyExit;
|
|
184
|
+
if (process.env['PROVAR_NO_UPDATE_CHECK'])
|
|
185
|
+
return earlyExit;
|
|
186
|
+
if (opts.noUpdateCheck)
|
|
187
|
+
return earlyExit;
|
|
188
|
+
const channel = deriveChannel(currentVersion);
|
|
189
|
+
const cached = readUpdateCache();
|
|
190
|
+
if (cached != null &&
|
|
191
|
+
cached.channel === channel &&
|
|
192
|
+
cached.currentVersion === currentVersion &&
|
|
193
|
+
Date.now() - cached.checkedAt < UPDATE_TTL_MS) {
|
|
194
|
+
log('info', 'updateChecker: cache hit', { channel, latestVersion: cached.latestVersion, fromCache: true });
|
|
195
|
+
return resultFromCache(cached, currentVersion);
|
|
196
|
+
}
|
|
197
|
+
let latestVersion = null;
|
|
198
|
+
try {
|
|
199
|
+
latestVersion = await fetchLatestVersion(channel);
|
|
200
|
+
}
|
|
201
|
+
catch (err) {
|
|
202
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
203
|
+
log('warn', 'updateChecker: registry fetch failed', { error: errMsg });
|
|
204
|
+
if (cached != null && Date.now() - cached.checkedAt < UPDATE_GRACE_MS) {
|
|
205
|
+
return resultFromCache(cached, currentVersion);
|
|
206
|
+
}
|
|
207
|
+
return earlyExit;
|
|
208
|
+
}
|
|
209
|
+
writeUpdateCache({ checkedAt: Date.now(), currentVersion, latestVersion, channel });
|
|
210
|
+
const updateAvailable = latestVersion ? isNewer(currentVersion, latestVersion) : false;
|
|
211
|
+
const updateCommand = updateAvailable && latestVersion ? buildUpdateCommand(latestVersion) : null;
|
|
212
|
+
if (updateAvailable && latestVersion) {
|
|
213
|
+
process.stderr.write('[provar-mcp] Update available: ' +
|
|
214
|
+
latestVersion +
|
|
215
|
+
' (current: ' +
|
|
216
|
+
currentVersion +
|
|
217
|
+
')\n' +
|
|
218
|
+
' Run: ' +
|
|
219
|
+
(updateCommand ?? '') +
|
|
220
|
+
'\n');
|
|
221
|
+
log('info', 'updateChecker: update available', { currentVersion, latestVersion, updateCommand });
|
|
222
|
+
if (opts.autoUpdate) {
|
|
223
|
+
applyAutoUpdate(latestVersion);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
return { currentVersion, latestVersion, updateAvailable, updateCommand, fromCache: false };
|
|
227
|
+
}
|
|
228
|
+
//# sourceMappingURL=updateChecker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"updateChecker.js","sourceRoot":"","sources":["../../../src/mcp/update/updateChecker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export type DetailLevel = 'summary' | 'standard' | 'full';
|
|
2
|
+
/**
|
|
3
|
+
* Shape a structured response object according to the requested detail level.
|
|
4
|
+
*
|
|
5
|
+
* - `summary` — retain only the keys listed in summaryFields
|
|
6
|
+
* - `standard` — return data unchanged (the existing default response shape)
|
|
7
|
+
* - `full` — return data unchanged (callers expand gated fields before calling)
|
|
8
|
+
*/
|
|
9
|
+
export declare function applyDetailLevel(data: Record<string, unknown>, level: DetailLevel, summaryFields: string[]): Record<string, unknown>;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2024 Provar Limited.
|
|
3
|
+
* All rights reserved.
|
|
4
|
+
* Licensed under the BSD 3-Clause license.
|
|
5
|
+
* For full license text, see LICENSE.md file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Shape a structured response object according to the requested detail level.
|
|
9
|
+
*
|
|
10
|
+
* - `summary` — retain only the keys listed in summaryFields
|
|
11
|
+
* - `standard` — return data unchanged (the existing default response shape)
|
|
12
|
+
* - `full` — return data unchanged (callers expand gated fields before calling)
|
|
13
|
+
*/
|
|
14
|
+
export function applyDetailLevel(data, level, summaryFields) {
|
|
15
|
+
if (level === 'summary') {
|
|
16
|
+
return Object.fromEntries(Object.entries(data).filter(([k]) => summaryFields.includes(k)));
|
|
17
|
+
}
|
|
18
|
+
return data;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=detailLevel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detailLevel.js","sourceRoot":"","sources":["../../../src/mcp/utils/detailLevel.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAC9B,IAA6B,EAC7B,KAAkB,EAClB,aAAuB;IAEvB,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7F,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mask an object (or array of objects) to retain only the specified fields.
|
|
3
|
+
*
|
|
4
|
+
* - Top-level keys: `"name"` keeps only the `name` property
|
|
5
|
+
* - Dot notation: `"steps.action"` keeps the `steps` array but only `action` within each element
|
|
6
|
+
* - Unknown field names are silently ignored — never an error
|
|
7
|
+
* - Arrays: masking is applied to every element
|
|
8
|
+
*
|
|
9
|
+
* @param obj Source object or array (typed as unknown; cast internally, never through any)
|
|
10
|
+
* @param fields Parsed field list — each entry is a dot-path string
|
|
11
|
+
*/
|
|
12
|
+
export declare function maskFields(obj: unknown, fields: string[]): unknown;
|
|
13
|
+
/**
|
|
14
|
+
* Parse a comma-separated fields string into a trimmed, non-empty field list.
|
|
15
|
+
* Returns null when the string is absent or blank (caller should skip masking).
|
|
16
|
+
*/
|
|
17
|
+
export declare function parseFieldsParam(fields: string | undefined): string[] | null;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2024 Provar Limited.
|
|
3
|
+
* All rights reserved.
|
|
4
|
+
* Licensed under the BSD 3-Clause license.
|
|
5
|
+
* For full license text, see LICENSE.md file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Mask an object (or array of objects) to retain only the specified fields.
|
|
9
|
+
*
|
|
10
|
+
* - Top-level keys: `"name"` keeps only the `name` property
|
|
11
|
+
* - Dot notation: `"steps.action"` keeps the `steps` array but only `action` within each element
|
|
12
|
+
* - Unknown field names are silently ignored — never an error
|
|
13
|
+
* - Arrays: masking is applied to every element
|
|
14
|
+
*
|
|
15
|
+
* @param obj Source object or array (typed as unknown; cast internally, never through any)
|
|
16
|
+
* @param fields Parsed field list — each entry is a dot-path string
|
|
17
|
+
*/
|
|
18
|
+
export function maskFields(obj, fields) {
|
|
19
|
+
if (Array.isArray(obj)) {
|
|
20
|
+
return obj.map((item) => maskFields(item, fields));
|
|
21
|
+
}
|
|
22
|
+
if (obj === null || typeof obj !== 'object') {
|
|
23
|
+
return obj;
|
|
24
|
+
}
|
|
25
|
+
const source = obj;
|
|
26
|
+
// Group fields: topLevelKeys contains every key to retain.
|
|
27
|
+
// dotFields[key] holds the sub-paths to drill into for that key.
|
|
28
|
+
const topLevelKeys = new Set();
|
|
29
|
+
const dotFields = {};
|
|
30
|
+
for (const field of fields) {
|
|
31
|
+
const dotIdx = field.indexOf('.');
|
|
32
|
+
if (dotIdx === -1) {
|
|
33
|
+
topLevelKeys.add(field);
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
const top = field.slice(0, dotIdx);
|
|
37
|
+
const rest = field.slice(dotIdx + 1);
|
|
38
|
+
topLevelKeys.add(top);
|
|
39
|
+
if (!dotFields[top])
|
|
40
|
+
dotFields[top] = [];
|
|
41
|
+
dotFields[top].push(rest);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
const result = {};
|
|
45
|
+
for (const key of topLevelKeys) {
|
|
46
|
+
if (!(key in source))
|
|
47
|
+
continue; // silently ignore unknown fields
|
|
48
|
+
const subPaths = dotFields[key];
|
|
49
|
+
if (subPaths) {
|
|
50
|
+
const val = source[key];
|
|
51
|
+
// Dot-path into a primitive can't be narrowed; omit rather than leak the whole value.
|
|
52
|
+
if (Array.isArray(val) || (val !== null && typeof val === 'object')) {
|
|
53
|
+
result[key] = maskFields(val, subPaths);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
result[key] = source[key];
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return result;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Parse a comma-separated fields string into a trimmed, non-empty field list.
|
|
64
|
+
* Returns null when the string is absent or blank (caller should skip masking).
|
|
65
|
+
*/
|
|
66
|
+
export function parseFieldsParam(fields) {
|
|
67
|
+
if (!fields)
|
|
68
|
+
return null;
|
|
69
|
+
const parsed = fields
|
|
70
|
+
.split(',')
|
|
71
|
+
.map((f) => f.trim())
|
|
72
|
+
.filter(Boolean);
|
|
73
|
+
return parsed.length > 0 ? parsed : null;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=fieldMask.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fieldMask.js","sourceRoot":"","sources":["../../../src/mcp/utils/fieldMask.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;;;;;GAUG;AACH,MAAM,UAAU,UAAU,CAAC,GAAY,EAAE,MAAgB;IACvD,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;IACrD,CAAC;IAED,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC5C,OAAO,GAAG,CAAC;IACb,CAAC;IAED,MAAM,MAAM,GAAG,GAA8B,CAAC;IAE9C,2DAA2D;IAC3D,iEAAiE;IACjE,MAAM,YAAY,GAAG,IAAI,GAAG,EAAU,CAAC;IACvC,MAAM,SAAS,GAA6B,EAAE,CAAC;IAE/C,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAClC,IAAI,MAAM,KAAK,CAAC,CAAC,EAAE,CAAC;YAClB,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC1B,CAAC;aAAM,CAAC;YACN,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;YACnC,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YACrC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACtB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC;gBAAE,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;YACzC,SAAS,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAA4B,EAAE,CAAC;IAC3C,KAAK,MAAM,GAAG,IAAI,YAAY,EAAE,CAAC;QAC/B,IAAI,CAAC,CAAC,GAAG,IAAI,MAAM,CAAC;YAAE,SAAS,CAAC,iCAAiC;QACjE,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;QAChC,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;YACxB,sFAAsF;YACtF,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ,CAAC,EAAE,CAAC;gBACpE,MAAM,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;YAC1C,CAAC;QACH,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAA0B;IACzD,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACzB,MAAM,MAAM,GAAG,MAAM;SAClB,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SACpB,MAAM,CAAC,OAAO,CAAC,CAAC;IACnB,OAAO,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AAC3C,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
type ContentItem = {
|
|
2
|
+
type: 'text';
|
|
3
|
+
text: string;
|
|
4
|
+
};
|
|
5
|
+
export interface ToolResult {
|
|
6
|
+
content: ContentItem[];
|
|
7
|
+
structuredContent?: Record<string, unknown>;
|
|
8
|
+
isError?: boolean;
|
|
9
|
+
}
|
|
10
|
+
interface ToolExtra {
|
|
11
|
+
sessionId?: string;
|
|
12
|
+
}
|
|
13
|
+
export type AnyToolCallback = (args: Record<string, unknown>, extra: ToolExtra) => ToolResult | Promise<ToolResult>;
|
|
14
|
+
interface SessionEntry {
|
|
15
|
+
calls: number;
|
|
16
|
+
totalEstimatedTokens: number;
|
|
17
|
+
}
|
|
18
|
+
export type DepthGuardState = Map<string, SessionEntry>;
|
|
19
|
+
export declare function createDepthGuardState(): DepthGuardState;
|
|
20
|
+
/**
|
|
21
|
+
* Wraps a tool handler to enforce a per-session call budget.
|
|
22
|
+
* Once `limit` calls have been made for a session, every further call returns
|
|
23
|
+
* TOOL_BUDGET_EXCEEDED without invoking the underlying handler.
|
|
24
|
+
* Callers without a sessionId (stdio transports — Claude Desktop, Cursor, etc.)
|
|
25
|
+
* share a single 'anon' bucket so the budget actually limits runaway tool use;
|
|
26
|
+
* giving each anon call a fresh UUID would defeat the purpose of the guard.
|
|
27
|
+
* `provardx_ping` is excluded from wrapping at the call site in server.ts.
|
|
28
|
+
*/
|
|
29
|
+
export declare function wrapWithDepthGuard(toolName: string, handler: AnyToolCallback, state: DepthGuardState, limit: number): AnyToolCallback;
|
|
30
|
+
export declare function estimateTokens(payload: unknown): number;
|
|
31
|
+
/**
|
|
32
|
+
* Appends a `_meta` key to `structuredContent` when PROVAR_MCP_EMIT_TOKEN_META=true.
|
|
33
|
+
* The `content[0].text` string is intentionally left unchanged — LLMs read that
|
|
34
|
+
* field, so including meta there would waste tokens on observability data.
|
|
35
|
+
*
|
|
36
|
+
* @param sessionTotalTokens - Cumulative estimated tokens for the session,
|
|
37
|
+
* included only on TOOL_BUDGET_EXCEEDED errors.
|
|
38
|
+
*/
|
|
39
|
+
export declare function attachMeta(response: ToolResult, toolName: string, detailLevel: string, sessionTotalTokens?: number): ToolResult;
|
|
40
|
+
export {};
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2024 Provar Limited.
|
|
3
|
+
* All rights reserved.
|
|
4
|
+
* Licensed under the BSD 3-Clause license.
|
|
5
|
+
* For full license text, see LICENSE.md file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
|
6
|
+
*/
|
|
7
|
+
const MAX_SESSIONS = 1000;
|
|
8
|
+
export function createDepthGuardState() {
|
|
9
|
+
return new Map();
|
|
10
|
+
}
|
|
11
|
+
function getOrCreateEntry(state, sessionId) {
|
|
12
|
+
if (!state.has(sessionId)) {
|
|
13
|
+
if (state.size >= MAX_SESSIONS) {
|
|
14
|
+
const oldest = state.keys().next().value;
|
|
15
|
+
if (oldest !== undefined)
|
|
16
|
+
state.delete(oldest);
|
|
17
|
+
}
|
|
18
|
+
state.set(sessionId, { calls: 0, totalEstimatedTokens: 0 });
|
|
19
|
+
}
|
|
20
|
+
// Non-null guaranteed by the set above or pre-existing entry.
|
|
21
|
+
return state.get(sessionId);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Wraps a tool handler to enforce a per-session call budget.
|
|
25
|
+
* Once `limit` calls have been made for a session, every further call returns
|
|
26
|
+
* TOOL_BUDGET_EXCEEDED without invoking the underlying handler.
|
|
27
|
+
* Callers without a sessionId (stdio transports — Claude Desktop, Cursor, etc.)
|
|
28
|
+
* share a single 'anon' bucket so the budget actually limits runaway tool use;
|
|
29
|
+
* giving each anon call a fresh UUID would defeat the purpose of the guard.
|
|
30
|
+
* `provardx_ping` is excluded from wrapping at the call site in server.ts.
|
|
31
|
+
*/
|
|
32
|
+
export function wrapWithDepthGuard(toolName, handler, state, limit) {
|
|
33
|
+
return async (args, extra) => {
|
|
34
|
+
const sessionId = extra.sessionId ?? 'anon';
|
|
35
|
+
const entry = getOrCreateEntry(state, sessionId);
|
|
36
|
+
if (entry.calls >= limit) {
|
|
37
|
+
const payload = {
|
|
38
|
+
error: 'TOOL_BUDGET_EXCEEDED',
|
|
39
|
+
callsMade: entry.calls,
|
|
40
|
+
limit,
|
|
41
|
+
suggestion: 'Summarize progress and return control to the user.',
|
|
42
|
+
};
|
|
43
|
+
const response = {
|
|
44
|
+
isError: true,
|
|
45
|
+
content: [{ type: 'text', text: JSON.stringify(payload) }],
|
|
46
|
+
structuredContent: payload,
|
|
47
|
+
};
|
|
48
|
+
return attachMeta(response, toolName, 'standard', entry.totalEstimatedTokens);
|
|
49
|
+
}
|
|
50
|
+
entry.calls++;
|
|
51
|
+
const result = await handler(args, extra);
|
|
52
|
+
if (process.env['PROVAR_MCP_EMIT_TOKEN_META'] === 'true') {
|
|
53
|
+
entry.totalEstimatedTokens += estimateTokens(result);
|
|
54
|
+
}
|
|
55
|
+
const detailLevel = typeof args['detail'] === 'string' ? args['detail'] : 'standard';
|
|
56
|
+
return attachMeta(result, toolName, detailLevel);
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
// --------------------------------------------------------------------------- //
|
|
60
|
+
// PDX-475 — Token meta attachment (PROVAR_MCP_EMIT_TOKEN_META)
|
|
61
|
+
// --------------------------------------------------------------------------- //
|
|
62
|
+
export function estimateTokens(payload) {
|
|
63
|
+
return Math.ceil(JSON.stringify(payload).length / 4);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Appends a `_meta` key to `structuredContent` when PROVAR_MCP_EMIT_TOKEN_META=true.
|
|
67
|
+
* The `content[0].text` string is intentionally left unchanged — LLMs read that
|
|
68
|
+
* field, so including meta there would waste tokens on observability data.
|
|
69
|
+
*
|
|
70
|
+
* @param sessionTotalTokens - Cumulative estimated tokens for the session,
|
|
71
|
+
* included only on TOOL_BUDGET_EXCEEDED errors.
|
|
72
|
+
*/
|
|
73
|
+
export function attachMeta(response, toolName, detailLevel, sessionTotalTokens) {
|
|
74
|
+
if (process.env['PROVAR_MCP_EMIT_TOKEN_META'] !== 'true')
|
|
75
|
+
return response;
|
|
76
|
+
const meta = {
|
|
77
|
+
tool: toolName,
|
|
78
|
+
detailLevel,
|
|
79
|
+
estimatedTokens: estimateTokens(response),
|
|
80
|
+
};
|
|
81
|
+
if (sessionTotalTokens !== undefined) {
|
|
82
|
+
meta['sessionTotalEstimatedTokens'] = sessionTotalTokens;
|
|
83
|
+
}
|
|
84
|
+
const existing = response.structuredContent ?? {};
|
|
85
|
+
return {
|
|
86
|
+
...response,
|
|
87
|
+
structuredContent: { ...existing, _meta: meta },
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=tokenMeta.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokenMeta.js","sourceRoot":"","sources":["../../../src/mcp/utils/tokenMeta.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
export type DiffableViolation = Record<string, unknown>;
|
|
2
|
+
export interface DiffResult {
|
|
3
|
+
added: DiffableViolation[];
|
|
4
|
+
resolved: DiffableViolation[];
|
|
5
|
+
unchanged_count: number;
|
|
6
|
+
run_id: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Compute a stable 8-char context hash for a tool + context pair. Used to
|
|
10
|
+
* scope baseline run lookups so that a run_id from context A cannot be diffed
|
|
11
|
+
* against context B (different project, different suite, different file).
|
|
12
|
+
*/
|
|
13
|
+
export declare function computeContextHash(toolTag: string, context: string): string;
|
|
14
|
+
/**
|
|
15
|
+
* Resolve the validation storage root for a given tool subdir. Honors the
|
|
16
|
+
* PROVAR_MCP_VALIDATION_DIR env var when set; otherwise falls back to
|
|
17
|
+
* `~/.provardx/validation/<subdir>`. The env override is useful for restricted
|
|
18
|
+
* CI/dev environments where the home directory is read-only or shared.
|
|
19
|
+
*/
|
|
20
|
+
export declare function resolveValidationDir(subdir: string): string;
|
|
21
|
+
/** Generate a run ID from a context string (e.g. project path or suite name). */
|
|
22
|
+
export declare function generateRunId(context: string): string;
|
|
23
|
+
/**
|
|
24
|
+
* Check whether any prior runs exist in the given storage directory.
|
|
25
|
+
* Used by calcNextAction to determine the first-run heuristic.
|
|
26
|
+
*/
|
|
27
|
+
export declare function hasAnyRun(storageDir: string): boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Save the current violations as a new run in the storage directory.
|
|
30
|
+
* Caps the index at MAX_RUNS by evicting the oldest entry when full.
|
|
31
|
+
* Returns the generated run_id.
|
|
32
|
+
*
|
|
33
|
+
* When `contextHash` is provided, it is recorded alongside the run so that
|
|
34
|
+
* `loadBaselineViolations` can reject a baseline_run_id whose context does
|
|
35
|
+
* not match the calling context (prevents cross-context diffs).
|
|
36
|
+
*/
|
|
37
|
+
export declare function saveRun(storageDir: string, runId: string, violations: DiffableViolation[], contextHash?: string): string;
|
|
38
|
+
/**
|
|
39
|
+
* Load the violations array for a given baseline run ID.
|
|
40
|
+
* Returns null if the run is not found in the index (BASELINE_NOT_FOUND).
|
|
41
|
+
* The filename is looked up from the index only — the run_id itself is never
|
|
42
|
+
* used to construct a file path, preventing path traversal.
|
|
43
|
+
*
|
|
44
|
+
* When `expectedContextHash` is provided, the record's `context_hash` must
|
|
45
|
+
* match. Records without a `context_hash` (written by older versions before
|
|
46
|
+
* H3) are treated as a mismatch and are effectively retired within one or
|
|
47
|
+
* two new runs as the FIFO cap evicts them. This guard prevents diffing a
|
|
48
|
+
* baseline from a different file/suite/project against the current context.
|
|
49
|
+
*/
|
|
50
|
+
export declare function loadBaselineViolations(storageDir: string, baselineRunId: string, expectedContextHash?: string): DiffableViolation[] | null;
|
|
51
|
+
/**
|
|
52
|
+
* Compute the diff between a baseline and current violations array.
|
|
53
|
+
* Uses (rule_id + applies_to + full message) as the unique key.
|
|
54
|
+
* Duplicate violations (same key, multiple occurrences) are treated as
|
|
55
|
+
* distinct entries — each occurrence is counted separately (multiset semantics).
|
|
56
|
+
*/
|
|
57
|
+
export declare function computeDiff(baseline: DiffableViolation[], current: DiffableViolation[]): Omit<DiffResult, 'run_id'>;
|