vigiles 28.0.0 → 29.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 +1 -1
- package/dist/adapter-registry.d.ts +39 -0
- package/dist/adapter-registry.js +45 -0
- package/dist/adapter.d.ts +8 -0
- package/dist/adapter.js +10 -1
- package/dist/adapters/claude-code/adapter.js +6 -0
- package/dist/adapters/claude-code/layout.d.ts +5 -0
- package/dist/adapters/claude-code/plugin-loader.d.ts +10 -1
- package/dist/adapters/claude-code/plugin-loader.js +10 -1
- package/dist/adapters/codex/adapter.js +6 -0
- package/dist/adapters/codex/layout.d.ts +51 -5
- package/dist/adapters/codex/layout.js +13 -4
- package/dist/adapters/opencode/adapter.js +6 -0
- package/dist/audit-report.template.html +1 -1
- package/dist/audit-score.d.ts +7 -0
- package/dist/audit-score.js +49 -2
- package/dist/cli-main.js +82 -20
- package/dist/core/adapter.d.ts +23 -0
- package/dist/core/compile.js +11 -1
- package/dist/core/config-schema.d.ts +244 -0
- package/dist/core/config-schema.js +452 -0
- package/dist/core/refs.js +10 -1
- package/dist/core/surface-discovery.d.ts +270 -0
- package/dist/core/surface-discovery.js +425 -0
- package/dist/core/surface-scopes.d.ts +38 -1
- package/dist/core/surface-scopes.js +73 -1
- package/dist/core/symbols.d.ts +24 -2
- package/dist/core/symbols.js +66 -18
- package/dist/core/types.d.ts +36 -107
- package/dist/core/validate.d.ts +36 -22
- package/dist/core/validate.js +88 -176
- package/dist/exclude.d.ts +20 -0
- package/dist/exclude.js +11 -1
- package/dist/layout-registry.d.ts +14 -0
- package/dist/layout-registry.js +40 -0
- package/dist/plugin-loader.d.ts +49 -1
- package/dist/plugin-loader.js +120 -14
- package/dist/scan-core.d.ts +19 -0
- package/dist/scan-core.js +30 -0
- package/dist/scan-files.js +15 -5
- package/dist/scan.d.ts +63 -0
- package/dist/scan.js +68 -12
- package/dist/score-core.js +8 -0
- package/dist/setup-plan.d.ts +2 -1
- package/dist/setup-plan.js +7 -2
- package/dist/surface-discovery-fs.d.ts +12 -0
- package/dist/surface-discovery-fs.js +108 -0
- package/dist/vigilesrc.schema.json +1689 -0
- package/package.json +10 -6
package/dist/core/symbols.js
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.installedGrammars = installedGrammars;
|
|
6
4
|
exports.langForFile = langForFile;
|
|
7
5
|
exports.definedSymbols = definedSymbols;
|
|
8
6
|
exports.definedSymbolsInFile = definedSymbolsInFile;
|
|
@@ -23,18 +21,60 @@ exports.fileDefinesSymbol = fileDefinesSymbol;
|
|
|
23
21
|
* delegated. Ambiguity (a name defined in several files) is reported, not guessed.
|
|
24
22
|
*/
|
|
25
23
|
const node_fs_1 = require("node:fs");
|
|
24
|
+
const node_module_1 = require("node:module");
|
|
26
25
|
const node_path_1 = require("node:path");
|
|
27
26
|
const napi_1 = require("@ast-grep/napi");
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
27
|
+
/**
|
|
28
|
+
* The non-web grammars, as OPTIONAL packages keyed by the id ast-grep registers them under.
|
|
29
|
+
*
|
|
30
|
+
* 🔴 WHY OPTIONAL, AND WHY IT IS NOT A PREFERENCE. These three are the only packages in this
|
|
31
|
+
* dependency tree carrying a `postinstall` (measured 2026-09-20 with `npm query
|
|
32
|
+
* ":attr(scripts, [postinstall])"`). Since pnpm 10 a consumer's install FAILS on an
|
|
33
|
+
* unapproved lifecycle script, so every downstream project installing vigiles with pnpm got
|
|
34
|
+
* `ERR_PNPM_IGNORED_BUILDS` and a non-zero exit — for grammars most of them never use. The web
|
|
35
|
+
* grammars every user does need (TypeScript, TSX, JavaScript, CSS) are built into
|
|
36
|
+
* `@ast-grep/napi` and cost nothing.
|
|
37
|
+
*
|
|
38
|
+
* They load through `createRequire` rather than `await import()` on purpose: the packages are
|
|
39
|
+
* CommonJS (`"main": "index.js"`, no `exports`), so a synchronous require works and NOTHING in
|
|
40
|
+
* this module's public surface has to become async. Measured, not assumed.
|
|
41
|
+
*/
|
|
42
|
+
const OPTIONAL_GRAMMARS = {
|
|
43
|
+
python: "@ast-grep/lang-python",
|
|
44
|
+
rust: "@ast-grep/lang-rust",
|
|
45
|
+
ruby: "@ast-grep/lang-ruby",
|
|
46
|
+
};
|
|
47
|
+
// Anchored on THIS module's own file, not on the consumer's project root. Under pnpm a
|
|
48
|
+
// consumer's root does not contain our transitive packages at all — the same addressing
|
|
49
|
+
// mistake that made every hook fail there — and these grammars are OUR optional dependencies,
|
|
50
|
+
// so they resolve from where this file lives. `__filename` rather than `import.meta.url`
|
|
51
|
+
// because this package compiles to CommonJS (`module: Node16`, `main: ./dist/test.js`).
|
|
52
|
+
const require_ = (0, node_module_1.createRequire)(__filename);
|
|
53
|
+
/** Registered grammar ids, populated on first use. `null` until then. */
|
|
54
|
+
let loaded = null;
|
|
32
55
|
function ensureRegistered() {
|
|
33
|
-
if (
|
|
34
|
-
return;
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
56
|
+
if (loaded)
|
|
57
|
+
return loaded;
|
|
58
|
+
const dynamic = {};
|
|
59
|
+
const present = new Set();
|
|
60
|
+
for (const [id, pkg] of Object.entries(OPTIONAL_GRAMMARS)) {
|
|
61
|
+
try {
|
|
62
|
+
dynamic[id] = require_(pkg);
|
|
63
|
+
present.add(id);
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
// Absent by design: an optional dependency the consumer did not install. The caller is
|
|
67
|
+
// told WHICH id is missing (see `langForFile`), so "not checked" never reads as "clean".
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
if (present.size > 0)
|
|
71
|
+
(0, napi_1.registerDynamicLanguage)(dynamic);
|
|
72
|
+
loaded = present;
|
|
73
|
+
return loaded;
|
|
74
|
+
}
|
|
75
|
+
/** Which optional grammars this process actually has. Exported so a report can say so. */
|
|
76
|
+
function installedGrammars() {
|
|
77
|
+
return ensureRegistered();
|
|
38
78
|
}
|
|
39
79
|
const EXT_LANG = {
|
|
40
80
|
".ts": napi_1.Lang.TypeScript,
|
|
@@ -53,11 +93,18 @@ const EXT_LANG = {
|
|
|
53
93
|
".rb": "ruby",
|
|
54
94
|
".rbi": "ruby",
|
|
55
95
|
};
|
|
56
|
-
/** The ast-grep language for a file, or null if unsupported (graceful skip). */
|
|
57
96
|
function langForFile(file) {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
97
|
+
const key = file.endsWith(".d.ts")
|
|
98
|
+
? napi_1.Lang.TypeScript
|
|
99
|
+
: EXT_LANG[(0, node_path_1.extname)(file).toLowerCase()];
|
|
100
|
+
if (key === undefined)
|
|
101
|
+
return { kind: "unsupported" };
|
|
102
|
+
// A string key is one of the dynamically registered grammars; the enum members are built in.
|
|
103
|
+
if (typeof key === "string" && key in OPTIONAL_GRAMMARS) {
|
|
104
|
+
if (!ensureRegistered().has(key))
|
|
105
|
+
return { kind: "grammar-missing", id: key, pkg: OPTIONAL_GRAMMARS[key] };
|
|
106
|
+
}
|
|
107
|
+
return { kind: "ready", lang: key };
|
|
61
108
|
}
|
|
62
109
|
const ID_KINDS = new Set(["identifier", "constant", "type_identifier"]);
|
|
63
110
|
const SCOPE_KINDS = new Set([
|
|
@@ -97,9 +144,10 @@ function definedSymbols(code, lang) {
|
|
|
97
144
|
}
|
|
98
145
|
/** Defined symbols for a file on disk, or [] if unreadable/unsupported. */
|
|
99
146
|
function definedSymbolsInFile(file) {
|
|
100
|
-
const
|
|
101
|
-
if (
|
|
147
|
+
const support = langForFile(file);
|
|
148
|
+
if (support.kind !== "ready")
|
|
102
149
|
return [];
|
|
150
|
+
const lang = support.lang;
|
|
103
151
|
try {
|
|
104
152
|
return definedSymbols((0, node_fs_1.readFileSync)(file, "utf-8"), lang);
|
|
105
153
|
}
|
package/dist/core/types.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { HarnessDialect } from "./dialect.js";
|
|
2
|
+
import type { HarnessDeclarationShape, VigilesConfigShape } from "./config-schema.js";
|
|
2
3
|
/** A parsed rule from a markdown instruction file. */
|
|
3
4
|
export interface ParsedRule {
|
|
4
5
|
title: string;
|
|
@@ -377,113 +378,41 @@ export interface RulesConfig {
|
|
|
377
378
|
export declare function ruleSeverity<T>(rule: RuleWithOptions<T> | undefined): RuleSeverity;
|
|
378
379
|
/** Extract options from a rule value (returns undefined for simple severity). */
|
|
379
380
|
export declare function ruleOptions<T>(rule: RuleWithOptions<T> | undefined): T | undefined;
|
|
380
|
-
/**
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
* benchmark fixtures, frozen reproductions (tsconfig-style, relative to the
|
|
416
|
-
* repo root; a bare directory name such as `"bench"` excludes its subtree, as
|
|
417
|
-
* do `"bench/"` and `"bench/**"`). `node_modules`/`dist`/`.git`/`.vigiles` are
|
|
418
|
-
* always excluded.
|
|
419
|
-
*
|
|
420
|
-
* ONE filter, every pass (#192): `compile` does not load an excluded spec,
|
|
421
|
-
* `lint` does not discover an excluded instruction file, nested bundle, doc, or
|
|
422
|
-
* surface, `audit` does not read an excluded instruction file, and
|
|
423
|
-
* `test`/`eval` do not discover an excluded script. It filters DISCOVERY only:
|
|
424
|
-
* a path you name on the command line is still processed, and one line says
|
|
425
|
-
* which pattern it matched. The rule-level `orphans.exclude` and
|
|
426
|
-
* `untested-*` `exclude` NARROW their own rule further and never re-admit a
|
|
427
|
-
* path excluded here (union, not override). Parsed once in `src/exclude.ts`.
|
|
428
|
-
*/
|
|
429
|
-
exclude?: readonly string[];
|
|
430
|
-
/**
|
|
431
|
-
* Top-level dir names shared across skills, e.g. `["scripts", "references"]`.
|
|
432
|
-
* OPT-IN: many skill libraries keep ONE top-level `scripts/`/`references/` tree
|
|
433
|
-
* rather than a copy beside every `SKILL.md`, so a bundled ref like
|
|
434
|
-
* `scripts/promptfoo/x.py` lives at the REPO ROOT. When a `SKILL.md` body ref's
|
|
435
|
-
* first path segment is a declared shared dir, `skill-resource-resolves` / audit
|
|
436
|
-
* ALSO resolves it against the repo root, not only the skill's own dir. Scoped
|
|
437
|
-
* to declared dirs on purpose: a repo that omits this key behaves exactly as
|
|
438
|
-
* before (skill-dir-only resolution), and a ref outside a shared dir is never
|
|
439
|
-
* masked by a same-named repo-root file. See feedback P1-4.
|
|
440
|
-
*/
|
|
441
|
-
sharedDirs?: readonly string[];
|
|
442
|
-
/**
|
|
443
|
-
* The harness(es) this repo targets — selects the compile dialect / skill
|
|
444
|
-
* frontmatter profile / instruction-file shape, instead of sniffing the cwd.
|
|
445
|
-
* A single name (`"codex"`) for the common single-harness repo, or an array
|
|
446
|
-
* (`["claude-code", "codex"]`) declaring the supported set. Written by
|
|
447
|
-
* `vigiles init`. Omitted → the CLI auto-detects (backwards-compatible).
|
|
448
|
-
* Canonical adapter names; `"claude"` is accepted as an alias for
|
|
449
|
-
* `"claude-code"`. See research/multi-harness-compile.md.
|
|
450
|
-
*/
|
|
451
|
-
harness?: string | string[];
|
|
452
|
-
/**
|
|
453
|
-
* `vigiles audit` preferences. `measure` is the sticky remembered answer to the
|
|
454
|
-
* "run the executing checks against your harness?" prompt — at a TTY `audit`
|
|
455
|
-
* asks once, then records the choice here so it never asks again. `true` runs
|
|
456
|
-
* the executing checks (safety battery · live MCP · skill firing) on every
|
|
457
|
-
* interactive run, `false` keeps them off (edit this key to change). Written by
|
|
458
|
-
* the audit consent prompt, not `init`. Headless runs never execute regardless
|
|
459
|
-
* (audit is a local report, not a CI step — there is no execution flag).
|
|
460
|
-
*/
|
|
461
|
-
audit?: {
|
|
462
|
-
measure?: boolean;
|
|
463
|
-
};
|
|
464
|
-
/**
|
|
465
|
-
* `vigiles eval` preferences. `apiVersion` is the hand-bumped **behavior epoch**
|
|
466
|
-
* folded into the eval LOCK's input hash (`src/eval-lock.ts`): bump it when a
|
|
467
|
-
* harness-side change YOU made (a CLAUDE.md edit, a global hook) would shift
|
|
468
|
-
* eval outputs but isn't otherwise visible to the lock — so `vigiles eval
|
|
469
|
-
* --check` reports the committed eval results STALE and forces a local re-run.
|
|
470
|
-
* Default 1. Distinct from the (auto-resolved) `claude` CLI version, which is
|
|
471
|
-
* recorded as provenance but deliberately NOT hashed.
|
|
472
|
-
*/
|
|
473
|
-
eval?: {
|
|
474
|
-
apiVersion?: number;
|
|
475
|
-
};
|
|
476
|
-
/**
|
|
477
|
-
* Suppress the adoption nudges `audit` prints (the "N surfaces not yet
|
|
478
|
-
* spec-managed → create specs" invitation). Set `"dismissed"` to hide them —
|
|
479
|
-
* the "remembered decline" half of the non-evil adoption contract, so a team
|
|
480
|
-
* that deliberately runs the integrity GATE alone (no specs/plugin) isn't
|
|
481
|
-
* nagged on every run. USER-SET only: `audit`/`lint` are pure reads and never
|
|
482
|
-
* write this (a read never writes). The deterministic findings + fixes are
|
|
483
|
-
* unaffected — this silences only the invitation, never a real finding.
|
|
484
|
-
*/
|
|
485
|
-
nudge?: "dismissed";
|
|
486
|
-
}
|
|
381
|
+
/**
|
|
382
|
+
* ONE harness's entry in {@link VigilesConfig.harnesses} — what this repo tells
|
|
383
|
+
* that harness about itself. Today that is only `roots`; the OBJECT (rather than
|
|
384
|
+
* a bare array of roots) is what leaves room for a second per-harness fact
|
|
385
|
+
* without another top-level key, which is how `surfaceRoots` came to exist
|
|
386
|
+
* beside `harness` in the first place.
|
|
387
|
+
*
|
|
388
|
+
* `{}` is meaningful and is the common case: "this repo targets this harness,
|
|
389
|
+
* and it reads it where it normally reads it."
|
|
390
|
+
*
|
|
391
|
+
* `roots` are extra repo-relative dirs THIS harness's surfaces live under, read
|
|
392
|
+
* with THIS harness's own `surfaceDirs` — `[".ai"]` under `"claude-code"` means
|
|
393
|
+
* `.ai/skills`, `.ai/agents`, `.ai/commands`. Every entry must resolve to at
|
|
394
|
+
* least one surface dir that exists on disk under this harness's layout; one
|
|
395
|
+
* that does not is a hard error, because a root declared under a harness that
|
|
396
|
+
* reads nothing there changes nothing and used to say nothing.
|
|
397
|
+
*/
|
|
398
|
+
export type HarnessDeclaration = HarnessDeclarationShape;
|
|
399
|
+
/**
|
|
400
|
+
* Full vigiles configuration, loaded from `.vigilesrc.json`.
|
|
401
|
+
*
|
|
402
|
+
* 🔴 DERIVED FROM THE SCHEMA, NOT WRITTEN BESIDE IT. The shape, the defaults and
|
|
403
|
+
* the per-key prose all live in `./config-schema.ts`; this is
|
|
404
|
+
* `z.infer<typeof vigilesConfigSchema>` with the defaults applied, so the type
|
|
405
|
+
* says exactly what a parsed config carries — `rules` non-optional and complete
|
|
406
|
+
* because every rule key has a schema default, optional keys optional because
|
|
407
|
+
* the schema says so. A hand-written twin is the copy that drifts: `harness` and
|
|
408
|
+
* `surfaceRoots` lived in that twin, in `docs/cli.md` and in the loader's
|
|
409
|
+
* coercions, and the three disagreed about what was read (#240).
|
|
410
|
+
*
|
|
411
|
+
* The re-export is TYPE-ONLY on purpose — `types.ts` is imported by node-free
|
|
412
|
+
* core modules, and a value import of the schema module would pull Zod into
|
|
413
|
+
* every one of them.
|
|
414
|
+
*/
|
|
415
|
+
export type VigilesConfig = VigilesConfigShape;
|
|
487
416
|
/** Valid marker types for rule detection. */
|
|
488
417
|
export type MarkerType = "headings" | "checkboxes";
|
|
489
418
|
/** Options for parseRules. */
|
package/dist/core/validate.d.ts
CHANGED
|
@@ -1,26 +1,20 @@
|
|
|
1
|
-
import type { ParsedRule, ValidationError, ValidationResult, ReadResult, FileResult, ValidatePathsResult, RulesConfig, VigilesConfig, MarkerType, ParseOptions, ValidateOptions, ValidatePathsOptions, ReadOptions } from "./types.js";
|
|
2
|
-
export type { ParsedRule, ValidationError, ValidationResult, ReadResult, FileResult, ValidatePathsResult, RulesConfig, VigilesConfig, MarkerType, ParseOptions, ValidateOptions, ValidatePathsOptions, ReadOptions, };
|
|
3
|
-
export declare const DEFAULT_RULES: Required<RulesConfig>;
|
|
4
|
-
export declare function findInstructionFiles(cwd?: string, configFiles?: string[]): string[];
|
|
1
|
+
import type { ParsedRule, ValidationError, ValidationResult, ReadResult, FileResult, ValidatePathsResult, RulesConfig, VigilesConfig, HarnessDeclaration, MarkerType, ParseOptions, ValidateOptions, ValidatePathsOptions, ReadOptions } from "./types.js";
|
|
2
|
+
export type { ParsedRule, ValidationError, ValidationResult, ReadResult, FileResult, ValidatePathsResult, RulesConfig, VigilesConfig, HarnessDeclaration, MarkerType, ParseOptions, ValidateOptions, ValidatePathsOptions, ReadOptions, };
|
|
5
3
|
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
* Coerce a config value that should be a `string[]`: a bare STRING becomes a
|
|
16
|
-
* one-element array (the natural first-value mistake), so `exclude` /
|
|
17
|
-
* `orphans.include` don't silently iterate a string's CHARACTERS as globs — a
|
|
18
|
-
* no-op at best, and garbage "orphan" matches (`.`, `/`, `README.md`) at worst.
|
|
19
|
-
* A non-string/array value falls back with a warning (the `ruleMarkers` pattern).
|
|
4
|
+
* The shipped default severity of every rule — DERIVED from the schema, never
|
|
5
|
+
* listed twice.
|
|
6
|
+
*
|
|
7
|
+
* It used to be the literal beside the type, which is exactly the pair that
|
|
8
|
+
* drifts: `rule-meta.test.ts` already cross-checks each rule's documented
|
|
9
|
+
* `defaultSeverity` against this object, and it could only ever catch a doc that
|
|
10
|
+
* disagreed with the literal, never a literal that disagreed with what parsing
|
|
11
|
+
* actually produced. Reading it out of the parser closes that gap: this IS what
|
|
12
|
+
* a `{}` config loads as.
|
|
20
13
|
*/
|
|
21
|
-
export declare
|
|
14
|
+
export declare const DEFAULT_RULES: Required<RulesConfig>;
|
|
15
|
+
export declare function findInstructionFiles(cwd?: string, configFiles?: string[]): string[];
|
|
22
16
|
/**
|
|
23
|
-
* Read `.vigilesrc.json`.
|
|
17
|
+
* Read and VALIDATE `.vigilesrc.json`.
|
|
24
18
|
*
|
|
25
19
|
* 🔴 `searchFrom` IS NOT A CONVENIENCE. cosmiconfig defaults to the process's
|
|
26
20
|
* working directory and walks up — right for a CLI verb, where the user is
|
|
@@ -31,9 +25,29 @@ export declare function asStringArray(v: unknown, fallback: readonly string[], k
|
|
|
31
25
|
* "off" was never found. Nothing in the output distinguishes that from a project
|
|
32
26
|
* that never configured the rule.
|
|
33
27
|
*
|
|
34
|
-
*
|
|
28
|
+
* 🔴 `onInvalid` IS THE ONE PLACE THE CALL SITES DIFFER, AND IT IS NOT A SPLIT
|
|
29
|
+
* IN WHAT IS CHECKED. Every reader validates; they disagree only about what a
|
|
30
|
+
* bad config is allowed to do to them. A VERB is a human standing at a prompt
|
|
31
|
+
* having just edited the file — `"throw"`, so the line they typed is refused out
|
|
32
|
+
* loud. A HOOK RAIL is a fresh process inside somebody's editing session, and a
|
|
33
|
+
* hook that dies on a malformed config turns a typo in a JSON file into a failed
|
|
34
|
+
* edit, which is a worse outcome than the nudge not firing — `"warn"`, print the
|
|
35
|
+
* same lines to stderr and carry on with the defaults.
|
|
36
|
+
*
|
|
37
|
+
* The two hook rails are `refsHookCommand` and `evalLockNudgeHookCommand`
|
|
38
|
+
* (`vigiles hook-runtime refs` / `eval-lock-nudge`, both registered as
|
|
39
|
+
* PostToolUse `Edit|Write` in `.claude-plugin/plugin.json`). Every other reader
|
|
40
|
+
* is a verb.
|
|
41
|
+
*
|
|
42
|
+
* ⚠️ THE SCHEMA MODULE IS REQUIRED IN-BODY, and that is hygiene rather than an
|
|
43
|
+
* optimization worth a paragraph: Zod is a ~45 ms cold import, `tsc` emits
|
|
44
|
+
* CommonJS across 230 separate files, so a `require` in a function body genuinely
|
|
45
|
+
* does not execute until the function is called. A rail that never reads a
|
|
46
|
+
* config never pays for the validator.
|
|
35
47
|
*/
|
|
36
|
-
export declare function loadConfig(searchFrom?: string
|
|
48
|
+
export declare function loadConfig(searchFrom?: string, { onInvalid }?: {
|
|
49
|
+
onInvalid?: "throw" | "warn";
|
|
50
|
+
}): VigilesConfig;
|
|
37
51
|
export declare function parseRules(content: string, { ruleMarkers }?: ParseOptions): ParsedRule[];
|
|
38
52
|
export declare function validate(content: string, { ruleMarkers, rules: rulesConfig, filePath, dialect }?: ValidateOptions): ValidationResult;
|
|
39
53
|
export declare function readInstructionFile(filePath: string, options?: ReadOptions): ReadResult;
|