@alis-build/harness-eval 0.1.2 → 0.1.3

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 (37) hide show
  1. package/README.md +92 -8
  2. package/dist/adapters/claude-code/index.d.ts +2 -2
  3. package/dist/adapters/claude-code/index.js +2 -1
  4. package/dist/adapters/codex/index.d.ts +68 -0
  5. package/dist/adapters/codex/index.js +3 -0
  6. package/dist/{claude-code-DZ4Vkgp6.js → claude-code-C_7hxC8z.js} +3 -245
  7. package/dist/claude-code-C_7hxC8z.js.map +1 -0
  8. package/dist/cli/bin.js +131 -151
  9. package/dist/cli/bin.js.map +1 -1
  10. package/dist/codex-0cHO2te9.js +496 -0
  11. package/dist/codex-0cHO2te9.js.map +1 -0
  12. package/dist/config/loader.d.ts +2 -2
  13. package/dist/config/loader.js +2 -2
  14. package/dist/{index-V22PrR0p.d.ts → index-DnvP1UBl.d.ts} +2 -2
  15. package/dist/index.d.ts +132 -6
  16. package/dist/index.js +6 -5
  17. package/dist/index.js.map +1 -1
  18. package/dist/loader-B1WmGGzf.d.ts +107 -0
  19. package/dist/{loader-DcI0KfRX.js → loader-DnQ6Jt0i.js} +472 -209
  20. package/dist/loader-DnQ6Jt0i.js.map +1 -0
  21. package/dist/{projections-BcX7w-f6.js → reporter-Biy-5-9M.js} +1335 -758
  22. package/dist/reporter-Biy-5-9M.js.map +1 -0
  23. package/dist/runner/suite.d.ts +1 -1
  24. package/dist/runner/suite.js +1 -1
  25. package/dist/{suite-DPJMIEbu.d.ts → suite-BEShV0by.d.ts} +2 -2
  26. package/dist/{suite-Dlzl-HI0.js → suite-BcP64nlb.js} +16 -2
  27. package/dist/{suite-Dlzl-HI0.js.map → suite-BcP64nlb.js.map} +1 -1
  28. package/dist/{types-CD3TwOtZ.d.ts → types-0QkNVyp9.d.ts} +2 -2
  29. package/dist/types-Bac8_Ixb.js +246 -0
  30. package/dist/types-Bac8_Ixb.js.map +1 -0
  31. package/dist/types-Bu8uOZZN.d.ts +77 -0
  32. package/dist/{types-B9H4IZtA.d.ts → types-C0gBkl0-.d.ts} +3 -2
  33. package/package.json +6 -2
  34. package/dist/claude-code-DZ4Vkgp6.js.map +0 -1
  35. package/dist/loader-C9yQHUPC.d.ts +0 -50
  36. package/dist/loader-DcI0KfRX.js.map +0 -1
  37. package/dist/projections-BcX7w-f6.js.map +0 -1
