feat(review): add Java and C/C++ support for deterministic analysis

Step 3 now supports:
- Java: mvn compile, checkstyle, spotbugs, pmd (Maven);
  gradle compileJava, checkstyleMain (Gradle)
- C/C++: clang-tidy (when compile_commands.json available)

Agent 5 build/test precedence now includes Maven and Gradle
before Makefile to avoid duplicate builds.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
wenshao 2026-04-07 07:19:56 +08:00
parent b2ec7b068e
commit cbf2aa06ac
2 changed files with 22 additions and 6 deletions

View file

@ -60,12 +60,14 @@ All agents run in parallel. All findings are then verified in a **single batch v
Before the LLM agents run, `/review` automatically runs your project's existing linters and type checkers: Before the LLM agents run, `/review` automatically runs your project's existing linters and type checkers:
| Language | Tools detected | | Language | Tools detected |
| --------------------- | ---------------------------------------- | | --------------------- | --------------------------------------------------- |
| TypeScript/JavaScript | `tsc --noEmit`, `npm run lint`, `eslint` | | TypeScript/JavaScript | `tsc --noEmit`, `npm run lint`, `eslint` |
| Python | `ruff`, `mypy`, `flake8` | | Python | `ruff`, `mypy`, `flake8` |
| Rust | `cargo clippy` | | Rust | `cargo clippy` |
| Go | `go vet`, `golangci-lint` | | Go | `go vet`, `golangci-lint` |
| Java | `mvn compile`, `checkstyle`, `spotbugs`, `pmd` |
| C/C++ | `clang-tidy` (if `compile_commands.json` available) |
Deterministic findings are tagged with `[linter]` or `[typecheck]` and skip LLM verification — they are ground truth. Deterministic findings are tagged with `[linter]` or `[typecheck]` and skip LLM verification — they are ground truth.

View file

@ -105,6 +105,16 @@ Extract the list of changed files from the diff output. For local uncommitted re
4. **Go projects**: 4. **Go projects**:
- If `go.mod` exists → `go vet ./... 2>&1` (vet includes compile checks, so Agent 5 can skip `go build` if vet ran successfully) and `golangci-lint run ./... 2>&1` (golangci-lint expects package patterns, not individual file paths; filter diagnostics to changed files after capture) - If `go.mod` exists → `go vet ./... 2>&1` (vet includes compile checks, so Agent 5 can skip `go build` if vet ran successfully) and `golangci-lint run ./... 2>&1` (golangci-lint expects package patterns, not individual file paths; filter diagnostics to changed files after capture)
5. **Java projects**:
- If `pom.xml` exists (Maven) → `mvn compile -q 2>&1` (compilation check; Agent 5 can skip build if this succeeds). If `checkstyle` plugin is configured → `mvn checkstyle:check -q 2>&1`
- Else if `build.gradle` or `build.gradle.kts` exists (Gradle) → `gradle compileJava -q 2>&1`. If `checkstyle` plugin is configured → `gradle checkstyleMain -q 2>&1`
- Else if `Makefile` exists (e.g., OpenJDK) → skip deterministic analysis for Java (build system is too project-specific; Agent 5 will handle build/test)
- If `spotbugs` or `pmd` is available → `mvn spotbugs:check -q 2>&1` or `mvn pmd:check -q 2>&1`
6. **C/C++ projects**:
- If `CMakeLists.txt` or `Makefile` exists → skip per-file linting (C/C++ linters like clang-tidy require full build context). Agent 5 will handle build verification.
- If `compile_commands.json` exists and `clang-tidy` is available → `clang-tidy <changed-files> 2>&1`
**Important**: For whole-project tools (`tsc`, `npm run lint`, `cargo clippy`, `go vet`), capture the full output first, then filter to only errors/warnings in changed files, then truncate to the first 200 lines. Do NOT pipe to `head` before filtering — this can drop relevant errors for changed files that appear later in the output. **Important**: For whole-project tools (`tsc`, `npm run lint`, `cargo clippy`, `go vet`), capture the full output first, then filter to only errors/warnings in changed files, then truncate to the first 200 lines. Do NOT pipe to `head` before filtering — this can drop relevant errors for changed files that appear later in the output.
**Timeout**: Set a 120-second timeout (120000ms when using `run_shell_command`) for type checkers (`tsc`, `mypy`) and 60-second timeout (60000ms) for linters. If a command times out or fails to run (tool not installed), skip it and record an informational note naming the skipped check and the reason (e.g., "tsc skipped: timeout after 120s" or "ruff skipped: tool not installed"). Include these notes in the Step 7 summary so the user knows which checks did not run. **Timeout**: Set a 120-second timeout (120000ms when using `run_shell_command`) for type checkers (`tsc`, `mypy`) and 60-second timeout (60000ms) for linters. If a command times out or fails to run (tool not installed), skip it and record an informational note naming the skipped check and the reason (e.g., "tsc skipped: timeout after 120s" or "ruff skipped: tool not installed"). Include these notes in the Step 7 summary so the user knows which checks did not run.
@ -187,11 +197,15 @@ This agent runs deterministic build and test commands to verify the code compile
1. Detect the build system and run **exactly one** build command (skip if Step 3 already verified compilation). Use this precedence order — choose the **first applicable** option only to avoid duplicate builds (e.g., a Makefile that wraps npm). Capture full output; if it exceeds 200 lines, keep the first 50 and last 100 lines: 1. Detect the build system and run **exactly one** build command (skip if Step 3 already verified compilation). Use this precedence order — choose the **first applicable** option only to avoid duplicate builds (e.g., a Makefile that wraps npm). Capture full output; if it exceeds 200 lines, keep the first 50 and last 100 lines:
- If `package.json` exists with a `build` script → `npm run build 2>&1` - If `package.json` exists with a `build` script → `npm run build 2>&1`
- Else if `pom.xml` exists → `mvn compile -q 2>&1`
- Else if `build.gradle` or `build.gradle.kts` exists → `gradle compileJava -q 2>&1`
- Else if `Makefile` exists → `make build 2>&1` - Else if `Makefile` exists → `make build 2>&1`
- Else if `Cargo.toml` exists → `cargo build 2>&1` - Else if `Cargo.toml` exists → `cargo build 2>&1`
- Else if `go.mod` exists → `go build ./... 2>&1` - Else if `go.mod` exists → `go build ./... 2>&1`
2. Run **exactly one** test command (same precedence and output handling): 2. Run **exactly one** test command (same precedence and output handling):
- If `package.json` exists with a `test` script → `npm test 2>&1` - If `package.json` exists with a `test` script → `npm test 2>&1`
- Else if `pom.xml` exists → `mvn test -q 2>&1`
- Else if `build.gradle` or `build.gradle.kts` exists → `gradle test -q 2>&1`
- Else if `pytest.ini` or `pyproject.toml` with `[tool.pytest]``pytest 2>&1` - Else if `pytest.ini` or `pyproject.toml` with `[tool.pytest]``pytest 2>&1`
- Else if `Cargo.toml` exists → `cargo test 2>&1` - Else if `Cargo.toml` exists → `cargo test 2>&1`
- Else if `go.mod` exists → `go test ./... 2>&1` - Else if `go.mod` exists → `go test ./... 2>&1`