npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

qualitas

v0.5.1

Published

Multi-language code quality measurement — 5-pillar Quality Score based on CC-Sonar, Halstead, and eye-tracking research

Readme

Qualitas

A next generation code quality measurement tool that actually works. It measures code quality across five research-backed pillars and returns a single 0–100 Quality Score to guide the health of your code base. It supports TypeScript/JavaScript, Rust, Python, Go, and Java out of the box. The core is written in Rust using oxc_parser and tree-sitter for native-speed analysis, distributed as a native npm package via napi-rs, and provides both a programmatic TypeScript API and a CLI binary for ease of use.


Why another complexity tool?

Cognitive Complexity (CC-Sonar, the metric behind SonarQube) is the leading code quality metric for modern languages, but a 2023 PMC study using EEG and eye-tracking found measurable gaps:

| Metric | Correlation with measured cognitive load | |--------|------------------------------------------| | Halstead Effort (DCI) | r = 0.901 | | Eye-tracking revisit count (IRC) | r = 0.963 | | CC-Sonar alone | r = 0.513 |

CC-Sonar only measures control flow structure. It misses:

  • Data complexity — how many variables, operators, and distinct symbols the reader must track simultaneously (Halstead)
  • Identifier churn — how often a reader must revisit a variable across a wide scope (eye-tracking research)
  • Saturation effect — once code is complex enough, doubling raw CC-Sonar doesn't double perceived difficulty

qualitas addresses all three gaps through a five-pillar composite score with an exponential saturation model.

PMC paper: "Measuring cognitive complexity in software development"https://pmc.ncbi.nlm.nih.gov/articles/PMC9942489/


Quick start

# Analyze a file (text output, default)
npx qualitas ./src/myFile.ts

# Analyze a directory
npx qualitas ./src/

# JSON report (writes to qualitas-report.json by default)
npx qualitas ./src/ -f json

# JSON report to a specific file
npx qualitas ./src/ -f json -o report.json

# Show only functions that have flags
npx qualitas ./src/ -f flagged

# Fail CI if any score is below threshold
npx qualitas ./src/ --threshold 65

# Zero-tolerance mode — fail on any warning flag
npx qualitas ./src/ --fail-on-flags warn

Installation

npm install qualitas

The correct native binary for your platform is installed automatically as an optional dependency:

| Platform | Package | |----------|---------| | macOS Apple Silicon | @qualitas/binding-darwin-arm64 | | macOS Intel | @qualitas/binding-darwin-x64 | | Linux x64 (glibc) | @qualitas/binding-linux-x64-gnu | | Linux arm64 (glibc) | @qualitas/binding-linux-arm64-gnu | | Windows x64 | @qualitas/binding-win32-x64-msvc |

No build step required when installing from npm.


The Five Pillars

1. Cognitive Flow Complexity (CFC) — 20% weight

Tracks nesting depth during AST traversal and applies progressively larger penalties for deeply nested control flow.

Scoring increments:

| AST Node | Increment | Nesting penalty? | |----------|-----------|-----------------| | if / else if | +1 | Yes (+nestingDepth) | | for, for...of, for...in | +1 | Yes | | while, do...while | +1 | Yes | | switch | +1 | Yes | | catch clause | +1 | Yes | | &&, \|\|, ?? (logical) | +1 per operator | No | | Ternary ?: | +1 | No | | Recursive call (self-reference) | +1 | No | | .then() / .catch() chain | +1 | Yes (current depth) | | Nested arrow callback | +nestingDepth | Yes | | await inside nested function | +1 | Yes |

Formula: CFC = Σ(1 + nestingDepth) for nesting nodes, +1 flat for non-nesting nodes.


2. Data Complexity Index (DCI) — 30% weight

Halstead-inspired metric. Addresses CC-Sonar's largest gap (r=0.901 correlation in the PMC paper vs CC-Sonar's r=0.513).

Counting:

  • Operators (η₁ distinct, N₁ total): +, -, *, /, ===, !==, <, >, <=, >=, =, +=, -=, &&, ||, ??, !, typeof, instanceof, ?., ??=, etc.
  • Operands (η₂ distinct, N₂ total): identifiers (variables/params), string/numeric/template literals, this, null, undefined, boolean literals