@@ -0,0 +1,496 @@
1
+ import { n as TrajectoryBuilder, t as AdapterError } from "./types-Bac8_Ixb.js";
2
+ import { spawn } from "node:child_process";
3
+ import { mkdtemp, readFile, rm } from "node:fs/promises";
4
+ import { tmpdir } from "node:os";
5
+ import { join } from "node:path";
6
+ import { randomUUID } from "node:crypto";
7
+ //#region src/adapters/codex/map-events.ts
8
+ /** Stateful mapper — tracks session id and pending tool calls across the stream. */
9
+ var CodexEventMapper = class {
10
+ sessionId = "codex-session";
11
+ sawInit = false;
12
+ startedItems = /* @__PURE__ */ new Set();
13
+ turnCount = 0;
14
+ /** Map one parsed Codex JSON object to zero or more stream events. */
15
+ map(event) {
16
+ const type = event.type;
17
+ if (!type) return [];
18
+ switch (type) {
19
+ case "thread.started": return [this.buildInit(event.thread_id ?? this.sessionId)];
20
+ case "item.started": return event.item ? this.mapItemStarted(event.item) : [];
21
+ case "item.completed": return event.item ? this.mapItemCompleted(event.item) : [];
22
+ case "turn.completed":
23
+ this.turnCount++;
24
+ return [this.buildResult(false, event.usage)];
25
+ case "turn.failed":
26
+ this.turnCount++;
27
+ return [this.buildResult(true, event.usage, event.message)];
28
+ default: return [];
29
+ }
30
+ }
31
+ buildInit(sessionId) {
32
+ this.sessionId = sessionId;
33
+ this.sawInit = true;
34
+ return {
35
+ type: "system",
36
+ subtype: "init",
37
+ session_id: sessionId,
38
+ cwd: "",
39
+ model: "",
40
+ tools: [],
41
+ mcp_servers: []
42
+ };
43
+ }
44
+ ensureInit() {
45
+ if (this.sawInit) return [];
46
+ return [this.buildInit(this.sessionId)];
47
+ }
48
+ mapItemStarted(item) {
49
+ const itemType = itemTypeOf(item);
50
+ if (itemType === "mcp_tool_call" || itemType === "command_execution") {
51
+ if (item.id) this.startedItems.add(item.id);
52
+ return [...this.ensureInit(), itemType === "mcp_tool_call" ? this.toolUseEvent(item) : this.commandUseEvent(item)];
53
+ }
54
+ return this.ensureInit();
55
+ }
56
+ mapItemCompleted(item) {
57
+ const itemType = itemTypeOf(item);
58
+ const prefix = this.ensureInit();
59
+ const id = item.id ?? "";
60
+ if (itemType === "mcp_tool_call") {
61
+ const events = [...prefix];
62
+ if (!this.startedItems.has(id)) events.push(this.toolUseEvent(item));
63
+ else this.startedItems.delete(id);
64
+ events.push(this.toolResultEvent(item));
65
+ return events;
66
+ }
67
+ if (itemType === "command_execution") {
68
+ const events = [...prefix];
69
+ if (!this.startedItems.has(id)) events.push(this.commandUseEvent(item));
70
+ else this.startedItems.delete(id);
71
+ events.push(this.toolResultEvent(item, "Bash"));
72
+ return events;
73
+ }
74
+ if (itemType === "assistant_message" && item.text) return [...prefix, {
75
+ type: "assistant",
76
+ session_id: this.sessionId,
77
+ message: {
78
+ id: item.id ?? `msg_${id}`,
79
+ type: "message",
80
+ role: "assistant",
81
+ content: [{
82
+ type: "text",
83
+ text: item.text
84
+ }],
85
+ stop_reason: "end_turn"
86
+ }
87
+ }];
88
+ return prefix;
89
+ }
90
+ toolUseEvent(item) {
91
+ const id = item.id ?? `item_${Math.random().toString(36).slice(2)}`;
92
+ const name = mcpToolName(item.server ?? "unknown", item.tool ?? "unknown");
93
+ return {
94
+ type: "assistant",
95
+ session_id: this.sessionId,
96
+ message: {
97
+ id: `assistant_${id}`,
98
+ type: "message",
99
+ role: "assistant",
100
+ content: [{
101
+ type: "tool_use",
102
+ id,
103
+ name,
104
+ input: item.arguments ?? {}
105
+ }],
106
+ stop_reason: "tool_use"
107
+ }
108
+ };
109
+ }
110
+ commandUseEvent(item) {
111
+ const id = item.id ?? `item_${Math.random().toString(36).slice(2)}`;
112
+ return {
113
+ type: "assistant",
114
+ session_id: this.sessionId,
115
+ message: {
116
+ id: `assistant_${id}`,
117
+ type: "message",
118
+ role: "assistant",
119
+ content: [{
120
+ type: "tool_use",
121
+ id,
122
+ name: "Bash",
123
+ input: { command: item.command ?? "" }
124
+ }],
125
+ stop_reason: "tool_use"
126
+ }
127
+ };
128
+ }
129
+ toolResultEvent(item, toolName) {
130
+ const id = item.id ?? "";
131
+ const isError = item.status === "failed" || item.error != null;
132
+ const content = toolName === "Bash" ? formatCommandResult(item) : formatMcpResult(item.result, item.error);
133
+ return {
134
+ type: "user",
135
+ session_id: this.sessionId,
136
+ message: {
137
+ role: "user",
138
+ content: [{
139
+ type: "tool_result",
140
+ tool_use_id: id,
141
+ content,
142
+ is_error: isError
143
+ }]
144
+ }
145
+ };
146
+ }
147
+ buildResult(isError, usage, message) {
148
+ return {
149
+ type: "result",
150
+ subtype: isError ? "error" : "success",
151
+ session_id: this.sessionId,
152
+ is_error: isError,
153
+ result: message ?? "",
154
+ usage: mapUsage(usage),
155
+ total_cost_usd: 0,
156
+ duration_ms: 0,
157
+ num_turns: this.turnCount
158
+ };
159
+ }
160
+ };
161
+ /** Map an entire fixture or stream of Codex events through a fresh mapper. */
162
+ function mapCodexEvents(events) {
163
+ const mapper = new CodexEventMapper();
164
+ const out = [];
165
+ for (const event of events) out.push(...mapper.map(event));
166
+ return out;
167
+ }
168
+ /** Build harness-qualified MCP tool name from Codex server + tool fields. */
169
+ function mcpToolName(server, tool) {
170
+ return `mcp__${server}__${tool}`;
171
+ }
172
+ function itemTypeOf(item) {
173
+ return item.type ?? item.item_type ?? "";
174
+ }
175
+ function mapUsage(usage) {
176
+ return {
177
+ input_tokens: usage?.input_tokens ?? 0,
178
+ output_tokens: usage?.output_tokens ?? 0
179
+ };
180
+ }
181
+ function formatMcpResult(result, error) {
182
+ if (error?.message) return error.message;
183
+ if (result == null) return "";
184
+ if (typeof result === "string") return result;
185
+ try {
186
+ return JSON.stringify(result);
187
+ } catch {
188
+ return String(result);
189
+ }
190
+ }
191
+ function formatCommandResult(item) {
192
+ if (item.aggregated_output) return item.aggregated_output;
193
+ if (item.exit_code != null) return String(item.exit_code);
194
+ return "";
195
+ }
196
+ //#endregion
197
+ //#region src/adapters/codex/parse-json.ts
198
+ /** Parse Codex JSONL stdout into parsed event objects. */
199
+ async function* parseCodexJson(stream) {
200
+ let buffer = "";
201
+ stream.setEncoding("utf8");
202
+ for await (const chunk of stream) {
203
+ buffer += chunk;
204
+ let newlineIdx;
205
+ while ((newlineIdx = buffer.indexOf("\n")) !== -1) {
206
+ const line = buffer.slice(0, newlineIdx).trim();
207
+ buffer = buffer.slice(newlineIdx + 1);
208
+ if (line.length === 0) continue;
209
+ yield tryParseLine(line);
210
+ }
211
+ }
212
+ const trailing = buffer.trim();
213
+ if (trailing.length > 0) yield tryParseLine(trailing);
214
+ }
215
+ function tryParseLine(line) {
216
+ try {
217
+ return {
218
+ ok: true,
219
+ event: JSON.parse(line),
220
+ rawLine: line
221
+ };
222
+ } catch (err) {
223
+ return {
224
+ ok: false,
225
+ error: err instanceof Error ? err : new Error(String(err)),
226
+ rawLine: line
227
+ };
228
+ }
229
+ }
230
+ //#endregion
231
+ //#region src/adapters/codex/flags.ts
232
+ /**
233
+ * Build CLI args for Codex harness and judge subprocesses.
234
+ *
235
+ * `--ask-for-approval` is a **global** flag (before `exec`). Other options attach
236
+ * to the `exec` subcommand per `codex exec --help`.
237
+ */
238
+ function pushRepeatableFlag(args, flag, values) {
239
+ if (!values) return;
240
+ for (const value of values) args.push(flag, value);
241
+ }
242
+ function pushOptionalFlag(args, flag, value) {
243
+ if (value === void 0) return;
244
+ if (typeof value === "boolean") {
245
+ if (value) args.push(flag);
246
+ return;
247
+ }
248
+ args.push(flag, String(value));
249
+ }
250
+ /** Prepend global flags that must appear before the `exec` subcommand. */
251
+ function appendGlobalCodexFlags(args, config) {
252
+ pushOptionalFlag(args, "--ask-for-approval", config.askForApproval ?? "never");
253
+ }
254
+ /** Append `codex exec` subcommand flags (after `exec`, before prompt). */
255
+ function appendExecCodexFlags(args, config) {
256
+ pushOptionalFlag(args, "--cd", config.cwd);
257
+ pushRepeatableFlag(args, "--add-dir", config.addDirs);
258
+ pushOptionalFlag(args, "--model", config.model);
259
+ pushOptionalFlag(args, "--profile", config.profile);
260
+ pushOptionalFlag(args, "--sandbox", config.sandbox);
261
+ pushOptionalFlag(args, "--dangerously-bypass-approvals-and-sandbox", config.dangerouslyBypassApprovalsAndSandbox);
262
+ pushOptionalFlag(args, "--dangerously-bypass-hook-trust", config.dangerouslyBypassHookTrust);
263
+ pushOptionalFlag(args, "--ephemeral", config.ephemeral);
264
+ pushOptionalFlag(args, "--ignore-user-config", config.ignoreUserConfig);
265
+ pushOptionalFlag(args, "--skip-git-repo-check", config.skipGitRepoCheck);
266
+ pushOptionalFlag(args, "--output-schema", config.outputSchema);
267
+ pushOptionalFlag(args, "--output-last-message", config.outputLastMessage);
268
+ if (config.configOverrides) for (const override of config.configOverrides) args.push("-c", override);
269
+ }
270
+ /** @deprecated Use appendGlobalCodexFlags + appendExecCodexFlags */
271
+ function appendCodexFlags(args, config) {
272
+ appendExecCodexFlags(args, config);
273
+ }
274
+ /**
275
+ * Ensure harness runs pass `--output-last-message` when capture is enabled.
276
+ * Returns the auto-generated path (for cleanup), or null if unchanged.
277
+ */
278
+ function ensureHarnessOutputLastMessage(config) {
279
+ if (config.captureLastMessage === false) return null;
280
+ if (config.outputLastMessage) return null;
281
+ const path = join(tmpdir(), `harness-eval-codex-last-msg-${randomUUID()}.txt`);
282
+ config.outputLastMessage = path;
283
+ return path;
284
+ }
285
+ /**
286
+ * Build argv for `codex --ask-for-approval never exec --json … "<prompt>"`.
287
+ *
288
+ * Expects `config.outputLastMessage` to already be set if capture is desired;
289
+ * call {@link ensureHarnessOutputLastMessage} before this if spawning outside
290
+ * of {@link spawnCodex}.
291
+ */
292
+ function buildArgs(config) {
293
+ const args = [];
294
+ appendGlobalCodexFlags(args, config);
295
+ args.push("exec", "--json");
296
+ appendExecCodexFlags(args, config);
297
+ args.push(config.prompt);
298
+ return args;
299
+ }
300
+ /**
301
+ * Build argv for `codex --ask-for-approval never exec … "<prompt>"` (no `--json`).
302
+ */
303
+ function buildJudgeArgs(prompt, config = {}) {
304
+ const args = [];
305
+ appendGlobalCodexFlags(args, {
306
+ ...config,
307
+ askForApproval: config.askForApproval ?? "never"
308
+ });
309
+ args.push("exec");
310
+ appendExecCodexFlags(args, config);
311
+ args.push(prompt);
312
+ return args;
313
+ }
314
+ //#endregion
315
+ //#region src/adapters/codex/process.ts
316
+ /**
317
+ * Process management for the Codex CLI adapter.
318
+ *
319
+ * Owns spawning, timeout, abort handling, and process-group teardown for
320
+ * `codex exec --json`. The orchestrator (`index.ts`) reads stdout and awaits
321
+ * completion; this module handles isolation via `$CODEX_HOME` and the
322
+ * SIGTERM → SIGKILL escalation path.
323
+ */
324
+ const DEFAULT_TIMEOUT_MS = 300 * 1e3;
325
+ /** Grace period between SIGTERM and SIGKILL on timeout or abort. */
326
+ const KILL_GRACE_MS = 5e3;
327
+ /** Resolve `$CODEX_HOME` for isolated runs. Exported for unit tests. */
328
+ function resolveCodexHome(config, tempDir) {
329
+ if (config.isolateConfig !== true || !tempDir) return void 0;
330
+ return tempDir;
331
+ }
332
+ /**
333
+ * Spawn `codex exec --json` with optional `$CODEX_HOME` isolation.
334
+ *
335
+ * Timeout and abort both send SIGTERM to the process group, then SIGKILL after
336
+ * {@link KILL_GRACE_MS} if the group is still alive.
337
+ */
338
+ async function spawnCodex(config) {
339
+ const binary = config.binary ?? "codex";
340
+ const autoLastMessagePath = ensureHarnessOutputLastMessage(config);
341
+ const args = buildArgs(config);
342
+ const tempConfigDir = config.isolateConfig === true ? await mkdtemp(join(tmpdir(), "harness-eval-codex-")) : null;
343
+ const env = {
344
+ ...process.env,
345
+ ...config.env
346
+ };
347
+ const codexHome = resolveCodexHome(config, tempConfigDir);
348
+ if (codexHome) env.CODEX_HOME = codexHome;
349
+ const child = spawn(binary, args, {
350
+ cwd: config.cwd ?? process.cwd(),
351
+ env,
352
+ stdio: [
353
+ "ignore",
354
+ "pipe",
355
+ "pipe"
356
+ ],
357
+ detached: true
358
+ });
359
+ let timedOut = false;
360
+ let killEscalation = null;
361
+ const timeoutMs = config.timeoutMs ?? DEFAULT_TIMEOUT_MS;
362
+ const scheduleKillEscalation = () => {
363
+ if (killEscalation) clearTimeout(killEscalation);
364
+ killEscalation = setTimeout(() => killTree(child, "SIGKILL"), KILL_GRACE_MS);
365
+ };
366
+ const timeoutTimer = setTimeout(() => {
367
+ timedOut = true;
368
+ killTree(child, "SIGTERM");
369
+ scheduleKillEscalation();
370
+ }, timeoutMs);
371
+ const onAbort = () => {
372
+ killTree(child, "SIGTERM");
373
+ scheduleKillEscalation();
374
+ };
375
+ config.signal?.addEventListener("abort", onAbort, { once: true });
376
+ const stderrChunks = [];
377
+ child.stderr?.setEncoding("utf8");
378
+ child.stderr?.on("data", (chunk) => {
379
+ stderrChunks.push(chunk);
380
+ });
381
+ const stderrCollected = new Promise((resolve) => {
382
+ const finalize = () => resolve(stderrChunks.join(""));
383
+ child.stderr?.on("end", finalize);
384
+ child.stderr?.on("error", finalize);
385
+ });
386
+ const done = new Promise((resolve) => {
387
+ let settled = false;
388
+ const finalize = (exitCode, signal) => {
389
+ if (settled) return;
390
+ settled = true;
391
+ clearTimeout(timeoutTimer);
392
+ if (killEscalation) clearTimeout(killEscalation);
393
+ config.signal?.removeEventListener("abort", onAbort);
394
+ resolve({
395
+ exitCode,
396
+ signal
397
+ });
398
+ };
399
+ child.on("close", (code, signal) => finalize(code, signal));
400
+ child.on("error", () => finalize(null, null));
401
+ });
402
+ const cleanup = async () => {
403
+ if (autoLastMessagePath) try {
404
+ await rm(autoLastMessagePath, { force: true });
405
+ } catch {}
406
+ if (!tempConfigDir) return;
407
+ try {
408
+ await rm(tempConfigDir, {
409
+ recursive: true,
410
+ force: true
411
+ });
412
+ } catch {}
413
+ };
414
+ return {
415
+ stdout: child.stdout,
416
+ done,
417
+ stderrCollected,
418
+ timedOut: () => timedOut,
419
+ cleanup
420
+ };
421
+ }
422
+ /** Kill the detached process group (fallback to single process if group kill fails). */
423
+ function killTree(child, signal) {
424
+ if (child.pid === void 0) return;
425
+ try {
426
+ process.kill(-child.pid, signal);
427
+ } catch {
428
+ try {
429
+ child.kill(signal);
430
+ } catch {}
431
+ }
432
+ }
433
+ //#endregion
434
+ //#region src/adapters/codex/index.ts
435
+ /**
436
+ * Codex CLI adapter — public API.
437
+ */
438
+ /** Run Codex in headless `exec --json` mode and return a trajectory. */
439
+ async function runCodex(config) {
440
+ const startTs = Date.now();
441
+ const spawned = await spawnCodex(config);
442
+ const builder = new TrajectoryBuilder();
443
+ const mapper = new CodexEventMapper();
444
+ const rawEvents = [];
445
+ const parseErrors = [];
446
+ try {
447
+ for await (const result of parseCodexJson(spawned.stdout)) {
448
+ if (!result.ok) {
449
+ parseErrors.push({
450
+ line: result.rawLine,
451
+ error: result.error.message
452
+ });
453
+ continue;
454
+ }
455
+ for (const event of mapper.map(result.event)) {
456
+ builder.consume(event);
457
+ rawEvents.push(event);
458
+ }
459
+ }
460
+ const [{ exitCode, signal }, stderr] = await Promise.all([spawned.done, spawned.stderrCollected]);
461
+ const diagnostics = {
462
+ exitCode,
463
+ signal,
464
+ stderr,
465
+ parseErrors,
466
+ timedOut: spawned.timedOut(),
467
+ durationMs: Date.now() - startTs
468
+ };
469
+ let view;
470
+ try {
471
+ view = builder.build();
472
+ } catch (err) {
473
+ throw new AdapterError(`harness produced no usable trajectory: ${err instanceof Error ? err.message : String(err)}`, diagnostics);
474
+ }
475
+ if (!view.finalResponse && config.outputLastMessage) try {
476
+ const lastMsg = await readFile(config.outputLastMessage, "utf8");
477
+ if (lastMsg.trim()) view.finalResponse = lastMsg.trim();
478
+ } catch {}
479
+ return {
480
+ view,
481
+ diagnostics,
482
+ rawEvents
483
+ };
484
+ } finally {
485
+ await spawned.cleanup();
486
+ }
487
+ }
488
+ /** Registered {@link HarnessAdapter} for Codex CLI headless runs. */
489
+ const codexAdapter = {
490
+ id: "codex",
491
+ run: runCodex
492
+ };
493
+ //#endregion
494
+ export { appendGlobalCodexFlags as a, ensureHarnessOutputLastMessage as c, mcpToolName as d, appendExecCodexFlags as i, CodexEventMapper as l, runCodex as n, buildArgs as o, appendCodexFlags as r, buildJudgeArgs as s, codexAdapter as t, mapCodexEvents as u };
495
+
496
+ //# sourceMappingURL=codex-0cHO2te9.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-0cHO2te9.js","names":[],"sources":["../src/adapters/codex/map-events.ts","../src/adapters/codex/parse-json.ts","../src/adapters/codex/flags.ts","../src/adapters/codex/process.ts","../src/adapters/codex/index.ts"],"sourcesContent":["/**\n * Map Codex `exec --json` NDJSON events into Claude stream-json {@link StreamEvent}\n * shapes for {@link TrajectoryBuilder}.\n */\n\nimport type { StreamEvent, Usage } from \"../../types/stream\";\nimport type { CodexItem, CodexJsonEvent, CodexUsage } from \"./types\";\n\n/** Stateful mapper — tracks session id and pending tool calls across the stream. */\nexport class CodexEventMapper {\n private sessionId = \"codex-session\";\n private sawInit = false;\n private startedItems = new Set<string>();\n private turnCount = 0;\n\n /** Map one parsed Codex JSON object to zero or more stream events. */\n map(event: CodexJsonEvent): StreamEvent[] {\n const type = event.type;\n if (!type) return [];\n\n switch (type) {\n case \"thread.started\":\n return [this.buildInit(event.thread_id ?? this.sessionId)];\n case \"item.started\":\n return event.item ? this.mapItemStarted(event.item) : [];\n case \"item.completed\":\n return event.item ? this.mapItemCompleted(event.item) : [];\n case \"turn.completed\":\n this.turnCount++;\n return [this.buildResult(false, event.usage)];\n case \"turn.failed\":\n this.turnCount++;\n return [this.buildResult(true, event.usage, event.message)];\n default:\n return [];\n }\n }\n\n private buildInit(sessionId: string): StreamEvent {\n this.sessionId = sessionId;\n this.sawInit = true;\n return {\n type: \"system\",\n subtype: \"init\",\n session_id: sessionId,\n cwd: \"\",\n model: \"\",\n tools: [],\n mcp_servers: [],\n };\n }\n\n private ensureInit(): StreamEvent[] {\n if (this.sawInit) return [];\n return [this.buildInit(this.sessionId)];\n }\n\n private mapItemStarted(item: CodexItem): StreamEvent[] {\n const itemType = itemTypeOf(item);\n if (itemType === \"mcp_tool_call\" || itemType === \"command_execution\") {\n if (item.id) this.startedItems.add(item.id);\n return [\n ...this.ensureInit(),\n itemType === \"mcp_tool_call\"\n ? this.toolUseEvent(item)\n : this.commandUseEvent(item),\n ];\n }\n return this.ensureInit();\n }\n\n private mapItemCompleted(item: CodexItem): StreamEvent[] {\n const itemType = itemTypeOf(item);\n const prefix = this.ensureInit();\n const id = item.id ?? \"\";\n\n if (itemType === \"mcp_tool_call\") {\n const events = [...prefix];\n // Codex may emit item.completed without a prior item.started; synthesize tool_use.\n if (!this.startedItems.has(id)) {\n events.push(this.toolUseEvent(item));\n } else {\n this.startedItems.delete(id);\n }\n events.push(this.toolResultEvent(item));\n return events;\n }\n\n if (itemType === \"command_execution\") {\n const events = [...prefix];\n if (!this.startedItems.has(id)) {\n events.push(this.commandUseEvent(item));\n } else {\n this.startedItems.delete(id);\n }\n events.push(this.toolResultEvent(item, \"Bash\"));\n return events;\n }\n\n if (itemType === \"assistant_message\" && item.text) {\n return [\n ...prefix,\n {\n type: \"assistant\",\n session_id: this.sessionId,\n message: {\n id: item.id ?? `msg_${id}`,\n type: \"message\",\n role: \"assistant\",\n content: [{ type: \"text\", text: item.text }],\n stop_reason: \"end_turn\",\n },\n },\n ];\n }\n\n return prefix;\n }\n\n private toolUseEvent(item: CodexItem): StreamEvent {\n const id = item.id ?? `item_${Math.random().toString(36).slice(2)}`;\n const name = mcpToolName(item.server ?? \"unknown\", item.tool ?? \"unknown\");\n return {\n type: \"assistant\",\n session_id: this.sessionId,\n message: {\n id: `assistant_${id}`,\n type: \"message\",\n role: \"assistant\",\n content: [\n {\n type: \"tool_use\",\n id,\n name,\n input: item.arguments ?? {},\n },\n ],\n stop_reason: \"tool_use\",\n },\n };\n }\n\n private commandUseEvent(item: CodexItem): StreamEvent {\n const id = item.id ?? `item_${Math.random().toString(36).slice(2)}`;\n return {\n type: \"assistant\",\n session_id: this.sessionId,\n message: {\n id: `assistant_${id}`,\n type: \"message\",\n role: \"assistant\",\n content: [\n {\n type: \"tool_use\",\n id,\n name: \"Bash\",\n input: { command: item.command ?? \"\" },\n },\n ],\n stop_reason: \"tool_use\",\n },\n };\n }\n\n private toolResultEvent(item: CodexItem, toolName?: string): StreamEvent {\n const id = item.id ?? \"\";\n const isError = item.status === \"failed\" || item.error != null;\n const content =\n toolName === \"Bash\"\n ? formatCommandResult(item)\n : formatMcpResult(item.result, item.error);\n\n return {\n type: \"user\",\n session_id: this.sessionId,\n message: {\n role: \"user\",\n content: [\n {\n type: \"tool_result\",\n tool_use_id: id,\n content,\n is_error: isError,\n },\n ],\n },\n };\n }\n\n private buildResult(\n isError: boolean,\n usage?: CodexUsage,\n message?: string,\n ): StreamEvent {\n return {\n type: \"result\",\n subtype: isError ? \"error\" : \"success\",\n session_id: this.sessionId,\n is_error: isError,\n result: message ?? \"\",\n usage: mapUsage(usage),\n total_cost_usd: 0,\n duration_ms: 0,\n num_turns: this.turnCount,\n };\n }\n}\n\n/** Map an entire fixture or stream of Codex events through a fresh mapper. */\nexport function mapCodexEvents(events: CodexJsonEvent[]): StreamEvent[] {\n const mapper = new CodexEventMapper();\n const out: StreamEvent[] = [];\n for (const event of events) {\n out.push(...mapper.map(event));\n }\n return out;\n}\n\n/** Build harness-qualified MCP tool name from Codex server + tool fields. */\nexport function mcpToolName(server: string, tool: string): string {\n return `mcp__${server}__${tool}`;\n}\n\nfunction itemTypeOf(item: CodexItem): string {\n return item.type ?? item.item_type ?? \"\";\n}\n\nfunction mapUsage(usage?: CodexUsage): Usage {\n return {\n input_tokens: usage?.input_tokens ?? 0,\n output_tokens: usage?.output_tokens ?? 0,\n };\n}\n\nfunction formatMcpResult(result: unknown, error?: { message?: string } | null): string {\n if (error?.message) return error.message;\n if (result == null) return \"\";\n if (typeof result === \"string\") return result;\n try {\n return JSON.stringify(result);\n } catch {\n return String(result);\n }\n}\n\nfunction formatCommandResult(item: CodexItem): string {\n if (item.aggregated_output) return item.aggregated_output;\n if (item.exit_code != null) return String(item.exit_code);\n return \"\";\n}\n","/**\n * Line-buffered NDJSON parser for Codex `exec --json` stdout.\n */\n\nimport type { Readable } from \"node:stream\";\n\nimport type { CodexJsonEvent } from \"./types\";\n\n/** Result of parsing one NDJSON line from Codex stdout. */\nexport type CodexParseResult =\n | { ok: true; event: CodexJsonEvent; rawLine: string }\n | { ok: false; error: Error; rawLine: string };\n\n/** Parse Codex JSONL stdout into parsed event objects. */\nexport async function* parseCodexJson(\n stream: Readable,\n): AsyncGenerator<CodexParseResult, void, void> {\n let buffer = \"\";\n stream.setEncoding(\"utf8\");\n\n for await (const chunk of stream) {\n buffer += chunk as string;\n\n let newlineIdx: number;\n while ((newlineIdx = buffer.indexOf(\"\\n\")) !== -1) {\n const line = buffer.slice(0, newlineIdx).trim();\n buffer = buffer.slice(newlineIdx + 1);\n if (line.length === 0) continue;\n yield tryParseLine(line);\n }\n }\n\n // Flush a final partial line when Codex closes stdout without a trailing newline.\n const trailing = buffer.trim();\n if (trailing.length > 0) {\n yield tryParseLine(trailing);\n }\n}\n\nfunction tryParseLine(line: string): CodexParseResult {\n try {\n const event = JSON.parse(line) as CodexJsonEvent;\n return { ok: true, event, rawLine: line };\n } catch (err) {\n return {\n ok: false,\n error: err instanceof Error ? err : new Error(String(err)),\n rawLine: line,\n };\n }\n}\n","/**\n * Build CLI args for Codex harness and judge subprocesses.\n *\n * `--ask-for-approval` is a **global** flag (before `exec`). Other options attach\n * to the `exec` subcommand per `codex exec --help`.\n */\n\nimport { randomUUID } from \"node:crypto\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\n\nimport type { CodexAdapterConfig, CodexOptions } from \"./types\";\n\nfunction pushRepeatableFlag(args: string[], flag: string, values?: string[]): void {\n if (!values) return;\n for (const value of values) {\n args.push(flag, value);\n }\n}\n\nfunction pushOptionalFlag(\n args: string[],\n flag: string,\n value: string | number | boolean | undefined,\n): void {\n if (value === undefined) return;\n if (typeof value === \"boolean\") {\n if (value) args.push(flag);\n return;\n }\n args.push(flag, String(value));\n}\n\n/** Prepend global flags that must appear before the `exec` subcommand. */\nexport function appendGlobalCodexFlags(\n args: string[],\n config: CodexOptions,\n): void {\n pushOptionalFlag(\n args,\n \"--ask-for-approval\",\n config.askForApproval ?? \"never\",\n );\n}\n\n/** Append `codex exec` subcommand flags (after `exec`, before prompt). */\nexport function appendExecCodexFlags(\n args: string[],\n config: CodexOptions & { model?: string; cwd?: string },\n): void {\n pushOptionalFlag(args, \"--cd\", config.cwd);\n pushRepeatableFlag(args, \"--add-dir\", config.addDirs);\n pushOptionalFlag(args, \"--model\", config.model);\n pushOptionalFlag(args, \"--profile\", config.profile);\n pushOptionalFlag(args, \"--sandbox\", config.sandbox);\n pushOptionalFlag(\n args,\n \"--dangerously-bypass-approvals-and-sandbox\",\n config.dangerouslyBypassApprovalsAndSandbox,\n );\n pushOptionalFlag(\n args,\n \"--dangerously-bypass-hook-trust\",\n config.dangerouslyBypassHookTrust,\n );\n pushOptionalFlag(args, \"--ephemeral\", config.ephemeral);\n pushOptionalFlag(args, \"--ignore-user-config\", config.ignoreUserConfig);\n pushOptionalFlag(args, \"--skip-git-repo-check\", config.skipGitRepoCheck);\n pushOptionalFlag(args, \"--output-schema\", config.outputSchema);\n pushOptionalFlag(args, \"--output-last-message\", config.outputLastMessage);\n\n if (config.configOverrides) {\n for (const override of config.configOverrides) {\n args.push(\"-c\", override);\n }\n }\n}\n\n/** @deprecated Use appendGlobalCodexFlags + appendExecCodexFlags */\nexport function appendCodexFlags(\n args: string[],\n config: CodexOptions & { model?: string; cwd?: string },\n): void {\n appendExecCodexFlags(args, config);\n}\n\n/**\n * Ensure harness runs pass `--output-last-message` when capture is enabled.\n * Returns the auto-generated path (for cleanup), or null if unchanged.\n */\nexport function ensureHarnessOutputLastMessage(\n config: CodexAdapterConfig,\n): string | null {\n if (config.captureLastMessage === false) return null;\n if (config.outputLastMessage) return null;\n\n const path = join(tmpdir(), `harness-eval-codex-last-msg-${randomUUID()}.txt`);\n config.outputLastMessage = path;\n return path;\n}\n\n/**\n * Build argv for `codex --ask-for-approval never exec --json … \"<prompt>\"`.\n *\n * Expects `config.outputLastMessage` to already be set if capture is desired;\n * call {@link ensureHarnessOutputLastMessage} before this if spawning outside\n * of {@link spawnCodex}.\n */\nexport function buildArgs(config: CodexAdapterConfig): string[] {\n const args: string[] = [];\n appendGlobalCodexFlags(args, config);\n args.push(\"exec\", \"--json\");\n appendExecCodexFlags(args, config);\n args.push(config.prompt);\n return args;\n}\n\n/**\n * Build argv for `codex --ask-for-approval never exec … \"<prompt>\"` (no `--json`).\n */\nexport function buildJudgeArgs(\n prompt: string,\n config: CodexOptions & { model?: string; cwd?: string } = {},\n): string[] {\n const args: string[] = [];\n appendGlobalCodexFlags(args, {\n ...config,\n askForApproval: config.askForApproval ?? \"never\",\n });\n args.push(\"exec\");\n appendExecCodexFlags(args, config);\n args.push(prompt);\n return args;\n}\n","/**\n * Process management for the Codex CLI adapter.\n *\n * Owns spawning, timeout, abort handling, and process-group teardown for\n * `codex exec --json`. The orchestrator (`index.ts`) reads stdout and awaits\n * completion; this module handles isolation via `$CODEX_HOME` and the\n * SIGTERM → SIGKILL escalation path.\n */\n\nimport { spawn, type ChildProcess } from \"node:child_process\";\nimport { mkdtemp, rm } from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport type { Readable } from \"node:stream\";\n\nimport { buildArgs, ensureHarnessOutputLastMessage } from \"./flags\";\nimport type { CodexAdapterConfig } from \"./types\";\n\nconst DEFAULT_TIMEOUT_MS = 5 * 60 * 1000;\n\n/** Grace period between SIGTERM and SIGKILL on timeout or abort. */\nconst KILL_GRACE_MS = 5_000;\n\n/**\n * Handle to a spawned `codex` process. Read `stdout` via {@link parseCodexJson},\n * await `done` for exit state, `stderrCollected` for diagnostics, then call\n * `cleanup()` to remove temp `$CODEX_HOME` and auto-generated last-message files.\n */\nexport interface SpawnedCodex {\n stdout: Readable;\n done: Promise<{ exitCode: number | null; signal: NodeJS.Signals | null }>;\n stderrCollected: Promise<string>;\n timedOut: () => boolean;\n cleanup: () => Promise<void>;\n}\n\n/** Resolve `$CODEX_HOME` for isolated runs. Exported for unit tests. */\nexport function resolveCodexHome(\n config: Pick<CodexAdapterConfig, \"isolateConfig\">,\n tempDir: string | null,\n): string | undefined {\n if (config.isolateConfig !== true || !tempDir) return undefined;\n return tempDir;\n}\n\n/**\n * Spawn `codex exec --json` with optional `$CODEX_HOME` isolation.\n *\n * Timeout and abort both send SIGTERM to the process group, then SIGKILL after\n * {@link KILL_GRACE_MS} if the group is still alive.\n */\nexport async function spawnCodex(\n config: CodexAdapterConfig,\n): Promise<SpawnedCodex> {\n const binary = config.binary ?? \"codex\";\n const autoLastMessagePath = ensureHarnessOutputLastMessage(config);\n const args = buildArgs(config);\n\n // Isolated runs use a fresh temp dir so auth and config do not leak between reps.\n const tempConfigDir =\n config.isolateConfig === true\n ? await mkdtemp(join(tmpdir(), \"harness-eval-codex-\"))\n : null;\n\n const env: Record<string, string | undefined> = {\n ...process.env,\n ...config.env,\n };\n\n const codexHome = resolveCodexHome(config, tempConfigDir);\n if (codexHome) {\n env.CODEX_HOME = codexHome;\n }\n\n const child = spawn(binary, args, {\n cwd: config.cwd ?? process.cwd(),\n env,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n detached: true,\n });\n\n let timedOut = false;\n let killEscalation: NodeJS.Timeout | null = null;\n const timeoutMs = config.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n\n const scheduleKillEscalation = () => {\n if (killEscalation) clearTimeout(killEscalation);\n killEscalation = setTimeout(\n () => killTree(child, \"SIGKILL\"),\n KILL_GRACE_MS,\n );\n };\n\n const timeoutTimer = setTimeout(() => {\n timedOut = true;\n killTree(child, \"SIGTERM\");\n scheduleKillEscalation();\n }, timeoutMs);\n\n const onAbort = () => {\n killTree(child, \"SIGTERM\");\n scheduleKillEscalation();\n };\n config.signal?.addEventListener(\"abort\", onAbort, { once: true });\n\n const stderrChunks: string[] = [];\n child.stderr?.setEncoding(\"utf8\");\n child.stderr?.on(\"data\", (chunk: string) => {\n stderrChunks.push(chunk);\n });\n\n const stderrCollected = new Promise<string>((resolve) => {\n const finalize = () => resolve(stderrChunks.join(\"\"));\n child.stderr?.on(\"end\", finalize);\n child.stderr?.on(\"error\", finalize);\n });\n\n const done = new Promise<{\n exitCode: number | null;\n signal: NodeJS.Signals | null;\n }>((resolve) => {\n let settled = false;\n const finalize = (\n exitCode: number | null,\n signal: NodeJS.Signals | null,\n ) => {\n if (settled) return;\n settled = true;\n clearTimeout(timeoutTimer);\n if (killEscalation) clearTimeout(killEscalation);\n config.signal?.removeEventListener(\"abort\", onAbort);\n resolve({ exitCode, signal });\n };\n\n child.on(\"close\", (code, signal) => finalize(code, signal));\n child.on(\"error\", () => finalize(null, null));\n });\n\n const cleanup = async () => {\n if (autoLastMessagePath) {\n try {\n await rm(autoLastMessagePath, { force: true });\n } catch {\n // best-effort temp cleanup\n }\n }\n if (!tempConfigDir) return;\n try {\n await rm(tempConfigDir, { recursive: true, force: true });\n } catch {\n // best-effort temp cleanup\n }\n };\n\n return {\n stdout: child.stdout!,\n done,\n stderrCollected,\n timedOut: () => timedOut,\n cleanup,\n };\n}\n\n/** Kill the detached process group (fallback to single process if group kill fails). */\nfunction killTree(child: ChildProcess, signal: NodeJS.Signals): void {\n if (child.pid === undefined) return;\n try {\n process.kill(-child.pid, signal);\n } catch {\n try {\n child.kill(signal);\n } catch {\n // process gone\n }\n }\n}\n","/**\n * Codex CLI adapter — public API.\n */\n\nimport { readFile } from \"node:fs/promises\";\n\nimport { TrajectoryBuilder } from \"../../trajectory/builder\";\nimport type { StreamEvent } from \"../../types/stream\";\n\nimport { AdapterError } from \"../types\";\nimport type { HarnessAdapter } from \"../types\";\nimport { CodexEventMapper } from \"./map-events\";\nimport { parseCodexJson } from \"./parse-json\";\nimport { spawnCodex } from \"./process\";\nimport type {\n AdapterDiagnostics,\n CodexAdapterConfig,\n CodexAdapterResult,\n ParseErrorRecord,\n} from \"./types\";\n\nexport { AdapterError } from \"../types\";\nexport type {\n AdapterDiagnostics,\n AdapterResult,\n CodexAdapterConfig,\n CodexAdapterResult,\n CodexOptions,\n ParseErrorRecord,\n} from \"./types\";\nexport { mcpToolName, mapCodexEvents, CodexEventMapper } from \"./map-events\";\nexport {\n buildArgs,\n buildJudgeArgs,\n appendCodexFlags,\n appendGlobalCodexFlags,\n appendExecCodexFlags,\n ensureHarnessOutputLastMessage,\n} from \"./flags\";\n\n/** Run Codex in headless `exec --json` mode and return a trajectory. */\nexport async function runCodex(\n config: CodexAdapterConfig,\n): Promise<CodexAdapterResult> {\n const startTs = Date.now();\n const spawned = await spawnCodex(config);\n\n const builder = new TrajectoryBuilder();\n const mapper = new CodexEventMapper();\n const rawEvents: StreamEvent[] = [];\n const parseErrors: ParseErrorRecord[] = [];\n\n try {\n for await (const result of parseCodexJson(spawned.stdout)) {\n if (!result.ok) {\n parseErrors.push({\n line: result.rawLine,\n error: result.error.message,\n });\n continue;\n }\n\n for (const event of mapper.map(result.event)) {\n builder.consume(event);\n rawEvents.push(event);\n }\n }\n\n const [{ exitCode, signal }, stderr] = await Promise.all([\n spawned.done,\n spawned.stderrCollected,\n ]);\n\n const diagnostics: AdapterDiagnostics = {\n exitCode,\n signal,\n stderr,\n parseErrors,\n timedOut: spawned.timedOut(),\n durationMs: Date.now() - startTs,\n };\n\n let view;\n try {\n view = builder.build();\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n throw new AdapterError(\n `harness produced no usable trajectory: ${message}`,\n diagnostics,\n );\n }\n\n if (!view.finalResponse && config.outputLastMessage) {\n try {\n const lastMsg = await readFile(config.outputLastMessage, \"utf8\");\n if (lastMsg.trim()) {\n view.finalResponse = lastMsg.trim();\n }\n } catch {\n // Codex may omit the file when the run times out or exits before writing.\n }\n }\n\n return { view, diagnostics, rawEvents };\n } finally {\n await spawned.cleanup();\n }\n}\n\n/** Registered {@link HarnessAdapter} for Codex CLI headless runs. */\nexport const codexAdapter: HarnessAdapter<CodexAdapterConfig> = {\n id: \"codex\",\n run: runCodex,\n};\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import { a as loadGradingConfig, i as GradingConfig, n as parseCasesFile, o as parseGradingConfig, r as parseSuite, s as ConfigError, t as loadSuite } from "../loader-C9yQHUPC.js";
2
- export { ConfigError, type GradingConfig, loadGradingConfig, loadSuite, parseCasesFile, parseGradingConfig, parseSuite };
1
+ import { a as loadSuiteDocument, c as GradingConfig, d as ConfigError, i as parseCasesFile, l as loadGradingConfig, n as parseSuite, o as SuiteDocument, r as parseSuiteDirectory, t as loadSuite, u as parseGradingConfig } from "../loader-B1WmGGzf.js";
2
+ export { ConfigError, type GradingConfig, type SuiteDocument, loadGradingConfig, loadSuite, loadSuiteDocument, parseCasesFile, parseGradingConfig, parseSuite, parseSuiteDirectory };
@@ -1,2 +1,2 @@
1
- import { a as parseGradingConfig, i as loadGradingConfig, n as parseCasesFile, o as ConfigError, r as parseSuite, t as loadSuite } from "../loader-DcI0KfRX.js";
2
- export { ConfigError, loadGradingConfig, loadSuite, parseCasesFile, parseGradingConfig, parseSuite };
1
+ import { a as parseGradingConfig, c as parseCasesFile, i as loadGradingConfig, l as ConfigError, n as parseSuite, o as loadSuiteDocument, r as parseSuiteDirectory, t as loadSuite } from "../loader-DnQ6Jt0i.js";
2
+ export { ConfigError, loadGradingConfig, loadSuite, loadSuiteDocument, parseCasesFile, parseGradingConfig, parseSuite, parseSuiteDirectory };
@@ -1,4 +1,4 @@
1
- import { a as HarnessAdapter, i as BaseAdapterConfig, n as AdapterError, o as ParseErrorRecord, r as AdapterResult, t as AdapterDiagnostics, x as StreamEvent } from "./types-B9H4IZtA.js";
1
+ import { a as HarnessAdapter, i as BaseAdapterConfig, n as AdapterError, o as ParseErrorRecord, r as AdapterResult, t as AdapterDiagnostics, x as StreamEvent } from "./types-C0gBkl0-.js";
2
2
 
3
3
  //#region src/adapters/claude-code/types.d.ts
4
4
  /** Claude Code permission modes (`--permission-mode`). */
@@ -70,4 +70,4 @@ declare function runClaudeCode(config: ClaudeCodeAdapterConfig): Promise<ClaudeC
70
70
  declare const claudeCodeAdapter: HarnessAdapter<ClaudeCodeAdapterConfig>;
71
71
  //#endregion
72
72
  export { ClaudeCodeAdapterResult as a, ClaudeCodeAdapterConfig as i, index_d_exports as n, ClaudeCodeOptions as o, runClaudeCode as r, PermissionMode as s, claudeCodeAdapter as t };
73
- //# sourceMappingURL=index-V22PrR0p.d.ts.map
73
+ //# sourceMappingURL=index-DnvP1UBl.d.ts.map