feat: add --json-out flag to write JSON reports to files#947
Conversation
Co-authored-by: Skosh <skoshx@users.noreply.github.com>
commit: |
…test stderr capture Co-authored-by: Skosh <skoshx@users.noreply.github.com>
Co-authored-by: Skosh <skoshx@users.noreply.github.com>
Deslop pass on #947: - e2e suite kept to the single case that exercises the real CLI flag-parse + strip-unknown-cli-flags wiring; the other three are unit-covered/pre-existing. - json-mode.test.ts: drop the stdout / compact re-tests already covered by the pre-existing suite. - inspect.ts: move the json.out_used metric inside the JSON-mode guard so `--json-out` without `--json` (a no-op) no longer inflates adoption. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 3910e06. Configure here.
| fs.writeFileSync(resolvedPath, `${serialized}\n`); | ||
| } else { | ||
| process.stdout.write(`${serialized}\n`); | ||
| } |
There was a problem hiding this comment.
Error fallback ignores json-out
Medium Severity
When --json-out is active, successful JSON reports go to the configured file, but the internal-error fallback in writeJsonErrorReport still writes only to stdout. CI jobs that expect an empty stdout and a file artifact can miss the error report on disk and see unexpected JSON on stdout instead.
Reviewed by Cursor Bugbot for commit 3910e06. Configure here.
There was a problem hiding this comment.
🔴 Last-resort error fallback writes to stdout instead of the specified output file
The internal error fallback is always written to stdout (process.stdout.write at packages/react-doctor/src/cli/utils/json-mode.ts:102) even when --json-out directs reports to a file, so downstream consumers reading the file see no report at all.
Impact: When error-report serialization itself fails under --json-out, CI pipelines reading the output file get no report while the fallback JSON silently goes to unmonitored stdout.
Trigger: buildJsonReportError throws while outputFile is configured
The writeJsonErrorReport function at packages/react-doctor/src/cli/utils/json-mode.ts:88-103 has a try/catch. The try block calls writeJsonReport() which correctly routes to the file when context.outputFile is set (packages/react-doctor/src/cli/utils/json-mode.ts:79-82). But the catch block at line 102 hardcodes process.stdout.write(INTERNAL_ERROR_JSON_FALLBACK), bypassing the file output path entirely. This catch fires when buildJsonReportError itself throws (e.g. due to a property accessor that throws, as tested in the existing "exploding proxy" test case at packages/react-doctor/tests/json-mode.test.ts:137-160).
The fix should mirror the writeJsonReport logic: check context?.outputFile and write the fallback to the file when set, falling back to stdout otherwise.
(Refers to line 102)
Was this helpful? React with 👍 or 👎 to provide feedback.
| }); | ||
|
|
||
| it("writeJsonReport writes to a file when outputFile is provided", () => { | ||
| const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "json-mode-test-")); |
There was a problem hiding this comment.
🟡 Shortened variable name violates repository naming convention
A temporary-directory variable uses the shorthand tempDir (packages/react-doctor/tests/json-mode.test.ts:163) instead of the full tempDirectory used everywhere else in the codebase, violating the repository rule against shorthands.
Impact: Inconsistent naming reduces readability; the codebase consistently uses tempDirectory (e.g. packages/react-doctor/tests/scan-result-cache.test.ts:16, packages/react-doctor/src/cli/commands/inspect.ts:340).
AGENTS.md rule: avoid shorthands in variable names
AGENTS.md states: "MUST: Use descriptive names for variables (avoid shorthands, or 1-2 character names)." The variable tempDir appears at lines 163, 174, 178, and 187 of packages/react-doctor/tests/json-mode.test.ts. Every other instance in the codebase uses the unabbreviated tempDirectory.
Prompt for agents
In packages/react-doctor/tests/json-mode.test.ts, the variable tempDir is used at lines 163, 174, 178, and 187. Per the AGENTS.md rule requiring descriptive names (no shorthands), rename all occurrences of tempDir to tempDirectory to match the codebase convention seen in packages/react-doctor/tests/scan-result-cache.test.ts and packages/react-doctor/src/cli/commands/inspect.ts.
Was this helpful? React with 👍 or 👎 to provide feedback.


Product brief:
--json-outflagJob: Developers integrating React Doctor into CI/CD pipelines need to save JSON reports as artifacts for storage, automated processing, and multi-format output. Currently they must use shell redirection (
> report.json), which is platform-specific (differs between bash/PowerShell/cmd), less discoverable, and error-prone in scripts.Change: Add
--json-out <path>flag that writes the JSON report to the specified file when--jsonis active (following ESLint's--output-fileand Jest's--outputFilepattern).Reuse: Searched for existing file output patterns -
--output-direxists but writes diagnostics dumps (per-rule text files), not the structured JSON report. This is complementary.Metric:
METRIC.jsonOutUsedcounter to track adoption; kill if <1% of--jsoninvocations after 3 releases.Compat: Patch changeset (
.changeset/json-out-flag.md); no schema changes; opt-in behavior (no default).Kill: Remove if
jsonOutUsed / jsonMode < 0.01after 3 releases.Implementation
--json-out <path>CLI flagjson-mode.tsto support writing to files (creates parent directories automatically)json.out_usedTesting
Examples
Closes #946