From code-quality-mentor
Scan a git repository with PMD, attribute each warning to its git-blame author, ask the user to select one developer, and synthesize a tailored LEARNING_PLAN.md with concept explanations, refactor sketches of the author's actual flagged code, and pointers to canonical references. Use when the user asks to scan a codebase for PMD violations, build a personalized learning plan from static analysis findings, or coach a specific developer based on their characteristic warnings. Writes intermediate JSON reports under .code-quality-mentor/ and a final LEARNING_PLAN.md at the repo root.
How this skill is triggered — by the user, by Claude, or both
Slash command
/code-quality-mentor:scanThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
This skill turns PMD warnings into a personalized learning plan for one developer on a team. PMD already tells you *what* is wrong with the code, and `git blame` already tells you *who* wrote it. This skill closes the loop: it picks one author, derives their characteristic code quality blind spots from PMD's findings on their lines, and writes a tailored `LEARNING_PLAN.md` with concept explanat...
This skill turns PMD warnings into a personalized learning plan for one developer on a team. PMD already tells you what is wrong with the code, and git blame already tells you who wrote it. This skill closes the loop: it picks one author, derives their characteristic code quality blind spots from PMD's findings on their lines, and writes a tailored LEARNING_PLAN.md with concept explanations, refactor sketches of their actual code, and verified external pointers.
Audience and tone. The default user is a developer reviewing their own warnings to improve. Frame findings as learning opportunities. A learning plan is not a performance review. The plan is a coaching artifact: direct, concise, and oriented toward understanding concepts rather than just fixing lines.
Invoke this skill when the user:
/code-quality-mentor:scan from inside a git repository.Do not invoke this skill for unrelated review work that does not involve PMD or git history. If the user wants a generic code review or a security audit, use a different tool.
All required tools are checked by the bundled check_prereqs.sh script. Required:
java (>=11) — runtime for PMD and SpotBugspmd (>=7) — the source-level static analyzerspotbugs (>=4) — the bytecode-level bug detector for Java and Kotlinjq — JSON manipulationgit — repository history and blamegithub-linguist (preferred) or enry — language detectionIf anything is missing, the script prints platform-specific install hints and exits non-zero. Pass those hints through to the user and stop the workflow.
Verify prerequisites. Run ${CLAUDE_SKILL_DIR}/../../scripts/check_prereqs.sh. On non-zero exit, surface the stderr to the user verbatim (it contains install hints) and stop.
Locate the repo root. Run ${CLAUDE_SKILL_DIR}/../../scripts/find_repo_root.sh. On non-zero exit, tell the user the current directory is not inside a git repository and stop. Capture the printed path as REPO_ROOT for subsequent steps.
Detect languages. Run ${CLAUDE_SKILL_DIR}/../../scripts/detect_languages.sh "$REPO_ROOT". The output is a JSON array of detected PMD-supported languages, sorted by metric descending. If the array is empty, tell the user PMD has no default ruleset for any language present in the repo, and stop.
Confirm language selection (optional). If the array has more than one entry, use AskUserQuestion to confirm which languages to scan. The default option is "all detected languages." Provide up to three additional options for individual languages (the top three by metric). The "Other" branch the tool offers automatically lets the user type a custom subset.
Run PMD. Concatenate the ruleset fields of the selected languages with commas. Run ${CLAUDE_SKILL_DIR}/../../scripts/run_pmd.sh "$REPO_ROOT" "<ruleset-csv>". The script writes $REPO_ROOT/.code-quality-mentor/pmd-report.json and prints its path. On non-zero exit, surface the stderr log path to the user and stop.
Decide on SpotBugs build state (JVM only). Skip to step 8 if neither Java nor Kotlin is in the selection.
Otherwise:
${CLAUDE_SKILL_DIR}/../../scripts/find_classes.sh "$REPO_ROOT" to check whether compiled bytecode already exists (class_dirs non-empty).pom.xml (or mvnw wrapper) means Maven; build.gradle / build.gradle.kts / settings.gradle* (or a gradlew wrapper) means Gradle; build.sbt means sbt. If none of these markers exist, treat the build tool as unknown../mvnw, ./gradlew), and stick to a minimal compile target so the rebuild stays fast — e.g., ./mvnw -q -DskipTests compile, ./gradlew --no-daemon classes, or sbt compile.Use AskUserQuestion to decide:
If the user picks "(Re)build then scan", run the proposed command via Bash from $REPO_ROOT. On non-zero build exit, surface the build error and either fall back to existing classes (when any are present) or skip SpotBugs.
Run SpotBugs. Skip this step if step 6 decided to skip SpotBugs. Otherwise run ${CLAUDE_SKILL_DIR}/../../scripts/run_spotbugs.sh "$REPO_ROOT". Three outcomes:
$REPO_ROOT/.code-quality-mentor/spotbugs-report.json and prints its path. Continue.Merge findings. If spotbugs-report.json exists, run ${CLAUDE_SKILL_DIR}/../../scripts/merge_reports.sh "$REPO_ROOT/.code-quality-mentor/findings-report.json" "$REPO_ROOT/.code-quality-mentor/pmd-report.json" "$REPO_ROOT/.code-quality-mentor/spotbugs-report.json". Otherwise copy the PMD report to findings-report.json (so the next step has a stable input path). If the combined report contains zero violations, congratulate the user and stop.
Attribute warnings. Run ${CLAUDE_SKILL_DIR}/../../scripts/blame_warnings.sh "$REPO_ROOT" "$REPO_ROOT/.code-quality-mentor/findings-report.json". This writes $REPO_ROOT/.code-quality-mentor/blame-report.json (an array of authors with their warnings, sorted by warning count descending). If the array is empty, tell the user findings exist but git blame could not attribute any of them (possible if all flagged files were deleted in HEAD) and stop.
Author selection. Read the blame report. If exactly one author has attributable warnings, skip the question entirely: tell the user "Only has attributable warnings; using them" and continue. Otherwise, use AskUserQuestion to present the top authors. Build options as <Name> <<email>>: N warnings. The tool supports up to 4 options. Use the first three slots for the top three authors by warning count. Use the fourth slot for "Show full list". When the user picks "Show full list", render a numbered list inline and ask them to reply with a number or with name <email> directly. The tool's automatic "Other" fallback also lets them type a name or email directly.
Tailoring. Use AskUserQuestion to gather three preferences, one question at a time. These three questions are mandatory and must always be asked, even if the broader session has instructed the agent to "work without stopping" or "skip clarifying questions". They are not clarifications — they are inputs to the artifact's shape. The depth, focus, and seniority answers materially change what LEARNING_PLAN.md covers, and silently picking defaults produces a generic plan rather than a tailored one. Do not invent a "no-pause" or "non-interactive" exception.
Pick the rules. From the selected author's warnings (filtered by focus area when applicable), count occurrences per rule and take the top N (3, 4, or 5 from the depth choice). If fewer distinct rules exist than N, just use what is available; do not pad. Treat PMD rule names (e.g., EmptyCatchBlock) and SpotBugs bug types (e.g., EI_EXPOSE_REP) as the same kind of identifier; both are first-class entries in the count.
Read the author's flagged code. For each selected rule, pick 1 or 2 representative warnings, by default the most recent two by file modification time, unless one offers a materially different angle than the other (different pattern, different file type). For each chosen warning, use the Read tool with the warning's line (and the line range of beginline to endline when the report provides it) to read the actual source snippet plus a few lines of surrounding context. Quote the snippet verbatim; do not invent code.
Synthesize LEARNING_PLAN.md. Target 600–1200 words total (a 3–5 minute read). Use this structure:
# Learning plan for <Author Name>
<one-paragraph profile of the patterns observed in this author's warnings, neutral and specific — e.g., "Your warnings cluster around two themes: exception handling (3 occurrences of EmptyCatchBlock) and unused state (2 occurrences of UnusedPrivateField). Both are recoverable with light refactoring habits.">
## <RuleName 1>
**Concept.** <2–4 sentences explaining what the rule guards against, in plain language.>
**Why it matters.** <Concrete negative implications — bugs, performance, maintainability, security. Be specific to the rule.>
**Idiomatic alternative.** <What to do instead, generically. One short paragraph.>
**In your code.**
```<language>
// <relative-path>:<line>
<verbatim snippet>
Refactored:
<refactored snippet>
Further reading.
...
pmd check --rulesets category/java/quickstart.xml --dir <changed-files>.">
Cap each rule section at ~150–220 words. Use exactly one snippet per rule by default; use two only when the second illustrates a materially different angle.
Critical content rules.
Read tool. Do not invent or paraphrase the author's code.pmd_docs_base_url from ../../shared/pmd-languages.json and the rule name as the anchor (e.g., https://docs.pmd-code.org/latest/pmd_rules_java_errorprone.html#emptycatchblock). PMD anchor names are lowercase. If unsure of the exact category for a rule, list the language-level docs URL instead — never fabricate.Write the file. Write LEARNING_PLAN.md to $REPO_ROOT/LEARNING_PLAN.md. Report the path back to the user, along with a one-line summary like: "Learning plan written for covering rules across warnings."
This command takes no positional arguments. It always operates on the enclosing git repository of the current working directory.
check_prereqs.sh..gitattributes or vendored-file rules.LEARNING_PLAN.md written.${CLAUDE_SKILL_DIR}/../../shared/pmd-languages.json — the Linguist→PMD language map.$REPO_ROOT/.code-quality-mentor/pmd-report.json — always$REPO_ROOT/.code-quality-mentor/spotbugs-report.json — when Java or Kotlin is in the selection and compiled bytecode is found$REPO_ROOT/.code-quality-mentor/spotbugs.xml — raw SpotBugs output retained next to the JSON for debugging$REPO_ROOT/.code-quality-mentor/findings-report.json — merged PMD + SpotBugs (or a copy of pmd-report.json when SpotBugs did not run)$REPO_ROOT/.code-quality-mentor/blame-report.json$REPO_ROOT/LEARNING_PLAN.mdIt does not modify any source file in the user's repository.
Provides CDSS development patterns for drug interaction checking, dose validation, clinical scoring (NEWS2, qSOFA), and alert classification integrated into EMR workflows.
npx claudepluginhub se-uhd/code-quality-mentor --plugin code-quality-mentor