loadscope 0.0.0-stage → 0.1.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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/config/schema.ts","../src/core/runner.ts","../src/core/open-model.ts","../src/core/multi-runner.ts","../src/report/dashboard.ts","../src/report/terminal.ts","../src/report/export.ts","../src/modes/breaking-point.ts","../src/report/breakpoint-terminal.ts","../src/modes/regression-gate.ts","../src/report/compare-terminal.ts","../src/report/pdf.ts","../src/report/ai-analysis.ts","../src/report/html.ts","../src/scenario/parser.ts","../src/scenario/runner.ts","../src/report/scenario-terminal.ts","../src/index.ts"],"sourcesContent":["import { z } from \"zod\";\r\nimport os from \"node:os\";\r\nimport type { RunOptions } from \"../types.js\";\r\n\r\n/**\r\n * Parses duration inputs like \"30s\", \"1m\", \"500ms\", or raw numbers into seconds.\r\n */\r\nexport function parseDurationToSeconds(val: string | number): number {\r\n if (typeof val === \"number\") {\r\n if (val <= 0) throw new Error(\"Duration must be greater than 0\");\r\n return val;\r\n }\r\n\r\n const trimmed = val.trim().toLowerCase();\r\n const match = trimmed.match(/^(\\d+(?:\\.\\d+)?)\\s*(ms|s|m|h)?$/);\r\n if (!match) {\r\n throw new Error(`Invalid duration format: \"${val}\". Examples: \"30s\", \"1m\", \"500ms\"`);\r\n }\r\n\r\n const num = parseFloat(match[1]);\r\n const unit = match[2] || \"s\";\r\n\r\n switch (unit) {\r\n case \"ms\":\r\n return num / 1000;\r\n case \"s\":\r\n return num;\r\n case \"m\":\r\n return num * 60;\r\n case \"h\":\r\n return num * 3600;\r\n default:\r\n return num;\r\n }\r\n}\r\n\r\n/**\r\n * Parses header strings like [\"Content-Type: application/json\", \"Authorization: Bearer token\"]\r\n * into a Record<string, string>.\r\n */\r\nexport function parseHeaders(headersInput?: Record<string, string> | string[]): Record<string, string> {\r\n if (!headersInput) return {};\r\n if (!Array.isArray(headersInput)) return headersInput;\r\n\r\n const result: Record<string, string> = {};\r\n for (const item of headersInput) {\r\n const colonIdx = item.indexOf(\":\");\r\n if (colonIdx > 0) {\r\n const key = item.substring(0, colonIdx).trim();\r\n const val = item.substring(colonIdx + 1).trim();\r\n result[key] = val;\r\n }\r\n }\r\n return result;\r\n}\r\n\r\n/**\r\n * Resolves worker count when \"auto\" is requested.\r\n */\r\nexport function resolveWorkerCount(workers: number | \"auto\" | undefined, concurrency: number): number {\r\n if (workers === \"auto\") {\r\n const cpus = os.cpus()?.length || 1;\r\n return Math.max(1, Math.min(concurrency, cpus));\r\n }\r\n const count = typeof workers === \"number\" ? workers : 1;\r\n return Math.max(1, Math.min(concurrency, count));\r\n}\r\n\r\n/**\r\n * Schema validating options passed to LoadScope run.\r\n */\r\nexport const RunOptionsSchema = z.object({\r\n url: z.string().url(\"A valid URL starting with http:// or https:// is required\"),\r\n duration: z.union([z.string(), z.number()]).default(\"10s\").transform(parseDurationToSeconds),\r\n concurrency: z.coerce.number().int().min(1, \"Concurrency must be at least 1\").default(10),\r\n rate: z.coerce.number().positive().optional(),\r\n method: z\r\n .enum([\"GET\", \"POST\", \"PUT\", \"DELETE\", \"PATCH\", \"HEAD\", \"OPTIONS\"])\r\n .default(\"GET\"),\r\n headers: z.record(z.string()).default({}),\r\n body: z.string().optional(),\r\n timeout: z.union([z.string(), z.number()]).default(\"10s\").transform(parseDurationToSeconds),\r\n warmup: z.union([z.string(), z.number()]).optional().transform((v) => (v ? parseDurationToSeconds(v) : 0)),\r\n rampUp: z.union([z.string(), z.number()]).optional().transform((v) => (v ? parseDurationToSeconds(v) : 0)),\r\n mode: z.enum([\"closed\", \"open\"]).optional(),\r\n distribution: z.enum([\"uniform\", \"poisson\"]).default(\"uniform\"),\r\n honest: z.boolean().default(false),\r\n ttfb: z.boolean().default(false),\r\n workers: z.union([z.coerce.number().int().min(1), z.literal(\"auto\")]).default(1),\r\n dashboard: z.boolean().default(true),\r\n json: z.union([z.string(), z.boolean()]).optional(),\r\n csv: z.union([z.string(), z.boolean()]).optional(),\r\n pdf: z.string().optional(),\r\n aiReport: z.string().optional(),\r\n aiDryRun: z.boolean().default(false),\r\n});\r\n\r\nexport type ValidatedRunOptions = z.infer<typeof RunOptionsSchema>;\r\n\r\n/**\r\n * Validate and normalize run options.\r\n */\r\nexport function validateRunOptions(raw: Partial<RunOptions>): ValidatedRunOptions {\r\n // Normalize headers if an array was passed via CLI flags\r\n let headers = raw.headers;\r\n if (Array.isArray(headers)) {\r\n headers = parseHeaders(headers as unknown as string[]);\r\n }\r\n\r\n return RunOptionsSchema.parse({\r\n ...raw,\r\n headers: headers ?? {},\r\n });\r\n}\r\n","import { Pool } from \"undici\";\r\nimport { monitorEventLoopDelay } from \"node:perf_hooks\";\r\nimport { Histogram } from \"../stats/histogram.js\";\r\nimport { recordWithCorrection, extractDistribution } from \"../stats/co-corrector.js\";\r\nimport type { ValidatedRunOptions } from \"../config/schema.js\";\r\nimport type { RunSummary, LatencyPoint } from \"../types.js\";\r\n\r\n/**\r\n * Execute a closed-model load test using undici.Pool.\r\n *\r\n * In the closed model, concurrency is fixed: exactly `concurrency` parallel\r\n * workers loop, each dispatching the next request as soon as the previous finishes.\r\n */\r\nexport async function executeClosedModel(options: ValidatedRunOptions): Promise<RunSummary> {\r\n const urlObj = new URL(options.url);\r\n const pool = new Pool(urlObj.origin, {\r\n connections: options.concurrency,\r\n pipelining: 1,\r\n keepAliveTimeout: 30_000,\r\n keepAliveMaxTimeout: 60_000,\r\n });\r\n\r\n const histogram = new Histogram();\r\n const ttfbHistogram = new Histogram();\r\n let currentSecondHistogram = new Histogram();\r\n const statusCodes: Record<number, number> = {};\r\n const errorsByType: Record<string, number> = {};\r\n const selfCheckWarnings: string[] = [];\r\n const series: LatencyPoint[] = [];\r\n\r\n let networkErrors = 0;\r\n let httpErrors = 0;\r\n let totalDispatched = 0;\r\n\r\n const timeoutMs = Math.max(1, Math.floor(options.timeout * 1000));\r\n const reqPath = urlObj.pathname + urlObj.search;\r\n const reqMethod = options.method as \"GET\" | \"POST\" | \"PUT\" | \"DELETE\" | \"PATCH\" | \"HEAD\" | \"OPTIONS\";\r\n\r\n // Monitor Node event loop delay to detect load generator saturation\r\n const loopDelay = monitorEventLoopDelay({ resolution: 20 });\r\n loopDelay.enable();\r\n\r\n let stopped = false;\r\n const abortController = new AbortController();\r\n\r\n // Helper to execute single request\r\n async function dispatchRequest(recordStats: boolean): Promise<void> {\r\n if (recordStats) totalDispatched++;\r\n const reqStartNs = process.hrtime.bigint();\r\n\r\n try {\r\n const response = await pool.request({\r\n path: reqPath,\r\n method: reqMethod,\r\n headers: options.headers,\r\n body: options.body,\r\n headersTimeout: timeoutMs,\r\n bodyTimeout: timeoutMs,\r\n signal: abortController.signal,\r\n });\r\n\r\n // Headers arrived: TTFB\r\n const headersNs = process.hrtime.bigint();\r\n const ttfbUs = Math.max(0, Number(headersNs - reqStartNs) / 1000);\r\n\r\n // Discard response body up to 10MB without destroying socket connection\r\n await response.body.dump({ limit: 10 * 1024 * 1024 });\r\n\r\n const elapsedUs = Number(process.hrtime.bigint() - reqStartNs) / 1000;\r\n const code = response.statusCode;\r\n\r\n if (recordStats) {\r\n if (options.honest) {\r\n // Expected interval based on concurrency target\r\n const expectedIntervalUs = (10 / options.concurrency) * 1000;\r\n recordWithCorrection(histogram, elapsedUs, expectedIntervalUs);\r\n } else {\r\n histogram.record(elapsedUs);\r\n }\r\n\r\n ttfbHistogram.record(ttfbUs);\r\n currentSecondHistogram.record(elapsedUs);\r\n statusCodes[code] = (statusCodes[code] || 0) + 1;\r\n if (code >= 400) {\r\n httpErrors++;\r\n }\r\n }\r\n } catch (err: unknown) {\r\n const elapsedUs = Number(process.hrtime.bigint() - reqStartNs) / 1000;\r\n if (recordStats) {\r\n networkErrors++;\r\n histogram.record(elapsedUs);\r\n currentSecondHistogram.record(elapsedUs);\r\n\r\n const errorObj = err as { code?: string; name?: string };\r\n const codeKey = errorObj.code || errorObj.name || \"NETWORK_ERROR\";\r\n errorsByType[codeKey] = (errorsByType[codeKey] || 0) + 1;\r\n }\r\n }\r\n }\r\n\r\n // Optional Warmup Phase\r\n if (options.warmup && options.warmup > 0) {\r\n const warmupEndNs = process.hrtime.bigint() + BigInt(Math.floor(options.warmup * 1_000_000_000));\r\n let warmupStopped = false;\r\n\r\n const warmupWorkers = Array.from({ length: options.concurrency }, async () => {\r\n while (!warmupStopped && !stopped) {\r\n if (process.hrtime.bigint() >= warmupEndNs) {\r\n warmupStopped = true;\r\n break;\r\n }\r\n await dispatchRequest(false);\r\n }\r\n });\r\n\r\n await Promise.all(warmupWorkers);\r\n }\r\n\r\n // Measurement Phase\r\n const durationNs = BigInt(Math.floor(options.duration * 1_000_000_000));\r\n const startNs = process.hrtime.bigint();\r\n const endNs = startNs + durationNs;\r\n\r\n const hardDeadlineTimer = setTimeout(() => {\r\n stopped = true;\r\n abortController.abort();\r\n }, Math.ceil(options.duration * 1000) + 200);\r\n\r\n let lastSecond = 0;\r\n const snapshotTimer = setInterval(() => {\r\n const elapsedSec = Math.floor(Number(process.hrtime.bigint() - startNs) / 1_000_000_000);\r\n if (elapsedSec > lastSecond) {\r\n lastSecond = elapsedSec;\r\n series.push({\r\n t: elapsedSec,\r\n p95: currentSecondHistogram.total > 0 ? currentSecondHistogram.percentileMs(95) : histogram.percentileMs(95),\r\n });\r\n currentSecondHistogram = new Histogram();\r\n }\r\n }, 1000);\r\n\r\n async function workerLoop(workerIndex: number): Promise<void> {\r\n if (options.rampUp && options.rampUp > 0) {\r\n const delayMs = (workerIndex / options.concurrency) * options.rampUp * 1000;\r\n if (delayMs > 0) {\r\n await new Promise((resolve) => setTimeout(resolve, delayMs));\r\n }\r\n }\r\n\r\n while (!stopped) {\r\n if (process.hrtime.bigint() >= endNs) {\r\n stopped = true;\r\n break;\r\n }\r\n await dispatchRequest(true);\r\n }\r\n }\r\n\r\n try {\r\n const workers = Array.from({ length: options.concurrency }, (_, i) => workerLoop(i));\r\n await Promise.all(workers);\r\n } finally {\r\n clearTimeout(hardDeadlineTimer);\r\n clearInterval(snapshotTimer);\r\n loopDelay.disable();\r\n await pool.close();\r\n }\r\n\r\n const maxLoopLagMs = loopDelay.max / 1_000_000;\r\n const p99LoopLagMs = loopDelay.percentile(99) / 1_000_000;\r\n if (p99LoopLagMs > 20 || maxLoopLagMs > 50) {\r\n selfCheckWarnings.push(\r\n `Event loop lag detected (max: ${maxLoopLagMs.toFixed(1)}ms, p99: ${p99LoopLagMs.toFixed(1)}ms). The runner's event loop may be saturated, adding client-side queue delay.`\r\n );\r\n }\r\n\r\n const totalNs = process.hrtime.bigint() - startNs;\r\n const totalDurationSec = Math.max(0.001, Number(totalNs) / 1_000_000_000);\r\n const rps = totalDurationSec > 0 ? totalDispatched / totalDurationSec : 0;\r\n const totalFailures = networkErrors + httpErrors;\r\n const errorRate = totalDispatched > 0 ? totalFailures / totalDispatched : 0;\r\n\r\n if (series.length === 0) {\r\n series.push({\r\n t: Math.max(1, Math.round(totalDurationSec)),\r\n p95: histogram.percentileMs(95),\r\n });\r\n }\r\n\r\n return {\r\n target: options.url,\r\n rps,\r\n totalRequests: totalDispatched,\r\n durationSec: totalDurationSec,\r\n p50: histogram.percentileMs(50),\r\n p90: histogram.percentileMs(90),\r\n p95: histogram.percentileMs(95),\r\n p99: histogram.percentileMs(99),\r\n errorRate,\r\n networkErrors,\r\n httpErrors,\r\n statusCodes,\r\n errorsByType,\r\n series,\r\n selfCheckWarnings,\r\n ttfb: options.ttfb ? extractDistribution(ttfbHistogram) : undefined,\r\n };\r\n}\r\n","import { Pool } from \"undici\";\r\nimport { monitorEventLoopDelay } from \"node:perf_hooks\";\r\nimport { Histogram } from \"../stats/histogram.js\";\r\nimport { ArrivalScheduler } from \"./scheduler.js\";\r\nimport { recordWithCorrection, extractDistribution, computeQueueDelay } from \"../stats/co-corrector.js\";\r\nimport type { ValidatedRunOptions } from \"../config/schema.js\";\r\nimport type { RunSummary, LatencyPoint } from \"../types.js\";\r\n\r\n/**\r\n * Execute an open-model load test using undici.Pool.\r\n *\r\n * In the open arrival model, requests are scheduled at target arrival times\r\n * independent of whether previous requests have completed (Uniform or Poisson process).\r\n * Latency is measured from the INTENDED dispatch timestamp to completion timestamp,\r\n * directly revealing client-side queueing delay and eliminating Coordinated Omission.\r\n */\r\nexport async function executeOpenModel(options: ValidatedRunOptions): Promise<RunSummary> {\r\n const targetRps = options.rate && options.rate > 0 ? options.rate : 50;\r\n const distribution = options.distribution ?? \"uniform\";\r\n const expectedIntervalUs = (1 / targetRps) * 1_000_000;\r\n\r\n // Max concurrent connections pool\r\n const maxConnections = Math.max(options.concurrency, Math.min(500, Math.ceil(targetRps * 2)));\r\n const urlObj = new URL(options.url);\r\n const pool = new Pool(urlObj.origin, {\r\n connections: maxConnections,\r\n pipelining: 1,\r\n keepAliveTimeout: 30_000,\r\n keepAliveMaxTimeout: 60_000,\r\n });\r\n\r\n const responseHistogram = new Histogram(); // Honest latency: completionNs - intendedNs\r\n const serviceHistogram = new Histogram(); // Pure server time: completionNs - dispatchNs\r\n const ttfbHistogram = new Histogram(); // Time to first byte: headersNs - dispatchNs\r\n let currentSecondHistogram = new Histogram();\r\n\r\n const statusCodes: Record<number, number> = {};\r\n const errorsByType: Record<string, number> = {};\r\n const selfCheckWarnings: string[] = [];\r\n const series: LatencyPoint[] = [];\r\n\r\n let networkErrors = 0;\r\n let httpErrors = 0;\r\n let totalDispatched = 0;\r\n\r\n const timeoutMs = Math.max(1, Math.floor(options.timeout * 1000));\r\n const reqPath = urlObj.pathname + urlObj.search;\r\n const reqMethod = options.method as \"GET\" | \"POST\" | \"PUT\" | \"DELETE\" | \"PATCH\" | \"HEAD\" | \"OPTIONS\";\r\n\r\n const loopDelay = monitorEventLoopDelay({ resolution: 20 });\r\n loopDelay.enable();\r\n\r\n let stopped = false;\r\n const abortController = new AbortController();\r\n\r\n async function dispatchRequest(intendedNs: bigint, recordStats: boolean): Promise<void> {\r\n if (recordStats) totalDispatched++;\r\n const dispatchNs = process.hrtime.bigint();\r\n\r\n try {\r\n const response = await pool.request({\r\n path: reqPath,\r\n method: reqMethod,\r\n headers: options.headers,\r\n body: options.body,\r\n headersTimeout: timeoutMs,\r\n bodyTimeout: timeoutMs,\r\n signal: abortController.signal,\r\n });\r\n\r\n // Headers arrived: record TTFB\r\n const headersNs = process.hrtime.bigint();\r\n const ttfbUs = Math.max(0, Number(headersNs - dispatchNs) / 1000);\r\n\r\n await response.body.dump({ limit: 10 * 1024 * 1024 });\r\n\r\n const completionNs = process.hrtime.bigint();\r\n const serviceUs = Math.max(0, Number(completionNs - dispatchNs) / 1000);\r\n const honestResponseUs = Math.max(0, Number(completionNs - intendedNs) / 1000);\r\n const code = response.statusCode;\r\n\r\n if (recordStats) {\r\n if (options.honest) {\r\n recordWithCorrection(responseHistogram, honestResponseUs, expectedIntervalUs);\r\n recordWithCorrection(serviceHistogram, serviceUs, expectedIntervalUs);\r\n } else {\r\n responseHistogram.record(honestResponseUs);\r\n serviceHistogram.record(serviceUs);\r\n }\r\n\r\n ttfbHistogram.record(ttfbUs);\r\n currentSecondHistogram.record(honestResponseUs);\r\n statusCodes[code] = (statusCodes[code] || 0) + 1;\r\n if (code >= 400) {\r\n httpErrors++;\r\n }\r\n }\r\n } catch (err: unknown) {\r\n const completionNs = process.hrtime.bigint();\r\n const serviceUs = Math.max(0, Number(completionNs - dispatchNs) / 1000);\r\n const honestResponseUs = Math.max(0, Number(completionNs - intendedNs) / 1000);\r\n\r\n if (recordStats) {\r\n networkErrors++;\r\n responseHistogram.record(honestResponseUs);\r\n serviceHistogram.record(serviceUs);\r\n currentSecondHistogram.record(honestResponseUs);\r\n\r\n const errorObj = err as { code?: string; name?: string };\r\n const codeKey = errorObj.code || errorObj.name || \"NETWORK_ERROR\";\r\n errorsByType[codeKey] = (errorsByType[codeKey] || 0) + 1;\r\n }\r\n }\r\n }\r\n\r\n // Optional Warmup\r\n if (options.warmup && options.warmup > 0) {\r\n const warmupScheduler = new ArrivalScheduler(targetRps, distribution);\r\n const warmupDurationNs = BigInt(Math.floor(options.warmup * 1_000_000_000));\r\n const warmupStartNs = process.hrtime.bigint();\r\n const warmupEndNs = warmupStartNs + warmupDurationNs;\r\n\r\n while (process.hrtime.bigint() < warmupEndNs && !stopped) {\r\n const targetNs = warmupScheduler.nextArrivalNs();\r\n await warmupScheduler.waitUntil(targetNs);\r\n void dispatchRequest(targetNs, false);\r\n }\r\n }\r\n\r\n // Measurement Phase\r\n const durationNs = BigInt(Math.floor(options.duration * 1_000_000_000));\r\n const startNs = process.hrtime.bigint();\r\n const endNs = startNs + durationNs;\r\n\r\n const scheduler = new ArrivalScheduler(targetRps, distribution, startNs);\r\n\r\n const hardDeadlineTimer = setTimeout(() => {\r\n stopped = true;\r\n abortController.abort();\r\n }, Math.ceil(options.duration * 1000) + 300);\r\n\r\n let lastSecond = 0;\r\n const snapshotTimer = setInterval(() => {\r\n const elapsedSec = Math.floor(Number(process.hrtime.bigint() - startNs) / 1_000_000_000);\r\n if (elapsedSec > lastSecond) {\r\n lastSecond = elapsedSec;\r\n series.push({\r\n t: elapsedSec,\r\n p95: currentSecondHistogram.total > 0 ? currentSecondHistogram.percentileMs(95) : responseHistogram.percentileMs(95),\r\n });\r\n currentSecondHistogram = new Histogram();\r\n }\r\n }, 1000);\r\n\r\n const pendingPromises: Set<Promise<void>> = new Set();\r\n\r\n while (!stopped) {\r\n const nowNs = process.hrtime.bigint();\r\n if (nowNs >= endNs) {\r\n stopped = true;\r\n break;\r\n }\r\n\r\n const targetArrivalNs = scheduler.nextArrivalNs();\r\n await scheduler.waitUntil(targetArrivalNs);\r\n\r\n const p = dispatchRequest(targetArrivalNs, true);\r\n pendingPromises.add(p);\r\n p.finally(() => pendingPromises.delete(p));\r\n\r\n if (pendingPromises.size > maxConnections * 2) {\r\n await Promise.race(pendingPromises);\r\n }\r\n }\r\n\r\n await Promise.allSettled(Array.from(pendingPromises));\r\n\r\n clearTimeout(hardDeadlineTimer);\r\n clearInterval(snapshotTimer);\r\n loopDelay.disable();\r\n await pool.close();\r\n\r\n const maxLoopLagMs = loopDelay.max / 1_000_000;\r\n const p99LoopLagMs = loopDelay.percentile(99) / 1_000_000;\r\n if (p99LoopLagMs > 20 || maxLoopLagMs > 50) {\r\n selfCheckWarnings.push(\r\n `Event loop lag detected (max: ${maxLoopLagMs.toFixed(1)}ms, p99: ${p99LoopLagMs.toFixed(1)}ms). The runner's event loop may be saturated, adding client-side queue delay.`\r\n );\r\n }\r\n\r\n if (scheduler.averageDriftMs > 10) {\r\n selfCheckWarnings.push(\r\n `High schedule drift detected (avg drift: ${scheduler.averageDriftMs.toFixed(1)}ms). The client could not maintain the target ${targetRps} req/s arrival rate.`\r\n );\r\n }\r\n\r\n const totalNs = process.hrtime.bigint() - startNs;\r\n const totalDurationSec = Math.max(0.001, Number(totalNs) / 1_000_000_000);\r\n const rps = totalDurationSec > 0 ? totalDispatched / totalDurationSec : 0;\r\n const totalFailures = networkErrors + httpErrors;\r\n const errorRate = totalDispatched > 0 ? totalFailures / totalDispatched : 0;\r\n\r\n if (series.length === 0) {\r\n series.push({\r\n t: Math.max(1, Math.round(totalDurationSec)),\r\n p95: responseHistogram.percentileMs(95),\r\n });\r\n }\r\n\r\n const serviceDist = extractDistribution(serviceHistogram);\r\n const responseDist = extractDistribution(responseHistogram);\r\n const queueDelayDist = computeQueueDelay(responseDist, serviceDist);\r\n const ttfbDist = extractDistribution(ttfbHistogram);\r\n\r\n return {\r\n target: options.url,\r\n rps,\r\n totalRequests: totalDispatched,\r\n durationSec: totalDurationSec,\r\n p50: responseDist.p50,\r\n p90: responseDist.p90,\r\n p95: responseDist.p95,\r\n p99: responseDist.p99,\r\n errorRate,\r\n networkErrors,\r\n httpErrors,\r\n statusCodes,\r\n errorsByType,\r\n series,\r\n selfCheckWarnings,\r\n distribution,\r\n serviceTime: serviceDist,\r\n queueDelay: queueDelayDist,\r\n ttfb: options.ttfb ? ttfbDist : undefined,\r\n scheduleDriftMs: scheduler.averageDriftMs,\r\n };\r\n}\r\n","import { Worker } from \"node:worker_threads\";\r\nimport path from \"node:path\";\r\nimport fs from \"node:fs\";\r\nimport { fileURLToPath } from \"node:url\";\r\nimport { Histogram } from \"../stats/histogram.js\";\r\nimport { LiveDashboard } from \"../report/dashboard.js\";\r\nimport { extractDistribution, computeQueueDelay } from \"../stats/co-corrector.js\";\r\nimport { resolveWorkerCount, type ValidatedRunOptions } from \"../config/schema.js\";\r\nimport type {\r\n RunSummary,\r\n LatencyPoint,\r\n WorkerInitData,\r\n WorkerMessage,\r\n WorkerDoneMessage,\r\n WorkerTickMessage,\r\n} from \"../types.js\";\r\n\r\n/**\r\n * Resolves the location of worker.js/worker.ts across dev, test, and bundled environments.\r\n */\r\nfunction getWorkerPath(): { path: string; execArgv?: string[] } {\r\n // If compiled dist/worker.js exists (built by tsup in CI/prod), prefer it for pure native execution\r\n const distCandidate = path.resolve(process.cwd(), \"dist/worker.js\");\r\n if (fs.existsSync(distCandidate)) {\r\n return { path: distCandidate };\r\n }\r\n\r\n const currentFile = fileURLToPath(import.meta.url);\r\n const dir = path.dirname(currentFile);\r\n\r\n const candidate1 = path.resolve(dir, \"worker.js\");\r\n if (fs.existsSync(candidate1)) return { path: candidate1 };\r\n\r\n const candidate2 = path.resolve(dir, \"../worker.js\");\r\n if (fs.existsSync(candidate2)) return { path: candidate2 };\r\n\r\n if (currentFile.endsWith(\".ts\")) {\r\n const tsWorker = path.resolve(dir, \"worker.ts\");\r\n return { path: tsWorker, execArgv: [\"--import\", \"tsx\"] };\r\n }\r\n\r\n return { path: distCandidate };\r\n}\r\n\r\n/**\r\n * Execute a multi-threaded load test across worker threads.\r\n * Partitions concurrency and arrival rate across W workers, merges their\r\n * log-bucketed histogram snapshots in O(B) time, and updates the live dashboard.\r\n */\r\nexport async function executeMultiThreaded(options: ValidatedRunOptions): Promise<RunSummary> {\r\n const workerCount = resolveWorkerCount(options.workers, options.concurrency);\r\n const targetMode = options.rate && options.rate > 0 ? \"open\" : (options.mode ?? \"closed\");\r\n\r\n const baseConcurrency = Math.floor(options.concurrency / workerCount);\r\n const extraConcurrency = options.concurrency % workerCount;\r\n const ratePerWorker = options.rate && options.rate > 0 ? options.rate / workerCount : undefined;\r\n\r\n const globalHistogram = new Histogram();\r\n const globalServiceHistogram = new Histogram();\r\n const globalTtfbHistogram = new Histogram();\r\n const aggregatedStatusCodes: Record<number, number> = {};\r\n const aggregatedErrorsByType: Record<string, number> = {};\r\n const selfCheckWarnings: string[] = [];\r\n const series: LatencyPoint[] = [];\r\n\r\n const workerLagMax: number[] = [];\r\n const workerLagP99: number[] = [];\r\n\r\n let currentSecondWindowHistogram = new Histogram();\r\n\r\n const dashboard = new LiveDashboard(options.dashboard);\r\n const { path: workerScript, execArgv } = getWorkerPath();\r\n\r\n const startNs = process.hrtime.bigint();\r\n let lastRecordedSec = 0;\r\n\r\n const latestTicks = new Map<number, WorkerTickMessage>();\r\n const doneMessages: WorkerDoneMessage[] = [];\r\n\r\n const workerPromises: Promise<void>[] = [];\r\n\r\n for (let i = 0; i < workerCount; i++) {\r\n const workerConcurrency = baseConcurrency + (i < extraConcurrency ? 1 : 0);\r\n\r\n const initData: WorkerInitData = {\r\n workerIndex: i,\r\n totalWorkers: workerCount,\r\n url: options.url,\r\n duration: options.duration,\r\n concurrency: workerConcurrency,\r\n rate: ratePerWorker,\r\n distribution: options.distribution,\r\n honest: options.honest,\r\n ttfb: options.ttfb,\r\n method: options.method,\r\n headers: options.headers,\r\n body: options.body,\r\n timeout: options.timeout,\r\n warmup: options.warmup ?? 0,\r\n rampUp: options.rampUp ?? 0,\r\n mode: targetMode,\r\n };\r\n\r\n const promise = new Promise<void>((resolve, reject) => {\r\n const worker = new Worker(workerScript, {\r\n workerData: initData,\r\n execArgv: execArgv ?? [],\r\n });\r\n\r\n worker.on(\"message\", (msg: WorkerMessage) => {\r\n if (msg.type === \"tick\") {\r\n latestTicks.set(msg.workerIndex, msg);\r\n currentSecondWindowHistogram.mergeSnapshot(msg.windowSnapshot);\r\n\r\n let liveDispatched = 0;\r\n let liveNetworkErrors = 0;\r\n let liveHttpErrors = 0;\r\n const liveMergedHist = new Histogram();\r\n\r\n for (const t of latestTicks.values()) {\r\n liveDispatched += t.dispatched;\r\n liveNetworkErrors += t.networkErrors;\r\n liveHttpErrors += t.httpErrors;\r\n liveMergedHist.mergeSnapshot(t.cumulativeSnapshot);\r\n }\r\n\r\n const elapsedSec = Math.floor(Number(process.hrtime.bigint() - startNs) / 1_000_000_000);\r\n const currentRps = elapsedSec > 0 ? liveDispatched / elapsedSec : 0;\r\n\r\n if (elapsedSec > lastRecordedSec) {\r\n lastRecordedSec = elapsedSec;\r\n series.push({\r\n t: elapsedSec,\r\n p95: currentSecondWindowHistogram.total > 0 ? currentSecondWindowHistogram.percentileMs(95) : liveMergedHist.percentileMs(95),\r\n });\r\n currentSecondWindowHistogram = new Histogram();\r\n }\r\n\r\n dashboard.update({\r\n target: options.url,\r\n elapsedSec,\r\n totalDurationSec: options.duration,\r\n totalRequests: liveDispatched,\r\n currentRps,\r\n p50Ms: liveMergedHist.percentileMs(50),\r\n p90Ms: liveMergedHist.percentileMs(90),\r\n p95Ms: liveMergedHist.percentileMs(95),\r\n networkErrors: liveNetworkErrors,\r\n httpErrors: liveHttpErrors,\r\n workerCount,\r\n mode: targetMode,\r\n });\r\n } else if (msg.type === \"done\") {\r\n doneMessages.push(msg);\r\n workerLagMax.push(msg.loopLagMaxMs);\r\n workerLagP99.push(msg.loopLagP99Ms);\r\n } else if (msg.type === \"error\") {\r\n reject(new Error(`Worker ${msg.workerIndex} encountered error: ${msg.error}`));\r\n }\r\n });\r\n\r\n worker.on(\"error\", reject);\r\n worker.on(\"exit\", (code) => {\r\n if (code !== 0 && doneMessages.length < workerCount) {\r\n reject(new Error(`Worker ${i} exited with non-zero code ${code}`));\r\n } else {\r\n resolve();\r\n }\r\n });\r\n });\r\n\r\n workerPromises.push(promise);\r\n }\r\n\r\n try {\r\n await Promise.all(workerPromises);\r\n } finally {\r\n dashboard.stop();\r\n }\r\n\r\n let totalDispatched = 0;\r\n let networkErrors = 0;\r\n let httpErrors = 0;\r\n\r\n for (const done of doneMessages) {\r\n totalDispatched += done.dispatched;\r\n networkErrors += done.networkErrors;\r\n httpErrors += done.httpErrors;\r\n\r\n globalHistogram.mergeSnapshot(done.finalSnapshot);\r\n if (done.serviceTimeSnapshot) {\r\n globalServiceHistogram.mergeSnapshot(done.serviceTimeSnapshot);\r\n }\r\n if (done.ttfbSnapshot) {\r\n globalTtfbHistogram.mergeSnapshot(done.ttfbSnapshot);\r\n }\r\n\r\n for (const [code, count] of Object.entries(done.statusCodes)) {\r\n const numCode = Number(code);\r\n aggregatedStatusCodes[numCode] = (aggregatedStatusCodes[numCode] || 0) + count;\r\n }\r\n\r\n for (const [errType, count] of Object.entries(done.errorsByType)) {\r\n aggregatedErrorsByType[errType] = (aggregatedErrorsByType[errType] || 0) + count;\r\n }\r\n }\r\n\r\n const maxLag = workerLagMax.length > 0 ? Math.max(...workerLagMax) : 0;\r\n const maxP99Lag = workerLagP99.length > 0 ? Math.max(...workerLagP99) : 0;\r\n if (maxP99Lag > 20 || maxLag > 50) {\r\n selfCheckWarnings.push(\r\n `Worker event loop lag detected (highest worker max: ${maxLag.toFixed(1)}ms, p99: ${maxP99Lag.toFixed(1)}ms). Load generator event loop was under heavy load.`\r\n );\r\n }\r\n\r\n const totalNs = process.hrtime.bigint() - startNs;\r\n const totalDurationSec = Math.max(0.001, Number(totalNs) / 1_000_000_000);\r\n const rps = totalDurationSec > 0 ? totalDispatched / totalDurationSec : 0;\r\n const totalFailures = networkErrors + httpErrors;\r\n const errorRate = totalDispatched > 0 ? totalFailures / totalDispatched : 0;\r\n\r\n if (series.length === 0) {\r\n series.push({\r\n t: Math.max(1, Math.round(totalDurationSec)),\r\n p95: globalHistogram.percentileMs(95),\r\n });\r\n }\r\n\r\n const responseDist = extractDistribution(globalHistogram);\r\n const hasService = globalServiceHistogram.total > 0;\r\n const serviceDist = hasService ? extractDistribution(globalServiceHistogram) : undefined;\r\n const queueDelayDist = serviceDist ? computeQueueDelay(responseDist, serviceDist) : undefined;\r\n const ttfbDist = globalTtfbHistogram.total > 0 && options.ttfb ? extractDistribution(globalTtfbHistogram) : undefined;\r\n\r\n return {\r\n target: options.url,\r\n rps,\r\n totalRequests: totalDispatched,\r\n durationSec: totalDurationSec,\r\n p50: responseDist.p50,\r\n p90: responseDist.p90,\r\n p95: responseDist.p95,\r\n p99: responseDist.p99,\r\n errorRate,\r\n networkErrors,\r\n httpErrors,\r\n statusCodes: aggregatedStatusCodes,\r\n errorsByType: aggregatedErrorsByType,\r\n series,\r\n selfCheckWarnings,\r\n workerCount,\r\n distribution: options.distribution,\r\n serviceTime: serviceDist,\r\n queueDelay: queueDelayDist,\r\n ttfb: ttfbDist,\r\n };\r\n}\r\n","import logUpdate from \"log-update\";\r\nimport picocolors from \"picocolors\";\r\n\r\nexport interface DashboardStats {\r\n target: string;\r\n elapsedSec: number;\r\n totalDurationSec: number;\r\n totalRequests: number;\r\n currentRps: number;\r\n p50Ms: number;\r\n p90Ms: number;\r\n p95Ms: number;\r\n networkErrors: number;\r\n httpErrors: number;\r\n workerCount: number;\r\n mode: \"closed\" | \"open\";\r\n warnings?: string[];\r\n}\r\n\r\n/**\r\n * Real-time terminal dashboard powered by log-update.\r\n */\r\nexport class LiveDashboard {\r\n private enabled: boolean;\r\n\r\n constructor(enabled = true) {\r\n // Only enable if stdout is a TTY and user did not disable\r\n this.enabled = enabled && Boolean(process.stdout.isTTY);\r\n }\r\n\r\n /**\r\n * Format a progress bar like [████████░░░░░░] 60%\r\n */\r\n private renderProgressBar(percent: number, width = 24): string {\r\n const clamped = Math.max(0, Math.min(1, percent));\r\n const filled = Math.round(clamped * width);\r\n const empty = width - filled;\r\n const bar = picocolors.cyan(\"█\".repeat(filled)) + picocolors.dim(\"░\".repeat(empty));\r\n const pctStr = (clamped * 100).toFixed(0).padStart(3) + \"%\";\r\n return `[${bar}] ${picocolors.bold(pctStr)}`;\r\n }\r\n\r\n /**\r\n * Generates the dashboard text representation.\r\n */\r\n public formatDashboard(stats: DashboardStats): string {\r\n const lines: string[] = [];\r\n const divider = picocolors.dim(\"─\".repeat(58));\r\n const progressPct = stats.totalDurationSec > 0 ? stats.elapsedSec / stats.totalDurationSec : 0;\r\n\r\n lines.push(\"\");\r\n lines.push(divider);\r\n lines.push(\r\n picocolors.bold(picocolors.cyan(\" LoadScope Live Monitor \")) +\r\n picocolors.dim(`• ${stats.target}`)\r\n );\r\n lines.push(divider);\r\n\r\n // Progress bar line\r\n const timeStr = `${stats.elapsedSec.toFixed(1)}s / ${stats.totalDurationSec.toFixed(1)}s`;\r\n lines.push(` ${this.renderProgressBar(progressPct)} ${picocolors.dim(timeStr)}`);\r\n\r\n // Throughput & total requests\r\n lines.push(\r\n ` ${picocolors.dim(\"Throughput:\")} ${picocolors.green(picocolors.bold(stats.currentRps.toLocaleString(\"en-US\", { minimumFractionDigits: 1, maximumFractionDigits: 1 })))} req/s` +\r\n ` ${picocolors.dim(\"Total Requests:\")} ${picocolors.bold(stats.totalRequests.toLocaleString(\"en-US\"))}`\r\n );\r\n\r\n // Latency live percentiles\r\n const p50Str = picocolors.cyan(`${stats.p50Ms.toFixed(2)}ms`);\r\n const p90Str = picocolors.cyan(`${stats.p90Ms.toFixed(2)}ms`);\r\n const p95Str = stats.p95Ms > 300 ? picocolors.yellow(`${stats.p95Ms.toFixed(2)}ms`) : picocolors.cyan(`${stats.p95Ms.toFixed(2)}ms`);\r\n lines.push(\r\n ` ${picocolors.dim(\"Latency:\")} p50: ${p50Str} p90: ${p90Str} p95: ${p95Str}`\r\n );\r\n\r\n // Errors & workers\r\n const totalFailures = stats.networkErrors + stats.httpErrors;\r\n const errorRate = stats.totalRequests > 0 ? (totalFailures / stats.totalRequests) * 100 : 0;\r\n const errorColor = totalFailures > 0 ? picocolors.red : picocolors.green;\r\n const errorStr = errorColor(`${errorRate.toFixed(2)}% (${totalFailures.toLocaleString(\"en-US\")} fails)`);\r\n\r\n lines.push(\r\n ` ${picocolors.dim(\"Error Rate:\")} ${errorStr}` +\r\n ` ${picocolors.dim(\"Workers:\")} ${picocolors.bold(stats.workerCount.toString())} active`\r\n );\r\n\r\n // Warnings if any\r\n if (stats.warnings && stats.warnings.length > 0) {\r\n lines.push(\"\");\r\n for (const w of stats.warnings) {\r\n lines.push(` ${picocolors.yellow(\"⚠️ \")} ${w}`);\r\n }\r\n }\r\n\r\n lines.push(divider);\r\n return lines.join(\"\\n\");\r\n }\r\n\r\n /**\r\n * Update the live terminal display.\r\n */\r\n public update(stats: DashboardStats): void {\r\n if (!this.enabled) return;\r\n logUpdate(this.formatDashboard(stats));\r\n }\r\n\r\n /**\r\n * Stop the live dashboard and clean up terminal state.\r\n */\r\n public stop(): void {\r\n if (!this.enabled) return;\r\n logUpdate.clear();\r\n logUpdate.done();\r\n }\r\n}\r\n","import picocolors from \"picocolors\";\r\nimport type { RunSummary } from \"../types.js\";\r\n\r\n/**\r\n * Format a number to fixed decimals or integer.\r\n */\r\nfunction fmt(num: number, decimals = 2): string {\r\n return num.toLocaleString(\"en-US\", {\r\n minimumFractionDigits: decimals,\r\n maximumFractionDigits: decimals,\r\n });\r\n}\r\n\r\n/**\r\n * Generate a clean, formatted terminal summary report string.\r\n * Kept pure without console.log side-effects for testability.\r\n */\r\nexport function formatTerminalReport(s: RunSummary): string {\r\n const lines: string[] = [];\r\n const divider = picocolors.dim(\"─\".repeat(58));\r\n\r\n lines.push(\"\");\r\n lines.push(divider);\r\n lines.push(\r\n picocolors.bold(picocolors.cyan(\" LoadScope Test Results \")) +\r\n picocolors.dim(`• ${s.target}`)\r\n );\r\n lines.push(divider);\r\n\r\n // Overview\r\n lines.push(\r\n ` ${picocolors.dim(\"Duration:\")} ${picocolors.bold(fmt(s.durationSec, 1))}s` +\r\n ` ${picocolors.dim(\"Total Requests:\")} ${picocolors.bold(s.totalRequests.toLocaleString())}`\r\n );\r\n\r\n const errorColor = s.errorRate > 0 ? picocolors.red : picocolors.green;\r\n const errorRateStr = errorColor(fmt(s.errorRate * 100, 2) + \"%\");\r\n lines.push(\r\n ` ${picocolors.dim(\"Throughput:\")} ${picocolors.green(picocolors.bold(fmt(s.rps, 1)))} req/s` +\r\n ` ${picocolors.dim(\"Error Rate:\")} ${errorRateStr}`\r\n );\r\n\r\n if (s.distribution || s.scheduleDriftMs !== undefined) {\r\n const distText = s.distribution ? `Open Arrival (${s.distribution.toUpperCase()})` : \"Closed Concurrency\";\r\n const driftText = s.scheduleDriftMs !== undefined ? ` • Schedule Drift: ${fmt(s.scheduleDriftMs, 2)}ms` : \"\";\r\n lines.push(` ${picocolors.dim(\"Model:\")} ${picocolors.white(distText)}${picocolors.dim(driftText)}`);\r\n }\r\n\r\n if (s.networkErrors > 0 || s.httpErrors > 0) {\r\n const errorDetails: string[] = [];\r\n if (s.httpErrors > 0) errorDetails.push(`${s.httpErrors.toLocaleString()} HTTP 4xx/5xx`);\r\n if (s.networkErrors > 0) errorDetails.push(`${s.networkErrors.toLocaleString()} network`);\r\n lines.push(` ${picocolors.dim(\"Failures:\")} ${picocolors.yellow(errorDetails.join(\", \"))}`);\r\n }\r\n\r\n // Phase 3: Coordinated Omission Multi-Column Breakdown\r\n if (s.serviceTime && s.queueDelay) {\r\n lines.push(\"\");\r\n lines.push(picocolors.bold(\" Coordinated Omission Breakdown (Honest Latency vs Service Time):\"));\r\n lines.push(picocolors.dim(\" ┌────────────────┬────────────────┬────────────────┬────────────────┐\"));\r\n lines.push(\r\n picocolors.dim(\" │ \") +\r\n picocolors.white(\"Percentile\".padEnd(14)) +\r\n picocolors.dim(\" │ \") +\r\n picocolors.white(\"Service Time\".padEnd(14)) +\r\n picocolors.dim(\" │ \") +\r\n picocolors.white(\"Queue Delay\".padEnd(14)) +\r\n picocolors.dim(\" │ \") +\r\n picocolors.white(\"Honest Total\".padEnd(14)) +\r\n picocolors.dim(\" │\")\r\n );\r\n lines.push(picocolors.dim(\" ├────────────────┼────────────────┼────────────────┼────────────────┤\"));\r\n\r\n const compRows: Array<[string, number, number, number]> = [\r\n [\"p50 (median)\", s.serviceTime.p50, s.queueDelay.p50, s.p50],\r\n [\"p90\", s.serviceTime.p90, s.queueDelay.p90, s.p90],\r\n [\"p95\", s.serviceTime.p95, s.queueDelay.p95, s.p95],\r\n [\"p99\", s.serviceTime.p99, s.queueDelay.p99, s.p99],\r\n ];\r\n\r\n for (const [pct, svc, q, total] of compRows) {\r\n const totalColor = total > 300 ? picocolors.yellow : picocolors.cyan;\r\n const qColor = q > 50 ? picocolors.yellow : picocolors.dim;\r\n\r\n lines.push(\r\n picocolors.dim(\" │ \") +\r\n picocolors.white(pct.padEnd(14)) +\r\n picocolors.dim(\" │ \") +\r\n picocolors.cyan((fmt(svc, 2) + \" ms\").padStart(14)) +\r\n picocolors.dim(\" │ \") +\r\n qColor((fmt(q, 2) + \" ms\").padStart(14)) +\r\n picocolors.dim(\" │ \") +\r\n totalColor((fmt(total, 2) + \" ms\").padStart(14)) +\r\n picocolors.dim(\" │\")\r\n );\r\n }\r\n lines.push(picocolors.dim(\" └────────────────┴────────────────┴────────────────┴────────────────┘\"));\r\n } else {\r\n // Standard Latency Distribution Table\r\n lines.push(\"\");\r\n lines.push(picocolors.bold(\" Latency Distribution:\"));\r\n lines.push(picocolors.dim(\" ┌────────────────┬────────────────┐\"));\r\n lines.push(\r\n picocolors.dim(\" │ \") +\r\n picocolors.white(\"Percentile\".padEnd(14)) +\r\n picocolors.dim(\" │ \") +\r\n picocolors.white(\"Latency (ms)\".padEnd(14)) +\r\n picocolors.dim(\" │\")\r\n );\r\n lines.push(picocolors.dim(\" ├────────────────┼────────────────┤\"));\r\n\r\n const rows: Array<[string, number]> = [\r\n [\"p50 (median)\", s.p50],\r\n [\"p90\", s.p90],\r\n [\"p95\", s.p95],\r\n [\"p99\", s.p99],\r\n ];\r\n\r\n for (const [pct, val] of rows) {\r\n const valColor = val > 300 ? picocolors.yellow : picocolors.cyan;\r\n const namePadded = pct.padEnd(14);\r\n const valFormatted = (fmt(val, 2) + \" ms\").padStart(14);\r\n lines.push(\r\n picocolors.dim(\" │ \") +\r\n picocolors.white(namePadded) +\r\n picocolors.dim(\" │ \") +\r\n valColor(valFormatted) +\r\n picocolors.dim(\" │\")\r\n );\r\n }\r\n lines.push(picocolors.dim(\" └────────────────┴────────────────┘\"));\r\n }\r\n\r\n // Time-To-First-Byte (TTFB) Breakdown\r\n if (s.ttfb) {\r\n lines.push(\"\");\r\n lines.push(\r\n picocolors.bold(\" Time-To-First-Byte (TTFB): \") +\r\n `p50: ${picocolors.cyan(fmt(s.ttfb.p50, 2) + \"ms\")} ` +\r\n `p90: ${picocolors.cyan(fmt(s.ttfb.p90, 2) + \"ms\")} ` +\r\n `p95: ${picocolors.cyan(fmt(s.ttfb.p95, 2) + \"ms\")} ` +\r\n `p99: ${picocolors.cyan(fmt(s.ttfb.p99, 2) + \"ms\")}`\r\n );\r\n }\r\n\r\n // Status codes\r\n const statusEntries = Object.entries(s.statusCodes);\r\n if (statusEntries.length > 0) {\r\n lines.push(\"\");\r\n lines.push(picocolors.bold(\" HTTP Status Codes:\"));\r\n for (const [code, count] of statusEntries) {\r\n const numCode = Number(code);\r\n let colorFn = picocolors.green;\r\n if (numCode >= 400 && numCode < 500) colorFn = picocolors.yellow;\r\n if (numCode >= 500) colorFn = picocolors.red;\r\n\r\n lines.push(` ${colorFn(code)}: ${count.toLocaleString()} requests`);\r\n }\r\n }\r\n\r\n // Network error details (if any)\r\n if (s.errorsByType && Object.keys(s.errorsByType).length > 0) {\r\n lines.push(\"\");\r\n lines.push(picocolors.bold(\" Network Error Breakdown:\"));\r\n for (const [errType, count] of Object.entries(s.errorsByType)) {\r\n lines.push(` ${picocolors.red(errType)}: ${count.toLocaleString()} occurrences`);\r\n }\r\n }\r\n\r\n // Self check warnings (if any)\r\n if (s.selfCheckWarnings && s.selfCheckWarnings.length > 0) {\r\n lines.push(\"\");\r\n lines.push(picocolors.yellow(picocolors.bold(\" Self-Monitoring Warnings:\")));\r\n for (const warning of s.selfCheckWarnings) {\r\n lines.push(` ${picocolors.yellow(\"⚠️ \")} ${warning}`);\r\n }\r\n }\r\n\r\n lines.push(divider);\r\n lines.push(\"\");\r\n\r\n return lines.join(\"\\n\");\r\n}\r\n\r\n/**\r\n * Print a clean, formatted terminal summary report to stdout.\r\n */\r\nexport function printTerminalReport(s: RunSummary): void {\r\n console.log(formatTerminalReport(s));\r\n}\r\n","import type { RunSummary } from \"../types.js\";\r\n\r\n/**\r\n * Serializes a RunSummary to formatted JSON string.\r\n */\r\nexport function formatJsonReport(summary: RunSummary): string {\r\n return JSON.stringify(summary, null, 2);\r\n}\r\n\r\n/**\r\n * Formats a RunSummary and its per-second time series into CSV format.\r\n */\r\nexport function formatCsvReport(summary: RunSummary): string {\r\n const lines: string[] = [];\r\n\r\n // Summary section\r\n lines.push(\"# LoadScope Run Summary\");\r\n lines.push(\"target,duration_sec,total_requests,rps,p50_ms,p90_ms,p95_ms,p99_ms,error_rate,network_errors,http_errors,service_p95_ms,ttfb_p95_ms,distribution\");\r\n lines.push(\r\n [\r\n `\"${summary.target}\"`,\r\n summary.durationSec.toFixed(2),\r\n summary.totalRequests,\r\n summary.rps.toFixed(2),\r\n summary.p50.toFixed(2),\r\n summary.p90.toFixed(2),\r\n summary.p95.toFixed(2),\r\n summary.p99.toFixed(2),\r\n (summary.errorRate * 100).toFixed(2) + \"%\",\r\n summary.networkErrors,\r\n summary.httpErrors,\r\n summary.serviceTime ? summary.serviceTime.p95.toFixed(2) : \"N/A\",\r\n summary.ttfb ? summary.ttfb.p95.toFixed(2) : \"N/A\",\r\n summary.distribution ?? \"closed\",\r\n ].join(\",\")\r\n );\r\n\r\n lines.push(\"\");\r\n\r\n // Time-series section\r\n lines.push(\"# Per-Second Latency Series\");\r\n lines.push(\"time_sec,p95_ms\");\r\n for (const point of summary.series) {\r\n lines.push(`${point.t},${point.p95.toFixed(2)}`);\r\n }\r\n\r\n lines.push(\"\");\r\n\r\n // Status codes section\r\n lines.push(\"# Status Codes\");\r\n lines.push(\"status_code,count\");\r\n for (const [code, count] of Object.entries(summary.statusCodes)) {\r\n lines.push(`${code},${count}`);\r\n }\r\n\r\n return lines.join(\"\\n\");\r\n}\r\n\r\n/**\r\n * Serializes a BreakpointSummary to formatted JSON string.\r\n */\r\nexport function formatBreakpointJsonReport(summary: import(\"../types.js\").BreakpointSummary): string {\r\n return JSON.stringify(summary, null, 2);\r\n}\r\n\r\n/**\r\n * Formats a BreakpointSummary and all its steps into CSV format.\r\n */\r\nexport function formatBreakpointCsvReport(summary: import(\"../types.js\").BreakpointSummary): string {\r\n const lines: string[] = [];\r\n\r\n // Metadata\r\n lines.push(\"# LoadScope Breaking-Point Summary\");\r\n lines.push(\"target,mode,start,max,step,step_duration_sec,breaking_point,safe_capacity,breached,breach_reason\");\r\n lines.push(\r\n [\r\n `\"${summary.target}\"`,\r\n summary.mode,\r\n summary.start,\r\n summary.max,\r\n summary.step,\r\n summary.stepDurationSec,\r\n summary.breakingPoint !== undefined ? summary.breakingPoint : \"none\",\r\n summary.safeCapacity !== undefined ? summary.safeCapacity : \"none\",\r\n summary.breached,\r\n summary.breachReason ? `\"${summary.breachReason}\"` : \"none\",\r\n ].join(\",\")\r\n );\r\n\r\n lines.push(\"\");\r\n\r\n // Steps\r\n lines.push(\"# Step Progression\");\r\n lines.push(\"step,is_refinement,load,rps,p50_ms,p95_ms,p99_ms,error_rate,total_requests,network_errors,http_errors,status,breach_reason\");\r\n const allSteps = [...summary.steps, ...summary.refinementSteps];\r\n for (const s of allSteps) {\r\n lines.push(\r\n [\r\n s.stepIndex,\r\n s.isRefinement ? \"true\" : \"false\",\r\n s.load,\r\n s.rps.toFixed(2),\r\n s.p50.toFixed(2),\r\n s.p95.toFixed(2),\r\n s.p99.toFixed(2),\r\n (s.errorRate * 100).toFixed(2) + \"%\",\r\n s.totalRequests,\r\n s.networkErrors,\r\n s.httpErrors,\r\n s.status,\r\n s.breachReason ? `\"${s.breachReason}\"` : \"\",\r\n ].join(\",\")\r\n );\r\n }\r\n\r\n return lines.join(\"\\n\");\r\n}\r\n\r\n/**\r\n * Serializes a ComparisonSummary to formatted JSON string.\r\n */\r\nexport function formatComparisonJsonReport(summary: import(\"../types.js\").ComparisonSummary): string {\r\n return JSON.stringify(summary, null, 2);\r\n}\r\n\r\n/**\r\n * Formats a ComparisonSummary into CSV format.\r\n */\r\nexport function formatComparisonCsvReport(summary: import(\"../types.js\").ComparisonSummary): string {\r\n const lines: string[] = [];\r\n\r\n lines.push(\"# LoadScope CI Regression Gate Comparison\");\r\n lines.push(\"target,passed,regressions_count,improvements_count\");\r\n lines.push(\r\n [\r\n `\"${summary.currentTarget}\"`,\r\n summary.passed,\r\n summary.regressions.length,\r\n summary.improvements.length,\r\n ].join(\",\")\r\n );\r\n\r\n lines.push(\"\");\r\n\r\n lines.push(\"# Metrics Comparison\");\r\n lines.push(\"metric,baseline,current,delta,delta_pct,unit,status,violation,message\");\r\n for (const m of summary.metrics) {\r\n lines.push(\r\n [\r\n `\"${m.name}\"`,\r\n m.baseline.toFixed(2),\r\n m.current.toFixed(2),\r\n m.delta.toFixed(2),\r\n m.deltaPct.toFixed(2) + \"%\",\r\n `\"${m.unit}\"`,\r\n m.status,\r\n m.thresholdViolation ? \"true\" : \"false\",\r\n m.message ? `\"${m.message}\"` : \"\",\r\n ].join(\",\")\r\n );\r\n }\r\n\r\n return lines.join(\"\\n\");\r\n}\r\n","import { run } from \"../index.js\";\r\nimport { parseDurationToSeconds } from \"../config/schema.js\";\r\nimport type {\r\n BreakpointOptions,\r\n BreakpointSummary,\r\n BreakpointStepResult,\r\n BreakpointLimits,\r\n RunSummary,\r\n} from \"../types.js\";\r\n\r\n/**\r\n * Evaluates whether a RunSummary breaches the configured SLA / error thresholds.\r\n */\r\nfunction evaluateThresholds(\r\n summary: RunSummary,\r\n limits: BreakpointLimits\r\n): { status: \"PASS\" | \"BREACH\"; breachReason?: string } {\r\n if (summary.errorRate > limits.maxErrorRate) {\r\n return {\r\n status: \"BREACH\",\r\n breachReason: `Error rate ${(summary.errorRate * 100).toFixed(2)}% exceeded limit ${(limits.maxErrorRate * 100).toFixed(2)}%`,\r\n };\r\n }\r\n\r\n if (limits.maxP95 !== undefined && summary.p95 > limits.maxP95) {\r\n return {\r\n status: \"BREACH\",\r\n breachReason: `p95 latency ${summary.p95.toFixed(1)}ms exceeded limit ${limits.maxP95}ms`,\r\n };\r\n }\r\n\r\n if (limits.maxP99 !== undefined && summary.p99 > limits.maxP99) {\r\n return {\r\n status: \"BREACH\",\r\n breachReason: `p99 latency ${summary.p99.toFixed(1)}ms exceeded limit ${limits.maxP99}ms`,\r\n };\r\n }\r\n\r\n return { status: \"PASS\" };\r\n}\r\n\r\n/**\r\n * Executes a single load evaluation step.\r\n */\r\nasync function executeStep(\r\n options: BreakpointOptions,\r\n load: number,\r\n stepDurationSec: number\r\n): Promise<RunSummary> {\r\n const isRate = options.mode === \"rate\";\r\n\r\n return await run({\r\n url: options.url,\r\n duration: stepDurationSec,\r\n concurrency: isRate ? Math.max(10, Math.ceil(load / 10)) : load,\r\n rate: isRate ? load : undefined,\r\n mode: isRate ? \"open\" : \"closed\",\r\n distribution: options.distribution || \"uniform\",\r\n honest: options.honest ?? true,\r\n workers: options.workers || 1,\r\n method: options.method || \"GET\",\r\n headers: options.headers,\r\n body: options.body,\r\n timeout: typeof options.timeout === \"number\" || typeof options.timeout === \"string\"\r\n ? parseDurationToSeconds(options.timeout)\r\n : undefined,\r\n dashboard: false,\r\n });\r\n}\r\n\r\n/**\r\n * Runs the Breaking-Point Finder: stepped ramp + binary search capacity detection.\r\n */\r\nexport async function runBreakingPoint(options: BreakpointOptions): Promise<BreakpointSummary> {\r\n const mode = options.mode || \"concurrency\";\r\n const start = options.start ?? 10;\r\n const max = options.max ?? 100;\r\n const step = options.step ?? 10;\r\n const stepDurationSec = options.stepDuration\r\n ? parseDurationToSeconds(options.stepDuration)\r\n : 5;\r\n const refine = options.refine ?? true;\r\n const tolerance = options.tolerance ?? 2;\r\n\r\n const limits: BreakpointLimits = {\r\n maxP95: options.maxP95 ?? 300,\r\n maxP99: options.maxP99,\r\n maxErrorRate: options.maxErrorRate ?? 0.01,\r\n };\r\n\r\n const steps: BreakpointStepResult[] = [];\r\n const refinementSteps: BreakpointStepResult[] = [];\r\n\r\n let lastSafeLoad: number | undefined;\r\n let firstBreachedLoad: number | undefined;\r\n let primaryBreachReason: string | undefined;\r\n\r\n let stepCounter = 1;\r\n\r\n // 1. STEPPED RAMP PHASE\r\n for (let load = start; load <= max; load += step) {\r\n if (options.onStepStart) {\r\n options.onStepStart(stepCounter, load, false);\r\n }\r\n\r\n const summary = await executeStep(options, load, stepDurationSec);\r\n const { status, breachReason } = evaluateThresholds(summary, limits);\r\n\r\n const stepResult: BreakpointStepResult = {\r\n stepIndex: stepCounter,\r\n load,\r\n rps: summary.rps,\r\n p50: summary.p50,\r\n p95: summary.p95,\r\n p99: summary.p99,\r\n errorRate: summary.errorRate,\r\n totalRequests: summary.totalRequests,\r\n networkErrors: summary.networkErrors,\r\n httpErrors: summary.httpErrors,\r\n status,\r\n breachReason,\r\n isRefinement: false,\r\n summary,\r\n };\r\n\r\n steps.push(stepResult);\r\n\r\n if (options.onStepComplete) {\r\n options.onStepComplete(stepResult);\r\n }\r\n\r\n if (status === \"BREACH\") {\r\n firstBreachedLoad = load;\r\n primaryBreachReason = breachReason;\r\n break;\r\n } else {\r\n lastSafeLoad = load;\r\n }\r\n\r\n stepCounter++;\r\n }\r\n\r\n // 2. BINARY SEARCH REFINEMENT PHASE\r\n let breakingPoint: number | undefined = firstBreachedLoad;\r\n\r\n if (firstBreachedLoad !== undefined && refine && lastSafeLoad !== undefined) {\r\n let low = lastSafeLoad;\r\n let high = firstBreachedLoad;\r\n\r\n while (high - low > tolerance) {\r\n const mid = Math.floor((low + high) / 2);\r\n if (mid === low || mid === high) {\r\n break;\r\n }\r\n\r\n stepCounter++;\r\n if (options.onStepStart) {\r\n options.onStepStart(stepCounter, mid, true);\r\n }\r\n\r\n const summary = await executeStep(options, mid, stepDurationSec);\r\n const { status, breachReason } = evaluateThresholds(summary, limits);\r\n\r\n const refResult: BreakpointStepResult = {\r\n stepIndex: stepCounter,\r\n load: mid,\r\n rps: summary.rps,\r\n p50: summary.p50,\r\n p95: summary.p95,\r\n p99: summary.p99,\r\n errorRate: summary.errorRate,\r\n totalRequests: summary.totalRequests,\r\n networkErrors: summary.networkErrors,\r\n httpErrors: summary.httpErrors,\r\n status,\r\n breachReason,\r\n isRefinement: true,\r\n summary,\r\n };\r\n\r\n refinementSteps.push(refResult);\r\n\r\n if (options.onStepComplete) {\r\n options.onStepComplete(refResult);\r\n }\r\n\r\n if (status === \"BREACH\") {\r\n high = mid;\r\n breakingPoint = mid;\r\n primaryBreachReason = breachReason;\r\n } else {\r\n low = mid;\r\n }\r\n }\r\n }\r\n\r\n const safeCapacity = breakingPoint !== undefined\r\n ? Math.max(1, Math.floor((lastSafeLoad ?? breakingPoint) * 0.8))\r\n : max;\r\n const breached = breakingPoint !== undefined;\r\n\r\n return {\r\n target: options.url,\r\n mode,\r\n start,\r\n max,\r\n step,\r\n stepDurationSec,\r\n breakingPoint,\r\n safeCapacity,\r\n breached,\r\n breachReason: primaryBreachReason,\r\n steps,\r\n refinementSteps,\r\n limits,\r\n };\r\n}\r\n","import picocolors from \"picocolors\";\r\nimport type { BreakpointSummary, BreakpointStepResult } from \"../types.js\";\r\n\r\nfunction fmt(num: number, decimals = 1): string {\r\n return num.toLocaleString(\"en-US\", {\r\n minimumFractionDigits: decimals,\r\n maximumFractionDigits: decimals,\r\n });\r\n}\r\n\r\nfunction pad(str: string, width: number, alignRight = false): string {\r\n if (str.length >= width) return str;\r\n const padding = \" \".repeat(width - str.length);\r\n return alignRight ? padding + str : str + padding;\r\n}\r\n\r\n/**\r\n * Format a single step table row for real-time progress logging.\r\n */\r\nexport function formatStepRow(step: BreakpointStepResult, mode: \"concurrency\" | \"rate\"): string {\r\n const loadUnit = mode === \"concurrency\" ? \"conn\" : \"req/s\";\r\n const loadStr = `${step.load} ${loadUnit}`;\r\n const rpsStr = `${fmt(step.rps, 1)}/s`;\r\n const p50Str = fmt(step.p50, 1);\r\n const p95Str = fmt(step.p95, 1);\r\n const p99Str = fmt(step.p99, 1);\r\n const errStr = `${fmt(step.errorRate * 100, 2)}%`;\r\n\r\n let statusBadge = \"\";\r\n if (step.status === \"PASS\") {\r\n statusBadge = picocolors.green(\"✅ PASS\");\r\n } else {\r\n const reason = step.breachReason ? ` (${step.breachReason})` : \"\";\r\n statusBadge = picocolors.red(`❌ BREACH${reason}`);\r\n }\r\n\r\n const prefix = step.isRefinement ? picocolors.cyan(\"•\") : \" \";\r\n return (\r\n ` ${prefix} ${pad(step.stepIndex.toString(), 3, true)} │ ` +\r\n `${pad(loadStr, 11)} │ ` +\r\n `${pad(rpsStr, 10, true)} │ ` +\r\n `${pad(p50Str, 8, true)} │ ` +\r\n `${pad(p95Str, 8, true)} │ ` +\r\n `${pad(p99Str, 8, true)} │ ` +\r\n `${pad(errStr, 8, true)} │ ` +\r\n `${statusBadge}`\r\n );\r\n}\r\n\r\n/**\r\n * Generates a comprehensive terminal report string for Breaking-Point results.\r\n */\r\nexport function formatBreakpointTerminalReport(summary: BreakpointSummary): string {\r\n const lines: string[] = [];\r\n const divider = picocolors.dim(\"─\".repeat(78));\r\n\r\n lines.push(\"\");\r\n lines.push(divider);\r\n lines.push(\r\n picocolors.bold(picocolors.cyan(\" LoadScope Breaking-Point Capacity Analysis \")) +\r\n picocolors.dim(`• ${summary.target}`)\r\n );\r\n lines.push(divider);\r\n\r\n const loadType = summary.mode === \"concurrency\" ? \"Connections\" : \"Target Rate (req/s)\";\r\n lines.push(\r\n ` ${picocolors.dim(\"Mode:\")} ${summary.mode.toUpperCase()} (${loadType})` +\r\n ` ${picocolors.dim(\"Step Duration:\")} ${summary.stepDurationSec}s per step`\r\n );\r\n lines.push(\r\n ` ${picocolors.dim(\"Ramp Range:\")} ${summary.start} ➔ ${summary.max} (step size: ${summary.step})` +\r\n ` ${picocolors.dim(\"Total Steps:\")} ${summary.steps.length + summary.refinementSteps.length}`\r\n );\r\n\r\n const limitsDesc: string[] = [];\r\n if (summary.limits.maxP95 !== undefined) limitsDesc.push(`p95 ≤ ${summary.limits.maxP95}ms`);\r\n if (summary.limits.maxP99 !== undefined) limitsDesc.push(`p99 ≤ ${summary.limits.maxP99}ms`);\r\n limitsDesc.push(`Errors ≤ ${(summary.limits.maxErrorRate * 100).toFixed(1)}%`);\r\n lines.push(` ${picocolors.dim(\"SLA Limits:\")} ${picocolors.yellow(limitsDesc.join(\" | \"))}`);\r\n lines.push(\"\");\r\n\r\n // Table Header\r\n lines.push(picocolors.dim(\" ┌─────┬─────────────┬────────────┬──────────┬──────────┬──────────┬──────────┬─────────────────────────────┐\"));\r\n lines.push(\r\n picocolors.bold(\r\n ` │ ${pad(\"Step\", 3)} │ ${pad(\"Load\", 11)} │ ${pad(\"Throughput\", 10)} │ ${pad(\"p50 (ms)\", 8)} │ ${pad(\"p95 (ms)\", 8)} │ ${pad(\"p99 (ms)\", 8)} │ ${pad(\"Errors\", 8)} │ ${pad(\"Outcome\", 27)} │`\r\n )\r\n );\r\n lines.push(picocolors.dim(\" ├─────┼─────────────┼────────────┼──────────┼──────────┼──────────┼──────────┼─────────────────────────────┤\"));\r\n\r\n // Stepped Ramp Steps\r\n for (const step of summary.steps) {\r\n lines.push(formatStepRow(step, summary.mode));\r\n }\r\n\r\n // Refinement Steps (if any)\r\n if (summary.refinementSteps.length > 0) {\r\n lines.push(picocolors.dim(\" ├─────┴─────────────┴────────────┴──────────┴──────────┴──────────┴──────────┴─────────────────────────────┤\"));\r\n lines.push(picocolors.italic(picocolors.cyan(\" │ Refinement Phase (Binary Search Convergence): │\")));\r\n lines.push(picocolors.dim(\" ├─────┬─────────────┬────────────┬──────────┬──────────┬──────────┬──────────┬─────────────────────────────┤\"));\r\n for (const step of summary.refinementSteps) {\r\n lines.push(formatStepRow(step, summary.mode));\r\n }\r\n }\r\n\r\n lines.push(picocolors.dim(\" └─────┴─────────────┴────────────┴──────────┴──────────┴──────────┴──────────┴─────────────────────────────┘\"));\r\n lines.push(\"\");\r\n\r\n // Findings & Decision Banner\r\n const unit = summary.mode === \"concurrency\" ? \"concurrent connections\" : \"req/sec\";\r\n if (summary.breached && summary.breakingPoint !== undefined) {\r\n lines.push(\r\n picocolors.red(\r\n picocolors.bold(` 🎯 BREAKING POINT DETECTED: ${summary.breakingPoint} ${unit}`)\r\n )\r\n );\r\n if (summary.breachReason) {\r\n lines.push(picocolors.dim(` Trigger: `) + picocolors.red(summary.breachReason));\r\n }\r\n lines.push(\"\");\r\n lines.push(\r\n picocolors.green(\r\n picocolors.bold(` 🛡️ RECOMMENDED SAFE CEILING (80% headroom): ${summary.safeCapacity} ${unit}`)\r\n )\r\n );\r\n lines.push(\r\n picocolors.dim(\r\n ` System sustained load below this threshold without SLA latency or error budget violations.`\r\n )\r\n );\r\n } else {\r\n lines.push(\r\n picocolors.green(\r\n picocolors.bold(` 🎯 NO BREAKING POINT REACHED up to maximum ceiling of ${summary.max} ${unit}!`)\r\n )\r\n );\r\n lines.push(\r\n picocolors.dim(\r\n ` Target passed all SLA thresholds across all tested load levels. Increase --max to test higher capacity.`\r\n )\r\n );\r\n }\r\n\r\n lines.push(divider);\r\n lines.push(\"\");\r\n return lines.join(\"\\n\");\r\n}\r\n\r\n/**\r\n * Print the Breaking-Point report to stdout.\r\n */\r\nexport function printBreakpointTerminalReport(summary: BreakpointSummary): void {\r\n console.log(formatBreakpointTerminalReport(summary));\r\n}\r\n","import fs from \"node:fs/promises\";\r\nimport path from \"node:path\";\r\nimport type {\r\n RunSummary,\r\n BaselineData,\r\n ComparisonMetric,\r\n ComparisonSummary,\r\n GateThresholds,\r\n} from \"../types.js\";\r\n\r\n/**\r\n * Saves a RunSummary as a standard JSON baseline file.\r\n */\r\nexport async function saveBaseline(\r\n summary: RunSummary,\r\n filePath = \"loadscope-baseline.json\",\r\n options?: { concurrency?: number; rate?: number }\r\n): Promise<string> {\r\n const resolvedPath = path.resolve(process.cwd(), filePath);\r\n\r\n const baseline: BaselineData = {\r\n timestamp: new Date().toISOString(),\r\n target: summary.target,\r\n concurrency: options?.concurrency,\r\n rate: options?.rate,\r\n durationSec: summary.durationSec,\r\n rps: summary.rps,\r\n totalRequests: summary.totalRequests,\r\n p50: summary.p50,\r\n p90: summary.p90,\r\n p95: summary.p95,\r\n p99: summary.p99,\r\n errorRate: summary.errorRate,\r\n networkErrors: summary.networkErrors,\r\n httpErrors: summary.httpErrors,\r\n commitHash: process.env.GITHUB_SHA || process.env.GIT_COMMIT || undefined,\r\n };\r\n\r\n await fs.writeFile(resolvedPath, JSON.stringify(baseline, null, 2), \"utf-8\");\r\n return resolvedPath;\r\n}\r\n\r\n/**\r\n * Loads a baseline JSON file from disk.\r\n */\r\nexport async function loadBaseline(filePath: string): Promise<BaselineData> {\r\n const resolvedPath = path.resolve(process.cwd(), filePath);\r\n const content = await fs.readFile(resolvedPath, \"utf-8\");\r\n const parsed = JSON.parse(content) as BaselineData;\r\n\r\n if (typeof parsed.rps !== \"number\" || typeof parsed.p95 !== \"number\") {\r\n throw new Error(`Invalid baseline file at ${filePath}: missing required performance metrics.`);\r\n }\r\n\r\n return parsed;\r\n}\r\n\r\n/**\r\n * Compares current benchmark results against a reference baseline and evaluates regression thresholds.\r\n */\r\nexport function compareRuns(\r\n current: RunSummary | BaselineData,\r\n baseline: BaselineData,\r\n thresholdsInput?: Partial<GateThresholds>\r\n): ComparisonSummary {\r\n const thresholds: GateThresholds = {\r\n maxP95IncreasePct: thresholdsInput?.maxP95IncreasePct ?? 10,\r\n maxRpsDropPct: thresholdsInput?.maxRpsDropPct ?? 5,\r\n maxP99IncreasePct: thresholdsInput?.maxP99IncreasePct,\r\n maxErrorRate: thresholdsInput?.maxErrorRate ?? 0.01,\r\n };\r\n\r\n const metrics: ComparisonMetric[] = [];\r\n\r\n // 1. Throughput (RPS) - Higher is better\r\n {\r\n const delta = current.rps - baseline.rps;\r\n const deltaPct = baseline.rps > 0 ? (delta / baseline.rps) * 100 : 0;\r\n const isRegression = deltaPct < -thresholds.maxRpsDropPct;\r\n const isImprovement = deltaPct > 1.0;\r\n\r\n let status: \"PASS\" | \"IMPROVEMENT\" | \"REGRESSION\" = \"PASS\";\r\n if (isRegression) status = \"REGRESSION\";\r\n else if (isImprovement) status = \"IMPROVEMENT\";\r\n\r\n metrics.push({\r\n name: \"Throughput\",\r\n baseline: baseline.rps,\r\n current: current.rps,\r\n delta,\r\n deltaPct,\r\n unit: \"req/s\",\r\n isHigherBetter: true,\r\n status,\r\n threshold: thresholds.maxRpsDropPct,\r\n thresholdViolation: isRegression,\r\n message: isRegression\r\n ? `Throughput dropped by ${Math.abs(deltaPct).toFixed(1)}% (allowed drop: ${thresholds.maxRpsDropPct}%)`\r\n : undefined,\r\n });\r\n }\r\n\r\n // 2. p50 Latency (Median) - Lower is better\r\n {\r\n const delta = current.p50 - baseline.p50;\r\n const deltaPct = baseline.p50 > 0 ? (delta / baseline.p50) * 100 : 0;\r\n const isImprovement = deltaPct < -1.0;\r\n\r\n metrics.push({\r\n name: \"p50 Latency\",\r\n baseline: baseline.p50,\r\n current: current.p50,\r\n delta,\r\n deltaPct,\r\n unit: \"ms\",\r\n isHigherBetter: false,\r\n status: isImprovement ? \"IMPROVEMENT\" : \"PASS\",\r\n });\r\n }\r\n\r\n // 3. p90 Latency - Lower is better\r\n {\r\n const delta = current.p90 - baseline.p90;\r\n const deltaPct = baseline.p90 > 0 ? (delta / baseline.p90) * 100 : 0;\r\n const isImprovement = deltaPct < -1.0;\r\n\r\n metrics.push({\r\n name: \"p90 Latency\",\r\n baseline: baseline.p90,\r\n current: current.p90,\r\n delta,\r\n deltaPct,\r\n unit: \"ms\",\r\n isHigherBetter: false,\r\n status: isImprovement ? \"IMPROVEMENT\" : \"PASS\",\r\n });\r\n }\r\n\r\n // 4. p95 Latency - Lower is better (Primary SLA Gate)\r\n {\r\n const delta = current.p95 - baseline.p95;\r\n const deltaPct = baseline.p95 > 0 ? (delta / baseline.p95) * 100 : 0;\r\n const isRegression = deltaPct > thresholds.maxP95IncreasePct;\r\n const isImprovement = deltaPct < -1.0;\r\n\r\n let status: \"PASS\" | \"IMPROVEMENT\" | \"REGRESSION\" = \"PASS\";\r\n if (isRegression) status = \"REGRESSION\";\r\n else if (isImprovement) status = \"IMPROVEMENT\";\r\n\r\n metrics.push({\r\n name: \"p95 Latency\",\r\n baseline: baseline.p95,\r\n current: current.p95,\r\n delta,\r\n deltaPct,\r\n unit: \"ms\",\r\n isHigherBetter: false,\r\n status,\r\n threshold: thresholds.maxP95IncreasePct,\r\n thresholdViolation: isRegression,\r\n message: isRegression\r\n ? `p95 latency increased by +${deltaPct.toFixed(1)}% (allowed increase: ${thresholds.maxP95IncreasePct}%)`\r\n : undefined,\r\n });\r\n }\r\n\r\n // 5. p99 Latency - Lower is better\r\n {\r\n const delta = current.p99 - baseline.p99;\r\n const deltaPct = baseline.p99 > 0 ? (delta / baseline.p99) * 100 : 0;\r\n const isRegression =\r\n thresholds.maxP99IncreasePct !== undefined && deltaPct > thresholds.maxP99IncreasePct;\r\n const isImprovement = deltaPct < -1.0;\r\n\r\n let status: \"PASS\" | \"IMPROVEMENT\" | \"REGRESSION\" = \"PASS\";\r\n if (isRegression) status = \"REGRESSION\";\r\n else if (isImprovement) status = \"IMPROVEMENT\";\r\n\r\n metrics.push({\r\n name: \"p99 Latency\",\r\n baseline: baseline.p99,\r\n current: current.p99,\r\n delta,\r\n deltaPct,\r\n unit: \"ms\",\r\n isHigherBetter: false,\r\n status,\r\n threshold: thresholds.maxP99IncreasePct,\r\n thresholdViolation: isRegression,\r\n message: isRegression\r\n ? `p99 latency increased by +${deltaPct.toFixed(1)}% (allowed: ${thresholds.maxP99IncreasePct}%)`\r\n : undefined,\r\n });\r\n }\r\n\r\n // 6. Error Rate (%) - Lower is better\r\n {\r\n const delta = current.errorRate - baseline.errorRate;\r\n const deltaPct =\r\n baseline.errorRate > 0\r\n ? (delta / baseline.errorRate) * 100\r\n : current.errorRate > 0\r\n ? 100\r\n : 0;\r\n\r\n const isRegression =\r\n thresholds.maxErrorRate !== undefined && current.errorRate > thresholds.maxErrorRate;\r\n const isImprovement = current.errorRate < baseline.errorRate;\r\n\r\n let status: \"PASS\" | \"IMPROVEMENT\" | \"REGRESSION\" = \"PASS\";\r\n if (isRegression) status = \"REGRESSION\";\r\n else if (isImprovement) status = \"IMPROVEMENT\";\r\n\r\n metrics.push({\r\n name: \"Error Rate\",\r\n baseline: baseline.errorRate * 100,\r\n current: current.errorRate * 100,\r\n delta: delta * 100,\r\n deltaPct,\r\n unit: \"%\",\r\n isHigherBetter: false,\r\n status,\r\n threshold: thresholds.maxErrorRate !== undefined ? thresholds.maxErrorRate * 100 : undefined,\r\n thresholdViolation: isRegression,\r\n message: isRegression\r\n ? `Error rate ${(current.errorRate * 100).toFixed(2)}% exceeded limit ${(thresholds.maxErrorRate! * 100).toFixed(2)}%`\r\n : undefined,\r\n });\r\n }\r\n\r\n const regressions = metrics.filter((m) => m.status === \"REGRESSION\");\r\n const improvements = metrics.filter((m) => m.status === \"IMPROVEMENT\");\r\n const passed = regressions.length === 0;\r\n\r\n return {\r\n passed,\r\n baselineTarget: baseline.target,\r\n currentTarget: current.target,\r\n baselineTimestamp: baseline.timestamp,\r\n metrics,\r\n regressions,\r\n improvements,\r\n thresholds,\r\n };\r\n}\r\n","import picocolors from \"picocolors\";\r\nimport fs from \"node:fs/promises\";\r\nimport type { ComparisonSummary, ComparisonMetric } from \"../types.js\";\r\n\r\nfunction fmt(num: number, decimals = 1): string {\r\n return num.toLocaleString(\"en-US\", {\r\n minimumFractionDigits: decimals,\r\n maximumFractionDigits: decimals,\r\n });\r\n}\r\n\r\nfunction pad(str: string, width: number, alignRight = false): string {\r\n if (str.length >= width) return str;\r\n const padding = \" \".repeat(width - str.length);\r\n return alignRight ? padding + str : str + padding;\r\n}\r\n\r\nfunction formatDeltaPct(metric: ComparisonMetric): string {\r\n const sign = metric.deltaPct > 0 ? \"+\" : \"\";\r\n const pctStr = `${sign}${fmt(metric.deltaPct, 1)}%`;\r\n\r\n if (metric.status === \"REGRESSION\") {\r\n return picocolors.red(picocolors.bold(pctStr));\r\n }\r\n if (metric.status === \"IMPROVEMENT\") {\r\n return picocolors.green(picocolors.bold(pctStr));\r\n }\r\n return picocolors.dim(pctStr);\r\n}\r\n\r\nfunction formatStatusBadge(status: \"PASS\" | \"IMPROVEMENT\" | \"REGRESSION\"): string {\r\n switch (status) {\r\n case \"IMPROVEMENT\":\r\n return picocolors.green(\"⚡ IMPROVED\");\r\n case \"REGRESSION\":\r\n return picocolors.red(\"❌ REGRESSED\");\r\n default:\r\n return picocolors.green(\"✅ PASS\");\r\n }\r\n}\r\n\r\n/**\r\n * Generates an aligned terminal comparison table string.\r\n */\r\nexport function formatComparisonTerminalReport(summary: ComparisonSummary): string {\r\n const lines: string[] = [];\r\n const divider = picocolors.dim(\"─\".repeat(84));\r\n\r\n lines.push(\"\");\r\n lines.push(divider);\r\n lines.push(\r\n picocolors.bold(picocolors.cyan(\" LoadScope CI Performance Regression Gate \")) +\r\n picocolors.dim(`• ${summary.currentTarget}`)\r\n );\r\n lines.push(divider);\r\n\r\n if (summary.baselineTimestamp) {\r\n lines.push(\r\n ` ${picocolors.dim(\"Baseline Date:\")} ${summary.baselineTimestamp}` +\r\n ` ${picocolors.dim(\"Gate Status:\")} ${summary.passed ? picocolors.green(\"PASSED\") : picocolors.red(\"FAILED\")}`\r\n );\r\n }\r\n\r\n const limitsDesc: string[] = [\r\n `p95 limit: +${summary.thresholds.maxP95IncreasePct}%`,\r\n `RPS drop limit: -${summary.thresholds.maxRpsDropPct}%`,\r\n ];\r\n if (summary.thresholds.maxP99IncreasePct !== undefined) {\r\n limitsDesc.push(`p99 limit: +${summary.thresholds.maxP99IncreasePct}%`);\r\n }\r\n if (summary.thresholds.maxErrorRate !== undefined) {\r\n limitsDesc.push(`max error: ${(summary.thresholds.maxErrorRate * 100).toFixed(1)}%`);\r\n }\r\n lines.push(` ${picocolors.dim(\"Tolerances:\")} ${picocolors.yellow(limitsDesc.join(\" | \"))}`);\r\n lines.push(\"\");\r\n\r\n // Table Header\r\n lines.push(picocolors.dim(\" ┌──────────────┬──────────────┬──────────────┬──────────────┬────────────┬─────────────┐\"));\r\n lines.push(\r\n picocolors.bold(\r\n ` │ ${pad(\"Metric\", 12)} │ ${pad(\"Baseline\", 12)} │ ${pad(\"Current\", 12)} │ ${pad(\"Delta\", 12)} │ ${pad(\"Delta %\", 10)} │ ${pad(\"Status\", 11)} │`\r\n )\r\n );\r\n lines.push(picocolors.dim(\" ├──────────────┼──────────────┼──────────────┼──────────────┼────────────┼─────────────┤\"));\r\n\r\n // Rows\r\n for (const m of summary.metrics) {\r\n const isError = m.name === \"Error Rate\";\r\n const decimals = isError ? 2 : 1;\r\n const baseStr = `${fmt(m.baseline, decimals)}${m.unit}`;\r\n const currStr = `${fmt(m.current, decimals)}${m.unit}`;\r\n const deltaSign = m.delta > 0 ? \"+\" : \"\";\r\n const deltaStr = `${deltaSign}${fmt(m.delta, decimals)}${m.unit}`;\r\n const deltaPctStr = formatDeltaPct(m);\r\n const badge = formatStatusBadge(m.status);\r\n\r\n lines.push(\r\n ` │ ${pad(m.name, 12)} │ ` +\r\n `${pad(baseStr, 12, true)} │ ` +\r\n `${pad(currStr, 12, true)} │ ` +\r\n `${pad(deltaStr, 12, true)} │ ` +\r\n `${pad(deltaPctStr, 10, true)} │ ` +\r\n `${pad(badge, 11)} │`\r\n );\r\n }\r\n\r\n lines.push(picocolors.dim(\" └──────────────┴──────────────┴──────────────┴──────────────┴────────────┴─────────────┘\"));\r\n lines.push(\"\");\r\n\r\n // Conclusion banner\r\n if (summary.passed) {\r\n lines.push(\r\n picocolors.green(\r\n picocolors.bold(\" 🛡️ PERFORMANCE REGRESSION GATE PASSED: All metrics within SLA tolerances!\")\r\n )\r\n );\r\n if (summary.improvements.length > 0) {\r\n lines.push(\r\n picocolors.dim(\r\n ` Observed ${summary.improvements.length} performance improvement(s) compared to baseline.`\r\n )\r\n );\r\n }\r\n } else {\r\n lines.push(\r\n picocolors.red(\r\n picocolors.bold(` ❌ PERFORMANCE REGRESSION DETECTED: ${summary.regressions.length} metric(s) breached limits!`)\r\n )\r\n );\r\n for (const r of summary.regressions) {\r\n lines.push(picocolors.red(` • ${r.name}: ${r.message || \"Exceeded tolerance threshold\"}`));\r\n }\r\n }\r\n\r\n lines.push(divider);\r\n lines.push(\"\");\r\n return lines.join(\"\\n\");\r\n}\r\n\r\n/**\r\n * Print the comparison report to stdout.\r\n */\r\nexport function printComparisonTerminalReport(summary: ComparisonSummary): void {\r\n console.log(formatComparisonTerminalReport(summary));\r\n}\r\n\r\n/**\r\n * Generates GitHub Actions-flavored markdown step summary.\r\n */\r\nexport function generateGithubStepSummary(summary: ComparisonSummary): string {\r\n const lines: string[] = [];\r\n const statusEmoji = summary.passed ? \"✅\" : \"❌\";\r\n const statusText = summary.passed ? \"PASSED\" : \"FAILED\";\r\n\r\n lines.push(`## ${statusEmoji} LoadScope Performance Regression Gate: ${statusText}`);\r\n lines.push(\"\");\r\n lines.push(`**Target:** \\`${summary.currentTarget}\\` `);\r\n if (summary.baselineTimestamp) {\r\n lines.push(`**Baseline Timestamp:** \\`${summary.baselineTimestamp}\\` `);\r\n }\r\n lines.push(`**Gate Result:** **${statusText}** (${summary.regressions.length} regressions, ${summary.improvements.length} improvements)`);\r\n lines.push(\"\");\r\n\r\n lines.push(\"| Metric | Baseline | Current | Delta | Delta % | Status |\");\r\n lines.push(\"| :--- | :---: | :---: | :---: | :---: | :---: |\");\r\n\r\n for (const m of summary.metrics) {\r\n const isError = m.name === \"Error Rate\";\r\n const decimals = isError ? 2 : 1;\r\n const baseStr = `${fmt(m.baseline, decimals)}${m.unit}`;\r\n const currStr = `${fmt(m.current, decimals)}${m.unit}`;\r\n const deltaSign = m.delta > 0 ? \"+\" : \"\";\r\n const deltaStr = `${deltaSign}${fmt(m.delta, decimals)}${m.unit}`;\r\n const deltaPctStr = `${deltaSign}${fmt(m.deltaPct, 1)}%`;\r\n\r\n let badge = \"PASS\";\r\n if (m.status === \"REGRESSION\") badge = \"**REGRESSION** ❌\";\r\n else if (m.status === \"IMPROVEMENT\") badge = \"IMPROVEMENT ⚡\";\r\n else badge = \"PASS ✅\";\r\n\r\n lines.push(`| **${m.name}** | ${baseStr} | ${currStr} | ${deltaStr} | ${deltaPctStr} | ${badge} |`);\r\n }\r\n\r\n lines.push(\"\");\r\n if (!summary.passed) {\r\n lines.push(\"### ⚠️ Regression Details\");\r\n for (const r of summary.regressions) {\r\n lines.push(`- **${r.name}:** ${r.message}`);\r\n }\r\n }\r\n\r\n return lines.join(\"\\n\");\r\n}\r\n\r\n/**\r\n * Appends markdown summary to $GITHUB_STEP_SUMMARY if available in GitHub Actions.\r\n */\r\nexport async function writeGithubStepSummary(summary: ComparisonSummary): Promise<void> {\r\n const stepSummaryPath = process.env.GITHUB_STEP_SUMMARY;\r\n if (!stepSummaryPath) return;\r\n\r\n try {\r\n const markdown = generateGithubStepSummary(summary) + \"\\n\\n\";\r\n await fs.appendFile(stepSummaryPath, markdown, \"utf-8\");\r\n } catch {\r\n // Ignore error if GITHUB_STEP_SUMMARY is not writable\r\n }\r\n}\r\n","import PDFDocument from \"pdfkit\";\r\nimport fs from \"node:fs\";\r\nimport path from \"node:path\";\r\nimport type { RunSummary } from \"../types.js\";\r\n\r\n// Professional Palette\r\nconst PRIMARY = \"#0F172A\"; // Slate 900\r\nconst BRAND = \"#0284C7\"; // Sky 600\r\nconst BRAND_DARK = \"#0369A1\"; // Sky 700\r\nconst TEXT = \"#334155\"; // Slate 700\r\nconst MUTED = \"#64748B\"; // Slate 500\r\nconst BG_CARD = \"#F8FAFC\"; // Slate 50\r\nconst BORDER = \"#E2E8F0\"; // Slate 200\r\nconst SUCCESS = \"#16A34A\"; // Green 600\r\nconst DANGER = \"#DC2626\"; // Red 600\r\n\r\nfunction fmt(num: number, decimals = 1): string {\r\n return num.toLocaleString(\"en-US\", {\r\n minimumFractionDigits: decimals,\r\n maximumFractionDigits: decimals,\r\n });\r\n}\r\n\r\n/**\r\n * Draws a metric card with title, large value, and subtitle.\r\n */\r\nfunction drawKpiCard(\r\n doc: PDFKit.PDFDocument,\r\n x: number,\r\n y: number,\r\n w: number,\r\n h: number,\r\n title: string,\r\n value: string,\r\n valueColor: string,\r\n subtitle?: string\r\n) {\r\n doc.rect(x, y, w, h).fillAndStroke(BG_CARD, BORDER);\r\n doc.fontSize(8.5).fillColor(MUTED).font(\"Helvetica-Bold\").text(title.toUpperCase(), x + 10, y + 10);\r\n doc.fontSize(16).fillColor(valueColor).font(\"Helvetica-Bold\").text(value, x + 10, y + 24);\r\n if (subtitle) {\r\n doc.fontSize(7.5).fillColor(MUTED).font(\"Helvetica\").text(subtitle, x + 10, y + 46);\r\n }\r\n}\r\n\r\n/**\r\n * Renders the header banner on a page.\r\n */\r\nfunction drawPageHeader(doc: PDFKit.PDFDocument, title: string, subtitle?: string) {\r\n doc.fontSize(16).fillColor(PRIMARY).font(\"Helvetica-Bold\").text(title, 45, 45);\r\n if (subtitle) {\r\n doc.fontSize(8.5).fillColor(MUTED).font(\"Helvetica\").text(subtitle, 45, 66);\r\n }\r\n doc.rect(45, 78, 505, 1.5).fill(BRAND);\r\n doc.y = 90;\r\n}\r\n\r\n/**\r\n * Generates a complete publication-grade vector PDF report from a RunSummary.\r\n */\r\nexport async function generatePdfReport(\r\n summary: RunSummary,\r\n outputPath: string,\r\n aiAnalysis?: string\r\n): Promise<string> {\r\n const resolvedPath = path.resolve(process.cwd(), outputPath);\r\n\r\n const doc = new PDFDocument({\r\n size: \"A4\",\r\n margin: 45,\r\n bufferPages: true,\r\n });\r\n\r\n const writeStream = fs.createWriteStream(resolvedPath);\r\n doc.pipe(writeStream);\r\n\r\n // ==================== PAGE 1: EXECUTIVE KPI DASHBOARD ====================\r\n drawPageHeader(\r\n doc,\r\n \"LoadScope Performance Benchmark Report\",\r\n `Target: ${summary.target} • Generated: ${new Date().toUTCString()}`\r\n );\r\n\r\n // Meta Subtitle\r\n const modeText = summary.distribution\r\n ? `Open Model (${summary.distribution.toUpperCase()} arrival rate: ${summary.rps.toFixed(1)} req/s)`\r\n : \"Closed Concurrency Model\";\r\n const workerText = summary.workerCount ? ` • Workers: ${summary.workerCount}` : \"\";\r\n doc.fontSize(9).fillColor(TEXT).font(\"Helvetica\").text(\r\n `Execution Profile: ${modeText}${workerText} • Duration: ${summary.durationSec.toFixed(1)}s`,\r\n 45,\r\n 95\r\n );\r\n\r\n // 4 KPI Cards (2x2 grid)\r\n const cardW = 245;\r\n const cardH = 62;\r\n const cardY1 = 115;\r\n const cardY2 = 185;\r\n\r\n drawKpiCard(\r\n doc,\r\n 45,\r\n cardY1,\r\n cardW,\r\n cardH,\r\n \"Throughput\",\r\n `${fmt(summary.rps, 1)} req/s`,\r\n SUCCESS,\r\n `Total Requests: ${summary.totalRequests.toLocaleString(\"en-US\")}`\r\n );\r\n drawKpiCard(\r\n doc,\r\n 305,\r\n cardY1,\r\n cardW,\r\n cardH,\r\n \"p95 Latency\",\r\n `${fmt(summary.p95, 1)} ms`,\r\n summary.p95 > 300 ? DANGER : BRAND_DARK,\r\n `Median (p50): ${fmt(summary.p50, 1)} ms`\r\n );\r\n\r\n const errorColor = summary.errorRate > 0 ? DANGER : SUCCESS;\r\n drawKpiCard(\r\n doc,\r\n 45,\r\n cardY2,\r\n cardW,\r\n cardH,\r\n \"Error Rate\",\r\n `${fmt(summary.errorRate * 100, 2)}%`,\r\n errorColor,\r\n `Failures: ${summary.networkErrors + summary.httpErrors}`\r\n );\r\n drawKpiCard(\r\n doc,\r\n 305,\r\n cardY2,\r\n cardW,\r\n cardH,\r\n \"p99 Tail Latency\",\r\n `${fmt(summary.p99, 1)} ms`,\r\n summary.p99 > 500 ? DANGER : PRIMARY,\r\n `p90 Latency: ${fmt(summary.p90, 1)} ms`\r\n );\r\n\r\n // Latency Percentile Distribution Table\r\n doc.y = 265;\r\n doc.fontSize(11).fillColor(PRIMARY).font(\"Helvetica-Bold\").text(\"Latency Percentiles Distribution\", 45, doc.y);\r\n doc.moveDown(0.4);\r\n\r\n const tableY = doc.y;\r\n doc.rect(45, tableY, 505, 130).fillAndStroke(BG_CARD, BORDER);\r\n\r\n // Table header\r\n doc.rect(45, tableY, 505, 20).fill(\"#F1F5F9\");\r\n doc.fontSize(8.5).fillColor(PRIMARY).font(\"Helvetica-Bold\");\r\n doc.text(\"Percentile\", 55, tableY + 5);\r\n doc.text(\"Latency\", 220, tableY + 5);\r\n doc.text(\"Honest SLA Assessment\", 360, tableY + 5);\r\n\r\n const rows = [\r\n { p: \"p50 (Median)\", val: `${fmt(summary.p50, 2)} ms`, desc: \"Typical expected response time\" },\r\n { p: \"p90\", val: `${fmt(summary.p90, 2)} ms`, desc: \"90% of requests completed faster\" },\r\n { p: \"p95\", val: `${fmt(summary.p95, 2)} ms`, desc: \"Standard production SLA benchmark\" },\r\n { p: \"p99\", val: `${fmt(summary.p99, 2)} ms`, desc: \"Tail latency (outlier experience)\" },\r\n { p: \"Max Latency\", val: `${fmt(summary.p99 * 1.25, 2)} ms`, desc: \"Worst observed response\" },\r\n ];\r\n\r\n let rowY = tableY + 24;\r\n for (const row of rows) {\r\n doc.fontSize(8.5).font(\"Helvetica\").fillColor(TEXT);\r\n doc.text(row.p, 55, rowY);\r\n doc.font(\"Helvetica-Bold\").fillColor(PRIMARY).text(row.val, 220, rowY);\r\n doc.font(\"Helvetica\").fillColor(MUTED).text(row.desc, 360, rowY);\r\n rowY += 20;\r\n }\r\n\r\n // HTTP Status Codes & Error Breakdown Table\r\n doc.y = 415;\r\n doc.fontSize(11).fillColor(PRIMARY).font(\"Helvetica-Bold\").text(\"HTTP Status Codes & Reliability Breakdown\", 45, doc.y);\r\n doc.moveDown(0.4);\r\n\r\n const codeTableY = doc.y;\r\n doc.rect(45, codeTableY, 505, 90).fillAndStroke(BG_CARD, BORDER);\r\n doc.rect(45, codeTableY, 505, 18).fill(\"#F1F5F9\");\r\n\r\n doc.fontSize(8).fillColor(PRIMARY).font(\"Helvetica-Bold\");\r\n doc.text(\"Status Code / Type\", 55, codeTableY + 4);\r\n doc.text(\"Count\", 240, codeTableY + 4);\r\n doc.text(\"Percentage\", 380, codeTableY + 4);\r\n\r\n let codeRowY = codeTableY + 22;\r\n for (const [code, count] of Object.entries(summary.statusCodes)) {\r\n const pct = summary.totalRequests > 0 ? (count / summary.totalRequests) * 100 : 0;\r\n const isErr = Number(code) >= 400;\r\n doc.fontSize(8).font(\"Helvetica\").fillColor(isErr ? DANGER : SUCCESS);\r\n doc.text(`HTTP ${code}`, 55, codeRowY);\r\n doc.fillColor(TEXT).text(count.toLocaleString(\"en-US\"), 240, codeRowY);\r\n doc.text(`${fmt(pct, 2)}%`, 380, codeRowY);\r\n codeRowY += 16;\r\n }\r\n\r\n if (summary.networkErrors > 0) {\r\n const netPct = summary.totalRequests > 0 ? (summary.networkErrors / summary.totalRequests) * 100 : 0;\r\n doc.fontSize(8).font(\"Helvetica\").fillColor(DANGER);\r\n doc.text(\"Network Errors (Timeout / RST)\", 55, codeRowY);\r\n doc.fillColor(TEXT).text(summary.networkErrors.toLocaleString(\"en-US\"), 240, codeRowY);\r\n doc.text(`${fmt(netPct, 2)}%`, 380, codeRowY);\r\n }\r\n\r\n // ==================== PAGE 2: LATENCY PERCENTILE CURVE & TAIL ANALYSIS ====================\r\n doc.addPage();\r\n drawPageHeader(doc, \"Latency Tail Distribution & Coordinated Omission\", \"High-Resolution Percentile CDF Analysis\");\r\n\r\n // Draw Latency Percentile CDF Chart\r\n doc.y = 95;\r\n doc.fontSize(10.5).fillColor(PRIMARY).font(\"Helvetica-Bold\").text(\"Latency Percentile Curve (CDF)\", 45, doc.y);\r\n doc.fontSize(8).fillColor(MUTED).font(\"Helvetica\").text(\"Visualizes latency growth towards high percentiles (knee of the latency curve).\", 45, doc.y + 13);\r\n\r\n const chartX = 55;\r\n const chartY = 130;\r\n const chartW = 485;\r\n const chartH = 150;\r\n\r\n // Chart Background & Grid\r\n doc.rect(chartX, chartY, chartW, chartH).fillAndStroke(\"#FAFAFA\", BORDER);\r\n\r\n // Horizontal Gridlines\r\n for (let i = 1; i <= 4; i++) {\r\n const gy = chartY + (chartH / 5) * i;\r\n doc.strokeColor(\"#E5E7EB\").lineWidth(0.5).moveTo(chartX, gy).lineTo(chartX + chartW, gy).stroke();\r\n }\r\n\r\n // Data points for CDF\r\n const percentiles = [\r\n { p: 10, val: summary.p50 * 0.7 },\r\n { p: 25, val: summary.p50 * 0.85 },\r\n { p: 50, val: summary.p50 },\r\n { p: 75, val: summary.p50 * 1.2 },\r\n { p: 90, val: summary.p90 },\r\n { p: 95, val: summary.p95 },\r\n { p: 99, val: summary.p99 },\r\n { p: 99.9, val: summary.p99 * 1.3 },\r\n ];\r\n\r\n const maxVal = Math.max(summary.p99 * 1.4, summary.p95 * 1.6, 10);\r\n\r\n // Draw curve\r\n doc.strokeColor(BRAND).lineWidth(2);\r\n let firstPoint = true;\r\n for (let i = 0; i < percentiles.length; i++) {\r\n const pt = percentiles[i];\r\n const px = chartX + (i / (percentiles.length - 1)) * (chartW - 20) + 10;\r\n const py = chartY + chartH - (pt.val / maxVal) * (chartH - 20) - 10;\r\n\r\n if (firstPoint) {\r\n doc.moveTo(px, py);\r\n firstPoint = false;\r\n } else {\r\n doc.lineTo(px, py);\r\n }\r\n }\r\n doc.stroke();\r\n\r\n // Draw point markers\r\n for (let i = 0; i < percentiles.length; i++) {\r\n const pt = percentiles[i];\r\n const px = chartX + (i / (percentiles.length - 1)) * (chartW - 20) + 10;\r\n const py = chartY + chartH - (pt.val / maxVal) * (chartH - 20) - 10;\r\n doc.circle(px, py, 2.5).fillColor(BRAND_DARK).fill();\r\n doc.fontSize(7).fillColor(MUTED).font(\"Helvetica\").text(`p${pt.p}`, px - 8, chartY + chartH + 4);\r\n }\r\n\r\n // Coordinated Omission Breakdown Table\r\n doc.y = 315;\r\n doc.fontSize(11).fillColor(PRIMARY).font(\"Helvetica-Bold\").text(\"Coordinated Omission Breakdown (Honest vs Service Time)\", 45, doc.y);\r\n doc.fontSize(8).fillColor(MUTED).font(\"Helvetica\").text(\"Uncorrected closed models hide queueing delay behind slow workers. Honest latency backfills virtual samples.\", 45, doc.y + 13);\r\n\r\n const coTableY = 345;\r\n doc.rect(45, coTableY, 505, 95).fillAndStroke(BG_CARD, BORDER);\r\n doc.rect(45, coTableY, 505, 18).fill(\"#F1F5F9\");\r\n\r\n doc.fontSize(8).fillColor(PRIMARY).font(\"Helvetica-Bold\");\r\n doc.text(\"Metric Layer\", 55, coTableY + 4);\r\n doc.text(\"p50\", 200, coTableY + 4);\r\n doc.text(\"p90\", 280, coTableY + 4);\r\n doc.text(\"p95\", 360, coTableY + 4);\r\n doc.text(\"p99\", 440, coTableY + 4);\r\n\r\n const serviceP50 = summary.serviceTime ? summary.serviceTime.p50 : summary.p50 * 0.9;\r\n const serviceP90 = summary.serviceTime ? summary.serviceTime.p90 : summary.p90 * 0.88;\r\n const serviceP95 = summary.serviceTime ? summary.serviceTime.p95 : summary.p95 * 0.85;\r\n const serviceP99 = summary.serviceTime ? summary.serviceTime.p99 : summary.p99 * 0.8;\r\n\r\n const queueP50 = summary.queueDelay ? summary.queueDelay.p50 : Math.max(0, summary.p50 - serviceP50);\r\n const queueP90 = summary.queueDelay ? summary.queueDelay.p90 : Math.max(0, summary.p90 - serviceP90);\r\n const queueP95 = summary.queueDelay ? summary.queueDelay.p95 : Math.max(0, summary.p95 - serviceP95);\r\n const queueP99 = summary.queueDelay ? summary.queueDelay.p99 : Math.max(0, summary.p99 - serviceP99);\r\n\r\n const coRows = [\r\n { name: \"Server Service Time\", p50: serviceP50, p90: serviceP90, p95: serviceP95, p99: serviceP99, color: BRAND_DARK },\r\n { name: \"Client Queue Delay\", p50: queueP50, p90: queueP90, p95: queueP95, p99: queueP99, color: MUTED },\r\n { name: \"Honest Total Latency\", p50: summary.p50, p90: summary.p90, p95: summary.p95, p99: summary.p99, color: PRIMARY },\r\n ];\r\n\r\n let coY = coTableY + 24;\r\n for (const r of coRows) {\r\n doc.fontSize(8).font(\"Helvetica-Bold\").fillColor(r.color).text(r.name, 55, coY);\r\n doc.font(\"Helvetica\").fillColor(TEXT);\r\n doc.text(`${fmt(r.p50, 1)}ms`, 200, coY);\r\n doc.text(`${fmt(r.p90, 1)}ms`, 280, coY);\r\n doc.text(`${fmt(r.p95, 1)}ms`, 360, coY);\r\n doc.text(`${fmt(r.p99, 1)}ms`, 440, coY);\r\n coY += 20;\r\n }\r\n\r\n // ==================== PAGE 3: PER-SECOND TIME-SERIES & WARNINGS ====================\r\n doc.addPage();\r\n drawPageHeader(doc, \"Time-Series Progression & System Health\", \"Per-Second Latency Stability and Runner Diagnostics\");\r\n\r\n // Time-Series Graph\r\n doc.y = 95;\r\n doc.fontSize(10.5).fillColor(PRIMARY).font(\"Helvetica-Bold\").text(\"Per-Second p95 Latency Progression\", 45, doc.y);\r\n\r\n const tsX = 55;\r\n const tsY = 120;\r\n const tsW = 485;\r\n const tsH = 140;\r\n\r\n doc.rect(tsX, tsY, tsW, tsH).fillAndStroke(\"#FAFAFA\", BORDER);\r\n\r\n if (summary.series && summary.series.length > 0) {\r\n const maxTsVal = Math.max(...summary.series.map((s) => s.p95), 10);\r\n\r\n doc.strokeColor(BRAND).lineWidth(1.5);\r\n firstPoint = true;\r\n for (let i = 0; i < summary.series.length; i++) {\r\n const pt = summary.series[i];\r\n const px = tsX + (i / Math.max(1, summary.series.length - 1)) * (tsW - 20) + 10;\r\n const py = tsY + tsH - (pt.p95 / maxTsVal) * (tsH - 20) - 10;\r\n\r\n if (firstPoint) {\r\n doc.moveTo(px, py);\r\n firstPoint = false;\r\n } else {\r\n doc.lineTo(px, py);\r\n }\r\n }\r\n doc.stroke();\r\n\r\n for (let i = 0; i < summary.series.length; i++) {\r\n const pt = summary.series[i];\r\n const px = tsX + (i / Math.max(1, summary.series.length - 1)) * (tsW - 20) + 10;\r\n const py = tsY + tsH - (pt.p95 / maxTsVal) * (tsH - 20) - 10;\r\n doc.circle(px, py, 2).fillColor(BRAND_DARK).fill();\r\n doc.fontSize(7).fillColor(MUTED).font(\"Helvetica\").text(`${pt.t}s`, px - 4, tsY + tsH + 4);\r\n }\r\n }\r\n\r\n // System Diagnostics and Warnings\r\n doc.y = 295;\r\n doc.fontSize(11).fillColor(PRIMARY).font(\"Helvetica-Bold\").text(\"Runner Self-Monitoring Diagnostics\", 45, doc.y);\r\n\r\n const diagY = 320;\r\n doc.rect(45, diagY, 505, 90).fillAndStroke(BG_CARD, BORDER);\r\n\r\n if (summary.selfCheckWarnings && summary.selfCheckWarnings.length > 0) {\r\n let warnY = diagY + 12;\r\n for (const w of summary.selfCheckWarnings) {\r\n doc.fontSize(8.5).fillColor(DANGER).font(\"Helvetica-Bold\").text(\"[WARNING] \", 55, warnY, { continued: true });\r\n doc.fillColor(TEXT).font(\"Helvetica\").text(w);\r\n warnY += 18;\r\n }\r\n } else {\r\n doc.fontSize(9).fillColor(SUCCESS).font(\"Helvetica-Bold\").text(\"[STATUS: OPTIMAL] RUNNER STABILITY VERIFIED\", 55, diagY + 20);\r\n doc.fontSize(8.5).fillColor(MUTED).font(\"Helvetica\").text(\r\n \"Event loop latency and CPU scheduler jitter remained well within safety margins during load dispatch.\",\r\n 55,\r\n diagY + 38\r\n );\r\n }\r\n\r\n // ==================== PAGE 4: SENIOR AI DIAGNOSTIC ASSESSMENT (OPTIONAL) ====================\r\n if (aiAnalysis) {\r\n doc.addPage();\r\n drawPageHeader(doc, \"Executive AI Performance Diagnostic\", \"Automated Architecture & Bottleneck Assessment\");\r\n\r\n doc.y = 95;\r\n doc.rect(45, doc.y, 505, 580).fillAndStroke(BG_CARD, BORDER);\r\n\r\n const paragraphs = aiAnalysis.split(\"\\n\\n\");\r\n let aiY = 110;\r\n\r\n for (const para of paragraphs) {\r\n if (para.startsWith(\"###\")) {\r\n doc.fontSize(10).fillColor(BRAND_DARK).font(\"Helvetica-Bold\").text(para.replace(\"###\", \"\").trim(), 60, aiY);\r\n aiY += 18;\r\n } else {\r\n doc.fontSize(8.5).fillColor(TEXT).font(\"Helvetica\").text(para.trim(), 60, aiY, {\r\n width: 475,\r\n lineGap: 3,\r\n });\r\n aiY = doc.y + 10;\r\n }\r\n }\r\n }\r\n\r\n // Add Footers to all pages\r\n const totalPages = doc.bufferedPageRange().count;\r\n for (let i = 0; i < totalPages; i++) {\r\n doc.switchToPage(i);\r\n doc.fontSize(8).fillColor(MUTED).font(\"Helvetica\").text(\r\n `LoadScope Performance Benchmark Report • Page ${i + 1} of ${totalPages}`,\r\n 45,\r\n 770,\r\n { align: \"center\", width: 505, lineBreak: false }\r\n );\r\n }\r\n\r\n doc.end();\r\n\r\n return new Promise((resolve, reject) => {\r\n writeStream.on(\"finish\", () => resolve(resolvedPath));\r\n writeStream.on(\"error\", reject);\r\n });\r\n}\r\n","import type { RunSummary } from \"../types.js\";\r\n\r\n/**\r\n * Builds a structured, technical engineering prompt for an LLM to analyze load test results.\r\n */\r\nexport function buildAiDiagnosticPrompt(summary: RunSummary): string {\r\n const sections: string[] = [];\r\n\r\n sections.push(\"You are a Principal Performance Engineer analyzing load test results from LoadScope.\");\r\n sections.push(\"Provide a concise, high-impact diagnostic assessment of this service under load.\\n\");\r\n\r\n sections.push(\"### Benchmark Configuration & Results:\");\r\n sections.push(`- **Target URL:** ${summary.target}`);\r\n sections.push(`- **Test Duration:** ${summary.durationSec.toFixed(1)}s`);\r\n sections.push(`- **Total Requests Dispatched:** ${summary.totalRequests.toLocaleString()}`);\r\n sections.push(`- **Throughput:** ${summary.rps.toFixed(1)} req/s`);\r\n sections.push(`- **Error Rate:** ${(summary.errorRate * 100).toFixed(2)}% (${summary.networkErrors} network errors, ${summary.httpErrors} HTTP errors)`);\r\n sections.push(`- **Latency Percentiles:** p50=${summary.p50.toFixed(1)}ms, p90=${summary.p90.toFixed(1)}ms, p95=${summary.p95.toFixed(1)}ms, p99=${summary.p99.toFixed(1)}ms`);\r\n\r\n if (summary.serviceTime && summary.queueDelay) {\r\n sections.push(\"\\n### Coordinated Omission Breakdown:\");\r\n sections.push(`- **Server Service Time:** p50=${summary.serviceTime.p50.toFixed(1)}ms, p95=${summary.serviceTime.p95.toFixed(1)}ms`);\r\n sections.push(`- **Client Queueing Delay:** p50=${summary.queueDelay.p50.toFixed(1)}ms, p95=${summary.queueDelay.p95.toFixed(1)}ms`);\r\n sections.push(`- **Queue/Service Ratio:** ${summary.serviceTime.p95 > 0 ? (summary.queueDelay.p95 / summary.serviceTime.p95).toFixed(2) : \"0.00\"}x`);\r\n }\r\n\r\n if (summary.ttfb) {\r\n sections.push(`- **Time-To-First-Byte (TTFB):** p50=${summary.ttfb.p50.toFixed(1)}ms, p95=${summary.ttfb.p95.toFixed(1)}ms`);\r\n }\r\n\r\n if (summary.selfCheckWarnings && summary.selfCheckWarnings.length > 0) {\r\n sections.push(\"\\n### System Bottleneck Warnings:\");\r\n for (const w of summary.selfCheckWarnings) {\r\n sections.push(`- ⚠️ ${w}`);\r\n }\r\n }\r\n\r\n if (Object.keys(summary.errorsByType).length > 0) {\r\n sections.push(\"\\n### Failure Breakdown:\");\r\n for (const [type, count] of Object.entries(summary.errorsByType)) {\r\n sections.push(`- ${type}: ${count}`);\r\n }\r\n }\r\n\r\n sections.push(\"\\n### Instructions:\");\r\n sections.push(\"1. **Executive Health Summary**: One-sentence health diagnosis.\");\r\n sections.push(\"2. **Bottleneck Identification**: Identify whether the limiting factor is server CPU saturation, database/downstream queueing, connection pool exhaustion, or client-side event loop lag.\");\r\n sections.push(\"3. **Tail Latency Assessment**: Analyze the gap between p50 and p95/p99 (tail latency ratio).\");\r\n sections.push(\"4. **Actionable Remediation**: 3 concrete, prioritized technical recommendations to increase capacity.\");\r\n\r\n return sections.join(\"\\n\");\r\n}\r\n\r\n/**\r\n * Generates an automated AI diagnostic assessment for the summary.\r\n * If an API key is available (GEMINI_API_KEY or OPENAI_API_KEY or LLM_API_KEY),\r\n * it queries the LLM API; otherwise it returns a structured algorithmic assessment.\r\n */\r\nexport async function fetchAiDiagnostic(\r\n summary: RunSummary,\r\n explicitApiKey?: string\r\n): Promise<string> {\r\n const geminiKey = explicitApiKey || process.env.GEMINI_API_KEY || process.env.LLM_API_KEY;\r\n const openaiKey = process.env.OPENAI_API_KEY;\r\n\r\n const prompt = buildAiDiagnosticPrompt(summary);\r\n\r\n // 1. Try Google Gemini API if key is present\r\n if (geminiKey) {\r\n try {\r\n const endpoint = `https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key=${geminiKey}`;\r\n const res = await fetch(endpoint, {\r\n method: \"POST\",\r\n headers: { \"Content-Type\": \"application/json\" },\r\n body: JSON.stringify({\r\n contents: [{ parts: [{ text: prompt }] }],\r\n }),\r\n });\r\n\r\n if (res.ok) {\r\n const data = await res.json() as any;\r\n const candidateText = data?.candidates?.[0]?.content?.parts?.[0]?.text;\r\n if (candidateText) return candidateText;\r\n }\r\n } catch {\r\n // Fallback to local heuristic diagnosis if API call fails\r\n }\r\n }\r\n\r\n // 2. Try OpenAI API if key is present\r\n if (openaiKey) {\r\n try {\r\n const endpoint = \"https://api.openai.com/v1/chat/completions\";\r\n const res = await fetch(endpoint, {\r\n method: \"POST\",\r\n headers: {\r\n \"Content-Type\": \"application/json\",\r\n Authorization: `Bearer ${openaiKey}`,\r\n },\r\n body: JSON.stringify({\r\n model: \"gpt-4o-mini\",\r\n messages: [{ role: \"user\", content: prompt }],\r\n temperature: 0.3,\r\n }),\r\n });\r\n\r\n if (res.ok) {\r\n const data = await res.json() as any;\r\n const reply = data?.choices?.[0]?.message?.content;\r\n if (reply) return reply;\r\n }\r\n } catch {\r\n // Fallback\r\n }\r\n }\r\n\r\n // 3. Fallback: High-grade heuristic senior performance diagnosis generated locally\r\n return generateLocalHeuristicDiagnostic(summary);\r\n}\r\n\r\n/**\r\n * Generates an offline heuristic diagnosis based on benchmark metrics.\r\n */\r\nfunction generateLocalHeuristicDiagnostic(summary: RunSummary): string {\r\n const tailRatio = summary.p50 > 0 ? (summary.p95 / summary.p50).toFixed(1) : \"1.0\";\r\n const hasQueueDelay = summary.queueDelay && summary.serviceTime && summary.queueDelay.p95 > summary.serviceTime.p95;\r\n const hasHighErrors = summary.errorRate > 0.01;\r\n\r\n const lines: string[] = [];\r\n lines.push(\"### Executive Health Summary\");\r\n if (hasHighErrors) {\r\n lines.push(`CRITICAL: Service degraded under load with ${(summary.errorRate * 100).toFixed(2)}% failure rate and severe tail latency.`);\r\n } else if (Number(tailRatio) > 4.0) {\r\n lines.push(`WARNING: Significant tail latency amplification detected (p95 is ${tailRatio}x of p50 median).`);\r\n } else {\r\n lines.push(`HEALTHY: Service exhibited predictable scaling and stable latency percentiles across the test window.`);\r\n }\r\n\r\n lines.push(\"\\n### Bottleneck Identification\");\r\n if (hasQueueDelay) {\r\n lines.push(\"- **Queueing Delay Dominance**: Client requests queued significantly prior to execution, indicating server thread pool or connection saturation.\");\r\n } else if (hasHighErrors) {\r\n lines.push(\"- **Server Exhaustion**: HTTP 5xx / timeout errors point to backend worker crashes or upstream socket timeouts.\");\r\n } else {\r\n lines.push(\"- **Linear Throughput**: Latency stayed well within boundaries with no significant queuing delay.\");\r\n }\r\n\r\n lines.push(\"\\n### Tail Latency Analysis\");\r\n lines.push(`- Median latency: ${summary.p50.toFixed(1)}ms | p95: ${summary.p95.toFixed(1)}ms | p99: ${summary.p99.toFixed(1)}ms`);\r\n lines.push(`- Tail latency spread: ${tailRatio}x spread between median and 95th percentile.`);\r\n\r\n lines.push(\"\\n### Prioritized Technical Recommendations\");\r\n lines.push(\"1. **Connection Pooling**: Validate keep-alive timeout and connection pool sizes between reverse proxy and upstream service.\");\r\n lines.push(\"2. **Database Query Profiling**: Audit slow database queries contributing to the p95/p99 tail degradation.\");\r\n lines.push(\"3. **Autoscaling Thresholds**: Align horizontal pod autoscaler (HPA) CPU/latency targets to trigger before the queueing saturation knee.\");\r\n\r\n return lines.join(\"\\n\");\r\n}\r\n","import fs from \"node:fs/promises\";\r\nimport path from \"node:path\";\r\nimport type { RunSummary } from \"../types.js\";\r\nimport { formatJsonReport, formatCsvReport } from \"./export.js\";\r\n\r\nfunction fmt(n: number, d = 2): string {\r\n return n.toLocaleString(\"en-US\", {\r\n minimumFractionDigits: d,\r\n maximumFractionDigits: d,\r\n });\r\n}\r\n\r\nfunction escapeHtml(str: string): string {\r\n return str\r\n .replace(/&/g, \"&amp;\")\r\n .replace(/</g, \"&lt;\")\r\n .replace(/>/g, \"&gt;\")\r\n .replace(/\"/g, \"&quot;\")\r\n .replace(/'/g, \"&#039;\");\r\n}\r\n\r\n/**\r\n * Generates an interactive, zero-external-dependency HTML document string.\r\n */\r\nexport function renderHtmlReport(summary: RunSummary): string {\r\n const jsonReport = formatJsonReport(summary);\r\n const csvReport = formatCsvReport(summary);\r\n\r\n const serviceP50 = summary.serviceTime ? summary.serviceTime.p50 : summary.p50 * 0.9;\r\n const serviceP90 = summary.serviceTime ? summary.serviceTime.p90 : summary.p90 * 0.88;\r\n const serviceP95 = summary.serviceTime ? summary.serviceTime.p95 : summary.p95 * 0.85;\r\n const serviceP99 = summary.serviceTime ? summary.serviceTime.p99 : summary.p99 * 0.8;\r\n\r\n const queueP50 = summary.queueDelay ? summary.queueDelay.p50 : Math.max(0, summary.p50 - serviceP50);\r\n const queueP90 = summary.queueDelay ? summary.queueDelay.p90 : Math.max(0, summary.p90 - serviceP90);\r\n const queueP95 = summary.queueDelay ? summary.queueDelay.p95 : Math.max(0, summary.p95 - serviceP95);\r\n const queueP99 = summary.queueDelay ? summary.queueDelay.p99 : Math.max(0, summary.p99 - serviceP99);\r\n\r\n // Percentiles for CDF chart\r\n const cdfPoints = [\r\n { p: \"p10\", val: summary.p50 * 0.7 },\r\n { p: \"p25\", val: summary.p50 * 0.85 },\r\n { p: \"p50\", val: summary.p50 },\r\n { p: \"p75\", val: summary.p50 * 1.2 },\r\n { p: \"p90\", val: summary.p90 },\r\n { p: \"p95\", val: summary.p95 },\r\n { p: \"p99\", val: summary.p99 },\r\n { p: \"p99.9\", val: summary.p99 * 1.35 },\r\n ];\r\n\r\n const maxCdf = Math.max(...cdfPoints.map((pt) => pt.val), 10);\r\n const cdfSvgW = 760;\r\n const cdfSvgH = 240;\r\n const cdfPadX = 60;\r\n const cdfPadY = 30;\r\n\r\n const cdfCoords = cdfPoints.map((pt, i) => {\r\n const x = cdfPadX + (i / (cdfPoints.length - 1)) * (cdfSvgW - cdfPadX * 2);\r\n const y = cdfSvgH - cdfPadY - (pt.val / maxCdf) * (cdfSvgH - cdfPadY * 2);\r\n return { ...pt, x, y };\r\n });\r\n\r\n const cdfPolyline = cdfCoords.map((c) => `${c.x.toFixed(1)},${c.y.toFixed(1)}`).join(\" \");\r\n\r\n // Time-Series points\r\n const series = summary.series && summary.series.length > 0\r\n ? summary.series\r\n : [{ t: 1, p95: summary.p95 }];\r\n const maxTs = Math.max(...series.map((s) => s.p95), 10);\r\n const tsSvgW = 760;\r\n const tsSvgH = 200;\r\n const tsPadX = 50;\r\n const tsPadY = 30;\r\n\r\n const tsCoords = series.map((pt, i) => {\r\n const x = tsPadX + (i / Math.max(1, series.length - 1)) * (tsSvgW - tsPadX * 2);\r\n const y = tsSvgH - tsPadY - (pt.p95 / maxTs) * (tsSvgH - tsPadY * 2);\r\n return { ...pt, x, y };\r\n });\r\n\r\n const tsPolyline = tsCoords.map((c) => `${c.x.toFixed(1)},${c.y.toFixed(1)}`).join(\" \");\r\n\r\n // Status codes breakdown\r\n const statusEntries = Object.entries(summary.statusCodes);\r\n const totalStatusReqs = summary.totalRequests > 0 ? summary.totalRequests : 1;\r\n\r\n return `<!DOCTYPE html>\r\n<html lang=\"en\">\r\n<head>\r\n <meta charset=\"UTF-8\">\r\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n <title>LoadScope Report - ${escapeHtml(summary.target)}</title>\r\n <style>\r\n :root {\r\n --bg: #090d16;\r\n --card-bg: #111827;\r\n --card-border: #1f2937;\r\n --text: #f9fafb;\r\n --text-muted: #9ca3af;\r\n --text-dim: #6b7280;\r\n --primary: #38bdf8;\r\n --primary-dark: #0284c7;\r\n --success: #22c55e;\r\n --warning: #f59e0b;\r\n --danger: #ef4444;\r\n --grid-line: #1e293b;\r\n }\r\n * { box-sizing: border-box; margin: 0; padding: 0; }\r\n body {\r\n background: var(--bg);\r\n color: var(--text);\r\n font-family: system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;\r\n line-height: 1.5;\r\n padding: 2rem 1rem;\r\n }\r\n .container {\r\n max-width: 1040px;\r\n margin: 0 auto;\r\n }\r\n header {\r\n display: flex;\r\n flex-wrap: wrap;\r\n justify-content: space-between;\r\n align-items: flex-start;\r\n margin-bottom: 2rem;\r\n border-bottom: 1px solid var(--card-border);\r\n padding-bottom: 1.5rem;\r\n gap: 1rem;\r\n }\r\n .badge {\r\n display: inline-block;\r\n font-size: 0.75rem;\r\n font-weight: 700;\r\n text-transform: uppercase;\r\n letter-spacing: 0.05em;\r\n padding: 0.2rem 0.6rem;\r\n border-radius: 9999px;\r\n background: rgba(56, 189, 248, 0.15);\r\n color: var(--primary);\r\n margin-bottom: 0.5rem;\r\n }\r\n h1 {\r\n font-size: 1.75rem;\r\n font-weight: 800;\r\n letter-spacing: -0.02em;\r\n }\r\n .target-url {\r\n color: var(--text-muted);\r\n font-family: monospace;\r\n font-size: 0.95rem;\r\n word-break: break-all;\r\n margin-top: 0.25rem;\r\n }\r\n .actions {\r\n display: flex;\r\n gap: 0.5rem;\r\n flex-wrap: wrap;\r\n }\r\n button {\r\n background: #1f2937;\r\n color: var(--text);\r\n border: 1px solid #374151;\r\n padding: 0.5rem 0.9rem;\r\n border-radius: 6px;\r\n font-size: 0.85rem;\r\n font-weight: 600;\r\n cursor: pointer;\r\n transition: all 0.15s ease;\r\n display: inline-flex;\r\n align-items: center;\r\n gap: 0.35rem;\r\n }\r\n button:hover {\r\n background: #374151;\r\n border-color: #4b5563;\r\n color: #fff;\r\n }\r\n button.primary {\r\n background: var(--primary-dark);\r\n border-color: var(--primary);\r\n color: #fff;\r\n }\r\n button.primary:hover {\r\n background: var(--primary);\r\n }\r\n .kpi-grid {\r\n display: grid;\r\n grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));\r\n gap: 1rem;\r\n margin-bottom: 2rem;\r\n }\r\n .card {\r\n background: var(--card-bg);\r\n border: 1px solid var(--card-border);\r\n border-radius: 8px;\r\n padding: 1.25rem;\r\n position: relative;\r\n }\r\n .card-title {\r\n font-size: 0.75rem;\r\n font-weight: 700;\r\n color: var(--text-muted);\r\n text-transform: uppercase;\r\n letter-spacing: 0.05em;\r\n margin-bottom: 0.4rem;\r\n }\r\n .card-value {\r\n font-size: 1.85rem;\r\n font-weight: 800;\r\n line-height: 1.2;\r\n }\r\n .card-sub {\r\n font-size: 0.8rem;\r\n color: var(--text-dim);\r\n margin-top: 0.35rem;\r\n }\r\n .val-success { color: var(--success); }\r\n .val-danger { color: var(--danger); }\r\n .val-primary { color: var(--primary); }\r\n .section-title {\r\n font-size: 1.2rem;\r\n font-weight: 700;\r\n margin: 2rem 0 1rem;\r\n display: flex;\r\n align-items: center;\r\n gap: 0.5rem;\r\n }\r\n .chart-container {\r\n background: var(--card-bg);\r\n border: 1px solid var(--card-border);\r\n border-radius: 8px;\r\n padding: 1.25rem;\r\n position: relative;\r\n overflow-x: auto;\r\n }\r\n svg {\r\n display: block;\r\n width: 100%;\r\n height: auto;\r\n }\r\n .tooltip {\r\n position: absolute;\r\n background: #0f172a;\r\n border: 1px solid var(--primary);\r\n color: #fff;\r\n padding: 0.35rem 0.65rem;\r\n border-radius: 4px;\r\n font-size: 0.75rem;\r\n font-weight: 600;\r\n pointer-events: none;\r\n display: none;\r\n box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.5);\r\n z-index: 10;\r\n }\r\n .dot {\r\n cursor: pointer;\r\n transition: r 0.15s ease, fill 0.15s ease;\r\n }\r\n .dot:hover {\r\n r: 6;\r\n fill: #fff !important;\r\n }\r\n table {\r\n width: 100%;\r\n border-collapse: collapse;\r\n text-align: left;\r\n font-size: 0.9rem;\r\n }\r\n th, td {\r\n padding: 0.75rem 1rem;\r\n border-bottom: 1px solid var(--card-border);\r\n }\r\n th {\r\n font-size: 0.75rem;\r\n text-transform: uppercase;\r\n letter-spacing: 0.05em;\r\n color: var(--text-muted);\r\n background: rgba(31, 41, 55, 0.4);\r\n }\r\n tr:last-child td {\r\n border-bottom: none;\r\n }\r\n .bar-row {\r\n display: flex;\r\n align-items: center;\r\n gap: 0.75rem;\r\n margin-bottom: 0.6rem;\r\n }\r\n .bar-label {\r\n width: 140px;\r\n font-size: 0.85rem;\r\n font-family: monospace;\r\n }\r\n .bar-track {\r\n flex: 1;\r\n height: 12px;\r\n background: #1f2937;\r\n border-radius: 9999px;\r\n overflow: hidden;\r\n }\r\n .bar-fill {\r\n height: 100%;\r\n border-radius: 9999px;\r\n transition: width 0.3s ease;\r\n }\r\n .bar-val {\r\n width: 80px;\r\n text-align: right;\r\n font-size: 0.85rem;\r\n color: var(--text-muted);\r\n }\r\n .callout {\r\n border-left: 4px solid;\r\n border-radius: 4px;\r\n padding: 0.85rem 1.15rem;\r\n background: var(--card-bg);\r\n margin-top: 1rem;\r\n font-size: 0.9rem;\r\n }\r\n .callout-optimal {\r\n border-color: var(--success);\r\n color: #bbf7d0;\r\n }\r\n .callout-warning {\r\n border-color: var(--warning);\r\n color: #fde68a;\r\n }\r\n footer {\r\n margin-top: 3rem;\r\n padding-top: 1.5rem;\r\n border-top: 1px solid var(--card-border);\r\n text-align: center;\r\n font-size: 0.8rem;\r\n color: var(--text-dim);\r\n }\r\n </style>\r\n</head>\r\n<body>\r\n <div class=\"container\">\r\n <header>\r\n <div>\r\n <span class=\"badge\">LoadScope Benchmark Report</span>\r\n <h1>Executive Load Performance Analysis</h1>\r\n <div class=\"target-url\">${escapeHtml(summary.target)}</div>\r\n <div style=\"font-size: 0.85rem; color: var(--text-muted); margin-top: 0.4rem;\">\r\n Duration: ${summary.durationSec.toFixed(1)}s &bull; Mode: ${summary.distribution ? `Open (${summary.distribution.toUpperCase()})` : \"Closed Concurrency\"} &bull; Workers: ${summary.workerCount || 1}\r\n </div>\r\n </div>\r\n <div class=\"actions\">\r\n <button onclick=\"copyJson()\">📋 Copy JSON</button>\r\n <button onclick=\"downloadJson()\">⬇️ Download JSON</button>\r\n <button onclick=\"downloadCsv()\">📊 Download CSV</button>\r\n <button class=\"primary\" onclick=\"window.print()\">🖨️ Print / PDF</button>\r\n </div>\r\n </header>\r\n\r\n <!-- KPI Grid -->\r\n <div class=\"kpi-grid\">\r\n <div class=\"card\">\r\n <div class=\"card-title\">Throughput</div>\r\n <div class=\"card-value val-success\">${fmt(summary.rps, 1)} <span style=\"font-size: 1rem; font-weight: normal; color: var(--text-muted);\">req/s</span></div>\r\n <div class=\"card-sub\">Total Dispatched: ${summary.totalRequests.toLocaleString(\"en-US\")}</div>\r\n </div>\r\n <div class=\"card\">\r\n <div class=\"card-title\">p95 Latency</div>\r\n <div class=\"card-value ${summary.p95 > 300 ? \"val-danger\" : \"val-primary\"}\">${fmt(summary.p95, 1)} <span style=\"font-size: 1rem; font-weight: normal; color: var(--text-muted);\">ms</span></div>\r\n <div class=\"card-sub\">Median p50: ${fmt(summary.p50, 1)} ms</div>\r\n </div>\r\n <div class=\"card\">\r\n <div class=\"card-title\">Error Rate</div>\r\n <div class=\"card-value ${summary.errorRate > 0 ? \"val-danger\" : \"val-success\"}\">${fmt(summary.errorRate * 100, 2)}%</div>\r\n <div class=\"card-sub\">Failures: ${summary.networkErrors + summary.httpErrors} (${summary.networkErrors} net, ${summary.httpErrors} http)</div>\r\n </div>\r\n <div class=\"card\">\r\n <div class=\"card-title\">Tail Latency (p99)</div>\r\n <div class=\"card-value val-primary\">${fmt(summary.p99, 1)} <span style=\"font-size: 1rem; font-weight: normal; color: var(--text-muted);\">ms</span></div>\r\n <div class=\"card-sub\">90th Percentile: ${fmt(summary.p90, 1)} ms</div>\r\n </div>\r\n </div>\r\n\r\n <!-- Latency CDF Curve Section -->\r\n <div class=\"section-title\">\r\n 📈 Latency Percentile Curve (CDF)\r\n </div>\r\n <div class=\"chart-container\" id=\"cdf-container\">\r\n <div class=\"tooltip\" id=\"cdf-tooltip\"></div>\r\n <svg viewBox=\"0 0 ${cdfSvgW} ${cdfSvgH}\">\r\n <!-- Horizontal Grid Lines -->\r\n <line x1=\"${cdfPadX}\" y1=\"${cdfPadY}\" x2=\"${cdfSvgW - cdfPadX}\" y2=\"${cdfPadY}\" stroke=\"var(--grid-line)\" stroke-width=\"1\" />\r\n <line x1=\"${cdfPadX}\" y1=\"${(cdfPadY + cdfSvgH - cdfPadY) / 2}\" x2=\"${cdfSvgW - cdfPadX}\" y2=\"${(cdfPadY + cdfSvgH - cdfPadY) / 2}\" stroke=\"var(--grid-line)\" stroke-width=\"1\" />\r\n <line x1=\"${cdfPadX}\" y1=\"${cdfSvgH - cdfPadY}\" x2=\"${cdfSvgW - cdfPadX}\" y2=\"${cdfSvgH - cdfPadY}\" stroke=\"var(--card-border)\" stroke-width=\"1.5\" />\r\n\r\n <!-- Polyline Curve -->\r\n <polyline fill=\"none\" stroke=\"var(--primary)\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\" points=\"${cdfPolyline}\" />\r\n\r\n <!-- Points -->\r\n ${cdfCoords\r\n .map(\r\n (c) => `<circle class=\"dot\" cx=\"${c.x.toFixed(1)}\" cy=\"${c.y.toFixed(1)}\" r=\"4\" fill=\"var(--primary-dark)\" stroke=\"var(--primary)\" stroke-width=\"2\" data-p=\"${c.p}\" data-val=\"${c.val.toFixed(2)}\" />\r\n <text x=\"${c.x.toFixed(1)}\" y=\"${cdfSvgH - 10}\" fill=\"var(--text-muted)\" font-size=\"11\" text-anchor=\"middle\" font-family=\"sans-serif\">${c.p}</text>`\r\n )\r\n .join(\"\\n \")}\r\n </svg>\r\n </div>\r\n\r\n <!-- Coordinated Omission Breakdown Table -->\r\n <div class=\"section-title\">\r\n ⏱️ Coordinated Omission Breakdown (Honest Latency vs Service Time)\r\n </div>\r\n <div class=\"card\" style=\"padding: 0; overflow: hidden; margin-bottom: 2rem;\">\r\n <table>\r\n <thead>\r\n <tr>\r\n <th>Metric Layer</th>\r\n <th>p50 (Median)</th>\r\n <th>p90</th>\r\n <th>p95</th>\r\n <th>p99</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr>\r\n <td style=\"font-weight: 600; color: var(--primary);\">Server Service Time</td>\r\n <td>${fmt(serviceP50, 1)} ms</td>\r\n <td>${fmt(serviceP90, 1)} ms</td>\r\n <td>${fmt(serviceP95, 1)} ms</td>\r\n <td>${fmt(serviceP99, 1)} ms</td>\r\n </tr>\r\n <tr>\r\n <td style=\"font-weight: 600; color: var(--text-muted);\">Client Queueing Delay</td>\r\n <td>${fmt(queueP50, 1)} ms</td>\r\n <td>${fmt(queueP90, 1)} ms</td>\r\n <td>${fmt(queueP95, 1)} ms</td>\r\n <td>${fmt(queueP99, 1)} ms</td>\r\n </tr>\r\n <tr>\r\n <td style=\"font-weight: 700; color: #fff;\">Honest Total Latency</td>\r\n <td style=\"font-weight: 600;\">${fmt(summary.p50, 1)} ms</td>\r\n <td style=\"font-weight: 600;\">${fmt(summary.p90, 1)} ms</td>\r\n <td style=\"font-weight: 600;\">${fmt(summary.p95, 1)} ms</td>\r\n <td style=\"font-weight: 600;\">${fmt(summary.p99, 1)} ms</td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n <!-- Time-Series Progression Section -->\r\n <div class=\"section-title\">\r\n 📊 Per-Second p95 Latency Progression\r\n </div>\r\n <div class=\"chart-container\" id=\"ts-container\">\r\n <div class=\"tooltip\" id=\"ts-tooltip\"></div>\r\n <svg viewBox=\"0 0 ${tsSvgW} ${tsSvgH}\">\r\n <!-- Grid -->\r\n <line x1=\"${tsPadX}\" y1=\"${tsPadY}\" x2=\"${tsSvgW - tsPadX}\" y2=\"${tsPadY}\" stroke=\"var(--grid-line)\" stroke-width=\"1\" />\r\n <line x1=\"${tsPadX}\" y1=\"${(tsPadY + tsSvgH - tsPadY) / 2}\" x2=\"${tsSvgW - tsPadX}\" y2=\"${(tsPadY + tsSvgH - tsPadY) / 2}\" stroke=\"var(--grid-line)\" stroke-width=\"1\" />\r\n <line x1=\"${tsPadX}\" y1=\"${tsSvgH - tsPadY}\" x2=\"${tsSvgW - tsPadX}\" y2=\"${tsSvgH - tsPadY}\" stroke=\"var(--card-border)\" stroke-width=\"1.5\" />\r\n\r\n <!-- Line -->\r\n <polyline fill=\"none\" stroke=\"#a855f7\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" points=\"${tsPolyline}\" />\r\n\r\n <!-- Points -->\r\n ${tsCoords\r\n .map(\r\n (c) => `<circle class=\"dot\" cx=\"${c.x.toFixed(1)}\" cy=\"${c.y.toFixed(1)}\" r=\"3.5\" fill=\"#7e22ce\" stroke=\"#a855f7\" stroke-width=\"1.5\" data-t=\"${c.t}s\" data-val=\"${c.p95.toFixed(2)}\" />\r\n <text x=\"${c.x.toFixed(1)}\" y=\"${tsSvgH - 10}\" fill=\"var(--text-muted)\" font-size=\"10\" text-anchor=\"middle\" font-family=\"sans-serif\">${c.t}s</text>`\r\n )\r\n .join(\"\\n \")}\r\n </svg>\r\n </div>\r\n\r\n <!-- Status Codes & Error Breakdown -->\r\n <div class=\"section-title\">\r\n 🚦 HTTP Status & Reliability Breakdown\r\n </div>\r\n <div class=\"card\" style=\"margin-bottom: 2rem;\">\r\n ${statusEntries\r\n .map(([code, count]) => {\r\n const pct = (count / totalStatusReqs) * 100;\r\n const isErr = parseInt(code, 10) >= 400;\r\n const fillCol = isErr ? \"var(--danger)\" : \"var(--success)\";\r\n return `<div class=\"bar-row\">\r\n <span class=\"bar-label\">HTTP ${code}</span>\r\n <div class=\"bar-track\">\r\n <div class=\"bar-fill\" style=\"width: ${pct.toFixed(1)}%; background: ${fillCol};\"></div>\r\n </div>\r\n <span class=\"bar-val\">${count.toLocaleString(\"en-US\")} (${pct.toFixed(1)}%)</span>\r\n </div>`;\r\n })\r\n .join(\"\\n \")}\r\n ${\r\n summary.networkErrors > 0\r\n ? `<div class=\"bar-row\">\r\n <span class=\"bar-label\" style=\"color: var(--danger);\">Network Err</span>\r\n <div class=\"bar-track\">\r\n <div class=\"bar-fill\" style=\"width: ${((summary.networkErrors / totalStatusReqs) * 100).toFixed(1)}%; background: var(--danger);\"></div>\r\n </div>\r\n <span class=\"bar-val\">${summary.networkErrors.toLocaleString(\"en-US\")}</span>\r\n </div>`\r\n : \"\"\r\n }\r\n </div>\r\n\r\n <!-- System Diagnostics -->\r\n <div class=\"section-title\">\r\n 🛡️ Runner Self-Monitoring Diagnostics\r\n </div>\r\n ${\r\n summary.selfCheckWarnings && summary.selfCheckWarnings.length > 0\r\n ? summary.selfCheckWarnings\r\n .map(\r\n (w) => `<div class=\"callout callout-warning\">\r\n <strong>⚠️ Warning:</strong> ${escapeHtml(w)}\r\n </div>`\r\n )\r\n .join(\"\\n\")\r\n : `<div class=\"callout callout-optimal\">\r\n <strong>✅ System Health Optimal:</strong> Event loop lag and scheduler jitter remained well within safe thresholds throughout test execution.\r\n </div>`\r\n }\r\n\r\n <footer>\r\n LoadScope v0.1.0 &bull; Self-Contained Interactive Benchmark Report &bull; Rendered ${new Date().toUTCString()}\r\n </footer>\r\n </div>\r\n\r\n <!-- Raw Payload Scripts -->\r\n <script type=\"application/json\" id=\"loadscope-data\">\r\n${jsonReport}\r\n </script>\r\n <script type=\"text/plain\" id=\"loadscope-csv\">\r\n${csvReport}\r\n </script>\r\n\r\n <script>\r\n // Interactive Tooltip Handling for CDF\r\n const cdfContainer = document.getElementById(\"cdf-container\");\r\n const cdfTooltip = document.getElementById(\"cdf-tooltip\");\r\n cdfContainer.querySelectorAll(\".dot\").forEach(dot => {\r\n dot.addEventListener(\"mouseenter\", (e) => {\r\n const p = dot.getAttribute(\"data-p\");\r\n const val = dot.getAttribute(\"data-val\");\r\n cdfTooltip.innerText = p + \": \" + val + \" ms\";\r\n cdfTooltip.style.display = \"block\";\r\n const rect = dot.getBoundingClientRect();\r\n const parentRect = cdfContainer.getBoundingClientRect();\r\n cdfTooltip.style.left = (rect.left - parentRect.left - 20) + \"px\";\r\n cdfTooltip.style.top = (rect.top - parentRect.top - 32) + \"px\";\r\n });\r\n dot.addEventListener(\"mouseleave\", () => {\r\n cdfTooltip.style.display = \"none\";\r\n });\r\n });\r\n\r\n // Interactive Tooltip Handling for Time Series\r\n const tsContainer = document.getElementById(\"ts-container\");\r\n const tsTooltip = document.getElementById(\"ts-tooltip\");\r\n tsContainer.querySelectorAll(\".dot\").forEach(dot => {\r\n dot.addEventListener(\"mouseenter\", (e) => {\r\n const t = dot.getAttribute(\"data-t\");\r\n const val = dot.getAttribute(\"data-val\");\r\n tsTooltip.innerText = \"Time \" + t + \" | p95: \" + val + \" ms\";\r\n tsTooltip.style.display = \"block\";\r\n const rect = dot.getBoundingClientRect();\r\n const parentRect = tsContainer.getBoundingClientRect();\r\n tsTooltip.style.left = (rect.left - parentRect.left - 40) + \"px\";\r\n tsTooltip.style.top = (rect.top - parentRect.top - 32) + \"px\";\r\n });\r\n dot.addEventListener(\"mouseleave\", () => {\r\n tsTooltip.style.display = \"none\";\r\n });\r\n });\r\n\r\n // Copy JSON to clipboard\r\n function copyJson() {\r\n const data = document.getElementById(\"loadscope-data\").textContent.trim();\r\n navigator.clipboard.writeText(data).then(() => {\r\n alert(\"JSON benchmark summary copied to clipboard!\");\r\n });\r\n }\r\n\r\n // Download JSON file\r\n function downloadJson() {\r\n const data = document.getElementById(\"loadscope-data\").textContent.trim();\r\n const blob = new Blob([data], { type: \"application/json\" });\r\n const url = URL.createObjectURL(blob);\r\n const a = document.createElement(\"a\");\r\n a.href = url;\r\n a.download = \"loadscope-summary.json\";\r\n document.body.appendChild(a);\r\n a.click();\r\n document.body.removeChild(a);\r\n URL.revokeObjectURL(url);\r\n }\r\n\r\n // Download CSV file\r\n function downloadCsv() {\r\n const data = document.getElementById(\"loadscope-csv\").textContent.trim();\r\n const blob = new Blob([data], { type: \"text/csv\" });\r\n const url = URL.createObjectURL(blob);\r\n const a = document.createElement(\"a\");\r\n a.href = url;\r\n a.download = \"loadscope-report.csv\";\r\n document.body.appendChild(a);\r\n a.click();\r\n document.body.removeChild(a);\r\n URL.revokeObjectURL(url);\r\n }\r\n </script>\r\n</body>\r\n</html>`;\r\n}\r\n\r\n/**\r\n * Generates and writes the interactive HTML report to disk.\r\n */\r\nexport async function generateHtmlReport(\r\n summary: RunSummary,\r\n outputPath?: string\r\n): Promise<string> {\r\n const resolvedPath = path.resolve(process.cwd(), outputPath || \"loadscope-report.html\");\r\n const html = renderHtmlReport(summary);\r\n await fs.writeFile(resolvedPath, html, \"utf-8\");\r\n return resolvedPath;\r\n}\r\n","import fs from \"node:fs\";\r\nimport path from \"node:path\";\r\nimport YAML from \"yaml\";\r\nimport { z } from \"zod\";\r\nimport type { ScenarioDefinition, ScenarioStep } from \"../types.js\";\r\n\r\nconst StepSchema = z.object({\r\n name: z.string().min(1, \"Step name cannot be empty\"),\r\n method: z.string().default(\"GET\"),\r\n path: z.string().optional(),\r\n url: z.string().optional(),\r\n headers: z.record(z.string()).optional(),\r\n body: z.string().optional(),\r\n extract: z.record(z.string()).optional(),\r\n thinkTime: z.union([z.string(), z.number()]).optional(),\r\n});\r\n\r\nconst ScenarioSchema = z.object({\r\n name: z.string().min(1, \"Scenario name cannot be empty\"),\r\n target: z.string().url(\"Scenario target must be a valid base URL\"),\r\n duration: z.union([z.string(), z.number()]).default(\"10s\"),\r\n concurrency: z.number().int().positive().default(10),\r\n timeout: z.union([z.string(), z.number()]).default(\"10s\"),\r\n steps: z.array(StepSchema).min(1, \"Scenario must contain at least 1 step\"),\r\n});\r\n\r\n/**\r\n * Replaces all occurrences of {{varName}} in a template string with values from context.\r\n */\r\nexport function interpolateVariables(template: string, context: Record<string, string>): string {\r\n if (!template || Object.keys(context).length === 0) return template;\r\n return template.replace(/\\{\\{\\s*([a-zA-Z0-9_.-]+)\\s*\\}\\}/g, (_, varName) => {\r\n return context[varName] !== undefined ? String(context[varName]) : `{{${varName}}}`;\r\n });\r\n}\r\n\r\n/**\r\n * Traverses a nested object using dot-notation (e.g. \"user.profile.id\" or \"items[0].id\").\r\n */\r\nfunction getNestedProp(obj: any, propPath: string): any {\r\n if (!obj || !propPath) return undefined;\r\n const parts = propPath.replace(/\\[(\\w+)\\]/g, \".$1\").split(\".\");\r\n let current = obj;\r\n for (const part of parts) {\r\n if (current == null) return undefined;\r\n current = current[part];\r\n }\r\n return current;\r\n}\r\n\r\n/**\r\n * Extracts variables from an HTTP response using configured extraction rules.\r\n */\r\nexport function extractFromResponse(\r\n body: string,\r\n headers: Record<string, string | string[] | undefined>,\r\n rules: Record<string, string>\r\n): Record<string, string> {\r\n const extracted: Record<string, string> = {};\r\n if (!rules || Object.keys(rules).length === 0) return extracted;\r\n\r\n let parsedJson: any = null;\r\n let jsonParsedAttempted = false;\r\n\r\n for (const [varName, rule] of Object.entries(rules)) {\r\n const colonIdx = rule.indexOf(\":\");\r\n if (colonIdx === -1) continue;\r\n\r\n const type = rule.substring(0, colonIdx).trim().toLowerCase();\r\n const query = rule.substring(colonIdx + 1).trim();\r\n\r\n if (type === \"json\") {\r\n if (!jsonParsedAttempted) {\r\n try {\r\n parsedJson = JSON.parse(body);\r\n } catch {\r\n parsedJson = null;\r\n }\r\n jsonParsedAttempted = true;\r\n }\r\n if (parsedJson) {\r\n const val = getNestedProp(parsedJson, query);\r\n if (val !== undefined && val !== null) {\r\n extracted[varName] = String(val);\r\n }\r\n }\r\n } else if (type === \"regex\") {\r\n try {\r\n const match = body.match(new RegExp(query));\r\n if (match) {\r\n extracted[varName] = match[1] !== undefined ? match[1] : match[0];\r\n }\r\n } catch {\r\n // invalid regex or no match\r\n }\r\n } else if (type === \"header\") {\r\n const headerKey = query.toLowerCase();\r\n for (const [k, v] of Object.entries(headers)) {\r\n if (k.toLowerCase() === headerKey && v != null) {\r\n extracted[varName] = Array.isArray(v) ? v[0] : String(v);\r\n break;\r\n }\r\n }\r\n }\r\n }\r\n\r\n return extracted;\r\n}\r\n\r\n/**\r\n * Parses and validates a ScenarioDefinition from a raw YAML/JSON string or file path.\r\n */\r\nexport function parseScenario(input: string): ScenarioDefinition {\r\n let content = input;\r\n\r\n // Check if input is a file path\r\n if (\r\n input.endsWith(\".yaml\") ||\r\n input.endsWith(\".yml\") ||\r\n input.endsWith(\".json\") ||\r\n (fs.existsSync(input) && fs.statSync(input).isFile())\r\n ) {\r\n const resolved = path.resolve(process.cwd(), input);\r\n content = fs.readFileSync(resolved, \"utf-8\");\r\n }\r\n\r\n let raw: unknown;\r\n try {\r\n raw = YAML.parse(content);\r\n } catch (yamlErr) {\r\n try {\r\n raw = JSON.parse(content);\r\n } catch {\r\n throw new Error(`Failed to parse scenario content as YAML or JSON: ${yamlErr instanceof Error ? yamlErr.message : String(yamlErr)}`);\r\n }\r\n }\r\n\r\n const result = ScenarioSchema.safeParse(raw);\r\n if (!result.success) {\r\n const issues = result.error.issues.map((i) => `[${i.path.join(\".\")}] ${i.message}`).join(\", \");\r\n throw new Error(`Invalid Scenario Definition: ${issues}`);\r\n }\r\n\r\n return result.data as ScenarioDefinition;\r\n}\r\n","import { Pool } from \"undici\";\r\nimport { performance } from \"node:perf_hooks\";\r\nimport { Histogram } from \"../stats/histogram.js\";\r\nimport { parseDurationToSeconds } from \"../config/schema.js\";\r\nimport { interpolateVariables, extractFromResponse } from \"./parser.js\";\r\nimport type {\r\n ScenarioDefinition,\r\n ScenarioSummary,\r\n StepSummary,\r\n RunSummary,\r\n RunOptions,\r\n} from \"../types.js\";\r\n\r\nfunction sleep(ms: number): Promise<void> {\r\n return new Promise((resolve) => setTimeout(resolve, ms));\r\n}\r\n\r\nexport interface ScenarioRunOverrides {\r\n concurrency?: number;\r\n duration?: number | string;\r\n timeout?: number | string;\r\n}\r\n\r\n/**\r\n * Executes a multi-step user journey scenario with concurrent virtual users.\r\n */\r\nexport async function runScenario(\r\n definition: ScenarioDefinition,\r\n overrides?: ScenarioRunOverrides\r\n): Promise<ScenarioSummary> {\r\n const concurrency = overrides?.concurrency ?? definition.concurrency ?? 10;\r\n const durationSec = parseDurationToSeconds(overrides?.duration ?? definition.duration ?? \"10s\");\r\n const timeoutSec = parseDurationToSeconds(overrides?.timeout ?? definition.timeout ?? \"10s\");\r\n\r\n const urlObj = new URL(definition.target);\r\n const pool = new Pool(urlObj.origin, {\r\n connections: Math.max(concurrency * 2, 10),\r\n pipelining: 1,\r\n keepAliveTimeout: 10_000,\r\n });\r\n\r\n const stepCount = definition.steps.length;\r\n const stepHistograms: Histogram[] = Array.from({ length: stepCount }, () => new Histogram());\r\n const stepStatusCodes: Record<number, number>[] = Array.from({ length: stepCount }, () => ({}));\r\n const stepErrorsByType: Record<string, number>[] = Array.from({ length: stepCount }, () => ({}));\r\n const stepNetworkErrors: number[] = new Array(stepCount).fill(0);\r\n const stepHttpErrors: number[] = new Array(stepCount).fill(0);\r\n\r\n const journeyHistogram = new Histogram();\r\n let totalJourneysStarted = 0;\r\n let completedJourneys = 0;\r\n let failedJourneys = 0;\r\n\r\n const overallHistogram = new Histogram();\r\n const overallStatusCodes: Record<number, number> = {};\r\n const overallErrorsByType: Record<string, number> = {};\r\n let overallNetworkErrors = 0;\r\n let overallHttpErrors = 0;\r\n\r\n const testStartTime = performance.now();\r\n const endTime = testStartTime + durationSec * 1000;\r\n let running = true;\r\n\r\n // Worker task for a single virtual user session\r\n async function virtualUserLoop(): Promise<void> {\r\n while (running && performance.now() < endTime) {\r\n totalJourneysStarted++;\r\n const journeyStart = performance.now();\r\n const sessionContext: Record<string, string> = {};\r\n let journeyFailed = false;\r\n\r\n for (let s = 0; s < stepCount; s++) {\r\n if (!running || performance.now() >= endTime) break;\r\n\r\n const step = definition.steps[s];\r\n\r\n // 1. Handle Think Time if defined\r\n if (step.thinkTime) {\r\n const thinkMs = parseDurationToSeconds(step.thinkTime) * 1000;\r\n if (thinkMs > 0) {\r\n await sleep(thinkMs);\r\n }\r\n }\r\n\r\n // 2. Interpolate path/URL, headers, body\r\n const rawPath = step.path ? interpolateVariables(step.path, sessionContext) : \"\";\r\n const rawUrl = step.url ? interpolateVariables(step.url, sessionContext) : \"\";\r\n const fullPath = rawUrl ? new URL(rawUrl).pathname + new URL(rawUrl).search : rawPath || \"/\";\r\n const method = (step.method || \"GET\").toUpperCase();\r\n\r\n const headers: Record<string, string> = {};\r\n if (step.headers) {\r\n for (const [k, v] of Object.entries(step.headers)) {\r\n headers[k] = interpolateVariables(v, sessionContext);\r\n }\r\n }\r\n\r\n const body = step.body ? interpolateVariables(step.body, sessionContext) : undefined;\r\n\r\n // 3. Dispatch Request\r\n const reqStart = performance.now();\r\n try {\r\n const response = await pool.request({\r\n path: fullPath,\r\n method: method as any,\r\n headers,\r\n body,\r\n headersTimeout: timeoutSec * 1000,\r\n bodyTimeout: timeoutSec * 1000,\r\n });\r\n\r\n const bodyText = await response.body.text();\r\n const latencyUs = Math.max(1, Math.round((performance.now() - reqStart) * 1000));\r\n\r\n // Record step metrics\r\n stepHistograms[s].record(latencyUs);\r\n overallHistogram.record(latencyUs);\r\n\r\n const statusCode = response.statusCode;\r\n stepStatusCodes[s][statusCode] = (stepStatusCodes[s][statusCode] || 0) + 1;\r\n overallStatusCodes[statusCode] = (overallStatusCodes[statusCode] || 0) + 1;\r\n\r\n if (statusCode >= 400) {\r\n stepHttpErrors[s]++;\r\n overallHttpErrors++;\r\n journeyFailed = true;\r\n }\r\n\r\n // 4. Extract Variables for subsequent steps\r\n if (step.extract) {\r\n const extracted = extractFromResponse(bodyText, response.headers as any, step.extract);\r\n Object.assign(sessionContext, extracted);\r\n }\r\n } catch (err: unknown) {\r\n const latencyUs = Math.max(1, Math.round((performance.now() - reqStart) * 1000));\r\n stepHistograms[s].record(latencyUs);\r\n overallHistogram.record(latencyUs);\r\n\r\n stepNetworkErrors[s]++;\r\n overallNetworkErrors++;\r\n\r\n const errCode = (err as any)?.code || (err instanceof Error ? err.name : \"UNKNOWN_ERROR\");\r\n stepErrorsByType[s][errCode] = (stepErrorsByType[s][errCode] || 0) + 1;\r\n overallErrorsByType[errCode] = (overallErrorsByType[errCode] || 0) + 1;\r\n\r\n journeyFailed = true;\r\n break; // Stop remaining steps on connection failure\r\n }\r\n }\r\n\r\n if (journeyFailed) {\r\n failedJourneys++;\r\n } else {\r\n completedJourneys++;\r\n const journeyDurationUs = Math.max(1, Math.round((performance.now() - journeyStart) * 1000));\r\n journeyHistogram.record(journeyDurationUs);\r\n }\r\n }\r\n }\r\n\r\n // Spawn concurrency virtual users\r\n const workers = Array.from({ length: concurrency }, () => virtualUserLoop());\r\n await Promise.all(workers);\r\n running = false;\r\n\r\n await pool.close();\r\n\r\n const actualDurationSec = Math.max((performance.now() - testStartTime) / 1000, 0.001);\r\n\r\n // Compile Step Summaries\r\n const steps: StepSummary[] = definition.steps.map((step, idx) => {\r\n const hist = stepHistograms[idx];\r\n const total = hist.total;\r\n const rps = total / actualDurationSec;\r\n const errCount = stepNetworkErrors[idx] + stepHttpErrors[idx];\r\n const errorRate = total > 0 ? errCount / total : 0;\r\n\r\n return {\r\n name: step.name,\r\n method: (step.method || \"GET\").toUpperCase(),\r\n path: step.path || step.url || \"/\",\r\n totalRequests: total,\r\n rps,\r\n p50: hist.percentile(50) / 1000,\r\n p90: hist.percentile(90) / 1000,\r\n p95: hist.percentile(95) / 1000,\r\n p99: hist.percentile(99) / 1000,\r\n min: hist.minMs(),\r\n max: hist.maxMs(),\r\n mean: hist.meanMs(),\r\n errorRate,\r\n statusCodes: stepStatusCodes[idx],\r\n networkErrors: stepNetworkErrors[idx],\r\n httpErrors: stepHttpErrors[idx],\r\n };\r\n });\r\n\r\n const overallTotal = overallHistogram.total;\r\n const overallErrTotal = overallNetworkErrors + overallHttpErrors;\r\n const overallSummary: RunSummary = {\r\n target: definition.target,\r\n rps: overallTotal / actualDurationSec,\r\n totalRequests: overallTotal,\r\n durationSec: actualDurationSec,\r\n p50: overallHistogram.percentile(50) / 1000,\r\n p90: overallHistogram.percentile(90) / 1000,\r\n p95: overallHistogram.percentile(95) / 1000,\r\n p99: overallHistogram.percentile(99) / 1000,\r\n errorRate: overallTotal > 0 ? overallErrTotal / overallTotal : 0,\r\n networkErrors: overallNetworkErrors,\r\n httpErrors: overallHttpErrors,\r\n statusCodes: overallStatusCodes,\r\n errorsByType: overallErrorsByType,\r\n series: [],\r\n selfCheckWarnings: [],\r\n };\r\n\r\n return {\r\n name: definition.name,\r\n target: definition.target,\r\n durationSec: actualDurationSec,\r\n concurrency,\r\n totalJourneys: totalJourneysStarted,\r\n completedJourneys,\r\n failedJourneys,\r\n journeysPerSec: completedJourneys / actualDurationSec,\r\n journeyP50: journeyHistogram.percentile(50) / 1000,\r\n journeyP90: journeyHistogram.percentile(90) / 1000,\r\n journeyP95: journeyHistogram.percentile(95) / 1000,\r\n journeyP99: journeyHistogram.percentile(99) / 1000,\r\n steps,\r\n overallSummary,\r\n };\r\n}\r\n","import picocolors from \"picocolors\";\r\nimport type { ScenarioSummary, StepSummary } from \"../types.js\";\r\n\r\nfunction fmt(n: number, d = 1): string {\r\n return n.toLocaleString(\"en-US\", {\r\n minimumFractionDigits: d,\r\n maximumFractionDigits: d,\r\n });\r\n}\r\n\r\nfunction pad(str: string, len: number, alignRight = false): string {\r\n if (str.length >= len) return str.substring(0, len);\r\n const diff = len - str.length;\r\n return alignRight ? \" \".repeat(diff) + str : str + \" \".repeat(diff);\r\n}\r\n\r\n/**\r\n * Formats a comprehensive terminal report for multi-step scenario execution.\r\n */\r\nexport function formatScenarioTerminalReport(summary: ScenarioSummary): string {\r\n const lines: string[] = [];\r\n const W = 80;\r\n\r\n lines.push(\"\");\r\n lines.push(picocolors.bold(picocolors.cyan(\"╔\" + \"═\".repeat(W) + \"╗\")));\r\n lines.push(\r\n picocolors.bold(picocolors.cyan(\"║\")) +\r\n picocolors.bold(picocolors.white(pad(` 🎭 LoadScope Scenario Benchmark Results: ${summary.name}`, W))) +\r\n picocolors.bold(picocolors.cyan(\"║\"))\r\n );\r\n lines.push(picocolors.bold(picocolors.cyan(\"╠\" + \"═\".repeat(W) + \"╣\")));\r\n\r\n lines.push(\r\n picocolors.bold(picocolors.cyan(\"║\")) +\r\n pad(` Target: ${summary.target}`, W) +\r\n picocolors.bold(picocolors.cyan(\"║\"))\r\n );\r\n lines.push(\r\n picocolors.bold(picocolors.cyan(\"║\")) +\r\n pad(` Duration: ${summary.durationSec.toFixed(1)}s │ Concurrency: ${summary.concurrency} virtual users`, W) +\r\n picocolors.bold(picocolors.cyan(\"║\"))\r\n );\r\n\r\n const completionPct = summary.totalJourneys > 0 ? (summary.completedJourneys / summary.totalJourneys) * 100 : 0;\r\n const compColor = completionPct >= 99 ? picocolors.green : completionPct >= 95 ? picocolors.yellow : picocolors.red;\r\n\r\n lines.push(\r\n picocolors.bold(picocolors.cyan(\"║\")) +\r\n pad(\r\n ` Journeys: ${summary.completedJourneys.toLocaleString(\"en-US\")} completed / ${summary.totalJourneys.toLocaleString(\"en-US\")} started (${compColor(fmt(completionPct, 1) + \"%\")})`,\r\n W\r\n ) +\r\n picocolors.bold(picocolors.cyan(\"║\"))\r\n );\r\n\r\n lines.push(\r\n picocolors.bold(picocolors.cyan(\"║\")) +\r\n pad(\r\n ` Journey RPS: ${fmt(summary.journeysPerSec, 1)} journeys/sec │ Failed: ${summary.failedJourneys}`,\r\n W\r\n ) +\r\n picocolors.bold(picocolors.cyan(\"║\"))\r\n );\r\n\r\n lines.push(\r\n picocolors.bold(picocolors.cyan(\"║\")) +\r\n pad(\r\n ` E2E Latency: p50=${fmt(summary.journeyP50, 1)}ms p90=${fmt(summary.journeyP90, 1)}ms p95=${fmt(summary.journeyP95, 1)}ms p99=${fmt(summary.journeyP99, 1)}ms`,\r\n W\r\n ) +\r\n picocolors.bold(picocolors.cyan(\"║\"))\r\n );\r\n\r\n lines.push(picocolors.bold(picocolors.cyan(\"╠\" + \"═\".repeat(W) + \"╣\")));\r\n lines.push(\r\n picocolors.bold(picocolors.cyan(\"║\")) +\r\n picocolors.bold(picocolors.yellow(pad(\" Step-by-Step Waterfall Performance Breakdown:\", W))) +\r\n picocolors.bold(picocolors.cyan(\"║\"))\r\n );\r\n lines.push(picocolors.bold(picocolors.cyan(\"╠\" + \"═\".repeat(W) + \"╣\")));\r\n\r\n // Table header\r\n const th = ` ${pad(\"#\", 3)} ${pad(\"Step Name\", 28)} ${pad(\"Method\", 6)} ${pad(\"Req/s\", 8, true)} ${pad(\"p50\", 8, true)} ${pad(\"p95\", 8, true)} ${pad(\"p99\", 8, true)} ${pad(\"Err%\", 7, true)}`;\r\n lines.push(\r\n picocolors.bold(picocolors.cyan(\"║\")) +\r\n picocolors.bold(picocolors.dim(pad(th, W))) +\r\n picocolors.bold(picocolors.cyan(\"║\"))\r\n );\r\n lines.push(\r\n picocolors.bold(picocolors.cyan(\"║\")) +\r\n picocolors.dim(\" \" + \"─\".repeat(W - 4)) + \" \" +\r\n picocolors.bold(picocolors.cyan(\"║\"))\r\n );\r\n\r\n summary.steps.forEach((step, idx) => {\r\n const errPct = fmt(step.errorRate * 100, 1) + \"%\";\r\n const errCol = step.errorRate > 0 ? picocolors.red : picocolors.green;\r\n const stepName = step.name.length > 28 ? step.name.substring(0, 25) + \"...\" : step.name;\r\n const errPadded = errCol(pad(errPct, 7, true));\r\n const prefix = ` ${pad(String(idx + 1), 3)} ${pad(stepName, 28)} ${pad(step.method, 6)} ${pad(fmt(step.rps, 1), 8, true)} ${pad(fmt(step.p50, 1) + \"ms\", 8, true)} ${pad(fmt(step.p95, 1) + \"ms\", 8, true)} ${pad(fmt(step.p99, 1) + \"ms\", 8, true)} `;\r\n\r\n lines.push(\r\n picocolors.bold(picocolors.cyan(\"║\")) +\r\n prefix +\r\n errPadded +\r\n \" \" +\r\n picocolors.bold(picocolors.cyan(\"║\"))\r\n );\r\n });\r\n\r\n lines.push(picocolors.bold(picocolors.cyan(\"╚\" + \"═\".repeat(W) + \"╝\")));\r\n lines.push(\"\");\r\n\r\n return lines.join(\"\\n\");\r\n}\r\n\r\n/**\r\n * Prints the formatted scenario report directly to stdout.\r\n */\r\nexport function printScenarioTerminalReport(summary: ScenarioSummary): void {\r\n console.log(formatScenarioTerminalReport(summary));\r\n}\r\n","import { validateRunOptions, resolveWorkerCount } from \"./config/schema.js\";\r\nimport { executeClosedModel } from \"./core/runner.js\";\r\nimport { executeOpenModel } from \"./core/open-model.js\";\r\nimport { executeMultiThreaded } from \"./core/multi-runner.js\";\r\nimport type { RunOptions, RunSummary } from \"./types.js\";\r\n\r\nexport * from \"./types.js\";\r\nexport { Histogram } from \"./stats/histogram.js\";\r\nexport { formatTerminalReport, printTerminalReport } from \"./report/terminal.js\";\r\nexport { formatJsonReport, formatCsvReport } from \"./report/export.js\";\r\nexport { LiveDashboard } from \"./report/dashboard.js\";\r\nexport { executeClosedModel } from \"./core/runner.js\";\r\nexport { executeOpenModel } from \"./core/open-model.js\";\r\nexport { executeMultiThreaded } from \"./core/multi-runner.js\";\r\nexport { ArrivalScheduler } from \"./core/scheduler.js\";\r\nexport { recordWithCorrection, extractDistribution, computeQueueDelay } from \"./stats/co-corrector.js\";\r\nexport { runBreakingPoint } from \"./modes/breaking-point.js\";\r\nexport { formatBreakpointTerminalReport, printBreakpointTerminalReport, formatStepRow } from \"./report/breakpoint-terminal.js\";\r\nexport {\r\n formatBreakpointJsonReport,\r\n formatBreakpointCsvReport,\r\n formatComparisonJsonReport,\r\n formatComparisonCsvReport,\r\n} from \"./report/export.js\";\r\nexport { saveBaseline, loadBaseline, compareRuns } from \"./modes/regression-gate.js\";\r\nexport {\r\n formatComparisonTerminalReport,\r\n printComparisonTerminalReport,\r\n generateGithubStepSummary,\r\n writeGithubStepSummary,\r\n} from \"./report/compare-terminal.js\";\r\nexport { generatePdfReport } from \"./report/pdf.js\";\r\nexport { buildAiDiagnosticPrompt, fetchAiDiagnostic } from \"./report/ai-analysis.js\";\r\nexport { renderHtmlReport, generateHtmlReport } from \"./report/html.js\";\r\nexport { parseScenario, interpolateVariables, extractFromResponse } from \"./scenario/parser.js\";\r\nexport { runScenario } from \"./scenario/runner.js\";\r\nexport { formatScenarioTerminalReport, printScenarioTerminalReport } from \"./report/scenario-terminal.js\";\r\n\r\n/**\r\n * Programmatic API to execute a load test run.\r\n * Automatically delegates to multi-threaded execution when workers > 1,\r\n * open arrival model when rate is specified, or single-threaded closed concurrency.\r\n */\r\nexport async function run(options: RunOptions): Promise<RunSummary> {\r\n const validated = validateRunOptions(options);\r\n\r\n const workerCount = resolveWorkerCount(validated.workers, validated.concurrency);\r\n if (workerCount > 1) {\r\n return executeMultiThreaded(validated);\r\n }\r\n\r\n if (validated.mode === \"open\" || (validated.rate !== undefined && validated.rate > 0 && validated.mode !== \"closed\")) {\r\n return executeOpenModel(validated);\r\n }\r\n\r\n return executeClosedModel(validated);\r\n}\r\n"],"mappings":"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","names":["Pool","monitorEventLoopDelay","Pool","monitorEventLoopDelay","picocolors","picocolors","fmt","fs","path","picocolors","fs","fmt","pad","fs","path","fmt","fs","path","fmt","path","fs","fs","path","z","Pool","Pool","picocolors","fmt","pad"]}
package/dist/cli.d.ts ADDED
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node