formatSessionSearchOutcome function
Renders outcome as the tool's text result (search mode): one
pointer line per hit, an honest continuation footer when the scan
stopped early — on EVERY path, including the zero-hit page (a capped
or time-budgeted scan with no hits on this page must never read as
"the archive has no matches"), and the verbatim unavailable reason
when no archive could be searched at all.
Implementation
String formatSessionSearchOutcome(SessionSearchOutcome outcome) {
if (outcome.map != null) return _formatArchiveMap(outcome);
final unavailable = outcome.unavailableReason;
if (unavailable.isNotEmpty) {
return 'session_search unavailable: $unavailable';
}
final lines = <String>[
if (outcome.hits.isEmpty)
'no records match (examined ${outcome.recordsExamined} of '
'${outcome.recordsTotal} records)'
else ...[
'${outcome.hits.length} hit(s) in the session archive '
'(examined ${outcome.recordsExamined} of ${outcome.recordsTotal} '
'records):',
for (final hit in outcome.hits)
'- ${hit.id} [${hit.kind}] ${hit.timestamp.toIso8601String()}: '
'${hit.preview}',
],
];
if (outcome.truncated) lines.add(_truncationFooter(outcome));
if (outcome.hits.isNotEmpty) {
lines.add(
'expand what matters with compact_expand {target: <id>} — previews '
'are pointers, not content',
);
}
return lines.join('\n');
}