vigiles 7.0.0 → 8.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/README.md +180 -89
- package/dist/cli-commands.d.ts +1 -1
- package/dist/cli-commands.js +2 -6
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +472 -132
- package/dist/core/adopt.d.ts +65 -0
- package/dist/core/adopt.js +199 -0
- package/dist/core/compose.d.ts +1 -1
- package/dist/core/compose.js +1 -1
- package/dist/core/evolve.d.ts +4 -0
- package/dist/core/evolve.js +4 -0
- package/dist/core/frontmatter.d.ts +8 -7
- package/dist/core/frontmatter.js +8 -7
- package/dist/core/generate-harness.d.ts +1 -1
- package/dist/core/generate-harness.js +3 -3
- package/dist/core/generate-schema.js +1 -1
- package/dist/core/inline.d.ts +6 -6
- package/dist/core/inline.js +6 -6
- package/dist/core/integrity.d.ts +31 -0
- package/dist/core/integrity.js +45 -0
- package/dist/core/orphans.js +1 -1
- package/dist/core/spec.d.ts +40 -2
- package/dist/core/spec.js +16 -1
- package/dist/core/types.d.ts +30 -6
- package/dist/core/validate.js +26 -26
- package/dist/guardrail-check.d.ts +1 -1
- package/dist/guardrail-check.js +1 -1
- package/dist/scan-trigger-suggest.d.ts +54 -0
- package/dist/scan-trigger-suggest.js +70 -0
- package/dist/scan.d.ts +17 -1
- package/dist/scan.js +32 -2
- package/dist/setup-plan.d.ts +59 -1
- package/dist/setup-plan.js +103 -5
- package/hooks/post-edit.sh +1 -1
- package/package.json +1 -1
- package/skills/adopt-spec/SKILL.md +7 -7
- package/skills/linter-docs/eslint.md +1 -1
- package/skills/strengthen/SKILL.md +1 -1
package/dist/setup-plan.d.ts
CHANGED
|
@@ -27,6 +27,10 @@ export interface SetupPlan {
|
|
|
27
27
|
export interface ParsedSetupArgs {
|
|
28
28
|
target?: string;
|
|
29
29
|
strict: boolean;
|
|
30
|
+
/** `--report-only` — write the gating rules at "warn" (nothing fails CI). The
|
|
31
|
+
* orthogonal severity dial; composes with `--strict` (which rules) by setting
|
|
32
|
+
* their severity. */
|
|
33
|
+
reportOnly: boolean;
|
|
30
34
|
yes: boolean;
|
|
31
35
|
/** `--force` — rewrite a stale CI workflow in place. */
|
|
32
36
|
force: boolean;
|
|
@@ -51,9 +55,52 @@ export declare function defaultPlan(strict?: boolean): SetupPlan;
|
|
|
51
55
|
* changed (so the IO layer skips the write). The IO (read/parse/write + the
|
|
52
56
|
* malformed-file guard) stays in cli.ts.
|
|
53
57
|
*/
|
|
58
|
+
/**
|
|
59
|
+
* The structural rules `init` gates BY DEFAULT (severity `error`, so a broken
|
|
60
|
+
* surface fails `vigiles lint`). Every one is HIGH-PRECISION / FP-safe — it fires
|
|
61
|
+
* only on a genuine defect (a never-available/typo'd tool, a subagent missing
|
|
62
|
+
* `name`/`description`, a typo'd hook event, a dead hook script, a broken MCP
|
|
63
|
+
* ref, two skills that collide in the selector) — so a well-formed plugin stays
|
|
64
|
+
* green and catching real breakage out of the box never cries wolf.
|
|
65
|
+
*
|
|
66
|
+
* Deliberately EXCLUDES `require-instructions-spec` and the workflow-forcing rules:
|
|
67
|
+
* those make a CLEAN repo fail (you simply haven't written the spec/test yet), so
|
|
68
|
+
* they stay opt-in under `--strict` (progressive adoption — see
|
|
69
|
+
* `STRICT_EXTRA_RULES`).
|
|
70
|
+
*
|
|
71
|
+
* This is the **`structural`** rule group (see research/install-enforcement-dx.md).
|
|
72
|
+
*/
|
|
73
|
+
export declare const STRUCTURAL_RULES: readonly ["subagent-tool-contract", "subagent-frontmatter", "hook-events", "hook-script-exists", "mcp-config", "mcp-tool-resolves", "mcp-hook-target-resolves", "disallowed-tools-contract", "description-overlap"];
|
|
74
|
+
/**
|
|
75
|
+
* The **`workflow`** group — the WORKFLOW-FORCING / opinionated tier `--strict`
|
|
76
|
+
* gates, which a clean repo can still fail because you haven't done the work yet:
|
|
77
|
+
* a spec per instruction file (`require-instructions-spec`), a test/eval per
|
|
78
|
+
* surface (`untested-*`). Opt-in by design (the smooth-adoption on-ramp). The
|
|
79
|
+
* Clippy-`pedantic` / TS-`strict` analog — ONE opinionated opt-in.
|
|
80
|
+
*
|
|
81
|
+
* NB `frontmatter-valid` / `skill-frontmatter` live in the `nudge` group, not
|
|
82
|
+
* here: they're acknowledged-noisy recommendations we never gate on (see
|
|
83
|
+
* research/install-enforcement-dx.md).
|
|
84
|
+
*/
|
|
85
|
+
export declare const WORKFLOW_RULES: readonly ["require-instructions-spec", "untested-skill", "untested-subagent", "untested-hook"];
|
|
86
|
+
/**
|
|
87
|
+
* The **`nudge`** group — recommendations / acknowledged-noisy checks that NEVER
|
|
88
|
+
* gate (not even under `--strict`): `frontmatter-valid` (js-yaml is stricter than
|
|
89
|
+
* CC's loader), `skill-frontmatter` (skills load without it) and `unmarked-refs`
|
|
90
|
+
* (the undecidable-plaintext nudge) sit at `warn`; `prefer-compiled-hooks` defaults
|
|
91
|
+
* OFF (a recommendation that shouldn't fire unasked — the shell lane stays
|
|
92
|
+
* first-class). `init` does not write these — they keep their own default
|
|
93
|
+
* severities. Named for the group taxonomy (research/install-enforcement-dx.md).
|
|
94
|
+
*/
|
|
95
|
+
export declare const NUDGE_RULES: readonly ["frontmatter-valid", "skill-frontmatter", "prefer-compiled-hooks", "unmarked-refs"];
|
|
54
96
|
export declare function mergeProjectConfig(existing: Record<string, unknown>, opts: {
|
|
55
97
|
harness: string | string[];
|
|
56
98
|
strict: boolean;
|
|
99
|
+
reportOnly?: boolean;
|
|
100
|
+
/** Whether the LINT pillar is on (default true). The rule gate is a lint-layer
|
|
101
|
+
* concern, so a test-only setup (`init --test` / `--no-lint`) records the
|
|
102
|
+
* harness but writes NO lint rules. */
|
|
103
|
+
lint?: boolean;
|
|
57
104
|
}): Record<string, unknown> | null;
|
|
58
105
|
/**
|
|
59
106
|
* Whether to drop into interactive prompts: a human at a TTY who passed neither
|
|
@@ -62,7 +109,18 @@ export declare function mergeProjectConfig(existing: Record<string, unknown>, op
|
|
|
62
109
|
*/
|
|
63
110
|
export declare function shouldPrompt(parsed: ParsedSetupArgs, isTTY: boolean): boolean;
|
|
64
111
|
/** Interactive answers (only the fields the prompts cover). */
|
|
65
|
-
export type SetupAnswers = Partial<Pick<SetupPlan, "lint" | "test" | "gha" | "plugin">>;
|
|
112
|
+
export type SetupAnswers = Partial<Pick<SetupPlan, "lint" | "test" | "gha" | "plugin" | "strict">>;
|
|
113
|
+
/** Ask one question with a default — injected so the interactive Q&A is pure +
|
|
114
|
+
* unit-testable (a fake `ask` scripts answers; no TTY, no readline). */
|
|
115
|
+
export type AskFn = (question: string, def: string) => Promise<string>;
|
|
116
|
+
/**
|
|
117
|
+
* The interactive setup Q&A as PURE logic over an injected `ask` — the prompts,
|
|
118
|
+
* their defaults, and the answer→`SetupAnswers` mapping. The IO shell (readline)
|
|
119
|
+
* lives in `cli.ts`'s `promptSetup`, which just supplies a real `ask`. Keeping
|
|
120
|
+
* this here means the fragile interactive path is unit-tested deterministically
|
|
121
|
+
* (the questions can't silently break) without a terminal.
|
|
122
|
+
*/
|
|
123
|
+
export declare function collectSetupAnswers(ask: AskFn): Promise<SetupAnswers>;
|
|
66
124
|
/**
|
|
67
125
|
* How to install vigiles's skills/hooks for ONE harness — the deterministic
|
|
68
126
|
* decision behind the IO in cli.ts, so a CI test asserts WHICH commands an
|
package/dist/setup-plan.js
CHANGED
|
@@ -10,10 +10,12 @@
|
|
|
10
10
|
* on a prompt. See docs/agent-setup.md.
|
|
11
11
|
*/
|
|
12
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.NUDGE_RULES = exports.WORKFLOW_RULES = exports.STRUCTURAL_RULES = void 0;
|
|
13
14
|
exports.parseSetupArgs = parseSetupArgs;
|
|
14
15
|
exports.defaultPlan = defaultPlan;
|
|
15
16
|
exports.mergeProjectConfig = mergeProjectConfig;
|
|
16
17
|
exports.shouldPrompt = shouldPrompt;
|
|
18
|
+
exports.collectSetupAnswers = collectSetupAnswers;
|
|
17
19
|
exports.planPluginInstall = planPluginInstall;
|
|
18
20
|
exports.resolvePlan = resolvePlan;
|
|
19
21
|
function flagValue(args, prefix) {
|
|
@@ -33,6 +35,7 @@ function parseSetupArgs(args) {
|
|
|
33
35
|
return {
|
|
34
36
|
target: flagValue(args, "--target="),
|
|
35
37
|
strict: args.includes("--strict"),
|
|
38
|
+
reportOnly: args.includes("--report-only"),
|
|
36
39
|
yes: args.includes("--yes") || args.includes("-y"),
|
|
37
40
|
force: args.includes("--force"),
|
|
38
41
|
lint: boolFlag(args, "lint"),
|
|
@@ -60,6 +63,64 @@ function defaultPlan(strict = false) {
|
|
|
60
63
|
* changed (so the IO layer skips the write). The IO (read/parse/write + the
|
|
61
64
|
* malformed-file guard) stays in cli.ts.
|
|
62
65
|
*/
|
|
66
|
+
/**
|
|
67
|
+
* The structural rules `init` gates BY DEFAULT (severity `error`, so a broken
|
|
68
|
+
* surface fails `vigiles lint`). Every one is HIGH-PRECISION / FP-safe — it fires
|
|
69
|
+
* only on a genuine defect (a never-available/typo'd tool, a subagent missing
|
|
70
|
+
* `name`/`description`, a typo'd hook event, a dead hook script, a broken MCP
|
|
71
|
+
* ref, two skills that collide in the selector) — so a well-formed plugin stays
|
|
72
|
+
* green and catching real breakage out of the box never cries wolf.
|
|
73
|
+
*
|
|
74
|
+
* Deliberately EXCLUDES `require-instructions-spec` and the workflow-forcing rules:
|
|
75
|
+
* those make a CLEAN repo fail (you simply haven't written the spec/test yet), so
|
|
76
|
+
* they stay opt-in under `--strict` (progressive adoption — see
|
|
77
|
+
* `STRICT_EXTRA_RULES`).
|
|
78
|
+
*
|
|
79
|
+
* This is the **`structural`** rule group (see research/install-enforcement-dx.md).
|
|
80
|
+
*/
|
|
81
|
+
exports.STRUCTURAL_RULES = [
|
|
82
|
+
"subagent-tool-contract",
|
|
83
|
+
"subagent-frontmatter",
|
|
84
|
+
"hook-events",
|
|
85
|
+
"hook-script-exists",
|
|
86
|
+
"mcp-config",
|
|
87
|
+
"mcp-tool-resolves",
|
|
88
|
+
"mcp-hook-target-resolves",
|
|
89
|
+
"disallowed-tools-contract",
|
|
90
|
+
"description-overlap",
|
|
91
|
+
];
|
|
92
|
+
/**
|
|
93
|
+
* The **`workflow`** group — the WORKFLOW-FORCING / opinionated tier `--strict`
|
|
94
|
+
* gates, which a clean repo can still fail because you haven't done the work yet:
|
|
95
|
+
* a spec per instruction file (`require-instructions-spec`), a test/eval per
|
|
96
|
+
* surface (`untested-*`). Opt-in by design (the smooth-adoption on-ramp). The
|
|
97
|
+
* Clippy-`pedantic` / TS-`strict` analog — ONE opinionated opt-in.
|
|
98
|
+
*
|
|
99
|
+
* NB `frontmatter-valid` / `skill-frontmatter` live in the `nudge` group, not
|
|
100
|
+
* here: they're acknowledged-noisy recommendations we never gate on (see
|
|
101
|
+
* research/install-enforcement-dx.md).
|
|
102
|
+
*/
|
|
103
|
+
exports.WORKFLOW_RULES = [
|
|
104
|
+
"require-instructions-spec",
|
|
105
|
+
"untested-skill",
|
|
106
|
+
"untested-subagent",
|
|
107
|
+
"untested-hook",
|
|
108
|
+
];
|
|
109
|
+
/**
|
|
110
|
+
* The **`nudge`** group — recommendations / acknowledged-noisy checks that NEVER
|
|
111
|
+
* gate (not even under `--strict`): `frontmatter-valid` (js-yaml is stricter than
|
|
112
|
+
* CC's loader), `skill-frontmatter` (skills load without it) and `unmarked-refs`
|
|
113
|
+
* (the undecidable-plaintext nudge) sit at `warn`; `prefer-compiled-hooks` defaults
|
|
114
|
+
* OFF (a recommendation that shouldn't fire unasked — the shell lane stays
|
|
115
|
+
* first-class). `init` does not write these — they keep their own default
|
|
116
|
+
* severities. Named for the group taxonomy (research/install-enforcement-dx.md).
|
|
117
|
+
*/
|
|
118
|
+
exports.NUDGE_RULES = [
|
|
119
|
+
"frontmatter-valid",
|
|
120
|
+
"skill-frontmatter",
|
|
121
|
+
"prefer-compiled-hooks",
|
|
122
|
+
"unmarked-refs",
|
|
123
|
+
];
|
|
63
124
|
function mergeProjectConfig(existing, opts) {
|
|
64
125
|
const config = { ...existing };
|
|
65
126
|
let changed = false;
|
|
@@ -67,13 +128,23 @@ function mergeProjectConfig(existing, opts) {
|
|
|
67
128
|
config.harness = opts.harness;
|
|
68
129
|
changed = true;
|
|
69
130
|
}
|
|
70
|
-
|
|
131
|
+
// The rule gate belongs to the LINT layer — a test-only setup records the
|
|
132
|
+
// harness but writes no rules (honoring the positive-flag contract that
|
|
133
|
+
// `--test` selects only the test pillar).
|
|
134
|
+
if (opts.lint !== false) {
|
|
135
|
+
// Gate the FP-safe `structural` group by default; `--strict` adds the
|
|
136
|
+
// `workflow` group on top. `--report-only` is the orthogonal severity dial —
|
|
137
|
+
// it writes the SAME rule set at "warn" (nothing fails CI; the
|
|
138
|
+
// migration/observe mode). Never clobber a severity the user already set —
|
|
139
|
+
// only fill the undefined ones.
|
|
140
|
+
const severity = opts.reportOnly ? "warn" : "error";
|
|
141
|
+
const gate = opts.strict
|
|
142
|
+
? [...exports.STRUCTURAL_RULES, ...exports.WORKFLOW_RULES]
|
|
143
|
+
: [...exports.STRUCTURAL_RULES];
|
|
71
144
|
const rules = { ...config.rules };
|
|
72
|
-
|
|
73
|
-
// no longer promotes it; it tightens only `require-spec` (instruction files).
|
|
74
|
-
for (const r of ["require-spec"]) {
|
|
145
|
+
for (const r of gate) {
|
|
75
146
|
if (rules[r] === undefined) {
|
|
76
|
-
rules[r] =
|
|
147
|
+
rules[r] = severity;
|
|
77
148
|
changed = true;
|
|
78
149
|
}
|
|
79
150
|
}
|
|
@@ -93,6 +164,31 @@ function shouldPrompt(parsed, isTTY) {
|
|
|
93
164
|
const allPinned = pillarsPinned && parsed.gha !== undefined && parsed.plugin !== undefined;
|
|
94
165
|
return !allPinned;
|
|
95
166
|
}
|
|
167
|
+
const isYesAnswer = (s) => /^y(es)?$/i.test(s);
|
|
168
|
+
/**
|
|
169
|
+
* The interactive setup Q&A as PURE logic over an injected `ask` — the prompts,
|
|
170
|
+
* their defaults, and the answer→`SetupAnswers` mapping. The IO shell (readline)
|
|
171
|
+
* lives in `cli.ts`'s `promptSetup`, which just supplies a real `ask`. Keeping
|
|
172
|
+
* this here means the fragile interactive path is unit-tested deterministically
|
|
173
|
+
* (the questions can't silently break) without a terminal.
|
|
174
|
+
*/
|
|
175
|
+
async function collectSetupAnswers(ask) {
|
|
176
|
+
const pillars = (await ask("Set up which pillars? [both/lint/test] (both): ", "both")).toLowerCase();
|
|
177
|
+
const gha = isYesAnswer(await ask("Wire CI (GitHub Action)? [Y/n]: ", "y"));
|
|
178
|
+
const plugin = isYesAnswer(await ask("Install the Claude Code plugin (hooks + skills)? [Y/n]: ", "y"));
|
|
179
|
+
// Structural gating (broken tools/hooks/MCP/collisions) is always on. This asks
|
|
180
|
+
// about the WORKFLOW tier — a spec per file + a test per surface — which a clean
|
|
181
|
+
// repo can fail just for not having done the work yet, so it's the recommended
|
|
182
|
+
// default a human opts OUT of (never forced on a silent run).
|
|
183
|
+
const strict = isYesAnswer(await ask("Also enforce specs + a test per surface (recommended)? [Y/n]: ", "y"));
|
|
184
|
+
return {
|
|
185
|
+
lint: pillars !== "test",
|
|
186
|
+
test: pillars !== "lint" && pillars !== "verify",
|
|
187
|
+
gha,
|
|
188
|
+
plugin,
|
|
189
|
+
strict,
|
|
190
|
+
};
|
|
191
|
+
}
|
|
96
192
|
/**
|
|
97
193
|
* Apply the pillar flags. A positive flag (`--lint` and/or `--test`) is an
|
|
98
194
|
* explicit SELECTION — enable exactly the named pillars. Otherwise default to
|
|
@@ -118,6 +214,8 @@ function applyAnswers(plan, answers) {
|
|
|
118
214
|
plan.gha = answers.gha;
|
|
119
215
|
if (answers.plugin !== undefined)
|
|
120
216
|
plan.plugin = answers.plugin;
|
|
217
|
+
if (answers.strict !== undefined)
|
|
218
|
+
plan.strict = answers.strict;
|
|
121
219
|
}
|
|
122
220
|
/** Per-harness install plan. `hasClaude` gates the auto-run `claude plugin` CLI
|
|
123
221
|
* (else the same two steps are printed as `/plugin` slash commands).
|
package/hooks/post-edit.sh
CHANGED
|
@@ -19,7 +19,7 @@ BASENAME=$(basename "$FILE")
|
|
|
19
19
|
case "$BASENAME" in
|
|
20
20
|
eslint.config.*|.eslintrc*|.stylelintrc*|.rubocop.yml|pyproject.toml|Cargo.toml|package.json)
|
|
21
21
|
if command -v npx &>/dev/null && [ -f "package.json" ]; then
|
|
22
|
-
npx vigiles generate
|
|
22
|
+
npx vigiles generate types 2>&1 || true
|
|
23
23
|
fi
|
|
24
24
|
;;
|
|
25
25
|
esac
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vigiles",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "8.0.0",
|
|
4
4
|
"description": "Lint & test the harness your AI agent runs on — verify the references in your CLAUDE.md / AGENTS.md and test that your hooks and skills actually work.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"claude-code",
|
|
@@ -7,7 +7,7 @@ argument-hint: <path to CLAUDE.md, defaults to CLAUDE.md>
|
|
|
7
7
|
|
|
8
8
|
Start a typed `CLAUDE.md.spec.ts` from an existing hand-written CLAUDE.md (or AGENTS.md). This is the non-destructive adoption path — you keep your existing instruction file as the starting point and get type safety going forward.
|
|
9
9
|
|
|
10
|
-
> **
|
|
10
|
+
> **Faithful by default, and reversible.** Adoption is non-destructive: the goal is a spec that compiles back to the user's existing file as closely as possible — preserve every rule, command, key file, and prose section. Don't upgrade `guidance()` to `enforce()` here; that's a separate, opt-in step (the `strengthen` skill). And it's never a one-way door — `vigiles eject <file>` hands the file back as plain hand-owned markdown anytime. For the lightest touch with no spec at all, inline `<!-- vigiles:enforce ... -->` comments are verified by `vigiles lint` with the same engine.
|
|
11
11
|
|
|
12
12
|
## Instructions
|
|
13
13
|
|
|
@@ -100,9 +100,9 @@ Show the user:
|
|
|
100
100
|
2. How many rules were converted (enforce vs guidance vs TODO)
|
|
101
101
|
3. How many file/cmd refs were added for stale reference detection
|
|
102
102
|
4. The command to compile: `npx vigiles compile`
|
|
103
|
-
5. The command to verify: `npx vigiles
|
|
103
|
+
5. The command to verify: `npx vigiles lint`
|
|
104
104
|
|
|
105
|
-
Ask if they want you to write the file. If yes, also suggest adding to `.gitignore` or updating CI to run `vigiles compile` and `vigiles
|
|
105
|
+
Ask if they want you to write the file. If yes, also suggest adding to `.gitignore` or updating CI to run `vigiles compile` and `vigiles lint`.
|
|
106
106
|
|
|
107
107
|
### Step 6: Optional — Set Up CI
|
|
108
108
|
|
|
@@ -111,14 +111,14 @@ If the user wants CI integration, suggest adding to their GitHub Actions workflo
|
|
|
111
111
|
```yaml
|
|
112
112
|
- name: Compile specs
|
|
113
113
|
run: npx vigiles compile
|
|
114
|
-
- name: Verify integrity
|
|
115
|
-
run: npx vigiles
|
|
114
|
+
- name: Verify references + integrity
|
|
115
|
+
run: npx vigiles lint
|
|
116
116
|
```
|
|
117
117
|
|
|
118
118
|
Or using the vigiles GitHub Action:
|
|
119
119
|
|
|
120
120
|
```yaml
|
|
121
|
-
- uses: zernie/vigiles@
|
|
121
|
+
- uses: zernie/vigiles@v1
|
|
122
122
|
with:
|
|
123
|
-
command:
|
|
123
|
+
command: lint
|
|
124
124
|
```
|
|
@@ -365,7 +365,7 @@ If two rules try to fix the same range of code, ESLint drops both fixes. Avoid t
|
|
|
365
365
|
### Monorepo considerations
|
|
366
366
|
|
|
367
367
|
- ESLint flat config is resolved from `cwd`, not from the file being linted. In a monorepo, set `cwd` to the package root, not the workspace root.
|
|
368
|
-
- `vigiles generate
|
|
368
|
+
- `vigiles generate types` discovers ESLint rules using `calculateConfigForFile("dummy.js")` from the project `basePath`. If your monorepo has different configs per package, run `generate types` from each package root.
|
|
369
369
|
- Plugin rules must be installed in the `node_modules` visible from the config file's location. Hoisted deps in a monorepo can cause "plugin not found" errors — install them in the package's own `devDependencies`.
|
|
370
370
|
|
|
371
371
|
## Mapping PR Feedback to Rule Strategy
|
|
@@ -20,7 +20,7 @@ Default to interactive if the user doesn't specify.
|
|
|
20
20
|
|
|
21
21
|
### Step 1: Discover What's Installed
|
|
22
22
|
|
|
23
|
-
Run `npx vigiles generate
|
|
23
|
+
Run `npx vigiles generate types` to get the full list of enabled linter rules in the project. Read `.vigiles/generated.d.ts` to see every rule available across all detected linters.
|
|
24
24
|
|
|
25
25
|
Note which linter prefixes appear in the generated types (e.g., `EslintRule`, `RuffRule`). You'll only need reference docs for detected linters.
|
|
26
26
|
|