Shoot the README screenshots, and make them regenerable
The screenshot section had been a placeholder since the shell was rebuilt as three panes, because there was no cheap way to re-shoot and a stale image is worse than no image. So this ships the capture, not just the captures: scripts/screenshots.mjs takes all ten pages at 1440x900 and 393x852, in light and dark, and screenshots-encode.py halves and re-encodes them to WebP — 16MB of PNG becomes 1.9MB in the tree. Two things would silently ruin a run, and the script exists to encode both. Seeding localStorage['pig.themeMode'] is not enough: the appearance preference is authoritative server-side and adopted after hydration, so every dark capture snapped back to light a beat after first paint. The /api/me/profile response is rewritten instead. And pig.sidebarOpen / pig.piggyDockOpen are per-device, so whatever the last human left behind would otherwise leak in. The run also fails on a wrong theme, a horizontal scrollbar or a console error — three things a screenshot cannot show you. Piggy is not pictured mid-conversation. It is off by default and no inference credential exists, so such an image would be a staged transcript rather than a capture. The README says that rather than implying the feature is missing. Correcting what the README asserted while shooting against the running code: read authorisation IS enforced — createReadGuardRoutes is mounted ahead of the feature routes, and routes/learn.ts and routes/activities.ts are mounted too, so only the HubSpot pair is still unreachable. The remaining read gap is that a grant cannot be narrowed, there being no row-level team filter in the query layer. Counts refreshed against the tree: 275 tests, ~47k lines, 14 migrations. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Downscale and re-encode the raw Playwright captures as WebP.
|
||||
|
||||
Called by scripts/screenshots.mjs; not useful on its own.
|
||||
|
||||
python3 scripts/screenshots-encode.py <raw-png-dir> <out-dir>
|
||||
|
||||
The captures are taken at 2x (desktop) and 3x (mobile) so text is sampled
|
||||
cleanly, then halved here. Halving rather than keeping the full capture is
|
||||
deliberate: a README renders images at roughly 850px wide, so a 2880px-wide PNG
|
||||
buys nothing but repository weight. WebP at q86 takes the forty-image set from
|
||||
about 16MB to under 2MB.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import pathlib
|
||||
import sys
|
||||
|
||||
from PIL import Image
|
||||
|
||||
QUALITY = 86
|
||||
|
||||
|
||||
def main() -> int:
|
||||
if len(sys.argv) != 3:
|
||||
print(__doc__, file=sys.stderr)
|
||||
return 2
|
||||
|
||||
src = pathlib.Path(sys.argv[1])
|
||||
dst = pathlib.Path(sys.argv[2])
|
||||
dst.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
captures = sorted(src.glob("*.png"))
|
||||
if not captures:
|
||||
print(f"no PNG captures in {src}", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
before = after = 0
|
||||
for png in captures:
|
||||
image = Image.open(png).convert("RGB")
|
||||
image = image.resize((image.width // 2, image.height // 2), Image.LANCZOS)
|
||||
out = dst / f"{png.stem}.webp"
|
||||
image.save(out, "WEBP", quality=QUALITY, method=6)
|
||||
before += png.stat().st_size
|
||||
after += out.stat().st_size
|
||||
|
||||
print(f"encoded {len(captures)} images: {before / 1e6:.1f}MB PNG -> {after / 1e6:.1f}MB WebP")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Reference in New Issue
Block a user