[PR #1397] [MERGED] fix(cli): accept JSON files for web capture and screenshot comparisons #2854

Closed
opened 2026-10-17 21:11:02 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/1397
Author: @kaoru0822-kitauji
Created: 10/10/2026
Status: ✅ Merged
Merged: 10/10/2026
Merged by: @kaoru0822-kitauji

Base: main ← Head: fix/compare-web-json-file-inputs


📝 Commits (1)

  • 006f73e fix(cli): accept JSON files for web capture and screenshot comparisons

📊 Changes

6 files changed (+238 additions, -95 deletions)

View changed files

📝 docs/browser-observation.md (+1 -0)
📝 src/cli/browserAdvancedCommands.ts (+78 -36)
📝 tests/boundary/cli/browserCli.test.ts (+1 -31)
➕ tests/boundary/cli/browserCompareJsonFiles.test.ts (+125 -0)
📝 tests/boundary/cli/browserRedirectShapeCompleteness.test.ts (+1 -28)
➕ tests/fixtures/cliJsonProcess.ts (+32 -0)

📄 Description

Problem

Every other CLI command that takes JSON (capture-browser-scenario, inspect-analysis-view, trace-application-feature, …) goes through parseCliJsonInput, which accepts inline JSON or a JSON file path. compare-web-captures and compare-web-screenshots parsed their arguments as inline JSON only.

These two inputs are the ones that cannot practically be passed inline. A screenshot artifact embeds the base64 PNG, and a scenario capture embeds screenshots. A 1280×720 viewport of an image-heavy page is easily over 1 MiB of JSON. That exceeds the command-line length limit (one argument may hold 128 KiB on Linux; macOS allows 1 MiB for all arguments), so the CLI cannot compare it at all, although MCP compare_web_screenshots accepts the same artifact:

$ rea compare-web-screenshots "$(cat before.json)" "$(cat after.json)"   # 1.86 MB artifact
zsh: argument list too long: node

$ rea compare-web-screenshots before.json after.json --format json
{ "error": "Browser observation failed", "code": "invalid_request",
  "message": "Analysis input is invalid. Check the arguments and try again." }   # no details at all

$ rea compare-web-captures missing.json missing.json --format json
… "issues": [{ "path": ["before"], "reason": "invalid_format", "expected": "JSON" }]   # a missing file reported as malformed JSON

compare-web-screenshots also discarded the schema issues, so a digest/size mismatch or a bad field produced an invalid_request with no details.

Change

src/cli/browserAdvancedCommands.ts:

  • Each argument (beforeJson, afterJson, --normalization-json) is read through parseCliJsonInput. Inline JSON behaves as before. A file path is read as a strict UTF-8 JSON file, including the streaming path for large files.
  • File failures (missing, not a regular file, unreadable, invalid JSON in a file) return parseCliJsonInput's diagnostics with input_path and input_reason, as the other JSON-input commands do.
  • Malformed inline JSON keeps the existing field-specific invalid_format issue (["before"], ["after"], ["normalization"]), which browserCli.test.ts already pins.
  • compare-web-screenshots schema failures now report projected issues, for example { path: ["before"], message: "Screenshot artifact digest or size mismatch" }.
  • Argument descriptions say "JSON or JSON file path". docs/browser-observation.md documents it.

No MCP or schema change.

Tests

New tests/boundary/cli/browserCompareJsonFiles.test.ts (all three fail on main):

  • two >1 MiB screenshot artifacts (generated 640×640 noise PNG) compared from files → identical, 0 changed pixels;
  • a size-mismatched artifact file → invalid_request with the ["before"] issue;
  • a missing capture file → invalid_value "(ENOENT): " with input_path, not invalid_format.

The identical runCli helper in browserCli.test.ts and browserRedirectShapeCompleteness.test.ts moved into tests/fixtures/cliJsonProcess.ts, so the new test adds no clone. jscpd is 2.445% (main 2.462%).

Verification:

  • npm run test:focused -- tests/boundary/cli/browserCompareJsonFiles.test.ts tests/boundary/cli/browserCli.test.ts tests/boundary/cli/browserRedirectShapeCompleteness.test.ts tests/boundary/cli/cliInputSchemaRequired.test.ts tests/boundary/filesystem/cliJsonInput.test.ts tests/boundary/filesystem/jsonUtf8Input.test.ts
  • npm run check:fast, npm run docs:check, npm run format:check
  • Real browser: captured a viewport screenshot from headless Brave (capture-web-screenshot over CDP), wrote its artifact and a 1.86 MB artifact to files, and compared them with rea compare-web-screenshots before.json after.json. Result: a pixel comparison (1280×720 vs 1280×583). Inline, the same comparison fails with "argument list too long".

No Hopper/Ghidra verification needed.

🤖 Generated with Claude Code


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/morluto/rea/pull/1397 **Author:** [@kaoru0822-kitauji](https://github.com/kaoru0822-kitauji) **Created:** 10/10/2026 **Status:** ✅ Merged **Merged:** 10/10/2026 **Merged by:** [@kaoru0822-kitauji](https://github.com/kaoru0822-kitauji) **Base:** `main` ← **Head:** `fix/compare-web-json-file-inputs` --- ### 📝 Commits (1) - [`006f73e`](https://github.com/morluto/rea/commit/006f73ef99ef8f68a59c61935aae2fe262d3049a) fix(cli): accept JSON files for web capture and screenshot comparisons ### 📊 Changes **6 files changed** (+238 additions, -95 deletions) <details> <summary>View changed files</summary> 📝 `docs/browser-observation.md` (+1 -0) 📝 `src/cli/browserAdvancedCommands.ts` (+78 -36) 📝 `tests/boundary/cli/browserCli.test.ts` (+1 -31) ➕ `tests/boundary/cli/browserCompareJsonFiles.test.ts` (+125 -0) 📝 `tests/boundary/cli/browserRedirectShapeCompleteness.test.ts` (+1 -28) ➕ `tests/fixtures/cliJsonProcess.ts` (+32 -0) </details> ### 📄 Description ## Problem Every other CLI command that takes JSON (`capture-browser-scenario`, `inspect-analysis-view`, `trace-application-feature`, …) goes through `parseCliJsonInput`, which accepts **inline JSON or a JSON file path**. `compare-web-captures` and `compare-web-screenshots` parsed their arguments as inline JSON only. These two inputs are the ones that cannot practically be passed inline. A screenshot artifact embeds the base64 PNG, and a scenario capture embeds screenshots. A 1280×720 viewport of an image-heavy page is easily over 1 MiB of JSON. That exceeds the command-line length limit (one argument may hold 128 KiB on Linux; macOS allows 1 MiB for all arguments), so the CLI cannot compare it at all, although MCP `compare_web_screenshots` accepts the same artifact: ``` $ rea compare-web-screenshots "$(cat before.json)" "$(cat after.json)" # 1.86 MB artifact zsh: argument list too long: node $ rea compare-web-screenshots before.json after.json --format json { "error": "Browser observation failed", "code": "invalid_request", "message": "Analysis input is invalid. Check the arguments and try again." } # no details at all $ rea compare-web-captures missing.json missing.json --format json … "issues": [{ "path": ["before"], "reason": "invalid_format", "expected": "JSON" }] # a missing file reported as malformed JSON ``` `compare-web-screenshots` also discarded the schema issues, so a digest/size mismatch or a bad field produced an `invalid_request` with no `details`. ## Change `src/cli/browserAdvancedCommands.ts`: - Each argument (`beforeJson`, `afterJson`, `--normalization-json`) is read through `parseCliJsonInput`. Inline JSON behaves as before. A file path is read as a strict UTF-8 JSON file, including the streaming path for large files. - File failures (missing, not a regular file, unreadable, invalid JSON in a file) return `parseCliJsonInput`'s diagnostics with `input_path` and `input_reason`, as the other JSON-input commands do. - Malformed **inline** JSON keeps the existing field-specific `invalid_format` issue (`["before"]`, `["after"]`, `["normalization"]`), which `browserCli.test.ts` already pins. - `compare-web-screenshots` schema failures now report projected issues, for example `{ path: ["before"], message: "Screenshot artifact digest or size mismatch" }`. - Argument descriptions say "JSON or JSON file path". `docs/browser-observation.md` documents it. No MCP or schema change. ## Tests New `tests/boundary/cli/browserCompareJsonFiles.test.ts` (all three fail on `main`): - two >1 MiB screenshot artifacts (generated 640×640 noise PNG) compared from files → `identical`, 0 changed pixels; - a size-mismatched artifact file → `invalid_request` with the `["before"]` issue; - a missing capture file → `invalid_value` "(ENOENT): <path>" with `input_path`, not `invalid_format`. The identical `runCli` helper in `browserCli.test.ts` and `browserRedirectShapeCompleteness.test.ts` moved into `tests/fixtures/cliJsonProcess.ts`, so the new test adds no clone. jscpd is 2.445% (main 2.462%). Verification: - `npm run test:focused -- tests/boundary/cli/browserCompareJsonFiles.test.ts tests/boundary/cli/browserCli.test.ts tests/boundary/cli/browserRedirectShapeCompleteness.test.ts tests/boundary/cli/cliInputSchemaRequired.test.ts tests/boundary/filesystem/cliJsonInput.test.ts tests/boundary/filesystem/jsonUtf8Input.test.ts` - `npm run check:fast`, `npm run docs:check`, `npm run format:check` - Real browser: captured a viewport screenshot from headless Brave (`capture-web-screenshot` over CDP), wrote its artifact and a 1.86 MB artifact to files, and compared them with `rea compare-web-screenshots before.json after.json`. Result: a pixel comparison (1280×720 vs 1280×583). Inline, the same comparison fails with "argument list too long". No Hopper/Ghidra verification needed. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-17 21:11:02 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#2854
No description provided.