* Lightweight forward scan of [0, endOffset) collecting only metadata-entry lines. * Uses raw Buffer chunks and byte-level marker matching — no readline, no per-line * string conversion for the ~99% of lines that are message content. * * Fast path: if a chunk contains zero markers (the common ca
( filePath: string, endOffset: number, )
| 3249 | * are <50 per session), the entire chunk is skipped without line splitting. |
| 3250 | */ |
| 3251 | async function scanPreBoundaryMetadata( |
| 3252 | filePath: string, |
| 3253 | endOffset: number, |
| 3254 | ): Promise<string[]> { |
| 3255 | const { createReadStream } = await import('fs') |
| 3256 | const NEWLINE = 0x0a |
| 3257 | |
| 3258 | const stream = createReadStream(filePath, { end: endOffset - 1 }) |
| 3259 | const metadataLines: string[] = [] |
| 3260 | let carry: Buffer | null = null |
| 3261 | |
| 3262 | for await (const chunk of stream) { |
| 3263 | const chunkBuf = chunk as Buffer |
| 3264 | const buf = resolveMetadataBuf(carry, chunkBuf) |
| 3265 | if (buf === null) { |
| 3266 | carry = null |
| 3267 | continue |
| 3268 | } |
| 3269 | |
| 3270 | // Fast path: most chunks contain zero metadata markers. Skip line splitting. |
| 3271 | let hasAnyMarker = false |
| 3272 | for (const m of METADATA_MARKER_BUFS) { |
| 3273 | if (buf.includes(m)) { |
| 3274 | hasAnyMarker = true |
| 3275 | break |
| 3276 | } |
| 3277 | } |
| 3278 | |
| 3279 | if (hasAnyMarker) { |
| 3280 | let lineStart = 0 |
| 3281 | let nl = buf.indexOf(NEWLINE) |
| 3282 | while (nl !== -1) { |
| 3283 | // Bounded marker check: only look within this line's byte range |
| 3284 | for (const m of METADATA_MARKER_BUFS) { |
| 3285 | const mIdx = buf.indexOf(m, lineStart) |
| 3286 | if (mIdx !== -1 && mIdx < nl) { |
| 3287 | metadataLines.push(buf.toString('utf-8', lineStart, nl)) |
| 3288 | break |
| 3289 | } |
| 3290 | } |
| 3291 | lineStart = nl + 1 |
| 3292 | nl = buf.indexOf(NEWLINE, lineStart) |
| 3293 | } |
| 3294 | carry = buf.subarray(lineStart) |
| 3295 | } else { |
| 3296 | // No markers in this chunk — just preserve the incomplete trailing line |
| 3297 | const lastNl = buf.lastIndexOf(NEWLINE) |
| 3298 | carry = lastNl >= 0 ? buf.subarray(lastNl + 1) : buf |
| 3299 | } |
| 3300 | |
| 3301 | // Guard against quadratic carry growth for pathological huge lines |
| 3302 | // (e.g., a 10 MB tool-output line with no newline). Real metadata entries |
| 3303 | // are <1 KB, so if carry exceeds this we're mid-message-content — drop it. |
| 3304 | if (carry.length > 64 * 1024) carry = null |
| 3305 | } |
| 3306 | |
| 3307 | // Final incomplete line (no trailing newline at endOffset) |
| 3308 | if (carry !== null && carry.length > 0) { |
no test coverage detected