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.
Files changed (209) hide show
  1. package/.claude-plugin/plugin.json +9 -0
  2. package/README.md +73 -434
  3. package/action.yml +143 -7
  4. package/dist/action-gate.d.ts +1 -1
  5. package/dist/action-gate.js +1 -1
  6. package/dist/adapter-conformance.d.ts +30 -0
  7. package/dist/adapter-conformance.js +153 -0
  8. package/dist/adapter-registry.d.ts +42 -0
  9. package/dist/adapter-registry.js +55 -0
  10. package/dist/adapter.d.ts +26 -0
  11. package/dist/adapter.js +16 -0
  12. package/dist/adapters/claude-code/adapter.d.ts +3 -0
  13. package/dist/adapters/claude-code/adapter.js +46 -0
  14. package/dist/{agent-result.d.ts → adapters/claude-code/agent-result.d.ts} +1 -1
  15. package/dist/adapters/claude-code/dialect.d.ts +13 -0
  16. package/dist/adapters/claude-code/dialect.js +51 -0
  17. package/dist/adapters/claude-code/egress-entry.d.ts +2 -0
  18. package/dist/adapters/claude-code/egress-entry.js +115 -0
  19. package/dist/adapters/claude-code/egress-proxy.d.ts +2 -0
  20. package/dist/adapters/claude-code/egress-proxy.js +60 -0
  21. package/dist/adapters/claude-code/egress.d.ts +114 -0
  22. package/dist/adapters/claude-code/egress.js +276 -0
  23. package/dist/adapters/claude-code/eval-baseline.d.ts +68 -0
  24. package/dist/adapters/claude-code/eval-baseline.js +173 -0
  25. package/dist/{eval-cache.d.ts → adapters/claude-code/eval-cache.d.ts} +1 -1
  26. package/dist/{eval-cache.js → adapters/claude-code/eval-cache.js} +1 -1
  27. package/dist/{eval.d.ts → adapters/claude-code/eval.d.ts} +28 -4
  28. package/dist/{eval.js → adapters/claude-code/eval.js} +61 -25
  29. package/dist/{harness-test.d.ts → adapters/claude-code/harness-test.d.ts} +33 -37
  30. package/dist/{harness-test.js → adapters/claude-code/harness-test.js} +124 -43
  31. package/dist/adapters/claude-code/hook-protocol.d.ts +10 -0
  32. package/dist/adapters/claude-code/hook-protocol.js +10 -0
  33. package/dist/adapters/claude-code/layout.d.ts +8 -0
  34. package/dist/adapters/claude-code/layout.js +18 -0
  35. package/dist/{mock-model.d.ts → adapters/claude-code/mock-model.d.ts} +2 -24
  36. package/dist/adapters/claude-code/model-mock.d.ts +11 -0
  37. package/dist/adapters/claude-code/model-mock.js +10 -0
  38. package/dist/adapters/claude-code/plugin-loader.d.ts +25 -0
  39. package/dist/adapters/claude-code/plugin-loader.js +19 -0
  40. package/dist/adapters/claude-code/run-hook.d.ts +204 -0
  41. package/dist/adapters/claude-code/run-hook.js +418 -0
  42. package/dist/adapters/claude-code/run-scripts.d.ts +52 -0
  43. package/dist/adapters/claude-code/run-scripts.js +150 -0
  44. package/dist/adapters/claude-code/runtime.d.ts +16 -0
  45. package/dist/adapters/claude-code/runtime.js +39 -0
  46. package/dist/{sandbox.d.ts → adapters/claude-code/sandbox.d.ts} +45 -4
  47. package/dist/{sandbox.js → adapters/claude-code/sandbox.js} +76 -8
  48. package/dist/{skill-driver.d.ts → adapters/claude-code/skill-driver.d.ts} +1 -1
  49. package/dist/adapters/codex/adapter.d.ts +3 -0
  50. package/dist/adapters/codex/adapter.js +49 -0
  51. package/dist/adapters/codex/dialect.d.ts +10 -0
  52. package/dist/adapters/codex/dialect.js +30 -0
  53. package/dist/adapters/codex/driver.d.ts +20 -0
  54. package/dist/adapters/codex/driver.js +89 -0
  55. package/dist/adapters/codex/hook-protocol.d.ts +10 -0
  56. package/dist/adapters/codex/hook-protocol.js +18 -0
  57. package/dist/adapters/codex/layout.d.ts +16 -0
  58. package/dist/adapters/codex/layout.js +18 -0
  59. package/dist/adapters/codex/mock-model.d.ts +52 -0
  60. package/dist/adapters/codex/mock-model.js +210 -0
  61. package/dist/adapters/codex/model-mock.d.ts +11 -0
  62. package/dist/adapters/codex/model-mock.js +10 -0
  63. package/dist/adapters/codex/runtime.d.ts +38 -0
  64. package/dist/adapters/codex/runtime.js +62 -0
  65. package/dist/adapters/opencode/adapter.d.ts +3 -0
  66. package/dist/adapters/opencode/adapter.js +48 -0
  67. package/dist/adapters/opencode/dialect.d.ts +10 -0
  68. package/dist/adapters/opencode/dialect.js +36 -0
  69. package/dist/adapters/opencode/layout.d.ts +9 -0
  70. package/dist/adapters/opencode/layout.js +25 -0
  71. package/dist/adapters/opencode/model-mock.d.ts +10 -0
  72. package/dist/adapters/opencode/model-mock.js +10 -0
  73. package/dist/adapters/opencode/runtime.d.ts +9 -0
  74. package/dist/adapters/opencode/runtime.js +21 -0
  75. package/dist/claude-code.d.ts +16 -0
  76. package/dist/claude-code.js +32 -0
  77. package/dist/cli-flags.d.ts +22 -0
  78. package/dist/cli-flags.js +38 -0
  79. package/dist/cli.js +406 -206
  80. package/dist/codex.d.ts +20 -0
  81. package/dist/codex.js +36 -0
  82. package/dist/community-skills.d.ts +1 -1
  83. package/dist/community-skills.js +2 -2
  84. package/dist/core/adapter.d.ts +88 -0
  85. package/dist/core/adapter.js +3 -0
  86. package/dist/{compile.d.ts → core/compile.d.ts} +11 -2
  87. package/dist/{compile.js → core/compile.js} +68 -53
  88. package/dist/core/compose.d.ts +79 -0
  89. package/dist/core/compose.js +145 -0
  90. package/dist/core/dialect.d.ts +51 -0
  91. package/dist/core/dialect.js +3 -0
  92. package/dist/core/harness-driver.d.ts +134 -0
  93. package/dist/core/harness-driver.js +3 -0
  94. package/dist/core/hook-protocol.d.ts +28 -0
  95. package/dist/core/hook-protocol.js +3 -0
  96. package/dist/core/layout.d.ts +43 -0
  97. package/dist/core/layout.js +3 -0
  98. package/dist/core/model-mock.d.ts +27 -0
  99. package/dist/core/model-mock.js +3 -0
  100. package/dist/core/refs.d.ts +62 -0
  101. package/dist/{refs.js → core/refs.js} +49 -23
  102. package/dist/core/runtime.d.ts +38 -0
  103. package/dist/core/runtime.js +3 -0
  104. package/dist/{types.d.ts → core/types.d.ts} +29 -0
  105. package/dist/{validate.d.ts → core/validate.d.ts} +1 -1
  106. package/dist/{validate.js → core/validate.js} +41 -4
  107. package/dist/e2e.d.ts +19 -0
  108. package/dist/e2e.js +39 -0
  109. package/dist/harness-assert.d.ts +60 -11
  110. package/dist/harness-assert.js +111 -9
  111. package/dist/integration.d.ts +16 -0
  112. package/dist/integration.js +32 -0
  113. package/dist/leaderboard.d.ts +33 -0
  114. package/dist/leaderboard.js +107 -0
  115. package/dist/linting.d.ts +9 -0
  116. package/dist/linting.js +25 -0
  117. package/dist/plugin-loader.d.ts +6 -3
  118. package/dist/plugin-loader.js +101 -49
  119. package/dist/scan.d.ts +49 -0
  120. package/dist/scan.js +177 -0
  121. package/dist/setup-plan.d.ts +51 -0
  122. package/dist/setup-plan.js +85 -0
  123. package/dist/skill-test.d.ts +1 -1
  124. package/dist/skill-test.js +1 -1
  125. package/dist/test-coverage.d.ts +71 -0
  126. package/dist/test-coverage.js +228 -0
  127. package/dist/testing.d.ts +12 -0
  128. package/dist/testing.js +28 -0
  129. package/dist/unit.d.ts +17 -0
  130. package/dist/unit.js +36 -0
  131. package/hooks/refs-nudge.sh +24 -0
  132. package/package.json +35 -16
  133. package/skills/audit-feedback-loop/SKILL.md +76 -0
  134. package/skills/edit-spec/SKILL.md +131 -0
  135. package/skills/enforce-rules-format/SKILL.md +71 -0
  136. package/skills/generate-logo/SKILL.md +103 -0
  137. package/skills/generate-rule/SKILL.md +64 -0
  138. package/skills/linter-docs/clippy.md +241 -0
  139. package/skills/linter-docs/eslint.md +384 -0
  140. package/skills/linter-docs/pylint.md +288 -0
  141. package/skills/linter-docs/rubocop.md +277 -0
  142. package/skills/linter-docs/ruff.md +187 -0
  143. package/skills/linter-docs/stylelint.md +247 -0
  144. package/skills/migrate-to-spec/SKILL.md +126 -0
  145. package/skills/pr-to-lint-rule/SKILL.md +97 -0
  146. package/skills/strengthen/SKILL.md +168 -0
  147. package/skills/test-harness/SKILL.md +157 -0
  148. package/dist/action.d.ts +0 -7
  149. package/dist/action.js +0 -180
  150. package/dist/refs.d.ts +0 -44
  151. package/dist/run-hook.d.ts +0 -77
  152. package/dist/run-hook.js +0 -80
  153. package/dist/run-scripts.d.ts +0 -20
  154. package/dist/run-scripts.js +0 -70
  155. /package/dist/{agent-result.js → adapters/claude-code/agent-result.js} +0 -0
  156. /package/dist/{agent-runtime.d.ts → adapters/claude-code/agent-runtime.d.ts} +0 -0
  157. /package/dist/{agent-runtime.js → adapters/claude-code/agent-runtime.js} +0 -0
  158. /package/dist/{judge.d.ts → adapters/claude-code/judge.d.ts} +0 -0
  159. /package/dist/{judge.js → adapters/claude-code/judge.js} +0 -0
  160. /package/dist/{mock-entry.d.ts → adapters/claude-code/mock-entry.d.ts} +0 -0
  161. /package/dist/{mock-entry.js → adapters/claude-code/mock-entry.js} +0 -0
  162. /package/dist/{mock-model.js → adapters/claude-code/mock-model.js} +0 -0
  163. /package/dist/{skill-driver.js → adapters/claude-code/skill-driver.js} +0 -0
  164. /package/dist/{skill-runtime.d.ts → adapters/claude-code/skill-runtime.d.ts} +0 -0
  165. /package/dist/{skill-runtime.js → adapters/claude-code/skill-runtime.js} +0 -0
  166. /package/dist/{stats.d.ts → adapters/claude-code/stats.d.ts} +0 -0
  167. /package/dist/{stats.js → adapters/claude-code/stats.js} +0 -0
  168. /package/dist/{compile-generator.d.ts → core/compile-generator.d.ts} +0 -0
  169. /package/dist/{compile-generator.js → core/compile-generator.js} +0 -0
  170. /package/dist/{coverage.d.ts → core/coverage.d.ts} +0 -0
  171. /package/dist/{coverage.js → core/coverage.js} +0 -0
  172. /package/dist/{doc-refs.d.ts → core/doc-refs.d.ts} +0 -0
  173. /package/dist/{doc-refs.js → core/doc-refs.js} +0 -0
  174. /package/dist/{evolve.d.ts → core/evolve.d.ts} +0 -0
  175. /package/dist/{evolve.js → core/evolve.js} +0 -0
  176. /package/dist/{frontmatter.d.ts → core/frontmatter.d.ts} +0 -0
  177. /package/dist/{frontmatter.js → core/frontmatter.js} +0 -0
  178. /package/dist/{generate-schema.d.ts → core/generate-schema.d.ts} +0 -0
  179. /package/dist/{generate-schema.js → core/generate-schema.js} +0 -0
  180. /package/dist/{generate-types.d.ts → core/generate-types.d.ts} +0 -0
  181. /package/dist/{generate-types.js → core/generate-types.js} +0 -0
  182. /package/dist/{hash.d.ts → core/hash.d.ts} +0 -0
  183. /package/dist/{hash.js → core/hash.js} +0 -0
  184. /package/dist/{inline.d.ts → core/inline.d.ts} +0 -0
  185. /package/dist/{inline.js → core/inline.js} +0 -0
  186. /package/dist/{integrity.d.ts → core/integrity.d.ts} +0 -0
  187. /package/dist/{integrity.js → core/integrity.js} +0 -0
  188. /package/dist/{linters.d.ts → core/linters.d.ts} +0 -0
  189. /package/dist/{linters.js → core/linters.js} +0 -0
  190. /package/dist/{mcp.d.ts → core/mcp.d.ts} +0 -0
  191. /package/dist/{mcp.js → core/mcp.js} +0 -0
  192. /package/dist/{orphans.d.ts → core/orphans.d.ts} +0 -0
  193. /package/dist/{orphans.js → core/orphans.js} +0 -0
  194. /package/dist/{proofs.d.ts → core/proofs.d.ts} +0 -0
  195. /package/dist/{proofs.js → core/proofs.js} +0 -0
  196. /package/dist/{session.d.ts → core/session.d.ts} +0 -0
  197. /package/dist/{session.js → core/session.js} +0 -0
  198. /package/dist/{sidecar.d.ts → core/sidecar.d.ts} +0 -0
  199. /package/dist/{sidecar.js → core/sidecar.js} +0 -0
  200. /package/dist/{spec.d.ts → core/spec.d.ts} +0 -0
  201. /package/dist/{spec.js → core/spec.js} +0 -0
  202. /package/dist/{symbols.d.ts → core/symbols.d.ts} +0 -0
  203. /package/dist/{symbols.js → core/symbols.js} +0 -0
  204. /package/dist/{test-utils.d.ts → core/test-utils.d.ts} +0 -0
  205. /package/dist/{test-utils.js → core/test-utils.js} +0 -0
  206. /package/dist/{types.js → core/types.js} +0 -0
  207. /package/{.claude-plugin/hooks → hooks}/post-edit.sh +0 -0
  208. /package/{.claude-plugin/hooks → hooks}/pre-edit.sh +0 -0
  209. /package/{.claude-plugin/hooks → hooks}/session-start.sh +0 -0
