vigiles 38.2.0 → 39.1.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/action.yml +18 -0
- 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/audit-report.d.ts +14 -1
- package/dist/audit-report.js +21 -5
- package/dist/audit-report.template.html +33 -28
- package/dist/audit-score.d.ts +4 -1
- package/dist/audit-score.js +3 -1
- package/dist/audit-verdict.d.ts +3 -1
- package/dist/cli-flag-check.d.ts +36 -0
- package/dist/cli-flag-check.js +76 -1
- package/dist/cli-flags.d.ts +1 -1
- package/dist/cli-main.d.ts +2 -2
- package/dist/cli-main.js +684 -434
- package/dist/core/CLAUDE.md.spec.js +2 -2
- package/dist/core/apply-rules.d.ts +71 -0
- package/dist/core/apply-rules.js +48 -0
- 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-migrations.d.ts +69 -0
- package/dist/core/config-migrations.js +145 -0
- package/dist/core/config-schema.d.ts +166 -160
- package/dist/core/config-schema.js +207 -244
- 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 +28 -4
- 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 +31 -34
- package/dist/core/presets.js +25 -38
- package/dist/core/rule-catalog.d.ts +11 -12
- package/dist/core/rule-catalog.js +25 -94
- package/dist/core/rule.d.ts +213 -0
- package/dist/core/rule.js +37 -0
- package/dist/core/skill-resources.d.ts +85 -15
- package/dist/core/skill-resources.js +63 -37
- 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 +19 -329
- package/dist/core/validate.d.ts +14 -14
- package/dist/core/validate.js +87 -73
- 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/optimize.d.ts +2 -1
- package/dist/overrides.d.ts +29 -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/rules/CLAUDE.md.spec.d.ts +3 -0
- package/dist/rules/CLAUDE.md.spec.js +22 -0
- package/dist/rules/groups.d.ts +32 -0
- package/dist/rules/groups.js +27 -0
- package/dist/rules/index.d.ts +412 -0
- package/dist/{core/rule-meta.js → rules/index.js} +329 -200
- package/dist/rules/skill-resource-resolves.d.ts +36 -0
- package/dist/rules/skill-resource-resolves.js +51 -0
- package/dist/run-hook.d.ts +27 -3
- package/dist/run-hook.js +48 -12
- package/dist/scan-core.d.ts +103 -29
- package/dist/scan-core.js +178 -186
- package/dist/scan-files.d.ts +0 -8
- package/dist/scan-files.js +79 -24
- package/dist/scan.d.ts +23 -28
- package/dist/scan.js +64 -18
- package/dist/score-core.js +3 -9
- package/dist/setup-plan.d.ts +13 -27
- package/dist/setup-plan.js +46 -71
- 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 +1347 -121
- package/package.json +2 -2
- package/packages/eslint-config/index.mjs +61 -0
- package/skills/adopt-spec/SKILL.md +2 -1
- package/dist/core/rule-meta.d.ts +0 -82
package/action.yml
CHANGED
|
@@ -36,6 +36,16 @@ inputs:
|
|
|
36
36
|
description: "Only check that linter rules exist; skip config-enabled checks (maps to the CLI's --catalog-only). 'true' or 'false'."
|
|
37
37
|
required: false
|
|
38
38
|
default: "false"
|
|
39
|
+
preset:
|
|
40
|
+
description: >
|
|
41
|
+
Add a preset for this run, on top of the repo's .vigilesrc.json (maps to
|
|
42
|
+
the CLI's --preset=; lint only). The names are the ones `extends` takes,
|
|
43
|
+
with or without the `vigiles:` prefix: 'experimental' turns on the checks
|
|
44
|
+
not yet measured reliable enough to grade on, at warn — so they report
|
|
45
|
+
and never fail the run. Comma-separate several. Empty (the default) adds
|
|
46
|
+
none.
|
|
47
|
+
required: false
|
|
48
|
+
default: ""
|
|
39
49
|
working-directory:
|
|
40
50
|
description: "Directory to run vigiles in."
|
|
41
51
|
required: false
|
|
@@ -80,6 +90,7 @@ runs:
|
|
|
80
90
|
VIGILES_VERSION: ${{ inputs.version }}
|
|
81
91
|
VIGILES_MAX_RULES: ${{ inputs.max-rules }}
|
|
82
92
|
VIGILES_CATALOG_ONLY: ${{ inputs.catalog-only }}
|
|
93
|
+
VIGILES_PRESET: ${{ inputs.preset }}
|
|
83
94
|
VIGILES_ACTION_PATH: ${{ github.action_path }}
|
|
84
95
|
VIGILES_COMMENT: ${{ inputs.comment }}
|
|
85
96
|
VIGILES_CAPABILITY_DIFF: ${{ inputs.capability-diff }}
|
|
@@ -114,6 +125,13 @@ runs:
|
|
|
114
125
|
args+=("--catalog-only")
|
|
115
126
|
fi
|
|
116
127
|
|
|
128
|
+
# The CLI validates the name (an unknown preset exits 2 naming the
|
|
129
|
+
# valid ones), so the value is passed through as written.
|
|
130
|
+
preset="${VIGILES_PRESET:-}"
|
|
131
|
+
if [[ -n "${preset// /}" ]]; then
|
|
132
|
+
args+=("--preset=${preset// /}")
|
|
133
|
+
fi
|
|
134
|
+
|
|
117
135
|
# Resolve the runner. 'local' runs the action's own build (CI
|
|
118
136
|
# dogfood via `uses: ./`); an explicit version runs the published npm
|
|
119
137
|
# package at that version. EMPTY (the default) runs the vigiles this
|
|
@@ -1,21 +1,35 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.claudeCodeEventCapabilities = void 0;
|
|
4
|
+
/*
|
|
5
|
+
* `halt` (doc, § JSON output, read 2026-10-12): `continue` is a universal field
|
|
6
|
+
* — "If `false`, Claude stops processing entirely after the hook runs" — and
|
|
7
|
+
* "Every event accepts them, but some events discard them [...]. Each event's
|
|
8
|
+
* section says so." The six rows that carry `halt` have no such sentence in
|
|
9
|
+
* their sections (and § JSON output names PreToolUse and PostToolUse: "the stop
|
|
10
|
+
* applies even when the tool call fails"). § PreCompact and § Notification
|
|
11
|
+
* each say they discard `continue`; SessionEnd has no turn left to stop.
|
|
12
|
+
* https://code.claude.com/docs/en/hooks
|
|
13
|
+
*/
|
|
4
14
|
exports.claudeCodeEventCapabilities = {
|
|
5
15
|
capturedFrom: "code.claude.com/docs/en/hooks (claude-code 2.1.273) + inject/veto measured 2026-09-16 headless",
|
|
6
16
|
events: {
|
|
7
17
|
// doc: SessionStart context is prepended to the session. MEASURED 2026-09-16:
|
|
8
18
|
// inject lands; exit 2 is ignored entirely (it is in noEffectHookEvents).
|
|
19
|
+
// doc (§ Exit code 0, read 2026-10-11): plain stdout is context here — "The
|
|
20
|
+
// exceptions are `UserPromptSubmit`, `UserPromptExpansion`, `SessionStart`,
|
|
21
|
+
// and `PostModelSwitch`, where Claude Code adds plain-text stdout as context".
|
|
9
22
|
SessionStart: {
|
|
10
23
|
carries: "session",
|
|
11
|
-
honours: ["inject"],
|
|
24
|
+
honours: ["inject", "stdout-context", "halt"],
|
|
12
25
|
matcher: false,
|
|
13
26
|
denyShape: "exit-code",
|
|
14
27
|
},
|
|
15
|
-
// doc: exit 2 blocks the prompt and erases it; stdout becomes context
|
|
28
|
+
// doc: exit 2 blocks the prompt and erases it; plain stdout becomes context
|
|
29
|
+
// (the same § Exit code 0 sentence as SessionStart).
|
|
16
30
|
UserPromptSubmit: {
|
|
17
31
|
carries: "prompt",
|
|
18
|
-
honours: ["veto", "inject"],
|
|
32
|
+
honours: ["veto", "inject", "stdout-context", "halt"],
|
|
19
33
|
matcher: false,
|
|
20
34
|
denyShape: "exit-code",
|
|
21
35
|
},
|
|
@@ -26,16 +40,18 @@ exports.claudeCodeEventCapabilities = {
|
|
|
26
40
|
// assumption nobody had run.
|
|
27
41
|
PreToolUse: {
|
|
28
42
|
carries: "tool",
|
|
29
|
-
honours: ["veto", "ask", "inject"],
|
|
43
|
+
honours: ["veto", "ask", "inject", "halt"],
|
|
30
44
|
matcher: true,
|
|
31
45
|
denyShape: "permission-decision",
|
|
32
46
|
},
|
|
33
47
|
// doc: exit 2 feeds stderr back to the MODEL but the tool has already run —
|
|
34
|
-
// feedback, never a veto.
|
|
48
|
+
// feedback, never a veto. NOT `stdout-context`, and NOT stderr at exit 0:
|
|
49
|
+
// "Claude never sees stderr from a hook that exits 0" (§ Exit code 0) — the
|
|
50
|
+
// channel a downstream KB linter used for weeks, delivering nothing. This distinction is why `hook-block-ineffective`
|
|
35
51
|
// does not flag PostToolUse and would cry wolf if it did.
|
|
36
52
|
PostToolUse: {
|
|
37
53
|
carries: "tool",
|
|
38
|
-
honours: ["feedback", "inject"],
|
|
54
|
+
honours: ["feedback", "inject", "halt"],
|
|
39
55
|
matcher: true,
|
|
40
56
|
denyShape: "exit-code",
|
|
41
57
|
},
|
|
@@ -43,7 +59,7 @@ exports.claudeCodeEventCapabilities = {
|
|
|
43
59
|
// shape). MEASURED 2026-09-16: inject lands too.
|
|
44
60
|
Stop: {
|
|
45
61
|
carries: "stop",
|
|
46
|
-
honours: ["veto", "inject"],
|
|
62
|
+
honours: ["veto", "inject", "halt"],
|
|
47
63
|
matcher: false,
|
|
48
64
|
denyShape: "exit-code",
|
|
49
65
|
},
|
|
@@ -51,7 +67,7 @@ exports.claudeCodeEventCapabilities = {
|
|
|
51
67
|
// it was not measured, and Stop's behaviour is not evidence about it.
|
|
52
68
|
SubagentStop: {
|
|
53
69
|
carries: "stop",
|
|
54
|
-
honours: ["veto"],
|
|
70
|
+
honours: ["veto", "halt"],
|
|
55
71
|
matcher: false,
|
|
56
72
|
denyShape: "exit-code",
|
|
57
73
|
},
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.claudeCodeHookProtocol = void 0;
|
|
4
4
|
const hook_condition_js_1 = require("./hook-condition.js");
|
|
5
5
|
const hook_install_js_1 = require("../../hook-install.js");
|
|
6
|
+
const layout_js_1 = require("./layout.js");
|
|
6
7
|
exports.claudeCodeHookProtocol = {
|
|
7
8
|
name: "claude-code",
|
|
8
9
|
blockExitCode: 2,
|
|
@@ -55,7 +56,7 @@ exports.claudeCodeHookProtocol = {
|
|
|
55
56
|
// step the core cannot take: `CompiledHooks` is the application layer's type,
|
|
56
57
|
// and a core port may not name it.
|
|
57
58
|
mergeRegistrations(existing, compiled, managedBy) {
|
|
58
|
-
return (0, hook_install_js_1.mergeHooksJson)(existing, compiled, managedBy);
|
|
59
|
+
return (0, hook_install_js_1.mergeHooksJson)(existing, compiled, managedBy, layout_js_1.claudeCodeLayout.projectRootTokens ?? []);
|
|
59
60
|
},
|
|
60
61
|
};
|
|
61
62
|
//# sourceMappingURL=hook-protocol.js.map
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.codexHookProtocol = void 0;
|
|
4
4
|
const hook_install_js_1 = require("../../hook-install.js");
|
|
5
|
+
const layout_js_1 = require("./layout.js");
|
|
5
6
|
exports.codexHookProtocol = {
|
|
6
7
|
name: "codex",
|
|
7
8
|
blockExitCode: 2,
|
|
@@ -35,7 +36,7 @@ exports.codexHookProtocol = {
|
|
|
35
36
|
return { hooks: { [on]: [entry] } };
|
|
36
37
|
},
|
|
37
38
|
mergeRegistrations(existing, compiled, managedBy) {
|
|
38
|
-
return (0, hook_install_js_1.mergeHooksToml)(existing, compiled, managedBy);
|
|
39
|
+
return (0, hook_install_js_1.mergeHooksToml)(existing, compiled, managedBy, layout_js_1.codexLayout.projectRootTokens ?? []);
|
|
39
40
|
},
|
|
40
41
|
};
|
|
41
42
|
//# sourceMappingURL=hook-protocol.js.map
|
package/dist/audit-report.d.ts
CHANGED
|
@@ -22,6 +22,7 @@ import type { RuleInventoryItem } from "./rule-inventory.js";
|
|
|
22
22
|
import type { RuleRouting } from "./rule-routing.js";
|
|
23
23
|
import type { EvidenceCounts } from "./coverage-evidence.js";
|
|
24
24
|
import type { DeprecatedKeyFilesFinding } from "./deprecated-key-files.js";
|
|
25
|
+
import { type FilteredScan, type UngradedGroup } from "./core/apply-rules.js";
|
|
25
26
|
/**
|
|
26
27
|
* The current schema version. Bump only on a BREAKING change to the shape.
|
|
27
28
|
* v2 (2026-07-15): the rule-map `mechanism` enum value for an unrouted rule
|
|
@@ -139,6 +140,16 @@ export interface AuditReport {
|
|
|
139
140
|
* uses the field. Additive/optional — schema version unchanged.
|
|
140
141
|
*/
|
|
141
142
|
readonly deprecatedKeyFiles?: readonly DeprecatedKeyFilesFinding[];
|
|
143
|
+
/**
|
|
144
|
+
* The UNGRADED rule groups — checks vigiles ships but has not measured as
|
|
145
|
+
* reliable enough to grade you on. One block per group with a rule this run
|
|
146
|
+
* turned on (a preset, `--preset=`, or the rule in `rules`), headed by the
|
|
147
|
+
* group's own label, each rule listed even when it found nothing; absent
|
|
148
|
+
* when none is on. NEVER scored: `score`, `verdict` and `recommendations`
|
|
149
|
+
* are computed from the graded view, without these. Additive/optional —
|
|
150
|
+
* schema version unchanged.
|
|
151
|
+
*/
|
|
152
|
+
readonly ungraded?: readonly UngradedGroup[];
|
|
142
153
|
/**
|
|
143
154
|
* The adoption preview — "what would vigiles catch in your repo?" Present only
|
|
144
155
|
* when the model-gated tier ran (behind consent); a deterministic read omits it.
|
|
@@ -208,7 +219,9 @@ export interface BuildAuditReportOptions extends AuditScoreOptions {
|
|
|
208
219
|
* The CLI attaches `meta.generatedAt` when it writes the JSON artifact; the
|
|
209
220
|
* HTML-embedded form omits it so the rendered file stays deterministic.
|
|
210
221
|
*/
|
|
211
|
-
export declare function buildAuditReport(
|
|
222
|
+
export declare function buildAuditReport(
|
|
223
|
+
/** Minted by `applyRules`: an off rule's findings are already gone. */
|
|
224
|
+
report: FilteredScan<ScanReport>, opts: BuildAuditReportOptions): AuditReport;
|
|
212
225
|
/**
|
|
213
226
|
* The versioned envelope for a `audit --json` run over MULTIPLE plugins (a
|
|
214
227
|
* marketplace expanded into its members, or several dirs) — the leaderboard.
|
package/dist/audit-report.js
CHANGED
|
@@ -20,6 +20,7 @@ exports.buildMarketplaceReport = buildMarketplaceReport;
|
|
|
20
20
|
const audit_score_js_1 = require("./audit-score.js");
|
|
21
21
|
const optimize_js_1 = require("./optimize.js");
|
|
22
22
|
const audit_verdict_js_1 = require("./audit-verdict.js");
|
|
23
|
+
const apply_rules_js_1 = require("./core/apply-rules.js");
|
|
23
24
|
/**
|
|
24
25
|
* The current schema version. Bump only on a BREAKING change to the shape.
|
|
25
26
|
* v2 (2026-07-15): the rule-map `mechanism` enum value for an unrouted rule
|
|
@@ -74,9 +75,13 @@ function inventoryOf(report) {
|
|
|
74
75
|
function outputStylesField(n) {
|
|
75
76
|
return n === undefined || n === 0 ? {} : { outputStyles: n };
|
|
76
77
|
}
|
|
77
|
-
/**
|
|
78
|
+
/**
|
|
79
|
+
* The scan's concrete finding lists, each present only when non-empty — and the
|
|
80
|
+
* ungraded groups' blocks, present only when some rule of one is on.
|
|
81
|
+
*/
|
|
78
82
|
function scanFindingLists(report) {
|
|
79
83
|
return {
|
|
84
|
+
...(report.ungraded.length > 0 ? { ungraded: report.ungraded } : {}),
|
|
80
85
|
...(report.danglingRefs.length
|
|
81
86
|
? { brokenReferences: report.danglingRefs }
|
|
82
87
|
: {}),
|
|
@@ -85,16 +90,27 @@ function scanFindingLists(report) {
|
|
|
85
90
|
: {}),
|
|
86
91
|
};
|
|
87
92
|
}
|
|
93
|
+
/**
|
|
94
|
+
* The graded half of the report — score, verdict, fixes — read off the GRADED
|
|
95
|
+
* view (`gradedView`), so an ungraded group's findings can never move it.
|
|
96
|
+
*/
|
|
97
|
+
function gradedPart(report, opts) {
|
|
98
|
+
const graded = (0, apply_rules_js_1.gradedView)(report);
|
|
99
|
+
const score = (0, audit_score_js_1.auditScore)(graded, { firingMeasured: opts.firingMeasured });
|
|
100
|
+
const recommendations = (0, optimize_js_1.optimize)(graded).recommendations;
|
|
101
|
+
const verdict = (0, audit_verdict_js_1.computeVerdict)({ report: graded, score, recommendations });
|
|
102
|
+
return { score, verdict, recommendations };
|
|
103
|
+
}
|
|
88
104
|
/**
|
|
89
105
|
* Assemble the versioned {@link AuditReport} from a scan report — pure, no clock.
|
|
90
106
|
* The CLI attaches `meta.generatedAt` when it writes the JSON artifact; the
|
|
91
107
|
* HTML-embedded form omits it so the rendered file stays deterministic.
|
|
92
108
|
*/
|
|
93
|
-
function buildAuditReport(
|
|
109
|
+
function buildAuditReport(
|
|
110
|
+
/** Minted by `applyRules`: an off rule's findings are already gone. */
|
|
111
|
+
report, opts) {
|
|
94
112
|
const adoptable = buildAdoptable(opts.adoptableSurfaces);
|
|
95
|
-
const score = (
|
|
96
|
-
const recommendations = (0, optimize_js_1.optimize)(report).recommendations;
|
|
97
|
-
const verdict = (0, audit_verdict_js_1.computeVerdict)({ report, score, recommendations });
|
|
113
|
+
const { score, verdict, recommendations } = gradedPart(report, opts);
|
|
98
114
|
return {
|
|
99
115
|
meta: {
|
|
100
116
|
schemaVersion: exports.AUDIT_SCHEMA_VERSION,
|