@sverka/arena 0.2.25 → 0.2.26

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sverka/arena",
3
- "version": "0.2.25",
3
+ "version": "0.2.26",
4
4
  "description": "Sverka agent arena — run agents against verification workflows",
5
5
  "license": "MIT",
6
6
  "sideEffects": false,
@@ -36,9 +36,9 @@
36
36
  "dependencies": {
37
37
  "@agentclientprotocol/sdk": "^1.5.0",
38
38
  "zod": "^4.6.5",
39
- "@sverka/runtime": "^0.2.25",
40
- "@sverka/reporter": "^0.2.25",
41
- "@sverka/workflow": "^0.2.25"
39
+ "@sverka/runtime": "^0.2.26",
40
+ "@sverka/reporter": "^0.2.26",
41
+ "@sverka/workflow": "^0.2.26"
42
42
  },
43
43
  "devDependencies": {
44
44
  "vitest": "^5.0.0",
@@ -1 +0,0 @@
1
- {"version":3,"file":"aggregate-report-BkLMmG16.mjs","names":["comboLabel","comboLabel"],"sources":["../src/acp.ts","../src/adapters/devin.ts","../src/judge.ts","../src/runner.ts","../src/config.ts","../src/report.ts","../src/aggregate-report.ts"],"sourcesContent":["/**\n * Shared ACP (Agent Client Protocol) utilities — extracted from the Devin\n * adapter so they can be reused by other adapters and the benchmark runner.\n *\n * This module contains:\n * - {@link sanitizeEnv}: strip host-contaminating env vars before spawning an agent.\n * - {@link createPermissionHandler}: auto-approve permission requests.\n * - {@link runAcpSession}: drive a full ACP connect/initialize/prompt/collect loop.\n */\n\nimport { Writable, Readable } from \"node:stream\";\nimport type { ChildProcess } from \"node:child_process\";\n\nimport * as acp from \"@agentclientprotocol/sdk\";\nimport type {\n PromptResponse,\n RequestPermissionResponse,\n SessionUpdate,\n} from \"@agentclientprotocol/sdk\";\n\nimport type { AgentSpawnConfig } from \"./types.js\";\n\n// ─── Types ───────────────────────────────────────────────────────────\n\n/** A `session/update` notification whose `sessionUpdate` is `\"tool_call\"`. */\nexport type ToolCallMessage = Extract<\n SessionUpdate,\n { sessionUpdate: \"tool_call\" }\n>;\n\n/** A `session/update` notification whose `sessionUpdate` is `\"tool_call_update\"`. */\nexport type ToolCallUpdateMessage = Extract<\n SessionUpdate,\n { sessionUpdate: \"tool_call_update\" }\n>;\n\n// ─── Environment sanitization ────────────────────────────────────────\n\n/** Env-var prefixes to strip from the spawned process environment. */\nconst SANITIZE_PREFIXES = [\n \"GC_\",\n \"BEADS_\",\n \"BD_\",\n \"MCP_\",\n \"CLAUDECODE\",\n \"CLAUDE_CODE_\",\n \"CODEX_\",\n];\n\n/** Exact env-var names to strip from the spawned process environment. */\nconst SANITIZE_EXACT = new Set([\n \"DEVIN_PERMISSION_MODE\",\n \"DEVIN_MODEL\",\n \"AGENTS_MD\",\n \"CLAUDE_PROJECT_MD\",\n]);\n\n/** Check if an env var name should be stripped from the agent environment. */\nfunction shouldSanitize(key: string): boolean {\n if (SANITIZE_EXACT.has(key)) return true;\n return SANITIZE_PREFIXES.some((p) => key.startsWith(p));\n}\n\n/** Copy process.env into a clean record, dropping sanitized entries. */\nfunction copyCleanEnv(): Record<string, string> {\n const env: Record<string, string> = {};\n for (const [key, value] of Object.entries(process.env)) {\n if (value === undefined) continue;\n if (shouldSanitize(key)) continue;\n env[key] = value;\n }\n return env;\n}\n\n/** Apply model and permission settings to the env record. */\nfunction applyModelEnv(\n env: Record<string, string>,\n config: AgentSpawnConfig,\n): void {\n const model = config.model;\n env.DEVIN_PERMISSION_MODE = config.permissionMode ?? \"dangerous\";\n env.DEVIN_MODEL = model.envVar ? (env[model.envVar] ?? model.id) : model.id;\n if (model.envVar) {\n env[model.envVar] = env[model.envVar] ?? model.id;\n }\n}\n\n/** Merge explicit env overrides from config (these win). */\nfunction mergeEnvOverrides(\n env: Record<string, string>,\n overrides?: Record<string, string>,\n): void {\n if (!overrides) return;\n for (const [key, value] of Object.entries(overrides)) {\n env[key] = value;\n }\n}\n\n/**\n * Build a sanitized environment for an agent subprocess.\n *\n * Strips out host contamination: Gas City, Beads, MCP servers, project\n * skills, and other variables that would leak the host's configuration\n * into the benchmark. The agent must only see what we explicitly install.\n *\n * Sets `DEVIN_PERMISSION_MODE` and `DEVIN_MODEL` from the spawn config,\n * then merges any explicit `config.env` overrides (which win).\n */\nexport function sanitizeEnv(config: AgentSpawnConfig): Record<string, string> {\n const env = copyCleanEnv();\n applyModelEnv(env, config);\n mergeEnvOverrides(env, config.env);\n return env;\n}\n\n// ─── Permission handling ──────────────────────────────────────────────\n\n/**\n * Create a permission-request handler that auto-approves tool calls.\n *\n * Selects the first `allow_once` or `allow_always` option, falling back to\n * the first available option. This is the same handler used by both the\n * Devin adapter and the benchmark runner.\n */\nexport function createPermissionHandler(): acp.ClientRequestHandler<\n acp.RequestPermissionRequest,\n acp.RequestPermissionResponse\n> {\n return (ctx): RequestPermissionResponse => {\n const options = ctx.params.options;\n const allow = options.find(\n (o) => o.kind === \"allow_once\" || o.kind === \"allow_always\",\n );\n return {\n outcome: {\n outcome: \"selected\",\n optionId: allow?.optionId ?? options[0]?.optionId ?? \"\",\n },\n };\n };\n}\n\n// ─── Session loop ────────────────────────────────────────────────────\n\n/**\n * Process a single {@link acp.ActiveSessionMessage} from the session update\n * stream. Returns the final {@link PromptResponse} when the session reports\n * a stop, otherwise invokes the appropriate callback and returns `undefined`\n * so the caller can continue collecting.\n */\nfunction handleSessionUpdate(\n message: acp.ActiveSessionMessage,\n onToolCall?: (update: ToolCallMessage, receivedAt: number) => void,\n onToolUpdate?: (update: ToolCallUpdateMessage, receivedAt: number) => void,\n): PromptResponse | undefined {\n if (message.kind === \"stop\") return message.response;\n const receivedAt = Date.now();\n const update = message.update;\n if (update.sessionUpdate === \"tool_call\") {\n onToolCall?.(update, receivedAt);\n } else if (update.sessionUpdate === \"tool_call_update\") {\n onToolUpdate?.(update, receivedAt);\n }\n return undefined;\n}\n\n/**\n * Drive a single ACP session: send the prompt, race the collect loop\n * against a timeout, and return the final {@link PromptResponse}.\n */\nasync function runSessionLoop(\n session: acp.ActiveSession,\n prompt: string,\n timeoutMs: number,\n onToolCall?: (update: ToolCallMessage, receivedAt: number) => void,\n onToolUpdate?: (update: ToolCallUpdateMessage, receivedAt: number) => void,\n onSession?: (sessionId: string) => void,\n): Promise<PromptResponse> {\n onSession?.(session.sessionId);\n const promptPromise = session.prompt(prompt);\n const timeoutPromise = new Promise<never>((_, reject) =>\n setTimeout(\n () => reject(new Error(`Agent timed out after ${timeoutMs}ms`)),\n timeoutMs,\n ),\n );\n\n const collectPromise = (async (): Promise<PromptResponse> => {\n for (;;) {\n const message = await session.nextUpdate();\n const result = handleSessionUpdate(message, onToolCall, onToolUpdate);\n if (result) return result;\n }\n })();\n\n return Promise.race([promptPromise, collectPromise, timeoutPromise]);\n}\n\n/**\n * Run a full ACP session against a spawned agent subprocess.\n *\n * Connects to the agent, initializes the protocol, creates a session in\n * `workspace`, sends `prompt`, and collects update events until the session\n * stops or `timeoutMs` elapses.\n *\n * The `onToolCall` and `onToolUpdate` callbacks let callers collect tool\n * calls and observations without duplicating the session loop logic. The\n * optional `onSession` callback reports the session ID once created. All\n * callbacks are optional.\n *\n * @returns The final {@link PromptResponse} from the agent.\n */\nexport async function runAcpSession(\n proc: ChildProcess,\n workspace: string,\n prompt: string,\n timeoutMs: number,\n onToolCall?: (update: ToolCallMessage, receivedAt: number) => void,\n onToolUpdate?: (update: ToolCallUpdateMessage, receivedAt: number) => void,\n onSession?: (sessionId: string) => void,\n): Promise<PromptResponse> {\n if (!proc.stdin || !proc.stdout) {\n throw new Error(\"Agent process missing stdin/stdout\");\n }\n\n const input = Writable.toWeb(proc.stdin);\n const output = Readable.toWeb(proc.stdout);\n const stream = acp.ndJsonStream(input, output);\n\n return acp\n .client({ name: \"sverka-arena\" })\n .onRequest(\n acp.methods.client.session.requestPermission,\n createPermissionHandler(),\n )\n .connectWith(stream, async (ctx) => {\n await ctx.request(acp.methods.agent.initialize, {\n protocolVersion: acp.PROTOCOL_VERSION,\n clientCapabilities: {},\n });\n return ctx\n .buildSession(workspace)\n .withSession((session) =>\n runSessionLoop(\n session,\n prompt,\n timeoutMs,\n onToolCall,\n onToolUpdate,\n onSession,\n ),\n );\n });\n}\n","/**\n * Devin ACP adapter — spawns `devin acp` as a subprocess and drives an\n * Agent Client Protocol session to collect trace data + metrics.\n *\n * The adapter is abstract over models and plugins: it accepts any\n * {@link ModelConfig} and any set of {@link PluginConfig}s, installs the\n * enabled plugins into the workspace, and runs the prompt against the\n * spawned agent. After the session completes it reads the Devin CLI\n * transcript file to build full {@link TraceData}.\n */\n\nimport { spawn, execSync, type ChildProcess } from \"node:child_process\";\nimport { mkdir, cp, rm, readFile, writeFile } from \"node:fs/promises\";\nimport { existsSync, mkdtempSync, mkdirSync, cpSync, rmSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir, tmpdir } from \"node:os\";\nimport { DatabaseSync } from \"node:sqlite\";\n\nimport type {\n PromptResponse,\n Usage,\n ToolCallContent,\n} from \"@agentclientprotocol/sdk\";\n\nimport type {\n AgentAdapter,\n AgentSpawnConfig,\n AgentProcess,\n RunResult,\n RunMetrics,\n TraceData,\n TraceStep,\n ToolCall,\n Observation,\n PluginConfig,\n ModelConfig,\n} from \"../types.js\";\nimport { sanitizeEnv, runAcpSession } from \"../acp.js\";\nimport type { ToolCallMessage, ToolCallUpdateMessage } from \"../acp.js\";\n\n// ─── Transcript source types (raw JSON from Devin CLI) ───────────────\n\n/** A single step in the raw Devin CLI transcript. */\ninterface TranscriptStep {\n step_id: number;\n source: \"system\" | \"agent\" | \"user\";\n message: string;\n timestamp: string;\n extra?: {\n generation_model?: string | null;\n telemetry?: {\n source?: string;\n operation?: string;\n } | null;\n } | null;\n}\n\n/** Final metrics block in a Devin CLI transcript. */\ninterface TranscriptMetrics {\n total_prompt_tokens: number;\n total_completion_tokens: number;\n total_cached_tokens: number;\n total_steps: number;\n}\n\n/** Full raw transcript written by the Devin CLI. */\ninterface Transcript {\n session_id: string;\n schema_version: string;\n agent: {\n name: string;\n version: string;\n model_name: string;\n };\n final_metrics: TranscriptMetrics;\n steps: TranscriptStep[];\n}\n\n// ─── Helpers ─────────────────────────────────────────────────────────\n\n/** Default transcript directory: ~/.local/share/devin/cli/transcripts */\nexport function transcriptDir(): string {\n return join(homedir(), \".local\", \"share\", \"devin\", \"cli\", \"transcripts\");\n}\n\n/**\n * Devin CLI session DB. It lives on the host at a fixed path — it does\n * NOT follow XDG_DATA_HOME, so isolated runs still write here.\n */\nexport function sessionDbPath(): string {\n return join(homedir(), \".local\", \"share\", \"devin\", \"cli\", \"sessions.db\");\n}\n\n/** Read a transcript JSON file by session ID. Throws if not found. */\nasync function readTranscript(\n sessionId: string,\n dir?: string,\n): Promise<Transcript> {\n const path = join(dir ?? transcriptDir(), `${sessionId}.json`);\n const content = await readFile(path, \"utf-8\");\n return JSON.parse(content) as Transcript;\n}\n\n/** A message_nodes row: chat_message is a JSON-encoded chat message. */\ninterface SessionNodeRow {\n node_id: number;\n created_at: number;\n chat_message: string;\n}\n\n/** Parsed fields of a session-DB chat message we care about. */\ninterface SessionNodeMessage {\n role: string;\n content?: string;\n thinking?: { thinking?: string } | null;\n tool_calls?: { id?: string; name?: string }[] | null;\n metadata?: {\n metrics?: {\n input_tokens?: number | null;\n output_tokens?: number | null;\n cache_read_tokens?: number | null;\n } | null;\n } | null;\n}\n\n/** One parsed session-DB node: a trace step plus its token metrics (inference calls only). */\ninterface ParsedNode {\n step: TranscriptStep;\n tokens: { prompt: number; completion: number; cached: number } | null;\n}\n\n/**\n * Map a message_nodes row to a {@link ParsedNode}. Returns `undefined`\n * for non-step roles (e.g. `tool` results — their content arrives via\n * ACP-collected observations; as steps they'd mislabel tool output as\n * agent output).\n */\nfunction parseNode(row: SessionNodeRow): ParsedNode | undefined {\n const node = JSON.parse(row.chat_message) as SessionNodeMessage;\n if (\n node.role !== \"system\" &&\n node.role !== \"user\" &&\n node.role !== \"assistant\"\n ) {\n return undefined;\n }\n const isInference = node.role === \"assistant\";\n const toolNames = (node.tool_calls ?? [])\n .map((t) => t.name)\n .filter(Boolean)\n .join(\", \");\n const message = (\n node.content?.trim() ||\n node.thinking?.thinking?.trim() ||\n toolNames\n ).slice(0, 4000);\n const m = node.metadata?.metrics;\n return {\n step: {\n step_id: row.node_id,\n // message_nodes.created_at is epoch SECONDS (the CLI batch-writes\n // nodes at session end, so per-step timing is identical anyway);\n // tolerate a future switch to ms.\n timestamp: new Date(\n row.created_at < 1e12 ? row.created_at * 1000 : row.created_at,\n ).toISOString(),\n source: isInference ? \"agent\" : (node.role as \"system\" | \"user\"),\n message,\n extra: isInference\n ? { telemetry: { source: \"assistant\", operation: \"inference\" } }\n : null,\n },\n tokens: isInference\n ? {\n prompt: m?.input_tokens ?? 0,\n completion: m?.output_tokens ?? 0,\n cached: m?.cache_read_tokens ?? 0,\n }\n : null,\n };\n}\n\n/** Accumulate one inference call's token counts into transcript totals. */\nfunction addTokens(\n metrics: TranscriptMetrics,\n tokens: NonNullable<ParsedNode[\"tokens\"]>,\n): void {\n metrics.total_prompt_tokens += tokens.prompt;\n metrics.total_completion_tokens += tokens.completion;\n metrics.total_cached_tokens += tokens.cached;\n metrics.total_steps += 1;\n}\n\n/**\n * Build a {@link Transcript} from the Devin session DB. `devin acp` never\n * writes transcript JSON files, but every message (incl. per-call token\n * metrics) lands in `message_nodes` — each `assistant` node is one LLM\n * inference call. Returns `undefined` when the session has no rows yet.\n */\nexport function readSessionTranscript(\n sessionId: string,\n dbPath?: string,\n): Transcript | undefined {\n const path = dbPath ?? sessionDbPath();\n if (!existsSync(path)) return undefined;\n\n const db = new DatabaseSync(path, { readOnly: true });\n try {\n const rows = db\n .prepare(\n \"SELECT node_id, created_at, chat_message FROM message_nodes WHERE session_id = ? ORDER BY node_id\",\n )\n .all(sessionId) as unknown as SessionNodeRow[];\n if (rows.length === 0) return undefined;\n\n const sessionRow = db\n .prepare(\"SELECT model FROM sessions WHERE id = ?\")\n .get(sessionId) as { model?: string } | undefined;\n\n const steps: TranscriptStep[] = [];\n const metrics: TranscriptMetrics = {\n total_prompt_tokens: 0,\n total_completion_tokens: 0,\n total_cached_tokens: 0,\n total_steps: 0,\n };\n for (const row of rows) {\n const parsed = parseNode(row);\n if (!parsed) continue;\n steps.push(parsed.step);\n if (parsed.tokens) addTokens(metrics, parsed.tokens);\n }\n\n return {\n session_id: sessionId,\n schema_version: \"session-db\",\n agent: {\n name: \"devin\",\n version: \"\",\n model_name: sessionRow?.model ?? \"\",\n },\n final_metrics: metrics,\n steps,\n };\n } finally {\n db.close();\n }\n}\n\n/**\n * Load a transcript for the session — session DB first (that's where\n * `devin acp` actually writes), then the transcript file as a fallback.\n * The DB write can lag `session/prompt` completion, so retry once.\n *\n * The session DB lives at `~/.local/share/devin/cli/` — it does NOT\n * follow XDG_DATA_HOME — so it lands under the child's resolved HOME\n * (`childHome`, which already accounts for any caller override). The\n * host-home path stays a last-resort fallback.\n */\nasync function loadTranscript(\n sessionId: string,\n childHome: string,\n): Promise<Transcript | undefined> {\n const childDataDir = join(childHome, \".local\", \"share\", \"devin\", \"cli\");\n const tryDb = (): Transcript | undefined => {\n try {\n return (\n readSessionTranscript(sessionId, join(childDataDir, \"sessions.db\")) ??\n readSessionTranscript(sessionId)\n );\n } catch {\n return undefined;\n }\n };\n const fromDb =\n tryDb() ??\n (await new Promise<Transcript | undefined>((resolve) =>\n setTimeout(() => resolve(tryDb()), 400),\n ));\n if (fromDb) return fromDb;\n try {\n return await readTranscript(sessionId, join(childDataDir, \"transcripts\"));\n } catch {\n return undefined;\n }\n}\n\n/** Count LLM inference calls in a transcript (agent steps with telemetry.operation === \"inference\"). */\nexport function countLlmCalls(transcript: Transcript): number {\n return transcript.steps.filter(\n (s) =>\n s.source === \"agent\" && s.extra?.telemetry?.operation === \"inference\",\n ).length;\n}\n\n/** Build a {@link TraceStep} from a raw transcript step. */\nfunction buildTraceStep(step: TranscriptStep): TraceStep {\n const isLlmCall =\n step.source === \"agent\" && step.extra?.telemetry?.operation === \"inference\";\n return {\n stepId: step.step_id,\n timestamp: step.timestamp,\n source: step.source,\n message: step.message,\n isLlmCall,\n };\n}\n\n/** Extract text content from a ToolCallContent array (best-effort). */\nfunction extractTextContent(\n contents: ReadonlyArray<ToolCallContent> | undefined,\n): string {\n if (!contents) return \"\";\n const parts: string[] = [];\n for (const c of contents) {\n if (c.type === \"content\" && c.content.type === \"text\") {\n parts.push(c.content.text);\n }\n }\n return parts.join(\"\\n\");\n}\n\n/** Extract token counts from a Usage object, defaulting to 0. */\nexport function extractUsageTokens(usage: Usage | null | undefined): {\n inputTokens: number;\n outputTokens: number;\n thoughtTokens: number;\n totalTokens: number;\n} {\n return {\n inputTokens: usage?.inputTokens ?? 0,\n outputTokens: usage?.outputTokens ?? 0,\n thoughtTokens: usage?.thoughtTokens ?? 0,\n totalTokens: usage?.totalTokens ?? 0,\n };\n}\n\n/** Build {@link RunMetrics} from a PromptResponse + collected counts + timing. */\nfunction buildMetrics(\n promptResult: { stopReason: string; usage?: Usage | null },\n toolCallCount: number,\n llmCallCount: number,\n startTime: number,\n): RunMetrics {\n return {\n ...extractUsageTokens(promptResult.usage),\n toolCallCount,\n llmCallCount,\n executionTimeMs: Date.now() - startTime,\n stopReason: promptResult.stopReason,\n };\n}\n\n/**\n * Extract the agent's final text output from the prompt response or trace.\n *\n * Prefers the text content from the ACP `PromptResponse`, falling back to\n * the last agent message in the trace.\n */\nfunction extractAgentOutput(\n promptResult: PromptResponse,\n trace: TraceData,\n): string {\n // PromptResponse in ACP v1 doesn't have a content field directly.\n // Fall back to the last agent message in the trace.\n for (let i = trace.steps.length - 1; i >= 0; i--) {\n const step = trace.steps[i];\n if (step?.source === \"agent\" && step.message.length > 0) {\n return step.message;\n }\n }\n return \"\";\n}\n\n// ─── Plugin installation ─────────────────────────────────────────────\n\n/**\n * Install enabled plugins and remove disabled ones from the workspace.\n *\n * CRITICAL: This function first removes the entire `.agents/skills/`\n * directory to ensure no inherited skills from the host contaminate the\n * benchmark. Only explicitly enabled plugins are installed.\n *\n * Each enabled plugin's `path` is copied to `workspace/.agents/skills/<id>/`.\n */\nexport async function installPlugins(\n workspace: string,\n plugins: PluginConfig[],\n): Promise<void> {\n const skillsDir = join(workspace, \".agents\", \"skills\");\n\n // Forbid every installed plugin at the repo level. Devin resolves plugin\n // authority enterprise > org > repo > user, and a repo-level wildcard\n // forbid blocks all user/managed installs (higher-authority \"required\"\n // plugins still load — they're a constant baseline across cells).\n // .agents/skills copies below are workspace content, not plugins, so\n // plugin-on cells are unaffected.\n await writeForbidManifest(workspace);\n\n // Nuke any existing skills directory — we start from a clean slate.\n // This prevents host skill contamination.\n await rm(skillsDir, { recursive: true, force: true });\n\n // Only create the directory if we have enabled plugins to install.\n const enabledPlugins = plugins.filter((p) => p.enabled);\n if (enabledPlugins.length === 0) return;\n\n await mkdir(skillsDir, { recursive: true });\n for (const plugin of enabledPlugins) {\n // Reject path-like plugin ids to prevent directory traversal\n if (\n plugin.id.includes(\"/\") ||\n plugin.id.includes(\"\\\\\") ||\n plugin.id.includes(\"..\")\n ) {\n throw new Error(`Invalid plugin id: ${plugin.id}`);\n }\n const dest = join(skillsDir, plugin.id);\n await mkdir(dest, { recursive: true });\n await cp(plugin.path, dest, { recursive: true });\n }\n}\n\n/**\n * Write (or merge into) `<workspace>/.devin/config.json` with\n * `forbiddenPlugins: [\"*\"]`. Preserves other keys the fixture may ship,\n * including `requiredPlugins` (same-manifest requireds are exempt from\n * its own forbids, so plugin fixtures still work).\n */\nasync function writeForbidManifest(workspace: string): Promise<void> {\n const devinDir = join(workspace, \".devin\");\n const manifestPath = join(devinDir, \"config.json\");\n let manifest: Record<string, unknown> = {};\n try {\n const parsed: unknown = JSON.parse(await readFile(manifestPath, \"utf8\"));\n if (typeof parsed === \"object\" && parsed !== null) {\n manifest = parsed as Record<string, unknown>;\n }\n } catch {\n // No existing manifest (or unreadable) — start fresh.\n }\n manifest.forbiddenPlugins = [\"*\"];\n await mkdir(devinDir, { recursive: true });\n await writeFile(manifestPath, `${JSON.stringify(manifest, null, 2)}\\n`); // codeql[js/insecure-temporary-file] — inside a private mkdtemp (0700) workspace, not a predictable shared temp file\n}\n\n/**\n * Create a fresh XDG home for the spawned agent and point `env` at it:\n * - `HOME` — drops host user-level skills (`~/.agents/skills`), which are\n * resolved via `homedir()` and would otherwise leak into every cell.\n * - `XDG_CONFIG_HOME` — drops global user skills, hooks, MCP config, and\n * user-level `AGENTS.md` so all cells share the builtin baseline.\n * - `XDG_DATA_HOME` — fresh plugin/session store; seeded with the host's\n * `devin/credentials.toml` so the agent stays authenticated without\n * writing session state into the user's real Devin data dir.\n *\n * Returns the env-home path — the caller must delete it after the run.\n *\n * An explicit `config.env.HOME` override wins over the redirect (the\n * caller then owns whatever leaks from that home).\n */\nfunction isolateAgentEnv(\n env: Record<string, string>,\n overrides?: Record<string, string>,\n): string {\n const envHome = mkdtempSync(join(tmpdir(), \"arena-env-\"));\n try {\n const configDir = join(envHome, \"config\");\n const dataDir = join(envHome, \"data\");\n const homeDir = join(envHome, \"home\");\n mkdirSync(join(dataDir, \"devin\"), { recursive: true });\n mkdirSync(configDir, { recursive: true });\n mkdirSync(homeDir, { recursive: true });\n\n const hostDataHome =\n process.env.XDG_DATA_HOME ?? join(homedir(), \".local\", \"share\");\n const creds = join(hostDataHome, \"devin\", \"credentials.toml\");\n if (existsSync(creds)) {\n cpSync(creds, join(dataDir, \"devin\", \"credentials.toml\"));\n }\n\n if (overrides?.[\"HOME\"] === undefined) env.HOME = homeDir;\n // Windows resolves the profile dir via USERPROFILE, not HOME.\n if (overrides?.[\"USERPROFILE\"] === undefined) env.USERPROFILE = homeDir;\n env.XDG_CONFIG_HOME = configDir;\n env.XDG_DATA_HOME = dataDir;\n return envHome;\n } catch (error) {\n rmSync(envHome, { recursive: true, force: true });\n throw error;\n }\n}\n\n// ─── Adapter ─────────────────────────────────────────────────────────\n\n/**\n * Devin ACP adapter — spawns `devin acp` as a subprocess.\n *\n * Usage:\n * ```ts\n * const adapter = new DevinAdapter();\n * const proc = adapter.spawn({ model, workspace, plugins });\n * const result = await proc.run(\"Fix the bug\", 120_000);\n * proc.kill();\n * ```\n */\nexport class DevinAdapter implements AgentAdapter {\n readonly id = \"devin\";\n\n spawn(config: AgentSpawnConfig): AgentProcess {\n const { proc, envHome, childHome } = spawnDevin(config);\n let killed = false;\n let cleaned = false;\n const cleanup = (): void => {\n if (cleaned) return;\n cleaned = true;\n rm(envHome, { recursive: true, force: true }).catch((err: unknown) => {\n console.warn(\n `[arena] failed to remove isolated env ${envHome}: ${String(err)}`,\n );\n });\n };\n\n // SIGTERM, wait for exit (SIGKILL fallback), then remove envHome —\n // the child may still be writing session data/transcripts into it.\n const terminate = (): void => {\n if (proc.exitCode != null || proc.signalCode != null) {\n cleanup();\n return;\n }\n proc.once(\"exit\", cleanup);\n const force = setTimeout(() => {\n proc.kill(\"SIGKILL\");\n cleanup();\n }, 5_000);\n force.unref();\n proc.kill(\"SIGTERM\");\n };\n\n return {\n run: async (prompt: string, timeoutMs: number): Promise<RunResult> => {\n try {\n return await runDevinSession(\n proc,\n config,\n prompt,\n timeoutMs,\n childHome,\n );\n } finally {\n terminate();\n }\n },\n kill: (): void => {\n if (killed) return;\n killed = true;\n terminate();\n },\n };\n }\n}\n\n/** Resolve the full path to the devin binary to avoid PATH-based lookup. */\nfunction resolveDevinBinary(): string {\n try {\n const opts = { encoding: \"utf-8\", stdio: \"pipe\" } as const;\n // NOSONAR suppresses only issues on the marker's own line — it must\n // trail the execSync call, not sit inside the options literal.\n return execSync(\"which devin\", opts).trim(); // NOSONAR — PATH needed to locate devin binary\n } catch {\n return \"devin\";\n }\n}\n\n/**\n * Spawn `devin acp --model <model.id>` as a subprocess in the workspace,\n * in an isolated XDG env (see {@link isolateAgentEnv}). Returns the child\n * process and the env-home path the caller must clean up.\n */\nfunction spawnDevin(config: AgentSpawnConfig): {\n proc: ChildProcess;\n envHome: string;\n childHome: string;\n} {\n const env = sanitizeEnv(config);\n const envHome = isolateAgentEnv(env, config.env);\n const devinBin = resolveDevinBinary();\n try {\n const proc = spawn(devinBin, [\"acp\", \"--model\", config.model.id], {\n cwd: config.workspace,\n stdio: [\"pipe\", \"pipe\", \"inherit\"],\n env,\n });\n // The session DB lives under the child's resolved HOME (it does NOT\n // follow XDG_DATA_HOME) — keep it for transcript loading.\n const childHome = env[\"HOME\"] ?? envHome;\n return { proc, envHome, childHome };\n } catch (error) {\n rm(envHome, { recursive: true, force: true }).catch(() => {});\n throw error;\n }\n}\n\n/** Mutable collection state + callbacks for gathering ACP tool calls and observations. */\ninterface ToolCollector {\n collectedToolCalls: ToolCall[];\n observationsByCallId: Map<string, Observation>;\n toolCallCount: number;\n onToolCall: (update: ToolCallMessage, receivedAt: number) => void;\n onToolUpdate: (update: ToolCallUpdateMessage, receivedAt: number) => void;\n}\n\n/** Create a {@link ToolCollector} with callbacks that populate shared state. */\nfunction createToolCollector(): ToolCollector {\n const collectedToolCalls: ToolCall[] = [];\n const observationsByCallId = new Map<string, Observation>();\n let toolCallCount = 0;\n\n const onToolCall = (update: ToolCallMessage, receivedAt: number): void => {\n toolCallCount++;\n const name = update.name ?? update.title ?? \"unknown\";\n const args = (update.rawInput as Record<string, unknown> | null) ?? {};\n collectedToolCalls.push({\n functionName: name,\n arguments: args,\n toolCallId: update.toolCallId,\n collectedAt: new Date(receivedAt).toISOString(),\n });\n };\n\n const onToolUpdate = (\n update: ToolCallUpdateMessage,\n _receivedAt: number,\n ): void => {\n const text = extractTextContent(update.content ?? undefined);\n if (text) {\n observationsByCallId.set(update.toolCallId, {\n sourceCallId: update.toolCallId,\n content: text,\n });\n }\n };\n\n return {\n collectedToolCalls,\n observationsByCallId,\n get toolCallCount() {\n return toolCallCount;\n },\n onToolCall,\n onToolUpdate,\n };\n}\n\n/** Build a {@link RunResult} for a failed session (best-effort trace from collected data). */\nfunction buildErrorResult(\n model: ModelConfig,\n pluginIds: string[],\n toolCallCount: number,\n sessionId: string,\n startTime: number,\n error: unknown,\n): RunResult {\n const metrics = buildMetrics(\n { stopReason: \"cancelled\", usage: null },\n toolCallCount,\n 0,\n startTime,\n );\n const trace: TraceData = {\n sessionId,\n model: model.id,\n steps: [],\n finalMetrics: {\n totalPromptTokens: 0,\n totalCompletionTokens: 0,\n totalCachedTokens: 0,\n totalSteps: 0,\n },\n };\n return {\n taskId: \"\",\n modelId: model.id,\n pluginIds,\n metrics,\n trace,\n output: \"\",\n checkResults: [],\n verdicts: [],\n success: false,\n error: error instanceof Error ? error.message : String(error),\n };\n}\n\n/** Run a full ACP session: initialize, create session, prompt, collect events, read transcript. */\nasync function runDevinSession(\n proc: ChildProcess,\n config: AgentSpawnConfig,\n prompt: string,\n timeoutMs: number,\n childHome: string,\n): Promise<RunResult> {\n const startTime = Date.now();\n const model = config.model;\n const pluginIds = config.plugins.filter((p) => p.enabled).map((p) => p.id);\n const collector = createToolCollector();\n let sessionId = \"\";\n\n try {\n const promptResult = await runAcpSession(\n proc,\n config.workspace,\n prompt,\n timeoutMs,\n collector.onToolCall,\n collector.onToolUpdate,\n (id) => {\n sessionId = id;\n },\n );\n\n const trace = await buildTrace(\n sessionId,\n model,\n collector.collectedToolCalls,\n collector.observationsByCallId,\n childHome,\n );\n const llmCallCount = trace.steps.filter((s) => s.isLlmCall).length;\n const metrics = buildMetrics(\n promptResult,\n collector.toolCallCount,\n llmCallCount,\n startTime,\n );\n const agentOutput = extractAgentOutput(promptResult, trace);\n\n return {\n taskId: \"\",\n modelId: model.id,\n pluginIds,\n metrics,\n trace,\n output: agentOutput,\n checkResults: [],\n verdicts: [],\n success: metrics.stopReason === \"end_turn\",\n };\n } catch (error) {\n return buildErrorResult(\n model,\n pluginIds,\n collector.toolCallCount,\n sessionId,\n startTime,\n error,\n );\n }\n}\n\n/**\n * Build {@link TraceData} from the Devin transcript, enriched with\n * ACP-collected tool calls. Returns `undefined` when no transcript is\n * available so the caller can fall back to {@link buildTraceFallback}.\n */\nasync function buildTraceFromTranscript(\n sessionId: string,\n collectedToolCalls: ToolCall[],\n observationsByCallId: Map<string, Observation>,\n childHome: string,\n): Promise<TraceData | undefined> {\n if (!sessionId) return undefined;\n try {\n const transcript = await loadTranscript(sessionId, childHome);\n if (!transcript) return undefined;\n const steps = transcript.steps.map(buildTraceStep);\n attachToolCallsToSteps(steps, collectedToolCalls, observationsByCallId);\n return {\n sessionId: transcript.session_id,\n model: transcript.agent.model_name,\n steps,\n finalMetrics: {\n totalPromptTokens: transcript.final_metrics.total_prompt_tokens,\n totalCompletionTokens: transcript.final_metrics.total_completion_tokens,\n totalCachedTokens: transcript.final_metrics.total_cached_tokens,\n totalSteps: transcript.final_metrics.total_steps,\n },\n };\n } catch {\n // Transcript not available — fall through to ACP-only trace.\n return undefined;\n }\n}\n\n/** Attach the next tool call + observation to an agent step. Returns true if attached. */\nfunction attachNextToolCall(\n step: TraceStep,\n collectedToolCalls: ToolCall[],\n observationsByCallId: Map<string, Observation>,\n toolIdx: number,\n): { attached: boolean; nextIdx: number } {\n if (toolIdx >= collectedToolCalls.length)\n return { attached: false, nextIdx: toolIdx };\n const tc = collectedToolCalls[toolIdx];\n if (!tc) return { attached: false, nextIdx: toolIdx };\n const calls: ToolCall[] = [tc];\n const obs = observationsByCallId.get(tc.toolCallId);\n const observations: Observation[] = obs ? [obs] : [];\n step.toolCalls = calls;\n // Real arrival time beats the DB's identical session-end stamps.\n if (tc.collectedAt) step.timestamp = tc.collectedAt;\n if (observations.length > 0) step.observations = observations;\n return { attached: true, nextIdx: toolIdx + 1 };\n}\n\n/** Attach ACP-collected tool calls/observations to agent steps in order. */\nfunction attachToolCallsToSteps(\n steps: TraceStep[],\n collectedToolCalls: ToolCall[],\n observationsByCallId: Map<string, Observation>,\n): void {\n let toolIdx = 0;\n for (const step of steps) {\n if (step.source !== \"agent\") continue;\n const result = attachNextToolCall(\n step,\n collectedToolCalls,\n observationsByCallId,\n toolIdx,\n );\n if (result.attached) toolIdx = result.nextIdx;\n }\n}\n\n/** Build a minimal {@link TraceData} from ACP-collected data only. */\nfunction buildTraceFallback(\n sessionId: string,\n model: ModelConfig,\n collectedToolCalls: ToolCall[],\n observationsByCallId: Map<string, Observation>,\n): TraceData {\n const steps: TraceStep[] = collectedToolCalls.map((tc, i): TraceStep => {\n const obs = observationsByCallId.get(tc.toolCallId);\n const step: TraceStep = {\n stepId: i,\n timestamp: tc.collectedAt ?? new Date().toISOString(),\n source: \"agent\",\n message: tc.functionName,\n toolCalls: [tc],\n isLlmCall: false,\n };\n if (obs) {\n step.observations = [obs];\n }\n return step;\n });\n\n return {\n sessionId,\n model: model.id,\n steps,\n finalMetrics: {\n totalPromptTokens: 0,\n totalCompletionTokens: 0,\n totalCachedTokens: 0,\n totalSteps: steps.length,\n },\n };\n}\n\n/** Build {@link TraceData} from the Devin transcript, falling back to ACP-only data. */\nasync function buildTrace(\n sessionId: string,\n model: ModelConfig,\n collectedToolCalls: ToolCall[],\n observationsByCallId: Map<string, Observation>,\n childHome: string,\n): Promise<TraceData> {\n return (\n (await buildTraceFromTranscript(\n sessionId,\n collectedToolCalls,\n observationsByCallId,\n childHome,\n )) ??\n buildTraceFallback(\n sessionId,\n model,\n collectedToolCalls,\n observationsByCallId,\n )\n );\n}\n","/**\n * Judge module — blind LLM evaluation of run outputs.\n *\n * The judge receives the task prompt + the agent's output and scores it\n * against the success criteria. It does NOT know which plugins were active\n * (blind evaluation) unless {@link JudgeConfig.revealPlugins} is set.\n *\n * The judge itself is driven through the same {@link AgentAdapter}\n * interface as the agent under test: it is spawned, sent a prompt, and\n * killed after the response is collected.\n */\n\nimport type {\n JudgeConfig,\n JudgeVerdict,\n RunResult,\n Task,\n ComboComparison,\n} from \"./types.js\";\n\n/** Default system prompt for the judge. */\nexport const DEFAULT_JUDGE_PROMPT =\n \"You are a blind evaluator. You will receive a task prompt and an agent's \" +\n \"response. Score the response 0-100 based on how well it completes the \" +\n \"task. Be strict but fair. Output JSON: \" +\n '{\"score\": number, \"passed\": boolean, \"reasoning\": string, \"issues\": string[]}. ' +\n \"A score of 70+ is passing.\";\n\n/** Default timeout for a single judge run (ms). */\nconst DEFAULT_JUDGE_TIMEOUT_MS = 120_000;\n\n/**\n * Build the judge prompt for a single run.\n *\n * Includes the task prompt, success criteria, and the agent's output. Does\n * NOT include which plugins were active unless `config.revealPlugins` is\n * true. Asks the judge for a JSON response with score, passed, reasoning,\n * and issues.\n */\nexport function buildJudgePrompt(\n task: Task,\n runOutput: string,\n config: JudgeConfig,\n pluginIds: string[] = [],\n): string {\n const systemPrompt = config.systemPrompt ?? DEFAULT_JUDGE_PROMPT;\n const lines: string[] = [systemPrompt, \"\", \"## Task Prompt\", task.prompt, \"\"];\n\n if (task.successCriteria) {\n lines.push(\"## Success Criteria\", task.successCriteria, \"\");\n }\n\n if (config.revealPlugins && task.id) {\n // Only reveal plugin info when explicitly requested.\n lines.push(\"## Plugins Active During Run\");\n if (pluginIds.length > 0) {\n lines.push(pluginIds.join(\", \"));\n } else {\n lines.push(\"(no plugins)\");\n }\n lines.push(\"\");\n }\n\n lines.push(\"## Agent Response\");\n lines.push(runOutput || \"(no output)\");\n lines.push(\"\");\n\n lines.push(\n \"## Instructions\\n\" +\n \"Evaluate the agent's response against the task prompt and success \" +\n 'criteria. Respond with ONLY a JSON object: {\"score\": number, \"passed\": ' +\n 'boolean, \"reasoning\": string, \"issues\": string[]}. A score of 70 or ' +\n \"above is passing. Do not include any text outside the JSON.\",\n );\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Parse a judge response into a {@link JudgeVerdict}.\n *\n * Extracts JSON from the response, handling markdown code fences\n * (` ```json ... ``` `). Falls back to `score=0, passed=false` when the\n * response cannot be parsed.\n */\nexport function parseJudgeResponse(\n response: string,\n runIndex: number,\n run: RunResult,\n): JudgeVerdict {\n const jsonText = extractJson(response);\n const fallback: JudgeVerdict = {\n runIndex,\n score: 0,\n passed: false,\n reasoning: response.trim() || \"Failed to parse judge response\",\n issues: [],\n taskId: run.taskId,\n modelId: run.modelId,\n pluginIds: run.pluginIds,\n };\n\n if (jsonText === null) {\n return fallback;\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(jsonText);\n } catch {\n return fallback;\n }\n\n if (typeof parsed !== \"object\" || parsed === null) {\n return fallback;\n }\n\n const obj = parsed as Record<string, unknown>;\n const score = typeof obj.score === \"number\" ? obj.score : 0;\n const passed = typeof obj.passed === \"boolean\" ? obj.passed : score >= 70;\n const reasoning = typeof obj.reasoning === \"string\" ? obj.reasoning : \"\";\n const issues = Array.isArray(obj.issues)\n ? obj.issues.filter((i): i is string => typeof i === \"string\")\n : [];\n\n return {\n runIndex,\n score,\n passed,\n reasoning,\n issues,\n taskId: run.taskId,\n modelId: run.modelId,\n pluginIds: run.pluginIds,\n };\n}\n\n/**\n * Judge a single run — spawn the judge agent, send the prompt, collect the\n * response, parse it into a {@link JudgeVerdict}, and kill the agent.\n */\nexport async function judgeRun(\n run: RunResult,\n task: Task,\n config: JudgeConfig,\n runIndex: number,\n): Promise<JudgeVerdict> {\n const prompt = buildJudgePrompt(task, run.output, config, run.pluginIds);\n\n const proc = config.agent.spawn({\n model: config.model,\n workspace: process.cwd(),\n plugins: [],\n permissionMode: \"dangerous\",\n });\n\n try {\n const result = await proc.run(prompt, DEFAULT_JUDGE_TIMEOUT_MS);\n return parseJudgeResponse(result.output, runIndex, run);\n } catch (error) {\n return {\n runIndex,\n score: 0,\n passed: false,\n reasoning: error instanceof Error ? error.message : String(error),\n issues: [],\n taskId: run.taskId,\n modelId: run.modelId,\n pluginIds: run.pluginIds,\n };\n } finally {\n proc.kill();\n }\n}\n\n/**\n * Judge all runs in a list, pairing each run with its matching task.\n *\n * Supports `config.repetitions` — the judge is run N times per run for\n * confidence. All verdicts are returned (one per repetition).\n */\nexport async function judgeAllRuns(\n results: RunResult[],\n tasks: Task[],\n config: JudgeConfig,\n): Promise<JudgeVerdict[]> {\n const taskById = new Map<string, Task>();\n for (const task of tasks) {\n taskById.set(task.id, task);\n }\n\n const repetitions = config.repetitions ?? 1;\n const verdicts: JudgeVerdict[] = [];\n\n for (let i = 0; i < results.length; i++) {\n const run = results[i];\n if (!run) continue;\n const task = taskById.get(run.taskId);\n if (!task) continue;\n\n for (let rep = 0; rep < repetitions; rep++) {\n // eslint-disable-next-line no-await-in-loop\n const verdict = await judgeRun(run, task, config, i);\n verdicts.push(verdict);\n }\n }\n\n return verdicts;\n}\n\n/**\n * Compare two plugin combos for a task (for {@link ComboComparison}).\n *\n * Computes deltas as `candidate - baseline`. Determines whether the\n * candidate is better:\n * - Lower tokens / toolCalls / llmCalls / time = better\n * - Higher judgeScore = better\n *\n * The judge score for each run is the average of its verdicts' scores\n * (0 when there are no verdicts).\n */\nexport function compareCombos(\n baseline: RunResult,\n candidate: RunResult,\n): ComboComparison {\n const baselineScore = avgJudgeScore(baseline);\n const candidateScore = avgJudgeScore(candidate);\n\n const deltaTokens =\n candidate.metrics.totalTokens - baseline.metrics.totalTokens;\n const deltaToolCalls =\n candidate.metrics.toolCallCount - baseline.metrics.toolCallCount;\n const deltaLlmCalls =\n candidate.metrics.llmCallCount - baseline.metrics.llmCallCount;\n const deltaTimeMs =\n candidate.metrics.executionTimeMs - baseline.metrics.executionTimeMs;\n const deltaJudgeScore = candidateScore - baselineScore;\n\n // Candidate is better when it uses fewer resources OR scores higher.\n // A strictly better on score, or equal score with fewer resources.\n const fewerResources =\n deltaTokens <= 0 &&\n deltaToolCalls <= 0 &&\n deltaLlmCalls <= 0 &&\n deltaTimeMs <= 0;\n\n const candidateBetter =\n deltaJudgeScore > 0 ||\n (deltaJudgeScore === 0 &&\n fewerResources &&\n (deltaTokens < 0 ||\n deltaToolCalls < 0 ||\n deltaLlmCalls < 0 ||\n deltaTimeMs < 0));\n\n return {\n baseline: comboLabel(baseline),\n candidate: comboLabel(candidate),\n deltaTokens,\n deltaToolCalls,\n deltaLlmCalls,\n deltaTimeMs,\n deltaJudgeScore,\n candidateBetter,\n };\n}\n\n// ─── Helpers ─────────────────────────────────────────────────────────\n\n/**\n * Extract the first JSON object from a response string.\n *\n * Handles raw JSON and JSON wrapped in markdown code fences\n * (` ```json ... ``` ` or ` ``` ... ``` `). Returns `null` when no JSON\n * object can be located.\n */\nfunction extractJson(response: string): string | null {\n const trimmed = response.trim();\n if (trimmed === \"\") return null;\n\n const fenced = extractFromFence(trimmed);\n if (fenced !== null) return fenced;\n\n const braced = extractFromBraces(trimmed);\n if (braced !== null) return braced;\n\n return null;\n}\n\n/** Extract JSON from inside a markdown code fence (```...```). */\nfunction extractFromFence(text: string): string | null {\n // Use string search instead of regex to avoid ReDoS on pathological input.\n const fenceStart = text.indexOf(\"```\");\n if (fenceStart === -1) return null;\n\n const afterFence = text.slice(fenceStart + 3);\n // Skip optional \"json\" label\n let contentStart = 0;\n if (afterFence.startsWith(\"json\")) {\n contentStart = 4;\n }\n // Skip whitespace after label\n while (\n contentStart < afterFence.length &&\n /\\s/.test(afterFence[contentStart]!)\n ) {\n contentStart++;\n }\n const fenceEnd = afterFence.indexOf(\"```\", contentStart);\n if (fenceEnd === -1) return null;\n\n const inner = afterFence.slice(contentStart, fenceEnd).trim();\n if (!looksLikeJson(inner)) return null;\n\n return inner;\n}\n\n/** Extract JSON by finding the first `{` and last `}` in the text. */\nfunction extractFromBraces(text: string): string | null {\n const start = text.indexOf(\"{\");\n const end = text.lastIndexOf(\"}\");\n if (start === -1 || end === -1 || end <= start) return null;\n\n return text.slice(start, end + 1);\n}\n\n/** Quick check that a string starts with `{` (a JSON object). */\nfunction looksLikeJson(text: string): boolean {\n return text.trim().startsWith(\"{\");\n}\n\n/** Average judge score across a run's verdicts (0 when no verdicts). */\nfunction avgJudgeScore(run: RunResult): number {\n if (run.verdicts.length === 0) return 0;\n const sum = run.verdicts.reduce((a, v) => a + v.score, 0);\n return sum / run.verdicts.length;\n}\n\n/** Build a human-readable combo label for a run's plugin set. */\nfunction comboLabel(run: RunResult): string {\n if (run.pluginIds.length === 0) return \"no-plugins\";\n return run.pluginIds.join(\",\");\n}\n","/**\n * Matrix runner — executes the full arena matrix:\n *\n * task × model × plugin combination × repetition\n *\n * For each cell it spawns the agent, runs the prompt, collects the result,\n * and kills the agent. Results are aggregated into {@link ArenaResult}.\n */\n\nimport { writeFile, mkdir, cp, rm, realpath } from \"node:fs/promises\";\nimport { existsSync, mkdtempSync, realpathSync, rmSync } from \"node:fs\";\nimport { isAbsolute, join, resolve, sep } from \"node:path\";\nimport { tmpdir } from \"node:os\";\nimport { spawn, spawnSync, type SpawnOptions } from \"node:child_process\";\nimport { fileURLToPath } from \"node:url\";\n\nimport type {\n ArenaConfig,\n ArenaResult,\n RunResult,\n AggregateMetrics,\n PluginConfig,\n ModelConfig,\n Task,\n CaseAnalysis,\n ComboComparison,\n CheckResult,\n} from \"./types.js\";\nimport { judgeAllRuns, compareCombos } from \"./judge.js\";\nimport { installPlugins } from \"./adapters/devin.js\";\n\n/** Resolve the arena package root (for fixture paths). */\nconst PKG_ROOT = resolve(\n typeof __dirname !== \"undefined\"\n ? __dirname\n : fileURLToPath(new URL(\".\", import.meta.url)),\n \"..\",\n);\n\n/**\n * Generate all plugin on/off combinations.\n *\n * For N plugins this produces 2^N combinations, each a full copy of the\n * plugins array with `enabled` set appropriately.\n *\n * - 0 plugins → `[[]]` (one empty combination)\n * - 1 plugin → `[[off], [on]]`\n * - 2 plugins → `[[off,off], [on,off], [off,on], [on,on]]`\n */\nexport function pluginCombinations(plugins: PluginConfig[]): PluginConfig[][] {\n if (plugins.length === 0) return [[]];\n\n const combos: PluginConfig[][] = [[]];\n for (const plugin of plugins) {\n const next: PluginConfig[][] = [];\n for (const combo of combos) {\n // Disabled variant\n next.push([...combo, { ...plugin, enabled: false }]);\n // Enabled variant\n next.push([...combo, { ...plugin, enabled: true }]);\n }\n combos.length = 0;\n combos.push(...next);\n }\n return combos;\n}\n\n/**\n * Run the full arena matrix: task × model × plugin combo × repetitions.\n *\n * Each cell spawns the configured agent adapter, installs the plugin\n * combination, runs the prompt, collects trace + metrics, and kills the\n * agent. Results are written to `config.outputDir/results.json` and the\n * full {@link ArenaResult} is returned.\n */\nexport async function runArena(config: ArenaConfig): Promise<ArenaResult> {\n const repetitions = config.repetitions ?? 1;\n const combos = pluginCombinations(config.plugins);\n const results = await runMatrix(config, combos);\n\n // Run the judge on all results if configured.\n if (config.judge) {\n const verdicts = await judgeAllRuns(results, config.tasks, config.judge);\n for (const verdict of verdicts) {\n const run = results[verdict.runIndex];\n if (run) run.verdicts.push(verdict);\n }\n }\n\n // Build aggregates AFTER judging so judge metrics are included.\n const aggregates = buildAggregates(results, config.models, combos);\n const analysis = computeAnalysis(results, config.tasks);\n const arenaResult: ArenaResult = {\n timestamp: new Date().toISOString(),\n config: {\n models: config.models.map((m) => m.id),\n plugins: config.plugins.map((p) => p.id),\n tasks: config.tasks.map((t) => t.id),\n repetitions,\n ...(config.judge ? { judgeModel: config.judge.model.id } : {}),\n },\n results,\n aggregates,\n analysis,\n };\n\n await mkdir(config.outputDir, { recursive: true });\n await writeFile(\n join(config.outputDir, \"results.json\"),\n JSON.stringify(arenaResult, null, 2),\n \"utf-8\",\n );\n return arenaResult;\n}\n\n/**\n * Run every cell of the task × model × combo × repetition matrix, collecting\n * results and logging per-cell progress to stderr.\n */\nasync function runMatrix(\n config: ArenaConfig,\n combos: PluginConfig[][],\n): Promise<RunResult[]> {\n const repetitions = config.repetitions ?? 1;\n const results: RunResult[] = [];\n for (const task of config.tasks) {\n for (const model of config.models) {\n for (const combo of combos) {\n for (let rep = 0; rep < repetitions; rep++) {\n const cellLabel = formatCell(task.id, model.id, combo, rep);\n process.stderr.write(`[arena] ${cellLabel} running...\\n`);\n const result = await runCell(\n config.agent,\n task,\n model,\n combo,\n rep,\n config.workspace,\n config.unshareNet,\n );\n results.push(result);\n process.stderr.write(\n `[arena] ${cellLabel} ${result.success ? \"PASS\" : \"FAIL\"} — ` +\n `${result.metrics.totalTokens} tokens, ${result.metrics.toolCallCount} tools, ` +\n `${result.metrics.llmCallCount} llm calls, ${result.metrics.executionTimeMs}ms\\n`,\n );\n }\n }\n }\n }\n return results;\n}\n\n/**\n * Aggregate metrics per (model × plugin combo) cell.\n */\nfunction buildAggregates(\n results: RunResult[],\n models: ModelConfig[],\n combos: PluginConfig[][],\n): AggregateMetrics[] {\n const aggregates: AggregateMetrics[] = [];\n for (const model of models) {\n for (const combo of combos) {\n const pluginIds = combo.filter((p) => p.enabled).map((p) => p.id);\n const label = formatAggregateLabel(model.id, pluginIds);\n aggregates.push(\n aggregateResults(\n results,\n (r) =>\n r.modelId === model.id && samePluginIds(r.pluginIds, pluginIds),\n label,\n ),\n );\n }\n }\n return aggregates;\n}\n\n/** Run a single matrix cell in an ISOLATED temp workspace. */\nasync function runCell(\n agent: ArenaConfig[\"agent\"],\n task: ArenaConfig[\"tasks\"][number],\n model: ArenaConfig[\"models\"][number],\n combo: PluginConfig[],\n rep: number,\n workspaceBase?: string,\n unshareNet = false,\n): Promise<RunResult> {\n const tempWorkspace = await createTempWorkspace(\n task,\n model,\n combo,\n rep,\n workspaceBase,\n );\n await installPlugins(tempWorkspace, combo);\n const result = await executeRun(\n agent,\n task,\n model,\n combo,\n tempWorkspace,\n unshareNet,\n );\n await rm(tempWorkspace, { recursive: true, force: true });\n return result;\n}\n\n/**\n * Create an isolated temp workspace with a fresh copy of the fixture (if any).\n * Each run gets its own copy to prevent skill contamination from the host repo.\n */\nasync function createTempWorkspace(\n task: ArenaConfig[\"tasks\"][number],\n model: ArenaConfig[\"models\"][number],\n combo: PluginConfig[],\n rep: number,\n base?: string,\n): Promise<string> {\n const tempWorkspace = join(\n base ?? tmpdir(),\n `arena-${task.id}-${model.id}-${combo.map((p) => p.id + (p.enabled ? \"on\" : \"off\")).join(\",\")}-r${rep}-${Date.now()}`,\n );\n await mkdir(tempWorkspace, { recursive: true });\n if (task.fixture) {\n const fixturePath = resolve(PKG_ROOT, task.fixture);\n // Prevent path traversal: relative fixtures must stay under PKG_ROOT.\n // Absolute paths (e.g. anchored to the config file by loadArenaConfig)\n // are trusted as intentional. realpath() catches a fixture dir that is\n // itself a symlink escaping the root.\n if (!isAbsolute(task.fixture)) {\n const real = await realpath(fixturePath);\n const realRoot = await realpath(PKG_ROOT);\n if (!real.startsWith(realRoot + sep) && real !== realRoot) {\n throw new Error(`Fixture path escapes package root: ${task.fixture}`);\n }\n }\n await cp(fixturePath, tempWorkspace, { recursive: true });\n }\n return tempWorkspace;\n}\n\n/**\n * Spawn the agent, run the prompt, run deterministic checks, and return the\n * result. On error returns a zeroed {@link RunResult} via {@link errorResult}.\n */\nasync function executeRun(\n agent: ArenaConfig[\"agent\"],\n task: ArenaConfig[\"tasks\"][number],\n model: ArenaConfig[\"models\"][number],\n combo: PluginConfig[],\n tempWorkspace: string,\n unshareNet = false,\n): Promise<RunResult> {\n const setupError = await runSetup(tempWorkspace, task.setup);\n if (setupError) return errorResult(task, model, combo, setupError);\n const proc = agent.spawn({\n model,\n workspace: tempWorkspace,\n plugins: combo,\n permissionMode: \"dangerous\",\n });\n try {\n const result = await proc.run(task.prompt, task.timeoutMs ?? 120_000);\n result.taskId = task.id;\n if (!result.verdicts) result.verdicts = [];\n if (!result.checkResults) result.checkResults = [];\n if (task.checks && task.checks.length > 0) {\n result.checkResults = await runChecks(\n tempWorkspace,\n task.checks,\n unshareNet,\n );\n result.success =\n result.success && result.checkResults.every((c) => c.passed);\n }\n return result;\n } catch (error) {\n return errorResult(task, model, combo, error);\n } finally {\n proc.kill();\n }\n}\n\n/** Run a task's setup commands; returns the failure, or null on success. */\nasync function runSetup(\n workspace: string,\n setup: string[] | undefined,\n): Promise<Error | null> {\n for (const command of setup ?? []) {\n try {\n const { output, exitCode } = await execShell(workspace, command);\n if (exitCode !== 0) {\n return new Error(\n `setup command failed (exit ${exitCode}): ${command}\\n${output.trim()}`,\n );\n }\n } catch (error) {\n return error instanceof Error ? error : new Error(String(error));\n }\n }\n return null;\n}\n\n/** Build a zeroed {@link RunResult} for a failed run. */\nfunction errorResult(\n task: ArenaConfig[\"tasks\"][number],\n model: ArenaConfig[\"models\"][number],\n combo: PluginConfig[],\n error: unknown,\n): RunResult {\n return {\n taskId: task.id,\n modelId: model.id,\n pluginIds: combo.filter((p) => p.enabled).map((p) => p.id),\n metrics: {\n inputTokens: 0,\n outputTokens: 0,\n thoughtTokens: 0,\n totalTokens: 0,\n toolCallCount: 0,\n llmCallCount: 0,\n executionTimeMs: 0,\n stopReason: \"cancelled\",\n },\n trace: {\n sessionId: \"\",\n model: model.id,\n steps: [],\n finalMetrics: {\n totalPromptTokens: 0,\n totalCompletionTokens: 0,\n totalCachedTokens: 0,\n totalSteps: 0,\n },\n },\n output: \"\",\n checkResults: [],\n verdicts: [],\n success: false,\n error: error instanceof Error ? error.message : String(error),\n };\n}\n\n/**\n * Env for check subprocesses. Checks run agent-written scripts (e.g.\n * `bun run verify` executes whatever the agent left in package.json), so\n * the runner's secrets must not leak in. Allowlist toolchain basics only.\n */\nexport function buildCheckEnv(\n env: Record<string, string | undefined> = process.env,\n home?: string,\n): Record<string, string> {\n // NODE_OPTIONS is deliberately excluded — host preload flags would inject\n // host modules into Node-based checks.\n const SAFE =\n /^(PATH|HOME|USERPROFILE|HOMEDRIVE|HOMEPATH|SYSTEMROOT|SystemRoot|WINDIR|COMSPEC|PATHEXT|TEMP|TMP|TMPDIR|SHELL|TERM|COLORTERM|FORCE_COLOR|NO_COLOR|LANG|LC_[A-Z_]+|USER|LOGNAME|XDG_CACHE_HOME|XDG_CONFIG_HOME|XDG_DATA_HOME|TZ|NODE_ENV|BUN_INSTALL|VIRTUAL_ENV|OSTYPE|MACHTYPE|HOSTTYPE)$/;\n const out: Record<string, string> = {};\n for (const [key, value] of Object.entries(env)) {\n if (typeof value === \"string\" && SAFE.test(key)) out[key] = value;\n }\n // Redirect the credential-bearing home dirs at a fresh empty home.\n if (home) {\n out[\"HOME\"] = home;\n out[\"USERPROFILE\"] = home;\n out[\"XDG_CACHE_HOME\"] = join(home, \".cache\");\n out[\"XDG_CONFIG_HOME\"] = join(home, \".config\");\n out[\"XDG_DATA_HOME\"] = join(home, \".local\", \"share\");\n // Keep package-manager caches warm: setup ran with the host HOME and\n // populated them, and caches carry no credentials. Without this every\n // check that installs or resolves deps re-downloads the world.\n const hostHome = env[\"HOME\"];\n if (hostHome) {\n out[\"BUN_INSTALL_CACHE_DIR\"] =\n env[\"BUN_INSTALL_CACHE_DIR\"] ??\n join(hostHome, \".bun\", \"install\", \"cache\");\n out[\"npm_config_cache\"] =\n env[\"npm_config_cache\"] ?? join(hostHome, \".npm\");\n }\n }\n out[\"CI\"] = \"true\"; // forced — checks always see CI mode\n return out;\n}\n\n/**\n * Host dirs bound read-only into the check sandbox — the toolchain (bun,\n * node, bash, git) plus /etc. Host $HOME is deliberately absent: that is\n * what makes credentials unreachable by absolute path, not just by env.\n */\nconst SANDBOX_RO_DIRS = [\"/usr\", \"/bin\", \"/sbin\", \"/lib\", \"/lib64\", \"/etc\"];\n\n/**\n * Toolchain prefixes outside the system dirs bound read-only — never a\n * wholesale parent like /opt or /home/linuxbrew, which would expose\n * arbitrary host files.\n */\nconst SANDBOX_RO_TOOL_DIRS = [\n \"/opt/hostedtoolcache\",\n \"/home/linuxbrew/.linuxbrew\",\n];\n\n/**\n * Toolchain subdirs under the host HOME bound read-only — binaries and\n * version managers only, never credential-bearing dirs. `~/.bun` and\n * `~/.local/bin` stay on PATH inside the sandbox without exposing\n * ~/.config, ~/.ssh or ~/.npmrc.\n */\nconst SANDBOX_HOME_TOOL_DIRS = [\n \".bun\",\n \".local/bin\",\n \".local/share/mise\",\n \".local/share/pnpm\",\n \".local/share/pipx\",\n \".local/share/uv\",\n \".cargo/bin\",\n \".rustup\",\n \".nvm\",\n \".volta\",\n \".asdf\",\n \".deno\",\n \".pyenv\",\n \".poetry\",\n \".rbenv\",\n \".sdkman\",\n];\n\n/**\n * Read-only bind args shared by the availability probe and the real\n * sandbox — both must mount the same view or the probe lies. A dir that\n * is inside, or equal to, the host HOME is never bound wholesale;\n * toolchain subtrees under HOME are re-exposed explicitly by\n * SANDBOX_HOME_TOOL_DIRS.\n */\nfunction sandboxRoBinds(hostHome: string | undefined): string[] {\n const argv: string[] = [];\n for (const dir of [...SANDBOX_RO_DIRS, ...SANDBOX_RO_TOOL_DIRS]) {\n if (hostHome && (dir === hostHome || dir.startsWith(hostHome + sep)))\n continue;\n if (existsSync(dir)) argv.push(\"--ro-bind\", dir, dir);\n }\n const resolv = resolvConfTarget(hostHome);\n if (resolv) argv.push(\"--ro-bind\", resolv, resolv);\n return argv;\n}\n\n/**\n * Resolved /etc/resolv.conf target worth binding, or undefined. The file\n * is often a symlink (/run/systemd/resolve/* on systemd-resolved,\n * /mnt/wsl/resolv.conf on WSL) whose target lives outside the /etc bind —\n * bind the target alone so sandboxed checks keep DNS without exposing\n * the whole parent dir. A target inside host HOME is skipped like any\n * other HOME path; a plain file stays covered by the /etc bind.\n */\nfunction resolvConfTarget(hostHome: string | undefined): string | undefined {\n try {\n const resolv = realpathSync(\"/etc/resolv.conf\");\n if (resolv === \"/etc/resolv.conf\") return undefined;\n const insideHome =\n hostHome !== undefined &&\n (resolv === hostHome || resolv.startsWith(hostHome + sep));\n return insideHome ? undefined : resolv;\n } catch {\n // No usable resolv.conf target — DNS is absent inside, like /run.\n return undefined;\n }\n}\n\n/**\n * Args masking the host HOME inside the sandbox and re-exposing only the\n * allowlisted toolchain subdirs. HOME may be a symlink into a bound dir\n * — a textual containment check would miss that /usr/runner is readable\n * through /usr — so containment is tested on the resolved path while\n * tool dirs bind back at the textual HOME so PATH entries keep working.\n */\nfunction sandboxHomeBinds(hostHome: string, roDirs: string[]): string[] {\n const resolvedHome = existsSync(hostHome) ? realpathSync(hostHome) : hostHome;\n const underBoundDir = (p: string) =>\n roDirs.some((d) => p.startsWith(d + sep));\n const argv: string[] = [];\n if (underBoundDir(resolvedHome)) argv.push(\"--tmpfs\", resolvedHome);\n if (hostHome !== resolvedHome && underBoundDir(hostHome)) {\n argv.push(\"--tmpfs\", hostHome);\n }\n for (const sub of SANDBOX_HOME_TOOL_DIRS) {\n const src = join(resolvedHome, sub);\n if (existsSync(src)) argv.push(\"--ro-bind\", src, join(hostHome, sub));\n }\n return argv;\n}\n\nconst bwrapDetected = new Map<boolean, boolean>();\nfunction hasBwrap(unshareNet = false): boolean {\n // Probe a real namespace launch — `bwrap --version` says nothing about\n // whether unprivileged user namespaces are enabled on this kernel. Run\n // the full argv (tmpfs + ro/rw binds, plus --unshare-net when the config\n // asks for it) against throwaway dirs so a mount/namespace-type failure\n // surfaces here, not on the first check.\n const cached = bwrapDetected.get(unshareNet);\n if (cached !== undefined) return cached;\n if (process.platform !== \"linux\") {\n bwrapDetected.set(unshareNet, false);\n return false;\n }\n const probeWs = mkdtempSync(join(tmpdir(), \"arena-probe-\"));\n const probeHome = mkdtempSync(join(tmpdir(), \"arena-probe-home-\"));\n let detected: boolean;\n try {\n detected =\n spawnSync(\n \"bwrap\", // NOSONAR — host PATH is trusted runner config\n [...buildSandboxArgv(probeWs, probeHome, unshareNet), \"true\"],\n { stdio: \"ignore\" },\n ).status === 0;\n } finally {\n rmSync(probeWs, { recursive: true, force: true });\n rmSync(probeHome, { recursive: true, force: true });\n }\n bwrapDetected.set(unshareNet, detected);\n return detected;\n}\n\n/**\n * bubblewrap argv wrapping a check command: fresh user+pid namespaces,\n * only the workspace and check HOME writable, toolchain dirs read-only.\n * Anything not bound (host $HOME, ~/.ssh, ~/.config) simply does not\n * exist inside — a real filesystem boundary, unlike env scrubbing.\n */\nexport function buildSandboxArgv(\n workspace: string,\n checkHome: string,\n unshareNet = false,\n): string[] {\n const argv = [\n \"--die-with-parent\",\n \"--unshare-user\",\n \"--uid\",\n \"0\",\n \"--gid\",\n \"0\",\n \"--unshare-pid\",\n // Opt-in: a fresh network namespace has no interfaces but loopback —\n // checks that must not reach the network get full isolation. Off by\n // default because checks legitimately install packages.\n ...(unshareNet ? [\"--unshare-net\"] : []),\n \"--new-session\",\n \"--dev\",\n \"/dev\",\n \"--proc\",\n \"/proc\",\n \"--tmpfs\",\n \"/tmp\",\n ];\n const hostHome = process.env[\"HOME\"];\n const roDirs = [...SANDBOX_RO_DIRS, ...SANDBOX_RO_TOOL_DIRS];\n argv.push(...sandboxRoBinds(hostHome));\n if (hostHome) argv.push(...sandboxHomeBinds(hostHome, roDirs));\n argv.push(\n \"--bind\",\n checkHome,\n checkHome,\n \"--bind\",\n workspace,\n workspace,\n \"--chdir\",\n workspace,\n \"--\",\n \"bash\",\n \"-c\",\n );\n return argv;\n}\n\n/** Run a shell command in the workspace, capturing combined output. */\nfunction execShell(\n workspace: string,\n command: string,\n env?: Record<string, string>,\n checkHome?: string,\n unshareNet = false,\n): Promise<{ output: string; exitCode: number }> {\n const opts: SpawnOptions = {\n cwd: workspace,\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n env: env ?? { ...process.env, CI: \"true\" },\n };\n const run = (\n sandboxed: boolean,\n ): Promise<{ output: string; exitCode: number }> =>\n new Promise((resolve, reject) => {\n const proc = sandboxed\n ? spawn(\n \"bwrap\", // NOSONAR — host PATH is trusted runner config\n [\n ...buildSandboxArgv(workspace, checkHome ?? \"\", unshareNet),\n command,\n ],\n opts,\n )\n : spawn(\"bash\", [\"-c\", command], opts); // NOSONAR — config-author shell commands\n // Cap captured output — a noisy command must not grow memory\n // without bound. 256 KiB keeps tail diagnostics while bounding the\n // worst case.\n const MAX_OUTPUT = 256 * 1024;\n let stdout = \"\";\n const append = (d: Buffer): void => {\n if (stdout.length < MAX_OUTPUT) stdout += d.toString();\n };\n proc.stdout?.on(\"data\", append);\n proc.stderr?.on(\"data\", append);\n proc.on(\"close\", (code: number | null) => {\n // null = killed by signal; treat as failure, not a crash source.\n resolve({ output: stdout, exitCode: code ?? -1 });\n });\n proc.on(\"error\", reject);\n });\n if (checkHome === undefined || !hasBwrap(unshareNet)) return run(false);\n // No retry on sandboxed failure: the check output is child-controlled,\n // so a nonzero result can never prove the sandbox itself failed —\n // treating any marker as \"retry outside\" would hand agent-authored\n // commands an un-sandboxed second run. Coverage lives in hasBwrap(),\n // which probes the full argv before the first check runs.\n return run(true);\n}\n\n/**\n * Run deterministic checks in the workspace. Checks execute agent-written\n * scripts, so they get a scrubbed env (see {@link buildCheckEnv}) plus a\n * fresh empty HOME. On Linux with bubblewrap available the command also\n * runs in a mount/user/pid namespace ({@link buildSandboxArgv}) — host\n * $HOME and credentials are unreachable even via absolute paths. Without\n * bwrap the env scrub stands alone: hygiene, not a sandbox.\n */\nasync function runChecks(\n workspace: string,\n checks: Task[\"checks\"],\n unshareNet = false,\n): Promise<CheckResult[]> {\n if (!checks) return [];\n const checkHome = mkdtempSync(join(tmpdir(), \"arena-check-home-\"));\n const env = buildCheckEnv(process.env, checkHome);\n if (unshareNet && !hasBwrap(true)) {\n // Requested network isolation is unavailable on this host — say so\n // loudly instead of silently running checks with host network.\n process.stderr.write(\n \"[arena] warning: unshareNet requested but the bwrap sandbox is \" +\n \"unavailable — checks run with host network\\n\",\n );\n }\n if (hasBwrap(unshareNet)) {\n // Host cache paths aren't bound inside the sandbox — point them at\n // writable dirs under the fresh check HOME instead.\n env[\"BUN_INSTALL_CACHE_DIR\"] = join(checkHome, \".bun\", \"install\", \"cache\");\n env[\"npm_config_cache\"] = join(checkHome, \".npm\");\n }\n const results: CheckResult[] = [];\n try {\n for (const check of checks) {\n try {\n const { output, exitCode } = await execShell(\n workspace,\n check.command,\n env,\n checkHome,\n unshareNet,\n );\n results.push({\n checkId: check.id,\n passed: exitCode === 0,\n output: output.trim(),\n exitCode,\n });\n } catch (error) {\n results.push({\n checkId: check.id,\n passed: false,\n output: error instanceof Error ? error.message : String(error),\n exitCode: -1,\n });\n }\n }\n return results;\n } finally {\n await rm(checkHome, { recursive: true, force: true }).catch(() => {});\n }\n}\n\n/**\n * Aggregate metrics for a group of runs selected by `filter`.\n *\n * Computes averages across all matching runs. Returns zeroed metrics when\n * no runs match. Includes judge-related fields (`avgJudgeScore`,\n * `judgePassCount`) and a `label` identifying the aggregate group.\n */\nexport function aggregateResults(\n results: RunResult[],\n filter: (r: RunResult) => boolean,\n label = \"\",\n): AggregateMetrics {\n const filtered = results.filter(filter);\n const n = filtered.length;\n if (n === 0) {\n return {\n totalRuns: 0,\n successCount: 0,\n avgInputTokens: 0,\n avgOutputTokens: 0,\n avgTotalTokens: 0,\n avgToolCalls: 0,\n avgLlmCalls: 0,\n avgExecutionTimeMs: 0,\n avgJudgeScore: 0,\n judgePassCount: 0,\n label,\n };\n }\n const sum = (f: (r: RunResult) => number) =>\n filtered.reduce((a, r) => a + f(r), 0);\n const round = (v: number) => Math.round(v);\n const round2 = (v: number) => Math.round(v * 100) / 100;\n\n // Judge scores: use verdicts[0].score (first judge verdict per run).\n const judgedRuns = filtered.filter((r) => r.verdicts.length > 0);\n const avgJudgeScore =\n judgedRuns.length === 0\n ? 0\n : round2(\n judgedRuns.reduce((a, r) => a + (r.verdicts[0]?.score ?? 0), 0) /\n judgedRuns.length,\n );\n const judgePassCount = filtered.filter(\n (r) => r.verdicts[0]?.passed === true,\n ).length;\n\n return {\n totalRuns: n,\n successCount: filtered.filter((r) => r.success).length,\n avgInputTokens: round(sum((r) => r.metrics.inputTokens) / n),\n avgOutputTokens: round(sum((r) => r.metrics.outputTokens) / n),\n avgTotalTokens: round(sum((r) => r.metrics.totalTokens) / n),\n avgToolCalls: round2(sum((r) => r.metrics.toolCallCount) / n),\n avgLlmCalls: round2(sum((r) => r.metrics.llmCallCount) / n),\n avgExecutionTimeMs: round(sum((r) => r.metrics.executionTimeMs) / n),\n avgJudgeScore,\n judgePassCount,\n label,\n };\n}\n\n/** Compare two plugin-id arrays for equality (order-insensitive). */\nfunction samePluginIds(a: string[], b: string[]): boolean {\n if (a.length !== b.length) return false;\n const set = new Set(a);\n for (const id of b) {\n if (!set.has(id)) return false;\n }\n return true;\n}\n\n/** Format a human-readable cell label for logging. */\nfunction formatCell(\n taskId: string,\n modelId: string,\n combo: PluginConfig[],\n rep: number,\n): string {\n const plugins = combo\n .map((p) => `${p.id}=${p.enabled ? \"on\" : \"off\"}`)\n .join(\",\");\n return `${taskId}/${modelId}/{${plugins}}#${rep}`;\n}\n\n/** Format an aggregate group label: \"model-id/plugins=on,off\" or \"model-id/no-plugins\". */\nfunction formatAggregateLabel(modelId: string, pluginIds: string[]): string {\n if (pluginIds.length === 0) return `${modelId}/no-plugins`;\n return `${modelId}/plugins=${pluginIds.join(\",\")}`;\n}\n\n/** Format a plugin combo label for comparisons: \"no-plugins\" or comma-joined ids. */\nfunction comboLabel(pluginIds: string[]): string {\n if (pluginIds.length === 0) return \"no-plugins\";\n return pluginIds.join(\",\");\n}\n\n// ─── Case analysis ───────────────────────────────────────────────────\n\n/**\n * Create a synthetic \"average\" {@link RunResult} representing a group of\n * runs with the same plugin combo. Used to feed {@link compareCombos} which\n * operates on single runs.\n */\nfunction averageRun(runs: RunResult[]): RunResult | null {\n if (runs.length === 0) return null;\n const n = runs.length;\n const avg = (f: (r: RunResult) => number): number =>\n Math.round(runs.reduce((a, r) => a + f(r), 0) / n);\n const avg2 = (f: (r: RunResult) => number): number =>\n Math.round((runs.reduce((a, r) => a + f(r), 0) / n) * 100) / 100;\n const first = runs[0]!;\n return {\n taskId: first.taskId,\n modelId: first.modelId,\n pluginIds: first.pluginIds,\n metrics: {\n inputTokens: avg((r) => r.metrics.inputTokens),\n outputTokens: avg((r) => r.metrics.outputTokens),\n thoughtTokens: avg((r) => r.metrics.thoughtTokens),\n totalTokens: avg((r) => r.metrics.totalTokens),\n toolCallCount: avg2((r) => r.metrics.toolCallCount),\n llmCallCount: avg2((r) => r.metrics.llmCallCount),\n executionTimeMs: avg((r) => r.metrics.executionTimeMs),\n stopReason: first.metrics.stopReason,\n },\n trace: first.trace,\n output: first.output,\n checkResults: first.checkResults ?? [],\n verdicts: first.verdicts,\n success: runs.every((r) => r.success),\n };\n}\n\n/**\n * Compute per-task analysis comparing baseline (no plugins) vs each\n * candidate plugin combo.\n *\n * For each task, groups runs by plugin combo, creates an averaged\n * representative run per group, then compares the baseline (empty\n * `pluginIds`) against every non-empty candidate combo using\n * {@link compareCombos} from `judge.ts`.\n */\nexport function computeAnalysis(\n results: RunResult[],\n tasks: Task[],\n): CaseAnalysis[] {\n const analyses: CaseAnalysis[] = [];\n\n for (const task of tasks) {\n const taskRuns = results.filter((r) => r.taskId === task.id);\n\n // Group runs by plugin combo (order-insensitive).\n const comboGroups = new Map<string, RunResult[]>();\n for (const run of taskRuns) {\n const key = comboLabel(run.pluginIds);\n const group = comboGroups.get(key);\n if (group) {\n group.push(run);\n } else {\n comboGroups.set(key, [run]);\n }\n }\n\n const baselineRuns = comboGroups.get(\"no-plugins\") ?? [];\n const baseline = averageRun(baselineRuns);\n const comparisons: ComboComparison[] = [];\n\n if (baseline) {\n for (const [key, candidateRuns] of comboGroups) {\n if (key === \"no-plugins\") continue;\n const candidate = averageRun(candidateRuns);\n if (candidate) {\n comparisons.push(compareCombos(baseline, candidate));\n }\n }\n }\n\n analyses.push({\n taskId: task.id,\n taskName: task.name,\n prompt: task.prompt,\n comparisons,\n });\n }\n\n return analyses;\n}\n","/**\n * Arena config file support — `arena.config.ts` exports declarative data;\n * the CLI resolves the agent adapter by name and validates the shape with\n * zod. See specs/49-arena-cli.\n */\n\nimport { z } from \"zod\";\nimport { pathToFileURL } from \"node:url\";\nimport { dirname, isAbsolute, resolve } from \"node:path\";\n\nimport type { AgentAdapter, ArenaConfig, ModelConfig } from \"./types.js\";\nimport { DevinAdapter } from \"./adapters/devin.js\";\n\nexport class ArenaError extends Error {\n constructor(\n message: string,\n readonly code: \"CONFIG_INVALID\" | \"CONFIG_NOT_FOUND\" | \"UNKNOWN_AGENT\",\n ) {\n super(message);\n this.name = \"ArenaError\";\n }\n}\n\n// ─── Adapter registry ────────────────────────────────────────────────\n\nconst ADAPTERS: Readonly<Record<string, () => AgentAdapter>> = {\n devin: () => new DevinAdapter(),\n};\n\nexport function resolveAdapter(name: string): AgentAdapter {\n if (!Object.hasOwn(ADAPTERS, name)) {\n throw new ArenaError(\n `unknown agent '${name}' — registered adapters: ${Object.keys(ADAPTERS).join(\", \")}`,\n \"UNKNOWN_AGENT\",\n );\n }\n return ADAPTERS[name]!();\n}\n\n// ─── Schema ──────────────────────────────────────────────────────────\n\nconst modelSchema = z.object({\n id: z.string(),\n name: z.string(),\n envVar: z.string().optional(),\n});\n\nconst pluginSchema = z.object({\n id: z.string(),\n name: z.string(),\n path: z.string(),\n enabled: z.boolean().optional(),\n installPath: z.string().optional(),\n});\n\nconst checkSchema = z.object({\n id: z.string(),\n command: z.string(),\n description: z.string(),\n});\n\nconst taskSchema = z.object({\n id: z.string(),\n name: z.string(),\n prompt: z.string(),\n timeoutMs: z.number().optional(),\n successCriteria: z.string().optional(),\n expectedOutput: z.string().optional(),\n fixture: z.string().optional(),\n setup: z.array(z.string()).optional(),\n checks: z.array(checkSchema).optional(),\n});\n\nconst configFileSchema = z.object({\n agent: z.string(),\n models: z.array(modelSchema).min(1),\n plugins: z.array(pluginSchema).optional(),\n tasks: z.array(taskSchema).min(1),\n workspace: z.string().optional(),\n repetitions: z.number().int().positive().optional(),\n unshareNet: z.boolean().optional(),\n outputDir: z.string(),\n judge: z\n .object({\n model: modelSchema,\n agent: z.string().optional(),\n repetitions: z.number().int().positive().optional(),\n revealPlugins: z.boolean().optional(),\n systemPrompt: z.string().optional(),\n })\n .optional(),\n});\n\n/** Declarative config shape authored in `arena.config.ts`. */\nexport type ArenaConfigFile = z.input<typeof configFileSchema>;\n\n/** Type-only identity helper — gives configs full typechecking. */\nexport function defineConfig(config: ArenaConfigFile): ArenaConfigFile {\n return config;\n}\n\n// ─── Loader ──────────────────────────────────────────────────────────\n\n/**\n * Load and validate an arena config file, resolving the named agent\n * (and judge agent, defaulting to the same adapter) to live adapters.\n */\nexport async function loadArenaConfig(\n configPath: string,\n): Promise<ArenaConfig> {\n const absPath = isAbsolute(configPath)\n ? configPath\n : resolve(process.cwd(), configPath);\n\n let mod: Record<string, unknown>;\n try {\n mod = (await import(pathToFileURL(absPath).href)) as Record<\n string,\n unknown\n >;\n } catch (err) {\n throw new ArenaError(\n `cannot load arena config '${absPath}': ${err instanceof Error ? err.message : String(err)}`,\n \"CONFIG_NOT_FOUND\",\n );\n }\n\n if (typeof mod.default !== \"object\" || mod.default === null) {\n throw new ArenaError(\n `arena config '${absPath}' must export a default config object`,\n \"CONFIG_INVALID\",\n );\n }\n\n const parsed = configFileSchema.safeParse(mod.default);\n if (!parsed.success) {\n const issues = parsed.error.issues\n .map((i) => ` ${i.path.join(\".\")}: ${i.message}`)\n .join(\"\\n\");\n throw new ArenaError(\n `invalid arena config '${absPath}':\\n${issues}`,\n \"CONFIG_INVALID\",\n );\n }\n\n const file = parsed.data;\n const agent = resolveAdapter(file.agent);\n\n // Paths in the config file resolve relative to the config file's\n // directory, so `sverka-arena` can be invoked from anywhere.\n const dir = dirname(absPath);\n const rel = (p: string): string => (isAbsolute(p) ? p : resolve(dir, p));\n\n return {\n agent,\n models: file.models as ModelConfig[],\n plugins: (file.plugins ?? []).map((p) => ({\n ...p,\n path: rel(p.path),\n })) as ArenaConfig[\"plugins\"],\n tasks: file.tasks.map((t) => ({\n ...t,\n ...(t.fixture !== undefined ? { fixture: rel(t.fixture) } : {}),\n })) as ArenaConfig[\"tasks\"],\n outputDir: rel(file.outputDir),\n ...optionalFields({\n workspace: file.workspace === undefined ? undefined : rel(file.workspace),\n repetitions: file.repetitions,\n unshareNet: file.unshareNet,\n }),\n ...(file.judge ? { judge: mapJudge(file.agent, file.judge) } : {}),\n };\n}\n\n/** Spreadable optional fields — drops keys whose value is undefined. */\nfunction optionalFields<T extends Record<string, unknown>>(\n fields: T,\n): { [K in keyof T]?: Exclude<T[K], undefined> } {\n return Object.fromEntries(\n Object.entries(fields).filter(([, v]) => v !== undefined),\n ) as { [K in keyof T]?: Exclude<T[K], undefined> };\n}\n\nfunction mapJudge(\n agentName: string,\n j: NonNullable<z.infer<typeof configFileSchema>[\"judge\"]>,\n): NonNullable<ArenaConfig[\"judge\"]> {\n return {\n model: j.model as ModelConfig,\n agent: resolveAdapter(j.agent ?? agentName),\n ...optionalFields({\n repetitions: j.repetitions,\n revealPlugins: j.revealPlugins,\n systemPrompt: j.systemPrompt,\n }),\n };\n}\n","/**\n * Text rendering for arena results — aggregate table + per-task analysis.\n * Used by `sverka-arena run` (post-run summary) and `sverka-arena report`.\n */\n\nimport type { AggregateMetrics, ArenaResult } from \"./types.js\";\n\nfunction fmtNum(n: number): string {\n return Number.isInteger(n) ? String(n) : n.toFixed(1);\n}\n\nfunction row(\n cells: readonly (string | number)[],\n widths: readonly number[],\n): string {\n return cells\n .map((c, i) => String(c).padEnd(widths[i] ?? 10))\n .join(\"\")\n .trimEnd();\n}\n\nfunction aggregateTable(aggregates: readonly AggregateMetrics[]): string {\n const header = [\n \"label\",\n \"runs\",\n \"pass\",\n \"tokens\",\n \"tools\",\n \"llm\",\n \"ms\",\n \"judge\",\n ];\n const data = aggregates.map((a) => [\n a.label,\n a.totalRuns,\n a.successCount,\n fmtNum(a.avgTotalTokens),\n fmtNum(a.avgToolCalls),\n fmtNum(a.avgLlmCalls),\n fmtNum(a.avgExecutionTimeMs),\n a.judgePassCount > 0 || a.avgJudgeScore > 0 ? fmtNum(a.avgJudgeScore) : \"-\",\n ]);\n const widths = header.map((h, i) =>\n Math.max(h.length + 2, ...data.map((r) => String(r[i] ?? \"\").length + 2)),\n );\n const lines = [row(header, widths)];\n for (const r of data) lines.push(row(r, widths));\n return lines.join(\"\\n\");\n}\n\n/** Render an ArenaResult as human-readable text. */\nexport function renderReport(result: ArenaResult): string {\n const parts: string[] = [];\n\n parts.push(\"Aggregates\", aggregateTable(result.aggregates));\n\n if (result.analysis.length > 0) {\n parts.push(\"\", \"Analysis\");\n for (const task of result.analysis) {\n parts.push(` ${task.taskName} (${task.taskId})`);\n for (const cmp of task.comparisons) {\n const verdict = cmp.candidateBetter ? \"better\" : \"worse\";\n parts.push(\n ` ${cmp.baseline} → ${cmp.candidate}: ` +\n `tokens ${cmp.deltaTokens}, tools ${cmp.deltaToolCalls}, ` +\n `llm ${cmp.deltaLlmCalls}, ms ${cmp.deltaTimeMs}, ` +\n `judge ${cmp.deltaJudgeScore} — ${verdict}`,\n );\n }\n if (task.summary !== undefined) {\n parts.push(` ${task.summary}`);\n }\n }\n }\n\n return parts.join(\"\\n\");\n}\n","/**\n * ArenaResult → one sverka report for the whole run matrix.\n *\n * The per-run trace report ({@link ./trace-report.js}) renders a single\n * agent run; this renders the benchmark itself as a pipeline: each task\n * is a pipeline, each run (task × model × plugin combo × repetition) is\n * a step. Durations are the real `executionTimeMs`, so the Gantt view is\n * an honest wall-clock comparison and the DAG shows the run matrix.\n */\nimport type { RunEvent } from \"@sverka/runtime\";\nimport type { DefinitionGraph } from \"@sverka/workflow\";\nimport type { ReportContext } from \"@sverka/reporter\";\nimport { createHtmlRenderer } from \"@sverka/reporter\";\nimport type { ArenaResult, RunResult } from \"./types.js\";\n\nfunction comboLabel(result: RunResult): string {\n return result.pluginIds.length ? result.pluginIds.join(\"+\") : \"no-plugins\";\n}\n\n/** Stable per-run step id — readable in the DAG, Gantt and step list. */\nexport function runStepId(result: RunResult, rep: number): string {\n return `${result.taskId}/${result.modelId}/${comboLabel(result)}/r${rep}`;\n}\n\n/**\n * Repetition number within (task, model, combo) — the global matrix\n * index would label task B's first run \"r13\" in a wide matrix.\n */\nfunction repNumbers(results: readonly RunResult[]): Map<RunResult, number> {\n const counts = new Map<string, number>();\n const reps = new Map<RunResult, number>();\n for (const r of results) {\n const key = `${r.taskId} ${r.modelId} ${comboLabel(r)}`;\n const rep = (counts.get(key) ?? 0) + 1;\n counts.set(key, rep);\n reps.set(r, rep);\n }\n return reps;\n}\n\nconst SENSITIVE_KEY = /TOKEN|KEY|SECRET|PASSWORD|PASSWD|CREDENTIAL/i;\n\n/**\n * Best-effort secret scrub before run output lands in a public HTML.\n * Word-wise, no content regexes — a scanner-auditable shape.\n */\nfunction redact(text: string): string {\n const words = text.split(\" \");\n for (let i = 0; i < words.length; i++) {\n const w = words[i]!;\n const eqIdx = w.indexOf(\"=\");\n const colonIdx = w.indexOf(\":\");\n const sepIdx = Math.min(\n eqIdx === -1 ? w.length : eqIdx,\n colonIdx === -1 ? w.length : colonIdx,\n );\n if (sepIdx === w.length || sepIdx === 0) continue;\n const key = w.slice(0, sepIdx);\n if (!SENSITIVE_KEY.test(key)) continue;\n if (sepIdx === w.length - 1 && i + 1 < words.length) {\n // \"KEY=\" or \"KEY:\" alone — the value is the next word.\n words[i + 1] = \"[REDACTED]\";\n } else {\n words[i] = `${key}=[REDACTED]`;\n }\n }\n return words.join(\" \").replace(/Bearer\\s+\\S+/gi, \"Bearer [REDACTED]\");\n}\n\nfunction formatTokens(n: number): string {\n return n >= 1000 ? `${(n / 1000).toFixed(1)}k` : String(n);\n}\n\nfunction metricsLine(result: RunResult): string {\n const m = result.metrics;\n if (m === undefined) return \"no metrics recorded\";\n const judge = result.verdicts?.length\n ? `, judge ${Math.round(\n result.verdicts.reduce((a, v) => a + v.score, 0) /\n result.verdicts.length,\n )}`\n : \"\";\n return `${formatTokens(m.totalTokens)} tokens, ${m.toolCallCount} tool calls, ${m.llmCallCount} llm calls${judge}`;\n}\n\nfunction failureReason(result: RunResult): string {\n const failed = (result.checkResults ?? []).filter((c) => !c.passed);\n if (failed.length > 0) {\n return redact(\n failed\n .map((c) => `${c.checkId}: ${c.output || \"exit \" + c.exitCode}`)\n .join(\"; \"),\n );\n }\n return redact(result.error ?? \"run reported success=false\");\n}\n\n/**\n * One pipeline per task, one step per run — no edges, so the DAG renders\n * the matrix as a fan-out per task.\n */\nexport function arenaResultGraph(result: ArenaResult): DefinitionGraph {\n const byTask = new Map<string, { id: string; dependencies: never[] }[]>();\n const reps = repNumbers(result.results);\n for (const r of result.results) {\n const steps = byTask.get(r.taskId) ?? [];\n steps.push({ id: runStepId(r, reps.get(r)!), dependencies: [] });\n byTask.set(r.taskId, steps);\n }\n return {\n project: {\n id: \"arena\",\n pipelines: [...byTask].map(([taskId, steps]) => ({\n id: taskId,\n inputs: {},\n entries: [],\n steps,\n outputs: [],\n })),\n },\n } as unknown as DefinitionGraph;\n}\n\n/**\n * Convert the whole matrix into a RunEvent stream. Runs are laid out\n * serially — each starts when the previous ended — because arena\n * executes the matrix sequentially; the Gantt then reads as the real\n * wall-clock timeline and `run-completed` carries the honest total.\n */\nexport function arenaResultToEvents(result: ArenaResult): RunEvent[] {\n const events: RunEvent[] = [\n { type: \"run-started\", runId: \"arena\", planId: \"arena\", at: 0 },\n ];\n let t = 0;\n const reps = repNumbers(result.results);\n for (const r of result.results) {\n const stepId = runStepId(r, reps.get(r)!);\n const dur = Math.max(r.metrics?.executionTimeMs ?? 0, 0);\n const end = t + dur;\n events.push({ type: \"step-started\", stepId, at: t });\n events.push(...outcomeEvents(r, stepId, dur, end));\n events.push(...verdictEvents(r, stepId, end));\n t = end;\n }\n const anyFail = result.results.some((r) => !r.success);\n events.push({\n type: \"run-completed\",\n runId: \"arena\",\n status: anyFail ? \"failure\" : \"success\",\n durationMs: t,\n at: t,\n });\n return events;\n}\n\nfunction outcomeEvents(\n r: RunResult,\n stepId: string,\n dur: number,\n end: number,\n): RunEvent[] {\n const events: RunEvent[] = [];\n if (r.metrics?.executionTimeMs === undefined || dur === 0) {\n events.push({\n type: \"diagnostic\",\n stepId,\n severity: \"info\",\n message: \"no duration recorded — run failed before/without timing\",\n at: end,\n });\n }\n if (r.success) {\n events.push({\n type: \"step-succeeded\",\n stepId,\n durationMs: dur,\n stdout: metricsLine(r),\n at: end,\n });\n } else {\n events.push({\n type: \"step-failed\",\n stepId,\n error: failureReason(r),\n durationMs: dur,\n stdout: metricsLine(r),\n at: end,\n });\n }\n return events;\n}\n\nfunction verdictEvents(r: RunResult, stepId: string, end: number): RunEvent[] {\n return (r.verdicts ?? []).map((v) => ({\n type: \"diagnostic\" as const,\n stepId,\n severity: (v.passed ? \"info\" : \"warn\") as \"info\" | \"warn\",\n message: redact(\n `judge score ${v.score}${v.passed ? \"\" : \" (failed)\"}: ${v.reasoning}`,\n ),\n at: end,\n }));\n}\n\n/** Render the whole arena matrix as a standalone sverka HTML report. */\nexport function writeAggregateReport(\n result: ArenaResult,\n outputPath: string,\n context?: ReportContext,\n): void {\n const meta = [\n { label: \"models\", value: result.config.models.join(\", \") },\n { label: \"plugins\", value: result.config.plugins.join(\", \") },\n { label: \"tasks\", value: result.config.tasks.join(\", \") },\n { label: \"repetitions\", value: String(result.config.repetitions) },\n { label: \"runs\", value: String(result.results.length) },\n ...(result.config.judgeModel\n ? [{ label: \"judge\", value: result.config.judgeModel }]\n : []),\n ...(context?.meta ?? []),\n ];\n const renderer = createHtmlRenderer({\n outputPath,\n graph: arenaResultGraph(result),\n context: {\n title: \"arena aggregate\",\n generatedAt: result.timestamp ?? new Date().toISOString(),\n command: \"sverka-arena report --format html\",\n ...context,\n meta,\n },\n });\n for (const e of arenaResultToEvents(result)) renderer.onEvent(e);\n renderer.flush();\n}\n"],"mappings":"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"}