Computed values:

Vocabulary  η = η₁ + η₂
Length      N = N₁ + N₂
Volume      V = N × log₂(η)
Difficulty  D = (η₁/2) × (N₂/η₂)
Effort      E = D × V

Normalized raw score:

DCI_raw = 0.6 × (D / 60) + 0.4 × (V / 3000)

Where 60 = F-tier difficulty threshold, 3000 = F-tier volume threshold.

Why it matters: A function with 20 distinct variable names, 15 distinct operators, and 200 total token appearances forces the reader to hold a large mental vocabulary simultaneously. CC-Sonar scores this identically to a trivial function with the same branching structure.


3. Identifier Reference Complexity (IRC) — 25% weight

Novel metric. Inspired by the eye-tracking finding (r=0.963) that revisit count — how often a developer re-reads a variable while understanding code — is the strongest predictor of cognitive load.

Algorithm: For each declared identifier (variable, parameter, destructured binding) in function scope:

cost = referenceCount × log₂(scopeSpanLines + 1)
     where scopeSpanLines = lastReferenceLine − definitionLine

Total IRC = Σ(cost) over all identifiers.

Why it matters: A variable x referenced once on the line after it's declared has cost ≈ 1. A variable config referenced 12 times across a 150-line function has cost ≈ 12 × log₂(151) ≈ 87. The log₂ damping prevents enormous scope spans from completely dominating — matching the paper's finding that saturation occurs.


4. Dependency Coupling (DC) — 15% weight

Measures how many external dependencies and distinct APIs a function/file touches.

At file level:

  • importCount — total import statements
  • distinctSources — unique module specifiers
  • externalRatio — imports from node_modules / total imports

At function level:

  • distinctApiCalls — distinct imported-module methods called (e.g., fs.readFile, axios.get = 2)
  • closureCaptures — identifiers from outer scope referenced inside

Normalized raw score:

DC_raw = 0.4 × (importCount / 20) + 0.3 × externalRatio + 0.3 × (distinctApiCalls / 15)

5. Structural Metrics (SM) — 10% weight

Count-based metrics that catch simple but impactful structural issues.

  • loc — non-blank, non-comment lines in function body
  • parameterCount — formal parameters (destructured objects count as 1)
  • maxNestingDepth — maximum block nesting depth
  • returnCount — number of return statements

Normalized raw score:

SM_raw = 0.4×(loc/100) + 0.3×(params/6) + 0.2×(nesting/6) + 0.1×(returns/5)

Composite Scoring Formula

Saturation model

Based on the PMC paper's finding that perceived difficulty saturates — once code is complex enough, doubling raw complexity doesn't double how hard it feels:

saturate(x) = 1 − e^(−k × x)    where k = 1.0

At x=1.0 (exactly at the F-tier threshold): saturate ≈ 0.63 At x=2.0 (twice F-tier): saturate ≈ 0.86 At x=3.0 (three times F-tier): saturate ≈ 0.95

This means once a function is in F-tier territory, further increases cause diminishing marginal penalty — reflecting actual developer experience.

Final score

penalty_i = saturate(raw_i) × weight_i × 100    for each pillar i
totalPenalty = Σ(penalty_i)
Quality Score = max(0, 100 − totalPenalty)

Higher score = better quality. Score 100 = no detected complexity.

Grade bands

| Grade | Score | Meaning | |-------|-------|---------| | A | 80–100 | Clean, maintainable | | B | 65–79 | Acceptable, minor improvements possible | | C | 50–64 | Needs attention | | D | 35–49 | Refactoring recommended | | F | 0–34 | Critical complexity, refactor immediately |

needsRefactoring = score < 65 (configurable via refactoringThreshold).


Refactoring Flags

Each flag has two thresholds: warn (first trigger) and error (severe). Flags can be individually enabled, disabled, or customized via qualitas.config.js. EXCESSIVE_RETURNS is disabled by default.

