A truncated caplog download used to completeError and discard every received
byte, so the user got nothing from a buffer still intact on the device (a tester
lost 8461/8608 bytes, 98.3%, deterministically per firmware#711 so retry can't
help). Now truncation is a soft outcome:
- downloadCaplog() returns a CaplogDownload (bytes + received/expected/chunks +
truncated) instead of throwing; busy/timeout still throw.
- serial_capture_screen still writes + LogExport.shareFile the partial bytes,
marks the file "# PARTIAL ..." with the counts, and shows a non-fatal warning
instead of a red error.
- Button label is now platform-aware (Download & save on desktop, & share on
mobile) via LogExport.actionVerb, matching the App/BLE log screens.
Replaces CaplogTruncatedException with CaplogDownload. Reassembler unchanged
(already keeps the bytes). Adds CaplogDownload contract tests.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>