Skip to main content

Multi-language code quality scanner — complexity, duplication, security, and smells

Project description

qlint

Multi-language code quality scanner. Walks any codebase and produces JSON, HTML, and Markdown reports covering complexity, duplication, security, code smells, and predictive risk (which files are most likely to cause your next outage).

Install

# from PyPI
pip install qlint

# from source
git clone https://github.com/ropean/qlint.git
cd qlint
pip install -e .

Usage

qlint /path/to/repo                  # JSON + HTML + Markdown; auto-opens HTML
qlint /path/to/repo --format md      # Markdown only
qlint /path/to/repo --format json,md # JSON + Markdown, no HTML, no auto-open
qlint /path/to/repo --no-open
qlint /path/to/repo --json-only      # print JSON to stdout, no files
qlint /path/to/repo -v               # verbose per-file output
qlint                                # interactive: prompts for path

qlint /path/to/repo --risk           # predictive risk report (top 5 chunked narrative)
qlint /path/to/repo --risk --risk-window 30
qlint /path/to/repo --risk-md /tmp/risk.md   # standalone markdown risk report

Reports are written to ~/Downloads/qlint-reports/<repo>/ as report.json, report.html, and report.md. HTML auto-opens only when an HTML report is produced. --risk alone prints to the console and writes nothing.

Options

Flag Description
--format, -f Comma-separated formats: json, html, md (default: all three)
--output, -o Custom JSON output path (implies json)
--html Custom HTML output path (implies html)
--md Custom Markdown output path (implies md)
--risk Print predictive risk report (top 5 files most likely to break)
--risk-window Days of git history to consider as "recent" (default 90)
--risk-md Write standalone risk Markdown report to PATH
--json-only Skip files, print JSON to stdout
--no-open Do not auto-open HTML report
--verbose, -v Show per-file progress
--version Show version

Analysis Features

Feature What it detects
Complexity Cyclomatic complexity per function, flags > 10
Duplication Duplicate 6-line blocks across files
Security Hardcoded secrets, dangerous functions (eval, exec, …)
Code Smells Long functions, deep nesting, long parameter lists
Predictive Risk Recency-weighted: recent_churn × complexity × (1 + 2·bug_fix_ratio) × (1 + 0.15·authors) / 100. Each top file gets a risk_level (critical/high/medium/low), structured signals, and human-readable reasons.

Predictive Risk

qlint --risk highlights the files most likely to cause your next outage by combining:

  • Static signals — complexity, smells, security issues
  • Git signals (recent window) — churn, commit frequency, bug-fix ratio, author count

Bug-fix detection scans commit subjects for fix|bug|hotfix|patch|revert (case-insensitive). Files with a high share of recent bug-fix commits get amplified scores — past fix density is a strong predictor of future fixes.

Risk levels are bucketed: critical (≥50), high (≥20), medium (≥5), low (<5).

Languages

Python, JavaScript, TypeScript, Java, Go, Ruby, Rust, C, C++, C#, PHP, Swift, Kotlin, Scala, Shell, HTML, CSS, SQL, YAML, JSON, and more.

JSON Output

{
  "scanId": "...",
  "timestamp": "...",
  "repository": { "path": "...", "totalFiles": 42, "totalLines": 8500, "languages": {} },
  "files": [
    {
      "path": "src/main.py",
      "language": "Python",
      "metrics": { "loc": 120, "code": 95, "comments": 10, "blank": 15, "functions": 8, "classes": 2, "complexity": 4.2 },
      "smells": [],
      "security_issues": [],
      "git_risk": {
        "commits": 12, "churn": 340, "authors": 2,
        "risk_score": 25.5, "risk_level": "high",
        "signals": { "...": "see gitRisk.top_risk_files for the full shape" },
        "reasons": ["active churn (340 lines / window)"]
      }
    }
  ],
  "qualityScore": 87,
  "grade": "B",
  "gitRisk": {
    "available": true,
    "window_days": 90,
    "top_risk_files": [
      {
        "file": "src/main.py",
        "risk_score": 25.5,
        "risk_level": "high",
        "reasons": ["active churn (340 lines / window)"],
        "signals": {
          "complexity": 4.2,
          "recent_commits": 5,
          "recent_churn": 340,
          "all_time_commits": 12,
          "all_time_churn": 600,
          "authors": 2,
          "bug_fix_ratio": 0.4,
          "smells": 1,
          "security_issues": 0
        }
      }
    ]
  }
}

Claude Code skill — qlint-refactor

The .claude/skills/qlint-refactor/ directory ships a Claude Code skill that turns the scanner into a feedback signal: it picks the riskiest file, proposes a behavior-preserving refactor, re-scans, and verifies the score dropped.

Loop:

  1. Baseline via scripts/risk_top.py (top-N risk JSON)
  2. Locate the worst function in the top-1 file
  3. Propose a minimal refactor (extract function, flatten conditionals, lookup tables)
  4. Apply, then scripts/verify.py FILE --baseline N.NNimproved / unchanged / regressed
  5. Roll back on no-improve; max 3 attempts per file; exit when all top-5 are risk_score < 50

Activates on prompts like "list top risk files", "explain why this file is risky", "refactor the risky code", "reduce risk score", "run the risk loop".

Development

make install   # pip install -e ".[dev]"
make lint      # ruff check
make format    # ruff format
make build     # python3 -m build

Requirements

  • Python 3.11+
  • git in PATH (for predictive risk; optional — --risk degrades gracefully on non-git dirs)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

qlint-0.3.0.tar.gz (32.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

qlint-0.3.0-py3-none-any.whl (36.7 kB view details)

Uploaded Python 3

File details

Details for the file qlint-0.3.0.tar.gz.

File metadata

  • Download URL: qlint-0.3.0.tar.gz
  • Upload date:
  • Size: 32.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for qlint-0.3.0.tar.gz
Algorithm Hash digest
SHA256 b4d26e5e9b5acda094caef29dfe59746b3bcae79809142f518584ff5487c17bb
MD5 12097b024ca465e2a1c9ecfaeb150f36
BLAKE2b-256 65cc8ddd036efcb29339b3ba70ec0f2344c717f9b595b8fc26fdaa50229d239f

See more details on using hashes here.

File details

Details for the file qlint-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: qlint-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 36.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for qlint-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ddeb9a69989455cbb47aac82213babf26348cb092b5aae9860b9a8064b5cc64a
MD5 b3e7f18ea016da93aaf67f7d8901c018
BLAKE2b-256 a504afdb9b4afc90485157336b0d891df2d5c4c92c39d7dfd179236eccca675f

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page