vigiles 30.0.1 → 31.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/linting.js CHANGED
@@ -1,38 +1,26 @@
1
1
  "use strict";
2
+ // 🔴 PUBLIC ENTRY POINT `vigiles/linting` — every export here is a promise to users. The default for a
3
+ // symbol is INTERNAL. It is exported only if (a) a NAMED external consumer uses it, or (b) it is
4
+ // a deliberate extension point listed in STABILITY.md (the adapter kit is the example). "Might
5
+ // be useful" is neither. Review point: the diff of `api-surface/vigiles-linting.api.md`, which
6
+ // `npm run api:check` fails on.
2
7
  /**
3
- * `vigiles/linting` — Pillar 1 entry point: the **linting layer** for instruction
4
- * files. The spec builders/types that describe a CLAUDE.md, a SKILL.md or an
5
- * agent, plus the public compile entry points, under one concern-named import.
8
+ * `vigiles/linting` — Pillar 1 entry point: what a spec AUTHOR imports to describe a CLAUDE.md,
9
+ * a SKILL.md or an agent — the builders, the verified-reference constructors and their types.
10
+ * Compiling is the CLI's job (`vigiles compile` / `vigiles lint`), not this subpath's.
6
11
  *
7
- * Curated (named, not `export *`) so the internal compiler validators, hash
8
- * helpers, and the linter cross-reference ENGINE stay out of the public surface,
9
- * the api reports, and the docs site (the CLI imports those from the source).
12
+ * Curated (named, not `export *`) so the internal compiler, validators, hash helpers and the
13
+ * linter cross-reference ENGINE stay out of the public surface, the api reports and the docs.
10
14
  *
11
- * 🔴 THAT SENTENCE USED TO BE FALSE, and so did the one after it (fixed
12
- * 2026-08-21). The file claimed to be curated while `export * from
13
- * "./core/spec.js"` sat one line below it, and it claimed "the spec builders are
14
- * also at the package root (`vigiles`)" — measured against `vigiles.api.md`: 191
15
- * exports there and zero matches for `claude`, `agent`, `enforce` or `result`.
16
- * The builders' second door is `vigiles/spec`, not the root. Both claims read as
17
- * documentation of a decision and were descriptions of the opposite one; a
18
- * header nobody re-reads is where an `export *` hides best.
19
- *
20
- * WHAT THE CURATION DROPS (28 symbols, measured — nothing in this repo imported
21
- * any of them from here; every in-repo user takes them from `vigiles/spec`, and
22
- * the one live consumer of this subpath in the docs takes `compileAgent`): the
23
- * typed-COMPOSITION family — `experimental_pipe`/`_pipeStep`/`_start`/
24
- * `_andThen`/`_needs`, `Pipeline`, `PipeStep`, `Supplies`, `Handoff`,
25
- * `NeedsContract`, `OkOf`, `TypedAgentSpec`, `TypedOutcome`, `Shape`,
26
- * `OutputFieldType` and the `result()` builder. Those verify HANDOFFS between
27
- * workers; they compile to nothing and lint nothing, so they are not pillar 1.
28
- *
29
- * ⚠️ The cut is not a clean slice along that line, and pretending otherwise
30
- * would strand a signature: the `result()` FUNCTION leaves, but the
31
- * `OutputContract` TYPE stays, because `compileAgent`/`compileSkill` name it in
32
- * their own types. A consumer who needs to BUILD one imports `vigiles/spec`.
15
+ * WHAT THE CURATION DROPS (28 symbols, measured 2026-08-21 — nothing in this repo imported any
16
+ * of them from here; every in-repo user takes them from `vigiles/spec`): the typed-COMPOSITION
17
+ * family — `experimental_pipe`/`_pipeStep`/`_start`/`_andThen`/`_needs`, `Pipeline`, `PipeStep`,
18
+ * `Supplies`, `Handoff`, `NeedsContract`, `OkOf`, `TypedAgentSpec`, `TypedOutcome`, `Shape`,
19
+ * `OutputFieldType` and the `result()` builder. Those verify HANDOFFS between workers; they
20
+ * compile to nothing and lint nothing, so they are not pillar 1.
33
21
  */
34
22
  Object.defineProperty(exports, "__esModule", { value: true });