| Flag | Warn | Error | Suggestion | |------|------|-------|------------| | HIGH_COGNITIVE_FLOW | CFC >= 13 | >= 19 | Extract nested branches into named functions | | HIGH_DATA_COMPLEXITY | difficulty >= 26 | >= 41 | Reduce variable density; extract computations | | HIGH_IDENTIFIER_CHURN | IRC >= 41 | >= 71 | Shorten function scope; break into smaller functions | | HIGH_HALSTEAD_EFFORT | effort >= 1500 | >= 5000 | Simplify expressions; extract complex calculations | | TOO_MANY_PARAMS | params >= 4 | >= 5 | Group related parameters into an options object | | TOO_LONG | LOC >= 41 | >= 61 | Extract sub-functions to keep each under 40 lines | | DEEP_NESTING | nesting >= 4 | >= 5 | Use early returns to flatten nesting | | HIGH_COUPLING | imports >= 10 | >= 15 | Consider splitting into smaller modules | | EXCESSIVE_RETURNS | returns >= 3 | >= 4 | Consolidate return paths (disabled by default) |


CLI Reference

qualitas <path> [options]

Arguments:
  path                          File or directory to analyze

Options:
  -f, --format <format>         Output format (default: text)
                                  text | compact | detail | flagged | json | markdown | summary
  -o, --output <path>           Output file for report formats (json, markdown)
  -c, --config <path>           Path to qualitas.config.js (overrides auto-detection)
  -p, --profile <name>          Weight profile: default | cc-focused | data-focused | strict
  -t, --threshold <n>           Exit code 1 if any score is below this (default: 65)
  --fail-on-flags <level>       Exit code 1 if any function has flags: warn | error
  --include-tests               Include test files (*.test.*, *.spec.*) in analysis
  -h, --help                    Show help
  -V, --version                 Show version

Output formats

Console formats — print to stdout, exit code reflects threshold/flag violations:

| Format | Description | |--------|-------------| | text (default) | Per-function rows with flags | | detail | Same as text with full metric breakdown per function | | flagged | Only show functions that have flags | | compact | One-line-per-file summary | | summary | Executive summary with pillar health, grade histograms, and deduction breakdown |

Report formats — write to file (defaults to qualitas-report.<ext> or use -o), always exit 0:

| Format | Description | |--------|-------------| | json | Full report as JSON (for agents/pipelines) | | markdown | Markdown tables with badge-style scores (for PRs) |

Exit codes

| Code | Meaning | |------|---------| | 0 | All scores at or above threshold (console formats), or report written successfully (json/markdown) | | 1 | One or more scores below threshold, or flags detected at the configured severity (console formats only) | | 2 | Parse error or file not found |

--fail-on-flags

By default, the exit code is based only on the score threshold. With --fail-on-flags, the CLI also fails if any function has flags at the specified severity:

  • --fail-on-flags warn — fail on any warning or error flag (zero tolerance)
  • --fail-on-flags error — fail only on error-level flags

This can also be set in qualitas.config.js via the failOnFlags field.

Examples

# Basic file analysis
qualitas ./src/payment.ts

# CI check — fail if any function scores below 70
qualitas ./src/ --threshold 70

# Zero-tolerance mode — fail on any warning or error flag
qualitas ./src/ --fail-on-flags warn

# Markdown report (writes to qualitas-report.md by default)
qualitas ./src/ -f markdown

# Markdown report to a specific path
qualitas ./src/ -f markdown -o quality-report.md

# JSON report to a specific path
qualitas ./src/ -f json -o report.json

# Use a config file from another location
qualitas /path/to/other-repo -c ./qualitas.config.js

# Executive summary with pillar health breakdown
qualitas ./src/ -f summary

# Use cc-focused profile (closer to pure SonarQube behavior)
qualitas ./src/ --profile cc-focused

# Show only flagged functions
qualitas ./src/ -f flagged

Programmatic API

import { quickScore, analyzeSource, analyzeFile, analyzeProject } from 'qualitas';
import type { FileQualityReport, QuickScore, AnalysisOptions, QualitasConfig } from 'qualitas';

