buildPreview function
Builds the symmetric preview for body — exactly what the session
stores and the model sees (issue #678 Decision). Pinned sectioning
(blank-line separated): header lines / head / omitted marker /
tail + read hint:
[spilled: <totalChars> chars, <totalLines> lines (threshold <T> chars)]
[spill file: <spillPath>]
<head — at most headChars, codepoint-safe cut>
[... <omitted> chars omitted ...]
<tail — at most tailChars, codepoint-safe cut>
[read the spill file above for the full output]
Char-bounded (never line-counted — a single giant line stays bounded,
AC3), UTF-16 surrogate-pair-safe (AC4), and the omitted marker
([... N chars omitted ...]) carries the TRUE omitted size (AC10).
Pure function.
Implementation
String buildPreview(
String body, {
required String spillPath,
required SpillsConfig config,
}) {
final head = _headExcerpt(body, config.headChars);
final tail = _tailExcerpt(body, config.tailChars);
final omitted = body.length - head.length - tail.length;
final lines = '\n'.allMatches(body).length + 1;
return '[spilled: ${body.length} chars, $lines lines '
'(threshold ${config.threshold} chars)]\n'
'[spill file: $spillPath]\n'
'\n'
'$head\n'
'\n'
'[... $omitted chars omitted ...]\n'
'\n'
'$tail\n'
'$spillReadHint';
}