fix(screenshot): validate images before saving capture proof - #70
Conversation
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
🟡 Changes recommended
The bundled jpeg-js patch file includes a malformed context line that can make the patch application brittle across install environments.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR hardens rokit screenshot capture by bounding downloaded image bytes, validating JPEG/PNG structure and decode integrity before saving, and ensuring npm-installed consumers receive consistent strict JPEG behavior via a bundled patched decoder.
Changes:
- Add bounded response-body reading and apply a 64 MiB cap to screenshot image downloads before validation.
- Introduce JPEG/PNG integrity validation (PNG CRC/pixel format/dimension checks; JPEG segment/restart/EOI checks + strict decode limits).
- Bundle a patched
jpeg-jsinto the packaged CLI output and document third-party/license + distribution implications.
File summaries
| File | Description |
|---|---|
| vite.config.ts | Bundles jpeg-js so installed npm consumers get the patched decoder behavior. |
| src/response-body.ts | Adds byte-budget support when reading response bodies. |
| src/screenshot.ts | Enforces screenshot byte cap and validates image integrity before writing proof artifacts. |
| src/screenshot-image.ts | Implements PNG/JPEG structural validation plus strict decoding limits. |
| test/response-body.test.ts | Adds regression coverage for stream cancellation when exceeding the byte budget. |
| test/screenshot-image.test.ts | Adds comprehensive validation coverage for supported/unsupported PNG formats and malformed JPEG/PNG cases. |
| test/fixtures/images.ts | Adds synthetic JPEG/PNG fixtures for validation and capture tests. |
| test/roku-capture.test.ts | Extends capture tests to cover jpg/png success and invalid (HTML) “image” retries without artifacts. |
| patches/jpeg-js@0.4.4.patch | Bundles strict-decoding behavioral changes into the pinned JPEG decoder. |
| pnpm-workspace.yaml | Registers the jpeg-js@0.4.4 patch for pnpm-based development builds. |
| pnpm-lock.yaml | Locks pngjs, jpeg-js, and patched dependency metadata for reproducible installs. |
| package.json | Adds runtime PNG decoder dependency and dev-only pinned jpeg-js for build/test. |
| README.md | Documents screenshot validation behavior and the concrete size/pixel limits. |
| skills/rokit/SKILL.md | Updates agent-facing guidance about screenshot failure modes and validation. |
| docs/DISTRIBUTION.md | Documents why bundling the patched decoder is required for ordinary npm consumers. |
| docs/THIRD-PARTY-NOTICES.md | Adds notices covering bundled third-party code and the local decoder modification. |
Review details
Files not reviewed (1)
- pnpm-lock.yaml: Generated file
- Files reviewed: 15/16 changed files
- Comments generated: 1
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
## [2.4.7](v2.4.6...v2.4.7) (2026-09-05) ### Bug Fixes * **screenshot:** validate images before saving capture proof ([#70](#70)) ([4dae889](4dae889))
|
🎉 This PR is included in version 2.4.7 🎉 The release is available on: Your semantic-release bot 📦🚀 |
Summary
Screenshot capture rejects non-image responses and detected JPEG/PNG framing or decoding errors before saving successful proof. Original bytes, existing paths, retries and cleanup are preserved.
Changed
Bound downloaded image data and decoding, validate PNG checksums and pixel formats, and reject incomplete JPEG scans. Bundle a small patch to the pinned JPEG decoder so valid final partial restart intervals decode and ordinary npm consumers receive the same strict behavior.
Risks
The JPEG patch must remain bundled until an upstream version passes its regression and installed-package checks. Captures support UHD/DCI 4K within documented byte, pixel and decoder limits; PNG axes are capped to bound per-scanline allocations. Validation detects structural errors and does not establish visual correctness.
Verification
The final repository gate passed 165 tests plus formatting, lint, types, skill checks, build, coverage and package dry-run. Regression checks reproduced the malformed-image failures before their fixes. Fresh ordinary npm installs passed genuine UHD JPEG/PNG and restart-interval controls, 15 legal PNG formats, malformed-image rejection, original-byte/path preservation, two-attempt retry, cleanup and installed CLI output. Installed capture validation also preserved all 19 archived device-generated 1280×720 JPEGs; no product fixtures were added here.
Whole-branch slopguard review with Codex Astra medium is clean at
5b6133dagainstba39780. The incomplete-scan and valid-partial-interval findings are fixed. The later claim that trailing PNG chunks were accepted was rejected after reproduction confirmed the pinned decoder already rejects them.Follow-Ups
Live capture on connected Roku hardware was not run. Archived-device-byte compatibility and installed capture behavior were exercised with controlled transport; the repository's distribution contract treats live device checks as manual follow-up, not an npm release gate.