Closes H4 and the remaining formatter half of H2.
- New @shared/format.ts is the single home for fmtBytes/fmtSpeed/fmtEta, imported
by both main and renderer. main/lib/formatters.ts re-exports them.
- DownloadProgress now carries raw speedBytesPerSec/etaSeconds instead of
pre-formatted speed/eta strings. main's parseProgress emits the raw numbers.
- The renderer stores the raw numbers on DownloadItem; QueueItem formats them for
per-item display, and summarizeQueue sums/maxes them directly. The lossy
string->number->string round-trip in queueStats (parseSpeed / parseEtaSeconds /
a local formatSpeed / formatEta) is deleted, along with a duplicate fmtEta in
store/downloads.ts.
- Per-item and aggregate speed now use the same 1024-based scale; the aggregate
previously used a 1000-based formatter (a latent inconsistency).
Tests updated for the raw-number contract (parseProgress, summarizeQueue).
typecheck + 248 tests + eslint + prettier green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>