// Fast check — returns only score, grade, and top flags (no full metric breakdown)
const qs: QuickScore = quickScore(`
  function add(a: number, b: number) { return a + b; }
`, 'add.ts');

console.log(qs.score);               // e.g. 98
console.log(qs.grade);               // 'A'
console.log(qs.needsRefactoring);    // false
console.log(qs.flaggedFunctionCount); // 0
console.log(qs.topFlags);            // []

// Full analysis — returns complete metric breakdown per function/class
const report = analyzeSource(`
  function add(a: number, b: number) {
    return a + b;
  }
`, 'add.ts');

console.log(report.score);   // e.g. 98
console.log(report.grade);   // 'A'
console.log(report.functions[0].metrics.cognitiveFlow.score); // raw CFC value

// Per-language flag overrides via config (e.g., stricter thresholds for Python)
const config: QualitasConfig = {
  languages: {
    python: { flags: { TOO_MANY_PARAMS: { warn: 3, error: 5 } } },
  },
};
const pyReport = analyzeSource(pythonSource, 'app.py', {}, config);

// Analyze a file (config parameter enables per-language flag resolution)
const fileReport = await analyzeFile('./src/payment.ts', {
  profile: 'strict',
  refactoringThreshold: 70,
});

// Analyze a full directory
const projectReport = await analyzeProject('./src/', {
  includeTests: false,
  refactoringThreshold: 65,
});

console.log(projectReport.summary.flaggedFunctions); // count of functions needing refactoring

quickScore vs analyzeSource

| | quickScore | analyzeSource | | --- | --- | --- | | Return type | QuickScore | FileQualityReport | | Per-function metrics | ✗ | ✓ | | Score + grade | ✓ | ✓ | | Top flags (up to 5) | ✓ | ✓ (per function) | | Use case | Editor plugins, CI pass/fail | Full reports, dashboards |

QuickScore

interface QuickScore {
  score: number;               // 0–100 composite score
  grade: 'A' | 'B' | 'C' | 'D' | 'F';
  needsRefactoring: boolean;
  functionCount: number;
  flaggedFunctionCount: number;
  topFlags: RefactoringFlag[]; // up to 5, from the worst functions
}

AnalysisOptions

interface AnalysisOptions {
  // Named weight profile
  profile?: 'default' | 'cc-focused' | 'data-focused' | 'strict';

  // Override individual pillar weights (must sum to 1.0)
  weights?: {
    cognitiveFlow?: number;       // default: 0.30
    dataComplexity?: number;      // default: 0.25
    identifierReference?: number; // default: 0.20
    dependencyCoupling?: number;  // default: 0.15
    structural?: number;          // default: 0.10
  };

  // Score below which needsRefactoring = true (default: 65)
  refactoringThreshold?: number;

  // Include test files in project analysis (default: false)
  includeTests?: boolean;

  // File extensions to include (default: .ts .tsx .js .jsx .mjs .cjs .py .pyi)
  extensions?: string[];

  // Directories/files to exclude (default: .git, qualitas.config.js)
  // Configure additional excludes (node_modules, dist, etc.) via qualitas.config.js
  exclude?: string[];

  // Per-flag overrides — supports both camelCase and SCREAMING_SNAKE_CASE keys
  flagOverrides?: Record<string, FlagConfig>;
}

FileQualityReport

interface FileQualityReport {
  filePath: string;
  score: number;           // 0–100
  grade: 'A' | 'B' | 'C' | 'D' | 'F';
  needsRefactoring: boolean;
  flags: RefactoringFlag[];
  functions: FunctionQualityReport[];
  classes: ClassQualityReport[];
  fileDependencies: DependencyCouplingResult;
  totalLines: number;
  functionCount: number;
  classCount: number;
  flaggedFunctionCount: number;
}

FunctionQualityReport

interface FunctionQualityReport {
  name: string;
  inferredName?: string;      // e.g. "const myFn = " for arrow functions
  score: number;
  grade: Grade;
  needsRefactoring: boolean;
  flags: RefactoringFlag[];
  metrics: MetricBreakdown;   // raw values for all 5 pillars
  scoreBreakdown: ScoreBreakdown; // per-pillar penalty contributions
  location: SourceLocation;
  isAsync: boolean;
  isGenerator: boolean;
}

