vigiles 39.0.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.
Files changed (51) hide show
  1. package/action.yml +18 -0
  2. package/dist/audit-report.d.ts +14 -1
  3. package/dist/audit-report.js +21 -5
  4. package/dist/audit-report.template.html +33 -28
  5. package/dist/audit-score.d.ts +4 -1
  6. package/dist/audit-score.js +3 -1
  7. package/dist/audit-verdict.d.ts +3 -1
  8. package/dist/cli-flag-check.js +4 -0
  9. package/dist/cli-flags.d.ts +1 -1
  10. package/dist/cli-main.js +152 -71
  11. package/dist/core/CLAUDE.md.spec.js +2 -2
  12. package/dist/core/apply-rules.d.ts +71 -0
  13. package/dist/core/apply-rules.js +48 -0
  14. package/dist/core/config-migrations.d.ts +69 -0
  15. package/dist/core/config-migrations.js +145 -0
  16. package/dist/core/config-schema.d.ts +163 -187
  17. package/dist/core/config-schema.js +185 -345
  18. package/dist/core/linter-adapter.d.ts +1 -1
  19. package/dist/core/presets.d.ts +31 -46
  20. package/dist/core/presets.js +25 -51
  21. package/dist/core/rule.d.ts +213 -0
  22. package/dist/core/rule.js +37 -0
  23. package/dist/core/skill-resources.d.ts +85 -15
  24. package/dist/core/skill-resources.js +63 -37
  25. package/dist/core/types.d.ts +12 -314
  26. package/dist/core/validate.d.ts +13 -12
  27. package/dist/core/validate.js +29 -28
  28. package/dist/optimize.d.ts +2 -1
  29. package/dist/overrides.d.ts +13 -9
  30. package/dist/overrides.js +1 -1
  31. package/dist/rules/CLAUDE.md.spec.d.ts +3 -0
  32. package/dist/rules/CLAUDE.md.spec.js +22 -0
  33. package/dist/rules/groups.d.ts +32 -0
  34. package/dist/rules/groups.js +27 -0
  35. package/dist/rules/index.d.ts +412 -0
  36. package/dist/{core/rule-meta.js → rules/index.js} +301 -209
  37. package/dist/rules/skill-resource-resolves.d.ts +36 -0
  38. package/dist/rules/skill-resource-resolves.js +51 -0
  39. package/dist/run-hook.d.ts +1 -1
  40. package/dist/scan-core.d.ts +7 -9
  41. package/dist/scan-core.js +7 -10
  42. package/dist/scan-files.js +1 -4
  43. package/dist/scan.d.ts +11 -16
  44. package/dist/scan.js +31 -8
  45. package/dist/score-core.js +3 -9
  46. package/dist/setup-plan.d.ts +6 -26
  47. package/dist/setup-plan.js +27 -60
  48. package/dist/vigilesrc.schema.json +18 -3
  49. package/package.json +2 -2
  50. package/packages/eslint-config/index.mjs +61 -0
  51. package/dist/core/rule-meta.d.ts +0 -94
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
@@ -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(report: ScanReport, opts: BuildAuditReportOptions): AuditReport;
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.
@@ -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
- /** The scan's concrete finding lists, each present only when non-empty. */
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(report, opts) {
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 = (0, audit_score_js_1.auditScore)(report, { firingMeasured: opts.firingMeasured });
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,