vigiles 38.2.0 → 39.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/adapters/claude-code/event-capability.js +24 -8
- package/dist/adapters/claude-code/hook-protocol.js +2 -1
- package/dist/adapters/codex/hook-protocol.js +2 -1
- package/dist/cli-flag-check.d.ts +36 -0
- package/dist/cli-flag-check.js +72 -1
- package/dist/cli-main.d.ts +2 -2
- package/dist/cli-main.js +548 -379
- package/dist/core/bash-effects.d.ts +0 -57
- package/dist/core/bash-effects.js +0 -147
- package/dist/core/compile-generator.d.ts +6 -6
- package/dist/core/compile-generator.js +4 -4
- package/dist/core/compile.d.ts +72 -8
- package/dist/core/compile.js +276 -133
- package/dist/core/config-schema.d.ts +40 -10
- package/dist/core/config-schema.js +139 -16
- package/dist/core/coverage.d.ts +16 -0
- package/dist/core/coverage.js +22 -0
- package/dist/core/doc-refs.d.ts +3 -2
- package/dist/core/doc-refs.js +2 -2
- package/dist/core/enforce-marker.d.ts +28 -0
- package/dist/core/enforce-marker.js +34 -0
- package/dist/core/eslint-inventory.d.ts +96 -0
- package/dist/core/eslint-inventory.js +251 -0
- package/dist/core/event-capability.d.ts +5 -1
- package/dist/core/frame.d.ts +43 -2
- package/dist/core/frame.js +85 -2
- package/dist/core/generate-schema.d.ts +3 -2
- package/dist/core/generate-schema.js +2 -2
- package/dist/core/generate-types.d.ts +11 -2
- package/dist/core/generate-types.js +12 -5
- package/dist/core/hook-command.d.ts +172 -0
- package/dist/core/hook-command.js +277 -0
- package/dist/core/hook-delivery.d.ts +133 -0
- package/dist/core/hook-delivery.js +150 -0
- package/dist/core/hook-paths.d.ts +14 -0
- package/dist/core/hook-paths.js +22 -0
- package/dist/core/hook-program.d.ts +4 -4
- package/dist/core/hook-program.js +13 -25
- package/dist/core/hook-state.d.ts +1 -1
- package/dist/core/hook-state.js +1 -1
- package/dist/core/instruction-remedies.d.ts +35 -0
- package/dist/core/instruction-remedies.js +70 -1
- package/dist/core/integrity-header.d.ts +54 -0
- package/dist/core/integrity-header.js +90 -0
- package/dist/core/integrity.d.ts +1 -25
- package/dist/core/integrity.js +16 -74
- package/dist/core/linter-adapter.d.ts +27 -3
- package/dist/core/linters.d.ts +8 -1
- package/dist/core/linters.js +116 -81
- package/dist/core/orphans.d.ts +3 -5
- package/dist/core/orphans.js +9 -10
- package/dist/core/presets.d.ts +19 -7
- package/dist/core/presets.js +19 -6
- package/dist/core/rule-catalog.d.ts +11 -12
- package/dist/core/rule-catalog.js +25 -94
- package/dist/core/rule-meta.d.ts +12 -0
- package/dist/core/rule-meta.js +47 -10
- package/dist/core/source-refs.d.ts +3 -23
- package/dist/core/source-refs.js +3 -27
- package/dist/core/test-utils.d.ts +13 -0
- package/dist/core/test-utils.js +40 -1
- package/dist/core/types.d.ts +18 -26
- package/dist/core/validate.d.ts +1 -2
- package/dist/core/validate.js +60 -47
- package/dist/coverage-evidence.js +2 -3
- package/dist/deprecated-key-files.d.ts +6 -0
- package/dist/deprecated-key-files.js +7 -6
- package/dist/exclude.d.ts +3 -1
- package/dist/exclude.js +9 -33
- package/dist/harness-assert.d.ts +18 -0
- package/dist/harness-assert.js +38 -0
- package/dist/hook-check-install.js +15 -6
- package/dist/hook-check.d.ts +1 -3
- package/dist/hook-check.js +3 -5
- package/dist/hook-install.d.ts +7 -41
- package/dist/hook-install.js +29 -96
- package/dist/hook-runtime.js +2 -1
- package/dist/load-hook.d.ts +3 -2
- package/dist/load-hook.js +28 -6
- package/dist/overrides.d.ts +25 -0
- package/dist/overrides.js +51 -0
- package/dist/plugin-loader.d.ts +23 -0
- package/dist/plugin-loader.js +42 -12
- package/dist/root-globs.d.ts +9 -0
- package/dist/root-globs.js +48 -0
- package/dist/rule-routing.js +6 -3
- package/dist/run-hook.d.ts +26 -2
- package/dist/run-hook.js +48 -12
- package/dist/scan-core.d.ts +96 -20
- package/dist/scan-core.js +171 -176
- package/dist/scan-files.d.ts +0 -8
- package/dist/scan-files.js +78 -20
- package/dist/scan.d.ts +12 -12
- package/dist/scan.js +33 -10
- package/dist/setup-plan.d.ts +15 -9
- package/dist/setup-plan.js +26 -18
- package/dist/test-coverage.d.ts +3 -8
- package/dist/test-coverage.js +6 -6
- package/dist/test.d.ts +1 -1
- package/dist/vigilesrc.schema.json +1329 -118
- package/package.json +1 -1
- package/skills/adopt-spec/SKILL.md +2 -1
|
@@ -225,61 +225,4 @@ export declare function leafCommandsNormalized(command: string): NormalizedLeaf[
|
|
|
225
225
|
* Parse failure → `[]`.
|
|
226
226
|
*/
|
|
227
227
|
export declare function leafArgvSource(command: string): string[][];
|
|
228
|
-
/**
|
|
229
|
-
* Every word of every simple command in `command` that could name a FILE, with
|
|
230
|
-
* inline PROGRAM TEXT removed — the primitive behind "does this hook's script
|
|
231
|
-
* exist?".
|
|
232
|
-
*
|
|
233
|
-
* 🔴 WHY A FOURTH EXTRACTOR, stated against the three that already exist,
|
|
234
|
-
* because "there is already one that returns words" is exactly the reasoning
|
|
235
|
-
* that produced the bug this replaces.
|
|
236
|
-
*
|
|
237
|
-
* - `leafCommands` drops every word it cannot reduce to a LITERAL, so
|
|
238
|
-
* `${CLAUDE_PLUGIN_ROOT}/hooks/x.sh` — the standard spelling of a hook path —
|
|
239
|
-
* disappears entirely. Unusable for a file question.
|
|
240
|
-
* - `leafCommandsNormalized` basenames the head, so `./hooks/x.sh` becomes
|
|
241
|
-
* `x.sh` and no resolver can find it.
|
|
242
|
-
* - `leafArgvSource` keeps the spelling but answers a DIFFERENT question:
|
|
243
|
-
* "which leaves unconditionally RUN". It drops the right-hand side of `&&`
|
|
244
|
-
* by design, so `cd "$ROOT" && node hooks/x.mjs` yields no script. For
|
|
245
|
-
* coverage attribution that abstention is correct; for "must this file
|
|
246
|
-
* exist?" it is a miss, because a conditionally-run script still has to be
|
|
247
|
-
* on disk.
|
|
248
|
-
*
|
|
249
|
-
* So this walks EVERY simple command, keeps every word at source level, and
|
|
250
|
-
* subtracts only the words that are provably not paths.
|
|
251
|
-
*
|
|
252
|
-
* 🔴 WHAT IT SUBTRACTS, and the defect that motivated it. The hook scanner used
|
|
253
|
-
* to run a regex over the raw command STRING. Against the standard portable
|
|
254
|
-
* plugin idiom —
|
|
255
|
-
*
|
|
256
|
-
* node -e "(async()=>{…await import(…join(root,'hooks','always-on.mjs'))…})()"
|
|
257
|
-
*
|
|
258
|
-
* — it grabbed a character run ending at `.mjs` and reported the hook's script
|
|
259
|
-
* as `import(require(node:url).pathToFileURL(require(node:path).join(root,hooks,always-on.mjs`,
|
|
260
|
-
* MISSING. `hooks/always-on.mjs` was 1,766 bytes on disk. Nine such findings
|
|
261
|
-
* across the 32-repo corpus, contributing to two `F/0` grades. Inside a shell
|
|
262
|
-
* parse the argument of `-e` is not a word the shell will ever resolve to a
|
|
263
|
-
* file, so it is not returned.
|
|
264
|
-
*
|
|
265
|
-
* ⚠️ HOW MUCH OF THAT THE FLAG TABLE ACTUALLY DID, measured rather than
|
|
266
|
-
* assumed: none of it, on that corpus. Mutating the `-e`/`-c` subtraction OFF
|
|
267
|
-
* and re-auditing all three affected repos still yields ZERO false hook-script
|
|
268
|
-
* findings, because both real payloads are single words that either contain
|
|
269
|
-
* whitespace or do not end in a script extension, and the caller anchors its
|
|
270
|
-
* match to a whole word. The table is kept because it is the difference
|
|
271
|
-
* between a function whose contract ("words that could name a file") is true
|
|
272
|
-
* and one whose contract is merely true-so-far: without it a JavaScript
|
|
273
|
-
* program is handed to every caller as a candidate filename, and the next
|
|
274
|
-
* caller inherits the bug. Recorded here so nobody reads a corpus number back
|
|
275
|
-
* onto the wrong mechanism.
|
|
276
|
-
*
|
|
277
|
-
* Words beginning with `-` are dropped as flags: a flag is not a path, and the
|
|
278
|
-
* one caller anchors its match to a whole word anyway.
|
|
279
|
-
*
|
|
280
|
-
* Returns `null` — not `[]` — when the text does not parse as shell, so a
|
|
281
|
-
* caller can tell "no file operands" from "no analysis", and cannot silently
|
|
282
|
-
* treat the second as the first.
|
|
283
|
-
*/
|
|
284
|
-
export declare function commandWords(command: string): string[] | null;
|
|
285
228
|
//# sourceMappingURL=bash-effects.d.ts.map
|
|
@@ -31,7 +31,6 @@ exports.leafCommands = leafCommands;
|
|
|
31
31
|
exports.stripWrappers = stripWrappers;
|
|
32
32
|
exports.leafCommandsNormalized = leafCommandsNormalized;
|
|
33
33
|
exports.leafArgvSource = leafArgvSource;
|
|
34
|
-
exports.commandWords = commandWords;
|
|
35
34
|
/**
|
|
36
35
|
* The parser is loaded ON FIRST PARSE, not at module load — `sh()` memoizes it.
|
|
37
36
|
*
|
|
@@ -1164,150 +1163,4 @@ function normalizeCallExpr(node, redirs) {
|
|
|
1164
1163
|
chdir: stripped.chdir,
|
|
1165
1164
|
};
|
|
1166
1165
|
}
|
|
1167
|
-
// ===========================================================================
|
|
1168
|
-
// FILE-OPERAND extraction (the reference question, not the effect question)
|
|
1169
|
-
// ===========================================================================
|
|
1170
|
-
/**
|
|
1171
|
-
* Interpreters, and the flags after which the NEXT word is a PROGRAM rather
|
|
1172
|
-
* than a path. `node -e "<js>"`, `python -c "<py>"`, `perl -E "<pl>"`.
|
|
1173
|
-
*
|
|
1174
|
-
* Keyed by the head's basename, so `/usr/local/bin/node` and `node` behave the
|
|
1175
|
-
* same.
|
|
1176
|
-
*/
|
|
1177
|
-
const INLINE_PROGRAM_FLAGS = new Map([
|
|
1178
|
-
["node", ["-e", "--eval", "-p", "--print"]],
|
|
1179
|
-
["nodejs", ["-e", "--eval", "-p", "--print"]],
|
|
1180
|
-
["bun", ["-e", "--eval", "-p", "--print"]],
|
|
1181
|
-
["deno", ["-e", "--eval", "-p", "--print"]],
|
|
1182
|
-
["python", ["-c"]],
|
|
1183
|
-
["python2", ["-c"]],
|
|
1184
|
-
["python3", ["-c"]],
|
|
1185
|
-
["ruby", ["-e"]],
|
|
1186
|
-
["perl", ["-e", "-E"]],
|
|
1187
|
-
["php", ["-r"]],
|
|
1188
|
-
]);
|
|
1189
|
-
/**
|
|
1190
|
-
* Shells, whose `-c` argument is a nested SHELL program. Not program text to be
|
|
1191
|
-
* discarded — program text to be PARSED, so `bash -c 'exec "$ROOT/hooks/x.sh"'`
|
|
1192
|
-
* still yields its script.
|
|
1193
|
-
*/
|
|
1194
|
-
const SHELL_HEADS = new Set([
|
|
1195
|
-
"sh",
|
|
1196
|
-
"bash",
|
|
1197
|
-
"zsh",
|
|
1198
|
-
"dash",
|
|
1199
|
-
"ksh",
|
|
1200
|
-
"ash",
|
|
1201
|
-
"busybox",
|
|
1202
|
-
]);
|
|
1203
|
-
/** Guard against a pathological `sh -c 'sh -c "sh -c …"'` nest. */
|
|
1204
|
-
const MAX_SHELL_NESTING = 3;
|
|
1205
|
-
/**
|
|
1206
|
-
* Every word of every simple command in `command` that could name a FILE, with
|
|
1207
|
-
* inline PROGRAM TEXT removed — the primitive behind "does this hook's script
|
|
1208
|
-
* exist?".
|
|
1209
|
-
*
|
|
1210
|
-
* 🔴 WHY A FOURTH EXTRACTOR, stated against the three that already exist,
|
|
1211
|
-
* because "there is already one that returns words" is exactly the reasoning
|
|
1212
|
-
* that produced the bug this replaces.
|
|
1213
|
-
*
|
|
1214
|
-
* - `leafCommands` drops every word it cannot reduce to a LITERAL, so
|
|
1215
|
-
* `${CLAUDE_PLUGIN_ROOT}/hooks/x.sh` — the standard spelling of a hook path —
|
|
1216
|
-
* disappears entirely. Unusable for a file question.
|
|
1217
|
-
* - `leafCommandsNormalized` basenames the head, so `./hooks/x.sh` becomes
|
|
1218
|
-
* `x.sh` and no resolver can find it.
|
|
1219
|
-
* - `leafArgvSource` keeps the spelling but answers a DIFFERENT question:
|
|
1220
|
-
* "which leaves unconditionally RUN". It drops the right-hand side of `&&`
|
|
1221
|
-
* by design, so `cd "$ROOT" && node hooks/x.mjs` yields no script. For
|
|
1222
|
-
* coverage attribution that abstention is correct; for "must this file
|
|
1223
|
-
* exist?" it is a miss, because a conditionally-run script still has to be
|
|
1224
|
-
* on disk.
|
|
1225
|
-
*
|
|
1226
|
-
* So this walks EVERY simple command, keeps every word at source level, and
|
|
1227
|
-
* subtracts only the words that are provably not paths.
|
|
1228
|
-
*
|
|
1229
|
-
* 🔴 WHAT IT SUBTRACTS, and the defect that motivated it. The hook scanner used
|
|
1230
|
-
* to run a regex over the raw command STRING. Against the standard portable
|
|
1231
|
-
* plugin idiom —
|
|
1232
|
-
*
|
|
1233
|
-
* node -e "(async()=>{…await import(…join(root,'hooks','always-on.mjs'))…})()"
|
|
1234
|
-
*
|
|
1235
|
-
* — it grabbed a character run ending at `.mjs` and reported the hook's script
|
|
1236
|
-
* as `import(require(node:url).pathToFileURL(require(node:path).join(root,hooks,always-on.mjs`,
|
|
1237
|
-
* MISSING. `hooks/always-on.mjs` was 1,766 bytes on disk. Nine such findings
|
|
1238
|
-
* across the 32-repo corpus, contributing to two `F/0` grades. Inside a shell
|
|
1239
|
-
* parse the argument of `-e` is not a word the shell will ever resolve to a
|
|
1240
|
-
* file, so it is not returned.
|
|
1241
|
-
*
|
|
1242
|
-
* ⚠️ HOW MUCH OF THAT THE FLAG TABLE ACTUALLY DID, measured rather than
|
|
1243
|
-
* assumed: none of it, on that corpus. Mutating the `-e`/`-c` subtraction OFF
|
|
1244
|
-
* and re-auditing all three affected repos still yields ZERO false hook-script
|
|
1245
|
-
* findings, because both real payloads are single words that either contain
|
|
1246
|
-
* whitespace or do not end in a script extension, and the caller anchors its
|
|
1247
|
-
* match to a whole word. The table is kept because it is the difference
|
|
1248
|
-
* between a function whose contract ("words that could name a file") is true
|
|
1249
|
-
* and one whose contract is merely true-so-far: without it a JavaScript
|
|
1250
|
-
* program is handed to every caller as a candidate filename, and the next
|
|
1251
|
-
* caller inherits the bug. Recorded here so nobody reads a corpus number back
|
|
1252
|
-
* onto the wrong mechanism.
|
|
1253
|
-
*
|
|
1254
|
-
* Words beginning with `-` are dropped as flags: a flag is not a path, and the
|
|
1255
|
-
* one caller anchors its match to a whole word anyway.
|
|
1256
|
-
*
|
|
1257
|
-
* Returns `null` — not `[]` — when the text does not parse as shell, so a
|
|
1258
|
-
* caller can tell "no file operands" from "no analysis", and cannot silently
|
|
1259
|
-
* treat the second as the first.
|
|
1260
|
-
*/
|
|
1261
|
-
function commandWords(command) {
|
|
1262
|
-
return commandWordsAt(command, 0);
|
|
1263
|
-
}
|
|
1264
|
-
function commandWordsAt(command, depth) {
|
|
1265
|
-
let file;
|
|
1266
|
-
try {
|
|
1267
|
-
file = sh().syntax.NewParser().Parse(command, "cmd.sh");
|
|
1268
|
-
}
|
|
1269
|
-
catch {
|
|
1270
|
-
return null;
|
|
1271
|
-
}
|
|
1272
|
-
const out = [];
|
|
1273
|
-
sh().syntax.Walk(file, (node) => {
|
|
1274
|
-
if (sh().syntax.NodeType(node) === "CallExpr" && node.Args?.length)
|
|
1275
|
-
fileOperandsOf(node.Args, depth, out);
|
|
1276
|
-
return true;
|
|
1277
|
-
});
|
|
1278
|
-
return out;
|
|
1279
|
-
}
|
|
1280
|
-
/**
|
|
1281
|
-
* The file-operand words of ONE simple command, appended to `out`.
|
|
1282
|
-
*
|
|
1283
|
-
* Wrappers are resolved through with the same table `leafArgvSource` uses (it
|
|
1284
|
-
* keys on the BASENAME head, and wrappers only ever drop words off the FRONT,
|
|
1285
|
-
* so a count maps the result back onto the original spellings — not a second
|
|
1286
|
-
* copy of the rule). Flags never name a file, so they are dropped; the word
|
|
1287
|
-
* AFTER an inline-program flag is dropped with them, and the word after a
|
|
1288
|
-
* shell's `-c` is parsed as shell instead.
|
|
1289
|
-
*/
|
|
1290
|
-
function fileOperandsOf(args, depth, out) {
|
|
1291
|
-
const raw = args.map((w) => sourceParts(w.Parts) ?? "");
|
|
1292
|
-
const probe = [normalizeHead(raw[0] ?? ""), ...raw.slice(1)];
|
|
1293
|
-
const argv = raw.slice(probe.length - stripWrappers(probe).argv.length);
|
|
1294
|
-
const head = normalizeHead(argv[0] ?? "");
|
|
1295
|
-
const programFlags = INLINE_PROGRAM_FLAGS.get(head);
|
|
1296
|
-
const nestsShell = SHELL_HEADS.has(head) && depth < MAX_SHELL_NESTING;
|
|
1297
|
-
for (let i = 0; i < argv.length; i++) {
|
|
1298
|
-
const w = argv[i] ?? "";
|
|
1299
|
-
if (w === "")
|
|
1300
|
-
continue;
|
|
1301
|
-
if (!w.startsWith("-")) {
|
|
1302
|
-
out.push(w);
|
|
1303
|
-
continue;
|
|
1304
|
-
}
|
|
1305
|
-
if (nestsShell && w === "-c") {
|
|
1306
|
-
out.push(...(commandWordsAt(argv[++i] ?? "", depth + 1) ?? []));
|
|
1307
|
-
}
|
|
1308
|
-
else if (programFlags?.includes(w)) {
|
|
1309
|
-
i++; // the program text — not a word any shell resolves to a file
|
|
1310
|
-
}
|
|
1311
|
-
}
|
|
1312
|
-
}
|
|
1313
1166
|
//# sourceMappingURL=bash-effects.js.map
|
|
@@ -48,16 +48,16 @@ export interface CompileGeneratorSkillResult {
|
|
|
48
48
|
* function* () { … })` — to a full SKILL.md (frontmatter + body + integrity
|
|
49
49
|
* hash), verifying gate references. This is the CLI entry for generator skills.
|
|
50
50
|
*/
|
|
51
|
-
export declare function compileGeneratorSkill(source: string, options
|
|
52
|
-
basePath
|
|
53
|
-
specFile?: string;
|
|
51
|
+
export declare function compileGeneratorSkill(source: string, options: {
|
|
52
|
+
readonly basePath: string;
|
|
53
|
+
readonly specFile?: string;
|
|
54
54
|
}): CompileGeneratorSkillResult;
|
|
55
55
|
/**
|
|
56
56
|
* Compile a generator's SOURCE text to SKILL.md markdown + verified-ref
|
|
57
57
|
* errors. `frontmatter` (name/description/…) is prepended verbatim if given.
|
|
58
58
|
*/
|
|
59
|
-
export declare function compileGenerator(source: string, options
|
|
60
|
-
basePath
|
|
61
|
-
frontmatter?: string;
|
|
59
|
+
export declare function compileGenerator(source: string, options: {
|
|
60
|
+
readonly basePath: string;
|
|
61
|
+
readonly frontmatter?: string;
|
|
62
62
|
}): CompileGeneratorResult;
|
|
63
63
|
//# sourceMappingURL=compile-generator.d.ts.map
|
|
@@ -263,8 +263,8 @@ function extractMeta(obj) {
|
|
|
263
263
|
* function* () { … })` — to a full SKILL.md (frontmatter + body + integrity
|
|
264
264
|
* hash), verifying gate references. This is the CLI entry for generator skills.
|
|
265
265
|
*/
|
|
266
|
-
function compileGeneratorSkill(source, options
|
|
267
|
-
const basePath = options.basePath
|
|
266
|
+
function compileGeneratorSkill(source, options) {
|
|
267
|
+
const basePath = options.basePath;
|
|
268
268
|
const specFile = options.specFile ?? "SKILL.md.spec.ts";
|
|
269
269
|
const sf = typescript_1.default.createSourceFile("s.ts", source, typescript_1.default.ScriptTarget.Latest, true);
|
|
270
270
|
const call = findGenSkillCall(sf);
|
|
@@ -309,8 +309,8 @@ function compileGeneratorSkill(source, options = {}) {
|
|
|
309
309
|
* Compile a generator's SOURCE text to SKILL.md markdown + verified-ref
|
|
310
310
|
* errors. `frontmatter` (name/description/…) is prepended verbatim if given.
|
|
311
311
|
*/
|
|
312
|
-
function compileGenerator(source, options
|
|
313
|
-
const basePath = options.basePath
|
|
312
|
+
function compileGenerator(source, options) {
|
|
313
|
+
const basePath = options.basePath;
|
|
314
314
|
const sf = typescript_1.default.createSourceFile("skill.ts", source, typescript_1.default.ScriptTarget.Latest, true);
|
|
315
315
|
const gen = findGenerator(sf);
|
|
316
316
|
if (!gen?.body) {
|
package/dist/core/compile.d.ts
CHANGED
|
@@ -66,6 +66,46 @@ export declare function validateCommandRef(command: string, basePath: string): C
|
|
|
66
66
|
export declare function validateSymbolRef(file: string, name: string, basePath: string): Promise<CompileError | null>;
|
|
67
67
|
export declare function validateDirRef(dirPath: string, basePath: string): CompileError | null;
|
|
68
68
|
export declare function validateGlobRef(pattern: string, basePath: string): CompileError | null;
|
|
69
|
+
/**
|
|
70
|
+
* Why an `enforce()` reference was NOT verified. Separate members, not one
|
|
71
|
+
* "unknown", because the compile output turns each into a different instruction
|
|
72
|
+
* (make-the-distinction-a-type): a switch someone turned off is fixed by turning
|
|
73
|
+
* it on, an unset rule by setting it, an unreadable config by fixing the probe.
|
|
74
|
+
*/
|
|
75
|
+
export type UnverifiedReason =
|
|
76
|
+
/** `enforce(…, { verify: false })` on this rule. */
|
|
77
|
+
"verify-false"
|
|
78
|
+
/** `verifyLinters: false` for the whole compile. */
|
|
79
|
+
| "verification-off"
|
|
80
|
+
/** `linterModes[<linter>] === false`. */
|
|
81
|
+
| "linter-off"
|
|
82
|
+
/** catalog-only: the rule exists, the config was not read. */
|
|
83
|
+
| "config-not-read"
|
|
84
|
+
/** the whole config was read and no block sets the rule. */
|
|
85
|
+
| "not-configured"
|
|
86
|
+
/** the rule exists; whether the config switches it on could not be read. */
|
|
87
|
+
| "enabled-unknown"
|
|
88
|
+
/** the rule does not exist (a compile error as well). */
|
|
89
|
+
| "not-found"
|
|
90
|
+
/** the config switches the rule off (a compile error as well). */
|
|
91
|
+
| "disabled";
|
|
92
|
+
/** What `compile` established about one `enforce()` reference. */
|
|
93
|
+
export type EnforceVerdict = {
|
|
94
|
+
readonly kind: "verified";
|
|
95
|
+
} | {
|
|
96
|
+
readonly kind: "unverified";
|
|
97
|
+
readonly reason: UnverifiedReason;
|
|
98
|
+
};
|
|
99
|
+
/** One `enforce()` reference and its verdict, in spec order. */
|
|
100
|
+
export interface EnforceVerdictEntry {
|
|
101
|
+
readonly ref: string;
|
|
102
|
+
readonly verdict: EnforceVerdict;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* The sentence the compile prints for an unverified reference: what happened
|
|
106
|
+
* and the one thing that turns it into "Enforced by".
|
|
107
|
+
*/
|
|
108
|
+
export declare function unverifiedAdvice(ref: string, reason: UnverifiedReason): string;
|
|
69
109
|
export interface CompileClaudeResult {
|
|
70
110
|
markdown: string;
|
|
71
111
|
errors: CompileError[];
|
|
@@ -86,10 +126,28 @@ export interface CompileClaudeResult {
|
|
|
86
126
|
*/
|
|
87
127
|
budgetFindings: CompileError[];
|
|
88
128
|
linterResults: LinterCheckResult[];
|
|
129
|
+
/**
|
|
130
|
+
* One entry per `enforce()` rule, in spec order: rendered "**Enforced by:**"
|
|
131
|
+
* exactly when `verdict.kind === "verified"`, "**Claimed (unverified):**"
|
|
132
|
+
* otherwise. The CLI's "N linter-verified" count is the verified entries.
|
|
133
|
+
*/
|
|
134
|
+
enforceVerdicts: EnforceVerdictEntry[];
|
|
89
135
|
/** Estimated token count of compiled output (~4 chars/token). */
|
|
90
136
|
tokens: number;
|
|
91
137
|
/** All targets from the spec (for multi-target compilation). */
|
|
92
138
|
targets: string[];
|
|
139
|
+
/**
|
|
140
|
+
* Each target's file: its repo-relative path (a secondary target is named
|
|
141
|
+
* from the primary's directory) and its markdown, rendered for THAT path so
|
|
142
|
+
* every link resolves from where the file sits. The first is the primary,
|
|
143
|
+
* whose markdown is `markdown`.
|
|
144
|
+
*/
|
|
145
|
+
outputs: CompiledOutput[];
|
|
146
|
+
}
|
|
147
|
+
/** One file a multi-target compile writes. */
|
|
148
|
+
export interface CompiledOutput {
|
|
149
|
+
readonly path: string;
|
|
150
|
+
readonly markdown: string;
|
|
93
151
|
}
|
|
94
152
|
export interface CompileClaudeOptions {
|
|
95
153
|
/**
|
|
@@ -107,7 +165,8 @@ export interface CompileClaudeOptions {
|
|
|
107
165
|
maxSectionChars?: number;
|
|
108
166
|
/** Character budget for the whole rendered Rules section (0 disables). */
|
|
109
167
|
maxRulesChars?: number;
|
|
110
|
-
|
|
168
|
+
/** The repo root every reference resolves against. Required: no cwd fallback. */
|
|
169
|
+
readonly basePath: string;
|
|
111
170
|
specFile?: string;
|
|
112
171
|
/** Injected harness dialect; its instructionTargets[0] is the default target. */
|
|
113
172
|
dialect?: HarnessDialect;
|
|
@@ -166,13 +225,15 @@ export declare const DEFAULT_MAX_SECTION_CHARS = 15000;
|
|
|
166
225
|
* budget, which leaves the other half for everything else the file carries.
|
|
167
226
|
*/
|
|
168
227
|
export declare const DEFAULT_MAX_RULES_CHARS = 20000;
|
|
228
|
+
/** The compile options that decide how an `enforce()` reference is verified. */
|
|
229
|
+
type LinterVerifyOptions = Pick<CompileClaudeOptions, "verifyLinters" | "linterModes" | "catalogOnly" | "linters">;
|
|
169
230
|
/**
|
|
170
231
|
* Compile a ClaudeSpec into markdown.
|
|
171
232
|
*
|
|
172
233
|
* Returns the compiled markdown, validation errors, and linter check results.
|
|
173
234
|
* The markdown is generated even if there are errors (with warnings).
|
|
174
235
|
*/
|
|
175
|
-
export declare function compileClaude(spec: ClaudeSpec, options
|
|
236
|
+
export declare function compileClaude(spec: ClaudeSpec, options: Readonly<CompileClaudeOptions>): Promise<CompileClaudeResult>;
|
|
176
237
|
export interface CompileSkillResult {
|
|
177
238
|
/**
|
|
178
239
|
* The stamped artifact — present ONLY when `errors` is empty. `null` is what
|
|
@@ -187,13 +248,14 @@ export interface CompileSkillResult {
|
|
|
187
248
|
/**
|
|
188
249
|
* Compile a SkillSpec into SKILL.md markdown with YAML frontmatter.
|
|
189
250
|
*/
|
|
190
|
-
export declare function compileSkill(spec: SkillSpec, options
|
|
191
|
-
|
|
251
|
+
export declare function compileSkill(spec: SkillSpec, options: Readonly<{
|
|
252
|
+
/** The repo root every reference resolves against. Required: no cwd fallback. */
|
|
253
|
+
readonly basePath: string;
|
|
192
254
|
specFile?: string;
|
|
193
255
|
/** The harness dialect — supplies `skillFrontmatterKeys`. Omitting it emits
|
|
194
256
|
* every key the compiler can render, so existing callers are unchanged. */
|
|
195
257
|
dialect?: HarnessDialect;
|
|
196
|
-
}): Promise<CompileSkillResult>;
|
|
258
|
+
}>): Promise<CompileSkillResult>;
|
|
197
259
|
export interface CompileAgentResult {
|
|
198
260
|
/**
|
|
199
261
|
* The stamped artifact — present ONLY when `errors` is empty. `null` is what
|
|
@@ -210,13 +272,14 @@ export interface CompileAgentResult {
|
|
|
210
272
|
* Verifies the tool contract and the body's references; the marks the body
|
|
211
273
|
* carries (`vigiles:symbol`, file/cmd refs) are the same ones `lint` re-checks.
|
|
212
274
|
*/
|
|
213
|
-
export declare function compileAgent(spec: AgentSpec, options: {
|
|
214
|
-
|
|
275
|
+
export declare function compileAgent(spec: AgentSpec, options: Readonly<{
|
|
276
|
+
/** The repo root every reference resolves against. Required: no cwd fallback. */
|
|
277
|
+
basePath: string;
|
|
215
278
|
specFile?: string;
|
|
216
279
|
/** The harness dialect to verify the tool contract against (required — the
|
|
217
280
|
* core defines no default dialect; the adapter/composition root injects it). */
|
|
218
281
|
dialect: HarnessDialect;
|
|
219
|
-
}): Promise<CompileAgentResult>;
|
|
282
|
+
} & LinterVerifyOptions>): Promise<CompileAgentResult>;
|
|
220
283
|
export interface CompileRailwayOptions {
|
|
221
284
|
/** Names of compiled agents, to resolve `delegate` targets. Skipped if omitted. */
|
|
222
285
|
knownAgents?: readonly string[];
|
|
@@ -261,4 +324,5 @@ export interface AdoptResult {
|
|
|
261
324
|
* Returns the diff so users can see what was manually changed.
|
|
262
325
|
*/
|
|
263
326
|
export declare function adoptDiff(filePath: string, spec: ClaudeSpec | SkillSpec | AgentSpec, basePath: string, dialect: HarnessDialect): Promise<AdoptResult>;
|
|
327
|
+
export {};
|
|
264
328
|
//# sourceMappingURL=compile.d.ts.map
|