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.
Files changed (78) hide show
  1. package/README.md +99 -48
  2. package/dist/action-gate.js +1 -1
  3. package/dist/adapters/claude-code/agent-runtime.d.ts +64 -4
  4. package/dist/adapters/claude-code/agent-runtime.js +131 -17
  5. package/dist/adapters/claude-code/dialect.d.ts +34 -0
  6. package/dist/adapters/claude-code/dialect.js +46 -33
  7. package/dist/adapters/claude-code/effect-region.js +1 -1
  8. package/dist/adapters/claude-code/skill-runtime.d.ts +1 -1
  9. package/dist/adapters/claude-code/skill-runtime.js +1 -9
  10. package/dist/adapters/claude-code/typed-spec.d.ts +58 -0
  11. package/dist/adapters/claude-code/typed-spec.js +55 -0
  12. package/dist/adapters/codex/hook-protocol.js +3 -0
  13. package/dist/adapters/codex/mock-model.js +1 -1
  14. package/dist/claude-code.d.ts +1 -0
  15. package/dist/claude-code.js +8 -1
  16. package/dist/cli-commands.d.ts +19 -0
  17. package/dist/cli-commands.js +51 -0
  18. package/dist/cli.js +735 -76
  19. package/dist/core/bash-effects.d.ts +12 -0
  20. package/dist/core/bash-effects.js +31 -0
  21. package/dist/core/capability-diff.d.ts +46 -0
  22. package/dist/core/capability-diff.js +97 -0
  23. package/dist/core/compile.d.ts +1 -1
  24. package/dist/core/compile.js +14 -0
  25. package/dist/core/generate-harness.d.ts +187 -0
  26. package/dist/core/generate-harness.js +337 -0
  27. package/dist/core/guards.d.ts +126 -0
  28. package/dist/core/guards.js +309 -0
  29. package/dist/core/harness-driver.d.ts +1 -1
  30. package/dist/core/hook-program.d.ts +459 -0
  31. package/dist/core/hook-program.js +468 -0
  32. package/dist/core/hook-protocol.d.ts +7 -0
  33. package/dist/core/hook-providers.d.ts +138 -0
  34. package/dist/core/hook-providers.js +155 -0
  35. package/dist/core/hook-spec.d.ts +74 -0
  36. package/dist/core/hook-spec.js +130 -0
  37. package/dist/core/inline.js +1 -1
  38. package/dist/core/mcp-tool.d.ts +12 -0
  39. package/dist/core/mcp-tool.js +20 -0
  40. package/dist/core/mcp.d.ts +13 -0
  41. package/dist/core/mcp.js +67 -0
  42. package/dist/core/spec.d.ts +290 -8
  43. package/dist/core/spec.js +118 -3
  44. package/dist/core/types.d.ts +8 -0
  45. package/dist/dialect-drift.d.ts +65 -0
  46. package/dist/dialect-drift.js +216 -0
  47. package/dist/eval.d.ts +40 -5
  48. package/dist/eval.js +59 -5
  49. package/dist/guardrail-check.d.ts +85 -0
  50. package/dist/guardrail-check.js +152 -0
  51. package/dist/harness-assert.d.ts +10 -0
  52. package/dist/harness-assert.js +30 -0
  53. package/dist/hook-install.d.ts +43 -0
  54. package/dist/hook-install.js +91 -0
  55. package/dist/hook.d.ts +52 -0
  56. package/dist/hook.js +98 -0
  57. package/dist/leaderboard.d.ts +6 -0
  58. package/dist/leaderboard.js +43 -1
  59. package/dist/linting.d.ts +9 -5
  60. package/dist/linting.js +17 -5
  61. package/dist/optimize.js +1 -1
  62. package/dist/scaffold-test.d.ts +28 -0
  63. package/dist/scaffold-test.js +134 -15
  64. package/dist/scan-behavioral.d.ts +60 -0
  65. package/dist/scan-behavioral.js +239 -1
  66. package/dist/scan.d.ts +14 -0
  67. package/dist/scan.js +33 -1
  68. package/dist/score-explainer.js +1 -1
  69. package/dist/self-command-refs.d.ts +21 -0
  70. package/dist/self-command-refs.js +125 -0
  71. package/dist/testing.d.ts +5 -3
  72. package/dist/testing.js +37 -23
  73. package/dist/tool-intercept.d.ts +4 -4
  74. package/dist/tool-intercept.js +5 -5
  75. package/dist/unit.d.ts +2 -0
  76. package/dist/unit.js +8 -1
  77. package/hooks/refs-nudge.sh +1 -1
  78. package/package.json +5 -3
