From claude-java-toolkit
Use when checking code quality before committing, when CI lint fails, when reviewing PMD/CPD/suppression violations, or when detecting AI-generated code quality issues (slop) on Java modules. Works on any Java project — with or without Maven/pom.xml.
How this skill is triggered — by the user, by Claude, or both
Slash command
/claude-java-toolkit:code-gateThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Pre-commit code quality gate with auto-fix capability. Two-phase progressive approach:
Pre-commit code quality gate with auto-fix capability. Two-phase progressive approach: fast standalone checks first, optional Maven-based ArchUnit second.
Works on any Java project. If pom.xml exists, automatically aligns PMD version with CI.
If not (including Gradle projects), uses PMD built-in rulesets with default settings.
Gradle projects are fully supported for scanning but PMD version auto-alignment is Maven-only.
All scripts follow a unified output convention:
---CODE_GATE_RESULT--- marker and a single-line JSON summaryWhen running scripts, parse the JSON after ---CODE_GATE_RESULT--- to get structured results.
Violation details above the marker are for auto-fix analysis.
Note:
--fix-imports-onlyalso reorders imports to Google style. This may differ from the team's IntelliJ/IDE import order settings.
| Tool | status values | Key fields |
|---|---|---|
detect-env | ready, failed | java, maven, pmd_engine, first_run |
pmd | skip, pass, fail, error | violations, files_checked, engine |
cpd | skip, pass, fail, error | duplications, mode |
suppressions | skip, pass, fail, error | violations |
$ARGUMENTS = [module] [--full] [--report-only] [--include-tests] [--all]
. for single-module projects. Default: auto-detect.src/test/java in addition to src/main/java.When --include-tests is specified, set env var before calling scripts:
export CODE_GATE_INCLUDE_TESTS=true
| Mode | Scope | Auto-fix | Use Case |
|---|---|---|---|
| Incremental (default) | Branch-changed files | Import + PMD safe fixes | Commit 前自檢 |
Full (--full) | Entire src/main/java | Import + PMD safe fixes | 全模組健檢 |
Report-only (--report-only) | Branch-changed files | None | 只想看問題 |
| Full + Report-only | Entire src/main/java | None | CI gate / audit |
Include tests (--include-tests) | + src/test/java | Same as mode | 測試程式碼也要掃 |
If this is the first run (no ~/.claude/tools/code-gate-env.sh exists), tell the user before running:
"首次執行需要下載 PMD CLI (~35MB) 和 google-java-format (~5MB),大約需要 30 秒。"
Run ${CLAUDE_SKILL_DIR}/scripts/detect-env.sh to verify environment.
Parse the JSON result. If status is "failed", report what's missing and stop.
If first_run is true, briefly note that tools were downloaded successfully.
If no module argument provided, auto-detect:
# Multi-module: find subdirectories with src/main/java
VALID_MODULES=$(find . -maxdepth 2 -path '*/src/main/java' -not -path './src/main/java' \
| sed 's|/src/main/java||; s|^\./||' | sort)
# Single-module: src/main/java at project root
if [[ -z "$VALID_MODULES" && -d "src/main/java" ]]; then
MODULE="."
fi
If git changes are available, narrow to changed modules:
# Auto-detect default branch (supports main, master, develop, etc.)
BASE_BRANCH=$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's@^refs/remotes/origin/@@') || BASE_BRANCH="master"
CHANGED_MODULES=$(git diff --name-only "$(git merge-base "$BASE_BRANCH" HEAD)" -- '*/src/main/java/**/*.java' \
| cut -d/ -f1 | sort -u)
If --all is specified, run Phase 1 on each module in CHANGED_MODULES sequentially,
collecting results into a combined summary table.
If multiple modules detected (without --all), list them and ask the user which one to check.
If a single module is found, use it automatically.
Unless --full is specified:
MODULE=$1 # e.g. MyModule or "."
if [[ "$MODULE" == "." ]]; then
SRC_PREFIX="src/main/java/"
else
SRC_PREFIX="$MODULE/src/main/java/"
fi
FILELIST=$(mktemp /tmp/code-gate-filelist-XXXXXX.txt)
# Reuse BASE_BRANCH from Step 2 (auto-detected)
{
git diff --name-only --diff-filter=ACMR "$(git merge-base "$BASE_BRANCH" HEAD)" -- "$SRC_PREFIX"
git ls-files --others --exclude-standard -- "$SRC_PREFIX"
} | grep '\.java$' | sort -u > "$FILELIST"
FILE_COUNT=$(wc -l < "$FILELIST")
If $FILE_COUNT is 0, report "No changed Java files — nothing to lint." and stop.
If --full, set FILELIST="" (empty string) for full-scan mode.
If --report-only: SKIP this step entirely.
source "$HOME/.claude/tools/code-gate-env.sh"
# Note: xargs without -r for macOS BSD compatibility; input is pre-validated non-empty
if [[ -n "$FILELIST" && -s "$FILELIST" ]]; then
xargs "$JAVA_GJF" -jar "$GJF_JAR" --fix-imports-only --replace < "$FILELIST"
else
if [[ "$MODULE" == "." ]]; then
find "src/main/java" -name '*.java' | \
xargs "$JAVA_GJF" -jar "$GJF_JAR" --fix-imports-only --replace
else
find "$MODULE/src/main/java" -name '*.java' | \
xargs "$JAVA_GJF" -jar "$GJF_JAR" --fix-imports-only --replace
fi
fi
Report how many files were modified.
source "${CLAUDE_SKILL_DIR}/scripts/run-pmd.sh"
run_pmd "$MODULE" "." "$FILELIST"
Parse the JSON result after ---CODE_GATE_RESULT---.
Violation details (lines above the marker) are for auto-fix analysis.
If violations found:
Normal mode: Claude reads ${CLAUDE_SKILL_DIR}/reference/violation-fixes.md and:
--report-only mode: List all violations. Do NOT fix. Do NOT read violation-fixes.md.
source "${CLAUDE_SKILL_DIR}/scripts/run-pmd.sh"
run_cpd "$MODULE" "." "$FILELIST"
Parse the JSON result. Report duplications. Do NOT auto-fix.
Note: CPD always scans the full
src/main/javadirectory even in incremental mode, because cross-file duplication detection requires full source context. The output is then post-filtered to only report duplications involving changed files.
bash "${CLAUDE_SKILL_DIR}/scripts/check-suppressions.sh" "$MODULE" "." "$FILELIST"
Parse the JSON result. Checks what PMD XPath cannot:
CPD-OFF / NOPMD comments@SuppressWarnings("all")@SuppressWarnings("PMD")Do NOT auto-fix suppressions.
Collect JSON results from PMD, CPD, and Suppressions steps. For imports (no JSON), count modified files from the command output. Present a single summary table:
| Check | Status | Detail |
|---|---|---|
| Imports | done/skip | N files fixed (count from command output) |
| PMD | from JSON status | violations count (M auto-fixed if applicable) |
| CPD | from JSON status | duplications count |
| Suppressions | from JSON status | violations count |
If all checks pass: Keep response to 2-3 lines. Do not elaborate. If issues remain: Show the table, then list only actionable items the user needs to address.
[[ -n "$FILELIST" && -f "$FILELIST" ]] && rm -f "$FILELIST"
Only offer Phase 2 if Phase 1 passes clean AND the detect-env JSON showed maven: true.
Ask user before proceeding.
# Auto-discover ArchUnit test classes (common naming conventions)
ARCH_TESTS=$(find "$MODULE/src/test/java" \( \
-name '*ArchRule*Test*.java' \
-o -name '*ArchitectureTest*.java' \
-o -name '*ArchTest*.java' \
-o -name '*LayerTest*.java' \
-o -name '*LintSuppression*Test*.java' \
\) 2>/dev/null \
| sed 's|.*/src/test/java/||; s|\.java$||; s|/|.|g' \
| paste -sd,)
# Fallback: search for @ArchTest annotation or ArchUnit imports
if [[ -z "$ARCH_TESTS" ]]; then
ARCH_TESTS=$(grep -rl 'com.tngtech.archunit\|@ArchTest' \
"$MODULE/src/test/java" 2>/dev/null \
| sed 's|.*/src/test/java/||; s|\.java$||; s|/|.|g' \
| paste -sd,)
fi
if [[ -n "$ARCH_TESTS" ]]; then
mvn test -pl "$MODULE" -Dtest="$ARCH_TESTS"
else
echo "No ArchUnit test classes found — skipping Phase 2."
fi
Report ArchUnit results if test classes found.
Provides UI/UX resources: 50+ styles, color palettes, font pairings, guidelines, charts for web/mobile across React, Next.js, Vue, Svelte, Tailwind, React Native, Flutter. Aids planning, building, reviewing interfaces.
Fetches up-to-date documentation from Context7 for libraries and frameworks like React, Next.js, Prisma. Use for setup questions, API references, and code examples.
npx claudepluginhub keepprogress/claude-java-toolkit --plugin claude-java-toolkit