@gobing-ai/ts-rule-engine 0.3.1 → 0.3.3
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 +328 -58
- package/dist/config/extensions.d.ts +10 -7
- package/dist/config/extensions.d.ts.map +1 -1
- package/dist/config/extensions.js +48 -23
- package/dist/config/loader.d.ts +7 -0
- package/dist/config/loader.d.ts.map +1 -1
- package/dist/config/loader.js +17 -12
- package/dist/engine.d.ts +13 -2
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +107 -45
- package/dist/evaluators/agent-detection-evaluator.d.ts.map +1 -1
- package/dist/evaluators/agent-detection-evaluator.js +2 -9
- package/dist/evaluators/coverage-gate-evaluator.d.ts.map +1 -1
- package/dist/evaluators/coverage-gate-evaluator.js +4 -5
- package/dist/evaluators/exit-code-evaluator.d.ts.map +1 -1
- package/dist/evaluators/exit-code-evaluator.js +6 -23
- package/dist/evaluators/file-utils.d.ts +25 -1
- package/dist/evaluators/file-utils.d.ts.map +1 -1
- package/dist/evaluators/file-utils.js +48 -8
- package/dist/evaluators/forbidden-import-evaluator.js +2 -10
- package/dist/evaluators/path-evaluator.d.ts.map +1 -1
- package/dist/evaluators/path-evaluator.js +5 -18
- package/dist/evaluators/regex-evaluator.js +3 -11
- package/dist/evaluators/ripgrep-evaluator.d.ts +50 -0
- package/dist/evaluators/ripgrep-evaluator.d.ts.map +1 -0
- package/dist/evaluators/ripgrep-evaluator.js +145 -0
- package/dist/evaluators/schema-artifact-evaluator.d.ts.map +1 -1
- package/dist/evaluators/schema-artifact-evaluator.js +3 -7
- package/dist/evaluators/sg-evaluator.d.ts +10 -2
- package/dist/evaluators/sg-evaluator.d.ts.map +1 -1
- package/dist/evaluators/sg-evaluator.js +21 -4
- package/dist/evaluators/test-location-evaluator.d.ts +2 -2
- package/dist/evaluators/test-location-evaluator.d.ts.map +1 -1
- package/dist/evaluators/test-location-evaluator.js +2 -15
- package/dist/events.d.ts +33 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +0 -0
- package/dist/fixers/fixers.d.ts +1 -1
- package/dist/fixers/fixers.d.ts.map +1 -1
- package/dist/fixers/fixers.js +4 -5
- package/dist/fixers/test-stub-fixer.d.ts +1 -1
- package/dist/fixers/test-stub-fixer.d.ts.map +1 -1
- package/dist/fixers/test-stub-fixer.js +3 -4
- package/dist/host/builtins.d.ts.map +1 -1
- package/dist/host/builtins.js +5 -3
- package/dist/host/bundled-rules.d.ts +1 -1
- package/dist/host/bundled-rules.js +1 -1
- package/dist/host/rule-engine-host.d.ts +1 -1
- package/dist/host/rule-engine-host.d.ts.map +1 -1
- package/dist/host/rule-engine-host.js +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -1
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +6 -0
- package/package.json +4 -5
- package/rules/example.yaml +13 -0
- package/src/config/extensions.ts +58 -29
- package/src/config/loader.ts +27 -12
- package/src/engine.ts +132 -47
- package/src/evaluators/agent-detection-evaluator.ts +2 -8
- package/src/evaluators/coverage-gate-evaluator.ts +4 -5
- package/src/evaluators/exit-code-evaluator.ts +6 -23
- package/src/evaluators/file-utils.ts +70 -8
- package/src/evaluators/forbidden-import-evaluator.ts +2 -9
- package/src/evaluators/path-evaluator.ts +5 -18
- package/src/evaluators/regex-evaluator.ts +4 -11
- package/src/evaluators/ripgrep-evaluator.ts +167 -0
- package/src/evaluators/schema-artifact-evaluator.ts +3 -8
- package/src/evaluators/sg-evaluator.ts +21 -4
- package/src/evaluators/test-location-evaluator.ts +3 -16
- package/src/events.ts +13 -0
- package/src/fixers/fixers.ts +12 -6
- package/src/fixers/test-stub-fixer.ts +4 -5
- package/src/host/builtins.ts +5 -3
- package/src/host/bundled-rules.ts +1 -1
- package/src/host/rule-engine-host.ts +1 -1
- package/src/index.ts +8 -1
- package/src/types.ts +7 -0
- package/dist/host/capability-registry.d.ts +0 -10
- package/dist/host/capability-registry.d.ts.map +0 -1
- package/dist/host/capability-registry.js +0 -9
- package/rules/recommended.yaml +0 -10
- package/rules/spur-dev.yaml +0 -6
- package/src/host/capability-registry.ts +0 -9
package/dist/config/loader.d.ts
CHANGED
|
@@ -15,6 +15,7 @@ export interface RuleLoaderOptions {
|
|
|
15
15
|
/** Optional fetch implementation for remote HTTP(S) schema refs. */
|
|
16
16
|
fetch?: (input: string) => Promise<Response>;
|
|
17
17
|
}
|
|
18
|
+
/** Options for loading a single rule file directly from disk. */
|
|
18
19
|
export interface RuleFileLoadOptions {
|
|
19
20
|
/** When true, honor top-level `$schema` refs. Defaults to true. */
|
|
20
21
|
validateSchema?: boolean;
|
|
@@ -36,6 +37,12 @@ export interface LoadedPreset {
|
|
|
36
37
|
* the rest of a preset's categories from the lower-priority roots.
|
|
37
38
|
*/
|
|
38
39
|
export declare function loadPreset(name: string, options: RuleLoaderOptions): Promise<LoadedPreset>;
|
|
40
|
+
/**
|
|
41
|
+
* Load a preset's resolved rules (convenience wrapper).
|
|
42
|
+
*
|
|
43
|
+
* Shortcut for `(await loadPreset(name, options)).rules` — returns only the
|
|
44
|
+
* normalized rule set without the extension module refs.
|
|
45
|
+
*/
|
|
39
46
|
export declare function loadPresetRules(name: string, options: RuleLoaderOptions): Promise<ConstraintRule[]>;
|
|
40
47
|
/**
|
|
41
48
|
* Load a direct rule file from disk.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/config/loader.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/config/loader.ts"],"names":[],"mappings":"AAUA,OAAO,EACH,KAAK,cAAc,EAOtB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAqB,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAEpE,wCAAwC;AACxC,MAAM,WAAW,iBAAiB;IAC9B;;;;;;OAMG;IACH,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,4FAA4F;IAC5F,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,oEAAoE;IACpE,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;CAChD;AAED,iEAAiE;AACjE,MAAM,WAAW,mBAAmB;IAChC,mEAAmE;IACnE,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,oEAAoE;IACpE,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;CAChD;AAED,mFAAmF;AACnF,MAAM,WAAW,YAAY;IACzB,+DAA+D;IAC/D,QAAQ,CAAC,KAAK,EAAE,cAAc,EAAE,CAAC;IACjC,kFAAkF;IAClF,QAAQ,CAAC,UAAU,EAAE,YAAY,EAAE,CAAC;CACvC;AAUD;;;;;;GAMG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,YAAY,CAAC,CAahG;AAyCD;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAEzG;AAED;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,mBAAwB,GAAG,OAAO,CAAC,YAAY,CAAC,CAS7G"}
|
package/dist/config/loader.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { loadStructuredConfig, NodeFileSystem } from '@gobing-ai/ts-runtime';
|
|
1
|
+
import { basenamePath, dirnamePath, joinPath, loadStructuredConfig, NodeFileSystem, relativePath, resolvePath, SEP, } from '@gobing-ai/ts-runtime';
|
|
3
2
|
import { ConstraintRuleFileSchema, ConstraintRuleSchema, PresetDefinitionSchema, } from '../types.js';
|
|
4
3
|
import { collectExtensions } from './extensions.js';
|
|
5
4
|
/**
|
|
@@ -10,13 +9,13 @@ import { collectExtensions } from './extensions.js';
|
|
|
10
9
|
* the rest of a preset's categories from the lower-priority roots.
|
|
11
10
|
*/
|
|
12
11
|
export async function loadPreset(name, options) {
|
|
13
|
-
const merged = await buildMergedRoots(options.roots.map((root) =>
|
|
12
|
+
const merged = await buildMergedRoots(options.roots.map((root) => resolvePath(root)));
|
|
14
13
|
const presetPath = findMergedPreset(merged, name);
|
|
15
14
|
if (presetPath === null)
|
|
16
15
|
return { rules: [], extensions: [] };
|
|
17
16
|
const preset = PresetDefinitionSchema.parse(await readStructuredFile(presetPath, options));
|
|
18
17
|
const rules = [];
|
|
19
|
-
const extensions = collectExtensions(preset.name,
|
|
18
|
+
const extensions = collectExtensions(preset.name, dirnamePath(presetPath), preset.extensions);
|
|
20
19
|
for (const entry of preset.extends) {
|
|
21
20
|
const loaded = await loadPresetEntry(merged, entry, new Set([name]), options);
|
|
22
21
|
rules.push(...loaded.rules);
|
|
@@ -53,6 +52,12 @@ function assertFixModeNotPromoted(presetName, rule, overrideMode) {
|
|
|
53
52
|
throw new Error(`Preset "${presetName}" override for rule "${rule.id}" raises fix mode from "${ruleMode}" to "${overrideMode}"; overrides may only lower fix authority`);
|
|
54
53
|
}
|
|
55
54
|
}
|
|
55
|
+
/**
|
|
56
|
+
* Load a preset's resolved rules (convenience wrapper).
|
|
57
|
+
*
|
|
58
|
+
* Shortcut for `(await loadPreset(name, options)).rules` — returns only the
|
|
59
|
+
* normalized rule set without the extension module refs.
|
|
60
|
+
*/
|
|
56
61
|
export async function loadPresetRules(name, options) {
|
|
57
62
|
return (await loadPreset(name, options)).rules;
|
|
58
63
|
}
|
|
@@ -66,12 +71,12 @@ export async function loadPresetRules(name, options) {
|
|
|
66
71
|
* object, not a `rules:` array) cannot declare extensions and yields `extensions: []`.
|
|
67
72
|
*/
|
|
68
73
|
export async function loadRuleFile(filePath, options = {}) {
|
|
69
|
-
const resolved =
|
|
74
|
+
const resolved = resolvePath(filePath);
|
|
70
75
|
const raw = await readStructuredFile(resolved, options);
|
|
71
76
|
const rules = normalizeRuleFile(raw, resolved);
|
|
72
77
|
const parsed = ConstraintRuleFileSchema.safeParse(raw);
|
|
73
78
|
const extensions = parsed.success
|
|
74
|
-
? collectExtensions(
|
|
79
|
+
? collectExtensions(basenamePath(resolved), dirnamePath(resolved), parsed.data.extensions)
|
|
75
80
|
: [];
|
|
76
81
|
return { rules, extensions };
|
|
77
82
|
}
|
|
@@ -86,7 +91,7 @@ async function loadPresetEntry(merged, entry, seen, options) {
|
|
|
86
91
|
const preset = PresetDefinitionSchema.safeParse(await readStructuredFile(presetPath, options));
|
|
87
92
|
if (preset.success) {
|
|
88
93
|
const rules = [];
|
|
89
|
-
const extensions = collectExtensions(preset.data.name,
|
|
94
|
+
const extensions = collectExtensions(preset.data.name, dirnamePath(presetPath), preset.data.extensions);
|
|
90
95
|
for (const child of preset.data.extends) {
|
|
91
96
|
const loaded = await loadPresetEntry(merged, child, nextSeen, options);
|
|
92
97
|
rules.push(...loaded.rules);
|
|
@@ -127,7 +132,7 @@ async function buildMergedRoots(roots) {
|
|
|
127
132
|
const categories = new Set();
|
|
128
133
|
for (const root of roots) {
|
|
129
134
|
for (const absPath of await walkYamlFiles(fs, root)) {
|
|
130
|
-
const relPath =
|
|
135
|
+
const relPath = relativePath(root, absPath).split(SEP).join('/');
|
|
131
136
|
const slashIdx = relPath.indexOf('/');
|
|
132
137
|
if (slashIdx > 0)
|
|
133
138
|
categories.add(relPath.slice(0, slashIdx));
|
|
@@ -181,7 +186,7 @@ async function walkYamlFiles(fs, dir, depth = 0) {
|
|
|
181
186
|
for (const entry of (await fs.readDir(dir)).sort()) {
|
|
182
187
|
if (depth === 0 && entry === 'presets')
|
|
183
188
|
continue;
|
|
184
|
-
const fullPath =
|
|
189
|
+
const fullPath = joinPath(dir, entry);
|
|
185
190
|
const entryStat = await fs.stat(fullPath);
|
|
186
191
|
if (entryStat?.isDirectory()) {
|
|
187
192
|
acc.push(...(await walkYamlFiles(fs, fullPath, depth + 1)));
|
|
@@ -201,7 +206,7 @@ async function listImmediateDirs(fs, dir) {
|
|
|
201
206
|
for (const entry of await fs.readDir(dir)) {
|
|
202
207
|
if (entry === 'presets')
|
|
203
208
|
continue;
|
|
204
|
-
const entryStat = await fs.stat(
|
|
209
|
+
const entryStat = await fs.stat(joinPath(dir, entry));
|
|
205
210
|
if (entryStat?.isDirectory())
|
|
206
211
|
dirs.push(entry);
|
|
207
212
|
}
|
|
@@ -214,7 +219,7 @@ async function readStructuredFile(path, options = {}) {
|
|
|
214
219
|
});
|
|
215
220
|
}
|
|
216
221
|
function normalizeRuleFile(raw, filePath) {
|
|
217
|
-
const sourceDir =
|
|
222
|
+
const sourceDir = dirnamePath(filePath);
|
|
218
223
|
const maybeFile = ConstraintRuleFileSchema.safeParse(raw);
|
|
219
224
|
if (maybeFile.success)
|
|
220
225
|
return normalizeFileRules(maybeFile.data, sourceDir);
|
|
@@ -226,7 +231,7 @@ function normalizeRuleFile(raw, filePath) {
|
|
|
226
231
|
// single-rule schema. Include field paths so the offending key is obvious.
|
|
227
232
|
const isRuleFileShape = typeof raw === 'object' && raw !== null && 'rules' in raw;
|
|
228
233
|
const issues = (isRuleFileShape ? maybeFile.error : maybeRule.error).issues;
|
|
229
|
-
throw new Error(`Invalid rule file "${
|
|
234
|
+
throw new Error(`Invalid rule file "${basenamePath(filePath)}": ${formatIssues(issues)}`);
|
|
230
235
|
}
|
|
231
236
|
/** Render Zod issues as `path: message` fragments for actionable diagnostics. */
|
|
232
237
|
function formatIssues(issues) {
|
package/dist/engine.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import type { EventBus, Logger } from '@gobing-ai/ts-infra';
|
|
1
2
|
import type { ProcessExecutor } from '@gobing-ai/ts-runtime';
|
|
3
|
+
import type { RuleEngineEvents } from './events';
|
|
2
4
|
import { type FixApplicationResult } from './fixers/fixers';
|
|
3
5
|
import { RuleEngineHost } from './host/rule-engine-host';
|
|
4
6
|
import type { ConstraintRule, Fix, FixMode, RuleEngineResult, RuleEvaluator } from './types';
|
|
@@ -8,6 +10,10 @@ export interface RuleEngineOptions {
|
|
|
8
10
|
processExecutor?: ProcessExecutor;
|
|
9
11
|
/** Optional preconfigured host. */
|
|
10
12
|
host?: RuleEngineHost;
|
|
13
|
+
/** Optional event bus for structured run observability (R-A4). */
|
|
14
|
+
events?: EventBus<RuleEngineEvents>;
|
|
15
|
+
/** Optional logger; defaults to the shared `rule-engine` category logger. */
|
|
16
|
+
logger?: Logger;
|
|
11
17
|
}
|
|
12
18
|
/** Orchestrates enabled constraint rules through a typed evaluator host. */
|
|
13
19
|
export declare class RuleEngine {
|
|
@@ -15,6 +21,8 @@ export declare class RuleEngine {
|
|
|
15
21
|
readonly host: RuleEngineHost;
|
|
16
22
|
/** Fixer providers keyed by evaluator type. */
|
|
17
23
|
private readonly fixers;
|
|
24
|
+
private readonly events;
|
|
25
|
+
private readonly logger;
|
|
18
26
|
constructor(options?: RuleEngineOptions);
|
|
19
27
|
/** Register or replace an evaluator. */
|
|
20
28
|
registerEvaluator(type: string, evaluator: RuleEvaluator): void;
|
|
@@ -26,7 +34,7 @@ export declare class RuleEngine {
|
|
|
26
34
|
* findings, never auto-generated fixes. Keeps the rule loop and error-finding
|
|
27
35
|
* semantics in one place.
|
|
28
36
|
*/
|
|
29
|
-
evaluate(rules: ConstraintRule[], workdir: string): Promise<RuleEngineResult>;
|
|
37
|
+
evaluate(rules: ConstraintRule[], workdir: string, stopOnFirst?: 'error' | 'warning' | 'info'): Promise<RuleEngineResult>;
|
|
30
38
|
/**
|
|
31
39
|
* Evaluate all enabled rules and collect candidate fixes.
|
|
32
40
|
*
|
|
@@ -37,9 +45,12 @@ export declare class RuleEngine {
|
|
|
37
45
|
* @param rules - Normalized rule definitions to evaluate.
|
|
38
46
|
* @param workdir - Working directory to scan.
|
|
39
47
|
* @param maxFixMode - Highest fix authority requested by the caller.
|
|
48
|
+
* @param stopOnFirst - When set, stop evaluating rules after the first rule
|
|
49
|
+
* whose findings meet/exceed this severity threshold. Undefined = exhaustive
|
|
50
|
+
* (today's behavior, zero breaking change).
|
|
40
51
|
* @returns Findings plus fixes allowed by the requested authority.
|
|
41
52
|
*/
|
|
42
|
-
evaluateWithFixes(rules: ConstraintRule[], workdir: string, maxFixMode?: FixMode): Promise<RuleEngineResult>;
|
|
53
|
+
evaluateWithFixes(rules: ConstraintRule[], workdir: string, maxFixMode?: FixMode, stopOnFirst?: 'error' | 'warning' | 'info'): Promise<RuleEngineResult>;
|
|
43
54
|
/**
|
|
44
55
|
* Apply or preview candidate byte-range fixes.
|
|
45
56
|
*
|
package/dist/engine.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAKH,KAAK,oBAAoB,EAE5B,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,KAAK,EAAqB,cAAc,EAAE,GAAG,EAAE,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAGhH,6CAA6C;AAC7C,MAAM,WAAW,iBAAiB;IAC9B,+DAA+D;IAC/D,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,mCAAmC;IACnC,IAAI,CAAC,EAAE,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAE5D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AACjD,OAAO,EAKH,KAAK,oBAAoB,EAE5B,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,KAAK,EAAqB,cAAc,EAAE,GAAG,EAAE,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAGhH,6CAA6C;AAC7C,MAAM,WAAW,iBAAiB;IAC9B,+DAA+D;IAC/D,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,mCAAmC;IACnC,IAAI,CAAC,EAAE,cAAc,CAAC;IACtB,kEAAkE;IAClE,MAAM,CAAC,EAAE,QAAQ,CAAC,gBAAgB,CAAC,CAAC;IACpC,6EAA6E;IAC7E,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,4EAA4E;AAC5E,qBAAa,UAAU;IACnB,2CAA2C;IAC3C,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAE9B,+CAA+C;IAC/C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiC;IACxD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAyC;IAChE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;gBAEpB,OAAO,GAAE,iBAAsB;IAQ3C,wCAAwC;IACxC,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,aAAa,GAAG,IAAI;IAI/D;;;;;;;OAOG;IACG,QAAQ,CACV,KAAK,EAAE,cAAc,EAAE,EACvB,OAAO,EAAE,MAAM,EACf,WAAW,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,GAC3C,OAAO,CAAC,gBAAgB,CAAC;IAI5B;;;;;;;;;;;;;;OAcG;IACG,iBAAiB,CACnB,KAAK,EAAE,cAAc,EAAE,EACvB,OAAO,EAAE,MAAM,EACf,UAAU,GAAE,OAAgB,EAC5B,WAAW,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,GAC3C,OAAO,CAAC,gBAAgB,CAAC;IAoH5B;;;;;;;OAOG;IACG,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,EAAE,EAAE,MAAM,UAAQ,GAAG,OAAO,CAAC,oBAAoB,CAAC;CAG1G"}
|
package/dist/engine.js
CHANGED
|
@@ -1,17 +1,22 @@
|
|
|
1
|
+
import { addSpanEvent, getLogger, traceAsync } from '@gobing-ai/ts-infra';
|
|
1
2
|
import { applyFixes as applyFixesImpl, builtInFixers, FIX_MODE_RANK, } from './fixers/fixers.js';
|
|
2
3
|
import { registerBuiltins } from './host/builtins.js';
|
|
3
4
|
import { RuleEngineHost } from './host/rule-engine-host.js';
|
|
4
|
-
import { createFinding } from './types.js';
|
|
5
|
+
import { createFinding, SEVERITY_RANK } from './types.js';
|
|
5
6
|
/** Orchestrates enabled constraint rules through a typed evaluator host. */
|
|
6
7
|
export class RuleEngine {
|
|
7
8
|
/** Capability host used by this engine. */
|
|
8
9
|
host;
|
|
9
10
|
/** Fixer providers keyed by evaluator type. */
|
|
10
11
|
fixers;
|
|
12
|
+
events;
|
|
13
|
+
logger;
|
|
11
14
|
constructor(options = {}) {
|
|
12
15
|
this.host = options.host ?? new RuleEngineHost();
|
|
13
16
|
registerBuiltins(this.host, options.processExecutor);
|
|
14
17
|
this.fixers = builtInFixers(this.host, options.processExecutor);
|
|
18
|
+
this.events = options.events;
|
|
19
|
+
this.logger = options.logger ?? getLogger('rule-engine');
|
|
15
20
|
}
|
|
16
21
|
/** Register or replace an evaluator. */
|
|
17
22
|
registerEvaluator(type, evaluator) {
|
|
@@ -25,8 +30,8 @@ export class RuleEngine {
|
|
|
25
30
|
* findings, never auto-generated fixes. Keeps the rule loop and error-finding
|
|
26
31
|
* semantics in one place.
|
|
27
32
|
*/
|
|
28
|
-
async evaluate(rules, workdir) {
|
|
29
|
-
return this.evaluateWithFixes(rules, workdir, 'none');
|
|
33
|
+
async evaluate(rules, workdir, stopOnFirst) {
|
|
34
|
+
return this.evaluateWithFixes(rules, workdir, 'none', stopOnFirst);
|
|
30
35
|
}
|
|
31
36
|
/**
|
|
32
37
|
* Evaluate all enabled rules and collect candidate fixes.
|
|
@@ -38,52 +43,109 @@ export class RuleEngine {
|
|
|
38
43
|
* @param rules - Normalized rule definitions to evaluate.
|
|
39
44
|
* @param workdir - Working directory to scan.
|
|
40
45
|
* @param maxFixMode - Highest fix authority requested by the caller.
|
|
46
|
+
* @param stopOnFirst - When set, stop evaluating rules after the first rule
|
|
47
|
+
* whose findings meet/exceed this severity threshold. Undefined = exhaustive
|
|
48
|
+
* (today's behavior, zero breaking change).
|
|
41
49
|
* @returns Findings plus fixes allowed by the requested authority.
|
|
42
50
|
*/
|
|
43
|
-
async evaluateWithFixes(rules, workdir, maxFixMode = 'auto') {
|
|
44
|
-
const
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
];
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
51
|
+
async evaluateWithFixes(rules, workdir, maxFixMode = 'auto', stopOnFirst) {
|
|
52
|
+
const enabledRules = rules.filter((r) => r.enabled !== false);
|
|
53
|
+
const runStartMs = Date.now();
|
|
54
|
+
return await traceAsync('rule.run', async () => {
|
|
55
|
+
this.logger.info('rule run started', { enabled: enabledRules.length, total: rules.length });
|
|
56
|
+
addSpanEvent('rule.run.start', { rules: enabledRules.length, total: rules.length });
|
|
57
|
+
void this.events?.emit('rule.run.start', { rules: enabledRules.length, total: rules.length });
|
|
58
|
+
const findings = [];
|
|
59
|
+
const fixes = [];
|
|
60
|
+
let index = 0;
|
|
61
|
+
let stoppedEarlyLocal = false;
|
|
62
|
+
for (const rule of rules) {
|
|
63
|
+
if (rule.enabled === false)
|
|
64
|
+
continue;
|
|
65
|
+
index++;
|
|
66
|
+
const evalStartMs = Date.now();
|
|
67
|
+
this.logger.debug('eval start', { ruleId: rule.id, index, total: enabledRules.length });
|
|
68
|
+
addSpanEvent('rule.eval.start', { ruleId: rule.id, index, total: enabledRules.length });
|
|
69
|
+
void this.events?.emit('rule.eval.start', { ruleId: rule.id, index, total: enabledRules.length });
|
|
70
|
+
let ruleFindings = [];
|
|
71
|
+
let ruleEvalFixes = [];
|
|
72
|
+
try {
|
|
73
|
+
const result = await this.host.evaluators
|
|
74
|
+
.get(rule.evaluator.type)
|
|
75
|
+
.evaluate(rule, { rule, workdir });
|
|
76
|
+
ruleFindings = result.findings;
|
|
77
|
+
ruleEvalFixes = result.fixes;
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
81
|
+
ruleFindings = [
|
|
82
|
+
createFinding(rule, message, null, {
|
|
83
|
+
code: `evaluator:${rule.evaluator.type}`,
|
|
84
|
+
kind: 'error',
|
|
85
|
+
}),
|
|
86
|
+
];
|
|
87
|
+
addSpanEvent('rule.eval.error', { ruleId: rule.id, error: message });
|
|
88
|
+
void this.events?.emit('rule.eval.error', { ruleId: rule.id, error: message });
|
|
89
|
+
}
|
|
90
|
+
const durationMs = Date.now() - evalStartMs;
|
|
91
|
+
addSpanEvent('rule.eval.done', {
|
|
92
|
+
ruleId: rule.id,
|
|
93
|
+
findings: ruleFindings.length,
|
|
94
|
+
durationMs,
|
|
95
|
+
});
|
|
96
|
+
void this.events?.emit('rule.eval.done', {
|
|
97
|
+
ruleId: rule.id,
|
|
98
|
+
findings: ruleFindings.length,
|
|
99
|
+
durationMs,
|
|
100
|
+
});
|
|
101
|
+
findings.push(...ruleFindings);
|
|
102
|
+
fixes.push(...ruleEvalFixes);
|
|
103
|
+
const ruleMode = rule.fix?.mode ?? 'none';
|
|
104
|
+
const effectiveMode = effectiveFixMode(ruleMode, maxFixMode);
|
|
105
|
+
if (effectiveMode !== 'none' && ruleFindings.length > 0) {
|
|
106
|
+
const provider = this.fixers.get(rule.evaluator.type);
|
|
107
|
+
if (provider) {
|
|
108
|
+
const effectiveFix = {
|
|
109
|
+
mode: effectiveMode,
|
|
110
|
+
...(rule.fix?.replacement !== undefined ? { replacement: rule.fix.replacement } : {}),
|
|
111
|
+
...(rule.fix?.params !== undefined ? { params: rule.fix.params } : {}),
|
|
112
|
+
};
|
|
113
|
+
const providerFixes = await provider.createFixes({
|
|
114
|
+
rule,
|
|
115
|
+
context: { rule, workdir },
|
|
116
|
+
findings: ruleFindings,
|
|
117
|
+
fix: effectiveFix,
|
|
118
|
+
});
|
|
119
|
+
fixes.push(...providerFixes);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
if (stopOnFirst &&
|
|
123
|
+
ruleFindings.some((f) => SEVERITY_RANK[f.severity] >= SEVERITY_RANK[stopOnFirst])) {
|
|
124
|
+
stoppedEarlyLocal = true;
|
|
125
|
+
break;
|
|
83
126
|
}
|
|
84
127
|
}
|
|
85
|
-
|
|
86
|
-
|
|
128
|
+
const runDurationMs = Date.now() - runStartMs;
|
|
129
|
+
this.logger.info('rule run done', {
|
|
130
|
+
rules: enabledRules.length,
|
|
131
|
+
findings: findings.length,
|
|
132
|
+
durationMs: runDurationMs,
|
|
133
|
+
stoppedEarly: stoppedEarlyLocal,
|
|
134
|
+
});
|
|
135
|
+
addSpanEvent('rule.run.done', {
|
|
136
|
+
rules: enabledRules.length,
|
|
137
|
+
findings: findings.length,
|
|
138
|
+
durationMs: runDurationMs,
|
|
139
|
+
stoppedEarly: stoppedEarlyLocal,
|
|
140
|
+
});
|
|
141
|
+
void this.events?.emit('rule.run.done', {
|
|
142
|
+
rules: enabledRules.length,
|
|
143
|
+
findings: findings.length,
|
|
144
|
+
durationMs: runDurationMs,
|
|
145
|
+
stoppedEarly: stoppedEarlyLocal,
|
|
146
|
+
});
|
|
147
|
+
return { findings, fixes };
|
|
148
|
+
}, { attributes: { 'rule.count': enabledRules.length } });
|
|
87
149
|
}
|
|
88
150
|
/**
|
|
89
151
|
* Apply or preview candidate byte-range fixes.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-detection-evaluator.d.ts","sourceRoot":"","sources":["../../src/evaluators/agent-detection-evaluator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAA+B,MAAM,yBAAyB,CAAC;AACrF,OAAO,EACH,KAAK,cAAc,EAEnB,KAAK,WAAW,EAChB,KAAK,oBAAoB,EACzB,KAAK,aAAa,EACrB,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"agent-detection-evaluator.d.ts","sourceRoot":"","sources":["../../src/evaluators/agent-detection-evaluator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAA+B,MAAM,yBAAyB,CAAC;AACrF,OAAO,EACH,KAAK,cAAc,EAEnB,KAAK,WAAW,EAChB,KAAK,oBAAoB,EACzB,KAAK,aAAa,EACrB,MAAM,UAAU,CAAC;AAGlB,gEAAgE;AAChE,qBAAa,uBAAwB,YAAW,aAAa;IAC7C,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,gBAAsB;IAE3D,gEAAgE;IAC1D,QAAQ,CAAC,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,WAAW,GAAG,OAAO,CAAC,oBAAoB,CAAC;CAe7F"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { AgentDetector, isAgentName } from '@gobing-ai/ts-ai-runner';
|
|
2
2
|
import { createFinding, } from '../types.js';
|
|
3
|
+
import { configArray } from './file-utils.js';
|
|
3
4
|
/** Evaluates local availability of configured coding agents. */
|
|
4
5
|
export class AgentDetectionEvaluator {
|
|
5
6
|
detector;
|
|
@@ -8,7 +9,7 @@ export class AgentDetectionEvaluator {
|
|
|
8
9
|
}
|
|
9
10
|
/** Probe required agents and emit findings for missing CLIs. */
|
|
10
11
|
async evaluate(rule, _context) {
|
|
11
|
-
const agents =
|
|
12
|
+
const agents = configArray(rule.evaluator.config ?? {}, 'agents', undefined, { evaluator: 'agent-detection' });
|
|
12
13
|
const findings = [];
|
|
13
14
|
for (const agent of agents) {
|
|
14
15
|
if (!isAgentName(agent)) {
|
|
@@ -23,11 +24,3 @@ export class AgentDetectionEvaluator {
|
|
|
23
24
|
return { findings, fixes: [] };
|
|
24
25
|
}
|
|
25
26
|
}
|
|
26
|
-
function arrayConfig(config, key) {
|
|
27
|
-
const value = config[key];
|
|
28
|
-
if (Array.isArray(value) && value.every((item) => typeof item === 'string'))
|
|
29
|
-
return value;
|
|
30
|
-
if (typeof value === 'string')
|
|
31
|
-
return [value];
|
|
32
|
-
throw new Error(`agent-detection evaluator requires string[] config "${key}"`);
|
|
33
|
-
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"coverage-gate-evaluator.d.ts","sourceRoot":"","sources":["../../src/evaluators/coverage-gate-evaluator.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"coverage-gate-evaluator.d.ts","sourceRoot":"","sources":["../../src/evaluators/coverage-gate-evaluator.ts"],"names":[],"mappings":"AACA,OAAO,EACH,KAAK,cAAc,EAEnB,KAAK,WAAW,EAChB,KAAK,oBAAoB,EACzB,KAAK,aAAa,EACrB,MAAM,UAAU,CAAC;AAyBlB;;;;;;;;;;;;GAYG;AACH,qBAAa,qBAAsB,YAAW,aAAa;IACvD,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAiB;;IAMpC,mEAAmE;IAC7D,QAAQ,CAAC,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,oBAAoB,CAAC;CA0C5F"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { NodeFileSystem } from '@gobing-ai/ts-runtime';
|
|
1
|
+
import { isAbsolutePath, NodeFileSystem, relativePath, resolvePath } from '@gobing-ai/ts-runtime';
|
|
3
2
|
import { createFinding, } from '../types.js';
|
|
4
3
|
import { matchesGlob } from './file-utils.js';
|
|
5
4
|
/**
|
|
@@ -24,8 +23,8 @@ export class CoverageGateEvaluator {
|
|
|
24
23
|
async evaluate(rule, context) {
|
|
25
24
|
const config = (rule.evaluator.config ?? {});
|
|
26
25
|
const lcovPath = config.lcovPath
|
|
27
|
-
?
|
|
28
|
-
:
|
|
26
|
+
? resolvePath(context.workdir, config.lcovPath)
|
|
27
|
+
: resolvePath(context.workdir, 'coverage', 'lcov.info');
|
|
29
28
|
if (!(await this.fs.exists(lcovPath))) {
|
|
30
29
|
return {
|
|
31
30
|
findings: [
|
|
@@ -107,6 +106,6 @@ function isAlwaysExcluded(filePath) {
|
|
|
107
106
|
}
|
|
108
107
|
/** Normalize an lcov `SF:` path to a workdir-relative forward-slash path. */
|
|
109
108
|
function normalizeLcovSourcePath(workdir, filePath) {
|
|
110
|
-
const normalized =
|
|
109
|
+
const normalized = isAbsolutePath(filePath) ? relativePath(workdir, filePath) : filePath;
|
|
111
110
|
return normalized.replaceAll('\\', '/');
|
|
112
111
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"exit-code-evaluator.d.ts","sourceRoot":"","sources":["../../src/evaluators/exit-code-evaluator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAClF,OAAO,EACH,KAAK,cAAc,EAEnB,KAAK,WAAW,EAChB,KAAK,oBAAoB,EACzB,KAAK,aAAa,EACrB,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"exit-code-evaluator.d.ts","sourceRoot":"","sources":["../../src/evaluators/exit-code-evaluator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAClF,OAAO,EACH,KAAK,cAAc,EAEnB,KAAK,WAAW,EAChB,KAAK,oBAAoB,EACzB,KAAK,aAAa,EACrB,MAAM,UAAU,CAAC;AAGlB,2EAA2E;AAC3E,qBAAa,iBAAkB,YAAW,aAAa;IACvC,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,GAAE,eAA2C;IAElF,4FAA4F;IACtF,QAAQ,CAAC,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,oBAAoB,CAAC;CA2B5F"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { NodeProcessExecutor } from '@gobing-ai/ts-runtime';
|
|
2
2
|
import { createFinding, } from '../types.js';
|
|
3
|
+
import { configArray, configNumber, configString } from './file-utils.js';
|
|
3
4
|
/** Evaluates a rule by running a subprocess and checking its exit code. */
|
|
4
5
|
export class ExitCodeEvaluator {
|
|
5
6
|
executor;
|
|
@@ -9,10 +10,10 @@ export class ExitCodeEvaluator {
|
|
|
9
10
|
/** Run configured command and emit a finding unless the exit code matches `successCode`. */
|
|
10
11
|
async evaluate(rule, context) {
|
|
11
12
|
const config = rule.evaluator.config ?? {};
|
|
12
|
-
const command =
|
|
13
|
-
const args =
|
|
14
|
-
const successCode =
|
|
15
|
-
const timeout =
|
|
13
|
+
const command = configString(config, 'command', undefined, { evaluator: 'exit-code' });
|
|
14
|
+
const args = configArray(config, 'args', []);
|
|
15
|
+
const successCode = configNumber(config, 'successCode', 0);
|
|
16
|
+
const timeout = configNumber(config, 'timeout', 60_000);
|
|
16
17
|
const result = await this.executor.run({
|
|
17
18
|
command,
|
|
18
19
|
args,
|
|
@@ -23,7 +24,7 @@ export class ExitCodeEvaluator {
|
|
|
23
24
|
});
|
|
24
25
|
if (result.exitCode === successCode)
|
|
25
26
|
return { findings: [], fixes: [] };
|
|
26
|
-
const template =
|
|
27
|
+
const template = configString(config, 'message', `Command failed (exit {code}): ${command} ${args.join(' ')}`.trim());
|
|
27
28
|
const message = template.replaceAll('{code}', String(result.exitCode));
|
|
28
29
|
return {
|
|
29
30
|
findings: [createFinding(rule, message, null, { code: 'exit-code:failed' })],
|
|
@@ -31,21 +32,3 @@ export class ExitCodeEvaluator {
|
|
|
31
32
|
};
|
|
32
33
|
}
|
|
33
34
|
}
|
|
34
|
-
function numberConfig(config, key, fallback) {
|
|
35
|
-
const value = config[key];
|
|
36
|
-
return typeof value === 'number' && Number.isFinite(value) ? value : fallback;
|
|
37
|
-
}
|
|
38
|
-
function stringConfig(config, key, fallback) {
|
|
39
|
-
const value = config[key];
|
|
40
|
-
if (typeof value === 'string')
|
|
41
|
-
return value;
|
|
42
|
-
if (fallback !== undefined)
|
|
43
|
-
return fallback;
|
|
44
|
-
throw new Error(`exit-code evaluator requires string config "${key}"`);
|
|
45
|
-
}
|
|
46
|
-
function arrayConfig(config, key, fallback) {
|
|
47
|
-
const value = config[key];
|
|
48
|
-
if (Array.isArray(value) && value.every((item) => typeof item === 'string'))
|
|
49
|
-
return value;
|
|
50
|
-
return fallback;
|
|
51
|
-
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type FileSystem, NodeFileSystem } from '@gobing-ai/ts-runtime';
|
|
1
|
+
import { type LegacyFileSystem as FileSystem, NodeFileSystem } from '@gobing-ai/ts-runtime';
|
|
2
2
|
/** Options for source-file discovery. */
|
|
3
3
|
export interface SourceDiscoveryOptions {
|
|
4
4
|
/** Working directory. */
|
|
@@ -10,6 +10,12 @@ export interface SourceDiscoveryOptions {
|
|
|
10
10
|
/** Filesystem adapter. */
|
|
11
11
|
fs?: FileSystem;
|
|
12
12
|
}
|
|
13
|
+
/**
|
|
14
|
+
* Directory names pruned from every file walk — heavy or generated trees that no rule
|
|
15
|
+
* should scan. Shared so subprocess-backed evaluators (e.g. `sg`) can forward the same
|
|
16
|
+
* skip-list to the external tool instead of relying on each rule to remember it.
|
|
17
|
+
*/
|
|
18
|
+
export declare const DEFAULT_EXCLUDES: Set<string>;
|
|
13
19
|
/** Resolve source files for evaluators using conservative path-fragment matching. */
|
|
14
20
|
export declare function discoverFiles(options: SourceDiscoveryOptions): Promise<string[]>;
|
|
15
21
|
/** Read a file from a workdir-relative path. */
|
|
@@ -72,6 +78,24 @@ export declare function matchesGlob(path: string, pattern: string): boolean;
|
|
|
72
78
|
export declare function escapeRegExp(value: string): string;
|
|
73
79
|
/** Return the value as a `string[]` when every item is a string, otherwise undefined. */
|
|
74
80
|
export declare function stringArray(value: unknown): string[] | undefined;
|
|
81
|
+
/** Optional accessor context — names the evaluator in "required config" errors for rule authors. */
|
|
82
|
+
export interface ConfigAccessorOptions {
|
|
83
|
+
/** Evaluator name surfaced in the error, e.g. `"regex evaluator requires string config \"pattern\""`. */
|
|
84
|
+
evaluator?: string;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Read a string entry from a rule's evaluator config. Returns the value when it is a string,
|
|
88
|
+
* the `fallback` when one is supplied, otherwise throws — so required keys fail loudly.
|
|
89
|
+
*/
|
|
90
|
+
export declare function configString(config: Record<string, unknown>, key: string, fallback?: string, options?: ConfigAccessorOptions): string;
|
|
91
|
+
/**
|
|
92
|
+
* Read a string-array entry from a rule's evaluator config. A bare string is coerced to a
|
|
93
|
+
* single-element array. Returns the `fallback` when one is supplied and the value is absent;
|
|
94
|
+
* otherwise throws — so required keys fail loudly.
|
|
95
|
+
*/
|
|
96
|
+
export declare function configArray(config: Record<string, unknown>, key: string, fallback?: string[], options?: ConfigAccessorOptions): string[];
|
|
97
|
+
/** Read a finite-number entry from a rule's evaluator config, falling back when absent or invalid. */
|
|
98
|
+
export declare function configNumber(config: Record<string, unknown>, key: string, fallback: number): number;
|
|
75
99
|
/**
|
|
76
100
|
* Split a leading ripgrep/PCRE-style `(?flags)` inline group off a regex source.
|
|
77
101
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-utils.d.ts","sourceRoot":"","sources":["../../src/evaluators/file-utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"file-utils.d.ts","sourceRoot":"","sources":["../../src/evaluators/file-utils.ts"],"names":[],"mappings":"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"}
|