// SPEC: PJ2026-010401 Web工作台 draft-2026-06-18-r1; PJ2026-010403 API契约 draft-2026-06-18-r1. // Responsibility: Same-origin fake Workbench API and static server for Playwright browser regression tests. import { createReadStream, existsSync, statSync } from "node:fs"; import { readFile } from "node:fs/promises"; import { createServer, type IncomingMessage, type ServerResponse } from "node:http"; import { extname, join, resolve, sep } from "node:path"; type JsonRecord = Record; interface SessionRecord extends JsonRecord { sessionId: string; threadId?: string | null; status?: string | null; lastTraceId?: string | null; messages?: JsonRecord[]; hidden?: boolean; } interface ScenarioState { scenarioId: string; providerProfile: string; selectedSessionId: string; sessions: SessionRecord[]; traces: Record; requestLedger: JsonRecord[]; legacyRequestLedger: JsonRecord[]; chatRequests: JsonRecord[]; listOmitSelected: boolean; sessionDelayMs: number; terminalScript: boolean; terminalFailureScript: boolean; staleTraceId: string | null; } const cwd = process.cwd(); const args = new Map(); for (let index = 2; index < process.argv.length; index += 1) { const key = process.argv[index]; const value = process.argv[index + 1]; if (key?.startsWith("--")) { args.set(key.slice(2), value && !value.startsWith("--") ? value : "true"); if (value && !value.startsWith("--")) index += 1; } } const port = Number(args.get("port") ?? process.env.HWLAB_WORKBENCH_E2E_PORT ?? 4173); const distDir = resolve(cwd, args.get("dist") ?? "dist"); const capturePath = resolve(cwd, "tests/workbench-e2e/fixtures/real-captures/d601-v03-redacted.json"); const capture = JSON.parse(await readFile(capturePath, "utf8")) as { scenario: { selectedSessionId: string; providerProfile: string; sessions: SessionRecord[]; traces: Record } }; let state = createScenarioState("baseline"); const server = createServer((request, response) => { void handleRequest(request, response).catch((error) => { json(response, 500, { ok: false, status: 500, error: { code: "e2e_server_error", message: error instanceof Error ? error.message : String(error) } }); }); }); server.listen(port, "127.0.0.1", () => { console.log(`workbench-e2e-server listening on http://127.0.0.1:${port}`); }); async function handleRequest(request: IncomingMessage, response: ServerResponse): Promise { const method = request.method ?? "GET"; const url = new URL(request.url ?? "/", `http://${request.headers.host ?? `127.0.0.1:${port}`}`); const path = url.pathname; recordLedger(method, url); if (path === "/__e2e/health") return json(response, 200, { ok: true, scenarioId: state.scenarioId }); if (path === "/__e2e/state") return json(response, 200, stateSummary()); if (path === "/__e2e/reset" && method === "POST") { const body = await readJson(request); state = createScenarioState(String(body.scenarioId ?? "baseline")); return json(response, 200, stateSummary()); } if (path === "/auth/session" || path === "/auth/bootstrap") return json(response, 200, authPayload()); if (path === "/auth/login" && method === "POST") return authLoginResponse(response); if (path === "/v1/workbench/events" && method === "GET") return sse(response, url); if (path === "/v1/workbench/sessions" && method === "GET") { await delay(state.sessionDelayMs); return json(response, 200, workbenchSessionListPayload(url)); } const turnMatch = path.match(/^\/v1\/workbench\/turns\/([^/]+)$/u); if (turnMatch && method === "GET") { const traceId = decodeURIComponent(turnMatch[1] ?? ""); if (state.scenarioId === "completed-replay-detail-404" && traceId === "trc_completed") return json(response, 404, { ok: false, status: 404, error: { code: "turn_replay_unavailable" } }); if (traceId === state.staleTraceId) return json(response, 502, { ok: false, status: 502, error: { code: "upstream_unavailable", message: "stale trace is unavailable" } }); return json(response, 200, { ok: true, status: "ok", contractVersion: "workbench-read-model-v1", turn: turnPayload(traceId) }); } const traceMatch = path.match(/^\/v1\/workbench\/traces\/([^/]+)\/events$/u); if (traceMatch && method === "GET") { const traceId = decodeURIComponent(traceMatch[1] ?? ""); if (state.scenarioId === "completed-replay-detail-404" && traceId === "trc_completed") return json(response, 404, { ok: false, status: 404, error: { code: "trace_replay_unavailable" } }); if (traceId === state.staleTraceId) return json(response, 502, { ok: false, status: 502, error: { code: "upstream_unavailable", message: "stale trace is unavailable" } }); return json(response, 200, workbenchTracePayload(traceId, url)); } const sessionMessagesMatch = path.match(/^\/v1\/workbench\/sessions\/([^/]+)\/messages$/u); if (sessionMessagesMatch && method === "GET") { const sessionId = canonicalSessionId(decodeURIComponent(sessionMessagesMatch[1] ?? "")); const session = visibleSessionById(sessionId); return session ? json(response, 200, workbenchSessionMessagesPayload(session, url)) : json(response, 404, { ok: false, status: 404, error: { code: "session_not_found" } }); } const workbenchSessionMatch = path.match(/^\/v1\/workbench\/sessions\/([^/]+)$/u); if (workbenchSessionMatch && method === "GET") { const sessionId = canonicalSessionId(decodeURIComponent(workbenchSessionMatch[1] ?? "")); if (state.scenarioId === "session-switch-detail-404-isolated" && sessionId === "ses_stale_404") return json(response, 404, { ok: false, status: 404, error: { code: "session_not_found" } }); if (state.scenarioId === "completed-replay-detail-404" && sessionId === "ses_completed") return json(response, 404, { ok: false, status: 404, error: { code: "session_replay_unavailable" } }); const session = visibleSessionById(sessionId, { includeArchived: true }); return session ? json(response, 200, { ok: true, status: "found", session }) : json(response, 404, { ok: false, status: 404, error: { code: "session_not_found" } }); } if (path === "/v1/agent/chat" && method === "POST") { const body = await readJson(request); state.chatRequests.push(redactRequestBody(body)); return json(response, 200, acceptChatTurn(body)); } if (path === "/v1/agent/sessions" && method === "POST") { const body = await readJson(request); const session = createManualSession(body); state.selectedSessionId = session.sessionId; state.sessions.unshift(session); return json(response, 200, { ok: true, status: "ok", session }); } const agentSessionMatch = path.match(/^\/v1\/agent\/sessions\/([^/]+)$/u); if (agentSessionMatch && method === "DELETE") { const session = sessionById(decodeURIComponent(agentSessionMatch[1] ?? "")); if (!session) return json(response, 404, { ok: false, status: 404, error: { code: "session_not_found" } }); session.status = "archived"; session.updatedAt = new Date().toISOString(); return json(response, 200, { ok: true, status: "archived", session, archivedCount: 1 }); } if (agentSessionMatch && method === "GET") return json(response, 200, { session: sessionPayload(decodeURIComponent(agentSessionMatch[1] ?? "")) }); if (path === "/v1/provider-profiles") return json(response, 200, { profiles: [{ profile: "codex-api", name: "Codex API", configured: true }, { profile: "deepseek", name: "DeepSeek", configured: true }] }); if (path === "/health/live" || path === "/health" || path === "/v1") return json(response, 200, { status: "ok", serviceId: "workbench-e2e", codeAgent: { ready: true, status: "ready" } }); if (path === "/v1/live-builds") return json(response, 200, { status: "ok", builds: [] }); if (path === "/v1/hwpod/specs") return json(response, 200, { specs: [] }); if (path === "/v1/hwpod-node-ops") return json(response, 200, { ok: true, status: "ready", events: [], groups: [] }); if (path.startsWith("/v1/") || path.startsWith("/auth/") || path.startsWith("/health")) return json(response, 500, { ok: false, status: 500, error: { code: "unmocked_request", path } }); return staticFile(response, path); } function createScenarioState(scenarioId: string): ScenarioState { const base = structuredClone(capture.scenario); const id = scenarioId || "baseline"; const sessions = base.sessions; const traces = base.traces; if (id === "cross-project-detail-boundary") sessions.push(hiddenBoundarySession()); if (id === "legacy-cnv-deeplink-canonical") { sessions.unshift(legacyCanonicalSession()); traces.trc_40badc15523146c9 = legacyCanonicalTrace(); } if (id === "session-rail-many") { for (let index = 0; index < 46; index += 1) sessions.push(manyRailSession(index)); } if (id === "session-switch-detail-404-isolated") { sessions.unshift(staleDetailSession()); sessions.push(emptySession()); } if (id === "terminal-empty-trace") { sessions.push(terminalEmptyTraceSession()); traces.trc_terminal_empty = terminalEmptyTrace(); } if (id === "deleted-session-deeplink") sessions.unshift(archivedDeletedSession()); if (id === "session-switch-empty-reload") sessions.push(emptySession()); const selectedSessionId = id === "deep-link" || id === "stale-nested-trace" ? "ses_failed" : id === "legacy-cnv-deeplink-canonical" ? "ses_running" : id === "session-switch-detail-404-isolated" || id === "completed-replay-detail-404" || id === "deleted-session-deeplink" || id === "terminal-turn-stale-session-active" ? "ses_completed" : id === "terminal-empty-trace" ? "ses_terminal_empty" : base.selectedSessionId; const staleTraceId = id === "stale-nested-trace" || id === "stale-submit-restore" ? "trc_stale_502" : null; return { scenarioId: id, providerProfile: base.providerProfile, selectedSessionId, sessions, traces, requestLedger: [], legacyRequestLedger: [], chatRequests: [], listOmitSelected: id === "selected-missing-from-list", sessionDelayMs: id === "loading" ? 2_500 : 0, terminalScript: id === "event-replay" || id === "running-to-terminal" || id === "stale-submit-restore", terminalFailureScript: id === "stale-submit-restore", staleTraceId }; } function createManualSession(body: JsonRecord): SessionRecord { const now = new Date().toISOString(); const token = state.scenarioId === "server-authoritative-create" ? "server_created" : Date.now().toString(36); const sessionId = typeof body.sessionId === "string" && body.sessionId.trim() ? body.sessionId : `ses_${token}`; const threadId = typeof body.threadId === "string" && body.threadId.trim() ? body.threadId : null; return { sessionId, threadId, status: "active", startedAt: now, updatedAt: now, messageCount: 0, firstUserMessagePreview: null, messages: [] }; } function hiddenBoundarySession(): SessionRecord { const now = new Date().toISOString(); return { sessionId: "ses_cross_project", threadId: "thr_cross_project", hidden: true, status: "completed", lastTraceId: "trc_cross_project", startedAt: now, updatedAt: now, messageCount: 2, firstUserMessagePreview: "边界外 session 不应泄露", messages: [] }; } function terminalEmptyTraceSession(): SessionRecord { const now = new Date().toISOString(); return { sessionId: "ses_terminal_empty", threadId: "thr_terminal_empty", status: "completed", lastTraceId: "trc_terminal_empty", startedAt: now, updatedAt: now, messageCount: 2, firstUserMessagePreview: "完成态空 Trace 文案验证", messages: [ { id: "msg_terminal_empty_user", role: "user", title: "用户", text: "完成态空 Trace 文案验证", status: "sent", createdAt: now, sessionId: "ses_terminal_empty", threadId: "thr_terminal_empty", turnId: "turn_terminal_empty" }, { id: "msg_terminal_empty_agent", role: "agent", title: "Code Agent", text: "终态空 Trace 已完成。", status: "completed", createdAt: now, sessionId: "ses_terminal_empty", threadId: "thr_terminal_empty", traceId: "trc_terminal_empty", turnId: "turn_terminal_empty", runnerTrace: terminalEmptyTrace() } ] }; } function terminalEmptyTrace(): JsonRecord { return { traceId: "trc_terminal_empty", status: "completed", sessionId: "ses_terminal_empty", threadId: "thr_terminal_empty", events: [], eventCount: 0, fullTraceLoaded: true, hasMore: false, finalResponse: { text: "终态空 Trace 已完成。" } }; } function legacyCanonicalSession(): SessionRecord { const now = new Date().toISOString(); return { sessionId: "ses_c5e1330558c94d8e", conversationId: "cnv_c5e1330558c94d8e", threadId: "thr_c5e1330558c94d8e", status: "completed", lastTraceId: "trc_40badc15523146c9", startedAt: now, updatedAt: now, messageCount: 2, firstUserMessagePreview: "legacy cnv deep link canonical smoke", messages: [ { id: "msg_c5_user", role: "user", title: "用户", text: "legacy cnv deep link canonical smoke", status: "sent", createdAt: now, sessionId: "ses_c5e1330558c94d8e", threadId: "thr_c5e1330558c94d8e", traceId: "trc_40badc15523146c9" }, { id: "msg_c5_agent", role: "agent", title: "Code Agent", text: "已完成:新增 Python benchmark 脚本。", status: "completed", createdAt: now, sessionId: "ses_c5e1330558c94d8e", threadId: "thr_c5e1330558c94d8e", traceId: "trc_40badc15523146c9", runnerTrace: legacyCanonicalTrace() } ] }; } function legacyCanonicalTrace(): JsonRecord { return { traceId: "trc_40badc15523146c9", status: "completed", sessionId: "ses_c5e1330558c94d8e", threadId: "thr_c5e1330558c94d8e", events: [{ seq: 1, label: "agentrun:assistant:message", type: "assistant_message", status: "completed", terminal: true, final: true, message: "已完成:新增 Python benchmark 脚本。" }], eventCount: 1, fullTraceLoaded: true, hasMore: false, finalResponse: { text: "已完成:新增 Python benchmark 脚本。", status: "completed" } }; } function manyRailSession(index: number): SessionRecord { const id = String(index).padStart(2, "0"); const now = new Date(Date.now() - (index + 1) * 1000).toISOString(); return { sessionId: `ses_many_${id}`, threadId: `thr_many_${id}`, status: "completed", lastTraceId: `trc_many_${id}`, startedAt: now, updatedAt: now, messageCount: 0, firstUserMessagePreview: `历史 session ${id}`, messages: [] }; } function staleDetailSession(): SessionRecord { const now = new Date().toISOString(); return { sessionId: "ses_stale_404", threadId: "thr_stale_404", status: "active", startedAt: now, updatedAt: now, messageCount: 0, firstUserMessagePreview: "已失效的列表项", messages: [] }; } function emptySession(): SessionRecord { const now = new Date().toISOString(); return { sessionId: "ses_empty", threadId: "thr_empty", status: "active", startedAt: now, updatedAt: now, messageCount: 0, firstUserMessagePreview: "空白会话", messages: [] }; } function archivedDeletedSession(): SessionRecord { const now = new Date().toISOString(); return { sessionId: "ses_deleted", threadId: "thr_deleted", status: "archived", startedAt: now, updatedAt: now, messageCount: 0, firstUserMessagePreview: "已删除 session", messages: [] }; } function acceptChatTurn(body: JsonRecord): JsonRecord { const sessionId = typeof body.sessionId === "string" && body.sessionId.trim() ? body.sessionId : state.selectedSessionId; const session = sessionById(sessionId) ?? createManualSession({ sessionId }); if (!state.sessions.includes(session)) state.sessions.unshift(session); const threadId = typeof body.threadId === "string" && body.threadId.trim() ? body.threadId : null; const traceId = typeof body.traceId === "string" && body.traceId.trim() ? body.traceId : `trc_${Date.now().toString(16)}`; const message = typeof body.message === "string" ? body.message : ""; const now = new Date().toISOString(); session.status = "running"; session.lastTraceId = traceId; session.updatedAt = now; session.firstUserMessagePreview = session.firstUserMessagePreview ?? message; session.messageCount = (session.messages?.length ?? 0) + 2; session.messages = [ ...(session.messages ?? []), { id: `msg_${traceId}_user`, role: "user", title: "用户", text: message, status: "sent", createdAt: now, sessionId, threadId, traceId }, { id: `msg_${traceId}_agent`, role: "agent", title: "Code Agent", text: "", status: "running", createdAt: now, sessionId, threadId, traceId, runnerTrace: { traceId, status: "running", sessionId, threadId, events: [], eventCount: 0, fullTraceLoaded: false, hasMore: false } } ]; state.traces[traceId] = { traceId, status: "running", sessionId, threadId, events: [], eventCount: 0, fullTraceLoaded: false, hasMore: false }; return { status: "running", accepted: true, running: true, terminal: false, traceId, sessionId, threadId, turnId: traceId }; } function sessionSummary(session: SessionRecord): SessionRecord { const { messages: _messages, hidden: _hidden, ...rest } = session; return rest as SessionRecord; } function workbenchSessionListPayload(url: URL): JsonRecord { if (url.searchParams.has("projectId") || url.searchParams.has("workspaceId")) return { ok: false, status: 400, error: { code: "workbench_authority_removed" } }; const includeSessionId = url.searchParams.get("includeSessionId") || ""; const visible = state.sessions.filter((item) => !item.hidden && (item.status !== "archived" || item.sessionId === includeSessionId)); const listed = state.listOmitSelected && includeSessionId ? visible.filter((item) => item.sessionId !== includeSessionId) : visible; const summaries = listed.map((session) => sessionSummary(session)); return { ok: true, status: "succeeded", sessions: summaries, count: summaries.length }; } function workbenchSessionMessagesPayload(session: SessionRecord, url: URL): JsonRecord { const messages = Array.isArray(session.messages) ? session.messages : []; const requestedLimit = Number(url.searchParams.get("limit") ?? messages.length); const limit = Math.max(1, Number.isFinite(requestedLimit) ? Math.trunc(requestedLimit) : messages.length || 100); const page = messages.slice(0, limit); return { ok: true, status: "succeeded", sessionId: session.sessionId, messages: page, count: page.length, total: messages.length, hasMore: messages.length > page.length }; } function sessionById(id: string): SessionRecord | null { return state.sessions.find((session) => session.sessionId === id) ?? null; } function canonicalSessionId(id: string): string { const text = id.trim(); if (!text.startsWith("cnv_")) return text; const conversation = state.sessions.find((session) => session.conversationId === text); return conversation?.sessionId ?? `ses_${text.slice("cnv_".length)}`; } function visibleSessionById(id: string, options: { includeArchived?: boolean } = {}): SessionRecord | null { const session = sessionById(id); if (!session || session.hidden) return null; if (session.status === "archived" && !options.includeArchived) return null; return session; } function sessionPayload(sessionId: string): JsonRecord { const session = sessionById(sessionId); if (state.scenarioId === "terminal-turn-stale-session-active" && sessionId === "ses_completed") return { sessionId, status: "active", lastTraceId: "trc_completed", updatedAt: new Date().toISOString() }; return { sessionId, status: session?.status ?? "unknown", lastTraceId: session?.lastTraceId ?? null, updatedAt: new Date().toISOString() }; } function turnPayload(traceId: string): JsonRecord { const trace = state.traces[traceId] ?? { traceId, status: "unknown", events: [] }; if (state.scenarioId === "terminal-turn-stale-session-active" && traceId === "trc_completed") return { ...trace, traceId, status: "active", running: true, terminal: false, trace: { status: "completed", eventCount: trace.eventCount ?? 0 } }; const status = String(trace.status ?? "unknown"); return { ...trace, traceId, status, running: ["running", "pending", "accepted"].includes(status), terminal: ["completed", "failed", "blocked", "timeout", "canceled"].includes(status) }; } function tracePayload(traceId: string, url: URL): JsonRecord { const turn = turnPayload(traceId); const events = Array.isArray(turn.events) ? turn.events as JsonRecord[] : []; const sinceSeq = Number(url.searchParams.get("sinceSeq") ?? 0); const requestedLimit = Number(url.searchParams.get("limit") ?? events.length); const limit = requestedLimit || events.length || 100; const filtered = Number.isFinite(sinceSeq) && sinceSeq > 0 ? events.filter((event) => Number(event.seq ?? 0) > sinceSeq) : events; const page = filtered.slice(0, Math.max(1, Number.isFinite(limit) ? limit : 100)); const lastSeq = Number(page.at(-1)?.seq ?? 0); const hasMore = filtered.length > page.length; return { ...turn, events: page, eventCount: events.length, hasMore, fullTraceLoaded: !hasMore, nextSinceSeq: hasMore ? lastSeq : null, range: { sinceSeq, returned: page.length, total: events.length } }; } function workbenchTracePayload(traceId: string, url: URL): JsonRecord { const payload = tracePayload(traceId, url); return { ok: true, status: "ok", contractVersion: "workbench-read-model-v1", traceId, traceStatus: payload.status, events: payload.events, eventCount: payload.eventCount, hasMore: payload.hasMore, nextSeq: payload.nextSinceSeq, range: payload.range, fullTraceLoaded: payload.fullTraceLoaded, terminalEvidence: payload.terminalEvidence, finalResponse: payload.finalResponse, traceSummary: payload.traceSummary, retention: payload.retention }; } function sse(response: ServerResponse, url: URL): void { response.writeHead(200, { "content-type": "text/event-stream; charset=utf-8", "cache-control": "no-cache", connection: "keep-alive" }); writeSse(response, "workbench.connected", { type: "connected", sessionId: url.searchParams.get("sessionId") }); if (!state.terminalScript) return; const scenarioId = state.scenarioId; setTimeout(() => { if (state.scenarioId !== scenarioId) return; const terminalStatus = state.terminalFailureScript ? "failed" : "completed"; const terminalText = state.terminalFailureScript ? "恢复后失败:缺少受控依赖。" : "事件重放后完成。"; const event = { seq: 3, createdAt: new Date().toISOString(), label: "agentrun:assistant:message", type: "assistant_message", status: terminalStatus, replyAuthority: true, final: true, message: terminalText, terminal: true }; writeSse(response, "workbench.trace.event", { type: "trace.event", traceId: "trc_running", event, snapshot: { traceId: "trc_running", status: terminalStatus, events: [event], eventCount: 3, fullTraceLoaded: true, finalResponse: { text: terminalText, status: terminalStatus } } }); finishRunningSession(terminalStatus, terminalText); writeSse(response, "workbench.turn.snapshot", { type: "turn.snapshot", traceId: "trc_running", turn: turnPayload("trc_running") }); }, 350); } function writeSse(response: ServerResponse, eventName: string, payload: JsonRecord): void { response.write(`event: ${eventName}\n`); response.write(`data: ${JSON.stringify(payload)}\n\n`); } function finishRunningSession(status: "completed" | "failed", text: string): void { const session = sessionById("ses_running"); if (!session) return; session.status = status; session.updatedAt = new Date().toISOString(); const trace = state.traces.trc_running ?? { traceId: "trc_running", status: "running", events: [] }; const finalEvent = { seq: 4, createdAt: new Date().toISOString(), label: `agentrun:terminal:${status}`, status, terminal: true }; const events = [...(Array.isArray(trace.events) ? trace.events as JsonRecord[] : []), finalEvent]; state.traces.trc_running = { ...trace, status, events, eventCount: events.length, fullTraceLoaded: true, hasMore: false, assistantText: text, finalResponse: { text, status } }; session.messages = (session.messages ?? []).map((message) => message.role === "agent" ? { ...message, text, status, runnerTrace: state.traces.trc_running } : message); } function stateSummary(): JsonRecord { return { scenarioId: state.scenarioId, selectedSessionId: state.selectedSessionId, requestLedger: state.requestLedger, legacyRequestLedger: state.legacyRequestLedger, chatRequests: state.chatRequests, staleTraceId: state.staleTraceId, sessions: state.sessions.map((item) => ({ sessionId: item.sessionId, threadId: item.threadId, status: item.status, lastTraceId: item.lastTraceId, hidden: item.hidden === true })) }; } function recordLedger(method: string, url: URL): void { if (!url.pathname.startsWith("/v1/")) return; const entry = { method, path: url.pathname, query: Object.fromEntries(url.searchParams.entries()) }; state.requestLedger.push(entry); if (isLegacyWorkbenchPath(url.pathname)) state.legacyRequestLedger.push(entry); } function isLegacyWorkbenchPath(path: string): boolean { if (/^\/v1\/workbench\/(sessions(?:\/[^/]+(?:\/messages)?)?|events|turns\/[^/]+|traces\/[^/]+\/events)$/u.test(path)) return false; if (path === "/v1/agent/chat" || /^\/v1\/agent\/sessions(?:\/[^/]+(?:\/select)?)?$/u.test(path)) return false; return path.startsWith("/v1/workbench/") || path.startsWith("/v1/agent/"); } function authPayload(): JsonRecord { if (state.scenarioId === "auth-upstream-unavailable" || state.scenarioId === "auth-invalid-credentials") return { authenticated: false, mode: "server", actor: null, user: null, expiresAt: null }; return { authenticated: true, mode: "server", actor: { id: "usr_e2e_admin", username: "e2e-admin", role: "admin", status: "active" }, user: { id: "usr_e2e_admin", username: "e2e-admin", role: "admin", status: "active" }, expiresAt: null }; } function authLoginResponse(response: ServerResponse): void { if (state.scenarioId === "auth-upstream-unavailable") return json(response, 502, { ok: false, status: "failed", error: { code: "upstream_unavailable", message: "auth upstream unavailable", retryable: true, layer: "proxy" } }); return json(response, 401, { ok: false, status: "failed", error: { code: "invalid_credentials", message: "invalid credentials" } }); } function redactRequestBody(value: JsonRecord): JsonRecord { const output: JsonRecord = {}; for (const [key, item] of Object.entries(value)) output[key] = /secret|token|key|password|authorization/iu.test(key) ? "" : item; return output; } async function readJson(request: IncomingMessage): Promise { const chunks: Buffer[] = []; for await (const chunk of request) chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)); if (chunks.length === 0) return {}; try { const parsed = JSON.parse(Buffer.concat(chunks).toString("utf8")); return parsed && typeof parsed === "object" ? parsed as JsonRecord : {}; } catch { return {}; } } function json(response: ServerResponse, status: number, body: unknown): void { response.writeHead(status, { "content-type": "application/json; charset=utf-8" }); response.end(JSON.stringify(body)); } function staticFile(response: ServerResponse, path: string): void { const filePath = safeStaticPath(path); const target = filePath && existsSync(filePath) && statSync(filePath).isFile() ? filePath : join(distDir, "index.html"); response.writeHead(200, { "content-type": contentType(target) }); createReadStream(target).pipe(response); } function safeStaticPath(path: string): string | null { const normalized = resolve(distDir, `.${decodeURIComponent(path === "/" ? "/index.html" : path)}`); return normalized === distDir || normalized.startsWith(`${distDir}${sep}`) ? normalized : null; } function contentType(filePath: string): string { switch (extname(filePath)) { case ".html": return "text/html; charset=utf-8"; case ".js": return "text/javascript; charset=utf-8"; case ".css": return "text/css; charset=utf-8"; case ".svg": return "image/svg+xml"; case ".ico": return "image/x-icon"; default: return "application/octet-stream"; } } function delay(ms: number): Promise { return ms > 0 ? new Promise((resolveDelay) => setTimeout(resolveDelay, ms)) : Promise.resolve(); }