Skip to content

Downscale display images and add visible captions to the Visual preview table #6324

Description

@JSONbored

Problem

Before/after screenshots embedded in the "Visual preview" table are full-page, native-resolution PNGs (up to 10,000px tall / 14.4M pixels / 5MB, per shot.ts's own caps) with NO server-side resizing before storage or embedding. The comment markup (unified-comment-bridge.ts) then displays them with only <img width="360" ...> — no height, no actual resize — so every viewer's browser downloads the full-resolution file (potentially multiple MB) just to render a 360px-wide thumbnail.

The only downscale seam in the codebase (image-downscale.ts) exists purely to shrink an image before an AI vision-model call — it never touches the copy that gets stored in R2/S3 and embedded for human viewers, and even that seam is a no-op passthrough in the hosted Cloudflare Worker path (only active in self-host builds via the esbuild swap).

Separately, the table doesn't match the contributor-facing screenshot contract this same bot enforces on PR authors (see e.g. .claude/skills/metagraphed/SKILL.md Phase B2 in JSONbored/metagraphed, and the equivalent contracts in other gate repos): "each image is a clickable thumbnail... with a one-line caption underneath." ORB's own table has only an invisible alt attribute (before /, after / (mobile), etc.) — no visible caption line naming the route/viewport under each thumbnail.

Area

src/review/visual/shot.ts (capture/storage), src/review/visual/image-downscale.ts (the existing but vision-only downscale seam), src/review/unified-comment-bridge.ts (table markup, width="360" hardcode).

Proposal

  • Add a real display-image downscale/re-encode step between capture and storage (or between storage and embed) that produces a reasonably-sized thumbnail-appropriate copy — not necessarily replacing the full-res original (which is still useful behind the "click to open full-size" link), but the copy actually EMBEDDED at width="360" should be a real ~360-720px-wide encode, not the raw capture. Consider whether this needs its OWN storage key (e.g. a -thumb.png sibling) alongside the existing full-res key so the "click for full-size" behavior is preserved.
  • Add a visible one-line caption under each thumbnail in the markup unified-comment-bridge.ts builds — route + viewport (+ theme, when configured) is already computed for the alt text; render it as visible text too, not just the hidden attribute.
  • Confirm the image-downscale.ts seam's hosted-mode no-op is intentional for the VISION use case (it may well be — Browser Rendering wall-clock is the binding constraint there) but make sure the NEW display-resize step doesn't inherit that same "no-op in hosted mode" limitation, since hosted mode is exactly where this matters most (that's where PUBLIC_API_ORIGIN-served/S3-served images reach real GitHub viewers).

Deliverables

  • The image embedded at width="360" in the Visual preview table is a real downscaled encode, not the raw full-page capture — meaningfully smaller in bytes for a typical route
  • The "click to open full-size" link still resolves to the original full-resolution capture
  • A visible one-line caption (route + viewport, + theme/diff label where applicable) appears under each thumbnail, matching the contributor screenshot contract's own "clickable thumbnail with a one-line caption underneath" shape
  • Tests covering: the new resize step's dimensions/byte-size bounds, the caption text for desktop/mobile/theme/diff cells, and that the full-size link is unaffected
  • Works in BOTH hosted (Cloudflare Worker) and self-host modes — no silent hosted-mode no-op like the existing vision seam has

Resources

  • src/review/visual/shot.ts — capture + MAX_SCREENSHOT_* caps
  • src/review/visual/image-downscale.ts — existing vision-only downscale seam (precedent for the hosted/self-host swap mechanism, scripts/build-selfhost.mjs's esbuild plugin)
  • src/review/unified-comment-bridge.ts — table markup (width="360" hardcode, missing caption)
  • .claude/skills/metagraphed/SKILL.md (JSONbored/metagraphed) — the contributor screenshot contract this table should match the shape of

Boundaries

Scope is the IMAGE pipeline and table markup only — not whether/when capture fires (isVisualPath) or the retry budget. Maintainer-only — assigned JSONbored.

Metadata

Metadata

Assignees

Labels

maintainer-onlyOwner-only work — yields no Gittensor points.

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions