7e13fc41

By: Michael Lynch <git@mtlynch.io>

Split convert package by abstraction level

The convert package mixed four altitudes: a storage abstraction, image
primitives, fs-to-storage transform pipelines, and ffmpeg primitives.
Separate them to match the layout the upload work (slice-3) builds on:

- mediastore: MediaWriter/LocalWriter/WriteFile plus a generic
  WriteConverted helper that consolidates the temp-file-and-write pipeline
  previously duplicated in convert and importers.
- images: pure image primitives (GenerateSquareThumbnail, ResizeToWidth).
- imagepipe: GenerateAndWriteSquareThumbnail/GenerateAndWriteResized,
  rebuilt on mediastore.WriteConverted + images primitives.
- convert: now only ffmpeg primitives (video, avif); stdlib-only imports.

Migrate all call sites (importers, the import-from-tinybeans main)
accordingly. s3.Writer needs no change since it satisfies the interface
implicitly.

This is the layout half of the slice-3 refactoring, applied to master in
isolation. The slice-3-only helpers that serve upload functionality
(mediastore.WriteProduced, images.Dimensions, images.Reencode) are
intentionally deferred to slice-3.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

Suite timing

Time to Start Worker time Duration Time to finish Idle
Config 0s 7s 7s 7s 0s
Eval 5s 44s 44s 49s 0s
Build 10s 5m53s 2m03s 2m14s 27s
Suite 0s 6m45s 2m14s 2m14s 27s

Timeline

0s0s10s20s30s40s50s1m1m10s1m20s1m30s1m40s