Skip to content

feat: add --json-out flag to write JSON reports to files#947

Merged
rayhanadev merged 4 commits into
mainfrom
cursor/triage-946-08f2
Jun 25, 2026
Merged

feat: add --json-out flag to write JSON reports to files#947
rayhanadev merged 4 commits into
mainfrom
cursor/triage-946-08f2

Conversation

@skoshx

@skoshx skoshx commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Product brief: --json-out flag

Job: 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 --json is active (following ESLint's --output-file and Jest's --outputFile pattern).

Reuse: Searched for existing file output patterns - --output-dir exists but writes diagnostics dumps (per-rule text files), not the structured JSON report. This is complementary.

Metric: METRIC.jsonOutUsed counter to track adoption; kill if <1% of --json invocations 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.01 after 3 releases.

Implementation

  • Added --json-out <path> CLI flag
  • Updated json-mode.ts to support writing to files (creates parent directories automatically)
  • Added telemetry metric json.out_used
  • Added unit tests for file writing functionality
  • Added e2e tests for the full CLI flow

Testing

  • ✅ Unit tests pass (json-mode.test.ts)
  • ✅ E2e tests pass (json-out-flag.test.ts)
  • ✅ Typecheck passes
  • ✅ Lint passes
  • ✅ Parity: N/A (pure UX feature, no diagnostic logic changes)

Examples

# Write JSON to file
npx react-doctor --json --json-out report.json

# With nested directories (creates them automatically)
npx react-doctor --json --json-out reports/ci/report.json

# Compact JSON to file
npx react-doctor --json --json-compact --json-out report.json

# Traditional stdout still works
npx react-doctor --json > report.json

Closes #946

Open in Web Open in Cursor 

Co-authored-by: Skosh <skoshx@users.noreply.github.com>
@pkg-pr-new

pkg-pr-new Bot commented Jun 23, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/eslint-plugin-react-doctor@947
npm i https://pkg.pr.new/oxlint-plugin-react-doctor@947
npm i https://pkg.pr.new/react-doctor@947

commit: 3910e06

cursoragent and others added 3 commits June 23, 2026 05:51
…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>
@rayhanadev rayhanadev marked this pull request as ready for review June 25, 2026 17:31
@rayhanadev rayhanadev merged commit 05cafc6 into main Jun 25, 2026
25 of 26 checks passed

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ 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`);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 3910e06. Configure here.

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 2 potential issues.

Open in Devin Review

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 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)

Open in Devin Review

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-"));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 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.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature Request: Add --json-out / --output option for saving JSON reports

3 participants