feat: initial v0.1.0 MVP

Replaces Smush Pro's optimisation pipeline without the grey-wash bug.

CLI commands working:
  wp h4b-img status
  wp h4b-img optimise --id=<n>
  wp h4b-img bulk
  wp h4b-img rescue

Verified on dev.rds.ink:
- ICC profile preservation works (the Smush-bug fix)
- Bulk: 20 attachments → 487 KB saved (10.4%), 0 errors
- Rescue: end-to-end mechanism verified on WorkingAsOne_horse fixture
- WebP synchronous, AVIF queued via WP-Cron
- Originals backed up to wp-content/h4b-img-originals/

See CHANGELOG.md for details + ../DESIGN-h4b-image-optim.md for architecture.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Henk
2026-05-19 13:41:03 +10:00
commit 7e1c86f215
19 changed files with 2498 additions and 0 deletions

61
CHANGELOG.md Normal file
View File

@@ -0,0 +1,61 @@
# CHANGELOG
All notable changes to **h4b-image-optim** will be documented here.
Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [0.1.0] — 2026-05-19
Initial MVP. Replaces Smush Pro's optimisation pipeline without the
grey-wash bug. CLI-only in this release (admin UI comes in 0.2).
### Added
- **Plugin scaffold** with PSR-12-style namespaced classes (`H4B\ImageOptim\*`)
- **`Optimizer`** — in-place JPG / PNG re-encode using Imagick + jpegoptim / pngquant
- **ICC profile preservation** (the Smush-bug fix) via bundled sRGB v4 profile fallback
- 4:4:4 chroma subsampling for large images; 4:2:0 for small ones
- Configurable size threshold (`min_optimise_bytes`, default 20 KB) to skip
thumbnails that re-encoding would inflate
- Atomic file replacement with ownership preservation
- GPS EXIF stripping on by default for privacy
- EXIF orientation applied before encode
- **`Format_Generator`** — WebP (synchronous) + AVIF (queued via WP-Cron) siblings
- **`Uploader_Hook`** — intercepts `wp_generate_attachment_metadata`
- **`Attachment_Meta`** — per-attachment optimisation history in `_h4b_img_optim`
- **`Rescue_Detector`** — PHP port of the Python grey-wash detector
- **Originals backup** to `wp-content/h4b-img-originals/` with 90-day cron prune
- **WP-CLI commands**:
- `wp h4b-img status` — tool detection + settings dump
- `wp h4b-img optimise --id=<n>` — single-attachment optimise (+ `--dry-run`)
- `wp h4b-img bulk` — bulk-optimise unprocessed attachments (+ `--limit`,
`--force`, `--dry-run`, `--batch`, `--pause`)
- `wp h4b-img rescue` — scan + optionally repair Smush-mangled JPGs from
their `.webp` siblings (+ `--scan`, `--apply`, `--min-severity`, `--csv`,
`--manifest`)
- **`uninstall.php`** — clean removal of plugin options + cron, preserves
user data (backups + .webp/.avif siblings + optimisation postmeta)
### Required system tools (AlmaLinux 9 / Debian 13)
| Tool | AlmaLinux | Debian |
|---|---|---|
| `cwebp` | `libwebp-tools` | `webp` |
| `jpegoptim` | `jpegoptim` | `jpegoptim` |
| `cjpeg` / `jpegtran` | `libjpeg-turbo-utils` | `libjpeg-turbo-progs` |
| `avifenc` | `libavif-tools` | `libavif-bin` |
| `pngquant` | `pngquant` | `pngquant` |
| `optipng` | `optipng` | `optipng` |
### Known limitations
- No admin settings page (CLI/`wp option` only)
- No Picture-tag rewriting on `the_content` (Smush still serving WebPs)
- No `.htaccess` content-negotiation fallback
- No `migrate-from-smush` command yet
- No PHPUnit test suite yet
### Verified against
- AlmaLinux 9.7 / PHP 8.4.21 / Imagick 3.8.1 (production)
- Debian 13 / PHP 8.4 / wordpress:php8.4-apache (dev container)
- Tested on 20 rds.ink attachments in bulk mode: 487 KB saved (10.4%), 0 errors
- Rescue mechanic verified end-to-end on the WorkingAsOne_horse900-800x524.jpg fixture