35
- exports.compileRailway = exports.compileAgent = exports.compileSkill = exports.compileClaude = exports.BUILTIN_LINTERS = exports.agent = exports.instructions = exports.claude = exports.experimental_agent = exports.experimental_skill = exports.project = exports.glob = exports.dir = exports.ref = exports.symbol = exports.cmd = exports.file = exports.guard = exports.guidance = exports.enforce = exports.experimental_effect = exports.prose = exports.instructionFile = void 0;
23
+ exports.BUILTIN_LINTERS = exports.agent = exports.instructions = exports.claude = exports.experimental_agent = exports.experimental_skill = exports.project = exports.glob = exports.dir = exports.ref = exports.symbol = exports.cmd = exports.file = exports.guard = exports.guidance = exports.enforce = exports.experimental_effect = exports.prose = exports.instructionFile = void 0;
36
24
  // --- the spec authoring builders: rules, refs, prose, and the three spec kinds ---
37
25
  var spec_js_1 = require("./core/spec.js");
38
26
  // instruction files
@@ -67,12 +55,11 @@ Object.defineProperty(exports, "instructions", { enumerable: true, get: function
67
55
  Object.defineProperty(exports, "agent", { enumerable: true, get: function () { return spec_js_1.agent; } });
68
56
  var spec_js_2 = require("./core/spec.js");
69
57
  Object.defineProperty(exports, "BUILTIN_LINTERS", { enumerable: true, get: function () { return spec_js_2.BUILTIN_LINTERS; } });
70
- // Compile: only the public entry points + their option/result types.
71
- var compile_js_1 = require("./core/compile.js");
72
- Object.defineProperty(exports, "compileClaude", { enumerable: true, get: function () { return compile_js_1.compileClaude; } });
73
- Object.defineProperty(exports, "compileSkill", { enumerable: true, get: function () { return compile_js_1.compileSkill; } });
74
- Object.defineProperty(exports, "compileAgent", { enumerable: true, get: function () { return compile_js_1.compileAgent; } });
75
- Object.defineProperty(exports, "compileRailway", { enumerable: true, get: function () { return compile_js_1.compileRailway; } });
58
+ // NO COMPILE ENTRY POINTS HERE (removed in the major that ships #257). `compileClaude`,
59
+ // `compileSkill`, `compileAgent`, `compileRailway` and their option/result types were public
60
+ // with no external caller — measured across the repos that depend on vigiles, every import is a
61
+ // spec builder — and the promise froze them synchronous while the symbol check they run became
62
+ // async. Spec authors run `vigiles compile`; the CLI imports the compiler from source.
76
63
  // core/linters is the cross-reference ENGINE (checkLinterRule/editDistance/…),
77
64
  // consumed by compile — not part of the public authoring surface.
78
65
  //# sourceMappingURL=linting.js.map
@@ -5,13 +5,30 @@
5
5
  * every "cannot tell".
6
6
  */
7
7
  export declare function trackedLocalFiles(root: string): string[];
8
+ /**
9
+ * Does the COMMITTED `.vigiles/.gitignore` (the one at `HEAD`) lack entries
10
+ * vigiles needs — i.e. will vigiles' additions show up as a change to a tracked
11
+ * file until someone commits them.
12
+ *
13
+ * The question is asked of `HEAD`, not of the worktree's dirtiness, and that
14
+ * is the point (Codex review on #275, third pass). "The file is modified" was
15
+ * the earlier predicate; it could not tell vigiles' additions from the owner's
16
+ * own unrelated edit, and then advised committing work in progress. Reading the
17
+ * committed copy answers only for vigiles' entries, staged or not, and says
18
+ * nothing once they are committed, whatever else the owner is editing.
19
+ * `HEAD:./path`, not `HEAD:path`: without `./` git resolves the path from the
20
+ * REPOSITORY root, so a package nested in a larger worktree read the wrong file
21
+ * — or none — and stayed silent (Codex review on #275, gitrevisions(7)).
22
+ * Silent on every "cannot tell": not in a repo, no `HEAD`, file not committed.
23
+ */
24
+ export declare function committedIgnoreFileLacksEntries(root: string): boolean;
8
25
  /**
9
26
  * The one-line warning for {@link trackedLocalFiles}, or `null` when there is
10
27
  * nothing to say. Files inside a tracked local DIRECTORY (`state/`,
11
28
  * `eval-cache/`) are named by that directory, so one line stays one line and the
12
29
  * command it prints untracks all of them.
13
30
  */
14
- export declare function formatTrackedLocalFiles(tracked: readonly string[]): string | null;
31
+ export declare function formatTrackedLocalFiles(tracked: readonly string[], committedLacksEntries?: boolean): string | null;
15
32
  /** Print the warning for `root` to stderr when there is one. CLI-only. */
16
33
  export declare function warnTrackedLocalFiles(root: string): void;
17
34
  //# sourceMappingURL=local-files-tracked.d.ts.map
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.trackedLocalFiles = trackedLocalFiles;
4
+ exports.committedIgnoreFileLacksEntries = committedIgnoreFileLacksEntries;
4
5
  exports.formatTrackedLocalFiles = formatTrackedLocalFiles;
5
6
  exports.warnTrackedLocalFiles = warnTrackedLocalFiles;
6
7
  /**
@@ -20,6 +21,8 @@ exports.warnTrackedLocalFiles = warnTrackedLocalFiles;
20
21
  const node_child_process_1 = require("node:child_process");
21
22
  const node_path_1 = require("node:path");
22
23
  const local_files_js_1 = require("./local-files.js");
24
+ /** `.vigiles/.gitignore`, repo-relative. */
25
+ const IGNORE_FILE = node_path_1.posix.join(local_files_js_1.VIGILES_DIR, local_files_js_1.LOCAL_GITIGNORE_FILE);
23
26
  /**
24
27
  * The per-checkout files under `<root>/.vigiles/` that git tracks, as
25
28
  * repo-relative paths from `root`. Empty when nothing is tracked, when `root` is
@@ -42,28 +45,67 @@ function trackedLocalFiles(root) {
42
45
  return [];
43
46
  }
44
47
  }
48
+ /**
49
+ * Does the COMMITTED `.vigiles/.gitignore` (the one at `HEAD`) lack entries
50
+ * vigiles needs — i.e. will vigiles' additions show up as a change to a tracked
51
+ * file until someone commits them.
52
+ *
53
+ * The question is asked of `HEAD`, not of the worktree's dirtiness, and that
54
+ * is the point (Codex review on #275, third pass). "The file is modified" was
55
+ * the earlier predicate; it could not tell vigiles' additions from the owner's
56
+ * own unrelated edit, and then advised committing work in progress. Reading the
57
+ * committed copy answers only for vigiles' entries, staged or not, and says
58
+ * nothing once they are committed, whatever else the owner is editing.
59
+ * `HEAD:./path`, not `HEAD:path`: without `./` git resolves the path from the
60
+ * REPOSITORY root, so a package nested in a larger worktree read the wrong file
61
+ * — or none — and stayed silent (Codex review on #275, gitrevisions(7)).
62
+ * Silent on every "cannot tell": not in a repo, no `HEAD`, file not committed.
63
+ */
64
+ function committedIgnoreFileLacksEntries(root) {
65
+ try {
66
+ const r = (0, node_child_process_1.spawnSync)("git", ["show", `HEAD:./${IGNORE_FILE}`], {
67
+ cwd: root,
68
+ encoding: "utf-8",
69
+ stdio: ["ignore", "pipe", "ignore"],
70
+ });
71
+ if (r.status !== 0 || typeof r.stdout !== "string")
72
+ return false;
73
+ return (0, local_files_js_1.entriesNotInEffect)(r.stdout).length > 0;
74
+ }
75
+ catch {
76
+ return false;
77
+ }
78
+ }
45
79
  /**
46
80
  * The one-line warning for {@link trackedLocalFiles}, or `null` when there is
47
81
  * nothing to say. Files inside a tracked local DIRECTORY (`state/`,
48
82
  * `eval-cache/`) are named by that directory, so one line stays one line and the
49
83
  * command it prints untracks all of them.
50
84
  */
51
- function formatTrackedLocalFiles(tracked) {
52
- if (tracked.length === 0)
53
- return null;
54
- // `.vigiles/state/.claude/hooks/x.json` → `.vigiles/state`: the list entry.
55
- const entries = [
56
- ...new Set(tracked.map((p) => p.split("/").slice(0, 2).join("/"))),
57
- ];
58
- const one = entries.length === 1;
59
- return (`⚠ ${entries.join(", ")} ${one ? "is" : "are"} tracked by git, but ` +
60
- `${local_files_js_1.VIGILES_DIR}/ local files describe one checkout and would credit a ` +
61
- `machine where nothing ran. .gitignore does not untrack a tracked file; ` +
62
- `untrack ${one ? "it" : "them"} once: git rm -r --cached ${entries.join(" ")}`);
85
+ function formatTrackedLocalFiles(tracked, committedLacksEntries = false) {
86
+ const lines = [];
87
+ if (tracked.length > 0) {
88
+ // `.vigiles/state/.claude/hooks/x.json` → `.vigiles/state`: the list entry.
89
+ const entries = [
90
+ ...new Set(tracked.map((p) => p.split("/").slice(0, 2).join("/"))),
91
+ ];
92
+ const one = entries.length === 1;
93
+ lines.push(`⚠ ${entries.join(", ")} ${one ? "is" : "are"} tracked by git, but ` +
94
+ `${local_files_js_1.VIGILES_DIR}/ local files describe one checkout and would credit a ` +
95
+ `machine where nothing ran. .gitignore does not untrack a tracked file; ` +
96
+ `untrack ${one ? "it" : "them"} once: git rm -r --cached ${entries.join(" ")}`);
97
+ }
98
+ // Not "untrack it": the repo may keep its own rules there, and untracking
99
+ // would take them away from everyone else.
100
+ if (committedLacksEntries)
101
+ lines.push(`⚠ ${IGNORE_FILE} is tracked by git and its committed version lacks ` +
102
+ `vigiles' local-file entries, which vigiles adds to your copy. Commit ` +
103
+ `those lines once; entries are appended only when missing.`);
104
+ return lines.length > 0 ? lines.join("\n") : null;
63
105
  }
64
106
  /** Print the warning for `root` to stderr when there is one. CLI-only. */
65
107
  function warnTrackedLocalFiles(root) {
66
- const line = formatTrackedLocalFiles(trackedLocalFiles(root));
108
+ const line = formatTrackedLocalFiles(trackedLocalFiles(root), committedIgnoreFileLacksEntries(root));
67
109
  if (line)
68
110
  process.stderr.write(line + "\n");
69
111
  }
@@ -35,6 +35,8 @@ export declare const LOCAL_FILES: readonly LocalFile[];
35
35
  */
36
36
  export declare const COMMITTED_PATHS: readonly string[];
37
37
  /** The header comment on a `.vigiles/.gitignore` vigiles creates. */
38
+ /** The ignore file vigiles keeps inside `.vigiles/`. One spelling for every reader. */
39
+ export declare const LOCAL_GITIGNORE_FILE = ".gitignore";
38
40
  export declare const LOCAL_GITIGNORE_HEADER: readonly string[];
39
41
  /** The ignore lines, in order: every local path, then the file itself. */
40
42
  export declare function localIgnoreEntries(): string[];
@@ -49,8 +51,9 @@ export declare function localIgnoreEntries(): string[];
49
51
  * or reordered. Appending is enough because git's last matching rule wins.
50
52
  *
51
53
  * "In effect" is judged the way git reads the file, not by text membership:
52
- * lines in order, a later `!/entry` cancels an earlier `/entry`, and leading
53
- * whitespace is part of the pattern (only trailing whitespace is dropped).
54
+ * lines in order, a later negation cancels an earlier `/entry` (see
55
+ * {@link inEffect}), and leading whitespace is part of the pattern (only
56
+ * trailing whitespace is dropped).
54
57
  * Both cases were measured with `git check-ignore`: `/coverage.json` followed
55
58
  * by `!/coverage.json`, and ` /coverage.json`, each leave the file NOT
56
59
  * ignored while a trimmed set would call the entry present.
@@ -58,5 +61,11 @@ export declare function localIgnoreEntries(): string[];
58
61
  * Costs one read on the hot path. Best-effort: any fs error is swallowed —
59
62
  * keeping git tidy must never break a hook, a test run or an audit.
60
63
  */
64
+ /**
65
+ * The entries a `.vigiles/.gitignore` with this content does NOT put in effect.
66
+ * One reader for both questions — "what to append" ({@link ensureLocalFilesIgnored})
67
+ * and "does the committed copy already carry them" (the CLI's tracked-file check).
68
+ */
69
+ export declare function entriesNotInEffect(content: string): string[];
61
70
  export declare function ensureLocalFilesIgnored(vigilesDir: string): void;
62
71
  //# sourceMappingURL=local-files.d.ts.map
@@ -1,7 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.LOCAL_GITIGNORE_HEADER = exports.COMMITTED_PATHS = exports.LOCAL_FILES = exports.EVAL_CACHE_DIR = exports.HOOK_OBSERVATIONS_FILE = exports.GUARD_LEDGER_FILE = exports.EFFECT_ACTIVE_FILE = exports.ACTIVE_AGENT_FILE = exports.ACTIVE_SKILL_FILE = exports.HOOK_STATE_DIR = exports.LEDGER_FILE = exports.COVERAGE_ARTIFACT_FILE = exports.VIGILES_DIR = void 0;
3
+ exports.LOCAL_GITIGNORE_HEADER = exports.LOCAL_GITIGNORE_FILE = exports.COMMITTED_PATHS = exports.LOCAL_FILES = exports.EVAL_CACHE_DIR = exports.HOOK_OBSERVATIONS_FILE = exports.GUARD_LEDGER_FILE = exports.EFFECT_ACTIVE_FILE = exports.ACTIVE_AGENT_FILE = exports.ACTIVE_SKILL_FILE = exports.HOOK_STATE_DIR = exports.LEDGER_FILE = exports.COVERAGE_ARTIFACT_FILE = exports.VIGILES_DIR = void 0;
4
4
  exports.localIgnoreEntries = localIgnoreEntries;
5
+ exports.entriesNotInEffect = entriesNotInEffect;
5
6
  exports.ensureLocalFilesIgnored = ensureLocalFilesIgnored;
6
7
  /**
7
8
  * The files vigiles writes into a project's `.vigiles/` that describe ONE
@@ -108,6 +109,8 @@ exports.COMMITTED_PATHS = [
108
109
  "action-gates.json", // declared action gates (`action-gate.ts`)
109
110
  ];
110
111
  /** The header comment on a `.vigiles/.gitignore` vigiles creates. */
112
+ /** The ignore file vigiles keeps inside `.vigiles/`. One spelling for every reader. */
113
+ exports.LOCAL_GITIGNORE_FILE = ".gitignore";
111
114
  exports.LOCAL_GITIGNORE_HEADER = [
112
115
  "# Written by vigiles. These files describe one checkout on one machine and are",
113
116
  "# never committed. Everything else in .vigiles/ is the project's: commit it.",
@@ -116,16 +119,25 @@ exports.LOCAL_GITIGNORE_HEADER = [
116
119
  function localIgnoreEntries() {
117
120
  return [
118
121
  ...exports.LOCAL_FILES.map((f) => `/${f.name}${f.dir ? "/" : ""}`),
119
- "/.gitignore",
122
+ `/${exports.LOCAL_GITIGNORE_FILE}`,
120
123
  ];
121
124
  }
122
- /** Is `entry` ignoring its path after git reads `lines` top to bottom. */
125
+ /**
126
+ * Is `entry` ignoring its path after git reads `lines` top to bottom.
127
+ *
128
+ * Conservative on purpose: ANY negation after the entry's last occurrence counts
129
+ * as cancelling it. Git re-includes on `!/coverage.json`, but equally on
130
+ * `!coverage.json` or `!*.json` (last matching pattern wins), and matching
131
+ * gitignore globs here would be a second, partial implementation of git. The
132
+ * cost of being conservative is one extra append after an unrelated negation;
133
+ * the next call finds the entries last and leaves the file alone.
134
+ */
123
135
  function inEffect(lines, entry) {
124
136
  let on = false;
125
137
  for (const line of lines) {
126
138
  if (line === entry)
127
139
  on = true;
128
- else if (line === `!${entry}`)
140
+ else if (line.startsWith("!"))
129
141
  on = false;
130
142
  }
131
143
  return on;
@@ -141,8 +153,9 @@ function inEffect(lines, entry) {
141
153
  * or reordered. Appending is enough because git's last matching rule wins.
142
154
  *
143
155
  * "In effect" is judged the way git reads the file, not by text membership:
144
- * lines in order, a later `!/entry` cancels an earlier `/entry`, and leading
145
- * whitespace is part of the pattern (only trailing whitespace is dropped).
156
+ * lines in order, a later negation cancels an earlier `/entry` (see
157
+ * {@link inEffect}), and leading whitespace is part of the pattern (only
158
+ * trailing whitespace is dropped).
146
159
  * Both cases were measured with `git check-ignore`: `/coverage.json` followed
147
160
  * by `!/coverage.json`, and ` /coverage.json`, each leave the file NOT
148
161
  * ignored while a trimmed set would call the entry present.
@@ -150,9 +163,18 @@ function inEffect(lines, entry) {
150
163
  * Costs one read on the hot path. Best-effort: any fs error is swallowed —
151
164
  * keeping git tidy must never break a hook, a test run or an audit.
152
165
  */
166
+ /**
167
+ * The entries a `.vigiles/.gitignore` with this content does NOT put in effect.
168
+ * One reader for both questions — "what to append" ({@link ensureLocalFilesIgnored})
169
+ * and "does the committed copy already carry them" (the CLI's tracked-file check).
170
+ */
171
+ function entriesNotInEffect(content) {
172
+ const lines = content.split(/\r?\n/).map((l) => l.replace(/\s+$/, ""));
173
+ return localIgnoreEntries().filter((e) => !inEffect(lines, e));
174
+ }
153
175
  function ensureLocalFilesIgnored(vigilesDir) {
154
176
  try {
155
- const file = (0, node_path_1.resolve)(vigilesDir, ".gitignore");
177
+ const file = (0, node_path_1.resolve)(vigilesDir, exports.LOCAL_GITIGNORE_FILE);
156
178
  const entries = localIgnoreEntries();
157
179
  let current;
158
180
  try {
@@ -166,11 +188,10 @@ function ensureLocalFilesIgnored(vigilesDir) {
166
188
  (0, node_fs_1.writeFileSync)(file, [...exports.LOCAL_GITIGNORE_HEADER, ...entries, ""].join("\n"));
167
189
  return;
168
190
  }
169
- const lines = current.split(/\r?\n/).map((l) => l.replace(/\s+$/, ""));
170
- const missing = entries.filter((e) => !inEffect(lines, e));
191
+ const missing = entriesNotInEffect(current);
171
192
  if (missing.length === 0)
172
193
  return;
173
- const header = lines.includes(exports.LOCAL_GITIGNORE_HEADER[0])
194
+ const header = current.split(/\r?\n/).includes(exports.LOCAL_GITIGNORE_HEADER[0])
174
195
  ? []
175
196
  : exports.LOCAL_GITIGNORE_HEADER;
176
197
  const sep = current === "" || current.endsWith("\n") ? "" : "\n";
package/dist/test.js CHANGED
@@ -1,4 +1,9 @@
1
1
  "use strict";
2
+ // 🔴 PUBLIC ENTRY POINT `vigiles` — every export here is a promise to users. The default for a
3
+ // symbol is INTERNAL. It is exported only if (a) a NAMED external consumer uses it, or (b) it is
4
+ // a deliberate extension point listed in STABILITY.md (the adapter kit is the example). "Might
5
+ // be useful" is neither. Review point: the diff of `api-surface/vigiles.api.md`, which
6
+ // `npm run api:check` fails on.
2
7
  /**
3
8
  * `vigiles` (the package root) — the **free** testing surface: everything you can
4
9
  * run without a model call, and therefore without a bill.
package/dist/vitest.mjs CHANGED
@@ -1,3 +1,8 @@
1
+ // 🔴 PUBLIC ENTRY POINT `vigiles/vitest` — every export here is a promise to users. The default for a
2
+ // symbol is INTERNAL. It is exported only if (a) a NAMED external consumer uses it, or (b) it is
3
+ // a deliberate extension point listed in STABILITY.md (the adapter kit is the example). "Might
4
+ // be useful" is neither. Review point: the diff of `api-surface/vigiles-vitest.api.md`, which
5
+ // `npm run api:check` fails on.
1
6
  /* eslint-disable max-params, @typescript-eslint/no-explicit-any --
2
7
  The matcher signatures mirror the runtime vigilesMatchers (positional args),
3
8
  and `Matchers<T = any>` must match @vitest/expect's generic default to merge. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vigiles",
3
- "version": "30.0.1",
3
+ "version": "31.0.0",
4
4
  "description": "Audit, test and measure the harness your AI agent runs on — grade your CLAUDE.md / AGENTS.md, skills, subagents and hooks, run them against a scripted model, and measure whether they actually fire.",
5
5
  "keywords": [
6
6
  "claude-code",
@@ -138,6 +138,7 @@
138
138
  "dependencies": {
139
139
  "@ast-grep/napi": "^0.43.0",
140
140
  "@iarna/toml": "^2.2.5",
141
+ "@vscode/tree-sitter-wasm": "0.3.1",
141
142
  "ci-info": "^4.4.0",
142
143
  "cosmiconfig": "^9.0.1",
143
144
  "glob": "^13.0.6",
@@ -148,10 +149,5 @@
148
149
  "ts-essentials": "^10.2.1",
149
150
  "typescript": "^5.9.3",
150
151
  "zod": "^4.6.5"
151
- },
152
- "optionalDependencies": {
153
- "@ast-grep/lang-python": "^0.0.6",
154
- "@ast-grep/lang-ruby": "^0.0.7",
155
- "@ast-grep/lang-rust": "^0.0.7"
156
152
  }
157
153
  }