| name | sonarqube |
| description | Use when the user asks to run `/sonarqube`, list or summarize Sonar findings, fix Sonar issues, check a quality gate, review new-code issues on changed files, or work with local SonarQube or SonarCloud results. |
SonarQube
YOU MUST EXECUTE THIS WORKFLOW. Do not just describe it.
Runs SonarQube/SonarCloud against files changed on the current branch, then iteratively fixes findings at/above a target severity (high by default) until clean or blocked.
Quick Reference
| Setting | Options | Default |
|---|
| Action | autofix / list | ask once, then autofix |
| Mode | local / cloud | ask once, then local |
| Severity | blocker / high / medium / low / info | high |
| Scope | new (changed lines) / changed (changed files) | new |
| Exit codes | 0 clean, 3 findings exist, 1 blocked | — |
When NOT to Use
- Project has no SonarQube server and no SonarCloud integration — set one up first.
- Findings are from a different branch or an unrelated project key.
- User wants a full-repo scan (not scoped to current branch changes) — use SonarQube UI directly.
Inputs
action: autofix|list (resolved from user intent)
mode: local|cloud (default local)
severity: blocker|high|medium|low|info (default high). Both software-quality labels (high, medium, low) and API/legacy labels (critical, major, minor) are accepted; the script normalizes automatically.
scope: new|changed (default new). new = only findings on changed lines; changed = all findings on changed files.
base_ref: branch to diff against (default auto-detect: origin/main, main, origin/master, master)
host_url: SonarQube URL (default http://localhost:9000; ignored in cloud mode)
auth: prefer SONAR_TOKEN; fallback to repo-local .env, then SONAR_USER + SONAR_PASSWORD
organization: SonarCloud organization key (cloud mode only)
config: path to .sonarqube-skill.yaml (optional, auto-detected at repo root). Provides defaults overridable by CLI/env.
sonar-project.properties: if present, read sonar.projectKey, sonar.host.url, sonar.sources, and sonar.tests
Bundled Script
scripts/sonarqube.py: single Python script handling both local and cloud modes. Subcommands:
scan: full pipeline — detect base ref, compute changed files, ensure server (local), bootstrap local SonarQube project state, run scanner (local), fetch issues, output findings.
fetch: fetch issues from an existing scan and filter to changed files (backward-compatible).
Outputs (default directory .sonarqube/):
changed-files.txt
changed-lines.json (when scope=new)
rust-clippy.json (when Rust report generation succeeds)
sonar-scanner.log (local mode only)
findings.json
findings.md
fix-plan.json / fix-plan.md (generated by agent before autofix loop)
blocked.json (generated by agent when findings cannot be auto-fixed)
Autonomous Workflow
- Resolve action from intent.
- If invoked as
/sonarqube with no explicit action, first show supported actions and ask once:
autofix: apply fixes for findings at/above threshold
list: show aggregated findings by severity (no code changes)
autofix keywords: autofix, fix, address, resolve, complete, remediate.
list keywords: list, show, find, report, summary, aggregate, count.
- If ambiguous, ask once:
Do you want autofix or list? (autofix/list).
- If unanswered/ambiguous, default to
autofix.
- Resolve mode.
- If user/context explicitly says
local or cloud, use it.
- If not explicit, ask once:
Do you want a local scan or SonarCloud results? (local/cloud).
- If unanswered/ambiguous, default to
local.
- Resolve severity threshold.
- If user/context explicitly provides severity, use it.
- If missing, ask once:
Which severity threshold? (blocker/high/medium/low/info).
- If unanswered/ambiguous, default to
high.
- Accept both models on input (
medium or major, high or critical, etc.) and apply the mapping above.
- For
local mode, run the full scan pipeline.
- If
action=list, pass --list-only:
python3 "<path-to-skill>/scripts/sonarqube.py" scan \
--mode local --severity "${SEVERITY:-high}" --scope "${SCOPE:-new}" \
--base-ref "${BASE_REF:-origin/main}" --list-only
python3 "<path-to-skill>/scripts/sonarqube.py" scan \
--mode local --severity "${SEVERITY:-high}" --scope "${SCOPE:-new}" \
--base-ref "${BASE_REF:-origin/main}"
- Local scan setup requirements:
- Reuse
SONAR_TOKEN from process env first, then repo-local .env
- If no token is available and the server is local, use
admin/admin, create the SonarQube project, generate a token, and persist it to .env
- Configure the new code period with
type=REFERENCE_BRANCH and the detected base branch (main by default)
- If you verify the new code period through the API, query
/api/new_code_periods/show with both project and branch; project-only responses can still show the inherited default
- Read
sonar.host.url, sonar.sources, and sonar.tests from sonar-project.properties when present
- Warn if
sonar.sources appears to include test paths but sonar.tests is unset
- Before scanning Rust repos, run
cargo clippy --message-format=json --all-targets --all-features and pass sonar.rust.clippy.reportPaths
- Skip to step 6 (interpret exit code).
-
For cloud mode, fetch existing findings (no local scanner needed).
Cloud mode retrieves findings already in SonarCloud from CI/CD scans. It does not run sonar-scanner locally.
a. MCP-first: Check if a SonarQube/SonarCloud MCP server is connected.
- Look for MCP tools containing
sonar in the name (e.g. sonarqube_issues_search, search_issues, or similar).
- If available, use the MCP tool to search issues for the project key with relevant severity/status filters.
- Parse the MCP response and filter results to files in
.sonarqube/changed-files.txt.
- Write results to
.sonarqube/findings.json and .sonarqube/findings.md using the standard schema (see Output Schema below).
b. REST API fallback: If no SonarCloud MCP server is available, run:
python3 "<path-to-skill>/scripts/sonarqube.py" scan \
--mode cloud \
--severity "${SEVERITY:-high}" --scope "${SCOPE:-new}" \
--token "$SONAR_TOKEN" \
--organization "${SONAR_ORGANIZATION:-}" \
--list-only
c. If neither MCP nor SONAR_TOKEN is available, report blocked with the exact missing dependency and stop.
d. If action=list, print aggregated findings from .sonarqube/findings.json and stop (no code edits).
e. Cloud autofix limitation: cloud mode uses a single-pass fix (see step 8, cloud mode). No iterative re-scan.
-
Interpret exit code (both modes).
0: no actionable findings; stop.
3: actionable findings exist; continue fix loop.
1: blocked (scanner/auth/infrastructure); surface blocker and stop.
- Generate fix plan (autofix only).
- Read
.sonarqube/findings.json.
- Group findings by file, then by rule within each file.
- Write
.sonarqube/fix-plan.md: human-readable plan listing each file, findings grouped by rule, intended fix approach.
- Write
.sonarqube/fix-plan.json: machine-readable version:
{"files": [{"path": "src/foo.py", "findings": [{"key": "...", "rule": "...", "severity": "...", "line": 42, "message": "..."}]}], "total_findings": 5, "total_files": 2}
- Continue to fix loop automatically (no user checkpoint).
- Fix loop.
- Local mode (iterative, no user checkpoints):
- Set
MAX_PASSES=8 unless user specified another limit.
- On each pass with exit code
3, read .sonarqube/findings.json and fix highest-severity findings first. When severities tie, prioritize vulnerabilities and bugs over code smells.
- Keep changes minimal and local to files in
changed-files.txt.
- After each pass run relevant verification (
make test preferred; if too slow, run targeted tests for touched packages/files).
- Re-run the scan after fixes to verify resolution.
- Cloud mode (single pass):
- Read
.sonarqube/findings.json and fix highest-severity findings first.
- Keep changes minimal and local to files in
changed-files.txt.
- Run tests after fixes.
- Do not re-scan — cloud API returns stale data until code is pushed and CI/CD re-analyzes.
- Advise the user that verification requires push + CI/CD.
- Stop conditions.
- Stop successfully when scan exits
0.
- Stop as blocked if findings are non-actionable. Write
.sonarqube/blocked.json with classification for each blocked finding:
false_positive_candidate: finding appears incorrect for the code context
external_dependency: fix requires changes outside the repository
unsupported_auto_fix: rule type has no safe automated fix
needs_behavioral_change: fix would change program behavior beyond the scope of a safe edit
infrastructure_failure: scan/server/auth error prevents re-verification
- Stop as failed if
MAX_PASSES is reached and findings remain; report remaining findings by severity.
- Completion behavior.
- Summarize files changed, remaining findings count (should be zero on success for local mode), and any blocked findings with their classifications.
- For cloud mode autofix: include a note that fixes were applied based on cloud findings but could not be verified locally. Recommend the user push and check the next SonarCloud analysis.
- Only commit if the user explicitly asked for a commit or the repo's
CLAUDE.md enables autonomous commits. Use a conventional commit message (e.g. fix: resolve sonar findings ...).
- Never push automatically.
Output Schema
Both modes produce the same findings.json schema:
findings.json:
{
"summary": {
"project_key": "...",
"severity_threshold": "...",
"scope": "new|changed",
"changed_files": 5,
"findings": 3,
"severity_counts": {"BLOCKER": 0, "CRITICAL": 2, "MAJOR": 1}
},
"findings": [
{
"key": "issue-key",
"rule": "rule-id",
"type": "BUG|VULNERABILITY|CODE_SMELL|SECURITY_HOTSPOT",
"severity": "BLOCKER|CRITICAL|MAJOR|MINOR|INFO",
"message": "description",
"file": "path/to/file",
"line": 42,
"status": "OPEN|CONFIRMED|REOPENED",
"effort": "estimation",
"tags": ["tag1"]
}
]
}
findings.md: Markdown table with columns: Severity | File | Line | Rule | Message.
Common Mistakes
- Claiming success without a clean scan: in local mode, always re-scan after fixes and require exit code
0 before reporting success.
- Re-scanning in cloud mode: cloud API returns stale data until code is pushed and CI/CD re-analyzes. Apply fixes in a single pass, run tests, then advise the user to push.
- Editing files outside the diff: keep changes scoped to files in
changed-files.txt. Do not "fix" findings in unchanged files.
- Skipping tests: always run tests after fixes, even if the scan is clean.
Execution Rules
- Do not ask the user to review each finding during this workflow.
- Cloud mode does not require
sonar-scanner or docker.