@@ -0,0 +1,210 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.renderResponsesSSE = renderResponsesSSE;
7
+ exports.parseResponsesRequest = parseResponsesRequest;
8
+ exports.startCodexMock = startCodexMock;
9
+ /**
10
+ * codex mock-model — EXPERIMENTAL, internal-only. A scripted, deterministic
11
+ * OpenAI **Responses API** mock that real `codex` completes a turn against.
12
+ *
13
+ * Codex speaks the Responses API: a turn-consuming request hits
14
+ * `POST /v1/responses` with `Accept: text/event-stream`, and the mock answers
15
+ * with the proven `response.created → … → response.completed` SSE sequence that
16
+ * makes codex emit one assistant text message. There is no count-tokens
17
+ * endpoint. This is the Codex-side analogue of the Anthropic Messages mock in
18
+ * `src/adapters/claude-code/mock-model.ts` (`startMock`).
19
+ *
20
+ * The wire format here is NOT guessed — it is PROVEN end-to-end against real
21
+ * `codex` (codex-cli 0.139.0) via the `-c model_providers.mock.*` recipe in
22
+ * `src/adapters/codex/runtime.ts` (`codexMockArgs`/`codexMockEnv`).
23
+ */
24
+ const node_http_1 = __importDefault(require("node:http"));
25
+ const MSG_ID = "msg_mock_1";
26
+ const RESP_ID = "resp_mock_1";
27
+ /**
28
+ * Render the PROVEN OpenAI-Responses SSE event sequence for a single assistant
29
+ * text message — `response.created` through `response.completed`. This exact
30
+ * sequence is confirmed to make real `codex` complete a turn. Pure and exported
31
+ * so the renderer is testable without the HTTP server.
32
+ */
33
+ function renderResponsesSSE(text, opts = {}) {
34
+ const model = opts.model ?? "gpt-5-codex";
35
+ const response = (status, output) => ({
36
+ id: RESP_ID,
37
+ object: "response",
38
+ status,
39
+ model,
40
+ output,
41
+ usage: null,
42
+ });
43
+ const completedItem = {
44
+ type: "message",
45
+ id: MSG_ID,
46
+ status: "completed",
47
+ role: "assistant",
48
+ content: [{ type: "output_text", text }],
49
+ };
50
+ const events = [
51
+ {
52
+ type: "response.created",
53
+ data: { response: response("in_progress", []) },
54
+ },
55
+ {
56
+ type: "response.in_progress",
57
+ data: { response: response("in_progress", []) },
58
+ },
59
+ {
60
+ type: "response.output_item.added",
61
+ data: {
62
+ output_index: 0,
63
+ item: {
64
+ type: "message",
65
+ id: MSG_ID,
66
+ status: "in_progress",
67
+ role: "assistant",
68
+ content: [],
69
+ },
70
+ },
71
+ },
72
+ {
73
+ type: "response.content_part.added",
74
+ data: {
75
+ item_id: MSG_ID,
76
+ output_index: 0,
77
+ content_index: 0,
78
+ part: { type: "output_text", text: "" },
79
+ },
80
+ },
81
+ {
82
+ type: "response.output_text.delta",
83
+ data: { item_id: MSG_ID, output_index: 0, content_index: 0, delta: text },
84
+ },
85
+ {
86
+ type: "response.output_text.done",
87
+ data: { item_id: MSG_ID, output_index: 0, content_index: 0, text },
88
+ },
89
+ {
90
+ type: "response.content_part.done",
91
+ data: {
92
+ item_id: MSG_ID,
93
+ output_index: 0,
94
+ content_index: 0,
95
+ part: { type: "output_text", text },
96
+ },
97
+ },
98
+ {
99
+ type: "response.output_item.done",
100
+ data: { output_index: 0, item: completedItem },
101
+ },
102
+ {
103
+ type: "response.completed",
104
+ data: { response: response("completed", [completedItem]) },
105
+ },
106
+ ];
107
+ return events
108
+ .map((e) => `event: ${e.type}\n` +
109
+ `data: ${JSON.stringify({ type: e.type, ...e.data })}\n\n`)
110
+ .join("");
111
+ }
112
+ function joinInputText(content) {
113
+ if (!Array.isArray(content))
114
+ return "";
115
+ return content
116
+ .map((c) => {
117
+ const t = c.text;
118
+ return typeof t === "string" ? t : "";
119
+ })
120
+ .join("");
121
+ }
122
+ /**
123
+ * Parse a Responses request body — the user's prompt (the LAST `input` item
124
+ * with `role:"user"`, joining its `content[].text`), the requested `model`, and
125
+ * the declared function-tool names. Tolerates malformed JSON (returns an empty
126
+ * prompt). Pure and exported so request capture is testable without the server.
127
+ */
128
+ function parseResponsesRequest(body) {
129
+ let parsed = {};
130
+ try {
131
+ parsed = JSON.parse(body);
132
+ }
133
+ catch {
134
+ return { prompt: "", model: "", toolNames: [] };
135
+ }
136
+ const input = Array.isArray(parsed.input)
137
+ ? parsed.input
138
+ : [];
139
+ const lastUser = [...input]
140
+ .reverse()
141
+ .find((item) => item.role === "user" && item.type === "message");
142
+ const prompt = lastUser ? joinInputText(lastUser.content) : "";
143
+ const model = typeof parsed.model === "string" ? parsed.model : "";
144
+ const toolNames = Array.isArray(parsed.tools)
145
+ ? parsed.tools
146
+ .map((t) => {
147
+ const tool = t;
148
+ if (typeof tool.name === "string")
149
+ return tool.name;
150
+ const fnName = tool.function?.name;
151
+ return typeof fnName === "string" ? fnName : "";
152
+ })
153
+ .filter((n) => n.length > 0)
154
+ : [];
155
+ return { prompt, model, toolNames };
156
+ }
157
+ /**
158
+ * Start the scripted Codex Responses mock on a free port. Each
159
+ * `POST /v1/responses` consumes the next scripted turn (the last turn repeats if
160
+ * codex asks for more); HEAD and any other path get `{}`. Resolves to a handle
161
+ * with the base `url`, the `port`, the recorded `requests`, and `close()`.
162
+ */
163
+ function startCodexMock(script, opts = {}) {
164
+ let i = 0;
165
+ const requests = [];
166
+ const server = node_http_1.default.createServer((req, res) => {
167
+ let body = "";
168
+ req.on("data", (c) => (body += c));
169
+ req.on("end", () => {
170
+ const url = req.url ?? "";
171
+ const isResponses = req.method === "POST" && url.includes("/v1/responses");
172
+ if (!isResponses) {
173
+ res.writeHead(200, { "content-type": "application/json" });
174
+ res.end("{}");
175
+ return;
176
+ }
177
+ const parsed = parseResponsesRequest(body);
178
+ requests.push(parsed);
179
+ opts.onRequest?.(parsed);
180
+ const turn = script[Math.min(i, script.length - 1)] ?? { text: "" };
181
+ i++;
182
+ const model = parsed.model || "gpt-5-codex";
183
+ res.writeHead(200, {
184
+ "content-type": "text/event-stream",
185
+ "cache-control": "no-cache",
186
+ connection: "keep-alive",
187
+ });
188
+ res.write(renderResponsesSSE(turn.text, { model }));
189
+ res.end();
190
+ });
191
+ });
192
+ return new Promise((resolve) => {
193
+ server.listen(0, "127.0.0.1", () => {
194
+ const { port } = server.address();
195
+ resolve({
196
+ url: `http://127.0.0.1:${String(port)}`,
197
+ port,
198
+ get requests() {
199
+ return requests;
200
+ },
201
+ close: () => new Promise((r) => {
202
+ server.close(() => {
203
+ r();
204
+ });
205
+ }),
206
+ });
207
+ });
208
+ });
209
+ }
210
+ //# sourceMappingURL=mock-model.js.map
@@ -0,0 +1,11 @@
1
+ /**
2
+ * codexModelMock — EXPERIMENTAL, internal-only. Codex speaks the OpenAI
3
+ * **Responses** API: a turn-consuming request hits `/v1/responses`, and there is
4
+ * no count-tokens endpoint. Finding: the `ModelMock` *descriptor* captures the
5
+ * wire facts cleanly; the SSE *renderer* (the `response.created → … →
6
+ * response.completed` event sequence + a Responses request-parser) is the
7
+ * deferred piece — built with the Codex transport tier, not declared here.
8
+ */
9
+ import type { ModelMock } from "../../core/model-mock.js";
10
+ export declare const codexModelMock: ModelMock;
11
+ //# sourceMappingURL=model-mock.d.ts.map
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.codexModelMock = void 0;
4
+ exports.codexModelMock = {
5
+ name: "codex",
6
+ wireApi: "openai-responses",
7
+ modelEndpoint: "/v1/responses",
8
+ // No count-tokens endpoint (countTokensEndpoint omitted).
9
+ };
10
+ //# sourceMappingURL=model-mock.js.map
@@ -0,0 +1,38 @@
1
+ /**
2
+ * codexRuntime — EXPERIMENTAL, internal-only. A prototype `HarnessRuntime` for
3
+ * Codex: spawn `codex`, and point it at a no-key mock.
4
+ *
5
+ * PROVEN wiring (validated against real codex-cli 0.139.0): the clean keyless
6
+ * route is NOT the built-in `OPENAI_BASE_URL` override the prototype guessed
7
+ * (the docs called that "messy") — it is a `[model_providers.mock]` provider
8
+ * defined inline via `-c` flags on `codex exec`. `codexMockArgs(baseUrl)`
9
+ * returns that flag array (the `wireMock` recipe as data) and `codexMockEnv()`
10
+ * returns the dummy-key env codex reads through it. So "point at the mock" is a
11
+ * flag-based *operation* here, not a single env var.
12
+ *
13
+ * The `HarnessRuntime` port still requires `modelBaseUrlEnv`/`modelApiKeyEnv`
14
+ * (the env-var transport axis), so we keep valid values for conformance — but
15
+ * codex's real wiring is the flag-based recipe below, not those env vars. The
16
+ * port's `wireMock(baseUrl)` surfaces that recipe as `{ args, env }` so the
17
+ * generalized `runHarnessTest` runner drives codex the same way it drives
18
+ * Claude Code; `codexMockArgs`/`codexMockEnv` remain exported (used by
19
+ * `wireMock` and by `mock-model.test.ts`).
20
+ */
21
+ import type { HarnessRuntime } from "../../core/runtime.js";
22
+ export declare const codexRuntime: HarnessRuntime;
23
+ /**
24
+ * The PROVEN `-c` flag array that points `codex exec` at a mock served at
25
+ * `baseUrl` (e.g. `http://127.0.0.1:PORT`) over the Responses wire API, keyless.
26
+ * Defines a `[model_providers.mock]` provider inline and selects it as the
27
+ * active model provider. `baseUrl` is suffixed with `/v1` (codex appends
28
+ * `/responses`). Combine with `codexMockEnv()` and the `codex exec` flags
29
+ * `--ignore-user-config --skip-git-repo-check --ephemeral
30
+ * --dangerously-bypass-approvals-and-sandbox -c model="gpt-5-codex"`.
31
+ */
32
+ export declare function codexMockArgs(baseUrl: string): string[];
33
+ /**
34
+ * The dummy-key env codex reads `model_providers.mock.env_key` through. Codex
35
+ * sends `Authorization: Bearer dummy-key`; the mock ignores it.
36
+ */
37
+ export declare function codexMockEnv(): Record<string, string>;
38
+ //# sourceMappingURL=runtime.d.ts.map
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.codexRuntime = void 0;
4
+ exports.codexMockArgs = codexMockArgs;
5
+ exports.codexMockEnv = codexMockEnv;
6
+ exports.codexRuntime = {
7
+ name: "codex",
8
+ agentBinary: "codex",
9
+ // Kept non-empty for HarnessRuntime conformance (the env-var transport axis).
10
+ // Codex's PROVEN keyless wiring is the flag-based codexMockArgs recipe, not
11
+ // this built-in-provider override.
12
+ modelBaseUrlEnv: "OPENAI_BASE_URL",
13
+ modelApiKeyEnv: "MOCK_KEY",
14
+ mockApiKey: "dummy-key",
15
+ /**
16
+ * Codex reaches the mock through the PROVEN keyless flag recipe (the
17
+ * `-c model_providers.mock.*` array), NOT a single base-URL env var. So
18
+ * `wireMock` carries args (the flags) AND env (the dummy key codex reads
19
+ * `model_providers.mock.env_key` through). The `wireMock` method unifies both
20
+ * transport axes (CC's env-only, Codex's flags) behind one call.
21
+ */
22
+ wireMock(baseUrl) {
23
+ return { args: codexMockArgs(baseUrl), env: codexMockEnv() };
24
+ },
25
+ };
26
+ /**
27
+ * The PROVEN `-c` flag array that points `codex exec` at a mock served at
28
+ * `baseUrl` (e.g. `http://127.0.0.1:PORT`) over the Responses wire API, keyless.
29
+ * Defines a `[model_providers.mock]` provider inline and selects it as the
30
+ * active model provider. `baseUrl` is suffixed with `/v1` (codex appends
31
+ * `/responses`). Combine with `codexMockEnv()` and the `codex exec` flags
32
+ * `--ignore-user-config --skip-git-repo-check --ephemeral
33
+ * --dangerously-bypass-approvals-and-sandbox -c model="gpt-5-codex"`.
34
+ */
35
+ function codexMockArgs(baseUrl) {
36
+ return [
37
+ "-c",
38
+ "model_provider=mock",
39
+ "-c",
40
+ 'model_providers.mock.name="mock"',
41
+ "-c",
42
+ `model_providers.mock.base_url="${baseUrl}/v1"`,
43
+ "-c",
44
+ 'model_providers.mock.wire_api="responses"',
45
+ "-c",
46
+ 'model_providers.mock.env_key="MOCK_KEY"',
47
+ "-c",
48
+ "model_providers.mock.requires_openai_auth=false",
49
+ "-c",
50
+ "model_providers.mock.request_max_retries=0",
51
+ "-c",
52
+ "model_providers.mock.stream_max_retries=0",
53
+ ];
54
+ }
55
+ /**
56
+ * The dummy-key env codex reads `model_providers.mock.env_key` through. Codex
57
+ * sends `Authorization: Bearer dummy-key`; the mock ignores it.
58
+ */
59
+ function codexMockEnv() {
60
+ return { MOCK_KEY: "dummy-key" };
61
+ }
62
+ //# sourceMappingURL=runtime.js.map
@@ -0,0 +1,3 @@
1
+ import type { HarnessAdapter } from "../../core/adapter.js";
2
+ export declare const opencodeAdapter: HarnessAdapter;
3
+ //# sourceMappingURL=adapter.d.ts.map
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.opencodeAdapter = void 0;
4
+ /**
5
+ * opencodeAdapter — EXPERIMENTAL, internal-only prototype `HarnessAdapter`. It
6
+ * exists to PROVE the kit generalizes to the optional-transport-port shape: a
7
+ * harness that does pillar 1 AND is mockable (openai-compatible) BUT whose hooks
8
+ * are in-process JS/TS plugin modules, not shell processes. So it declares
9
+ * `shellHooks: false`, ships NO `hookProtocol`, and the conformance kit must
10
+ * accept it without demanding a fake one. This is the pillar-1-+-mockable-but-
11
+ * no-shell-hooks shape the capability gating was built for.
12
+ *
13
+ * It is deliberately NOT registered in `src/adapter-registry.ts` and NOT exported
14
+ * from any `vigiles/*` subpath, so the CLI never auto-detects OpenCode and
15
+ * consumers can't import it. Promote it (register + `vigiles/opencode` export +
16
+ * the deferred transport renderers) only when OpenCode support actually ships.
17
+ */
18
+ const node_fs_1 = require("node:fs");
19
+ const node_path_1 = require("node:path");
20
+ const dialect_js_1 = require("./dialect.js");
21
+ const layout_js_1 = require("./layout.js");
22
+ const runtime_js_1 = require("./runtime.js");
23
+ const model_mock_js_1 = require("./model-mock.js");
24
+ exports.opencodeAdapter = {
25
+ name: "opencode",
26
+ // Pillar 1 + mockable (openai-chat SSE), but hooks are in-process JS/TS plugin
27
+ // modules — no shell-hook tier, hence shellHooks:false and NO hookProtocol.
28
+ capabilities: {
29
+ referenceVerification: true,
30
+ harnessTesting: true,
31
+ shellHooks: false,
32
+ },
33
+ dialect: dialect_js_1.opencodeDialect,
34
+ layout: layout_js_1.opencodeLayout,
35
+ runtime: runtime_js_1.opencodeRuntime,
36
+ modelMock: model_mock_js_1.opencodeModelMock,
37
+ // No hookProtocol: OpenCode hooks are code modules, not shell processes.
38
+ detect(root) {
39
+ // An `opencode.json` is a strong signal; a bare AGENTS.md is weak (many
40
+ // harnesses read it). (Unused while unregistered — kept for symmetry.)
41
+ if ((0, node_fs_1.existsSync)((0, node_path_1.join)(root, "opencode.json")))
42
+ return 3;
43
+ if ((0, node_fs_1.existsSync)((0, node_path_1.join)(root, layout_js_1.opencodeLayout.instructionFile)))
44
+ return 1;
45
+ return 0;
46
+ },
47
+ };
48
+ //# sourceMappingURL=adapter.js.map
@@ -0,0 +1,10 @@
1
+ /**
2
+ * opencodeDialect — EXPERIMENTAL, internal-only. A prototype `HarnessDialect` for
3
+ * OpenCode, built to validate that the format axis generalizes to a harness whose
4
+ * hooks are in-process JS/TS plugin modules rather than shell processes. NOT
5
+ * exported from `vigiles/*` and NOT registered in the adapter registry — it exists
6
+ * to be run through the conformance kit + real OpenCode-shaped fixtures.
7
+ */
8
+ import type { HarnessDialect } from "../../core/dialect.js";
9
+ export declare const opencodeDialect: HarnessDialect;
10
+ //# sourceMappingURL=dialect.d.ts.map
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.opencodeDialect = void 0;
4
+ exports.opencodeDialect = {
5
+ name: "opencode",
6
+ // OpenCode's lowercase built-in tool catalog (file/shell/search + task).
7
+ builtinAgentTools: [
8
+ "bash",
9
+ "edit",
10
+ "read",
11
+ "write",
12
+ "grep",
13
+ "glob",
14
+ "list",
15
+ "webfetch",
16
+ "task",
17
+ ],
18
+ // No documented "never available to a subagent" set — left empty.
19
+ neverAvailableTools: [],
20
+ mcpToolPattern: /^mcp__[a-z0-9_-]+__[a-z0-9_-]+$/i,
21
+ // OpenCode's event-bus names, NOT shell hook events: a plugin module subscribes
22
+ // to these in-process (no exit-code/env wire protocol → shellHooks:false).
23
+ hookEvents: [
24
+ "session.start",
25
+ "tool.execute.before",
26
+ "tool.execute.after",
27
+ "session.idle",
28
+ ],
29
+ // AGENTS.md native + CLAUDE.md fallback.
30
+ instructionTargets: ["AGENTS.md", "CLAUDE.md"],
31
+ pluginRootToken: "${OPENCODE_PLUGIN_ROOT}",
32
+ // OpenCode reads the minimal cross-tool SKILL.md frontmatter (name +
33
+ // description); the CC-only keys are not part of its format.
34
+ skillFrontmatter: "minimal",
35
+ };
36
+ //# sourceMappingURL=dialect.js.map
@@ -0,0 +1,9 @@
1
+ /**
2
+ * opencodeLayout — EXPERIMENTAL, internal-only. A prototype `PluginLayout` for
3
+ * OpenCode: `opencode.json` manifest/settings, `AGENTS.md`, `.opencode/`
4
+ * surfaces, `${OPENCODE_PLUGIN_ROOT}`. Validates the layout port against real
5
+ * OpenCode shapes. NOT exported / NOT registered.
6
+ */
7
+ import type { PluginLayout } from "../../core/layout.js";
8
+ export declare const opencodeLayout: PluginLayout;
9
+ //# sourceMappingURL=layout.d.ts.map
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.opencodeLayout = void 0;
4
+ exports.opencodeLayout = {
5
+ name: "opencode",
6
+ manifestPath: "opencode.json",
7
+ // Vestigial: OpenCode hooks are JS plugin modules under `.opencode/plugin`, not
8
+ // shell-hook settings, so the shell-hook settings round-trip does NOT apply here
9
+ // (the adapter declares shellHooks:false; assertAdapterLoadsHooks is skipped).
10
+ hooksConventionPath: ".opencode/plugin",
11
+ settingsPath: "opencode.json",
12
+ settingsFormat: "json",
13
+ instructionFile: "AGENTS.md",
14
+ // OpenCode's surfaces already live UNDER `.opencode/` at the source, so they
15
+ // are NOT relocated — materializeRoot is "" (no prefix) to avoid doubling the
16
+ // `.opencode/` segment. (Contrast Claude Code: root-level `skills/` surfaces
17
+ // relocated under `.claude`.)
18
+ surfaceDirs: [".opencode/agent", ".opencode/command"],
19
+ materializeRoot: "",
20
+ pluginRootToken: "${OPENCODE_PLUGIN_ROOT}",
21
+ mcpConfigFile: "opencode.json",
22
+ mcpManifestKey: "mcp",
23
+ intraRefDirs: [".opencode/agent", ".opencode/command"],
24
+ };
25
+ //# sourceMappingURL=layout.js.map
@@ -0,0 +1,10 @@
1
+ /**
2
+ * opencodeModelMock — EXPERIMENTAL, internal-only. OpenCode is OpenAI-compatible
3
+ * and speaks the OpenAI **Chat Completions** API: a turn-consuming request hits
4
+ * `/v1/chat/completions`, with no separate count-tokens endpoint. The descriptor
5
+ * captures the wire facts; the SSE renderer is the deferred piece (built with the
6
+ * OpenCode transport tier, not declared here). NOT exported / NOT registered.
7
+ */
8
+ import type { ModelMock } from "../../core/model-mock.js";
9
+ export declare const opencodeModelMock: ModelMock;
10
+ //# sourceMappingURL=model-mock.d.ts.map
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.opencodeModelMock = void 0;
4
+ exports.opencodeModelMock = {
5
+ name: "opencode",
6
+ wireApi: "openai-chat",
7
+ modelEndpoint: "/v1/chat/completions",
8
+ // No count-tokens endpoint (countTokensEndpoint omitted).
9
+ };
10
+ //# sourceMappingURL=model-mock.js.map
@@ -0,0 +1,9 @@
1
+ /**
2
+ * opencodeRuntime — EXPERIMENTAL, internal-only. A prototype `HarnessRuntime` for
3
+ * OpenCode: spawn `opencode`, reach a mock via the OpenAI-compatible base-URL env.
4
+ * OpenCode is BYOM/openai-compatible, so the env-var "point at the mock" route
5
+ * fits cleanly. NOT exported / NOT registered.
6
+ */
7
+ import type { HarnessRuntime } from "../../core/runtime.js";
8
+ export declare const opencodeRuntime: HarnessRuntime;
9
+ //# sourceMappingURL=runtime.d.ts.map
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.opencodeRuntime = void 0;
4
+ exports.opencodeRuntime = {
5
+ name: "opencode",
6
+ agentBinary: "opencode",
7
+ modelBaseUrlEnv: "OPENAI_BASE_URL",
8
+ modelApiKeyEnv: "OPENAI_API_KEY",
9
+ mockApiKey: "sk-mock-opencode",
10
+ /** Env-only (OpenAI-compatible base-URL override), like Claude Code. */
11
+ wireMock(baseUrl) {
12
+ return {
13
+ args: [],
14
+ env: {
15
+ [exports.opencodeRuntime.modelBaseUrlEnv]: baseUrl,
16
+ [exports.opencodeRuntime.modelApiKeyEnv]: exports.opencodeRuntime.mockApiKey,
17
+ },
18
+ };
19
+ },
20
+ };
21
+ //# sourceMappingURL=runtime.js.map
@@ -0,0 +1,16 @@
1
+ /**
2
+ * `vigiles/claude-code` — the Claude Code-specific harness pieces a *different*
3
+ * harness would swap out: the plugin/repo loader (reads real Claude Code plugin
4
+ * layouts) and the scriptable Anthropic Messages mock. Split from
5
+ * `vigiles/testing` on purpose — the test API above is the stable surface; this
6
+ * is the adapter, so a future `vigiles/<other-harness>` can sit beside it.
7
+ */
8
+ export * from "./adapters/claude-code/plugin-loader.js";
9
+ export * from "./adapters/claude-code/mock-model.js";
10
+ export * from "./adapters/claude-code/dialect.js";
11
+ export * from "./adapters/claude-code/layout.js";
12
+ export * from "./adapters/claude-code/runtime.js";
13
+ export * from "./adapters/claude-code/hook-protocol.js";
14
+ export * from "./adapters/claude-code/model-mock.js";
15
+ export * from "./adapters/claude-code/adapter.js";
16
+ //# sourceMappingURL=claude-code.d.ts.map
@@ -0,0 +1,32 @@
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/claude-code` — the Claude Code-specific harness pieces a *different*
19
+ * harness would swap out: the plugin/repo loader (reads real Claude Code plugin
20
+ * layouts) and the scriptable Anthropic Messages mock. Split from
21
+ * `vigiles/testing` on purpose — the test API above is the stable surface; this
22
+ * is the adapter, so a future `vigiles/<other-harness>` can sit beside it.
23
+ */
24
+ __exportStar(require("./adapters/claude-code/plugin-loader.js"), exports);
25
+ __exportStar(require("./adapters/claude-code/mock-model.js"), exports);
26
+ __exportStar(require("./adapters/claude-code/dialect.js"), exports);
27
+ __exportStar(require("./adapters/claude-code/layout.js"), exports);
28
+ __exportStar(require("./adapters/claude-code/runtime.js"), exports);
29
+ __exportStar(require("./adapters/claude-code/hook-protocol.js"), exports);
30
+ __exportStar(require("./adapters/claude-code/model-mock.js"), exports);
31
+ __exportStar(require("./adapters/claude-code/adapter.js"), exports);
32
+ //# sourceMappingURL=claude-code.js.map
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Command-line config overrides.
3
+ *
4
+ * The GitHub Action is a thin composite over this CLI, so every Action
5
+ * input must map to a real CLI flag (no config-file-only knobs the Action
6
+ * can't reach — see the `prod-grade-gha-cli` rule). This module turns the
7
+ * shared flags into `VigilesConfig` overrides on top of the loaded config.
8
+ *
9
+ * Pure and exported for unit testing.
10
+ */
11
+ import type { VigilesConfig } from "./core/types.js";
12
+ /**
13
+ * Apply shared command-line overrides to a loaded config.
14
+ *
15
+ * --max-rules=<n> → config.maxRules (positive integer; ignored otherwise)
16
+ * --catalog-only → config.catalogOnly = true
17
+ *
18
+ * Unknown flags are left untouched (each command parses its own besides
19
+ * these). Returns a new object; the input is not mutated.
20
+ */
21
+ export declare function applyConfigFlags(config: VigilesConfig, args: readonly string[]): VigilesConfig;
22
+ //# sourceMappingURL=cli-flags.d.ts.map
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ /**
3
+ * Command-line config overrides.
4
+ *
5
+ * The GitHub Action is a thin composite over this CLI, so every Action
6
+ * input must map to a real CLI flag (no config-file-only knobs the Action
7
+ * can't reach — see the `prod-grade-gha-cli` rule). This module turns the
8
+ * shared flags into `VigilesConfig` overrides on top of the loaded config.
9
+ *
10
+ * Pure and exported for unit testing.
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.applyConfigFlags = applyConfigFlags;
14
+ const MAX_RULES = "--max-rules=";
15
+ /**
16
+ * Apply shared command-line overrides to a loaded config.
17
+ *
18
+ * --max-rules=<n> → config.maxRules (positive integer; ignored otherwise)
19
+ * --catalog-only → config.catalogOnly = true
20
+ *
21
+ * Unknown flags are left untouched (each command parses its own besides
22
+ * these). Returns a new object; the input is not mutated.
23
+ */
24
+ function applyConfigFlags(config, args) {
25
+ const next = { ...config };
26
+ const maxRulesFlag = args.find((a) => a.startsWith(MAX_RULES));
27
+ if (maxRulesFlag) {
28
+ const n = Number(maxRulesFlag.slice(MAX_RULES.length));
29
+ if (Number.isInteger(n) && n > 0) {
30
+ next.maxRules = n;
31
+ }
32
+ }
33
+ if (args.includes("--catalog-only")) {
34
+ next.catalogOnly = true;
35
+ }
36
+ return next;
37
+ }
38
+ //# sourceMappingURL=cli-flags.js.map