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.
Files changed (129) hide show
  1. package/action.yml +18 -0
  2. package/dist/adapters/claude-code/event-capability.js +24 -8
  3. package/dist/adapters/claude-code/hook-protocol.js +2 -1
  4. package/dist/adapters/codex/hook-protocol.js +2 -1
  5. package/dist/audit-report.d.ts +14 -1
  6. package/dist/audit-report.js +21 -5
  7. package/dist/audit-report.template.html +33 -28
  8. package/dist/audit-score.d.ts +4 -1
  9. package/dist/audit-score.js +3 -1
  10. package/dist/audit-verdict.d.ts +3 -1
  11. package/dist/cli-flag-check.d.ts +36 -0
  12. package/dist/cli-flag-check.js +76 -1
  13. package/dist/cli-flags.d.ts +1 -1
  14. package/dist/cli-main.d.ts +2 -2
  15. package/dist/cli-main.js +684 -434
  16. package/dist/core/CLAUDE.md.spec.js +2 -2
  17. package/dist/core/apply-rules.d.ts +71 -0
  18. package/dist/core/apply-rules.js +48 -0
  19. package/dist/core/bash-effects.d.ts +0 -57
  20. package/dist/core/bash-effects.js +0 -147
  21. package/dist/core/compile-generator.d.ts +6 -6
  22. package/dist/core/compile-generator.js +4 -4
  23. package/dist/core/compile.d.ts +72 -8
  24. package/dist/core/compile.js +276 -133
  25. package/dist/core/config-migrations.d.ts +69 -0
  26. package/dist/core/config-migrations.js +145 -0
  27. package/dist/core/config-schema.d.ts +166 -160
  28. package/dist/core/config-schema.js +207 -244
  29. package/dist/core/coverage.d.ts +16 -0
  30. package/dist/core/coverage.js +22 -0
  31. package/dist/core/doc-refs.d.ts +3 -2
  32. package/dist/core/doc-refs.js +2 -2
  33. package/dist/core/enforce-marker.d.ts +28 -0
  34. package/dist/core/enforce-marker.js +34 -0
  35. package/dist/core/eslint-inventory.d.ts +96 -0
  36. package/dist/core/eslint-inventory.js +251 -0
  37. package/dist/core/event-capability.d.ts +5 -1
  38. package/dist/core/frame.d.ts +43 -2
  39. package/dist/core/frame.js +85 -2
  40. package/dist/core/generate-schema.d.ts +3 -2
  41. package/dist/core/generate-schema.js +2 -2
  42. package/dist/core/generate-types.d.ts +11 -2
  43. package/dist/core/generate-types.js +12 -5
  44. package/dist/core/hook-command.d.ts +172 -0
  45. package/dist/core/hook-command.js +277 -0
  46. package/dist/core/hook-delivery.d.ts +133 -0
  47. package/dist/core/hook-delivery.js +150 -0
  48. package/dist/core/hook-paths.d.ts +14 -0
  49. package/dist/core/hook-paths.js +22 -0
  50. package/dist/core/hook-program.d.ts +4 -4
  51. package/dist/core/hook-program.js +13 -25
  52. package/dist/core/hook-state.d.ts +1 -1
  53. package/dist/core/hook-state.js +1 -1
  54. package/dist/core/instruction-remedies.d.ts +35 -0
  55. package/dist/core/instruction-remedies.js +70 -1
  56. package/dist/core/integrity-header.d.ts +54 -0
  57. package/dist/core/integrity-header.js +90 -0
  58. package/dist/core/integrity.d.ts +1 -25
  59. package/dist/core/integrity.js +16 -74
  60. package/dist/core/linter-adapter.d.ts +28 -4
  61. package/dist/core/linters.d.ts +8 -1
  62. package/dist/core/linters.js +116 -81
  63. package/dist/core/orphans.d.ts +3 -5
  64. package/dist/core/orphans.js +9 -10
  65. package/dist/core/presets.d.ts +31 -34
  66. package/dist/core/presets.js +25 -38
  67. package/dist/core/rule-catalog.d.ts +11 -12
  68. package/dist/core/rule-catalog.js +25 -94
  69. package/dist/core/rule.d.ts +213 -0
  70. package/dist/core/rule.js +37 -0
  71. package/dist/core/skill-resources.d.ts +85 -15
  72. package/dist/core/skill-resources.js +63 -37
  73. package/dist/core/source-refs.d.ts +3 -23
  74. package/dist/core/source-refs.js +3 -27
  75. package/dist/core/test-utils.d.ts +13 -0
  76. package/dist/core/test-utils.js +40 -1
  77. package/dist/core/types.d.ts +19 -329
  78. package/dist/core/validate.d.ts +14 -14
  79. package/dist/core/validate.js +87 -73
  80. package/dist/coverage-evidence.js +2 -3
  81. package/dist/deprecated-key-files.d.ts +6 -0
  82. package/dist/deprecated-key-files.js +7 -6
  83. package/dist/exclude.d.ts +3 -1
  84. package/dist/exclude.js +9 -33
  85. package/dist/harness-assert.d.ts +18 -0
  86. package/dist/harness-assert.js +38 -0
  87. package/dist/hook-check-install.js +15 -6
  88. package/dist/hook-check.d.ts +1 -3
  89. package/dist/hook-check.js +3 -5
  90. package/dist/hook-install.d.ts +7 -41
  91. package/dist/hook-install.js +29 -96
  92. package/dist/hook-runtime.js +2 -1
  93. package/dist/load-hook.d.ts +3 -2
  94. package/dist/load-hook.js +28 -6
  95. package/dist/optimize.d.ts +2 -1
  96. package/dist/overrides.d.ts +29 -0
  97. package/dist/overrides.js +51 -0
  98. package/dist/plugin-loader.d.ts +23 -0
  99. package/dist/plugin-loader.js +42 -12
  100. package/dist/root-globs.d.ts +9 -0
  101. package/dist/root-globs.js +48 -0
  102. package/dist/rule-routing.js +6 -3
  103. package/dist/rules/CLAUDE.md.spec.d.ts +3 -0
  104. package/dist/rules/CLAUDE.md.spec.js +22 -0
  105. package/dist/rules/groups.d.ts +32 -0
  106. package/dist/rules/groups.js +27 -0
  107. package/dist/rules/index.d.ts +412 -0
  108. package/dist/{core/rule-meta.js → rules/index.js} +329 -200
  109. package/dist/rules/skill-resource-resolves.d.ts +36 -0
  110. package/dist/rules/skill-resource-resolves.js +51 -0
  111. package/dist/run-hook.d.ts +27 -3
  112. package/dist/run-hook.js +48 -12
  113. package/dist/scan-core.d.ts +103 -29
  114. package/dist/scan-core.js +178 -186
  115. package/dist/scan-files.d.ts +0 -8
  116. package/dist/scan-files.js +79 -24
  117. package/dist/scan.d.ts +23 -28
  118. package/dist/scan.js +64 -18
  119. package/dist/score-core.js +3 -9
  120. package/dist/setup-plan.d.ts +13 -27
  121. package/dist/setup-plan.js +46 -71
  122. package/dist/test-coverage.d.ts +3 -8
  123. package/dist/test-coverage.js +6 -6
  124. package/dist/test.d.ts +1 -1
  125. package/dist/vigilesrc.schema.json +1347 -121
  126. package/package.json +2 -2
  127. package/packages/eslint-config/index.mjs +61 -0
  128. package/skills/adopt-spec/SKILL.md +2 -1
  129. package/dist/core/rule-meta.d.ts +0 -82
