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.
Files changed (42) hide show
  1. package/dist/adapter-conformance.js +17 -0
  2. package/dist/adapters/claude-code/dialect.d.ts +19 -13
  3. package/dist/adapters/claude-code/dialect.js +40 -62
  4. package/dist/adapters/claude-code/run-scripts.d.ts +19 -3
  5. package/dist/adapters/claude-code/run-scripts.js +17 -7
  6. package/dist/adapters/claude-code/vocabulary.d.ts +133 -0
  7. package/dist/adapters/claude-code/vocabulary.js +208 -0
  8. package/dist/adapters/codex/eval.js +2 -0
  9. package/dist/audit-score.js +1 -1
  10. package/dist/cli.js +7 -2
  11. package/dist/core/compile.js +6 -1
  12. package/dist/core/dialect.d.ts +27 -0
  13. package/dist/core/eval-load-phase.d.ts +78 -0
  14. package/dist/core/eval-load-phase.js +104 -0
  15. package/dist/core/hook-events.d.ts +32 -15
  16. package/dist/core/hook-events.js +23 -29
  17. package/dist/core/hook-program.js +12 -4
  18. package/dist/core/rule-meta.js +2 -2
  19. package/dist/core/tool-contract.d.ts +69 -30
  20. package/dist/core/tool-contract.js +59 -57
  21. package/dist/core/vocabulary-consistency.d.ts +35 -0
  22. package/dist/core/vocabulary-consistency.js +81 -0
  23. package/dist/core/vocabulary.d.ts +138 -0
  24. package/dist/core/vocabulary.js +262 -0
  25. package/dist/eval-define.d.ts +166 -0
  26. package/dist/eval-define.js +182 -0
  27. package/dist/eval-entry.d.ts +41 -0
  28. package/dist/eval-entry.js +203 -0
  29. package/dist/eval.js +2 -0
  30. package/dist/judge.js +2 -0
  31. package/dist/scan-behavioral.js +2 -0
  32. package/dist/scan-core.d.ts +8 -1
  33. package/dist/scan-core.js +64 -6
  34. package/dist/scan-files.js +4 -1
  35. package/dist/scan.d.ts +45 -0
  36. package/dist/scan.js +13 -1
  37. package/dist/test-coverage.d.ts +45 -0
  38. package/dist/test-coverage.js +91 -3
  39. package/dist/test.d.ts +2 -0
  40. package/dist/test.js +8 -1
  41. package/package.json +1 -1
  42. 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
- * `claudeCodeDialect.builtinAgentTools` references this same array — one source
15
- * of truth for the runtime catalog AND the compile-time tool vocabulary.
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", "Write", "Edit", "MultiEdit", "Bash", "BashOutput", "KillBash", "Grep", "Glob", "LS", "WebSearch", "WebFetch", "NotebookEdit", "TodoWrite", "Task", "Skill"];
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 as a `const` tuple (the complement of
20
- * read-only within `builtinAgentTools`). `claudeCodeDialect.sideEffectingTools`
21
- * references this; the typed vocabulary derives the read-only / bounded splits.
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", "BashOutput", "KillBash", "Edit", "MultiEdit", "Write", "NotebookEdit", "WebFetch", "WebSearch", "Skill", "Task", "TodoWrite"];
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/MultiEdit/NotebookEdit) ∪ `Bash` (its
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
- * NOTE: `BashOutput`/`KillBash` are read-only-ish helpers tied to a running
41
- * Bash; `Bash` is the admitting tool, so they're included via the read-only
42
- * exclusion path only if read-only — here they stay side-effecting, hence the
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" | "MultiEdit" | "NotebookEdit" | "Bash";
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
- * `claudeCodeDialect.builtinAgentTools` references this same array — one source
8
- * of truth for the runtime catalog AND the compile-time tool vocabulary.
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
- "Read",
12
- "Write",
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 as a `const` tuple (the complement of
30
- * read-only within `builtinAgentTools`). `claudeCodeDialect.sideEffectingTools`
31
- * references this; the typed vocabulary derives the read-only / bounded splits.
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 never exposes to a subagent, whatever the list says — so
53
- // a subagent listing one is a guaranteed-dead reference only a compiler catches.
54
- neverAvailableTools: [
55
- "Agent",
56
- "AskUserQuestion",
57
- "EnterPlanMode",
58
- "ExitPlanMode",
59
- "ScheduleWakeup",
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. (Was wrong: PreSession/PostSession don't
69
- // exist; SessionStart/SessionEnd/Stop/SubagentStop/UserPromptSubmit/PreCompact
70
- // were missing verified against the events real plugins register.)
71
- hookEvents: [
72
- "PreToolUse",
73
- "PostToolUse",
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, LS, ToolSearch (and LSP/Agent
109
- // which are not in the subagent catalog). Bash is side-effecting because
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>`, inheriting stdio so the script's own report
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 [file];
105
+ return tail;
97
106
  if (caps.tsx)
98
- return ["--import", "tsx", file];
107
+ return ["--import", "tsx", ...tail];
99
108
  if (caps.stripTypes)
100
- return ["--experimental-strip-types", file];
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>`, inheriting stdio so the script's own report
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