@wix/evalforge-evaluator 0.126.0 → 0.128.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/index.ts", "../src/config.ts", "../src/api-client.ts", "../src/fetch-evaluation-data.ts", "../src/resolve-placeholders.ts", "../src/run-scenario/index.ts", "../src/run-scenario/environment.ts", "../src/run-scenario/utils/write-files.ts", "../src/run-scenario/run-agent-with-context.ts", "../src/run-scenario/agents/registry.ts", "../src/run-scenario/agents/claude-code/claude-code-adapter.ts", "../src/run-scenario/agents/claude-code/execute.ts", "../src/run-scenario/agents/claude-code/write-skills.ts", "../src/run-scenario/agents/claude-code/write-mcp.ts", "../src/run-scenario/agents/shared/resolve-mcp-placeholders.ts", "../src/run-scenario/agents/claude-code/write-sub-agents.ts", "../src/run-scenario/agents/claude-code/write-rules.ts", "../src/run-scenario/agents/claude-code/build-conversation.ts", "../src/run-scenario/agents/shared/trace-emit.ts", "../src/run-scenario/agents/claude-code/index.ts", "../src/run-scenario/agents/opencode/opencode-adapter.ts", "../src/run-scenario/agents/opencode/execute.ts", "../src/run-scenario/agents/opencode/types.ts", "../src/run-scenario/agents/opencode/write-skills.ts", "../src/run-scenario/agents/opencode/write-sub-agents.ts", "../src/run-scenario/agents/opencode/config.ts", "../src/run-scenario/agents/opencode/build-trace.ts", "../src/run-scenario/agents/opencode/build-conversation.ts", "../src/run-scenario/agents/opencode/index.ts", "../src/run-scenario/agents/simple-agent/execute.ts", "../src/run-scenario/agents/simple-agent/mcp-tools.ts", "../src/run-scenario/agents/shared/detect-tool-error.ts", "../src/run-scenario/agents/simple-agent/cost-calculation.ts", "../src/run-scenario/agents/simple-agent/build-conversation.ts", "../src/run-scenario/agents/simple-agent/simple-agent-adapter.ts", "../src/run-scenario/agents/simple-agent/index.ts", "../src/run-scenario/file-diff.ts", "../../../node_modules/diff/lib/index.mjs", "../src/error-reporter.ts"],
4
- "sourcesContent": ["#!/usr/bin/env node\n\n/**\n * EvalForge Evaluator Entry Point\n *\n * This module runs evaluations on a remote Dev Machine.\n * It fetches evaluation data from the server, runs scenarios,\n * and reports results (including detailed error information).\n */\n\n// CRITICAL: Log immediately at module load time to catch import failures\nconsole.error(\n '[EVALUATOR-BOOT] Module loading started',\n new Date().toISOString()\n);\n\nimport { EvalStatus } from '@wix/evalforge-types';\nimport { loadConfig, type EvaluatorConfig } from './config.js';\nimport { createApiClient, type ApiClient } from './api-client.js';\nimport { fetchEvaluationData } from './fetch-evaluation-data.js';\nimport { runScenario } from './run-scenario/index.js';\nimport {\n formatError,\n formatErrorForJobError,\n ExecutionPhase\n} from './error-reporter.js';\n// Diagnostics disabled - was causing Invalid Date entries in UI\n// import { runDiagnostics } from './diagnostics.js';\n\nconsole.error('[EVALUATOR-BOOT] All static imports successful');\n\n/**\n * State that persists across the evaluation for error reporting.\n * This allows us to report errors even when config/api are not yet initialized.\n */\ninterface EvaluationState {\n config: EvaluatorConfig | null;\n api: ApiClient | null;\n currentPhase: string;\n currentContext: Record<string, unknown>;\n}\n\n/**\n * Run the evaluation with comprehensive error tracking.\n *\n * @param projectId - The project ID\n * @param evalRunId - The eval run ID\n */\nasync function runEvaluation(\n projectId: string,\n evalRunId: string\n): Promise<void> {\n // Initialize state for error tracking\n const state: EvaluationState = {\n config: null,\n api: null,\n currentPhase: ExecutionPhase.CONFIG,\n currentContext: { projectId, evalRunId }\n };\n\n console.error(\n '[DEBUG-H1] runEvaluation entry',\n JSON.stringify({ projectId, evalRunId, timestamp: Date.now() })\n );\n\n // ============================================\n // PHASE 1: Load Configuration\n // ============================================\n state.currentPhase = ExecutionPhase.CONFIG;\n state.currentContext = { projectId, evalRunId };\n\n let config: EvaluatorConfig;\n try {\n config = loadConfig();\n state.config = config;\n console.error(\n '[DEBUG-H1] loadConfig SUCCESS',\n JSON.stringify({\n serverUrl: config.serverUrl,\n apiPrefix: config.apiPrefix || '(none)',\n aiGatewayUrl: config.aiGatewayUrl,\n hasHeaders: Object.keys(config.aiGatewayHeaders).length > 0,\n timestamp: Date.now()\n })\n );\n } catch (configErr) {\n console.error(\n '[DEBUG-H1] loadConfig FAILED',\n JSON.stringify({\n error:\n configErr instanceof Error ? configErr.message : String(configErr),\n stack: configErr instanceof Error ? configErr.stack : undefined,\n timestamp: Date.now()\n })\n );\n // Can't report to server without config, but error will be caught by main handler\n throw new Error(\n `[${ExecutionPhase.CONFIG}] ${configErr instanceof Error ? configErr.message : String(configErr)}`\n );\n }\n\n console.log('[Evaluator] Config loaded', {\n serverUrl: config.serverUrl,\n aiGatewayUrl: config.aiGatewayUrl,\n evaluationsDir: config.evaluationsDir,\n hasAiGatewayHeaders: Object.keys(config.aiGatewayHeaders).length > 0,\n hasRouteHeader: !!config.routeHeader\n });\n\n // ============================================\n // PHASE 2: Create API Client\n // ============================================\n state.currentPhase = ExecutionPhase.API_CLIENT;\n\n let api: ApiClient;\n try {\n api = createApiClient(config.serverUrl, {\n apiPrefix: config.apiPrefix,\n routeHeader: config.routeHeader,\n authToken: config.authToken\n });\n state.api = api;\n } catch (apiErr) {\n throw new Error(\n `[${ExecutionPhase.API_CLIENT}] Failed to create API client: ${apiErr instanceof Error ? apiErr.message : String(apiErr)}`\n );\n }\n\n // ============================================\n // PHASE 3: Fetch Evaluation Data\n // ============================================\n state.currentPhase = ExecutionPhase.FETCH_EVAL_RUN;\n state.currentContext = { projectId, evalRunId, serverUrl: config.serverUrl };\n\n console.error(\n '[DEBUG-H2] fetchEvaluationData START',\n JSON.stringify({ serverUrl: config.serverUrl, timestamp: Date.now() })\n );\n\n let evalData;\n try {\n evalData = await fetchEvaluationData(api, projectId, evalRunId);\n console.error(\n '[DEBUG-H2] fetchEvaluationData SUCCESS',\n JSON.stringify({\n scenarioItemCount: evalData.scenarioItems.length,\n scenarios: evalData.scenarioItems.map((s) => s.scenario.name),\n skillsCount: evalData.skills.length,\n hasAgent: !!evalData.agent,\n timestamp: Date.now()\n })\n );\n } catch (fetchErr) {\n const errorMsg =\n fetchErr instanceof Error ? fetchErr.message : String(fetchErr);\n console.error(\n '[DEBUG-H2] fetchEvaluationData FAILED',\n JSON.stringify({\n error: errorMsg,\n stack: fetchErr instanceof Error ? fetchErr.stack : undefined,\n timestamp: Date.now()\n })\n );\n throw new Error(\n `[${ExecutionPhase.FETCH_EVAL_RUN}] Failed to fetch evaluation data: ${errorMsg}`\n );\n }\n\n const { agent, skills, scenarioItems } = evalData;\n\n // ============================================\n // PHASE 4: Validation\n // ============================================\n state.currentPhase = ExecutionPhase.VALIDATION;\n state.currentContext = {\n projectId,\n evalRunId,\n scenarioCount: scenarioItems.length,\n skillCount: skills.length,\n hasAgent: !!agent,\n agentId: evalData.evalRun.agentId,\n presetId: evalData.evalRun.presetId,\n skillIds: evalData.evalRun.skillIds\n };\n\n if (scenarioItems.length > 0 && !agent) {\n throw new Error(\n `[${ExecutionPhase.VALIDATION}] Eval run has no agent: set agentId for evaluation runs. ` +\n `(agentId: ${evalData.evalRun.agentId || 'not set'})`\n );\n }\n\n // ============================================\n // PHASE 5: Execute Scenarios\n // ============================================\n // Note: Wix auth file (~/.wix/auth/api-key.json) is written by the backend\n // before the evaluator starts, so CLI/MCP tools are already authenticated.\n let completedScenarios = 0;\n const totalScenarios = scenarioItems.length;\n\n for (const { scenario, template, resolvedAssertions } of scenarioItems) {\n state.currentPhase = ExecutionPhase.EXECUTE_SKILL;\n state.currentContext = {\n projectId,\n evalRunId,\n scenarioId: scenario.id,\n scenarioName: scenario.name,\n presetId: evalData.evalRun.presetId,\n presetName: evalData.presetName,\n agentId: agent?.id,\n agentName: agent?.name,\n progress: `${completedScenarios + 1}/${totalScenarios}`\n };\n\n const skillNames = evalData.skills.map((s) => s.name).join(', ');\n console.log(\n '[Evaluator] Running scenario with preset:',\n evalData.presetName,\n skillNames ? `(${skillNames})` : '',\n agent ? `with agent: ${agent.name}` : '',\n `(${completedScenarios + 1}/${totalScenarios})`\n );\n\n try {\n const result = await runScenario(\n config,\n evalRunId,\n scenario,\n evalData,\n template,\n resolvedAssertions\n );\n\n console.log('[Evaluator] Scenario completed, adding result');\n\n // Update phase for result reporting\n state.currentPhase = ExecutionPhase.ADD_RESULT;\n state.currentContext = {\n ...state.currentContext,\n resultId: result.id\n };\n\n await api.addResult(projectId, evalRunId, result);\n completedScenarios++;\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n const errorStack = err instanceof Error ? err.stack : undefined;\n console.error(\n '[Evaluator] Failed to run scenario with preset:',\n evalData.presetName,\n 'Error:',\n errorMsg\n );\n if (errorStack) {\n console.error('[Evaluator] Stack trace:', errorStack);\n }\n\n // Include full context in the error\n throw new Error(\n `[${state.currentPhase}] Failed to execute preset \"${evalData.presetName}\" on scenario \"${scenario.name}\": ${errorMsg}`\n );\n }\n }\n\n // ============================================\n // PHASE 6: Update Status to Completed\n // ============================================\n state.currentPhase = ExecutionPhase.UPDATE_STATUS;\n state.currentContext = {\n projectId,\n evalRunId,\n completedScenarios,\n totalScenarios\n };\n\n try {\n await api.updateEvalRun(projectId, evalRunId, {\n status: EvalStatus.COMPLETED,\n completedAt: new Date().toISOString()\n });\n } catch (updateErr) {\n throw new Error(\n `[${ExecutionPhase.UPDATE_STATUS}] Failed to update eval run status to COMPLETED: ${updateErr instanceof Error ? updateErr.message : String(updateErr)}`\n );\n }\n}\n\n// ============================================\n// Main Entry Point\n// ============================================\nconst projectId = process.argv[2];\nconst evalRunId = process.argv[3];\n\nconsole.error(\n '[EVALUATOR-BOOT] Args parsed',\n JSON.stringify({ projectId, evalRunId })\n);\n\nif (!projectId || !evalRunId) {\n console.error('Usage: evaluator <project-id> <eval-run-id>');\n process.exit(1);\n}\n\nrunEvaluation(projectId, evalRunId)\n .then(() => {\n console.error('[EVALUATOR-BOOT] runEvaluation completed successfully');\n process.exit(0);\n })\n .catch(async (err) => {\n // Extract detailed error information\n const errorDetails = formatError(err, 'main-execution', {\n projectId,\n evalRunId\n });\n const jobError = formatErrorForJobError(errorDetails);\n\n console.error('[EVALUATOR-BOOT] runEvaluation FAILED');\n console.error(\n '[EVALUATOR-BOOT] Error details:',\n JSON.stringify(errorDetails, null, 2)\n );\n\n // Try to update status to FAILED with detailed error info\n try {\n const config = loadConfig();\n const api = createApiClient(config.serverUrl, {\n apiPrefix: config.apiPrefix,\n routeHeader: config.routeHeader,\n authToken: config.authToken\n });\n await api.updateEvalRun(projectId, evalRunId, {\n status: EvalStatus.FAILED,\n completedAt: new Date().toISOString(),\n jobError,\n jobStatus: 'FAILED'\n });\n console.error(\n '[EVALUATOR-BOOT] Updated eval run status to FAILED with error details'\n );\n } catch (updateErr) {\n console.error(\n '[EVALUATOR-BOOT] Failed to update eval run status:',\n updateErr instanceof Error ? updateErr.message : String(updateErr)\n );\n\n // If config loading failed, try with minimal config from env\n try {\n const serverUrl = process.env.EVAL_SERVER_URL;\n const authToken = process.env.EVAL_AUTH_TOKEN;\n const routeHeader = process.env.EVAL_ROUTE_HEADER;\n\n if (serverUrl) {\n const api = createApiClient(serverUrl, {\n routeHeader,\n authToken\n });\n await api.updateEvalRun(projectId, evalRunId, {\n status: EvalStatus.FAILED,\n completedAt: new Date().toISOString(),\n jobError: `Config load failed, then: ${jobError}`,\n jobStatus: 'FAILED'\n });\n console.error('[EVALUATOR-BOOT] Fallback: Updated status to FAILED');\n }\n } catch (fallbackErr) {\n console.error(\n '[EVALUATOR-BOOT] Fallback also failed:',\n fallbackErr instanceof Error\n ? fallbackErr.message\n : String(fallbackErr)\n );\n }\n }\n\n process.exit(1);\n });\n", "/**\n * Evaluator Configuration\n *\n * Reads configuration from environment variables set by the server\n * when spawning the evaluator process.\n */\n\nexport interface EvaluatorConfig {\n /** Backend server URL for fetching data and reporting results */\n serverUrl: string;\n /** API path prefix (default: empty, set to \"/api/v1\" if needed for production) */\n apiPrefix: string;\n /** AI Gateway base URL for LLM calls */\n aiGatewayUrl: string;\n /** Custom headers for AI Gateway requests (parsed from \"key:value\" lines) */\n aiGatewayHeaders: Record<string, string>;\n /** Directory for storing evaluation working directories */\n evaluationsDir?: string;\n /** URL to push trace events to (for remote job execution) */\n tracePushUrl?: string;\n /**\n * Optional x-wix-route header value for deploy preview routing.\n * When set, this header is included in all API requests to route\n * them to the correct deploy preview instance.\n */\n routeHeader?: string;\n /**\n * Optional Bearer token for authenticating with public endpoints.\n * When set, this token is included as Authorization header in API requests.\n */\n authToken?: string;\n}\n\n/**\n * Load evaluator configuration from environment variables.\n *\n * @throws Error if required environment variables are missing\n */\nexport function loadConfig(): EvaluatorConfig {\n const serverUrl = process.env.EVAL_SERVER_URL;\n // API prefix: set to \"/api/v1\" if your API gateway requires it, or empty string\n const apiPrefix = process.env.EVAL_API_PREFIX || '';\n const aiGatewayUrl = process.env.AI_GATEWAY_URL;\n const aiGatewayHeadersRaw = process.env.AI_GATEWAY_HEADERS;\n const evaluationsDir = process.env.EVALUATIONS_DIR;\n\n if (!serverUrl) {\n throw new Error('EVAL_SERVER_URL environment variable is required');\n }\n if (!aiGatewayUrl) {\n throw new Error('AI_GATEWAY_URL environment variable is required');\n }\n\n // Parse headers from newline-separated \"key:value\" format\n const aiGatewayHeaders: Record<string, string> = {};\n if (aiGatewayHeadersRaw) {\n for (const line of aiGatewayHeadersRaw.split('\\n')) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n const colonIndex = trimmed.indexOf(':');\n if (colonIndex === -1) {\n throw new Error(\n `Invalid header format: \"${trimmed}\". Expected \"key:value\" format.`\n );\n }\n const key = trimmed.substring(0, colonIndex).trim();\n const value = trimmed.substring(colonIndex + 1).trim();\n aiGatewayHeaders[key] = value;\n }\n }\n\n // Always disable proxy-level caching so eval runs hit the real LLM\n aiGatewayHeaders['x-wix-ai-gateway-disable-cache'] = 'true';\n\n // Optional trace push URL for remote job execution\n const tracePushUrl = process.env.TRACE_PUSH_URL;\n\n // Optional route header for deploy preview routing\n const routeHeader = process.env.EVAL_ROUTE_HEADER;\n\n // Optional auth token for public endpoint authentication\n const authToken = process.env.EVAL_AUTH_TOKEN;\n\n return {\n serverUrl,\n apiPrefix,\n aiGatewayUrl,\n aiGatewayHeaders,\n evaluationsDir,\n tracePushUrl,\n routeHeader,\n authToken\n };\n}\n", "/**\n * API Client for fetching data from the eval server.\n */\n\nimport type {\n EvalRun,\n EvalRunResult,\n TestScenario,\n Template,\n SkillWithLatestVersion,\n SkillVersion,\n Agent,\n Preset,\n MCPEntity,\n SubAgent,\n Rule\n} from '@wix/evalforge-types';\n\nexport interface ApiClient {\n getEvalRun(projectId: string, id: string): Promise<EvalRun>;\n getScenario(projectId: string, id: string): Promise<TestScenario>;\n getSkill(projectId: string, id: string): Promise<SkillWithLatestVersion>;\n getSkillVersion(\n projectId: string,\n skillId: string,\n versionId: string\n ): Promise<SkillVersion>;\n getLatestSkillVersion(\n projectId: string,\n skillId: string\n ): Promise<SkillVersion>;\n getAgent(projectId: string, id: string): Promise<Agent>;\n getTemplate(projectId: string, id: string): Promise<Template>;\n getMcp(projectId: string, id: string): Promise<MCPEntity>;\n getSubAgent(projectId: string, id: string): Promise<SubAgent>;\n getRule(projectId: string, id: string): Promise<Rule>;\n getPreset(projectId: string, id: string): Promise<Preset>;\n addResult(\n projectId: string,\n evalRunId: string,\n result: EvalRunResult\n ): Promise<void>;\n clearResults(projectId: string, evalRunId: string): Promise<void>;\n updateEvalRun(\n projectId: string,\n evalRunId: string,\n update: Partial<EvalRun>\n ): Promise<void>;\n}\n\n/**\n * Options for creating an API client.\n */\nexport interface ApiClientOptions {\n /** API path prefix (default: empty string, set to \"/api/v1\" if needed) */\n apiPrefix?: string;\n /**\n * Optional x-wix-route header value for deploy preview routing.\n * When set, this header is included in all requests.\n */\n routeHeader?: string;\n /**\n * Optional Bearer token for authenticating with public endpoints.\n * When set, this token is included as Authorization header in all requests.\n */\n authToken?: string;\n}\n\n/**\n * Create an API client for the eval server.\n *\n * @param serverUrl - Base URL of the server (e.g., \"https://bo.wix.com/_api/evalforge-backend\")\n * @param options - Optional configuration including apiPrefix and routeHeader\n */\nexport function createApiClient(\n serverUrl: string,\n options: ApiClientOptions | string = ''\n): ApiClient {\n // Support legacy signature: createApiClient(serverUrl, apiPrefix)\n const opts: ApiClientOptions =\n typeof options === 'string' ? { apiPrefix: options } : options;\n const apiPrefix = opts.apiPrefix ?? '';\n const routeHeader = opts.routeHeader;\n const authToken = opts.authToken;\n\n // When authToken is provided, use /public prefix for all endpoints\n // This routes requests to token-authenticated public endpoints\n const pathPrefix = authToken ? '/public' : '';\n\n /**\n * Build headers for requests, including auth and route headers if configured.\n */\n function buildHeaders(\n additionalHeaders?: Record<string, string>\n ): Record<string, string> {\n const headers: Record<string, string> = { ...additionalHeaders };\n if (authToken) {\n headers['Authorization'] = `Bearer ${authToken}`;\n }\n if (routeHeader) {\n headers['x-wix-route'] = routeHeader;\n }\n return headers;\n }\n\n async function fetchJson<T>(path: string): Promise<T> {\n const url = `${serverUrl}${apiPrefix}${pathPrefix}${path}`;\n console.error(`[API] GET ${url}`);\n const headers = buildHeaders();\n const response = await fetch(url, {\n headers: Object.keys(headers).length > 0 ? headers : undefined\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(\n `API request failed: ${response.status} ${response.statusText} - ${errorText}`\n );\n }\n\n return response.json() as Promise<T>;\n }\n\n async function postJson(path: string, body: unknown): Promise<void> {\n const url = `${serverUrl}${apiPrefix}${pathPrefix}${path}`;\n console.error(`[API] POST ${url}`);\n const response = await fetch(url, {\n method: 'POST',\n headers: buildHeaders({ 'Content-Type': 'application/json' }),\n body: JSON.stringify(body)\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(\n `API request failed: ${response.status} ${response.statusText} - ${errorText}`\n );\n }\n }\n\n async function deleteRequest(path: string): Promise<void> {\n const url = `${serverUrl}${apiPrefix}${pathPrefix}${path}`;\n console.error(`[API] DELETE ${url}`);\n const headers = buildHeaders();\n const response = await fetch(url, {\n method: 'DELETE',\n headers: Object.keys(headers).length > 0 ? headers : undefined\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(\n `API request failed: ${response.status} ${response.statusText} - ${errorText}`\n );\n }\n }\n\n async function putJson(path: string, body: unknown): Promise<void> {\n const url = `${serverUrl}${apiPrefix}${pathPrefix}${path}`;\n console.error(`[API] PUT ${url}`);\n const response = await fetch(url, {\n method: 'PUT',\n headers: buildHeaders({ 'Content-Type': 'application/json' }),\n body: JSON.stringify(body)\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(\n `API request failed: ${response.status} ${response.statusText} - ${errorText}`\n );\n }\n }\n\n return {\n getEvalRun(projectId: string, id: string): Promise<EvalRun> {\n return fetchJson(`/projects/${projectId}/eval-runs/${id}`);\n },\n\n getScenario(projectId: string, id: string): Promise<TestScenario> {\n return fetchJson(`/projects/${projectId}/test-scenarios/${id}`);\n },\n\n getSkill(projectId: string, id: string): Promise<SkillWithLatestVersion> {\n return fetchJson(`/projects/${projectId}/skills/${id}`);\n },\n\n getSkillVersion(\n projectId: string,\n skillId: string,\n versionId: string\n ): Promise<SkillVersion> {\n return fetchJson(\n `/projects/${projectId}/skills/${skillId}/versions/${versionId}`\n );\n },\n\n getLatestSkillVersion(\n projectId: string,\n skillId: string\n ): Promise<SkillVersion> {\n return fetchJson(\n `/projects/${projectId}/skills/${skillId}/versions/latest`\n );\n },\n\n getAgent(projectId: string, id: string): Promise<Agent> {\n return fetchJson(`/projects/${projectId}/agents/${id}`);\n },\n\n getTemplate(projectId: string, id: string): Promise<Template> {\n return fetchJson(`/projects/${projectId}/templates/${id}`);\n },\n\n getMcp(projectId: string, id: string): Promise<MCPEntity> {\n return fetchJson(`/projects/${projectId}/mcps/${id}`);\n },\n\n getSubAgent(projectId: string, id: string): Promise<SubAgent> {\n return fetchJson(`/projects/${projectId}/sub-agents/${id}`);\n },\n\n getRule(projectId: string, id: string): Promise<Rule> {\n return fetchJson(`/projects/${projectId}/rules/${id}`);\n },\n\n getPreset(projectId: string, id: string): Promise<Preset> {\n return fetchJson(`/projects/${projectId}/presets/${id}`);\n },\n\n addResult(\n projectId: string,\n evalRunId: string,\n result: EvalRunResult\n ): Promise<void> {\n return postJson(\n `/projects/${projectId}/eval-runs/${evalRunId}/results`,\n result\n );\n },\n\n clearResults(projectId: string, evalRunId: string): Promise<void> {\n return deleteRequest(\n `/projects/${projectId}/eval-runs/${evalRunId}/results`\n );\n },\n\n updateEvalRun(\n projectId: string,\n evalRunId: string,\n update: Partial<EvalRun>\n ): Promise<void> {\n return putJson(`/projects/${projectId}/eval-runs/${evalRunId}`, update);\n }\n };\n}\n", "import type {\n EvalRun,\n TestScenario,\n SkillWithLatestVersion,\n Agent,\n Template,\n Assertion,\n MCPEntity,\n SubAgent,\n Rule\n} from '@wix/evalforge-types';\nimport {\n isSystemAssertionId,\n SYSTEM_ASSERTIONS,\n type SystemAssertionId\n} from '@wix/evalforge-types';\nimport type { ApiClient } from './api-client.js';\nimport { resolvePlaceholdersInString } from './resolve-placeholders.js';\n\n/**\n * Parse skillNames from a JSON array string stored in assertion params.\n * Params only hold primitives, so the frontend serialises the string[]\n * into a JSON string like '[\"SkillA\",\"SkillB\"]'.\n */\nexport function parseSkillNamesFromParams(value: unknown): string[] {\n if (typeof value !== 'string') {\n return [];\n }\n const parsed: unknown = JSON.parse(value);\n if (Array.isArray(parsed)) {\n return parsed.map(String);\n }\n return [];\n}\n\n/**\n * Apply parameter values to an assertion.\n * Replaces placeholder values with actual params from the scenario link.\n */\nexport function applyParamsToAssertion(\n assertion: Assertion,\n params?: Record<string, unknown>\n): Assertion {\n if (!params || Object.keys(params).length === 0) {\n return assertion;\n }\n\n // For llm_judge, replace {{param}} placeholders and apply config overrides\n if (assertion.type === 'llm_judge') {\n const stringParams: Record<string, string> = {};\n for (const [key, value] of Object.entries(params)) {\n stringParams[key] = String(value ?? '');\n }\n const prompt = resolvePlaceholdersInString(assertion.prompt, stringParams);\n\n return {\n ...assertion,\n prompt,\n ...(params.model !== undefined && { model: params.model as string }),\n ...(params.maxTokens !== undefined && {\n maxTokens: params.maxTokens as number\n }),\n ...(params.temperature !== undefined && {\n temperature: params.temperature as number\n }),\n ...(params.minScore !== undefined && {\n minScore: params.minScore as number\n })\n };\n }\n\n // For time, params override maxDurationMs directly\n if (assertion.type === 'time_limit' && params.maxDurationMs !== undefined) {\n return {\n ...assertion,\n maxDurationMs: params.maxDurationMs as number\n };\n }\n\n // For skill_was_called, parse skillNames from params (may be JSON string)\n if (\n assertion.type === 'skill_was_called' &&\n params.skillNames !== undefined\n ) {\n return {\n ...assertion,\n skillNames: parseSkillNamesFromParams(params.skillNames),\n ...(params.negate !== undefined && { negate: params.negate as boolean })\n };\n }\n\n // For tool_called_with_param, params override toolName and expectedParams directly\n if (assertion.type === 'tool_called_with_param') {\n return {\n ...assertion,\n ...(params.toolName !== undefined && {\n toolName: params.toolName as string\n }),\n ...(params.expectedParams !== undefined && {\n expectedParams: params.expectedParams as string\n }),\n ...(params.requireSuccess !== undefined && {\n requireSuccess: params.requireSuccess as boolean\n }),\n ...(params.negate !== undefined && { negate: params.negate as boolean })\n };\n }\n\n // For build_passed and cost, params override config values directly\n return { ...assertion, ...params } as Assertion;\n}\n\n/**\n * Resolve a system assertion to inline Assertion format with params applied.\n */\nexport function resolveSystemAssertion(\n assertionId: SystemAssertionId,\n params?: Record<string, unknown>\n): Assertion {\n const systemAssertion = SYSTEM_ASSERTIONS[assertionId];\n\n // Build base assertion from system assertion type\n let baseAssertion: Assertion;\n switch (systemAssertion.type) {\n case 'skill_was_called':\n baseAssertion = {\n type: 'skill_was_called',\n skillNames: parseSkillNamesFromParams(params?.skillNames),\n ...(params?.negate !== undefined && {\n negate: params.negate as boolean\n })\n };\n break;\n case 'tool_called_with_param':\n baseAssertion = {\n type: 'tool_called_with_param',\n toolName: (params?.toolName as string) ?? '',\n ...(params?.expectedParams !== undefined && {\n expectedParams: params.expectedParams as string\n }),\n ...(params?.requireSuccess !== undefined && {\n requireSuccess: params.requireSuccess as boolean\n }),\n ...(params?.negate !== undefined && {\n negate: params.negate as boolean\n })\n };\n break;\n case 'build_passed':\n baseAssertion = {\n type: 'build_passed',\n command: (params?.command as string) ?? undefined,\n expectedExitCode: (params?.expectedExitCode as number) ?? undefined\n };\n break;\n case 'time_limit':\n baseAssertion = {\n type: 'time_limit',\n maxDurationMs: (params?.maxDurationMs as number) ?? 300000\n };\n break;\n case 'cost':\n baseAssertion = {\n type: 'cost',\n maxCostUsd: (params?.maxCostUsd as number) ?? 1.0\n };\n break;\n case 'llm_judge':\n baseAssertion = {\n type: 'llm_judge',\n prompt: (params?.prompt as string) ?? '',\n minScore: params?.minScore as number | undefined,\n model: params?.model as string | undefined,\n maxTokens: params?.maxTokens as number | undefined,\n temperature: params?.temperature as number | undefined\n };\n break;\n case 'api_call':\n baseAssertion = {\n type: 'api_call',\n url: (params?.url as string) ?? '',\n expectedResponse: (params?.expectedResponse as string) ?? '{}',\n method: (params?.method as 'GET' | 'POST') ?? undefined,\n requestBody: (params?.requestBody as string) ?? undefined,\n requestHeaders: (params?.requestHeaders as string) ?? undefined,\n timeoutMs: (params?.timeoutMs as number) ?? undefined\n };\n break;\n default:\n // Should not happen for system assertions\n baseAssertion = { type: 'llm_judge', prompt: '' };\n }\n\n return baseAssertion;\n}\n\n/**\n * A scenario paired with its optional template and resolved assertions.\n */\nexport interface ScenarioItem {\n scenario: TestScenario;\n template?: Template;\n /** Resolved assertions from assertionIds (converted to inline format) */\n resolvedAssertions?: Assertion[];\n}\n\n/**\n * Data shape returned by fetchEvaluationData for the run flow.\n * Run-level agent + skills + mcps + subAgents; per-scenario template.\n */\nexport interface EvaluationData {\n evalRun: EvalRun;\n agent: Agent | null;\n skills: SkillWithLatestVersion[];\n /** Display name: preset name from DB when available, otherwise joined skill names */\n presetName: string;\n mcps: MCPEntity[];\n subAgents: SubAgent[];\n rules: Rule[];\n scenarioItems: ScenarioItem[];\n}\n\n/**\n * Fetch all data needed to run an evaluation.\n *\n * Uses evalRun.agentId and evalRun.skillIds as run-level inputs.\n * Loads skills by ID; loads code agent; loads scenarios and templates by scenario.templateId.\n *\n * @throws Error if eval run has no code agent when expected\n * @throws Error if eval run has no skills group or skills group has no skills when expected\n */\nexport async function fetchEvaluationData(\n api: ApiClient,\n projectId: string,\n evalRunId: string\n): Promise<EvaluationData> {\n const evalRun = await api.getEvalRun(projectId, evalRunId);\n\n const scenarios = await Promise.all(\n (evalRun.scenarioIds ?? []).map((id) => api.getScenario(projectId, id))\n );\n\n let agent: Agent | null = null;\n if (evalRun.agentId) {\n agent = await api.getAgent(projectId, evalRun.agentId);\n }\n\n let skills: SkillWithLatestVersion[] = [];\n const resolvedSkillIds = evalRun.skillIds ?? [];\n\n if (resolvedSkillIds.length > 0) {\n const fetchResults = await Promise.allSettled(\n resolvedSkillIds.map((id) => api.getSkill(projectId, id))\n );\n skills = fetchResults\n .filter(\n (r): r is PromiseFulfilledResult<SkillWithLatestVersion> =>\n r.status === 'fulfilled'\n )\n .map((r) => r.value)\n .filter((s) => !s.deleted);\n\n // Override latestVersion with pinned versions from the eval run\n if (\n evalRun.skillVersions &&\n Object.keys(evalRun.skillVersions).length > 0\n ) {\n skills = await Promise.all(\n skills.map(async (skill) => {\n const versionId = evalRun.skillVersions?.[skill.id];\n if (versionId) {\n const version = await api.getSkillVersion(\n projectId,\n skill.id,\n versionId\n );\n return { ...skill, latestVersion: version };\n }\n return skill;\n })\n );\n }\n\n // For GitHub-sourced skills with no pinned version, clear latestVersion\n // so writeSkillsToFilesystem fetches live from GitHub using skill.source\n skills = skills.map((skill) => {\n const hasPinnedVersion = evalRun.skillVersions?.[skill.id];\n if (!hasPinnedVersion && skill.source) {\n return { ...skill, latestVersion: undefined };\n }\n return skill;\n });\n }\n\n let mcps: MCPEntity[] = [];\n if (evalRun.mcpIds && evalRun.mcpIds.length > 0) {\n mcps = await Promise.all(\n evalRun.mcpIds.map((id) => api.getMcp(projectId, id))\n );\n }\n\n let subAgents: SubAgent[] = [];\n if (evalRun.subAgentIds && evalRun.subAgentIds.length > 0) {\n subAgents = await Promise.all(\n evalRun.subAgentIds.map((id) => api.getSubAgent(projectId, id))\n );\n }\n\n let rules: Rule[] = [];\n if (evalRun.ruleIds && evalRun.ruleIds.length > 0) {\n rules = await Promise.all(\n evalRun.ruleIds.map((id) => api.getRule(projectId, id))\n );\n }\n\n const templateIds = [\n ...new Set(\n scenarios.map((s) => s.templateId).filter((id): id is string => !!id)\n )\n ];\n const templates =\n templateIds.length > 0\n ? await Promise.all(\n templateIds.map((id) => api.getTemplate(projectId, id))\n )\n : [];\n const templateMap = new Map(templates.map((t) => [t.id, t]));\n\n const scenarioItems: ScenarioItem[] = scenarios.map((scenario) => {\n // Resolve assertion links to inline Assertion format with params applied\n const resolvedAssertions = (scenario.assertionLinks ?? [])\n .map((link) => {\n const { assertionId, params } = link;\n\n if (!isSystemAssertionId(assertionId)) {\n return null;\n }\n\n return resolveSystemAssertion(\n assertionId as SystemAssertionId,\n params as Record<string, unknown>\n );\n })\n .filter((a): a is Assertion => a !== null);\n\n return {\n scenario,\n template: scenario.templateId\n ? templateMap.get(scenario.templateId)\n : undefined,\n resolvedAssertions:\n resolvedAssertions.length > 0 ? resolvedAssertions : undefined\n };\n });\n\n let presetName = '';\n if (evalRun.presetId) {\n try {\n const preset = await api.getPreset(projectId, evalRun.presetId);\n presetName = preset.name;\n } catch {\n presetName =\n skills.length > 0 ? skills.map((s) => s.name).join(', ') : '';\n }\n } else if (skills.length > 0) {\n presetName = skills.map((s) => s.name).join(', ');\n }\n\n return {\n evalRun,\n agent,\n skills,\n presetName,\n mcps,\n subAgents,\n rules,\n scenarioItems\n };\n}\n", "/**\n * Generic `{{placeholder}}` resolution utilities.\n *\n * Provides low-level functions for detecting and replacing `{{key}}`\n * tokens inside arbitrary JSON-like values (strings, arrays, objects).\n *\n * Used by:\n * - MCP config resolution (wix-auth tokens)\n * - LLM judge assertion param substitution\n */\n\nconst PLACEHOLDER_PATTERN = /\\{\\{([^}]+)\\}\\}/g;\n\n/**\n * Find all unique placeholder keys referenced in an arbitrary value.\n * Recursively traverses strings, arrays, and plain objects.\n */\nexport function findPlaceholders(value: unknown): string[] {\n const keys = new Set<string>();\n collectPlaceholders(value, keys);\n return [...keys];\n}\n\nfunction collectPlaceholders(value: unknown, keys: Set<string>): void {\n if (typeof value === 'string') {\n for (const match of value.matchAll(PLACEHOLDER_PATTERN)) {\n keys.add(match[1].trim());\n }\n } else if (Array.isArray(value)) {\n for (const item of value) {\n collectPlaceholders(item, keys);\n }\n } else if (typeof value === 'object' && value !== null) {\n for (const val of Object.values(value)) {\n collectPlaceholders(val, keys);\n }\n }\n}\n\n/**\n * Replace `{{key}}` tokens in an arbitrary value using the given map.\n * Recursively traverses strings, arrays, and plain objects.\n * Unknown placeholders (not in `placeholders`) are left as-is.\n */\nexport function resolveValue(\n value: unknown,\n placeholders: Record<string, string>\n): unknown {\n if (typeof value === 'string') {\n return value.replace(PLACEHOLDER_PATTERN, (match, key: string) => {\n const trimmed = key.trim();\n return trimmed in placeholders ? placeholders[trimmed] : match;\n });\n }\n if (Array.isArray(value)) {\n return value.map((item) => resolveValue(item, placeholders));\n }\n if (typeof value === 'object' && value !== null) {\n const result: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value)) {\n result[k] = resolveValue(v, placeholders);\n }\n return result;\n }\n return value;\n}\n\n/**\n * Replace `{{key}}` tokens in a single string.\n * Convenience wrapper around {@link resolveValue} with a narrower return type.\n */\nexport function resolvePlaceholdersInString(\n text: string,\n placeholders: Record<string, string>\n): string {\n return resolveValue(text, placeholders) as string;\n}\n", "import type {\n EvalRunResult,\n TestScenario,\n Template\n} from '@wix/evalforge-types';\nimport {\n AssertionResultStatus,\n DEFAULT_JUDGE_MODEL\n} from '@wix/evalforge-types';\nimport {\n evaluateAssertions as evaluateAssertionsBase,\n type EvaluationInput,\n type AssertionContext\n} from '@wix/eval-assertions';\nimport type { EvaluatorConfig } from '../config.js';\nimport { prepareWorkingDirectory } from './environment.js';\nimport { runAgentWithContext } from './run-agent-with-context.js';\nimport type { Assertion } from '@wix/evalforge-types';\nimport type { EvaluationData } from '../fetch-evaluation-data.js';\n\nexport type { PartialEvalRunResult } from './types.js';\nexport type { ScenarioItem, EvaluationData } from '../fetch-evaluation-data.js';\n\n/**\n * Run a single scenario using evaluation data.\n *\n * @param config - Evaluator configuration\n * @param evalRunId - The evaluation run ID\n * @param scenario - The test scenario to run\n * @param evalData - Fetched evaluation data (skills, agent, mcps, subAgents)\n * @param template - Optional pre-fetched template entity\n * @param resolvedAssertions - Optional assertions resolved from assertionIds\n * @returns Complete evaluation result\n */\nexport async function runScenario(\n config: EvaluatorConfig,\n evalRunId: string,\n scenario: TestScenario,\n evalData: EvaluationData,\n template?: Template,\n resolvedAssertions?: Assertion[]\n): Promise<EvalRunResult> {\n const targetId =\n evalData.evalRun.presetId ?? evalData.agent?.id ?? evalData.evalRun.id;\n\n const workDir = await prepareWorkingDirectory(\n config,\n evalRunId,\n targetId,\n scenario.id,\n template\n );\n\n const partialResult = await runAgentWithContext(\n config,\n evalRunId,\n scenario,\n evalData,\n workDir\n );\n\n // Combine inline assertions with resolved assertions from assertionIds\n const inlineAssertions = scenario.assertions ?? [];\n const assertions: Assertion[] = [\n ...inlineAssertions,\n ...(resolvedAssertions ?? [])\n ];\n\n // Adapt PartialEvalRunResult to EvaluationInput for the assertions package\n // Use templateFiles to get file status (new, modified, unchanged)\n const templateFilesMap = new Map(\n (partialResult.templateFiles ?? []).map((f) => [f.path, f.status])\n );\n const evaluationInput: EvaluationInput = {\n outputText: partialResult.outputText,\n llmTrace: partialResult.llmTrace,\n fileDiffs: partialResult.fileDiffs?.map((d) => ({\n path: d.path,\n status: templateFilesMap.get(d.path) as 'new' | 'modified' | undefined\n })),\n durationMs: partialResult.duration\n };\n\n const defaultJudgeModel = DEFAULT_JUDGE_MODEL;\n const assertionContext: AssertionContext = {\n workDir,\n defaultJudgeModel,\n llmConfig: {\n baseUrl: config.aiGatewayUrl,\n headers: config.aiGatewayHeaders\n }\n };\n\n const assertionResults: EvalRunResult['assertionResults'] =\n assertions.length > 0\n ? await evaluateAssertionsBase(\n evaluationInput,\n assertions,\n assertionContext\n )\n : [];\n\n const passed = assertionResults.filter(\n (r) => r.status === AssertionResultStatus.PASSED\n ).length;\n const failed = assertionResults.filter(\n (r) => r.status === AssertionResultStatus.FAILED\n ).length;\n const total = assertionResults.length;\n const passRate = total > 0 ? Math.round((passed / total) * 100) : 100;\n\n return {\n ...partialResult,\n assertionResults,\n passed,\n failed,\n passRate\n };\n}\n", "import type { Template } from '@wix/evalforge-types';\nimport { mkdirSync, existsSync, rmSync, readFileSync, writeFileSync } from 'fs';\nimport { tmpdir } from 'os';\nimport path from 'path';\nimport type { EvaluatorConfig } from '../config.js';\nimport { fetchGitHubFolder } from '@wix/evalforge-github-client';\nimport { writeFilesToDirectory } from './utils/write-files.js';\n\n/**\n * Fetch template files from GitHub and write them to the working directory.\n */\nasync function fetchAndWriteTemplateFiles(\n template: Template,\n workDir: string\n): Promise<void> {\n if (!template.source) {\n console.warn(\n `Template \"${template.name}\" has no source configured, creating empty directory`\n );\n return;\n }\n\n const files = await fetchGitHubFolder(template.source, {\n userAgent: 'EvalForge-Evaluator'\n });\n\n await writeFilesToDirectory(workDir, files);\n}\n\nfunction writeWixEnvFile(workDir: string): void {\n const configPath = path.join(workDir, 'wix.config.json');\n if (!existsSync(configPath)) {\n return;\n }\n try {\n const config = JSON.parse(readFileSync(configPath, 'utf-8'));\n if (config.appId) {\n writeFileSync(\n path.join(workDir, '.env'),\n `WIX_CLIENT_ID=${config.appId}\\n`,\n 'utf-8'\n );\n console.log('[environment] Wrote WIX_CLIENT_ID to .env');\n }\n } catch {\n console.warn('[environment] Failed to read wix.config.json');\n }\n}\n\n/**\n * Prepare the working directory for a scenario.\n * If a template with source is provided, fetch files from GitHub.\n * If no template, create an empty directory so file creation/modification can be tracked.\n *\n * @param config - Evaluator configuration\n * @param evalRunId - The evaluation run ID\n * @param targetId - The target ID (prompt agent, skill, or agent)\n * @param scenarioId - The scenario ID (for per-scenario isolation when no template)\n * @param template - Optional pre-fetched template entity\n * @returns The working directory path\n */\nexport async function prepareWorkingDirectory(\n config: EvaluatorConfig,\n evalRunId: string,\n targetId: string,\n scenarioId: string,\n template?: Template\n): Promise<string> {\n const baseDir =\n config.evaluationsDir ?? path.join(tmpdir(), 'evalforge-evaluations');\n\n if (template) {\n if (!config.evaluationsDir) {\n console.warn(\n 'Template specified but EVALUATIONS_DIR not set, using temp directory'\n );\n }\n const workDir = path.join(baseDir, `${evalRunId}_${targetId}`);\n if (existsSync(workDir)) {\n rmSync(workDir, { recursive: true });\n }\n mkdirSync(workDir, { recursive: true });\n await fetchAndWriteTemplateFiles(template, workDir);\n console.log(`Template files written to ${workDir}`);\n writeWixEnvFile(workDir);\n return workDir;\n }\n\n const workDir = path.join(baseDir, `${evalRunId}_${targetId}_${scenarioId}`);\n if (existsSync(workDir)) {\n rmSync(workDir, { recursive: true });\n }\n mkdirSync(workDir, { recursive: true });\n console.log(`Empty working directory created at ${workDir}`);\n return workDir;\n}\n", "import { mkdir, writeFile } from 'fs/promises';\nimport { dirname, resolve, sep } from 'path';\nimport type { SkillFile } from '@wix/evalforge-types';\n\n/**\n * Write an array of {path, content} files to a target directory.\n * Validates paths to prevent directory traversal.\n */\nexport async function writeFilesToDirectory(\n targetDir: string,\n files: SkillFile[]\n): Promise<void> {\n const resolvedBase = resolve(targetDir);\n for (const file of files) {\n const filePath = resolve(targetDir, file.path);\n if (!filePath.startsWith(resolvedBase + sep) && filePath !== resolvedBase) {\n throw new Error(\n `Path traversal detected: \"${file.path}\" resolves outside target directory`\n );\n }\n await mkdir(dirname(filePath), { recursive: true });\n await writeFile(filePath, file.content, 'utf-8');\n }\n}\n", "import type { TestScenario, AgentExecutionContext } from '@wix/evalforge-types';\nimport { randomUUID } from 'crypto';\nimport type { EvaluatorConfig } from '../config.js';\nimport type { PartialEvalRunResult } from './types.js';\nimport type { EvaluationData } from '../fetch-evaluation-data.js';\nimport { getAdapter } from './agents/index.js';\nimport { simpleAgentAdapter } from './agents/simple-agent/simple-agent-adapter.js';\nimport {\n snapshotDirectory,\n diffSnapshots,\n extractTemplateFiles,\n deriveInfrastructurePaths\n} from './file-diff.js';\n\nimport { AgentRunCommand, AgentType } from '@wix/evalforge-types';\n\nconst DEFAULT_AGENT_COMMAND = AgentRunCommand.CLAUDE;\n\n/**\n * Run the agent with the full execution context (skills, MCPs, sub-agents, etc.).\n *\n * Uses the agent adapter registry to select the appropriate adapter based on\n * the agent's runCommand (for CLI agents) or adapter ID (for SDK agents).\n * If no agent is specified, defaults to 'claude'.\n *\n * @param config - Evaluator configuration\n * @param evalRunId - The evaluation run ID (for live trace context)\n * @param scenario - The test scenario to run\n * @param evalData - Fetched evaluation data (skills, agent, mcps, subAgents)\n * @param workDir - Optional working directory for the scenario\n * @returns Partial result without assertion fields\n */\nexport async function runAgentWithContext(\n config: EvaluatorConfig,\n evalRunId: string,\n scenario: TestScenario,\n evalData: EvaluationData,\n workDir?: string\n): Promise<PartialEvalRunResult> {\n const agent = evalData.agent ?? undefined;\n const isSDK = agent?.agentType === AgentType.SDK;\n\n const identifier: string = isSDK\n ? simpleAgentAdapter.id\n : (agent?.runCommand ?? DEFAULT_AGENT_COMMAND);\n const adapter = getAdapter(identifier);\n\n const startedAt = new Date().toISOString();\n\n const targetId =\n evalData.evalRun.presetId ?? agent?.id ?? evalData.evalRun.id;\n const targetName = evalData.presetName || agent?.name || '';\n\n const executionContext: AgentExecutionContext = {\n skills: evalData.skills,\n scenario,\n cwd: workDir || process.cwd(),\n modelConfig: agent?.modelConfig,\n aiGatewayUrl: config.aiGatewayUrl,\n aiGatewayHeaders: config.aiGatewayHeaders,\n traceContext: {\n evalRunId,\n scenarioId: scenario.id,\n scenarioName: scenario.name,\n targetId,\n targetName,\n tracePushUrl: config.tracePushUrl,\n routeHeader: config.routeHeader,\n authToken: config.authToken\n },\n mcps: evalData.mcps.length > 0 ? evalData.mcps : undefined,\n subAgents: evalData.subAgents.length > 0 ? evalData.subAgents : undefined,\n rules: evalData.rules?.length > 0 ? evalData.rules : undefined,\n systemPrompt: agent?.systemPrompt\n };\n\n const hasPrepare = !!adapter.prepareEnvironment;\n\n // Snapshot before prepareEnvironment to detect which files are infrastructure.\n const prePrepSnapshot =\n hasPrepare && workDir ? snapshotDirectory(workDir) : {};\n\n // Let the adapter write infrastructure files (skills, MCPs, rules, etc.)\n // *before* the baseline snapshot so they don't appear as \"new\" in diffs.\n if (hasPrepare) {\n await adapter.prepareEnvironment!(executionContext);\n }\n\n const beforeSnapshot = workDir ? snapshotDirectory(workDir) : {};\n const infrastructurePaths = hasPrepare\n ? deriveInfrastructurePaths(prePrepSnapshot, beforeSnapshot)\n : new Set<string>();\n\n const { outputText, durationMs, llmTrace, conversation } =\n await adapter.execute(executionContext);\n\n const completedAt = new Date().toISOString();\n\n const afterSnapshot = workDir ? snapshotDirectory(workDir) : {};\n const fileDiffs = diffSnapshots(\n beforeSnapshot,\n afterSnapshot,\n infrastructurePaths\n );\n const templateFiles = workDir\n ? extractTemplateFiles(beforeSnapshot, afterSnapshot, infrastructurePaths)\n : undefined;\n\n const resolvedModelConfig = agent?.modelConfig\n ?? (llmTrace?.summary.modelsUsed?.[0]\n ? { model: llmTrace.summary.modelsUsed[0] }\n : undefined);\n\n return {\n id: randomUUID(),\n targetId,\n targetName,\n scenarioId: scenario.id,\n scenarioName: scenario.name,\n modelConfig: resolvedModelConfig,\n duration: durationMs,\n outputText,\n fileDiffs: fileDiffs.length > 0 ? fileDiffs : undefined,\n templateFiles:\n templateFiles && templateFiles.length > 0 ? templateFiles : undefined,\n startedAt,\n completedAt,\n llmTrace,\n conversation\n };\n}\n", "import type { AgentAdapter } from '@wix/evalforge-types';\n\n/**\n * Registry for agent adapters.\n *\n * Supports two lookup strategies:\n * - By CLI command (e.g. 'claude') for CLI-based agents\n * - By adapter ID (e.g. 'simple-agent') for SDK-based agents\n *\n * @example\n * ```typescript\n * const registry = new AgentAdapterRegistry();\n * registry.register(new ClaudeCodeAdapter());\n *\n * const adapter = registry.resolve('claude');\n * if (adapter) {\n * const result = await adapter.execute(context);\n * }\n * ```\n */\nexport class AgentAdapterRegistry {\n /** Map of CLI commands to their registered adapters. */\n private commandMap = new Map<string, AgentAdapter>();\n\n /** Map of adapter IDs to their registered adapters. */\n private idMap = new Map<string, AgentAdapter>();\n\n /** Set of all registered adapter instances (for getAll). */\n private registeredAdapters = new Set<AgentAdapter>();\n\n /**\n * Register an agent adapter.\n *\n * The adapter is registered by its ID and for all commands in its supportedCommands array.\n * If a command or ID is already registered, it will be overwritten with a warning.\n */\n register(adapter: AgentAdapter): void {\n this.registeredAdapters.add(adapter);\n this.idMap.set(adapter.id, adapter);\n\n for (const command of adapter.supportedCommands) {\n if (this.commandMap.has(command)) {\n const existing = this.commandMap.get(command)!;\n console.warn(\n `[AgentAdapterRegistry] Command \"${command}\" already registered by adapter \"${existing.id}\". ` +\n `Overwriting with adapter \"${adapter.id}\".`\n );\n }\n this.commandMap.set(command, adapter);\n }\n }\n\n /** Get an adapter by CLI command. */\n getByCommand(command: string): AgentAdapter | undefined {\n return this.commandMap.get(command);\n }\n\n /** Get an adapter by adapter ID. */\n getById(adapterId: string): AgentAdapter | undefined {\n return this.idMap.get(adapterId);\n }\n\n /**\n * Unified lookup: tries CLI command first, then adapter ID.\n * Use this when the identifier could be either a command or an adapter ID.\n */\n resolve(identifier: string): AgentAdapter | undefined {\n return this.commandMap.get(identifier) ?? this.idMap.get(identifier);\n }\n\n /** Check if a command or adapter ID has a registered adapter. */\n has(identifier: string): boolean {\n return this.commandMap.has(identifier) || this.idMap.has(identifier);\n }\n\n /** Get all registered adapters. */\n getAll(): AgentAdapter[] {\n return Array.from(this.registeredAdapters);\n }\n\n /** Get all supported CLI commands. */\n getSupportedCommands(): string[] {\n return Array.from(this.commandMap.keys());\n }\n\n /** Get all registered adapter IDs. */\n getAdapterIds(): string[] {\n return Array.from(this.idMap.keys());\n }\n\n /**\n * Unregister an adapter by its ID.\n * Removes the adapter and all its command mappings.\n */\n unregister(adapterId: string): boolean {\n let found = false;\n\n for (const adapter of this.registeredAdapters) {\n if (adapter.id === adapterId) {\n this.registeredAdapters.delete(adapter);\n this.idMap.delete(adapterId);\n found = true;\n\n for (const command of adapter.supportedCommands) {\n if (this.commandMap.get(command) === adapter) {\n this.commandMap.delete(command);\n }\n }\n break;\n }\n }\n\n return found;\n }\n\n /** Clear all registered adapters. Primarily useful for testing. */\n clear(): void {\n this.commandMap.clear();\n this.idMap.clear();\n this.registeredAdapters.clear();\n }\n}\n\n/**\n * Default global registry instance.\n * Adapters are auto-registered here when their modules are imported.\n */\nexport const defaultRegistry = new AgentAdapterRegistry();\n\n/**\n * Get an adapter from the default registry.\n *\n * Uses unified lookup (command first, then adapter ID).\n * Throws a helpful error if the adapter is not found.\n */\nexport function getAdapter(identifier: string): AgentAdapter {\n const adapter = defaultRegistry.resolve(identifier);\n if (!adapter) {\n const commands = defaultRegistry.getSupportedCommands();\n const ids = defaultRegistry.getAdapterIds();\n throw new Error(\n `No agent adapter registered for \"${identifier}\". ` +\n `Supported commands: ${commands.length > 0 ? commands.join(', ') : '(none)'}. ` +\n `Registered adapters: ${ids.length > 0 ? ids.join(', ') : '(none)'}`\n );\n }\n return adapter;\n}\n\n/** Check if an identifier has a registered adapter in the default registry. */\nexport function hasAdapter(identifier: string): boolean {\n return defaultRegistry.has(identifier);\n}\n", "import type {\n AgentAdapter,\n AgentExecutionContext,\n AgentExecutionResult\n} from '@wix/evalforge-types';\nimport { AgentRunCommand } from '@wix/evalforge-types';\nimport {\n executeWithClaudeCode,\n prepareClaudeCodeEnvironment\n} from './execute.js';\nimport type { ClaudeCodeExecutionOptions } from './types.js';\n\n/**\n * Claude Code agent adapter.\n *\n * Implements the AgentAdapter interface for the Claude Code CLI/SDK.\n * This adapter wraps the existing executeWithClaudeCode function to provide\n * a standardized interface for the evaluation system.\n *\n * Supported commands: 'claude'\n */\nexport class ClaudeCodeAdapter implements AgentAdapter {\n readonly id = 'claude-code';\n readonly name = 'Claude Code';\n readonly supportedCommands = [AgentRunCommand.CLAUDE] as const;\n\n /**\n * Write infrastructure files (settings, MCPs, sub-agents, rules, skills)\n * before the baseline snapshot is taken.\n */\n async prepareEnvironment(context: AgentExecutionContext): Promise<void> {\n await prepareClaudeCodeEnvironment(context.cwd, context.skills, {\n mcps: context.mcps,\n subAgents: context.subAgents,\n rules: context.rules\n });\n }\n\n /**\n * Execute a skill using the Claude Code SDK.\n *\n * @param context - The agent-agnostic execution context\n * @returns The standardized execution result\n */\n async execute(context: AgentExecutionContext): Promise<AgentExecutionResult> {\n const {\n skills,\n scenario,\n cwd,\n modelConfig,\n aiGatewayUrl,\n aiGatewayHeaders,\n traceContext,\n mcps,\n subAgents,\n rules,\n systemPrompt\n } = context;\n\n // Pass the enum value directly \u2014 the proxy resolves it to the gateway model\n const modelForSdk = modelConfig?.model;\n\n const options: ClaudeCodeExecutionOptions = {\n cwd,\n model: modelForSdk,\n temperature: modelConfig?.temperature,\n maxTokens: modelConfig?.maxTokens,\n maxTurns: modelConfig?.maxTurns,\n aiGatewayUrl,\n aiGatewayHeaders,\n traceContext,\n mcps,\n subAgents,\n rules,\n systemPrompt\n };\n\n // Execute using the existing Claude Code implementation\n const { result, llmTrace, conversation } = await executeWithClaudeCode(\n skills,\n scenario,\n options\n );\n\n // Map to the agent-agnostic result format\n return {\n outputText: result.outputText,\n durationMs: result.durationMs,\n usage: {\n inputTokens: result.usage.inputTokens,\n outputTokens: result.usage.outputTokens,\n totalTokens: result.usage.totalTokens\n },\n costUsd: result.costUsd,\n llmTrace,\n conversation\n };\n }\n}\n\n/**\n * Singleton instance of the Claude Code adapter.\n */\nexport const claudeCodeAdapter = new ClaudeCodeAdapter();\n", "import type {\n SkillWithLatestVersion,\n TestScenario,\n LLMTrace,\n LiveTraceEvent,\n ConversationMessage\n} from '@wix/evalforge-types';\nimport {\n ClaudeModel,\n DEFAULT_EVALUATOR_SYSTEM_PROMPT,\n LLMStepType,\n LiveTraceEventType\n} from '@wix/evalforge-types';\nimport { writeSkillsToFilesystem } from './write-skills.js';\nimport { randomUUID } from 'crypto';\nimport type { CapturedStep } from '../../types.js';\nimport type {\n ClaudeCodeExecutionOptions,\n ClaudeCodeExecutionResult,\n TraceContext\n} from './types.js';\nimport { writeMcpToFilesystem } from './write-mcp.js';\nimport { writeSubAgentsToFilesystem } from './write-sub-agents.js';\nimport { writeRulesToFilesystem } from './write-rules.js';\nimport { buildConversation } from './build-conversation.js';\nimport { emitTraceEvent } from '../shared/trace-emit.js';\n\n/**\n * Import SDK types directly from Claude Agent SDK.\n * Type-only imports are erased at compile time - zero runtime overhead.\n * The SDK is still dynamically imported at runtime in executeWithClaudeCode().\n */\nimport type {\n SDKAssistantMessage,\n SDKResultMessage,\n SDKUserMessage,\n SDKSystemMessage,\n SDKMessage\n} from '@anthropic-ai/claude-agent-sdk' with { 'resolution-mode': 'import' };\n\n/**\n * Message with timestamp \u2014 tracks when each message was received.\n */\nexport interface TimestampedMessage {\n message: SDKMessage;\n receivedAt: Date;\n}\n\nconst DEFAULT_MODEL = ClaudeModel.CLAUDE_4_5_SONNET_1_0;\n\n/**\n * Extract a meaningful action description from tool name and arguments.\n * This provides more informative progress messages than just \"Using Tool...\".\n *\n * @param toolName - The name of the tool being used\n * @param toolArgs - JSON string of tool arguments\n * @returns A human-readable action description\n */\nfunction extractToolActionDescription(\n toolName: string | undefined,\n toolArgs: string | undefined\n): string {\n if (!toolName) {\n return 'Using tool...';\n }\n\n // Try to parse tool args for more context\n if (toolArgs) {\n try {\n const args = JSON.parse(toolArgs) as Record<string, unknown>;\n\n // Task/SubAgent tool - show the description with tool prefix\n // This makes it clear the agent is waiting for a sub-task to complete\n if (\n (toolName === 'Task' || toolName === 'dispatch_agent') &&\n args.description\n ) {\n const desc = String(args.description).slice(0, 55);\n const truncatedDesc =\n desc.length < String(args.description).length ? `${desc}...` : desc;\n return `Task: ${truncatedDesc}`;\n }\n\n // Bash/Command tool - show the command\n if (\n (toolName === 'Bash' ||\n toolName === 'bash' ||\n toolName === 'execute') &&\n args.command\n ) {\n const cmd = String(args.command).slice(0, 50);\n return `Running: ${cmd}${String(args.command).length > 50 ? '...' : ''}`;\n }\n\n // Search/Grep tool - show the query/pattern\n if (\n toolName === 'Search' ||\n toolName === 'search' ||\n toolName === 'Grep'\n ) {\n const query = args.query || args.pattern || args.search;\n if (query) {\n return `Searching: ${String(query).slice(0, 40)}`;\n }\n }\n\n // List files tool\n if (toolName === 'LS' || toolName === 'ls' || toolName === 'ListFiles') {\n const path = args.path || args.directory || '.';\n return `Listing: ${String(path).slice(0, 50)}`;\n }\n\n // Read tool with file path\n if (\n (toolName === 'Read' || toolName === 'read' || toolName === 'View') &&\n (args.file_path || args.path || args.target_file)\n ) {\n const filePath = String(\n args.file_path || args.path || args.target_file\n ).slice(0, 50);\n return `Reading: ${filePath}`;\n }\n\n // Write/Edit tool with file path\n if (\n (toolName === 'Write' || toolName === 'Edit' || toolName === 'write') &&\n (args.file_path || args.path || args.target_file)\n ) {\n const filePath = String(\n args.file_path || args.path || args.target_file\n ).slice(0, 50);\n return `Writing: ${filePath}`;\n }\n } catch {\n // Failed to parse, use default\n }\n }\n\n // Default: just show tool name\n return `Using ${toolName}...`;\n}\n\n/**\n * Create a trace event from an SDK message.\n * @param message - The SDK message to convert\n * @param context - The trace context\n * @param stepNumber - The current step number\n * @param isComplete - Whether this is the final event\n * @returns The trace event\n */\nfunction createTraceEventFromMessage(\n message: SDKAssistantMessage,\n context: TraceContext,\n stepNumber: number,\n isComplete: boolean\n): LiveTraceEvent {\n let type: LiveTraceEventType = LiveTraceEventType.COMPLETION;\n let toolName: string | undefined;\n let toolArgs: string | undefined;\n let outputPreview: string | undefined;\n let filePath: string | undefined;\n let thinking: string | undefined;\n\n for (const block of message.message.content) {\n if (block.type === 'tool_use') {\n type = LiveTraceEventType.TOOL_USE;\n toolName = block.name;\n toolArgs = JSON.stringify(block.input).slice(0, 500);\n\n const input = block.input as Record<string, unknown>;\n if (input.file_path || input.path || input.target_file) {\n filePath = String(input.file_path || input.path || input.target_file);\n if (\n block.name === 'Write' ||\n block.name === 'Edit' ||\n block.name === 'write' ||\n block.name === 'edit'\n ) {\n type = LiveTraceEventType.FILE_WRITE;\n } else if (\n block.name === 'Read' ||\n block.name === 'read' ||\n block.name === 'View'\n ) {\n type = LiveTraceEventType.FILE_READ;\n }\n }\n } else if (block.type === 'text') {\n outputPreview = block.text.slice(0, 500);\n if (!toolName) {\n type = LiveTraceEventType.COMPLETION;\n }\n } else if (block.type === 'thinking') {\n const thinkingBlock = block as { type: 'thinking'; thinking: string };\n thinking = thinkingBlock.thinking.slice(0, 500);\n if (!outputPreview && !toolName) {\n type = LiveTraceEventType.THINKING;\n }\n }\n }\n\n return {\n evalRunId: context.evalRunId,\n scenarioId: context.scenarioId,\n scenarioName: context.scenarioName,\n targetId: context.targetId,\n targetName: context.targetName,\n stepNumber,\n type,\n toolName,\n toolArgs,\n outputPreview,\n filePath,\n thinking,\n timestamp: new Date().toISOString(),\n isComplete\n };\n}\n\n/**\n * Create a trace event from any SDK message type.\n * @param message - Any SDK message\n * @param context - The trace context\n * @param stepNumber - The current step number\n * @param isComplete - Whether this is the final event\n * @returns The trace event or null if message type is not traceable\n */\nfunction createTraceEventFromAnyMessage(\n message: SDKMessage,\n context: TraceContext,\n stepNumber: number,\n isComplete: boolean\n): LiveTraceEvent | null {\n const baseEvent = {\n evalRunId: context.evalRunId,\n scenarioId: context.scenarioId,\n scenarioName: context.scenarioName,\n targetId: context.targetId,\n targetName: context.targetName,\n stepNumber,\n timestamp: new Date().toISOString(),\n isComplete\n };\n\n if (isAssistantMessage(message)) {\n return createTraceEventFromMessage(\n message,\n context,\n stepNumber,\n isComplete\n );\n }\n\n if (message.type === 'user') {\n const userMsg = message as SDKUserMessage;\n let outputPreview = '';\n\n // Extract preview from user message content\n // Content can be string or array of blocks (text or tool_result)\n const content = userMsg.message?.content;\n if (typeof content === 'string') {\n outputPreview = content.slice(0, 500);\n } else if (Array.isArray(content)) {\n for (const block of content) {\n if (typeof block !== 'object' || block === null) continue;\n const b = block as unknown as Record<string, unknown>;\n if (b.type === 'text' && typeof b.text === 'string') {\n outputPreview = b.text.slice(0, 500);\n break;\n }\n if (b.type === 'tool_result') {\n const raw = b.content;\n const preview =\n typeof raw === 'string'\n ? raw\n : Array.isArray(raw)\n ? (raw as Array<Record<string, unknown>>)\n .filter(\n (c) => c.type === 'text' && typeof c.text === 'string'\n )\n .map((c) => c.text as string)\n .join('\\n')\n : '';\n outputPreview = preview.slice(0, 500);\n break;\n }\n }\n }\n\n return {\n ...baseEvent,\n type: LiveTraceEventType.TOOL_RESULT,\n outputPreview: outputPreview || '(tool result)'\n };\n }\n\n if (message.type === 'system') {\n const sysMsg = message as SDKSystemMessage;\n // SDKSystemMessage has subtype (e.g., 'init') but no 'message' field\n return {\n ...baseEvent,\n type: LiveTraceEventType.SYSTEM,\n outputPreview: sysMsg.subtype || 'system'\n };\n }\n\n if (message.type === 'result') {\n // Result messages indicate completion, already handled elsewhere\n return null;\n }\n\n // Unknown message type - emit as generic progress\n return {\n ...baseEvent,\n type: LiveTraceEventType.PROGRESS,\n outputPreview: `Message type: ${message.type}`\n };\n}\n\n/**\n * Write all infrastructure files (settings, MCPs, sub-agents, rules, skills)\n * to the working directory. Called by the adapter's `prepareEnvironment()` so\n * that the orchestrator can take the baseline snapshot *after* infra is in place.\n */\nexport async function prepareClaudeCodeEnvironment(\n cwd: string,\n skills: SkillWithLatestVersion[],\n options: Pick<ClaudeCodeExecutionOptions, 'mcps' | 'subAgents' | 'rules'>\n): Promise<void> {\n const { mkdir: mkdirAsync, writeFile } = await import('fs/promises');\n const claudeDir = `${cwd}/.claude`;\n await mkdirAsync(claudeDir, { recursive: true });\n await writeFile(`${claudeDir}/settings.json`, '{}', {\n flag: 'wx'\n }).catch(() => {\n // File already exists \u2014 that's fine\n });\n\n if (options.mcps && options.mcps.length > 0) {\n await writeMcpToFilesystem(cwd, options.mcps);\n }\n\n if (options.subAgents && options.subAgents.length > 0) {\n await writeSubAgentsToFilesystem(cwd, options.subAgents);\n }\n\n if (options.rules && options.rules.length > 0) {\n await writeRulesToFilesystem(cwd, options.rules);\n }\n\n try {\n await writeSkillsToFilesystem(cwd, skills);\n } catch (writeError) {\n throw new Error(\n `Failed to write skills to filesystem: ${writeError instanceof Error ? writeError.message : String(writeError)}`\n );\n }\n}\n\n/**\n * Execute skills using the Claude Agent SDK.\n *\n * All skills are written to .claude/skills/<name>/SKILL.md. The SDK discovers\n * them from the filesystem; no system prompt is passed. The agent has access\n * to all skills as a group.\n *\n * @param skills - All skills to execute (each written to its own directory)\n * @param scenario - The test scenario containing the trigger prompt\n * @param options - Execution options (cwd, mcps, etc.)\n * @returns Execution result with output, usage, and LLM trace\n */\nexport async function executeWithClaudeCode(\n skills: SkillWithLatestVersion[],\n scenario: TestScenario,\n options: ClaudeCodeExecutionOptions\n): Promise<{\n result: ClaudeCodeExecutionResult;\n llmTrace: LLMTrace;\n conversation: ConversationMessage[];\n}> {\n const skillNames = skills.map((s) => s.name).join(', ');\n console.log('[executeWithClaudeCode] Starting execution', {\n skillCount: skills.length,\n skillNames,\n scenarioId: scenario.id,\n scenarioName: scenario.name,\n cwd: options.cwd,\n aiGatewayUrl: options.aiGatewayUrl,\n hasAiGatewayHeaders: !!options.aiGatewayHeaders,\n model: options.model\n });\n\n // Dynamic import for ESM module\n let query;\n try {\n const sdk = await import('@anthropic-ai/claude-agent-sdk');\n query = sdk.query;\n } catch (importError) {\n throw new Error(\n `Failed to import Claude Agent SDK: ${importError instanceof Error ? importError.message : String(importError)}`\n );\n }\n\n const startTime = new Date();\n const allMessages: TimestampedMessage[] = [];\n\n // Build environment variables for the SDK\n const sdkEnv = buildSdkEnvironment(options);\n\n // Track step number for trace events\n let traceStepNumber = 0;\n const traceContext = options.traceContext;\n\n // Track the last action for informative heartbeat messages\n let lastAction = 'Starting...';\n let lastToolName: string | undefined;\n let lastFilePath: string | undefined;\n\n // Execute the query using Claude Agent SDK\n const maxTurns = options.maxTurns ?? 10;\n\n let messageCount = 0;\n\n // Custom permission handler that auto-allows all tool usage.\n // This is used instead of 'bypassPermissions' mode because that mode\n // cannot be used when running as root (the dev machine container runs as root).\n // The Claude CLI explicitly blocks --dangerously-skip-permissions for security\n // when running with root/sudo privileges.\n // Must return both `behavior: 'allow'` and `updatedInput` to satisfy\n // the SDK's runtime Zod validation union.\n const canUseTool = async (\n _toolName: string,\n input: Record<string, unknown>\n ) => ({ behavior: 'allow' as const, updatedInput: input });\n\n const baseAllowedTools = [\n 'Skill',\n 'Read',\n 'Write',\n 'Edit',\n 'Bash',\n 'Glob',\n 'Grep',\n 'Agent',\n 'WebFetch',\n 'WebSearch'\n ];\n const allowedTools =\n (options.mcps?.length ?? 0) > 0\n ? [...baseAllowedTools, 'mcp__*']\n : baseAllowedTools;\n\n const queryOptions: Record<string, unknown> = {\n env: sdkEnv,\n cwd: options.cwd,\n settingSources: ['project'],\n allowedTools,\n model: options.model || DEFAULT_MODEL,\n maxTurns,\n maxThinkingTokens: options.maxThinkingTokens,\n // Use 'default' permission mode with custom canUseTool handler\n // instead of 'bypassPermissions' which fails on root\n permissionMode: 'default',\n canUseTool\n };\n\n // System prompt override: undefined = default behavioral instructions,\n // null or empty string = no system prompt (raw agent), non-empty string = custom prompt\n if (options.systemPrompt === null || options.systemPrompt === '') {\n // Explicitly disabled -- omit systemPrompt entirely for raw agent behavior\n } else if (options.systemPrompt != null) {\n queryOptions.systemPrompt = {\n type: 'preset',\n preset: 'claude_code',\n append: options.systemPrompt\n };\n } else {\n queryOptions.systemPrompt = {\n type: 'preset',\n preset: 'claude_code',\n append: DEFAULT_EVALUATOR_SYSTEM_PROMPT\n };\n }\n if (options.temperature !== undefined) {\n queryOptions.temperature = options.temperature;\n }\n if (options.maxTokens !== undefined) {\n queryOptions.maxTokens = options.maxTokens;\n }\n\n // Log query options (excluding env which we already logged)\n console.log('[SDK-DEBUG] Query options:');\n console.log('[SDK-DEBUG] model:', queryOptions.model);\n console.log('[SDK-DEBUG] maxTurns:', queryOptions.maxTurns);\n console.log(\n '[SDK-DEBUG] maxThinkingTokens:',\n queryOptions.maxThinkingTokens\n );\n console.log('[SDK-DEBUG] temperature:', queryOptions.temperature);\n console.log('[SDK-DEBUG] maxTokens:', queryOptions.maxTokens);\n console.log('[SDK-DEBUG] permissionMode:', queryOptions.permissionMode);\n console.log(\n '[SDK-DEBUG] canUseTool:',\n queryOptions.canUseTool ? 'custom handler (auto-allow)' : 'not set'\n );\n console.log('[SDK-DEBUG] systemPrompt:', queryOptions.systemPrompt);\n console.log('[SDK-DEBUG] settingSources:', queryOptions.settingSources);\n console.log('[SDK-DEBUG] allowedTools:', queryOptions.allowedTools);\n console.log('[SDK-DEBUG] Calling SDK query()...');\n\n // Emit a diagnostic trace event before calling the SDK\n // This helps identify if the failure happens before or during SDK execution\n if (traceContext) {\n const preExecEvent = {\n evalRunId: traceContext.evalRunId,\n scenarioId: traceContext.scenarioId,\n scenarioName: traceContext.scenarioName,\n targetId: traceContext.targetId,\n targetName: traceContext.targetName,\n stepNumber: 0,\n type: LiveTraceEventType.DIAGNOSTIC,\n outputPreview: JSON.stringify({\n event: 'pre-sdk-execution',\n model: queryOptions.model,\n maxTurns: queryOptions.maxTurns,\n sdkEnv: {\n ANTHROPIC_BASE_URL: sdkEnv.ANTHROPIC_BASE_URL,\n hasANTHROPIC_API_KEY: !!sdkEnv.ANTHROPIC_API_KEY,\n hasANTHROPIC_AUTH_TOKEN: !!sdkEnv.ANTHROPIC_AUTH_TOKEN,\n hasANTHROPIC_CUSTOM_HEADERS: !!sdkEnv.ANTHROPIC_CUSTOM_HEADERS\n },\n timestamp: new Date().toISOString()\n }),\n timestamp: new Date().toISOString(),\n isComplete: false\n };\n emitTraceEvent(\n preExecEvent,\n traceContext.tracePushUrl,\n traceContext.routeHeader,\n traceContext.authToken\n );\n }\n\n // SDK execution timeout to prevent infinite hangs\n // Default 5 minutes per skill, can be adjusted based on maxTurns\n const SDK_TIMEOUT_MS = Math.max(300000, maxTurns * 60000);\n let timeoutHandle: ReturnType<typeof setTimeout> | undefined;\n let timedOut = false;\n\n // Heartbeat interval to emit progress events every 10 seconds\n // This keeps the UI updated during long-running operations\n const HEARTBEAT_INTERVAL_MS = 10000;\n let heartbeatHandle: ReturnType<typeof setInterval> | undefined;\n const executionStartTime = Date.now();\n\n try {\n // Create timeout promise that rejects after SDK_TIMEOUT_MS\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutHandle = setTimeout(() => {\n timedOut = true;\n reject(\n new Error(\n `SDK execution timed out after ${SDK_TIMEOUT_MS}ms. ` +\n `Skills: ${skillNames}, Scenario: ${scenario.name}, ` +\n `Messages received: ${messageCount}, MaxTurns: ${maxTurns}`\n )\n );\n }, SDK_TIMEOUT_MS);\n });\n\n // Start heartbeat interval to emit progress events\n if (traceContext) {\n // Track how many heartbeats we've sent for the same action\n let lastReportedAction = '';\n let sameActionCount = 0;\n\n heartbeatHandle = setInterval(() => {\n const elapsedMs = Date.now() - executionStartTime;\n\n // Build informative progress message with last action\n let progressMessage = lastAction;\n\n // Track how long we've been on the same action\n if (lastAction === lastReportedAction) {\n sameActionCount++;\n } else {\n sameActionCount = 1;\n lastReportedAction = lastAction;\n }\n\n // For Task/sub-agent tools, show waiting status after first heartbeat\n const isTaskTool =\n lastToolName === 'Task' || lastToolName === 'dispatch_agent';\n if (isTaskTool && sameActionCount > 1) {\n // Show that we're waiting for the sub-task to complete\n progressMessage = `Waiting for ${lastAction}`;\n } else if (lastToolName && lastFilePath) {\n progressMessage = `${lastToolName}: ${lastFilePath}`;\n } else if (lastToolName && !isTaskTool) {\n progressMessage = `Using ${lastToolName}...`;\n }\n\n // Add elapsed time and step info\n const elapsedSec = Math.round(elapsedMs / 1000);\n progressMessage += ` (${elapsedSec}s, step ${traceStepNumber})`;\n\n const progressEvent: LiveTraceEvent = {\n evalRunId: traceContext.evalRunId,\n scenarioId: traceContext.scenarioId,\n scenarioName: traceContext.scenarioName,\n targetId: traceContext.targetId,\n targetName: traceContext.targetName,\n stepNumber: traceStepNumber,\n type: LiveTraceEventType.PROGRESS,\n outputPreview: progressMessage,\n toolName: lastToolName,\n filePath: lastFilePath,\n elapsedMs,\n timestamp: new Date().toISOString(),\n isComplete: false\n };\n emitTraceEvent(\n progressEvent,\n traceContext.tracePushUrl,\n traceContext.routeHeader,\n traceContext.authToken\n );\n }, HEARTBEAT_INTERVAL_MS);\n }\n\n // SDK execution promise\n const sdkPromise = (async () => {\n for await (const message of query({\n prompt: scenario.triggerPrompt,\n options: queryOptions\n })) {\n // Log all messages for debugging and capture timestamp\n messageCount++;\n const receivedAt = new Date();\n console.log('[SDK Message]', JSON.stringify(message, null, 2));\n allMessages.push({ message: message as SDKMessage, receivedAt });\n // Emit live trace events for ALL message types if trace context is provided\n if (traceContext) {\n traceStepNumber++;\n const traceEvent = createTraceEventFromAnyMessage(\n message as SDKMessage,\n traceContext,\n traceStepNumber,\n false // Not complete yet\n );\n if (traceEvent) {\n // Update last action tracking for informative heartbeats\n lastToolName = traceEvent.toolName;\n lastFilePath = traceEvent.filePath;\n if (traceEvent.type === LiveTraceEventType.THINKING) {\n lastAction = 'Thinking...';\n } else if (traceEvent.type === LiveTraceEventType.TOOL_USE) {\n // Try to extract meaningful info from tool args for better progress messages\n lastAction = extractToolActionDescription(\n traceEvent.toolName,\n traceEvent.toolArgs\n );\n } else if (traceEvent.type === LiveTraceEventType.FILE_WRITE) {\n lastAction = `Writing: ${traceEvent.filePath || 'file'}`;\n } else if (traceEvent.type === LiveTraceEventType.FILE_READ) {\n lastAction = `Reading: ${traceEvent.filePath || 'file'}`;\n } else if (traceEvent.type === LiveTraceEventType.COMPLETION) {\n lastAction = 'Processing response...';\n }\n\n emitTraceEvent(\n traceEvent,\n traceContext.tracePushUrl,\n traceContext.routeHeader,\n traceContext.authToken\n );\n }\n }\n }\n })();\n\n // Race between SDK execution and timeout\n await Promise.race([sdkPromise, timeoutPromise]);\n\n // Clear timeout and heartbeat if SDK completed successfully\n if (timeoutHandle) {\n clearTimeout(timeoutHandle);\n }\n if (heartbeatHandle) {\n clearInterval(heartbeatHandle);\n }\n\n console.log(\n '[executeWithClaudeCode] Claude Agent SDK query completed, received',\n allMessages.length,\n 'messages'\n );\n } catch (sdkError) {\n // Clear timeout and heartbeat on error\n if (timeoutHandle) {\n clearTimeout(timeoutHandle);\n }\n if (heartbeatHandle) {\n clearInterval(heartbeatHandle);\n }\n\n // Log if this was a timeout\n if (timedOut) {\n console.error('[SDK-TIMEOUT] Execution timed out:', sdkError);\n }\n // === COMPREHENSIVE ERROR DEBUGGING ===\n console.error('[SDK-ERROR] ====== CLAUDE SDK EXECUTION FAILED ======');\n console.error('[SDK-ERROR] Timestamp:', new Date().toISOString());\n console.error(\n '[SDK-ERROR] Messages received before failure:',\n messageCount\n );\n\n // Capture basic error info\n const errorMessage =\n sdkError instanceof Error ? sdkError.message : String(sdkError);\n const errorStack = sdkError instanceof Error ? sdkError.stack : undefined;\n const errorName = sdkError instanceof Error ? sdkError.name : 'Unknown';\n\n console.error('[SDK-ERROR] Error name:', errorName);\n console.error('[SDK-ERROR] Error message:', errorMessage);\n\n if (errorStack) {\n console.error('[SDK-ERROR] Full stack trace:');\n console.error(errorStack);\n }\n\n // Extract ALL properties from the error object\n if (sdkError && typeof sdkError === 'object') {\n const errObj = sdkError as Record<string, unknown>;\n console.error('[SDK-ERROR] Error object properties:');\n\n // Log all enumerable properties\n for (const key of Object.keys(errObj)) {\n const value = errObj[key];\n if (value !== undefined && key !== 'stack') {\n try {\n const valueStr =\n typeof value === 'object'\n ? JSON.stringify(value, null, 2)\n : String(value);\n console.error(`[SDK-ERROR] ${key}:`, valueStr.substring(0, 1000));\n } catch {\n console.error(`[SDK-ERROR] ${key}: [cannot serialize]`);\n }\n }\n }\n\n // Specifically check for common SDK error properties\n const sdkErrorKeys = [\n 'code',\n 'status',\n 'statusCode',\n 'statusText',\n 'stderr',\n 'stdout',\n 'output',\n 'exitCode',\n 'signal',\n 'killed',\n 'cause',\n 'reason',\n 'details',\n 'response',\n 'request',\n 'config',\n 'errno',\n 'syscall',\n 'path',\n 'spawnargs'\n ];\n\n const extraInfo: Record<string, unknown> = {};\n for (const key of sdkErrorKeys) {\n if (key in errObj && errObj[key] !== undefined) {\n extraInfo[key] = errObj[key];\n }\n }\n\n if (Object.keys(extraInfo).length > 0) {\n console.error('[SDK-ERROR] SDK-specific error details:');\n console.error(JSON.stringify(extraInfo, null, 2));\n }\n\n // Check for nested cause\n if (errObj.cause && typeof errObj.cause === 'object') {\n console.error('[SDK-ERROR] Error cause:');\n try {\n console.error(JSON.stringify(errObj.cause, null, 2));\n } catch {\n console.error('[SDK-ERROR] Error cause: [cannot serialize]');\n }\n }\n }\n\n // Log execution context\n console.error('[SDK-ERROR] Execution context:');\n console.error('[SDK-ERROR] skillCount:', skills.length);\n console.error('[SDK-ERROR] skillNames:', skillNames);\n console.error('[SDK-ERROR] scenarioId:', scenario.id);\n console.error('[SDK-ERROR] scenarioName:', scenario.name);\n console.error('[SDK-ERROR] cwd:', options.cwd);\n console.error('[SDK-ERROR] model:', options.model || DEFAULT_MODEL);\n console.error('[SDK-ERROR] aiGatewayUrl:', options.aiGatewayUrl);\n console.error(\n '[SDK-ERROR] hasAiGatewayHeaders:',\n !!options.aiGatewayHeaders\n );\n\n // Log environment info that might be relevant\n console.error('[SDK-ERROR] Environment info:');\n console.error('[SDK-ERROR] NODE_ENV:', process.env.NODE_ENV);\n console.error('[SDK-ERROR] HOME:', process.env.HOME);\n console.error('[SDK-ERROR] USER:', process.env.USER);\n console.error('[SDK-ERROR] SHELL:', process.env.SHELL);\n\n console.error('[SDK-ERROR] ==========================================');\n\n // Re-throw with comprehensive context - include ALL debug info for backend visibility\n const errObj = sdkError as Record<string, unknown>;\n\n // Capture SDK-specific properties that are critical for debugging\n const sdkSpecificInfo: Record<string, unknown> = {};\n const sdkErrorKeys = [\n 'exitCode',\n 'stderr',\n 'stdout',\n 'signal',\n 'killed',\n 'code',\n 'status',\n 'errno',\n 'syscall',\n 'spawnargs'\n ];\n for (const key of sdkErrorKeys) {\n if (errObj && key in errObj && errObj[key] !== undefined) {\n // Truncate long strings to avoid huge error messages\n const val = errObj[key];\n if (typeof val === 'string' && val.length > 500) {\n sdkSpecificInfo[key] = val.substring(0, 500) + '... [truncated]';\n } else {\n sdkSpecificInfo[key] = val;\n }\n }\n }\n\n // Capture cause if present\n let causeInfo: string | undefined;\n if (errObj?.cause && typeof errObj.cause === 'object') {\n try {\n const causeStr = JSON.stringify(errObj.cause, null, 2);\n causeInfo =\n causeStr.length > 500\n ? causeStr.substring(0, 500) + '... [truncated]'\n : causeStr;\n } catch {\n causeInfo = '[cannot serialize cause]';\n }\n }\n\n // Capture SDK environment configuration for debugging\n const sdkEnvDebug = {\n ANTHROPIC_BASE_URL: sdkEnv.ANTHROPIC_BASE_URL,\n hasANTHROPIC_API_KEY: !!sdkEnv.ANTHROPIC_API_KEY,\n hasANTHROPIC_AUTH_TOKEN: !!sdkEnv.ANTHROPIC_AUTH_TOKEN,\n hasANTHROPIC_CUSTOM_HEADERS: !!sdkEnv.ANTHROPIC_CUSTOM_HEADERS,\n ANTHROPIC_CUSTOM_HEADERS_preview: sdkEnv.ANTHROPIC_CUSTOM_HEADERS\n ? sdkEnv.ANTHROPIC_CUSTOM_HEADERS.split('\\n')\n .map((h) => h.split(':')[0])\n .join(', ')\n : undefined\n };\n\n const errorDetails = {\n messageCount,\n errorName,\n errorMessage,\n skillCount: skills.length,\n skillNames,\n scenarioId: scenario.id,\n model: options.model || DEFAULT_MODEL,\n sdkEnv: sdkEnvDebug,\n sdkError:\n Object.keys(sdkSpecificInfo).length > 0 ? sdkSpecificInfo : undefined,\n cause: causeInfo\n };\n\n // Emit error trace event for visibility in the UI\n if (traceContext) {\n const errorTraceEvent = {\n evalRunId: traceContext.evalRunId,\n scenarioId: traceContext.scenarioId,\n scenarioName: traceContext.scenarioName,\n targetId: traceContext.targetId,\n targetName: traceContext.targetName,\n stepNumber: traceStepNumber + 1,\n type: LiveTraceEventType.DIAGNOSTIC,\n outputPreview: JSON.stringify(\n {\n event: 'sdk-execution-failed',\n error: errorMessage,\n errorName,\n messageCount,\n sdkEnv: sdkEnvDebug,\n sdkError: sdkSpecificInfo,\n cause: causeInfo\n },\n null,\n 2\n ).slice(0, 2000),\n timestamp: new Date().toISOString(),\n isComplete: true\n };\n emitTraceEvent(\n errorTraceEvent,\n traceContext.tracePushUrl,\n traceContext.routeHeader,\n traceContext.authToken\n );\n }\n\n throw new Error(\n `Claude SDK execution failed after ${messageCount} messages: ${errorMessage}` +\n `\\nDetails: ${JSON.stringify(errorDetails, null, 2)}` +\n (errorStack\n ? `\\nStack: ${errorStack.split('\\n').slice(0, 5).join('\\n')}`\n : '')\n );\n }\n\n // Emit completion trace event\n if (traceContext) {\n emitTraceEvent(\n {\n evalRunId: traceContext.evalRunId,\n scenarioId: traceContext.scenarioId,\n scenarioName: traceContext.scenarioName,\n targetId: traceContext.targetId,\n targetName: traceContext.targetName,\n stepNumber: traceStepNumber + 1,\n type: LiveTraceEventType.COMPLETION,\n outputPreview: 'Scenario execution completed',\n timestamp: new Date().toISOString(),\n isComplete: true\n },\n traceContext.tracePushUrl,\n traceContext.routeHeader,\n traceContext.authToken\n );\n }\n\n const endTime = new Date();\n const totalDurationMs = endTime.getTime() - startTime.getTime();\n\n // Process messages into steps for trace building\n const { steps, result: sdkResult } = processMessages(\n allMessages,\n startTime,\n endTime\n );\n\n // Extract final output, surfacing SDK errors if no output was produced\n const rawOutput = extractFinalOutput(allMessages);\n const isError = sdkResult?.subtype !== 'success';\n let outputText = rawOutput;\n if (!rawOutput && isError) {\n const hasErrors =\n sdkResult && 'errors' in sdkResult && sdkResult.errors?.length;\n const errorDetails = hasErrors\n ? (sdkResult.errors as string[]).join('; ')\n : (sdkResult?.subtype ?? 'unknown');\n outputText = `[ERROR] Agent execution failed: ${errorDetails}`;\n }\n const usage = extractTotalUsage(sdkResult);\n\n // Build LLM trace from captured steps\n const llmTrace = buildLLMTraceFromSteps(\n steps,\n totalDurationMs,\n usage,\n options.model || DEFAULT_MODEL\n );\n\n const conversation = buildConversation(allMessages);\n\n return {\n result: {\n outputText,\n durationMs: totalDurationMs,\n usage: {\n inputTokens: usage.inputTokens,\n outputTokens: usage.outputTokens,\n totalTokens: usage.totalTokens\n },\n costUsd: usage.costUsd\n },\n llmTrace,\n conversation\n };\n}\n\n/**\n * Build environment variables for the Claude Agent SDK.\n *\n * Starts with process.env to preserve PATH and other necessary variables,\n * then adds AI Gateway configuration:\n * - ANTHROPIC_BASE_URL: The gateway URL\n * - ANTHROPIC_CUSTOM_HEADERS: Headers in \"key:value\\nkey2:value2\" format\n *\n * @param options - Execution options containing gateway configuration\n * @returns Environment variables object for the SDK\n */\nfunction buildSdkEnvironment(\n options: ClaudeCodeExecutionOptions\n): Record<string, string | undefined> {\n // Start with process.env to preserve PATH and other necessary variables\n const env: Record<string, string | undefined> = { ...process.env };\n\n // The Claude Agent SDK requires ANTHROPIC_API_KEY in the environment.\n // We use a placeholder token because actual authentication is handled by the AI Gateway\n // via ANTHROPIC_BASE_URL and ANTHROPIC_CUSTOM_HEADERS.\n // The key format matches Anthropic's API key format (sk-ant-...) to pass any validation.\n // Note: Both ANTHROPIC_API_KEY and ANTHROPIC_AUTH_TOKEN are set for compatibility\n // with different SDK versions and internal validation.\n const placeholderApiKey =\n 'sk-ant-api03-placeholder-auth-handled-by-gateway-000000000000000000000000';\n env.ANTHROPIC_API_KEY = placeholderApiKey;\n env.ANTHROPIC_AUTH_TOKEN = placeholderApiKey;\n\n // Set the base URL for the Anthropic API (points to our AI Gateway)\n if (options.aiGatewayUrl) {\n env.ANTHROPIC_BASE_URL = `${options.aiGatewayUrl}/proxy/anthropic`;\n }\n\n // Format headers as \"key:value\\nkey2:value2\"\n // These headers contain the actual authentication for the AI Gateway\n if (options.aiGatewayHeaders) {\n const headerLines = Object.entries(options.aiGatewayHeaders)\n .map(([key, value]) => `${key}:${value}`)\n .join('\\n');\n env.ANTHROPIC_CUSTOM_HEADERS = headerLines;\n }\n\n return env;\n}\n\n/**\n * Type guard for assistant messages.\n */\nfunction isAssistantMessage(\n message: SDKMessage\n): message is SDKAssistantMessage {\n return message.type === 'assistant';\n}\n\n/**\n * Type guard for result messages.\n */\nfunction isResultMessage(message: SDKMessage): message is SDKResultMessage {\n return message.type === 'result';\n}\n\n/**\n * Process SDK messages into CapturedSteps for LLM trace building.\n * Uses actual timestamps from when messages were received to calculate durations.\n */\nfunction processMessages(\n timestampedMessages: TimestampedMessage[],\n startTime: Date,\n endTime: Date\n): {\n steps: CapturedStep[];\n result?: SDKResultMessage;\n} {\n const steps: CapturedStep[] = [];\n let result: SDKResultMessage | undefined;\n\n // Group assistant messages by UUID to combine streaming chunks\n // Track both the messages and their timestamps\n const assistantMessageGroups = new Map<\n string,\n {\n messages: SDKAssistantMessage[];\n firstReceivedAt: Date;\n lastReceivedAt: Date;\n }\n >();\n\n for (const { message, receivedAt } of timestampedMessages) {\n if (isAssistantMessage(message)) {\n const uuid = message.uuid;\n if (!assistantMessageGroups.has(uuid)) {\n assistantMessageGroups.set(uuid, {\n messages: [],\n firstReceivedAt: receivedAt,\n lastReceivedAt: receivedAt\n });\n }\n const group = assistantMessageGroups.get(uuid)!;\n group.messages.push(message);\n group.lastReceivedAt = receivedAt;\n } else if (isResultMessage(message)) {\n result = message;\n }\n }\n\n // Convert to array and sort by first received time to maintain order\n const sortedGroups = Array.from(assistantMessageGroups.values()).sort(\n (a, b) => a.firstReceivedAt.getTime() - b.firstReceivedAt.getTime()\n );\n\n // Merge consecutive UUID groups that share the same input_tokens into a\n // single \"API turn\". The SDK often emits separate messages (with different\n // UUIDs) for thinking, text, and tool_use within one API call \u2014 each\n // reporting the same cumulative input_tokens.\n type MergedTurn = {\n groups: typeof sortedGroups;\n firstReceivedAt: Date;\n lastReceivedAt: Date;\n };\n const mergedTurns: MergedTurn[] = [];\n for (const group of sortedGroups) {\n const lastMsg = group.messages[group.messages.length - 1];\n const inputTokens = lastMsg.message.usage.input_tokens;\n const prev = mergedTurns[mergedTurns.length - 1];\n const prevLastMsg = prev?.groups[prev.groups.length - 1].messages.at(-1);\n const prevInputTokens = prevLastMsg?.message.usage.input_tokens;\n\n if (prev && prevInputTokens === inputTokens) {\n prev.groups.push(group);\n prev.lastReceivedAt = group.lastReceivedAt;\n } else {\n mergedTurns.push({\n groups: [group],\n firstReceivedAt: group.firstReceivedAt,\n lastReceivedAt: group.lastReceivedAt\n });\n }\n }\n\n // Build a CapturedStep from each merged turn\n for (let i = 0; i < mergedTurns.length; i++) {\n const turn = mergedTurns[i];\n const stepStartTime = turn.firstReceivedAt;\n const nextStepStartTime =\n i < mergedTurns.length - 1 ? mergedTurns[i + 1].firstReceivedAt : endTime;\n const durationMs = nextStepStartTime.getTime() - stepStartTime.getTime();\n\n let text = '';\n let thinking = '';\n const toolCalls: Array<{\n toolName: string;\n toolUseId?: string;\n args: unknown;\n }> = [];\n let lastStopReason: string | null = null;\n let inputTokens = 0;\n let outputTokens = 0;\n let cacheReadTokens: number | undefined;\n let cacheWriteTokens: number | undefined;\n\n for (const group of turn.groups) {\n const lastMessage = group.messages[group.messages.length - 1];\n lastStopReason = lastMessage.message.stop_reason;\n\n // Use usage from the last group (they're identical within a turn)\n const msgUsage = lastMessage.message.usage;\n inputTokens = msgUsage.input_tokens;\n outputTokens = msgUsage.output_tokens;\n cacheReadTokens = msgUsage.cache_read_input_tokens ?? undefined;\n cacheWriteTokens = msgUsage.cache_creation_input_tokens ?? undefined;\n\n for (const block of lastMessage.message.content) {\n if (block.type === 'text') {\n text += block.text;\n } else if (block.type === 'thinking') {\n thinking += (block as { type: 'thinking'; thinking: string })\n .thinking;\n } else if (block.type === 'tool_use') {\n toolCalls.push({\n toolName: block.name,\n toolUseId: (block as { id?: string }).id,\n args: block.input\n });\n }\n }\n }\n\n steps.push({\n text,\n thinking: thinking || undefined,\n usage: {\n inputTokens,\n outputTokens,\n totalTokens: inputTokens + outputTokens,\n cacheReadTokens: cacheReadTokens || undefined,\n cacheWriteTokens: cacheWriteTokens || undefined\n },\n finishReason: mapStopReason(lastStopReason),\n toolCalls: toolCalls.length > 0 ? toolCalls : undefined,\n startedAt: stepStartTime,\n durationMs: Math.max(0, durationMs)\n });\n }\n\n // Correlate tool results from user messages to mark tool call errors.\n // Build a map of tool_use_id \u2192 error info from user messages.\n const toolResultErrors = new Map<string, string>();\n for (const { message } of timestampedMessages) {\n if (message.type !== 'user') continue;\n const content = (message as SDKUserMessage).message?.content;\n if (!Array.isArray(content)) continue;\n for (const block of content) {\n if (typeof block !== 'object' || block === null) continue;\n const b = block as unknown as Record<string, unknown>;\n if (\n b.type === 'tool_result' &&\n b.is_error === true &&\n typeof b.tool_use_id === 'string'\n ) {\n const errorContent =\n typeof b.content === 'string'\n ? b.content\n : Array.isArray(b.content)\n ? (b.content as Array<Record<string, unknown>>)\n .filter(\n (c) => c.type === 'text' && typeof c.text === 'string'\n )\n .map((c) => c.text as string)\n .join('\\n')\n : 'Tool call failed';\n toolResultErrors.set(b.tool_use_id, errorContent.slice(0, 500));\n }\n }\n }\n\n if (toolResultErrors.size > 0) {\n for (const step of steps) {\n if (!step.toolCalls) continue;\n for (const tc of step.toolCalls) {\n if (tc.toolUseId && toolResultErrors.has(tc.toolUseId)) {\n step.hasToolError = true;\n step.toolErrorContent = toolResultErrors.get(tc.toolUseId);\n break;\n }\n }\n }\n }\n\n return { steps, result };\n}\n\n/**\n * Map Anthropic stop reason to standard finish reason.\n */\nfunction mapStopReason(stopReason: string | null): string {\n switch (stopReason) {\n case 'end_turn':\n case 'stop_sequence':\n return 'stop';\n case 'tool_use':\n return 'tool-calls';\n case 'max_tokens':\n return 'length';\n default:\n return 'unknown';\n }\n}\n\n/**\n * Extract final output text from messages.\n */\nfunction extractFinalOutput(timestampedMessages: TimestampedMessage[]): string {\n // Find the last assistant message with text content\n for (let i = timestampedMessages.length - 1; i >= 0; i--) {\n const { message } = timestampedMessages[i];\n if (isAssistantMessage(message)) {\n for (const block of message.message.content) {\n if (block.type === 'text' && block.text) {\n return block.text;\n }\n }\n }\n }\n return '';\n}\n\n/**\n * Extract total usage from result message.\n */\nfunction extractTotalUsage(result: SDKResultMessage | undefined): {\n inputTokens: number;\n outputTokens: number;\n totalTokens: number;\n costUsd?: number;\n cacheReadTokens?: number;\n cacheWriteTokens?: number;\n durationApiMs?: number;\n} {\n if (!result) {\n return { inputTokens: 0, outputTokens: 0, totalTokens: 0 };\n }\n\n const usage = result.usage;\n return {\n inputTokens: usage.input_tokens,\n outputTokens: usage.output_tokens,\n totalTokens: usage.input_tokens + usage.output_tokens,\n costUsd: result.total_cost_usd,\n cacheReadTokens: usage.cache_read_input_tokens || undefined,\n cacheWriteTokens: usage.cache_creation_input_tokens || undefined,\n durationApiMs: result.duration_api_ms || undefined\n };\n}\n\n/**\n * Build LLM trace from captured steps.\n * Calculates per-step costs using model pricing and sums tokens from steps as fallback.\n */\nfunction buildLLMTraceFromSteps(\n steps: CapturedStep[],\n totalDurationMs: number,\n usage: {\n inputTokens: number;\n outputTokens: number;\n totalTokens: number;\n costUsd?: number;\n cacheReadTokens?: number;\n cacheWriteTokens?: number;\n durationApiMs?: number;\n },\n model: string\n): LLMTrace {\n const totalCost = usage.costUsd ?? 0;\n\n // Use \"effective\" input tokens (input + cache_read + cache_write) for\n // proportion calculations. The Anthropic API reports `input_tokens`\n // excluding cached tokens, so later turns with heavy caching can report\n // near-zero input_tokens while cache_read_input_tokens is large.\n // Using only input_tokens would starve cached turns of their fair share.\n const effectiveInput = (s: CapturedStep) =>\n s.usage.inputTokens +\n (s.usage.cacheReadTokens ?? 0) +\n (s.usage.cacheWriteTokens ?? 0);\n\n // The SDK may send multiple SDKAssistantMessages per API turn (thinking,\n // text, tool_use) each with a different UUID but reporting the SAME\n // cumulative input_tokens for that turn. Detect this by comparing the\n // per-step input sum against the result's authoritative total.\n // When duplicated, fall back to distributing by duration proportion.\n const totalStepEffectiveInput = steps.reduce(\n (sum, s) => sum + effectiveInput(s),\n 0\n );\n const totalStepDuration = steps.reduce((sum, s) => sum + s.durationMs, 0);\n const authoritativeEffectiveInput =\n usage.inputTokens +\n (usage.cacheReadTokens ?? 0) +\n (usage.cacheWriteTokens ?? 0);\n // 1.2x threshold: when per-step input tokens sum to >120% of the authoritative\n // total, the SDK duplicated cumulative counts across split messages within a\n // single API turn. The 20% buffer accounts for minor rounding differences.\n const inputTokensDuplicated =\n authoritativeEffectiveInput > 0 &&\n totalStepEffectiveInput > authoritativeEffectiveInput * 1.2;\n\n const traceSteps = steps\n .flatMap((step, turnIndex) => {\n let stepPromptTokens: number;\n let stepOutputTokens: number;\n let proportion: number;\n\n if (inputTokensDuplicated) {\n proportion =\n totalStepDuration > 0 ? step.durationMs / totalStepDuration : 0;\n stepPromptTokens = Math.round(usage.inputTokens * proportion);\n stepOutputTokens = Math.round(usage.outputTokens * proportion);\n } else {\n const stepEffective = effectiveInput(step);\n proportion =\n totalStepEffectiveInput > 0\n ? stepEffective / totalStepEffectiveInput\n : 0;\n stepPromptTokens = Math.round(usage.inputTokens * proportion);\n stepOutputTokens = Math.round(usage.outputTokens * proportion);\n }\n\n const costProportion = proportion;\n const toolCallCount = step.toolCalls?.length ?? 0;\n const isSuccess = step.finishReason !== 'error' && !step.hasToolError;\n const errorMsg = step.hasToolError\n ? (step.toolErrorContent ?? 'Tool call failed')\n : step.finishReason === 'error'\n ? 'Generation failed'\n : undefined;\n\n // Build a list of sub-steps for this turn. When the SDK merges\n // thinking, text, and tool_use into a single turn we split them\n // into separate trace steps for full visibility.\n const subSteps: Array<{\n id: string;\n stepNumber: number;\n turnIndex: number;\n type: LLMStepType;\n model: string;\n provider: string;\n startedAt: string;\n durationMs: number;\n tokenUsage: { prompt: number; completion: number; total: number };\n costUsd: number;\n toolName?: string;\n toolArguments?: string;\n outputPreview?: string;\n success: boolean;\n error?: string;\n }> = [];\n\n const stepCost = totalCost * costProportion;\n const hasThinking = !!step.thinking;\n const hasText = !!step.text;\n // Count how many sub-steps we'll produce so we can distribute tokens\n const thinkingSubSteps = hasThinking ? 1 : 0;\n const toolSubSteps = toolCallCount > 0 ? toolCallCount : 0;\n const textSubSteps = hasText && toolCallCount > 0 ? 1 : 0; // text step only when tools also present\n const totalSubSteps = thinkingSubSteps + toolSubSteps + textSubSteps || 1;\n\n // Emit a THINKING sub-step when thinking co-exists with text or tools\n if (hasThinking && (hasText || toolCallCount > 0)) {\n subSteps.push({\n id: randomUUID(),\n stepNumber: 0, // renumbered below\n turnIndex,\n type: LLMStepType.THINKING,\n model,\n provider: 'anthropic',\n startedAt: step.startedAt.toISOString(),\n durationMs: Math.round(step.durationMs / totalSubSteps),\n tokenUsage: {\n prompt: Math.round(stepPromptTokens / totalSubSteps),\n completion: Math.round(stepOutputTokens / totalSubSteps),\n total: Math.round(\n (stepPromptTokens + stepOutputTokens) / totalSubSteps\n )\n },\n costUsd: stepCost / totalSubSteps,\n outputPreview: step.thinking?.slice(0, 200),\n success: isSuccess,\n error: errorMsg\n });\n }\n\n // Emit TOOL_USE sub-steps \u2014 one per tool call\n if (toolCallCount > 0) {\n for (let tcIdx = 0; tcIdx < toolCallCount; tcIdx++) {\n const tc = step.toolCalls![tcIdx];\n const isLast = tcIdx === toolCallCount - 1 && textSubSteps === 0;\n // Remaining budget after thinking step\n const toolBudgetSteps = toolSubSteps + textSubSteps;\n const toolFraction = toolBudgetSteps > 0 ? 1 / toolBudgetSteps : 1;\n const remainingFraction =\n (totalSubSteps - thinkingSubSteps) / totalSubSteps;\n\n subSteps.push({\n id: randomUUID(),\n stepNumber: 0,\n turnIndex,\n type: LLMStepType.TOOL_USE,\n model,\n provider: 'anthropic',\n startedAt: step.startedAt.toISOString(),\n durationMs: isLast\n ? step.durationMs -\n subSteps.reduce((s, ss) => s + ss.durationMs, 0)\n : Math.round(step.durationMs * remainingFraction * toolFraction),\n tokenUsage: {\n prompt: Math.round(\n stepPromptTokens * remainingFraction * toolFraction\n ),\n completion: Math.round(\n stepOutputTokens * remainingFraction * toolFraction\n ),\n total: Math.round(\n (stepPromptTokens + stepOutputTokens) *\n remainingFraction *\n toolFraction\n )\n },\n costUsd: stepCost * remainingFraction * toolFraction,\n toolName: tc.toolName,\n toolArguments: JSON.stringify(tc.args),\n outputPreview:\n tcIdx === 0 && !hasText\n ? (step.text || step.thinking)?.slice(0, 200)\n : undefined,\n success: isSuccess,\n error: errorMsg\n });\n }\n }\n\n // Emit a COMPLETION sub-step for text when tools were also present\n // (otherwise the text output would be lost)\n if (hasText && toolCallCount > 0) {\n subSteps.push({\n id: randomUUID(),\n stepNumber: 0,\n turnIndex,\n type: LLMStepType.COMPLETION,\n model,\n provider: 'anthropic',\n startedAt: step.startedAt.toISOString(),\n durationMs:\n step.durationMs - subSteps.reduce((s, ss) => s + ss.durationMs, 0),\n tokenUsage: {\n prompt:\n stepPromptTokens -\n subSteps.reduce((s, ss) => s + ss.tokenUsage.prompt, 0),\n completion:\n stepOutputTokens -\n subSteps.reduce((s, ss) => s + ss.tokenUsage.completion, 0),\n total:\n stepPromptTokens +\n stepOutputTokens -\n subSteps.reduce((s, ss) => s + ss.tokenUsage.total, 0)\n },\n costUsd: stepCost - subSteps.reduce((s, ss) => s + ss.costUsd, 0),\n outputPreview: step.text?.slice(0, 200),\n success: isSuccess,\n error: errorMsg\n });\n }\n\n // Fallback: if no sub-steps were produced (pure text or pure thinking),\n // emit a single step as before.\n if (subSteps.length === 0) {\n const stepType =\n hasThinking && !hasText\n ? LLMStepType.THINKING\n : LLMStepType.COMPLETION;\n subSteps.push({\n id: randomUUID(),\n stepNumber: 0,\n turnIndex,\n type: stepType,\n model,\n provider: 'anthropic',\n startedAt: step.startedAt.toISOString(),\n durationMs: step.durationMs,\n tokenUsage: {\n prompt: stepPromptTokens,\n completion: stepOutputTokens,\n total: stepPromptTokens + stepOutputTokens\n },\n costUsd: stepCost,\n outputPreview: (step.text || step.thinking)?.slice(0, 200),\n success: isSuccess,\n error: errorMsg\n });\n }\n\n return subSteps;\n })\n .map((s, i) => ({ ...s, stepNumber: i + 1 }));\n\n const finalTokens = {\n prompt: usage.inputTokens,\n completion: usage.outputTokens,\n total: usage.totalTokens\n };\n\n // Build stepTypeBreakdown by grouping trace steps by type\n const stepTypeBreakdown: Record<\n string,\n { count: number; durationMs: number; tokens: number; costUsd: number }\n > = {};\n for (const ts of traceSteps) {\n const entry = stepTypeBreakdown[ts.type] ?? {\n count: 0,\n durationMs: 0,\n tokens: 0,\n costUsd: 0\n };\n entry.count += 1;\n entry.durationMs += ts.durationMs;\n entry.tokens += ts.tokenUsage.total;\n entry.costUsd += ts.costUsd;\n stepTypeBreakdown[ts.type] = entry;\n }\n\n const summary = {\n totalSteps: traceSteps.length,\n totalTurns: steps.length,\n totalDurationMs,\n totalTokens: finalTokens,\n totalCostUsd: totalCost,\n modelBreakdown: {\n [model]: {\n count: traceSteps.length,\n durationMs: totalDurationMs,\n tokens: finalTokens.total,\n costUsd: totalCost\n }\n },\n modelsUsed: [model],\n stepTypeBreakdown\n };\n\n return {\n id: randomUUID(),\n steps: traceSteps,\n summary\n };\n}\n", "import { mkdir } from 'fs/promises';\nimport { join } from 'path';\nimport type {\n GitHubSource,\n SkillFile,\n SkillWithLatestVersion\n} from '@wix/evalforge-types';\nimport { fetchGitHubFolder } from '@wix/evalforge-github-client';\nimport { writeFilesToDirectory } from '../../utils/write-files.js';\n\nexport type FetchGitHubFolderFn = (\n source: GitHubSource,\n options?: { userAgent?: string }\n) => Promise<SkillFile[]>;\n\n/**\n * Write all skills to the filesystem so Claude Agent SDK can discover them.\n *\n * Content resolution:\n * 1. Pinned (version has `files`): writes all files from the stored snapshot\n * 2. Live (skill has `source`, no pinned files): fetches from GitHub at runtime\n *\n * @param cwd - Working directory where .claude/skills/ will be created\n * @param skills - All skills to write\n * @param fetchFn - Function to fetch files from GitHub (defaults to fetchGitHubFolder)\n */\nexport async function writeSkillsToFilesystem(\n cwd: string,\n skills: SkillWithLatestVersion[],\n fetchFn: FetchGitHubFolderFn = fetchGitHubFolder\n): Promise<void> {\n await Promise.all(\n skills.map((skill) => writeSkillToFilesystem(cwd, skill, fetchFn))\n );\n}\n\nexport async function writeSkillToFilesystem(\n cwd: string,\n skill: SkillWithLatestVersion,\n fetchFn: FetchGitHubFolderFn = fetchGitHubFolder\n): Promise<void> {\n const skillName = skill.name;\n const skillDir = join(cwd, '.claude', 'skills', skillName);\n await mkdir(skillDir, { recursive: true });\n\n const version = skill.latestVersion;\n\n if (version?.files && version.files.length > 0) {\n await writeFilesToDirectory(skillDir, version.files);\n console.log(\n `[Skill] ${skillName}: wrote ${version.files.length} file(s) from snapshot`\n );\n } else if (skill.source) {\n try {\n const files = await fetchFn(skill.source, {\n userAgent: 'EvalForge-Evaluator'\n });\n await writeFilesToDirectory(skillDir, files);\n console.log(\n `[Skill] ${skillName}: wrote ${files.length} file(s) from GitHub (live)`\n );\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n console.error(\n `[Skill] ${skillName}: GitHub fetch failed: ${message}, no files to fall back to`\n );\n throw new Error(\n `Failed to write skill ${skillName} to filesystem: ${message}`\n );\n }\n } else {\n throw new Error(`Skill ${skillName} has no files and no source configured`);\n }\n}\n\n/**\n * Write skill files from a snapshot array to the filesystem.\n * @deprecated Use writeFilesToDirectory from utils/write-files.ts instead\n */\nexport const writeSkillFiles = writeFilesToDirectory;\n", "import { writeFile } from 'fs/promises';\nimport { join } from 'path';\nimport type { MCPEntity } from '@wix/evalforge-types';\nimport { MCP_SERVERS_JSON_KEY } from '@wix/evalforge-types';\nimport { resolveMcpPlaceholders } from '../shared/resolve-mcp-placeholders.js';\n\n/**\n * Write .mcp.json at the project root (cwd) for Claude Code to discover MCPs.\n *\n * The config field already contains the keyed `.mcp.json` entry\n * (e.g. `{ \"wix-mcp\": { \"type\": \"http\", ... } }`), so each MCP's config\n * is spread directly into the mcpServers object.\n *\n * Any `{{placeholder}}` values in the config are resolved before writing\n * (e.g. `{{wix-auth-token}}` \u2192 token from ~/.wix/auth/api-key.json).\n *\n * @see https://code.claude.com/docs/en/mcp#mcp-installation-scopes\n * @param cwd - Working directory (project root for Claude Code)\n * @param mcps - MCP entities whose config is merged into mcpServers\n */\nexport async function writeMcpToFilesystem(\n cwd: string,\n mcps: MCPEntity[]\n): Promise<void> {\n if (mcps.length === 0) return;\n\n const mcpServers: Record<string, Record<string, unknown>> = {};\n for (const mcp of mcps) {\n const config = mcp.config as Record<string, unknown>;\n for (const [key, value] of Object.entries(config)) {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n throw new Error(\n `MCP \"${mcp.name}\" has invalid config: value for key \"${key}\" must be an object (got ${typeof value}). ` +\n 'Config must use keyed format, e.g. { \"server-name\": { \"command\": \"npx\", ... } }'\n );\n }\n mcpServers[key] = value as Record<string, unknown>;\n }\n }\n\n const resolvedServers = await resolveMcpPlaceholders(mcpServers, { cwd });\n\n const content = JSON.stringify(\n { [MCP_SERVERS_JSON_KEY]: resolvedServers },\n null,\n 2\n );\n const filePath = join(cwd, '.mcp.json');\n await writeFile(filePath, content, 'utf8');\n\n console.log(`[MCP] Written to ${filePath}`);\n}\n", "/**\n * MCP Config Placeholder Resolution\n *\n * Resolves `{{placeholder}}` patterns in MCP config values at eval startup.\n *\n * Supported placeholders:\n * - {{wix-auth-token}} \u2192 token from ~/.wix/auth/api-key.json\n * - {{wix-auth-user-id}} \u2192 userInfo.userId from api-key.json\n * - {{cwd}} \u2192 environment folder (working directory)\n */\n\nimport { readFile } from 'fs/promises';\nimport { join } from 'path';\nimport { homedir } from 'os';\nimport {\n findPlaceholders,\n resolveValue\n} from '../../../resolve-placeholders.js';\n\nexport { findPlaceholders, resolveValue };\n\nconst WIX_AUTH_FILE = join(homedir(), '.wix', 'auth', 'api-key.json');\n\ninterface WixApiKeyAuth {\n token: string;\n accountId: string;\n userInfo: {\n userId: string;\n email: string;\n };\n}\n\nexport interface ResolveMcpPlaceholdersOptions {\n cwd?: string;\n authFilePath?: string;\n}\n\n/**\n * Read Wix auth placeholders from ~/.wix/auth/api-key.json.\n * Returns an empty map when the file is missing or malformed.\n *\n * @param authFilePath - Override for testing (default: ~/.wix/auth/api-key.json)\n */\nexport async function loadWixAuthPlaceholders(\n authFilePath = WIX_AUTH_FILE\n): Promise<Record<string, string>> {\n try {\n const content = await readFile(authFilePath, 'utf-8');\n const auth = JSON.parse(content) as WixApiKeyAuth;\n\n if (!auth.token || !auth.userInfo?.userId) {\n return {};\n }\n\n return {\n 'wix-auth-token': auth.token,\n 'wix-auth-user-id': auth.userInfo.userId\n };\n } catch (err) {\n console.warn(\n `[MCP] Could not load Wix auth file: ${(err as Error).message}`\n );\n return {};\n }\n}\n\n/**\n * Resolve all `{{...}}` placeholders in an MCP server config map.\n *\n * Loads available placeholder values (Wix auth file + cwd),\n * scans the config for placeholders, and fails if any are unresolvable.\n *\n * @param mcpServers - The mcpServers map (server-name \u2192 config)\n * @param options - Optional cwd and authFilePath overrides\n * @throws When a config references placeholders that cannot be resolved\n */\nexport async function resolveMcpPlaceholders(\n mcpServers: Record<string, Record<string, unknown>>,\n options: ResolveMcpPlaceholdersOptions = {}\n): Promise<Record<string, Record<string, unknown>>> {\n const needed = findPlaceholders(mcpServers);\n if (needed.length === 0) {\n return mcpServers;\n }\n\n const placeholders: Record<string, string> = {\n ...(await loadWixAuthPlaceholders(options.authFilePath)),\n ...(options.cwd ? { cwd: options.cwd } : {})\n };\n\n const unresolved = needed.filter((key) => !(key in placeholders));\n if (unresolved.length > 0) {\n throw new Error(\n `MCP config contains unresolvable placeholders: ${unresolved.map((k) => `{{${k}}}`).join(', ')}. ` +\n 'Ensure ~/.wix/auth/api-key.json exists (run `npx @wix/cli login`).'\n );\n }\n\n console.log(`[MCP] Resolved ${needed.length} placeholder(s)`);\n\n return resolveValue(mcpServers, placeholders) as Record<\n string,\n Record<string, unknown>\n >;\n}\n", "import { mkdir, writeFile } from 'fs/promises';\nimport { join } from 'path';\nimport type { SubAgent, GitHubSource } from '@wix/evalforge-types';\nimport {\n fetchGitHubFile,\n type FetchGitHubFolderOptions\n} from '@wix/evalforge-github-client';\n\n/** Signature for the single-file GitHub fetch function (injectable for tests). */\nexport type FetchGitHubFileFn = (\n source: GitHubSource,\n options?: FetchGitHubFolderOptions\n) => Promise<string>;\n\n/** Directory where Claude Code discovers project sub-agents */\nconst AGENTS_DIR = '.claude/agents';\n\n/**\n * Build a unique, sanitized filename for a sub-agent.\n *\n * Sanitizes to lowercase alphanumeric + hyphens, falls back to\n * \"sub-agent-{index}\" for empty names, and appends a numeric suffix\n * (-2, -3, ...) when a name has already been used.\n */\nfunction toAgentFilename(\n name: string,\n index: number,\n nameCount: Map<string, number>\n): string {\n const base =\n (name || '')\n .toLowerCase()\n .replace(/\\s+/g, '-')\n .replace(/[^a-z0-9-]/g, '')\n .replace(/^-+|-+$/g, '') || `sub-agent-${index}`;\n\n const count = nameCount.get(base) ?? 0;\n nameCount.set(base, count + 1);\n\n return count === 0 ? base : `${base}-${count + 1}`;\n}\n\n/**\n * Resolve the markdown content for a sub-agent.\n * If a GitHub source is configured, live-fetches the latest .md file.\n * Throws if the fetch fails (consistent with skill content resolution).\n * Otherwise falls back to the inline subAgentMd content.\n */\nasync function resolveSubAgentContent(\n agent: SubAgent,\n fetchFn: FetchGitHubFileFn\n): Promise<string> {\n if (agent.source) {\n try {\n const content = await fetchFn(agent.source, {\n userAgent: 'EvalForge-Evaluator'\n });\n console.log(\n `[SubAgents] Fetched \"${agent.name}\" from ${agent.source.owner}/${agent.source.repo}/${agent.source.path}@${agent.source.ref}`\n );\n return content;\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n console.error(\n `[SubAgents] \"${agent.name}\": GitHub fetch failed: ${message}`\n );\n throw new Error(\n `Failed to fetch sub-agent \"${agent.name}\" from GitHub: ${message}`\n );\n }\n }\n if (!agent.subAgentMd) {\n console.warn(\n `[SubAgents] \"${agent.name}\" has empty inline content \u2013 the agent file will be blank`\n );\n }\n return agent.subAgentMd;\n}\n\n/**\n * Write sub-agent markdown files to .claude/agents/ for Claude Code to discover.\n *\n * For sub-agents with a GitHub source, the latest .md file is live-fetched.\n * For inline sub-agents, the stored subAgentMd is used directly.\n *\n * @see https://code.claude.com/docs/en/sub-agents#write-subagent-files\n * @param cwd - Working directory (project root for Claude Code)\n * @param subAgents - Sub-agent entities to write\n * @param fetchFn - Optional fetch function for testing (defaults to fetchGitHubFile)\n */\nexport async function writeSubAgentsToFilesystem(\n cwd: string,\n subAgents: SubAgent[],\n fetchFn: FetchGitHubFileFn = fetchGitHubFile\n): Promise<void> {\n if (subAgents.length === 0) return;\n\n const agentsDir = join(cwd, AGENTS_DIR);\n await mkdir(agentsDir, { recursive: true });\n\n const nameCount = new Map<string, number>();\n\n for (const [i, agent] of subAgents.entries()) {\n const filename = toAgentFilename(agent.name, i, nameCount);\n const filePath = join(agentsDir, `${filename}.md`);\n const content = await resolveSubAgentContent(agent, fetchFn);\n await writeFile(filePath, content, 'utf8');\n }\n\n console.log(`[SubAgents] Written to ${agentsDir}`);\n}\n", "import { mkdir, writeFile, readFile } from 'fs/promises';\nimport { join } from 'path';\nimport type { Rule } from '@wix/evalforge-types';\n\nconst CURSOR_RULES_DIR = '.cursor/rules';\n\n/**\n * Build a sanitized filename from a rule name.\n *\n * Sanitizes to lowercase alphanumeric + hyphens, falls back to\n * \"rule-{index}\" for empty names, and appends a numeric suffix\n * (-2, -3, ...) when a name has already been used.\n */\nfunction toRuleFilename(\n name: string,\n index: number,\n nameCount: Map<string, number>\n): string {\n const base =\n (name || '')\n .toLowerCase()\n .replace(/\\s+/g, '-')\n .replace(/[^a-z0-9-]/g, '')\n .replace(/^-+|-+$/g, '') || `rule-${index}`;\n\n const count = nameCount.get(base) ?? 0;\n nameCount.set(base, count + 1);\n\n return count === 0 ? base : `${base}-${count + 1}`;\n}\n\n/**\n * Safely append content to a file, creating it if it doesn't exist.\n * Separates appended blocks with double newlines.\n */\nasync function appendToFile(filePath: string, content: string): Promise<void> {\n let existing = '';\n try {\n existing = await readFile(filePath, 'utf8');\n } catch {\n // File doesn't exist yet\n }\n\n const merged = existing ? `${existing.trimEnd()}\\n\\n${content}` : content;\n\n await writeFile(filePath, merged, 'utf8');\n}\n\n/**\n * Write rule content to the filesystem based on each rule's `ruleType`.\n *\n * Placement:\n * - `claude-md` -> `{cwd}/CLAUDE.md` (appends if multiple)\n * - `agents-md` -> `{cwd}/AGENTS.md` (appends if multiple)\n * - `cursor-rule` -> `{cwd}/.cursor/rules/{name}.md` (one file per rule)\n *\n * @param cwd - Working directory (project root for Claude Code)\n * @param rules - Rule entities to write\n */\nexport async function writeRulesToFilesystem(\n cwd: string,\n rules: Rule[]\n): Promise<void> {\n if (rules.length === 0) return;\n\n const nameCount = new Map<string, number>();\n let hasCursorRules = false;\n\n for (const [i, rule] of rules.entries()) {\n switch (rule.ruleType) {\n case 'claude-md': {\n await appendToFile(join(cwd, 'CLAUDE.md'), rule.content);\n break;\n }\n case 'agents-md': {\n await appendToFile(join(cwd, 'AGENTS.md'), rule.content);\n break;\n }\n case 'cursor-rule': {\n if (!hasCursorRules) {\n await mkdir(join(cwd, CURSOR_RULES_DIR), { recursive: true });\n hasCursorRules = true;\n }\n const filename = toRuleFilename(rule.name, i, nameCount);\n const filePath = join(cwd, CURSOR_RULES_DIR, `${filename}.md`);\n await writeFile(filePath, rule.content, 'utf8');\n break;\n }\n }\n }\n\n console.log(`[Rules] Written ${rules.length} rule(s) to ${cwd}`);\n}\n", "import type { ConversationMessage } from '@wix/evalforge-types';\nimport type { TimestampedMessage } from './execute.js';\nimport type {\n SDKAssistantMessage,\n SDKUserMessage,\n SDKSystemMessage,\n SDKMessage\n} from '@anthropic-ai/claude-agent-sdk' with { 'resolution-mode': 'import' };\n\nfunction isAssistantMessage(\n message: SDKMessage\n): message is SDKAssistantMessage {\n return message.type === 'assistant';\n}\n\n/**\n * Build a full conversation from raw SDK messages.\n * Extracts text, thinking, tool_use, and tool_result blocks into a\n * serializable ConversationMessage array for storage and later display.\n */\nexport function buildConversation(\n timestampedMessages: TimestampedMessage[]\n): ConversationMessage[] {\n const messages: ConversationMessage[] = [];\n\n for (const { message, receivedAt } of timestampedMessages) {\n const timestamp = receivedAt.toISOString();\n\n if (isAssistantMessage(message)) {\n const content: ConversationMessage['content'] = [];\n for (const block of message.message.content) {\n if (block.type === 'text') {\n content.push({ type: 'text', text: block.text });\n } else if (block.type === 'thinking') {\n content.push({\n type: 'thinking',\n thinking: (block as { type: 'thinking'; thinking: string }).thinking\n });\n } else if (block.type === 'tool_use') {\n content.push({\n type: 'tool_use',\n toolName: block.name,\n toolId: block.id,\n input: block.input\n });\n }\n }\n if (content.length > 0) {\n messages.push({ role: 'assistant', content, timestamp });\n }\n } else if (message.type === 'user') {\n const userMsg = message as SDKUserMessage;\n const content: ConversationMessage['content'] = [];\n const msgContent = userMsg.message?.content;\n\n if (typeof msgContent === 'string') {\n content.push({ type: 'text', text: msgContent });\n } else if (Array.isArray(msgContent)) {\n for (const block of msgContent) {\n if (typeof block === 'object' && block !== null) {\n const b = block as unknown as Record<string, unknown>;\n if (b.type === 'tool_result') {\n const rawContent = b.content;\n let text = '';\n if (typeof rawContent === 'string') {\n text = rawContent;\n } else if (Array.isArray(rawContent)) {\n text = rawContent\n .filter(\n (c: unknown) =>\n typeof c === 'object' &&\n c !== null &&\n (c as Record<string, unknown>).type === 'text'\n )\n .map((c: unknown) => (c as { text: string }).text)\n .join('\\n');\n }\n content.push({\n type: 'tool_result',\n toolUseId: String(b.tool_use_id ?? ''),\n content: text,\n isError: b.is_error === true ? true : undefined\n });\n } else if (b.type === 'text' && typeof b.text === 'string') {\n content.push({ type: 'text', text: b.text });\n }\n }\n }\n }\n\n if (content.length > 0) {\n messages.push({ role: 'user', content, timestamp });\n }\n } else if (message.type === 'system') {\n const sysMsg = message as SDKSystemMessage;\n messages.push({\n role: 'system',\n content: [{ type: 'text', text: sysMsg.subtype || 'system' }],\n timestamp\n });\n }\n }\n\n return messages;\n}\n", "import type { LiveTraceEvent } from '@wix/evalforge-types';\nimport { TRACE_EVENT_PREFIX } from '@wix/evalforge-types';\n\n/**\n * Push a trace event to the backend via HTTP POST.\n * Used for remote job execution where stdout is not accessible.\n */\nasync function pushTraceEvent(\n url: string,\n event: LiveTraceEvent,\n routeHeader?: string,\n authToken?: string\n): Promise<void> {\n try {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json'\n };\n\n if (authToken) {\n headers['Authorization'] = `Bearer ${authToken}`;\n }\n\n if (routeHeader) {\n headers['x-wix-route'] = routeHeader;\n }\n\n const response = await fetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify(event)\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n console.error(\n `[Trace Push] HTTP ${response.status}: ${errorText.slice(0, 200)}`\n );\n }\n } catch (err) {\n console.error('[Trace Push] Network error:', err);\n }\n}\n\n/**\n * Emit a live trace event to stdout for the backend to capture.\n * Also pushes to HTTP endpoint if tracePushUrl is provided (for remote job execution).\n */\nexport function emitTraceEvent(\n event: LiveTraceEvent,\n tracePushUrl?: string,\n routeHeader?: string,\n authToken?: string\n): void {\n console.log(`${TRACE_EVENT_PREFIX}${JSON.stringify(event)}`);\n\n if (tracePushUrl) {\n pushTraceEvent(tracePushUrl, event, routeHeader, authToken).catch((err) => {\n console.error('[Trace Push] Failed to push trace event:', err);\n });\n }\n}\n", "/**\n * Claude Code agent adapter module.\n *\n * This module provides the Claude Code implementation of the AgentAdapter\n * interface. It wraps the @anthropic-ai/claude-agent-sdk to execute skills\n * with full LLM trace support.\n *\n * The adapter is automatically registered with the default registry when\n * this module is imported.\n */\n\n// Export the adapter class and singleton instance\nexport { ClaudeCodeAdapter, claudeCodeAdapter } from './claude-code-adapter.js';\n\n// Export the execution function for direct use if needed\nexport { executeWithClaudeCode } from './execute.js';\nexport { buildConversation } from './build-conversation.js';\n\n// Export Claude-specific types\nexport type {\n ClaudeCodeExecutionOptions,\n ClaudeCodeExecutionResult\n} from './types.js';\n\n// Re-export TraceContext from the shared types\nexport type { TraceContext } from '@wix/evalforge-types';\n\n// Register the adapter with the default registry\nimport { defaultRegistry } from '../registry.js';\nimport { claudeCodeAdapter } from './claude-code-adapter.js';\n\ndefaultRegistry.register(claudeCodeAdapter);\n", "import type {\n AgentAdapter,\n AgentExecutionContext,\n AgentExecutionResult\n} from '@wix/evalforge-types';\nimport { AgentRunCommand } from '@wix/evalforge-types';\nimport { executeWithOpenCode, prepareOpenCodeEnvironment } from './execute.js';\nimport type { OpenCodeExecutionOptions } from './types.js';\n\n/**\n * OpenCode agent adapter.\n *\n * Implements the AgentAdapter interface by spawning the `opencode` CLI\n * and parsing NDJSON events from stdout.\n *\n * Supported commands: 'opencode'\n */\nexport class OpenCodeAdapter implements AgentAdapter {\n readonly id = 'opencode';\n readonly name = 'OpenCode';\n readonly supportedCommands = [AgentRunCommand.OPENCODE] as const;\n\n async prepareEnvironment(context: AgentExecutionContext): Promise<void> {\n await prepareOpenCodeEnvironment(context.cwd, context.skills, {\n mcps: context.mcps,\n subAgents: context.subAgents,\n rules: context.rules\n });\n }\n\n async execute(context: AgentExecutionContext): Promise<AgentExecutionResult> {\n const {\n skills,\n scenario,\n cwd,\n modelConfig,\n aiGatewayUrl,\n aiGatewayHeaders,\n traceContext,\n mcps,\n subAgents,\n rules,\n systemPrompt\n } = context;\n\n const options: OpenCodeExecutionOptions = {\n cwd,\n model: modelConfig?.model,\n temperature: modelConfig?.temperature,\n maxTurns: modelConfig?.maxTurns,\n aiGatewayUrl,\n aiGatewayHeaders,\n traceContext,\n mcps,\n subAgents,\n rules,\n systemPrompt\n };\n\n const { result, llmTrace, conversation } = await executeWithOpenCode(\n skills,\n scenario,\n options\n );\n\n return {\n outputText: result.outputText,\n durationMs: result.durationMs,\n usage: {\n inputTokens: result.usage.inputTokens,\n outputTokens: result.usage.outputTokens,\n totalTokens: result.usage.totalTokens\n },\n costUsd: result.costUsd,\n llmTrace,\n conversation\n };\n }\n}\n\nexport const openCodeAdapter = new OpenCodeAdapter();\n", "import { spawn, type ChildProcess } from 'child_process';\nimport type {\n SkillWithLatestVersion,\n TestScenario,\n LLMTrace,\n LiveTraceEvent,\n ConversationMessage\n} from '@wix/evalforge-types';\nimport {\n DEFAULT_EVALUATOR_SYSTEM_PROMPT,\n LiveTraceEventType\n} from '@wix/evalforge-types';\nimport type {\n OpenCodeExecutionOptions,\n OpenCodeExecutionResult,\n OpenCodeEvent,\n OpenCodeTextEvent,\n OpenCodeToolUseEvent,\n OpenCodeStepFinishEvent,\n TimestampedOpenCodeEvent,\n TraceContext\n} from './types.js';\nimport { tryParseJson } from './types.js';\nimport { writeSkillsToFilesystem } from './write-skills.js';\nimport { writeSubAgentsToFilesystem } from './write-sub-agents.js';\nimport { writeRulesToFilesystem } from '../claude-code/write-rules.js';\nimport { buildOpenCodeEnv } from './config.js';\nimport { buildLLMTrace } from './build-trace.js';\nimport { buildConversation } from './build-conversation.js';\nimport { emitTraceEvent } from '../shared/trace-emit.js';\nimport { writeFile, mkdir } from 'fs/promises';\nimport { join } from 'path';\n\nconst KILL_GRACE_PERIOD_MS = 5_000;\nconst IDLE_TIMEOUT_MS = 120_000;\nconst IDLE_CHECK_INTERVAL_MS = 15_000;\nconst MAX_IDLE_RETRIES = 3;\n\n/**\n * Extract a human-readable action description from a tool event.\n */\nfunction extractToolAction(\n toolName: string,\n args: Record<string, unknown> | undefined\n): string {\n if (!toolName) return 'Using tool...';\n\n if (\n (toolName === 'Task' || toolName === 'dispatch_agent') &&\n args?.description\n ) {\n const desc = String(args.description).slice(0, 55);\n return `Task: ${desc}${String(args.description).length > 55 ? '...' : ''}`;\n }\n\n if (\n (toolName === 'Bash' || toolName === 'bash' || toolName === 'execute') &&\n args?.command\n ) {\n const cmd = String(args.command).slice(0, 50);\n return `Running: ${cmd}${String(args.command).length > 50 ? '...' : ''}`;\n }\n\n if (args?.file_path || args?.path || args?.target_file) {\n const filePath = String(\n args.file_path || args.path || args.target_file\n ).slice(0, 50);\n if (/write|edit/i.test(toolName)) return `Writing: ${filePath}`;\n if (/read|view/i.test(toolName)) return `Reading: ${filePath}`;\n }\n\n return `Using ${toolName}...`;\n}\n\n/**\n * Create a LiveTraceEvent from an NDJSON event.\n */\nfunction createTraceEventFromNdjson(\n evt: OpenCodeEvent,\n context: TraceContext,\n stepNumber: number,\n isComplete: boolean\n): LiveTraceEvent | null {\n const base = {\n evalRunId: context.evalRunId,\n scenarioId: context.scenarioId,\n scenarioName: context.scenarioName,\n targetId: context.targetId,\n targetName: context.targetName,\n stepNumber,\n timestamp: new Date().toISOString(),\n isComplete\n };\n\n switch (evt.type) {\n case 'text': {\n const te = evt as OpenCodeTextEvent;\n return {\n ...base,\n type: LiveTraceEventType.COMPLETION,\n outputPreview: te.part.text.slice(0, 500)\n };\n }\n case 'reasoning':\n return {\n ...base,\n type: LiveTraceEventType.THINKING,\n thinking: evt.part.text.slice(0, 500)\n };\n case 'tool_use': {\n const tu = evt as OpenCodeToolUseEvent;\n const toolName = tu.part.tool;\n const args = tu.part.state.input;\n const toolArgs = JSON.stringify(args).slice(0, 500);\n\n let type: LiveTraceEventType = LiveTraceEventType.TOOL_USE;\n let filePath: string | undefined;\n\n if (args) {\n if (args.file_path || args.path || args.target_file) {\n filePath = String(args.file_path || args.path || args.target_file);\n if (/write|edit/i.test(toolName)) {\n type = LiveTraceEventType.FILE_WRITE;\n } else if (/read|view/i.test(toolName)) {\n type = LiveTraceEventType.FILE_READ;\n }\n }\n }\n\n return { ...base, type, toolName, toolArgs, filePath };\n }\n case 'step_finish':\n return {\n ...base,\n type: LiveTraceEventType.PROGRESS,\n outputPreview: 'Step completed'\n };\n default:\n return null;\n }\n}\n\n/**\n * Write all infrastructure files (sub-agents, rules, skills)\n * to the working directory. Called by the adapter's `prepareEnvironment()` so\n * that the orchestrator can take the baseline snapshot *after* infra is in place.\n *\n * Note: MCPs for OpenCode are passed inline via config, not written to filesystem.\n */\nexport async function prepareOpenCodeEnvironment(\n cwd: string,\n skills: SkillWithLatestVersion[],\n options: Pick<OpenCodeExecutionOptions, 'mcps' | 'subAgents' | 'rules'>\n): Promise<void> {\n if (options.mcps && options.mcps.length > 0) {\n console.log(\n `[MCP] ${options.mcps.length} MCP(s) will be configured inline`\n );\n }\n\n if (options.subAgents && options.subAgents.length > 0) {\n await writeSubAgentsToFilesystem(cwd, options.subAgents);\n }\n\n if (options.rules && options.rules.length > 0) {\n await writeRulesToFilesystem(cwd, options.rules);\n }\n\n try {\n await writeSkillsToFilesystem(cwd, skills);\n } catch (writeError) {\n throw new Error(\n `Failed to write skills to filesystem: ${writeError instanceof Error ? writeError.message : String(writeError)}`\n );\n }\n}\n\n/**\n * Write the system prompt as an OpenCode rule file so it is picked up by the CLI.\n */\nasync function writeSystemPromptRule(\n cwd: string,\n systemPrompt: string\n): Promise<void> {\n const rulesDir = join(cwd, '.opencode', 'rules');\n await mkdir(rulesDir, { recursive: true });\n await writeFile(\n join(rulesDir, 'evalforge-system-prompt.md'),\n systemPrompt,\n 'utf-8'\n );\n}\n\n/**\n * Kill a process and its process group (for cleanup of MCP servers, bash, etc.).\n */\nfunction killProcess(child: ChildProcess, resolved: boolean): void {\n if (!child) return;\n\n const killSignal = (signal: NodeJS.Signals): void => {\n if (child.pid) {\n try {\n process.kill(-child.pid, signal);\n console.log(\n `[OpenCode] Sent ${signal} to process group (pid: -${child.pid})`\n );\n return;\n } catch {\n // Process group kill failed, fall back\n }\n }\n child.kill(signal);\n };\n\n killSignal('SIGTERM');\n setTimeout(() => {\n if (child && !resolved) {\n killSignal('SIGKILL');\n }\n }, KILL_GRACE_PERIOD_MS);\n}\n\n// ---------------------------------------------------------------------------\n// Retry support\n// ---------------------------------------------------------------------------\n\ninterface SpawnAttemptResult {\n events: TimestampedOpenCodeEvent[];\n success: boolean;\n isIdleTimeout: boolean;\n error?: Error;\n finalStepNumber: number;\n}\n\n/**\n * Build a summary of tool actions from events, used in the recovery prompt.\n */\nfunction summarizeToolActions(events: TimestampedOpenCodeEvent[]): string {\n const actions: string[] = [];\n for (const { event: evt } of events) {\n if (evt.type === 'tool_use') {\n const tu = evt as OpenCodeToolUseEvent;\n const tool = tu.part.tool;\n const input = tu.part.state.input;\n const filePath = input?.file_path || input?.path || input?.target_file;\n if (filePath) {\n actions.push(`- ${tool}: ${String(filePath)}`);\n } else if (input?.command) {\n actions.push(`- ${tool}: ${String(input.command).slice(0, 80)}`);\n } else {\n actions.push(`- ${tool}`);\n }\n }\n }\n return actions.length > 0 ? actions.join('\\n') : '(no tool actions recorded)';\n}\n\n/**\n * Build a recovery prompt for retrying after an idle timeout.\n * Tells the agent to continue the original task, noting what was already done.\n */\nfunction buildRecoveryPrompt(\n originalPrompt: string,\n events: TimestampedOpenCodeEvent[]\n): string {\n const toolSummary = summarizeToolActions(events);\n return `You are continuing a task that was interrupted due to a session error.\n\nORIGINAL TASK:\n${originalPrompt}\n\nACTIONS ALREADY COMPLETED IN THE PREVIOUS SESSION:\n${toolSummary}\n\nINSTRUCTIONS:\n1. Review the actions listed above that were already completed in the previous session\n2. Check the filesystem to verify what was already done\n3. Continue with any remaining work needed to fulfill the original task\n4. Do NOT redo work that is already done \u2014 only continue from where the previous session left off`;\n}\n\n/**\n * Spawn a single OpenCode process, collect NDJSON events, and return the result.\n * Always resolves (never rejects) so the caller can inspect the result and retry.\n *\n * @see https://github.com/anomalyco/opencode/issues/13230 - Memory leak causes OOM\n * @see https://github.com/anomalyco/opencode/issues/13841 - LLM connection stalls\n */\nfunction spawnOpenCodeProcess(opts: {\n args: string[];\n env: NodeJS.ProcessEnv;\n cwd: string;\n skillNames: string;\n scenarioName: string;\n sdkTimeoutMs: number;\n traceContext?: TraceContext;\n initialStepNumber: number;\n}): Promise<SpawnAttemptResult> {\n const {\n args,\n env,\n cwd,\n skillNames,\n scenarioName,\n sdkTimeoutMs,\n traceContext,\n initialStepNumber\n } = opts;\n\n return new Promise((resolve) => {\n let resolved = false;\n let stderr = '';\n let lineBuffer = '';\n let lastOutputTime = Date.now();\n let traceStepNumber = initialStepNumber;\n let lastAction = 'Starting...';\n let lastToolName: string | undefined;\n let lastFilePath: string | undefined;\n\n const events: TimestampedOpenCodeEvent[] = [];\n\n const timers: {\n timeout?: ReturnType<typeof setTimeout>;\n idleCheck?: ReturnType<typeof setInterval>;\n heartbeat?: ReturnType<typeof setInterval>;\n } = {};\n\n const cleanup = (): void => {\n if (timers.timeout) clearTimeout(timers.timeout);\n if (timers.idleCheck) clearInterval(timers.idleCheck);\n if (timers.heartbeat) clearInterval(timers.heartbeat);\n };\n\n const finalize = (\n success: boolean,\n isIdleTimeout: boolean,\n error?: Error\n ): void => {\n if (resolved) return;\n resolved = true;\n cleanup();\n\n resolve({\n events,\n success,\n isIdleTimeout,\n error,\n finalStepNumber: traceStepNumber\n });\n };\n\n // Spawn the process\n let child: ChildProcess;\n try {\n child = spawn('opencode', args, {\n cwd,\n env,\n stdio: ['ignore', 'pipe', 'pipe'],\n detached: true\n });\n } catch (spawnError) {\n resolve({\n events: [],\n success: false,\n isIdleTimeout: false,\n error: new Error(\n `Failed to spawn opencode: ${spawnError instanceof Error ? spawnError.message : String(spawnError)}`\n ),\n finalStepNumber: traceStepNumber\n });\n return;\n }\n\n // Total timeout\n timers.timeout = setTimeout(() => {\n if (!resolved) {\n console.error(`[OpenCode] Process timed out after ${sdkTimeoutMs}ms`);\n killProcess(child, resolved);\n finalize(\n false,\n false,\n new Error(\n `OpenCode execution timed out after ${sdkTimeoutMs}ms. ` +\n `Skills: ${skillNames}, Scenario: ${scenarioName}`\n )\n );\n }\n }, sdkTimeoutMs);\n\n // Idle watchdog\n timers.idleCheck = setInterval(() => {\n if (resolved) return;\n const idleTime = Date.now() - lastOutputTime;\n if (idleTime >= IDLE_TIMEOUT_MS) {\n console.warn(\n `[OpenCode] Process appears stuck - no output for ${Math.round(idleTime / 1000)}s. Killing process.`\n );\n killProcess(child, resolved);\n finalize(\n false,\n true,\n new Error(\n `OpenCode process stuck - no output for ${Math.round(idleTime / 1000)} seconds (idle timeout). ` +\n `Skills: ${skillNames}, Scenario: ${scenarioName}`\n )\n );\n }\n }, IDLE_CHECK_INTERVAL_MS);\n\n // Heartbeat for live tracing\n if (traceContext) {\n const executionStartTime = Date.now();\n let lastReportedAction = '';\n let sameActionCount = 0;\n\n timers.heartbeat = setInterval(() => {\n const elapsedMs = Date.now() - executionStartTime;\n let progressMessage = lastAction;\n\n if (lastAction === lastReportedAction) {\n sameActionCount++;\n } else {\n sameActionCount = 1;\n lastReportedAction = lastAction;\n }\n\n const isTaskTool =\n lastToolName === 'Task' || lastToolName === 'dispatch_agent';\n if (isTaskTool && sameActionCount > 1) {\n progressMessage = `Waiting for ${lastAction}`;\n } else if (lastToolName && lastFilePath) {\n progressMessage = `${lastToolName}: ${lastFilePath}`;\n } else if (lastToolName && !isTaskTool) {\n progressMessage = `Using ${lastToolName}...`;\n }\n\n const elapsedSec = Math.round(elapsedMs / 1000);\n progressMessage += ` (${elapsedSec}s, step ${traceStepNumber})`;\n\n emitTraceEvent(\n {\n evalRunId: traceContext.evalRunId,\n scenarioId: traceContext.scenarioId,\n scenarioName: traceContext.scenarioName,\n targetId: traceContext.targetId,\n targetName: traceContext.targetName,\n stepNumber: traceStepNumber,\n type: LiveTraceEventType.PROGRESS,\n outputPreview: progressMessage,\n toolName: lastToolName,\n filePath: lastFilePath,\n elapsedMs,\n timestamp: new Date().toISOString(),\n isComplete: false\n },\n traceContext.tracePushUrl,\n traceContext.routeHeader,\n traceContext.authToken\n );\n }, 10_000);\n }\n\n // Process stdout (NDJSON lines)\n child.stdout?.on('data', (data: Buffer) => {\n const text = data.toString();\n lastOutputTime = Date.now();\n\n lineBuffer += text;\n const lines = lineBuffer.split('\\n');\n lineBuffer = lines.pop() || '';\n\n for (const line of lines) {\n if (!line.trim()) continue;\n\n const evt = tryParseJson<OpenCodeEvent>(line);\n if (!evt || !evt.type) continue;\n\n events.push({ event: evt, receivedAt: Date.now() });\n\n // Live tracing\n if (traceContext) {\n traceStepNumber++;\n const traceEvt = createTraceEventFromNdjson(\n evt,\n traceContext,\n traceStepNumber,\n false\n );\n if (traceEvt) {\n lastToolName = traceEvt.toolName;\n lastFilePath = traceEvt.filePath;\n if (traceEvt.type === LiveTraceEventType.THINKING) {\n lastAction = 'Thinking...';\n } else if (traceEvt.type === LiveTraceEventType.TOOL_USE) {\n lastAction = extractToolAction(\n traceEvt.toolName ?? '',\n undefined\n );\n } else if (traceEvt.type === LiveTraceEventType.FILE_WRITE) {\n lastAction = `Writing: ${traceEvt.filePath || 'file'}`;\n } else if (traceEvt.type === LiveTraceEventType.FILE_READ) {\n lastAction = `Reading: ${traceEvt.filePath || 'file'}`;\n } else if (traceEvt.type === LiveTraceEventType.COMPLETION) {\n lastAction = 'Processing response...';\n }\n emitTraceEvent(\n traceEvt,\n traceContext.tracePushUrl,\n traceContext.routeHeader,\n traceContext.authToken\n );\n }\n }\n }\n });\n\n // Process stderr\n child.stderr?.on('data', (data: Buffer) => {\n const text = data.toString();\n stderr += text;\n lastOutputTime = Date.now();\n });\n\n // Handle process close\n child.on('close', (code) => {\n // Flush remaining line buffer\n if (lineBuffer.trim()) {\n const evt = tryParseJson<OpenCodeEvent>(lineBuffer);\n if (evt && evt.type) {\n events.push({ event: evt, receivedAt: Date.now() });\n }\n }\n\n console.log(\n `[executeWithOpenCode] Process exited with code ${code}, ${events.length} events collected`\n );\n\n if (code === 0) {\n finalize(true, false);\n } else {\n finalize(\n false,\n false,\n new Error(\n `OpenCode CLI exited with code ${code}.\\nStderr: ${stderr.slice(0, 1000)}`\n )\n );\n }\n });\n\n // Handle spawn errors\n child.on('error', (error) => {\n finalize(\n false,\n false,\n new Error(`OpenCode CLI spawn error: ${error.message}`)\n );\n });\n });\n}\n\n/**\n * Execute skills using the OpenCode CLI with automatic retry on idle timeouts.\n *\n * When the OpenCode process stalls (no output for 120s), it is killed and\n * retried with a recovery prompt that carries context about work already done.\n * This works around known OpenCode hanging issues where the upstream LLM\n * connection stalls mid-stream.\n *\n * @see https://github.com/anomalyco/opencode/issues/13230 - Memory leak causes OOM\n * @see https://github.com/anomalyco/opencode/issues/13841 - LLM connection stalls\n */\nexport async function executeWithOpenCode(\n skills: SkillWithLatestVersion[],\n scenario: TestScenario,\n options: OpenCodeExecutionOptions\n): Promise<{\n result: OpenCodeExecutionResult;\n llmTrace: LLMTrace;\n conversation: ConversationMessage[];\n}> {\n const skillNames = skills.map((s) => s.name).join(', ');\n console.log('[executeWithOpenCode] Starting execution', {\n skillCount: skills.length,\n skillNames,\n scenarioId: scenario.id,\n scenarioName: scenario.name,\n cwd: options.cwd,\n aiGatewayUrl: options.aiGatewayUrl,\n hasAiGatewayHeaders: !!options.aiGatewayHeaders,\n model: options.model\n });\n\n const startTime = new Date();\n const maxTurns = options.maxTurns ?? 10;\n const sdkTimeoutMs = Math.max(300_000, maxTurns * 60_000);\n\n const { env, providerID, modelID } = await buildOpenCodeEnv({\n model: options.model,\n temperature: options.temperature,\n maxTurns,\n aiGatewayUrl: options.aiGatewayUrl,\n aiGatewayHeaders: options.aiGatewayHeaders,\n mcps: options.mcps,\n cwd: options.cwd\n });\n\n const traceContext = options.traceContext;\n\n // Emit pre-execution diagnostic\n if (traceContext) {\n emitTraceEvent(\n {\n evalRunId: traceContext.evalRunId,\n scenarioId: traceContext.scenarioId,\n scenarioName: traceContext.scenarioName,\n targetId: traceContext.targetId,\n targetName: traceContext.targetName,\n stepNumber: 0,\n type: LiveTraceEventType.DIAGNOSTIC,\n outputPreview: JSON.stringify({\n event: 'pre-cli-execution',\n model: `${providerID}/${modelID}`,\n maxTurns,\n timestamp: new Date().toISOString()\n }),\n timestamp: new Date().toISOString(),\n isComplete: false\n },\n traceContext.tracePushUrl,\n traceContext.routeHeader,\n traceContext.authToken\n );\n }\n\n // Write system prompt as a rule file\n let systemPrompt: string | undefined;\n if (options.systemPrompt === null || options.systemPrompt === '') {\n // Explicitly disabled\n } else if (options.systemPrompt != null) {\n systemPrompt = options.systemPrompt;\n } else {\n systemPrompt = DEFAULT_EVALUATOR_SYSTEM_PROMPT;\n }\n if (systemPrompt) {\n await writeSystemPromptRule(options.cwd, systemPrompt);\n }\n\n // Build base CLI args (prompt is appended per attempt)\n const baseArgs = [\n 'run',\n '--format',\n 'json',\n '--thinking',\n '--variant',\n 'high',\n '--model',\n `${providerID}/${modelID}`,\n '--dir',\n options.cwd\n ];\n\n // Retry loop \u2014 on idle timeout, kill the process and retry with recovery context\n const accumulatedEvents: TimestampedOpenCodeEvent[] = [];\n let traceStepNumber = 0;\n let lastAttemptResult: SpawnAttemptResult | undefined;\n\n for (let attempt = 1; attempt <= MAX_IDLE_RETRIES; attempt++) {\n const prompt =\n attempt === 1\n ? scenario.triggerPrompt\n : buildRecoveryPrompt(scenario.triggerPrompt, accumulatedEvents);\n\n if (attempt > 1) {\n console.log(\n `[OpenCode] Retry attempt ${attempt}/${MAX_IDLE_RETRIES} \u2014 starting fresh session with recovery context`\n );\n if (traceContext) {\n emitTraceEvent(\n {\n evalRunId: traceContext.evalRunId,\n scenarioId: traceContext.scenarioId,\n scenarioName: traceContext.scenarioName,\n targetId: traceContext.targetId,\n targetName: traceContext.targetName,\n stepNumber: traceStepNumber + 1,\n type: LiveTraceEventType.DIAGNOSTIC,\n outputPreview: JSON.stringify({\n event: 'idle-timeout-retry',\n attempt,\n maxRetries: MAX_IDLE_RETRIES,\n eventsFromPreviousAttempts: accumulatedEvents.length\n }),\n timestamp: new Date().toISOString(),\n isComplete: false\n },\n traceContext.tracePushUrl,\n traceContext.routeHeader,\n traceContext.authToken\n );\n }\n }\n\n const args = [...baseArgs, prompt];\n console.log(\n `[executeWithOpenCode] Spawning attempt ${attempt}: opencode`,\n args.slice(0, 5)\n );\n\n lastAttemptResult = await spawnOpenCodeProcess({\n args,\n env,\n cwd: options.cwd,\n skillNames,\n scenarioName: scenario.name,\n sdkTimeoutMs,\n traceContext,\n initialStepNumber: traceStepNumber\n });\n\n accumulatedEvents.push(...lastAttemptResult.events);\n traceStepNumber = lastAttemptResult.finalStepNumber;\n\n if (lastAttemptResult.success) {\n break;\n }\n\n if (!lastAttemptResult.isIdleTimeout || attempt >= MAX_IDLE_RETRIES) {\n // Non-retryable error or all retries exhausted\n if (traceContext) {\n emitTraceEvent(\n {\n evalRunId: traceContext.evalRunId,\n scenarioId: traceContext.scenarioId,\n scenarioName: traceContext.scenarioName,\n targetId: traceContext.targetId,\n targetName: traceContext.targetName,\n stepNumber: traceStepNumber + 1,\n type: LiveTraceEventType.DIAGNOSTIC,\n outputPreview: JSON.stringify({\n event: 'cli-execution-failed',\n error: lastAttemptResult.error?.message ?? 'Unknown error',\n attempt,\n isIdleTimeout: lastAttemptResult.isIdleTimeout\n }).slice(0, 2000),\n timestamp: new Date().toISOString(),\n isComplete: true\n },\n traceContext.tracePushUrl,\n traceContext.routeHeader,\n traceContext.authToken\n );\n }\n throw (\n lastAttemptResult.error ??\n new Error(\n `OpenCode CLI execution failed.\\nAttempt: ${attempt}, Events: ${accumulatedEvents.length}`\n )\n );\n }\n\n console.warn(\n `[OpenCode] Attempt ${attempt} failed due to idle timeout, will retry`\n );\n }\n\n // Build final result from accumulated events across all attempts\n const endTime = new Date();\n const totalDurationMs = endTime.getTime() - startTime.getTime();\n\n let outputText = '';\n for (const { event: evt } of accumulatedEvents) {\n if (evt.type === 'text') {\n outputText += (evt as OpenCodeTextEvent).part.text;\n }\n }\n\n if (!outputText) {\n throw new Error(\n 'Agent produced no text output. ' +\n `Model: ${providerID}/${modelID}, Events: ${accumulatedEvents.length}`\n );\n }\n\n let inputTokens = 0;\n let outputTokens = 0;\n let costUsd = 0;\n for (const { event: evt } of accumulatedEvents) {\n if (evt.type === 'step_finish') {\n const sf = evt as OpenCodeStepFinishEvent;\n inputTokens += sf.part.tokens.input;\n outputTokens += sf.part.tokens.output;\n costUsd += sf.part.cost;\n }\n }\n\n // Emit completion trace event\n if (traceContext) {\n emitTraceEvent(\n {\n evalRunId: traceContext.evalRunId,\n scenarioId: traceContext.scenarioId,\n scenarioName: traceContext.scenarioName,\n targetId: traceContext.targetId,\n targetName: traceContext.targetName,\n stepNumber: traceStepNumber + 1,\n type: LiveTraceEventType.COMPLETION,\n outputPreview: 'Scenario execution completed',\n timestamp: new Date().toISOString(),\n isComplete: true\n },\n traceContext.tracePushUrl,\n traceContext.routeHeader,\n traceContext.authToken\n );\n }\n\n const modelStr = options.model || `${providerID}/${modelID}`;\n const llmTrace = buildLLMTrace(\n accumulatedEvents,\n totalDurationMs,\n modelStr,\n providerID,\n startTime\n );\n const conversation = buildConversation(accumulatedEvents);\n\n return {\n result: {\n outputText,\n durationMs: totalDurationMs,\n usage: {\n inputTokens,\n outputTokens,\n totalTokens: inputTokens + outputTokens\n },\n costUsd\n },\n llmTrace,\n conversation\n };\n}\n", "import type { MCPEntity, SubAgent, Rule } from '@wix/evalforge-types';\n\nexport type { TraceContext } from '@wix/evalforge-types';\n\n// ---------------------------------------------------------------------------\n// NDJSON event types emitted by `opencode run --format json`\n// ---------------------------------------------------------------------------\n\nexport interface OpenCodeTextEvent {\n type: 'text';\n part: { text: string };\n}\n\nexport interface OpenCodeReasoningEvent {\n type: 'reasoning';\n part: { text: string };\n}\n\nexport interface OpenCodeToolUseEvent {\n type: 'tool_use';\n part: {\n tool: string;\n callID: string;\n state: {\n status: string;\n input?: Record<string, unknown>;\n output?: string;\n error?: string;\n title?: string;\n metadata?: Record<string, unknown>;\n };\n };\n}\n\nexport interface OpenCodeStepFinishEvent {\n type: 'step_finish';\n part: {\n reason: string;\n cost: number;\n tokens: {\n total: number;\n input: number;\n output: number;\n reasoning: number;\n cache: { read: number; write: number };\n };\n modelID?: string;\n providerID?: string;\n };\n}\n\nexport type OpenCodeEvent =\n | OpenCodeTextEvent\n | OpenCodeReasoningEvent\n | OpenCodeToolUseEvent\n | OpenCodeStepFinishEvent;\n\nexport interface TimestampedOpenCodeEvent {\n event: OpenCodeEvent;\n receivedAt: number;\n}\n\n// ---------------------------------------------------------------------------\n// Execution options & result\n// ---------------------------------------------------------------------------\n\nexport interface OpenCodeExecutionOptions {\n cwd: string;\n mcps?: MCPEntity[];\n subAgents?: SubAgent[];\n rules?: Rule[];\n model?: string;\n temperature?: number;\n maxTurns?: number;\n aiGatewayUrl?: string;\n aiGatewayHeaders?: Record<string, string>;\n traceContext?: import('@wix/evalforge-types').TraceContext;\n systemPrompt?: string | null;\n}\n\nexport interface OpenCodeExecutionResult {\n outputText: string;\n durationMs: number;\n usage: {\n inputTokens: number;\n outputTokens: number;\n totalTokens: number;\n };\n costUsd?: number;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nexport function tryParseJson<T>(text: string): T | null {\n try {\n return JSON.parse(text) as T;\n } catch {\n return null;\n }\n}\n", "import { mkdir } from 'fs/promises';\nimport { join } from 'path';\nimport type {\n GitHubSource,\n SkillFile,\n SkillWithLatestVersion\n} from '@wix/evalforge-types';\nimport { fetchGitHubFolder } from '@wix/evalforge-github-client';\nimport { writeFilesToDirectory } from '../../utils/write-files.js';\n\nexport type FetchGitHubFolderFn = (\n source: GitHubSource,\n options?: { userAgent?: string }\n) => Promise<SkillFile[]>;\n\n/**\n * Write all skills to .opencode/skills/ so OpenCode can discover them.\n *\n * Content resolution:\n * 1. Pinned (version has `files`): writes all files from the stored snapshot\n * 2. Live (skill has `source`, no pinned files): fetches from GitHub at runtime\n */\nexport async function writeSkillsToFilesystem(\n cwd: string,\n skills: SkillWithLatestVersion[],\n fetchFn: FetchGitHubFolderFn = fetchGitHubFolder\n): Promise<void> {\n await Promise.all(\n skills.map((skill) => writeSkillToFilesystem(cwd, skill, fetchFn))\n );\n}\n\nasync function writeSkillToFilesystem(\n cwd: string,\n skill: SkillWithLatestVersion,\n fetchFn: FetchGitHubFolderFn\n): Promise<void> {\n const skillName = skill.name;\n const skillDir = join(cwd, '.opencode', 'skills', skillName);\n await mkdir(skillDir, { recursive: true });\n\n const version = skill.latestVersion;\n\n if (version?.files && version.files.length > 0) {\n await writeFilesToDirectory(skillDir, version.files);\n console.log(\n `[Skill] ${skillName}: wrote ${version.files.length} file(s) from snapshot`\n );\n } else if (skill.source) {\n try {\n const files = await fetchFn(skill.source, {\n userAgent: 'EvalForge-Evaluator'\n });\n await writeFilesToDirectory(skillDir, files);\n console.log(\n `[Skill] ${skillName}: wrote ${files.length} file(s) from GitHub (live)`\n );\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n console.error(\n `[Skill] ${skillName}: GitHub fetch failed: ${message}, no files to fall back to`\n );\n throw new Error(\n `Failed to write skill ${skillName} to filesystem: ${message}`\n );\n }\n } else {\n throw new Error(`Skill ${skillName} has no files and no source configured`);\n }\n}\n", "import { mkdir, writeFile } from 'fs/promises';\nimport { join } from 'path';\nimport type { SubAgent, GitHubSource } from '@wix/evalforge-types';\nimport {\n fetchGitHubFile,\n type FetchGitHubFolderOptions\n} from '@wix/evalforge-github-client';\n\nexport type FetchGitHubFileFn = (\n source: GitHubSource,\n options?: FetchGitHubFolderOptions\n) => Promise<string>;\n\nconst AGENTS_DIR = '.opencode/agents';\n\nfunction toAgentFilename(\n name: string,\n index: number,\n nameCount: Map<string, number>\n): string {\n const base =\n (name || '')\n .toLowerCase()\n .replace(/\\s+/g, '-')\n .replace(/[^a-z0-9-]/g, '')\n .replace(/^-+|-+$/g, '') || `sub-agent-${index}`;\n\n const count = nameCount.get(base) ?? 0;\n nameCount.set(base, count + 1);\n\n return count === 0 ? base : `${base}-${count + 1}`;\n}\n\nasync function resolveSubAgentContent(\n agent: SubAgent,\n fetchFn: FetchGitHubFileFn\n): Promise<string> {\n if (agent.source) {\n try {\n const content = await fetchFn(agent.source, {\n userAgent: 'EvalForge-Evaluator'\n });\n console.log(\n `[SubAgents] Fetched \"${agent.name}\" from ${agent.source.owner}/${agent.source.repo}/${agent.source.path}@${agent.source.ref}`\n );\n return content;\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n console.error(\n `[SubAgents] \"${agent.name}\": GitHub fetch failed: ${message}`\n );\n throw new Error(\n `Failed to fetch sub-agent \"${agent.name}\" from GitHub: ${message}`\n );\n }\n }\n if (!agent.subAgentMd) {\n console.warn(\n `[SubAgents] \"${agent.name}\" has empty inline content \u2013 the agent file will be blank`\n );\n }\n return agent.subAgentMd;\n}\n\n/**\n * Write sub-agent markdown files to .opencode/agents/ for OpenCode to discover.\n */\nexport async function writeSubAgentsToFilesystem(\n cwd: string,\n subAgents: SubAgent[],\n fetchFn: FetchGitHubFileFn = fetchGitHubFile\n): Promise<void> {\n if (subAgents.length === 0) return;\n\n const agentsDir = join(cwd, AGENTS_DIR);\n await mkdir(agentsDir, { recursive: true });\n\n const nameCount = new Map<string, number>();\n\n for (const [i, agent] of subAgents.entries()) {\n const filename = toAgentFilename(agent.name, i, nameCount);\n const filePath = join(agentsDir, `${filename}.md`);\n const content = await resolveSubAgentContent(agent, fetchFn);\n await writeFile(filePath, content, 'utf8');\n }\n\n console.log(`[SubAgents] Written to ${agentsDir}`);\n}\n", "import { homedir } from 'os';\nimport {\n ClaudeModel,\n AVAILABLE_OPENAI_MODEL_IDS,\n type MCPEntity\n} from '@wix/evalforge-types';\nimport { resolveMcpPlaceholders } from '../shared/resolve-mcp-placeholders.js';\n\nconst DEFAULT_MODEL = `${ClaudeModel.CLAUDE_4_5_SONNET_1_0}`;\n\nexport interface OpenCodeConfigOptions {\n model?: string;\n temperature?: number;\n maxTurns?: number;\n aiGatewayUrl?: string;\n aiGatewayHeaders?: Record<string, string>;\n mcps?: MCPEntity[];\n cwd: string;\n}\n\n/**\n * Parse a model string into provider and model ID.\n * Accepts \"provider/model-id\" or bare \"model-id\" (defaults to anthropic).\n */\nfunction parseModel(model: string): { providerID: string; modelID: string } {\n const slashIndex = model.indexOf('/');\n if (slashIndex > 0) {\n return {\n providerID: model.slice(0, slashIndex),\n modelID: model.slice(slashIndex + 1)\n };\n }\n const isOpenAI = (AVAILABLE_OPENAI_MODEL_IDS as readonly string[]).includes(\n model\n );\n return { providerID: isOpenAI ? 'openai' : 'anthropic', modelID: model };\n}\n\n/**\n * Convert generic MCP server entries into the OpenCode config format.\n */\nfunction toOpenCodeMcpConfig(\n servers: Record<string, Record<string, unknown>>\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n\n for (const [name, entry] of Object.entries(servers)) {\n if (entry.type === 'local' || entry.type === 'remote') {\n result[name] = entry;\n continue;\n }\n\n if (entry.url && typeof entry.url === 'string') {\n result[name] = {\n type: 'remote' as const,\n url: entry.url,\n ...(entry.headers\n ? { headers: entry.headers as Record<string, string> }\n : {}),\n ...(typeof entry.enabled === 'boolean'\n ? { enabled: entry.enabled }\n : {})\n };\n continue;\n }\n\n if (entry.command && typeof entry.command === 'string') {\n const commandArray = [\n entry.command as string,\n ...((entry.args as string[]) || [])\n ];\n result[name] = {\n type: 'local' as const,\n command: commandArray,\n ...(entry.env\n ? { environment: entry.env as Record<string, string> }\n : {}),\n ...(typeof entry.enabled === 'boolean'\n ? { enabled: entry.enabled }\n : {})\n };\n continue;\n }\n\n console.warn(\n `[MCP] Server \"${name}\" has unrecognized format, passing through as-is:`,\n JSON.stringify(entry)\n );\n result[name] = entry;\n }\n\n return result;\n}\n\n/**\n * Ensure `~/.opencode/bin` is on a PATH string.\n */\nfunction ensureOpenCodeInPath(currentPath: string): string {\n const opencodeBin = `${homedir()}/.opencode/bin`;\n if (currentPath.includes(opencodeBin)) {\n return currentPath;\n }\n return `${opencodeBin}:${currentPath}`;\n}\n\n/**\n * Build environment variables for spawning `opencode run`.\n *\n * Returns the env object (including `OPENCODE_CONFIG_CONTENT`) and the\n * parsed provider/model IDs needed by the caller.\n */\nexport async function buildOpenCodeEnv(\n options: OpenCodeConfigOptions\n): Promise<{\n env: NodeJS.ProcessEnv;\n providerID: string;\n modelID: string;\n}> {\n const modelStr = options.model || DEFAULT_MODEL;\n const { providerID, modelID } = parseModel(modelStr);\n\n // Build provider config\n const provider: Record<string, unknown> = {};\n if (options.aiGatewayUrl) {\n const providerOptions: Record<string, unknown> = {\n baseURL: `${options.aiGatewayUrl}/proxy/${providerID}`,\n apiKey: 'sk-placeholder-auth-handled-by-gateway'\n };\n if (options.aiGatewayHeaders) {\n providerOptions.headers = { ...options.aiGatewayHeaders };\n }\n provider[providerID] = { options: providerOptions };\n }\n\n // Build MCP config\n let mcp: Record<string, unknown> | undefined;\n if (options.mcps && options.mcps.length > 0) {\n const mcpServers: Record<string, Record<string, unknown>> = {};\n for (const mcpEntity of options.mcps) {\n const entityConfig = mcpEntity.config as Record<string, unknown>;\n for (const [key, value] of Object.entries(entityConfig)) {\n if (\n typeof value !== 'object' ||\n value === null ||\n Array.isArray(value)\n ) {\n throw new Error(\n `MCP \"${mcpEntity.name}\" has invalid config: value for key \"${key}\" must be an object (got ${typeof value}).`\n );\n }\n mcpServers[key] = value as Record<string, unknown>;\n }\n }\n const resolved = await resolveMcpPlaceholders(mcpServers, {\n cwd: options.cwd\n });\n mcp = toOpenCodeMcpConfig(resolved);\n }\n\n // Build agent overrides\n const agentOverrides: Record<string, unknown> = {};\n if (options.temperature != null) {\n agentOverrides.temperature = options.temperature;\n }\n if (options.maxTurns != null) {\n agentOverrides.maxSteps = options.maxTurns;\n }\n\n // Assemble the full config object\n const config: Record<string, unknown> = {\n model: `${providerID}/${modelID}`,\n provider,\n ...(Object.keys(agentOverrides).length > 0\n ? { agent: { build: agentOverrides } }\n : {}),\n permission: {\n edit: 'allow',\n bash: 'allow',\n webfetch: 'allow',\n doom_loop: 'allow',\n external_directory: 'allow'\n },\n ...(mcp ? { mcp } : {})\n };\n\n const env: NodeJS.ProcessEnv = {\n ...process.env,\n PATH: ensureOpenCodeInPath(process.env.PATH || ''),\n OPENCODE_CONFIG_CONTENT: JSON.stringify(config),\n OPENCODE_DISABLE_LSP_DOWNLOAD: 'true'\n };\n\n return { env, providerID, modelID };\n}\n", "import type {\n LLMTrace,\n LLMTraceStep,\n LLMTraceSummary\n} from '@wix/evalforge-types';\nimport { LLMStepType } from '@wix/evalforge-types';\nimport { randomUUID } from 'crypto';\nimport type {\n OpenCodeTextEvent,\n OpenCodeReasoningEvent,\n OpenCodeToolUseEvent,\n OpenCodeStepFinishEvent,\n TimestampedOpenCodeEvent\n} from './types.js';\n\n/**\n * A \"turn\" is a group of events between two step_finish boundaries.\n * Each turn produces one or more LLMTraceSteps.\n */\ninterface Turn {\n textParts: string[];\n reasoningParts: string[];\n toolCalls: Array<{ toolName: string; args: unknown }>;\n stepFinish?: OpenCodeStepFinishEvent['part'];\n receivedAt?: number;\n}\n\n/**\n * Build an LLMTrace from the NDJSON events emitted by `opencode run --format json`.\n *\n * Events are grouped into turns delimited by `step_finish` events.\n * Each turn may produce THINKING, TOOL_USE, and COMPLETION sub-steps\n * to match the claude-code trace format.\n */\nexport function buildLLMTrace(\n timestampedEvents: TimestampedOpenCodeEvent[],\n totalDurationMs: number,\n model: string,\n provider: string,\n executionStartTime: Date\n): LLMTrace {\n // Group events into turns\n const turns: Turn[] = [];\n let current: Turn = {\n textParts: [],\n reasoningParts: [],\n toolCalls: []\n };\n\n for (const { event: evt, receivedAt } of timestampedEvents) {\n switch (evt.type) {\n case 'text':\n current.textParts.push((evt as OpenCodeTextEvent).part.text);\n break;\n case 'reasoning':\n current.reasoningParts.push((evt as OpenCodeReasoningEvent).part.text);\n break;\n case 'tool_use': {\n const tu = evt as OpenCodeToolUseEvent;\n current.toolCalls.push({\n toolName: tu.part.tool,\n args: tu.part.state.input\n });\n break;\n }\n case 'step_finish': {\n const sf = evt as OpenCodeStepFinishEvent;\n current.stepFinish = sf.part;\n current.receivedAt = receivedAt;\n turns.push(current);\n current = {\n textParts: [],\n reasoningParts: [],\n toolCalls: []\n };\n break;\n }\n }\n }\n\n // If there are remaining events with no step_finish, flush them\n if (\n current.textParts.length > 0 ||\n current.reasoningParts.length > 0 ||\n current.toolCalls.length > 0\n ) {\n // Use the last event's receivedAt for the incomplete turn\n if (timestampedEvents.length > 0) {\n current.receivedAt =\n timestampedEvents[timestampedEvents.length - 1].receivedAt;\n }\n turns.push(current);\n }\n\n // Convert turns into trace steps using real per-turn timing\n const executionStartMs = executionStartTime.getTime();\n\n const allSteps: LLMTraceStep[] = turns\n .flatMap((turn, turnIndex) => {\n const sf = turn.stepFinish;\n const stepInputTokens = sf?.tokens.input ?? 0;\n const stepOutputTokens = sf?.tokens.output ?? 0;\n const stepCost = sf?.cost ?? 0;\n const finishReason = sf?.reason ?? 'unknown';\n const stepModel = sf?.modelID || model;\n const stepProvider = sf?.providerID || provider;\n\n // Compute real timing from receivedAt timestamps\n const turnEndMs = turn.receivedAt ?? executionStartMs + totalDurationMs;\n const prevEndMs =\n turnIndex > 0\n ? (turns[turnIndex - 1].receivedAt ?? executionStartMs)\n : executionStartMs;\n const durationMs = Math.max(0, turnEndMs - prevEndMs);\n const startedAt = new Date(prevEndMs).toISOString();\n\n const text = turn.textParts.join('');\n const thinking = turn.reasoningParts.join('');\n const toolCallCount = turn.toolCalls.length;\n const hasThinking = !!thinking;\n const hasText = !!text;\n const isSuccess = finishReason !== 'error';\n const errorMsg =\n finishReason === 'error' ? 'Generation failed' : undefined;\n\n const subSteps: LLMTraceStep[] = [];\n const thinkingSubSteps =\n hasThinking && (hasText || toolCallCount > 0) ? 1 : 0;\n const toolSubSteps = toolCallCount;\n const textSubSteps = hasText && toolCallCount > 0 ? 1 : 0;\n const totalSubSteps = thinkingSubSteps + toolSubSteps + textSubSteps || 1;\n\n // THINKING sub-step\n if (hasThinking && (hasText || toolCallCount > 0)) {\n subSteps.push({\n id: randomUUID(),\n stepNumber: 0,\n turnIndex,\n type: LLMStepType.THINKING,\n model: stepModel,\n provider: stepProvider,\n startedAt,\n durationMs: Math.round(durationMs / totalSubSteps),\n tokenUsage: {\n prompt: Math.round(stepInputTokens / totalSubSteps),\n completion: Math.round(stepOutputTokens / totalSubSteps),\n total: Math.round(\n (stepInputTokens + stepOutputTokens) / totalSubSteps\n )\n },\n costUsd: stepCost / totalSubSteps,\n outputPreview: thinking.slice(0, 200),\n success: isSuccess,\n error: errorMsg\n });\n }\n\n // TOOL_USE sub-steps\n if (toolCallCount > 0) {\n for (let tcIdx = 0; tcIdx < toolCallCount; tcIdx++) {\n const tc = turn.toolCalls[tcIdx];\n const isLast = tcIdx === toolCallCount - 1 && textSubSteps === 0;\n const toolBudgetSteps = toolSubSteps + textSubSteps;\n const toolFraction = toolBudgetSteps > 0 ? 1 / toolBudgetSteps : 1;\n const remainingFraction =\n (totalSubSteps - thinkingSubSteps) / totalSubSteps;\n\n subSteps.push({\n id: randomUUID(),\n stepNumber: 0,\n turnIndex,\n type: LLMStepType.TOOL_USE,\n model: stepModel,\n provider: stepProvider,\n startedAt,\n durationMs: isLast\n ? durationMs - subSteps.reduce((s, ss) => s + ss.durationMs, 0)\n : Math.round(durationMs * remainingFraction * toolFraction),\n tokenUsage: {\n prompt: Math.round(\n stepInputTokens * remainingFraction * toolFraction\n ),\n completion: Math.round(\n stepOutputTokens * remainingFraction * toolFraction\n ),\n total: Math.round(\n (stepInputTokens + stepOutputTokens) *\n remainingFraction *\n toolFraction\n )\n },\n costUsd: stepCost * remainingFraction * toolFraction,\n toolName: tc.toolName,\n toolArguments: JSON.stringify(tc.args),\n outputPreview:\n tcIdx === 0 && !hasText\n ? (text || thinking)?.slice(0, 200)\n : undefined,\n success: isSuccess,\n error: errorMsg\n });\n }\n }\n\n // COMPLETION sub-step (text when tools were also present)\n if (hasText && toolCallCount > 0) {\n subSteps.push({\n id: randomUUID(),\n stepNumber: 0,\n turnIndex,\n type: LLMStepType.COMPLETION,\n model: stepModel,\n provider: stepProvider,\n startedAt,\n durationMs:\n durationMs - subSteps.reduce((s, ss) => s + ss.durationMs, 0),\n tokenUsage: {\n prompt:\n stepInputTokens -\n subSteps.reduce((s, ss) => s + ss.tokenUsage.prompt, 0),\n completion:\n stepOutputTokens -\n subSteps.reduce((s, ss) => s + ss.tokenUsage.completion, 0),\n total:\n stepInputTokens +\n stepOutputTokens -\n subSteps.reduce((s, ss) => s + ss.tokenUsage.total, 0)\n },\n costUsd: stepCost - subSteps.reduce((s, ss) => s + ss.costUsd, 0),\n outputPreview: text.slice(0, 200),\n success: isSuccess,\n error: errorMsg\n });\n }\n\n // Fallback: pure text or pure thinking\n if (subSteps.length === 0) {\n const stepType =\n hasThinking && !hasText\n ? LLMStepType.THINKING\n : LLMStepType.COMPLETION;\n subSteps.push({\n id: randomUUID(),\n stepNumber: 0,\n turnIndex,\n type: stepType,\n model: stepModel,\n provider: stepProvider,\n startedAt,\n durationMs,\n tokenUsage: {\n prompt: stepInputTokens,\n completion: stepOutputTokens,\n total: stepInputTokens + stepOutputTokens\n },\n costUsd: stepCost,\n outputPreview: (text || thinking)?.slice(0, 200),\n success: isSuccess,\n error: errorMsg\n });\n }\n\n return subSteps;\n })\n .map((s, i) => ({ ...s, stepNumber: i + 1 }));\n\n // Aggregate totals\n let totalPrompt = 0;\n let totalCompletion = 0;\n let totalCost = 0;\n for (const turn of turns) {\n if (turn.stepFinish) {\n totalPrompt += turn.stepFinish.tokens.input;\n totalCompletion += turn.stepFinish.tokens.output;\n totalCost += turn.stepFinish.cost;\n }\n }\n const totalTokens = {\n prompt: totalPrompt,\n completion: totalCompletion,\n total: totalPrompt + totalCompletion\n };\n\n const stepTypeBreakdown: Record<\n string,\n { count: number; durationMs: number; tokens: number; costUsd: number }\n > = {};\n for (const step of allSteps) {\n const entry = stepTypeBreakdown[step.type] ?? {\n count: 0,\n durationMs: 0,\n tokens: 0,\n costUsd: 0\n };\n entry.count += 1;\n entry.durationMs += step.durationMs;\n entry.tokens += step.tokenUsage.total;\n entry.costUsd += step.costUsd;\n stepTypeBreakdown[step.type] = entry;\n }\n\n const modelUsed = allSteps[0]?.model || model;\n const summary: LLMTraceSummary = {\n totalSteps: allSteps.length,\n totalTurns: turns.length,\n totalDurationMs,\n totalTokens,\n totalCostUsd: totalCost,\n modelBreakdown: {\n [modelUsed]: {\n count: allSteps.length,\n durationMs: totalDurationMs,\n tokens: totalTokens.total,\n costUsd: totalCost\n }\n },\n modelsUsed: [modelUsed],\n stepTypeBreakdown\n };\n\n return {\n id: randomUUID(),\n steps: allSteps,\n summary\n };\n}\n", "import type { ConversationMessage } from '@wix/evalforge-types';\nimport type {\n OpenCodeTextEvent,\n OpenCodeReasoningEvent,\n OpenCodeToolUseEvent,\n TimestampedOpenCodeEvent\n} from './types.js';\n\n/**\n * Build a conversation from the NDJSON events emitted by\n * `opencode run --format json`.\n *\n * Events are grouped into assistant turns (text, reasoning, tool_use)\n * separated by step_finish events. Tool results appear as user messages.\n */\nexport function buildConversation(\n timestampedEvents: TimestampedOpenCodeEvent[]\n): ConversationMessage[] {\n const result: ConversationMessage[] = [];\n\n let assistantContent: ConversationMessage['content'] = [];\n let userContent: ConversationMessage['content'] = [];\n let latestReceivedAt = 0;\n\n const flushAssistant = (): void => {\n if (assistantContent.length > 0) {\n const timestamp =\n latestReceivedAt > 0\n ? new Date(latestReceivedAt).toISOString()\n : new Date().toISOString();\n result.push({ role: 'assistant', content: assistantContent, timestamp });\n assistantContent = [];\n }\n };\n\n const flushUser = (): void => {\n if (userContent.length > 0) {\n const timestamp =\n latestReceivedAt > 0\n ? new Date(latestReceivedAt).toISOString()\n : new Date().toISOString();\n result.push({ role: 'user', content: userContent, timestamp });\n userContent = [];\n }\n };\n\n for (const { event: evt, receivedAt } of timestampedEvents) {\n latestReceivedAt = receivedAt;\n\n switch (evt.type) {\n case 'text': {\n const te = evt as OpenCodeTextEvent;\n assistantContent.push({ type: 'text', text: te.part.text });\n break;\n }\n case 'reasoning': {\n const re = evt as OpenCodeReasoningEvent;\n assistantContent.push({ type: 'thinking', thinking: re.part.text });\n break;\n }\n case 'tool_use': {\n const tu = evt as OpenCodeToolUseEvent;\n // Tool invocation goes on the assistant side\n assistantContent.push({\n type: 'tool_use',\n toolName: tu.part.tool,\n toolId: tu.part.callID,\n input: tu.part.state.input\n });\n\n // If the tool has completed or errored, emit a user tool_result\n if (\n tu.part.state.status === 'completed' ||\n tu.part.state.status === 'error'\n ) {\n // Flush any pending assistant content first\n flushAssistant();\n\n const isError = tu.part.state.status === 'error';\n const content = isError\n ? tu.part.state.error || 'Tool execution failed'\n : tu.part.state.output || '';\n userContent.push({\n type: 'tool_result',\n toolUseId: tu.part.callID,\n content,\n ...(isError ? { isError: true } : {})\n });\n flushUser();\n }\n break;\n }\n case 'step_finish': {\n // Flush the current turn\n flushAssistant();\n flushUser();\n break;\n }\n }\n }\n\n // Flush any remaining content\n flushAssistant();\n flushUser();\n\n return result;\n}\n", "/**\n * OpenCode agent adapter module.\n *\n * Provides the OpenCode implementation of the AgentAdapter interface.\n * Spawns the `opencode` CLI and parses NDJSON events from stdout.\n *\n * The adapter is automatically registered with the default registry when\n * this module is imported.\n */\n\nexport { OpenCodeAdapter, openCodeAdapter } from './opencode-adapter.js';\nexport { executeWithOpenCode } from './execute.js';\nexport { buildConversation } from './build-conversation.js';\n\nexport type {\n OpenCodeExecutionOptions,\n OpenCodeExecutionResult\n} from './types.js';\nexport type { TraceContext } from '@wix/evalforge-types';\n\n// Register the adapter with the default registry\nimport { defaultRegistry } from '../registry.js';\nimport { openCodeAdapter } from './opencode-adapter.js';\n\ndefaultRegistry.register(openCodeAdapter);\n", "import {\n generateText,\n stepCountIs,\n type LanguageModel,\n type StepResult,\n type ToolSet\n} from 'ai';\nimport { createAnthropic } from '@ai-sdk/anthropic';\nimport { createOpenAI } from '@ai-sdk/openai';\nimport type {\n AgentExecutionContext,\n AgentExecutionResult,\n LLMTrace,\n TraceContext\n} from '@wix/evalforge-types';\nimport {\n AVAILABLE_CLAUDE_MODEL_IDS,\n OPENAI_RESPONSES_MODEL_IDS,\n LLMStepType,\n LiveTraceEventType\n} from '@wix/evalforge-types';\nimport { randomUUID } from 'crypto';\nimport { buildMcpTools, closeMcpClients } from './mcp-tools.js';\nimport { emitTraceEvent } from '../shared/trace-emit.js';\nimport { detectMcpToolError } from '../shared/detect-tool-error.js';\nimport { calculateStepCost } from './cost-calculation.js';\nimport { buildConversation } from './build-conversation.js';\n\nconst PROVIDER_ANTHROPIC = 'anthropic';\nconst PROVIDER_OPENAI = 'openai';\n\n/**\n * Default agentic loop iterations when MCP tools are available.\n * Caps tool-use rounds to prevent runaway loops; a single-step\n * limit is used when no tools are present. Can be overridden via\n * modelConfig.maxTurns.\n */\nconst DEFAULT_MAX_TOOL_STEPS = 25;\n\nexport function createModel(\n modelId: string,\n baseUrl: string,\n headers: Record<string, string>\n): LanguageModel {\n const isClaudeModel = isClaudeModelId(modelId);\n\n if (isClaudeModel) {\n const anthropic = createAnthropic({\n baseURL: `${baseUrl}/proxy/anthropic`,\n apiKey: 'proxy-auth',\n headers\n });\n return anthropic(modelId);\n }\n\n const openai = createOpenAI({\n baseURL: `${baseUrl}/proxy/openai`,\n apiKey: 'proxy-auth',\n headers\n });\n\n if (\n [...OPENAI_RESPONSES_MODEL_IDS].some(\n (id) => modelId === id || modelId.startsWith(id)\n )\n ) {\n return openai.responses(modelId);\n }\n\n return openai.chat(modelId);\n}\n\nexport function isClaudeModelId(modelId: string): boolean {\n return (AVAILABLE_CLAUDE_MODEL_IDS as string[]).some(\n (id) => modelId === id || modelId.startsWith(id)\n );\n}\n\n/**\n * Extract text content from a skill's latest version files.\n * Concatenates all file contents, prioritizing SKILL.md if present.\n */\nexport function extractSkillContent(\n files: Array<{ path: string; content: string }> | undefined\n): string | undefined {\n if (!files || files.length === 0) return undefined;\n\n const skillMd = files.find((f) => f.path === 'SKILL.md');\n if (skillMd) return skillMd.content;\n\n return files.map((f) => f.content).join('\\n\\n');\n}\n\nexport async function executeWithAiSdk(\n context: AgentExecutionContext\n): Promise<AgentExecutionResult> {\n const {\n scenario,\n cwd,\n modelConfig,\n aiGatewayUrl,\n aiGatewayHeaders = {},\n mcps,\n traceContext\n } = context;\n\n if (!aiGatewayUrl) {\n throw new Error('Simple Agent requires aiGatewayUrl');\n }\n if (!modelConfig?.model) {\n throw new Error('Simple Agent requires a model in modelConfig');\n }\n\n const model = createModel(modelConfig.model, aiGatewayUrl, aiGatewayHeaders);\n const provider = isClaudeModelId(modelConfig.model)\n ? PROVIDER_ANTHROPIC\n : PROVIDER_OPENAI;\n\n const systemPrompt = composeSystemPrompt(context);\n\n const { tools: mcpTools, clients } =\n mcps && mcps.length > 0\n ? await buildMcpTools(mcps, cwd)\n : { tools: undefined, clients: [] };\n\n const startTime = Date.now();\n\n if (traceContext) {\n emitStartEvent(traceContext, startTime);\n }\n\n try {\n const isAnthropic = provider === PROVIDER_ANTHROPIC;\n const isResponsesAPI = [...OPENAI_RESPONSES_MODEL_IDS].some(\n (id) => modelConfig.model === id || modelConfig.model.startsWith(id)\n );\n const supportsThinking = isAnthropic || isResponsesAPI;\n\n const providerOpts = {\n ...(isAnthropic && {\n anthropic: {\n thinking: { type: 'enabled', budgetTokens: 10000 }\n }\n }),\n ...(isResponsesAPI && {\n openai: {\n // Prevent the SDK from sending item_reference inputs that the proxy can't forward\n store: false,\n forceReasoning: true,\n reasoningEffort: 'high' as const,\n reasoningSummary: 'detailed' as const\n }\n })\n };\n\n const stepTimestamps: number[] = [];\n\n const result = await generateText({\n model,\n system: systemPrompt,\n prompt: scenario.triggerPrompt,\n temperature: supportsThinking ? undefined : modelConfig.temperature,\n maxOutputTokens: modelConfig.maxTokens,\n tools: mcpTools as ToolSet | undefined,\n stopWhen: mcpTools\n ? stepCountIs(modelConfig.maxTurns ?? DEFAULT_MAX_TOOL_STEPS)\n : stepCountIs(1),\n providerOptions: providerOpts,\n onStepFinish: (step) => {\n stepTimestamps.push(Date.now());\n if (traceContext) {\n const isToolStep = step.toolCalls.length > 0;\n const firstToolCall = step.toolCalls[0];\n emitTraceEvent(\n {\n evalRunId: traceContext.evalRunId,\n scenarioId: traceContext.scenarioId,\n scenarioName: traceContext.scenarioName,\n targetId: traceContext.targetId,\n targetName: traceContext.targetName,\n stepNumber: stepTimestamps.length,\n type: isToolStep\n ? LiveTraceEventType.TOOL_USE\n : LiveTraceEventType.COMPLETION,\n toolName: firstToolCall?.toolName,\n toolArgs: firstToolCall\n ? (JSON.stringify(firstToolCall.input) ?? '').slice(0, 500)\n : undefined,\n outputPreview: step.text?.slice(0, 500),\n elapsedMs: Date.now() - startTime,\n timestamp: new Date().toISOString(),\n isComplete: false\n },\n traceContext.tracePushUrl,\n traceContext.routeHeader,\n traceContext.authToken\n );\n }\n }\n });\n\n const durationMs = Date.now() - startTime;\n\n const usage = {\n inputTokens: result.usage.inputTokens ?? 0,\n outputTokens: result.usage.outputTokens ?? 0,\n totalTokens: result.usage.totalTokens ?? 0\n };\n\n const llmTrace = buildLLMTrace(\n result.steps,\n durationMs,\n usage,\n modelConfig.model,\n provider,\n startTime,\n stepTimestamps\n );\n\n if (traceContext) {\n emitCompletionEvent(traceContext, stepTimestamps.length + 1);\n }\n\n const conversation = buildConversation(\n scenario.triggerPrompt,\n result.steps,\n startTime,\n stepTimestamps\n );\n\n return {\n outputText: result.text,\n durationMs,\n usage,\n llmTrace,\n conversation\n };\n } finally {\n await closeMcpClients(clients);\n }\n}\n\n/**\n * Build the system prompt for Simple Agent from skills, rules, and optional override.\n *\n * Unlike CLI agents (which have DEFAULT_EVALUATOR_SYSTEM_PROMPT), the Simple Agent\n * has no built-in default instructions. The three-state `systemPrompt` contract\n * (undefined = default, null = none, string = custom) effectively collapses to\n * two states here: both undefined and null result in no base prompt being prepended,\n * while a non-empty string is included as the first segment.\n */\nexport function composeSystemPrompt(\n context: AgentExecutionContext\n): string | undefined {\n const parts: string[] = [];\n\n if (context.systemPrompt) {\n parts.push(context.systemPrompt);\n }\n\n for (const skill of context.skills) {\n const content = extractSkillContent(skill.latestVersion?.files);\n if (content) {\n parts.push(content);\n }\n }\n\n if (context.rules) {\n for (const rule of context.rules) {\n if (rule.content) {\n parts.push(rule.content);\n }\n }\n }\n\n return parts.length > 0 ? parts.join('\\n\\n---\\n\\n') : undefined;\n}\n\n/**\n * Check if any tool result in a step indicates an error.\n * Returns the error text if found, null otherwise.\n */\nfunction findToolResultError(step: StepResult<ToolSet>): string | null {\n for (const tr of step.toolResults) {\n const output = (tr as { output?: unknown }).output;\n const error = detectMcpToolError(output);\n if (error) return error;\n }\n return null;\n}\n\nexport function buildLLMTrace(\n steps: StepResult<ToolSet>[],\n totalDurationMs: number,\n totalUsage: {\n inputTokens: number;\n outputTokens: number;\n totalTokens: number;\n },\n modelId: string,\n provider: string,\n executionStartMs: number,\n stepTimestamps: number[]\n): LLMTrace {\n const traceSteps = steps.map((step, i) => {\n const stepFinishedAt = stepTimestamps[i] ?? executionStartMs;\n const stepStartedAt =\n i === 0 ? executionStartMs : (stepTimestamps[i - 1] ?? executionStartMs);\n const stepDurationMs = stepFinishedAt - stepStartedAt;\n const firstToolCall = step.toolCalls[0];\n\n const tokenUsage = {\n prompt: step.usage.inputTokens ?? 0,\n completion: step.usage.outputTokens ?? 0,\n total: step.usage.totalTokens ?? 0\n };\n\n const costUsd = calculateStepCost(step, modelId, provider, tokenUsage);\n\n // Check if any tool result for this step indicates an error.\n // MCP tool results embed isError in the output content.\n const toolResultError = findToolResultError(step);\n\n return {\n id: randomUUID(),\n stepNumber: i + 1,\n turnIndex: i,\n type:\n step.toolCalls.length > 0\n ? LLMStepType.TOOL_USE\n : LLMStepType.COMPLETION,\n model: modelId,\n provider,\n startedAt: new Date(stepStartedAt).toISOString(),\n durationMs: stepDurationMs,\n tokenUsage,\n costUsd,\n toolName: firstToolCall?.toolName,\n toolArguments: firstToolCall\n ? (JSON.stringify(firstToolCall.input) ?? undefined)\n : undefined,\n outputPreview: step.text?.slice(0, 200),\n success: step.finishReason !== 'error' && !toolResultError,\n error:\n step.finishReason === 'error'\n ? 'Generation failed'\n : (toolResultError ?? undefined)\n };\n });\n\n const totalCostUsd = traceSteps.reduce((sum, s) => sum + s.costUsd, 0);\n\n const finalTokens = {\n prompt: totalUsage.inputTokens,\n completion: totalUsage.outputTokens,\n total: totalUsage.totalTokens\n };\n\n return {\n id: randomUUID(),\n steps: traceSteps,\n summary: {\n totalSteps: traceSteps.length,\n totalTurns: traceSteps.length,\n totalDurationMs,\n totalTokens: finalTokens,\n totalCostUsd,\n modelBreakdown: {\n [modelId]: {\n count: traceSteps.length,\n durationMs: totalDurationMs,\n tokens: finalTokens.total,\n costUsd: totalCostUsd\n }\n },\n modelsUsed: [modelId]\n }\n };\n}\n\nfunction emitStartEvent(traceContext: TraceContext, startTime: number): void {\n emitTraceEvent(\n {\n evalRunId: traceContext.evalRunId,\n scenarioId: traceContext.scenarioId,\n scenarioName: traceContext.scenarioName,\n targetId: traceContext.targetId,\n targetName: traceContext.targetName,\n stepNumber: 0,\n type: LiveTraceEventType.PROGRESS,\n outputPreview: 'Starting Simple Agent execution...',\n elapsedMs: Date.now() - startTime,\n timestamp: new Date().toISOString(),\n isComplete: false\n },\n traceContext.tracePushUrl,\n traceContext.routeHeader,\n traceContext.authToken\n );\n}\n\nfunction emitCompletionEvent(\n traceContext: TraceContext,\n stepNumber: number\n): void {\n emitTraceEvent(\n {\n evalRunId: traceContext.evalRunId,\n scenarioId: traceContext.scenarioId,\n scenarioName: traceContext.scenarioName,\n targetId: traceContext.targetId,\n targetName: traceContext.targetName,\n stepNumber,\n type: LiveTraceEventType.COMPLETION,\n outputPreview: 'Scenario execution completed',\n timestamp: new Date().toISOString(),\n isComplete: true\n },\n traceContext.tracePushUrl,\n traceContext.routeHeader,\n traceContext.authToken\n );\n}\n", "import { createMCPClient } from '@ai-sdk/mcp';\nimport { Experimental_StdioMCPTransport } from '@ai-sdk/mcp/mcp-stdio';\nimport type { MCPEntity } from '@wix/evalforge-types';\nimport { resolveMcpPlaceholders } from '../shared/resolve-mcp-placeholders.js';\n\ninterface McpToolsResult {\n tools: Record<string, unknown>;\n clients: Array<{ close: () => Promise<void> }>;\n}\n\n/**\n * Build AI SDK tools from MCP entity configs.\n *\n * Each `MCPEntity.config` is a keyed record matching the `.mcp.json` shape,\n * e.g. `{ \"server-name\": { \"type\": \"stdio\", \"command\": \"node\", \"args\": [\"server.js\"] } }`.\n * Each entry becomes a live MCP client whose tools are merged into the result.\n *\n * Tool names are namespaced as `${serverName}__${toolName}` to avoid collisions.\n */\nexport async function buildMcpTools(\n mcps: MCPEntity[],\n cwd: string\n): Promise<McpToolsResult> {\n const allTools: Record<string, unknown> = {};\n const clients: Array<{ close: () => Promise<void> }> = [];\n\n try {\n for (const mcp of mcps) {\n const resolvedConfig = await resolveMcpPlaceholders(\n mcp.config as Record<string, Record<string, unknown>>,\n { cwd }\n );\n for (const [serverName, serverConfig] of Object.entries(resolvedConfig)) {\n const config = serverConfig as Record<string, unknown>;\n const transport = buildTransport(serverName, config, cwd);\n const client = await createMCPClient({ transport });\n clients.push(client);\n const tools = await client.tools();\n\n for (const [toolName, tool] of Object.entries(tools)) {\n allTools[`${serverName}__${toolName}`] = tool;\n }\n }\n }\n } catch (err) {\n await closeMcpClients(clients);\n throw err;\n }\n\n return { tools: allTools, clients };\n}\n\nexport async function closeMcpClients(\n clients: Array<{ close: () => Promise<void> }>\n): Promise<void> {\n await Promise.allSettled(clients.map((c) => c.close()));\n}\n\n/**\n * Build an AI SDK MCP transport from a server config entry.\n *\n * Supports three transport types:\n * - stdio: local process (Experimental_StdioMCPTransport)\n * - http: streamable HTTP (config object with type: 'http')\n * - sse: Server-Sent Events (config object with type: 'sse')\n */\nexport function buildTransport(\n serverName: string,\n config: Record<string, unknown>,\n cwd: string\n) {\n const type = config.type as string | undefined;\n const headers = config.headers as Record<string, string> | undefined;\n\n if (type === 'stdio' || config.command) {\n return new Experimental_StdioMCPTransport({\n command: config.command as string,\n args: (config.args as string[]) ?? [],\n env: { ...(config.env as Record<string, string> | undefined), PWD: cwd },\n cwd\n });\n }\n\n if (type === 'http') {\n return {\n type: 'http' as const,\n url: config.url as string,\n ...(headers && { headers })\n };\n }\n\n if (type === 'sse' || config.url) {\n return {\n type: 'sse' as const,\n url: config.url as string,\n ...(headers && { headers })\n };\n }\n\n throw new Error(\n `MCP server \"${serverName}\" has unsupported transport config (type=${type ?? 'unset'}). ` +\n `Expected type \"stdio\", \"http\", or \"sse\", or a config with \"command\" or \"url\".`\n );\n}\n", "/**\n * Detect if an MCP tool result output indicates an error.\n *\n * MCP tool results embed `isError: true` in the output object.\n * We first check the structured object, then fall back to string matching\n * for cases where the output is already serialized.\n *\n * @returns The error text if found, null otherwise.\n */\nexport function detectMcpToolError(output: unknown): string | null {\n if (output == null) return null;\n\n // Structured check: output is an object with isError flag\n if (typeof output === 'object' && 'isError' in output) {\n const obj = output as {\n isError?: boolean;\n content?: Array<{ text?: string }>;\n };\n if (obj.isError === true) {\n return extractErrorText(obj.content);\n }\n }\n\n // Fallback: output is a serialized string containing the error pattern\n const str = typeof output === 'string' ? output : null;\n if (\n str &&\n (str.includes('\"isError\":true') || str.includes('\"isError\": true'))\n ) {\n try {\n const parsed = JSON.parse(str) as {\n isError?: boolean;\n content?: Array<{ text?: string }>;\n };\n if (parsed.isError === true) {\n return extractErrorText(parsed.content);\n }\n } catch {\n // Unparseable \u2014 return raw string as error\n return str.slice(0, 500);\n }\n }\n\n return null;\n}\n\nfunction extractErrorText(\n content: Array<{ text?: string }> | undefined\n): string {\n if (Array.isArray(content)) {\n const text = content\n .filter((c) => typeof c.text === 'string')\n .map((c) => c.text)\n .join('\\n');\n if (text) return text.slice(0, 500);\n }\n return 'Tool call failed';\n}\n", "import type { StepResult, ToolSet } from 'ai';\nimport { normalizeModelId } from '@wix/evalforge-types';\n\nconst PROVIDER_ANTHROPIC = 'anthropic';\n\n/**\n * Per-1M-token pricing keyed by official model ID.\n * Used as fallback when the gateway doesn't report cost.\n */\nconst MODEL_PRICING: Record<string, { input: number; output: number }> = {\n // Anthropic \u2014 Claude 4.6\n 'claude-sonnet-4-6': { input: 3, output: 15 },\n 'claude-opus-4-6': { input: 15, output: 75 },\n // Anthropic \u2014 Claude 4.5\n 'claude-opus-4-5': { input: 5, output: 25 },\n 'claude-sonnet-4-5': { input: 3, output: 15 },\n 'claude-haiku-4-5': { input: 1, output: 5 },\n // Anthropic \u2014 Claude 4\n 'claude-opus-4': { input: 15, output: 75 },\n 'claude-sonnet-4': { input: 3, output: 15 },\n\n // OpenAI \u2014 GPT-5\n 'gpt-5': { input: 1.25, output: 10 },\n 'gpt-5-mini': { input: 0.25, output: 2 },\n 'gpt-5-nano': { input: 0.05, output: 0.4 },\n // OpenAI \u2014 GPT-4.1\n 'gpt-4.1': { input: 2, output: 8 },\n 'gpt-4.1-mini': { input: 0.4, output: 1.6 },\n 'gpt-4.1-nano': { input: 0.1, output: 0.4 },\n // OpenAI \u2014 GPT-4o\n 'gpt-4o': { input: 2.5, output: 10 },\n 'gpt-4o-mini': { input: 0.15, output: 0.6 },\n // OpenAI \u2014 Reasoning\n o3: { input: 2, output: 8 },\n 'o4-mini': { input: 1.1, output: 4.4 },\n 'o3-mini': { input: 1.1, output: 4.4 },\n o1: { input: 15, output: 60 }\n};\n\n/**\n * Extract gateway-computed cost from a Vercel AI SDK step result.\n * The Wix AI Gateway reports accurate cost (including cache discounts)\n * via `total_cost_usd` injected by the proxy into the provider response.\n *\n * - Anthropic: available in `providerMetadata.anthropic.usage.total_cost_usd`\n * - OpenAI: available at the top level of `response.body.total_cost_usd`\n */\nfunction extractGatewayCost(\n step: StepResult<ToolSet>,\n provider: string\n): number | undefined {\n try {\n if (provider === PROVIDER_ANTHROPIC) {\n const meta = step.providerMetadata as Record<string, unknown> | undefined;\n const anthropic = meta?.anthropic as Record<string, unknown> | undefined;\n const usage = anthropic?.usage as Record<string, unknown> | undefined;\n const cost = usage?.total_cost_usd;\n return typeof cost === 'number' && cost > 0 ? cost : undefined;\n }\n\n const body = step.response?.body as Record<string, unknown> | undefined;\n const cost = body?.total_cost_usd;\n return typeof cost === 'number' && cost > 0 ? cost : undefined;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Calculate cost from the built-in pricing table.\n * Normalizes legacy gateway model IDs before lookup.\n * Returns 0 for unknown models.\n */\nfunction calculateFromPricing(\n modelId: string,\n tokenUsage: { prompt: number; completion: number }\n): number {\n const normalized = normalizeModelId(modelId);\n const pricing =\n MODEL_PRICING[normalized] ??\n MODEL_PRICING[\n Object.keys(MODEL_PRICING).find((key) => normalized.startsWith(key)) ?? ''\n ];\n if (!pricing) return 0;\n\n return (\n (tokenUsage.prompt / 1_000_000) * pricing.input +\n (tokenUsage.completion / 1_000_000) * pricing.output\n );\n}\n\n/**\n * Calculate the cost for a single LLM step.\n * Prefers the gateway-reported cost (accurate with cache discounts),\n * falling back to the built-in pricing table.\n */\nexport function calculateStepCost(\n step: StepResult<ToolSet>,\n modelId: string,\n provider: string,\n tokenUsage: { prompt: number; completion: number }\n): number {\n return (\n extractGatewayCost(step, provider) ??\n calculateFromPricing(modelId, tokenUsage)\n );\n}\n", "import type {\n ConversationBlock,\n ConversationMessage\n} from '@wix/evalforge-types';\nimport type { StepResult, ToolSet } from 'ai';\nimport { detectMcpToolError } from '../shared/detect-tool-error.js';\n\n/**\n * Build a serializable conversation from Vercel AI SDK step results.\n *\n * Maps the step-based execution model to the same ConversationMessage\n * format used by the Claude Code adapter, so both agent types render\n * identically in the Conversation tab.\n */\nexport function buildConversation(\n triggerPrompt: string,\n steps: StepResult<ToolSet>[],\n executionStartMs: number,\n stepTimestamps: number[]\n): ConversationMessage[] {\n const messages: ConversationMessage[] = [];\n\n messages.push({\n role: 'user',\n content: [{ type: 'text', text: triggerPrompt }],\n timestamp: new Date(executionStartMs).toISOString()\n });\n\n for (let i = 0; i < steps.length; i++) {\n const step = steps[i];\n const stepTimestamp = new Date(\n stepTimestamps[i] ?? executionStartMs\n ).toISOString();\n\n const assistantContent: ConversationBlock[] = [];\n\n if (step.reasoningText) {\n assistantContent.push({ type: 'thinking', thinking: step.reasoningText });\n }\n\n if (step.text) {\n assistantContent.push({ type: 'text', text: step.text });\n }\n\n for (const tc of step.toolCalls) {\n assistantContent.push({\n type: 'tool_use',\n toolName: tc.toolName,\n toolId: tc.toolCallId,\n input: tc.input\n });\n }\n\n if (assistantContent.length > 0) {\n messages.push({\n role: 'assistant',\n content: assistantContent,\n timestamp: stepTimestamp\n });\n }\n\n if (step.toolResults.length > 0) {\n const resultBlocks: ConversationBlock[] = step.toolResults.map((tr) => {\n const outputStr =\n typeof tr.output === 'string' ? tr.output : JSON.stringify(tr.output);\n const isError = detectMcpToolError(tr.output) !== null;\n return {\n type: 'tool_result' as const,\n toolUseId: tr.toolCallId,\n content: outputStr,\n ...(isError ? { isError: true } : {})\n };\n });\n messages.push({\n role: 'user',\n content: resultBlocks,\n timestamp: stepTimestamp\n });\n }\n }\n\n return messages;\n}\n", "import type {\n AgentAdapter,\n AgentExecutionContext,\n AgentExecutionResult\n} from '@wix/evalforge-types';\nimport type { AgentRunCommand } from '@wix/evalforge-types';\nimport { executeWithAiSdk } from './execute.js';\n\n/**\n * Simple Agent adapter.\n *\n * Executes LLM calls in-process via the Vercel AI SDK, routing through\n * our proxy to support both Claude and OpenAI models. Supports MCP tools\n * for interacting with the working directory.\n *\n * Looked up by adapter ID (not CLI command) since SDK agents have\n * empty supportedCommands.\n */\nexport class SimpleAgentAdapter implements AgentAdapter {\n readonly id = 'simple-agent';\n readonly name = 'Simple Agent';\n readonly supportedCommands: readonly AgentRunCommand[] = [];\n\n async execute(context: AgentExecutionContext): Promise<AgentExecutionResult> {\n return executeWithAiSdk(context);\n }\n}\n\nexport const simpleAgentAdapter = new SimpleAgentAdapter();\n", "import { defaultRegistry } from '../registry.js';\nimport { simpleAgentAdapter } from './simple-agent-adapter.js';\n\ndefaultRegistry.register(simpleAgentAdapter);\n", "/**\n * File diff utilities for capturing and comparing file changes.\n *\n * Used to track changes made by Claude during scenario execution\n * when running against a template.\n */\n\nimport { readdirSync, readFileSync, statSync, existsSync } from 'fs';\nimport { join, relative } from 'path';\nimport { diffLines as computeDiff } from 'diff';\nimport type { DiffContent, DiffLine, TemplateFile } from '@wix/evalforge-types';\n\n/**\n * Derive the set of infrastructure file paths by comparing a pre-prepare\n * snapshot with the post-prepare (baseline) snapshot.\n * Any file that was created or modified by `prepareEnvironment()` is infrastructure.\n */\nexport function deriveInfrastructurePaths(\n prePrep: FileSnapshot,\n postPrep: FileSnapshot\n): Set<string> {\n const infraPaths = new Set<string>();\n for (const path of Object.keys(postPrep)) {\n if (prePrep[path] === undefined || prePrep[path] !== postPrep[path]) {\n infraPaths.add(path);\n }\n }\n return infraPaths;\n}\n\n/**\n * A snapshot of file contents in a directory.\n * Maps relative file paths to their contents.\n */\nexport interface FileSnapshot {\n [relativePath: string]: string;\n}\n\n/**\n * Directories and patterns to ignore when snapshotting.\n */\nconst IGNORED_PATTERNS = [\n 'node_modules',\n '.git',\n '.cursor',\n 'dist',\n 'build',\n '.next',\n '.turbo',\n '__pycache__',\n '.pytest_cache',\n '.venv',\n 'venv',\n '.DS_Store'\n];\n\n/**\n * File extensions to treat as binary (skip content reading).\n */\nconst BINARY_EXTENSIONS = [\n '.png',\n '.jpg',\n '.jpeg',\n '.gif',\n '.webp',\n '.ico',\n '.svg',\n '.woff',\n '.woff2',\n '.ttf',\n '.eot',\n '.mp3',\n '.mp4',\n '.wav',\n '.avi',\n '.mov',\n '.pdf',\n '.zip',\n '.tar',\n '.gz',\n '.rar',\n '.7z',\n '.exe',\n '.dll',\n '.so',\n '.dylib'\n];\n\n/**\n * Maximum file size to read (100KB).\n * Larger files are skipped to avoid memory issues.\n */\nconst MAX_FILE_SIZE = 100 * 1024;\n\n/**\n * Check if a path should be ignored.\n */\nfunction shouldIgnore(name: string): boolean {\n return IGNORED_PATTERNS.some(\n (pattern) => name === pattern || name.startsWith(pattern + '/')\n );\n}\n\n/**\n * Check if a file is binary based on extension.\n */\nfunction isBinaryFile(filename: string): boolean {\n const lower = filename.toLowerCase();\n return BINARY_EXTENSIONS.some((ext) => lower.endsWith(ext));\n}\n\n/**\n * Recursively snapshot a directory.\n *\n * @param dir - The directory to snapshot\n * @param baseDir - The base directory for computing relative paths\n * @returns A map of relative paths to file contents\n */\nexport function snapshotDirectory(dir: string, baseDir?: string): FileSnapshot {\n const snapshot: FileSnapshot = {};\n const base = baseDir || dir;\n\n if (!existsSync(dir)) {\n return snapshot;\n }\n\n const entries = readdirSync(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = join(dir, entry.name);\n const relativePath = relative(base, fullPath);\n\n // Skip ignored directories and files\n if (shouldIgnore(entry.name)) {\n continue;\n }\n\n if (entry.isDirectory()) {\n // Recursively snapshot subdirectories\n const subSnapshot = snapshotDirectory(fullPath, base);\n Object.assign(snapshot, subSnapshot);\n } else if (entry.isFile()) {\n // Skip binary files\n if (isBinaryFile(entry.name)) {\n continue;\n }\n\n // Skip files that are too large\n try {\n const stats = statSync(fullPath);\n if (stats.size > MAX_FILE_SIZE) {\n continue;\n }\n\n // Read file contents\n const content = readFileSync(fullPath, 'utf-8');\n snapshot[relativePath] = content;\n } catch {\n // Skip files that can't be read\n continue;\n }\n }\n }\n\n return snapshot;\n}\n\n/**\n * Generate diff lines from before/after content using the Myers diff algorithm.\n * This correctly identifies the minimal set of changes by comparing content,\n * not just line positions.\n */\nfunction generateDiffLines(before: string, after: string): DiffLine[] {\n const changes = computeDiff(before, after);\n const result: DiffLine[] = [];\n let lineNumber = 1;\n\n for (const change of changes) {\n // Remove trailing newline and split into individual lines\n const lines = change.value.replace(/\\n$/, '').split('\\n');\n const type: DiffLine['type'] = change.added\n ? 'added'\n : change.removed\n ? 'removed'\n : 'unchanged';\n\n for (const content of lines) {\n result.push({\n type,\n content,\n lineNumber: lineNumber++\n });\n }\n }\n\n return result;\n}\n\n/**\n * Compare two snapshots and generate diffs for changed files.\n * Includes new empty files and detects file renames.\n *\n * @param before - Snapshot before execution\n * @param after - Snapshot after execution\n * @param infrastructurePaths - Optional set of paths known to be infrastructure files\n * @returns Array of DiffContent for files that were created, modified, or renamed\n */\nexport function diffSnapshots(\n before: FileSnapshot,\n after: FileSnapshot,\n infrastructurePaths?: Set<string>\n): DiffContent[] {\n const diffs: DiffContent[] = [];\n const allPaths = new Set([...Object.keys(before), ...Object.keys(after)]);\n\n for (const path of allPaths) {\n const beforeContent = before[path] ?? '';\n const afterContent = after[path] ?? '';\n\n // Skip when it's an existing file with no changes.\n if (before[path] !== undefined && beforeContent === afterContent) {\n continue;\n }\n\n // Generate diff\n const diffLines = generateDiffLines(beforeContent, afterContent);\n\n diffs.push({\n path,\n expected: beforeContent,\n actual: afterContent,\n diffLines,\n ...(infrastructurePaths?.has(path) && { isInfrastructure: true })\n });\n }\n\n const deletedPaths = [...allPaths].filter((p) => after[p] === undefined);\n const addedPaths = [...allPaths].filter((p) => before[p] === undefined);\n\n const renamedFromByNewPath = new Map<string, string>();\n const deletedPathsToRemove = new Set<string>();\n\n for (const addedPath of addedPaths) {\n const addedContent = after[addedPath] ?? '';\n const deletedMatch = deletedPaths.find(\n (dp) =>\n (before[dp] ?? '') === addedContent && !deletedPathsToRemove.has(dp)\n );\n if (deletedMatch) {\n renamedFromByNewPath.set(addedPath, deletedMatch);\n deletedPathsToRemove.add(deletedMatch);\n }\n }\n\n const result = diffs\n .filter((d) => !deletedPathsToRemove.has(d.path))\n .map((d) => {\n const renamedFrom = renamedFromByNewPath.get(d.path);\n return renamedFrom ? { ...d, renamedFrom } : d;\n });\n\n // Sort by path for consistent ordering\n result.sort((a, b) => a.path.localeCompare(b.path));\n\n return result;\n}\n\n/**\n * Extract template files with their status from before/after snapshots.\n *\n * @param before - Snapshot before execution\n * @param after - Snapshot after execution\n * @param infrastructurePaths - Optional set of paths known to be infrastructure files\n * @returns Array of TemplateFile with status indicators\n */\nexport function extractTemplateFiles(\n before: FileSnapshot,\n after: FileSnapshot,\n infrastructurePaths?: Set<string>\n): TemplateFile[] {\n const files: TemplateFile[] = [];\n const allPaths = new Set([...Object.keys(before), ...Object.keys(after)]);\n\n for (const path of allPaths) {\n const beforeContent = before[path];\n const afterContent = after[path];\n\n // Only include files that exist after execution (skip deleted files)\n if (afterContent === undefined) {\n continue;\n }\n\n let status: 'new' | 'modified' | 'unchanged';\n if (beforeContent === undefined) {\n status = 'new';\n } else if (beforeContent !== afterContent) {\n status = 'modified';\n } else {\n status = 'unchanged';\n }\n\n files.push({\n path,\n content: afterContent,\n status,\n ...(infrastructurePaths?.has(path) && { isInfrastructure: true })\n });\n }\n\n // Sort by path for consistent ordering\n files.sort((a, b) => a.path.localeCompare(b.path));\n\n return files;\n}\n", "function Diff() {}\nDiff.prototype = {\n diff: function diff(oldString, newString) {\n var _options$timeout;\n var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n var callback = options.callback;\n if (typeof options === 'function') {\n callback = options;\n options = {};\n }\n var self = this;\n function done(value) {\n value = self.postProcess(value, options);\n if (callback) {\n setTimeout(function () {\n callback(value);\n }, 0);\n return true;\n } else {\n return value;\n }\n }\n\n // Allow subclasses to massage the input prior to running\n oldString = this.castInput(oldString, options);\n newString = this.castInput(newString, options);\n oldString = this.removeEmpty(this.tokenize(oldString, options));\n newString = this.removeEmpty(this.tokenize(newString, options));\n var newLen = newString.length,\n oldLen = oldString.length;\n var editLength = 1;\n var maxEditLength = newLen + oldLen;\n if (options.maxEditLength != null) {\n maxEditLength = Math.min(maxEditLength, options.maxEditLength);\n }\n var maxExecutionTime = (_options$timeout = options.timeout) !== null && _options$timeout !== void 0 ? _options$timeout : Infinity;\n var abortAfterTimestamp = Date.now() + maxExecutionTime;\n var bestPath = [{\n oldPos: -1,\n lastComponent: undefined\n }];\n\n // Seed editLength = 0, i.e. the content starts with the same values\n var newPos = this.extractCommon(bestPath[0], newString, oldString, 0, options);\n if (bestPath[0].oldPos + 1 >= oldLen && newPos + 1 >= newLen) {\n // Identity per the equality and tokenizer\n return done(buildValues(self, bestPath[0].lastComponent, newString, oldString, self.useLongestToken));\n }\n\n // Once we hit the right edge of the edit graph on some diagonal k, we can\n // definitely reach the end of the edit graph in no more than k edits, so\n // there's no point in considering any moves to diagonal k+1 any more (from\n // which we're guaranteed to need at least k+1 more edits).\n // Similarly, once we've reached the bottom of the edit graph, there's no\n // point considering moves to lower diagonals.\n // We record this fact by setting minDiagonalToConsider and\n // maxDiagonalToConsider to some finite value once we've hit the edge of\n // the edit graph.\n // This optimization is not faithful to the original algorithm presented in\n // Myers's paper, which instead pointlessly extends D-paths off the end of\n // the edit graph - see page 7 of Myers's paper which notes this point\n // explicitly and illustrates it with a diagram. This has major performance\n // implications for some common scenarios. For instance, to compute a diff\n // where the new text simply appends d characters on the end of the\n // original text of length n, the true Myers algorithm will take O(n+d^2)\n // time while this optimization needs only O(n+d) time.\n var minDiagonalToConsider = -Infinity,\n maxDiagonalToConsider = Infinity;\n\n // Main worker method. checks all permutations of a given edit length for acceptance.\n function execEditLength() {\n for (var diagonalPath = Math.max(minDiagonalToConsider, -editLength); diagonalPath <= Math.min(maxDiagonalToConsider, editLength); diagonalPath += 2) {\n var basePath = void 0;\n var removePath = bestPath[diagonalPath - 1],\n addPath = bestPath[diagonalPath + 1];\n if (removePath) {\n // No one else is going to attempt to use this value, clear it\n bestPath[diagonalPath - 1] = undefined;\n }\n var canAdd = false;\n if (addPath) {\n // what newPos will be after we do an insertion:\n var addPathNewPos = addPath.oldPos - diagonalPath;\n canAdd = addPath && 0 <= addPathNewPos && addPathNewPos < newLen;\n }\n var canRemove = removePath && removePath.oldPos + 1 < oldLen;\n if (!canAdd && !canRemove) {\n // If this path is a terminal then prune\n bestPath[diagonalPath] = undefined;\n continue;\n }\n\n // Select the diagonal that we want to branch from. We select the prior\n // path whose position in the old string is the farthest from the origin\n // and does not pass the bounds of the diff graph\n if (!canRemove || canAdd && removePath.oldPos < addPath.oldPos) {\n basePath = self.addToPath(addPath, true, false, 0, options);\n } else {\n basePath = self.addToPath(removePath, false, true, 1, options);\n }\n newPos = self.extractCommon(basePath, newString, oldString, diagonalPath, options);\n if (basePath.oldPos + 1 >= oldLen && newPos + 1 >= newLen) {\n // If we have hit the end of both strings, then we are done\n return done(buildValues(self, basePath.lastComponent, newString, oldString, self.useLongestToken));\n } else {\n bestPath[diagonalPath] = basePath;\n if (basePath.oldPos + 1 >= oldLen) {\n maxDiagonalToConsider = Math.min(maxDiagonalToConsider, diagonalPath - 1);\n }\n if (newPos + 1 >= newLen) {\n minDiagonalToConsider = Math.max(minDiagonalToConsider, diagonalPath + 1);\n }\n }\n }\n editLength++;\n }\n\n // Performs the length of edit iteration. Is a bit fugly as this has to support the\n // sync and async mode which is never fun. Loops over execEditLength until a value\n // is produced, or until the edit length exceeds options.maxEditLength (if given),\n // in which case it will return undefined.\n if (callback) {\n (function exec() {\n setTimeout(function () {\n if (editLength > maxEditLength || Date.now() > abortAfterTimestamp) {\n return callback();\n }\n if (!execEditLength()) {\n exec();\n }\n }, 0);\n })();\n } else {\n while (editLength <= maxEditLength && Date.now() <= abortAfterTimestamp) {\n var ret = execEditLength();\n if (ret) {\n return ret;\n }\n }\n }\n },\n addToPath: function addToPath(path, added, removed, oldPosInc, options) {\n var last = path.lastComponent;\n if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {\n return {\n oldPos: path.oldPos + oldPosInc,\n lastComponent: {\n count: last.count + 1,\n added: added,\n removed: removed,\n previousComponent: last.previousComponent\n }\n };\n } else {\n return {\n oldPos: path.oldPos + oldPosInc,\n lastComponent: {\n count: 1,\n added: added,\n removed: removed,\n previousComponent: last\n }\n };\n }\n },\n extractCommon: function extractCommon(basePath, newString, oldString, diagonalPath, options) {\n var newLen = newString.length,\n oldLen = oldString.length,\n oldPos = basePath.oldPos,\n newPos = oldPos - diagonalPath,\n commonCount = 0;\n while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(oldString[oldPos + 1], newString[newPos + 1], options)) {\n newPos++;\n oldPos++;\n commonCount++;\n if (options.oneChangePerToken) {\n basePath.lastComponent = {\n count: 1,\n previousComponent: basePath.lastComponent,\n added: false,\n removed: false\n };\n }\n }\n if (commonCount && !options.oneChangePerToken) {\n basePath.lastComponent = {\n count: commonCount,\n previousComponent: basePath.lastComponent,\n added: false,\n removed: false\n };\n }\n basePath.oldPos = oldPos;\n return newPos;\n },\n equals: function equals(left, right, options) {\n if (options.comparator) {\n return options.comparator(left, right);\n } else {\n return left === right || options.ignoreCase && left.toLowerCase() === right.toLowerCase();\n }\n },\n removeEmpty: function removeEmpty(array) {\n var ret = [];\n for (var i = 0; i < array.length; i++) {\n if (array[i]) {\n ret.push(array[i]);\n }\n }\n return ret;\n },\n castInput: function castInput(value) {\n return value;\n },\n tokenize: function tokenize(value) {\n return Array.from(value);\n },\n join: function join(chars) {\n return chars.join('');\n },\n postProcess: function postProcess(changeObjects) {\n return changeObjects;\n }\n};\nfunction buildValues(diff, lastComponent, newString, oldString, useLongestToken) {\n // First we convert our linked list of components in reverse order to an\n // array in the right order:\n var components = [];\n var nextComponent;\n while (lastComponent) {\n components.push(lastComponent);\n nextComponent = lastComponent.previousComponent;\n delete lastComponent.previousComponent;\n lastComponent = nextComponent;\n }\n components.reverse();\n var componentPos = 0,\n componentLen = components.length,\n newPos = 0,\n oldPos = 0;\n for (; componentPos < componentLen; componentPos++) {\n var component = components[componentPos];\n if (!component.removed) {\n if (!component.added && useLongestToken) {\n var value = newString.slice(newPos, newPos + component.count);\n value = value.map(function (value, i) {\n var oldValue = oldString[oldPos + i];\n return oldValue.length > value.length ? oldValue : value;\n });\n component.value = diff.join(value);\n } else {\n component.value = diff.join(newString.slice(newPos, newPos + component.count));\n }\n newPos += component.count;\n\n // Common case\n if (!component.added) {\n oldPos += component.count;\n }\n } else {\n component.value = diff.join(oldString.slice(oldPos, oldPos + component.count));\n oldPos += component.count;\n }\n }\n return components;\n}\n\nvar characterDiff = new Diff();\nfunction diffChars(oldStr, newStr, options) {\n return characterDiff.diff(oldStr, newStr, options);\n}\n\nfunction longestCommonPrefix(str1, str2) {\n var i;\n for (i = 0; i < str1.length && i < str2.length; i++) {\n if (str1[i] != str2[i]) {\n return str1.slice(0, i);\n }\n }\n return str1.slice(0, i);\n}\nfunction longestCommonSuffix(str1, str2) {\n var i;\n\n // Unlike longestCommonPrefix, we need a special case to handle all scenarios\n // where we return the empty string since str1.slice(-0) will return the\n // entire string.\n if (!str1 || !str2 || str1[str1.length - 1] != str2[str2.length - 1]) {\n return '';\n }\n for (i = 0; i < str1.length && i < str2.length; i++) {\n if (str1[str1.length - (i + 1)] != str2[str2.length - (i + 1)]) {\n return str1.slice(-i);\n }\n }\n return str1.slice(-i);\n}\nfunction replacePrefix(string, oldPrefix, newPrefix) {\n if (string.slice(0, oldPrefix.length) != oldPrefix) {\n throw Error(\"string \".concat(JSON.stringify(string), \" doesn't start with prefix \").concat(JSON.stringify(oldPrefix), \"; this is a bug\"));\n }\n return newPrefix + string.slice(oldPrefix.length);\n}\nfunction replaceSuffix(string, oldSuffix, newSuffix) {\n if (!oldSuffix) {\n return string + newSuffix;\n }\n if (string.slice(-oldSuffix.length) != oldSuffix) {\n throw Error(\"string \".concat(JSON.stringify(string), \" doesn't end with suffix \").concat(JSON.stringify(oldSuffix), \"; this is a bug\"));\n }\n return string.slice(0, -oldSuffix.length) + newSuffix;\n}\nfunction removePrefix(string, oldPrefix) {\n return replacePrefix(string, oldPrefix, '');\n}\nfunction removeSuffix(string, oldSuffix) {\n return replaceSuffix(string, oldSuffix, '');\n}\nfunction maximumOverlap(string1, string2) {\n return string2.slice(0, overlapCount(string1, string2));\n}\n\n// Nicked from https://stackoverflow.com/a/60422853/1709587\nfunction overlapCount(a, b) {\n // Deal with cases where the strings differ in length\n var startA = 0;\n if (a.length > b.length) {\n startA = a.length - b.length;\n }\n var endB = b.length;\n if (a.length < b.length) {\n endB = a.length;\n }\n // Create a back-reference for each index\n // that should be followed in case of a mismatch.\n // We only need B to make these references:\n var map = Array(endB);\n var k = 0; // Index that lags behind j\n map[0] = 0;\n for (var j = 1; j < endB; j++) {\n if (b[j] == b[k]) {\n map[j] = map[k]; // skip over the same character (optional optimisation)\n } else {\n map[j] = k;\n }\n while (k > 0 && b[j] != b[k]) {\n k = map[k];\n }\n if (b[j] == b[k]) {\n k++;\n }\n }\n // Phase 2: use these references while iterating over A\n k = 0;\n for (var i = startA; i < a.length; i++) {\n while (k > 0 && a[i] != b[k]) {\n k = map[k];\n }\n if (a[i] == b[k]) {\n k++;\n }\n }\n return k;\n}\n\n/**\n * Returns true if the string consistently uses Windows line endings.\n */\nfunction hasOnlyWinLineEndings(string) {\n return string.includes('\\r\\n') && !string.startsWith('\\n') && !string.match(/[^\\r]\\n/);\n}\n\n/**\n * Returns true if the string consistently uses Unix line endings.\n */\nfunction hasOnlyUnixLineEndings(string) {\n return !string.includes('\\r\\n') && string.includes('\\n');\n}\n\n// Based on https://en.wikipedia.org/wiki/Latin_script_in_Unicode\n//\n// Ranges and exceptions:\n// Latin-1 Supplement, 0080\u201300FF\n// - U+00D7 \u00D7 Multiplication sign\n// - U+00F7 \u00F7 Division sign\n// Latin Extended-A, 0100\u2013017F\n// Latin Extended-B, 0180\u2013024F\n// IPA Extensions, 0250\u201302AF\n// Spacing Modifier Letters, 02B0\u201302FF\n// - U+02C7 \u02C7 &#711; Caron\n// - U+02D8 \u02D8 &#728; Breve\n// - U+02D9 \u02D9 &#729; Dot Above\n// - U+02DA \u02DA &#730; Ring Above\n// - U+02DB \u02DB &#731; Ogonek\n// - U+02DC \u02DC &#732; Small Tilde\n// - U+02DD \u02DD &#733; Double Acute Accent\n// Latin Extended Additional, 1E00\u20131EFF\nvar extendedWordChars = \"a-zA-Z0-9_\\\\u{C0}-\\\\u{FF}\\\\u{D8}-\\\\u{F6}\\\\u{F8}-\\\\u{2C6}\\\\u{2C8}-\\\\u{2D7}\\\\u{2DE}-\\\\u{2FF}\\\\u{1E00}-\\\\u{1EFF}\";\n\n// Each token is one of the following:\n// - A punctuation mark plus the surrounding whitespace\n// - A word plus the surrounding whitespace\n// - Pure whitespace (but only in the special case where this the entire text\n// is just whitespace)\n//\n// We have to include surrounding whitespace in the tokens because the two\n// alternative approaches produce horribly broken results:\n// * If we just discard the whitespace, we can't fully reproduce the original\n// text from the sequence of tokens and any attempt to render the diff will\n// get the whitespace wrong.\n// * If we have separate tokens for whitespace, then in a typical text every\n// second token will be a single space character. But this often results in\n// the optimal diff between two texts being a perverse one that preserves\n// the spaces between words but deletes and reinserts actual common words.\n// See https://github.com/kpdecker/jsdiff/issues/160#issuecomment-1866099640\n// for an example.\n//\n// Keeping the surrounding whitespace of course has implications for .equals\n// and .join, not just .tokenize.\n\n// This regex does NOT fully implement the tokenization rules described above.\n// Instead, it gives runs of whitespace their own \"token\". The tokenize method\n// then handles stitching whitespace tokens onto adjacent word or punctuation\n// tokens.\nvar tokenizeIncludingWhitespace = new RegExp(\"[\".concat(extendedWordChars, \"]+|\\\\s+|[^\").concat(extendedWordChars, \"]\"), 'ug');\nvar wordDiff = new Diff();\nwordDiff.equals = function (left, right, options) {\n if (options.ignoreCase) {\n left = left.toLowerCase();\n right = right.toLowerCase();\n }\n return left.trim() === right.trim();\n};\nwordDiff.tokenize = function (value) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n var parts;\n if (options.intlSegmenter) {\n if (options.intlSegmenter.resolvedOptions().granularity != 'word') {\n throw new Error('The segmenter passed must have a granularity of \"word\"');\n }\n parts = Array.from(options.intlSegmenter.segment(value), function (segment) {\n return segment.segment;\n });\n } else {\n parts = value.match(tokenizeIncludingWhitespace) || [];\n }\n var tokens = [];\n var prevPart = null;\n parts.forEach(function (part) {\n if (/\\s/.test(part)) {\n if (prevPart == null) {\n tokens.push(part);\n } else {\n tokens.push(tokens.pop() + part);\n }\n } else if (/\\s/.test(prevPart)) {\n if (tokens[tokens.length - 1] == prevPart) {\n tokens.push(tokens.pop() + part);\n } else {\n tokens.push(prevPart + part);\n }\n } else {\n tokens.push(part);\n }\n prevPart = part;\n });\n return tokens;\n};\nwordDiff.join = function (tokens) {\n // Tokens being joined here will always have appeared consecutively in the\n // same text, so we can simply strip off the leading whitespace from all the\n // tokens except the first (and except any whitespace-only tokens - but such\n // a token will always be the first and only token anyway) and then join them\n // and the whitespace around words and punctuation will end up correct.\n return tokens.map(function (token, i) {\n if (i == 0) {\n return token;\n } else {\n return token.replace(/^\\s+/, '');\n }\n }).join('');\n};\nwordDiff.postProcess = function (changes, options) {\n if (!changes || options.oneChangePerToken) {\n return changes;\n }\n var lastKeep = null;\n // Change objects representing any insertion or deletion since the last\n // \"keep\" change object. There can be at most one of each.\n var insertion = null;\n var deletion = null;\n changes.forEach(function (change) {\n if (change.added) {\n insertion = change;\n } else if (change.removed) {\n deletion = change;\n } else {\n if (insertion || deletion) {\n // May be false at start of text\n dedupeWhitespaceInChangeObjects(lastKeep, deletion, insertion, change);\n }\n lastKeep = change;\n insertion = null;\n deletion = null;\n }\n });\n if (insertion || deletion) {\n dedupeWhitespaceInChangeObjects(lastKeep, deletion, insertion, null);\n }\n return changes;\n};\nfunction diffWords(oldStr, newStr, options) {\n // This option has never been documented and never will be (it's clearer to\n // just call `diffWordsWithSpace` directly if you need that behavior), but\n // has existed in jsdiff for a long time, so we retain support for it here\n // for the sake of backwards compatibility.\n if ((options === null || options === void 0 ? void 0 : options.ignoreWhitespace) != null && !options.ignoreWhitespace) {\n return diffWordsWithSpace(oldStr, newStr, options);\n }\n return wordDiff.diff(oldStr, newStr, options);\n}\nfunction dedupeWhitespaceInChangeObjects(startKeep, deletion, insertion, endKeep) {\n // Before returning, we tidy up the leading and trailing whitespace of the\n // change objects to eliminate cases where trailing whitespace in one object\n // is repeated as leading whitespace in the next.\n // Below are examples of the outcomes we want here to explain the code.\n // I=insert, K=keep, D=delete\n // 1. diffing 'foo bar baz' vs 'foo baz'\n // Prior to cleanup, we have K:'foo ' D:' bar ' K:' baz'\n // After cleanup, we want: K:'foo ' D:'bar ' K:'baz'\n //\n // 2. Diffing 'foo bar baz' vs 'foo qux baz'\n // Prior to cleanup, we have K:'foo ' D:' bar ' I:' qux ' K:' baz'\n // After cleanup, we want K:'foo ' D:'bar' I:'qux' K:' baz'\n //\n // 3. Diffing 'foo\\nbar baz' vs 'foo baz'\n // Prior to cleanup, we have K:'foo ' D:'\\nbar ' K:' baz'\n // After cleanup, we want K'foo' D:'\\nbar' K:' baz'\n //\n // 4. Diffing 'foo baz' vs 'foo\\nbar baz'\n // Prior to cleanup, we have K:'foo\\n' I:'\\nbar ' K:' baz'\n // After cleanup, we ideally want K'foo' I:'\\nbar' K:' baz'\n // but don't actually manage this currently (the pre-cleanup change\n // objects don't contain enough information to make it possible).\n //\n // 5. Diffing 'foo bar baz' vs 'foo baz'\n // Prior to cleanup, we have K:'foo ' D:' bar ' K:' baz'\n // After cleanup, we want K:'foo ' D:' bar ' K:'baz'\n //\n // Our handling is unavoidably imperfect in the case where there's a single\n // indel between keeps and the whitespace has changed. For instance, consider\n // diffing 'foo\\tbar\\nbaz' vs 'foo baz'. Unless we create an extra change\n // object to represent the insertion of the space character (which isn't even\n // a token), we have no way to avoid losing information about the texts'\n // original whitespace in the result we return. Still, we do our best to\n // output something that will look sensible if we e.g. print it with\n // insertions in green and deletions in red.\n\n // Between two \"keep\" change objects (or before the first or after the last\n // change object), we can have either:\n // * A \"delete\" followed by an \"insert\"\n // * Just an \"insert\"\n // * Just a \"delete\"\n // We handle the three cases separately.\n if (deletion && insertion) {\n var oldWsPrefix = deletion.value.match(/^\\s*/)[0];\n var oldWsSuffix = deletion.value.match(/\\s*$/)[0];\n var newWsPrefix = insertion.value.match(/^\\s*/)[0];\n var newWsSuffix = insertion.value.match(/\\s*$/)[0];\n if (startKeep) {\n var commonWsPrefix = longestCommonPrefix(oldWsPrefix, newWsPrefix);\n startKeep.value = replaceSuffix(startKeep.value, newWsPrefix, commonWsPrefix);\n deletion.value = removePrefix(deletion.value, commonWsPrefix);\n insertion.value = removePrefix(insertion.value, commonWsPrefix);\n }\n if (endKeep) {\n var commonWsSuffix = longestCommonSuffix(oldWsSuffix, newWsSuffix);\n endKeep.value = replacePrefix(endKeep.value, newWsSuffix, commonWsSuffix);\n deletion.value = removeSuffix(deletion.value, commonWsSuffix);\n insertion.value = removeSuffix(insertion.value, commonWsSuffix);\n }\n } else if (insertion) {\n // The whitespaces all reflect what was in the new text rather than\n // the old, so we essentially have no information about whitespace\n // insertion or deletion. We just want to dedupe the whitespace.\n // We do that by having each change object keep its trailing\n // whitespace and deleting duplicate leading whitespace where\n // present.\n if (startKeep) {\n insertion.value = insertion.value.replace(/^\\s*/, '');\n }\n if (endKeep) {\n endKeep.value = endKeep.value.replace(/^\\s*/, '');\n }\n // otherwise we've got a deletion and no insertion\n } else if (startKeep && endKeep) {\n var newWsFull = endKeep.value.match(/^\\s*/)[0],\n delWsStart = deletion.value.match(/^\\s*/)[0],\n delWsEnd = deletion.value.match(/\\s*$/)[0];\n\n // Any whitespace that comes straight after startKeep in both the old and\n // new texts, assign to startKeep and remove from the deletion.\n var newWsStart = longestCommonPrefix(newWsFull, delWsStart);\n deletion.value = removePrefix(deletion.value, newWsStart);\n\n // Any whitespace that comes straight before endKeep in both the old and\n // new texts, and hasn't already been assigned to startKeep, assign to\n // endKeep and remove from the deletion.\n var newWsEnd = longestCommonSuffix(removePrefix(newWsFull, newWsStart), delWsEnd);\n deletion.value = removeSuffix(deletion.value, newWsEnd);\n endKeep.value = replacePrefix(endKeep.value, newWsFull, newWsEnd);\n\n // If there's any whitespace from the new text that HASN'T already been\n // assigned, assign it to the start:\n startKeep.value = replaceSuffix(startKeep.value, newWsFull, newWsFull.slice(0, newWsFull.length - newWsEnd.length));\n } else if (endKeep) {\n // We are at the start of the text. Preserve all the whitespace on\n // endKeep, and just remove whitespace from the end of deletion to the\n // extent that it overlaps with the start of endKeep.\n var endKeepWsPrefix = endKeep.value.match(/^\\s*/)[0];\n var deletionWsSuffix = deletion.value.match(/\\s*$/)[0];\n var overlap = maximumOverlap(deletionWsSuffix, endKeepWsPrefix);\n deletion.value = removeSuffix(deletion.value, overlap);\n } else if (startKeep) {\n // We are at the END of the text. Preserve all the whitespace on\n // startKeep, and just remove whitespace from the start of deletion to\n // the extent that it overlaps with the end of startKeep.\n var startKeepWsSuffix = startKeep.value.match(/\\s*$/)[0];\n var deletionWsPrefix = deletion.value.match(/^\\s*/)[0];\n var _overlap = maximumOverlap(startKeepWsSuffix, deletionWsPrefix);\n deletion.value = removePrefix(deletion.value, _overlap);\n }\n}\nvar wordWithSpaceDiff = new Diff();\nwordWithSpaceDiff.tokenize = function (value) {\n // Slightly different to the tokenizeIncludingWhitespace regex used above in\n // that this one treats each individual newline as a distinct tokens, rather\n // than merging them into other surrounding whitespace. This was requested\n // in https://github.com/kpdecker/jsdiff/issues/180 &\n // https://github.com/kpdecker/jsdiff/issues/211\n var regex = new RegExp(\"(\\\\r?\\\\n)|[\".concat(extendedWordChars, \"]+|[^\\\\S\\\\n\\\\r]+|[^\").concat(extendedWordChars, \"]\"), 'ug');\n return value.match(regex) || [];\n};\nfunction diffWordsWithSpace(oldStr, newStr, options) {\n return wordWithSpaceDiff.diff(oldStr, newStr, options);\n}\n\nfunction generateOptions(options, defaults) {\n if (typeof options === 'function') {\n defaults.callback = options;\n } else if (options) {\n for (var name in options) {\n /* istanbul ignore else */\n if (options.hasOwnProperty(name)) {\n defaults[name] = options[name];\n }\n }\n }\n return defaults;\n}\n\nvar lineDiff = new Diff();\nlineDiff.tokenize = function (value, options) {\n if (options.stripTrailingCr) {\n // remove one \\r before \\n to match GNU diff's --strip-trailing-cr behavior\n value = value.replace(/\\r\\n/g, '\\n');\n }\n var retLines = [],\n linesAndNewlines = value.split(/(\\n|\\r\\n)/);\n\n // Ignore the final empty token that occurs if the string ends with a new line\n if (!linesAndNewlines[linesAndNewlines.length - 1]) {\n linesAndNewlines.pop();\n }\n\n // Merge the content and line separators into single tokens\n for (var i = 0; i < linesAndNewlines.length; i++) {\n var line = linesAndNewlines[i];\n if (i % 2 && !options.newlineIsToken) {\n retLines[retLines.length - 1] += line;\n } else {\n retLines.push(line);\n }\n }\n return retLines;\n};\nlineDiff.equals = function (left, right, options) {\n // If we're ignoring whitespace, we need to normalise lines by stripping\n // whitespace before checking equality. (This has an annoying interaction\n // with newlineIsToken that requires special handling: if newlines get their\n // own token, then we DON'T want to trim the *newline* tokens down to empty\n // strings, since this would cause us to treat whitespace-only line content\n // as equal to a separator between lines, which would be weird and\n // inconsistent with the documented behavior of the options.)\n if (options.ignoreWhitespace) {\n if (!options.newlineIsToken || !left.includes('\\n')) {\n left = left.trim();\n }\n if (!options.newlineIsToken || !right.includes('\\n')) {\n right = right.trim();\n }\n } else if (options.ignoreNewlineAtEof && !options.newlineIsToken) {\n if (left.endsWith('\\n')) {\n left = left.slice(0, -1);\n }\n if (right.endsWith('\\n')) {\n right = right.slice(0, -1);\n }\n }\n return Diff.prototype.equals.call(this, left, right, options);\n};\nfunction diffLines(oldStr, newStr, callback) {\n return lineDiff.diff(oldStr, newStr, callback);\n}\n\n// Kept for backwards compatibility. This is a rather arbitrary wrapper method\n// that just calls `diffLines` with `ignoreWhitespace: true`. It's confusing to\n// have two ways to do exactly the same thing in the API, so we no longer\n// document this one (library users should explicitly use `diffLines` with\n// `ignoreWhitespace: true` instead) but we keep it around to maintain\n// compatibility with code that used old versions.\nfunction diffTrimmedLines(oldStr, newStr, callback) {\n var options = generateOptions(callback, {\n ignoreWhitespace: true\n });\n return lineDiff.diff(oldStr, newStr, options);\n}\n\nvar sentenceDiff = new Diff();\nsentenceDiff.tokenize = function (value) {\n return value.split(/(\\S.+?[.!?])(?=\\s+|$)/);\n};\nfunction diffSentences(oldStr, newStr, callback) {\n return sentenceDiff.diff(oldStr, newStr, callback);\n}\n\nvar cssDiff = new Diff();\ncssDiff.tokenize = function (value) {\n return value.split(/([{}:;,]|\\s+)/);\n};\nfunction diffCss(oldStr, newStr, callback) {\n return cssDiff.diff(oldStr, newStr, callback);\n}\n\nfunction ownKeys(e, r) {\n var t = Object.keys(e);\n if (Object.getOwnPropertySymbols) {\n var o = Object.getOwnPropertySymbols(e);\n r && (o = o.filter(function (r) {\n return Object.getOwnPropertyDescriptor(e, r).enumerable;\n })), t.push.apply(t, o);\n }\n return t;\n}\nfunction _objectSpread2(e) {\n for (var r = 1; r < arguments.length; r++) {\n var t = null != arguments[r] ? arguments[r] : {};\n r % 2 ? ownKeys(Object(t), !0).forEach(function (r) {\n _defineProperty(e, r, t[r]);\n }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {\n Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));\n });\n }\n return e;\n}\nfunction _toPrimitive(t, r) {\n if (\"object\" != typeof t || !t) return t;\n var e = t[Symbol.toPrimitive];\n if (void 0 !== e) {\n var i = e.call(t, r || \"default\");\n if (\"object\" != typeof i) return i;\n throw new TypeError(\"@@toPrimitive must return a primitive value.\");\n }\n return (\"string\" === r ? String : Number)(t);\n}\nfunction _toPropertyKey(t) {\n var i = _toPrimitive(t, \"string\");\n return \"symbol\" == typeof i ? i : i + \"\";\n}\nfunction _typeof(o) {\n \"@babel/helpers - typeof\";\n\n return _typeof = \"function\" == typeof Symbol && \"symbol\" == typeof Symbol.iterator ? function (o) {\n return typeof o;\n } : function (o) {\n return o && \"function\" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? \"symbol\" : typeof o;\n }, _typeof(o);\n}\nfunction _defineProperty(obj, key, value) {\n key = _toPropertyKey(key);\n if (key in obj) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n } else {\n obj[key] = value;\n }\n return obj;\n}\nfunction _toConsumableArray(arr) {\n return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();\n}\nfunction _arrayWithoutHoles(arr) {\n if (Array.isArray(arr)) return _arrayLikeToArray(arr);\n}\nfunction _iterableToArray(iter) {\n if (typeof Symbol !== \"undefined\" && iter[Symbol.iterator] != null || iter[\"@@iterator\"] != null) return Array.from(iter);\n}\nfunction _unsupportedIterableToArray(o, minLen) {\n if (!o) return;\n if (typeof o === \"string\") return _arrayLikeToArray(o, minLen);\n var n = Object.prototype.toString.call(o).slice(8, -1);\n if (n === \"Object\" && o.constructor) n = o.constructor.name;\n if (n === \"Map\" || n === \"Set\") return Array.from(o);\n if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);\n}\nfunction _arrayLikeToArray(arr, len) {\n if (len == null || len > arr.length) len = arr.length;\n for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];\n return arr2;\n}\nfunction _nonIterableSpread() {\n throw new TypeError(\"Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\");\n}\n\nvar jsonDiff = new Diff();\n// Discriminate between two lines of pretty-printed, serialized JSON where one of them has a\n// dangling comma and the other doesn't. Turns out including the dangling comma yields the nicest output:\njsonDiff.useLongestToken = true;\njsonDiff.tokenize = lineDiff.tokenize;\njsonDiff.castInput = function (value, options) {\n var undefinedReplacement = options.undefinedReplacement,\n _options$stringifyRep = options.stringifyReplacer,\n stringifyReplacer = _options$stringifyRep === void 0 ? function (k, v) {\n return typeof v === 'undefined' ? undefinedReplacement : v;\n } : _options$stringifyRep;\n return typeof value === 'string' ? value : JSON.stringify(canonicalize(value, null, null, stringifyReplacer), stringifyReplacer, ' ');\n};\njsonDiff.equals = function (left, right, options) {\n return Diff.prototype.equals.call(jsonDiff, left.replace(/,([\\r\\n])/g, '$1'), right.replace(/,([\\r\\n])/g, '$1'), options);\n};\nfunction diffJson(oldObj, newObj, options) {\n return jsonDiff.diff(oldObj, newObj, options);\n}\n\n// This function handles the presence of circular references by bailing out when encountering an\n// object that is already on the \"stack\" of items being processed. Accepts an optional replacer\nfunction canonicalize(obj, stack, replacementStack, replacer, key) {\n stack = stack || [];\n replacementStack = replacementStack || [];\n if (replacer) {\n obj = replacer(key, obj);\n }\n var i;\n for (i = 0; i < stack.length; i += 1) {\n if (stack[i] === obj) {\n return replacementStack[i];\n }\n }\n var canonicalizedObj;\n if ('[object Array]' === Object.prototype.toString.call(obj)) {\n stack.push(obj);\n canonicalizedObj = new Array(obj.length);\n replacementStack.push(canonicalizedObj);\n for (i = 0; i < obj.length; i += 1) {\n canonicalizedObj[i] = canonicalize(obj[i], stack, replacementStack, replacer, key);\n }\n stack.pop();\n replacementStack.pop();\n return canonicalizedObj;\n }\n if (obj && obj.toJSON) {\n obj = obj.toJSON();\n }\n if (_typeof(obj) === 'object' && obj !== null) {\n stack.push(obj);\n canonicalizedObj = {};\n replacementStack.push(canonicalizedObj);\n var sortedKeys = [],\n _key;\n for (_key in obj) {\n /* istanbul ignore else */\n if (Object.prototype.hasOwnProperty.call(obj, _key)) {\n sortedKeys.push(_key);\n }\n }\n sortedKeys.sort();\n for (i = 0; i < sortedKeys.length; i += 1) {\n _key = sortedKeys[i];\n canonicalizedObj[_key] = canonicalize(obj[_key], stack, replacementStack, replacer, _key);\n }\n stack.pop();\n replacementStack.pop();\n } else {\n canonicalizedObj = obj;\n }\n return canonicalizedObj;\n}\n\nvar arrayDiff = new Diff();\narrayDiff.tokenize = function (value) {\n return value.slice();\n};\narrayDiff.join = arrayDiff.removeEmpty = function (value) {\n return value;\n};\nfunction diffArrays(oldArr, newArr, callback) {\n return arrayDiff.diff(oldArr, newArr, callback);\n}\n\nfunction unixToWin(patch) {\n if (Array.isArray(patch)) {\n return patch.map(unixToWin);\n }\n return _objectSpread2(_objectSpread2({}, patch), {}, {\n hunks: patch.hunks.map(function (hunk) {\n return _objectSpread2(_objectSpread2({}, hunk), {}, {\n lines: hunk.lines.map(function (line, i) {\n var _hunk$lines;\n return line.startsWith('\\\\') || line.endsWith('\\r') || (_hunk$lines = hunk.lines[i + 1]) !== null && _hunk$lines !== void 0 && _hunk$lines.startsWith('\\\\') ? line : line + '\\r';\n })\n });\n })\n });\n}\nfunction winToUnix(patch) {\n if (Array.isArray(patch)) {\n return patch.map(winToUnix);\n }\n return _objectSpread2(_objectSpread2({}, patch), {}, {\n hunks: patch.hunks.map(function (hunk) {\n return _objectSpread2(_objectSpread2({}, hunk), {}, {\n lines: hunk.lines.map(function (line) {\n return line.endsWith('\\r') ? line.substring(0, line.length - 1) : line;\n })\n });\n })\n });\n}\n\n/**\n * Returns true if the patch consistently uses Unix line endings (or only involves one line and has\n * no line endings).\n */\nfunction isUnix(patch) {\n if (!Array.isArray(patch)) {\n patch = [patch];\n }\n return !patch.some(function (index) {\n return index.hunks.some(function (hunk) {\n return hunk.lines.some(function (line) {\n return !line.startsWith('\\\\') && line.endsWith('\\r');\n });\n });\n });\n}\n\n/**\n * Returns true if the patch uses Windows line endings and only Windows line endings.\n */\nfunction isWin(patch) {\n if (!Array.isArray(patch)) {\n patch = [patch];\n }\n return patch.some(function (index) {\n return index.hunks.some(function (hunk) {\n return hunk.lines.some(function (line) {\n return line.endsWith('\\r');\n });\n });\n }) && patch.every(function (index) {\n return index.hunks.every(function (hunk) {\n return hunk.lines.every(function (line, i) {\n var _hunk$lines2;\n return line.startsWith('\\\\') || line.endsWith('\\r') || ((_hunk$lines2 = hunk.lines[i + 1]) === null || _hunk$lines2 === void 0 ? void 0 : _hunk$lines2.startsWith('\\\\'));\n });\n });\n });\n}\n\nfunction parsePatch(uniDiff) {\n var diffstr = uniDiff.split(/\\n/),\n list = [],\n i = 0;\n function parseIndex() {\n var index = {};\n list.push(index);\n\n // Parse diff metadata\n while (i < diffstr.length) {\n var line = diffstr[i];\n\n // File header found, end parsing diff metadata\n if (/^(\\-\\-\\-|\\+\\+\\+|@@)\\s/.test(line)) {\n break;\n }\n\n // Diff index\n var header = /^(?:Index:|diff(?: -r \\w+)+)\\s+(.+?)\\s*$/.exec(line);\n if (header) {\n index.index = header[1];\n }\n i++;\n }\n\n // Parse file headers if they are defined. Unified diff requires them, but\n // there's no technical issues to have an isolated hunk without file header\n parseFileHeader(index);\n parseFileHeader(index);\n\n // Parse hunks\n index.hunks = [];\n while (i < diffstr.length) {\n var _line = diffstr[i];\n if (/^(Index:\\s|diff\\s|\\-\\-\\-\\s|\\+\\+\\+\\s|===================================================================)/.test(_line)) {\n break;\n } else if (/^@@/.test(_line)) {\n index.hunks.push(parseHunk());\n } else if (_line) {\n throw new Error('Unknown line ' + (i + 1) + ' ' + JSON.stringify(_line));\n } else {\n i++;\n }\n }\n }\n\n // Parses the --- and +++ headers, if none are found, no lines\n // are consumed.\n function parseFileHeader(index) {\n var fileHeader = /^(---|\\+\\+\\+)\\s+(.*)\\r?$/.exec(diffstr[i]);\n if (fileHeader) {\n var keyPrefix = fileHeader[1] === '---' ? 'old' : 'new';\n var data = fileHeader[2].split('\\t', 2);\n var fileName = data[0].replace(/\\\\\\\\/g, '\\\\');\n if (/^\".*\"$/.test(fileName)) {\n fileName = fileName.substr(1, fileName.length - 2);\n }\n index[keyPrefix + 'FileName'] = fileName;\n index[keyPrefix + 'Header'] = (data[1] || '').trim();\n i++;\n }\n }\n\n // Parses a hunk\n // This assumes that we are at the start of a hunk.\n function parseHunk() {\n var chunkHeaderIndex = i,\n chunkHeaderLine = diffstr[i++],\n chunkHeader = chunkHeaderLine.split(/@@ -(\\d+)(?:,(\\d+))? \\+(\\d+)(?:,(\\d+))? @@/);\n var hunk = {\n oldStart: +chunkHeader[1],\n oldLines: typeof chunkHeader[2] === 'undefined' ? 1 : +chunkHeader[2],\n newStart: +chunkHeader[3],\n newLines: typeof chunkHeader[4] === 'undefined' ? 1 : +chunkHeader[4],\n lines: []\n };\n\n // Unified Diff Format quirk: If the chunk size is 0,\n // the first number is one lower than one would expect.\n // https://www.artima.com/weblogs/viewpost.jsp?thread=164293\n if (hunk.oldLines === 0) {\n hunk.oldStart += 1;\n }\n if (hunk.newLines === 0) {\n hunk.newStart += 1;\n }\n var addCount = 0,\n removeCount = 0;\n for (; i < diffstr.length && (removeCount < hunk.oldLines || addCount < hunk.newLines || (_diffstr$i = diffstr[i]) !== null && _diffstr$i !== void 0 && _diffstr$i.startsWith('\\\\')); i++) {\n var _diffstr$i;\n var operation = diffstr[i].length == 0 && i != diffstr.length - 1 ? ' ' : diffstr[i][0];\n if (operation === '+' || operation === '-' || operation === ' ' || operation === '\\\\') {\n hunk.lines.push(diffstr[i]);\n if (operation === '+') {\n addCount++;\n } else if (operation === '-') {\n removeCount++;\n } else if (operation === ' ') {\n addCount++;\n removeCount++;\n }\n } else {\n throw new Error(\"Hunk at line \".concat(chunkHeaderIndex + 1, \" contained invalid line \").concat(diffstr[i]));\n }\n }\n\n // Handle the empty block count case\n if (!addCount && hunk.newLines === 1) {\n hunk.newLines = 0;\n }\n if (!removeCount && hunk.oldLines === 1) {\n hunk.oldLines = 0;\n }\n\n // Perform sanity checking\n if (addCount !== hunk.newLines) {\n throw new Error('Added line count did not match for hunk at line ' + (chunkHeaderIndex + 1));\n }\n if (removeCount !== hunk.oldLines) {\n throw new Error('Removed line count did not match for hunk at line ' + (chunkHeaderIndex + 1));\n }\n return hunk;\n }\n while (i < diffstr.length) {\n parseIndex();\n }\n return list;\n}\n\n// Iterator that traverses in the range of [min, max], stepping\n// by distance from a given start position. I.e. for [0, 4], with\n// start of 2, this will iterate 2, 3, 1, 4, 0.\nfunction distanceIterator (start, minLine, maxLine) {\n var wantForward = true,\n backwardExhausted = false,\n forwardExhausted = false,\n localOffset = 1;\n return function iterator() {\n if (wantForward && !forwardExhausted) {\n if (backwardExhausted) {\n localOffset++;\n } else {\n wantForward = false;\n }\n\n // Check if trying to fit beyond text length, and if not, check it fits\n // after offset location (or desired location on first iteration)\n if (start + localOffset <= maxLine) {\n return start + localOffset;\n }\n forwardExhausted = true;\n }\n if (!backwardExhausted) {\n if (!forwardExhausted) {\n wantForward = true;\n }\n\n // Check if trying to fit before text beginning, and if not, check it fits\n // before offset location\n if (minLine <= start - localOffset) {\n return start - localOffset++;\n }\n backwardExhausted = true;\n return iterator();\n }\n\n // We tried to fit hunk before text beginning and beyond text length, then\n // hunk can't fit on the text. Return undefined\n };\n}\n\nfunction applyPatch(source, uniDiff) {\n var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n if (typeof uniDiff === 'string') {\n uniDiff = parsePatch(uniDiff);\n }\n if (Array.isArray(uniDiff)) {\n if (uniDiff.length > 1) {\n throw new Error('applyPatch only works with a single input.');\n }\n uniDiff = uniDiff[0];\n }\n if (options.autoConvertLineEndings || options.autoConvertLineEndings == null) {\n if (hasOnlyWinLineEndings(source) && isUnix(uniDiff)) {\n uniDiff = unixToWin(uniDiff);\n } else if (hasOnlyUnixLineEndings(source) && isWin(uniDiff)) {\n uniDiff = winToUnix(uniDiff);\n }\n }\n\n // Apply the diff to the input\n var lines = source.split('\\n'),\n hunks = uniDiff.hunks,\n compareLine = options.compareLine || function (lineNumber, line, operation, patchContent) {\n return line === patchContent;\n },\n fuzzFactor = options.fuzzFactor || 0,\n minLine = 0;\n if (fuzzFactor < 0 || !Number.isInteger(fuzzFactor)) {\n throw new Error('fuzzFactor must be a non-negative integer');\n }\n\n // Special case for empty patch.\n if (!hunks.length) {\n return source;\n }\n\n // Before anything else, handle EOFNL insertion/removal. If the patch tells us to make a change\n // to the EOFNL that is redundant/impossible - i.e. to remove a newline that's not there, or add a\n // newline that already exists - then we either return false and fail to apply the patch (if\n // fuzzFactor is 0) or simply ignore the problem and do nothing (if fuzzFactor is >0).\n // If we do need to remove/add a newline at EOF, this will always be in the final hunk:\n var prevLine = '',\n removeEOFNL = false,\n addEOFNL = false;\n for (var i = 0; i < hunks[hunks.length - 1].lines.length; i++) {\n var line = hunks[hunks.length - 1].lines[i];\n if (line[0] == '\\\\') {\n if (prevLine[0] == '+') {\n removeEOFNL = true;\n } else if (prevLine[0] == '-') {\n addEOFNL = true;\n }\n }\n prevLine = line;\n }\n if (removeEOFNL) {\n if (addEOFNL) {\n // This means the final line gets changed but doesn't have a trailing newline in either the\n // original or patched version. In that case, we do nothing if fuzzFactor > 0, and if\n // fuzzFactor is 0, we simply validate that the source file has no trailing newline.\n if (!fuzzFactor && lines[lines.length - 1] == '') {\n return false;\n }\n } else if (lines[lines.length - 1] == '') {\n lines.pop();\n } else if (!fuzzFactor) {\n return false;\n }\n } else if (addEOFNL) {\n if (lines[lines.length - 1] != '') {\n lines.push('');\n } else if (!fuzzFactor) {\n return false;\n }\n }\n\n /**\n * Checks if the hunk can be made to fit at the provided location with at most `maxErrors`\n * insertions, substitutions, or deletions, while ensuring also that:\n * - lines deleted in the hunk match exactly, and\n * - wherever an insertion operation or block of insertion operations appears in the hunk, the\n * immediately preceding and following lines of context match exactly\n *\n * `toPos` should be set such that lines[toPos] is meant to match hunkLines[0].\n *\n * If the hunk can be applied, returns an object with properties `oldLineLastI` and\n * `replacementLines`. Otherwise, returns null.\n */\n function applyHunk(hunkLines, toPos, maxErrors) {\n var hunkLinesI = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;\n var lastContextLineMatched = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true;\n var patchedLines = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : [];\n var patchedLinesLength = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : 0;\n var nConsecutiveOldContextLines = 0;\n var nextContextLineMustMatch = false;\n for (; hunkLinesI < hunkLines.length; hunkLinesI++) {\n var hunkLine = hunkLines[hunkLinesI],\n operation = hunkLine.length > 0 ? hunkLine[0] : ' ',\n content = hunkLine.length > 0 ? hunkLine.substr(1) : hunkLine;\n if (operation === '-') {\n if (compareLine(toPos + 1, lines[toPos], operation, content)) {\n toPos++;\n nConsecutiveOldContextLines = 0;\n } else {\n if (!maxErrors || lines[toPos] == null) {\n return null;\n }\n patchedLines[patchedLinesLength] = lines[toPos];\n return applyHunk(hunkLines, toPos + 1, maxErrors - 1, hunkLinesI, false, patchedLines, patchedLinesLength + 1);\n }\n }\n if (operation === '+') {\n if (!lastContextLineMatched) {\n return null;\n }\n patchedLines[patchedLinesLength] = content;\n patchedLinesLength++;\n nConsecutiveOldContextLines = 0;\n nextContextLineMustMatch = true;\n }\n if (operation === ' ') {\n nConsecutiveOldContextLines++;\n patchedLines[patchedLinesLength] = lines[toPos];\n if (compareLine(toPos + 1, lines[toPos], operation, content)) {\n patchedLinesLength++;\n lastContextLineMatched = true;\n nextContextLineMustMatch = false;\n toPos++;\n } else {\n if (nextContextLineMustMatch || !maxErrors) {\n return null;\n }\n\n // Consider 3 possibilities in sequence:\n // 1. lines contains a *substitution* not included in the patch context, or\n // 2. lines contains an *insertion* not included in the patch context, or\n // 3. lines contains a *deletion* not included in the patch context\n // The first two options are of course only possible if the line from lines is non-null -\n // i.e. only option 3 is possible if we've overrun the end of the old file.\n return lines[toPos] && (applyHunk(hunkLines, toPos + 1, maxErrors - 1, hunkLinesI + 1, false, patchedLines, patchedLinesLength + 1) || applyHunk(hunkLines, toPos + 1, maxErrors - 1, hunkLinesI, false, patchedLines, patchedLinesLength + 1)) || applyHunk(hunkLines, toPos, maxErrors - 1, hunkLinesI + 1, false, patchedLines, patchedLinesLength);\n }\n }\n }\n\n // Before returning, trim any unmodified context lines off the end of patchedLines and reduce\n // toPos (and thus oldLineLastI) accordingly. This allows later hunks to be applied to a region\n // that starts in this hunk's trailing context.\n patchedLinesLength -= nConsecutiveOldContextLines;\n toPos -= nConsecutiveOldContextLines;\n patchedLines.length = patchedLinesLength;\n return {\n patchedLines: patchedLines,\n oldLineLastI: toPos - 1\n };\n }\n var resultLines = [];\n\n // Search best fit offsets for each hunk based on the previous ones\n var prevHunkOffset = 0;\n for (var _i = 0; _i < hunks.length; _i++) {\n var hunk = hunks[_i];\n var hunkResult = void 0;\n var maxLine = lines.length - hunk.oldLines + fuzzFactor;\n var toPos = void 0;\n for (var maxErrors = 0; maxErrors <= fuzzFactor; maxErrors++) {\n toPos = hunk.oldStart + prevHunkOffset - 1;\n var iterator = distanceIterator(toPos, minLine, maxLine);\n for (; toPos !== undefined; toPos = iterator()) {\n hunkResult = applyHunk(hunk.lines, toPos, maxErrors);\n if (hunkResult) {\n break;\n }\n }\n if (hunkResult) {\n break;\n }\n }\n if (!hunkResult) {\n return false;\n }\n\n // Copy everything from the end of where we applied the last hunk to the start of this hunk\n for (var _i2 = minLine; _i2 < toPos; _i2++) {\n resultLines.push(lines[_i2]);\n }\n\n // Add the lines produced by applying the hunk:\n for (var _i3 = 0; _i3 < hunkResult.patchedLines.length; _i3++) {\n var _line = hunkResult.patchedLines[_i3];\n resultLines.push(_line);\n }\n\n // Set lower text limit to end of the current hunk, so next ones don't try\n // to fit over already patched text\n minLine = hunkResult.oldLineLastI + 1;\n\n // Note the offset between where the patch said the hunk should've applied and where we\n // applied it, so we can adjust future hunks accordingly:\n prevHunkOffset = toPos + 1 - hunk.oldStart;\n }\n\n // Copy over the rest of the lines from the old text\n for (var _i4 = minLine; _i4 < lines.length; _i4++) {\n resultLines.push(lines[_i4]);\n }\n return resultLines.join('\\n');\n}\n\n// Wrapper that supports multiple file patches via callbacks.\nfunction applyPatches(uniDiff, options) {\n if (typeof uniDiff === 'string') {\n uniDiff = parsePatch(uniDiff);\n }\n var currentIndex = 0;\n function processIndex() {\n var index = uniDiff[currentIndex++];\n if (!index) {\n return options.complete();\n }\n options.loadFile(index, function (err, data) {\n if (err) {\n return options.complete(err);\n }\n var updatedContent = applyPatch(data, index, options);\n options.patched(index, updatedContent, function (err) {\n if (err) {\n return options.complete(err);\n }\n processIndex();\n });\n });\n }\n processIndex();\n}\n\nfunction structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) {\n if (!options) {\n options = {};\n }\n if (typeof options === 'function') {\n options = {\n callback: options\n };\n }\n if (typeof options.context === 'undefined') {\n options.context = 4;\n }\n if (options.newlineIsToken) {\n throw new Error('newlineIsToken may not be used with patch-generation functions, only with diffing functions');\n }\n if (!options.callback) {\n return diffLinesResultToPatch(diffLines(oldStr, newStr, options));\n } else {\n var _options = options,\n _callback = _options.callback;\n diffLines(oldStr, newStr, _objectSpread2(_objectSpread2({}, options), {}, {\n callback: function callback(diff) {\n var patch = diffLinesResultToPatch(diff);\n _callback(patch);\n }\n }));\n }\n function diffLinesResultToPatch(diff) {\n // STEP 1: Build up the patch with no \"\\" lines and with the arrays\n // of lines containing trailing newline characters. We'll tidy up later...\n\n if (!diff) {\n return;\n }\n diff.push({\n value: '',\n lines: []\n }); // Append an empty value to make cleanup easier\n\n function contextLines(lines) {\n return lines.map(function (entry) {\n return ' ' + entry;\n });\n }\n var hunks = [];\n var oldRangeStart = 0,\n newRangeStart = 0,\n curRange = [],\n oldLine = 1,\n newLine = 1;\n var _loop = function _loop() {\n var current = diff[i],\n lines = current.lines || splitLines(current.value);\n current.lines = lines;\n if (current.added || current.removed) {\n var _curRange;\n // If we have previous context, start with that\n if (!oldRangeStart) {\n var prev = diff[i - 1];\n oldRangeStart = oldLine;\n newRangeStart = newLine;\n if (prev) {\n curRange = options.context > 0 ? contextLines(prev.lines.slice(-options.context)) : [];\n oldRangeStart -= curRange.length;\n newRangeStart -= curRange.length;\n }\n }\n\n // Output our changes\n (_curRange = curRange).push.apply(_curRange, _toConsumableArray(lines.map(function (entry) {\n return (current.added ? '+' : '-') + entry;\n })));\n\n // Track the updated file position\n if (current.added) {\n newLine += lines.length;\n } else {\n oldLine += lines.length;\n }\n } else {\n // Identical context lines. Track line changes\n if (oldRangeStart) {\n // Close out any changes that have been output (or join overlapping)\n if (lines.length <= options.context * 2 && i < diff.length - 2) {\n var _curRange2;\n // Overlapping\n (_curRange2 = curRange).push.apply(_curRange2, _toConsumableArray(contextLines(lines)));\n } else {\n var _curRange3;\n // end the range and output\n var contextSize = Math.min(lines.length, options.context);\n (_curRange3 = curRange).push.apply(_curRange3, _toConsumableArray(contextLines(lines.slice(0, contextSize))));\n var _hunk = {\n oldStart: oldRangeStart,\n oldLines: oldLine - oldRangeStart + contextSize,\n newStart: newRangeStart,\n newLines: newLine - newRangeStart + contextSize,\n lines: curRange\n };\n hunks.push(_hunk);\n oldRangeStart = 0;\n newRangeStart = 0;\n curRange = [];\n }\n }\n oldLine += lines.length;\n newLine += lines.length;\n }\n };\n for (var i = 0; i < diff.length; i++) {\n _loop();\n }\n\n // Step 2: eliminate the trailing `\\n` from each line of each hunk, and, where needed, add\n // \"\\".\n for (var _i = 0, _hunks = hunks; _i < _hunks.length; _i++) {\n var hunk = _hunks[_i];\n for (var _i2 = 0; _i2 < hunk.lines.length; _i2++) {\n if (hunk.lines[_i2].endsWith('\\n')) {\n hunk.lines[_i2] = hunk.lines[_i2].slice(0, -1);\n } else {\n hunk.lines.splice(_i2 + 1, 0, '\\\');\n _i2++; // Skip the line we just added, then continue iterating\n }\n }\n }\n return {\n oldFileName: oldFileName,\n newFileName: newFileName,\n oldHeader: oldHeader,\n newHeader: newHeader,\n hunks: hunks\n };\n }\n}\nfunction formatPatch(diff) {\n if (Array.isArray(diff)) {\n return diff.map(formatPatch).join('\\n');\n }\n var ret = [];\n if (diff.oldFileName == diff.newFileName) {\n ret.push('Index: ' + diff.oldFileName);\n }\n ret.push('===================================================================');\n ret.push('--- ' + diff.oldFileName + (typeof diff.oldHeader === 'undefined' ? '' : '\\t' + diff.oldHeader));\n ret.push('+++ ' + diff.newFileName + (typeof diff.newHeader === 'undefined' ? '' : '\\t' + diff.newHeader));\n for (var i = 0; i < diff.hunks.length; i++) {\n var hunk = diff.hunks[i];\n // Unified Diff Format quirk: If the chunk size is 0,\n // the first number is one lower than one would expect.\n // https://www.artima.com/weblogs/viewpost.jsp?thread=164293\n if (hunk.oldLines === 0) {\n hunk.oldStart -= 1;\n }\n if (hunk.newLines === 0) {\n hunk.newStart -= 1;\n }\n ret.push('@@ -' + hunk.oldStart + ',' + hunk.oldLines + ' +' + hunk.newStart + ',' + hunk.newLines + ' @@');\n ret.push.apply(ret, hunk.lines);\n }\n return ret.join('\\n') + '\\n';\n}\nfunction createTwoFilesPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) {\n var _options2;\n if (typeof options === 'function') {\n options = {\n callback: options\n };\n }\n if (!((_options2 = options) !== null && _options2 !== void 0 && _options2.callback)) {\n var patchObj = structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options);\n if (!patchObj) {\n return;\n }\n return formatPatch(patchObj);\n } else {\n var _options3 = options,\n _callback2 = _options3.callback;\n structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, _objectSpread2(_objectSpread2({}, options), {}, {\n callback: function callback(patchObj) {\n if (!patchObj) {\n _callback2();\n } else {\n _callback2(formatPatch(patchObj));\n }\n }\n }));\n }\n}\nfunction createPatch(fileName, oldStr, newStr, oldHeader, newHeader, options) {\n return createTwoFilesPatch(fileName, fileName, oldStr, newStr, oldHeader, newHeader, options);\n}\n\n/**\n * Split `text` into an array of lines, including the trailing newline character (where present)\n */\nfunction splitLines(text) {\n var hasTrailingNl = text.endsWith('\\n');\n var result = text.split('\\n').map(function (line) {\n return line + '\\n';\n });\n if (hasTrailingNl) {\n result.pop();\n } else {\n result.push(result.pop().slice(0, -1));\n }\n return result;\n}\n\nfunction arrayEqual(a, b) {\n if (a.length !== b.length) {\n return false;\n }\n return arrayStartsWith(a, b);\n}\nfunction arrayStartsWith(array, start) {\n if (start.length > array.length) {\n return false;\n }\n for (var i = 0; i < start.length; i++) {\n if (start[i] !== array[i]) {\n return false;\n }\n }\n return true;\n}\n\nfunction calcLineCount(hunk) {\n var _calcOldNewLineCount = calcOldNewLineCount(hunk.lines),\n oldLines = _calcOldNewLineCount.oldLines,\n newLines = _calcOldNewLineCount.newLines;\n if (oldLines !== undefined) {\n hunk.oldLines = oldLines;\n } else {\n delete hunk.oldLines;\n }\n if (newLines !== undefined) {\n hunk.newLines = newLines;\n } else {\n delete hunk.newLines;\n }\n}\nfunction merge(mine, theirs, base) {\n mine = loadPatch(mine, base);\n theirs = loadPatch(theirs, base);\n var ret = {};\n\n // For index we just let it pass through as it doesn't have any necessary meaning.\n // Leaving sanity checks on this to the API consumer that may know more about the\n // meaning in their own context.\n if (mine.index || theirs.index) {\n ret.index = mine.index || theirs.index;\n }\n if (mine.newFileName || theirs.newFileName) {\n if (!fileNameChanged(mine)) {\n // No header or no change in ours, use theirs (and ours if theirs does not exist)\n ret.oldFileName = theirs.oldFileName || mine.oldFileName;\n ret.newFileName = theirs.newFileName || mine.newFileName;\n ret.oldHeader = theirs.oldHeader || mine.oldHeader;\n ret.newHeader = theirs.newHeader || mine.newHeader;\n } else if (!fileNameChanged(theirs)) {\n // No header or no change in theirs, use ours\n ret.oldFileName = mine.oldFileName;\n ret.newFileName = mine.newFileName;\n ret.oldHeader = mine.oldHeader;\n ret.newHeader = mine.newHeader;\n } else {\n // Both changed... figure it out\n ret.oldFileName = selectField(ret, mine.oldFileName, theirs.oldFileName);\n ret.newFileName = selectField(ret, mine.newFileName, theirs.newFileName);\n ret.oldHeader = selectField(ret, mine.oldHeader, theirs.oldHeader);\n ret.newHeader = selectField(ret, mine.newHeader, theirs.newHeader);\n }\n }\n ret.hunks = [];\n var mineIndex = 0,\n theirsIndex = 0,\n mineOffset = 0,\n theirsOffset = 0;\n while (mineIndex < mine.hunks.length || theirsIndex < theirs.hunks.length) {\n var mineCurrent = mine.hunks[mineIndex] || {\n oldStart: Infinity\n },\n theirsCurrent = theirs.hunks[theirsIndex] || {\n oldStart: Infinity\n };\n if (hunkBefore(mineCurrent, theirsCurrent)) {\n // This patch does not overlap with any of the others, yay.\n ret.hunks.push(cloneHunk(mineCurrent, mineOffset));\n mineIndex++;\n theirsOffset += mineCurrent.newLines - mineCurrent.oldLines;\n } else if (hunkBefore(theirsCurrent, mineCurrent)) {\n // This patch does not overlap with any of the others, yay.\n ret.hunks.push(cloneHunk(theirsCurrent, theirsOffset));\n theirsIndex++;\n mineOffset += theirsCurrent.newLines - theirsCurrent.oldLines;\n } else {\n // Overlap, merge as best we can\n var mergedHunk = {\n oldStart: Math.min(mineCurrent.oldStart, theirsCurrent.oldStart),\n oldLines: 0,\n newStart: Math.min(mineCurrent.newStart + mineOffset, theirsCurrent.oldStart + theirsOffset),\n newLines: 0,\n lines: []\n };\n mergeLines(mergedHunk, mineCurrent.oldStart, mineCurrent.lines, theirsCurrent.oldStart, theirsCurrent.lines);\n theirsIndex++;\n mineIndex++;\n ret.hunks.push(mergedHunk);\n }\n }\n return ret;\n}\nfunction loadPatch(param, base) {\n if (typeof param === 'string') {\n if (/^@@/m.test(param) || /^Index:/m.test(param)) {\n return parsePatch(param)[0];\n }\n if (!base) {\n throw new Error('Must provide a base reference or pass in a patch');\n }\n return structuredPatch(undefined, undefined, base, param);\n }\n return param;\n}\nfunction fileNameChanged(patch) {\n return patch.newFileName && patch.newFileName !== patch.oldFileName;\n}\nfunction selectField(index, mine, theirs) {\n if (mine === theirs) {\n return mine;\n } else {\n index.conflict = true;\n return {\n mine: mine,\n theirs: theirs\n };\n }\n}\nfunction hunkBefore(test, check) {\n return test.oldStart < check.oldStart && test.oldStart + test.oldLines < check.oldStart;\n}\nfunction cloneHunk(hunk, offset) {\n return {\n oldStart: hunk.oldStart,\n oldLines: hunk.oldLines,\n newStart: hunk.newStart + offset,\n newLines: hunk.newLines,\n lines: hunk.lines\n };\n}\nfunction mergeLines(hunk, mineOffset, mineLines, theirOffset, theirLines) {\n // This will generally result in a conflicted hunk, but there are cases where the context\n // is the only overlap where we can successfully merge the content here.\n var mine = {\n offset: mineOffset,\n lines: mineLines,\n index: 0\n },\n their = {\n offset: theirOffset,\n lines: theirLines,\n index: 0\n };\n\n // Handle any leading content\n insertLeading(hunk, mine, their);\n insertLeading(hunk, their, mine);\n\n // Now in the overlap content. Scan through and select the best changes from each.\n while (mine.index < mine.lines.length && their.index < their.lines.length) {\n var mineCurrent = mine.lines[mine.index],\n theirCurrent = their.lines[their.index];\n if ((mineCurrent[0] === '-' || mineCurrent[0] === '+') && (theirCurrent[0] === '-' || theirCurrent[0] === '+')) {\n // Both modified ...\n mutualChange(hunk, mine, their);\n } else if (mineCurrent[0] === '+' && theirCurrent[0] === ' ') {\n var _hunk$lines;\n // Mine inserted\n (_hunk$lines = hunk.lines).push.apply(_hunk$lines, _toConsumableArray(collectChange(mine)));\n } else if (theirCurrent[0] === '+' && mineCurrent[0] === ' ') {\n var _hunk$lines2;\n // Theirs inserted\n (_hunk$lines2 = hunk.lines).push.apply(_hunk$lines2, _toConsumableArray(collectChange(their)));\n } else if (mineCurrent[0] === '-' && theirCurrent[0] === ' ') {\n // Mine removed or edited\n removal(hunk, mine, their);\n } else if (theirCurrent[0] === '-' && mineCurrent[0] === ' ') {\n // Their removed or edited\n removal(hunk, their, mine, true);\n } else if (mineCurrent === theirCurrent) {\n // Context identity\n hunk.lines.push(mineCurrent);\n mine.index++;\n their.index++;\n } else {\n // Context mismatch\n conflict(hunk, collectChange(mine), collectChange(their));\n }\n }\n\n // Now push anything that may be remaining\n insertTrailing(hunk, mine);\n insertTrailing(hunk, their);\n calcLineCount(hunk);\n}\nfunction mutualChange(hunk, mine, their) {\n var myChanges = collectChange(mine),\n theirChanges = collectChange(their);\n if (allRemoves(myChanges) && allRemoves(theirChanges)) {\n // Special case for remove changes that are supersets of one another\n if (arrayStartsWith(myChanges, theirChanges) && skipRemoveSuperset(their, myChanges, myChanges.length - theirChanges.length)) {\n var _hunk$lines3;\n (_hunk$lines3 = hunk.lines).push.apply(_hunk$lines3, _toConsumableArray(myChanges));\n return;\n } else if (arrayStartsWith(theirChanges, myChanges) && skipRemoveSuperset(mine, theirChanges, theirChanges.length - myChanges.length)) {\n var _hunk$lines4;\n (_hunk$lines4 = hunk.lines).push.apply(_hunk$lines4, _toConsumableArray(theirChanges));\n return;\n }\n } else if (arrayEqual(myChanges, theirChanges)) {\n var _hunk$lines5;\n (_hunk$lines5 = hunk.lines).push.apply(_hunk$lines5, _toConsumableArray(myChanges));\n return;\n }\n conflict(hunk, myChanges, theirChanges);\n}\nfunction removal(hunk, mine, their, swap) {\n var myChanges = collectChange(mine),\n theirChanges = collectContext(their, myChanges);\n if (theirChanges.merged) {\n var _hunk$lines6;\n (_hunk$lines6 = hunk.lines).push.apply(_hunk$lines6, _toConsumableArray(theirChanges.merged));\n } else {\n conflict(hunk, swap ? theirChanges : myChanges, swap ? myChanges : theirChanges);\n }\n}\nfunction conflict(hunk, mine, their) {\n hunk.conflict = true;\n hunk.lines.push({\n conflict: true,\n mine: mine,\n theirs: their\n });\n}\nfunction insertLeading(hunk, insert, their) {\n while (insert.offset < their.offset && insert.index < insert.lines.length) {\n var line = insert.lines[insert.index++];\n hunk.lines.push(line);\n insert.offset++;\n }\n}\nfunction insertTrailing(hunk, insert) {\n while (insert.index < insert.lines.length) {\n var line = insert.lines[insert.index++];\n hunk.lines.push(line);\n }\n}\nfunction collectChange(state) {\n var ret = [],\n operation = state.lines[state.index][0];\n while (state.index < state.lines.length) {\n var line = state.lines[state.index];\n\n // Group additions that are immediately after subtractions and treat them as one \"atomic\" modify change.\n if (operation === '-' && line[0] === '+') {\n operation = '+';\n }\n if (operation === line[0]) {\n ret.push(line);\n state.index++;\n } else {\n break;\n }\n }\n return ret;\n}\nfunction collectContext(state, matchChanges) {\n var changes = [],\n merged = [],\n matchIndex = 0,\n contextChanges = false,\n conflicted = false;\n while (matchIndex < matchChanges.length && state.index < state.lines.length) {\n var change = state.lines[state.index],\n match = matchChanges[matchIndex];\n\n // Once we've hit our add, then we are done\n if (match[0] === '+') {\n break;\n }\n contextChanges = contextChanges || change[0] !== ' ';\n merged.push(match);\n matchIndex++;\n\n // Consume any additions in the other block as a conflict to attempt\n // to pull in the remaining context after this\n if (change[0] === '+') {\n conflicted = true;\n while (change[0] === '+') {\n changes.push(change);\n change = state.lines[++state.index];\n }\n }\n if (match.substr(1) === change.substr(1)) {\n changes.push(change);\n state.index++;\n } else {\n conflicted = true;\n }\n }\n if ((matchChanges[matchIndex] || '')[0] === '+' && contextChanges) {\n conflicted = true;\n }\n if (conflicted) {\n return changes;\n }\n while (matchIndex < matchChanges.length) {\n merged.push(matchChanges[matchIndex++]);\n }\n return {\n merged: merged,\n changes: changes\n };\n}\nfunction allRemoves(changes) {\n return changes.reduce(function (prev, change) {\n return prev && change[0] === '-';\n }, true);\n}\nfunction skipRemoveSuperset(state, removeChanges, delta) {\n for (var i = 0; i < delta; i++) {\n var changeContent = removeChanges[removeChanges.length - delta + i].substr(1);\n if (state.lines[state.index + i] !== ' ' + changeContent) {\n return false;\n }\n }\n state.index += delta;\n return true;\n}\nfunction calcOldNewLineCount(lines) {\n var oldLines = 0;\n var newLines = 0;\n lines.forEach(function (line) {\n if (typeof line !== 'string') {\n var myCount = calcOldNewLineCount(line.mine);\n var theirCount = calcOldNewLineCount(line.theirs);\n if (oldLines !== undefined) {\n if (myCount.oldLines === theirCount.oldLines) {\n oldLines += myCount.oldLines;\n } else {\n oldLines = undefined;\n }\n }\n if (newLines !== undefined) {\n if (myCount.newLines === theirCount.newLines) {\n newLines += myCount.newLines;\n } else {\n newLines = undefined;\n }\n }\n } else {\n if (newLines !== undefined && (line[0] === '+' || line[0] === ' ')) {\n newLines++;\n }\n if (oldLines !== undefined && (line[0] === '-' || line[0] === ' ')) {\n oldLines++;\n }\n }\n });\n return {\n oldLines: oldLines,\n newLines: newLines\n };\n}\n\nfunction reversePatch(structuredPatch) {\n if (Array.isArray(structuredPatch)) {\n return structuredPatch.map(reversePatch).reverse();\n }\n return _objectSpread2(_objectSpread2({}, structuredPatch), {}, {\n oldFileName: structuredPatch.newFileName,\n oldHeader: structuredPatch.newHeader,\n newFileName: structuredPatch.oldFileName,\n newHeader: structuredPatch.oldHeader,\n hunks: structuredPatch.hunks.map(function (hunk) {\n return {\n oldLines: hunk.newLines,\n oldStart: hunk.newStart,\n newLines: hunk.oldLines,\n newStart: hunk.oldStart,\n lines: hunk.lines.map(function (l) {\n if (l.startsWith('-')) {\n return \"+\".concat(l.slice(1));\n }\n if (l.startsWith('+')) {\n return \"-\".concat(l.slice(1));\n }\n return l;\n })\n };\n })\n });\n}\n\n// See: http://code.google.com/p/google-diff-match-patch/wiki/API\nfunction convertChangesToDMP(changes) {\n var ret = [],\n change,\n operation;\n for (var i = 0; i < changes.length; i++) {\n change = changes[i];\n if (change.added) {\n operation = 1;\n } else if (change.removed) {\n operation = -1;\n } else {\n operation = 0;\n }\n ret.push([operation, change.value]);\n }\n return ret;\n}\n\nfunction convertChangesToXML(changes) {\n var ret = [];\n for (var i = 0; i < changes.length; i++) {\n var change = changes[i];\n if (change.added) {\n ret.push('<ins>');\n } else if (change.removed) {\n ret.push('<del>');\n }\n ret.push(escapeHTML(change.value));\n if (change.added) {\n ret.push('</ins>');\n } else if (change.removed) {\n ret.push('</del>');\n }\n }\n return ret.join('');\n}\nfunction escapeHTML(s) {\n var n = s;\n n = n.replace(/&/g, '&amp;');\n n = n.replace(/</g, '&lt;');\n n = n.replace(/>/g, '&gt;');\n n = n.replace(/\"/g, '&quot;');\n return n;\n}\n\nexport { Diff, applyPatch, applyPatches, canonicalize, convertChangesToDMP, convertChangesToXML, createPatch, createTwoFilesPatch, diffArrays, diffChars, diffCss, diffJson, diffLines, diffSentences, diffTrimmedLines, diffWords, diffWordsWithSpace, formatPatch, merge, parsePatch, reversePatch, structuredPatch };\n", "/**\n * Error Reporter Module\n *\n * Provides comprehensive error reporting functionality for the evaluator.\n * Captures detailed error information including stack traces and context,\n * and sends it to the server so failures can be debugged without accessing\n * the remote machine logs.\n */\n\nimport { EvalStatus } from '@wix/evalforge-types';\nimport type { EvaluatorConfig } from './config.js';\nimport { createApiClient } from './api-client.js';\n\n/**\n * Detailed error information to send to the server.\n */\nexport interface ErrorDetails {\n /** Short error message */\n message: string;\n /** Full stack trace if available */\n stack?: string;\n /** Error name/type (e.g., \"TypeError\", \"Error\") */\n errorType?: string;\n /** Phase of execution where the error occurred */\n phase?: string;\n /** Additional context about what was happening */\n context?: Record<string, unknown>;\n /** Timestamp when the error occurred */\n timestamp: string;\n}\n\n/**\n * Format an error into detailed error information.\n *\n * @param error - The error to format\n * @param phase - The phase of execution (e.g., \"config\", \"fetch\", \"execution\")\n * @param context - Additional context about what was happening\n * @returns Formatted error details\n */\nexport function formatError(\n error: unknown,\n phase?: string,\n context?: Record<string, unknown>\n): ErrorDetails {\n const timestamp = new Date().toISOString();\n\n if (error instanceof Error) {\n return {\n message: error.message,\n stack: error.stack,\n errorType: error.constructor.name,\n phase,\n context,\n timestamp\n };\n }\n\n // Handle non-Error types (strings, objects, etc.)\n return {\n message: String(error),\n errorType: typeof error,\n phase,\n context,\n timestamp\n };\n}\n\n/**\n * Format error details into a string suitable for the jobError field.\n * Includes the message, stack trace, and context in a readable format.\n *\n * @param details - The error details to format\n * @returns A formatted string with all error information\n */\nexport function formatErrorForJobError(details: ErrorDetails): string {\n const parts: string[] = [];\n\n // Add phase context\n if (details.phase) {\n parts.push(`[Phase: ${details.phase}]`);\n }\n\n // Add error type and message\n if (details.errorType && details.errorType !== 'Error') {\n parts.push(`${details.errorType}: ${details.message}`);\n } else {\n parts.push(details.message);\n }\n\n // Add context if present\n if (details.context && Object.keys(details.context).length > 0) {\n parts.push(`\\nContext: ${JSON.stringify(details.context)}`);\n }\n\n // Add stack trace (first 5 lines to keep it manageable)\n if (details.stack) {\n const stackLines = details.stack.split('\\n').slice(0, 6);\n parts.push(`\\nStack:\\n${stackLines.join('\\n')}`);\n }\n\n return parts.join(' ');\n}\n\n/**\n * Report an error to the server.\n *\n * This function attempts to update the eval run status to FAILED\n * with detailed error information. If the update fails, it logs\n * the error to stderr.\n *\n * @param config - Evaluator configuration (can be partial if config loading failed)\n * @param projectId - The project ID\n * @param evalRunId - The eval run ID\n * @param error - The error to report\n * @param phase - The phase where the error occurred\n * @param context - Additional context\n */\nexport async function reportError(\n config: Partial<EvaluatorConfig> | null,\n projectId: string,\n evalRunId: string,\n error: unknown,\n phase?: string,\n context?: Record<string, unknown>\n): Promise<void> {\n const errorDetails = formatError(error, phase, context);\n const jobError = formatErrorForJobError(errorDetails);\n\n // Log to stderr for local debugging\n console.error('[EVALUATOR-ERROR]', JSON.stringify(errorDetails, null, 2));\n\n // If we don't have a valid config, we can't report to the server\n if (!config?.serverUrl) {\n console.error('[EVALUATOR-ERROR] Cannot report to server: no serverUrl');\n return;\n }\n\n try {\n const api = createApiClient(config.serverUrl, {\n apiPrefix: config.apiPrefix,\n routeHeader: config.routeHeader,\n authToken: config.authToken\n });\n\n await api.updateEvalRun(projectId, evalRunId, {\n status: EvalStatus.FAILED,\n completedAt: new Date().toISOString(),\n jobError,\n jobStatus: 'FAILED'\n });\n\n console.error('[EVALUATOR-ERROR] Successfully reported error to server');\n } catch (reportErr) {\n console.error(\n '[EVALUATOR-ERROR] Failed to report error to server:',\n reportErr\n );\n }\n}\n\n/**\n * Execution phases for error context.\n */\nexport const ExecutionPhase = {\n /** Environment diagnostics phase (runs before execution) */\n DIAGNOSTICS: 'diagnostics',\n CONFIG: 'config-loading',\n API_CLIENT: 'api-client-creation',\n FETCH_EVAL_RUN: 'fetch-eval-run',\n FETCH_SKILLS: 'fetch-skills',\n FETCH_AGENT: 'fetch-agent',\n FETCH_SCENARIOS: 'fetch-scenarios',\n VALIDATION: 'validation',\n PREPARE_WORKSPACE: 'prepare-workspace',\n EXECUTE_SKILL: 'execute-skill',\n EXECUTE_AGENT: 'execute-agent',\n CLAUDE_SDK_IMPORT: 'claude-sdk-import',\n CLAUDE_SDK_EXECUTION: 'claude-sdk-execution',\n ADD_RESULT: 'add-result',\n UPDATE_STATUS: 'update-status'\n} as const;\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["#!/usr/bin/env node\n\n/**\n * EvalForge Evaluator Entry Point\n *\n * This module runs evaluations on a remote Dev Machine.\n * It fetches evaluation data from the server, runs scenarios,\n * and reports results (including detailed error information).\n */\n\n// CRITICAL: Log immediately at module load time to catch import failures\nconsole.error(\n '[EVALUATOR-BOOT] Module loading started',\n new Date().toISOString()\n);\n\nimport { EvalStatus } from '@wix/evalforge-types';\nimport { loadConfig, type EvaluatorConfig } from './config.js';\nimport { createApiClient, type ApiClient } from './api-client.js';\nimport { fetchEvaluationData } from './fetch-evaluation-data.js';\nimport { runScenario } from './run-scenario/index.js';\nimport {\n formatError,\n formatErrorForJobError,\n ExecutionPhase\n} from './error-reporter.js';\n// Diagnostics disabled - was causing Invalid Date entries in UI\n// import { runDiagnostics } from './diagnostics.js';\n\nconsole.error('[EVALUATOR-BOOT] All static imports successful');\n\n/**\n * State that persists across the evaluation for error reporting.\n * This allows us to report errors even when config/api are not yet initialized.\n */\ninterface EvaluationState {\n config: EvaluatorConfig | null;\n api: ApiClient | null;\n currentPhase: string;\n currentContext: Record<string, unknown>;\n}\n\n/**\n * Run the evaluation with comprehensive error tracking.\n *\n * @param projectId - The project ID\n * @param evalRunId - The eval run ID\n */\nasync function runEvaluation(\n projectId: string,\n evalRunId: string\n): Promise<void> {\n // Initialize state for error tracking\n const state: EvaluationState = {\n config: null,\n api: null,\n currentPhase: ExecutionPhase.CONFIG,\n currentContext: { projectId, evalRunId }\n };\n\n console.error(\n '[DEBUG-H1] runEvaluation entry',\n JSON.stringify({ projectId, evalRunId, timestamp: Date.now() })\n );\n\n // ============================================\n // PHASE 1: Load Configuration\n // ============================================\n state.currentPhase = ExecutionPhase.CONFIG;\n state.currentContext = { projectId, evalRunId };\n\n let config: EvaluatorConfig;\n try {\n config = loadConfig();\n state.config = config;\n console.error(\n '[DEBUG-H1] loadConfig SUCCESS',\n JSON.stringify({\n serverUrl: config.serverUrl,\n apiPrefix: config.apiPrefix || '(none)',\n aiGatewayUrl: config.aiGatewayUrl,\n hasHeaders: Object.keys(config.aiGatewayHeaders).length > 0,\n timestamp: Date.now()\n })\n );\n } catch (configErr) {\n console.error(\n '[DEBUG-H1] loadConfig FAILED',\n JSON.stringify({\n error:\n configErr instanceof Error ? configErr.message : String(configErr),\n stack: configErr instanceof Error ? configErr.stack : undefined,\n timestamp: Date.now()\n })\n );\n // Can't report to server without config, but error will be caught by main handler\n throw new Error(\n `[${ExecutionPhase.CONFIG}] ${configErr instanceof Error ? configErr.message : String(configErr)}`\n );\n }\n\n console.log('[Evaluator] Config loaded', {\n serverUrl: config.serverUrl,\n aiGatewayUrl: config.aiGatewayUrl,\n evaluationsDir: config.evaluationsDir,\n hasAiGatewayHeaders: Object.keys(config.aiGatewayHeaders).length > 0,\n hasRouteHeader: !!config.routeHeader\n });\n\n // ============================================\n // PHASE 2: Create API Client\n // ============================================\n state.currentPhase = ExecutionPhase.API_CLIENT;\n\n let api: ApiClient;\n try {\n api = createApiClient(config.serverUrl, {\n apiPrefix: config.apiPrefix,\n routeHeader: config.routeHeader,\n authToken: config.authToken\n });\n state.api = api;\n } catch (apiErr) {\n throw new Error(\n `[${ExecutionPhase.API_CLIENT}] Failed to create API client: ${apiErr instanceof Error ? apiErr.message : String(apiErr)}`\n );\n }\n\n // ============================================\n // PHASE 3: Fetch Evaluation Data\n // ============================================\n state.currentPhase = ExecutionPhase.FETCH_EVAL_RUN;\n state.currentContext = { projectId, evalRunId, serverUrl: config.serverUrl };\n\n console.error(\n '[DEBUG-H2] fetchEvaluationData START',\n JSON.stringify({ serverUrl: config.serverUrl, timestamp: Date.now() })\n );\n\n let evalData;\n try {\n evalData = await fetchEvaluationData(api, projectId, evalRunId);\n console.error(\n '[DEBUG-H2] fetchEvaluationData SUCCESS',\n JSON.stringify({\n scenarioItemCount: evalData.scenarioItems.length,\n scenarios: evalData.scenarioItems.map((s) => s.scenario.name),\n skillsCount: evalData.skills.length,\n hasAgent: !!evalData.agent,\n timestamp: Date.now()\n })\n );\n } catch (fetchErr) {\n const errorMsg =\n fetchErr instanceof Error ? fetchErr.message : String(fetchErr);\n console.error(\n '[DEBUG-H2] fetchEvaluationData FAILED',\n JSON.stringify({\n error: errorMsg,\n stack: fetchErr instanceof Error ? fetchErr.stack : undefined,\n timestamp: Date.now()\n })\n );\n throw new Error(\n `[${ExecutionPhase.FETCH_EVAL_RUN}] Failed to fetch evaluation data: ${errorMsg}`\n );\n }\n\n const { agent, skills, scenarioItems } = evalData;\n\n // ============================================\n // PHASE 4: Validation\n // ============================================\n state.currentPhase = ExecutionPhase.VALIDATION;\n state.currentContext = {\n projectId,\n evalRunId,\n scenarioCount: scenarioItems.length,\n skillCount: skills.length,\n hasAgent: !!agent,\n agentId: evalData.evalRun.agentId,\n presetId: evalData.evalRun.presetId,\n skillIds: evalData.evalRun.skillIds\n };\n\n if (scenarioItems.length > 0 && !agent) {\n throw new Error(\n `[${ExecutionPhase.VALIDATION}] Eval run has no agent: set agentId for evaluation runs. ` +\n `(agentId: ${evalData.evalRun.agentId || 'not set'})`\n );\n }\n\n // ============================================\n // PHASE 5: Execute Scenarios\n // ============================================\n // Note: Wix auth file (~/.wix/auth/api-key.json) is written by the backend\n // before the evaluator starts, so CLI/MCP tools are already authenticated.\n let completedScenarios = 0;\n const totalScenarios = scenarioItems.length;\n\n for (const { scenario, template, resolvedAssertions } of scenarioItems) {\n state.currentPhase = ExecutionPhase.EXECUTE_SKILL;\n state.currentContext = {\n projectId,\n evalRunId,\n scenarioId: scenario.id,\n scenarioName: scenario.name,\n presetId: evalData.evalRun.presetId,\n presetName: evalData.presetName,\n agentId: agent?.id,\n agentName: agent?.name,\n progress: `${completedScenarios + 1}/${totalScenarios}`\n };\n\n const skillNames = evalData.skills.map((s) => s.name).join(', ');\n console.log(\n '[Evaluator] Running scenario with preset:',\n evalData.presetName,\n skillNames ? `(${skillNames})` : '',\n agent ? `with agent: ${agent.name}` : '',\n `(${completedScenarios + 1}/${totalScenarios})`\n );\n\n try {\n const result = await runScenario(\n config,\n evalRunId,\n scenario,\n evalData,\n template,\n resolvedAssertions\n );\n\n console.log('[Evaluator] Scenario completed, adding result');\n\n // Update phase for result reporting\n state.currentPhase = ExecutionPhase.ADD_RESULT;\n state.currentContext = {\n ...state.currentContext,\n resultId: result.id\n };\n\n await api.addResult(projectId, evalRunId, result);\n completedScenarios++;\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n const errorStack = err instanceof Error ? err.stack : undefined;\n console.error(\n '[Evaluator] Failed to run scenario with preset:',\n evalData.presetName,\n 'Error:',\n errorMsg\n );\n if (errorStack) {\n console.error('[Evaluator] Stack trace:', errorStack);\n }\n\n // Include full context in the error\n throw new Error(\n `[${state.currentPhase}] Failed to execute preset \"${evalData.presetName}\" on scenario \"${scenario.name}\": ${errorMsg}`\n );\n }\n }\n\n // ============================================\n // PHASE 6: Update Status to Completed\n // ============================================\n state.currentPhase = ExecutionPhase.UPDATE_STATUS;\n state.currentContext = {\n projectId,\n evalRunId,\n completedScenarios,\n totalScenarios\n };\n\n try {\n await api.updateEvalRun(projectId, evalRunId, {\n status: EvalStatus.COMPLETED,\n completedAt: new Date().toISOString()\n });\n } catch (updateErr) {\n throw new Error(\n `[${ExecutionPhase.UPDATE_STATUS}] Failed to update eval run status to COMPLETED: ${updateErr instanceof Error ? updateErr.message : String(updateErr)}`\n );\n }\n}\n\n// ============================================\n// Main Entry Point\n// ============================================\nconst projectId = process.argv[2];\nconst evalRunId = process.argv[3];\n\nconsole.error(\n '[EVALUATOR-BOOT] Args parsed',\n JSON.stringify({ projectId, evalRunId })\n);\n\nif (!projectId || !evalRunId) {\n console.error('Usage: evaluator <project-id> <eval-run-id>');\n process.exit(1);\n}\n\nrunEvaluation(projectId, evalRunId)\n .then(() => {\n console.error('[EVALUATOR-BOOT] runEvaluation completed successfully');\n process.exit(0);\n })\n .catch(async (err) => {\n // Extract detailed error information\n const errorDetails = formatError(err, 'main-execution', {\n projectId,\n evalRunId\n });\n const jobError = formatErrorForJobError(errorDetails);\n\n console.error('[EVALUATOR-BOOT] runEvaluation FAILED');\n console.error(\n '[EVALUATOR-BOOT] Error details:',\n JSON.stringify(errorDetails, null, 2)\n );\n\n // Try to update status to FAILED with detailed error info\n try {\n const config = loadConfig();\n const api = createApiClient(config.serverUrl, {\n apiPrefix: config.apiPrefix,\n routeHeader: config.routeHeader,\n authToken: config.authToken\n });\n await api.updateEvalRun(projectId, evalRunId, {\n status: EvalStatus.FAILED,\n completedAt: new Date().toISOString(),\n jobError,\n jobStatus: 'FAILED'\n });\n console.error(\n '[EVALUATOR-BOOT] Updated eval run status to FAILED with error details'\n );\n } catch (updateErr) {\n console.error(\n '[EVALUATOR-BOOT] Failed to update eval run status:',\n updateErr instanceof Error ? updateErr.message : String(updateErr)\n );\n\n // If config loading failed, try with minimal config from env\n try {\n const serverUrl = process.env.EVAL_SERVER_URL;\n const authToken = process.env.EVAL_AUTH_TOKEN;\n const routeHeader = process.env.EVAL_ROUTE_HEADER;\n\n if (serverUrl) {\n const api = createApiClient(serverUrl, {\n routeHeader,\n authToken\n });\n await api.updateEvalRun(projectId, evalRunId, {\n status: EvalStatus.FAILED,\n completedAt: new Date().toISOString(),\n jobError: `Config load failed, then: ${jobError}`,\n jobStatus: 'FAILED'\n });\n console.error('[EVALUATOR-BOOT] Fallback: Updated status to FAILED');\n }\n } catch (fallbackErr) {\n console.error(\n '[EVALUATOR-BOOT] Fallback also failed:',\n fallbackErr instanceof Error\n ? fallbackErr.message\n : String(fallbackErr)\n );\n }\n }\n\n process.exit(1);\n });\n", "/**\n * Evaluator Configuration\n *\n * Reads configuration from environment variables set by the server\n * when spawning the evaluator process.\n */\n\nexport interface EvaluatorConfig {\n /** Backend server URL for fetching data and reporting results */\n serverUrl: string;\n /** API path prefix (default: empty, set to \"/api/v1\" if needed for production) */\n apiPrefix: string;\n /** AI Gateway base URL for LLM calls */\n aiGatewayUrl: string;\n /** Custom headers for AI Gateway requests (parsed from \"key:value\" lines) */\n aiGatewayHeaders: Record<string, string>;\n /** Directory for storing evaluation working directories */\n evaluationsDir?: string;\n /** URL to push trace events to (for remote job execution) */\n tracePushUrl?: string;\n /**\n * Optional x-wix-route header value for deploy preview routing.\n * When set, this header is included in all API requests to route\n * them to the correct deploy preview instance.\n */\n routeHeader?: string;\n /**\n * Optional Bearer token for authenticating with public endpoints.\n * When set, this token is included as Authorization header in API requests.\n */\n authToken?: string;\n}\n\n/**\n * Load evaluator configuration from environment variables.\n *\n * @throws Error if required environment variables are missing\n */\nexport function loadConfig(): EvaluatorConfig {\n const serverUrl = process.env.EVAL_SERVER_URL;\n // API prefix: set to \"/api/v1\" if your API gateway requires it, or empty string\n const apiPrefix = process.env.EVAL_API_PREFIX || '';\n const aiGatewayUrl = process.env.AI_GATEWAY_URL;\n const aiGatewayHeadersRaw = process.env.AI_GATEWAY_HEADERS;\n const evaluationsDir = process.env.EVALUATIONS_DIR;\n\n if (!serverUrl) {\n throw new Error('EVAL_SERVER_URL environment variable is required');\n }\n if (!aiGatewayUrl) {\n throw new Error('AI_GATEWAY_URL environment variable is required');\n }\n\n // Parse headers from newline-separated \"key:value\" format\n const aiGatewayHeaders: Record<string, string> = {};\n if (aiGatewayHeadersRaw) {\n for (const line of aiGatewayHeadersRaw.split('\\n')) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n const colonIndex = trimmed.indexOf(':');\n if (colonIndex === -1) {\n throw new Error(\n `Invalid header format: \"${trimmed}\". Expected \"key:value\" format.`\n );\n }\n const key = trimmed.substring(0, colonIndex).trim();\n const value = trimmed.substring(colonIndex + 1).trim();\n aiGatewayHeaders[key] = value;\n }\n }\n\n // Always disable proxy-level caching so eval runs hit the real LLM\n aiGatewayHeaders['x-wix-ai-gateway-disable-cache'] = 'true';\n\n // Optional trace push URL for remote job execution\n const tracePushUrl = process.env.TRACE_PUSH_URL;\n\n // Optional route header for deploy preview routing\n const routeHeader = process.env.EVAL_ROUTE_HEADER;\n\n // Optional auth token for public endpoint authentication\n const authToken = process.env.EVAL_AUTH_TOKEN;\n\n return {\n serverUrl,\n apiPrefix,\n aiGatewayUrl,\n aiGatewayHeaders,\n evaluationsDir,\n tracePushUrl,\n routeHeader,\n authToken\n };\n}\n", "/**\n * API Client for fetching data from the eval server.\n */\n\nimport type {\n EvalRun,\n EvalRunResult,\n TestScenario,\n Template,\n SkillWithLatestVersion,\n SkillVersion,\n Agent,\n Preset,\n MCPEntity,\n SubAgent,\n Rule\n} from '@wix/evalforge-types';\n\nexport interface ApiClient {\n getEvalRun(projectId: string, id: string): Promise<EvalRun>;\n getScenario(projectId: string, id: string): Promise<TestScenario>;\n getSkill(projectId: string, id: string): Promise<SkillWithLatestVersion>;\n getSkillVersion(\n projectId: string,\n skillId: string,\n versionId: string\n ): Promise<SkillVersion>;\n getLatestSkillVersion(\n projectId: string,\n skillId: string\n ): Promise<SkillVersion>;\n getAgent(projectId: string, id: string): Promise<Agent>;\n getTemplate(projectId: string, id: string): Promise<Template>;\n getMcp(projectId: string, id: string): Promise<MCPEntity>;\n getSubAgent(projectId: string, id: string): Promise<SubAgent>;\n getRule(projectId: string, id: string): Promise<Rule>;\n getPreset(projectId: string, id: string): Promise<Preset>;\n addResult(\n projectId: string,\n evalRunId: string,\n result: EvalRunResult\n ): Promise<void>;\n clearResults(projectId: string, evalRunId: string): Promise<void>;\n updateEvalRun(\n projectId: string,\n evalRunId: string,\n update: Partial<EvalRun>\n ): Promise<void>;\n}\n\n/**\n * Options for creating an API client.\n */\nexport interface ApiClientOptions {\n /** API path prefix (default: empty string, set to \"/api/v1\" if needed) */\n apiPrefix?: string;\n /**\n * Optional x-wix-route header value for deploy preview routing.\n * When set, this header is included in all requests.\n */\n routeHeader?: string;\n /**\n * Optional Bearer token for authenticating with public endpoints.\n * When set, this token is included as Authorization header in all requests.\n */\n authToken?: string;\n}\n\n/**\n * Create an API client for the eval server.\n *\n * @param serverUrl - Base URL of the server (e.g., \"https://bo.wix.com/_api/evalforge-backend\")\n * @param options - Optional configuration including apiPrefix and routeHeader\n */\nexport function createApiClient(\n serverUrl: string,\n options: ApiClientOptions | string = ''\n): ApiClient {\n // Support legacy signature: createApiClient(serverUrl, apiPrefix)\n const opts: ApiClientOptions =\n typeof options === 'string' ? { apiPrefix: options } : options;\n const apiPrefix = opts.apiPrefix ?? '';\n const routeHeader = opts.routeHeader;\n const authToken = opts.authToken;\n\n // When authToken is provided, use /public prefix for all endpoints\n // This routes requests to token-authenticated public endpoints\n const pathPrefix = authToken ? '/public' : '';\n\n /**\n * Build headers for requests, including auth and route headers if configured.\n */\n function buildHeaders(\n additionalHeaders?: Record<string, string>\n ): Record<string, string> {\n const headers: Record<string, string> = { ...additionalHeaders };\n if (authToken) {\n headers['Authorization'] = `Bearer ${authToken}`;\n }\n if (routeHeader) {\n headers['x-wix-route'] = routeHeader;\n }\n return headers;\n }\n\n async function fetchJson<T>(path: string): Promise<T> {\n const url = `${serverUrl}${apiPrefix}${pathPrefix}${path}`;\n console.error(`[API] GET ${url}`);\n const headers = buildHeaders();\n const response = await fetch(url, {\n headers: Object.keys(headers).length > 0 ? headers : undefined\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(\n `API request failed: ${response.status} ${response.statusText} - ${errorText}`\n );\n }\n\n return response.json() as Promise<T>;\n }\n\n async function postJson(path: string, body: unknown): Promise<void> {\n const url = `${serverUrl}${apiPrefix}${pathPrefix}${path}`;\n console.error(`[API] POST ${url}`);\n const response = await fetch(url, {\n method: 'POST',\n headers: buildHeaders({ 'Content-Type': 'application/json' }),\n body: JSON.stringify(body)\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(\n `API request failed: ${response.status} ${response.statusText} - ${errorText}`\n );\n }\n }\n\n async function deleteRequest(path: string): Promise<void> {\n const url = `${serverUrl}${apiPrefix}${pathPrefix}${path}`;\n console.error(`[API] DELETE ${url}`);\n const headers = buildHeaders();\n const response = await fetch(url, {\n method: 'DELETE',\n headers: Object.keys(headers).length > 0 ? headers : undefined\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(\n `API request failed: ${response.status} ${response.statusText} - ${errorText}`\n );\n }\n }\n\n async function putJson(path: string, body: unknown): Promise<void> {\n const url = `${serverUrl}${apiPrefix}${pathPrefix}${path}`;\n console.error(`[API] PUT ${url}`);\n const response = await fetch(url, {\n method: 'PUT',\n headers: buildHeaders({ 'Content-Type': 'application/json' }),\n body: JSON.stringify(body)\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(\n `API request failed: ${response.status} ${response.statusText} - ${errorText}`\n );\n }\n }\n\n return {\n getEvalRun(projectId: string, id: string): Promise<EvalRun> {\n return fetchJson(`/projects/${projectId}/eval-runs/${id}`);\n },\n\n getScenario(projectId: string, id: string): Promise<TestScenario> {\n return fetchJson(`/projects/${projectId}/test-scenarios/${id}`);\n },\n\n getSkill(projectId: string, id: string): Promise<SkillWithLatestVersion> {\n return fetchJson(`/projects/${projectId}/skills/${id}`);\n },\n\n getSkillVersion(\n projectId: string,\n skillId: string,\n versionId: string\n ): Promise<SkillVersion> {\n return fetchJson(\n `/projects/${projectId}/skills/${skillId}/versions/${versionId}`\n );\n },\n\n getLatestSkillVersion(\n projectId: string,\n skillId: string\n ): Promise<SkillVersion> {\n return fetchJson(\n `/projects/${projectId}/skills/${skillId}/versions/latest`\n );\n },\n\n getAgent(projectId: string, id: string): Promise<Agent> {\n return fetchJson(`/projects/${projectId}/agents/${id}`);\n },\n\n getTemplate(projectId: string, id: string): Promise<Template> {\n return fetchJson(`/projects/${projectId}/templates/${id}`);\n },\n\n getMcp(projectId: string, id: string): Promise<MCPEntity> {\n return fetchJson(`/projects/${projectId}/mcps/${id}`);\n },\n\n getSubAgent(projectId: string, id: string): Promise<SubAgent> {\n return fetchJson(`/projects/${projectId}/sub-agents/${id}`);\n },\n\n getRule(projectId: string, id: string): Promise<Rule> {\n return fetchJson(`/projects/${projectId}/rules/${id}`);\n },\n\n getPreset(projectId: string, id: string): Promise<Preset> {\n return fetchJson(`/projects/${projectId}/presets/${id}`);\n },\n\n addResult(\n projectId: string,\n evalRunId: string,\n result: EvalRunResult\n ): Promise<void> {\n return postJson(\n `/projects/${projectId}/eval-runs/${evalRunId}/results`,\n result\n );\n },\n\n clearResults(projectId: string, evalRunId: string): Promise<void> {\n return deleteRequest(\n `/projects/${projectId}/eval-runs/${evalRunId}/results`\n );\n },\n\n updateEvalRun(\n projectId: string,\n evalRunId: string,\n update: Partial<EvalRun>\n ): Promise<void> {\n return putJson(`/projects/${projectId}/eval-runs/${evalRunId}`, update);\n }\n };\n}\n", "import type {\n EvalRun,\n TestScenario,\n SkillWithLatestVersion,\n Agent,\n Template,\n Assertion,\n MCPEntity,\n SubAgent,\n Rule\n} from '@wix/evalforge-types';\nimport {\n isSystemAssertionId,\n SYSTEM_ASSERTIONS,\n type SystemAssertionId\n} from '@wix/evalforge-types';\nimport type { ApiClient } from './api-client.js';\nimport { resolvePlaceholdersInString } from './resolve-placeholders.js';\n\n/**\n * Parse skillNames from a JSON array string stored in assertion params.\n * Params only hold primitives, so the frontend serialises the string[]\n * into a JSON string like '[\"SkillA\",\"SkillB\"]'.\n */\nexport function parseSkillNamesFromParams(value: unknown): string[] {\n if (typeof value !== 'string') {\n return [];\n }\n const parsed: unknown = JSON.parse(value);\n if (Array.isArray(parsed)) {\n return parsed.map(String);\n }\n return [];\n}\n\n/**\n * Apply parameter values to an assertion.\n * Replaces placeholder values with actual params from the scenario link.\n */\nexport function applyParamsToAssertion(\n assertion: Assertion,\n params?: Record<string, unknown>\n): Assertion {\n if (!params || Object.keys(params).length === 0) {\n return assertion;\n }\n\n // For llm_judge, replace {{param}} placeholders and apply config overrides\n if (assertion.type === 'llm_judge') {\n const stringParams: Record<string, string> = {};\n for (const [key, value] of Object.entries(params)) {\n stringParams[key] = String(value ?? '');\n }\n const prompt = resolvePlaceholdersInString(assertion.prompt, stringParams);\n\n return {\n ...assertion,\n prompt,\n ...(params.model !== undefined && { model: params.model as string }),\n ...(params.maxTokens !== undefined && {\n maxTokens: params.maxTokens as number\n }),\n ...(params.temperature !== undefined && {\n temperature: params.temperature as number\n }),\n ...(params.minScore !== undefined && {\n minScore: params.minScore as number\n })\n };\n }\n\n // For time, params override maxDurationMs directly\n if (assertion.type === 'time_limit' && params.maxDurationMs !== undefined) {\n return {\n ...assertion,\n maxDurationMs: params.maxDurationMs as number\n };\n }\n\n // For skill_was_called, parse skillNames from params (may be JSON string)\n if (\n assertion.type === 'skill_was_called' &&\n params.skillNames !== undefined\n ) {\n return {\n ...assertion,\n skillNames: parseSkillNamesFromParams(params.skillNames),\n ...(params.negate !== undefined && { negate: params.negate as boolean })\n };\n }\n\n // For tool_called_with_param, params override toolName and expectedParams directly\n if (assertion.type === 'tool_called_with_param') {\n return {\n ...assertion,\n ...(params.toolName !== undefined && {\n toolName: params.toolName as string\n }),\n ...(params.expectedParams !== undefined && {\n expectedParams: params.expectedParams as string\n }),\n ...(params.requireSuccess !== undefined && {\n requireSuccess: params.requireSuccess as boolean\n }),\n ...(params.negate !== undefined && { negate: params.negate as boolean })\n };\n }\n\n // For build_passed and cost, params override config values directly\n return { ...assertion, ...params } as Assertion;\n}\n\n/**\n * Resolve a system assertion to inline Assertion format with params applied.\n */\nexport function resolveSystemAssertion(\n assertionId: SystemAssertionId,\n params?: Record<string, unknown>\n): Assertion {\n const systemAssertion = SYSTEM_ASSERTIONS[assertionId];\n\n // Build base assertion from system assertion type\n let baseAssertion: Assertion;\n switch (systemAssertion.type) {\n case 'skill_was_called':\n baseAssertion = {\n type: 'skill_was_called',\n skillNames: parseSkillNamesFromParams(params?.skillNames),\n ...(params?.negate !== undefined && {\n negate: params.negate as boolean\n })\n };\n break;\n case 'tool_called_with_param':\n baseAssertion = {\n type: 'tool_called_with_param',\n toolName: (params?.toolName as string) ?? '',\n ...(params?.expectedParams !== undefined && {\n expectedParams: params.expectedParams as string\n }),\n ...(params?.requireSuccess !== undefined && {\n requireSuccess: params.requireSuccess as boolean\n }),\n ...(params?.negate !== undefined && {\n negate: params.negate as boolean\n })\n };\n break;\n case 'build_passed':\n baseAssertion = {\n type: 'build_passed',\n command: (params?.command as string) ?? undefined,\n expectedExitCode: (params?.expectedExitCode as number) ?? undefined\n };\n break;\n case 'time_limit':\n baseAssertion = {\n type: 'time_limit',\n maxDurationMs: (params?.maxDurationMs as number) ?? 300000\n };\n break;\n case 'cost':\n baseAssertion = {\n type: 'cost',\n maxCostUsd: (params?.maxCostUsd as number) ?? 1.0\n };\n break;\n case 'llm_judge':\n baseAssertion = {\n type: 'llm_judge',\n prompt: (params?.prompt as string) ?? '',\n minScore: params?.minScore as number | undefined,\n model: params?.model as string | undefined,\n maxTokens: params?.maxTokens as number | undefined,\n temperature: params?.temperature as number | undefined\n };\n break;\n case 'api_call':\n baseAssertion = {\n type: 'api_call',\n url: (params?.url as string) ?? '',\n expectedResponse: (params?.expectedResponse as string) ?? '{}',\n method: (params?.method as 'GET' | 'POST') ?? undefined,\n requestBody: (params?.requestBody as string) ?? undefined,\n requestHeaders: (params?.requestHeaders as string) ?? undefined,\n timeoutMs: (params?.timeoutMs as number) ?? undefined\n };\n break;\n default:\n // Should not happen for system assertions\n baseAssertion = { type: 'llm_judge', prompt: '' };\n }\n\n return baseAssertion;\n}\n\n/**\n * A scenario paired with its optional template and resolved assertions.\n */\nexport interface ScenarioItem {\n scenario: TestScenario;\n template?: Template;\n /** Resolved assertions from assertionIds (converted to inline format) */\n resolvedAssertions?: Assertion[];\n}\n\n/**\n * Data shape returned by fetchEvaluationData for the run flow.\n * Run-level agent + skills + mcps + subAgents; per-scenario template.\n */\nexport interface EvaluationData {\n evalRun: EvalRun;\n agent: Agent | null;\n skills: SkillWithLatestVersion[];\n /** Display name: preset name from DB when available, otherwise joined skill names */\n presetName: string;\n mcps: MCPEntity[];\n subAgents: SubAgent[];\n rules: Rule[];\n scenarioItems: ScenarioItem[];\n}\n\n/**\n * Fetch all data needed to run an evaluation.\n *\n * Uses evalRun.agentId and evalRun.skillIds as run-level inputs.\n * Loads skills by ID; loads code agent; loads scenarios and templates by scenario.templateId.\n *\n * @throws Error if eval run has no code agent when expected\n * @throws Error if eval run has no skills group or skills group has no skills when expected\n */\nexport async function fetchEvaluationData(\n api: ApiClient,\n projectId: string,\n evalRunId: string\n): Promise<EvaluationData> {\n const evalRun = await api.getEvalRun(projectId, evalRunId);\n\n const scenarios = await Promise.all(\n (evalRun.scenarioIds ?? []).map((id) => api.getScenario(projectId, id))\n );\n\n let agent: Agent | null = null;\n if (evalRun.agentId) {\n agent = await api.getAgent(projectId, evalRun.agentId);\n }\n\n let skills: SkillWithLatestVersion[] = [];\n const resolvedSkillIds = evalRun.skillIds ?? [];\n\n if (resolvedSkillIds.length > 0) {\n const fetchResults = await Promise.allSettled(\n resolvedSkillIds.map((id) => api.getSkill(projectId, id))\n );\n skills = fetchResults\n .filter(\n (r): r is PromiseFulfilledResult<SkillWithLatestVersion> =>\n r.status === 'fulfilled'\n )\n .map((r) => r.value)\n .filter((s) => !s.deleted);\n\n // Override latestVersion with pinned versions from the eval run\n if (\n evalRun.skillVersions &&\n Object.keys(evalRun.skillVersions).length > 0\n ) {\n skills = await Promise.all(\n skills.map(async (skill) => {\n const versionId = evalRun.skillVersions?.[skill.id];\n if (versionId) {\n const version = await api.getSkillVersion(\n projectId,\n skill.id,\n versionId\n );\n return { ...skill, latestVersion: version };\n }\n return skill;\n })\n );\n }\n\n // For GitHub-sourced skills with no pinned version, clear latestVersion\n // so writeSkillsToFilesystem fetches live from GitHub using skill.source\n skills = skills.map((skill) => {\n const hasPinnedVersion = evalRun.skillVersions?.[skill.id];\n if (!hasPinnedVersion && skill.source) {\n return { ...skill, latestVersion: undefined };\n }\n return skill;\n });\n }\n\n let mcps: MCPEntity[] = [];\n if (evalRun.mcpIds && evalRun.mcpIds.length > 0) {\n mcps = await Promise.all(\n evalRun.mcpIds.map((id) => api.getMcp(projectId, id))\n );\n }\n\n let subAgents: SubAgent[] = [];\n if (evalRun.subAgentIds && evalRun.subAgentIds.length > 0) {\n subAgents = await Promise.all(\n evalRun.subAgentIds.map((id) => api.getSubAgent(projectId, id))\n );\n }\n\n let rules: Rule[] = [];\n if (evalRun.ruleIds && evalRun.ruleIds.length > 0) {\n rules = await Promise.all(\n evalRun.ruleIds.map((id) => api.getRule(projectId, id))\n );\n }\n\n const templateIds = [\n ...new Set(\n scenarios.map((s) => s.templateId).filter((id): id is string => !!id)\n )\n ];\n const templates =\n templateIds.length > 0\n ? await Promise.all(\n templateIds.map((id) => api.getTemplate(projectId, id))\n )\n : [];\n const templateMap = new Map(templates.map((t) => [t.id, t]));\n\n const scenarioItems: ScenarioItem[] = scenarios.map((scenario) => {\n // Resolve assertion links to inline Assertion format with params applied\n const resolvedAssertions = (scenario.assertionLinks ?? [])\n .map((link) => {\n const { assertionId, params } = link;\n\n if (!isSystemAssertionId(assertionId)) {\n return null;\n }\n\n return resolveSystemAssertion(\n assertionId as SystemAssertionId,\n params as Record<string, unknown>\n );\n })\n .filter((a): a is Assertion => a !== null);\n\n return {\n scenario,\n template: scenario.templateId\n ? templateMap.get(scenario.templateId)\n : undefined,\n resolvedAssertions:\n resolvedAssertions.length > 0 ? resolvedAssertions : undefined\n };\n });\n\n let presetName = '';\n if (evalRun.presetId) {\n try {\n const preset = await api.getPreset(projectId, evalRun.presetId);\n presetName = preset.name;\n } catch {\n presetName =\n skills.length > 0 ? skills.map((s) => s.name).join(', ') : '';\n }\n } else if (skills.length > 0) {\n presetName = skills.map((s) => s.name).join(', ');\n }\n\n return {\n evalRun,\n agent,\n skills,\n presetName,\n mcps,\n subAgents,\n rules,\n scenarioItems\n };\n}\n", "/**\n * Generic `{{placeholder}}` resolution utilities.\n *\n * Provides low-level functions for detecting and replacing `{{key}}`\n * tokens inside arbitrary JSON-like values (strings, arrays, objects).\n *\n * Used by:\n * - MCP config resolution (wix-auth tokens)\n * - LLM judge assertion param substitution\n */\n\nconst PLACEHOLDER_PATTERN = /\\{\\{([^}]+)\\}\\}/g;\n\n/**\n * Find all unique placeholder keys referenced in an arbitrary value.\n * Recursively traverses strings, arrays, and plain objects.\n */\nexport function findPlaceholders(value: unknown): string[] {\n const keys = new Set<string>();\n collectPlaceholders(value, keys);\n return [...keys];\n}\n\nfunction collectPlaceholders(value: unknown, keys: Set<string>): void {\n if (typeof value === 'string') {\n for (const match of value.matchAll(PLACEHOLDER_PATTERN)) {\n keys.add(match[1].trim());\n }\n } else if (Array.isArray(value)) {\n for (const item of value) {\n collectPlaceholders(item, keys);\n }\n } else if (typeof value === 'object' && value !== null) {\n for (const val of Object.values(value)) {\n collectPlaceholders(val, keys);\n }\n }\n}\n\n/**\n * Replace `{{key}}` tokens in an arbitrary value using the given map.\n * Recursively traverses strings, arrays, and plain objects.\n * Unknown placeholders (not in `placeholders`) are left as-is.\n */\nexport function resolveValue(\n value: unknown,\n placeholders: Record<string, string>\n): unknown {\n if (typeof value === 'string') {\n return value.replace(PLACEHOLDER_PATTERN, (match, key: string) => {\n const trimmed = key.trim();\n return trimmed in placeholders ? placeholders[trimmed] : match;\n });\n }\n if (Array.isArray(value)) {\n return value.map((item) => resolveValue(item, placeholders));\n }\n if (typeof value === 'object' && value !== null) {\n const result: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value)) {\n result[k] = resolveValue(v, placeholders);\n }\n return result;\n }\n return value;\n}\n\n/**\n * Replace `{{key}}` tokens in a single string.\n * Convenience wrapper around {@link resolveValue} with a narrower return type.\n */\nexport function resolvePlaceholdersInString(\n text: string,\n placeholders: Record<string, string>\n): string {\n return resolveValue(text, placeholders) as string;\n}\n", "import type {\n EvalRunResult,\n TestScenario,\n Template\n} from '@wix/evalforge-types';\nimport {\n AssertionResultStatus,\n DEFAULT_JUDGE_MODEL\n} from '@wix/evalforge-types';\nimport {\n evaluateAssertions as evaluateAssertionsBase,\n type EvaluationInput,\n type AssertionContext\n} from '@wix/eval-assertions';\nimport type { EvaluatorConfig } from '../config.js';\nimport { prepareWorkingDirectory } from './environment.js';\nimport { runAgentWithContext } from './run-agent-with-context.js';\nimport type { Assertion } from '@wix/evalforge-types';\nimport type { EvaluationData } from '../fetch-evaluation-data.js';\n\nexport type { PartialEvalRunResult } from './types.js';\nexport type { ScenarioItem, EvaluationData } from '../fetch-evaluation-data.js';\n\n/**\n * Run a single scenario using evaluation data.\n *\n * @param config - Evaluator configuration\n * @param evalRunId - The evaluation run ID\n * @param scenario - The test scenario to run\n * @param evalData - Fetched evaluation data (skills, agent, mcps, subAgents)\n * @param template - Optional pre-fetched template entity\n * @param resolvedAssertions - Optional assertions resolved from assertionIds\n * @returns Complete evaluation result\n */\nexport async function runScenario(\n config: EvaluatorConfig,\n evalRunId: string,\n scenario: TestScenario,\n evalData: EvaluationData,\n template?: Template,\n resolvedAssertions?: Assertion[]\n): Promise<EvalRunResult> {\n const targetId =\n evalData.evalRun.presetId ?? evalData.agent?.id ?? evalData.evalRun.id;\n\n const workDir = await prepareWorkingDirectory(\n config,\n evalRunId,\n targetId,\n scenario.id,\n template\n );\n\n const partialResult = await runAgentWithContext(\n config,\n evalRunId,\n scenario,\n evalData,\n workDir\n );\n\n // Combine inline assertions with resolved assertions from assertionIds\n const inlineAssertions = scenario.assertions ?? [];\n const assertions: Assertion[] = [\n ...inlineAssertions,\n ...(resolvedAssertions ?? [])\n ];\n\n // Adapt PartialEvalRunResult to EvaluationInput for the assertions package\n // Use templateFiles to get file status (new, modified, unchanged)\n const templateFilesMap = new Map(\n (partialResult.templateFiles ?? []).map((f) => [f.path, f.status])\n );\n const evaluationInput: EvaluationInput = {\n outputText: partialResult.outputText,\n llmTrace: partialResult.llmTrace,\n fileDiffs: partialResult.fileDiffs?.map((d) => ({\n path: d.path,\n status: templateFilesMap.get(d.path) as 'new' | 'modified' | undefined\n })),\n durationMs: partialResult.duration\n };\n\n const defaultJudgeModel = DEFAULT_JUDGE_MODEL;\n const assertionContext: AssertionContext = {\n workDir,\n defaultJudgeModel,\n llmConfig: {\n baseUrl: config.aiGatewayUrl,\n headers: config.aiGatewayHeaders\n }\n };\n\n const assertionResults: EvalRunResult['assertionResults'] =\n assertions.length > 0\n ? await evaluateAssertionsBase(\n evaluationInput,\n assertions,\n assertionContext\n )\n : [];\n\n const passed = assertionResults.filter(\n (r) => r.status === AssertionResultStatus.PASSED\n ).length;\n const failed = assertionResults.filter(\n (r) => r.status === AssertionResultStatus.FAILED\n ).length;\n const total = assertionResults.length;\n const passRate = total > 0 ? Math.round((passed / total) * 100) : 100;\n\n return {\n ...partialResult,\n assertionResults,\n passed,\n failed,\n passRate\n };\n}\n", "import type { Template } from '@wix/evalforge-types';\nimport { mkdirSync, existsSync, rmSync, readFileSync, writeFileSync } from 'fs';\nimport { tmpdir } from 'os';\nimport path from 'path';\nimport type { EvaluatorConfig } from '../config.js';\nimport { fetchGitHubFolder } from '@wix/evalforge-github-client';\nimport { writeFilesToDirectory } from './utils/write-files.js';\n\n/**\n * Fetch template files from GitHub and write them to the working directory.\n */\nasync function fetchAndWriteTemplateFiles(\n template: Template,\n workDir: string\n): Promise<void> {\n if (!template.source) {\n console.warn(\n `Template \"${template.name}\" has no source configured, creating empty directory`\n );\n return;\n }\n\n const files = await fetchGitHubFolder(template.source, {\n userAgent: 'EvalForge-Evaluator'\n });\n\n await writeFilesToDirectory(workDir, files);\n}\n\nfunction writeWixEnvFile(workDir: string): void {\n const configPath = path.join(workDir, 'wix.config.json');\n if (!existsSync(configPath)) {\n return;\n }\n try {\n const config = JSON.parse(readFileSync(configPath, 'utf-8'));\n if (config.appId) {\n writeFileSync(\n path.join(workDir, '.env'),\n `WIX_CLIENT_ID=${config.appId}\\n`,\n 'utf-8'\n );\n console.log('[environment] Wrote WIX_CLIENT_ID to .env');\n }\n } catch {\n console.warn('[environment] Failed to read wix.config.json');\n }\n}\n\n/**\n * Prepare the working directory for a scenario.\n * If a template with source is provided, fetch files from GitHub.\n * If no template, create an empty directory so file creation/modification can be tracked.\n *\n * @param config - Evaluator configuration\n * @param evalRunId - The evaluation run ID\n * @param targetId - The target ID (prompt agent, skill, or agent)\n * @param scenarioId - The scenario ID (for per-scenario isolation when no template)\n * @param template - Optional pre-fetched template entity\n * @returns The working directory path\n */\nexport async function prepareWorkingDirectory(\n config: EvaluatorConfig,\n evalRunId: string,\n targetId: string,\n scenarioId: string,\n template?: Template\n): Promise<string> {\n const baseDir =\n config.evaluationsDir ?? path.join(tmpdir(), 'evalforge-evaluations');\n\n if (template) {\n if (!config.evaluationsDir) {\n console.warn(\n 'Template specified but EVALUATIONS_DIR not set, using temp directory'\n );\n }\n const workDir = path.join(baseDir, `${evalRunId}_${targetId}`);\n if (existsSync(workDir)) {\n rmSync(workDir, { recursive: true });\n }\n mkdirSync(workDir, { recursive: true });\n await fetchAndWriteTemplateFiles(template, workDir);\n console.log(`Template files written to ${workDir}`);\n writeWixEnvFile(workDir);\n return workDir;\n }\n\n const workDir = path.join(baseDir, `${evalRunId}_${targetId}_${scenarioId}`);\n if (existsSync(workDir)) {\n rmSync(workDir, { recursive: true });\n }\n mkdirSync(workDir, { recursive: true });\n console.log(`Empty working directory created at ${workDir}`);\n return workDir;\n}\n", "import { mkdir, writeFile } from 'fs/promises';\nimport { dirname, resolve, sep } from 'path';\nimport type { SkillFile } from '@wix/evalforge-types';\n\n/**\n * Write an array of {path, content} files to a target directory.\n * Validates paths to prevent directory traversal.\n */\nexport async function writeFilesToDirectory(\n targetDir: string,\n files: SkillFile[]\n): Promise<void> {\n const resolvedBase = resolve(targetDir);\n for (const file of files) {\n const filePath = resolve(targetDir, file.path);\n if (!filePath.startsWith(resolvedBase + sep) && filePath !== resolvedBase) {\n throw new Error(\n `Path traversal detected: \"${file.path}\" resolves outside target directory`\n );\n }\n await mkdir(dirname(filePath), { recursive: true });\n await writeFile(filePath, file.content, 'utf-8');\n }\n}\n", "import type { TestScenario, AgentExecutionContext } from '@wix/evalforge-types';\nimport { randomUUID } from 'crypto';\nimport type { EvaluatorConfig } from '../config.js';\nimport type { PartialEvalRunResult } from './types.js';\nimport type { EvaluationData } from '../fetch-evaluation-data.js';\nimport { getAdapter } from './agents/index.js';\nimport { simpleAgentAdapter } from './agents/simple-agent/simple-agent-adapter.js';\nimport {\n snapshotDirectory,\n diffSnapshots,\n extractTemplateFiles,\n deriveInfrastructurePaths\n} from './file-diff.js';\n\nimport { AgentRunCommand, AgentType } from '@wix/evalforge-types';\n\nconst DEFAULT_AGENT_COMMAND = AgentRunCommand.CLAUDE;\n\n/**\n * Run the agent with the full execution context (skills, MCPs, sub-agents, etc.).\n *\n * Uses the agent adapter registry to select the appropriate adapter based on\n * the agent's runCommand (for CLI agents) or adapter ID (for SDK agents).\n * If no agent is specified, defaults to 'claude'.\n *\n * @param config - Evaluator configuration\n * @param evalRunId - The evaluation run ID (for live trace context)\n * @param scenario - The test scenario to run\n * @param evalData - Fetched evaluation data (skills, agent, mcps, subAgents)\n * @param workDir - Optional working directory for the scenario\n * @returns Partial result without assertion fields\n */\nexport async function runAgentWithContext(\n config: EvaluatorConfig,\n evalRunId: string,\n scenario: TestScenario,\n evalData: EvaluationData,\n workDir?: string\n): Promise<PartialEvalRunResult> {\n const agent = evalData.agent ?? undefined;\n const isSDK = agent?.agentType === AgentType.SDK;\n\n const identifier: string = isSDK\n ? simpleAgentAdapter.id\n : (agent?.runCommand ?? DEFAULT_AGENT_COMMAND);\n const adapter = getAdapter(identifier);\n\n const startedAt = new Date().toISOString();\n\n const targetId =\n evalData.evalRun.presetId ?? agent?.id ?? evalData.evalRun.id;\n const targetName = evalData.presetName || agent?.name || '';\n\n const executionContext: AgentExecutionContext = {\n skills: evalData.skills,\n scenario,\n cwd: workDir || process.cwd(),\n modelConfig: agent?.modelConfig,\n aiGatewayUrl: config.aiGatewayUrl,\n aiGatewayHeaders: config.aiGatewayHeaders,\n traceContext: {\n evalRunId,\n scenarioId: scenario.id,\n scenarioName: scenario.name,\n targetId,\n targetName,\n tracePushUrl: config.tracePushUrl,\n routeHeader: config.routeHeader,\n authToken: config.authToken\n },\n mcps: evalData.mcps.length > 0 ? evalData.mcps : undefined,\n subAgents: evalData.subAgents.length > 0 ? evalData.subAgents : undefined,\n rules: evalData.rules?.length > 0 ? evalData.rules : undefined,\n systemPrompt: agent?.systemPrompt\n };\n\n const hasPrepare = !!adapter.prepareEnvironment;\n\n // Snapshot before prepareEnvironment to detect which files are infrastructure.\n const prePrepSnapshot =\n hasPrepare && workDir ? snapshotDirectory(workDir) : {};\n\n // Let the adapter write infrastructure files (skills, MCPs, rules, etc.)\n // *before* the baseline snapshot so they don't appear as \"new\" in diffs.\n if (hasPrepare) {\n await adapter.prepareEnvironment!(executionContext);\n }\n\n const beforeSnapshot = workDir ? snapshotDirectory(workDir) : {};\n const infrastructurePaths = hasPrepare\n ? deriveInfrastructurePaths(prePrepSnapshot, beforeSnapshot)\n : new Set<string>();\n\n const { outputText, durationMs, llmTrace, conversation } =\n await adapter.execute(executionContext);\n\n const completedAt = new Date().toISOString();\n\n const afterSnapshot = workDir ? snapshotDirectory(workDir) : {};\n const fileDiffs = diffSnapshots(\n beforeSnapshot,\n afterSnapshot,\n infrastructurePaths\n );\n const templateFiles = workDir\n ? extractTemplateFiles(beforeSnapshot, afterSnapshot, infrastructurePaths)\n : undefined;\n\n const resolvedModelConfig =\n agent?.modelConfig ??\n (llmTrace?.summary.modelsUsed?.[0]\n ? { model: llmTrace.summary.modelsUsed[0] }\n : undefined);\n\n return {\n id: randomUUID(),\n targetId,\n targetName,\n scenarioId: scenario.id,\n scenarioName: scenario.name,\n modelConfig: resolvedModelConfig,\n duration: durationMs,\n outputText,\n fileDiffs: fileDiffs.length > 0 ? fileDiffs : undefined,\n templateFiles:\n templateFiles && templateFiles.length > 0 ? templateFiles : undefined,\n startedAt,\n completedAt,\n llmTrace,\n conversation\n };\n}\n", "import type { AgentAdapter } from '@wix/evalforge-types';\n\n/**\n * Registry for agent adapters.\n *\n * Supports two lookup strategies:\n * - By CLI command (e.g. 'claude') for CLI-based agents\n * - By adapter ID (e.g. 'simple-agent') for SDK-based agents\n *\n * @example\n * ```typescript\n * const registry = new AgentAdapterRegistry();\n * registry.register(new ClaudeCodeAdapter());\n *\n * const adapter = registry.resolve('claude');\n * if (adapter) {\n * const result = await adapter.execute(context);\n * }\n * ```\n */\nexport class AgentAdapterRegistry {\n /** Map of CLI commands to their registered adapters. */\n private commandMap = new Map<string, AgentAdapter>();\n\n /** Map of adapter IDs to their registered adapters. */\n private idMap = new Map<string, AgentAdapter>();\n\n /** Set of all registered adapter instances (for getAll). */\n private registeredAdapters = new Set<AgentAdapter>();\n\n /**\n * Register an agent adapter.\n *\n * The adapter is registered by its ID and for all commands in its supportedCommands array.\n * If a command or ID is already registered, it will be overwritten with a warning.\n */\n register(adapter: AgentAdapter): void {\n this.registeredAdapters.add(adapter);\n this.idMap.set(adapter.id, adapter);\n\n for (const command of adapter.supportedCommands) {\n if (this.commandMap.has(command)) {\n const existing = this.commandMap.get(command)!;\n console.warn(\n `[AgentAdapterRegistry] Command \"${command}\" already registered by adapter \"${existing.id}\". ` +\n `Overwriting with adapter \"${adapter.id}\".`\n );\n }\n this.commandMap.set(command, adapter);\n }\n }\n\n /** Get an adapter by CLI command. */\n getByCommand(command: string): AgentAdapter | undefined {\n return this.commandMap.get(command);\n }\n\n /** Get an adapter by adapter ID. */\n getById(adapterId: string): AgentAdapter | undefined {\n return this.idMap.get(adapterId);\n }\n\n /**\n * Unified lookup: tries CLI command first, then adapter ID.\n * Use this when the identifier could be either a command or an adapter ID.\n */\n resolve(identifier: string): AgentAdapter | undefined {\n return this.commandMap.get(identifier) ?? this.idMap.get(identifier);\n }\n\n /** Check if a command or adapter ID has a registered adapter. */\n has(identifier: string): boolean {\n return this.commandMap.has(identifier) || this.idMap.has(identifier);\n }\n\n /** Get all registered adapters. */\n getAll(): AgentAdapter[] {\n return Array.from(this.registeredAdapters);\n }\n\n /** Get all supported CLI commands. */\n getSupportedCommands(): string[] {\n return Array.from(this.commandMap.keys());\n }\n\n /** Get all registered adapter IDs. */\n getAdapterIds(): string[] {\n return Array.from(this.idMap.keys());\n }\n\n /**\n * Unregister an adapter by its ID.\n * Removes the adapter and all its command mappings.\n */\n unregister(adapterId: string): boolean {\n let found = false;\n\n for (const adapter of this.registeredAdapters) {\n if (adapter.id === adapterId) {\n this.registeredAdapters.delete(adapter);\n this.idMap.delete(adapterId);\n found = true;\n\n for (const command of adapter.supportedCommands) {\n if (this.commandMap.get(command) === adapter) {\n this.commandMap.delete(command);\n }\n }\n break;\n }\n }\n\n return found;\n }\n\n /** Clear all registered adapters. Primarily useful for testing. */\n clear(): void {\n this.commandMap.clear();\n this.idMap.clear();\n this.registeredAdapters.clear();\n }\n}\n\n/**\n * Default global registry instance.\n * Adapters are auto-registered here when their modules are imported.\n */\nexport const defaultRegistry = new AgentAdapterRegistry();\n\n/**\n * Get an adapter from the default registry.\n *\n * Uses unified lookup (command first, then adapter ID).\n * Throws a helpful error if the adapter is not found.\n */\nexport function getAdapter(identifier: string): AgentAdapter {\n const adapter = defaultRegistry.resolve(identifier);\n if (!adapter) {\n const commands = defaultRegistry.getSupportedCommands();\n const ids = defaultRegistry.getAdapterIds();\n throw new Error(\n `No agent adapter registered for \"${identifier}\". ` +\n `Supported commands: ${commands.length > 0 ? commands.join(', ') : '(none)'}. ` +\n `Registered adapters: ${ids.length > 0 ? ids.join(', ') : '(none)'}`\n );\n }\n return adapter;\n}\n\n/** Check if an identifier has a registered adapter in the default registry. */\nexport function hasAdapter(identifier: string): boolean {\n return defaultRegistry.has(identifier);\n}\n", "import type {\n AgentAdapter,\n AgentExecutionContext,\n AgentExecutionResult\n} from '@wix/evalforge-types';\nimport { AgentRunCommand } from '@wix/evalforge-types';\nimport {\n executeWithClaudeCode,\n prepareClaudeCodeEnvironment\n} from './execute.js';\nimport type { ClaudeCodeExecutionOptions } from './types.js';\n\n/**\n * Claude Code agent adapter.\n *\n * Implements the AgentAdapter interface for the Claude Code CLI/SDK.\n * This adapter wraps the existing executeWithClaudeCode function to provide\n * a standardized interface for the evaluation system.\n *\n * Supported commands: 'claude'\n */\nexport class ClaudeCodeAdapter implements AgentAdapter {\n readonly id = 'claude-code';\n readonly name = 'Claude Code';\n readonly supportedCommands = [AgentRunCommand.CLAUDE] as const;\n\n /**\n * Write infrastructure files (settings, MCPs, sub-agents, rules, skills)\n * before the baseline snapshot is taken.\n */\n async prepareEnvironment(context: AgentExecutionContext): Promise<void> {\n await prepareClaudeCodeEnvironment(context.cwd, context.skills, {\n mcps: context.mcps,\n subAgents: context.subAgents,\n rules: context.rules\n });\n }\n\n /**\n * Execute a skill using the Claude Code SDK.\n *\n * @param context - The agent-agnostic execution context\n * @returns The standardized execution result\n */\n async execute(context: AgentExecutionContext): Promise<AgentExecutionResult> {\n const {\n skills,\n scenario,\n cwd,\n modelConfig,\n aiGatewayUrl,\n aiGatewayHeaders,\n traceContext,\n mcps,\n subAgents,\n rules,\n systemPrompt\n } = context;\n\n // Pass the enum value directly \u2014 the proxy resolves it to the gateway model\n const modelForSdk = modelConfig?.model;\n\n const options: ClaudeCodeExecutionOptions = {\n cwd,\n model: modelForSdk,\n temperature: modelConfig?.temperature,\n maxTokens: modelConfig?.maxTokens,\n maxTurns: modelConfig?.maxTurns,\n aiGatewayUrl,\n aiGatewayHeaders,\n traceContext,\n mcps,\n subAgents,\n rules,\n systemPrompt\n };\n\n // Execute using the existing Claude Code implementation\n const { result, llmTrace, conversation } = await executeWithClaudeCode(\n skills,\n scenario,\n options\n );\n\n // Map to the agent-agnostic result format\n return {\n outputText: result.outputText,\n durationMs: result.durationMs,\n usage: {\n inputTokens: result.usage.inputTokens,\n outputTokens: result.usage.outputTokens,\n totalTokens: result.usage.totalTokens\n },\n costUsd: result.costUsd,\n llmTrace,\n conversation\n };\n }\n}\n\n/**\n * Singleton instance of the Claude Code adapter.\n */\nexport const claudeCodeAdapter = new ClaudeCodeAdapter();\n", "import type {\n SkillWithLatestVersion,\n TestScenario,\n LLMTrace,\n LiveTraceEvent,\n ConversationMessage\n} from '@wix/evalforge-types';\nimport {\n ClaudeModel,\n DEFAULT_EVALUATOR_SYSTEM_PROMPT,\n LLMStepType,\n LiveTraceEventType\n} from '@wix/evalforge-types';\nimport { writeSkillsToFilesystem } from './write-skills.js';\nimport { randomUUID } from 'crypto';\nimport type { CapturedStep } from '../../types.js';\nimport type {\n ClaudeCodeExecutionOptions,\n ClaudeCodeExecutionResult,\n TraceContext\n} from './types.js';\nimport { writeMcpToFilesystem } from './write-mcp.js';\nimport { writeSubAgentsToFilesystem } from './write-sub-agents.js';\nimport { writeRulesToFilesystem } from './write-rules.js';\nimport { buildConversation } from './build-conversation.js';\nimport { emitTraceEvent } from '../shared/trace-emit.js';\n\n/**\n * Import SDK types directly from Claude Agent SDK.\n * Type-only imports are erased at compile time - zero runtime overhead.\n * The SDK is still dynamically imported at runtime in executeWithClaudeCode().\n */\nimport type {\n SDKAssistantMessage,\n SDKResultMessage,\n SDKUserMessage,\n SDKSystemMessage,\n SDKMessage\n} from '@anthropic-ai/claude-agent-sdk' with { 'resolution-mode': 'import' };\n\n/**\n * Message with timestamp \u2014 tracks when each message was received.\n */\nexport interface TimestampedMessage {\n message: SDKMessage;\n receivedAt: Date;\n}\n\nconst DEFAULT_MODEL = ClaudeModel.CLAUDE_4_5_SONNET_1_0;\n\n/**\n * Extract a meaningful action description from tool name and arguments.\n * This provides more informative progress messages than just \"Using Tool...\".\n *\n * @param toolName - The name of the tool being used\n * @param toolArgs - JSON string of tool arguments\n * @returns A human-readable action description\n */\nfunction extractToolActionDescription(\n toolName: string | undefined,\n toolArgs: string | undefined\n): string {\n if (!toolName) {\n return 'Using tool...';\n }\n\n // Try to parse tool args for more context\n if (toolArgs) {\n try {\n const args = JSON.parse(toolArgs) as Record<string, unknown>;\n\n // Task/SubAgent tool - show the description with tool prefix\n // This makes it clear the agent is waiting for a sub-task to complete\n if (\n (toolName === 'Task' || toolName === 'dispatch_agent') &&\n args.description\n ) {\n const desc = String(args.description).slice(0, 55);\n const truncatedDesc =\n desc.length < String(args.description).length ? `${desc}...` : desc;\n return `Task: ${truncatedDesc}`;\n }\n\n // Bash/Command tool - show the command\n if (\n (toolName === 'Bash' ||\n toolName === 'bash' ||\n toolName === 'execute') &&\n args.command\n ) {\n const cmd = String(args.command).slice(0, 50);\n return `Running: ${cmd}${String(args.command).length > 50 ? '...' : ''}`;\n }\n\n // Search/Grep tool - show the query/pattern\n if (\n toolName === 'Search' ||\n toolName === 'search' ||\n toolName === 'Grep'\n ) {\n const query = args.query || args.pattern || args.search;\n if (query) {\n return `Searching: ${String(query).slice(0, 40)}`;\n }\n }\n\n // List files tool\n if (toolName === 'LS' || toolName === 'ls' || toolName === 'ListFiles') {\n const path = args.path || args.directory || '.';\n return `Listing: ${String(path).slice(0, 50)}`;\n }\n\n // Read tool with file path\n if (\n (toolName === 'Read' || toolName === 'read' || toolName === 'View') &&\n (args.file_path || args.path || args.target_file)\n ) {\n const filePath = String(\n args.file_path || args.path || args.target_file\n ).slice(0, 50);\n return `Reading: ${filePath}`;\n }\n\n // Write/Edit tool with file path\n if (\n (toolName === 'Write' || toolName === 'Edit' || toolName === 'write') &&\n (args.file_path || args.path || args.target_file)\n ) {\n const filePath = String(\n args.file_path || args.path || args.target_file\n ).slice(0, 50);\n return `Writing: ${filePath}`;\n }\n } catch {\n // Failed to parse, use default\n }\n }\n\n // Default: just show tool name\n return `Using ${toolName}...`;\n}\n\n/**\n * Create a trace event from an SDK message.\n * @param message - The SDK message to convert\n * @param context - The trace context\n * @param stepNumber - The current step number\n * @param isComplete - Whether this is the final event\n * @returns The trace event\n */\nfunction createTraceEventFromMessage(\n message: SDKAssistantMessage,\n context: TraceContext,\n stepNumber: number,\n isComplete: boolean\n): LiveTraceEvent {\n let type: LiveTraceEventType = LiveTraceEventType.COMPLETION;\n let toolName: string | undefined;\n let toolArgs: string | undefined;\n let outputPreview: string | undefined;\n let filePath: string | undefined;\n let thinking: string | undefined;\n\n for (const block of message.message.content) {\n if (block.type === 'tool_use') {\n type = LiveTraceEventType.TOOL_USE;\n toolName = block.name;\n toolArgs = JSON.stringify(block.input).slice(0, 500);\n\n const input = block.input as Record<string, unknown>;\n if (input.file_path || input.path || input.target_file) {\n filePath = String(input.file_path || input.path || input.target_file);\n if (\n block.name === 'Write' ||\n block.name === 'Edit' ||\n block.name === 'write' ||\n block.name === 'edit'\n ) {\n type = LiveTraceEventType.FILE_WRITE;\n } else if (\n block.name === 'Read' ||\n block.name === 'read' ||\n block.name === 'View'\n ) {\n type = LiveTraceEventType.FILE_READ;\n }\n }\n } else if (block.type === 'text') {\n outputPreview = block.text.slice(0, 500);\n if (!toolName) {\n type = LiveTraceEventType.COMPLETION;\n }\n } else if (block.type === 'thinking') {\n const thinkingBlock = block as { type: 'thinking'; thinking: string };\n thinking = thinkingBlock.thinking.slice(0, 500);\n if (!outputPreview && !toolName) {\n type = LiveTraceEventType.THINKING;\n }\n }\n }\n\n return {\n evalRunId: context.evalRunId,\n scenarioId: context.scenarioId,\n scenarioName: context.scenarioName,\n targetId: context.targetId,\n targetName: context.targetName,\n stepNumber,\n type,\n toolName,\n toolArgs,\n outputPreview,\n filePath,\n thinking,\n timestamp: new Date().toISOString(),\n isComplete\n };\n}\n\n/**\n * Create a trace event from any SDK message type.\n * @param message - Any SDK message\n * @param context - The trace context\n * @param stepNumber - The current step number\n * @param isComplete - Whether this is the final event\n * @returns The trace event or null if message type is not traceable\n */\nfunction createTraceEventFromAnyMessage(\n message: SDKMessage,\n context: TraceContext,\n stepNumber: number,\n isComplete: boolean\n): LiveTraceEvent | null {\n const baseEvent = {\n evalRunId: context.evalRunId,\n scenarioId: context.scenarioId,\n scenarioName: context.scenarioName,\n targetId: context.targetId,\n targetName: context.targetName,\n stepNumber,\n timestamp: new Date().toISOString(),\n isComplete\n };\n\n if (isAssistantMessage(message)) {\n return createTraceEventFromMessage(\n message,\n context,\n stepNumber,\n isComplete\n );\n }\n\n if (message.type === 'user') {\n const userMsg = message as SDKUserMessage;\n let outputPreview = '';\n\n // Extract preview from user message content\n // Content can be string or array of blocks (text or tool_result)\n const content = userMsg.message?.content;\n if (typeof content === 'string') {\n outputPreview = content.slice(0, 500);\n } else if (Array.isArray(content)) {\n for (const block of content) {\n if (typeof block !== 'object' || block === null) continue;\n const b = block as unknown as Record<string, unknown>;\n if (b.type === 'text' && typeof b.text === 'string') {\n outputPreview = b.text.slice(0, 500);\n break;\n }\n if (b.type === 'tool_result') {\n const raw = b.content;\n const preview =\n typeof raw === 'string'\n ? raw\n : Array.isArray(raw)\n ? (raw as Array<Record<string, unknown>>)\n .filter(\n (c) => c.type === 'text' && typeof c.text === 'string'\n )\n .map((c) => c.text as string)\n .join('\\n')\n : '';\n outputPreview = preview.slice(0, 500);\n break;\n }\n }\n }\n\n return {\n ...baseEvent,\n type: LiveTraceEventType.TOOL_RESULT,\n outputPreview: outputPreview || '(tool result)'\n };\n }\n\n if (message.type === 'system') {\n const sysMsg = message as SDKSystemMessage;\n // SDKSystemMessage has subtype (e.g., 'init') but no 'message' field\n return {\n ...baseEvent,\n type: LiveTraceEventType.SYSTEM,\n outputPreview: sysMsg.subtype || 'system'\n };\n }\n\n if (message.type === 'result') {\n // Result messages indicate completion, already handled elsewhere\n return null;\n }\n\n // Unknown message type - emit as generic progress\n return {\n ...baseEvent,\n type: LiveTraceEventType.PROGRESS,\n outputPreview: `Message type: ${message.type}`\n };\n}\n\n/**\n * Write all infrastructure files (settings, MCPs, sub-agents, rules, skills)\n * to the working directory. Called by the adapter's `prepareEnvironment()` so\n * that the orchestrator can take the baseline snapshot *after* infra is in place.\n */\nexport async function prepareClaudeCodeEnvironment(\n cwd: string,\n skills: SkillWithLatestVersion[],\n options: Pick<ClaudeCodeExecutionOptions, 'mcps' | 'subAgents' | 'rules'>\n): Promise<void> {\n const { mkdir: mkdirAsync, writeFile } = await import('fs/promises');\n const claudeDir = `${cwd}/.claude`;\n await mkdirAsync(claudeDir, { recursive: true });\n await writeFile(`${claudeDir}/settings.json`, '{}', {\n flag: 'wx'\n }).catch(() => {\n // File already exists \u2014 that's fine\n });\n\n if (options.mcps && options.mcps.length > 0) {\n await writeMcpToFilesystem(cwd, options.mcps);\n }\n\n if (options.subAgents && options.subAgents.length > 0) {\n await writeSubAgentsToFilesystem(cwd, options.subAgents);\n }\n\n if (options.rules && options.rules.length > 0) {\n await writeRulesToFilesystem(cwd, options.rules);\n }\n\n try {\n await writeSkillsToFilesystem(cwd, skills);\n } catch (writeError) {\n throw new Error(\n `Failed to write skills to filesystem: ${writeError instanceof Error ? writeError.message : String(writeError)}`\n );\n }\n}\n\n/**\n * Execute skills using the Claude Agent SDK.\n *\n * All skills are written to .claude/skills/<name>/SKILL.md. The SDK discovers\n * them from the filesystem; no system prompt is passed. The agent has access\n * to all skills as a group.\n *\n * @param skills - All skills to execute (each written to its own directory)\n * @param scenario - The test scenario containing the trigger prompt\n * @param options - Execution options (cwd, mcps, etc.)\n * @returns Execution result with output, usage, and LLM trace\n */\nexport async function executeWithClaudeCode(\n skills: SkillWithLatestVersion[],\n scenario: TestScenario,\n options: ClaudeCodeExecutionOptions\n): Promise<{\n result: ClaudeCodeExecutionResult;\n llmTrace: LLMTrace;\n conversation: ConversationMessage[];\n}> {\n const skillNames = skills.map((s) => s.name).join(', ');\n console.log('[executeWithClaudeCode] Starting execution', {\n skillCount: skills.length,\n skillNames,\n scenarioId: scenario.id,\n scenarioName: scenario.name,\n cwd: options.cwd,\n aiGatewayUrl: options.aiGatewayUrl,\n hasAiGatewayHeaders: !!options.aiGatewayHeaders,\n model: options.model\n });\n\n // Dynamic import for ESM module\n let query;\n try {\n const sdk = await import('@anthropic-ai/claude-agent-sdk');\n query = sdk.query;\n } catch (importError) {\n throw new Error(\n `Failed to import Claude Agent SDK: ${importError instanceof Error ? importError.message : String(importError)}`\n );\n }\n\n const startTime = new Date();\n const allMessages: TimestampedMessage[] = [];\n\n // Build environment variables for the SDK\n const sdkEnv = buildSdkEnvironment(options);\n\n // Track step number for trace events\n let traceStepNumber = 0;\n const traceContext = options.traceContext;\n\n // Track the last action for informative heartbeat messages\n let lastAction = 'Starting...';\n let lastToolName: string | undefined;\n let lastFilePath: string | undefined;\n\n // Execute the query using Claude Agent SDK\n const maxTurns = options.maxTurns ?? 10;\n\n let messageCount = 0;\n\n // Custom permission handler that auto-allows all tool usage.\n // This is used instead of 'bypassPermissions' mode because that mode\n // cannot be used when running as root (the dev machine container runs as root).\n // The Claude CLI explicitly blocks --dangerously-skip-permissions for security\n // when running with root/sudo privileges.\n // Must return both `behavior: 'allow'` and `updatedInput` to satisfy\n // the SDK's runtime Zod validation union.\n const canUseTool = async (\n _toolName: string,\n input: Record<string, unknown>\n ) => ({ behavior: 'allow' as const, updatedInput: input });\n\n const baseAllowedTools = [\n 'Skill',\n 'Read',\n 'Write',\n 'Edit',\n 'Bash',\n 'Glob',\n 'Grep',\n 'Agent',\n 'WebFetch',\n 'WebSearch'\n ];\n const allowedTools =\n (options.mcps?.length ?? 0) > 0\n ? [...baseAllowedTools, 'mcp__*']\n : baseAllowedTools;\n\n const queryOptions: Record<string, unknown> = {\n env: sdkEnv,\n cwd: options.cwd,\n settingSources: ['project'],\n allowedTools,\n model: options.model || DEFAULT_MODEL,\n maxTurns,\n maxThinkingTokens: options.maxThinkingTokens,\n // Use 'default' permission mode with custom canUseTool handler\n // instead of 'bypassPermissions' which fails on root\n permissionMode: 'default',\n canUseTool\n };\n\n // System prompt override: undefined = default behavioral instructions,\n // null or empty string = no system prompt (raw agent), non-empty string = custom prompt\n if (options.systemPrompt === null || options.systemPrompt === '') {\n // Explicitly disabled -- omit systemPrompt entirely for raw agent behavior\n } else if (options.systemPrompt != null) {\n queryOptions.systemPrompt = {\n type: 'preset',\n preset: 'claude_code',\n append: options.systemPrompt\n };\n } else {\n queryOptions.systemPrompt = {\n type: 'preset',\n preset: 'claude_code',\n append: DEFAULT_EVALUATOR_SYSTEM_PROMPT\n };\n }\n if (options.temperature !== undefined) {\n queryOptions.temperature = options.temperature;\n }\n if (options.maxTokens !== undefined) {\n queryOptions.maxTokens = options.maxTokens;\n }\n\n // Log query options (excluding env which we already logged)\n console.log('[SDK-DEBUG] Query options:');\n console.log('[SDK-DEBUG] model:', queryOptions.model);\n console.log('[SDK-DEBUG] maxTurns:', queryOptions.maxTurns);\n console.log(\n '[SDK-DEBUG] maxThinkingTokens:',\n queryOptions.maxThinkingTokens\n );\n console.log('[SDK-DEBUG] temperature:', queryOptions.temperature);\n console.log('[SDK-DEBUG] maxTokens:', queryOptions.maxTokens);\n console.log('[SDK-DEBUG] permissionMode:', queryOptions.permissionMode);\n console.log(\n '[SDK-DEBUG] canUseTool:',\n queryOptions.canUseTool ? 'custom handler (auto-allow)' : 'not set'\n );\n console.log('[SDK-DEBUG] systemPrompt:', queryOptions.systemPrompt);\n console.log('[SDK-DEBUG] settingSources:', queryOptions.settingSources);\n console.log('[SDK-DEBUG] allowedTools:', queryOptions.allowedTools);\n console.log('[SDK-DEBUG] Calling SDK query()...');\n\n // Emit a diagnostic trace event before calling the SDK\n // This helps identify if the failure happens before or during SDK execution\n if (traceContext) {\n const preExecEvent = {\n evalRunId: traceContext.evalRunId,\n scenarioId: traceContext.scenarioId,\n scenarioName: traceContext.scenarioName,\n targetId: traceContext.targetId,\n targetName: traceContext.targetName,\n stepNumber: 0,\n type: LiveTraceEventType.DIAGNOSTIC,\n outputPreview: JSON.stringify({\n event: 'pre-sdk-execution',\n model: queryOptions.model,\n maxTurns: queryOptions.maxTurns,\n sdkEnv: {\n ANTHROPIC_BASE_URL: sdkEnv.ANTHROPIC_BASE_URL,\n hasANTHROPIC_API_KEY: !!sdkEnv.ANTHROPIC_API_KEY,\n hasANTHROPIC_AUTH_TOKEN: !!sdkEnv.ANTHROPIC_AUTH_TOKEN,\n hasANTHROPIC_CUSTOM_HEADERS: !!sdkEnv.ANTHROPIC_CUSTOM_HEADERS\n },\n timestamp: new Date().toISOString()\n }),\n timestamp: new Date().toISOString(),\n isComplete: false\n };\n emitTraceEvent(\n preExecEvent,\n traceContext.tracePushUrl,\n traceContext.routeHeader,\n traceContext.authToken\n );\n }\n\n // SDK execution timeout to prevent infinite hangs\n // Default 5 minutes per skill, can be adjusted based on maxTurns\n const SDK_TIMEOUT_MS = Math.max(300000, maxTurns * 60000);\n let timeoutHandle: ReturnType<typeof setTimeout> | undefined;\n let timedOut = false;\n\n // Heartbeat interval to emit progress events every 10 seconds\n // This keeps the UI updated during long-running operations\n const HEARTBEAT_INTERVAL_MS = 10000;\n let heartbeatHandle: ReturnType<typeof setInterval> | undefined;\n const executionStartTime = Date.now();\n\n try {\n // Create timeout promise that rejects after SDK_TIMEOUT_MS\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutHandle = setTimeout(() => {\n timedOut = true;\n reject(\n new Error(\n `SDK execution timed out after ${SDK_TIMEOUT_MS}ms. ` +\n `Skills: ${skillNames}, Scenario: ${scenario.name}, ` +\n `Messages received: ${messageCount}, MaxTurns: ${maxTurns}`\n )\n );\n }, SDK_TIMEOUT_MS);\n });\n\n // Start heartbeat interval to emit progress events\n if (traceContext) {\n // Track how many heartbeats we've sent for the same action\n let lastReportedAction = '';\n let sameActionCount = 0;\n\n heartbeatHandle = setInterval(() => {\n const elapsedMs = Date.now() - executionStartTime;\n\n // Build informative progress message with last action\n let progressMessage = lastAction;\n\n // Track how long we've been on the same action\n if (lastAction === lastReportedAction) {\n sameActionCount++;\n } else {\n sameActionCount = 1;\n lastReportedAction = lastAction;\n }\n\n // For Task/sub-agent tools, show waiting status after first heartbeat\n const isTaskTool =\n lastToolName === 'Task' || lastToolName === 'dispatch_agent';\n if (isTaskTool && sameActionCount > 1) {\n // Show that we're waiting for the sub-task to complete\n progressMessage = `Waiting for ${lastAction}`;\n } else if (lastToolName && lastFilePath) {\n progressMessage = `${lastToolName}: ${lastFilePath}`;\n } else if (lastToolName && !isTaskTool) {\n progressMessage = `Using ${lastToolName}...`;\n }\n\n // Add elapsed time and step info\n const elapsedSec = Math.round(elapsedMs / 1000);\n progressMessage += ` (${elapsedSec}s, step ${traceStepNumber})`;\n\n const progressEvent: LiveTraceEvent = {\n evalRunId: traceContext.evalRunId,\n scenarioId: traceContext.scenarioId,\n scenarioName: traceContext.scenarioName,\n targetId: traceContext.targetId,\n targetName: traceContext.targetName,\n stepNumber: traceStepNumber,\n type: LiveTraceEventType.PROGRESS,\n outputPreview: progressMessage,\n toolName: lastToolName,\n filePath: lastFilePath,\n elapsedMs,\n timestamp: new Date().toISOString(),\n isComplete: false\n };\n emitTraceEvent(\n progressEvent,\n traceContext.tracePushUrl,\n traceContext.routeHeader,\n traceContext.authToken\n );\n }, HEARTBEAT_INTERVAL_MS);\n }\n\n // SDK execution promise\n const sdkPromise = (async () => {\n for await (const message of query({\n prompt: scenario.triggerPrompt,\n options: queryOptions\n })) {\n // Log all messages for debugging and capture timestamp\n messageCount++;\n const receivedAt = new Date();\n console.log('[SDK Message]', JSON.stringify(message, null, 2));\n allMessages.push({ message: message as SDKMessage, receivedAt });\n // Emit live trace events for ALL message types if trace context is provided\n if (traceContext) {\n traceStepNumber++;\n const traceEvent = createTraceEventFromAnyMessage(\n message as SDKMessage,\n traceContext,\n traceStepNumber,\n false // Not complete yet\n );\n if (traceEvent) {\n // Update last action tracking for informative heartbeats\n lastToolName = traceEvent.toolName;\n lastFilePath = traceEvent.filePath;\n if (traceEvent.type === LiveTraceEventType.THINKING) {\n lastAction = 'Thinking...';\n } else if (traceEvent.type === LiveTraceEventType.TOOL_USE) {\n // Try to extract meaningful info from tool args for better progress messages\n lastAction = extractToolActionDescription(\n traceEvent.toolName,\n traceEvent.toolArgs\n );\n } else if (traceEvent.type === LiveTraceEventType.FILE_WRITE) {\n lastAction = `Writing: ${traceEvent.filePath || 'file'}`;\n } else if (traceEvent.type === LiveTraceEventType.FILE_READ) {\n lastAction = `Reading: ${traceEvent.filePath || 'file'}`;\n } else if (traceEvent.type === LiveTraceEventType.COMPLETION) {\n lastAction = 'Processing response...';\n }\n\n emitTraceEvent(\n traceEvent,\n traceContext.tracePushUrl,\n traceContext.routeHeader,\n traceContext.authToken\n );\n }\n }\n }\n })();\n\n // Race between SDK execution and timeout\n await Promise.race([sdkPromise, timeoutPromise]);\n\n // Clear timeout and heartbeat if SDK completed successfully\n if (timeoutHandle) {\n clearTimeout(timeoutHandle);\n }\n if (heartbeatHandle) {\n clearInterval(heartbeatHandle);\n }\n\n console.log(\n '[executeWithClaudeCode] Claude Agent SDK query completed, received',\n allMessages.length,\n 'messages'\n );\n } catch (sdkError) {\n // Clear timeout and heartbeat on error\n if (timeoutHandle) {\n clearTimeout(timeoutHandle);\n }\n if (heartbeatHandle) {\n clearInterval(heartbeatHandle);\n }\n\n // Log if this was a timeout\n if (timedOut) {\n console.error('[SDK-TIMEOUT] Execution timed out:', sdkError);\n }\n // === COMPREHENSIVE ERROR DEBUGGING ===\n console.error('[SDK-ERROR] ====== CLAUDE SDK EXECUTION FAILED ======');\n console.error('[SDK-ERROR] Timestamp:', new Date().toISOString());\n console.error(\n '[SDK-ERROR] Messages received before failure:',\n messageCount\n );\n\n // Capture basic error info\n const errorMessage =\n sdkError instanceof Error ? sdkError.message : String(sdkError);\n const errorStack = sdkError instanceof Error ? sdkError.stack : undefined;\n const errorName = sdkError instanceof Error ? sdkError.name : 'Unknown';\n\n console.error('[SDK-ERROR] Error name:', errorName);\n console.error('[SDK-ERROR] Error message:', errorMessage);\n\n if (errorStack) {\n console.error('[SDK-ERROR] Full stack trace:');\n console.error(errorStack);\n }\n\n // Extract ALL properties from the error object\n if (sdkError && typeof sdkError === 'object') {\n const errObj = sdkError as Record<string, unknown>;\n console.error('[SDK-ERROR] Error object properties:');\n\n // Log all enumerable properties\n for (const key of Object.keys(errObj)) {\n const value = errObj[key];\n if (value !== undefined && key !== 'stack') {\n try {\n const valueStr =\n typeof value === 'object'\n ? JSON.stringify(value, null, 2)\n : String(value);\n console.error(`[SDK-ERROR] ${key}:`, valueStr.substring(0, 1000));\n } catch {\n console.error(`[SDK-ERROR] ${key}: [cannot serialize]`);\n }\n }\n }\n\n // Specifically check for common SDK error properties\n const sdkErrorKeys = [\n 'code',\n 'status',\n 'statusCode',\n 'statusText',\n 'stderr',\n 'stdout',\n 'output',\n 'exitCode',\n 'signal',\n 'killed',\n 'cause',\n 'reason',\n 'details',\n 'response',\n 'request',\n 'config',\n 'errno',\n 'syscall',\n 'path',\n 'spawnargs'\n ];\n\n const extraInfo: Record<string, unknown> = {};\n for (const key of sdkErrorKeys) {\n if (key in errObj && errObj[key] !== undefined) {\n extraInfo[key] = errObj[key];\n }\n }\n\n if (Object.keys(extraInfo).length > 0) {\n console.error('[SDK-ERROR] SDK-specific error details:');\n console.error(JSON.stringify(extraInfo, null, 2));\n }\n\n // Check for nested cause\n if (errObj.cause && typeof errObj.cause === 'object') {\n console.error('[SDK-ERROR] Error cause:');\n try {\n console.error(JSON.stringify(errObj.cause, null, 2));\n } catch {\n console.error('[SDK-ERROR] Error cause: [cannot serialize]');\n }\n }\n }\n\n // Log execution context\n console.error('[SDK-ERROR] Execution context:');\n console.error('[SDK-ERROR] skillCount:', skills.length);\n console.error('[SDK-ERROR] skillNames:', skillNames);\n console.error('[SDK-ERROR] scenarioId:', scenario.id);\n console.error('[SDK-ERROR] scenarioName:', scenario.name);\n console.error('[SDK-ERROR] cwd:', options.cwd);\n console.error('[SDK-ERROR] model:', options.model || DEFAULT_MODEL);\n console.error('[SDK-ERROR] aiGatewayUrl:', options.aiGatewayUrl);\n console.error(\n '[SDK-ERROR] hasAiGatewayHeaders:',\n !!options.aiGatewayHeaders\n );\n\n // Log environment info that might be relevant\n console.error('[SDK-ERROR] Environment info:');\n console.error('[SDK-ERROR] NODE_ENV:', process.env.NODE_ENV);\n console.error('[SDK-ERROR] HOME:', process.env.HOME);\n console.error('[SDK-ERROR] USER:', process.env.USER);\n console.error('[SDK-ERROR] SHELL:', process.env.SHELL);\n\n console.error('[SDK-ERROR] ==========================================');\n\n // Re-throw with comprehensive context - include ALL debug info for backend visibility\n const errObj = sdkError as Record<string, unknown>;\n\n // Capture SDK-specific properties that are critical for debugging\n const sdkSpecificInfo: Record<string, unknown> = {};\n const sdkErrorKeys = [\n 'exitCode',\n 'stderr',\n 'stdout',\n 'signal',\n 'killed',\n 'code',\n 'status',\n 'errno',\n 'syscall',\n 'spawnargs'\n ];\n for (const key of sdkErrorKeys) {\n if (errObj && key in errObj && errObj[key] !== undefined) {\n // Truncate long strings to avoid huge error messages\n const val = errObj[key];\n if (typeof val === 'string' && val.length > 500) {\n sdkSpecificInfo[key] = val.substring(0, 500) + '... [truncated]';\n } else {\n sdkSpecificInfo[key] = val;\n }\n }\n }\n\n // Capture cause if present\n let causeInfo: string | undefined;\n if (errObj?.cause && typeof errObj.cause === 'object') {\n try {\n const causeStr = JSON.stringify(errObj.cause, null, 2);\n causeInfo =\n causeStr.length > 500\n ? causeStr.substring(0, 500) + '... [truncated]'\n : causeStr;\n } catch {\n causeInfo = '[cannot serialize cause]';\n }\n }\n\n // Capture SDK environment configuration for debugging\n const sdkEnvDebug = {\n ANTHROPIC_BASE_URL: sdkEnv.ANTHROPIC_BASE_URL,\n hasANTHROPIC_API_KEY: !!sdkEnv.ANTHROPIC_API_KEY,\n hasANTHROPIC_AUTH_TOKEN: !!sdkEnv.ANTHROPIC_AUTH_TOKEN,\n hasANTHROPIC_CUSTOM_HEADERS: !!sdkEnv.ANTHROPIC_CUSTOM_HEADERS,\n ANTHROPIC_CUSTOM_HEADERS_preview: sdkEnv.ANTHROPIC_CUSTOM_HEADERS\n ? sdkEnv.ANTHROPIC_CUSTOM_HEADERS.split('\\n')\n .map((h) => h.split(':')[0])\n .join(', ')\n : undefined\n };\n\n const errorDetails = {\n messageCount,\n errorName,\n errorMessage,\n skillCount: skills.length,\n skillNames,\n scenarioId: scenario.id,\n model: options.model || DEFAULT_MODEL,\n sdkEnv: sdkEnvDebug,\n sdkError:\n Object.keys(sdkSpecificInfo).length > 0 ? sdkSpecificInfo : undefined,\n cause: causeInfo\n };\n\n // Emit error trace event for visibility in the UI\n if (traceContext) {\n const errorTraceEvent = {\n evalRunId: traceContext.evalRunId,\n scenarioId: traceContext.scenarioId,\n scenarioName: traceContext.scenarioName,\n targetId: traceContext.targetId,\n targetName: traceContext.targetName,\n stepNumber: traceStepNumber + 1,\n type: LiveTraceEventType.DIAGNOSTIC,\n outputPreview: JSON.stringify(\n {\n event: 'sdk-execution-failed',\n error: errorMessage,\n errorName,\n messageCount,\n sdkEnv: sdkEnvDebug,\n sdkError: sdkSpecificInfo,\n cause: causeInfo\n },\n null,\n 2\n ).slice(0, 2000),\n timestamp: new Date().toISOString(),\n isComplete: true\n };\n emitTraceEvent(\n errorTraceEvent,\n traceContext.tracePushUrl,\n traceContext.routeHeader,\n traceContext.authToken\n );\n }\n\n throw new Error(\n `Claude SDK execution failed after ${messageCount} messages: ${errorMessage}` +\n `\\nDetails: ${JSON.stringify(errorDetails, null, 2)}` +\n (errorStack\n ? `\\nStack: ${errorStack.split('\\n').slice(0, 5).join('\\n')}`\n : '')\n );\n }\n\n // Emit completion trace event\n if (traceContext) {\n emitTraceEvent(\n {\n evalRunId: traceContext.evalRunId,\n scenarioId: traceContext.scenarioId,\n scenarioName: traceContext.scenarioName,\n targetId: traceContext.targetId,\n targetName: traceContext.targetName,\n stepNumber: traceStepNumber + 1,\n type: LiveTraceEventType.COMPLETION,\n outputPreview: 'Scenario execution completed',\n timestamp: new Date().toISOString(),\n isComplete: true\n },\n traceContext.tracePushUrl,\n traceContext.routeHeader,\n traceContext.authToken\n );\n }\n\n const endTime = new Date();\n const totalDurationMs = endTime.getTime() - startTime.getTime();\n\n // Process messages into steps for trace building\n const { steps, result: sdkResult } = processMessages(\n allMessages,\n startTime,\n endTime\n );\n\n // Extract final output, surfacing SDK errors if no output was produced\n const rawOutput = extractFinalOutput(allMessages);\n const isError = sdkResult?.subtype !== 'success';\n let outputText = rawOutput;\n if (!rawOutput && isError) {\n const hasErrors =\n sdkResult && 'errors' in sdkResult && sdkResult.errors?.length;\n const errorDetails = hasErrors\n ? (sdkResult.errors as string[]).join('; ')\n : (sdkResult?.subtype ?? 'unknown');\n outputText = `[ERROR] Agent execution failed: ${errorDetails}`;\n }\n const usage = extractTotalUsage(sdkResult);\n\n // Build LLM trace from captured steps\n const llmTrace = buildLLMTraceFromSteps(\n steps,\n totalDurationMs,\n usage,\n options.model || DEFAULT_MODEL\n );\n\n const conversation = buildConversation(allMessages);\n\n return {\n result: {\n outputText,\n durationMs: totalDurationMs,\n usage: {\n inputTokens: usage.inputTokens,\n outputTokens: usage.outputTokens,\n totalTokens: usage.totalTokens\n },\n costUsd: usage.costUsd\n },\n llmTrace,\n conversation\n };\n}\n\n/**\n * Build environment variables for the Claude Agent SDK.\n *\n * Starts with process.env to preserve PATH and other necessary variables,\n * then adds AI Gateway configuration:\n * - ANTHROPIC_BASE_URL: The gateway URL\n * - ANTHROPIC_CUSTOM_HEADERS: Headers in \"key:value\\nkey2:value2\" format\n *\n * @param options - Execution options containing gateway configuration\n * @returns Environment variables object for the SDK\n */\nfunction buildSdkEnvironment(\n options: ClaudeCodeExecutionOptions\n): Record<string, string | undefined> {\n // Start with process.env to preserve PATH and other necessary variables\n const env: Record<string, string | undefined> = { ...process.env };\n\n // The Claude Agent SDK requires ANTHROPIC_API_KEY in the environment.\n // We use a placeholder token because actual authentication is handled by the AI Gateway\n // via ANTHROPIC_BASE_URL and ANTHROPIC_CUSTOM_HEADERS.\n // The key format matches Anthropic's API key format (sk-ant-...) to pass any validation.\n // Note: Both ANTHROPIC_API_KEY and ANTHROPIC_AUTH_TOKEN are set for compatibility\n // with different SDK versions and internal validation.\n const placeholderApiKey =\n 'sk-ant-api03-placeholder-auth-handled-by-gateway-000000000000000000000000';\n env.ANTHROPIC_API_KEY = placeholderApiKey;\n env.ANTHROPIC_AUTH_TOKEN = placeholderApiKey;\n\n // Set the base URL for the Anthropic API (points to our AI Gateway)\n if (options.aiGatewayUrl) {\n env.ANTHROPIC_BASE_URL = `${options.aiGatewayUrl}/proxy/anthropic`;\n }\n\n // Format headers as \"key:value\\nkey2:value2\"\n // These headers contain the actual authentication for the AI Gateway\n if (options.aiGatewayHeaders) {\n const headerLines = Object.entries(options.aiGatewayHeaders)\n .map(([key, value]) => `${key}:${value}`)\n .join('\\n');\n env.ANTHROPIC_CUSTOM_HEADERS = headerLines;\n }\n\n return env;\n}\n\n/**\n * Type guard for assistant messages.\n */\nfunction isAssistantMessage(\n message: SDKMessage\n): message is SDKAssistantMessage {\n return message.type === 'assistant';\n}\n\n/**\n * Type guard for result messages.\n */\nfunction isResultMessage(message: SDKMessage): message is SDKResultMessage {\n return message.type === 'result';\n}\n\n/**\n * Process SDK messages into CapturedSteps for LLM trace building.\n * Uses actual timestamps from when messages were received to calculate durations.\n */\nfunction processMessages(\n timestampedMessages: TimestampedMessage[],\n startTime: Date,\n endTime: Date\n): {\n steps: CapturedStep[];\n result?: SDKResultMessage;\n} {\n const steps: CapturedStep[] = [];\n let result: SDKResultMessage | undefined;\n\n // Group assistant messages by UUID to combine streaming chunks\n // Track both the messages and their timestamps\n const assistantMessageGroups = new Map<\n string,\n {\n messages: SDKAssistantMessage[];\n firstReceivedAt: Date;\n lastReceivedAt: Date;\n }\n >();\n\n for (const { message, receivedAt } of timestampedMessages) {\n if (isAssistantMessage(message)) {\n const uuid = message.uuid;\n if (!assistantMessageGroups.has(uuid)) {\n assistantMessageGroups.set(uuid, {\n messages: [],\n firstReceivedAt: receivedAt,\n lastReceivedAt: receivedAt\n });\n }\n const group = assistantMessageGroups.get(uuid)!;\n group.messages.push(message);\n group.lastReceivedAt = receivedAt;\n } else if (isResultMessage(message)) {\n result = message;\n }\n }\n\n // Convert to array and sort by first received time to maintain order\n const sortedGroups = Array.from(assistantMessageGroups.values()).sort(\n (a, b) => a.firstReceivedAt.getTime() - b.firstReceivedAt.getTime()\n );\n\n // Merge consecutive UUID groups that share the same input_tokens into a\n // single \"API turn\". The SDK often emits separate messages (with different\n // UUIDs) for thinking, text, and tool_use within one API call \u2014 each\n // reporting the same cumulative input_tokens.\n type MergedTurn = {\n groups: typeof sortedGroups;\n firstReceivedAt: Date;\n lastReceivedAt: Date;\n };\n const mergedTurns: MergedTurn[] = [];\n for (const group of sortedGroups) {\n const lastMsg = group.messages[group.messages.length - 1];\n const inputTokens = lastMsg.message.usage.input_tokens;\n const prev = mergedTurns[mergedTurns.length - 1];\n const prevLastMsg = prev?.groups[prev.groups.length - 1].messages.at(-1);\n const prevInputTokens = prevLastMsg?.message.usage.input_tokens;\n\n if (prev && prevInputTokens === inputTokens) {\n prev.groups.push(group);\n prev.lastReceivedAt = group.lastReceivedAt;\n } else {\n mergedTurns.push({\n groups: [group],\n firstReceivedAt: group.firstReceivedAt,\n lastReceivedAt: group.lastReceivedAt\n });\n }\n }\n\n // Build a CapturedStep from each merged turn\n for (let i = 0; i < mergedTurns.length; i++) {\n const turn = mergedTurns[i];\n const stepStartTime = turn.firstReceivedAt;\n const nextStepStartTime =\n i < mergedTurns.length - 1 ? mergedTurns[i + 1].firstReceivedAt : endTime;\n const durationMs = nextStepStartTime.getTime() - stepStartTime.getTime();\n\n let text = '';\n let thinking = '';\n const toolCalls: Array<{\n toolName: string;\n toolUseId?: string;\n args: unknown;\n }> = [];\n let lastStopReason: string | null = null;\n let inputTokens = 0;\n let outputTokens = 0;\n let cacheReadTokens: number | undefined;\n let cacheWriteTokens: number | undefined;\n\n for (const group of turn.groups) {\n const lastMessage = group.messages[group.messages.length - 1];\n lastStopReason = lastMessage.message.stop_reason;\n\n // Use usage from the last group (they're identical within a turn)\n const msgUsage = lastMessage.message.usage;\n inputTokens = msgUsage.input_tokens;\n outputTokens = msgUsage.output_tokens;\n cacheReadTokens = msgUsage.cache_read_input_tokens ?? undefined;\n cacheWriteTokens = msgUsage.cache_creation_input_tokens ?? undefined;\n\n for (const block of lastMessage.message.content) {\n if (block.type === 'text') {\n text += block.text;\n } else if (block.type === 'thinking') {\n thinking += (block as { type: 'thinking'; thinking: string })\n .thinking;\n } else if (block.type === 'tool_use') {\n toolCalls.push({\n toolName: block.name,\n toolUseId: (block as { id?: string }).id,\n args: block.input\n });\n }\n }\n }\n\n steps.push({\n text,\n thinking: thinking || undefined,\n usage: {\n inputTokens,\n outputTokens,\n totalTokens: inputTokens + outputTokens,\n cacheReadTokens: cacheReadTokens || undefined,\n cacheWriteTokens: cacheWriteTokens || undefined\n },\n finishReason: mapStopReason(lastStopReason),\n toolCalls: toolCalls.length > 0 ? toolCalls : undefined,\n startedAt: stepStartTime,\n durationMs: Math.max(0, durationMs)\n });\n }\n\n // Correlate tool results from user messages to mark tool call errors.\n // Build a map of tool_use_id \u2192 error info from user messages.\n const toolResultErrors = new Map<string, string>();\n for (const { message } of timestampedMessages) {\n if (message.type !== 'user') continue;\n const content = (message as SDKUserMessage).message?.content;\n if (!Array.isArray(content)) continue;\n for (const block of content) {\n if (typeof block !== 'object' || block === null) continue;\n const b = block as unknown as Record<string, unknown>;\n if (\n b.type === 'tool_result' &&\n b.is_error === true &&\n typeof b.tool_use_id === 'string'\n ) {\n const errorContent =\n typeof b.content === 'string'\n ? b.content\n : Array.isArray(b.content)\n ? (b.content as Array<Record<string, unknown>>)\n .filter(\n (c) => c.type === 'text' && typeof c.text === 'string'\n )\n .map((c) => c.text as string)\n .join('\\n')\n : 'Tool call failed';\n toolResultErrors.set(b.tool_use_id, errorContent.slice(0, 500));\n }\n }\n }\n\n if (toolResultErrors.size > 0) {\n for (const step of steps) {\n if (!step.toolCalls) continue;\n for (const tc of step.toolCalls) {\n if (tc.toolUseId && toolResultErrors.has(tc.toolUseId)) {\n step.hasToolError = true;\n step.toolErrorContent = toolResultErrors.get(tc.toolUseId);\n break;\n }\n }\n }\n }\n\n return { steps, result };\n}\n\n/**\n * Map Anthropic stop reason to standard finish reason.\n */\nfunction mapStopReason(stopReason: string | null): string {\n switch (stopReason) {\n case 'end_turn':\n case 'stop_sequence':\n return 'stop';\n case 'tool_use':\n return 'tool-calls';\n case 'max_tokens':\n return 'length';\n default:\n return 'unknown';\n }\n}\n\n/**\n * Extract final output text from messages.\n */\nfunction extractFinalOutput(timestampedMessages: TimestampedMessage[]): string {\n // Find the last assistant message with text content\n for (let i = timestampedMessages.length - 1; i >= 0; i--) {\n const { message } = timestampedMessages[i];\n if (isAssistantMessage(message)) {\n for (const block of message.message.content) {\n if (block.type === 'text' && block.text) {\n return block.text;\n }\n }\n }\n }\n return '';\n}\n\n/**\n * Extract total usage from result message.\n */\nfunction extractTotalUsage(result: SDKResultMessage | undefined): {\n inputTokens: number;\n outputTokens: number;\n totalTokens: number;\n costUsd?: number;\n cacheReadTokens?: number;\n cacheWriteTokens?: number;\n durationApiMs?: number;\n} {\n if (!result) {\n return { inputTokens: 0, outputTokens: 0, totalTokens: 0 };\n }\n\n const usage = result.usage;\n return {\n inputTokens: usage.input_tokens,\n outputTokens: usage.output_tokens,\n totalTokens: usage.input_tokens + usage.output_tokens,\n costUsd: result.total_cost_usd,\n cacheReadTokens: usage.cache_read_input_tokens || undefined,\n cacheWriteTokens: usage.cache_creation_input_tokens || undefined,\n durationApiMs: result.duration_api_ms || undefined\n };\n}\n\n/**\n * Build LLM trace from captured steps.\n * Calculates per-step costs using model pricing and sums tokens from steps as fallback.\n */\nfunction buildLLMTraceFromSteps(\n steps: CapturedStep[],\n totalDurationMs: number,\n usage: {\n inputTokens: number;\n outputTokens: number;\n totalTokens: number;\n costUsd?: number;\n cacheReadTokens?: number;\n cacheWriteTokens?: number;\n durationApiMs?: number;\n },\n model: string\n): LLMTrace {\n const totalCost = usage.costUsd ?? 0;\n\n // Use \"effective\" input tokens (input + cache_read + cache_write) for\n // proportion calculations. The Anthropic API reports `input_tokens`\n // excluding cached tokens, so later turns with heavy caching can report\n // near-zero input_tokens while cache_read_input_tokens is large.\n // Using only input_tokens would starve cached turns of their fair share.\n const effectiveInput = (s: CapturedStep) =>\n s.usage.inputTokens +\n (s.usage.cacheReadTokens ?? 0) +\n (s.usage.cacheWriteTokens ?? 0);\n\n // The SDK may send multiple SDKAssistantMessages per API turn (thinking,\n // text, tool_use) each with a different UUID but reporting the SAME\n // cumulative input_tokens for that turn. Detect this by comparing the\n // per-step input sum against the result's authoritative total.\n // When duplicated, fall back to distributing by duration proportion.\n const totalStepEffectiveInput = steps.reduce(\n (sum, s) => sum + effectiveInput(s),\n 0\n );\n const totalStepDuration = steps.reduce((sum, s) => sum + s.durationMs, 0);\n const authoritativeEffectiveInput =\n usage.inputTokens +\n (usage.cacheReadTokens ?? 0) +\n (usage.cacheWriteTokens ?? 0);\n // 1.2x threshold: when per-step input tokens sum to >120% of the authoritative\n // total, the SDK duplicated cumulative counts across split messages within a\n // single API turn. The 20% buffer accounts for minor rounding differences.\n const inputTokensDuplicated =\n authoritativeEffectiveInput > 0 &&\n totalStepEffectiveInput > authoritativeEffectiveInput * 1.2;\n\n const traceSteps = steps\n .flatMap((step, turnIndex) => {\n let stepPromptTokens: number;\n let stepOutputTokens: number;\n let proportion: number;\n\n if (inputTokensDuplicated) {\n proportion =\n totalStepDuration > 0 ? step.durationMs / totalStepDuration : 0;\n stepPromptTokens = Math.round(usage.inputTokens * proportion);\n stepOutputTokens = Math.round(usage.outputTokens * proportion);\n } else {\n const stepEffective = effectiveInput(step);\n proportion =\n totalStepEffectiveInput > 0\n ? stepEffective / totalStepEffectiveInput\n : 0;\n stepPromptTokens = Math.round(usage.inputTokens * proportion);\n stepOutputTokens = Math.round(usage.outputTokens * proportion);\n }\n\n const costProportion = proportion;\n const toolCallCount = step.toolCalls?.length ?? 0;\n const isSuccess = step.finishReason !== 'error' && !step.hasToolError;\n const errorMsg = step.hasToolError\n ? (step.toolErrorContent ?? 'Tool call failed')\n : step.finishReason === 'error'\n ? 'Generation failed'\n : undefined;\n\n // Build a list of sub-steps for this turn. When the SDK merges\n // thinking, text, and tool_use into a single turn we split them\n // into separate trace steps for full visibility.\n const subSteps: Array<{\n id: string;\n stepNumber: number;\n turnIndex: number;\n type: LLMStepType;\n model: string;\n provider: string;\n startedAt: string;\n durationMs: number;\n tokenUsage: { prompt: number; completion: number; total: number };\n costUsd: number;\n toolName?: string;\n toolArguments?: string;\n outputPreview?: string;\n success: boolean;\n error?: string;\n }> = [];\n\n const stepCost = totalCost * costProportion;\n const hasThinking = !!step.thinking;\n const hasText = !!step.text;\n // Count how many sub-steps we'll produce so we can distribute tokens\n const thinkingSubSteps = hasThinking ? 1 : 0;\n const toolSubSteps = toolCallCount > 0 ? toolCallCount : 0;\n const textSubSteps = hasText && toolCallCount > 0 ? 1 : 0; // text step only when tools also present\n const totalSubSteps = thinkingSubSteps + toolSubSteps + textSubSteps || 1;\n\n // Emit a THINKING sub-step when thinking co-exists with text or tools\n if (hasThinking && (hasText || toolCallCount > 0)) {\n subSteps.push({\n id: randomUUID(),\n stepNumber: 0, // renumbered below\n turnIndex,\n type: LLMStepType.THINKING,\n model,\n provider: 'anthropic',\n startedAt: step.startedAt.toISOString(),\n durationMs: Math.round(step.durationMs / totalSubSteps),\n tokenUsage: {\n prompt: Math.round(stepPromptTokens / totalSubSteps),\n completion: Math.round(stepOutputTokens / totalSubSteps),\n total: Math.round(\n (stepPromptTokens + stepOutputTokens) / totalSubSteps\n )\n },\n costUsd: stepCost / totalSubSteps,\n outputPreview: step.thinking?.slice(0, 200),\n success: isSuccess,\n error: errorMsg\n });\n }\n\n // Emit TOOL_USE sub-steps \u2014 one per tool call\n if (toolCallCount > 0) {\n for (let tcIdx = 0; tcIdx < toolCallCount; tcIdx++) {\n const tc = step.toolCalls![tcIdx];\n const isLast = tcIdx === toolCallCount - 1 && textSubSteps === 0;\n // Remaining budget after thinking step\n const toolBudgetSteps = toolSubSteps + textSubSteps;\n const toolFraction = toolBudgetSteps > 0 ? 1 / toolBudgetSteps : 1;\n const remainingFraction =\n (totalSubSteps - thinkingSubSteps) / totalSubSteps;\n\n subSteps.push({\n id: randomUUID(),\n stepNumber: 0,\n turnIndex,\n type: LLMStepType.TOOL_USE,\n model,\n provider: 'anthropic',\n startedAt: step.startedAt.toISOString(),\n durationMs: isLast\n ? step.durationMs -\n subSteps.reduce((s, ss) => s + ss.durationMs, 0)\n : Math.round(step.durationMs * remainingFraction * toolFraction),\n tokenUsage: {\n prompt: Math.round(\n stepPromptTokens * remainingFraction * toolFraction\n ),\n completion: Math.round(\n stepOutputTokens * remainingFraction * toolFraction\n ),\n total: Math.round(\n (stepPromptTokens + stepOutputTokens) *\n remainingFraction *\n toolFraction\n )\n },\n costUsd: stepCost * remainingFraction * toolFraction,\n toolName: tc.toolName,\n toolArguments: JSON.stringify(tc.args),\n outputPreview:\n tcIdx === 0 && !hasText\n ? (step.text || step.thinking)?.slice(0, 200)\n : undefined,\n success: isSuccess,\n error: errorMsg\n });\n }\n }\n\n // Emit a COMPLETION sub-step for text when tools were also present\n // (otherwise the text output would be lost)\n if (hasText && toolCallCount > 0) {\n subSteps.push({\n id: randomUUID(),\n stepNumber: 0,\n turnIndex,\n type: LLMStepType.COMPLETION,\n model,\n provider: 'anthropic',\n startedAt: step.startedAt.toISOString(),\n durationMs:\n step.durationMs - subSteps.reduce((s, ss) => s + ss.durationMs, 0),\n tokenUsage: {\n prompt:\n stepPromptTokens -\n subSteps.reduce((s, ss) => s + ss.tokenUsage.prompt, 0),\n completion:\n stepOutputTokens -\n subSteps.reduce((s, ss) => s + ss.tokenUsage.completion, 0),\n total:\n stepPromptTokens +\n stepOutputTokens -\n subSteps.reduce((s, ss) => s + ss.tokenUsage.total, 0)\n },\n costUsd: stepCost - subSteps.reduce((s, ss) => s + ss.costUsd, 0),\n outputPreview: step.text?.slice(0, 200),\n success: isSuccess,\n error: errorMsg\n });\n }\n\n // Fallback: if no sub-steps were produced (pure text or pure thinking),\n // emit a single step as before.\n if (subSteps.length === 0) {\n const stepType =\n hasThinking && !hasText\n ? LLMStepType.THINKING\n : LLMStepType.COMPLETION;\n subSteps.push({\n id: randomUUID(),\n stepNumber: 0,\n turnIndex,\n type: stepType,\n model,\n provider: 'anthropic',\n startedAt: step.startedAt.toISOString(),\n durationMs: step.durationMs,\n tokenUsage: {\n prompt: stepPromptTokens,\n completion: stepOutputTokens,\n total: stepPromptTokens + stepOutputTokens\n },\n costUsd: stepCost,\n outputPreview: (step.text || step.thinking)?.slice(0, 200),\n success: isSuccess,\n error: errorMsg\n });\n }\n\n return subSteps;\n })\n .map((s, i) => ({ ...s, stepNumber: i + 1 }));\n\n const finalTokens = {\n prompt: usage.inputTokens,\n completion: usage.outputTokens,\n total: usage.totalTokens\n };\n\n // Build stepTypeBreakdown by grouping trace steps by type\n const stepTypeBreakdown: Record<\n string,\n { count: number; durationMs: number; tokens: number; costUsd: number }\n > = {};\n for (const ts of traceSteps) {\n const entry = stepTypeBreakdown[ts.type] ?? {\n count: 0,\n durationMs: 0,\n tokens: 0,\n costUsd: 0\n };\n entry.count += 1;\n entry.durationMs += ts.durationMs;\n entry.tokens += ts.tokenUsage.total;\n entry.costUsd += ts.costUsd;\n stepTypeBreakdown[ts.type] = entry;\n }\n\n const summary = {\n totalSteps: traceSteps.length,\n totalTurns: steps.length,\n totalDurationMs,\n totalTokens: finalTokens,\n totalCostUsd: totalCost,\n modelBreakdown: {\n [model]: {\n count: traceSteps.length,\n durationMs: totalDurationMs,\n tokens: finalTokens.total,\n costUsd: totalCost\n }\n },\n modelsUsed: [model],\n stepTypeBreakdown\n };\n\n return {\n id: randomUUID(),\n steps: traceSteps,\n summary\n };\n}\n", "import { mkdir } from 'fs/promises';\nimport { join } from 'path';\nimport type {\n GitHubSource,\n SkillFile,\n SkillWithLatestVersion\n} from '@wix/evalforge-types';\nimport { fetchGitHubFolder } from '@wix/evalforge-github-client';\nimport { writeFilesToDirectory } from '../../utils/write-files.js';\n\nexport type FetchGitHubFolderFn = (\n source: GitHubSource,\n options?: { userAgent?: string }\n) => Promise<SkillFile[]>;\n\n/**\n * Write all skills to the filesystem so Claude Agent SDK can discover them.\n *\n * Content resolution:\n * 1. Pinned (version has `files`): writes all files from the stored snapshot\n * 2. Live (skill has `source`, no pinned files): fetches from GitHub at runtime\n *\n * @param cwd - Working directory where .claude/skills/ will be created\n * @param skills - All skills to write\n * @param fetchFn - Function to fetch files from GitHub (defaults to fetchGitHubFolder)\n */\nexport async function writeSkillsToFilesystem(\n cwd: string,\n skills: SkillWithLatestVersion[],\n fetchFn: FetchGitHubFolderFn = fetchGitHubFolder\n): Promise<void> {\n await Promise.all(\n skills.map((skill) => writeSkillToFilesystem(cwd, skill, fetchFn))\n );\n}\n\nexport async function writeSkillToFilesystem(\n cwd: string,\n skill: SkillWithLatestVersion,\n fetchFn: FetchGitHubFolderFn = fetchGitHubFolder\n): Promise<void> {\n const skillName = skill.name;\n const skillDir = join(cwd, '.claude', 'skills', skillName);\n await mkdir(skillDir, { recursive: true });\n\n const version = skill.latestVersion;\n\n if (version?.files && version.files.length > 0) {\n await writeFilesToDirectory(skillDir, version.files);\n console.log(\n `[Skill] ${skillName}: wrote ${version.files.length} file(s) from snapshot`\n );\n } else if (skill.source) {\n try {\n const files = await fetchFn(skill.source, {\n userAgent: 'EvalForge-Evaluator'\n });\n await writeFilesToDirectory(skillDir, files);\n console.log(\n `[Skill] ${skillName}: wrote ${files.length} file(s) from GitHub (live)`\n );\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n console.error(\n `[Skill] ${skillName}: GitHub fetch failed: ${message}, no files to fall back to`\n );\n throw new Error(\n `Failed to write skill ${skillName} to filesystem: ${message}`\n );\n }\n } else {\n throw new Error(`Skill ${skillName} has no files and no source configured`);\n }\n}\n\n/**\n * Write skill files from a snapshot array to the filesystem.\n * @deprecated Use writeFilesToDirectory from utils/write-files.ts instead\n */\nexport const writeSkillFiles = writeFilesToDirectory;\n", "import { writeFile } from 'fs/promises';\nimport { join } from 'path';\nimport type { MCPEntity } from '@wix/evalforge-types';\nimport { MCP_SERVERS_JSON_KEY } from '@wix/evalforge-types';\nimport { resolveMcpPlaceholders } from '../shared/resolve-mcp-placeholders.js';\n\n/**\n * Write .mcp.json at the project root (cwd) for Claude Code to discover MCPs.\n *\n * The config field already contains the keyed `.mcp.json` entry\n * (e.g. `{ \"wix-mcp\": { \"type\": \"http\", ... } }`), so each MCP's config\n * is spread directly into the mcpServers object.\n *\n * Any `{{placeholder}}` values in the config are resolved before writing\n * (e.g. `{{wix-auth-token}}` \u2192 token from ~/.wix/auth/api-key.json).\n *\n * @see https://code.claude.com/docs/en/mcp#mcp-installation-scopes\n * @param cwd - Working directory (project root for Claude Code)\n * @param mcps - MCP entities whose config is merged into mcpServers\n */\nexport async function writeMcpToFilesystem(\n cwd: string,\n mcps: MCPEntity[]\n): Promise<void> {\n if (mcps.length === 0) return;\n\n const mcpServers: Record<string, Record<string, unknown>> = {};\n for (const mcp of mcps) {\n const config = mcp.config as Record<string, unknown>;\n for (const [key, value] of Object.entries(config)) {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n throw new Error(\n `MCP \"${mcp.name}\" has invalid config: value for key \"${key}\" must be an object (got ${typeof value}). ` +\n 'Config must use keyed format, e.g. { \"server-name\": { \"command\": \"npx\", ... } }'\n );\n }\n mcpServers[key] = value as Record<string, unknown>;\n }\n }\n\n const resolvedServers = await resolveMcpPlaceholders(mcpServers, { cwd });\n\n const content = JSON.stringify(\n { [MCP_SERVERS_JSON_KEY]: resolvedServers },\n null,\n 2\n );\n const filePath = join(cwd, '.mcp.json');\n await writeFile(filePath, content, 'utf8');\n\n console.log(`[MCP] Written to ${filePath}`);\n}\n", "/**\n * MCP Config Placeholder Resolution\n *\n * Resolves `{{placeholder}}` patterns in MCP config values at eval startup.\n *\n * Supported placeholders:\n * - {{wix-auth-token}} \u2192 token from ~/.wix/auth/api-key.json\n * - {{wix-auth-user-id}} \u2192 userInfo.userId from api-key.json\n * - {{cwd}} \u2192 environment folder (working directory)\n */\n\nimport { readFile } from 'fs/promises';\nimport { join } from 'path';\nimport { homedir } from 'os';\nimport {\n findPlaceholders,\n resolveValue\n} from '../../../resolve-placeholders.js';\n\nexport { findPlaceholders, resolveValue };\n\nconst WIX_AUTH_FILE = join(homedir(), '.wix', 'auth', 'api-key.json');\n\ninterface WixApiKeyAuth {\n token: string;\n accountId: string;\n userInfo: {\n userId: string;\n email: string;\n };\n}\n\nexport interface ResolveMcpPlaceholdersOptions {\n cwd?: string;\n authFilePath?: string;\n}\n\n/**\n * Read Wix auth placeholders from ~/.wix/auth/api-key.json.\n * Returns an empty map when the file is missing or malformed.\n *\n * @param authFilePath - Override for testing (default: ~/.wix/auth/api-key.json)\n */\nexport async function loadWixAuthPlaceholders(\n authFilePath = WIX_AUTH_FILE\n): Promise<Record<string, string>> {\n try {\n const content = await readFile(authFilePath, 'utf-8');\n const auth = JSON.parse(content) as WixApiKeyAuth;\n\n if (!auth.token || !auth.userInfo?.userId) {\n return {};\n }\n\n return {\n 'wix-auth-token': auth.token,\n 'wix-auth-user-id': auth.userInfo.userId\n };\n } catch (err) {\n console.warn(\n `[MCP] Could not load Wix auth file: ${(err as Error).message}`\n );\n return {};\n }\n}\n\n/**\n * Resolve all `{{...}}` placeholders in an MCP server config map.\n *\n * Loads available placeholder values (Wix auth file + cwd),\n * scans the config for placeholders, and fails if any are unresolvable.\n *\n * @param mcpServers - The mcpServers map (server-name \u2192 config)\n * @param options - Optional cwd and authFilePath overrides\n * @throws When a config references placeholders that cannot be resolved\n */\nexport async function resolveMcpPlaceholders(\n mcpServers: Record<string, Record<string, unknown>>,\n options: ResolveMcpPlaceholdersOptions = {}\n): Promise<Record<string, Record<string, unknown>>> {\n const needed = findPlaceholders(mcpServers);\n if (needed.length === 0) {\n return mcpServers;\n }\n\n const placeholders: Record<string, string> = {\n ...(await loadWixAuthPlaceholders(options.authFilePath)),\n ...(options.cwd ? { cwd: options.cwd } : {})\n };\n\n const unresolved = needed.filter((key) => !(key in placeholders));\n if (unresolved.length > 0) {\n throw new Error(\n `MCP config contains unresolvable placeholders: ${unresolved.map((k) => `{{${k}}}`).join(', ')}. ` +\n 'Ensure ~/.wix/auth/api-key.json exists (run `npx @wix/cli login`).'\n );\n }\n\n console.log(`[MCP] Resolved ${needed.length} placeholder(s)`);\n\n return resolveValue(mcpServers, placeholders) as Record<\n string,\n Record<string, unknown>\n >;\n}\n", "import { mkdir, writeFile } from 'fs/promises';\nimport { join } from 'path';\nimport type { SubAgent, GitHubSource } from '@wix/evalforge-types';\nimport {\n fetchGitHubFile,\n type FetchGitHubFolderOptions\n} from '@wix/evalforge-github-client';\n\n/** Signature for the single-file GitHub fetch function (injectable for tests). */\nexport type FetchGitHubFileFn = (\n source: GitHubSource,\n options?: FetchGitHubFolderOptions\n) => Promise<string>;\n\n/** Directory where Claude Code discovers project sub-agents */\nconst AGENTS_DIR = '.claude/agents';\n\n/**\n * Build a unique, sanitized filename for a sub-agent.\n *\n * Sanitizes to lowercase alphanumeric + hyphens, falls back to\n * \"sub-agent-{index}\" for empty names, and appends a numeric suffix\n * (-2, -3, ...) when a name has already been used.\n */\nfunction toAgentFilename(\n name: string,\n index: number,\n nameCount: Map<string, number>\n): string {\n const base =\n (name || '')\n .toLowerCase()\n .replace(/\\s+/g, '-')\n .replace(/[^a-z0-9-]/g, '')\n .replace(/^-+|-+$/g, '') || `sub-agent-${index}`;\n\n const count = nameCount.get(base) ?? 0;\n nameCount.set(base, count + 1);\n\n return count === 0 ? base : `${base}-${count + 1}`;\n}\n\n/**\n * Resolve the markdown content for a sub-agent.\n * If a GitHub source is configured, live-fetches the latest .md file.\n * Throws if the fetch fails (consistent with skill content resolution).\n * Otherwise falls back to the inline subAgentMd content.\n */\nasync function resolveSubAgentContent(\n agent: SubAgent,\n fetchFn: FetchGitHubFileFn\n): Promise<string> {\n if (agent.source) {\n try {\n const content = await fetchFn(agent.source, {\n userAgent: 'EvalForge-Evaluator'\n });\n console.log(\n `[SubAgents] Fetched \"${agent.name}\" from ${agent.source.owner}/${agent.source.repo}/${agent.source.path}@${agent.source.ref}`\n );\n return content;\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n console.error(\n `[SubAgents] \"${agent.name}\": GitHub fetch failed: ${message}`\n );\n throw new Error(\n `Failed to fetch sub-agent \"${agent.name}\" from GitHub: ${message}`\n );\n }\n }\n if (!agent.subAgentMd) {\n console.warn(\n `[SubAgents] \"${agent.name}\" has empty inline content \u2013 the agent file will be blank`\n );\n }\n return agent.subAgentMd;\n}\n\n/**\n * Write sub-agent markdown files to .claude/agents/ for Claude Code to discover.\n *\n * For sub-agents with a GitHub source, the latest .md file is live-fetched.\n * For inline sub-agents, the stored subAgentMd is used directly.\n *\n * @see https://code.claude.com/docs/en/sub-agents#write-subagent-files\n * @param cwd - Working directory (project root for Claude Code)\n * @param subAgents - Sub-agent entities to write\n * @param fetchFn - Optional fetch function for testing (defaults to fetchGitHubFile)\n */\nexport async function writeSubAgentsToFilesystem(\n cwd: string,\n subAgents: SubAgent[],\n fetchFn: FetchGitHubFileFn = fetchGitHubFile\n): Promise<void> {\n if (subAgents.length === 0) return;\n\n const agentsDir = join(cwd, AGENTS_DIR);\n await mkdir(agentsDir, { recursive: true });\n\n const nameCount = new Map<string, number>();\n\n for (const [i, agent] of subAgents.entries()) {\n const filename = toAgentFilename(agent.name, i, nameCount);\n const filePath = join(agentsDir, `${filename}.md`);\n const content = await resolveSubAgentContent(agent, fetchFn);\n await writeFile(filePath, content, 'utf8');\n }\n\n console.log(`[SubAgents] Written to ${agentsDir}`);\n}\n", "import { mkdir, writeFile, readFile } from 'fs/promises';\nimport { join } from 'path';\nimport type { Rule } from '@wix/evalforge-types';\n\nconst CURSOR_RULES_DIR = '.cursor/rules';\n\n/**\n * Build a sanitized filename from a rule name.\n *\n * Sanitizes to lowercase alphanumeric + hyphens, falls back to\n * \"rule-{index}\" for empty names, and appends a numeric suffix\n * (-2, -3, ...) when a name has already been used.\n */\nfunction toRuleFilename(\n name: string,\n index: number,\n nameCount: Map<string, number>\n): string {\n const base =\n (name || '')\n .toLowerCase()\n .replace(/\\s+/g, '-')\n .replace(/[^a-z0-9-]/g, '')\n .replace(/^-+|-+$/g, '') || `rule-${index}`;\n\n const count = nameCount.get(base) ?? 0;\n nameCount.set(base, count + 1);\n\n return count === 0 ? base : `${base}-${count + 1}`;\n}\n\n/**\n * Safely append content to a file, creating it if it doesn't exist.\n * Separates appended blocks with double newlines.\n */\nasync function appendToFile(filePath: string, content: string): Promise<void> {\n let existing = '';\n try {\n existing = await readFile(filePath, 'utf8');\n } catch {\n // File doesn't exist yet\n }\n\n const merged = existing ? `${existing.trimEnd()}\\n\\n${content}` : content;\n\n await writeFile(filePath, merged, 'utf8');\n}\n\n/**\n * Write rule content to the filesystem based on each rule's `ruleType`.\n *\n * Placement:\n * - `claude-md` -> `{cwd}/CLAUDE.md` (appends if multiple)\n * - `agents-md` -> `{cwd}/AGENTS.md` (appends if multiple)\n * - `cursor-rule` -> `{cwd}/.cursor/rules/{name}.md` (one file per rule)\n *\n * @param cwd - Working directory (project root for Claude Code)\n * @param rules - Rule entities to write\n */\nexport async function writeRulesToFilesystem(\n cwd: string,\n rules: Rule[]\n): Promise<void> {\n if (rules.length === 0) return;\n\n const nameCount = new Map<string, number>();\n let hasCursorRules = false;\n\n for (const [i, rule] of rules.entries()) {\n switch (rule.ruleType) {\n case 'claude-md': {\n await appendToFile(join(cwd, 'CLAUDE.md'), rule.content);\n break;\n }\n case 'agents-md': {\n await appendToFile(join(cwd, 'AGENTS.md'), rule.content);\n break;\n }\n case 'cursor-rule': {\n if (!hasCursorRules) {\n await mkdir(join(cwd, CURSOR_RULES_DIR), { recursive: true });\n hasCursorRules = true;\n }\n const filename = toRuleFilename(rule.name, i, nameCount);\n const filePath = join(cwd, CURSOR_RULES_DIR, `${filename}.md`);\n await writeFile(filePath, rule.content, 'utf8');\n break;\n }\n }\n }\n\n console.log(`[Rules] Written ${rules.length} rule(s) to ${cwd}`);\n}\n", "import type { ConversationMessage } from '@wix/evalforge-types';\nimport type { TimestampedMessage } from './execute.js';\nimport type {\n SDKAssistantMessage,\n SDKUserMessage,\n SDKSystemMessage,\n SDKMessage\n} from '@anthropic-ai/claude-agent-sdk' with { 'resolution-mode': 'import' };\n\nfunction isAssistantMessage(\n message: SDKMessage\n): message is SDKAssistantMessage {\n return message.type === 'assistant';\n}\n\n/**\n * Build a full conversation from raw SDK messages.\n * Extracts text, thinking, tool_use, and tool_result blocks into a\n * serializable ConversationMessage array for storage and later display.\n */\nexport function buildConversation(\n timestampedMessages: TimestampedMessage[]\n): ConversationMessage[] {\n const messages: ConversationMessage[] = [];\n\n for (const { message, receivedAt } of timestampedMessages) {\n const timestamp = receivedAt.toISOString();\n\n if (isAssistantMessage(message)) {\n const content: ConversationMessage['content'] = [];\n for (const block of message.message.content) {\n if (block.type === 'text') {\n content.push({ type: 'text', text: block.text });\n } else if (block.type === 'thinking') {\n content.push({\n type: 'thinking',\n thinking: (block as { type: 'thinking'; thinking: string }).thinking\n });\n } else if (block.type === 'tool_use') {\n content.push({\n type: 'tool_use',\n toolName: block.name,\n toolId: block.id,\n input: block.input\n });\n }\n }\n if (content.length > 0) {\n messages.push({ role: 'assistant', content, timestamp });\n }\n } else if (message.type === 'user') {\n const userMsg = message as SDKUserMessage;\n const content: ConversationMessage['content'] = [];\n const msgContent = userMsg.message?.content;\n\n if (typeof msgContent === 'string') {\n content.push({ type: 'text', text: msgContent });\n } else if (Array.isArray(msgContent)) {\n for (const block of msgContent) {\n if (typeof block === 'object' && block !== null) {\n const b = block as unknown as Record<string, unknown>;\n if (b.type === 'tool_result') {\n const rawContent = b.content;\n let text = '';\n if (typeof rawContent === 'string') {\n text = rawContent;\n } else if (Array.isArray(rawContent)) {\n text = rawContent\n .filter(\n (c: unknown) =>\n typeof c === 'object' &&\n c !== null &&\n (c as Record<string, unknown>).type === 'text'\n )\n .map((c: unknown) => (c as { text: string }).text)\n .join('\\n');\n }\n content.push({\n type: 'tool_result',\n toolUseId: String(b.tool_use_id ?? ''),\n content: text,\n isError: b.is_error === true ? true : undefined\n });\n } else if (b.type === 'text' && typeof b.text === 'string') {\n content.push({ type: 'text', text: b.text });\n }\n }\n }\n }\n\n if (content.length > 0) {\n messages.push({ role: 'user', content, timestamp });\n }\n } else if (message.type === 'system') {\n const sysMsg = message as SDKSystemMessage;\n messages.push({\n role: 'system',\n content: [{ type: 'text', text: sysMsg.subtype || 'system' }],\n timestamp\n });\n }\n }\n\n return messages;\n}\n", "import type { LiveTraceEvent } from '@wix/evalforge-types';\nimport { TRACE_EVENT_PREFIX } from '@wix/evalforge-types';\n\n/**\n * Push a trace event to the backend via HTTP POST.\n * Used for remote job execution where stdout is not accessible.\n */\nasync function pushTraceEvent(\n url: string,\n event: LiveTraceEvent,\n routeHeader?: string,\n authToken?: string\n): Promise<void> {\n try {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json'\n };\n\n if (authToken) {\n headers['Authorization'] = `Bearer ${authToken}`;\n }\n\n if (routeHeader) {\n headers['x-wix-route'] = routeHeader;\n }\n\n const response = await fetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify(event)\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n console.error(\n `[Trace Push] HTTP ${response.status}: ${errorText.slice(0, 200)}`\n );\n }\n } catch (err) {\n console.error('[Trace Push] Network error:', err);\n }\n}\n\n/**\n * Emit a live trace event to stdout for the backend to capture.\n * Also pushes to HTTP endpoint if tracePushUrl is provided (for remote job execution).\n */\nexport function emitTraceEvent(\n event: LiveTraceEvent,\n tracePushUrl?: string,\n routeHeader?: string,\n authToken?: string\n): void {\n console.log(`${TRACE_EVENT_PREFIX}${JSON.stringify(event)}`);\n\n if (tracePushUrl) {\n pushTraceEvent(tracePushUrl, event, routeHeader, authToken).catch((err) => {\n console.error('[Trace Push] Failed to push trace event:', err);\n });\n }\n}\n", "/**\n * Claude Code agent adapter module.\n *\n * This module provides the Claude Code implementation of the AgentAdapter\n * interface. It wraps the @anthropic-ai/claude-agent-sdk to execute skills\n * with full LLM trace support.\n *\n * The adapter is automatically registered with the default registry when\n * this module is imported.\n */\n\n// Export the adapter class and singleton instance\nexport { ClaudeCodeAdapter, claudeCodeAdapter } from './claude-code-adapter.js';\n\n// Export the execution function for direct use if needed\nexport { executeWithClaudeCode } from './execute.js';\nexport { buildConversation } from './build-conversation.js';\n\n// Export Claude-specific types\nexport type {\n ClaudeCodeExecutionOptions,\n ClaudeCodeExecutionResult\n} from './types.js';\n\n// Re-export TraceContext from the shared types\nexport type { TraceContext } from '@wix/evalforge-types';\n\n// Register the adapter with the default registry\nimport { defaultRegistry } from '../registry.js';\nimport { claudeCodeAdapter } from './claude-code-adapter.js';\n\ndefaultRegistry.register(claudeCodeAdapter);\n", "import type {\n AgentAdapter,\n AgentExecutionContext,\n AgentExecutionResult\n} from '@wix/evalforge-types';\nimport { AgentRunCommand } from '@wix/evalforge-types';\nimport { executeWithOpenCode, prepareOpenCodeEnvironment } from './execute.js';\nimport type { OpenCodeExecutionOptions } from './types.js';\n\n/**\n * OpenCode agent adapter.\n *\n * Implements the AgentAdapter interface by spawning the `opencode` CLI\n * and parsing NDJSON events from stdout.\n *\n * Supported commands: 'opencode'\n */\nexport class OpenCodeAdapter implements AgentAdapter {\n readonly id = 'opencode';\n readonly name = 'OpenCode';\n readonly supportedCommands = [AgentRunCommand.OPENCODE] as const;\n\n async prepareEnvironment(context: AgentExecutionContext): Promise<void> {\n await prepareOpenCodeEnvironment(context.cwd, context.skills, {\n mcps: context.mcps,\n subAgents: context.subAgents,\n rules: context.rules\n });\n }\n\n async execute(context: AgentExecutionContext): Promise<AgentExecutionResult> {\n const {\n skills,\n scenario,\n cwd,\n modelConfig,\n aiGatewayUrl,\n aiGatewayHeaders,\n traceContext,\n mcps,\n subAgents,\n rules,\n systemPrompt\n } = context;\n\n const options: OpenCodeExecutionOptions = {\n cwd,\n model: modelConfig?.model,\n temperature: modelConfig?.temperature,\n maxTurns: modelConfig?.maxTurns,\n aiGatewayUrl,\n aiGatewayHeaders,\n traceContext,\n mcps,\n subAgents,\n rules,\n systemPrompt\n };\n\n const { result, llmTrace, conversation } = await executeWithOpenCode(\n skills,\n scenario,\n options\n );\n\n return {\n outputText: result.outputText,\n durationMs: result.durationMs,\n usage: {\n inputTokens: result.usage.inputTokens,\n outputTokens: result.usage.outputTokens,\n totalTokens: result.usage.totalTokens\n },\n costUsd: result.costUsd,\n llmTrace,\n conversation\n };\n }\n}\n\nexport const openCodeAdapter = new OpenCodeAdapter();\n", "import { spawn, type ChildProcess } from 'child_process';\nimport type {\n SkillWithLatestVersion,\n TestScenario,\n LLMTrace,\n LiveTraceEvent,\n ConversationMessage\n} from '@wix/evalforge-types';\nimport {\n DEFAULT_EVALUATOR_SYSTEM_PROMPT,\n LiveTraceEventType\n} from '@wix/evalforge-types';\nimport type {\n OpenCodeExecutionOptions,\n OpenCodeExecutionResult,\n OpenCodeEvent,\n OpenCodeTextEvent,\n OpenCodeToolUseEvent,\n OpenCodeStepFinishEvent,\n TimestampedOpenCodeEvent,\n TraceContext\n} from './types.js';\nimport { tryParseJson } from './types.js';\nimport { writeSkillsToFilesystem } from './write-skills.js';\nimport { writeSubAgentsToFilesystem } from './write-sub-agents.js';\nimport { writeRulesToFilesystem } from '../claude-code/write-rules.js';\nimport { buildOpenCodeEnv } from './config.js';\nimport { buildLLMTrace } from './build-trace.js';\nimport { buildConversation } from './build-conversation.js';\nimport { emitTraceEvent } from '../shared/trace-emit.js';\nimport { writeFile, mkdir } from 'fs/promises';\nimport { join } from 'path';\n\nconst KILL_GRACE_PERIOD_MS = 5_000;\nconst IDLE_TIMEOUT_MS = 120_000;\nconst IDLE_CHECK_INTERVAL_MS = 15_000;\nconst MAX_IDLE_RETRIES = 3;\n\n/**\n * Extract a human-readable action description from a tool event.\n */\nfunction extractToolAction(\n toolName: string,\n args: Record<string, unknown> | undefined\n): string {\n if (!toolName) return 'Using tool...';\n\n if (\n (toolName === 'Task' || toolName === 'dispatch_agent') &&\n args?.description\n ) {\n const desc = String(args.description).slice(0, 55);\n return `Task: ${desc}${String(args.description).length > 55 ? '...' : ''}`;\n }\n\n if (\n (toolName === 'Bash' || toolName === 'bash' || toolName === 'execute') &&\n args?.command\n ) {\n const cmd = String(args.command).slice(0, 50);\n return `Running: ${cmd}${String(args.command).length > 50 ? '...' : ''}`;\n }\n\n if (args?.file_path || args?.path || args?.target_file) {\n const filePath = String(\n args.file_path || args.path || args.target_file\n ).slice(0, 50);\n if (/write|edit/i.test(toolName)) return `Writing: ${filePath}`;\n if (/read|view/i.test(toolName)) return `Reading: ${filePath}`;\n }\n\n return `Using ${toolName}...`;\n}\n\n/**\n * Create a LiveTraceEvent from an NDJSON event.\n */\nfunction createTraceEventFromNdjson(\n evt: OpenCodeEvent,\n context: TraceContext,\n stepNumber: number,\n isComplete: boolean\n): LiveTraceEvent | null {\n const base = {\n evalRunId: context.evalRunId,\n scenarioId: context.scenarioId,\n scenarioName: context.scenarioName,\n targetId: context.targetId,\n targetName: context.targetName,\n stepNumber,\n timestamp: new Date().toISOString(),\n isComplete\n };\n\n switch (evt.type) {\n case 'text': {\n const te = evt as OpenCodeTextEvent;\n return {\n ...base,\n type: LiveTraceEventType.COMPLETION,\n outputPreview: te.part.text.slice(0, 500)\n };\n }\n case 'reasoning':\n return {\n ...base,\n type: LiveTraceEventType.THINKING,\n thinking: evt.part.text.slice(0, 500)\n };\n case 'tool_use': {\n const tu = evt as OpenCodeToolUseEvent;\n const toolName = tu.part.tool;\n const args = tu.part.state.input;\n const toolArgs = JSON.stringify(args).slice(0, 500);\n\n let type: LiveTraceEventType = LiveTraceEventType.TOOL_USE;\n let filePath: string | undefined;\n\n if (args) {\n if (args.file_path || args.path || args.target_file) {\n filePath = String(args.file_path || args.path || args.target_file);\n if (/write|edit/i.test(toolName)) {\n type = LiveTraceEventType.FILE_WRITE;\n } else if (/read|view/i.test(toolName)) {\n type = LiveTraceEventType.FILE_READ;\n }\n }\n }\n\n return { ...base, type, toolName, toolArgs, filePath };\n }\n case 'step_finish':\n return {\n ...base,\n type: LiveTraceEventType.PROGRESS,\n outputPreview: 'Step completed'\n };\n default:\n return null;\n }\n}\n\n/**\n * Write all infrastructure files (sub-agents, rules, skills)\n * to the working directory. Called by the adapter's `prepareEnvironment()` so\n * that the orchestrator can take the baseline snapshot *after* infra is in place.\n *\n * Note: MCPs for OpenCode are passed inline via config, not written to filesystem.\n */\nexport async function prepareOpenCodeEnvironment(\n cwd: string,\n skills: SkillWithLatestVersion[],\n options: Pick<OpenCodeExecutionOptions, 'mcps' | 'subAgents' | 'rules'>\n): Promise<void> {\n if (options.mcps && options.mcps.length > 0) {\n console.log(\n `[MCP] ${options.mcps.length} MCP(s) will be configured inline`\n );\n }\n\n if (options.subAgents && options.subAgents.length > 0) {\n await writeSubAgentsToFilesystem(cwd, options.subAgents);\n }\n\n if (options.rules && options.rules.length > 0) {\n await writeRulesToFilesystem(cwd, options.rules);\n }\n\n try {\n await writeSkillsToFilesystem(cwd, skills);\n } catch (writeError) {\n throw new Error(\n `Failed to write skills to filesystem: ${writeError instanceof Error ? writeError.message : String(writeError)}`\n );\n }\n}\n\n/**\n * Write the system prompt as an OpenCode rule file so it is picked up by the CLI.\n */\nasync function writeSystemPromptRule(\n cwd: string,\n systemPrompt: string\n): Promise<void> {\n const rulesDir = join(cwd, '.opencode', 'rules');\n await mkdir(rulesDir, { recursive: true });\n await writeFile(\n join(rulesDir, 'evalforge-system-prompt.md'),\n systemPrompt,\n 'utf-8'\n );\n}\n\n/**\n * Kill a process and its process group (for cleanup of MCP servers, bash, etc.).\n */\nfunction killProcess(child: ChildProcess, resolved: boolean): void {\n if (!child) return;\n\n const killSignal = (signal: NodeJS.Signals): void => {\n if (child.pid) {\n try {\n process.kill(-child.pid, signal);\n console.log(\n `[OpenCode] Sent ${signal} to process group (pid: -${child.pid})`\n );\n return;\n } catch {\n // Process group kill failed, fall back\n }\n }\n child.kill(signal);\n };\n\n killSignal('SIGTERM');\n setTimeout(() => {\n if (child && !resolved) {\n killSignal('SIGKILL');\n }\n }, KILL_GRACE_PERIOD_MS);\n}\n\n// ---------------------------------------------------------------------------\n// Retry support\n// ---------------------------------------------------------------------------\n\ninterface SpawnAttemptResult {\n events: TimestampedOpenCodeEvent[];\n success: boolean;\n isIdleTimeout: boolean;\n error?: Error;\n finalStepNumber: number;\n}\n\n/**\n * Build a summary of tool actions from events, used in the recovery prompt.\n */\nfunction summarizeToolActions(events: TimestampedOpenCodeEvent[]): string {\n const actions: string[] = [];\n for (const { event: evt } of events) {\n if (evt.type === 'tool_use') {\n const tu = evt as OpenCodeToolUseEvent;\n const tool = tu.part.tool;\n const input = tu.part.state.input;\n const filePath = input?.file_path || input?.path || input?.target_file;\n if (filePath) {\n actions.push(`- ${tool}: ${String(filePath)}`);\n } else if (input?.command) {\n actions.push(`- ${tool}: ${String(input.command).slice(0, 80)}`);\n } else {\n actions.push(`- ${tool}`);\n }\n }\n }\n return actions.length > 0 ? actions.join('\\n') : '(no tool actions recorded)';\n}\n\n/**\n * Build a recovery prompt for retrying after an idle timeout.\n * Tells the agent to continue the original task, noting what was already done.\n */\nfunction buildRecoveryPrompt(\n originalPrompt: string,\n events: TimestampedOpenCodeEvent[]\n): string {\n const toolSummary = summarizeToolActions(events);\n return `You are continuing a task that was interrupted due to a session error.\n\nORIGINAL TASK:\n${originalPrompt}\n\nACTIONS ALREADY COMPLETED IN THE PREVIOUS SESSION:\n${toolSummary}\n\nINSTRUCTIONS:\n1. Review the actions listed above that were already completed in the previous session\n2. Check the filesystem to verify what was already done\n3. Continue with any remaining work needed to fulfill the original task\n4. Do NOT redo work that is already done \u2014 only continue from where the previous session left off`;\n}\n\n/**\n * Spawn a single OpenCode process, collect NDJSON events, and return the result.\n * Always resolves (never rejects) so the caller can inspect the result and retry.\n *\n * @see https://github.com/anomalyco/opencode/issues/13230 - Memory leak causes OOM\n * @see https://github.com/anomalyco/opencode/issues/13841 - LLM connection stalls\n */\nfunction spawnOpenCodeProcess(opts: {\n args: string[];\n env: NodeJS.ProcessEnv;\n cwd: string;\n skillNames: string;\n scenarioName: string;\n sdkTimeoutMs: number;\n traceContext?: TraceContext;\n initialStepNumber: number;\n}): Promise<SpawnAttemptResult> {\n const {\n args,\n env,\n cwd,\n skillNames,\n scenarioName,\n sdkTimeoutMs,\n traceContext,\n initialStepNumber\n } = opts;\n\n return new Promise((resolve) => {\n let resolved = false;\n let stderr = '';\n let lineBuffer = '';\n let lastOutputTime = Date.now();\n let traceStepNumber = initialStepNumber;\n let lastAction = 'Starting...';\n let lastToolName: string | undefined;\n let lastFilePath: string | undefined;\n\n const events: TimestampedOpenCodeEvent[] = [];\n\n const timers: {\n timeout?: ReturnType<typeof setTimeout>;\n idleCheck?: ReturnType<typeof setInterval>;\n heartbeat?: ReturnType<typeof setInterval>;\n } = {};\n\n const cleanup = (): void => {\n if (timers.timeout) clearTimeout(timers.timeout);\n if (timers.idleCheck) clearInterval(timers.idleCheck);\n if (timers.heartbeat) clearInterval(timers.heartbeat);\n };\n\n const finalize = (\n success: boolean,\n isIdleTimeout: boolean,\n error?: Error\n ): void => {\n if (resolved) return;\n resolved = true;\n cleanup();\n\n resolve({\n events,\n success,\n isIdleTimeout,\n error,\n finalStepNumber: traceStepNumber\n });\n };\n\n // Spawn the process\n let child: ChildProcess;\n try {\n child = spawn('opencode', args, {\n cwd,\n env,\n stdio: ['ignore', 'pipe', 'pipe'],\n detached: true\n });\n } catch (spawnError) {\n resolve({\n events: [],\n success: false,\n isIdleTimeout: false,\n error: new Error(\n `Failed to spawn opencode: ${spawnError instanceof Error ? spawnError.message : String(spawnError)}`\n ),\n finalStepNumber: traceStepNumber\n });\n return;\n }\n\n // Total timeout\n timers.timeout = setTimeout(() => {\n if (!resolved) {\n console.error(`[OpenCode] Process timed out after ${sdkTimeoutMs}ms`);\n killProcess(child, resolved);\n finalize(\n false,\n false,\n new Error(\n `OpenCode execution timed out after ${sdkTimeoutMs}ms. ` +\n `Skills: ${skillNames}, Scenario: ${scenarioName}`\n )\n );\n }\n }, sdkTimeoutMs);\n\n // Idle watchdog\n timers.idleCheck = setInterval(() => {\n if (resolved) return;\n const idleTime = Date.now() - lastOutputTime;\n if (idleTime >= IDLE_TIMEOUT_MS) {\n console.warn(\n `[OpenCode] Process appears stuck - no output for ${Math.round(idleTime / 1000)}s. Killing process.`\n );\n killProcess(child, resolved);\n finalize(\n false,\n true,\n new Error(\n `OpenCode process stuck - no output for ${Math.round(idleTime / 1000)} seconds (idle timeout). ` +\n `Skills: ${skillNames}, Scenario: ${scenarioName}`\n )\n );\n }\n }, IDLE_CHECK_INTERVAL_MS);\n\n // Heartbeat for live tracing\n if (traceContext) {\n const executionStartTime = Date.now();\n let lastReportedAction = '';\n let sameActionCount = 0;\n\n timers.heartbeat = setInterval(() => {\n const elapsedMs = Date.now() - executionStartTime;\n let progressMessage = lastAction;\n\n if (lastAction === lastReportedAction) {\n sameActionCount++;\n } else {\n sameActionCount = 1;\n lastReportedAction = lastAction;\n }\n\n const isTaskTool =\n lastToolName === 'Task' || lastToolName === 'dispatch_agent';\n if (isTaskTool && sameActionCount > 1) {\n progressMessage = `Waiting for ${lastAction}`;\n } else if (lastToolName && lastFilePath) {\n progressMessage = `${lastToolName}: ${lastFilePath}`;\n } else if (lastToolName && !isTaskTool) {\n progressMessage = `Using ${lastToolName}...`;\n }\n\n const elapsedSec = Math.round(elapsedMs / 1000);\n progressMessage += ` (${elapsedSec}s, step ${traceStepNumber})`;\n\n emitTraceEvent(\n {\n evalRunId: traceContext.evalRunId,\n scenarioId: traceContext.scenarioId,\n scenarioName: traceContext.scenarioName,\n targetId: traceContext.targetId,\n targetName: traceContext.targetName,\n stepNumber: traceStepNumber,\n type: LiveTraceEventType.PROGRESS,\n outputPreview: progressMessage,\n toolName: lastToolName,\n filePath: lastFilePath,\n elapsedMs,\n timestamp: new Date().toISOString(),\n isComplete: false\n },\n traceContext.tracePushUrl,\n traceContext.routeHeader,\n traceContext.authToken\n );\n }, 10_000);\n }\n\n // Process stdout (NDJSON lines)\n child.stdout?.on('data', (data: Buffer) => {\n const text = data.toString();\n lastOutputTime = Date.now();\n\n lineBuffer += text;\n const lines = lineBuffer.split('\\n');\n lineBuffer = lines.pop() || '';\n\n for (const line of lines) {\n if (!line.trim()) continue;\n\n const evt = tryParseJson<OpenCodeEvent>(line);\n if (!evt || !evt.type) continue;\n\n events.push({ event: evt, receivedAt: Date.now() });\n\n // Live tracing\n if (traceContext) {\n traceStepNumber++;\n const traceEvt = createTraceEventFromNdjson(\n evt,\n traceContext,\n traceStepNumber,\n false\n );\n if (traceEvt) {\n lastToolName = traceEvt.toolName;\n lastFilePath = traceEvt.filePath;\n if (traceEvt.type === LiveTraceEventType.THINKING) {\n lastAction = 'Thinking...';\n } else if (traceEvt.type === LiveTraceEventType.TOOL_USE) {\n lastAction = extractToolAction(\n traceEvt.toolName ?? '',\n undefined\n );\n } else if (traceEvt.type === LiveTraceEventType.FILE_WRITE) {\n lastAction = `Writing: ${traceEvt.filePath || 'file'}`;\n } else if (traceEvt.type === LiveTraceEventType.FILE_READ) {\n lastAction = `Reading: ${traceEvt.filePath || 'file'}`;\n } else if (traceEvt.type === LiveTraceEventType.COMPLETION) {\n lastAction = 'Processing response...';\n }\n emitTraceEvent(\n traceEvt,\n traceContext.tracePushUrl,\n traceContext.routeHeader,\n traceContext.authToken\n );\n }\n }\n }\n });\n\n // Process stderr\n child.stderr?.on('data', (data: Buffer) => {\n const text = data.toString();\n stderr += text;\n lastOutputTime = Date.now();\n });\n\n // Handle process close\n child.on('close', (code) => {\n // Flush remaining line buffer\n if (lineBuffer.trim()) {\n const evt = tryParseJson<OpenCodeEvent>(lineBuffer);\n if (evt && evt.type) {\n events.push({ event: evt, receivedAt: Date.now() });\n }\n }\n\n console.log(\n `[executeWithOpenCode] Process exited with code ${code}, ${events.length} events collected`\n );\n\n if (code === 0) {\n finalize(true, false);\n } else {\n finalize(\n false,\n false,\n new Error(\n `OpenCode CLI exited with code ${code}.\\nStderr: ${stderr.slice(0, 1000)}`\n )\n );\n }\n });\n\n // Handle spawn errors\n child.on('error', (error) => {\n finalize(\n false,\n false,\n new Error(`OpenCode CLI spawn error: ${error.message}`)\n );\n });\n });\n}\n\n/**\n * Execute skills using the OpenCode CLI with automatic retry on idle timeouts.\n *\n * When the OpenCode process stalls (no output for 120s), it is killed and\n * retried with a recovery prompt that carries context about work already done.\n * This works around known OpenCode hanging issues where the upstream LLM\n * connection stalls mid-stream.\n *\n * @see https://github.com/anomalyco/opencode/issues/13230 - Memory leak causes OOM\n * @see https://github.com/anomalyco/opencode/issues/13841 - LLM connection stalls\n */\nexport async function executeWithOpenCode(\n skills: SkillWithLatestVersion[],\n scenario: TestScenario,\n options: OpenCodeExecutionOptions\n): Promise<{\n result: OpenCodeExecutionResult;\n llmTrace: LLMTrace;\n conversation: ConversationMessage[];\n}> {\n const skillNames = skills.map((s) => s.name).join(', ');\n console.log('[executeWithOpenCode] Starting execution', {\n skillCount: skills.length,\n skillNames,\n scenarioId: scenario.id,\n scenarioName: scenario.name,\n cwd: options.cwd,\n aiGatewayUrl: options.aiGatewayUrl,\n hasAiGatewayHeaders: !!options.aiGatewayHeaders,\n model: options.model\n });\n\n const startTime = new Date();\n const maxTurns = options.maxTurns ?? 10;\n const sdkTimeoutMs = Math.max(300_000, maxTurns * 60_000);\n\n const { env, providerID, modelID } = await buildOpenCodeEnv({\n model: options.model,\n temperature: options.temperature,\n maxTurns,\n aiGatewayUrl: options.aiGatewayUrl,\n aiGatewayHeaders: options.aiGatewayHeaders,\n mcps: options.mcps,\n cwd: options.cwd\n });\n\n const traceContext = options.traceContext;\n\n // Emit pre-execution diagnostic\n if (traceContext) {\n emitTraceEvent(\n {\n evalRunId: traceContext.evalRunId,\n scenarioId: traceContext.scenarioId,\n scenarioName: traceContext.scenarioName,\n targetId: traceContext.targetId,\n targetName: traceContext.targetName,\n stepNumber: 0,\n type: LiveTraceEventType.DIAGNOSTIC,\n outputPreview: JSON.stringify({\n event: 'pre-cli-execution',\n model: `${providerID}/${modelID}`,\n maxTurns,\n timestamp: new Date().toISOString()\n }),\n timestamp: new Date().toISOString(),\n isComplete: false\n },\n traceContext.tracePushUrl,\n traceContext.routeHeader,\n traceContext.authToken\n );\n }\n\n // Write system prompt as a rule file\n let systemPrompt: string | undefined;\n if (options.systemPrompt === null || options.systemPrompt === '') {\n // Explicitly disabled\n } else if (options.systemPrompt != null) {\n systemPrompt = options.systemPrompt;\n } else {\n systemPrompt = DEFAULT_EVALUATOR_SYSTEM_PROMPT;\n }\n if (systemPrompt) {\n await writeSystemPromptRule(options.cwd, systemPrompt);\n }\n\n // Build base CLI args (prompt is appended per attempt)\n const baseArgs = [\n 'run',\n '--format',\n 'json',\n '--thinking',\n '--variant',\n 'high',\n '--model',\n `${providerID}/${modelID}`,\n '--dir',\n options.cwd\n ];\n\n // Retry loop \u2014 on idle timeout, kill the process and retry with recovery context\n const accumulatedEvents: TimestampedOpenCodeEvent[] = [];\n let traceStepNumber = 0;\n let lastAttemptResult: SpawnAttemptResult | undefined;\n\n for (let attempt = 1; attempt <= MAX_IDLE_RETRIES; attempt++) {\n const prompt =\n attempt === 1\n ? scenario.triggerPrompt\n : buildRecoveryPrompt(scenario.triggerPrompt, accumulatedEvents);\n\n if (attempt > 1) {\n console.log(\n `[OpenCode] Retry attempt ${attempt}/${MAX_IDLE_RETRIES} \u2014 starting fresh session with recovery context`\n );\n if (traceContext) {\n emitTraceEvent(\n {\n evalRunId: traceContext.evalRunId,\n scenarioId: traceContext.scenarioId,\n scenarioName: traceContext.scenarioName,\n targetId: traceContext.targetId,\n targetName: traceContext.targetName,\n stepNumber: traceStepNumber + 1,\n type: LiveTraceEventType.DIAGNOSTIC,\n outputPreview: JSON.stringify({\n event: 'idle-timeout-retry',\n attempt,\n maxRetries: MAX_IDLE_RETRIES,\n eventsFromPreviousAttempts: accumulatedEvents.length\n }),\n timestamp: new Date().toISOString(),\n isComplete: false\n },\n traceContext.tracePushUrl,\n traceContext.routeHeader,\n traceContext.authToken\n );\n }\n }\n\n const args = [...baseArgs, prompt];\n console.log(\n `[executeWithOpenCode] Spawning attempt ${attempt}: opencode`,\n args.slice(0, 5)\n );\n\n lastAttemptResult = await spawnOpenCodeProcess({\n args,\n env,\n cwd: options.cwd,\n skillNames,\n scenarioName: scenario.name,\n sdkTimeoutMs,\n traceContext,\n initialStepNumber: traceStepNumber\n });\n\n accumulatedEvents.push(...lastAttemptResult.events);\n traceStepNumber = lastAttemptResult.finalStepNumber;\n\n if (lastAttemptResult.success) {\n break;\n }\n\n if (!lastAttemptResult.isIdleTimeout || attempt >= MAX_IDLE_RETRIES) {\n // Non-retryable error or all retries exhausted\n if (traceContext) {\n emitTraceEvent(\n {\n evalRunId: traceContext.evalRunId,\n scenarioId: traceContext.scenarioId,\n scenarioName: traceContext.scenarioName,\n targetId: traceContext.targetId,\n targetName: traceContext.targetName,\n stepNumber: traceStepNumber + 1,\n type: LiveTraceEventType.DIAGNOSTIC,\n outputPreview: JSON.stringify({\n event: 'cli-execution-failed',\n error: lastAttemptResult.error?.message ?? 'Unknown error',\n attempt,\n isIdleTimeout: lastAttemptResult.isIdleTimeout\n }).slice(0, 2000),\n timestamp: new Date().toISOString(),\n isComplete: true\n },\n traceContext.tracePushUrl,\n traceContext.routeHeader,\n traceContext.authToken\n );\n }\n throw (\n lastAttemptResult.error ??\n new Error(\n `OpenCode CLI execution failed.\\nAttempt: ${attempt}, Events: ${accumulatedEvents.length}`\n )\n );\n }\n\n console.warn(\n `[OpenCode] Attempt ${attempt} failed due to idle timeout, will retry`\n );\n }\n\n // Build final result from accumulated events across all attempts\n const endTime = new Date();\n const totalDurationMs = endTime.getTime() - startTime.getTime();\n\n let outputText = '';\n for (const { event: evt } of accumulatedEvents) {\n if (evt.type === 'text') {\n outputText += (evt as OpenCodeTextEvent).part.text;\n }\n }\n\n if (!outputText) {\n throw new Error(\n 'Agent produced no text output. ' +\n `Model: ${providerID}/${modelID}, Events: ${accumulatedEvents.length}`\n );\n }\n\n let inputTokens = 0;\n let outputTokens = 0;\n let costUsd = 0;\n for (const { event: evt } of accumulatedEvents) {\n if (evt.type === 'step_finish') {\n const sf = evt as OpenCodeStepFinishEvent;\n inputTokens += sf.part.tokens.input;\n outputTokens += sf.part.tokens.output;\n costUsd += sf.part.cost;\n }\n }\n\n // Emit completion trace event\n if (traceContext) {\n emitTraceEvent(\n {\n evalRunId: traceContext.evalRunId,\n scenarioId: traceContext.scenarioId,\n scenarioName: traceContext.scenarioName,\n targetId: traceContext.targetId,\n targetName: traceContext.targetName,\n stepNumber: traceStepNumber + 1,\n type: LiveTraceEventType.COMPLETION,\n outputPreview: 'Scenario execution completed',\n timestamp: new Date().toISOString(),\n isComplete: true\n },\n traceContext.tracePushUrl,\n traceContext.routeHeader,\n traceContext.authToken\n );\n }\n\n const modelStr = options.model || `${providerID}/${modelID}`;\n const llmTrace = buildLLMTrace(\n accumulatedEvents,\n totalDurationMs,\n modelStr,\n providerID,\n startTime\n );\n const conversation = buildConversation(accumulatedEvents);\n\n return {\n result: {\n outputText,\n durationMs: totalDurationMs,\n usage: {\n inputTokens,\n outputTokens,\n totalTokens: inputTokens + outputTokens\n },\n costUsd\n },\n llmTrace,\n conversation\n };\n}\n", "import type { MCPEntity, SubAgent, Rule } from '@wix/evalforge-types';\n\nexport type { TraceContext } from '@wix/evalforge-types';\n\n// ---------------------------------------------------------------------------\n// NDJSON event types emitted by `opencode run --format json`\n// ---------------------------------------------------------------------------\n\nexport interface OpenCodeTextEvent {\n type: 'text';\n part: { text: string };\n}\n\nexport interface OpenCodeReasoningEvent {\n type: 'reasoning';\n part: { text: string };\n}\n\nexport interface OpenCodeToolUseEvent {\n type: 'tool_use';\n part: {\n tool: string;\n callID: string;\n state: {\n status: string;\n input?: Record<string, unknown>;\n output?: string;\n error?: string;\n title?: string;\n metadata?: Record<string, unknown>;\n };\n };\n}\n\nexport interface OpenCodeStepFinishEvent {\n type: 'step_finish';\n part: {\n reason: string;\n cost: number;\n tokens: {\n total: number;\n input: number;\n output: number;\n reasoning: number;\n cache: { read: number; write: number };\n };\n modelID?: string;\n providerID?: string;\n };\n}\n\nexport type OpenCodeEvent =\n | OpenCodeTextEvent\n | OpenCodeReasoningEvent\n | OpenCodeToolUseEvent\n | OpenCodeStepFinishEvent;\n\nexport interface TimestampedOpenCodeEvent {\n event: OpenCodeEvent;\n receivedAt: number;\n}\n\n// ---------------------------------------------------------------------------\n// Execution options & result\n// ---------------------------------------------------------------------------\n\nexport interface OpenCodeExecutionOptions {\n cwd: string;\n mcps?: MCPEntity[];\n subAgents?: SubAgent[];\n rules?: Rule[];\n model?: string;\n temperature?: number;\n maxTurns?: number;\n aiGatewayUrl?: string;\n aiGatewayHeaders?: Record<string, string>;\n traceContext?: import('@wix/evalforge-types').TraceContext;\n systemPrompt?: string | null;\n}\n\nexport interface OpenCodeExecutionResult {\n outputText: string;\n durationMs: number;\n usage: {\n inputTokens: number;\n outputTokens: number;\n totalTokens: number;\n };\n costUsd?: number;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nexport function tryParseJson<T>(text: string): T | null {\n try {\n return JSON.parse(text) as T;\n } catch {\n return null;\n }\n}\n", "import { mkdir } from 'fs/promises';\nimport { join } from 'path';\nimport type {\n GitHubSource,\n SkillFile,\n SkillWithLatestVersion\n} from '@wix/evalforge-types';\nimport { fetchGitHubFolder } from '@wix/evalforge-github-client';\nimport { writeFilesToDirectory } from '../../utils/write-files.js';\n\nexport type FetchGitHubFolderFn = (\n source: GitHubSource,\n options?: { userAgent?: string }\n) => Promise<SkillFile[]>;\n\n/**\n * Write all skills to .opencode/skills/ so OpenCode can discover them.\n *\n * Content resolution:\n * 1. Pinned (version has `files`): writes all files from the stored snapshot\n * 2. Live (skill has `source`, no pinned files): fetches from GitHub at runtime\n */\nexport async function writeSkillsToFilesystem(\n cwd: string,\n skills: SkillWithLatestVersion[],\n fetchFn: FetchGitHubFolderFn = fetchGitHubFolder\n): Promise<void> {\n await Promise.all(\n skills.map((skill) => writeSkillToFilesystem(cwd, skill, fetchFn))\n );\n}\n\nasync function writeSkillToFilesystem(\n cwd: string,\n skill: SkillWithLatestVersion,\n fetchFn: FetchGitHubFolderFn\n): Promise<void> {\n const skillName = skill.name;\n const skillDir = join(cwd, '.opencode', 'skills', skillName);\n await mkdir(skillDir, { recursive: true });\n\n const version = skill.latestVersion;\n\n if (version?.files && version.files.length > 0) {\n await writeFilesToDirectory(skillDir, version.files);\n console.log(\n `[Skill] ${skillName}: wrote ${version.files.length} file(s) from snapshot`\n );\n } else if (skill.source) {\n try {\n const files = await fetchFn(skill.source, {\n userAgent: 'EvalForge-Evaluator'\n });\n await writeFilesToDirectory(skillDir, files);\n console.log(\n `[Skill] ${skillName}: wrote ${files.length} file(s) from GitHub (live)`\n );\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n console.error(\n `[Skill] ${skillName}: GitHub fetch failed: ${message}, no files to fall back to`\n );\n throw new Error(\n `Failed to write skill ${skillName} to filesystem: ${message}`\n );\n }\n } else {\n throw new Error(`Skill ${skillName} has no files and no source configured`);\n }\n}\n", "import { mkdir, writeFile } from 'fs/promises';\nimport { join } from 'path';\nimport type { SubAgent, GitHubSource } from '@wix/evalforge-types';\nimport {\n fetchGitHubFile,\n type FetchGitHubFolderOptions\n} from '@wix/evalforge-github-client';\n\nexport type FetchGitHubFileFn = (\n source: GitHubSource,\n options?: FetchGitHubFolderOptions\n) => Promise<string>;\n\nconst AGENTS_DIR = '.opencode/agents';\n\nfunction toAgentFilename(\n name: string,\n index: number,\n nameCount: Map<string, number>\n): string {\n const base =\n (name || '')\n .toLowerCase()\n .replace(/\\s+/g, '-')\n .replace(/[^a-z0-9-]/g, '')\n .replace(/^-+|-+$/g, '') || `sub-agent-${index}`;\n\n const count = nameCount.get(base) ?? 0;\n nameCount.set(base, count + 1);\n\n return count === 0 ? base : `${base}-${count + 1}`;\n}\n\nasync function resolveSubAgentContent(\n agent: SubAgent,\n fetchFn: FetchGitHubFileFn\n): Promise<string> {\n if (agent.source) {\n try {\n const content = await fetchFn(agent.source, {\n userAgent: 'EvalForge-Evaluator'\n });\n console.log(\n `[SubAgents] Fetched \"${agent.name}\" from ${agent.source.owner}/${agent.source.repo}/${agent.source.path}@${agent.source.ref}`\n );\n return content;\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n console.error(\n `[SubAgents] \"${agent.name}\": GitHub fetch failed: ${message}`\n );\n throw new Error(\n `Failed to fetch sub-agent \"${agent.name}\" from GitHub: ${message}`\n );\n }\n }\n if (!agent.subAgentMd) {\n console.warn(\n `[SubAgents] \"${agent.name}\" has empty inline content \u2013 the agent file will be blank`\n );\n }\n return agent.subAgentMd;\n}\n\n/**\n * Write sub-agent markdown files to .opencode/agents/ for OpenCode to discover.\n */\nexport async function writeSubAgentsToFilesystem(\n cwd: string,\n subAgents: SubAgent[],\n fetchFn: FetchGitHubFileFn = fetchGitHubFile\n): Promise<void> {\n if (subAgents.length === 0) return;\n\n const agentsDir = join(cwd, AGENTS_DIR);\n await mkdir(agentsDir, { recursive: true });\n\n const nameCount = new Map<string, number>();\n\n for (const [i, agent] of subAgents.entries()) {\n const filename = toAgentFilename(agent.name, i, nameCount);\n const filePath = join(agentsDir, `${filename}.md`);\n const content = await resolveSubAgentContent(agent, fetchFn);\n await writeFile(filePath, content, 'utf8');\n }\n\n console.log(`[SubAgents] Written to ${agentsDir}`);\n}\n", "import { homedir } from 'os';\nimport {\n ClaudeModel,\n AVAILABLE_OPENAI_MODEL_IDS,\n type MCPEntity\n} from '@wix/evalforge-types';\nimport { resolveMcpPlaceholders } from '../shared/resolve-mcp-placeholders.js';\n\nconst DEFAULT_MODEL = `${ClaudeModel.CLAUDE_4_5_SONNET_1_0}`;\n\nexport interface OpenCodeConfigOptions {\n model?: string;\n temperature?: number;\n maxTurns?: number;\n aiGatewayUrl?: string;\n aiGatewayHeaders?: Record<string, string>;\n mcps?: MCPEntity[];\n cwd: string;\n}\n\n/**\n * Parse a model string into provider and model ID.\n * Accepts \"provider/model-id\" or bare \"model-id\" (defaults to anthropic).\n */\nfunction parseModel(model: string): { providerID: string; modelID: string } {\n const slashIndex = model.indexOf('/');\n if (slashIndex > 0) {\n return {\n providerID: model.slice(0, slashIndex),\n modelID: model.slice(slashIndex + 1)\n };\n }\n const isOpenAI = (AVAILABLE_OPENAI_MODEL_IDS as readonly string[]).includes(\n model\n );\n return { providerID: isOpenAI ? 'openai' : 'anthropic', modelID: model };\n}\n\n/**\n * Convert generic MCP server entries into the OpenCode config format.\n */\nfunction toOpenCodeMcpConfig(\n servers: Record<string, Record<string, unknown>>\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n\n for (const [name, entry] of Object.entries(servers)) {\n if (entry.type === 'local' || entry.type === 'remote') {\n result[name] = entry;\n continue;\n }\n\n if (entry.url && typeof entry.url === 'string') {\n result[name] = {\n type: 'remote' as const,\n url: entry.url,\n ...(entry.headers\n ? { headers: entry.headers as Record<string, string> }\n : {}),\n ...(typeof entry.enabled === 'boolean'\n ? { enabled: entry.enabled }\n : {})\n };\n continue;\n }\n\n if (entry.command && typeof entry.command === 'string') {\n const commandArray = [\n entry.command as string,\n ...((entry.args as string[]) || [])\n ];\n result[name] = {\n type: 'local' as const,\n command: commandArray,\n ...(entry.env\n ? { environment: entry.env as Record<string, string> }\n : {}),\n ...(typeof entry.enabled === 'boolean'\n ? { enabled: entry.enabled }\n : {})\n };\n continue;\n }\n\n console.warn(\n `[MCP] Server \"${name}\" has unrecognized format, passing through as-is:`,\n JSON.stringify(entry)\n );\n result[name] = entry;\n }\n\n return result;\n}\n\n/**\n * Ensure `~/.opencode/bin` is on a PATH string.\n */\nfunction ensureOpenCodeInPath(currentPath: string): string {\n const opencodeBin = `${homedir()}/.opencode/bin`;\n if (currentPath.includes(opencodeBin)) {\n return currentPath;\n }\n return `${opencodeBin}:${currentPath}`;\n}\n\n/**\n * Build environment variables for spawning `opencode run`.\n *\n * Returns the env object (including `OPENCODE_CONFIG_CONTENT`) and the\n * parsed provider/model IDs needed by the caller.\n */\nexport async function buildOpenCodeEnv(\n options: OpenCodeConfigOptions\n): Promise<{\n env: NodeJS.ProcessEnv;\n providerID: string;\n modelID: string;\n}> {\n const modelStr = options.model || DEFAULT_MODEL;\n const { providerID, modelID } = parseModel(modelStr);\n\n // Build provider config\n const provider: Record<string, unknown> = {};\n if (options.aiGatewayUrl) {\n const providerOptions: Record<string, unknown> = {\n baseURL: `${options.aiGatewayUrl}/proxy/${providerID}`,\n apiKey: 'sk-placeholder-auth-handled-by-gateway'\n };\n if (options.aiGatewayHeaders) {\n providerOptions.headers = { ...options.aiGatewayHeaders };\n }\n provider[providerID] = { options: providerOptions };\n }\n\n // Build MCP config\n let mcp: Record<string, unknown> | undefined;\n if (options.mcps && options.mcps.length > 0) {\n const mcpServers: Record<string, Record<string, unknown>> = {};\n for (const mcpEntity of options.mcps) {\n const entityConfig = mcpEntity.config as Record<string, unknown>;\n for (const [key, value] of Object.entries(entityConfig)) {\n if (\n typeof value !== 'object' ||\n value === null ||\n Array.isArray(value)\n ) {\n throw new Error(\n `MCP \"${mcpEntity.name}\" has invalid config: value for key \"${key}\" must be an object (got ${typeof value}).`\n );\n }\n mcpServers[key] = value as Record<string, unknown>;\n }\n }\n const resolved = await resolveMcpPlaceholders(mcpServers, {\n cwd: options.cwd\n });\n mcp = toOpenCodeMcpConfig(resolved);\n }\n\n // Build agent overrides\n const agentOverrides: Record<string, unknown> = {};\n if (options.temperature != null) {\n agentOverrides.temperature = options.temperature;\n }\n if (options.maxTurns != null) {\n agentOverrides.maxSteps = options.maxTurns;\n }\n\n // Assemble the full config object\n const config: Record<string, unknown> = {\n model: `${providerID}/${modelID}`,\n provider,\n ...(Object.keys(agentOverrides).length > 0\n ? { agent: { build: agentOverrides } }\n : {}),\n permission: {\n edit: 'allow',\n bash: 'allow',\n webfetch: 'allow',\n doom_loop: 'allow',\n external_directory: 'allow'\n },\n ...(mcp ? { mcp } : {})\n };\n\n const env: NodeJS.ProcessEnv = {\n ...process.env,\n PATH: ensureOpenCodeInPath(process.env.PATH || ''),\n OPENCODE_CONFIG_CONTENT: JSON.stringify(config),\n OPENCODE_DISABLE_LSP_DOWNLOAD: 'true'\n };\n\n return { env, providerID, modelID };\n}\n", "import type {\n LLMTrace,\n LLMTraceStep,\n LLMTraceSummary\n} from '@wix/evalforge-types';\nimport { LLMStepType } from '@wix/evalforge-types';\nimport { randomUUID } from 'crypto';\nimport type {\n OpenCodeTextEvent,\n OpenCodeReasoningEvent,\n OpenCodeToolUseEvent,\n OpenCodeStepFinishEvent,\n TimestampedOpenCodeEvent\n} from './types.js';\n\n/**\n * A \"turn\" is a group of events between two step_finish boundaries.\n * Each turn produces one or more LLMTraceSteps.\n */\ninterface Turn {\n textParts: string[];\n reasoningParts: string[];\n toolCalls: Array<{ toolName: string; args: unknown }>;\n stepFinish?: OpenCodeStepFinishEvent['part'];\n receivedAt?: number;\n}\n\n/**\n * Build an LLMTrace from the NDJSON events emitted by `opencode run --format json`.\n *\n * Events are grouped into turns delimited by `step_finish` events.\n * Each turn may produce THINKING, TOOL_USE, and COMPLETION sub-steps\n * to match the claude-code trace format.\n */\nexport function buildLLMTrace(\n timestampedEvents: TimestampedOpenCodeEvent[],\n totalDurationMs: number,\n model: string,\n provider: string,\n executionStartTime: Date\n): LLMTrace {\n // Group events into turns\n const turns: Turn[] = [];\n let current: Turn = {\n textParts: [],\n reasoningParts: [],\n toolCalls: []\n };\n\n for (const { event: evt, receivedAt } of timestampedEvents) {\n switch (evt.type) {\n case 'text':\n current.textParts.push((evt as OpenCodeTextEvent).part.text);\n break;\n case 'reasoning':\n current.reasoningParts.push((evt as OpenCodeReasoningEvent).part.text);\n break;\n case 'tool_use': {\n const tu = evt as OpenCodeToolUseEvent;\n current.toolCalls.push({\n toolName: tu.part.tool,\n args: tu.part.state.input\n });\n break;\n }\n case 'step_finish': {\n const sf = evt as OpenCodeStepFinishEvent;\n current.stepFinish = sf.part;\n current.receivedAt = receivedAt;\n turns.push(current);\n current = {\n textParts: [],\n reasoningParts: [],\n toolCalls: []\n };\n break;\n }\n }\n }\n\n // If there are remaining events with no step_finish, flush them\n if (\n current.textParts.length > 0 ||\n current.reasoningParts.length > 0 ||\n current.toolCalls.length > 0\n ) {\n // Use the last event's receivedAt for the incomplete turn\n if (timestampedEvents.length > 0) {\n current.receivedAt =\n timestampedEvents[timestampedEvents.length - 1].receivedAt;\n }\n turns.push(current);\n }\n\n // Convert turns into trace steps using real per-turn timing\n const executionStartMs = executionStartTime.getTime();\n\n const allSteps: LLMTraceStep[] = turns\n .flatMap((turn, turnIndex) => {\n const sf = turn.stepFinish;\n const stepInputTokens = sf?.tokens.input ?? 0;\n const stepOutputTokens = sf?.tokens.output ?? 0;\n const stepCost = sf?.cost ?? 0;\n const finishReason = sf?.reason ?? 'unknown';\n const stepModel = sf?.modelID || model;\n const stepProvider = sf?.providerID || provider;\n\n // Compute real timing from receivedAt timestamps\n const turnEndMs = turn.receivedAt ?? executionStartMs + totalDurationMs;\n const prevEndMs =\n turnIndex > 0\n ? (turns[turnIndex - 1].receivedAt ?? executionStartMs)\n : executionStartMs;\n const durationMs = Math.max(0, turnEndMs - prevEndMs);\n const startedAt = new Date(prevEndMs).toISOString();\n\n const text = turn.textParts.join('');\n const thinking = turn.reasoningParts.join('');\n const toolCallCount = turn.toolCalls.length;\n const hasThinking = !!thinking;\n const hasText = !!text;\n const isSuccess = finishReason !== 'error';\n const errorMsg =\n finishReason === 'error' ? 'Generation failed' : undefined;\n\n const subSteps: LLMTraceStep[] = [];\n const thinkingSubSteps =\n hasThinking && (hasText || toolCallCount > 0) ? 1 : 0;\n const toolSubSteps = toolCallCount;\n const textSubSteps = hasText && toolCallCount > 0 ? 1 : 0;\n const totalSubSteps = thinkingSubSteps + toolSubSteps + textSubSteps || 1;\n\n // THINKING sub-step\n if (hasThinking && (hasText || toolCallCount > 0)) {\n subSteps.push({\n id: randomUUID(),\n stepNumber: 0,\n turnIndex,\n type: LLMStepType.THINKING,\n model: stepModel,\n provider: stepProvider,\n startedAt,\n durationMs: Math.round(durationMs / totalSubSteps),\n tokenUsage: {\n prompt: Math.round(stepInputTokens / totalSubSteps),\n completion: Math.round(stepOutputTokens / totalSubSteps),\n total: Math.round(\n (stepInputTokens + stepOutputTokens) / totalSubSteps\n )\n },\n costUsd: stepCost / totalSubSteps,\n outputPreview: thinking.slice(0, 200),\n success: isSuccess,\n error: errorMsg\n });\n }\n\n // TOOL_USE sub-steps\n if (toolCallCount > 0) {\n for (let tcIdx = 0; tcIdx < toolCallCount; tcIdx++) {\n const tc = turn.toolCalls[tcIdx];\n const isLast = tcIdx === toolCallCount - 1 && textSubSteps === 0;\n const toolBudgetSteps = toolSubSteps + textSubSteps;\n const toolFraction = toolBudgetSteps > 0 ? 1 / toolBudgetSteps : 1;\n const remainingFraction =\n (totalSubSteps - thinkingSubSteps) / totalSubSteps;\n\n subSteps.push({\n id: randomUUID(),\n stepNumber: 0,\n turnIndex,\n type: LLMStepType.TOOL_USE,\n model: stepModel,\n provider: stepProvider,\n startedAt,\n durationMs: isLast\n ? durationMs - subSteps.reduce((s, ss) => s + ss.durationMs, 0)\n : Math.round(durationMs * remainingFraction * toolFraction),\n tokenUsage: {\n prompt: Math.round(\n stepInputTokens * remainingFraction * toolFraction\n ),\n completion: Math.round(\n stepOutputTokens * remainingFraction * toolFraction\n ),\n total: Math.round(\n (stepInputTokens + stepOutputTokens) *\n remainingFraction *\n toolFraction\n )\n },\n costUsd: stepCost * remainingFraction * toolFraction,\n toolName: tc.toolName,\n toolArguments: JSON.stringify(tc.args),\n outputPreview:\n tcIdx === 0 && !hasText\n ? (text || thinking)?.slice(0, 200)\n : undefined,\n success: isSuccess,\n error: errorMsg\n });\n }\n }\n\n // COMPLETION sub-step (text when tools were also present)\n if (hasText && toolCallCount > 0) {\n subSteps.push({\n id: randomUUID(),\n stepNumber: 0,\n turnIndex,\n type: LLMStepType.COMPLETION,\n model: stepModel,\n provider: stepProvider,\n startedAt,\n durationMs:\n durationMs - subSteps.reduce((s, ss) => s + ss.durationMs, 0),\n tokenUsage: {\n prompt:\n stepInputTokens -\n subSteps.reduce((s, ss) => s + ss.tokenUsage.prompt, 0),\n completion:\n stepOutputTokens -\n subSteps.reduce((s, ss) => s + ss.tokenUsage.completion, 0),\n total:\n stepInputTokens +\n stepOutputTokens -\n subSteps.reduce((s, ss) => s + ss.tokenUsage.total, 0)\n },\n costUsd: stepCost - subSteps.reduce((s, ss) => s + ss.costUsd, 0),\n outputPreview: text.slice(0, 200),\n success: isSuccess,\n error: errorMsg\n });\n }\n\n // Fallback: pure text or pure thinking\n if (subSteps.length === 0) {\n const stepType =\n hasThinking && !hasText\n ? LLMStepType.THINKING\n : LLMStepType.COMPLETION;\n subSteps.push({\n id: randomUUID(),\n stepNumber: 0,\n turnIndex,\n type: stepType,\n model: stepModel,\n provider: stepProvider,\n startedAt,\n durationMs,\n tokenUsage: {\n prompt: stepInputTokens,\n completion: stepOutputTokens,\n total: stepInputTokens + stepOutputTokens\n },\n costUsd: stepCost,\n outputPreview: (text || thinking)?.slice(0, 200),\n success: isSuccess,\n error: errorMsg\n });\n }\n\n return subSteps;\n })\n .map((s, i) => ({ ...s, stepNumber: i + 1 }));\n\n // Aggregate totals\n let totalPrompt = 0;\n let totalCompletion = 0;\n let totalCost = 0;\n for (const turn of turns) {\n if (turn.stepFinish) {\n totalPrompt += turn.stepFinish.tokens.input;\n totalCompletion += turn.stepFinish.tokens.output;\n totalCost += turn.stepFinish.cost;\n }\n }\n const totalTokens = {\n prompt: totalPrompt,\n completion: totalCompletion,\n total: totalPrompt + totalCompletion\n };\n\n const stepTypeBreakdown: Record<\n string,\n { count: number; durationMs: number; tokens: number; costUsd: number }\n > = {};\n for (const step of allSteps) {\n const entry = stepTypeBreakdown[step.type] ?? {\n count: 0,\n durationMs: 0,\n tokens: 0,\n costUsd: 0\n };\n entry.count += 1;\n entry.durationMs += step.durationMs;\n entry.tokens += step.tokenUsage.total;\n entry.costUsd += step.costUsd;\n stepTypeBreakdown[step.type] = entry;\n }\n\n const modelUsed = allSteps[0]?.model || model;\n const summary: LLMTraceSummary = {\n totalSteps: allSteps.length,\n totalTurns: turns.length,\n totalDurationMs,\n totalTokens,\n totalCostUsd: totalCost,\n modelBreakdown: {\n [modelUsed]: {\n count: allSteps.length,\n durationMs: totalDurationMs,\n tokens: totalTokens.total,\n costUsd: totalCost\n }\n },\n modelsUsed: [modelUsed],\n stepTypeBreakdown\n };\n\n return {\n id: randomUUID(),\n steps: allSteps,\n summary\n };\n}\n", "import type { ConversationMessage } from '@wix/evalforge-types';\nimport type {\n OpenCodeTextEvent,\n OpenCodeReasoningEvent,\n OpenCodeToolUseEvent,\n TimestampedOpenCodeEvent\n} from './types.js';\n\n/**\n * Build a conversation from the NDJSON events emitted by\n * `opencode run --format json`.\n *\n * Events are grouped into assistant turns (text, reasoning, tool_use)\n * separated by step_finish events. Tool results appear as user messages.\n */\nexport function buildConversation(\n timestampedEvents: TimestampedOpenCodeEvent[]\n): ConversationMessage[] {\n const result: ConversationMessage[] = [];\n\n let assistantContent: ConversationMessage['content'] = [];\n let userContent: ConversationMessage['content'] = [];\n let latestReceivedAt = 0;\n\n const flushAssistant = (): void => {\n if (assistantContent.length > 0) {\n const timestamp =\n latestReceivedAt > 0\n ? new Date(latestReceivedAt).toISOString()\n : new Date().toISOString();\n result.push({ role: 'assistant', content: assistantContent, timestamp });\n assistantContent = [];\n }\n };\n\n const flushUser = (): void => {\n if (userContent.length > 0) {\n const timestamp =\n latestReceivedAt > 0\n ? new Date(latestReceivedAt).toISOString()\n : new Date().toISOString();\n result.push({ role: 'user', content: userContent, timestamp });\n userContent = [];\n }\n };\n\n for (const { event: evt, receivedAt } of timestampedEvents) {\n latestReceivedAt = receivedAt;\n\n switch (evt.type) {\n case 'text': {\n const te = evt as OpenCodeTextEvent;\n assistantContent.push({ type: 'text', text: te.part.text });\n break;\n }\n case 'reasoning': {\n const re = evt as OpenCodeReasoningEvent;\n assistantContent.push({ type: 'thinking', thinking: re.part.text });\n break;\n }\n case 'tool_use': {\n const tu = evt as OpenCodeToolUseEvent;\n // Tool invocation goes on the assistant side\n assistantContent.push({\n type: 'tool_use',\n toolName: tu.part.tool,\n toolId: tu.part.callID,\n input: tu.part.state.input\n });\n\n // If the tool has completed or errored, emit a user tool_result\n if (\n tu.part.state.status === 'completed' ||\n tu.part.state.status === 'error'\n ) {\n // Flush any pending assistant content first\n flushAssistant();\n\n const isError = tu.part.state.status === 'error';\n const content = isError\n ? tu.part.state.error || 'Tool execution failed'\n : tu.part.state.output || '';\n userContent.push({\n type: 'tool_result',\n toolUseId: tu.part.callID,\n content,\n ...(isError ? { isError: true } : {})\n });\n flushUser();\n }\n break;\n }\n case 'step_finish': {\n // Flush the current turn\n flushAssistant();\n flushUser();\n break;\n }\n }\n }\n\n // Flush any remaining content\n flushAssistant();\n flushUser();\n\n return result;\n}\n", "/**\n * OpenCode agent adapter module.\n *\n * Provides the OpenCode implementation of the AgentAdapter interface.\n * Spawns the `opencode` CLI and parses NDJSON events from stdout.\n *\n * The adapter is automatically registered with the default registry when\n * this module is imported.\n */\n\nexport { OpenCodeAdapter, openCodeAdapter } from './opencode-adapter.js';\nexport { executeWithOpenCode } from './execute.js';\nexport { buildConversation } from './build-conversation.js';\n\nexport type {\n OpenCodeExecutionOptions,\n OpenCodeExecutionResult\n} from './types.js';\nexport type { TraceContext } from '@wix/evalforge-types';\n\n// Register the adapter with the default registry\nimport { defaultRegistry } from '../registry.js';\nimport { openCodeAdapter } from './opencode-adapter.js';\n\ndefaultRegistry.register(openCodeAdapter);\n", "import {\n generateText,\n stepCountIs,\n type LanguageModel,\n type StepResult,\n type ToolSet\n} from 'ai';\nimport { createAnthropic } from '@ai-sdk/anthropic';\nimport { createOpenAI } from '@ai-sdk/openai';\nimport type {\n AgentExecutionContext,\n AgentExecutionResult,\n LLMTrace,\n TraceContext\n} from '@wix/evalforge-types';\nimport {\n AVAILABLE_CLAUDE_MODEL_IDS,\n OPENAI_RESPONSES_MODEL_IDS,\n LLMStepType,\n LiveTraceEventType\n} from '@wix/evalforge-types';\nimport { randomUUID } from 'crypto';\nimport { buildMcpTools, closeMcpClients } from './mcp-tools.js';\nimport { emitTraceEvent } from '../shared/trace-emit.js';\nimport { detectMcpToolError } from '../shared/detect-tool-error.js';\nimport { calculateStepCost } from './cost-calculation.js';\nimport { buildConversation } from './build-conversation.js';\n\nconst PROVIDER_ANTHROPIC = 'anthropic';\nconst PROVIDER_OPENAI = 'openai';\n\n/**\n * Default agentic loop iterations when MCP tools are available.\n * Caps tool-use rounds to prevent runaway loops; a single-step\n * limit is used when no tools are present. Can be overridden via\n * modelConfig.maxTurns.\n */\nconst DEFAULT_MAX_TOOL_STEPS = 25;\n\nexport function createModel(\n modelId: string,\n baseUrl: string,\n headers: Record<string, string>\n): LanguageModel {\n const isClaudeModel = isClaudeModelId(modelId);\n\n if (isClaudeModel) {\n const anthropic = createAnthropic({\n baseURL: `${baseUrl}/proxy/anthropic`,\n apiKey: 'proxy-auth',\n headers\n });\n return anthropic(modelId);\n }\n\n const openai = createOpenAI({\n baseURL: `${baseUrl}/proxy/openai`,\n apiKey: 'proxy-auth',\n headers\n });\n\n if (\n [...OPENAI_RESPONSES_MODEL_IDS].some(\n (id) => modelId === id || modelId.startsWith(id)\n )\n ) {\n return openai.responses(modelId);\n }\n\n return openai.chat(modelId);\n}\n\nexport function isClaudeModelId(modelId: string): boolean {\n return (AVAILABLE_CLAUDE_MODEL_IDS as string[]).some(\n (id) => modelId === id || modelId.startsWith(id)\n );\n}\n\n/**\n * Extract text content from a skill's latest version files.\n * Concatenates all file contents, prioritizing SKILL.md if present.\n */\nexport function extractSkillContent(\n files: Array<{ path: string; content: string }> | undefined\n): string | undefined {\n if (!files || files.length === 0) return undefined;\n\n const skillMd = files.find((f) => f.path === 'SKILL.md');\n if (skillMd) return skillMd.content;\n\n return files.map((f) => f.content).join('\\n\\n');\n}\n\nexport async function executeWithAiSdk(\n context: AgentExecutionContext\n): Promise<AgentExecutionResult> {\n const {\n scenario,\n cwd,\n modelConfig,\n aiGatewayUrl,\n aiGatewayHeaders = {},\n mcps,\n traceContext\n } = context;\n\n if (!aiGatewayUrl) {\n throw new Error('Simple Agent requires aiGatewayUrl');\n }\n if (!modelConfig?.model) {\n throw new Error('Simple Agent requires a model in modelConfig');\n }\n\n const model = createModel(modelConfig.model, aiGatewayUrl, aiGatewayHeaders);\n const provider = isClaudeModelId(modelConfig.model)\n ? PROVIDER_ANTHROPIC\n : PROVIDER_OPENAI;\n\n const systemPrompt = composeSystemPrompt(context);\n\n const { tools: mcpTools, clients } =\n mcps && mcps.length > 0\n ? await buildMcpTools(mcps, cwd)\n : { tools: undefined, clients: [] };\n\n const startTime = Date.now();\n\n if (traceContext) {\n emitStartEvent(traceContext, startTime);\n }\n\n try {\n const isAnthropic = provider === PROVIDER_ANTHROPIC;\n const isResponsesAPI = [...OPENAI_RESPONSES_MODEL_IDS].some(\n (id) => modelConfig.model === id || modelConfig.model.startsWith(id)\n );\n const supportsThinking = isAnthropic || isResponsesAPI;\n\n const providerOpts = {\n ...(isAnthropic && {\n anthropic: {\n thinking: { type: 'enabled', budgetTokens: 10000 }\n }\n }),\n ...(isResponsesAPI && {\n openai: {\n // Prevent the SDK from sending item_reference inputs that the proxy can't forward\n store: false,\n forceReasoning: true,\n reasoningEffort: 'high' as const,\n reasoningSummary: 'detailed' as const\n }\n })\n };\n\n const stepTimestamps: number[] = [];\n\n const result = await generateText({\n model,\n system: systemPrompt,\n prompt: scenario.triggerPrompt,\n temperature: supportsThinking ? undefined : modelConfig.temperature,\n maxOutputTokens: modelConfig.maxTokens,\n tools: mcpTools as ToolSet | undefined,\n stopWhen: mcpTools\n ? stepCountIs(modelConfig.maxTurns ?? DEFAULT_MAX_TOOL_STEPS)\n : stepCountIs(1),\n providerOptions: providerOpts,\n onStepFinish: (step) => {\n stepTimestamps.push(Date.now());\n if (traceContext) {\n const isToolStep = step.toolCalls.length > 0;\n const firstToolCall = step.toolCalls[0];\n emitTraceEvent(\n {\n evalRunId: traceContext.evalRunId,\n scenarioId: traceContext.scenarioId,\n scenarioName: traceContext.scenarioName,\n targetId: traceContext.targetId,\n targetName: traceContext.targetName,\n stepNumber: stepTimestamps.length,\n type: isToolStep\n ? LiveTraceEventType.TOOL_USE\n : LiveTraceEventType.COMPLETION,\n toolName: firstToolCall?.toolName,\n toolArgs: firstToolCall\n ? (JSON.stringify(firstToolCall.input) ?? '').slice(0, 500)\n : undefined,\n outputPreview: step.text?.slice(0, 500),\n elapsedMs: Date.now() - startTime,\n timestamp: new Date().toISOString(),\n isComplete: false\n },\n traceContext.tracePushUrl,\n traceContext.routeHeader,\n traceContext.authToken\n );\n }\n }\n });\n\n const durationMs = Date.now() - startTime;\n\n const usage = {\n inputTokens: result.usage.inputTokens ?? 0,\n outputTokens: result.usage.outputTokens ?? 0,\n totalTokens: result.usage.totalTokens ?? 0\n };\n\n const llmTrace = buildLLMTrace(\n result.steps,\n durationMs,\n usage,\n modelConfig.model,\n provider,\n startTime,\n stepTimestamps\n );\n\n if (traceContext) {\n emitCompletionEvent(traceContext, stepTimestamps.length + 1);\n }\n\n const conversation = buildConversation(\n scenario.triggerPrompt,\n result.steps,\n startTime,\n stepTimestamps\n );\n\n return {\n outputText: result.text,\n durationMs,\n usage,\n llmTrace,\n conversation\n };\n } finally {\n await closeMcpClients(clients);\n }\n}\n\n/**\n * Build the system prompt for Simple Agent from skills, rules, and optional override.\n *\n * Unlike CLI agents (which have DEFAULT_EVALUATOR_SYSTEM_PROMPT), the Simple Agent\n * has no built-in default instructions. The three-state `systemPrompt` contract\n * (undefined = default, null = none, string = custom) effectively collapses to\n * two states here: both undefined and null result in no base prompt being prepended,\n * while a non-empty string is included as the first segment.\n */\nexport function composeSystemPrompt(\n context: AgentExecutionContext\n): string | undefined {\n const parts: string[] = [];\n\n if (context.systemPrompt) {\n parts.push(context.systemPrompt);\n }\n\n for (const skill of context.skills) {\n const content = extractSkillContent(skill.latestVersion?.files);\n if (content) {\n parts.push(content);\n }\n }\n\n if (context.rules) {\n for (const rule of context.rules) {\n if (rule.content) {\n parts.push(rule.content);\n }\n }\n }\n\n return parts.length > 0 ? parts.join('\\n\\n---\\n\\n') : undefined;\n}\n\n/**\n * Check if any tool result in a step indicates an error.\n * Returns the error text if found, null otherwise.\n */\nfunction findToolResultError(step: StepResult<ToolSet>): string | null {\n for (const tr of step.toolResults) {\n const output = (tr as { output?: unknown }).output;\n const error = detectMcpToolError(output);\n if (error) return error;\n }\n return null;\n}\n\nexport function buildLLMTrace(\n steps: StepResult<ToolSet>[],\n totalDurationMs: number,\n totalUsage: {\n inputTokens: number;\n outputTokens: number;\n totalTokens: number;\n },\n modelId: string,\n provider: string,\n executionStartMs: number,\n stepTimestamps: number[]\n): LLMTrace {\n const traceSteps = steps.map((step, i) => {\n const stepFinishedAt = stepTimestamps[i] ?? executionStartMs;\n const stepStartedAt =\n i === 0 ? executionStartMs : (stepTimestamps[i - 1] ?? executionStartMs);\n const stepDurationMs = stepFinishedAt - stepStartedAt;\n const firstToolCall = step.toolCalls[0];\n\n const tokenUsage = {\n prompt: step.usage.inputTokens ?? 0,\n completion: step.usage.outputTokens ?? 0,\n total: step.usage.totalTokens ?? 0\n };\n\n const costUsd = calculateStepCost(step, modelId, provider, tokenUsage);\n\n // Check if any tool result for this step indicates an error.\n // MCP tool results embed isError in the output content.\n const toolResultError = findToolResultError(step);\n\n return {\n id: randomUUID(),\n stepNumber: i + 1,\n turnIndex: i,\n type:\n step.toolCalls.length > 0\n ? LLMStepType.TOOL_USE\n : LLMStepType.COMPLETION,\n model: modelId,\n provider,\n startedAt: new Date(stepStartedAt).toISOString(),\n durationMs: stepDurationMs,\n tokenUsage,\n costUsd,\n toolName: firstToolCall?.toolName,\n toolArguments: firstToolCall\n ? (JSON.stringify(firstToolCall.input) ?? undefined)\n : undefined,\n outputPreview: step.text?.slice(0, 200),\n success: step.finishReason !== 'error' && !toolResultError,\n error:\n step.finishReason === 'error'\n ? 'Generation failed'\n : (toolResultError ?? undefined)\n };\n });\n\n const totalCostUsd = traceSteps.reduce((sum, s) => sum + s.costUsd, 0);\n\n const finalTokens = {\n prompt: totalUsage.inputTokens,\n completion: totalUsage.outputTokens,\n total: totalUsage.totalTokens\n };\n\n return {\n id: randomUUID(),\n steps: traceSteps,\n summary: {\n totalSteps: traceSteps.length,\n totalTurns: traceSteps.length,\n totalDurationMs,\n totalTokens: finalTokens,\n totalCostUsd,\n modelBreakdown: {\n [modelId]: {\n count: traceSteps.length,\n durationMs: totalDurationMs,\n tokens: finalTokens.total,\n costUsd: totalCostUsd\n }\n },\n modelsUsed: [modelId]\n }\n };\n}\n\nfunction emitStartEvent(traceContext: TraceContext, startTime: number): void {\n emitTraceEvent(\n {\n evalRunId: traceContext.evalRunId,\n scenarioId: traceContext.scenarioId,\n scenarioName: traceContext.scenarioName,\n targetId: traceContext.targetId,\n targetName: traceContext.targetName,\n stepNumber: 0,\n type: LiveTraceEventType.PROGRESS,\n outputPreview: 'Starting Simple Agent execution...',\n elapsedMs: Date.now() - startTime,\n timestamp: new Date().toISOString(),\n isComplete: false\n },\n traceContext.tracePushUrl,\n traceContext.routeHeader,\n traceContext.authToken\n );\n}\n\nfunction emitCompletionEvent(\n traceContext: TraceContext,\n stepNumber: number\n): void {\n emitTraceEvent(\n {\n evalRunId: traceContext.evalRunId,\n scenarioId: traceContext.scenarioId,\n scenarioName: traceContext.scenarioName,\n targetId: traceContext.targetId,\n targetName: traceContext.targetName,\n stepNumber,\n type: LiveTraceEventType.COMPLETION,\n outputPreview: 'Scenario execution completed',\n timestamp: new Date().toISOString(),\n isComplete: true\n },\n traceContext.tracePushUrl,\n traceContext.routeHeader,\n traceContext.authToken\n );\n}\n", "import { createMCPClient } from '@ai-sdk/mcp';\nimport { Experimental_StdioMCPTransport } from '@ai-sdk/mcp/mcp-stdio';\nimport type { MCPEntity } from '@wix/evalforge-types';\nimport { resolveMcpPlaceholders } from '../shared/resolve-mcp-placeholders.js';\n\ninterface McpToolsResult {\n tools: Record<string, unknown>;\n clients: Array<{ close: () => Promise<void> }>;\n}\n\n/**\n * Build AI SDK tools from MCP entity configs.\n *\n * Each `MCPEntity.config` is a keyed record matching the `.mcp.json` shape,\n * e.g. `{ \"server-name\": { \"type\": \"stdio\", \"command\": \"node\", \"args\": [\"server.js\"] } }`.\n * Each entry becomes a live MCP client whose tools are merged into the result.\n *\n * Tool names are namespaced as `${serverName}__${toolName}` to avoid collisions.\n */\nexport async function buildMcpTools(\n mcps: MCPEntity[],\n cwd: string\n): Promise<McpToolsResult> {\n const allTools: Record<string, unknown> = {};\n const clients: Array<{ close: () => Promise<void> }> = [];\n\n try {\n for (const mcp of mcps) {\n const resolvedConfig = await resolveMcpPlaceholders(\n mcp.config as Record<string, Record<string, unknown>>,\n { cwd }\n );\n for (const [serverName, serverConfig] of Object.entries(resolvedConfig)) {\n const config = serverConfig as Record<string, unknown>;\n const transport = buildTransport(serverName, config, cwd);\n const client = await createMCPClient({ transport });\n clients.push(client);\n const tools = await client.tools();\n\n for (const [toolName, tool] of Object.entries(tools)) {\n allTools[`${serverName}__${toolName}`] = tool;\n }\n }\n }\n } catch (err) {\n await closeMcpClients(clients);\n throw err;\n }\n\n return { tools: allTools, clients };\n}\n\nexport async function closeMcpClients(\n clients: Array<{ close: () => Promise<void> }>\n): Promise<void> {\n await Promise.allSettled(clients.map((c) => c.close()));\n}\n\n/**\n * Build an AI SDK MCP transport from a server config entry.\n *\n * Supports three transport types:\n * - stdio: local process (Experimental_StdioMCPTransport)\n * - http: streamable HTTP (config object with type: 'http')\n * - sse: Server-Sent Events (config object with type: 'sse')\n */\nexport function buildTransport(\n serverName: string,\n config: Record<string, unknown>,\n cwd: string\n) {\n const type = config.type as string | undefined;\n const headers = config.headers as Record<string, string> | undefined;\n\n if (type === 'stdio' || config.command) {\n return new Experimental_StdioMCPTransport({\n command: config.command as string,\n args: (config.args as string[]) ?? [],\n env: { ...(config.env as Record<string, string> | undefined), PWD: cwd },\n cwd\n });\n }\n\n if (type === 'http') {\n return {\n type: 'http' as const,\n url: config.url as string,\n ...(headers && { headers })\n };\n }\n\n if (type === 'sse' || config.url) {\n return {\n type: 'sse' as const,\n url: config.url as string,\n ...(headers && { headers })\n };\n }\n\n throw new Error(\n `MCP server \"${serverName}\" has unsupported transport config (type=${type ?? 'unset'}). ` +\n `Expected type \"stdio\", \"http\", or \"sse\", or a config with \"command\" or \"url\".`\n );\n}\n", "/**\n * Detect if an MCP tool result output indicates an error.\n *\n * MCP tool results embed `isError: true` in the output object.\n * We first check the structured object, then fall back to string matching\n * for cases where the output is already serialized.\n *\n * @returns The error text if found, null otherwise.\n */\nexport function detectMcpToolError(output: unknown): string | null {\n if (output == null) return null;\n\n // Structured check: output is an object with isError flag\n if (typeof output === 'object' && 'isError' in output) {\n const obj = output as {\n isError?: boolean;\n content?: Array<{ text?: string }>;\n };\n if (obj.isError === true) {\n return extractErrorText(obj.content);\n }\n }\n\n // Fallback: output is a serialized string containing the error pattern\n const str = typeof output === 'string' ? output : null;\n if (\n str &&\n (str.includes('\"isError\":true') || str.includes('\"isError\": true'))\n ) {\n try {\n const parsed = JSON.parse(str) as {\n isError?: boolean;\n content?: Array<{ text?: string }>;\n };\n if (parsed.isError === true) {\n return extractErrorText(parsed.content);\n }\n } catch {\n // Unparseable \u2014 return raw string as error\n return str.slice(0, 500);\n }\n }\n\n return null;\n}\n\nfunction extractErrorText(\n content: Array<{ text?: string }> | undefined\n): string {\n if (Array.isArray(content)) {\n const text = content\n .filter((c) => typeof c.text === 'string')\n .map((c) => c.text)\n .join('\\n');\n if (text) return text.slice(0, 500);\n }\n return 'Tool call failed';\n}\n", "import type { StepResult, ToolSet } from 'ai';\nimport { normalizeModelId } from '@wix/evalforge-types';\n\nconst PROVIDER_ANTHROPIC = 'anthropic';\n\n/**\n * Per-1M-token pricing keyed by official model ID.\n * Used as fallback when the gateway doesn't report cost.\n */\nconst MODEL_PRICING: Record<string, { input: number; output: number }> = {\n // Anthropic \u2014 Claude 4.6\n 'claude-sonnet-4-6': { input: 3, output: 15 },\n 'claude-opus-4-6': { input: 15, output: 75 },\n // Anthropic \u2014 Claude 4.5\n 'claude-opus-4-5': { input: 5, output: 25 },\n 'claude-sonnet-4-5': { input: 3, output: 15 },\n 'claude-haiku-4-5': { input: 1, output: 5 },\n // Anthropic \u2014 Claude 4\n 'claude-opus-4': { input: 15, output: 75 },\n 'claude-sonnet-4': { input: 3, output: 15 },\n\n // OpenAI \u2014 GPT-5\n 'gpt-5': { input: 1.25, output: 10 },\n 'gpt-5-mini': { input: 0.25, output: 2 },\n 'gpt-5-nano': { input: 0.05, output: 0.4 },\n // OpenAI \u2014 GPT-4.1\n 'gpt-4.1': { input: 2, output: 8 },\n 'gpt-4.1-mini': { input: 0.4, output: 1.6 },\n 'gpt-4.1-nano': { input: 0.1, output: 0.4 },\n // OpenAI \u2014 GPT-4o\n 'gpt-4o': { input: 2.5, output: 10 },\n 'gpt-4o-mini': { input: 0.15, output: 0.6 },\n // OpenAI \u2014 Reasoning\n o3: { input: 2, output: 8 },\n 'o4-mini': { input: 1.1, output: 4.4 },\n 'o3-mini': { input: 1.1, output: 4.4 },\n o1: { input: 15, output: 60 }\n};\n\n/**\n * Extract gateway-computed cost from a Vercel AI SDK step result.\n * The Wix AI Gateway reports accurate cost (including cache discounts)\n * via `total_cost_usd` injected by the proxy into the provider response.\n *\n * - Anthropic: available in `providerMetadata.anthropic.usage.total_cost_usd`\n * - OpenAI: available at the top level of `response.body.total_cost_usd`\n */\nfunction extractGatewayCost(\n step: StepResult<ToolSet>,\n provider: string\n): number | undefined {\n try {\n if (provider === PROVIDER_ANTHROPIC) {\n const meta = step.providerMetadata as Record<string, unknown> | undefined;\n const anthropic = meta?.anthropic as Record<string, unknown> | undefined;\n const usage = anthropic?.usage as Record<string, unknown> | undefined;\n const cost = usage?.total_cost_usd;\n return typeof cost === 'number' && cost > 0 ? cost : undefined;\n }\n\n const body = step.response?.body as Record<string, unknown> | undefined;\n const cost = body?.total_cost_usd;\n return typeof cost === 'number' && cost > 0 ? cost : undefined;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Calculate cost from the built-in pricing table.\n * Normalizes legacy gateway model IDs before lookup.\n * Returns 0 for unknown models.\n */\nfunction calculateFromPricing(\n modelId: string,\n tokenUsage: { prompt: number; completion: number }\n): number {\n const normalized = normalizeModelId(modelId);\n const pricing =\n MODEL_PRICING[normalized] ??\n MODEL_PRICING[\n Object.keys(MODEL_PRICING).find((key) => normalized.startsWith(key)) ?? ''\n ];\n if (!pricing) return 0;\n\n return (\n (tokenUsage.prompt / 1_000_000) * pricing.input +\n (tokenUsage.completion / 1_000_000) * pricing.output\n );\n}\n\n/**\n * Calculate the cost for a single LLM step.\n * Prefers the gateway-reported cost (accurate with cache discounts),\n * falling back to the built-in pricing table.\n */\nexport function calculateStepCost(\n step: StepResult<ToolSet>,\n modelId: string,\n provider: string,\n tokenUsage: { prompt: number; completion: number }\n): number {\n return (\n extractGatewayCost(step, provider) ??\n calculateFromPricing(modelId, tokenUsage)\n );\n}\n", "import type {\n ConversationBlock,\n ConversationMessage\n} from '@wix/evalforge-types';\nimport type { StepResult, ToolSet } from 'ai';\nimport { detectMcpToolError } from '../shared/detect-tool-error.js';\n\n/**\n * Build a serializable conversation from Vercel AI SDK step results.\n *\n * Maps the step-based execution model to the same ConversationMessage\n * format used by the Claude Code adapter, so both agent types render\n * identically in the Conversation tab.\n */\nexport function buildConversation(\n triggerPrompt: string,\n steps: StepResult<ToolSet>[],\n executionStartMs: number,\n stepTimestamps: number[]\n): ConversationMessage[] {\n const messages: ConversationMessage[] = [];\n\n messages.push({\n role: 'user',\n content: [{ type: 'text', text: triggerPrompt }],\n timestamp: new Date(executionStartMs).toISOString()\n });\n\n for (let i = 0; i < steps.length; i++) {\n const step = steps[i];\n const stepTimestamp = new Date(\n stepTimestamps[i] ?? executionStartMs\n ).toISOString();\n\n const assistantContent: ConversationBlock[] = [];\n\n if (step.reasoningText) {\n assistantContent.push({ type: 'thinking', thinking: step.reasoningText });\n }\n\n if (step.text) {\n assistantContent.push({ type: 'text', text: step.text });\n }\n\n for (const tc of step.toolCalls) {\n assistantContent.push({\n type: 'tool_use',\n toolName: tc.toolName,\n toolId: tc.toolCallId,\n input: tc.input\n });\n }\n\n if (assistantContent.length > 0) {\n messages.push({\n role: 'assistant',\n content: assistantContent,\n timestamp: stepTimestamp\n });\n }\n\n if (step.toolResults.length > 0) {\n const resultBlocks: ConversationBlock[] = step.toolResults.map((tr) => {\n const outputStr =\n typeof tr.output === 'string' ? tr.output : JSON.stringify(tr.output);\n const isError = detectMcpToolError(tr.output) !== null;\n return {\n type: 'tool_result' as const,\n toolUseId: tr.toolCallId,\n content: outputStr,\n ...(isError ? { isError: true } : {})\n };\n });\n messages.push({\n role: 'user',\n content: resultBlocks,\n timestamp: stepTimestamp\n });\n }\n }\n\n return messages;\n}\n", "import type {\n AgentAdapter,\n AgentExecutionContext,\n AgentExecutionResult\n} from '@wix/evalforge-types';\nimport type { AgentRunCommand } from '@wix/evalforge-types';\nimport { executeWithAiSdk } from './execute.js';\n\n/**\n * Simple Agent adapter.\n *\n * Executes LLM calls in-process via the Vercel AI SDK, routing through\n * our proxy to support both Claude and OpenAI models. Supports MCP tools\n * for interacting with the working directory.\n *\n * Looked up by adapter ID (not CLI command) since SDK agents have\n * empty supportedCommands.\n */\nexport class SimpleAgentAdapter implements AgentAdapter {\n readonly id = 'simple-agent';\n readonly name = 'Simple Agent';\n readonly supportedCommands: readonly AgentRunCommand[] = [];\n\n async execute(context: AgentExecutionContext): Promise<AgentExecutionResult> {\n return executeWithAiSdk(context);\n }\n}\n\nexport const simpleAgentAdapter = new SimpleAgentAdapter();\n", "import { defaultRegistry } from '../registry.js';\nimport { simpleAgentAdapter } from './simple-agent-adapter.js';\n\ndefaultRegistry.register(simpleAgentAdapter);\n", "/**\n * File diff utilities for capturing and comparing file changes.\n *\n * Used to track changes made by Claude during scenario execution\n * when running against a template.\n */\n\nimport { readdirSync, readFileSync, statSync, existsSync } from 'fs';\nimport { join, relative } from 'path';\nimport { diffLines as computeDiff } from 'diff';\nimport type { DiffContent, DiffLine, TemplateFile } from '@wix/evalforge-types';\n\n/**\n * Derive the set of infrastructure file paths by comparing a pre-prepare\n * snapshot with the post-prepare (baseline) snapshot.\n * Any file that was created or modified by `prepareEnvironment()` is infrastructure.\n */\nexport function deriveInfrastructurePaths(\n prePrep: FileSnapshot,\n postPrep: FileSnapshot\n): Set<string> {\n const infraPaths = new Set<string>();\n for (const path of Object.keys(postPrep)) {\n if (prePrep[path] === undefined || prePrep[path] !== postPrep[path]) {\n infraPaths.add(path);\n }\n }\n return infraPaths;\n}\n\n/**\n * A snapshot of file contents in a directory.\n * Maps relative file paths to their contents.\n */\nexport interface FileSnapshot {\n [relativePath: string]: string;\n}\n\n/**\n * Directories and patterns to ignore when snapshotting.\n */\nconst IGNORED_PATTERNS = [\n 'node_modules',\n '.git',\n '.cursor',\n 'dist',\n 'build',\n '.next',\n '.turbo',\n '__pycache__',\n '.pytest_cache',\n '.venv',\n 'venv',\n '.DS_Store'\n];\n\n/**\n * File extensions to treat as binary (skip content reading).\n */\nconst BINARY_EXTENSIONS = [\n '.png',\n '.jpg',\n '.jpeg',\n '.gif',\n '.webp',\n '.ico',\n '.svg',\n '.woff',\n '.woff2',\n '.ttf',\n '.eot',\n '.mp3',\n '.mp4',\n '.wav',\n '.avi',\n '.mov',\n '.pdf',\n '.zip',\n '.tar',\n '.gz',\n '.rar',\n '.7z',\n '.exe',\n '.dll',\n '.so',\n '.dylib'\n];\n\n/**\n * Maximum file size to read (100KB).\n * Larger files are skipped to avoid memory issues.\n */\nconst MAX_FILE_SIZE = 100 * 1024;\n\n/**\n * Check if a path should be ignored.\n */\nfunction shouldIgnore(name: string): boolean {\n return IGNORED_PATTERNS.some(\n (pattern) => name === pattern || name.startsWith(pattern + '/')\n );\n}\n\n/**\n * Check if a file is binary based on extension.\n */\nfunction isBinaryFile(filename: string): boolean {\n const lower = filename.toLowerCase();\n return BINARY_EXTENSIONS.some((ext) => lower.endsWith(ext));\n}\n\n/**\n * Recursively snapshot a directory.\n *\n * @param dir - The directory to snapshot\n * @param baseDir - The base directory for computing relative paths\n * @returns A map of relative paths to file contents\n */\nexport function snapshotDirectory(dir: string, baseDir?: string): FileSnapshot {\n const snapshot: FileSnapshot = {};\n const base = baseDir || dir;\n\n if (!existsSync(dir)) {\n return snapshot;\n }\n\n const entries = readdirSync(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = join(dir, entry.name);\n const relativePath = relative(base, fullPath);\n\n // Skip ignored directories and files\n if (shouldIgnore(entry.name)) {\n continue;\n }\n\n if (entry.isDirectory()) {\n // Recursively snapshot subdirectories\n const subSnapshot = snapshotDirectory(fullPath, base);\n Object.assign(snapshot, subSnapshot);\n } else if (entry.isFile()) {\n // Skip binary files\n if (isBinaryFile(entry.name)) {\n continue;\n }\n\n // Skip files that are too large\n try {\n const stats = statSync(fullPath);\n if (stats.size > MAX_FILE_SIZE) {\n continue;\n }\n\n // Read file contents\n const content = readFileSync(fullPath, 'utf-8');\n snapshot[relativePath] = content;\n } catch {\n // Skip files that can't be read\n continue;\n }\n }\n }\n\n return snapshot;\n}\n\n/**\n * Generate diff lines from before/after content using the Myers diff algorithm.\n * This correctly identifies the minimal set of changes by comparing content,\n * not just line positions.\n */\nfunction generateDiffLines(before: string, after: string): DiffLine[] {\n const changes = computeDiff(before, after);\n const result: DiffLine[] = [];\n let lineNumber = 1;\n\n for (const change of changes) {\n // Remove trailing newline and split into individual lines\n const lines = change.value.replace(/\\n$/, '').split('\\n');\n const type: DiffLine['type'] = change.added\n ? 'added'\n : change.removed\n ? 'removed'\n : 'unchanged';\n\n for (const content of lines) {\n result.push({\n type,\n content,\n lineNumber: lineNumber++\n });\n }\n }\n\n return result;\n}\n\n/**\n * Compare two snapshots and generate diffs for changed files.\n * Includes new empty files and detects file renames.\n *\n * @param before - Snapshot before execution\n * @param after - Snapshot after execution\n * @param infrastructurePaths - Optional set of paths known to be infrastructure files\n * @returns Array of DiffContent for files that were created, modified, or renamed\n */\nexport function diffSnapshots(\n before: FileSnapshot,\n after: FileSnapshot,\n infrastructurePaths?: Set<string>\n): DiffContent[] {\n const diffs: DiffContent[] = [];\n const allPaths = new Set([...Object.keys(before), ...Object.keys(after)]);\n\n for (const path of allPaths) {\n const beforeContent = before[path] ?? '';\n const afterContent = after[path] ?? '';\n\n // Skip when it's an existing file with no changes.\n if (before[path] !== undefined && beforeContent === afterContent) {\n continue;\n }\n\n // Generate diff\n const diffLines = generateDiffLines(beforeContent, afterContent);\n\n diffs.push({\n path,\n expected: beforeContent,\n actual: afterContent,\n diffLines,\n ...(infrastructurePaths?.has(path) && { isInfrastructure: true })\n });\n }\n\n const deletedPaths = [...allPaths].filter((p) => after[p] === undefined);\n const addedPaths = [...allPaths].filter((p) => before[p] === undefined);\n\n const renamedFromByNewPath = new Map<string, string>();\n const deletedPathsToRemove = new Set<string>();\n\n for (const addedPath of addedPaths) {\n const addedContent = after[addedPath] ?? '';\n const deletedMatch = deletedPaths.find(\n (dp) =>\n (before[dp] ?? '') === addedContent && !deletedPathsToRemove.has(dp)\n );\n if (deletedMatch) {\n renamedFromByNewPath.set(addedPath, deletedMatch);\n deletedPathsToRemove.add(deletedMatch);\n }\n }\n\n const result = diffs\n .filter((d) => !deletedPathsToRemove.has(d.path))\n .map((d) => {\n const renamedFrom = renamedFromByNewPath.get(d.path);\n return renamedFrom ? { ...d, renamedFrom } : d;\n });\n\n // Sort by path for consistent ordering\n result.sort((a, b) => a.path.localeCompare(b.path));\n\n return result;\n}\n\n/**\n * Extract template files with their status from before/after snapshots.\n *\n * @param before - Snapshot before execution\n * @param after - Snapshot after execution\n * @param infrastructurePaths - Optional set of paths known to be infrastructure files\n * @returns Array of TemplateFile with status indicators\n */\nexport function extractTemplateFiles(\n before: FileSnapshot,\n after: FileSnapshot,\n infrastructurePaths?: Set<string>\n): TemplateFile[] {\n const files: TemplateFile[] = [];\n const allPaths = new Set([...Object.keys(before), ...Object.keys(after)]);\n\n for (const path of allPaths) {\n const beforeContent = before[path];\n const afterContent = after[path];\n\n // Only include files that exist after execution (skip deleted files)\n if (afterContent === undefined) {\n continue;\n }\n\n let status: 'new' | 'modified' | 'unchanged';\n if (beforeContent === undefined) {\n status = 'new';\n } else if (beforeContent !== afterContent) {\n status = 'modified';\n } else {\n status = 'unchanged';\n }\n\n files.push({\n path,\n content: afterContent,\n status,\n ...(infrastructurePaths?.has(path) && { isInfrastructure: true })\n });\n }\n\n // Sort by path for consistent ordering\n files.sort((a, b) => a.path.localeCompare(b.path));\n\n return files;\n}\n", "function Diff() {}\nDiff.prototype = {\n diff: function diff(oldString, newString) {\n var _options$timeout;\n var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n var callback = options.callback;\n if (typeof options === 'function') {\n callback = options;\n options = {};\n }\n var self = this;\n function done(value) {\n value = self.postProcess(value, options);\n if (callback) {\n setTimeout(function () {\n callback(value);\n }, 0);\n return true;\n } else {\n return value;\n }\n }\n\n // Allow subclasses to massage the input prior to running\n oldString = this.castInput(oldString, options);\n newString = this.castInput(newString, options);\n oldString = this.removeEmpty(this.tokenize(oldString, options));\n newString = this.removeEmpty(this.tokenize(newString, options));\n var newLen = newString.length,\n oldLen = oldString.length;\n var editLength = 1;\n var maxEditLength = newLen + oldLen;\n if (options.maxEditLength != null) {\n maxEditLength = Math.min(maxEditLength, options.maxEditLength);\n }\n var maxExecutionTime = (_options$timeout = options.timeout) !== null && _options$timeout !== void 0 ? _options$timeout : Infinity;\n var abortAfterTimestamp = Date.now() + maxExecutionTime;\n var bestPath = [{\n oldPos: -1,\n lastComponent: undefined\n }];\n\n // Seed editLength = 0, i.e. the content starts with the same values\n var newPos = this.extractCommon(bestPath[0], newString, oldString, 0, options);\n if (bestPath[0].oldPos + 1 >= oldLen && newPos + 1 >= newLen) {\n // Identity per the equality and tokenizer\n return done(buildValues(self, bestPath[0].lastComponent, newString, oldString, self.useLongestToken));\n }\n\n // Once we hit the right edge of the edit graph on some diagonal k, we can\n // definitely reach the end of the edit graph in no more than k edits, so\n // there's no point in considering any moves to diagonal k+1 any more (from\n // which we're guaranteed to need at least k+1 more edits).\n // Similarly, once we've reached the bottom of the edit graph, there's no\n // point considering moves to lower diagonals.\n // We record this fact by setting minDiagonalToConsider and\n // maxDiagonalToConsider to some finite value once we've hit the edge of\n // the edit graph.\n // This optimization is not faithful to the original algorithm presented in\n // Myers's paper, which instead pointlessly extends D-paths off the end of\n // the edit graph - see page 7 of Myers's paper which notes this point\n // explicitly and illustrates it with a diagram. This has major performance\n // implications for some common scenarios. For instance, to compute a diff\n // where the new text simply appends d characters on the end of the\n // original text of length n, the true Myers algorithm will take O(n+d^2)\n // time while this optimization needs only O(n+d) time.\n var minDiagonalToConsider = -Infinity,\n maxDiagonalToConsider = Infinity;\n\n // Main worker method. checks all permutations of a given edit length for acceptance.\n function execEditLength() {\n for (var diagonalPath = Math.max(minDiagonalToConsider, -editLength); diagonalPath <= Math.min(maxDiagonalToConsider, editLength); diagonalPath += 2) {\n var basePath = void 0;\n var removePath = bestPath[diagonalPath - 1],\n addPath = bestPath[diagonalPath + 1];\n if (removePath) {\n // No one else is going to attempt to use this value, clear it\n bestPath[diagonalPath - 1] = undefined;\n }\n var canAdd = false;\n if (addPath) {\n // what newPos will be after we do an insertion:\n var addPathNewPos = addPath.oldPos - diagonalPath;\n canAdd = addPath && 0 <= addPathNewPos && addPathNewPos < newLen;\n }\n var canRemove = removePath && removePath.oldPos + 1 < oldLen;\n if (!canAdd && !canRemove) {\n // If this path is a terminal then prune\n bestPath[diagonalPath] = undefined;\n continue;\n }\n\n // Select the diagonal that we want to branch from. We select the prior\n // path whose position in the old string is the farthest from the origin\n // and does not pass the bounds of the diff graph\n if (!canRemove || canAdd && removePath.oldPos < addPath.oldPos) {\n basePath = self.addToPath(addPath, true, false, 0, options);\n } else {\n basePath = self.addToPath(removePath, false, true, 1, options);\n }\n newPos = self.extractCommon(basePath, newString, oldString, diagonalPath, options);\n if (basePath.oldPos + 1 >= oldLen && newPos + 1 >= newLen) {\n // If we have hit the end of both strings, then we are done\n return done(buildValues(self, basePath.lastComponent, newString, oldString, self.useLongestToken));\n } else {\n bestPath[diagonalPath] = basePath;\n if (basePath.oldPos + 1 >= oldLen) {\n maxDiagonalToConsider = Math.min(maxDiagonalToConsider, diagonalPath - 1);\n }\n if (newPos + 1 >= newLen) {\n minDiagonalToConsider = Math.max(minDiagonalToConsider, diagonalPath + 1);\n }\n }\n }\n editLength++;\n }\n\n // Performs the length of edit iteration. Is a bit fugly as this has to support the\n // sync and async mode which is never fun. Loops over execEditLength until a value\n // is produced, or until the edit length exceeds options.maxEditLength (if given),\n // in which case it will return undefined.\n if (callback) {\n (function exec() {\n setTimeout(function () {\n if (editLength > maxEditLength || Date.now() > abortAfterTimestamp) {\n return callback();\n }\n if (!execEditLength()) {\n exec();\n }\n }, 0);\n })();\n } else {\n while (editLength <= maxEditLength && Date.now() <= abortAfterTimestamp) {\n var ret = execEditLength();\n if (ret) {\n return ret;\n }\n }\n }\n },\n addToPath: function addToPath(path, added, removed, oldPosInc, options) {\n var last = path.lastComponent;\n if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {\n return {\n oldPos: path.oldPos + oldPosInc,\n lastComponent: {\n count: last.count + 1,\n added: added,\n removed: removed,\n previousComponent: last.previousComponent\n }\n };\n } else {\n return {\n oldPos: path.oldPos + oldPosInc,\n lastComponent: {\n count: 1,\n added: added,\n removed: removed,\n previousComponent: last\n }\n };\n }\n },\n extractCommon: function extractCommon(basePath, newString, oldString, diagonalPath, options) {\n var newLen = newString.length,\n oldLen = oldString.length,\n oldPos = basePath.oldPos,\n newPos = oldPos - diagonalPath,\n commonCount = 0;\n while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(oldString[oldPos + 1], newString[newPos + 1], options)) {\n newPos++;\n oldPos++;\n commonCount++;\n if (options.oneChangePerToken) {\n basePath.lastComponent = {\n count: 1,\n previousComponent: basePath.lastComponent,\n added: false,\n removed: false\n };\n }\n }\n if (commonCount && !options.oneChangePerToken) {\n basePath.lastComponent = {\n count: commonCount,\n previousComponent: basePath.lastComponent,\n added: false,\n removed: false\n };\n }\n basePath.oldPos = oldPos;\n return newPos;\n },\n equals: function equals(left, right, options) {\n if (options.comparator) {\n return options.comparator(left, right);\n } else {\n return left === right || options.ignoreCase && left.toLowerCase() === right.toLowerCase();\n }\n },\n removeEmpty: function removeEmpty(array) {\n var ret = [];\n for (var i = 0; i < array.length; i++) {\n if (array[i]) {\n ret.push(array[i]);\n }\n }\n return ret;\n },\n castInput: function castInput(value) {\n return value;\n },\n tokenize: function tokenize(value) {\n return Array.from(value);\n },\n join: function join(chars) {\n return chars.join('');\n },\n postProcess: function postProcess(changeObjects) {\n return changeObjects;\n }\n};\nfunction buildValues(diff, lastComponent, newString, oldString, useLongestToken) {\n // First we convert our linked list of components in reverse order to an\n // array in the right order:\n var components = [];\n var nextComponent;\n while (lastComponent) {\n components.push(lastComponent);\n nextComponent = lastComponent.previousComponent;\n delete lastComponent.previousComponent;\n lastComponent = nextComponent;\n }\n components.reverse();\n var componentPos = 0,\n componentLen = components.length,\n newPos = 0,\n oldPos = 0;\n for (; componentPos < componentLen; componentPos++) {\n var component = components[componentPos];\n if (!component.removed) {\n if (!component.added && useLongestToken) {\n var value = newString.slice(newPos, newPos + component.count);\n value = value.map(function (value, i) {\n var oldValue = oldString[oldPos + i];\n return oldValue.length > value.length ? oldValue : value;\n });\n component.value = diff.join(value);\n } else {\n component.value = diff.join(newString.slice(newPos, newPos + component.count));\n }\n newPos += component.count;\n\n // Common case\n if (!component.added) {\n oldPos += component.count;\n }\n } else {\n component.value = diff.join(oldString.slice(oldPos, oldPos + component.count));\n oldPos += component.count;\n }\n }\n return components;\n}\n\nvar characterDiff = new Diff();\nfunction diffChars(oldStr, newStr, options) {\n return characterDiff.diff(oldStr, newStr, options);\n}\n\nfunction longestCommonPrefix(str1, str2) {\n var i;\n for (i = 0; i < str1.length && i < str2.length; i++) {\n if (str1[i] != str2[i]) {\n return str1.slice(0, i);\n }\n }\n return str1.slice(0, i);\n}\nfunction longestCommonSuffix(str1, str2) {\n var i;\n\n // Unlike longestCommonPrefix, we need a special case to handle all scenarios\n // where we return the empty string since str1.slice(-0) will return the\n // entire string.\n if (!str1 || !str2 || str1[str1.length - 1] != str2[str2.length - 1]) {\n return '';\n }\n for (i = 0; i < str1.length && i < str2.length; i++) {\n if (str1[str1.length - (i + 1)] != str2[str2.length - (i + 1)]) {\n return str1.slice(-i);\n }\n }\n return str1.slice(-i);\n}\nfunction replacePrefix(string, oldPrefix, newPrefix) {\n if (string.slice(0, oldPrefix.length) != oldPrefix) {\n throw Error(\"string \".concat(JSON.stringify(string), \" doesn't start with prefix \").concat(JSON.stringify(oldPrefix), \"; this is a bug\"));\n }\n return newPrefix + string.slice(oldPrefix.length);\n}\nfunction replaceSuffix(string, oldSuffix, newSuffix) {\n if (!oldSuffix) {\n return string + newSuffix;\n }\n if (string.slice(-oldSuffix.length) != oldSuffix) {\n throw Error(\"string \".concat(JSON.stringify(string), \" doesn't end with suffix \").concat(JSON.stringify(oldSuffix), \"; this is a bug\"));\n }\n return string.slice(0, -oldSuffix.length) + newSuffix;\n}\nfunction removePrefix(string, oldPrefix) {\n return replacePrefix(string, oldPrefix, '');\n}\nfunction removeSuffix(string, oldSuffix) {\n return replaceSuffix(string, oldSuffix, '');\n}\nfunction maximumOverlap(string1, string2) {\n return string2.slice(0, overlapCount(string1, string2));\n}\n\n// Nicked from https://stackoverflow.com/a/60422853/1709587\nfunction overlapCount(a, b) {\n // Deal with cases where the strings differ in length\n var startA = 0;\n if (a.length > b.length) {\n startA = a.length - b.length;\n }\n var endB = b.length;\n if (a.length < b.length) {\n endB = a.length;\n }\n // Create a back-reference for each index\n // that should be followed in case of a mismatch.\n // We only need B to make these references:\n var map = Array(endB);\n var k = 0; // Index that lags behind j\n map[0] = 0;\n for (var j = 1; j < endB; j++) {\n if (b[j] == b[k]) {\n map[j] = map[k]; // skip over the same character (optional optimisation)\n } else {\n map[j] = k;\n }\n while (k > 0 && b[j] != b[k]) {\n k = map[k];\n }\n if (b[j] == b[k]) {\n k++;\n }\n }\n // Phase 2: use these references while iterating over A\n k = 0;\n for (var i = startA; i < a.length; i++) {\n while (k > 0 && a[i] != b[k]) {\n k = map[k];\n }\n if (a[i] == b[k]) {\n k++;\n }\n }\n return k;\n}\n\n/**\n * Returns true if the string consistently uses Windows line endings.\n */\nfunction hasOnlyWinLineEndings(string) {\n return string.includes('\\r\\n') && !string.startsWith('\\n') && !string.match(/[^\\r]\\n/);\n}\n\n/**\n * Returns true if the string consistently uses Unix line endings.\n */\nfunction hasOnlyUnixLineEndings(string) {\n return !string.includes('\\r\\n') && string.includes('\\n');\n}\n\n// Based on https://en.wikipedia.org/wiki/Latin_script_in_Unicode\n//\n// Ranges and exceptions:\n// Latin-1 Supplement, 0080\u201300FF\n// - U+00D7 \u00D7 Multiplication sign\n// - U+00F7 \u00F7 Division sign\n// Latin Extended-A, 0100\u2013017F\n// Latin Extended-B, 0180\u2013024F\n// IPA Extensions, 0250\u201302AF\n// Spacing Modifier Letters, 02B0\u201302FF\n// - U+02C7 \u02C7 &#711; Caron\n// - U+02D8 \u02D8 &#728; Breve\n// - U+02D9 \u02D9 &#729; Dot Above\n// - U+02DA \u02DA &#730; Ring Above\n// - U+02DB \u02DB &#731; Ogonek\n// - U+02DC \u02DC &#732; Small Tilde\n// - U+02DD \u02DD &#733; Double Acute Accent\n// Latin Extended Additional, 1E00\u20131EFF\nvar extendedWordChars = \"a-zA-Z0-9_\\\\u{C0}-\\\\u{FF}\\\\u{D8}-\\\\u{F6}\\\\u{F8}-\\\\u{2C6}\\\\u{2C8}-\\\\u{2D7}\\\\u{2DE}-\\\\u{2FF}\\\\u{1E00}-\\\\u{1EFF}\";\n\n// Each token is one of the following:\n// - A punctuation mark plus the surrounding whitespace\n// - A word plus the surrounding whitespace\n// - Pure whitespace (but only in the special case where this the entire text\n// is just whitespace)\n//\n// We have to include surrounding whitespace in the tokens because the two\n// alternative approaches produce horribly broken results:\n// * If we just discard the whitespace, we can't fully reproduce the original\n// text from the sequence of tokens and any attempt to render the diff will\n// get the whitespace wrong.\n// * If we have separate tokens for whitespace, then in a typical text every\n// second token will be a single space character. But this often results in\n// the optimal diff between two texts being a perverse one that preserves\n// the spaces between words but deletes and reinserts actual common words.\n// See https://github.com/kpdecker/jsdiff/issues/160#issuecomment-1866099640\n// for an example.\n//\n// Keeping the surrounding whitespace of course has implications for .equals\n// and .join, not just .tokenize.\n\n// This regex does NOT fully implement the tokenization rules described above.\n// Instead, it gives runs of whitespace their own \"token\". The tokenize method\n// then handles stitching whitespace tokens onto adjacent word or punctuation\n// tokens.\nvar tokenizeIncludingWhitespace = new RegExp(\"[\".concat(extendedWordChars, \"]+|\\\\s+|[^\").concat(extendedWordChars, \"]\"), 'ug');\nvar wordDiff = new Diff();\nwordDiff.equals = function (left, right, options) {\n if (options.ignoreCase) {\n left = left.toLowerCase();\n right = right.toLowerCase();\n }\n return left.trim() === right.trim();\n};\nwordDiff.tokenize = function (value) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n var parts;\n if (options.intlSegmenter) {\n if (options.intlSegmenter.resolvedOptions().granularity != 'word') {\n throw new Error('The segmenter passed must have a granularity of \"word\"');\n }\n parts = Array.from(options.intlSegmenter.segment(value), function (segment) {\n return segment.segment;\n });\n } else {\n parts = value.match(tokenizeIncludingWhitespace) || [];\n }\n var tokens = [];\n var prevPart = null;\n parts.forEach(function (part) {\n if (/\\s/.test(part)) {\n if (prevPart == null) {\n tokens.push(part);\n } else {\n tokens.push(tokens.pop() + part);\n }\n } else if (/\\s/.test(prevPart)) {\n if (tokens[tokens.length - 1] == prevPart) {\n tokens.push(tokens.pop() + part);\n } else {\n tokens.push(prevPart + part);\n }\n } else {\n tokens.push(part);\n }\n prevPart = part;\n });\n return tokens;\n};\nwordDiff.join = function (tokens) {\n // Tokens being joined here will always have appeared consecutively in the\n // same text, so we can simply strip off the leading whitespace from all the\n // tokens except the first (and except any whitespace-only tokens - but such\n // a token will always be the first and only token anyway) and then join them\n // and the whitespace around words and punctuation will end up correct.\n return tokens.map(function (token, i) {\n if (i == 0) {\n return token;\n } else {\n return token.replace(/^\\s+/, '');\n }\n }).join('');\n};\nwordDiff.postProcess = function (changes, options) {\n if (!changes || options.oneChangePerToken) {\n return changes;\n }\n var lastKeep = null;\n // Change objects representing any insertion or deletion since the last\n // \"keep\" change object. There can be at most one of each.\n var insertion = null;\n var deletion = null;\n changes.forEach(function (change) {\n if (change.added) {\n insertion = change;\n } else if (change.removed) {\n deletion = change;\n } else {\n if (insertion || deletion) {\n // May be false at start of text\n dedupeWhitespaceInChangeObjects(lastKeep, deletion, insertion, change);\n }\n lastKeep = change;\n insertion = null;\n deletion = null;\n }\n });\n if (insertion || deletion) {\n dedupeWhitespaceInChangeObjects(lastKeep, deletion, insertion, null);\n }\n return changes;\n};\nfunction diffWords(oldStr, newStr, options) {\n // This option has never been documented and never will be (it's clearer to\n // just call `diffWordsWithSpace` directly if you need that behavior), but\n // has existed in jsdiff for a long time, so we retain support for it here\n // for the sake of backwards compatibility.\n if ((options === null || options === void 0 ? void 0 : options.ignoreWhitespace) != null && !options.ignoreWhitespace) {\n return diffWordsWithSpace(oldStr, newStr, options);\n }\n return wordDiff.diff(oldStr, newStr, options);\n}\nfunction dedupeWhitespaceInChangeObjects(startKeep, deletion, insertion, endKeep) {\n // Before returning, we tidy up the leading and trailing whitespace of the\n // change objects to eliminate cases where trailing whitespace in one object\n // is repeated as leading whitespace in the next.\n // Below are examples of the outcomes we want here to explain the code.\n // I=insert, K=keep, D=delete\n // 1. diffing 'foo bar baz' vs 'foo baz'\n // Prior to cleanup, we have K:'foo ' D:' bar ' K:' baz'\n // After cleanup, we want: K:'foo ' D:'bar ' K:'baz'\n //\n // 2. Diffing 'foo bar baz' vs 'foo qux baz'\n // Prior to cleanup, we have K:'foo ' D:' bar ' I:' qux ' K:' baz'\n // After cleanup, we want K:'foo ' D:'bar' I:'qux' K:' baz'\n //\n // 3. Diffing 'foo\\nbar baz' vs 'foo baz'\n // Prior to cleanup, we have K:'foo ' D:'\\nbar ' K:' baz'\n // After cleanup, we want K'foo' D:'\\nbar' K:' baz'\n //\n // 4. Diffing 'foo baz' vs 'foo\\nbar baz'\n // Prior to cleanup, we have K:'foo\\n' I:'\\nbar ' K:' baz'\n // After cleanup, we ideally want K'foo' I:'\\nbar' K:' baz'\n // but don't actually manage this currently (the pre-cleanup change\n // objects don't contain enough information to make it possible).\n //\n // 5. Diffing 'foo bar baz' vs 'foo baz'\n // Prior to cleanup, we have K:'foo ' D:' bar ' K:' baz'\n // After cleanup, we want K:'foo ' D:' bar ' K:'baz'\n //\n // Our handling is unavoidably imperfect in the case where there's a single\n // indel between keeps and the whitespace has changed. For instance, consider\n // diffing 'foo\\tbar\\nbaz' vs 'foo baz'. Unless we create an extra change\n // object to represent the insertion of the space character (which isn't even\n // a token), we have no way to avoid losing information about the texts'\n // original whitespace in the result we return. Still, we do our best to\n // output something that will look sensible if we e.g. print it with\n // insertions in green and deletions in red.\n\n // Between two \"keep\" change objects (or before the first or after the last\n // change object), we can have either:\n // * A \"delete\" followed by an \"insert\"\n // * Just an \"insert\"\n // * Just a \"delete\"\n // We handle the three cases separately.\n if (deletion && insertion) {\n var oldWsPrefix = deletion.value.match(/^\\s*/)[0];\n var oldWsSuffix = deletion.value.match(/\\s*$/)[0];\n var newWsPrefix = insertion.value.match(/^\\s*/)[0];\n var newWsSuffix = insertion.value.match(/\\s*$/)[0];\n if (startKeep) {\n var commonWsPrefix = longestCommonPrefix(oldWsPrefix, newWsPrefix);\n startKeep.value = replaceSuffix(startKeep.value, newWsPrefix, commonWsPrefix);\n deletion.value = removePrefix(deletion.value, commonWsPrefix);\n insertion.value = removePrefix(insertion.value, commonWsPrefix);\n }\n if (endKeep) {\n var commonWsSuffix = longestCommonSuffix(oldWsSuffix, newWsSuffix);\n endKeep.value = replacePrefix(endKeep.value, newWsSuffix, commonWsSuffix);\n deletion.value = removeSuffix(deletion.value, commonWsSuffix);\n insertion.value = removeSuffix(insertion.value, commonWsSuffix);\n }\n } else if (insertion) {\n // The whitespaces all reflect what was in the new text rather than\n // the old, so we essentially have no information about whitespace\n // insertion or deletion. We just want to dedupe the whitespace.\n // We do that by having each change object keep its trailing\n // whitespace and deleting duplicate leading whitespace where\n // present.\n if (startKeep) {\n insertion.value = insertion.value.replace(/^\\s*/, '');\n }\n if (endKeep) {\n endKeep.value = endKeep.value.replace(/^\\s*/, '');\n }\n // otherwise we've got a deletion and no insertion\n } else if (startKeep && endKeep) {\n var newWsFull = endKeep.value.match(/^\\s*/)[0],\n delWsStart = deletion.value.match(/^\\s*/)[0],\n delWsEnd = deletion.value.match(/\\s*$/)[0];\n\n // Any whitespace that comes straight after startKeep in both the old and\n // new texts, assign to startKeep and remove from the deletion.\n var newWsStart = longestCommonPrefix(newWsFull, delWsStart);\n deletion.value = removePrefix(deletion.value, newWsStart);\n\n // Any whitespace that comes straight before endKeep in both the old and\n // new texts, and hasn't already been assigned to startKeep, assign to\n // endKeep and remove from the deletion.\n var newWsEnd = longestCommonSuffix(removePrefix(newWsFull, newWsStart), delWsEnd);\n deletion.value = removeSuffix(deletion.value, newWsEnd);\n endKeep.value = replacePrefix(endKeep.value, newWsFull, newWsEnd);\n\n // If there's any whitespace from the new text that HASN'T already been\n // assigned, assign it to the start:\n startKeep.value = replaceSuffix(startKeep.value, newWsFull, newWsFull.slice(0, newWsFull.length - newWsEnd.length));\n } else if (endKeep) {\n // We are at the start of the text. Preserve all the whitespace on\n // endKeep, and just remove whitespace from the end of deletion to the\n // extent that it overlaps with the start of endKeep.\n var endKeepWsPrefix = endKeep.value.match(/^\\s*/)[0];\n var deletionWsSuffix = deletion.value.match(/\\s*$/)[0];\n var overlap = maximumOverlap(deletionWsSuffix, endKeepWsPrefix);\n deletion.value = removeSuffix(deletion.value, overlap);\n } else if (startKeep) {\n // We are at the END of the text. Preserve all the whitespace on\n // startKeep, and just remove whitespace from the start of deletion to\n // the extent that it overlaps with the end of startKeep.\n var startKeepWsSuffix = startKeep.value.match(/\\s*$/)[0];\n var deletionWsPrefix = deletion.value.match(/^\\s*/)[0];\n var _overlap = maximumOverlap(startKeepWsSuffix, deletionWsPrefix);\n deletion.value = removePrefix(deletion.value, _overlap);\n }\n}\nvar wordWithSpaceDiff = new Diff();\nwordWithSpaceDiff.tokenize = function (value) {\n // Slightly different to the tokenizeIncludingWhitespace regex used above in\n // that this one treats each individual newline as a distinct tokens, rather\n // than merging them into other surrounding whitespace. This was requested\n // in https://github.com/kpdecker/jsdiff/issues/180 &\n // https://github.com/kpdecker/jsdiff/issues/211\n var regex = new RegExp(\"(\\\\r?\\\\n)|[\".concat(extendedWordChars, \"]+|[^\\\\S\\\\n\\\\r]+|[^\").concat(extendedWordChars, \"]\"), 'ug');\n return value.match(regex) || [];\n};\nfunction diffWordsWithSpace(oldStr, newStr, options) {\n return wordWithSpaceDiff.diff(oldStr, newStr, options);\n}\n\nfunction generateOptions(options, defaults) {\n if (typeof options === 'function') {\n defaults.callback = options;\n } else if (options) {\n for (var name in options) {\n /* istanbul ignore else */\n if (options.hasOwnProperty(name)) {\n defaults[name] = options[name];\n }\n }\n }\n return defaults;\n}\n\nvar lineDiff = new Diff();\nlineDiff.tokenize = function (value, options) {\n if (options.stripTrailingCr) {\n // remove one \\r before \\n to match GNU diff's --strip-trailing-cr behavior\n value = value.replace(/\\r\\n/g, '\\n');\n }\n var retLines = [],\n linesAndNewlines = value.split(/(\\n|\\r\\n)/);\n\n // Ignore the final empty token that occurs if the string ends with a new line\n if (!linesAndNewlines[linesAndNewlines.length - 1]) {\n linesAndNewlines.pop();\n }\n\n // Merge the content and line separators into single tokens\n for (var i = 0; i < linesAndNewlines.length; i++) {\n var line = linesAndNewlines[i];\n if (i % 2 && !options.newlineIsToken) {\n retLines[retLines.length - 1] += line;\n } else {\n retLines.push(line);\n }\n }\n return retLines;\n};\nlineDiff.equals = function (left, right, options) {\n // If we're ignoring whitespace, we need to normalise lines by stripping\n // whitespace before checking equality. (This has an annoying interaction\n // with newlineIsToken that requires special handling: if newlines get their\n // own token, then we DON'T want to trim the *newline* tokens down to empty\n // strings, since this would cause us to treat whitespace-only line content\n // as equal to a separator between lines, which would be weird and\n // inconsistent with the documented behavior of the options.)\n if (options.ignoreWhitespace) {\n if (!options.newlineIsToken || !left.includes('\\n')) {\n left = left.trim();\n }\n if (!options.newlineIsToken || !right.includes('\\n')) {\n right = right.trim();\n }\n } else if (options.ignoreNewlineAtEof && !options.newlineIsToken) {\n if (left.endsWith('\\n')) {\n left = left.slice(0, -1);\n }\n if (right.endsWith('\\n')) {\n right = right.slice(0, -1);\n }\n }\n return Diff.prototype.equals.call(this, left, right, options);\n};\nfunction diffLines(oldStr, newStr, callback) {\n return lineDiff.diff(oldStr, newStr, callback);\n}\n\n// Kept for backwards compatibility. This is a rather arbitrary wrapper method\n// that just calls `diffLines` with `ignoreWhitespace: true`. It's confusing to\n// have two ways to do exactly the same thing in the API, so we no longer\n// document this one (library users should explicitly use `diffLines` with\n// `ignoreWhitespace: true` instead) but we keep it around to maintain\n// compatibility with code that used old versions.\nfunction diffTrimmedLines(oldStr, newStr, callback) {\n var options = generateOptions(callback, {\n ignoreWhitespace: true\n });\n return lineDiff.diff(oldStr, newStr, options);\n}\n\nvar sentenceDiff = new Diff();\nsentenceDiff.tokenize = function (value) {\n return value.split(/(\\S.+?[.!?])(?=\\s+|$)/);\n};\nfunction diffSentences(oldStr, newStr, callback) {\n return sentenceDiff.diff(oldStr, newStr, callback);\n}\n\nvar cssDiff = new Diff();\ncssDiff.tokenize = function (value) {\n return value.split(/([{}:;,]|\\s+)/);\n};\nfunction diffCss(oldStr, newStr, callback) {\n return cssDiff.diff(oldStr, newStr, callback);\n}\n\nfunction ownKeys(e, r) {\n var t = Object.keys(e);\n if (Object.getOwnPropertySymbols) {\n var o = Object.getOwnPropertySymbols(e);\n r && (o = o.filter(function (r) {\n return Object.getOwnPropertyDescriptor(e, r).enumerable;\n })), t.push.apply(t, o);\n }\n return t;\n}\nfunction _objectSpread2(e) {\n for (var r = 1; r < arguments.length; r++) {\n var t = null != arguments[r] ? arguments[r] : {};\n r % 2 ? ownKeys(Object(t), !0).forEach(function (r) {\n _defineProperty(e, r, t[r]);\n }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {\n Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));\n });\n }\n return e;\n}\nfunction _toPrimitive(t, r) {\n if (\"object\" != typeof t || !t) return t;\n var e = t[Symbol.toPrimitive];\n if (void 0 !== e) {\n var i = e.call(t, r || \"default\");\n if (\"object\" != typeof i) return i;\n throw new TypeError(\"@@toPrimitive must return a primitive value.\");\n }\n return (\"string\" === r ? String : Number)(t);\n}\nfunction _toPropertyKey(t) {\n var i = _toPrimitive(t, \"string\");\n return \"symbol\" == typeof i ? i : i + \"\";\n}\nfunction _typeof(o) {\n \"@babel/helpers - typeof\";\n\n return _typeof = \"function\" == typeof Symbol && \"symbol\" == typeof Symbol.iterator ? function (o) {\n return typeof o;\n } : function (o) {\n return o && \"function\" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? \"symbol\" : typeof o;\n }, _typeof(o);\n}\nfunction _defineProperty(obj, key, value) {\n key = _toPropertyKey(key);\n if (key in obj) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n } else {\n obj[key] = value;\n }\n return obj;\n}\nfunction _toConsumableArray(arr) {\n return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();\n}\nfunction _arrayWithoutHoles(arr) {\n if (Array.isArray(arr)) return _arrayLikeToArray(arr);\n}\nfunction _iterableToArray(iter) {\n if (typeof Symbol !== \"undefined\" && iter[Symbol.iterator] != null || iter[\"@@iterator\"] != null) return Array.from(iter);\n}\nfunction _unsupportedIterableToArray(o, minLen) {\n if (!o) return;\n if (typeof o === \"string\") return _arrayLikeToArray(o, minLen);\n var n = Object.prototype.toString.call(o).slice(8, -1);\n if (n === \"Object\" && o.constructor) n = o.constructor.name;\n if (n === \"Map\" || n === \"Set\") return Array.from(o);\n if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);\n}\nfunction _arrayLikeToArray(arr, len) {\n if (len == null || len > arr.length) len = arr.length;\n for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];\n return arr2;\n}\nfunction _nonIterableSpread() {\n throw new TypeError(\"Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\");\n}\n\nvar jsonDiff = new Diff();\n// Discriminate between two lines of pretty-printed, serialized JSON where one of them has a\n// dangling comma and the other doesn't. Turns out including the dangling comma yields the nicest output:\njsonDiff.useLongestToken = true;\njsonDiff.tokenize = lineDiff.tokenize;\njsonDiff.castInput = function (value, options) {\n var undefinedReplacement = options.undefinedReplacement,\n _options$stringifyRep = options.stringifyReplacer,\n stringifyReplacer = _options$stringifyRep === void 0 ? function (k, v) {\n return typeof v === 'undefined' ? undefinedReplacement : v;\n } : _options$stringifyRep;\n return typeof value === 'string' ? value : JSON.stringify(canonicalize(value, null, null, stringifyReplacer), stringifyReplacer, ' ');\n};\njsonDiff.equals = function (left, right, options) {\n return Diff.prototype.equals.call(jsonDiff, left.replace(/,([\\r\\n])/g, '$1'), right.replace(/,([\\r\\n])/g, '$1'), options);\n};\nfunction diffJson(oldObj, newObj, options) {\n return jsonDiff.diff(oldObj, newObj, options);\n}\n\n// This function handles the presence of circular references by bailing out when encountering an\n// object that is already on the \"stack\" of items being processed. Accepts an optional replacer\nfunction canonicalize(obj, stack, replacementStack, replacer, key) {\n stack = stack || [];\n replacementStack = replacementStack || [];\n if (replacer) {\n obj = replacer(key, obj);\n }\n var i;\n for (i = 0; i < stack.length; i += 1) {\n if (stack[i] === obj) {\n return replacementStack[i];\n }\n }\n var canonicalizedObj;\n if ('[object Array]' === Object.prototype.toString.call(obj)) {\n stack.push(obj);\n canonicalizedObj = new Array(obj.length);\n replacementStack.push(canonicalizedObj);\n for (i = 0; i < obj.length; i += 1) {\n canonicalizedObj[i] = canonicalize(obj[i], stack, replacementStack, replacer, key);\n }\n stack.pop();\n replacementStack.pop();\n return canonicalizedObj;\n }\n if (obj && obj.toJSON) {\n obj = obj.toJSON();\n }\n if (_typeof(obj) === 'object' && obj !== null) {\n stack.push(obj);\n canonicalizedObj = {};\n replacementStack.push(canonicalizedObj);\n var sortedKeys = [],\n _key;\n for (_key in obj) {\n /* istanbul ignore else */\n if (Object.prototype.hasOwnProperty.call(obj, _key)) {\n sortedKeys.push(_key);\n }\n }\n sortedKeys.sort();\n for (i = 0; i < sortedKeys.length; i += 1) {\n _key = sortedKeys[i];\n canonicalizedObj[_key] = canonicalize(obj[_key], stack, replacementStack, replacer, _key);\n }\n stack.pop();\n replacementStack.pop();\n } else {\n canonicalizedObj = obj;\n }\n return canonicalizedObj;\n}\n\nvar arrayDiff = new Diff();\narrayDiff.tokenize = function (value) {\n return value.slice();\n};\narrayDiff.join = arrayDiff.removeEmpty = function (value) {\n return value;\n};\nfunction diffArrays(oldArr, newArr, callback) {\n return arrayDiff.diff(oldArr, newArr, callback);\n}\n\nfunction unixToWin(patch) {\n if (Array.isArray(patch)) {\n return patch.map(unixToWin);\n }\n return _objectSpread2(_objectSpread2({}, patch), {}, {\n hunks: patch.hunks.map(function (hunk) {\n return _objectSpread2(_objectSpread2({}, hunk), {}, {\n lines: hunk.lines.map(function (line, i) {\n var _hunk$lines;\n return line.startsWith('\\\\') || line.endsWith('\\r') || (_hunk$lines = hunk.lines[i + 1]) !== null && _hunk$lines !== void 0 && _hunk$lines.startsWith('\\\\') ? line : line + '\\r';\n })\n });\n })\n });\n}\nfunction winToUnix(patch) {\n if (Array.isArray(patch)) {\n return patch.map(winToUnix);\n }\n return _objectSpread2(_objectSpread2({}, patch), {}, {\n hunks: patch.hunks.map(function (hunk) {\n return _objectSpread2(_objectSpread2({}, hunk), {}, {\n lines: hunk.lines.map(function (line) {\n return line.endsWith('\\r') ? line.substring(0, line.length - 1) : line;\n })\n });\n })\n });\n}\n\n/**\n * Returns true if the patch consistently uses Unix line endings (or only involves one line and has\n * no line endings).\n */\nfunction isUnix(patch) {\n if (!Array.isArray(patch)) {\n patch = [patch];\n }\n return !patch.some(function (index) {\n return index.hunks.some(function (hunk) {\n return hunk.lines.some(function (line) {\n return !line.startsWith('\\\\') && line.endsWith('\\r');\n });\n });\n });\n}\n\n/**\n * Returns true if the patch uses Windows line endings and only Windows line endings.\n */\nfunction isWin(patch) {\n if (!Array.isArray(patch)) {\n patch = [patch];\n }\n return patch.some(function (index) {\n return index.hunks.some(function (hunk) {\n return hunk.lines.some(function (line) {\n return line.endsWith('\\r');\n });\n });\n }) && patch.every(function (index) {\n return index.hunks.every(function (hunk) {\n return hunk.lines.every(function (line, i) {\n var _hunk$lines2;\n return line.startsWith('\\\\') || line.endsWith('\\r') || ((_hunk$lines2 = hunk.lines[i + 1]) === null || _hunk$lines2 === void 0 ? void 0 : _hunk$lines2.startsWith('\\\\'));\n });\n });\n });\n}\n\nfunction parsePatch(uniDiff) {\n var diffstr = uniDiff.split(/\\n/),\n list = [],\n i = 0;\n function parseIndex() {\n var index = {};\n list.push(index);\n\n // Parse diff metadata\n while (i < diffstr.length) {\n var line = diffstr[i];\n\n // File header found, end parsing diff metadata\n if (/^(\\-\\-\\-|\\+\\+\\+|@@)\\s/.test(line)) {\n break;\n }\n\n // Diff index\n var header = /^(?:Index:|diff(?: -r \\w+)+)\\s+(.+?)\\s*$/.exec(line);\n if (header) {\n index.index = header[1];\n }\n i++;\n }\n\n // Parse file headers if they are defined. Unified diff requires them, but\n // there's no technical issues to have an isolated hunk without file header\n parseFileHeader(index);\n parseFileHeader(index);\n\n // Parse hunks\n index.hunks = [];\n while (i < diffstr.length) {\n var _line = diffstr[i];\n if (/^(Index:\\s|diff\\s|\\-\\-\\-\\s|\\+\\+\\+\\s|===================================================================)/.test(_line)) {\n break;\n } else if (/^@@/.test(_line)) {\n index.hunks.push(parseHunk());\n } else if (_line) {\n throw new Error('Unknown line ' + (i + 1) + ' ' + JSON.stringify(_line));\n } else {\n i++;\n }\n }\n }\n\n // Parses the --- and +++ headers, if none are found, no lines\n // are consumed.\n function parseFileHeader(index) {\n var fileHeader = /^(---|\\+\\+\\+)\\s+(.*)\\r?$/.exec(diffstr[i]);\n if (fileHeader) {\n var keyPrefix = fileHeader[1] === '---' ? 'old' : 'new';\n var data = fileHeader[2].split('\\t', 2);\n var fileName = data[0].replace(/\\\\\\\\/g, '\\\\');\n if (/^\".*\"$/.test(fileName)) {\n fileName = fileName.substr(1, fileName.length - 2);\n }\n index[keyPrefix + 'FileName'] = fileName;\n index[keyPrefix + 'Header'] = (data[1] || '').trim();\n i++;\n }\n }\n\n // Parses a hunk\n // This assumes that we are at the start of a hunk.\n function parseHunk() {\n var chunkHeaderIndex = i,\n chunkHeaderLine = diffstr[i++],\n chunkHeader = chunkHeaderLine.split(/@@ -(\\d+)(?:,(\\d+))? \\+(\\d+)(?:,(\\d+))? @@/);\n var hunk = {\n oldStart: +chunkHeader[1],\n oldLines: typeof chunkHeader[2] === 'undefined' ? 1 : +chunkHeader[2],\n newStart: +chunkHeader[3],\n newLines: typeof chunkHeader[4] === 'undefined' ? 1 : +chunkHeader[4],\n lines: []\n };\n\n // Unified Diff Format quirk: If the chunk size is 0,\n // the first number is one lower than one would expect.\n // https://www.artima.com/weblogs/viewpost.jsp?thread=164293\n if (hunk.oldLines === 0) {\n hunk.oldStart += 1;\n }\n if (hunk.newLines === 0) {\n hunk.newStart += 1;\n }\n var addCount = 0,\n removeCount = 0;\n for (; i < diffstr.length && (removeCount < hunk.oldLines || addCount < hunk.newLines || (_diffstr$i = diffstr[i]) !== null && _diffstr$i !== void 0 && _diffstr$i.startsWith('\\\\')); i++) {\n var _diffstr$i;\n var operation = diffstr[i].length == 0 && i != diffstr.length - 1 ? ' ' : diffstr[i][0];\n if (operation === '+' || operation === '-' || operation === ' ' || operation === '\\\\') {\n hunk.lines.push(diffstr[i]);\n if (operation === '+') {\n addCount++;\n } else if (operation === '-') {\n removeCount++;\n } else if (operation === ' ') {\n addCount++;\n removeCount++;\n }\n } else {\n throw new Error(\"Hunk at line \".concat(chunkHeaderIndex + 1, \" contained invalid line \").concat(diffstr[i]));\n }\n }\n\n // Handle the empty block count case\n if (!addCount && hunk.newLines === 1) {\n hunk.newLines = 0;\n }\n if (!removeCount && hunk.oldLines === 1) {\n hunk.oldLines = 0;\n }\n\n // Perform sanity checking\n if (addCount !== hunk.newLines) {\n throw new Error('Added line count did not match for hunk at line ' + (chunkHeaderIndex + 1));\n }\n if (removeCount !== hunk.oldLines) {\n throw new Error('Removed line count did not match for hunk at line ' + (chunkHeaderIndex + 1));\n }\n return hunk;\n }\n while (i < diffstr.length) {\n parseIndex();\n }\n return list;\n}\n\n// Iterator that traverses in the range of [min, max], stepping\n// by distance from a given start position. I.e. for [0, 4], with\n// start of 2, this will iterate 2, 3, 1, 4, 0.\nfunction distanceIterator (start, minLine, maxLine) {\n var wantForward = true,\n backwardExhausted = false,\n forwardExhausted = false,\n localOffset = 1;\n return function iterator() {\n if (wantForward && !forwardExhausted) {\n if (backwardExhausted) {\n localOffset++;\n } else {\n wantForward = false;\n }\n\n // Check if trying to fit beyond text length, and if not, check it fits\n // after offset location (or desired location on first iteration)\n if (start + localOffset <= maxLine) {\n return start + localOffset;\n }\n forwardExhausted = true;\n }\n if (!backwardExhausted) {\n if (!forwardExhausted) {\n wantForward = true;\n }\n\n // Check if trying to fit before text beginning, and if not, check it fits\n // before offset location\n if (minLine <= start - localOffset) {\n return start - localOffset++;\n }\n backwardExhausted = true;\n return iterator();\n }\n\n // We tried to fit hunk before text beginning and beyond text length, then\n // hunk can't fit on the text. Return undefined\n };\n}\n\nfunction applyPatch(source, uniDiff) {\n var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n if (typeof uniDiff === 'string') {\n uniDiff = parsePatch(uniDiff);\n }\n if (Array.isArray(uniDiff)) {\n if (uniDiff.length > 1) {\n throw new Error('applyPatch only works with a single input.');\n }\n uniDiff = uniDiff[0];\n }\n if (options.autoConvertLineEndings || options.autoConvertLineEndings == null) {\n if (hasOnlyWinLineEndings(source) && isUnix(uniDiff)) {\n uniDiff = unixToWin(uniDiff);\n } else if (hasOnlyUnixLineEndings(source) && isWin(uniDiff)) {\n uniDiff = winToUnix(uniDiff);\n }\n }\n\n // Apply the diff to the input\n var lines = source.split('\\n'),\n hunks = uniDiff.hunks,\n compareLine = options.compareLine || function (lineNumber, line, operation, patchContent) {\n return line === patchContent;\n },\n fuzzFactor = options.fuzzFactor || 0,\n minLine = 0;\n if (fuzzFactor < 0 || !Number.isInteger(fuzzFactor)) {\n throw new Error('fuzzFactor must be a non-negative integer');\n }\n\n // Special case for empty patch.\n if (!hunks.length) {\n return source;\n }\n\n // Before anything else, handle EOFNL insertion/removal. If the patch tells us to make a change\n // to the EOFNL that is redundant/impossible - i.e. to remove a newline that's not there, or add a\n // newline that already exists - then we either return false and fail to apply the patch (if\n // fuzzFactor is 0) or simply ignore the problem and do nothing (if fuzzFactor is >0).\n // If we do need to remove/add a newline at EOF, this will always be in the final hunk:\n var prevLine = '',\n removeEOFNL = false,\n addEOFNL = false;\n for (var i = 0; i < hunks[hunks.length - 1].lines.length; i++) {\n var line = hunks[hunks.length - 1].lines[i];\n if (line[0] == '\\\\') {\n if (prevLine[0] == '+') {\n removeEOFNL = true;\n } else if (prevLine[0] == '-') {\n addEOFNL = true;\n }\n }\n prevLine = line;\n }\n if (removeEOFNL) {\n if (addEOFNL) {\n // This means the final line gets changed but doesn't have a trailing newline in either the\n // original or patched version. In that case, we do nothing if fuzzFactor > 0, and if\n // fuzzFactor is 0, we simply validate that the source file has no trailing newline.\n if (!fuzzFactor && lines[lines.length - 1] == '') {\n return false;\n }\n } else if (lines[lines.length - 1] == '') {\n lines.pop();\n } else if (!fuzzFactor) {\n return false;\n }\n } else if (addEOFNL) {\n if (lines[lines.length - 1] != '') {\n lines.push('');\n } else if (!fuzzFactor) {\n return false;\n }\n }\n\n /**\n * Checks if the hunk can be made to fit at the provided location with at most `maxErrors`\n * insertions, substitutions, or deletions, while ensuring also that:\n * - lines deleted in the hunk match exactly, and\n * - wherever an insertion operation or block of insertion operations appears in the hunk, the\n * immediately preceding and following lines of context match exactly\n *\n * `toPos` should be set such that lines[toPos] is meant to match hunkLines[0].\n *\n * If the hunk can be applied, returns an object with properties `oldLineLastI` and\n * `replacementLines`. Otherwise, returns null.\n */\n function applyHunk(hunkLines, toPos, maxErrors) {\n var hunkLinesI = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;\n var lastContextLineMatched = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true;\n var patchedLines = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : [];\n var patchedLinesLength = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : 0;\n var nConsecutiveOldContextLines = 0;\n var nextContextLineMustMatch = false;\n for (; hunkLinesI < hunkLines.length; hunkLinesI++) {\n var hunkLine = hunkLines[hunkLinesI],\n operation = hunkLine.length > 0 ? hunkLine[0] : ' ',\n content = hunkLine.length > 0 ? hunkLine.substr(1) : hunkLine;\n if (operation === '-') {\n if (compareLine(toPos + 1, lines[toPos], operation, content)) {\n toPos++;\n nConsecutiveOldContextLines = 0;\n } else {\n if (!maxErrors || lines[toPos] == null) {\n return null;\n }\n patchedLines[patchedLinesLength] = lines[toPos];\n return applyHunk(hunkLines, toPos + 1, maxErrors - 1, hunkLinesI, false, patchedLines, patchedLinesLength + 1);\n }\n }\n if (operation === '+') {\n if (!lastContextLineMatched) {\n return null;\n }\n patchedLines[patchedLinesLength] = content;\n patchedLinesLength++;\n nConsecutiveOldContextLines = 0;\n nextContextLineMustMatch = true;\n }\n if (operation === ' ') {\n nConsecutiveOldContextLines++;\n patchedLines[patchedLinesLength] = lines[toPos];\n if (compareLine(toPos + 1, lines[toPos], operation, content)) {\n patchedLinesLength++;\n lastContextLineMatched = true;\n nextContextLineMustMatch = false;\n toPos++;\n } else {\n if (nextContextLineMustMatch || !maxErrors) {\n return null;\n }\n\n // Consider 3 possibilities in sequence:\n // 1. lines contains a *substitution* not included in the patch context, or\n // 2. lines contains an *insertion* not included in the patch context, or\n // 3. lines contains a *deletion* not included in the patch context\n // The first two options are of course only possible if the line from lines is non-null -\n // i.e. only option 3 is possible if we've overrun the end of the old file.\n return lines[toPos] && (applyHunk(hunkLines, toPos + 1, maxErrors - 1, hunkLinesI + 1, false, patchedLines, patchedLinesLength + 1) || applyHunk(hunkLines, toPos + 1, maxErrors - 1, hunkLinesI, false, patchedLines, patchedLinesLength + 1)) || applyHunk(hunkLines, toPos, maxErrors - 1, hunkLinesI + 1, false, patchedLines, patchedLinesLength);\n }\n }\n }\n\n // Before returning, trim any unmodified context lines off the end of patchedLines and reduce\n // toPos (and thus oldLineLastI) accordingly. This allows later hunks to be applied to a region\n // that starts in this hunk's trailing context.\n patchedLinesLength -= nConsecutiveOldContextLines;\n toPos -= nConsecutiveOldContextLines;\n patchedLines.length = patchedLinesLength;\n return {\n patchedLines: patchedLines,\n oldLineLastI: toPos - 1\n };\n }\n var resultLines = [];\n\n // Search best fit offsets for each hunk based on the previous ones\n var prevHunkOffset = 0;\n for (var _i = 0; _i < hunks.length; _i++) {\n var hunk = hunks[_i];\n var hunkResult = void 0;\n var maxLine = lines.length - hunk.oldLines + fuzzFactor;\n var toPos = void 0;\n for (var maxErrors = 0; maxErrors <= fuzzFactor; maxErrors++) {\n toPos = hunk.oldStart + prevHunkOffset - 1;\n var iterator = distanceIterator(toPos, minLine, maxLine);\n for (; toPos !== undefined; toPos = iterator()) {\n hunkResult = applyHunk(hunk.lines, toPos, maxErrors);\n if (hunkResult) {\n break;\n }\n }\n if (hunkResult) {\n break;\n }\n }\n if (!hunkResult) {\n return false;\n }\n\n // Copy everything from the end of where we applied the last hunk to the start of this hunk\n for (var _i2 = minLine; _i2 < toPos; _i2++) {\n resultLines.push(lines[_i2]);\n }\n\n // Add the lines produced by applying the hunk:\n for (var _i3 = 0; _i3 < hunkResult.patchedLines.length; _i3++) {\n var _line = hunkResult.patchedLines[_i3];\n resultLines.push(_line);\n }\n\n // Set lower text limit to end of the current hunk, so next ones don't try\n // to fit over already patched text\n minLine = hunkResult.oldLineLastI + 1;\n\n // Note the offset between where the patch said the hunk should've applied and where we\n // applied it, so we can adjust future hunks accordingly:\n prevHunkOffset = toPos + 1 - hunk.oldStart;\n }\n\n // Copy over the rest of the lines from the old text\n for (var _i4 = minLine; _i4 < lines.length; _i4++) {\n resultLines.push(lines[_i4]);\n }\n return resultLines.join('\\n');\n}\n\n// Wrapper that supports multiple file patches via callbacks.\nfunction applyPatches(uniDiff, options) {\n if (typeof uniDiff === 'string') {\n uniDiff = parsePatch(uniDiff);\n }\n var currentIndex = 0;\n function processIndex() {\n var index = uniDiff[currentIndex++];\n if (!index) {\n return options.complete();\n }\n options.loadFile(index, function (err, data) {\n if (err) {\n return options.complete(err);\n }\n var updatedContent = applyPatch(data, index, options);\n options.patched(index, updatedContent, function (err) {\n if (err) {\n return options.complete(err);\n }\n processIndex();\n });\n });\n }\n processIndex();\n}\n\nfunction structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) {\n if (!options) {\n options = {};\n }\n if (typeof options === 'function') {\n options = {\n callback: options\n };\n }\n if (typeof options.context === 'undefined') {\n options.context = 4;\n }\n if (options.newlineIsToken) {\n throw new Error('newlineIsToken may not be used with patch-generation functions, only with diffing functions');\n }\n if (!options.callback) {\n return diffLinesResultToPatch(diffLines(oldStr, newStr, options));\n } else {\n var _options = options,\n _callback = _options.callback;\n diffLines(oldStr, newStr, _objectSpread2(_objectSpread2({}, options), {}, {\n callback: function callback(diff) {\n var patch = diffLinesResultToPatch(diff);\n _callback(patch);\n }\n }));\n }\n function diffLinesResultToPatch(diff) {\n // STEP 1: Build up the patch with no \"\\" lines and with the arrays\n // of lines containing trailing newline characters. We'll tidy up later...\n\n if (!diff) {\n return;\n }\n diff.push({\n value: '',\n lines: []\n }); // Append an empty value to make cleanup easier\n\n function contextLines(lines) {\n return lines.map(function (entry) {\n return ' ' + entry;\n });\n }\n var hunks = [];\n var oldRangeStart = 0,\n newRangeStart = 0,\n curRange = [],\n oldLine = 1,\n newLine = 1;\n var _loop = function _loop() {\n var current = diff[i],\n lines = current.lines || splitLines(current.value);\n current.lines = lines;\n if (current.added || current.removed) {\n var _curRange;\n // If we have previous context, start with that\n if (!oldRangeStart) {\n var prev = diff[i - 1];\n oldRangeStart = oldLine;\n newRangeStart = newLine;\n if (prev) {\n curRange = options.context > 0 ? contextLines(prev.lines.slice(-options.context)) : [];\n oldRangeStart -= curRange.length;\n newRangeStart -= curRange.length;\n }\n }\n\n // Output our changes\n (_curRange = curRange).push.apply(_curRange, _toConsumableArray(lines.map(function (entry) {\n return (current.added ? '+' : '-') + entry;\n })));\n\n // Track the updated file position\n if (current.added) {\n newLine += lines.length;\n } else {\n oldLine += lines.length;\n }\n } else {\n // Identical context lines. Track line changes\n if (oldRangeStart) {\n // Close out any changes that have been output (or join overlapping)\n if (lines.length <= options.context * 2 && i < diff.length - 2) {\n var _curRange2;\n // Overlapping\n (_curRange2 = curRange).push.apply(_curRange2, _toConsumableArray(contextLines(lines)));\n } else {\n var _curRange3;\n // end the range and output\n var contextSize = Math.min(lines.length, options.context);\n (_curRange3 = curRange).push.apply(_curRange3, _toConsumableArray(contextLines(lines.slice(0, contextSize))));\n var _hunk = {\n oldStart: oldRangeStart,\n oldLines: oldLine - oldRangeStart + contextSize,\n newStart: newRangeStart,\n newLines: newLine - newRangeStart + contextSize,\n lines: curRange\n };\n hunks.push(_hunk);\n oldRangeStart = 0;\n newRangeStart = 0;\n curRange = [];\n }\n }\n oldLine += lines.length;\n newLine += lines.length;\n }\n };\n for (var i = 0; i < diff.length; i++) {\n _loop();\n }\n\n // Step 2: eliminate the trailing `\\n` from each line of each hunk, and, where needed, add\n // \"\\".\n for (var _i = 0, _hunks = hunks; _i < _hunks.length; _i++) {\n var hunk = _hunks[_i];\n for (var _i2 = 0; _i2 < hunk.lines.length; _i2++) {\n if (hunk.lines[_i2].endsWith('\\n')) {\n hunk.lines[_i2] = hunk.lines[_i2].slice(0, -1);\n } else {\n hunk.lines.splice(_i2 + 1, 0, '\\\');\n _i2++; // Skip the line we just added, then continue iterating\n }\n }\n }\n return {\n oldFileName: oldFileName,\n newFileName: newFileName,\n oldHeader: oldHeader,\n newHeader: newHeader,\n hunks: hunks\n };\n }\n}\nfunction formatPatch(diff) {\n if (Array.isArray(diff)) {\n return diff.map(formatPatch).join('\\n');\n }\n var ret = [];\n if (diff.oldFileName == diff.newFileName) {\n ret.push('Index: ' + diff.oldFileName);\n }\n ret.push('===================================================================');\n ret.push('--- ' + diff.oldFileName + (typeof diff.oldHeader === 'undefined' ? '' : '\\t' + diff.oldHeader));\n ret.push('+++ ' + diff.newFileName + (typeof diff.newHeader === 'undefined' ? '' : '\\t' + diff.newHeader));\n for (var i = 0; i < diff.hunks.length; i++) {\n var hunk = diff.hunks[i];\n // Unified Diff Format quirk: If the chunk size is 0,\n // the first number is one lower than one would expect.\n // https://www.artima.com/weblogs/viewpost.jsp?thread=164293\n if (hunk.oldLines === 0) {\n hunk.oldStart -= 1;\n }\n if (hunk.newLines === 0) {\n hunk.newStart -= 1;\n }\n ret.push('@@ -' + hunk.oldStart + ',' + hunk.oldLines + ' +' + hunk.newStart + ',' + hunk.newLines + ' @@');\n ret.push.apply(ret, hunk.lines);\n }\n return ret.join('\\n') + '\\n';\n}\nfunction createTwoFilesPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) {\n var _options2;\n if (typeof options === 'function') {\n options = {\n callback: options\n };\n }\n if (!((_options2 = options) !== null && _options2 !== void 0 && _options2.callback)) {\n var patchObj = structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options);\n if (!patchObj) {\n return;\n }\n return formatPatch(patchObj);\n } else {\n var _options3 = options,\n _callback2 = _options3.callback;\n structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, _objectSpread2(_objectSpread2({}, options), {}, {\n callback: function callback(patchObj) {\n if (!patchObj) {\n _callback2();\n } else {\n _callback2(formatPatch(patchObj));\n }\n }\n }));\n }\n}\nfunction createPatch(fileName, oldStr, newStr, oldHeader, newHeader, options) {\n return createTwoFilesPatch(fileName, fileName, oldStr, newStr, oldHeader, newHeader, options);\n}\n\n/**\n * Split `text` into an array of lines, including the trailing newline character (where present)\n */\nfunction splitLines(text) {\n var hasTrailingNl = text.endsWith('\\n');\n var result = text.split('\\n').map(function (line) {\n return line + '\\n';\n });\n if (hasTrailingNl) {\n result.pop();\n } else {\n result.push(result.pop().slice(0, -1));\n }\n return result;\n}\n\nfunction arrayEqual(a, b) {\n if (a.length !== b.length) {\n return false;\n }\n return arrayStartsWith(a, b);\n}\nfunction arrayStartsWith(array, start) {\n if (start.length > array.length) {\n return false;\n }\n for (var i = 0; i < start.length; i++) {\n if (start[i] !== array[i]) {\n return false;\n }\n }\n return true;\n}\n\nfunction calcLineCount(hunk) {\n var _calcOldNewLineCount = calcOldNewLineCount(hunk.lines),\n oldLines = _calcOldNewLineCount.oldLines,\n newLines = _calcOldNewLineCount.newLines;\n if (oldLines !== undefined) {\n hunk.oldLines = oldLines;\n } else {\n delete hunk.oldLines;\n }\n if (newLines !== undefined) {\n hunk.newLines = newLines;\n } else {\n delete hunk.newLines;\n }\n}\nfunction merge(mine, theirs, base) {\n mine = loadPatch(mine, base);\n theirs = loadPatch(theirs, base);\n var ret = {};\n\n // For index we just let it pass through as it doesn't have any necessary meaning.\n // Leaving sanity checks on this to the API consumer that may know more about the\n // meaning in their own context.\n if (mine.index || theirs.index) {\n ret.index = mine.index || theirs.index;\n }\n if (mine.newFileName || theirs.newFileName) {\n if (!fileNameChanged(mine)) {\n // No header or no change in ours, use theirs (and ours if theirs does not exist)\n ret.oldFileName = theirs.oldFileName || mine.oldFileName;\n ret.newFileName = theirs.newFileName || mine.newFileName;\n ret.oldHeader = theirs.oldHeader || mine.oldHeader;\n ret.newHeader = theirs.newHeader || mine.newHeader;\n } else if (!fileNameChanged(theirs)) {\n // No header or no change in theirs, use ours\n ret.oldFileName = mine.oldFileName;\n ret.newFileName = mine.newFileName;\n ret.oldHeader = mine.oldHeader;\n ret.newHeader = mine.newHeader;\n } else {\n // Both changed... figure it out\n ret.oldFileName = selectField(ret, mine.oldFileName, theirs.oldFileName);\n ret.newFileName = selectField(ret, mine.newFileName, theirs.newFileName);\n ret.oldHeader = selectField(ret, mine.oldHeader, theirs.oldHeader);\n ret.newHeader = selectField(ret, mine.newHeader, theirs.newHeader);\n }\n }\n ret.hunks = [];\n var mineIndex = 0,\n theirsIndex = 0,\n mineOffset = 0,\n theirsOffset = 0;\n while (mineIndex < mine.hunks.length || theirsIndex < theirs.hunks.length) {\n var mineCurrent = mine.hunks[mineIndex] || {\n oldStart: Infinity\n },\n theirsCurrent = theirs.hunks[theirsIndex] || {\n oldStart: Infinity\n };\n if (hunkBefore(mineCurrent, theirsCurrent)) {\n // This patch does not overlap with any of the others, yay.\n ret.hunks.push(cloneHunk(mineCurrent, mineOffset));\n mineIndex++;\n theirsOffset += mineCurrent.newLines - mineCurrent.oldLines;\n } else if (hunkBefore(theirsCurrent, mineCurrent)) {\n // This patch does not overlap with any of the others, yay.\n ret.hunks.push(cloneHunk(theirsCurrent, theirsOffset));\n theirsIndex++;\n mineOffset += theirsCurrent.newLines - theirsCurrent.oldLines;\n } else {\n // Overlap, merge as best we can\n var mergedHunk = {\n oldStart: Math.min(mineCurrent.oldStart, theirsCurrent.oldStart),\n oldLines: 0,\n newStart: Math.min(mineCurrent.newStart + mineOffset, theirsCurrent.oldStart + theirsOffset),\n newLines: 0,\n lines: []\n };\n mergeLines(mergedHunk, mineCurrent.oldStart, mineCurrent.lines, theirsCurrent.oldStart, theirsCurrent.lines);\n theirsIndex++;\n mineIndex++;\n ret.hunks.push(mergedHunk);\n }\n }\n return ret;\n}\nfunction loadPatch(param, base) {\n if (typeof param === 'string') {\n if (/^@@/m.test(param) || /^Index:/m.test(param)) {\n return parsePatch(param)[0];\n }\n if (!base) {\n throw new Error('Must provide a base reference or pass in a patch');\n }\n return structuredPatch(undefined, undefined, base, param);\n }\n return param;\n}\nfunction fileNameChanged(patch) {\n return patch.newFileName && patch.newFileName !== patch.oldFileName;\n}\nfunction selectField(index, mine, theirs) {\n if (mine === theirs) {\n return mine;\n } else {\n index.conflict = true;\n return {\n mine: mine,\n theirs: theirs\n };\n }\n}\nfunction hunkBefore(test, check) {\n return test.oldStart < check.oldStart && test.oldStart + test.oldLines < check.oldStart;\n}\nfunction cloneHunk(hunk, offset) {\n return {\n oldStart: hunk.oldStart,\n oldLines: hunk.oldLines,\n newStart: hunk.newStart + offset,\n newLines: hunk.newLines,\n lines: hunk.lines\n };\n}\nfunction mergeLines(hunk, mineOffset, mineLines, theirOffset, theirLines) {\n // This will generally result in a conflicted hunk, but there are cases where the context\n // is the only overlap where we can successfully merge the content here.\n var mine = {\n offset: mineOffset,\n lines: mineLines,\n index: 0\n },\n their = {\n offset: theirOffset,\n lines: theirLines,\n index: 0\n };\n\n // Handle any leading content\n insertLeading(hunk, mine, their);\n insertLeading(hunk, their, mine);\n\n // Now in the overlap content. Scan through and select the best changes from each.\n while (mine.index < mine.lines.length && their.index < their.lines.length) {\n var mineCurrent = mine.lines[mine.index],\n theirCurrent = their.lines[their.index];\n if ((mineCurrent[0] === '-' || mineCurrent[0] === '+') && (theirCurrent[0] === '-' || theirCurrent[0] === '+')) {\n // Both modified ...\n mutualChange(hunk, mine, their);\n } else if (mineCurrent[0] === '+' && theirCurrent[0] === ' ') {\n var _hunk$lines;\n // Mine inserted\n (_hunk$lines = hunk.lines).push.apply(_hunk$lines, _toConsumableArray(collectChange(mine)));\n } else if (theirCurrent[0] === '+' && mineCurrent[0] === ' ') {\n var _hunk$lines2;\n // Theirs inserted\n (_hunk$lines2 = hunk.lines).push.apply(_hunk$lines2, _toConsumableArray(collectChange(their)));\n } else if (mineCurrent[0] === '-' && theirCurrent[0] === ' ') {\n // Mine removed or edited\n removal(hunk, mine, their);\n } else if (theirCurrent[0] === '-' && mineCurrent[0] === ' ') {\n // Their removed or edited\n removal(hunk, their, mine, true);\n } else if (mineCurrent === theirCurrent) {\n // Context identity\n hunk.lines.push(mineCurrent);\n mine.index++;\n their.index++;\n } else {\n // Context mismatch\n conflict(hunk, collectChange(mine), collectChange(their));\n }\n }\n\n // Now push anything that may be remaining\n insertTrailing(hunk, mine);\n insertTrailing(hunk, their);\n calcLineCount(hunk);\n}\nfunction mutualChange(hunk, mine, their) {\n var myChanges = collectChange(mine),\n theirChanges = collectChange(their);\n if (allRemoves(myChanges) && allRemoves(theirChanges)) {\n // Special case for remove changes that are supersets of one another\n if (arrayStartsWith(myChanges, theirChanges) && skipRemoveSuperset(their, myChanges, myChanges.length - theirChanges.length)) {\n var _hunk$lines3;\n (_hunk$lines3 = hunk.lines).push.apply(_hunk$lines3, _toConsumableArray(myChanges));\n return;\n } else if (arrayStartsWith(theirChanges, myChanges) && skipRemoveSuperset(mine, theirChanges, theirChanges.length - myChanges.length)) {\n var _hunk$lines4;\n (_hunk$lines4 = hunk.lines).push.apply(_hunk$lines4, _toConsumableArray(theirChanges));\n return;\n }\n } else if (arrayEqual(myChanges, theirChanges)) {\n var _hunk$lines5;\n (_hunk$lines5 = hunk.lines).push.apply(_hunk$lines5, _toConsumableArray(myChanges));\n return;\n }\n conflict(hunk, myChanges, theirChanges);\n}\nfunction removal(hunk, mine, their, swap) {\n var myChanges = collectChange(mine),\n theirChanges = collectContext(their, myChanges);\n if (theirChanges.merged) {\n var _hunk$lines6;\n (_hunk$lines6 = hunk.lines).push.apply(_hunk$lines6, _toConsumableArray(theirChanges.merged));\n } else {\n conflict(hunk, swap ? theirChanges : myChanges, swap ? myChanges : theirChanges);\n }\n}\nfunction conflict(hunk, mine, their) {\n hunk.conflict = true;\n hunk.lines.push({\n conflict: true,\n mine: mine,\n theirs: their\n });\n}\nfunction insertLeading(hunk, insert, their) {\n while (insert.offset < their.offset && insert.index < insert.lines.length) {\n var line = insert.lines[insert.index++];\n hunk.lines.push(line);\n insert.offset++;\n }\n}\nfunction insertTrailing(hunk, insert) {\n while (insert.index < insert.lines.length) {\n var line = insert.lines[insert.index++];\n hunk.lines.push(line);\n }\n}\nfunction collectChange(state) {\n var ret = [],\n operation = state.lines[state.index][0];\n while (state.index < state.lines.length) {\n var line = state.lines[state.index];\n\n // Group additions that are immediately after subtractions and treat them as one \"atomic\" modify change.\n if (operation === '-' && line[0] === '+') {\n operation = '+';\n }\n if (operation === line[0]) {\n ret.push(line);\n state.index++;\n } else {\n break;\n }\n }\n return ret;\n}\nfunction collectContext(state, matchChanges) {\n var changes = [],\n merged = [],\n matchIndex = 0,\n contextChanges = false,\n conflicted = false;\n while (matchIndex < matchChanges.length && state.index < state.lines.length) {\n var change = state.lines[state.index],\n match = matchChanges[matchIndex];\n\n // Once we've hit our add, then we are done\n if (match[0] === '+') {\n break;\n }\n contextChanges = contextChanges || change[0] !== ' ';\n merged.push(match);\n matchIndex++;\n\n // Consume any additions in the other block as a conflict to attempt\n // to pull in the remaining context after this\n if (change[0] === '+') {\n conflicted = true;\n while (change[0] === '+') {\n changes.push(change);\n change = state.lines[++state.index];\n }\n }\n if (match.substr(1) === change.substr(1)) {\n changes.push(change);\n state.index++;\n } else {\n conflicted = true;\n }\n }\n if ((matchChanges[matchIndex] || '')[0] === '+' && contextChanges) {\n conflicted = true;\n }\n if (conflicted) {\n return changes;\n }\n while (matchIndex < matchChanges.length) {\n merged.push(matchChanges[matchIndex++]);\n }\n return {\n merged: merged,\n changes: changes\n };\n}\nfunction allRemoves(changes) {\n return changes.reduce(function (prev, change) {\n return prev && change[0] === '-';\n }, true);\n}\nfunction skipRemoveSuperset(state, removeChanges, delta) {\n for (var i = 0; i < delta; i++) {\n var changeContent = removeChanges[removeChanges.length - delta + i].substr(1);\n if (state.lines[state.index + i] !== ' ' + changeContent) {\n return false;\n }\n }\n state.index += delta;\n return true;\n}\nfunction calcOldNewLineCount(lines) {\n var oldLines = 0;\n var newLines = 0;\n lines.forEach(function (line) {\n if (typeof line !== 'string') {\n var myCount = calcOldNewLineCount(line.mine);\n var theirCount = calcOldNewLineCount(line.theirs);\n if (oldLines !== undefined) {\n if (myCount.oldLines === theirCount.oldLines) {\n oldLines += myCount.oldLines;\n } else {\n oldLines = undefined;\n }\n }\n if (newLines !== undefined) {\n if (myCount.newLines === theirCount.newLines) {\n newLines += myCount.newLines;\n } else {\n newLines = undefined;\n }\n }\n } else {\n if (newLines !== undefined && (line[0] === '+' || line[0] === ' ')) {\n newLines++;\n }\n if (oldLines !== undefined && (line[0] === '-' || line[0] === ' ')) {\n oldLines++;\n }\n }\n });\n return {\n oldLines: oldLines,\n newLines: newLines\n };\n}\n\nfunction reversePatch(structuredPatch) {\n if (Array.isArray(structuredPatch)) {\n return structuredPatch.map(reversePatch).reverse();\n }\n return _objectSpread2(_objectSpread2({}, structuredPatch), {}, {\n oldFileName: structuredPatch.newFileName,\n oldHeader: structuredPatch.newHeader,\n newFileName: structuredPatch.oldFileName,\n newHeader: structuredPatch.oldHeader,\n hunks: structuredPatch.hunks.map(function (hunk) {\n return {\n oldLines: hunk.newLines,\n oldStart: hunk.newStart,\n newLines: hunk.oldLines,\n newStart: hunk.oldStart,\n lines: hunk.lines.map(function (l) {\n if (l.startsWith('-')) {\n return \"+\".concat(l.slice(1));\n }\n if (l.startsWith('+')) {\n return \"-\".concat(l.slice(1));\n }\n return l;\n })\n };\n })\n });\n}\n\n// See: http://code.google.com/p/google-diff-match-patch/wiki/API\nfunction convertChangesToDMP(changes) {\n var ret = [],\n change,\n operation;\n for (var i = 0; i < changes.length; i++) {\n change = changes[i];\n if (change.added) {\n operation = 1;\n } else if (change.removed) {\n operation = -1;\n } else {\n operation = 0;\n }\n ret.push([operation, change.value]);\n }\n return ret;\n}\n\nfunction convertChangesToXML(changes) {\n var ret = [];\n for (var i = 0; i < changes.length; i++) {\n var change = changes[i];\n if (change.added) {\n ret.push('<ins>');\n } else if (change.removed) {\n ret.push('<del>');\n }\n ret.push(escapeHTML(change.value));\n if (change.added) {\n ret.push('</ins>');\n } else if (change.removed) {\n ret.push('</del>');\n }\n }\n return ret.join('');\n}\nfunction escapeHTML(s) {\n var n = s;\n n = n.replace(/&/g, '&amp;');\n n = n.replace(/</g, '&lt;');\n n = n.replace(/>/g, '&gt;');\n n = n.replace(/\"/g, '&quot;');\n return n;\n}\n\nexport { Diff, applyPatch, applyPatches, canonicalize, convertChangesToDMP, convertChangesToXML, createPatch, createTwoFilesPatch, diffArrays, diffChars, diffCss, diffJson, diffLines, diffSentences, diffTrimmedLines, diffWords, diffWordsWithSpace, formatPatch, merge, parsePatch, reversePatch, structuredPatch };\n", "/**\n * Error Reporter Module\n *\n * Provides comprehensive error reporting functionality for the evaluator.\n * Captures detailed error information including stack traces and context,\n * and sends it to the server so failures can be debugged without accessing\n * the remote machine logs.\n */\n\nimport { EvalStatus } from '@wix/evalforge-types';\nimport type { EvaluatorConfig } from './config.js';\nimport { createApiClient } from './api-client.js';\n\n/**\n * Detailed error information to send to the server.\n */\nexport interface ErrorDetails {\n /** Short error message */\n message: string;\n /** Full stack trace if available */\n stack?: string;\n /** Error name/type (e.g., \"TypeError\", \"Error\") */\n errorType?: string;\n /** Phase of execution where the error occurred */\n phase?: string;\n /** Additional context about what was happening */\n context?: Record<string, unknown>;\n /** Timestamp when the error occurred */\n timestamp: string;\n}\n\n/**\n * Format an error into detailed error information.\n *\n * @param error - The error to format\n * @param phase - The phase of execution (e.g., \"config\", \"fetch\", \"execution\")\n * @param context - Additional context about what was happening\n * @returns Formatted error details\n */\nexport function formatError(\n error: unknown,\n phase?: string,\n context?: Record<string, unknown>\n): ErrorDetails {\n const timestamp = new Date().toISOString();\n\n if (error instanceof Error) {\n return {\n message: error.message,\n stack: error.stack,\n errorType: error.constructor.name,\n phase,\n context,\n timestamp\n };\n }\n\n // Handle non-Error types (strings, objects, etc.)\n return {\n message: String(error),\n errorType: typeof error,\n phase,\n context,\n timestamp\n };\n}\n\n/**\n * Format error details into a string suitable for the jobError field.\n * Includes the message, stack trace, and context in a readable format.\n *\n * @param details - The error details to format\n * @returns A formatted string with all error information\n */\nexport function formatErrorForJobError(details: ErrorDetails): string {\n const parts: string[] = [];\n\n // Add phase context\n if (details.phase) {\n parts.push(`[Phase: ${details.phase}]`);\n }\n\n // Add error type and message\n if (details.errorType && details.errorType !== 'Error') {\n parts.push(`${details.errorType}: ${details.message}`);\n } else {\n parts.push(details.message);\n }\n\n // Add context if present\n if (details.context && Object.keys(details.context).length > 0) {\n parts.push(`\\nContext: ${JSON.stringify(details.context)}`);\n }\n\n // Add stack trace (first 5 lines to keep it manageable)\n if (details.stack) {\n const stackLines = details.stack.split('\\n').slice(0, 6);\n parts.push(`\\nStack:\\n${stackLines.join('\\n')}`);\n }\n\n return parts.join(' ');\n}\n\n/**\n * Report an error to the server.\n *\n * This function attempts to update the eval run status to FAILED\n * with detailed error information. If the update fails, it logs\n * the error to stderr.\n *\n * @param config - Evaluator configuration (can be partial if config loading failed)\n * @param projectId - The project ID\n * @param evalRunId - The eval run ID\n * @param error - The error to report\n * @param phase - The phase where the error occurred\n * @param context - Additional context\n */\nexport async function reportError(\n config: Partial<EvaluatorConfig> | null,\n projectId: string,\n evalRunId: string,\n error: unknown,\n phase?: string,\n context?: Record<string, unknown>\n): Promise<void> {\n const errorDetails = formatError(error, phase, context);\n const jobError = formatErrorForJobError(errorDetails);\n\n // Log to stderr for local debugging\n console.error('[EVALUATOR-ERROR]', JSON.stringify(errorDetails, null, 2));\n\n // If we don't have a valid config, we can't report to the server\n if (!config?.serverUrl) {\n console.error('[EVALUATOR-ERROR] Cannot report to server: no serverUrl');\n return;\n }\n\n try {\n const api = createApiClient(config.serverUrl, {\n apiPrefix: config.apiPrefix,\n routeHeader: config.routeHeader,\n authToken: config.authToken\n });\n\n await api.updateEvalRun(projectId, evalRunId, {\n status: EvalStatus.FAILED,\n completedAt: new Date().toISOString(),\n jobError,\n jobStatus: 'FAILED'\n });\n\n console.error('[EVALUATOR-ERROR] Successfully reported error to server');\n } catch (reportErr) {\n console.error(\n '[EVALUATOR-ERROR] Failed to report error to server:',\n reportErr\n );\n }\n}\n\n/**\n * Execution phases for error context.\n */\nexport const ExecutionPhase = {\n /** Environment diagnostics phase (runs before execution) */\n DIAGNOSTICS: 'diagnostics',\n CONFIG: 'config-loading',\n API_CLIENT: 'api-client-creation',\n FETCH_EVAL_RUN: 'fetch-eval-run',\n FETCH_SKILLS: 'fetch-skills',\n FETCH_AGENT: 'fetch-agent',\n FETCH_SCENARIOS: 'fetch-scenarios',\n VALIDATION: 'validation',\n PREPARE_WORKSPACE: 'prepare-workspace',\n EXECUTE_SKILL: 'execute-skill',\n EXECUTE_AGENT: 'execute-agent',\n CLAUDE_SDK_IMPORT: 'claude-sdk-import',\n CLAUDE_SDK_EXECUTION: 'claude-sdk-execution',\n ADD_RESULT: 'add-result',\n UPDATE_STATUS: 'update-status'\n} as const;\n"],
5
+ "mappings": "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",
6
6
  "names": ["import_evalforge_types", "path", "projectId", "evalRunId", "projectId", "evalRunId", "import_evalforge_types", "import_path", "path", "evalRunId", "workDir", "import_crypto", "import_evalforge_types", "import_evalforge_types", "import_promises", "import_path", "import_evalforge_github_client", "import_promises", "import_path", "import_evalforge_types", "import_promises", "import_path", "import_os", "import_promises", "import_path", "import_evalforge_github_client", "import_promises", "import_path", "import_evalforge_types", "path", "isAssistantMessage", "writeFile", "errObj", "sdkErrorKeys", "import_evalforge_types", "import_evalforge_types", "import_promises", "import_path", "import_evalforge_github_client", "writeSkillsToFilesystem", "writeSkillToFilesystem", "import_promises", "import_path", "import_evalforge_github_client", "AGENTS_DIR", "toAgentFilename", "resolveSubAgentContent", "writeSubAgentsToFilesystem", "import_os", "import_evalforge_types", "DEFAULT_MODEL", "import_evalforge_types", "import_crypto", "buildConversation", "import_promises", "import_path", "writeSubAgentsToFilesystem", "writeSkillsToFilesystem", "resolve", "buildConversation", "import_evalforge_types", "import_crypto", "import_evalforge_types", "cost", "buildConversation", "PROVIDER_ANTHROPIC", "buildLLMTrace", "buildConversation", "import_fs", "import_path", "path", "join", "diff", "value", "o", "path", "diffLines", "import_evalforge_types", "evalRunId", "evalRunId", "evaluateAssertionsBase", "import_evalforge_types", "projectId", "evalRunId"]
7
7
  }