Weight Profiles

default (recommended)

Weights derived from the PMC correlation coefficients, calibrated to avoid over-penalizing simple pattern matches (which inflate CFC but carry no real cognitive load):

| Pillar | Weight | Rationale | | -------- | -------- | ----------- | | DCI | 0.30 | Highest EEG correlation (r=0.901) — best indicator of real data complexity | | IRC | 0.25 | Strongest single predictor (r=0.963) — captures variable-tracking cost | | CFC | 0.20 | Good predictor but over-counts exhaustive matches and simple switches | | DC | 0.15 | Important but less directly studied | | SM | 0.10 | Useful sanity check, already partially captured by other pillars |

cc-focused

Boosts CFC to 0.50. Behaves similarly to SonarQube Cognitive Complexity for teams transitioning from that tool.

data-focused

Boosts DCI+IRC to 0.65 combined. Emphasizes Halstead/data complexity — useful for codebases with complex algorithms and data transformations.

strict

Same weights as default but tighter grade bands: A≥90, B≥75, C≥60, D≥40.


Sample Text Output

qualitas: src/processPayment.ts
████░░░░░░  score: 42.0  grade: D

  ✗ processPayment()  [D]  score: 42  ← needs refactoring
    Flags:
    [error] Cognitive flow complexity is 44 (threshold: 19)
           → Extract nested branches into separate named functions. Use early returns to flatten the nesting hierarchy.
    [error] Identifier reference complexity is 178.2 (threshold: 71)
           → Variables are referenced many times across a wide scope. Break this function into smaller functions to shorten variable lifetimes.
    [error] Function has 6 parameters (threshold: 5)
           → Group related parameters into an options object: `{ option1, option2, ... }`.
    [error] Maximum nesting depth is 10 (threshold: 5)
           → Use early returns (guard clauses) to flatten the nesting hierarchy.

  ✓ validateCard()    [B]  score: 71
  ✓ formatAmount()    [A]  score: 97

File: D — 42.0  — 1 of 3 function(s) need refactoring

Architecture

qualitas/
├── crates/
│   ├── qualitas-core/          Language-agnostic analysis engine
│   │   ├── analyzer.rs         Orchestrator: extract → metrics → score → report
│   │   ├── types.rs            All Rust structs (serde → JSON → TypeScript)
│   │   ├── constants.rs        Thresholds, weights, saturation K, grade bands
│   │   ├── ir/                 Intermediate representation (event-based)
│   │   ├── languages/          Language adapters (TypeScript, Rust, Python)
│   │   ├── metrics/            5 metric collectors (CFC, DCI, IRC, DC, SM)
│   │   ├── scorer/             Composite score + flag generation
│   │   └── parser/             Shared parsing utilities (LOC counting, etc.)
│   │
│   ├── qualitas-cli/           Standalone Rust CLI binary
│   │   ├── main.rs             CLI entry point (clap)
│   │   ├── config.rs           qualitas.config.js loader
│   │   └── reporters/          text, compact, detail, flagged, json, markdown, summary
│   │
│   └── qualitas-napi/          Node.js native binding (napi-rs)
│
├── js/                         TypeScript wrapper (thin layer over native binding)
│   ├── index.ts                Public API: analyzeSource, analyzeFile, analyzeProject
│   ├── types.ts                TypeScript interfaces mirroring Rust serde structs
│   ├── cli.ts                  Commander CLI (Node.js)
│   └── reporters/              text, json, markdown reporters
│
├── tests/
│   ├── shared/                 Cross-cutting tests (scoring, config, reporters, project)
│   ├── typescript/             TypeScript adapter tests + fixtures
│   └── _template/              Template for adding new language adapter tests
│
├── qualitas_napi.js            Platform-aware native binding loader (auto-generated)
└── bin/qualitas.js             Node.js CLI entry point shim

Supported languages

Adding a new language requires only one adapter file. See CONTRIBUTING_LANGUAGE.md.

Why Rust + napi-rs?

