vigiles 2.1.1 → 2.3.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 +127 -5
- package/dist/action-gate.d.ts +28 -0
- package/dist/action-gate.js +73 -0
- package/dist/cli.js +450 -75
- package/dist/community-skills.d.ts +22 -0
- package/dist/community-skills.js +86 -0
- package/dist/compile-generator.d.ts +48 -0
- package/dist/compile-generator.js +322 -0
- package/dist/compile.d.ts +3 -0
- package/dist/compile.js +217 -26
- package/dist/eval.d.ts +87 -0
- package/dist/eval.js +208 -0
- package/dist/frontmatter.d.ts +24 -6
- package/dist/frontmatter.js +103 -30
- package/dist/generate-schema.js +10 -0
- package/dist/harness-assert.d.ts +68 -0
- package/dist/harness-assert.js +127 -0
- package/dist/harness-test.d.ts +45 -0
- package/dist/harness-test.js +138 -0
- package/dist/inline.d.ts +22 -4
- package/dist/inline.js +60 -13
- package/dist/jest.d.ts +9 -0
- package/dist/jest.js +23 -0
- package/dist/judge.d.ts +29 -0
- package/dist/judge.js +88 -0
- package/dist/linters.js +28 -0
- package/dist/mock-model.d.ts +31 -0
- package/dist/mock-model.js +189 -0
- package/dist/plugin-loader.d.ts +37 -0
- package/dist/plugin-loader.js +195 -0
- package/dist/refs.d.ts +44 -0
- package/dist/refs.js +144 -0
- package/dist/run-hook.d.ts +77 -0
- package/dist/run-hook.js +80 -0
- package/dist/run-scripts.d.ts +20 -0
- package/dist/run-scripts.js +70 -0
- package/dist/skill-driver.d.ts +77 -0
- package/dist/skill-driver.js +76 -0
- package/dist/skill-runtime.d.ts +101 -0
- package/dist/skill-runtime.js +289 -0
- package/dist/skill-test.d.ts +47 -0
- package/dist/skill-test.js +77 -0
- package/dist/spec.d.ts +90 -4
- package/dist/spec.js +29 -0
- package/dist/symbols.d.ts +30 -0
- package/dist/symbols.js +142 -0
- package/dist/vitest.d.mts +9 -0
- package/dist/vitest.mjs +22 -0
- package/package.json +45 -6
package/dist/spec.d.ts
CHANGED
|
@@ -135,7 +135,13 @@ export interface SkillRef {
|
|
|
135
135
|
readonly _ref: "skill";
|
|
136
136
|
readonly path: VerifiedRef;
|
|
137
137
|
}
|
|
138
|
-
|
|
138
|
+
/** A typed symbol reference — the named file must define the named symbol. */
|
|
139
|
+
export interface SymbolRef {
|
|
140
|
+
readonly _ref: "symbol";
|
|
141
|
+
readonly file: VerifiedPath;
|
|
142
|
+
readonly symbol: string;
|
|
143
|
+
}
|
|
144
|
+
export type Ref = FileRef | CmdRef | SkillRef | SymbolRef;
|
|
139
145
|
/**
|
|
140
146
|
* Reference a file path — verified to exist at compile time.
|
|
141
147
|
* When generated types are present, narrowed to known project files.
|
|
@@ -146,6 +152,13 @@ export declare function file(path: NoInfer<StrictFile>): FileRef;
|
|
|
146
152
|
* When generated types are present, narrowed to known npm scripts.
|
|
147
153
|
*/
|
|
148
154
|
export declare function cmd(command: NoInfer<StrictCmd>): CmdRef;
|
|
155
|
+
/**
|
|
156
|
+
* Reference a symbol defined in a file — verified at compile time that the
|
|
157
|
+
* named file exists AND defines the named symbol (via ast-grep, cross-language).
|
|
158
|
+
* Compiles to the file-qualified inline form `` `file#symbol` `` so the markdown
|
|
159
|
+
* `audit` / `refs-hook` re-verify the same reference.
|
|
160
|
+
*/
|
|
161
|
+
export declare function symbol(file: NoInfer<StrictFile>, name: string): SymbolRef;
|
|
149
162
|
/**
|
|
150
163
|
* Reference another skill or instruction file — verified to exist.
|
|
151
164
|
* Compiles to a markdown link: [skill name](path)
|
|
@@ -214,18 +227,91 @@ type ClaudeSpecInput = ClaudeSpecBase & ClaudeSpecSections;
|
|
|
214
227
|
* export default claude({ commands: {...}, rules: {...} });
|
|
215
228
|
*/
|
|
216
229
|
export declare function claude(spec: ClaudeSpecInput): ClaudeSpec;
|
|
230
|
+
/**
|
|
231
|
+
* A deterministic gate on a skill step or its final result. A gate is one of:
|
|
232
|
+
* a command (exit 0), a file (must exist), or a *project role* that resolves to
|
|
233
|
+
* the host project's real command at run time. cmd/file gates are verified
|
|
234
|
+
* against the repo at author time; role gates are portable — a skill that runs
|
|
235
|
+
* in other repos should prefer `project("test")` over a hard-coded `npm test`.
|
|
236
|
+
*/
|
|
237
|
+
export type Gate = CmdRef | FileRef | RoleGate;
|
|
238
|
+
/** Project command roles, resolved per host project at run time. */
|
|
239
|
+
export type ProjectRole = "test" | "build" | "lint";
|
|
240
|
+
/** A portable gate that resolves to the host project's command for a role. */
|
|
241
|
+
export interface RoleGate {
|
|
242
|
+
readonly _ref: "role";
|
|
243
|
+
readonly role: ProjectRole;
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* A portable gate that resolves to the host project's command for a role
|
|
247
|
+
* (e.g. `project("test")` → `npm test` / `pytest` / `cargo test`). Use this
|
|
248
|
+
* in skills meant to run across projects, instead of hard-coding a command.
|
|
249
|
+
*/
|
|
250
|
+
export declare function project(role: ProjectRole): RoleGate;
|
|
251
|
+
/**
|
|
252
|
+
* A declared skill input. Compiles to the `argument-hint` frontmatter and a
|
|
253
|
+
* `## Arguments` section; referenced as `$1`/`$2`/`$ARGUMENTS` in the body.
|
|
254
|
+
*/
|
|
255
|
+
export interface SkillInput {
|
|
256
|
+
/** Argument name, e.g. "pattern". */
|
|
257
|
+
readonly name: string;
|
|
258
|
+
/** Human-readable hint shown in argument-hint and the Arguments section. */
|
|
259
|
+
readonly hint: string;
|
|
260
|
+
/** Required by default; set false to render as optional (`[<name>]`). */
|
|
261
|
+
readonly required?: boolean;
|
|
262
|
+
}
|
|
263
|
+
/** One step of a gated skill pipeline. */
|
|
264
|
+
export interface SkillStep {
|
|
265
|
+
/** What the model should do — prose, optionally with typed refs. */
|
|
266
|
+
readonly do: string | InstructionFragment[];
|
|
267
|
+
/** Deterministic check that must pass before advancing to the next step. */
|
|
268
|
+
readonly gate?: Gate;
|
|
269
|
+
/** Max attempts to satisfy the gate before the step fails (default 1). */
|
|
270
|
+
readonly retry?: number;
|
|
271
|
+
}
|
|
272
|
+
/** Declare a skill input (compiles to argument-hint + an Arguments entry). */
|
|
273
|
+
export declare function input(name: string, hint: string, opts?: {
|
|
274
|
+
required?: boolean;
|
|
275
|
+
}): SkillInput;
|
|
276
|
+
/** Declare a gated pipeline step. */
|
|
277
|
+
export declare function step(instr: string | InstructionFragment[], opts?: {
|
|
278
|
+
gate?: Gate;
|
|
279
|
+
retry?: number;
|
|
280
|
+
}): SkillStep;
|
|
217
281
|
export interface SkillSpec {
|
|
218
282
|
readonly _specType: "skill";
|
|
219
283
|
/** Skill name (used in frontmatter). */
|
|
220
284
|
readonly name: string;
|
|
221
285
|
/** Short description (used in frontmatter). */
|
|
222
286
|
readonly description: string;
|
|
223
|
-
/**
|
|
287
|
+
/**
|
|
288
|
+
* Hint for the argument (frontmatter). Ignored when `inputs` is set —
|
|
289
|
+
* `inputs` derive the argument-hint instead.
|
|
290
|
+
*/
|
|
224
291
|
readonly argumentHint?: string;
|
|
292
|
+
/** Typed inputs — compile to argument-hint + a `## Arguments` section. */
|
|
293
|
+
readonly inputs?: readonly SkillInput[];
|
|
225
294
|
/** Whether to disable model invocation (frontmatter flag). */
|
|
226
295
|
readonly disableModelInvocation?: boolean;
|
|
227
|
-
/**
|
|
228
|
-
|
|
296
|
+
/**
|
|
297
|
+
* Gated pipeline steps. When set, the skill compiles to a `## Steps`
|
|
298
|
+
* checklist with a deterministic gate per step. Use this OR `body`.
|
|
299
|
+
*/
|
|
300
|
+
readonly steps?: readonly SkillStep[];
|
|
301
|
+
/**
|
|
302
|
+
* Terminal postcondition — the skill is "done" only when this gate passes.
|
|
303
|
+
* Compiles to a `## Result` section + a `vigiles:result` marker.
|
|
304
|
+
*/
|
|
305
|
+
readonly result?: Gate;
|
|
306
|
+
/** Freeform instruction body (linear/unstructured skills). Use this OR `steps`. */
|
|
307
|
+
readonly body?: string | InstructionFragment[];
|
|
308
|
+
/**
|
|
309
|
+
* Max lines for an inline fenced code block before compilation errors,
|
|
310
|
+
* forcing the script into a file referenced via `file()` (default 20).
|
|
311
|
+
* Keeps big scripts out of the skill body (token budget + progressive
|
|
312
|
+
* disclosure). Set 0 to disable.
|
|
313
|
+
*/
|
|
314
|
+
readonly maxInlineCodeLines?: number;
|
|
229
315
|
}
|
|
230
316
|
/**
|
|
231
317
|
* Define a SKILL.md specification.
|
package/dist/spec.js
CHANGED
|
@@ -15,9 +15,13 @@ exports.guidance = guidance;
|
|
|
15
15
|
exports.guard = guard;
|
|
16
16
|
exports.file = file;
|
|
17
17
|
exports.cmd = cmd;
|
|
18
|
+
exports.symbol = symbol;
|
|
18
19
|
exports.ref = ref;
|
|
19
20
|
exports.instructions = instructions;
|
|
20
21
|
exports.claude = claude;
|
|
22
|
+
exports.project = project;
|
|
23
|
+
exports.input = input;
|
|
24
|
+
exports.step = step;
|
|
21
25
|
exports.skill = skill;
|
|
22
26
|
exports.defineConfig = defineConfig;
|
|
23
27
|
// ---------------------------------------------------------------------------
|
|
@@ -81,6 +85,15 @@ function file(path) {
|
|
|
81
85
|
function cmd(command) {
|
|
82
86
|
return { _ref: "cmd", command: command };
|
|
83
87
|
}
|
|
88
|
+
/**
|
|
89
|
+
* Reference a symbol defined in a file — verified at compile time that the
|
|
90
|
+
* named file exists AND defines the named symbol (via ast-grep, cross-language).
|
|
91
|
+
* Compiles to the file-qualified inline form `` `file#symbol` `` so the markdown
|
|
92
|
+
* `audit` / `refs-hook` re-verify the same reference.
|
|
93
|
+
*/
|
|
94
|
+
function symbol(file, name) {
|
|
95
|
+
return { _ref: "symbol", file: file, symbol: name };
|
|
96
|
+
}
|
|
84
97
|
/**
|
|
85
98
|
* Reference another skill or instruction file — verified to exist.
|
|
86
99
|
* Compiles to a markdown link: [skill name](path)
|
|
@@ -116,6 +129,22 @@ function instructions(strings, ...values) {
|
|
|
116
129
|
function claude(spec) {
|
|
117
130
|
return { _specType: "claude", ...spec };
|
|
118
131
|
}
|
|
132
|
+
/**
|
|
133
|
+
* A portable gate that resolves to the host project's command for a role
|
|
134
|
+
* (e.g. `project("test")` → `npm test` / `pytest` / `cargo test`). Use this
|
|
135
|
+
* in skills meant to run across projects, instead of hard-coding a command.
|
|
136
|
+
*/
|
|
137
|
+
function project(role) {
|
|
138
|
+
return { _ref: "role", role };
|
|
139
|
+
}
|
|
140
|
+
/** Declare a skill input (compiles to argument-hint + an Arguments entry). */
|
|
141
|
+
function input(name, hint, opts = {}) {
|
|
142
|
+
return { name, hint, required: opts.required };
|
|
143
|
+
}
|
|
144
|
+
/** Declare a gated pipeline step. */
|
|
145
|
+
function step(instr, opts = {}) {
|
|
146
|
+
return { do: instr, gate: opts.gate, retry: opts.retry };
|
|
147
|
+
}
|
|
119
148
|
/**
|
|
120
149
|
* Define a SKILL.md specification.
|
|
121
150
|
*
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Lang } from "@ast-grep/napi";
|
|
2
|
+
/** A language key accepted by ast-grep's `parse` (core enum or registered id). */
|
|
3
|
+
type LangKey = Lang | string;
|
|
4
|
+
/** The ast-grep language for a file, or null if unsupported (graceful skip). */
|
|
5
|
+
export declare function langForFile(file: string): LangKey | null;
|
|
6
|
+
/** A symbol definition found in a file. */
|
|
7
|
+
export interface SymbolDef {
|
|
8
|
+
/** The defined identifier, e.g. "parseConfig". */
|
|
9
|
+
readonly name: string;
|
|
10
|
+
/** The tree-sitter node kind, e.g. "function_declaration" (raw, per-grammar). */
|
|
11
|
+
readonly kind: string;
|
|
12
|
+
/** Enclosing class/module name, or "" at top level. */
|
|
13
|
+
readonly scope: string;
|
|
14
|
+
/** 1-based line of the definition. */
|
|
15
|
+
readonly line: number;
|
|
16
|
+
}
|
|
17
|
+
/** Extract the symbols defined in a single file's source. */
|
|
18
|
+
export declare function definedSymbols(code: string, lang: LangKey): SymbolDef[];
|
|
19
|
+
/** Defined symbols for a file on disk, or [] if unreadable/unsupported. */
|
|
20
|
+
export declare function definedSymbolsInFile(file: string): SymbolDef[];
|
|
21
|
+
/**
|
|
22
|
+
* Whether `file` defines a top-level (or scoped) symbol named `name`. This is
|
|
23
|
+
* the whole check for a file-qualified reference (`path#symbol`): we parse the
|
|
24
|
+
* one named file — no project-wide index, no resolution across files. As a
|
|
25
|
+
* fallback we also consult a co-located declaration file (`.rbi` / `.d.ts`), so
|
|
26
|
+
* typed dynamic symbols resolve without running Sorbet / the TS compiler.
|
|
27
|
+
*/
|
|
28
|
+
export declare function fileDefinesSymbol(file: string, name: string): boolean;
|
|
29
|
+
export {};
|
|
30
|
+
//# sourceMappingURL=symbols.d.ts.map
|
package/dist/symbols.js
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.langForFile = langForFile;
|
|
7
|
+
exports.definedSymbols = definedSymbols;
|
|
8
|
+
exports.definedSymbolsInFile = definedSymbolsInFile;
|
|
9
|
+
exports.fileDefinesSymbol = fileDefinesSymbol;
|
|
10
|
+
/**
|
|
11
|
+
* vigiles — cross-language symbol index (ast-grep / tree-sitter).
|
|
12
|
+
*
|
|
13
|
+
* The kernel of harness-pinned reference verification. Instruction files
|
|
14
|
+
* reference project symbols in prose (`parseConfig`, `User`, `create_docx.py`);
|
|
15
|
+
* authors never write a verifiable `file#symbol` form (corpus: ~0%). So instead
|
|
16
|
+
* of asking authors to annotate, the *harness* resolves a bare reference against
|
|
17
|
+
* the live code at write time and pins it. This module is the resolver: extract
|
|
18
|
+
* the symbols a file defines, and build a project-wide name → locations index.
|
|
19
|
+
*
|
|
20
|
+
* Boundary (see research/symbol-verification.md): we answer "does a definition
|
|
21
|
+
* with this name (in this scope) exist", NOT "does this reference resolve through
|
|
22
|
+
* imports / Zeitwerk / tsconfig". Resolution is per-language and architectural —
|
|
23
|
+
* delegated. Ambiguity (a name defined in several files) is reported, not guessed.
|
|
24
|
+
*/
|
|
25
|
+
const node_fs_1 = require("node:fs");
|
|
26
|
+
const node_path_1 = require("node:path");
|
|
27
|
+
const napi_1 = require("@ast-grep/napi");
|
|
28
|
+
const lang_python_1 = __importDefault(require("@ast-grep/lang-python"));
|
|
29
|
+
const lang_rust_1 = __importDefault(require("@ast-grep/lang-rust"));
|
|
30
|
+
const lang_ruby_1 = __importDefault(require("@ast-grep/lang-ruby"));
|
|
31
|
+
let registered = false;
|
|
32
|
+
function ensureRegistered() {
|
|
33
|
+
if (registered)
|
|
34
|
+
return;
|
|
35
|
+
// Non-web grammars ship as separate packages registered at runtime.
|
|
36
|
+
(0, napi_1.registerDynamicLanguage)({ python: lang_python_1.default, rust: lang_rust_1.default, ruby: lang_ruby_1.default });
|
|
37
|
+
registered = true;
|
|
38
|
+
}
|
|
39
|
+
const EXT_LANG = {
|
|
40
|
+
".ts": napi_1.Lang.TypeScript,
|
|
41
|
+
".tsx": napi_1.Lang.Tsx,
|
|
42
|
+
".mts": napi_1.Lang.TypeScript,
|
|
43
|
+
".cts": napi_1.Lang.TypeScript,
|
|
44
|
+
".d.ts": napi_1.Lang.TypeScript,
|
|
45
|
+
".js": napi_1.Lang.JavaScript,
|
|
46
|
+
".jsx": napi_1.Lang.JavaScript,
|
|
47
|
+
".mjs": napi_1.Lang.JavaScript,
|
|
48
|
+
".cjs": napi_1.Lang.JavaScript,
|
|
49
|
+
".css": napi_1.Lang.Css,
|
|
50
|
+
".py": "python",
|
|
51
|
+
".pyi": "python",
|
|
52
|
+
".rs": "rust",
|
|
53
|
+
".rb": "ruby",
|
|
54
|
+
".rbi": "ruby",
|
|
55
|
+
};
|
|
56
|
+
/** The ast-grep language for a file, or null if unsupported (graceful skip). */
|
|
57
|
+
function langForFile(file) {
|
|
58
|
+
if (file.endsWith(".d.ts"))
|
|
59
|
+
return napi_1.Lang.TypeScript;
|
|
60
|
+
return EXT_LANG[(0, node_path_1.extname)(file).toLowerCase()] ?? null;
|
|
61
|
+
}
|
|
62
|
+
const ID_KINDS = new Set(["identifier", "constant", "type_identifier"]);
|
|
63
|
+
const SCOPE_KINDS = new Set([
|
|
64
|
+
"class_declaration",
|
|
65
|
+
"class_definition",
|
|
66
|
+
"class",
|
|
67
|
+
"module",
|
|
68
|
+
"interface_declaration",
|
|
69
|
+
"enum_declaration",
|
|
70
|
+
]);
|
|
71
|
+
function recordNode(node, scope, out) {
|
|
72
|
+
const line = node.range().start.line + 1;
|
|
73
|
+
const nameNode = node.field("name");
|
|
74
|
+
if (nameNode) {
|
|
75
|
+
out.push({ name: nameNode.text(), kind: node.kind(), scope, line });
|
|
76
|
+
}
|
|
77
|
+
// Assignment-style constants (Python/Ruby `X = ...`): the identifier is the
|
|
78
|
+
// `left` field, not `name`.
|
|
79
|
+
const left = node.field("left");
|
|
80
|
+
if (left && ID_KINDS.has(left.kind())) {
|
|
81
|
+
out.push({ name: left.text(), kind: node.kind(), scope, line });
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/** Extract the symbols defined in a single file's source. */
|
|
85
|
+
function definedSymbols(code, lang) {
|
|
86
|
+
ensureRegistered();
|
|
87
|
+
const out = [];
|
|
88
|
+
const walk = (node, scope) => {
|
|
89
|
+
recordNode(node, scope, out);
|
|
90
|
+
const nameNode = node.field("name");
|
|
91
|
+
const nextScope = SCOPE_KINDS.has(node.kind()) && nameNode ? nameNode.text() : scope;
|
|
92
|
+
for (const child of node.children())
|
|
93
|
+
walk(child, nextScope);
|
|
94
|
+
};
|
|
95
|
+
walk((0, napi_1.parse)(lang, code).root(), "");
|
|
96
|
+
return out;
|
|
97
|
+
}
|
|
98
|
+
/** Defined symbols for a file on disk, or [] if unreadable/unsupported. */
|
|
99
|
+
function definedSymbolsInFile(file) {
|
|
100
|
+
const lang = langForFile(file);
|
|
101
|
+
if (!lang)
|
|
102
|
+
return [];
|
|
103
|
+
try {
|
|
104
|
+
return definedSymbols((0, node_fs_1.readFileSync)(file, "utf-8"), lang);
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
return [];
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
// A co-located declaration file that may declare symbols the source defines
|
|
111
|
+
// dynamically (Sorbet `.rbi`, TypeScript `.d.ts`) — checked as a fallback so a
|
|
112
|
+
// metaprogrammed `define_method` / ambient declaration still resolves.
|
|
113
|
+
const DECL_SIBLING = {
|
|
114
|
+
".ts": ".d.ts",
|
|
115
|
+
".tsx": ".d.ts",
|
|
116
|
+
".js": ".d.ts",
|
|
117
|
+
".jsx": ".d.ts",
|
|
118
|
+
".mjs": ".d.ts",
|
|
119
|
+
".rb": ".rbi",
|
|
120
|
+
};
|
|
121
|
+
/**
|
|
122
|
+
* Whether `file` defines a top-level (or scoped) symbol named `name`. This is
|
|
123
|
+
* the whole check for a file-qualified reference (`path#symbol`): we parse the
|
|
124
|
+
* one named file — no project-wide index, no resolution across files. As a
|
|
125
|
+
* fallback we also consult a co-located declaration file (`.rbi` / `.d.ts`), so
|
|
126
|
+
* typed dynamic symbols resolve without running Sorbet / the TS compiler.
|
|
127
|
+
*/
|
|
128
|
+
function fileDefinesSymbol(file, name) {
|
|
129
|
+
if (definedSymbolsInFile(file).some((d) => d.name === name))
|
|
130
|
+
return true;
|
|
131
|
+
const ext = (0, node_path_1.extname)(file);
|
|
132
|
+
const decl = DECL_SIBLING[ext];
|
|
133
|
+
if (decl && !file.endsWith(decl)) {
|
|
134
|
+
const sibling = file.slice(0, -ext.length) + decl;
|
|
135
|
+
if ((0, node_fs_1.existsSync)(sibling) &&
|
|
136
|
+
definedSymbolsInFile(sibling).some((d) => d.name === name)) {
|
|
137
|
+
return true;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return false;
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=symbols.js.map
|
package/dist/vitest.mjs
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/* eslint-disable max-params, @typescript-eslint/no-explicit-any --
|
|
2
|
+
The matcher signatures mirror the runtime vigilesMatchers (positional args),
|
|
3
|
+
and `Matchers<T = any>` must match @vitest/expect's generic default to merge. */
|
|
4
|
+
/**
|
|
5
|
+
* vigiles — vitest integration (opt-in). ESM, because vitest is ESM-only.
|
|
6
|
+
*
|
|
7
|
+
* Importing this entry registers the vigiles matchers AND augments vitest's
|
|
8
|
+
* types so `toHaveCreated` / `toBeatBaseline` type-check.
|
|
9
|
+
*
|
|
10
|
+
* // vitest.config.ts → test: { setupFiles: ["vigiles/vitest"] }
|
|
11
|
+
* // …or at the top of a test file:
|
|
12
|
+
* import "vigiles/vitest";
|
|
13
|
+
*
|
|
14
|
+
* expect(result).toHaveCreated("DONE");
|
|
15
|
+
* expect(report).toBeatBaseline("vanilla", "gated", "caught");
|
|
16
|
+
*
|
|
17
|
+
* vitest is an optional peer dependency — only vitest users load this entry.
|
|
18
|
+
*/
|
|
19
|
+
import { expect } from "vitest";
|
|
20
|
+
import { vigilesMatchers } from "./harness-assert.js";
|
|
21
|
+
expect.extend(vigilesMatchers);
|
|
22
|
+
//# sourceMappingURL=vitest.mjs.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vigiles",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.0",
|
|
4
4
|
"description": "Compile .spec.ts files to instruction files (CLAUDE.md, AGENTS.md) with linter cross-referencing",
|
|
5
5
|
"bin": {
|
|
6
6
|
"vigiles": "dist/cli.js"
|
|
@@ -11,11 +11,25 @@
|
|
|
11
11
|
".": "./dist/spec.js",
|
|
12
12
|
"./spec": "./dist/spec.js",
|
|
13
13
|
"./compile": "./dist/compile.js",
|
|
14
|
-
"./linters": "./dist/linters.js"
|
|
14
|
+
"./linters": "./dist/linters.js",
|
|
15
|
+
"./eval": "./dist/eval.js",
|
|
16
|
+
"./harness-test": "./dist/harness-test.js",
|
|
17
|
+
"./harness-assert": "./dist/harness-assert.js",
|
|
18
|
+
"./run-hook": "./dist/run-hook.js",
|
|
19
|
+
"./plugin-loader": "./dist/plugin-loader.js",
|
|
20
|
+
"./judge": "./dist/judge.js",
|
|
21
|
+
"./mock-model": "./dist/mock-model.js",
|
|
22
|
+
"./vitest": {
|
|
23
|
+
"types": "./dist/vitest.d.mts",
|
|
24
|
+
"default": "./dist/vitest.mjs"
|
|
25
|
+
},
|
|
26
|
+
"./jest": "./dist/jest.js"
|
|
15
27
|
},
|
|
16
28
|
"files": [
|
|
17
29
|
"dist/**/*.js",
|
|
30
|
+
"dist/**/*.mjs",
|
|
18
31
|
"dist/**/*.d.ts",
|
|
32
|
+
"dist/**/*.d.mts",
|
|
19
33
|
"!dist/**/*.test.js",
|
|
20
34
|
"!dist/**/*.test.d.ts",
|
|
21
35
|
"action.yml",
|
|
@@ -25,10 +39,16 @@
|
|
|
25
39
|
],
|
|
26
40
|
"scripts": {
|
|
27
41
|
"build": "tsc",
|
|
28
|
-
"test": "npm run build && node --test dist/spec.test.js dist/validate.test.js dist/cli.test.js dist/proofs.test.js dist/inline.test.js dist/sidecar.test.js dist/coverage.test.js dist/session.test.js dist/orphans.test.js dist/cedar.test.js dist/doc-refs.test.js dist/frontmatter.test.js",
|
|
42
|
+
"test": "npm run build && node --test dist/spec.test.js dist/validate.test.js dist/cli.test.js dist/proofs.test.js dist/inline.test.js dist/sidecar.test.js dist/coverage.test.js dist/session.test.js dist/orphans.test.js dist/cedar.test.js dist/doc-refs.test.js dist/frontmatter.test.js dist/skill-pipeline.test.js dist/skill-runtime.test.js dist/skill-driver.test.js dist/skill-test.test.js dist/compile-generator.test.js dist/community-skills.test.js dist/action-gate.test.js dist/symbols.test.js dist/refs.test.js dist/harness-test.test.js dist/eval.test.js dist/run-scripts.test.js dist/plugin-loader.test.js dist/harness-assert.test.js dist/judge.test.js dist/run-hook.test.js",
|
|
29
43
|
"lint": "eslint src/",
|
|
30
44
|
"fmt": "prettier --write .",
|
|
31
|
-
"fmt:check": "prettier --check ."
|
|
45
|
+
"fmt:check": "prettier --check .",
|
|
46
|
+
"test:e2e": "bash test/e2e/run.sh",
|
|
47
|
+
"test:harness": "npm run build && node dist/cli.js test",
|
|
48
|
+
"test:eval": "npm run build && node dist/cli.js eval",
|
|
49
|
+
"test:vitest": "npm run build && vitest run",
|
|
50
|
+
"test:jest": "npm run build && jest",
|
|
51
|
+
"test:types": "npm run build && tsc --noEmit -p test/types/tsconfig.json"
|
|
32
52
|
},
|
|
33
53
|
"devDependencies": {
|
|
34
54
|
"@eslint/js": "^10.0.1",
|
|
@@ -40,15 +60,34 @@
|
|
|
40
60
|
"eslint": "^10.1.0",
|
|
41
61
|
"eslint-plugin-sonarjs": "^4.0.2",
|
|
42
62
|
"globals": "^17.4.0",
|
|
63
|
+
"jest": "^30.4.2",
|
|
43
64
|
"prettier": "^3.8.1",
|
|
44
65
|
"tsx": "^4.21.0",
|
|
45
|
-
"typescript": "^5.9.3"
|
|
66
|
+
"typescript": "^5.9.3",
|
|
67
|
+
"vitest": "^4.1.8"
|
|
68
|
+
},
|
|
69
|
+
"peerDependencies": {
|
|
70
|
+
"jest": ">=28",
|
|
71
|
+
"vitest": ">=1"
|
|
72
|
+
},
|
|
73
|
+
"peerDependenciesMeta": {
|
|
74
|
+
"jest": {
|
|
75
|
+
"optional": true
|
|
76
|
+
},
|
|
77
|
+
"vitest": {
|
|
78
|
+
"optional": true
|
|
79
|
+
}
|
|
46
80
|
},
|
|
47
81
|
"dependencies": {
|
|
82
|
+
"@ast-grep/lang-python": "^0.0.6",
|
|
83
|
+
"@ast-grep/lang-ruby": "^0.0.7",
|
|
84
|
+
"@ast-grep/lang-rust": "^0.0.7",
|
|
85
|
+
"@ast-grep/napi": "^0.43.0",
|
|
48
86
|
"@jackchuka/mdschema": "^0.12.8",
|
|
49
87
|
"cosmiconfig": "^9.0.1",
|
|
50
88
|
"glob": "^13.0.6",
|
|
51
89
|
"js-yaml": "^4.1.0",
|
|
52
|
-
"minimatch": "^10.0.1"
|
|
90
|
+
"minimatch": "^10.0.1",
|
|
91
|
+
"typescript": "^5.9.3"
|
|
53
92
|
}
|
|
54
93
|
}
|