vigiles 2.1.1 → 2.2.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 +76 -5
- package/dist/action-gate.d.ts +28 -0
- package/dist/action-gate.js +73 -0
- package/dist/cli.js +408 -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 +62 -0
- package/dist/eval.js +174 -0
- package/dist/frontmatter.d.ts +24 -6
- package/dist/frontmatter.js +103 -30
- package/dist/generate-schema.js +10 -0
- package/dist/harness-test.d.ts +38 -0
- package/dist/harness-test.js +129 -0
- package/dist/inline.d.ts +22 -4
- package/dist/inline.js +60 -13
- package/dist/linters.js +28 -0
- package/dist/mock-model.d.ts +31 -0
- package/dist/mock-model.js +189 -0
- package/dist/refs.d.ts +44 -0
- package/dist/refs.js +144 -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/package.json +14 -5
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vigiles",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.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,7 +11,10 @@
|
|
|
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
|
+
"./mock-model": "./dist/mock-model.js"
|
|
15
18
|
},
|
|
16
19
|
"files": [
|
|
17
20
|
"dist/**/*.js",
|
|
@@ -25,10 +28,11 @@
|
|
|
25
28
|
],
|
|
26
29
|
"scripts": {
|
|
27
30
|
"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",
|
|
31
|
+
"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",
|
|
29
32
|
"lint": "eslint src/",
|
|
30
33
|
"fmt": "prettier --write .",
|
|
31
|
-
"fmt:check": "prettier --check ."
|
|
34
|
+
"fmt:check": "prettier --check .",
|
|
35
|
+
"test:e2e": "bash test/e2e/run.sh"
|
|
32
36
|
},
|
|
33
37
|
"devDependencies": {
|
|
34
38
|
"@eslint/js": "^10.0.1",
|
|
@@ -45,10 +49,15 @@
|
|
|
45
49
|
"typescript": "^5.9.3"
|
|
46
50
|
},
|
|
47
51
|
"dependencies": {
|
|
52
|
+
"@ast-grep/lang-python": "^0.0.6",
|
|
53
|
+
"@ast-grep/lang-ruby": "^0.0.7",
|
|
54
|
+
"@ast-grep/lang-rust": "^0.0.7",
|
|
55
|
+
"@ast-grep/napi": "^0.43.0",
|
|
48
56
|
"@jackchuka/mdschema": "^0.12.8",
|
|
49
57
|
"cosmiconfig": "^9.0.1",
|
|
50
58
|
"glob": "^13.0.6",
|
|
51
59
|
"js-yaml": "^4.1.0",
|
|
52
|
-
"minimatch": "^10.0.1"
|
|
60
|
+
"minimatch": "^10.0.1",
|
|
61
|
+
"typescript": "^5.9.3"
|
|
53
62
|
}
|
|
54
63
|
}
|