@@ -39,6 +39,7 @@
39
39
  */
40
40
  import { type PluginScore } from "./score-core.js";
41
41
  import type { ScanReport } from "./scan.js";
42
+ import type { GradedView } from "./core/apply-rules.js";
42
43
  export type CategoryKey = "Truthfulness" | "Triggering" | "Structure" | "Safety" | "Tested" | "Evaluated";
43
44
  export interface CategoryScore {
44
45
  readonly key: CategoryKey;
@@ -106,7 +107,9 @@ export interface AuditScoreOptions {
106
107
  * any n/a ring are shown but excluded from the headline — the grade weighting is
107
108
  * UNCHANGED by the Tested/Evaluated split.
108
109
  */
109
- export declare function auditScore(report: ScanReport, opts?: AuditScoreOptions): AuditScore;
110
+ export declare function auditScore(
111
+ /** The graded view: an ungraded group's findings never reach a ring. */
112
+ report: GradedView<ScanReport>, opts?: AuditScoreOptions): AuditScore;
110
113
  /**
111
114
  * The ring's number as the reader sees it — THREE distinct labels, never two.
112
115
  * A measured `0` and an unasked question are different facts and must not render
@@ -497,7 +497,9 @@ function isEmptyAudit(r) {
497
497
  * any n/a ring are shown but excluded from the headline — the grade weighting is
498
498
  * UNCHANGED by the Tested/Evaluated split.
499
499
  */
500
- function auditScore(report, opts = {}) {
500
+ function auditScore(
501
+ /** The graded view: an ungraded group's findings never reach a ring. */
502
+ report, opts = {}) {
501
503
  if (isEmptyAudit(report)) {
502
504
  const categories = [
503
505
  "Truthfulness",
@@ -42,6 +42,7 @@ import { type AuditScore } from "./audit-score.js";
42
42
  import type { Recommendation } from "./optimize.js";
43
43
  import { type PluginScore } from "./score-core.js";
44
44
  import type { ScanReport } from "./scan.js";
45
+ import type { GradedView } from "./core/apply-rules.js";
45
46
  /**
46
47
  * The inputs the verdict needs — exactly the pieces {@link buildAuditReport}
47
48
  * already holds. `score` is the authoritative base (`overall` + `grade`) the
@@ -49,7 +50,8 @@ import type { ScanReport } from "./scan.js";
49
50
  * it; `recommendations` is the array whose indices `perRecommendation` aligns to.
50
51
  */
51
52
  export interface VerdictInput {
52
- readonly report: ScanReport;
53
+ /** The graded view: an ungraded group's findings never reach the verdict. */
54
+ readonly report: GradedView<ScanReport>;
53
55
  readonly score: AuditScore;
54
56
  readonly recommendations: readonly Recommendation[];
55
57
  }
@@ -70,4 +70,40 @@ export declare function unknownFlags(command: string, argv: readonly string[]):
70
70
  export declare function nearestFlag(unknown: string, known: readonly FlagSpec[]): string | undefined;
71
71
  /** The message printed to stderr for one unrecognised flag. */
72
72
  export declare function formatUnknownFlag(command: string, flag: string): string;
73
+ /**
74
+ * Which of a verb's arguments name a PATH. The CLI runs every command from the
75
+ * project root it resolves once (`findProjectRoot`), but a path the user types
76
+ * means "from where I typed it"; these are the arguments re-expressed from the
77
+ * root before the command runs. One table beside the flag table, so a new
78
+ * path-valued flag is declared where flags are.
79
+ */
80
+ interface PathArguments {
81
+ /**
82
+ * Which directory the verb runs from. `project`: the resolved project root.
83
+ * `invocation`: where it was typed — `init` makes THAT directory a project
84
+ * (a workspace member it sets up must not become its monorepo's root), and
85
+ * `hook-runtime` takes its root from the harness event, not from a directory.
86
+ */
87
+ readonly root: "project" | "invocation";
88
+ /** Positionals that are paths: all of them, all after the first (a kind), or none. */
89
+ readonly positionals: "all" | "after-first" | "none";
90
+ /** `--flag=` specs whose value is a path. */
91
+ readonly flags: readonly FlagSpec[];
92
+ }
93
+ export declare const PATH_ARGUMENTS: Readonly<Record<Verb, PathArguments>>;
94
+ /**
95
+ * Whether `command` runs from the resolved project root. A word that is not a
96
+ * verb (`--version`, a typo) runs nowhere in particular: it is answered where
97
+ * it was typed.
98
+ */
99
+ export declare function runsFromProjectRoot(command: string): boolean;
100
+ /**
101
+ * The verb's arguments (everything after the verb) with each path argument
102
+ * passed through `rebase`. Flags that do not take a path, words, and `--`
103
+ * itself are returned unchanged. After `--` every word is an operand: a path
104
+ * among them is rebased like any other positional, and a dash-led one is never
105
+ * mistaken for a path-valued flag.
106
+ */
107
+ export declare function rebasePathArgs(command: string, argv: readonly string[], rebase: (path: string) => string): readonly string[];
108
+ export {};
73
109
  //# sourceMappingURL=cli-flag-check.d.ts.map
@@ -39,11 +39,13 @@
39
39
  * rejection in a user's face.
40
40
  */
41
41
  Object.defineProperty(exports, "__esModule", { value: true });
42
- exports.COMMAND_FLAGS = exports.SHARED_FLAGS = void 0;
42
+ exports.PATH_ARGUMENTS = exports.COMMAND_FLAGS = exports.SHARED_FLAGS = void 0;
43
43
  exports.knownFlagsFor = knownFlagsFor;
44
44
  exports.unknownFlags = unknownFlags;
45
45
  exports.nearestFlag = nearestFlag;
46
46
  exports.formatUnknownFlag = formatUnknownFlag;
47
+ exports.runsFromProjectRoot = runsFromProjectRoot;
48
+ exports.rebasePathArgs = rebasePathArgs;
47
49
  /**
48
50
  * Flags every verb accepts: the config overrides applied in `main()` before
49
51
  * dispatch (see `applyConfigFlags`) plus the harness override, which the shared
@@ -80,6 +82,9 @@ exports.COMMAND_FLAGS = {
80
82
  compile: [],
81
83
  eject: ["--keep-spec"],
82
84
  lint: [
85
+ // A preset applied on top of the repo's own config for this run (the same
86
+ // names `extends` takes) — see parsePresetFlags.
87
+ "--preset=",
83
88
  "--bundles=",
84
89
  "--summary",
85
90
  "--json",
@@ -100,6 +105,7 @@ exports.COMMAND_FLAGS = {
100
105
  "--update",
101
106
  ],
102
107
  audit: [
108
+ "--preset=",
103
109
  "--json",
104
110
  "--md",
105
111
  "--single",
@@ -203,4 +209,73 @@ function formatUnknownFlag(command, flag) {
203
209
  lines.push(` Flags for \`${command}\`: ${[...known].sort().join(" ")}`, ` \`vigiles ${command} --help\` lists them with descriptions.`);
204
210
  return lines.join("\n");
205
211
  }
212
+ exports.PATH_ARGUMENTS = {
213
+ init: { root: "invocation", positionals: "none", flags: ["--target="] },
214
+ compile: { root: "project", positionals: "all", flags: [] },
215
+ eject: { root: "project", positionals: "all", flags: [] },
216
+ lint: { root: "project", positionals: "all", flags: ["--json-out="] },
217
+ test: { root: "project", positionals: "all", flags: [] },
218
+ eval: { root: "project", positionals: "all", flags: [] },
219
+ audit: {
220
+ root: "project",
221
+ positionals: "all",
222
+ flags: ["--out=", "--capability-diff=", "--prompts="],
223
+ },
224
+ // `generate <kind> [out]`: the kind is a word, the rest are paths.
225
+ generate: { root: "project", positionals: "after-first", flags: [] },
226
+ // The harness supplies its argv; its paths are already what it means.
227
+ "hook-runtime": { root: "invocation", positionals: "none", flags: [] },
228
+ };
229
+ /** The verb's row, or undefined for a word that is not a verb. */
230
+ function pathArgumentsOf(command) {
231
+ return Object.entries(exports.PATH_ARGUMENTS).find(([verb]) => verb === command)?.[1];
232
+ }
233
+ /**
234
+ * Whether `command` runs from the resolved project root. A word that is not a
235
+ * verb (`--version`, a typo) runs nowhere in particular: it is answered where
236
+ * it was typed.
237
+ */
238
+ function runsFromProjectRoot(command) {
239
+ return pathArgumentsOf(command)?.root === "project";
240
+ }
241
+ /** Which of the positional argument indexes are paths, per the verb's spec. */
242
+ function pathPositionalIndexes(positionals, indexes) {
243
+ switch (positionals) {
244
+ case "all":
245
+ return indexes;
246
+ case "after-first":
247
+ return indexes.slice(1);
248
+ case "none":
249
+ return [];
250
+ }
251
+ }
252
+ /** A positional word: before `--`, one not led by a dash; after it, every word. */
253
+ function isOperand(arg, index, end) {
254
+ if (index < end)
255
+ return !arg.startsWith("-");
256
+ return index > end;
257
+ }
258
+ /**
259
+ * The verb's arguments (everything after the verb) with each path argument
260
+ * passed through `rebase`. Flags that do not take a path, words, and `--`
261
+ * itself are returned unchanged. After `--` every word is an operand: a path
262
+ * among them is rebased like any other positional, and a dash-led one is never
263
+ * mistaken for a path-valued flag.
264
+ */
265
+ function rebasePathArgs(command, argv, rebase) {
266
+ const spec = pathArgumentsOf(command);
267
+ if (!spec)
268
+ return [...argv];
269
+ const end = argv.includes("--") ? argv.indexOf("--") : argv.length;
270
+ const positionalIndexes = argv.flatMap((a, i) => isOperand(a, i, end) ? [i] : []);
271
+ const pathPositionals = new Set(pathPositionalIndexes(spec.positionals, positionalIndexes));
272
+ return argv.map((arg, i) => {
273
+ if (pathPositionals.has(i))
274
+ return rebase(arg);
275
+ if (i >= end)
276
+ return arg;
277
+ const flag = spec.flags.find((f) => arg.startsWith(f));
278
+ return flag ? `${flag}${rebase(arg.slice(flag.length))}` : arg;
279
+ });
280
+ }
206
281
  //# sourceMappingURL=cli-flag-check.js.map
@@ -18,5 +18,5 @@ import type { VigilesConfig } from "./core/types.js";
18
18
  * Unknown flags are left untouched (each command parses its own besides
19
19
  * these). Returns a new object; the input is not mutated.
20
20
  */
21
- export declare function applyConfigFlags(config: VigilesConfig, args: readonly string[]): VigilesConfig;
21
+ export declare function applyConfigFlags<C extends VigilesConfig>(config: C, args: readonly string[]): C;
22
22
  //# sourceMappingURL=cli-flags.d.ts.map
@@ -58,6 +58,8 @@ interface LintReport {
58
58
  mcpToolErrors: number;
59
59
  hookScriptIssues: number;
60
60
  hookScriptErrors: number;
61
+ handWrittenHookIssues: number;
62
+ handWrittenHookErrors: number;
61
63
  disallowedToolIssues: number;
62
64
  disallowedToolErrors: number;
63
65
  descriptionOverlapIssues: number;
@@ -68,8 +70,6 @@ interface LintReport {
68
70
  frontmatterValidErrors: number;
69
71
  mcpHookIssues: number;
70
72
  mcpHookErrors: number;
71
- preferCompiledHookIssues: number;
72
- preferCompiledHookErrors: number;
73
73
  lethalTrifectaIssues: number;
74
74
  lethalTrifectaErrors: number;
75
75
  skillResourceIssues: number;