@@ -17,7 +17,7 @@
17
17
  *
18
18
  * Safety: this executes the gate commands the skill author declared (e.g.
19
19
  * `npm test`, `validate.py`) via an explicit, user-invoked command
20
- * (`vigiles run-skill`). It is not a silent hook and runs nothing the spec
20
+ * (`vigiles hook-runtime run-skill`). It is not a silent hook and runs nothing the spec
21
21
  * didn't declare as a gate.
22
22
  */
23
23
  import type { PurityLevel } from "../../core/effects.js";
@@ -18,7 +18,7 @@
18
18
  *
19
19
  * Safety: this executes the gate commands the skill author declared (e.g.
20
20
  * `npm test`, `validate.py`) via an explicit, user-invoked command
21
- * (`vigiles run-skill`). It is not a silent hook and runs nothing the spec
21
+ * (`vigiles hook-runtime run-skill`). It is not a silent hook and runs nothing the spec
22
22
  * didn't declare as a gate.
23
23
  */
24
24
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -38,7 +38,6 @@ const node_fs_1 = require("node:fs");
38
38
  const node_path_1 = require("node:path");
39
39
  const effects_js_1 = require("../../core/effects.js");
40
40
  const dialect_js_1 = require("./dialect.js");
41
- const effect_region_js_1 = require("./effect-region.js");
42
41
  const STEP_RE = /^###\s+Step\s+(\d+)/;
43
42
  const GATE_CMD_RE = /<!--\s*vigiles:gate\s+"([^"]*)"(?:\s+retry:(\d+))?\s*-->/;
44
43
  const GATE_FILE_RE = /<!--\s*vigiles:gate\s+file:(\S+)\s*-->/;
