vigiles 2.5.0 → 3.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/.claude-plugin/plugin.json +9 -0
- package/README.md +73 -434
- package/action.yml +143 -7
- package/dist/action-gate.d.ts +1 -1
- package/dist/action-gate.js +1 -1
- package/dist/adapter-conformance.d.ts +30 -0
- package/dist/adapter-conformance.js +153 -0
- package/dist/adapter-registry.d.ts +42 -0
- package/dist/adapter-registry.js +55 -0
- package/dist/adapter.d.ts +26 -0
- package/dist/adapter.js +16 -0
- package/dist/adapters/claude-code/adapter.d.ts +3 -0
- package/dist/adapters/claude-code/adapter.js +46 -0
- package/dist/{agent-result.d.ts → adapters/claude-code/agent-result.d.ts} +1 -1
- package/dist/adapters/claude-code/dialect.d.ts +13 -0
- package/dist/adapters/claude-code/dialect.js +51 -0
- package/dist/adapters/claude-code/egress-entry.d.ts +2 -0
- package/dist/adapters/claude-code/egress-entry.js +115 -0
- package/dist/adapters/claude-code/egress-proxy.d.ts +2 -0
- package/dist/adapters/claude-code/egress-proxy.js +60 -0
- package/dist/adapters/claude-code/egress.d.ts +114 -0
- package/dist/adapters/claude-code/egress.js +276 -0
- package/dist/adapters/claude-code/eval-baseline.d.ts +68 -0
- package/dist/adapters/claude-code/eval-baseline.js +173 -0
- package/dist/{eval-cache.d.ts → adapters/claude-code/eval-cache.d.ts} +1 -1
- package/dist/{eval-cache.js → adapters/claude-code/eval-cache.js} +1 -1
- package/dist/{eval.d.ts → adapters/claude-code/eval.d.ts} +28 -4
- package/dist/{eval.js → adapters/claude-code/eval.js} +61 -25
- package/dist/{harness-test.d.ts → adapters/claude-code/harness-test.d.ts} +33 -37
- package/dist/{harness-test.js → adapters/claude-code/harness-test.js} +124 -43
- package/dist/adapters/claude-code/hook-protocol.d.ts +10 -0
- package/dist/adapters/claude-code/hook-protocol.js +10 -0
- package/dist/adapters/claude-code/layout.d.ts +8 -0
- package/dist/adapters/claude-code/layout.js +18 -0
- package/dist/{mock-model.d.ts → adapters/claude-code/mock-model.d.ts} +2 -24
- package/dist/adapters/claude-code/model-mock.d.ts +11 -0
- package/dist/adapters/claude-code/model-mock.js +10 -0
- package/dist/adapters/claude-code/plugin-loader.d.ts +25 -0
- package/dist/adapters/claude-code/plugin-loader.js +19 -0
- package/dist/adapters/claude-code/run-hook.d.ts +204 -0
- package/dist/adapters/claude-code/run-hook.js +418 -0
- package/dist/adapters/claude-code/run-scripts.d.ts +52 -0
- package/dist/adapters/claude-code/run-scripts.js +150 -0
- package/dist/adapters/claude-code/runtime.d.ts +16 -0
- package/dist/adapters/claude-code/runtime.js +39 -0
- package/dist/{sandbox.d.ts → adapters/claude-code/sandbox.d.ts} +45 -4
- package/dist/{sandbox.js → adapters/claude-code/sandbox.js} +76 -8
- package/dist/{skill-driver.d.ts → adapters/claude-code/skill-driver.d.ts} +1 -1
- package/dist/adapters/codex/adapter.d.ts +3 -0
- package/dist/adapters/codex/adapter.js +49 -0
- package/dist/adapters/codex/dialect.d.ts +10 -0
- package/dist/adapters/codex/dialect.js +30 -0
- package/dist/adapters/codex/driver.d.ts +20 -0
- package/dist/adapters/codex/driver.js +89 -0
- package/dist/adapters/codex/hook-protocol.d.ts +10 -0
- package/dist/adapters/codex/hook-protocol.js +18 -0
- package/dist/adapters/codex/layout.d.ts +16 -0
- package/dist/adapters/codex/layout.js +18 -0
- package/dist/adapters/codex/mock-model.d.ts +52 -0
- package/dist/adapters/codex/mock-model.js +210 -0
- package/dist/adapters/codex/model-mock.d.ts +11 -0
- package/dist/adapters/codex/model-mock.js +10 -0
- package/dist/adapters/codex/runtime.d.ts +38 -0
- package/dist/adapters/codex/runtime.js +62 -0
- package/dist/adapters/opencode/adapter.d.ts +3 -0
- package/dist/adapters/opencode/adapter.js +48 -0
- package/dist/adapters/opencode/dialect.d.ts +10 -0
- package/dist/adapters/opencode/dialect.js +36 -0
- package/dist/adapters/opencode/layout.d.ts +9 -0
- package/dist/adapters/opencode/layout.js +25 -0
- package/dist/adapters/opencode/model-mock.d.ts +10 -0
- package/dist/adapters/opencode/model-mock.js +10 -0
- package/dist/adapters/opencode/runtime.d.ts +9 -0
- package/dist/adapters/opencode/runtime.js +21 -0
- package/dist/claude-code.d.ts +16 -0
- package/dist/claude-code.js +32 -0
- package/dist/cli-flags.d.ts +22 -0
- package/dist/cli-flags.js +38 -0
- package/dist/cli.js +406 -206
- package/dist/codex.d.ts +20 -0
- package/dist/codex.js +36 -0
- package/dist/community-skills.d.ts +1 -1
- package/dist/community-skills.js +2 -2
- package/dist/core/adapter.d.ts +88 -0
- package/dist/core/adapter.js +3 -0
- package/dist/{compile.d.ts → core/compile.d.ts} +11 -2
- package/dist/{compile.js → core/compile.js} +68 -53
- package/dist/core/compose.d.ts +79 -0
- package/dist/core/compose.js +145 -0
- package/dist/core/dialect.d.ts +51 -0
- package/dist/core/dialect.js +3 -0
- package/dist/core/harness-driver.d.ts +134 -0
- package/dist/core/harness-driver.js +3 -0
- package/dist/core/hook-protocol.d.ts +28 -0
- package/dist/core/hook-protocol.js +3 -0
- package/dist/core/layout.d.ts +43 -0
- package/dist/core/layout.js +3 -0
- package/dist/core/model-mock.d.ts +27 -0
- package/dist/core/model-mock.js +3 -0
- package/dist/core/refs.d.ts +62 -0
- package/dist/{refs.js → core/refs.js} +49 -23
- package/dist/core/runtime.d.ts +38 -0
- package/dist/core/runtime.js +3 -0
- package/dist/{types.d.ts → core/types.d.ts} +29 -0
- package/dist/{validate.d.ts → core/validate.d.ts} +1 -1
- package/dist/{validate.js → core/validate.js} +41 -4
- package/dist/e2e.d.ts +19 -0
- package/dist/e2e.js +39 -0
- package/dist/harness-assert.d.ts +60 -11
- package/dist/harness-assert.js +111 -9
- package/dist/integration.d.ts +16 -0
- package/dist/integration.js +32 -0
- package/dist/leaderboard.d.ts +33 -0
- package/dist/leaderboard.js +107 -0
- package/dist/linting.d.ts +9 -0
- package/dist/linting.js +25 -0
- package/dist/plugin-loader.d.ts +6 -3
- package/dist/plugin-loader.js +101 -49
- package/dist/scan.d.ts +49 -0
- package/dist/scan.js +177 -0
- package/dist/setup-plan.d.ts +51 -0
- package/dist/setup-plan.js +85 -0
- package/dist/skill-test.d.ts +1 -1
- package/dist/skill-test.js +1 -1
- package/dist/test-coverage.d.ts +71 -0
- package/dist/test-coverage.js +228 -0
- package/dist/testing.d.ts +12 -0
- package/dist/testing.js +28 -0
- package/dist/unit.d.ts +17 -0
- package/dist/unit.js +36 -0
- package/hooks/refs-nudge.sh +24 -0
- package/package.json +35 -16
- package/skills/audit-feedback-loop/SKILL.md +76 -0
- package/skills/edit-spec/SKILL.md +131 -0
- package/skills/enforce-rules-format/SKILL.md +71 -0
- package/skills/generate-logo/SKILL.md +103 -0
- package/skills/generate-rule/SKILL.md +64 -0
- package/skills/linter-docs/clippy.md +241 -0
- package/skills/linter-docs/eslint.md +384 -0
- package/skills/linter-docs/pylint.md +288 -0
- package/skills/linter-docs/rubocop.md +277 -0
- package/skills/linter-docs/ruff.md +187 -0
- package/skills/linter-docs/stylelint.md +247 -0
- package/skills/migrate-to-spec/SKILL.md +126 -0
- package/skills/pr-to-lint-rule/SKILL.md +97 -0
- package/skills/strengthen/SKILL.md +168 -0
- package/skills/test-harness/SKILL.md +157 -0
- package/dist/action.d.ts +0 -7
- package/dist/action.js +0 -180
- package/dist/refs.d.ts +0 -44
- package/dist/run-hook.d.ts +0 -77
- package/dist/run-hook.js +0 -80
- package/dist/run-scripts.d.ts +0 -20
- package/dist/run-scripts.js +0 -70
- /package/dist/{agent-result.js → adapters/claude-code/agent-result.js} +0 -0
- /package/dist/{agent-runtime.d.ts → adapters/claude-code/agent-runtime.d.ts} +0 -0
- /package/dist/{agent-runtime.js → adapters/claude-code/agent-runtime.js} +0 -0
- /package/dist/{judge.d.ts → adapters/claude-code/judge.d.ts} +0 -0
- /package/dist/{judge.js → adapters/claude-code/judge.js} +0 -0
- /package/dist/{mock-entry.d.ts → adapters/claude-code/mock-entry.d.ts} +0 -0
- /package/dist/{mock-entry.js → adapters/claude-code/mock-entry.js} +0 -0
- /package/dist/{mock-model.js → adapters/claude-code/mock-model.js} +0 -0
- /package/dist/{skill-driver.js → adapters/claude-code/skill-driver.js} +0 -0
- /package/dist/{skill-runtime.d.ts → adapters/claude-code/skill-runtime.d.ts} +0 -0
- /package/dist/{skill-runtime.js → adapters/claude-code/skill-runtime.js} +0 -0
- /package/dist/{stats.d.ts → adapters/claude-code/stats.d.ts} +0 -0
- /package/dist/{stats.js → adapters/claude-code/stats.js} +0 -0
- /package/dist/{compile-generator.d.ts → core/compile-generator.d.ts} +0 -0
- /package/dist/{compile-generator.js → core/compile-generator.js} +0 -0
- /package/dist/{coverage.d.ts → core/coverage.d.ts} +0 -0
- /package/dist/{coverage.js → core/coverage.js} +0 -0
- /package/dist/{doc-refs.d.ts → core/doc-refs.d.ts} +0 -0
- /package/dist/{doc-refs.js → core/doc-refs.js} +0 -0
- /package/dist/{evolve.d.ts → core/evolve.d.ts} +0 -0
- /package/dist/{evolve.js → core/evolve.js} +0 -0
- /package/dist/{frontmatter.d.ts → core/frontmatter.d.ts} +0 -0
- /package/dist/{frontmatter.js → core/frontmatter.js} +0 -0
- /package/dist/{generate-schema.d.ts → core/generate-schema.d.ts} +0 -0
- /package/dist/{generate-schema.js → core/generate-schema.js} +0 -0
- /package/dist/{generate-types.d.ts → core/generate-types.d.ts} +0 -0
- /package/dist/{generate-types.js → core/generate-types.js} +0 -0
- /package/dist/{hash.d.ts → core/hash.d.ts} +0 -0
- /package/dist/{hash.js → core/hash.js} +0 -0
- /package/dist/{inline.d.ts → core/inline.d.ts} +0 -0
- /package/dist/{inline.js → core/inline.js} +0 -0
- /package/dist/{integrity.d.ts → core/integrity.d.ts} +0 -0
- /package/dist/{integrity.js → core/integrity.js} +0 -0
- /package/dist/{linters.d.ts → core/linters.d.ts} +0 -0
- /package/dist/{linters.js → core/linters.js} +0 -0
- /package/dist/{mcp.d.ts → core/mcp.d.ts} +0 -0
- /package/dist/{mcp.js → core/mcp.js} +0 -0
- /package/dist/{orphans.d.ts → core/orphans.d.ts} +0 -0
- /package/dist/{orphans.js → core/orphans.js} +0 -0
- /package/dist/{proofs.d.ts → core/proofs.d.ts} +0 -0
- /package/dist/{proofs.js → core/proofs.js} +0 -0
- /package/dist/{session.d.ts → core/session.d.ts} +0 -0
- /package/dist/{session.js → core/session.js} +0 -0
- /package/dist/{sidecar.d.ts → core/sidecar.d.ts} +0 -0
- /package/dist/{sidecar.js → core/sidecar.js} +0 -0
- /package/dist/{spec.d.ts → core/spec.d.ts} +0 -0
- /package/dist/{spec.js → core/spec.js} +0 -0
- /package/dist/{symbols.d.ts → core/symbols.d.ts} +0 -0
- /package/dist/{symbols.js → core/symbols.js} +0 -0
- /package/dist/{test-utils.d.ts → core/test-utils.d.ts} +0 -0
- /package/dist/{test-utils.js → core/test-utils.js} +0 -0
- /package/dist/{types.js → core/types.js} +0 -0
- /package/{.claude-plugin/hooks → hooks}/post-edit.sh +0 -0
- /package/{.claude-plugin/hooks → hooks}/pre-edit.sh +0 -0
- /package/{.claude-plugin/hooks → hooks}/session-start.sh +0 -0
package/dist/codex.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `vigiles/codex` — the OpenAI Codex harness adapter. Sits beside
|
|
3
|
+
* `vigiles/claude-code`: same harness-agnostic `vigiles/testing` core, a
|
|
4
|
+
* different transport (the `codex` binary + the OpenAI **Responses** SSE mock).
|
|
5
|
+
*
|
|
6
|
+
* Pillar 2 (harness testing) is proven here — `startCodexMock` serves the
|
|
7
|
+
* Responses SSE that real `codex exec` completes a turn against, keylessly (see
|
|
8
|
+
* `codexMockArgs`/`codexMockEnv` for the wiring). Pillar 1 instruction/skill
|
|
9
|
+
* *renderers* still emit the Claude-Code shape until the format-axis renderers
|
|
10
|
+
* land (see `research/code-adapter-architecture.md`).
|
|
11
|
+
*/
|
|
12
|
+
export * from "./adapters/codex/dialect.js";
|
|
13
|
+
export * from "./adapters/codex/layout.js";
|
|
14
|
+
export * from "./adapters/codex/runtime.js";
|
|
15
|
+
export * from "./adapters/codex/hook-protocol.js";
|
|
16
|
+
export * from "./adapters/codex/model-mock.js";
|
|
17
|
+
export * from "./adapters/codex/mock-model.js";
|
|
18
|
+
export * from "./adapters/codex/driver.js";
|
|
19
|
+
export * from "./adapters/codex/adapter.js";
|
|
20
|
+
//# sourceMappingURL=codex.d.ts.map
|
package/dist/codex.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
/**
|
|
18
|
+
* `vigiles/codex` — the OpenAI Codex harness adapter. Sits beside
|
|
19
|
+
* `vigiles/claude-code`: same harness-agnostic `vigiles/testing` core, a
|
|
20
|
+
* different transport (the `codex` binary + the OpenAI **Responses** SSE mock).
|
|
21
|
+
*
|
|
22
|
+
* Pillar 2 (harness testing) is proven here — `startCodexMock` serves the
|
|
23
|
+
* Responses SSE that real `codex exec` completes a turn against, keylessly (see
|
|
24
|
+
* `codexMockArgs`/`codexMockEnv` for the wiring). Pillar 1 instruction/skill
|
|
25
|
+
* *renderers* still emit the Claude-Code shape until the format-axis renderers
|
|
26
|
+
* land (see `research/code-adapter-architecture.md`).
|
|
27
|
+
*/
|
|
28
|
+
__exportStar(require("./adapters/codex/dialect.js"), exports);
|
|
29
|
+
__exportStar(require("./adapters/codex/layout.js"), exports);
|
|
30
|
+
__exportStar(require("./adapters/codex/runtime.js"), exports);
|
|
31
|
+
__exportStar(require("./adapters/codex/hook-protocol.js"), exports);
|
|
32
|
+
__exportStar(require("./adapters/codex/model-mock.js"), exports);
|
|
33
|
+
__exportStar(require("./adapters/codex/mock-model.js"), exports);
|
|
34
|
+
__exportStar(require("./adapters/codex/driver.js"), exports);
|
|
35
|
+
__exportStar(require("./adapters/codex/adapter.js"), exports);
|
|
36
|
+
//# sourceMappingURL=codex.js.map
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
*
|
|
13
13
|
* These are exercised in community-skills.test.ts with a scripted model.
|
|
14
14
|
*/
|
|
15
|
-
import { type SkillProgram } from "./skill-driver.js";
|
|
15
|
+
import { type SkillProgram } from "./adapters/claude-code/skill-driver.js";
|
|
16
16
|
/** COLLECT → BATCH → FIX rounds; ceiling 7; exit when no actionable feedback. */
|
|
17
17
|
export declare const prReviewLoop: SkillProgram;
|
|
18
18
|
/** Red → Green → Refactor, once per behavior until done. */
|
package/dist/community-skills.js
CHANGED
|
@@ -15,8 +15,8 @@ exports.subagentDriven = exports.tdd = exports.prReviewLoop = void 0;
|
|
|
15
15
|
*
|
|
16
16
|
* These are exercised in community-skills.test.ts with a scripted model.
|
|
17
17
|
*/
|
|
18
|
-
const skill_driver_js_1 = require("./skill-driver.js");
|
|
19
|
-
const spec_js_1 = require("./spec.js");
|
|
18
|
+
const skill_driver_js_1 = require("./adapters/claude-code/skill-driver.js");
|
|
19
|
+
const spec_js_1 = require("./core/spec.js");
|
|
20
20
|
/** COLLECT → BATCH → FIX rounds; ceiling 7; exit when no actionable feedback. */
|
|
21
21
|
const prReviewLoop = function* () {
|
|
22
22
|
let round = 0;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HarnessAdapter — the bundle that makes a harness a single, addable unit.
|
|
3
|
+
*
|
|
4
|
+
* Each port (HarnessDialect, PluginLayout, HarnessRuntime, HookProtocol,
|
|
5
|
+
* ModelMock) decouples one axis of Claude-Code coupling. A `HarnessAdapter`
|
|
6
|
+
* groups a harness's five port implementations plus a `detect` predicate, so
|
|
7
|
+
* **adding a harness is writing one object** — `codexAdapter`, `geminiAdapter`,
|
|
8
|
+
* `myHarnessAdapter` — not editing the core. The library stays import-named
|
|
9
|
+
* (`import { claudeCodeAdapter } from "vigiles/claude-code"`); the bundle is the
|
|
10
|
+
* thing the CLI auto-detects and the conformance kit checks.
|
|
11
|
+
*
|
|
12
|
+
* See `docs/authoring-an-adapter.md` (third-party guide) and
|
|
13
|
+
* `research/code-adapter-architecture.md` (the design).
|
|
14
|
+
*/
|
|
15
|
+
import type { HarnessDialect } from "./dialect.js";
|
|
16
|
+
import type { PluginLayout } from "./layout.js";
|
|
17
|
+
import type { HarnessRuntime } from "./runtime.js";
|
|
18
|
+
import type { HookProtocol } from "./hook-protocol.js";
|
|
19
|
+
import type { ModelMock } from "./model-mock.js";
|
|
20
|
+
import type { HarnessTestDriver } from "./harness-driver.js";
|
|
21
|
+
/**
|
|
22
|
+
* Which vigiles pillars/tiers a harness can drive — the capability matrix made
|
|
23
|
+
* executable (see `docs/harnesses.md`). Not every harness reaches every tier:
|
|
24
|
+
* a closed, un-mockable one (Cursor, Devin, Amp, Amazon Q) can only ever do
|
|
25
|
+
* pillar 1, and a harness whose hooks are in-process code modules (OpenCode)
|
|
26
|
+
* has no shell-hook tier. Declaring this lets the conformance kit relax the
|
|
27
|
+
* port requirements for what an adapter says it can't do (instead of forcing a
|
|
28
|
+
* fake `runtime`/`modelMock`/`hookProtocol`), and lets the pillar-2 runners
|
|
29
|
+
* refuse — rather than mysteriously hang on — an adapter that can't be mocked.
|
|
30
|
+
*/
|
|
31
|
+
export interface AdapterCapabilities {
|
|
32
|
+
/**
|
|
33
|
+
* Pillar 1 — reference verification (dialect + layout). Always `true`: every
|
|
34
|
+
* harness with an instruction-file format can have its references verified.
|
|
35
|
+
*/
|
|
36
|
+
readonly referenceVerification: true;
|
|
37
|
+
/**
|
|
38
|
+
* Pillar 2 — deterministic harness tests + evals: the binary can be spawned
|
|
39
|
+
* and pointed at a mock model. Requires `runtime` + `modelMock`. `false` for
|
|
40
|
+
* closed harnesses that route through a fixed backend (no BYOM): Cursor,
|
|
41
|
+
* Devin, Amp, Amazon Q — they are pillar-1-only adapters.
|
|
42
|
+
*/
|
|
43
|
+
readonly harnessTesting: boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Hooks are shell processes speaking the exit-code/env block protocol —
|
|
46
|
+
* Claude Code, Codex, Crush. Requires `hookProtocol`. `false` when hooks are
|
|
47
|
+
* in-process code modules (OpenCode's TS plugins), so the `run-hook` unit
|
|
48
|
+
* tier and the `HookProtocol` port do not apply.
|
|
49
|
+
*/
|
|
50
|
+
readonly shellHooks: boolean;
|
|
51
|
+
}
|
|
52
|
+
export interface HarnessAdapter {
|
|
53
|
+
/** Stable identifier, e.g. "claude-code". The CLI/registry key. */
|
|
54
|
+
readonly name: string;
|
|
55
|
+
/** What this harness can drive — gates which ports below are required. */
|
|
56
|
+
readonly capabilities: AdapterCapabilities;
|
|
57
|
+
/** Format axis: tool catalog, hook events, instruction targets, plugin-root token. */
|
|
58
|
+
readonly dialect: HarnessDialect;
|
|
59
|
+
/** Layout axis: where the instruction file / skills / agents / hooks live on disk. */
|
|
60
|
+
readonly layout: PluginLayout;
|
|
61
|
+
/** Transport axis: the agent binary to spawn + the mock-model env. Present iff
|
|
62
|
+
* `capabilities.harnessTesting`. */
|
|
63
|
+
readonly runtime?: HarnessRuntime;
|
|
64
|
+
/** Transport axis: how a hook signals a block/deny. Present iff
|
|
65
|
+
* `capabilities.shellHooks`. */
|
|
66
|
+
readonly hookProtocol?: HookProtocol;
|
|
67
|
+
/** Transport axis: the mock model's wire format + endpoints. Present iff
|
|
68
|
+
* `capabilities.harnessTesting`. */
|
|
69
|
+
readonly modelMock?: ModelMock;
|
|
70
|
+
/**
|
|
71
|
+
* Pillar-2 deterministic-runner driver: how `runHarnessTest` builds this
|
|
72
|
+
* harness's argv, starts its scripted mock, and parses its stdout. Present iff
|
|
73
|
+
* `capabilities.harnessTesting` (it composes the runtime + modelMock into the
|
|
74
|
+
* one seam the runner dispatches through). Carried on the bundle so the runner
|
|
75
|
+
* never imports a sibling adapter to find it.
|
|
76
|
+
*/
|
|
77
|
+
readonly harnessTestDriver?: HarnessTestDriver;
|
|
78
|
+
/**
|
|
79
|
+
* How strongly a repo at `root` looks like it targets this harness — the CLI
|
|
80
|
+
* uses it to auto-detect which adapter to use (the library selects by import).
|
|
81
|
+
* Returns a **specificity score**: 0 = not this harness; higher = a more
|
|
82
|
+
* specific match. The registry picks the highest scorer, so a strong signal
|
|
83
|
+
* (a `.claude-plugin/` manifest) beats a weak one (a bare `CLAUDE.md`, or an
|
|
84
|
+
* `AGENTS.md` that many harnesses share) regardless of registration order.
|
|
85
|
+
*/
|
|
86
|
+
detect(root: string): number;
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=adapter.d.ts.map
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import type { ClaudeSpec, SkillSpec, AgentSpec, Railway } from "./spec.js";
|
|
8
8
|
import type { LinterCheckResult } from "./linters.js";
|
|
9
|
+
import type { HarnessDialect } from "./dialect.js";
|
|
9
10
|
/** @internal Compute SHA-256 hash of content (excluding any existing hash line). */
|
|
10
11
|
export declare function computeHash(content: string): string;
|
|
11
12
|
/** @internal Prepend a hash comment to compiled content. */
|
|
@@ -44,6 +45,8 @@ export interface CompileClaudeResult {
|
|
|
44
45
|
export interface CompileClaudeOptions {
|
|
45
46
|
basePath?: string;
|
|
46
47
|
specFile?: string;
|
|
48
|
+
/** Injected harness dialect; its instructionTargets[0] is the default target. */
|
|
49
|
+
dialect?: HarnessDialect;
|
|
47
50
|
/** Maximum number of rules allowed. Compilation fails if exceeded. */
|
|
48
51
|
maxRules?: number;
|
|
49
52
|
/** Maximum estimated tokens for compiled output. */
|
|
@@ -78,6 +81,9 @@ export interface CompileSkillResult {
|
|
|
78
81
|
export declare function compileSkill(spec: SkillSpec, options?: {
|
|
79
82
|
basePath?: string;
|
|
80
83
|
specFile?: string;
|
|
84
|
+
/** The harness dialect — selects the SKILL.md frontmatter profile. Omitting
|
|
85
|
+
* it defaults to the Claude Code profile, so existing callers are unchanged. */
|
|
86
|
+
dialect?: HarnessDialect;
|
|
81
87
|
}): CompileSkillResult;
|
|
82
88
|
export interface CompileAgentResult {
|
|
83
89
|
markdown: string;
|
|
@@ -88,9 +94,12 @@ export interface CompileAgentResult {
|
|
|
88
94
|
* Verifies the tool contract and the body's references; the marks the body
|
|
89
95
|
* carries (`vigiles:symbol`, file/cmd refs) are the same ones `audit` re-checks.
|
|
90
96
|
*/
|
|
91
|
-
export declare function compileAgent(spec: AgentSpec, options
|
|
97
|
+
export declare function compileAgent(spec: AgentSpec, options: {
|
|
92
98
|
basePath?: string;
|
|
93
99
|
specFile?: string;
|
|
100
|
+
/** The harness dialect to verify the tool contract against (required — the
|
|
101
|
+
* core defines no default dialect; the adapter/composition root injects it). */
|
|
102
|
+
dialect: HarnessDialect;
|
|
94
103
|
}): CompileAgentResult;
|
|
95
104
|
export interface CompileRailwayOptions {
|
|
96
105
|
/** Names of compiled agents, to resolve `delegate` targets. Skipped if omitted. */
|
|
@@ -130,5 +139,5 @@ export interface AdoptResult {
|
|
|
130
139
|
* Compare a generated file against what the spec would produce.
|
|
131
140
|
* Returns the diff so users can see what was manually changed.
|
|
132
141
|
*/
|
|
133
|
-
export declare function adoptDiff(filePath: string, spec: ClaudeSpec | SkillSpec | AgentSpec, basePath: string): AdoptResult;
|
|
142
|
+
export declare function adoptDiff(filePath: string, spec: ClaudeSpec | SkillSpec | AgentSpec, basePath: string, dialect: HarnessDialect): AdoptResult;
|
|
134
143
|
//# sourceMappingURL=compile.d.ts.map
|
|
@@ -26,6 +26,10 @@ const node_path_1 = require("node:path");
|
|
|
26
26
|
const hash_js_1 = require("./hash.js");
|
|
27
27
|
const symbols_js_1 = require("./symbols.js");
|
|
28
28
|
const linters_js_1 = require("./linters.js");
|
|
29
|
+
// vigiles's default compile target when a spec names none and no dialect is
|
|
30
|
+
// injected — a product convention (vigiles emits CLAUDE.md by default), not a
|
|
31
|
+
// harness dialect. When a dialect IS injected its instructionTargets win.
|
|
32
|
+
const DEFAULT_TARGET = "CLAUDE.md";
|
|
29
33
|
// ---------------------------------------------------------------------------
|
|
30
34
|
// Hash utilities
|
|
31
35
|
// ---------------------------------------------------------------------------
|
|
@@ -388,8 +392,14 @@ function compileRulesSection(spec, basePath, options) {
|
|
|
388
392
|
* Returns the compiled markdown, validation errors, and linter check results.
|
|
389
393
|
* The markdown is generated even if there are errors (with warnings).
|
|
390
394
|
*/
|
|
395
|
+
// The instruction-file renderer is format-neutral: it emits plain markdown (h1
|
|
396
|
+
// from the dialect's instructionTargets, prose/Key-Files/Commands/Rules sections,
|
|
397
|
+
// and the trailing integrity-hash comment). That is exactly the AGENTS.md shape
|
|
398
|
+
// (no frontmatter), so Codex/OpenCode reuse it unchanged — only the h1 target
|
|
399
|
+
// differs, which already comes from the injected dialect. Nothing here is
|
|
400
|
+
// CC-only, so there is no per-dialect branch to gate.
|
|
391
401
|
function compileClaude(spec, options = {}) {
|
|
392
|
-
const targets = spec.target ??
|
|
402
|
+
const targets = spec.target ?? options.dialect?.instructionTargets[0] ?? DEFAULT_TARGET;
|
|
393
403
|
const target = Array.isArray(targets) ? targets[0] : targets;
|
|
394
404
|
const basePath = options.basePath ?? process.cwd();
|
|
395
405
|
const specFile = options.specFile ?? `${target}.spec.ts`;
|
|
@@ -546,22 +556,32 @@ function collectSkillRefs(spec) {
|
|
|
546
556
|
refs.push(spec.result);
|
|
547
557
|
return refs;
|
|
548
558
|
}
|
|
549
|
-
/**
|
|
550
|
-
|
|
559
|
+
/**
|
|
560
|
+
* Build the SKILL.md YAML frontmatter block under the harness's frontmatter
|
|
561
|
+
* profile. The `"minimal"` profile (Codex/OpenCode) emits ONLY name +
|
|
562
|
+
* description; `"claude-code"` adds the CC-only keys (disable-model-invocation,
|
|
563
|
+
* argument-hint). Default is `"claude-code"` so callers that pass no dialect get
|
|
564
|
+
* byte-identical output to before.
|
|
565
|
+
*/
|
|
566
|
+
function renderSkillFrontmatter(spec, profile = "claude-code") {
|
|
551
567
|
const fm = [
|
|
552
568
|
"---",
|
|
553
569
|
"",
|
|
554
570
|
`name: ${spec.name}`,
|
|
555
571
|
`description: ${spec.description}`,
|
|
556
572
|
];
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
573
|
+
// The CC-only keys below are inert in a minimal (Codex/OpenCode) SKILL.md, so
|
|
574
|
+
// they're omitted entirely under that profile.
|
|
575
|
+
if (profile === "claude-code") {
|
|
576
|
+
if (spec.disableModelInvocation !== undefined) {
|
|
577
|
+
fm.push(`disable-model-invocation: ${String(spec.disableModelInvocation)}`);
|
|
578
|
+
}
|
|
579
|
+
const argHint = spec.inputs && spec.inputs.length > 0
|
|
580
|
+
? renderArgumentHint(spec.inputs)
|
|
581
|
+
: spec.argumentHint;
|
|
582
|
+
if (argHint)
|
|
583
|
+
fm.push(`argument-hint: ${argHint}`);
|
|
584
|
+
}
|
|
565
585
|
fm.push("", "---");
|
|
566
586
|
return fm.join("\n");
|
|
567
587
|
}
|
|
@@ -621,6 +641,7 @@ function checkInlineCode(markdown, max) {
|
|
|
621
641
|
function compileSkill(spec, options = {}) {
|
|
622
642
|
const basePath = options.basePath ?? process.cwd();
|
|
623
643
|
const specFile = options.specFile ?? "SKILL.md.spec.ts";
|
|
644
|
+
const profile = options.dialect?.skillFrontmatter ?? "claude-code";
|
|
624
645
|
const errors = [];
|
|
625
646
|
// Verify spec file naming
|
|
626
647
|
if (!specFile.endsWith(".spec.ts")) {
|
|
@@ -641,45 +662,29 @@ function compileSkill(spec, options = {}) {
|
|
|
641
662
|
errors.push(...validateRefs(collectSkillRefs(spec), basePath));
|
|
642
663
|
const sections = renderSkillSections(spec);
|
|
643
664
|
errors.push(...checkInlineCode(sections, spec.maxInlineCodeLines ?? DEFAULT_MAX_INLINE_CODE_LINES));
|
|
644
|
-
const content = renderSkillFrontmatter(spec) + "\n\n" + sections.trim() + "\n";
|
|
665
|
+
const content = renderSkillFrontmatter(spec, profile) + "\n\n" + sections.trim() + "\n";
|
|
645
666
|
return { markdown: addHash(content, specFile), errors };
|
|
646
667
|
}
|
|
647
668
|
// ---------------------------------------------------------------------------
|
|
648
669
|
// Compile a subagent spec → agents/<name>.md
|
|
649
670
|
// ---------------------------------------------------------------------------
|
|
650
|
-
// The tool
|
|
651
|
-
//
|
|
652
|
-
//
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
"NotebookEdit",
|
|
663
|
-
"TodoWrite",
|
|
664
|
-
"Task",
|
|
665
|
-
"Skill",
|
|
666
|
-
];
|
|
667
|
-
const MCP_TOOL_RE = /^mcp__[a-z0-9_-]+__[a-z0-9_-]+$/i;
|
|
668
|
-
// Tools the platform never exposes to a subagent, whatever the list says — so a
|
|
669
|
-
// subagent listing one is a guaranteed-dead reference only a compiler catches.
|
|
670
|
-
const NEVER_AVAILABLE_TOOLS = new Set([
|
|
671
|
-
"Agent",
|
|
672
|
-
"AskUserQuestion",
|
|
673
|
-
"EnterPlanMode",
|
|
674
|
-
"ExitPlanMode",
|
|
675
|
-
"ScheduleWakeup",
|
|
676
|
-
"WaitForMcpServers",
|
|
677
|
-
]);
|
|
671
|
+
// The subagent tool catalog (built-in / never-available / MCP shape) is the
|
|
672
|
+
// harness's format-axis vocabulary — it lives in the HarnessDialect port
|
|
673
|
+
// (src/core/dialect.ts), injected here, never hard-coded for one harness.
|
|
674
|
+
//
|
|
675
|
+
// SCOPE: compileAgent renders vigiles's agent() — a VERIFIED TOOL CONTRACT — to
|
|
676
|
+
// a Claude-Code-shaped subagent markdown file. Compiling that to Codex is a
|
|
677
|
+
// deliberate NON-GOAL, not a missing renderer: a Codex "subagent" is an
|
|
678
|
+
// [agents.<name>] TOML concurrency table (max_threads / max_depth), which is a
|
|
679
|
+
// runtime-orchestration knob, NOT a tool contract. The two models don't map, so
|
|
680
|
+
// vigiles does not emit a TOML [agents] block. The Codex dialect still verifies
|
|
681
|
+
// an agent()'s tool contract (its built-in catalog) — only the OUTPUT renderer
|
|
682
|
+
// is CC-only here. See research/codex-prototype-findings.md (gaps).
|
|
678
683
|
/** Closest known tool by edit distance (≤ 3), for a "did you mean" hint. */
|
|
679
|
-
function closestTool(tool) {
|
|
684
|
+
function closestTool(tool, dialect) {
|
|
680
685
|
let best = null;
|
|
681
686
|
let bestDistance = Infinity;
|
|
682
|
-
for (const known of
|
|
687
|
+
for (const known of dialect.builtinAgentTools) {
|
|
683
688
|
const d = (0, linters_js_1.editDistance)(tool.toLowerCase(), known.toLowerCase());
|
|
684
689
|
if (d < bestDistance) {
|
|
685
690
|
bestDistance = d;
|
|
@@ -689,25 +694,26 @@ function closestTool(tool) {
|
|
|
689
694
|
return bestDistance <= 3 ? best : null;
|
|
690
695
|
}
|
|
691
696
|
/** Verify a subagent's allowed-tools contract — the rails are real tools. */
|
|
692
|
-
function validateAgentTools(tools) {
|
|
697
|
+
function validateAgentTools(tools, dialect) {
|
|
698
|
+
const never = new Set(dialect.neverAvailableTools);
|
|
693
699
|
const errors = [];
|
|
694
700
|
for (const tool of tools) {
|
|
695
|
-
if (
|
|
701
|
+
if (never.has(tool)) {
|
|
696
702
|
errors.push({
|
|
697
703
|
type: "unknown-tool",
|
|
698
704
|
message: `Tool "${tool}" is never available to a subagent — remove it from the tools list.`,
|
|
699
705
|
});
|
|
700
706
|
continue;
|
|
701
707
|
}
|
|
702
|
-
if (
|
|
708
|
+
if (dialect.builtinAgentTools.includes(tool))
|
|
703
709
|
continue;
|
|
704
|
-
if (
|
|
710
|
+
if (dialect.mcpToolPattern.test(tool))
|
|
705
711
|
continue;
|
|
706
|
-
const near = closestTool(tool);
|
|
712
|
+
const near = closestTool(tool, dialect);
|
|
707
713
|
const hint = near ? ` Did you mean "${near}"?` : "";
|
|
708
714
|
errors.push({
|
|
709
715
|
type: "unknown-tool",
|
|
710
|
-
message: `Unknown tool "${tool}" in agent tools — use a built-in tool (${
|
|
716
|
+
message: `Unknown tool "${tool}" in agent tools — use a built-in tool (${dialect.builtinAgentTools.join(", ")}) or an MCP tool (mcp__server__tool).${hint}`,
|
|
711
717
|
});
|
|
712
718
|
}
|
|
713
719
|
return errors;
|
|
@@ -798,9 +804,10 @@ function renderAgentRules(rules) {
|
|
|
798
804
|
* Verifies the tool contract and the body's references; the marks the body
|
|
799
805
|
* carries (`vigiles:symbol`, file/cmd refs) are the same ones `audit` re-checks.
|
|
800
806
|
*/
|
|
801
|
-
function compileAgent(spec, options
|
|
807
|
+
function compileAgent(spec, options) {
|
|
802
808
|
const basePath = options.basePath ?? process.cwd();
|
|
803
809
|
const specFile = options.specFile ?? "agent.md.spec.ts";
|
|
810
|
+
const dialect = options.dialect;
|
|
804
811
|
const errors = [];
|
|
805
812
|
if (!specFile.endsWith(".spec.ts")) {
|
|
806
813
|
errors.push({
|
|
@@ -815,7 +822,7 @@ function compileAgent(spec, options = {}) {
|
|
|
815
822
|
});
|
|
816
823
|
}
|
|
817
824
|
if (spec.tools)
|
|
818
|
-
errors.push(...validateAgentTools(spec.tools));
|
|
825
|
+
errors.push(...validateAgentTools(spec.tools, dialect));
|
|
819
826
|
if (Array.isArray(spec.body)) {
|
|
820
827
|
errors.push(...validateRefs(spec.body, basePath));
|
|
821
828
|
}
|
|
@@ -921,7 +928,7 @@ function checkFileHash(filePath) {
|
|
|
921
928
|
* Compare a generated file against what the spec would produce.
|
|
922
929
|
* Returns the diff so users can see what was manually changed.
|
|
923
930
|
*/
|
|
924
|
-
function adoptDiff(filePath, spec, basePath) {
|
|
931
|
+
function adoptDiff(filePath, spec, basePath, dialect) {
|
|
925
932
|
const fullPath = (0, node_path_1.resolve)(basePath, filePath);
|
|
926
933
|
const currentContent = (0, node_fs_1.existsSync)(fullPath)
|
|
927
934
|
? (0, node_fs_1.readFileSync)(fullPath, "utf-8")
|
|
@@ -930,7 +937,11 @@ function adoptDiff(filePath, spec, basePath) {
|
|
|
930
937
|
// Compile the spec to get what it WOULD produce
|
|
931
938
|
let compiledContent = null;
|
|
932
939
|
if (spec._specType === "claude") {
|
|
933
|
-
const { markdown } = compileClaude(spec, {
|
|
940
|
+
const { markdown } = compileClaude(spec, {
|
|
941
|
+
basePath,
|
|
942
|
+
specFile: filePath,
|
|
943
|
+
dialect,
|
|
944
|
+
});
|
|
934
945
|
compiledContent = markdown;
|
|
935
946
|
}
|
|
936
947
|
else if (spec._specType === "skill") {
|
|
@@ -938,7 +949,11 @@ function adoptDiff(filePath, spec, basePath) {
|
|
|
938
949
|
compiledContent = markdown;
|
|
939
950
|
}
|
|
940
951
|
else if (spec._specType === "agent") {
|
|
941
|
-
const { markdown } = compileAgent(spec, {
|
|
952
|
+
const { markdown } = compileAgent(spec, {
|
|
953
|
+
basePath,
|
|
954
|
+
specFile: filePath,
|
|
955
|
+
dialect,
|
|
956
|
+
});
|
|
942
957
|
compiledContent = markdown;
|
|
943
958
|
}
|
|
944
959
|
// Simple line-based diff
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sync-tool compatibility detector — keep vigiles composable with the rule-sync
|
|
3
|
+
* tools (Ruler, rulesync) instead of fighting them for the same files.
|
|
4
|
+
*
|
|
5
|
+
* Both vigiles and a sync tool want to *write* CLAUDE.md / AGENTS.md. That
|
|
6
|
+
* collision is the whole compatibility problem: vigiles stamps a SHA-256
|
|
7
|
+
* integrity header on line 1 (see `integrity.ts`), but Ruler concatenates its
|
|
8
|
+
* source files into CLAUDE.md (prepending `<!-- Source: … -->`) and rulesync
|
|
9
|
+
* regenerates it — either way the hash silently goes stale. The clean topology
|
|
10
|
+
* is "vigiles upstream": compile into the tool's *source slot* and let the tool
|
|
11
|
+
* distribute (see `research/sync-tool-compatibility.md`).
|
|
12
|
+
*
|
|
13
|
+
* This detector is pure filesystem inspection — the same deterministic-detector
|
|
14
|
+
* shape as `orphans.ts` / `test-coverage.ts`. It reports which tools are present
|
|
15
|
+
* and any target that collides with a file the tool regenerates, so `vigiles
|
|
16
|
+
* audit` can warn before the integrity guarantee is lost.
|
|
17
|
+
*/
|
|
18
|
+
/** A rule-sync tool vigiles should compose with rather than reimplement. */
|
|
19
|
+
export type SyncToolName = "ruler" | "rulesync";
|
|
20
|
+
export interface DetectedSyncTool {
|
|
21
|
+
readonly name: SyncToolName;
|
|
22
|
+
/**
|
|
23
|
+
* Where vigiles should compile its canonical output so the tool picks it up
|
|
24
|
+
* as a source (Topology A), e.g. `.ruler/AGENTS.md`.
|
|
25
|
+
*/
|
|
26
|
+
readonly sourceSlot: string;
|
|
27
|
+
/**
|
|
28
|
+
* Files the tool regenerates/concatenates as distribution output. A vigiles
|
|
29
|
+
* compile target that lands in this set collides (the integrity hazard).
|
|
30
|
+
*/
|
|
31
|
+
readonly distributes: readonly string[];
|
|
32
|
+
}
|
|
33
|
+
export interface ComposeCollision {
|
|
34
|
+
readonly tool: SyncToolName;
|
|
35
|
+
/** The vigiles compile target that the tool also owns. */
|
|
36
|
+
readonly target: string;
|
|
37
|
+
/** The source slot to compile into instead. */
|
|
38
|
+
readonly redirectTo: string;
|
|
39
|
+
readonly reason: string;
|
|
40
|
+
}
|
|
41
|
+
/** CLAUDE.md and AGENTS.md recognized as one artifact (symlinked or synced). */
|
|
42
|
+
export interface InstructionMirror {
|
|
43
|
+
/** The two instruction filenames that mirror each other. */
|
|
44
|
+
readonly files: readonly [string, string];
|
|
45
|
+
/** How they're kept identical: a symlink, or byte-identical synced content. */
|
|
46
|
+
readonly kind: "symlink" | "identical-content";
|
|
47
|
+
/** For `kind: "symlink"`, which filename is the link and which is the real file. */
|
|
48
|
+
readonly link?: string;
|
|
49
|
+
readonly realTarget?: string;
|
|
50
|
+
readonly reason: string;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Detect the rule-sync tools configured in the repo at `root`. Ruler is keyed
|
|
54
|
+
* on its `.ruler/` source dir or a `ruler.toml`; rulesync on its `.rulesync/`
|
|
55
|
+
* dir. Returns each tool's recommended source slot and the files it owns as
|
|
56
|
+
* distribution output (used to find collisions).
|
|
57
|
+
*/
|
|
58
|
+
export declare function detectSyncTools(root: string): DetectedSyncTool[];
|
|
59
|
+
/**
|
|
60
|
+
* Detect whether `CLAUDE.md` and `AGENTS.md` at `root` are ONE artifact, not two
|
|
61
|
+
* — a symlink in either direction (`ln -s CLAUDE.md AGENTS.md`) or byte-identical
|
|
62
|
+
* content (a sync tool keeping them in lockstep). Claude Code reads CLAUDE.md
|
|
63
|
+
* only ([anthropics/claude-code#34235]); users bridge to the AGENTS.md tools this
|
|
64
|
+
* way (see `research/sync-tool-compatibility.md` requirement 7). When mirrored,
|
|
65
|
+
* vigiles must treat them as the same file — hash + `require-spec` run once on the
|
|
66
|
+
* real one, and the mirror is never flagged as a second, spec-less instruction
|
|
67
|
+
* file. Returns null when one is absent, or both exist but genuinely differ.
|
|
68
|
+
*/
|
|
69
|
+
export declare function detectInstructionMirror(root: string): InstructionMirror | null;
|
|
70
|
+
/**
|
|
71
|
+
* Given the repo `root` and the spec's compile `targets`, report every case
|
|
72
|
+
* where a target is also a file a detected sync tool regenerates. Each
|
|
73
|
+
* collision carries the source slot to compile into instead — the actionable
|
|
74
|
+
* fix that preserves the integrity hash (the tool distributes from there).
|
|
75
|
+
*
|
|
76
|
+
* No detected tool, or no overlapping target, yields an empty list.
|
|
77
|
+
*/
|
|
78
|
+
export declare function composeCollisions(root: string, targets: readonly string[]): ComposeCollision[];
|
|
79
|
+
//# sourceMappingURL=compose.d.ts.map
|