/** * SSE write helper with stream-injection hardening (CVE-2026-003). * * Every `data:` frame is JSON-stringified and newlines / U+2028 / U+2029 are * escaped so a chunk containing `}\n\n` or other control characters cannot * break out of the event stream and inject fake events. */ export function sseSafe(obj) { return JSON.stringify(obj) .replace(/\n/g, "\\n") .replace(/\u2028/g, "\\u2028") .replace(/\u2029/g, "\\u2029"); } /** * Write one SSE event. No-op if the response has already ended (guards the * "write after end" error that can otherwise surface when an AI error handler * closes the stream and the caller keeps writing). */ export function sseWrite(res, obj) { if (res.writableEnded) return; res.write(`data: ${sseSafe(obj)}\n\n`); }