@@ -294,13 +293,6 @@ function evaluateSkillPreToolUse(cwd, tool, command) {
294
293
  return { allow: true, message: "" };
295
294
  const md = (0, node_fs_1.readFileSync)(full, "utf-8");
296
295
  const purity = parseSkillPurity(md);
297
- const boundary = (0, effect_region_js_1.hasEffectBoundary)(md);
298
- if (boundary) {
299
- const effective = (0, effect_region_js_1.readEffectActive)(cwd)
300
- ? (purity ?? "unrestricted")
301
- : "pure";
302
- return (0, effects_js_1.decidePurityGate)(effective, tool, command, dialect_js_1.claudeCodeDialect);
303
- }
304
296
  if (!purity)
305
297
  return { allow: true, message: "" };
306
298
  return (0, effects_js_1.decidePurityGate)(purity, tool, command, dialect_js_1.claudeCodeDialect);
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Typed Claude Code authoring surface — the compile-time half of the purity
3
+ * contract, bound to the Claude Code tool vocabulary.
4
+ *
5
+ * The core `agent()` / `skill()` builders (`vigiles/spec`) are generic over a
6
+ * tool `ToolVocabulary` that DEFAULTS to fully-open (`string` at every purity
7
+ * level), so they accept any tools — backwards-compatible, harness-agnostic.
8
+ * This module re-binds them to the CONCRETE Claude Code vocabulary derived from
9
+ * `claudeCodeDialect`, so authoring a spec with an invalid `purity`×`tools`
10
+ * combination is a `tsc` error at EDIT TIME, before any vigiles command runs:
11
+ *
12
+ * import { agent } from "vigiles/claude-code";
13
+ *
14
+ * agent({ purity: "pure", tools: ["Read", "Bash"] });
15
+ * // ^^^^^^ tsc error — Bash side-effecting
16
+ *
17
+ * agent({ purity: "bounded", tools: ["Read", "Bash", "Write"] }); // OK
18
+ * agent({ purity: "bounded", tools: ["mcp__x__y"] });
19
+ * // ^^^^^^^^^^^ tsc error — MCP not decidable
20
+ *
21
+ * agent({ tools: ["anything", "mcp__x__y"] }); // no purity → open, OK
22
+ *
23
+ * This is a STRICT ADDITION to the runtime/compile checks: `purityViolations`
24
+ * (`vigiles compile`) and `decidePurityGate` (the PreToolUse gate) are unchanged
25
+ * and remain the universal backstop. In particular the command-level decision a
26
+ * `bounded` unit makes for `Bash` (read-only command allowed, mutating denied)
27
+ * is the RUNTIME gate's job — the type only admits the `Bash` TOOL at `bounded`.
28
+ *
29
+ * The CC literal tool names live ONLY in this adapter (and the dialect it reads
30
+ * from), never in core — the hexagonal boundary that keeps the domain
31
+ * harness-agnostic.
32
+ */
33
+ import { type AgentSpec, type AgentSpecInput, type SkillSpec, type SkillSpecInput, type AuthoredPurity, type ToolVocabulary } from "../../core/spec.js";
34
+ import type { ClaudeCodeReadOnlyTool, ClaudeCodeBoundedTool } from "./dialect.js";
35
+ /**
36
+ * The Claude Code tool vocabulary, split by the purity floor that admits each
37
+ * tool (mirrors the runtime ladder in `core/effects.ts`):
38
+ * - `readOnly`: tools a `pure` unit may declare (Read/Grep/Glob/LS).
39
+ * - `bounded`: read-only ∪ Write/Edit/MultiEdit/NotebookEdit ∪ `Bash`.
40
+ */
41
+ export interface ClaudeCodeToolVocabulary extends ToolVocabulary {
42
+ readonly readOnly: ClaudeCodeReadOnlyTool;
43
+ readonly bounded: ClaudeCodeBoundedTool;
44
+ }
45
+ /**
46
+ * Define a Claude Code subagent with the purity floor enforced AT COMPILE TIME
47
+ * against the Claude Code tool catalog. Identical to the core `agent()` at
48
+ * runtime (it IS the core builder); the only difference is the typed `tools`
49
+ * constraint. `P` is inferred from the literal `purity` field.
50
+ */
51
+ export declare function agent<const P extends AuthoredPurity | undefined = undefined>(spec: AgentSpecInput<P, ClaudeCodeToolVocabulary>): AgentSpec;
52
+ /**
53
+ * Define a Claude Code skill with the purity floor enforced AT COMPILE TIME
54
+ * against the Claude Code tool catalog. Identical to the core `skill()` at
55
+ * runtime; the typed `tools` constraint is the only difference.
56
+ */
57
+ export declare function skill<const P extends AuthoredPurity | undefined = undefined>(spec: SkillSpecInput<P, ClaudeCodeToolVocabulary>): SkillSpec;
58
+ //# sourceMappingURL=typed-spec.d.ts.map
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.agent = agent;
4
+ exports.skill = skill;
5
+ /**
6
+ * Typed Claude Code authoring surface — the compile-time half of the purity
7
+ * contract, bound to the Claude Code tool vocabulary.
8
+ *
9
+ * The core `agent()` / `skill()` builders (`vigiles/spec`) are generic over a
10
+ * tool `ToolVocabulary` that DEFAULTS to fully-open (`string` at every purity
11
+ * level), so they accept any tools — backwards-compatible, harness-agnostic.
12
+ * This module re-binds them to the CONCRETE Claude Code vocabulary derived from
13
+ * `claudeCodeDialect`, so authoring a spec with an invalid `purity`×`tools`
14
+ * combination is a `tsc` error at EDIT TIME, before any vigiles command runs:
15
+ *
16
+ * import { agent } from "vigiles/claude-code";
17
+ *
18
+ * agent({ purity: "pure", tools: ["Read", "Bash"] });
19
+ * // ^^^^^^ tsc error — Bash side-effecting
20
+ *
21
+ * agent({ purity: "bounded", tools: ["Read", "Bash", "Write"] }); // OK
22
+ * agent({ purity: "bounded", tools: ["mcp__x__y"] });
23
+ * // ^^^^^^^^^^^ tsc error — MCP not decidable
24
+ *
25
+ * agent({ tools: ["anything", "mcp__x__y"] }); // no purity → open, OK
26
+ *
27
+ * This is a STRICT ADDITION to the runtime/compile checks: `purityViolations`
28
+ * (`vigiles compile`) and `decidePurityGate` (the PreToolUse gate) are unchanged
29
+ * and remain the universal backstop. In particular the command-level decision a
30
+ * `bounded` unit makes for `Bash` (read-only command allowed, mutating denied)
31
+ * is the RUNTIME gate's job — the type only admits the `Bash` TOOL at `bounded`.
32
+ *
33
+ * The CC literal tool names live ONLY in this adapter (and the dialect it reads
34
+ * from), never in core — the hexagonal boundary that keeps the domain
35
+ * harness-agnostic.
36
+ */
37
+ const spec_js_1 = require("../../core/spec.js");
38
+ /**
39
+ * Define a Claude Code subagent with the purity floor enforced AT COMPILE TIME
40
+ * against the Claude Code tool catalog. Identical to the core `agent()` at
41
+ * runtime (it IS the core builder); the only difference is the typed `tools`
42
+ * constraint. `P` is inferred from the literal `purity` field.
43
+ */
44
+ function agent(spec) {
45
+ return (0, spec_js_1.agent)(spec);
46
+ }
47
+ /**
48
+ * Define a Claude Code skill with the purity floor enforced AT COMPILE TIME
49
+ * against the Claude Code tool catalog. Identical to the core `skill()` at
50
+ * runtime; the typed `tools` constraint is the only difference.
51
+ */
52
+ function skill(spec) {
53
+ return (0, spec_js_1.skill)(spec);
54
+ }
55
+ //# sourceMappingURL=typed-spec.js.map
@@ -5,6 +5,9 @@ exports.codexHookProtocol = {
5
5
  name: "codex",
6
6
  blockExitCode: 2,
7
7
  denyDecisionValues: ["block", "deny"],
8
+ // Codex matchers are anchored regexes (`matcher = "^Bash$"`), unlike Claude
9
+ // Code's exact tool name / `A|B` alternation.
10
+ matcherStyle: "regex",
8
11
  eventEnvVars: [
9
12
  "session_id",
10
13
  "cwd",
@@ -15,7 +15,7 @@ exports.startCodexMock = startCodexMock;
15
15
  * with the proven `response.created → … → response.completed` SSE sequence that
16
16
  * makes codex emit one assistant text message. There is no count-tokens
17
17
  * endpoint. This is the Codex-side analogue of the Anthropic Messages mock in
18
- * `src/adapters/claude-code/mock-model.ts` (`startMock`).
18
+ * `src/mock-model.ts` (`startMock`).
19
19
  *
20
20
  * The wire format here is NOT guessed — it is PROVEN end-to-end against real
21
21
  * `codex` (codex-cli 0.139.0) via the `-c model_providers.mock.*` recipe in
@@ -9,6 +9,7 @@ export * from "./adapters/claude-code/plugin-loader.js";
9
9
  export * from "./mock-model.js";
10
10
  export { claudeCodeDriver, buildClaudeArgs, parseClaudeRun, claudeAvailable, } from "./harness-test.js";
11
11
  export * from "./adapters/claude-code/dialect.js";
12
+ export { agent, skill, type ClaudeCodeToolVocabulary, } from "./adapters/claude-code/typed-spec.js";
12
13
  export * from "./adapters/claude-code/layout.js";
13
14
  export * from "./adapters/claude-code/runtime.js";
14
15
  export * from "./adapters/claude-code/hook-protocol.js";
@@ -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.claudeAvailable = exports.parseClaudeRun = exports.buildClaudeArgs = exports.claudeCodeDriver = void 0;
17
+ exports.skill = exports.agent = exports.claudeAvailable = exports.parseClaudeRun = exports.buildClaudeArgs = exports.claudeCodeDriver = void 0;
18
18
  /**
19
19
  * `vigiles/claude-code` — the Claude Code-specific harness pieces a *different*
20
20
  * harness would swap out: the plugin/repo loader (reads real Claude Code plugin
@@ -35,6 +35,13 @@ Object.defineProperty(exports, "buildClaudeArgs", { enumerable: true, get: funct
35
35
  Object.defineProperty(exports, "parseClaudeRun", { enumerable: true, get: function () { return harness_test_js_1.parseClaudeRun; } });
36
36
  Object.defineProperty(exports, "claudeAvailable", { enumerable: true, get: function () { return harness_test_js_1.claudeAvailable; } });
37
37
  __exportStar(require("./adapters/claude-code/dialect.js"), exports);
38
+ // The typed Claude Code authoring surface: `agent` / `skill` with the `purity`
39
+ // floor enforced AT COMPILE TIME against the CC tool catalog (a `tsc` error for
40
+ // e.g. `purity: "pure"` + `"Bash"`). A strict addition to the runtime/compile
41
+ // purity checks; the bare core `agent()`/`skill()` (`vigiles/spec`) stay open.
42
+ var typed_spec_js_1 = require("./adapters/claude-code/typed-spec.js");
43
+ Object.defineProperty(exports, "agent", { enumerable: true, get: function () { return typed_spec_js_1.agent; } });
44
+ Object.defineProperty(exports, "skill", { enumerable: true, get: function () { return typed_spec_js_1.skill; } });
38
45
  __exportStar(require("./adapters/claude-code/layout.js"), exports);
39
46
  __exportStar(require("./adapters/claude-code/runtime.js"), exports);
40
47
  __exportStar(require("./adapters/claude-code/hook-protocol.js"), exports);
@@ -0,0 +1,19 @@
1
+ /**
2
+ * The canonical vigiles command surface — the SINGLE SOURCE OF TRUTH the
3
+ * self-command-refs dogfood (`src/self-command-refs.test.ts`) cross-references
4
+ * vigiles's OWN docs + comments against, so a renamed/removed command can't
5
+ * leave a stale `vigiles <cmd>` reference rotting in the docs (the cross-ref
6
+ * moat applied to vigiles itself; the cohesive-cli-surface rule).
7
+ *
8
+ * VERBS are typed by a human/agent/CI. HOOK_RUNTIME_KINDS are the hidden runtime
9
+ * entrypoints under `vigiles hook-runtime <kind>`, emitted into hooks configs and
10
+ * never typed by hand. A behavioural test asserts the dispatch (`src/cli.ts`)
11
+ * recognizes exactly these, so this list can't silently drift from the code.
12
+ */
13
+ /** Human-facing verbs (printed in help; typed by a human/agent/CI). */
14
+ export declare const VERBS: readonly ["init", "compile", "lint", "refs", "test", "eval", "scan", "measure", "explain", "scaffold-test", "generate-types", "generate-schema", "generate-harness", "hook-runtime"];
15
+ /** Runtime entrypoint kinds under `vigiles hook-runtime <kind>` (emitted, not typed). */
16
+ export declare const HOOK_RUNTIME_KINDS: readonly ["run-program", "agent", "agent-start", "agent-done", "skill", "skill-tool", "skill-start", "skill-done", "run-skill", "intercept-tool", "guard", "action", "refs", "effect-enter", "effect-exit"];
17
+ export type Verb = (typeof VERBS)[number];
18
+ export type HookRuntimeKind = (typeof HOOK_RUNTIME_KINDS)[number];
19
+ //# sourceMappingURL=cli-commands.d.ts.map
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ /**
3
+ * The canonical vigiles command surface — the SINGLE SOURCE OF TRUTH the
4
+ * self-command-refs dogfood (`src/self-command-refs.test.ts`) cross-references
5
+ * vigiles's OWN docs + comments against, so a renamed/removed command can't
6
+ * leave a stale `vigiles <cmd>` reference rotting in the docs (the cross-ref
7
+ * moat applied to vigiles itself; the cohesive-cli-surface rule).
8
+ *
9
+ * VERBS are typed by a human/agent/CI. HOOK_RUNTIME_KINDS are the hidden runtime
10
+ * entrypoints under `vigiles hook-runtime <kind>`, emitted into hooks configs and
11
+ * never typed by hand. A behavioural test asserts the dispatch (`src/cli.ts`)
12
+ * recognizes exactly these, so this list can't silently drift from the code.
13
+ */
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.HOOK_RUNTIME_KINDS = exports.VERBS = void 0;
16
+ /** Human-facing verbs (printed in help; typed by a human/agent/CI). */
17
+ exports.VERBS = [
18
+ "init",
19
+ "compile",
20
+ "lint",
21
+ "refs",
22
+ "test",
23
+ "eval",
24
+ "scan",
25
+ "measure",
26
+ "explain",
27
+ "scaffold-test",
28
+ "generate-types",
29
+ "generate-schema",
30
+ "generate-harness",
31
+ "hook-runtime",
32
+ ];
33
+ /** Runtime entrypoint kinds under `vigiles hook-runtime <kind>` (emitted, not typed). */
34
+ exports.HOOK_RUNTIME_KINDS = [
35
+ "run-program",
36
+ "agent",
37
+ "agent-start",
38
+ "agent-done",
39
+ "skill",
40
+ "skill-tool",
41
+ "skill-start",
42
+ "skill-done",
43
+ "run-skill",
44
+ "intercept-tool",
45
+ "guard",
46
+ "action",
47
+ "refs",
48
+ "effect-enter",
49
+ "effect-exit",
50
+ ];
51
+ //# sourceMappingURL=cli-commands.js.map