The core analysis engine is written in Rust for three reasons:

  1. Speed: oxc_parser (the parser powering Oxc/Biome/Rolldown) parses TypeScript at ~26ms vs SWC's ~84ms on large files. Arena-allocated AST with no GC pauses means analyzing 100+ file projects completes in under a second.

  2. Correctness: Rust's type system enforces exhaustive handling of all AST node variants at compile time. Missing a node type is a compile error, not a runtime bug.

  3. Distribution: The napi-rs optional-dependency pattern (same as SWC, Rspack, Oxlint) lets users npm install without any build toolchain. Pre-compiled binaries for all 5 platforms ship as separate optional packages and are selected automatically.

Event-based IR

Language adapters parse source code and emit a stream of QualitasEvent values (control flow, operators, operands, nesting, etc.). The 5 metric collectors consume these events without knowing anything about the source language. This makes adding a new language a matter of writing one adapter file — the scoring engine is fully language-agnostic.


Configuration

Create a qualitas.config.js in your project root. All fields are optional — CLI flags take priority.

Config file search order:

  1. Explicit -c / --config path (if provided)
  2. Walk up from the analyzed directory looking for qualitas.config.js
  3. Look next to the qualitas executable
module.exports = {
  // Exit code 1 if any function scores below this threshold (0-100)
  threshold: 80,

  // Fail on flags regardless of score: 'warn' | 'error'
  failOnFlags: 'error',

  // Weight profile: 'default' | 'cc-focused' | 'data-focused' | 'strict'
  profile: 'default',

  // Directories/files to exclude from analysis.
  // Only .git and qualitas.config.js are excluded by default — configure all others here.
  exclude: ['node_modules', 'dist', 'build', 'coverage', 'target'],

  // Per-flag configuration (enable/disable, custom thresholds).
  // Both camelCase and SCREAMING_SNAKE_CASE keys are supported.
  flags: {
    TOO_MANY_PARAMS: { warn: 5, error: 7 },
    EXCESSIVE_RETURNS: true,  // re-enable (disabled by default)
    DEEP_NESTING: false,      // disable entirely
  },

  // Per-language configuration
  languages: {
    typescript: {
      testPatterns: ['.test.', '.spec.', 'tests/'],
    },
    python: {
      testPatterns: ['test_', '_test.py', 'tests/', 'conftest.py'],
      // Per-language flag overrides (take precedence over global flags)
      flags: {
        TOO_MANY_PARAMS: { warn: 4, error: 6 },
      },
    },
    rust: {
      testPatterns: ['_test.rs', '_tests.rs', 'tests/'],
    },
  },
};

Building from Source

Prerequisites: Rust toolchain (≥1.75), Node.js (≥18), @napi-rs/cli v3

# Install Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# Install napi-rs CLI
npm install -g @napi-rs/cli

# Clone and build
git clone https://github.com/An631/qualitas.git
cd qualitas
npm install

# Build native binary (debug, fast)
npm run build:debug

# Build native binary (release, optimized)
npm run build

# Build TypeScript wrapper
npm run build:ts

# Run all tests
cargo test -p qualitas-core   # 146 Rust unit tests
npm run test:ts               # 69 JS integration tests

Testing

Rust unit tests (cargo test -p qualitas-core)

146 tests across all modules. Cover:

  • Per-language conformance tests (TypeScript, Rust, and Python adapters)
  • CFC, DCI, IRC, DC, SM metric collectors via event-based IR
  • Composite scorer saturation invariants (sublinearity, score bounds)
  • Flag generation with default and custom thresholds
  • Grade assignment across all profiles

JavaScript integration tests (npm run test:ts)

69 tests across tests/shared/ and tests/typescript/. Exercise the full stack (Rust → napi → JS):

  • Scoring invariants, config loading/merging, reporter output, project analysis
  • Flag overrides: camelCase and SCREAMING_SNAKE_CASE keys, custom thresholds, enable/disable
  • Per-language flag overrides via config parameter
  • TypeScript adapter: function collection patterns, class methods, arrow functions
  • Python adapter: function/class extraction, comprehensions, decorators, async/await
  • Weight profiles, threshold configuration, scope filtering

License

MIT