vigiles 16.1.2 → 17.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/adapter-conformance.js +17 -0
- package/dist/adapters/claude-code/dialect.d.ts +19 -13
- package/dist/adapters/claude-code/dialect.js +40 -62
- package/dist/adapters/claude-code/run-scripts.d.ts +19 -3
- package/dist/adapters/claude-code/run-scripts.js +17 -7
- package/dist/adapters/claude-code/vocabulary.d.ts +133 -0
- package/dist/adapters/claude-code/vocabulary.js +208 -0
- package/dist/adapters/codex/eval.js +2 -0
- package/dist/audit-score.js +1 -1
- package/dist/cli.js +7 -2
- package/dist/core/compile.js +6 -1
- package/dist/core/dialect.d.ts +27 -0
- package/dist/core/eval-load-phase.d.ts +78 -0
- package/dist/core/eval-load-phase.js +104 -0
- package/dist/core/hook-events.d.ts +32 -15
- package/dist/core/hook-events.js +23 -29
- package/dist/core/hook-program.js +12 -4
- package/dist/core/rule-meta.js +2 -2
- package/dist/core/tool-contract.d.ts +69 -30
- package/dist/core/tool-contract.js +59 -57
- package/dist/core/vocabulary-consistency.d.ts +35 -0
- package/dist/core/vocabulary-consistency.js +81 -0
- package/dist/core/vocabulary.d.ts +138 -0
- package/dist/core/vocabulary.js +262 -0
- package/dist/eval-define.d.ts +166 -0
- package/dist/eval-define.js +182 -0
- package/dist/eval-entry.d.ts +41 -0
- package/dist/eval-entry.js +203 -0
- package/dist/eval.js +2 -0
- package/dist/judge.js +2 -0
- package/dist/scan-behavioral.js +2 -0
- package/dist/scan-core.d.ts +8 -1
- package/dist/scan-core.js +64 -6
- package/dist/scan-files.js +4 -1
- package/dist/scan.d.ts +45 -0
- package/dist/scan.js +13 -1
- package/dist/test-coverage.d.ts +45 -0
- package/dist/test-coverage.js +91 -3
- package/dist/test.d.ts +2 -0
- package/dist/test.js +8 -1
- package/package.json +1 -1
- package/skills/test-harness/SKILL.md +31 -22
|
@@ -18,6 +18,7 @@ const node_path_1 = require("node:path");
|
|
|
18
18
|
const compile_js_1 = require("./core/compile.js");
|
|
19
19
|
const spec_js_1 = require("./core/spec.js");
|
|
20
20
|
const plugin_loader_js_1 = require("./plugin-loader.js");
|
|
21
|
+
const vocabulary_consistency_js_1 = require("./core/vocabulary-consistency.js");
|
|
21
22
|
/** Check an adapter against the port contracts; returns the (possibly empty) failure list. */
|
|
22
23
|
function checkAdapterConformance(adapter) {
|
|
23
24
|
const failures = [];
|
|
@@ -33,6 +34,22 @@ function checkAdapterConformance(adapter) {
|
|
|
33
34
|
need(refVerification, "capabilities.referenceVerification must be true (every adapter does pillar 1)");
|
|
34
35
|
// --- Pillar 1 (always required): dialect + layout ---
|
|
35
36
|
need(adapter.dialect.builtinAgentTools.length > 0, "dialect has no builtinAgentTools");
|
|
37
|
+
// The dialect's several name lists describe ONE vocabulary from different
|
|
38
|
+
// angles, and nothing used to check they agreed — which is how `Agent` came to
|
|
39
|
+
// sit in `neverAvailableTools` while its own alias `Task` sat in the built-in
|
|
40
|
+
// catalog, undetected, for every consumer of the adapter. Cheap, total, and it
|
|
41
|
+
// runs for every adapter including third-party ones.
|
|
42
|
+
for (const problem of (0, vocabulary_consistency_js_1.dialectVocabularyProblems)(adapter.dialect))
|
|
43
|
+
need(false, `dialect self-contradiction: ${problem}`);
|
|
44
|
+
// When a dialect ships the richer vocabulary AND the flat lists, the flat ones
|
|
45
|
+
// must be exactly its projections — else the two drift apart again, one level
|
|
46
|
+
// down.
|
|
47
|
+
if (adapter.dialect.subagentToolVocabulary !== undefined)
|
|
48
|
+
for (const problem of (0, vocabulary_consistency_js_1.vocabularyProjectionProblems)(adapter.dialect.subagentToolVocabulary, adapter.dialect.builtinAgentTools, adapter.dialect.neverAvailableTools))
|
|
49
|
+
need(false, `subagentToolVocabulary: ${problem}`);
|
|
50
|
+
if (adapter.dialect.hookEventVocabulary !== undefined)
|
|
51
|
+
for (const problem of (0, vocabulary_consistency_js_1.vocabularyProjectionProblems)(adapter.dialect.hookEventVocabulary, adapter.dialect.hookEvents, []))
|
|
52
|
+
need(false, `hookEventVocabulary: ${problem}`);
|
|
36
53
|
need(adapter.dialect.instructionTargets.length > 0, "dialect has no instructionTargets");
|
|
37
54
|
need(adapter.layout.instructionFile.length > 0, "layout.instructionFile is empty");
|
|
38
55
|
need(adapter.layout.manifestPath.length > 0, "layout.manifestPath is empty");
|
|
@@ -11,16 +11,23 @@ import type { HarnessDialect } from "../../core/dialect.js";
|
|
|
11
11
|
/**
|
|
12
12
|
* The Claude Code built-in subagent tool catalog as a `const` tuple, so a typed
|
|
13
13
|
* authoring surface can derive a LITERAL union (`ClaudeCodeBuiltinTool`) from it.
|
|
14
|
-
*
|
|
15
|
-
*
|
|
14
|
+
*
|
|
15
|
+
* DERIVED, not authored: it is exactly the vocabulary's declarable terms — the
|
|
16
|
+
* ones the platform provides outright plus the ones it withholds only under a
|
|
17
|
+
* condition. Both halves are legitimate to write in a `tools:` line, which is
|
|
18
|
+
* why `Agent` belongs here and used to sit in `neverAvailableTools` instead.
|
|
19
|
+
* Because this is a projection rather than a second hand-kept list, the two can
|
|
20
|
+
* no longer disagree; `vocabularyProjectionProblems` asserts it in the
|
|
21
|
+
* conformance kit rather than leaving it to care.
|
|
16
22
|
*/
|
|
17
|
-
export declare const claudeCodeBuiltinAgentTools: readonly ["Read", "
|
|
23
|
+
export declare const claudeCodeBuiltinAgentTools: readonly ["Read", "Grep", "Glob", "Bash", "PowerShell", "Edit", "Write", "NotebookEdit", "WebFetch", "WebSearch", "TodoWrite", "Skill", "ToolSearch", "EnterWorktree", "ExitWorktree", "Monitor", "TaskStop", "SendMessage", "Artifact", "Agent", "Task", "ExitPlanMode", "ListAgents", "LSP", "ShareOnboardingGuide", "CronCreate", "CronDelete", "CronList", "TaskCreate", "TaskGet", "TaskList", "TaskUpdate"];
|
|
18
24
|
/**
|
|
19
|
-
* The Claude Code side-effecting tools
|
|
20
|
-
*
|
|
21
|
-
*
|
|
25
|
+
* The Claude Code side-effecting tools (the complement of read-only within
|
|
26
|
+
* `builtinAgentTools`). Authored in `vocabulary.ts` beside the catalog it
|
|
27
|
+
* partitions, because a name added to the catalog without a decision here would
|
|
28
|
+
* silently be classified read-only.
|
|
22
29
|
*/
|
|
23
|
-
export declare const claudeCodeSideEffectingTools: readonly ["Bash", "
|
|
30
|
+
export declare const claudeCodeSideEffectingTools: readonly ["Bash", "PowerShell", "Edit", "Write", "NotebookEdit", "WebFetch", "WebSearch", "Skill", "TodoWrite", "Monitor", "SendMessage", "Artifact", "EnterWorktree", "ExitWorktree", "TaskStop", "Agent", "Task", "TaskCreate", "TaskUpdate", "CronCreate", "CronDelete", "ShareOnboardingGuide"];
|
|
24
31
|
export declare const claudeCodeDialect: HarnessDialect;
|
|
25
32
|
/** Every Claude Code built-in subagent tool (literal union). */
|
|
26
33
|
export type ClaudeCodeBuiltinTool = (typeof claudeCodeBuiltinAgentTools)[number];
|
|
@@ -33,15 +40,14 @@ export type ClaudeCodeSideEffectingTool = (typeof claudeCodeSideEffectingTools)[
|
|
|
33
40
|
export type ClaudeCodeReadOnlyTool = Exclude<ClaudeCodeBuiltinTool, ClaudeCodeSideEffectingTool>;
|
|
34
41
|
/**
|
|
35
42
|
* Tools a `bounded` CC unit may declare: read-only ∪ the decidable
|
|
36
|
-
* side-effecting tools (Write/Edit/
|
|
43
|
+
* side-effecting tools (Write/Edit/NotebookEdit) ∪ `Bash`/`PowerShell` (whose
|
|
37
44
|
* command is decided at RUNTIME by the gate). Bars MCP / unknown / wildcard —
|
|
38
45
|
* those are simply not in the built-in union, so listing one is a `tsc` error.
|
|
39
46
|
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
* explicit add of the bounded-decidable set plus `Bash`.
|
|
47
|
+
* `MultiEdit` was listed here until 2026-08-17. It is not a Claude Code tool —
|
|
48
|
+
* it appears zero times across the vendor's documentation — so it is gone along
|
|
49
|
+
* with `BashOutput`, `KillBash` and `LS`.
|
|
44
50
|
*/
|
|
45
|
-
export type ClaudeCodeBoundedTool = ClaudeCodeReadOnlyTool | "Write" | "Edit" | "
|
|
51
|
+
export type ClaudeCodeBoundedTool = ClaudeCodeReadOnlyTool | "Write" | "Edit" | "NotebookEdit" | "Bash" | "PowerShell";
|
|
46
52
|
export type { HarnessDialect } from "../../core/dialect.js";
|
|
47
53
|
//# sourceMappingURL=dialect.d.ts.map
|
|
@@ -1,84 +1,55 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.claudeCodeDialect = exports.claudeCodeSideEffectingTools = exports.claudeCodeBuiltinAgentTools = void 0;
|
|
4
|
+
const vocabulary_js_1 = require("./vocabulary.js");
|
|
4
5
|
/**
|
|
5
6
|
* The Claude Code built-in subagent tool catalog as a `const` tuple, so a typed
|
|
6
7
|
* authoring surface can derive a LITERAL union (`ClaudeCodeBuiltinTool`) from it.
|
|
7
|
-
*
|
|
8
|
-
*
|
|
8
|
+
*
|
|
9
|
+
* DERIVED, not authored: it is exactly the vocabulary's declarable terms — the
|
|
10
|
+
* ones the platform provides outright plus the ones it withholds only under a
|
|
11
|
+
* condition. Both halves are legitimate to write in a `tools:` line, which is
|
|
12
|
+
* why `Agent` belongs here and used to sit in `neverAvailableTools` instead.
|
|
13
|
+
* Because this is a projection rather than a second hand-kept list, the two can
|
|
14
|
+
* no longer disagree; `vocabularyProjectionProblems` asserts it in the
|
|
15
|
+
* conformance kit rather than leaving it to care.
|
|
9
16
|
*/
|
|
10
17
|
exports.claudeCodeBuiltinAgentTools = [
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
"Edit",
|
|
14
|
-
"MultiEdit",
|
|
15
|
-
"Bash",
|
|
16
|
-
"BashOutput",
|
|
17
|
-
"KillBash",
|
|
18
|
-
"Grep",
|
|
19
|
-
"Glob",
|
|
20
|
-
"LS",
|
|
21
|
-
"WebSearch",
|
|
22
|
-
"WebFetch",
|
|
23
|
-
"NotebookEdit",
|
|
24
|
-
"TodoWrite",
|
|
25
|
-
"Task",
|
|
26
|
-
"Skill",
|
|
18
|
+
...vocabulary_js_1.claudeCodeAvailableAgentTools,
|
|
19
|
+
...vocabulary_js_1.claudeCodeConditionalAgentToolNames,
|
|
27
20
|
];
|
|
28
21
|
/**
|
|
29
|
-
* The Claude Code side-effecting tools
|
|
30
|
-
*
|
|
31
|
-
*
|
|
22
|
+
* The Claude Code side-effecting tools (the complement of read-only within
|
|
23
|
+
* `builtinAgentTools`). Authored in `vocabulary.ts` beside the catalog it
|
|
24
|
+
* partitions, because a name added to the catalog without a decision here would
|
|
25
|
+
* silently be classified read-only.
|
|
32
26
|
*/
|
|
33
|
-
exports.claudeCodeSideEffectingTools =
|
|
34
|
-
"Bash",
|
|
35
|
-
"BashOutput",
|
|
36
|
-
"KillBash",
|
|
37
|
-
"Edit",
|
|
38
|
-
"MultiEdit",
|
|
39
|
-
"Write",
|
|
40
|
-
"NotebookEdit",
|
|
41
|
-
"WebFetch",
|
|
42
|
-
"WebSearch",
|
|
43
|
-
"Skill",
|
|
44
|
-
"Task",
|
|
45
|
-
"TodoWrite",
|
|
46
|
-
];
|
|
27
|
+
exports.claudeCodeSideEffectingTools = vocabulary_js_1.claudeCodeSideEffectingAgentTools;
|
|
47
28
|
exports.claudeCodeDialect = {
|
|
48
29
|
name: "claude-code",
|
|
49
30
|
// The tool contract a subagent may declare — the rails it runs on. Anything
|
|
50
31
|
// else must be an MCP tool, else it's a typo / nonexistent tool.
|
|
51
32
|
builtinAgentTools: exports.claudeCodeBuiltinAgentTools,
|
|
52
|
-
// Tools the platform
|
|
53
|
-
//
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
"WaitForMcpServers",
|
|
61
|
-
],
|
|
33
|
+
// Tools the platform removes UNCONDITIONALLY, whatever the list says — so a
|
|
34
|
+
// subagent listing one is a guaranteed-dead reference only a compiler catches.
|
|
35
|
+
// Derived from the vocabulary's `withheld` terms. `Agent` and `ExitPlanMode`
|
|
36
|
+
// are deliberately absent: the vendor removes both only under a stated
|
|
37
|
+
// condition (depth limit / `permissionMode: plan`), so they are `conditional`
|
|
38
|
+
// and reported as a note. Listing them here is what told delegating subagents
|
|
39
|
+
// to delete the tool they exist to use.
|
|
40
|
+
neverAvailableTools: vocabulary_js_1.claudeCodeWithheldAgentTools,
|
|
62
41
|
mcpToolPattern: /^mcp__[a-z0-9_-]+__[a-z0-9_-]+$/i,
|
|
63
42
|
// Claude Code's own built-in MCP server: the IDE integration provides
|
|
64
43
|
// `mcp__ide__getDiagnostics` / `mcp__ide__executeCode` at runtime without any
|
|
65
44
|
// plugin declaring it, so a contract that lists those must NOT be flagged as
|
|
66
45
|
// referencing an undeclared server (the mcp-tool-resolves allowlist).
|
|
67
46
|
knownMcpServers: ["ide"],
|
|
68
|
-
// The real Claude Code hook events
|
|
69
|
-
//
|
|
70
|
-
//
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
"UserPromptSubmit",
|
|
75
|
-
"Notification",
|
|
76
|
-
"Stop",
|
|
77
|
-
"SubagentStop",
|
|
78
|
-
"PreCompact",
|
|
79
|
-
"SessionStart",
|
|
80
|
-
"SessionEnd",
|
|
81
|
-
],
|
|
47
|
+
// The real Claude Code hook events — all 31 the vendor documents, derived from
|
|
48
|
+
// `claudeCodeHookEventNames`. This list held 9 until 2026-08-17; `Setup` was
|
|
49
|
+
// reported as "never fires" and the other 21 absentees drew nothing at all,
|
|
50
|
+
// because whether an unknown name was accused or ignored came down to its edit
|
|
51
|
+
// distance from the 9 we had. See `vocabulary.ts` for the capture.
|
|
52
|
+
hookEvents: vocabulary_js_1.claudeCodeHookEventNames,
|
|
82
53
|
// Events where a block decision is silently ignored ENTIRELY — no veto AND no
|
|
83
54
|
// model feedback (exit 2 there writes stderr only to the user). These are the
|
|
84
55
|
// ONLY events hook-block-ineffective flags as wrong-event. PostToolUse is NOT
|
|
@@ -105,10 +76,17 @@ exports.claudeCodeDialect = {
|
|
|
105
76
|
// disable-model-invocation, argument-hint, …).
|
|
106
77
|
skillFrontmatter: "claude-code",
|
|
107
78
|
// Tools that produce side effects in Claude Code. The complement — the
|
|
108
|
-
// read-only tools — are: Read, Grep, Glob,
|
|
109
|
-
//
|
|
110
|
-
// `cat` and `rm -rf` are the same tool at the tool-name level — the
|
|
79
|
+
// read-only tools — are: Read, Grep, Glob, ToolSearch, LSP, ListAgents,
|
|
80
|
+
// TaskGet, TaskList, CronList. Bash (and PowerShell) are side-effecting
|
|
81
|
+
// because `cat` and `rm -rf` are the same tool at the tool-name level — the
|
|
111
82
|
// sandbox is the only closure for subprocess effects.
|
|
112
83
|
sideEffectingTools: exports.claudeCodeSideEffectingTools,
|
|
84
|
+
// The richer catalogs the flat lists above project from — status per term,
|
|
85
|
+
// with the vendor capture they were read from. An unknown name resolves
|
|
86
|
+
// against these to an `unrecognised` ADVISORY that names vigiles as the
|
|
87
|
+
// possibly-stale party, instead of the silence-or-accusation coin flip that
|
|
88
|
+
// edit distance used to decide.
|
|
89
|
+
hookEventVocabulary: vocabulary_js_1.claudeCodeHookEventVocabulary,
|
|
90
|
+
subagentToolVocabulary: vocabulary_js_1.claudeCodeSubagentToolVocabulary,
|
|
113
91
|
};
|
|
114
92
|
//# sourceMappingURL=dialect.js.map
|
|
@@ -74,10 +74,16 @@ import type { NodeCaps } from "../../ts-runner-caps.js";
|
|
|
74
74
|
* type stripping. Throws a clear, actionable error when neither is available.
|
|
75
75
|
* Pure — exported for testing.
|
|
76
76
|
*
|
|
77
|
+
* `entry` interposes a program that takes the script as its ARGUMENT instead of
|
|
78
|
+
* running the script as the program. `vigiles eval` passes one: an eval file
|
|
79
|
+
* describes its eval rather than running it (see `src/eval-define.ts`), so
|
|
80
|
+
* something has to import the description and execute what it declares. Harness
|
|
81
|
+
* scripts pass nothing and are launched exactly as before.
|
|
82
|
+
*
|
|
77
83
|
* 🔴 The disjunction below is `canRunTypeScript` — keep them together. When they
|
|
78
84
|
* drifted, the tool recommended a `.ts` file and then refused to run it.
|
|
79
85
|
*/
|
|
80
|
-
export declare function interpreterArgs(file: string, caps: NodeCaps): string[];
|
|
86
|
+
export declare function interpreterArgs(file: string, caps: NodeCaps, entry?: string): string[];
|
|
81
87
|
/**
|
|
82
88
|
* Expand the given path/glob patterns into concrete script files. A pattern
|
|
83
89
|
* that is an existing file passes through unchanged; anything else is treated
|
|
@@ -85,8 +91,18 @@ export declare function interpreterArgs(file: string, caps: NodeCaps): string[];
|
|
|
85
91
|
* are deduped and sorted; `node_modules` and `dist` are always ignored.
|
|
86
92
|
*/
|
|
87
93
|
export declare function discoverScripts(patterns: readonly string[], defaultGlob: string, cwd: string): string[];
|
|
94
|
+
/** Extra wiring for {@link runScripts}. */
|
|
95
|
+
export interface RunScriptsOptions {
|
|
96
|
+
/**
|
|
97
|
+
* A program to run INSTEAD of each script, with the script's path as its one
|
|
98
|
+
* argument. `vigiles eval` passes `dist/eval-entry.js`; `vigiles test` passes
|
|
99
|
+
* nothing. See {@link interpreterArgs}.
|
|
100
|
+
*/
|
|
101
|
+
readonly entry?: string;
|
|
102
|
+
}
|
|
88
103
|
/**
|
|
89
|
-
* Run each script as `node <file
|
|
104
|
+
* Run each script as `node <file>` (or `node <entry> <file>`, see
|
|
105
|
+
* {@link RunScriptsOptions}), inheriting stdio so the script's own report
|
|
90
106
|
* streams to the console. `env` is merged over `process.env` for every child
|
|
91
107
|
* (e.g. `VIGILES_TRIALS`). Returns the per-file exit codes + check counts.
|
|
92
108
|
*
|
|
@@ -100,7 +116,7 @@ export declare function discoverScripts(patterns: readonly string[], defaultGlob
|
|
|
100
116
|
* record them (`.vigiles/coverage.json`) and coverage can answer "tested?" from
|
|
101
117
|
* execution rather than from a matching file name.
|
|
102
118
|
*/
|
|
103
|
-
export declare function runScripts(files: readonly string[], cwd: string, env?: NodeJS.ProcessEnv): ScriptRunResult[];
|
|
119
|
+
export declare function runScripts(files: readonly string[], cwd: string, env?: NodeJS.ProcessEnv, opts?: RunScriptsOptions): ScriptRunResult[];
|
|
104
120
|
/**
|
|
105
121
|
* Whether any script FAILED. Neither a skip nor a vacuous run counts: the first
|
|
106
122
|
* declined to run, the second ran and verified nothing, and neither is evidence
|
|
@@ -88,16 +88,25 @@ const ts_runner_caps_js_2 = require("../../ts-runner-caps.js");
|
|
|
88
88
|
* type stripping. Throws a clear, actionable error when neither is available.
|
|
89
89
|
* Pure — exported for testing.
|
|
90
90
|
*
|
|
91
|
+
* `entry` interposes a program that takes the script as its ARGUMENT instead of
|
|
92
|
+
* running the script as the program. `vigiles eval` passes one: an eval file
|
|
93
|
+
* describes its eval rather than running it (see `src/eval-define.ts`), so
|
|
94
|
+
* something has to import the description and execute what it declares. Harness
|
|
95
|
+
* scripts pass nothing and are launched exactly as before.
|
|
96
|
+
*
|
|
91
97
|
* 🔴 The disjunction below is `canRunTypeScript` — keep them together. When they
|
|
92
98
|
* drifted, the tool recommended a `.ts` file and then refused to run it.
|
|
93
99
|
*/
|
|
94
|
-
function interpreterArgs(file, caps) {
|
|
100
|
+
function interpreterArgs(file, caps, entry) {
|
|
101
|
+
// The TS flags are chosen from FILE's extension even when `entry` runs — a
|
|
102
|
+
// JavaScript entry importing a `.ts` eval still needs the loader installed.
|
|
103
|
+
const tail = entry === undefined ? [file] : [entry, file];
|
|
95
104
|
if (!TS_EXT.test(file))
|
|
96
|
-
return
|
|
105
|
+
return tail;
|
|
97
106
|
if (caps.tsx)
|
|
98
|
-
return ["--import", "tsx",
|
|
107
|
+
return ["--import", "tsx", ...tail];
|
|
99
108
|
if (caps.stripTypes)
|
|
100
|
-
return ["--experimental-strip-types",
|
|
109
|
+
return ["--experimental-strip-types", ...tail];
|
|
101
110
|
throw new Error(`Cannot run TypeScript test script "${file}": install tsx ` +
|
|
102
111
|
`(npm i -D tsx) or use Node >= 22.6, or author it as a .mjs file.`);
|
|
103
112
|
}
|
|
@@ -154,7 +163,8 @@ function readCheckReport(path) {
|
|
|
154
163
|
}
|
|
155
164
|
}
|
|
156
165
|
/**
|
|
157
|
-
* Run each script as `node <file
|
|
166
|
+
* Run each script as `node <file>` (or `node <entry> <file>`, see
|
|
167
|
+
* {@link RunScriptsOptions}), inheriting stdio so the script's own report
|
|
158
168
|
* streams to the console. `env` is merged over `process.env` for every child
|
|
159
169
|
* (e.g. `VIGILES_TRIALS`). Returns the per-file exit codes + check counts.
|
|
160
170
|
*
|
|
@@ -168,7 +178,7 @@ function readCheckReport(path) {
|
|
|
168
178
|
* record them (`.vigiles/coverage.json`) and coverage can answer "tested?" from
|
|
169
179
|
* execution rather than from a matching file name.
|
|
170
180
|
*/
|
|
171
|
-
function runScripts(files, cwd, env = {}) {
|
|
181
|
+
function runScripts(files, cwd, env = {}, opts = {}) {
|
|
172
182
|
const caps = (0, ts_runner_caps_js_2.detectNodeCaps)(cwd);
|
|
173
183
|
const results = [];
|
|
174
184
|
const countDir = (0, node_fs_1.mkdtempSync)((0, node_path_1.join)((0, node_os_1.tmpdir)(), "vigiles-checks-"));
|
|
@@ -176,7 +186,7 @@ function runScripts(files, cwd, env = {}) {
|
|
|
176
186
|
files.forEach((file, i) => {
|
|
177
187
|
let argv;
|
|
178
188
|
try {
|
|
179
|
-
argv = interpreterArgs(file, caps);
|
|
189
|
+
argv = interpreterArgs(file, caps, opts.entry);
|
|
180
190
|
}
|
|
181
191
|
catch (e) {
|
|
182
192
|
console.error(`✗ ${file}: ${e.message}`);
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Claude Code vocabularies — hook events and subagent tools — re-derived
|
|
3
|
+
* from the vendor's own documentation on 2026-08-17 against Claude Code 2.1.233
|
|
4
|
+
* (`claude --version` on the capture box).
|
|
5
|
+
*
|
|
6
|
+
* Every entry below came from a STRUCTURAL read of the docs, not a prose grep:
|
|
7
|
+
* the hook events are the 31 `<h3>` subsections of the `## Hook events` section
|
|
8
|
+
* of https://code.claude.com/docs/en/hooks (2,589,700 bytes as fetched), in
|
|
9
|
+
* document order; the tool statuses are the two filter lists in the
|
|
10
|
+
* "Available tools" section of https://code.claude.com/docs/en/sub-agents
|
|
11
|
+
* (1,126,213 bytes as fetched). The `condition` strings are the vendor's own
|
|
12
|
+
* wording, trimmed.
|
|
13
|
+
*
|
|
14
|
+
* This file is the ONE authored place for both catalogs. `dialect.ts` builds
|
|
15
|
+
* `builtinAgentTools` / `neverAvailableTools` / `sideEffectingTools` and the
|
|
16
|
+
* literal tool unions from the tuples below, so the state that produced the
|
|
17
|
+
* `Agent`/`Task` inversion — two hand-kept lists disagreeing with each other —
|
|
18
|
+
* has nowhere left to live.
|
|
19
|
+
*
|
|
20
|
+
* WHAT THIS CORRECTS, and how badly it was wrong (measured; the mechanism is
|
|
21
|
+
* documented in `core/vocabulary.ts`):
|
|
22
|
+
*
|
|
23
|
+
* - HOOK EVENTS: the old catalog held 9 of 31. It was NOT "current except for
|
|
24
|
+
* `Setup`" — 22 documented events were missing, and 21 of those went unsaid
|
|
25
|
+
* only because they sit more than 2 edit distance from a name we held.
|
|
26
|
+
* `Setup` was the one that happened to land within 2 of `Stop`, so it alone
|
|
27
|
+
* drew an accusation, and the fix it suggested — rewire a one-shot setup hook
|
|
28
|
+
* onto every turn's Stop — would have broken the repo it was aimed at.
|
|
29
|
+
* - `Agent` WAS BACKWARDS. The old dialect listed `Agent` as never-available
|
|
30
|
+
* and `Task` as a built-in. The vendor renamed it the other way round:
|
|
31
|
+
*
|
|
32
|
+
* > In version 2.1.63, the Task tool was renamed to Agent. Existing
|
|
33
|
+
* > `Task(...)` references in settings and agent definitions still work
|
|
34
|
+
* > as aliases.
|
|
35
|
+
*
|
|
36
|
+
* and ships `tools: Agent(worker, researcher), Read, Bash` as a worked
|
|
37
|
+
* example. vigiles rejected the current name, accepted the deprecated one,
|
|
38
|
+
* and told orchestrator subagents to delete the one tool they exist to use.
|
|
39
|
+
* - FOUR NAMES WE HELD DO NOT EXIST. `MultiEdit`, `BashOutput`, `KillBash` and
|
|
40
|
+
* `LS` appear ZERO times across all six vendor doc pages fetched (hooks,
|
|
41
|
+
* sub-agents, tools-reference, settings, iam, tool-use). They are historical.
|
|
42
|
+
* They are gone from this catalog, so listing one now draws an
|
|
43
|
+
* `unrecognised` advisory instead of silent approval.
|
|
44
|
+
* - THE EVIDENCE WAS ALREADY IN THE REPO. `dialect-drift.ts`'s
|
|
45
|
+
* `ACKNOWLEDGED_TOOL_INPUT_TYPES` has carried `Agent`, `TaskOutput` and
|
|
46
|
+
* `Workflow` — read from the vendor's own `sdk-tools.d.ts` — since 2.1.187,
|
|
47
|
+
* under a note asserting they are "NOT subagent-grantable". Nothing ever
|
|
48
|
+
* compared that list against this one, so the drift alarm watched the
|
|
49
|
+
* platform move while our two catalogs contradicted both it and each other.
|
|
50
|
+
*
|
|
51
|
+
* WHY `conditional` IS NOT A DEFECT. The vendor is explicit that a subagent's
|
|
52
|
+
* tool set is not a property of the name:
|
|
53
|
+
*
|
|
54
|
+
* > Claude Code removes every other built-in tool from a background subagent,
|
|
55
|
+
* > whether inherited or listed in the `tools` field, so the same definition
|
|
56
|
+
* > can resolve to different tools in the foreground and the background.
|
|
57
|
+
*
|
|
58
|
+
* and, of the catalog as a whole:
|
|
59
|
+
*
|
|
60
|
+
* > Your exact tool set depends on your provider, platform, and settings.
|
|
61
|
+
*
|
|
62
|
+
* Availability is therefore a function of foreground/background, spawn depth,
|
|
63
|
+
* `permissionMode`, model, provider and settings — none of which vigiles can
|
|
64
|
+
* read off a `tools:` line. `conditional` records the condition and reports it
|
|
65
|
+
* as a note. Evaluating those conditions (two of them are decidable from
|
|
66
|
+
* frontmatter we already parse — `ExitPlanMode` against the agent's own
|
|
67
|
+
* `permissionMode`, and background-vs-foreground) is real follow-on work and is
|
|
68
|
+
* deliberately NOT done here.
|
|
69
|
+
*
|
|
70
|
+
* KNOWN GAP, recorded rather than smoothed: `TodoWrite` is named by the vendor
|
|
71
|
+
* among the built-ins a background subagent keeps, so it is `available` — but
|
|
72
|
+
* `tools-reference` also says that from 2.1.233 `TodoWrite`, `TaskCreate`,
|
|
73
|
+
* `TaskGet`, `TaskUpdate` and `TaskList` are withheld on Opus 4.8 / Sonnet 5 /
|
|
74
|
+
* Fable 5 / Mythos 5 and later unless opted in. That is a MODEL axis on top of
|
|
75
|
+
* the two filter axes. The four `Task*` tools are `conditional` for the
|
|
76
|
+
* background reason anyway and their condition says so; `TodoWrite` stays
|
|
77
|
+
* `available` because the vendor names it in the kept-list verbatim. One
|
|
78
|
+
* condition string cannot express three independent axes, and adding a field to
|
|
79
|
+
* hold a case we still could not evaluate would be worse than saying so here.
|
|
80
|
+
*/
|
|
81
|
+
import type { HarnessVocabulary } from "../../core/vocabulary.js";
|
|
82
|
+
/**
|
|
83
|
+
* The Claude Code hook events — the 31 `###` subsections under `## Hook events`
|
|
84
|
+
* at https://code.claude.com/docs/en/hooks, in document order.
|
|
85
|
+
*
|
|
86
|
+
* `Setup` is the third. It is a real event with its own `Setup input` and
|
|
87
|
+
* `Setup decision control` subsections; the old catalog's absence of it is what
|
|
88
|
+
* produced the two-letter grade inversion this file exists to fix.
|
|
89
|
+
*/
|
|
90
|
+
export declare const claudeCodeHookEventNames: readonly ["SessionStart", "Setup", "InstructionsLoaded", "UserPromptSubmit", "UserPromptExpansion", "MessageDisplay", "PreToolUse", "PermissionRequest", "PostToolUse", "PostToolUseFailure", "PostToolBatch", "PermissionDenied", "Notification", "SubagentStart", "SubagentStop", "TaskCreated", "TaskCompleted", "Stop", "StopFailure", "TeammateIdle", "ConfigChange", "CwdChanged", "DirectoryAdded", "FileChanged", "WorktreeCreate", "WorktreeRemove", "PreCompact", "PostCompact", "SessionEnd", "Elicitation", "ElicitationResult"];
|
|
91
|
+
/**
|
|
92
|
+
* The 19 built-ins the vendor names as the set a BACKGROUND subagent keeps —
|
|
93
|
+
* the default case, and the only tool set vigiles can assume without reading
|
|
94
|
+
* conditions it cannot see.
|
|
95
|
+
*/
|
|
96
|
+
export declare const claudeCodeAvailableAgentTools: readonly ["Read", "Grep", "Glob", "Bash", "PowerShell", "Edit", "Write", "NotebookEdit", "WebFetch", "WebSearch", "TodoWrite", "Skill", "ToolSearch", "EnterWorktree", "ExitWorktree", "Monitor", "TaskStop", "SendMessage", "Artifact"];
|
|
97
|
+
/**
|
|
98
|
+
* The 7 unconditional entries of the vendor's first filter — "removes these
|
|
99
|
+
* tools, even when listed in the `tools` field", with no qualifier attached.
|
|
100
|
+
* Listing one is a genuine dead reference, and the only tool verdict that
|
|
101
|
+
* still enters the grade.
|
|
102
|
+
*/
|
|
103
|
+
export declare const claudeCodeWithheldAgentTools: readonly ["AskUserQuestion", "EndConversation", "EnterPlanMode", "ScheduleWakeup", "TaskOutput", "WaitForMcpServers", "Workflow"];
|
|
104
|
+
/**
|
|
105
|
+
* Tools the platform removes only under a stated condition — the qualified
|
|
106
|
+
* entries of the first filter, plus the built-ins that survive in the
|
|
107
|
+
* foreground but not in the background. Declaring one is legitimate, so none
|
|
108
|
+
* of these is scored; the condition is reported and vigiles stops there.
|
|
109
|
+
*/
|
|
110
|
+
export declare const claudeCodeConditionalAgentToolNames: readonly ["Agent", "Task", "ExitPlanMode", "ListAgents", "LSP", "ShareOnboardingGuide", "CronCreate", "CronDelete", "CronList", "TaskCreate", "TaskGet", "TaskList", "TaskUpdate"];
|
|
111
|
+
/**
|
|
112
|
+
* The side-effecting subset of everything a subagent may declare (the
|
|
113
|
+
* complement is read-only). Two rules decided the additions here, both from the
|
|
114
|
+
* vendor's own tool descriptions rather than from the tool's name:
|
|
115
|
+
*
|
|
116
|
+
* - `Monitor` "writes a small script, runs it in the background" and can open
|
|
117
|
+
* a WebSocket — execution plus network, so it is side-effecting despite
|
|
118
|
+
* reading like an observer.
|
|
119
|
+
* - `LSP`, `ToolSearch`, `ListAgents`, `TaskGet`, `TaskList` and `CronList`
|
|
120
|
+
* only report state, so they stay read-only.
|
|
121
|
+
*
|
|
122
|
+
* This matters beyond tidiness: `classifyToolEffect` treats "in the built-in
|
|
123
|
+
* catalog and NOT here" as read-only, so a name added to the catalog without a
|
|
124
|
+
* decision here would silently be declared harmless — and a spawning tool
|
|
125
|
+
* misfiled as read-only would let a subagent pass the lethal-trifecta check it
|
|
126
|
+
* should fail.
|
|
127
|
+
*/
|
|
128
|
+
export declare const claudeCodeSideEffectingAgentTools: readonly ["Bash", "PowerShell", "Edit", "Write", "NotebookEdit", "WebFetch", "WebSearch", "Skill", "TodoWrite", "Monitor", "SendMessage", "Artifact", "EnterWorktree", "ExitWorktree", "TaskStop", "Agent", "Task", "TaskCreate", "TaskUpdate", "CronCreate", "CronDelete", "ShareOnboardingGuide"];
|
|
129
|
+
/** The hook-event vocabulary — every documented event, all currently available. */
|
|
130
|
+
export declare const claudeCodeHookEventVocabulary: HarnessVocabulary;
|
|
131
|
+
/** The subagent-tool vocabulary — available / withheld / conditional. */
|
|
132
|
+
export declare const claudeCodeSubagentToolVocabulary: HarnessVocabulary;
|
|
133
|
+
//# sourceMappingURL=vocabulary.d.ts.map
|