@wix/evalforge-evaluator 0.76.0 → 0.78.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/run-scenario/index.ts", "../src/run-scenario/environment.ts", "../src/run-scenario/agents/claude-code/write-skills.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-mcp.ts", "../src/run-scenario/agents/claude-code/write-sub-agents.ts", "../src/run-scenario/agents/claude-code/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 hasCodeAgent: !!evalData.codeAgent,\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 { codeAgent, 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: !!codeAgent,\n agentId: evalData.evalRun.agentId,\n skillsGroupId: evalData.evalRun.skillsGroupId\n };\n\n if (scenarioItems.length > 0 && skills.length === 0) {\n throw new Error(\n `[${ExecutionPhase.VALIDATION}] Eval run has no skills: set skillsGroupId and ensure the group has skills. ` +\n `(skillsGroupId: ${evalData.evalRun.skillsGroupId || 'not set'})`\n );\n }\n if (scenarioItems.length > 0 && skills.length > 0 && !codeAgent) {\n throw new Error(\n `[${ExecutionPhase.VALIDATION}] Eval run has no code agent: set agentId for skill-based 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 skillsGroupId: evalData.evalRun.skillsGroupId,\n skillsGroupName: evalData.skillsGroupName,\n agentId: codeAgent?.id,\n agentName: codeAgent?.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 skills group:',\n evalData.skillsGroupName,\n skillNames ? `(${skillNames})` : '',\n codeAgent ? `with agent: ${codeAgent.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 skills group:',\n evalData.skillsGroupName,\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 skills group \"${evalData.skillsGroupName}\" 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 // 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 SkillsGroup,\n TestScenario,\n Template,\n SkillWithLatestVersion,\n SkillVersion,\n Agent,\n CustomAssertion,\n MCPEntity,\n SubAgent\n} from '@wix/evalforge-types';\n\nexport interface ApiClient {\n getEvalRun(projectId: string, id: string): Promise<EvalRun>;\n getSkillsGroup(projectId: string, id: string): Promise<SkillsGroup>;\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 getAssertion(projectId: string, id: string): Promise<CustomAssertion>;\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 getSkillsGroup(projectId: string, id: string): Promise<SkillsGroup> {\n return fetchJson(`/projects/${projectId}/skills-groups/${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 getAssertion(projectId: string, id: string): Promise<CustomAssertion> {\n return fetchJson(`/projects/${projectId}/assertions/${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 SkillsGroup,\n Agent,\n Template,\n CustomAssertion,\n Assertion,\n MCPEntity,\n SubAgent\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';\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, we need to replace {{param}} placeholders in the prompt\n if (assertion.type === 'llm_judge') {\n let prompt = assertion.prompt;\n let systemPrompt = assertion.systemPrompt;\n\n for (const [key, value] of Object.entries(params)) {\n const placeholder = `{{${key}}}`;\n // Escape special regex characters in the placeholder (curly braces)\n const escapedPlaceholder = placeholder.replace(/[{}]/g, '\\\\$&');\n const replacement = String(value ?? '');\n prompt = prompt.replace(new RegExp(escapedPlaceholder, 'g'), replacement);\n if (systemPrompt) {\n systemPrompt = systemPrompt.replace(\n new RegExp(escapedPlaceholder, 'g'),\n replacement\n );\n }\n }\n\n return { ...assertion, prompt, systemPrompt };\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 };\n }\n\n // For build_passed, 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 };\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 'llm_judge':\n baseAssertion = {\n type: 'llm_judge',\n prompt: (params?.prompt as string) ?? '',\n systemPrompt: params?.systemPrompt as string | undefined,\n minScore: params?.minScore 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 * Convert a CustomAssertion (database entity) to an Assertion (inline format).\n */\nexport function customAssertionToAssertion(\n ca: CustomAssertion,\n params?: Record<string, unknown>\n): Assertion {\n const config = ca.config as Record<string, unknown>;\n\n // Custom assertions are always llm_judge (skill_was_called and\n // build_passed are system-only assertions, never stored in the DB).\n const baseAssertion: Assertion = {\n type: 'llm_judge',\n prompt: (config?.prompt as string) ?? '',\n systemPrompt: config?.systemPrompt as string | undefined,\n minScore: config?.minScore as number | undefined,\n model: config?.model as string | undefined,\n maxTokens: config?.maxTokens as number | undefined,\n temperature: config?.temperature as number | undefined\n };\n\n return applyParamsToAssertion(baseAssertion, params);\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 code agent + skills + skills group + mcps + subAgents; per-scenario template.\n */\nexport interface EvaluationData {\n evalRun: EvalRun;\n codeAgent: Agent | null;\n skills: SkillWithLatestVersion[];\n skillsGroup: SkillsGroup | null;\n /** Display name for the skills group (from skillsGroup.name when present) */\n skillsGroupName: string;\n mcps: MCPEntity[];\n subAgents: SubAgent[];\n scenarioItems: ScenarioItem[];\n}\n\n/**\n * Fetch all data needed to run an evaluation.\n *\n * Uses evalRun.agentId and evalRun.skillsGroupId as run-level inputs.\n * Loads skills from the skills group; 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 codeAgent: Agent | null = null;\n if (evalRun.agentId) {\n codeAgent = await api.getAgent(projectId, evalRun.agentId);\n }\n\n let skills: SkillWithLatestVersion[] = [];\n let skillsGroup: SkillsGroup | null = null;\n if (evalRun.skillsGroupId) {\n skillsGroup = await api.getSkillsGroup(projectId, evalRun.skillsGroupId);\n if (skillsGroup.skillIds.length > 0) {\n skills = await Promise.all(\n skillsGroup.skillIds.map((id) => api.getSkill(projectId, id))\n );\n }\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 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 // Collect all unique custom assertion IDs from scenarios (filter out system assertions)\n const assertionIds = [\n ...new Set(\n scenarios\n .flatMap((s) => s.assertionLinks ?? [])\n .map((link) => link.assertionId)\n .filter((id) => !isSystemAssertionId(id))\n )\n ];\n\n // Fetch all assertions in parallel\n const assertions =\n assertionIds.length > 0\n ? await Promise.all(\n assertionIds.map((id) => api.getAssertion(projectId, id))\n )\n : [];\n const assertionMap = new Map(assertions.map((a) => [a.id, a]));\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 // Handle system assertions\n if (isSystemAssertionId(assertionId)) {\n return resolveSystemAssertion(\n assertionId as SystemAssertionId,\n params as Record<string, unknown>\n );\n }\n\n // Handle custom assertions from database\n const customAssertion = assertionMap.get(assertionId);\n if (!customAssertion) {\n return null;\n }\n return customAssertionToAssertion(\n customAssertion,\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 const skillsGroupName = skillsGroup?.name ?? '';\n\n return {\n evalRun,\n codeAgent,\n skills,\n skillsGroup,\n skillsGroupName,\n mcps,\n subAgents,\n scenarioItems\n };\n}\n", "import type {\n EvalRunResult,\n TestScenario,\n Template\n} from '@wix/evalforge-types';\nimport { AssertionResultStatus } 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, skillsGroup, codeAgent, 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 skillsGroupId = evalData.evalRun.skillsGroupId!;\n\n const workDir = await prepareWorkingDirectory(\n config,\n evalRunId,\n skillsGroupId,\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 };\n\n // Adapt EvaluatorConfig to AssertionContext\n const assertionContext: AssertionContext = {\n workDir,\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 } from 'fs';\nimport { tmpdir } from 'os';\nimport path from 'path';\nimport type { EvaluatorConfig } from '../config.js';\nimport { fetchGitHubFolder } from '@wix/evalforge-github-client';\nimport { writeSkillFiles } from './agents/claude-code/write-skills.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 writeSkillFiles(workDir, files);\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 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, join, resolve, sep } from 'path';\nimport type {\n GitHubSource,\n SkillFile,\n SkillWithLatestVersion\n} from '@wix/evalforge-types';\nimport { fetchGitHubFolder } from '@wix/evalforge-github-client';\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 writeSkillFiles(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 writeSkillFiles(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 */\nexport async function writeSkillFiles(\n skillDir: string,\n files: SkillFile[]\n): Promise<void> {\n const resolvedBase = resolve(skillDir);\n for (const file of files) {\n const filePath = resolve(skillDir, file.path);\n if (!filePath.startsWith(resolvedBase + sep) && filePath !== resolvedBase) {\n throw new Error(\n `Path traversal detected in skill file: \"${file.path}\" resolves outside skill 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 {\n snapshotDirectory,\n diffSnapshots,\n extractTemplateFiles\n} from './file-diff.js';\n\n/**\n * Default agent command to use when no agent is specified.\n * This maintains backward compatibility with existing behavior.\n */\nconst DEFAULT_AGENT_COMMAND = '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. If no agent is specified, defaults to 'claude'.\n * The context includes skills group, optional MCPs, optional sub-agents.\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, skillsGroup, codeAgent, 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 skillsGroupId = evalData.evalRun.skillsGroupId;\n if (!skillsGroupId) {\n throw new Error(`Eval run ${evalData.evalRun.id} has no skillsGroupId`);\n }\n const agent = evalData.codeAgent ?? undefined;\n\n // Get the appropriate adapter for this agent command\n // Falls back to default 'claude' if no agent is specified\n const runCommand = agent?.runCommand ?? DEFAULT_AGENT_COMMAND;\n const adapter = getAdapter(runCommand);\n\n const startedAt = new Date().toISOString();\n\n // Snapshot directory before execution (if workDir is provided)\n const beforeSnapshot = workDir ? snapshotDirectory(workDir) : {};\n\n // Build the agent-agnostic execution context\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: skillsGroupId,\n targetName: evalData.skillsGroupName,\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 };\n\n const { outputText, durationMs, llmTrace } =\n await adapter.execute(executionContext);\n\n const completedAt = new Date().toISOString();\n\n // Snapshot directory after execution and compute diffs\n const afterSnapshot = workDir ? snapshotDirectory(workDir) : {};\n const fileDiffs = diffSnapshots(beforeSnapshot, afterSnapshot);\n const templateFiles = workDir\n ? extractTemplateFiles(beforeSnapshot, afterSnapshot)\n : undefined;\n\n return {\n id: randomUUID(),\n targetId: skillsGroupId,\n targetName: evalData.skillsGroupName,\n scenarioId: scenario.id,\n scenarioName: scenario.name,\n modelConfig: agent?.modelConfig,\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 };\n}\n", "import type { AgentAdapter } from '@wix/evalforge-types';\n\n/**\n * Registry for agent adapters.\n *\n * Provides registration and lookup of agent adapters by their supported\n * commands. This enables the evaluation system to dynamically select\n * the appropriate adapter based on the agent's runCommand property.\n *\n * @example\n * ```typescript\n * const registry = new AgentAdapterRegistry();\n * registry.register(new ClaudeCodeAdapter());\n *\n * const adapter = registry.get('claude');\n * if (adapter) {\n * const result = await adapter.execute(context);\n * }\n * ```\n */\nexport class AgentAdapterRegistry {\n /**\n * Map of command strings to their registered adapters.\n * Multiple commands can map to the same adapter.\n */\n private adapters = new Map<string, AgentAdapter>();\n\n /**\n * Set of all registered adapter instances (for getAll).\n */\n private registeredAdapters = new Set<AgentAdapter>();\n\n /**\n * Register an agent adapter.\n *\n * The adapter will be registered for all commands in its supportedCommands array.\n * If a command is already registered, it will be overwritten with a warning.\n *\n * @param adapter - The adapter to register\n */\n register(adapter: AgentAdapter): void {\n // Add to the set of all adapters\n this.registeredAdapters.add(adapter);\n\n // Register for each supported command\n for (const command of adapter.supportedCommands) {\n if (this.adapters.has(command)) {\n const existing = this.adapters.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.adapters.set(command, adapter);\n }\n }\n\n /**\n * Get an adapter by command string.\n *\n * @param runCommand - The command string to look up (e.g., 'claude', 'cursor')\n * @returns The registered adapter, or undefined if not found\n */\n get(runCommand: string): AgentAdapter | undefined {\n return this.adapters.get(runCommand);\n }\n\n /**\n * Check if a command has a registered adapter.\n *\n * @param runCommand - The command string to check\n * @returns True if an adapter is registered for this command\n */\n has(runCommand: string): boolean {\n return this.adapters.has(runCommand);\n }\n\n /**\n * Get all registered adapters.\n *\n * @returns Array of all unique registered adapters\n */\n getAll(): AgentAdapter[] {\n return Array.from(this.registeredAdapters);\n }\n\n /**\n * Get all supported commands.\n *\n * @returns Array of all registered command strings\n */\n getSupportedCommands(): string[] {\n return Array.from(this.adapters.keys());\n }\n\n /**\n * Unregister an adapter by its ID.\n *\n * Removes the adapter and all its command mappings.\n *\n * @param adapterId - The ID of the adapter to remove\n * @returns True if the adapter was found and removed\n */\n unregister(adapterId: string): boolean {\n let found = false;\n\n // Find and remove the adapter from the set\n for (const adapter of this.registeredAdapters) {\n if (adapter.id === adapterId) {\n this.registeredAdapters.delete(adapter);\n found = true;\n\n // Remove all command mappings for this adapter\n for (const command of adapter.supportedCommands) {\n if (this.adapters.get(command) === adapter) {\n this.adapters.delete(command);\n }\n }\n break;\n }\n }\n\n return found;\n }\n\n /**\n * Clear all registered adapters.\n * Primarily useful for testing.\n */\n clear(): void {\n this.adapters.clear();\n this.registeredAdapters.clear();\n }\n}\n\n/**\n * Default global registry instance.\n *\n * This is the main registry used by the evaluation system.\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 * Convenience function that throws a helpful error if the adapter is not found.\n *\n * @param runCommand - The command string to look up\n * @returns The registered adapter\n * @throws Error if no adapter is registered for the command\n */\nexport function getAdapter(runCommand: string): AgentAdapter {\n const adapter = defaultRegistry.get(runCommand);\n if (!adapter) {\n const supported = defaultRegistry.getSupportedCommands();\n throw new Error(\n `No agent adapter registered for command \"${runCommand}\". ` +\n `Supported commands: ${supported.length > 0 ? supported.join(', ') : '(none registered)'}`\n );\n }\n return adapter;\n}\n\n/**\n * Check if a command has a registered adapter in the default registry.\n *\n * @param runCommand - The command string to check\n * @returns True if an adapter is registered for this command\n */\nexport function hasAdapter(runCommand: string): boolean {\n return defaultRegistry.has(runCommand);\n}\n", "import type {\n AgentAdapter,\n AgentExecutionContext,\n AgentExecutionResult\n} from '@wix/evalforge-types';\nimport { AVAILABLE_MODELS_MAP } from '@wix/evalforge-types';\nimport { executeWithClaudeCode } 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 = ['claude'] as const;\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 } = context;\n\n const modelForSdk = modelConfig?.model\n ? (AVAILABLE_MODELS_MAP[modelConfig.model]?.providerModelId ??\n modelConfig.model)\n : undefined;\n\n // Build Claude-specific execution options from the generic context\n // Skills are written to .claude/skills/ and discovered by the SDK - no system prompt needed\n const options: ClaudeCodeExecutionOptions = {\n cwd,\n model: modelForSdk,\n temperature: modelConfig?.temperature,\n maxTokens: modelConfig?.maxTokens,\n aiGatewayUrl,\n aiGatewayHeaders,\n traceContext,\n mcps,\n subAgents\n };\n\n // Execute using the existing Claude Code implementation\n const { result, llmTrace } = 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 };\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 Model\n} from '@wix/evalforge-types';\nimport {\n LLMStepType,\n LiveTraceEventType,\n TRACE_EVENT_PREFIX,\n AVAILABLE_MODELS\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';\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 - tracks when each message was received.\n */\ninterface TimestampedMessage {\n message: SDKMessage;\n receivedAt: Date;\n}\n\n/**\n * Default model to use for Claude Code execution.\n * Using claude-3-5-sonnet-latest which is confirmed working with AI Gateway.\n */\nconst DEFAULT_MODEL = 'claude-3-5-sonnet-latest';\n\n/**\n * Calculate cost in USD based on token usage and model name.\n * Looks up pricing from AVAILABLE_MODELS by matching the model name.\n */\nfunction calculateStepCost(\n inputTokens: number,\n outputTokens: number,\n modelName: string\n): number {\n // Find model by matching name or providerModelId\n const model = AVAILABLE_MODELS.find((m: Model) =>\n m.name === modelName ||\n m.providerModelId === modelName ||\n // Handle model aliases like \"claude-3-5-sonnet-latest\" -> \"claude-3-5-sonnet-20241022\"\n modelName.includes('claude-3-5-sonnet')\n ? m.providerModelId.includes('claude-3-5-sonnet')\n : modelName.includes('claude-4-sonnet')\n ? m.providerModelId.includes('claude-4-sonnet')\n : modelName.includes('claude-4-opus')\n ? m.providerModelId.includes('claude-4-opus')\n : false\n );\n\n if (!model) {\n // Default to Claude 3.5 Sonnet pricing if model not found\n const inputCost = (inputTokens / 1_000_000) * 3;\n const outputCost = (outputTokens / 1_000_000) * 15;\n return inputCost + outputCost;\n }\n\n const inputCost = (inputTokens / 1_000_000) * model.pricing.inputPer1M;\n const outputCost = (outputTokens / 1_000_000) * model.pricing.outputPer1M;\n return inputCost + outputCost;\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 * @param event - The trace event to emit\n * @param tracePushUrl - Optional URL to push trace events via HTTP\n * @param routeHeader - Optional x-wix-route header for deploy preview routing\n * @param authToken - Optional Bearer token for public endpoint authentication\n */\nfunction emitTraceEvent(\n event: LiveTraceEvent,\n tracePushUrl?: string,\n routeHeader?: string,\n authToken?: string\n): void {\n // Always emit to stdout for local execution\n console.log(`${TRACE_EVENT_PREFIX}${JSON.stringify(event)}`);\n\n // If trace push URL is provided (remote execution), POST the event\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/**\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 * Push a trace event to the backend via HTTP POST.\n * This is used for remote job execution where stdout is not accessible.\n * @param url - The trace push URL\n * @param event - The trace event to push\n * @param routeHeader - Optional x-wix-route header for deploy preview routing\n * @param authToken - Optional Bearer token for public endpoint authentication\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 // Add Authorization header for public endpoint authentication\n if (authToken) {\n headers['Authorization'] = `Bearer ${authToken}`;\n }\n\n // Add x-wix-route header for deploy preview routing if provided\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 * 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 // Determine event type and extract relevant data\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\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 // Extract file path from common tool inputs\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 // Detect file operation type\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 }\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 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 text from user message content\n // Content can be string or array of blocks\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' && 'text' in block && block.text) {\n outputPreview = String(block.text).slice(0, 500);\n break;\n }\n }\n }\n\n return {\n ...baseEvent,\n type: LiveTraceEventType.USER,\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 * 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}> {\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 // #region agent log H3\n console.error(\n '[DEBUG-H3] Importing Claude Agent SDK...',\n JSON.stringify({ timestamp: Date.now() })\n );\n // #endregion\n let query;\n try {\n const sdk = await import('@anthropic-ai/claude-agent-sdk');\n query = sdk.query;\n // #region agent log H3\n console.error(\n '[DEBUG-H3] Claude Agent SDK import SUCCESS',\n JSON.stringify({ timestamp: Date.now() })\n );\n // #endregion\n } catch (importError) {\n // #region agent log H3\n console.error(\n '[DEBUG-H3] Claude Agent SDK import FAILED',\n JSON.stringify({\n error:\n importError instanceof Error\n ? importError.message\n : String(importError),\n stack: importError instanceof Error ? importError.stack : undefined,\n timestamp: Date.now()\n })\n );\n // #endregion\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 if (options.mcps && options.mcps.length > 0) {\n await writeMcpToFilesystem(options.cwd, options.mcps);\n }\n\n if (options.subAgents && options.subAgents.length > 0) {\n await writeSubAgentsToFilesystem(options.cwd, options.subAgents);\n }\n\n // Write all skills to filesystem so Claude Agent SDK can discover them\n // #region agent log H4\n console.error(\n '[DEBUG-H4] writeSkillsToFilesystem START',\n JSON.stringify({\n cwd: options.cwd,\n skillCount: skills.length,\n skillNames: skills.map((s) => s.name),\n timestamp: Date.now()\n })\n );\n // #endregion\n try {\n await writeSkillsToFilesystem(options.cwd, skills);\n // #region agent log H4\n console.error(\n '[DEBUG-H4] writeSkillsToFilesystem SUCCESS',\n JSON.stringify({ timestamp: Date.now() })\n );\n // #endregion\n } catch (writeError) {\n // #region agent log H4\n console.error(\n '[DEBUG-H4] writeSkillsToFilesystem FAILED',\n JSON.stringify({\n error:\n writeError instanceof Error ? writeError.message : String(writeError),\n stack: writeError instanceof Error ? writeError.stack : undefined,\n timestamp: Date.now()\n })\n );\n // #endregion\n throw new Error(\n `Failed to write skills to filesystem: ${writeError instanceof Error ? writeError.message : String(writeError)}`\n );\n }\n\n // Build environment variables for the SDK\n const sdkEnv = buildSdkEnvironment(options);\n\n // === COMPREHENSIVE DEBUG LOGGING ===\n console.log('[SDK-DEBUG] ====== CLAUDE SDK INITIALIZATION ======');\n console.log('[SDK-DEBUG] Timestamp:', new Date().toISOString());\n console.log('[SDK-DEBUG] Node version:', process.version);\n console.log('[SDK-DEBUG] Platform:', process.platform, process.arch);\n console.log('[SDK-DEBUG] CWD:', options.cwd);\n console.log('[SDK-DEBUG] Process CWD:', process.cwd());\n\n // Log SDK environment (redact secrets)\n console.log('[SDK-DEBUG] SDK Environment:');\n console.log(\n '[SDK-DEBUG] ANTHROPIC_API_KEY:',\n sdkEnv.ANTHROPIC_API_KEY\n ? `${sdkEnv.ANTHROPIC_API_KEY.substring(0, 15)}...`\n : 'NOT SET'\n );\n console.log(\n '[SDK-DEBUG] ANTHROPIC_AUTH_TOKEN:',\n sdkEnv.ANTHROPIC_AUTH_TOKEN\n ? `${sdkEnv.ANTHROPIC_AUTH_TOKEN.substring(0, 15)}...`\n : 'NOT SET'\n );\n console.log(\n '[SDK-DEBUG] ANTHROPIC_BASE_URL:',\n sdkEnv.ANTHROPIC_BASE_URL || 'NOT SET'\n );\n console.log(\n '[SDK-DEBUG] ANTHROPIC_CUSTOM_HEADERS present:',\n !!sdkEnv.ANTHROPIC_CUSTOM_HEADERS\n );\n if (sdkEnv.ANTHROPIC_CUSTOM_HEADERS) {\n const headerNames = sdkEnv.ANTHROPIC_CUSTOM_HEADERS.split('\\n')\n .map((h) => {\n const colonIdx = h.indexOf(':');\n return colonIdx > 0 ? h.substring(0, colonIdx) : h;\n })\n .join(', ');\n console.log('[SDK-DEBUG] ANTHROPIC_CUSTOM_HEADERS keys:', headerNames);\n }\n console.log('[SDK-DEBUG] PATH available:', !!sdkEnv.PATH);\n console.log('[SDK-DEBUG] HOME:', sdkEnv.HOME || 'NOT SET');\n\n // Log skills and scenario info\n console.log(\n '[SDK-DEBUG] Skills:',\n skills.map((s) => `${s.id} - ${s.name}`).join(', ')\n );\n console.log('[SDK-DEBUG] Scenario:', scenario.id, '-', scenario.name);\n console.log(\n '[SDK-DEBUG] Prompt preview:',\n scenario.triggerPrompt.substring(0, 100) + '...'\n );\n console.log('[SDK-DEBUG] ============================================');\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 // #region agent log H5\n console.error(\n '[DEBUG-H5] Claude SDK query START',\n JSON.stringify({\n prompt: scenario.triggerPrompt.slice(0, 50),\n model: options.model || DEFAULT_MODEL,\n maxTurns,\n timestamp: Date.now()\n })\n );\n // #endregion\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 ];\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 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] 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 // Append instructions to ensure Claude executes immediately without asking for confirmation.\n // This is necessary because in automated evaluation runs, there's no human to confirm.\n // Also discourage excessive planning and sub-task delegation to reduce run duration.\n const evaluatorPromptSuffix = `\n\nIMPORTANT: This is an automated evaluation run. Follow these guidelines:\n1. Execute the requested changes immediately without asking for confirmation.\n2. Do NOT ask \"would you like me to proceed?\" or similar questions.\n3. Do NOT use the Task tool to delegate simple operations - do them directly yourself.\n4. Keep your approach simple and direct - avoid excessive planning.\n5. Make targeted edits using Read and Edit tools rather than exploring the entire codebase.\n6. If you encounter an error, fix it directly rather than starting over.\n7. Your project root is the current working directory. Always create and modify source code files relative to the project root, NOT inside .claude/skills/ directories.`;\n\n const fullPrompt = scenario.triggerPrompt + evaluatorPromptSuffix;\n\n for await (const message of query({\n prompt: fullPrompt,\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 // #region agent log H5\n if (messageCount <= 3) {\n console.error(\n '[DEBUG-H5] SDK message received',\n JSON.stringify({\n messageCount,\n type: (message as { type?: string }).type,\n timestamp: Date.now()\n })\n );\n }\n // #endregion\n\n\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 and usage\n const outputText = extractFinalOutput(allMessages);\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 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 };\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;\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 // Process grouped assistant messages into steps with actual timestamps\n for (let i = 0; i < sortedGroups.length; i++) {\n const group = sortedGroups[i];\n const lastMessage = group.messages[group.messages.length - 1];\n\n // Calculate actual duration:\n // Duration is from when we first received this message to when we received the next one\n // For the last step, use the end time\n const stepStartTime = group.firstReceivedAt;\n const nextStepStartTime =\n i < sortedGroups.length - 1\n ? sortedGroups[i + 1].firstReceivedAt\n : endTime;\n const durationMs = nextStepStartTime.getTime() - stepStartTime.getTime();\n\n // Extract usage from the message\n const usage = lastMessage.message.usage;\n const inputTokens = usage.input_tokens;\n const outputTokens = usage.output_tokens;\n\n // Extract text from content blocks\n let text = '';\n const toolCalls: Array<{ toolName: string; args: unknown }> = [];\n\n for (const block of lastMessage.message.content) {\n if (block.type === 'text') {\n text += block.text;\n } else if (block.type === 'tool_use') {\n toolCalls.push({\n toolName: block.name,\n args: block.input\n });\n }\n }\n\n steps.push({\n text,\n usage: {\n inputTokens,\n outputTokens,\n totalTokens: inputTokens + outputTokens\n },\n finishReason: mapStopReason(lastMessage.message.stop_reason),\n toolCalls: toolCalls.length > 0 ? toolCalls : undefined,\n startedAt: stepStartTime,\n durationMs: Math.max(0, durationMs) // Ensure non-negative\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} {\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 };\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 },\n model: string\n): LLMTrace {\n // Map steps to LLMTraceStep format with calculated costs\n const traceSteps = steps.map((step, index) => {\n // Calculate cost for this step using model pricing\n const stepCost = calculateStepCost(\n step.usage.inputTokens,\n step.usage.outputTokens,\n model\n );\n\n return {\n id: randomUUID(),\n stepNumber: index + 1,\n type: step.toolCalls?.length\n ? LLMStepType.TOOL_USE\n : LLMStepType.COMPLETION,\n model,\n provider: 'anthropic',\n startedAt: step.startedAt.toISOString(),\n durationMs: step.durationMs,\n tokenUsage: {\n prompt: step.usage.inputTokens,\n completion: step.usage.outputTokens,\n total: step.usage.totalTokens\n },\n costUsd: stepCost,\n toolName: step.toolCalls?.[0]?.toolName,\n toolArguments: step.toolCalls?.[0]\n ? JSON.stringify(step.toolCalls[0].args)\n : undefined,\n outputPreview: step.text?.slice(0, 200),\n success: step.finishReason !== 'error',\n error: step.finishReason === 'error' ? 'Generation failed' : undefined\n };\n });\n\n // Sum tokens and costs from steps (fallback if SDK result is missing or zero)\n const stepsTokens = {\n prompt: traceSteps.reduce((sum, s) => sum + s.tokenUsage.prompt, 0),\n completion: traceSteps.reduce((sum, s) => sum + s.tokenUsage.completion, 0),\n total: traceSteps.reduce((sum, s) => sum + s.tokenUsage.total, 0)\n };\n const stepsTotalCost = traceSteps.reduce((sum, s) => sum + s.costUsd, 0);\n\n // Use SDK-provided usage if available, otherwise use summed values from steps\n const finalTokens = {\n prompt: usage.inputTokens > 0 ? usage.inputTokens : stepsTokens.prompt,\n completion:\n usage.outputTokens > 0 ? usage.outputTokens : stepsTokens.completion,\n total: usage.totalTokens > 0 ? usage.totalTokens : stepsTokens.total\n };\n\n // Use SDK-provided cost if available, otherwise use calculated cost from steps\n const finalCost =\n usage.costUsd !== undefined && usage.costUsd > 0\n ? usage.costUsd\n : stepsTotalCost;\n\n // Build summary with actual values\n const summary = {\n totalSteps: traceSteps.length,\n totalDurationMs,\n totalTokens: finalTokens,\n totalCostUsd: finalCost,\n modelBreakdown: {\n [model]: {\n count: traceSteps.length,\n durationMs: totalDurationMs,\n tokens: finalTokens.total,\n costUsd: finalCost\n }\n },\n modelsUsed: [model]\n };\n\n return {\n id: randomUUID(),\n steps: traceSteps,\n summary\n };\n}\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';\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 * @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 content = JSON.stringify(\n { [MCP_SERVERS_JSON_KEY]: mcpServers },\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", "import { mkdir, writeFile } from 'fs/promises';\nimport { join } from 'path';\nimport type { SubAgent } from '@wix/evalforge-types';\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 * Write sub-agent markdown files to .claude/agents/ for Claude Code to discover.\n *\n * Each sub-agent's subAgentMd (YAML frontmatter + body) is written to\n * .claude/agents/{name}.md. Claude Code loads these at session start.\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 */\nexport async function writeSubAgentsToFilesystem(\n cwd: string,\n subAgents: SubAgent[]\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 await writeFile(filePath, agent.subAgentMd, 'utf8');\n }\n\n console.log(`[SubAgents] Written to ${agentsDir}`);\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';\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", "/**\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 * 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 * @returns Array of DiffContent for files that were created, modified, or renamed\n */\nexport function diffSnapshots(\n before: FileSnapshot,\n after: FileSnapshot\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 });\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 * @returns Array of TemplateFile with status indicators\n */\nexport function extractTemplateFiles(\n before: FileSnapshot,\n after: FileSnapshot\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 });\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 hasCodeAgent: !!evalData.codeAgent,\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 { codeAgent, 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: !!codeAgent,\n agentId: evalData.evalRun.agentId,\n skillsGroupId: evalData.evalRun.skillsGroupId\n };\n\n if (scenarioItems.length > 0 && skills.length === 0) {\n throw new Error(\n `[${ExecutionPhase.VALIDATION}] Eval run has no skills: set skillsGroupId and ensure the group has skills. ` +\n `(skillsGroupId: ${evalData.evalRun.skillsGroupId || 'not set'})`\n );\n }\n if (scenarioItems.length > 0 && skills.length > 0 && !codeAgent) {\n throw new Error(\n `[${ExecutionPhase.VALIDATION}] Eval run has no code agent: set agentId for skill-based 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 skillsGroupId: evalData.evalRun.skillsGroupId,\n skillsGroupName: evalData.skillsGroupName,\n agentId: codeAgent?.id,\n agentName: codeAgent?.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 skills group:',\n evalData.skillsGroupName,\n skillNames ? `(${skillNames})` : '',\n codeAgent ? `with agent: ${codeAgent.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 skills group:',\n evalData.skillsGroupName,\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 skills group \"${evalData.skillsGroupName}\" 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 // 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 SkillsGroup,\n TestScenario,\n Template,\n SkillWithLatestVersion,\n SkillVersion,\n Agent,\n CustomAssertion,\n MCPEntity,\n SubAgent\n} from '@wix/evalforge-types';\n\nexport interface ApiClient {\n getEvalRun(projectId: string, id: string): Promise<EvalRun>;\n getSkillsGroup(projectId: string, id: string): Promise<SkillsGroup>;\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 getAssertion(projectId: string, id: string): Promise<CustomAssertion>;\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 getSkillsGroup(projectId: string, id: string): Promise<SkillsGroup> {\n return fetchJson(`/projects/${projectId}/skills-groups/${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 getAssertion(projectId: string, id: string): Promise<CustomAssertion> {\n return fetchJson(`/projects/${projectId}/assertions/${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 SkillsGroup,\n Agent,\n Template,\n CustomAssertion,\n Assertion,\n MCPEntity,\n SubAgent\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';\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, we need to replace {{param}} placeholders in the prompt\n if (assertion.type === 'llm_judge') {\n let prompt = assertion.prompt;\n let systemPrompt = assertion.systemPrompt;\n\n for (const [key, value] of Object.entries(params)) {\n const placeholder = `{{${key}}}`;\n // Escape special regex characters in the placeholder (curly braces)\n const escapedPlaceholder = placeholder.replace(/[{}]/g, '\\\\$&');\n const replacement = String(value ?? '');\n prompt = prompt.replace(new RegExp(escapedPlaceholder, 'g'), replacement);\n if (systemPrompt) {\n systemPrompt = systemPrompt.replace(\n new RegExp(escapedPlaceholder, 'g'),\n replacement\n );\n }\n }\n\n return { ...assertion, prompt, systemPrompt };\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 };\n }\n\n // For build_passed, 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 };\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 'llm_judge':\n baseAssertion = {\n type: 'llm_judge',\n prompt: (params?.prompt as string) ?? '',\n systemPrompt: params?.systemPrompt as string | undefined,\n minScore: params?.minScore 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 * Convert a CustomAssertion (database entity) to an Assertion (inline format).\n */\nexport function customAssertionToAssertion(\n ca: CustomAssertion,\n params?: Record<string, unknown>\n): Assertion {\n const config = ca.config as Record<string, unknown>;\n\n // Custom assertions are always llm_judge (skill_was_called and\n // build_passed are system-only assertions, never stored in the DB).\n const baseAssertion: Assertion = {\n type: 'llm_judge',\n prompt: (config?.prompt as string) ?? '',\n systemPrompt: config?.systemPrompt as string | undefined,\n minScore: config?.minScore as number | undefined,\n model: config?.model as string | undefined,\n maxTokens: config?.maxTokens as number | undefined,\n temperature: config?.temperature as number | undefined\n };\n\n return applyParamsToAssertion(baseAssertion, params);\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 code agent + skills + skills group + mcps + subAgents; per-scenario template.\n */\nexport interface EvaluationData {\n evalRun: EvalRun;\n codeAgent: Agent | null;\n skills: SkillWithLatestVersion[];\n skillsGroup: SkillsGroup | null;\n /** Display name for the skills group (from skillsGroup.name when present) */\n skillsGroupName: string;\n mcps: MCPEntity[];\n subAgents: SubAgent[];\n scenarioItems: ScenarioItem[];\n}\n\n/**\n * Fetch all data needed to run an evaluation.\n *\n * Uses evalRun.agentId and evalRun.skillsGroupId as run-level inputs.\n * Loads skills from the skills group; 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 codeAgent: Agent | null = null;\n if (evalRun.agentId) {\n codeAgent = await api.getAgent(projectId, evalRun.agentId);\n }\n\n let skills: SkillWithLatestVersion[] = [];\n let skillsGroup: SkillsGroup | null = null;\n if (evalRun.skillsGroupId) {\n skillsGroup = await api.getSkillsGroup(projectId, evalRun.skillsGroupId);\n if (skillsGroup.skillIds.length > 0) {\n const fetchResults = await Promise.allSettled(\n skillsGroup.skillIds.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\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 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 // Collect all unique custom assertion IDs from scenarios (filter out system assertions)\n const assertionIds = [\n ...new Set(\n scenarios\n .flatMap((s) => s.assertionLinks ?? [])\n .map((link) => link.assertionId)\n .filter((id) => !isSystemAssertionId(id))\n )\n ];\n\n // Fetch all assertions in parallel\n const assertions =\n assertionIds.length > 0\n ? await Promise.all(\n assertionIds.map((id) => api.getAssertion(projectId, id))\n )\n : [];\n const assertionMap = new Map(assertions.map((a) => [a.id, a]));\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 // Handle system assertions\n if (isSystemAssertionId(assertionId)) {\n return resolveSystemAssertion(\n assertionId as SystemAssertionId,\n params as Record<string, unknown>\n );\n }\n\n // Handle custom assertions from database\n const customAssertion = assertionMap.get(assertionId);\n if (!customAssertion) {\n return null;\n }\n return customAssertionToAssertion(\n customAssertion,\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 const skillsGroupName = skillsGroup?.name ?? '';\n\n return {\n evalRun,\n codeAgent,\n skills,\n skillsGroup,\n skillsGroupName,\n mcps,\n subAgents,\n scenarioItems\n };\n}\n", "import type {\n EvalRunResult,\n TestScenario,\n Template\n} from '@wix/evalforge-types';\nimport { AssertionResultStatus } 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, skillsGroup, codeAgent, 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 skillsGroupId = evalData.evalRun.skillsGroupId!;\n\n const workDir = await prepareWorkingDirectory(\n config,\n evalRunId,\n skillsGroupId,\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 };\n\n // Adapt EvaluatorConfig to AssertionContext\n const assertionContext: AssertionContext = {\n workDir,\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 } from 'fs';\nimport { tmpdir } from 'os';\nimport path from 'path';\nimport type { EvaluatorConfig } from '../config.js';\nimport { fetchGitHubFolder } from '@wix/evalforge-github-client';\nimport { writeSkillFiles } from './agents/claude-code/write-skills.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 writeSkillFiles(workDir, files);\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 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, join, resolve, sep } from 'path';\nimport type {\n GitHubSource,\n SkillFile,\n SkillWithLatestVersion\n} from '@wix/evalforge-types';\nimport { fetchGitHubFolder } from '@wix/evalforge-github-client';\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 writeSkillFiles(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 writeSkillFiles(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 */\nexport async function writeSkillFiles(\n skillDir: string,\n files: SkillFile[]\n): Promise<void> {\n const resolvedBase = resolve(skillDir);\n for (const file of files) {\n const filePath = resolve(skillDir, file.path);\n if (!filePath.startsWith(resolvedBase + sep) && filePath !== resolvedBase) {\n throw new Error(\n `Path traversal detected in skill file: \"${file.path}\" resolves outside skill 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 {\n snapshotDirectory,\n diffSnapshots,\n extractTemplateFiles\n} from './file-diff.js';\n\n/**\n * Default agent command to use when no agent is specified.\n * This maintains backward compatibility with existing behavior.\n */\nconst DEFAULT_AGENT_COMMAND = '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. If no agent is specified, defaults to 'claude'.\n * The context includes skills group, optional MCPs, optional sub-agents.\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, skillsGroup, codeAgent, 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 skillsGroupId = evalData.evalRun.skillsGroupId;\n if (!skillsGroupId) {\n throw new Error(`Eval run ${evalData.evalRun.id} has no skillsGroupId`);\n }\n const agent = evalData.codeAgent ?? undefined;\n\n // Get the appropriate adapter for this agent command\n // Falls back to default 'claude' if no agent is specified\n const runCommand = agent?.runCommand ?? DEFAULT_AGENT_COMMAND;\n const adapter = getAdapter(runCommand);\n\n const startedAt = new Date().toISOString();\n\n // Snapshot directory before execution (if workDir is provided)\n const beforeSnapshot = workDir ? snapshotDirectory(workDir) : {};\n\n // Build the agent-agnostic execution context\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: skillsGroupId,\n targetName: evalData.skillsGroupName,\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 };\n\n const { outputText, durationMs, llmTrace } =\n await adapter.execute(executionContext);\n\n const completedAt = new Date().toISOString();\n\n // Snapshot directory after execution and compute diffs\n const afterSnapshot = workDir ? snapshotDirectory(workDir) : {};\n const fileDiffs = diffSnapshots(beforeSnapshot, afterSnapshot);\n const templateFiles = workDir\n ? extractTemplateFiles(beforeSnapshot, afterSnapshot)\n : undefined;\n\n return {\n id: randomUUID(),\n targetId: skillsGroupId,\n targetName: evalData.skillsGroupName,\n scenarioId: scenario.id,\n scenarioName: scenario.name,\n modelConfig: agent?.modelConfig,\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 };\n}\n", "import type { AgentAdapter } from '@wix/evalforge-types';\n\n/**\n * Registry for agent adapters.\n *\n * Provides registration and lookup of agent adapters by their supported\n * commands. This enables the evaluation system to dynamically select\n * the appropriate adapter based on the agent's runCommand property.\n *\n * @example\n * ```typescript\n * const registry = new AgentAdapterRegistry();\n * registry.register(new ClaudeCodeAdapter());\n *\n * const adapter = registry.get('claude');\n * if (adapter) {\n * const result = await adapter.execute(context);\n * }\n * ```\n */\nexport class AgentAdapterRegistry {\n /**\n * Map of command strings to their registered adapters.\n * Multiple commands can map to the same adapter.\n */\n private adapters = new Map<string, AgentAdapter>();\n\n /**\n * Set of all registered adapter instances (for getAll).\n */\n private registeredAdapters = new Set<AgentAdapter>();\n\n /**\n * Register an agent adapter.\n *\n * The adapter will be registered for all commands in its supportedCommands array.\n * If a command is already registered, it will be overwritten with a warning.\n *\n * @param adapter - The adapter to register\n */\n register(adapter: AgentAdapter): void {\n // Add to the set of all adapters\n this.registeredAdapters.add(adapter);\n\n // Register for each supported command\n for (const command of adapter.supportedCommands) {\n if (this.adapters.has(command)) {\n const existing = this.adapters.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.adapters.set(command, adapter);\n }\n }\n\n /**\n * Get an adapter by command string.\n *\n * @param runCommand - The command string to look up (e.g., 'claude', 'cursor')\n * @returns The registered adapter, or undefined if not found\n */\n get(runCommand: string): AgentAdapter | undefined {\n return this.adapters.get(runCommand);\n }\n\n /**\n * Check if a command has a registered adapter.\n *\n * @param runCommand - The command string to check\n * @returns True if an adapter is registered for this command\n */\n has(runCommand: string): boolean {\n return this.adapters.has(runCommand);\n }\n\n /**\n * Get all registered adapters.\n *\n * @returns Array of all unique registered adapters\n */\n getAll(): AgentAdapter[] {\n return Array.from(this.registeredAdapters);\n }\n\n /**\n * Get all supported commands.\n *\n * @returns Array of all registered command strings\n */\n getSupportedCommands(): string[] {\n return Array.from(this.adapters.keys());\n }\n\n /**\n * Unregister an adapter by its ID.\n *\n * Removes the adapter and all its command mappings.\n *\n * @param adapterId - The ID of the adapter to remove\n * @returns True if the adapter was found and removed\n */\n unregister(adapterId: string): boolean {\n let found = false;\n\n // Find and remove the adapter from the set\n for (const adapter of this.registeredAdapters) {\n if (adapter.id === adapterId) {\n this.registeredAdapters.delete(adapter);\n found = true;\n\n // Remove all command mappings for this adapter\n for (const command of adapter.supportedCommands) {\n if (this.adapters.get(command) === adapter) {\n this.adapters.delete(command);\n }\n }\n break;\n }\n }\n\n return found;\n }\n\n /**\n * Clear all registered adapters.\n * Primarily useful for testing.\n */\n clear(): void {\n this.adapters.clear();\n this.registeredAdapters.clear();\n }\n}\n\n/**\n * Default global registry instance.\n *\n * This is the main registry used by the evaluation system.\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 * Convenience function that throws a helpful error if the adapter is not found.\n *\n * @param runCommand - The command string to look up\n * @returns The registered adapter\n * @throws Error if no adapter is registered for the command\n */\nexport function getAdapter(runCommand: string): AgentAdapter {\n const adapter = defaultRegistry.get(runCommand);\n if (!adapter) {\n const supported = defaultRegistry.getSupportedCommands();\n throw new Error(\n `No agent adapter registered for command \"${runCommand}\". ` +\n `Supported commands: ${supported.length > 0 ? supported.join(', ') : '(none registered)'}`\n );\n }\n return adapter;\n}\n\n/**\n * Check if a command has a registered adapter in the default registry.\n *\n * @param runCommand - The command string to check\n * @returns True if an adapter is registered for this command\n */\nexport function hasAdapter(runCommand: string): boolean {\n return defaultRegistry.has(runCommand);\n}\n", "import type {\n AgentAdapter,\n AgentExecutionContext,\n AgentExecutionResult\n} from '@wix/evalforge-types';\nimport { AVAILABLE_MODELS_MAP } from '@wix/evalforge-types';\nimport { executeWithClaudeCode } 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 = ['claude'] as const;\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 } = context;\n\n const modelForSdk = modelConfig?.model\n ? (AVAILABLE_MODELS_MAP[modelConfig.model]?.providerModelId ??\n modelConfig.model)\n : undefined;\n\n // Build Claude-specific execution options from the generic context\n // Skills are written to .claude/skills/ and discovered by the SDK - no system prompt needed\n const options: ClaudeCodeExecutionOptions = {\n cwd,\n model: modelForSdk,\n temperature: modelConfig?.temperature,\n maxTokens: modelConfig?.maxTokens,\n aiGatewayUrl,\n aiGatewayHeaders,\n traceContext,\n mcps,\n subAgents\n };\n\n // Execute using the existing Claude Code implementation\n const { result, llmTrace } = 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 };\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 Model\n} from '@wix/evalforge-types';\nimport {\n LLMStepType,\n LiveTraceEventType,\n TRACE_EVENT_PREFIX,\n AVAILABLE_MODELS\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';\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 - tracks when each message was received.\n */\ninterface TimestampedMessage {\n message: SDKMessage;\n receivedAt: Date;\n}\n\n/**\n * Default model to use for Claude Code execution.\n * Using claude-3-5-sonnet-latest which is confirmed working with AI Gateway.\n */\nconst DEFAULT_MODEL = 'claude-3-5-sonnet-latest';\n\n/**\n * Calculate cost in USD based on token usage and model name.\n * Looks up pricing from AVAILABLE_MODELS by matching the model name.\n */\nfunction calculateStepCost(\n inputTokens: number,\n outputTokens: number,\n modelName: string\n): number {\n // Find model by matching name or providerModelId\n const model = AVAILABLE_MODELS.find((m: Model) =>\n m.name === modelName ||\n m.providerModelId === modelName ||\n // Handle model aliases like \"claude-3-5-sonnet-latest\" -> \"claude-3-5-sonnet-20241022\"\n modelName.includes('claude-3-5-sonnet')\n ? m.providerModelId.includes('claude-3-5-sonnet')\n : modelName.includes('claude-4-sonnet')\n ? m.providerModelId.includes('claude-4-sonnet')\n : modelName.includes('claude-4-opus')\n ? m.providerModelId.includes('claude-4-opus')\n : false\n );\n\n if (!model) {\n // Default to Claude 3.5 Sonnet pricing if model not found\n const inputCost = (inputTokens / 1_000_000) * 3;\n const outputCost = (outputTokens / 1_000_000) * 15;\n return inputCost + outputCost;\n }\n\n const inputCost = (inputTokens / 1_000_000) * model.pricing.inputPer1M;\n const outputCost = (outputTokens / 1_000_000) * model.pricing.outputPer1M;\n return inputCost + outputCost;\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 * @param event - The trace event to emit\n * @param tracePushUrl - Optional URL to push trace events via HTTP\n * @param routeHeader - Optional x-wix-route header for deploy preview routing\n * @param authToken - Optional Bearer token for public endpoint authentication\n */\nfunction emitTraceEvent(\n event: LiveTraceEvent,\n tracePushUrl?: string,\n routeHeader?: string,\n authToken?: string\n): void {\n // Always emit to stdout for local execution\n console.log(`${TRACE_EVENT_PREFIX}${JSON.stringify(event)}`);\n\n // If trace push URL is provided (remote execution), POST the event\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/**\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 * Push a trace event to the backend via HTTP POST.\n * This is used for remote job execution where stdout is not accessible.\n * @param url - The trace push URL\n * @param event - The trace event to push\n * @param routeHeader - Optional x-wix-route header for deploy preview routing\n * @param authToken - Optional Bearer token for public endpoint authentication\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 // Add Authorization header for public endpoint authentication\n if (authToken) {\n headers['Authorization'] = `Bearer ${authToken}`;\n }\n\n // Add x-wix-route header for deploy preview routing if provided\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 * 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 // Determine event type and extract relevant data\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\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 // Extract file path from common tool inputs\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 // Detect file operation type\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 }\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 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 text from user message content\n // Content can be string or array of blocks\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' && 'text' in block && block.text) {\n outputPreview = String(block.text).slice(0, 500);\n break;\n }\n }\n }\n\n return {\n ...baseEvent,\n type: LiveTraceEventType.USER,\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 * 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}> {\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 // #region agent log H3\n console.error(\n '[DEBUG-H3] Importing Claude Agent SDK...',\n JSON.stringify({ timestamp: Date.now() })\n );\n // #endregion\n let query;\n try {\n const sdk = await import('@anthropic-ai/claude-agent-sdk');\n query = sdk.query;\n // #region agent log H3\n console.error(\n '[DEBUG-H3] Claude Agent SDK import SUCCESS',\n JSON.stringify({ timestamp: Date.now() })\n );\n // #endregion\n } catch (importError) {\n // #region agent log H3\n console.error(\n '[DEBUG-H3] Claude Agent SDK import FAILED',\n JSON.stringify({\n error:\n importError instanceof Error\n ? importError.message\n : String(importError),\n stack: importError instanceof Error ? importError.stack : undefined,\n timestamp: Date.now()\n })\n );\n // #endregion\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 if (options.mcps && options.mcps.length > 0) {\n await writeMcpToFilesystem(options.cwd, options.mcps);\n }\n\n if (options.subAgents && options.subAgents.length > 0) {\n await writeSubAgentsToFilesystem(options.cwd, options.subAgents);\n }\n\n // Write all skills to filesystem so Claude Agent SDK can discover them\n // #region agent log H4\n console.error(\n '[DEBUG-H4] writeSkillsToFilesystem START',\n JSON.stringify({\n cwd: options.cwd,\n skillCount: skills.length,\n skillNames: skills.map((s) => s.name),\n timestamp: Date.now()\n })\n );\n // #endregion\n try {\n await writeSkillsToFilesystem(options.cwd, skills);\n // #region agent log H4\n console.error(\n '[DEBUG-H4] writeSkillsToFilesystem SUCCESS',\n JSON.stringify({ timestamp: Date.now() })\n );\n // #endregion\n } catch (writeError) {\n // #region agent log H4\n console.error(\n '[DEBUG-H4] writeSkillsToFilesystem FAILED',\n JSON.stringify({\n error:\n writeError instanceof Error ? writeError.message : String(writeError),\n stack: writeError instanceof Error ? writeError.stack : undefined,\n timestamp: Date.now()\n })\n );\n // #endregion\n throw new Error(\n `Failed to write skills to filesystem: ${writeError instanceof Error ? writeError.message : String(writeError)}`\n );\n }\n\n // Build environment variables for the SDK\n const sdkEnv = buildSdkEnvironment(options);\n\n // === COMPREHENSIVE DEBUG LOGGING ===\n console.log('[SDK-DEBUG] ====== CLAUDE SDK INITIALIZATION ======');\n console.log('[SDK-DEBUG] Timestamp:', new Date().toISOString());\n console.log('[SDK-DEBUG] Node version:', process.version);\n console.log('[SDK-DEBUG] Platform:', process.platform, process.arch);\n console.log('[SDK-DEBUG] CWD:', options.cwd);\n console.log('[SDK-DEBUG] Process CWD:', process.cwd());\n\n // Log SDK environment (redact secrets)\n console.log('[SDK-DEBUG] SDK Environment:');\n console.log(\n '[SDK-DEBUG] ANTHROPIC_API_KEY:',\n sdkEnv.ANTHROPIC_API_KEY\n ? `${sdkEnv.ANTHROPIC_API_KEY.substring(0, 15)}...`\n : 'NOT SET'\n );\n console.log(\n '[SDK-DEBUG] ANTHROPIC_AUTH_TOKEN:',\n sdkEnv.ANTHROPIC_AUTH_TOKEN\n ? `${sdkEnv.ANTHROPIC_AUTH_TOKEN.substring(0, 15)}...`\n : 'NOT SET'\n );\n console.log(\n '[SDK-DEBUG] ANTHROPIC_BASE_URL:',\n sdkEnv.ANTHROPIC_BASE_URL || 'NOT SET'\n );\n console.log(\n '[SDK-DEBUG] ANTHROPIC_CUSTOM_HEADERS present:',\n !!sdkEnv.ANTHROPIC_CUSTOM_HEADERS\n );\n if (sdkEnv.ANTHROPIC_CUSTOM_HEADERS) {\n const headerNames = sdkEnv.ANTHROPIC_CUSTOM_HEADERS.split('\\n')\n .map((h) => {\n const colonIdx = h.indexOf(':');\n return colonIdx > 0 ? h.substring(0, colonIdx) : h;\n })\n .join(', ');\n console.log('[SDK-DEBUG] ANTHROPIC_CUSTOM_HEADERS keys:', headerNames);\n }\n console.log('[SDK-DEBUG] PATH available:', !!sdkEnv.PATH);\n console.log('[SDK-DEBUG] HOME:', sdkEnv.HOME || 'NOT SET');\n\n // Log skills and scenario info\n console.log(\n '[SDK-DEBUG] Skills:',\n skills.map((s) => `${s.id} - ${s.name}`).join(', ')\n );\n console.log('[SDK-DEBUG] Scenario:', scenario.id, '-', scenario.name);\n console.log(\n '[SDK-DEBUG] Prompt preview:',\n scenario.triggerPrompt.substring(0, 100) + '...'\n );\n console.log('[SDK-DEBUG] ============================================');\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 // #region agent log H5\n console.error(\n '[DEBUG-H5] Claude SDK query START',\n JSON.stringify({\n prompt: scenario.triggerPrompt.slice(0, 50),\n model: options.model || DEFAULT_MODEL,\n maxTurns,\n timestamp: Date.now()\n })\n );\n // #endregion\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 ];\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 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] 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 // Append instructions to ensure Claude executes immediately without asking for confirmation.\n // This is necessary because in automated evaluation runs, there's no human to confirm.\n // Also discourage excessive planning and sub-task delegation to reduce run duration.\n const evaluatorPromptSuffix = `\n\nIMPORTANT: This is an automated evaluation run. Follow these guidelines:\n1. Execute the requested changes immediately without asking for confirmation.\n2. Do NOT ask \"would you like me to proceed?\" or similar questions.\n3. Do NOT use the Task tool to delegate simple operations - do them directly yourself.\n4. Keep your approach simple and direct - avoid excessive planning.\n5. Make targeted edits using Read and Edit tools rather than exploring the entire codebase.\n6. If you encounter an error, fix it directly rather than starting over.\n7. Your project root is the current working directory. Always create and modify source code files relative to the project root, NOT inside .claude/skills/ directories.\n8. Before finishing, run the project's package manager install command (e.g. \\`npm install\\`, \\`yarn install\\`, or \\`pnpm install\\` depending on the lockfile present) to ensure all dependencies are installed and the project is ready to build.`;\n\n const fullPrompt = scenario.triggerPrompt + evaluatorPromptSuffix;\n\n for await (const message of query({\n prompt: fullPrompt,\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 // #region agent log H5\n if (messageCount <= 3) {\n console.error(\n '[DEBUG-H5] SDK message received',\n JSON.stringify({\n messageCount,\n type: (message as { type?: string }).type,\n timestamp: Date.now()\n })\n );\n }\n // #endregion\n\n\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 and usage\n const outputText = extractFinalOutput(allMessages);\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 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 };\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;\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 // Process grouped assistant messages into steps with actual timestamps\n for (let i = 0; i < sortedGroups.length; i++) {\n const group = sortedGroups[i];\n const lastMessage = group.messages[group.messages.length - 1];\n\n // Calculate actual duration:\n // Duration is from when we first received this message to when we received the next one\n // For the last step, use the end time\n const stepStartTime = group.firstReceivedAt;\n const nextStepStartTime =\n i < sortedGroups.length - 1\n ? sortedGroups[i + 1].firstReceivedAt\n : endTime;\n const durationMs = nextStepStartTime.getTime() - stepStartTime.getTime();\n\n // Extract usage from the message\n const usage = lastMessage.message.usage;\n const inputTokens = usage.input_tokens;\n const outputTokens = usage.output_tokens;\n\n // Extract text from content blocks\n let text = '';\n const toolCalls: Array<{ toolName: string; args: unknown }> = [];\n\n for (const block of lastMessage.message.content) {\n if (block.type === 'text') {\n text += block.text;\n } else if (block.type === 'tool_use') {\n toolCalls.push({\n toolName: block.name,\n args: block.input\n });\n }\n }\n\n steps.push({\n text,\n usage: {\n inputTokens,\n outputTokens,\n totalTokens: inputTokens + outputTokens\n },\n finishReason: mapStopReason(lastMessage.message.stop_reason),\n toolCalls: toolCalls.length > 0 ? toolCalls : undefined,\n startedAt: stepStartTime,\n durationMs: Math.max(0, durationMs) // Ensure non-negative\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} {\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 };\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 },\n model: string\n): LLMTrace {\n // Map steps to LLMTraceStep format with calculated costs\n const traceSteps = steps.map((step, index) => {\n // Calculate cost for this step using model pricing\n const stepCost = calculateStepCost(\n step.usage.inputTokens,\n step.usage.outputTokens,\n model\n );\n\n return {\n id: randomUUID(),\n stepNumber: index + 1,\n type: step.toolCalls?.length\n ? LLMStepType.TOOL_USE\n : LLMStepType.COMPLETION,\n model,\n provider: 'anthropic',\n startedAt: step.startedAt.toISOString(),\n durationMs: step.durationMs,\n tokenUsage: {\n prompt: step.usage.inputTokens,\n completion: step.usage.outputTokens,\n total: step.usage.totalTokens\n },\n costUsd: stepCost,\n toolName: step.toolCalls?.[0]?.toolName,\n toolArguments: step.toolCalls?.[0]\n ? JSON.stringify(step.toolCalls[0].args)\n : undefined,\n outputPreview: step.text?.slice(0, 200),\n success: step.finishReason !== 'error',\n error: step.finishReason === 'error' ? 'Generation failed' : undefined\n };\n });\n\n // Sum tokens and costs from steps (fallback if SDK result is missing or zero)\n const stepsTokens = {\n prompt: traceSteps.reduce((sum, s) => sum + s.tokenUsage.prompt, 0),\n completion: traceSteps.reduce((sum, s) => sum + s.tokenUsage.completion, 0),\n total: traceSteps.reduce((sum, s) => sum + s.tokenUsage.total, 0)\n };\n const stepsTotalCost = traceSteps.reduce((sum, s) => sum + s.costUsd, 0);\n\n // Use SDK-provided usage if available, otherwise use summed values from steps\n const finalTokens = {\n prompt: usage.inputTokens > 0 ? usage.inputTokens : stepsTokens.prompt,\n completion:\n usage.outputTokens > 0 ? usage.outputTokens : stepsTokens.completion,\n total: usage.totalTokens > 0 ? usage.totalTokens : stepsTokens.total\n };\n\n // Use SDK-provided cost if available, otherwise use calculated cost from steps\n const finalCost =\n usage.costUsd !== undefined && usage.costUsd > 0\n ? usage.costUsd\n : stepsTotalCost;\n\n // Build summary with actual values\n const summary = {\n totalSteps: traceSteps.length,\n totalDurationMs,\n totalTokens: finalTokens,\n totalCostUsd: finalCost,\n modelBreakdown: {\n [model]: {\n count: traceSteps.length,\n durationMs: totalDurationMs,\n tokens: finalTokens.total,\n costUsd: finalCost\n }\n },\n modelsUsed: [model]\n };\n\n return {\n id: randomUUID(),\n steps: traceSteps,\n summary\n };\n}\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';\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 * @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 content = JSON.stringify(\n { [MCP_SERVERS_JSON_KEY]: mcpServers },\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", "import { mkdir, writeFile } from 'fs/promises';\nimport { join } from 'path';\nimport type { SubAgent } from '@wix/evalforge-types';\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 * Write sub-agent markdown files to .claude/agents/ for Claude Code to discover.\n *\n * Each sub-agent's subAgentMd (YAML frontmatter + body) is written to\n * .claude/agents/{name}.md. Claude Code loads these at session start.\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 */\nexport async function writeSubAgentsToFilesystem(\n cwd: string,\n subAgents: SubAgent[]\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 await writeFile(filePath, agent.subAgentMd, 'utf8');\n }\n\n console.log(`[SubAgents] Written to ${agentsDir}`);\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';\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", "/**\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 * 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 * @returns Array of DiffContent for files that were created, modified, or renamed\n */\nexport function diffSnapshots(\n before: FileSnapshot,\n after: FileSnapshot\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 });\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 * @returns Array of TemplateFile with status indicators\n */\nexport function extractTemplateFiles(\n before: FileSnapshot,\n after: FileSnapshot\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 });\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": ["EvalStatus", "path", "projectId", "evalRunId", "projectId", "evalRunId", "fetchGitHubFolder", "fetchGitHubFolder", "evalRunId", "workDir", "randomUUID", "writeFile", "join", "mkdir", "writeFile", "join", "inputCost", "outputCost", "path", "errObj", "sdkErrorKeys", "existsSync", "join", "path", "join", "diff", "value", "o", "existsSync", "join", "path", "diffLines", "evalRunId", "randomUUID", "evalRunId", "projectId", "evalRunId", "EvalStatus"]
7
7
  }