vigiles 5.2.0 → 7.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 +99 -48
- package/dist/action-gate.js +1 -1
- package/dist/adapters/claude-code/agent-runtime.d.ts +64 -4
- package/dist/adapters/claude-code/agent-runtime.js +131 -17
- package/dist/adapters/claude-code/dialect.d.ts +34 -0
- package/dist/adapters/claude-code/dialect.js +46 -33
- package/dist/adapters/claude-code/effect-region.js +1 -1
- package/dist/adapters/claude-code/skill-runtime.d.ts +1 -1
- package/dist/adapters/claude-code/skill-runtime.js +1 -9
- package/dist/adapters/claude-code/typed-spec.d.ts +58 -0
- package/dist/adapters/claude-code/typed-spec.js +55 -0
- package/dist/adapters/codex/hook-protocol.js +3 -0
- package/dist/adapters/codex/mock-model.js +1 -1
- package/dist/claude-code.d.ts +1 -0
- package/dist/claude-code.js +8 -1
- package/dist/cli-commands.d.ts +19 -0
- package/dist/cli-commands.js +51 -0
- package/dist/cli.js +735 -76
- package/dist/core/bash-effects.d.ts +12 -0
- package/dist/core/bash-effects.js +31 -0
- package/dist/core/capability-diff.d.ts +46 -0
- package/dist/core/capability-diff.js +97 -0
- package/dist/core/compile.d.ts +1 -1
- package/dist/core/compile.js +14 -0
- package/dist/core/generate-harness.d.ts +187 -0
- package/dist/core/generate-harness.js +337 -0
- package/dist/core/guards.d.ts +126 -0
- package/dist/core/guards.js +309 -0
- package/dist/core/harness-driver.d.ts +1 -1
- package/dist/core/hook-program.d.ts +459 -0
- package/dist/core/hook-program.js +468 -0
- package/dist/core/hook-protocol.d.ts +7 -0
- package/dist/core/hook-providers.d.ts +138 -0
- package/dist/core/hook-providers.js +155 -0
- package/dist/core/hook-spec.d.ts +74 -0
- package/dist/core/hook-spec.js +130 -0
- package/dist/core/inline.js +1 -1
- package/dist/core/mcp-tool.d.ts +12 -0
- package/dist/core/mcp-tool.js +20 -0
- package/dist/core/mcp.d.ts +13 -0
- package/dist/core/mcp.js +67 -0
- package/dist/core/spec.d.ts +290 -8
- package/dist/core/spec.js +118 -3
- package/dist/core/types.d.ts +8 -0
- package/dist/dialect-drift.d.ts +65 -0
- package/dist/dialect-drift.js +216 -0
- package/dist/eval.d.ts +40 -5
- package/dist/eval.js +59 -5
- package/dist/guardrail-check.d.ts +85 -0
- package/dist/guardrail-check.js +152 -0
- package/dist/harness-assert.d.ts +10 -0
- package/dist/harness-assert.js +30 -0
- package/dist/hook-install.d.ts +43 -0
- package/dist/hook-install.js +91 -0
- package/dist/hook.d.ts +52 -0
- package/dist/hook.js +98 -0
- package/dist/leaderboard.d.ts +6 -0
- package/dist/leaderboard.js +43 -1
- package/dist/linting.d.ts +9 -5
- package/dist/linting.js +17 -5
- package/dist/optimize.js +1 -1
- package/dist/scaffold-test.d.ts +28 -0
- package/dist/scaffold-test.js +134 -15
- package/dist/scan-behavioral.d.ts +60 -0
- package/dist/scan-behavioral.js +239 -1
- package/dist/scan.d.ts +14 -0
- package/dist/scan.js +33 -1
- package/dist/score-explainer.js +1 -1
- package/dist/self-command-refs.d.ts +21 -0
- package/dist/self-command-refs.js +125 -0
- package/dist/testing.d.ts +5 -3
- package/dist/testing.js +37 -23
- package/dist/tool-intercept.d.ts +4 -4
- package/dist/tool-intercept.js +5 -5
- package/dist/unit.d.ts +2 -0
- package/dist/unit.js +8 -1
- package/hooks/refs-nudge.sh +1 -1
- package/package.json +5 -3
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.findStaleCommandRefs = findStaleCommandRefs;
|
|
4
|
+
/**
|
|
5
|
+
* Self-command-reference verification — the cross-reference moat applied to
|
|
6
|
+
* vigiles's OWN docs. vigiles verifies that a CLAUDE.md's commands resolve; its
|
|
7
|
+
* own docs cite ITS OWN commands, and nothing checked those until a rename left
|
|
8
|
+
* `vigiles compile-hook` / `vigiles run-skill` rotting in the docs. This is the
|
|
9
|
+
* deterministic gate: every `vigiles <cmd>` reference in a doc/comment must
|
|
10
|
+
* resolve to a real command (a VERB or a `hook-runtime <kind>`).
|
|
11
|
+
*
|
|
12
|
+
* HIGH-PRECISION by construction (don't-cry-wolf). A reference is inspected only
|
|
13
|
+
* when it's an unambiguous COMMAND — i.e. it sits inside an inline `` `span` ``,
|
|
14
|
+
* inside a ```shell fence```, or is prefixed `npx vigiles` / `Usage: vigiles` /
|
|
15
|
+
* is a `cli.js` or `${CLI}` invocation (the harness-test convention `node ${CLI}
|
|
16
|
+
* <cmd>`). Prose ("vigiles compiles the spec", "adds vigiles to devDependencies")
|
|
17
|
+
* and non-shell fences (```text agent prompts, ```ts) are never matched. A bare unknown VERB is flagged only when hyphenated (every
|
|
18
|
+
* renamed vigiles command is — `compile-hook`, `run-skill`) or in an explicit
|
|
19
|
+
* invocation; `hook-runtime <kind>` is checked in any command context. Source of
|
|
20
|
+
* truth: {@link VERBS} / {@link HOOK_RUNTIME_KINDS}.
|
|
21
|
+
*
|
|
22
|
+
* KNOWN LIMITATION (measured, deliberately not "fixed"): this catches the
|
|
23
|
+
* `vigiles <cmd>` / `cli.js <cmd>` INVOCATION form. It does NOT flag a BARE
|
|
24
|
+
* command name (`agent-hook` without the `vigiles ` prefix) nor a bare file path
|
|
25
|
+
* (`src/foo.ts`), because both collide with legitimate non-references: bare
|
|
26
|
+
* command names double as CONCEPT names (`the refs-hook nudge` appears as a
|
|
27
|
+
* feature name in ~10 files; `agent-hook` as a rail name + in test labels +
|
|
28
|
+
* `makeTmpDir("agent-hook-cli")`), and bare paths collide with ILLUSTRATIVE
|
|
29
|
+
* examples (the README's `src/auth/login.ts`, `docs/foo.md`) and test fixtures
|
|
30
|
+
* (`session.test.ts` builds fake `src/compile.ts` diffs). A denylist over either
|
|
31
|
+
* would cry wolf on dozens of valid usages — so terminology/path-accuracy stays
|
|
32
|
+
* the JUDGMENT half the `doc-consistency` rule assigns to discipline, not a check.
|
|
33
|
+
*/
|
|
34
|
+
const cli_commands_js_1 = require("./cli-commands.js");
|
|
35
|
+
const DEFAULT_KNOWN = {
|
|
36
|
+
verbs: cli_commands_js_1.VERBS,
|
|
37
|
+
kinds: cli_commands_js_1.HOOK_RUNTIME_KINDS,
|
|
38
|
+
};
|
|
39
|
+
const TOKEN = "[a-z][a-z0-9-]*";
|
|
40
|
+
// `[npx ][vigiles|cli.js|${CLI}] <verb> [<kind>]` — capture the optional prefix +
|
|
41
|
+
// literal. `${CLI}` is the harness-test convention (`const CLI = new
|
|
42
|
+
// URL("…/dist/cli.js")` → `node ${CLI} <cmd>`); without it a stale runtime ref in
|
|
43
|
+
// a `.mjs`/`.test.ts` invocation slips through (it did: refs-nudge.harness.mjs kept
|
|
44
|
+
// calling `refs-hook` after the hook-runtime rename). `\b` can't anchor `${CLI}`
|
|
45
|
+
// (it starts with `$`, a non-word char), so each word literal carries its own `\b`.
|
|
46
|
+
const INVOKE = new RegExp(String.raw `(npx |Usage: )?(\bvigiles|\bcli\.js|\$\{CLI\})\s+(${TOKEN})(?:\s+(${TOKEN}))?`, "g");
|
|
47
|
+
// A bare `hook-runtime <kind>` (e.g. `node ${CLI} hook-runtime agent` in a test).
|
|
48
|
+
const KIND = new RegExp(String.raw `hook-runtime\s+(${TOKEN})`, "g");
|
|
49
|
+
const SHELL_FENCE = /^\s*```(?:bash|sh|shell|zsh|console|shell-session)\s*$/;
|
|
50
|
+
const FENCE = /^\s*```/;
|
|
51
|
+
/** Inclusive index ranges of inline `code spans` in a line. */
|
|
52
|
+
function codeSpans(line) {
|
|
53
|
+
const ranges = [];
|
|
54
|
+
for (const m of line.matchAll(/`[^`\n]+`/g))
|
|
55
|
+
ranges.push([m.index, m.index + m[0].length]);
|
|
56
|
+
return ranges;
|
|
57
|
+
}
|
|
58
|
+
const inSpan = (i, spans) => spans.some(([a, b]) => i >= a && i < b);
|
|
59
|
+
function scanLine(line, inShellFence, known) {
|
|
60
|
+
const spans = inShellFence ? null : codeSpans(line);
|
|
61
|
+
const ctx = (i) => inShellFence || inSpan(i, spans ?? []);
|
|
62
|
+
const out = [];
|
|
63
|
+
const seen = new Set();
|
|
64
|
+
const push = (ref, reason) => {
|
|
65
|
+
const key = ref + "\0" + reason;
|
|
66
|
+
if (!seen.has(key)) {
|
|
67
|
+
seen.add(key);
|
|
68
|
+
out.push({ ref, reason });
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
for (const m of line.matchAll(INVOKE)) {
|
|
72
|
+
const explicit = inShellFence || Boolean(m[1]) || m[2] === "cli.js" || m[2] === "${CLI}";
|
|
73
|
+
if (!explicit && !ctx(m.index))
|
|
74
|
+
continue;
|
|
75
|
+
const verb = m[3];
|
|
76
|
+
if (verb === "hook-runtime") {
|
|
77
|
+
if (m[4] !== undefined && !known.kinds.includes(m[4]))
|
|
78
|
+
push(`hook-runtime ${m[4]}`, `unknown hook-runtime kind "${m[4]}"`);
|
|
79
|
+
}
|
|
80
|
+
else if (!known.verbs.includes(verb) &&
|
|
81
|
+
(verb.includes("-") || explicit)) {
|
|
82
|
+
push(`${m[2]} ${verb}`, `unknown/removed command "${verb}"`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
// Bare `hook-runtime <kind>` (no vigiles/cli.js literal) inside a command context.
|
|
86
|
+
for (const m of line.matchAll(KIND)) {
|
|
87
|
+
if (!ctx(m.index))
|
|
88
|
+
continue;
|
|
89
|
+
if (!known.kinds.includes(m[1]))
|
|
90
|
+
push(`hook-runtime ${m[1]}`, `unknown hook-runtime kind "${m[1]}"`);
|
|
91
|
+
}
|
|
92
|
+
return out;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Find stale/unknown vigiles command references across the given files. Pure —
|
|
96
|
+
* the caller supplies file contents (so it works over the repo in a test, or any
|
|
97
|
+
* file set).
|
|
98
|
+
*/
|
|
99
|
+
function findStaleCommandRefs(files, known = DEFAULT_KNOWN) {
|
|
100
|
+
const issues = [];
|
|
101
|
+
for (const { path, content } of files) {
|
|
102
|
+
let inAnyFence = false;
|
|
103
|
+
let inShellFence = false;
|
|
104
|
+
const lines = content.split("\n");
|
|
105
|
+
for (let i = 0; i < lines.length; i++) {
|
|
106
|
+
const line = lines[i];
|
|
107
|
+
if (FENCE.test(line)) {
|
|
108
|
+
if (inAnyFence) {
|
|
109
|
+
inAnyFence = inShellFence = false;
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
inAnyFence = true;
|
|
113
|
+
inShellFence = SHELL_FENCE.test(line);
|
|
114
|
+
}
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
if (line.includes("vigiles:ignore-cmd"))
|
|
118
|
+
continue;
|
|
119
|
+
for (const f of scanLine(line, inShellFence, known))
|
|
120
|
+
issues.push({ file: path, line: i + 1, ref: f.ref, reason: f.reason });
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return issues;
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=self-command-refs.js.map
|
package/dist/testing.d.ts
CHANGED
|
@@ -10,13 +10,15 @@
|
|
|
10
10
|
* boundary forbids importing `src/adapters/*` from here. See
|
|
11
11
|
* `research/adapter-api-design.md`.
|
|
12
12
|
*/
|
|
13
|
-
export
|
|
14
|
-
export
|
|
13
|
+
export { runHook, propertyHook } from "./run-hook.js";
|
|
14
|
+
export type { HookRunResult, RunHookOptions, HookInput, HookOutput, HookPropertyResult, } from "./run-hook.js";
|
|
15
|
+
export { runEval, measure, measureArms, measureTriggerRate, assertRates, assertPromptDiversity, checkPromptDiversity, checkReportToJUnit, formatCheckReport, formatEvalReport, formatTriggerRateReport, claudeEvalDriver, parseClaudeRun, stubSkillBody, } from "./eval.js";
|
|
16
|
+
export type { EvalArm, EvalDriver, EvalSpec, EvalReport, EvalUsage, MeasureSpec, ArmsMeasureSpec, ArmReport, ArmUsage, ArmsCheckReport, CheckRate, CheckReport, MetricStat, Metrics, ModelOutputParser, ParsedModelRun, PromptDiversityIssue, PromptTriggerStat, RunContext, RunOut, SelectionTrialResult, TriggerRateReport, TriggerRateSpec, AgentRunArgs, AgentRunner, } from "./eval.js";
|
|
15
17
|
export * from "./harness-assert.js";
|
|
16
18
|
export * from "./check.js";
|
|
17
19
|
export { hookFired } from "./check.js";
|
|
18
20
|
export { judge } from "./judge.js";
|
|
19
21
|
export * from "./tool-stub.js";
|
|
20
|
-
export { runHarnessTest, runHarness
|
|
22
|
+
export { runHarnessTest, runHarness } from "./harness-test.js";
|
|
21
23
|
export type { HarnessTestSpec, Trace, SubagentTrace, HarnessTestResult, RunHarnessTestOptions, ModelTurn, ModelRequest, ToolCall, HookFire, HarnessTestDriver, SandboxMode, } from "./harness-test.js";
|
|
22
24
|
//# sourceMappingURL=testing.d.ts.map
|
package/dist/testing.js
CHANGED
|
@@ -1,4 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* `vigiles/testing` — Pillar 2 entry point: the **harness-testing** API. Re-exports
|
|
4
|
+
* the three tiers — `runHook` (unit), `runHarnessTest` (deterministic), `runEval`
|
|
5
|
+
* (eval) — plus the runner-agnostic predicates/assertions. Kept deliberately
|
|
6
|
+
* separate from `vigiles/claude-code` so this surface can stay harness-agnostic as
|
|
7
|
+
* more harnesses are added. Granular paths (`vigiles/run-hook`, etc.) still work.
|
|
8
|
+
*
|
|
9
|
+
* It re-exports the composition-root runner modules (which do the Claude-Code
|
|
10
|
+
* default-wiring), never an adapter directly — the `agnostic-surface` eslint
|
|
11
|
+
* boundary forbids importing `src/adapters/*` from here. See
|
|
12
|
+
* `research/adapter-api-design.md`.
|
|
13
|
+
*/
|
|
14
|
+
// Curated public re-exports (named, not `export *`) so the internal seams —
|
|
15
|
+
// the injectable `*With` runners, low-level `parse*`, pool/aggregate/model-tier
|
|
16
|
+
// helpers — stay out of the public surface, the api reports, and the docs site.
|
|
17
|
+
// (vigiles's own tests import those from the source modules directly.)
|
|
2
18
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
19
|
if (k2 === undefined) k2 = k;
|
|
4
20
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
@@ -14,21 +30,27 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
30
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
31
|
};
|
|
16
32
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
33
|
+
exports.runHarness = exports.runHarnessTest = exports.judge = exports.hookFired = exports.stubSkillBody = exports.parseClaudeRun = exports.claudeEvalDriver = exports.formatTriggerRateReport = exports.formatEvalReport = exports.formatCheckReport = exports.checkReportToJUnit = exports.checkPromptDiversity = exports.assertPromptDiversity = exports.assertRates = exports.measureTriggerRate = exports.measureArms = exports.measure = exports.runEval = exports.propertyHook = exports.runHook = void 0;
|
|
34
|
+
// --- unit tier: runHook ---
|
|
35
|
+
var run_hook_js_1 = require("./run-hook.js");
|
|
36
|
+
Object.defineProperty(exports, "runHook", { enumerable: true, get: function () { return run_hook_js_1.runHook; } });
|
|
37
|
+
Object.defineProperty(exports, "propertyHook", { enumerable: true, get: function () { return run_hook_js_1.propertyHook; } });
|
|
38
|
+
// --- eval tier: runEval / measure / trigger-rate ---
|
|
39
|
+
var eval_js_1 = require("./eval.js");
|
|
40
|
+
Object.defineProperty(exports, "runEval", { enumerable: true, get: function () { return eval_js_1.runEval; } });
|
|
41
|
+
Object.defineProperty(exports, "measure", { enumerable: true, get: function () { return eval_js_1.measure; } });
|
|
42
|
+
Object.defineProperty(exports, "measureArms", { enumerable: true, get: function () { return eval_js_1.measureArms; } });
|
|
43
|
+
Object.defineProperty(exports, "measureTriggerRate", { enumerable: true, get: function () { return eval_js_1.measureTriggerRate; } });
|
|
44
|
+
Object.defineProperty(exports, "assertRates", { enumerable: true, get: function () { return eval_js_1.assertRates; } });
|
|
45
|
+
Object.defineProperty(exports, "assertPromptDiversity", { enumerable: true, get: function () { return eval_js_1.assertPromptDiversity; } });
|
|
46
|
+
Object.defineProperty(exports, "checkPromptDiversity", { enumerable: true, get: function () { return eval_js_1.checkPromptDiversity; } });
|
|
47
|
+
Object.defineProperty(exports, "checkReportToJUnit", { enumerable: true, get: function () { return eval_js_1.checkReportToJUnit; } });
|
|
48
|
+
Object.defineProperty(exports, "formatCheckReport", { enumerable: true, get: function () { return eval_js_1.formatCheckReport; } });
|
|
49
|
+
Object.defineProperty(exports, "formatEvalReport", { enumerable: true, get: function () { return eval_js_1.formatEvalReport; } });
|
|
50
|
+
Object.defineProperty(exports, "formatTriggerRateReport", { enumerable: true, get: function () { return eval_js_1.formatTriggerRateReport; } });
|
|
51
|
+
Object.defineProperty(exports, "claudeEvalDriver", { enumerable: true, get: function () { return eval_js_1.claudeEvalDriver; } });
|
|
52
|
+
Object.defineProperty(exports, "parseClaudeRun", { enumerable: true, get: function () { return eval_js_1.parseClaudeRun; } });
|
|
53
|
+
Object.defineProperty(exports, "stubSkillBody", { enumerable: true, get: function () { return eval_js_1.stubSkillBody; } });
|
|
32
54
|
__exportStar(require("./harness-assert.js"), exports);
|
|
33
55
|
// The declarative check vocabulary is now first-class at the front door. Its
|
|
34
56
|
// `hookFired` (a `Check<Trace>`) supersedes the legacy boolean predicate of the
|
|
@@ -51,12 +73,4 @@ __exportStar(require("./tool-stub.js"), exports);
|
|
|
51
73
|
var harness_test_js_1 = require("./harness-test.js");
|
|
52
74
|
Object.defineProperty(exports, "runHarnessTest", { enumerable: true, get: function () { return harness_test_js_1.runHarnessTest; } });
|
|
53
75
|
Object.defineProperty(exports, "runHarness", { enumerable: true, get: function () { return harness_test_js_1.runHarness; } });
|
|
54
|
-
Object.defineProperty(exports, "parseToolCalls", { enumerable: true, get: function () { return harness_test_js_1.parseToolCalls; } });
|
|
55
|
-
Object.defineProperty(exports, "parseSubagents", { enumerable: true, get: function () { return harness_test_js_1.parseSubagents; } });
|
|
56
|
-
Object.defineProperty(exports, "parseResultEvent", { enumerable: true, get: function () { return harness_test_js_1.parseResultEvent; } });
|
|
57
|
-
Object.defineProperty(exports, "parseOutput", { enumerable: true, get: function () { return harness_test_js_1.parseOutput; } });
|
|
58
|
-
Object.defineProperty(exports, "parseHooks", { enumerable: true, get: function () { return harness_test_js_1.parseHooks; } });
|
|
59
|
-
Object.defineProperty(exports, "decideSandbox", { enumerable: true, get: function () { return harness_test_js_1.decideSandbox; } });
|
|
60
|
-
Object.defineProperty(exports, "specTrusted", { enumerable: true, get: function () { return harness_test_js_1.specTrusted; } });
|
|
61
|
-
Object.defineProperty(exports, "sandboxAvailable", { enumerable: true, get: function () { return harness_test_js_1.sandboxAvailable; } });
|
|
62
76
|
//# sourceMappingURL=testing.js.map
|
package/dist/tool-intercept.d.ts
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
*
|
|
16
16
|
* - `decideIntercept` — does this call get intercepted, and with what deny reason;
|
|
17
17
|
* - `buildInterceptSettings` — the PreToolUse hook fragment routing matched tools
|
|
18
|
-
* through `vigiles intercept-tool
|
|
18
|
+
* through `vigiles hook-runtime intercept-tool`;
|
|
19
19
|
* - `serializeIntercepts` / `parseIntercepts` — the env round-trip (incl. RegExp
|
|
20
20
|
* matchers) the hook subprocess reads back.
|
|
21
21
|
*
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
* tools, so deny+reason is the closest available — with that ceiling.
|
|
33
33
|
*/
|
|
34
34
|
import { type ArgMatcher } from "./arg-match.js";
|
|
35
|
-
/** Env var the spawned `vigiles intercept-tool
|
|
35
|
+
/** Env var the spawned `vigiles hook-runtime intercept-tool` reads its intercept list from. */
|
|
36
36
|
export declare const INTERCEPT_TOOLS_ENV = "VIGILES_INTERCEPT_TOOLS";
|
|
37
37
|
/** Declare a tool to intercept: deny its real execution with a block message. */
|
|
38
38
|
export interface ToolIntercept {
|
|
@@ -63,7 +63,7 @@ export type InterceptDecision = {
|
|
|
63
63
|
/**
|
|
64
64
|
* Decide whether a tool call should be intercepted. Returns the first matching
|
|
65
65
|
* intercept's denial reason (preventing real execution), or `{ intercept: false }`
|
|
66
|
-
* to let the call run for real. Pure — the same logic `vigiles intercept-tool
|
|
66
|
+
* to let the call run for real. Pure — the same logic `vigiles hook-runtime intercept-tool`
|
|
67
67
|
* runs.
|
|
68
68
|
*/
|
|
69
69
|
export declare function decideIntercept(toolName: string, input: unknown, intercepts: readonly ToolIntercept[]): InterceptDecision;
|
|
@@ -81,7 +81,7 @@ export interface InterceptSettings {
|
|
|
81
81
|
}
|
|
82
82
|
/**
|
|
83
83
|
* Build the PreToolUse hook fragment that routes every intercepted tool through
|
|
84
|
-
* `vigiles intercept-tool
|
|
84
|
+
* `vigiles hook-runtime intercept-tool`. The `matcher` is a CC tool-name regex over the
|
|
85
85
|
* union of intercepted tool names (each escaped), so unrelated tools are never
|
|
86
86
|
* intercepted. Merge the result into an arm's `settings`; the intercept list
|
|
87
87
|
* itself travels in the {@link INTERCEPT_TOOLS_ENV} env var (see
|
package/dist/tool-intercept.js
CHANGED
|
@@ -23,7 +23,7 @@ exports.parseIntercepts = parseIntercepts;
|
|
|
23
23
|
*
|
|
24
24
|
* - `decideIntercept` — does this call get intercepted, and with what deny reason;
|
|
25
25
|
* - `buildInterceptSettings` — the PreToolUse hook fragment routing matched tools
|
|
26
|
-
* through `vigiles intercept-tool
|
|
26
|
+
* through `vigiles hook-runtime intercept-tool`;
|
|
27
27
|
* - `serializeIntercepts` / `parseIntercepts` — the env round-trip (incl. RegExp
|
|
28
28
|
* matchers) the hook subprocess reads back.
|
|
29
29
|
*
|
|
@@ -40,7 +40,7 @@ exports.parseIntercepts = parseIntercepts;
|
|
|
40
40
|
* tools, so deny+reason is the closest available — with that ceiling.
|
|
41
41
|
*/
|
|
42
42
|
const arg_match_js_1 = require("./arg-match.js");
|
|
43
|
-
/** Env var the spawned `vigiles intercept-tool
|
|
43
|
+
/** Env var the spawned `vigiles hook-runtime intercept-tool` reads its intercept list from. */
|
|
44
44
|
exports.INTERCEPT_TOOLS_ENV = "VIGILES_INTERCEPT_TOOLS";
|
|
45
45
|
/** The default denial reason — honest that the call was intercepted (prevented), NOT executed. */
|
|
46
46
|
exports.DEFAULT_INTERCEPT_REASON = "vigiles intercepted this tool call for testing — it was NOT executed. " +
|
|
@@ -48,7 +48,7 @@ exports.DEFAULT_INTERCEPT_REASON = "vigiles intercepted this tool call for testi
|
|
|
48
48
|
/**
|
|
49
49
|
* Decide whether a tool call should be intercepted. Returns the first matching
|
|
50
50
|
* intercept's denial reason (preventing real execution), or `{ intercept: false }`
|
|
51
|
-
* to let the call run for real. Pure — the same logic `vigiles intercept-tool
|
|
51
|
+
* to let the call run for real. Pure — the same logic `vigiles hook-runtime intercept-tool`
|
|
52
52
|
* runs.
|
|
53
53
|
*/
|
|
54
54
|
function decideIntercept(toolName, input, intercepts) {
|
|
@@ -90,14 +90,14 @@ function uniqueToolNames(intercepts) {
|
|
|
90
90
|
}
|
|
91
91
|
/**
|
|
92
92
|
* Build the PreToolUse hook fragment that routes every intercepted tool through
|
|
93
|
-
* `vigiles intercept-tool
|
|
93
|
+
* `vigiles hook-runtime intercept-tool`. The `matcher` is a CC tool-name regex over the
|
|
94
94
|
* union of intercepted tool names (each escaped), so unrelated tools are never
|
|
95
95
|
* intercepted. Merge the result into an arm's `settings`; the intercept list
|
|
96
96
|
* itself travels in the {@link INTERCEPT_TOOLS_ENV} env var (see
|
|
97
97
|
* {@link serializeIntercepts}).
|
|
98
98
|
*/
|
|
99
99
|
function buildInterceptSettings(intercepts, opts = {}) {
|
|
100
|
-
const command = opts.command ?? "npx vigiles intercept-tool
|
|
100
|
+
const command = opts.command ?? "npx vigiles hook-runtime intercept-tool";
|
|
101
101
|
const matcher = uniqueToolNames(intercepts).map(escapeRegex).join("|");
|
|
102
102
|
return {
|
|
103
103
|
hooks: {
|
package/dist/unit.d.ts
CHANGED
|
@@ -16,4 +16,6 @@ export { runHook, parseHookOutput, decideHook, propertyHook, } from "./run-hook.
|
|
|
16
16
|
export type { HookInput, HookOutput, HookRunResult, RunHookOptions, HookPropertyResult, } from "./run-hook.js";
|
|
17
17
|
export * from "./check.js";
|
|
18
18
|
export { hookFired } from "./check.js";
|
|
19
|
+
export { DISASTER_CATALOG, verifyGuardrail, unblockedDisasters, assertBlocksDisasters, formatGuardrailReport, } from "./guardrail-check.js";
|
|
20
|
+
export type { DisasterEvent, DisasterCategory, GuardrailResult, VerifyGuardrailOptions, } from "./guardrail-check.js";
|
|
19
21
|
//# sourceMappingURL=unit.d.ts.map
|
package/dist/unit.js
CHANGED
|
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.hookFired = exports.propertyHook = exports.decideHook = exports.parseHookOutput = exports.runHook = void 0;
|
|
17
|
+
exports.formatGuardrailReport = exports.assertBlocksDisasters = exports.unblockedDisasters = exports.verifyGuardrail = exports.DISASTER_CATALOG = exports.hookFired = exports.propertyHook = exports.decideHook = exports.parseHookOutput = exports.runHook = void 0;
|
|
18
18
|
/**
|
|
19
19
|
* `vigiles/unit` — the **no-capability** harness-testing surface.
|
|
20
20
|
*
|
|
@@ -39,4 +39,11 @@ Object.defineProperty(exports, "propertyHook", { enumerable: true, get: function
|
|
|
39
39
|
__exportStar(require("./check.js"), exports);
|
|
40
40
|
var check_js_1 = require("./check.js");
|
|
41
41
|
Object.defineProperty(exports, "hookFired", { enumerable: true, get: function () { return check_js_1.hookFired; } });
|
|
42
|
+
// Guardrail verification — "prove your safety hook actually blocks" (over runHook).
|
|
43
|
+
var guardrail_check_js_1 = require("./guardrail-check.js");
|
|
44
|
+
Object.defineProperty(exports, "DISASTER_CATALOG", { enumerable: true, get: function () { return guardrail_check_js_1.DISASTER_CATALOG; } });
|
|
45
|
+
Object.defineProperty(exports, "verifyGuardrail", { enumerable: true, get: function () { return guardrail_check_js_1.verifyGuardrail; } });
|
|
46
|
+
Object.defineProperty(exports, "unblockedDisasters", { enumerable: true, get: function () { return guardrail_check_js_1.unblockedDisasters; } });
|
|
47
|
+
Object.defineProperty(exports, "assertBlocksDisasters", { enumerable: true, get: function () { return guardrail_check_js_1.assertBlocksDisasters; } });
|
|
48
|
+
Object.defineProperty(exports, "formatGuardrailReport", { enumerable: true, get: function () { return guardrail_check_js_1.formatGuardrailReport; } });
|
|
42
49
|
//# sourceMappingURL=unit.js.map
|
package/hooks/refs-nudge.sh
CHANGED
|
@@ -13,7 +13,7 @@ INPUT=$(cat)
|
|
|
13
13
|
command -v npx >/dev/null 2>&1 || exit 0
|
|
14
14
|
[ -f package.json ] || exit 0
|
|
15
15
|
|
|
16
|
-
printf '%s' "$INPUT" | npx vigiles refs
|
|
16
|
+
printf '%s' "$INPUT" | npx vigiles hook-runtime refs
|
|
17
17
|
status=${PIPESTATUS[1]}
|
|
18
18
|
|
|
19
19
|
# Propagate ONLY an explicit block (exit 2). Swallow tool/setup errors so a
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vigiles",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "7.0.0",
|
|
4
4
|
"description": "Lint & test the harness your AI agent runs on — verify the references in your CLAUDE.md / AGENTS.md and test that your hooks and skills actually work.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"claude-code",
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
"./linting": "./dist/linting.js",
|
|
39
39
|
"./testing": "./dist/testing.js",
|
|
40
40
|
"./unit": "./dist/unit.js",
|
|
41
|
+
"./hook": "./dist/hook.js",
|
|
41
42
|
"./integration": "./dist/integration.js",
|
|
42
43
|
"./e2e": "./dist/e2e.js",
|
|
43
44
|
"./claude-code": "./dist/claude-code.js",
|
|
@@ -82,11 +83,10 @@
|
|
|
82
83
|
"test:types": "npm run build && tsc --noEmit -p test/types/tsconfig.json",
|
|
83
84
|
"api:report": "npm run build && node scripts/api-extractor.mjs --local",
|
|
84
85
|
"api:check": "npm run build && node scripts/api-extractor.mjs",
|
|
85
|
-
"docs:api": "
|
|
86
|
+
"docs:api": "typedoc"
|
|
86
87
|
},
|
|
87
88
|
"devDependencies": {
|
|
88
89
|
"@eslint/js": "^10.0.1",
|
|
89
|
-
"@microsoft/api-documenter": "^7.30.7",
|
|
90
90
|
"@microsoft/api-extractor": "^7.58.9",
|
|
91
91
|
"@types/js-yaml": "^4.0.9",
|
|
92
92
|
"@types/minimatch": "^5.1.2",
|
|
@@ -102,6 +102,7 @@
|
|
|
102
102
|
"jest": "^30.4.2",
|
|
103
103
|
"prettier": "^3.8.1",
|
|
104
104
|
"tsx": "^4.21.0",
|
|
105
|
+
"typedoc": "^0.28.19",
|
|
105
106
|
"typescript": "^5.9.3",
|
|
106
107
|
"vitest": "^4.1.8"
|
|
107
108
|
},
|
|
@@ -124,6 +125,7 @@
|
|
|
124
125
|
"@ast-grep/napi": "^0.43.0",
|
|
125
126
|
"@iarna/toml": "^2.2.5",
|
|
126
127
|
"@jackchuka/mdschema": "^0.12.8",
|
|
128
|
+
"ci-info": "^4.4.0",
|
|
127
129
|
"cosmiconfig": "^9.0.1",
|
|
128
130
|
"glob": "^13.0.6",
|
|
129
131
|
"js-yaml": "^4.1.0",
|