vigiles 38.2.0 → 39.0.0
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/adapters/claude-code/event-capability.js +24 -8
- package/dist/adapters/claude-code/hook-protocol.js +2 -1
- package/dist/adapters/codex/hook-protocol.js +2 -1
- package/dist/cli-flag-check.d.ts +36 -0
- package/dist/cli-flag-check.js +72 -1
- package/dist/cli-main.d.ts +2 -2
- package/dist/cli-main.js +548 -379
- package/dist/core/bash-effects.d.ts +0 -57
- package/dist/core/bash-effects.js +0 -147
- package/dist/core/compile-generator.d.ts +6 -6
- package/dist/core/compile-generator.js +4 -4
- package/dist/core/compile.d.ts +72 -8
- package/dist/core/compile.js +276 -133
- package/dist/core/config-schema.d.ts +40 -10
- package/dist/core/config-schema.js +139 -16
- package/dist/core/coverage.d.ts +16 -0
- package/dist/core/coverage.js +22 -0
- package/dist/core/doc-refs.d.ts +3 -2
- package/dist/core/doc-refs.js +2 -2
- package/dist/core/enforce-marker.d.ts +28 -0
- package/dist/core/enforce-marker.js +34 -0
- package/dist/core/eslint-inventory.d.ts +96 -0
- package/dist/core/eslint-inventory.js +251 -0
- package/dist/core/event-capability.d.ts +5 -1
- package/dist/core/frame.d.ts +43 -2
- package/dist/core/frame.js +85 -2
- package/dist/core/generate-schema.d.ts +3 -2
- package/dist/core/generate-schema.js +2 -2
- package/dist/core/generate-types.d.ts +11 -2
- package/dist/core/generate-types.js +12 -5
- package/dist/core/hook-command.d.ts +172 -0
- package/dist/core/hook-command.js +277 -0
- package/dist/core/hook-delivery.d.ts +133 -0
- package/dist/core/hook-delivery.js +150 -0
- package/dist/core/hook-paths.d.ts +14 -0
- package/dist/core/hook-paths.js +22 -0
- package/dist/core/hook-program.d.ts +4 -4
- package/dist/core/hook-program.js +13 -25
- package/dist/core/hook-state.d.ts +1 -1
- package/dist/core/hook-state.js +1 -1
- package/dist/core/instruction-remedies.d.ts +35 -0
- package/dist/core/instruction-remedies.js +70 -1
- package/dist/core/integrity-header.d.ts +54 -0
- package/dist/core/integrity-header.js +90 -0
- package/dist/core/integrity.d.ts +1 -25
- package/dist/core/integrity.js +16 -74
- package/dist/core/linter-adapter.d.ts +27 -3
- package/dist/core/linters.d.ts +8 -1
- package/dist/core/linters.js +116 -81
- package/dist/core/orphans.d.ts +3 -5
- package/dist/core/orphans.js +9 -10
- package/dist/core/presets.d.ts +19 -7
- package/dist/core/presets.js +19 -6
- package/dist/core/rule-catalog.d.ts +11 -12
- package/dist/core/rule-catalog.js +25 -94
- package/dist/core/rule-meta.d.ts +12 -0
- package/dist/core/rule-meta.js +47 -10
- package/dist/core/source-refs.d.ts +3 -23
- package/dist/core/source-refs.js +3 -27
- package/dist/core/test-utils.d.ts +13 -0
- package/dist/core/test-utils.js +40 -1
- package/dist/core/types.d.ts +18 -26
- package/dist/core/validate.d.ts +1 -2
- package/dist/core/validate.js +60 -47
- package/dist/coverage-evidence.js +2 -3
- package/dist/deprecated-key-files.d.ts +6 -0
- package/dist/deprecated-key-files.js +7 -6
- package/dist/exclude.d.ts +3 -1
- package/dist/exclude.js +9 -33
- package/dist/harness-assert.d.ts +18 -0
- package/dist/harness-assert.js +38 -0
- package/dist/hook-check-install.js +15 -6
- package/dist/hook-check.d.ts +1 -3
- package/dist/hook-check.js +3 -5
- package/dist/hook-install.d.ts +7 -41
- package/dist/hook-install.js +29 -96
- package/dist/hook-runtime.js +2 -1
- package/dist/load-hook.d.ts +3 -2
- package/dist/load-hook.js +28 -6
- package/dist/overrides.d.ts +25 -0
- package/dist/overrides.js +51 -0
- package/dist/plugin-loader.d.ts +23 -0
- package/dist/plugin-loader.js +42 -12
- package/dist/root-globs.d.ts +9 -0
- package/dist/root-globs.js +48 -0
- package/dist/rule-routing.js +6 -3
- package/dist/run-hook.d.ts +26 -2
- package/dist/run-hook.js +48 -12
- package/dist/scan-core.d.ts +96 -20
- package/dist/scan-core.js +171 -176
- package/dist/scan-files.d.ts +0 -8
- package/dist/scan-files.js +78 -20
- package/dist/scan.d.ts +12 -12
- package/dist/scan.js +33 -10
- package/dist/setup-plan.d.ts +15 -9
- package/dist/setup-plan.js +26 -18
- package/dist/test-coverage.d.ts +3 -8
- package/dist/test-coverage.js +6 -6
- package/dist/test.d.ts +1 -1
- package/dist/vigilesrc.schema.json +1329 -118
- package/package.json +1 -1
- package/skills/adopt-spec/SKILL.md +2 -1
|
@@ -42,6 +42,8 @@
|
|
|
42
42
|
* requires, against which 45 ms is ~13%.
|
|
43
43
|
*/
|
|
44
44
|
import { z } from "zod";
|
|
45
|
+
/** The config file; the directory holding it is a project root. */
|
|
46
|
+
export declare const PROJECT_CONFIG_FILE = ".vigilesrc.json";
|
|
45
47
|
/** The rule names, for the "did you mean" on an unknown one. */
|
|
46
48
|
export declare const RULE_NAMES: readonly string[];
|
|
47
49
|
/**
|
|
@@ -84,38 +86,30 @@ export declare const vigilesConfigSchema: z.ZodObject<{
|
|
|
84
86
|
}, z.core.$strict>], null>]>>;
|
|
85
87
|
"untested-skill": z.ZodDefault<z.ZodUnion<readonly [z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "error" | "warn", boolean | 0 | 1 | 2 | "error" | "warn" | "off">>, z.ZodTuple<[z.ZodLiteral<"warn">, z.ZodObject<{
|
|
86
88
|
include: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>, z.ZodTransform<readonly string[], string | string[]>>>;
|
|
87
|
-
exclude: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>, z.ZodTransform<readonly string[], string | string[]>>>;
|
|
88
89
|
testExtension: z.ZodOptional<z.ZodString>;
|
|
89
90
|
}, z.core.$strict>], null>, z.ZodTuple<[z.ZodLiteral<"error">, z.ZodObject<{
|
|
90
91
|
include: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>, z.ZodTransform<readonly string[], string | string[]>>>;
|
|
91
|
-
exclude: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>, z.ZodTransform<readonly string[], string | string[]>>>;
|
|
92
92
|
testExtension: z.ZodOptional<z.ZodString>;
|
|
93
93
|
}, z.core.$strict>], null>]>>;
|
|
94
94
|
"untested-subagent": z.ZodDefault<z.ZodUnion<readonly [z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "error" | "warn", boolean | 0 | 1 | 2 | "error" | "warn" | "off">>, z.ZodTuple<[z.ZodLiteral<"warn">, z.ZodObject<{
|
|
95
95
|
include: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>, z.ZodTransform<readonly string[], string | string[]>>>;
|
|
96
|
-
exclude: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>, z.ZodTransform<readonly string[], string | string[]>>>;
|
|
97
96
|
testExtension: z.ZodOptional<z.ZodString>;
|
|
98
97
|
}, z.core.$strict>], null>, z.ZodTuple<[z.ZodLiteral<"error">, z.ZodObject<{
|
|
99
98
|
include: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>, z.ZodTransform<readonly string[], string | string[]>>>;
|
|
100
|
-
exclude: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>, z.ZodTransform<readonly string[], string | string[]>>>;
|
|
101
99
|
testExtension: z.ZodOptional<z.ZodString>;
|
|
102
100
|
}, z.core.$strict>], null>]>>;
|
|
103
101
|
"untested-hook": z.ZodDefault<z.ZodUnion<readonly [z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "error" | "warn", boolean | 0 | 1 | 2 | "error" | "warn" | "off">>, z.ZodTuple<[z.ZodLiteral<"warn">, z.ZodObject<{
|
|
104
102
|
include: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>, z.ZodTransform<readonly string[], string | string[]>>>;
|
|
105
|
-
exclude: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>, z.ZodTransform<readonly string[], string | string[]>>>;
|
|
106
103
|
testExtension: z.ZodOptional<z.ZodString>;
|
|
107
104
|
}, z.core.$strict>], null>, z.ZodTuple<[z.ZodLiteral<"error">, z.ZodObject<{
|
|
108
105
|
include: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>, z.ZodTransform<readonly string[], string | string[]>>>;
|
|
109
|
-
exclude: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>, z.ZodTransform<readonly string[], string | string[]>>>;
|
|
110
106
|
testExtension: z.ZodOptional<z.ZodString>;
|
|
111
107
|
}, z.core.$strict>], null>]>>;
|
|
112
108
|
"untested-output-style": z.ZodDefault<z.ZodUnion<readonly [z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "error" | "warn", boolean | 0 | 1 | 2 | "error" | "warn" | "off">>, z.ZodTuple<[z.ZodLiteral<"warn">, z.ZodObject<{
|
|
113
109
|
include: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>, z.ZodTransform<readonly string[], string | string[]>>>;
|
|
114
|
-
exclude: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>, z.ZodTransform<readonly string[], string | string[]>>>;
|
|
115
110
|
testExtension: z.ZodOptional<z.ZodString>;
|
|
116
111
|
}, z.core.$strict>], null>, z.ZodTuple<[z.ZodLiteral<"error">, z.ZodObject<{
|
|
117
112
|
include: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>, z.ZodTransform<readonly string[], string | string[]>>>;
|
|
118
|
-
exclude: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>, z.ZodTransform<readonly string[], string | string[]>>>;
|
|
119
113
|
testExtension: z.ZodOptional<z.ZodString>;
|
|
120
114
|
}, z.core.$strict>], null>]>>;
|
|
121
115
|
"unmarked-refs": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "error" | "warn", boolean | 0 | 1 | 2 | "error" | "warn" | "off">>>;
|
|
@@ -126,7 +120,7 @@ export declare const vigilesConfigSchema: z.ZodObject<{
|
|
|
126
120
|
"skill-frontmatter": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "error" | "warn", boolean | 0 | 1 | 2 | "error" | "warn" | "off">>>;
|
|
127
121
|
"mcp-tool-resolves": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "error" | "warn", boolean | 0 | 1 | 2 | "error" | "warn" | "off">>>;
|
|
128
122
|
"hook-script-exists": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "error" | "warn", boolean | 0 | 1 | 2 | "error" | "warn" | "off">>>;
|
|
129
|
-
"
|
|
123
|
+
"hand-written-hook": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "error" | "warn", boolean | 0 | 1 | 2 | "error" | "warn" | "off">>>;
|
|
130
124
|
"disallowed-tools-contract": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "error" | "warn", boolean | 0 | 1 | 2 | "error" | "warn" | "off">>>;
|
|
131
125
|
"description-overlap": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "error" | "warn", boolean | 0 | 1 | 2 | "error" | "warn" | "off">>>;
|
|
132
126
|
"skill-description-budget": z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "error" | "warn", boolean | 0 | 1 | 2 | "error" | "warn" | "off">>>;
|
|
@@ -170,9 +164,14 @@ export declare const vigilesConfigSchema: z.ZodObject<{
|
|
|
170
164
|
}>>;
|
|
171
165
|
orphans: z.ZodOptional<z.ZodObject<{
|
|
172
166
|
include: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>, z.ZodTransform<readonly string[], string | string[]>>>;
|
|
173
|
-
exclude: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>, z.ZodTransform<readonly string[], string | string[]>>>;
|
|
174
167
|
}, z.core.$strict>>;
|
|
175
168
|
exclude: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>, z.ZodTransform<readonly string[], string | string[]>>>;
|
|
169
|
+
overrides: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
170
|
+
files: z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>, z.ZodTransform<readonly string[], string | string[]>>;
|
|
171
|
+
rules: z.ZodObject<{
|
|
172
|
+
[x: string]: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"warn">, z.ZodLiteral<"error">, z.ZodLiteral<false>, z.ZodLiteral<"off">, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<true>]>, z.ZodTransform<false | "error" | "warn", boolean | 0 | 1 | 2 | "error" | "warn" | "off">>>;
|
|
173
|
+
}, z.core.$strict>;
|
|
174
|
+
}, z.core.$strict>>>;
|
|
176
175
|
sharedDirs: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>, z.ZodTransform<readonly string[], string | string[]>>>;
|
|
177
176
|
harnesses: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
178
177
|
roots: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>, z.ZodTransform<readonly string[], string | string[]>>>;
|
|
@@ -253,6 +252,37 @@ export declare const REPLACED_KEYS: ReadonlyArray<{
|
|
|
253
252
|
* it shows the reader their own keys instead of somebody else's.
|
|
254
253
|
*/
|
|
255
254
|
export declare function replacedKeyMessage(present: ReadonlyArray<(typeof REPLACED_KEYS)[number]>, names: readonly string[]): string;
|
|
255
|
+
/**
|
|
256
|
+
* The per-rule `exclude` options that became `overrides`, and the rules an
|
|
257
|
+
* equivalent override turns off. `untested-*` shared ONE merged option set, so
|
|
258
|
+
* an `exclude` on any of them skipped those paths for all four.
|
|
259
|
+
*/
|
|
260
|
+
export declare const MOVED_TO_OVERRIDES: ReadonlyArray<{
|
|
261
|
+
/** Where the option sat: a rule name, or the `orphans` block. */
|
|
262
|
+
readonly owner: string;
|
|
263
|
+
/** The rules the equivalent override turns off. */
|
|
264
|
+
readonly rules: readonly string[];
|
|
265
|
+
}>;
|
|
266
|
+
/**
|
|
267
|
+
* The message an old config with a per-rule `exclude` gets — the user's OWN
|
|
268
|
+
* globs, written as the `overrides` entry that does what the option did.
|
|
269
|
+
*
|
|
270
|
+
* Read BEFORE the schema, like {@link REPLACED_KEYS}: the reader's config used
|
|
271
|
+
* to work, so "unknown key exclude" would be true and useless.
|
|
272
|
+
*/
|
|
273
|
+
export declare function movedToOverridesMessages(raw: unknown): readonly string[];
|
|
274
|
+
/** Rules whose findings another rule now reports, and what changed. */
|
|
275
|
+
export declare const FOLDED_RULES: ReadonlyArray<{
|
|
276
|
+
readonly rule: string;
|
|
277
|
+
readonly into: string;
|
|
278
|
+
readonly what: string;
|
|
279
|
+
}>;
|
|
280
|
+
/**
|
|
281
|
+
* The message a config naming a folded rule gets — in `rules` or in an
|
|
282
|
+
* `overrides` entry. Read BEFORE the schema, like {@link REPLACED_KEYS}: the
|
|
283
|
+
* reader's config used to work, so "unknown key" would be true and useless.
|
|
284
|
+
*/
|
|
285
|
+
export declare function foldedRuleMessages(raw: unknown): readonly string[];
|
|
256
286
|
/**
|
|
257
287
|
* Turn a Zod failure into the lines a human acts on — ONE per real problem.
|
|
258
288
|
*
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.REPLACED_KEYS = exports.VigilesConfigError = exports.vigilesConfigSchema = exports.RULE_NAMES = void 0;
|
|
3
|
+
exports.FOLDED_RULES = exports.MOVED_TO_OVERRIDES = exports.REPLACED_KEYS = exports.VigilesConfigError = exports.vigilesConfigSchema = exports.RULE_NAMES = exports.PROJECT_CONFIG_FILE = void 0;
|
|
4
4
|
exports.parseVigilesConfig = parseVigilesConfig;
|
|
5
5
|
exports.replacedKeyMessage = replacedKeyMessage;
|
|
6
|
+
exports.movedToOverridesMessages = movedToOverridesMessages;
|
|
7
|
+
exports.foldedRuleMessages = foldedRuleMessages;
|
|
6
8
|
exports.formatConfigIssues = formatConfigIssues;
|
|
7
9
|
/**
|
|
8
10
|
* `.vigilesrc.json`, AS A SCHEMA — the one place the config's shape, its
|
|
@@ -50,6 +52,8 @@ exports.formatConfigIssues = formatConfigIssues;
|
|
|
50
52
|
const zod_1 = require("zod");
|
|
51
53
|
const edit_distance_js_1 = require("./edit-distance.js");
|
|
52
54
|
const presets_js_1 = require("./presets.js");
|
|
55
|
+
/** The config file; the directory holding it is a project root. */
|
|
56
|
+
exports.PROJECT_CONFIG_FILE = ".vigilesrc.json";
|
|
53
57
|
// ---------------------------------------------------------------------------
|
|
54
58
|
// Primitives
|
|
55
59
|
// ---------------------------------------------------------------------------
|
|
@@ -114,11 +118,14 @@ const coverageThresholds = zod_1.z
|
|
|
114
118
|
scripts: zod_1.z.number().optional(),
|
|
115
119
|
})
|
|
116
120
|
.strict();
|
|
117
|
-
/**
|
|
121
|
+
/**
|
|
122
|
+
* Discovery options shared by the `untested-*` rules. `include` is where tests
|
|
123
|
+
* live — a real option of the rule. Skipping paths is not: that is `overrides`
|
|
124
|
+
* with the rule off (see {@link MOVED_TO_OVERRIDES}).
|
|
125
|
+
*/
|
|
118
126
|
const testCoverageConfig = zod_1.z
|
|
119
127
|
.object({
|
|
120
128
|
include: stringList.optional(),
|
|
121
|
-
exclude: stringList.optional(),
|
|
122
129
|
testExtension: zod_1.z.string().optional(),
|
|
123
130
|
})
|
|
124
131
|
.strict();
|
|
@@ -177,7 +184,8 @@ const rulesSchema = zod_1.z
|
|
|
177
184
|
"skill-frontmatter": severitySchema.default("warn"),
|
|
178
185
|
"mcp-tool-resolves": severitySchema.default("warn"),
|
|
179
186
|
"hook-script-exists": severitySchema.default("warn"),
|
|
180
|
-
|
|
187
|
+
// OFF: its only cure is a compiled hook, an experimental API (docs/experimental.md).
|
|
188
|
+
"hand-written-hook": severitySchema.default(false),
|
|
181
189
|
"disallowed-tools-contract": severitySchema.default("warn"),
|
|
182
190
|
"description-overlap": severitySchema.default("warn"),
|
|
183
191
|
"skill-description-budget": severitySchema.default("warn"),
|
|
@@ -199,6 +207,35 @@ const rulesSchema = zod_1.z
|
|
|
199
207
|
/** The rule names, for the "did you mean" on an unknown one. */
|
|
200
208
|
exports.RULE_NAMES = Object.keys(rulesSchema.shape);
|
|
201
209
|
// ---------------------------------------------------------------------------
|
|
210
|
+
// Overrides — per-path severities (`./overrides.ts`)
|
|
211
|
+
// ---------------------------------------------------------------------------
|
|
212
|
+
/**
|
|
213
|
+
* The rule set as an override may spell it: every rule, a SEVERITY only, no
|
|
214
|
+
* default. Options stay in `rules` — one place — so `["error", { … }]` here is
|
|
215
|
+
* refused rather than accepted and never read. Derived from `rulesSchema`'s
|
|
216
|
+
* keys, so a rule added there is overridable with no second list, and an
|
|
217
|
+
* unknown name gets the same "did you mean" as in `rules`.
|
|
218
|
+
*/
|
|
219
|
+
const overrideRulesSchema = zod_1.z
|
|
220
|
+
.object(Object.fromEntries(Object.keys(rulesSchema.shape).map((name) => [
|
|
221
|
+
name,
|
|
222
|
+
severitySchema.optional(),
|
|
223
|
+
])))
|
|
224
|
+
.strict();
|
|
225
|
+
/**
|
|
226
|
+
* One `overrides` entry. `files` are root-relative globs with top-level
|
|
227
|
+
* `exclude`'s semantics; an entry with none would apply nowhere, so it is
|
|
228
|
+
* refused rather than kept as a line that does nothing.
|
|
229
|
+
*/
|
|
230
|
+
const overrideSchema = zod_1.z
|
|
231
|
+
.object({
|
|
232
|
+
files: stringList.refine((globs) => globs.length > 0, {
|
|
233
|
+
message: "needs at least one glob",
|
|
234
|
+
}),
|
|
235
|
+
rules: overrideRulesSchema,
|
|
236
|
+
})
|
|
237
|
+
.strict();
|
|
238
|
+
// ---------------------------------------------------------------------------
|
|
202
239
|
// Harnesses (#240)
|
|
203
240
|
// ---------------------------------------------------------------------------
|
|
204
241
|
/**
|
|
@@ -251,11 +288,16 @@ exports.vigilesConfigSchema = zod_1.z
|
|
|
251
288
|
orphans: zod_1.z
|
|
252
289
|
.object({
|
|
253
290
|
include: stringList.optional(),
|
|
254
|
-
exclude: stringList.optional(),
|
|
255
291
|
})
|
|
256
292
|
.strict()
|
|
257
293
|
.optional(),
|
|
258
294
|
exclude: stringList.optional(),
|
|
295
|
+
/**
|
|
296
|
+
* Per-path rule severities, ESLint's `{ files, rules }` list: a later entry
|
|
297
|
+
* wins over an earlier one, any entry over `rules`, `rules` over `extends`.
|
|
298
|
+
* Resolved by `ruleResolver` (`./overrides.ts`).
|
|
299
|
+
*/
|
|
300
|
+
overrides: zod_1.z.array(overrideSchema).optional(),
|
|
259
301
|
sharedDirs: stringList.optional(),
|
|
260
302
|
harnesses: zod_1.z.record(zod_1.z.string(), harnessDeclarationSchema).optional(),
|
|
261
303
|
audit: zod_1.z.object({ measure: zod_1.z.boolean().optional() }).strict().optional(),
|
|
@@ -396,6 +438,83 @@ function replacedKeyMessage(present, names) {
|
|
|
396
438
|
`skills and read no instruction file, the other read the instruction file and found no ` +
|
|
397
439
|
`skills. Scoping each root under the harness that reads it removes the order.`);
|
|
398
440
|
}
|
|
441
|
+
/**
|
|
442
|
+
* The per-rule `exclude` options that became `overrides`, and the rules an
|
|
443
|
+
* equivalent override turns off. `untested-*` shared ONE merged option set, so
|
|
444
|
+
* an `exclude` on any of them skipped those paths for all four.
|
|
445
|
+
*/
|
|
446
|
+
exports.MOVED_TO_OVERRIDES = [
|
|
447
|
+
...[
|
|
448
|
+
"untested-skill",
|
|
449
|
+
"untested-subagent",
|
|
450
|
+
"untested-hook",
|
|
451
|
+
"untested-output-style",
|
|
452
|
+
].map((owner, _i, all) => ({ owner, rules: all })),
|
|
453
|
+
{ owner: "orphans", rules: ["orphan-docs"] },
|
|
454
|
+
];
|
|
455
|
+
/** A plain JSON object, narrowed without a cast. */
|
|
456
|
+
function isRecord(v) {
|
|
457
|
+
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
458
|
+
}
|
|
459
|
+
/** The `exclude` an old config wrote under `owner`, as a glob list, if any. */
|
|
460
|
+
function movedExclude(raw, owner) {
|
|
461
|
+
if (!isRecord(raw))
|
|
462
|
+
return null;
|
|
463
|
+
const value = isRecord(raw.rules) ? raw.rules[owner] : undefined;
|
|
464
|
+
const tuple = Array.isArray(value) ? value : [];
|
|
465
|
+
const holder = owner === "orphans" ? raw.orphans : tuple[1];
|
|
466
|
+
if (!isRecord(holder) || holder.exclude === undefined)
|
|
467
|
+
return null;
|
|
468
|
+
const globs = [holder.exclude].flat();
|
|
469
|
+
return globs.filter((g) => typeof g === "string");
|
|
470
|
+
}
|
|
471
|
+
/**
|
|
472
|
+
* The message an old config with a per-rule `exclude` gets — the user's OWN
|
|
473
|
+
* globs, written as the `overrides` entry that does what the option did.
|
|
474
|
+
*
|
|
475
|
+
* Read BEFORE the schema, like {@link REPLACED_KEYS}: the reader's config used
|
|
476
|
+
* to work, so "unknown key exclude" would be true and useless.
|
|
477
|
+
*/
|
|
478
|
+
function movedToOverridesMessages(raw) {
|
|
479
|
+
return exports.MOVED_TO_OVERRIDES.flatMap(({ owner, rules }) => {
|
|
480
|
+
const globs = movedExclude(raw, owner);
|
|
481
|
+
if (globs === null)
|
|
482
|
+
return [];
|
|
483
|
+
const files = globs.map((g) => JSON.stringify(g)).join(", ");
|
|
484
|
+
const off = rules.map((r) => `"${r}": "off"`).join(", ");
|
|
485
|
+
return [
|
|
486
|
+
`.vigilesrc.json: "exclude" inside "${owner}" moved to "overrides" — skipping paths is not a rule option any more; an override turns the rule off for them.\n` +
|
|
487
|
+
` Write: "overrides": [{ "files": [${files}], "rules": { ${off} } }]\n` +
|
|
488
|
+
` and remove "exclude" from "${owner}". Paths top-level "exclude" removes are not read at all; an override only changes what a rule reports.`,
|
|
489
|
+
];
|
|
490
|
+
});
|
|
491
|
+
}
|
|
492
|
+
/** Rules whose findings another rule now reports, and what changed. */
|
|
493
|
+
exports.FOLDED_RULES = [
|
|
494
|
+
{
|
|
495
|
+
rule: "prefer-compiled-hooks",
|
|
496
|
+
into: "hand-written-hook",
|
|
497
|
+
what: "every hook line vigiles did not write is now one hand-written-hook finding that names it",
|
|
498
|
+
},
|
|
499
|
+
];
|
|
500
|
+
/**
|
|
501
|
+
* The message a config naming a folded rule gets — in `rules` or in an
|
|
502
|
+
* `overrides` entry. Read BEFORE the schema, like {@link REPLACED_KEYS}: the
|
|
503
|
+
* reader's config used to work, so "unknown key" would be true and useless.
|
|
504
|
+
*/
|
|
505
|
+
function foldedRuleMessages(raw) {
|
|
506
|
+
if (!isRecord(raw))
|
|
507
|
+
return [];
|
|
508
|
+
const overrides = Array.isArray(raw.overrides)
|
|
509
|
+
? raw.overrides
|
|
510
|
+
: [];
|
|
511
|
+
const ruleBlocks = [
|
|
512
|
+
raw.rules,
|
|
513
|
+
...overrides.map((o) => (isRecord(o) ? o.rules : undefined)),
|
|
514
|
+
];
|
|
515
|
+
return exports.FOLDED_RULES.filter(({ rule }) => ruleBlocks.some((b) => isRecord(b) && rule in b)).map(({ rule, into, what }) => `.vigilesrc.json: rule "${rule}" was folded into "${into}": ${what}.\n` +
|
|
516
|
+
` Remove "${rule}"; set "${into}" to change how those findings report.`);
|
|
517
|
+
}
|
|
399
518
|
// ---------------------------------------------------------------------------
|
|
400
519
|
// Messages — the half a schema library does NOT give you
|
|
401
520
|
// ---------------------------------------------------------------------------
|
|
@@ -412,17 +531,7 @@ function replacedKeyMessage(present, names) {
|
|
|
412
531
|
function knownKeysAt(path) {
|
|
413
532
|
let node = exports.vigilesConfigSchema;
|
|
414
533
|
for (const seg of path) {
|
|
415
|
-
|
|
416
|
-
?.def;
|
|
417
|
-
if (def?.type === "object") {
|
|
418
|
-
node = def.shape?.[String(seg)];
|
|
419
|
-
}
|
|
420
|
-
else if (def?.type === "record") {
|
|
421
|
-
node = def.valueType;
|
|
422
|
-
}
|
|
423
|
-
else {
|
|
424
|
-
return [];
|
|
425
|
-
}
|
|
534
|
+
node = childAt(node, seg);
|
|
426
535
|
if (node === undefined)
|
|
427
536
|
return [];
|
|
428
537
|
node = unwrap(node);
|
|
@@ -432,6 +541,20 @@ function knownKeysAt(path) {
|
|
|
432
541
|
? Object.keys(def.shape)
|
|
433
542
|
: [];
|
|
434
543
|
}
|
|
544
|
+
/**
|
|
545
|
+
* One step down a schema node: an object's field `seg`, an array's element, a
|
|
546
|
+
* record's value. `undefined` where the node has no child to step into.
|
|
547
|
+
*/
|
|
548
|
+
function childAt(node, seg) {
|
|
549
|
+
const def = node._zod?.def;
|
|
550
|
+
if (def?.type === "object")
|
|
551
|
+
return def.shape?.[String(seg)];
|
|
552
|
+
if (def?.type === "array")
|
|
553
|
+
return def.element;
|
|
554
|
+
if (def?.type === "record")
|
|
555
|
+
return def.valueType;
|
|
556
|
+
return undefined;
|
|
557
|
+
}
|
|
435
558
|
/** Peel `.optional()` / `.default()` / `.prefault()` wrappers off a schema node. */
|
|
436
559
|
function unwrap(node) {
|
|
437
560
|
let cur = node;
|
package/dist/core/coverage.d.ts
CHANGED
|
@@ -54,4 +54,20 @@ export declare function checkCoverage(basePath: string, thresholds: CoverageThre
|
|
|
54
54
|
* Format coverage report as human-readable text.
|
|
55
55
|
*/
|
|
56
56
|
export declare function formatCoverageReport(report: CoverageReport): string;
|
|
57
|
+
/**
|
|
58
|
+
* What `vigiles lint` says under the linter-rule coverage line when some enabled
|
|
59
|
+
* rules are undocumented. Empty when nothing is.
|
|
60
|
+
*
|
|
61
|
+
* 🔴 IT MUST NOT TELL ANYONE TO WRITE MORE INTO THE INSTRUCTION FILE. This used
|
|
62
|
+
* to read "Consider adding enforce() rules for frequently-triggered undocumented
|
|
63
|
+
* rules", which turns a coverage percentage into a to-do list for CLAUDE.md —
|
|
64
|
+
* the one file whose every line is loaded into every request and every subagent.
|
|
65
|
+
* An enabled linter rule is already enforced: the agent meets it as a failing
|
|
66
|
+
* lint with the rule's own message. Documentation only earns its place where the
|
|
67
|
+
* WHY is not in that message, and then it belongs where it is read on demand.
|
|
68
|
+
*/
|
|
69
|
+
export declare function undocumentedRulesAdvice(totals: Readonly<{
|
|
70
|
+
enabled: number;
|
|
71
|
+
documented: number;
|
|
72
|
+
}>): readonly string[];
|
|
57
73
|
//# sourceMappingURL=coverage.d.ts.map
|
package/dist/core/coverage.js
CHANGED
|
@@ -16,6 +16,7 @@ exports.computeScriptCoverage = computeScriptCoverage;
|
|
|
16
16
|
exports.computeLinterRuleCoverage = computeLinterRuleCoverage;
|
|
17
17
|
exports.checkCoverage = checkCoverage;
|
|
18
18
|
exports.formatCoverageReport = formatCoverageReport;
|
|
19
|
+
exports.undocumentedRulesAdvice = undocumentedRulesAdvice;
|
|
19
20
|
const node_fs_1 = require("node:fs");
|
|
20
21
|
const integrity_js_1 = require("./integrity.js");
|
|
21
22
|
const node_path_1 = require("node:path");
|
|
@@ -183,4 +184,25 @@ function formatCoverageReport(report) {
|
|
|
183
184
|
}
|
|
184
185
|
return lines.join("\n");
|
|
185
186
|
}
|
|
187
|
+
/**
|
|
188
|
+
* What `vigiles lint` says under the linter-rule coverage line when some enabled
|
|
189
|
+
* rules are undocumented. Empty when nothing is.
|
|
190
|
+
*
|
|
191
|
+
* 🔴 IT MUST NOT TELL ANYONE TO WRITE MORE INTO THE INSTRUCTION FILE. This used
|
|
192
|
+
* to read "Consider adding enforce() rules for frequently-triggered undocumented
|
|
193
|
+
* rules", which turns a coverage percentage into a to-do list for CLAUDE.md —
|
|
194
|
+
* the one file whose every line is loaded into every request and every subagent.
|
|
195
|
+
* An enabled linter rule is already enforced: the agent meets it as a failing
|
|
196
|
+
* lint with the rule's own message. Documentation only earns its place where the
|
|
197
|
+
* WHY is not in that message, and then it belongs where it is read on demand.
|
|
198
|
+
*/
|
|
199
|
+
function undocumentedRulesAdvice(totals) {
|
|
200
|
+
if (totals.documented >= totals.enabled)
|
|
201
|
+
return [];
|
|
202
|
+
return [
|
|
203
|
+
"Undocumented is not unenforced: the linter already enforces these rules, and the agent meets each one as a lint failure.",
|
|
204
|
+
"Every line added to CLAUDE.md is loaded into every request, so do not document a rule just to raise this number.",
|
|
205
|
+
"Where the WHY is not obvious from the rule's own message, put it in docs/ (linked, read on demand) or declare the rule with enforce() in the spec, which also verifies it stays enabled.",
|
|
206
|
+
];
|
|
207
|
+
}
|
|
186
208
|
//# sourceMappingURL=coverage.js.map
|
package/dist/core/doc-refs.d.ts
CHANGED
|
@@ -40,7 +40,8 @@ export interface DocRefReport {
|
|
|
40
40
|
readonly placeholders: number;
|
|
41
41
|
}
|
|
42
42
|
export interface FindDocRefsOptions {
|
|
43
|
-
|
|
43
|
+
/** The repo root. Required: no cwd fallback. */
|
|
44
|
+
readonly basePath: string;
|
|
44
45
|
/** The repo exclude (`ExcludeSet.globIgnore`), or patterns relative to `basePath`. */
|
|
45
46
|
readonly ignore?: GlobIgnore;
|
|
46
47
|
}
|
|
@@ -55,7 +56,7 @@ interface ExtractResult {
|
|
|
55
56
|
* spec.ts. Honors `<!-- vigiles:ignore-file -->` (skip the whole file)
|
|
56
57
|
* and `<!-- vigiles:ignore -->` (skip the next code block).
|
|
57
58
|
*/
|
|
58
|
-
export declare function findDocRefs(options
|
|
59
|
+
export declare function findDocRefs(options: FindDocRefsOptions): DocRefReport;
|
|
59
60
|
/** Format a DocRefReport as human-readable text. */
|
|
60
61
|
export declare function formatDocRefReport(report: DocRefReport,
|
|
61
62
|
/**
|
package/dist/core/doc-refs.js
CHANGED
|
@@ -238,8 +238,8 @@ function validateRefs(refs, basePath) {
|
|
|
238
238
|
* spec.ts. Honors `<!-- vigiles:ignore-file -->` (skip the whole file)
|
|
239
239
|
* and `<!-- vigiles:ignore -->` (skip the next code block).
|
|
240
240
|
*/
|
|
241
|
-
function findDocRefs(options
|
|
242
|
-
const basePath = options.basePath
|
|
241
|
+
function findDocRefs(options) {
|
|
242
|
+
const basePath = options.basePath;
|
|
243
243
|
const ignore = (0, glob_ignore_js_1.withIgnored)(DEFAULT_IGNORE, options.ignore);
|
|
244
244
|
const files = (0, glob_1.globSync)("**/*.md", { cwd: basePath, ignore });
|
|
245
245
|
const allRefs = [];
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The two ways a compiled instruction file can state an `enforce()` reference,
|
|
3
|
+
* spelled in ONE place so the renderer and every reader agree (#351).
|
|
4
|
+
*
|
|
5
|
+
* "**Enforced by:**" is the product's promise that a machine holds the rule, so
|
|
6
|
+
* `compile` writes it only for a reference it VERIFIED: the rule exists in the
|
|
7
|
+
* linter's catalog and the project's config switches it on. Anything less — the
|
|
8
|
+
* check was turned off (`verify: false`, `verifyLinters: false`, a per-linter
|
|
9
|
+
* `false`, catalog-only), the config does not set the rule, or the config could
|
|
10
|
+
* not be read — renders as "**Claimed (unverified):**". A reader of the compiled
|
|
11
|
+
* file can then tell the two apart without the compile log.
|
|
12
|
+
*
|
|
13
|
+
* Zero imports: `validate.ts`, `rule-routing.ts` and the CLI read these markers
|
|
14
|
+
* too, and some of them are browser-safe.
|
|
15
|
+
*/
|
|
16
|
+
/** A reference `compile` verified: exists, and the project's config runs it. */
|
|
17
|
+
export declare const ENFORCED_MARKER = "**Enforced by:**";
|
|
18
|
+
/** A reference `compile` did not or could not verify. */
|
|
19
|
+
export declare const CLAIMED_MARKER = "**Claimed (unverified):**";
|
|
20
|
+
/**
|
|
21
|
+
* Either marker followed by its backticked reference, anywhere in a line.
|
|
22
|
+
* Group 1 is the marker's label (`Enforced by` / `Claimed (unverified)`),
|
|
23
|
+
* group 2 the reference.
|
|
24
|
+
*/
|
|
25
|
+
export declare const RULE_MARKER_SOURCE: string;
|
|
26
|
+
/** Is the label captured by {@link RULE_MARKER_SOURCE} the verified one? */
|
|
27
|
+
export declare function isVerifiedLabel(label: string): boolean;
|
|
28
|
+
//# sourceMappingURL=enforce-marker.d.ts.map
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* The two ways a compiled instruction file can state an `enforce()` reference,
|
|
4
|
+
* spelled in ONE place so the renderer and every reader agree (#351).
|
|
5
|
+
*
|
|
6
|
+
* "**Enforced by:**" is the product's promise that a machine holds the rule, so
|
|
7
|
+
* `compile` writes it only for a reference it VERIFIED: the rule exists in the
|
|
8
|
+
* linter's catalog and the project's config switches it on. Anything less — the
|
|
9
|
+
* check was turned off (`verify: false`, `verifyLinters: false`, a per-linter
|
|
10
|
+
* `false`, catalog-only), the config does not set the rule, or the config could
|
|
11
|
+
* not be read — renders as "**Claimed (unverified):**". A reader of the compiled
|
|
12
|
+
* file can then tell the two apart without the compile log.
|
|
13
|
+
*
|
|
14
|
+
* Zero imports: `validate.ts`, `rule-routing.ts` and the CLI read these markers
|
|
15
|
+
* too, and some of them are browser-safe.
|
|
16
|
+
*/
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.RULE_MARKER_SOURCE = exports.CLAIMED_MARKER = exports.ENFORCED_MARKER = void 0;
|
|
19
|
+
exports.isVerifiedLabel = isVerifiedLabel;
|
|
20
|
+
/** A reference `compile` verified: exists, and the project's config runs it. */
|
|
21
|
+
exports.ENFORCED_MARKER = "**Enforced by:**";
|
|
22
|
+
/** A reference `compile` did not or could not verify. */
|
|
23
|
+
exports.CLAIMED_MARKER = "**Claimed (unverified):**";
|
|
24
|
+
/**
|
|
25
|
+
* Either marker followed by its backticked reference, anywhere in a line.
|
|
26
|
+
* Group 1 is the marker's label (`Enforced by` / `Claimed (unverified)`),
|
|
27
|
+
* group 2 the reference.
|
|
28
|
+
*/
|
|
29
|
+
exports.RULE_MARKER_SOURCE = /\*\*(Enforced by|Claimed \(unverified\)):\*\*\s*`([^`]+)`/.source;
|
|
30
|
+
/** Is the label captured by {@link RULE_MARKER_SOURCE} the verified one? */
|
|
31
|
+
function isVerifiedLabel(label) {
|
|
32
|
+
return label === "Enforced by";
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=enforce-marker.js.map
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The ONE answer to "which ESLint rules exist in this repo, which are enabled
|
|
3
|
+
* where, and did the config load" — read from ESLint itself.
|
|
4
|
+
*
|
|
5
|
+
* Three callers used to ask ESLint three different ways, and each saw a
|
|
6
|
+
* different repo: `generate types` probed one representative path per
|
|
7
|
+
* (directory, extension) (#352), `enforce()` verification probed one path per
|
|
8
|
+
* config block `files` glob (#351), and the routing catalog asked about
|
|
9
|
+
* `src/index.ts` alone. The same rule could be enabled for one caller and
|
|
10
|
+
* absent for another. This module owns the probe; every caller reads the same
|
|
11
|
+
* {@link EslintInventory}.
|
|
12
|
+
*
|
|
13
|
+
* This module is the pure half (the probe's script, its wire schema, and every
|
|
14
|
+
* question asked of the answer); `eslintInventory` in `linters.ts` runs the
|
|
15
|
+
* probe beside the other linter subprocesses, cached per project.
|
|
16
|
+
*
|
|
17
|
+
* HOW: a child `node -e` process runs in the project's directory, so `eslint`
|
|
18
|
+
* and the config's own imports resolve from the project exactly as `npx eslint`
|
|
19
|
+
* would, and nothing of the project's config loads into our process. The child
|
|
20
|
+
* lists the config's blocks (plugins they register, rules they mention, a probe
|
|
21
|
+
* path synthesized from each `files` glob), adds one representative path per
|
|
22
|
+
* (directory, name shape) of the project's files, and asks
|
|
23
|
+
* `calculateConfigForFile` for each. A rule is `enabled` if any probe has it on,
|
|
24
|
+
* `disabled` if every probe that sets it has it off.
|
|
25
|
+
*
|
|
26
|
+
* LIMITS, named: a block naming one exact file that shares directory and
|
|
27
|
+
* extension with siblings is reached only if its glob synthesizes that path; a
|
|
28
|
+
* config in a SUBDIRECTORY (v10 looks configs up per file) is not listed; a
|
|
29
|
+
* `files` entry given as a function is not probed. A rule that a block mentions
|
|
30
|
+
* but no probe reached reads `unknown`, never `unconfigured`.
|
|
31
|
+
*/
|
|
32
|
+
import type { ConfigEnabledStatus } from "./linter-adapter.js";
|
|
33
|
+
/** What ESLint's resolved config says about the repo, when it loaded. */
|
|
34
|
+
export interface EslintConfigView {
|
|
35
|
+
/** ESLint's built-in rule ids. */
|
|
36
|
+
readonly core: ReadonlySet<string>;
|
|
37
|
+
/** plugin namespace → its rule names, from the plugin objects ESLint holds. */
|
|
38
|
+
readonly plugins: ReadonlyMap<string, ReadonlySet<string>>;
|
|
39
|
+
/** rule id → state, merged over every probe path. */
|
|
40
|
+
readonly rules: ReadonlyMap<string, "enabled" | "disabled">;
|
|
41
|
+
/** rule ids some block sets, whether or not a probe reached that block. */
|
|
42
|
+
readonly mentioned: ReadonlySet<string>;
|
|
43
|
+
/** every block of the config was listed, so an unmentioned rule is unset. */
|
|
44
|
+
readonly complete: boolean;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* The inventory. Separate members because each is a different instruction to
|
|
48
|
+
* the user: no ESLint, no config, a config that throws, a config that loads and
|
|
49
|
+
* switches nothing on, a config with rules.
|
|
50
|
+
*/
|
|
51
|
+
export type EslintInventory = {
|
|
52
|
+
readonly kind: "not-installed";
|
|
53
|
+
} | {
|
|
54
|
+
readonly kind: "no-config";
|
|
55
|
+
} | {
|
|
56
|
+
readonly kind: "failed";
|
|
57
|
+
readonly error: string;
|
|
58
|
+
} | {
|
|
59
|
+
readonly kind: "empty";
|
|
60
|
+
readonly view: EslintConfigView;
|
|
61
|
+
} | {
|
|
62
|
+
readonly kind: "loaded";
|
|
63
|
+
readonly view: EslintConfigView;
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* One representative path per distinct (directory, name shape) pair of the
|
|
67
|
+
* project's files. A flat-config `files` glob selects on the directory and the
|
|
68
|
+
* name's extension chain, so one file per pair sees every block any file of
|
|
69
|
+
* that pair could match — without linting a single file.
|
|
70
|
+
*/
|
|
71
|
+
export declare function representativePaths(files: readonly string[]): readonly string[];
|
|
72
|
+
/** The files `representativePaths` picks from: everything but dependencies and git. */
|
|
73
|
+
export declare const PROJECT_FILES_GLOB: {
|
|
74
|
+
readonly pattern: "**/*";
|
|
75
|
+
readonly ignore: readonly ["**/node_modules/**", "**/.git/**"];
|
|
76
|
+
};
|
|
77
|
+
export declare const ESLINT_PROBE_SCRIPT: string;
|
|
78
|
+
/**
|
|
79
|
+
* Turn the child's stdout into an inventory. Pure, so every shape of answer is
|
|
80
|
+
* testable without spawning ESLint. @internal
|
|
81
|
+
*/
|
|
82
|
+
export declare function parseEslintInventory(stdout: string): EslintInventory;
|
|
83
|
+
/** The view, when the config loaded (with or without enabled rules). */
|
|
84
|
+
export declare function configView(inv: EslintInventory): EslintConfigView | null;
|
|
85
|
+
/** Ids of every rule the config switches on somewhere, sorted. */
|
|
86
|
+
export declare function enabledRuleIds(view: EslintConfigView): readonly string[];
|
|
87
|
+
/** Enabled state of one rule id across every block of the config. */
|
|
88
|
+
export declare function eslintRuleState(inv: EslintInventory, ruleId: string): ConfigEnabledStatus;
|
|
89
|
+
/**
|
|
90
|
+
* Does the plugin the config REGISTERS under `ruleId`'s namespace define the
|
|
91
|
+
* rule? null when the config registers no plugin under that namespace (or did
|
|
92
|
+
* not load). The namespace is everything before the LAST slash — ESLint's own
|
|
93
|
+
* split, so `@scope/plugin/rule` works.
|
|
94
|
+
*/
|
|
95
|
+
export declare function registeredPluginHasRule(inv: EslintInventory, ruleId: string): boolean | null;
|
|
96
|
+
//# sourceMappingURL=eslint-inventory.d.ts.map
|