From 798777156a2fb3c9d7cff22cd5e1611db7ddbb8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20Miko=C5=82ajczak?= Date: Thu, 12 Mar 2026 13:16:30 +0100 Subject: [PATCH 1/3] Replace npx healthcheck with npm compliance script in reviewer --- .claude/commands/review-code-pr.md | 2 +- .../skills/coding-standards/rules/clean-react-0-compiler.md | 6 ++++-- .github/workflows/claude-review.yml | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.claude/commands/review-code-pr.md b/.claude/commands/review-code-pr.md index f2cf709276083..3b07f69fbe812 100644 --- a/.claude/commands/review-code-pr.md +++ b/.claude/commands/review-code-pr.md @@ -1,5 +1,5 @@ --- -allowed-tools: Bash(gh pr diff:*),Bash(gh pr view:*) +allowed-tools: Bash(gh pr diff:*),Bash(gh pr view:*),Bash(npm run react-compiler-compliance-check:*) description: Review a code contribution pull request --- diff --git a/.claude/skills/coding-standards/rules/clean-react-0-compiler.md b/.claude/skills/coding-standards/rules/clean-react-0-compiler.md index af697f1499458..51d89d454682e 100644 --- a/.claude/skills/coding-standards/rules/clean-react-0-compiler.md +++ b/.claude/skills/coding-standards/rules/clean-react-0-compiler.md @@ -98,10 +98,12 @@ function Avatar({source, size}: AvatarProps) { Before flagging, verify that the file actually compiles with React Compiler: ```bash -npx react-compiler-healthcheck --src "" --verbose +npm run react-compiler-compliance-check check ``` -If the output contains **"Failed to compile"** for the file under review, the rule **does not apply** — the author may have no alternative to manual memoization until the compilation issue is resolved. +Parse the output as follows: +- If the file appears under **"Failed to compile"** in the output, the file does **not** compile with React Compiler - the rule **does not apply**. The author may have no alternative to manual memoization until the compilation issue is resolved. +- If the file does **not** appear under "Failed to compile" (or the output shows only successes), the file compiles successfully - proceed to flag manual memoization as redundant. #### Condition diff --git a/.github/workflows/claude-review.yml b/.github/workflows/claude-review.yml index 98578ba2bc78c..3edcdc2c86947 100644 --- a/.github/workflows/claude-review.yml +++ b/.github/workflows/claude-review.yml @@ -74,7 +74,7 @@ jobs: prompt: "/review-code-pr REPO: ${{ github.repository }} PR_NUMBER: ${{ github.event.pull_request.number }}" claude_args: | --model claude-opus-4-6 - --allowedTools "Task,Glob,Grep,Read,Bash(gh pr diff:*),Bash(gh pr view:*)" --json-schema '${{ steps.schema.outputs.json }}' + --allowedTools "Task,Glob,Grep,Read,Bash(gh pr diff:*),Bash(gh pr view:*),Bash(npm run react-compiler-compliance-check:*)" --json-schema '${{ steps.schema.outputs.json }}' - name: Post code review results if: steps.code-review.outcome == 'success' && steps.filter.outputs.code == 'true' From f4853b15dcf20ff04339d4ba1e310cc64c237888 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20Miko=C5=82ajczak?= Date: Thu, 12 Mar 2026 13:31:51 +0100 Subject: [PATCH 2/3] Revert verbose parsing instructions, keep original wording Only the command changes from npx to npm run; the single-line parsing instruction was already clear enough for the reviewer agent. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../skills/coding-standards/rules/clean-react-0-compiler.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.claude/skills/coding-standards/rules/clean-react-0-compiler.md b/.claude/skills/coding-standards/rules/clean-react-0-compiler.md index 51d89d454682e..64b2d25068400 100644 --- a/.claude/skills/coding-standards/rules/clean-react-0-compiler.md +++ b/.claude/skills/coding-standards/rules/clean-react-0-compiler.md @@ -101,9 +101,7 @@ Before flagging, verify that the file actually compiles with React Compiler: npm run react-compiler-compliance-check check ``` -Parse the output as follows: -- If the file appears under **"Failed to compile"** in the output, the file does **not** compile with React Compiler - the rule **does not apply**. The author may have no alternative to manual memoization until the compilation issue is resolved. -- If the file does **not** appear under "Failed to compile" (or the output shows only successes), the file compiles successfully - proceed to flag manual memoization as redundant. +If the output contains **"Failed to compile"** for the file under review, the rule **does not apply** — the author may have no alternative to manual memoization until the compilation issue is resolved. #### Condition From 37b22abef3b418a0024617ed0f7f2f9cf992c586 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20Miko=C5=82ajczak?= Date: Mon, 16 Mar 2026 10:22:40 +0100 Subject: [PATCH 3/3] Use secure wrapper script instead of direct npm run Add check-compiler.sh that validates filepaths with a strict allowlist regex before calling the compliance script. This follows the same pattern as other reviewer proxy scripts (addPrReaction.sh, createInlineComment.sh). Reverts the execFileSync change since input validation at the boundary is sufficient. Co-Authored-By: Claude Opus 4.6 (1M context) --- .claude/commands/review-code-pr.md | 2 +- .claude/scripts/check-compiler.sh | 20 +++++++++++++++++++ .../rules/clean-react-0-compiler.md | 2 +- .github/workflows/claude-review.yml | 2 +- 4 files changed, 23 insertions(+), 3 deletions(-) create mode 100755 .claude/scripts/check-compiler.sh diff --git a/.claude/commands/review-code-pr.md b/.claude/commands/review-code-pr.md index 3b07f69fbe812..6e4364d4518b3 100644 --- a/.claude/commands/review-code-pr.md +++ b/.claude/commands/review-code-pr.md @@ -1,5 +1,5 @@ --- -allowed-tools: Bash(gh pr diff:*),Bash(gh pr view:*),Bash(npm run react-compiler-compliance-check:*) +allowed-tools: Bash(gh pr diff:*),Bash(gh pr view:*),Bash(check-compiler.sh:*) description: Review a code contribution pull request --- diff --git a/.claude/scripts/check-compiler.sh b/.claude/scripts/check-compiler.sh new file mode 100755 index 0000000000000..a1279c942bcac --- /dev/null +++ b/.claude/scripts/check-compiler.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +# Secure proxy script to run React Compiler compliance check on a single file. +# Validates the filepath before passing it to the underlying npm script. +set -eu + +if [[ $# -lt 1 ]]; then + echo "Usage: $0 " >&2 + exit 1 +fi + +readonly FILEPATH="$1" + +# Strict filepath validation - reject shell metacharacters +if ! [[ "$FILEPATH" =~ ^[a-zA-Z0-9_./@-]+$ ]]; then + echo "Error: Invalid filepath (contains disallowed characters)" >&2 + exit 1 +fi + +npm run react-compiler-compliance-check -- check "$FILEPATH" diff --git a/.claude/skills/coding-standards/rules/clean-react-0-compiler.md b/.claude/skills/coding-standards/rules/clean-react-0-compiler.md index 64b2d25068400..c2a5283346b94 100644 --- a/.claude/skills/coding-standards/rules/clean-react-0-compiler.md +++ b/.claude/skills/coding-standards/rules/clean-react-0-compiler.md @@ -98,7 +98,7 @@ function Avatar({source, size}: AvatarProps) { Before flagging, verify that the file actually compiles with React Compiler: ```bash -npm run react-compiler-compliance-check check +check-compiler.sh ``` If the output contains **"Failed to compile"** for the file under review, the rule **does not apply** — the author may have no alternative to manual memoization until the compilation issue is resolved. diff --git a/.github/workflows/claude-review.yml b/.github/workflows/claude-review.yml index 3edcdc2c86947..89d2256ec0a65 100644 --- a/.github/workflows/claude-review.yml +++ b/.github/workflows/claude-review.yml @@ -74,7 +74,7 @@ jobs: prompt: "/review-code-pr REPO: ${{ github.repository }} PR_NUMBER: ${{ github.event.pull_request.number }}" claude_args: | --model claude-opus-4-6 - --allowedTools "Task,Glob,Grep,Read,Bash(gh pr diff:*),Bash(gh pr view:*),Bash(npm run react-compiler-compliance-check:*)" --json-schema '${{ steps.schema.outputs.json }}' + --allowedTools "Task,Glob,Grep,Read,Bash(gh pr diff:*),Bash(gh pr view:*),Bash(check-compiler.sh:*)" --json-schema '${{ steps.schema.outputs.json }}' - name: Post code review results if: steps.code-review.outcome == 'success' && steps.filter.outputs.code == 'true'