# code-metrics

Static code-metrics pack: language-agnostic complexity and quality analysis by heuristic parsing (no compiler, no AST library). Counts cyclomatic complexity from branch/decision keywords...


**Language-agnostic static code metrics** by heuristic parsing — no compiler, no AST library. Feed it
source code and it measures complexity, size, and quality. Works on JavaScript/TypeScript, Python,
Java, C/C++, C#, Go, Rust, Ruby, and PHP (comment syntax + keyword set per language, auto-detected).

It is an *intelligent microservice*: every tool has a deterministic heuristic core that runs fully
offline; `summary` can optionally add a plain-English AI review and silently falls back to the
scorecard. Results are tagged `{ mode: 'heuristic' | 'llm' }` where a model can contribute.

## How it works

Comments and string/char literals are stripped **first** (length-preserving), so keyword counts never
fire inside comments or strings. Then:

- **cyclomatic** = `1 + decision points` (branch keywords + `&&`/`||` + ternary) — the McCabe approximation.
- **halstead** — distinct/total operators & operands → volume, difficulty, effort, time, estimated bugs.
- **maintainabilityIndex** — the SEI/Visual-Studio formula, normalized to `0..100` with a rating.
- **loc** — SLOC vs comment vs blank, and comment ratio.
- **duplicationEstimate** — k-line shingling: fraction of repeated line-windows (cheap clone density).
- **functionCount** — multi-language signature patterns + anonymous callbacks + avg lines/function.
- **summary** — all of the above plus a composite `0..100` health score, letter grade, and flags.

## Tools

| Tool | Output |
|---|---|
| `cyclomatic` | `{ complexity, decisionPoints, rating, breakdown }` |
| `maintainabilityIndex` | `{ maintainabilityIndex, rating, inputs }` |
| `halstead` | operators/operands, `volume`, `difficulty`, `effort`, `estimatedBugs` |
| `loc` | `{ total, source, comment, blank, commentRatio }` |
| `duplicationEstimate` | `{ duplicationRatio, duplicatedWindows, rating }` |
| `functionCount` | `{ functions, anonymousCallbacks, avgLinesPerFunction }` |
| `summary` | composite scorecard + `healthScore` + `grade` + `flags` (+ optional `review`) |

## Usage

```js
import metrics from './index.js';

metrics.adapters.cyclomatic({ code: 'function f(x){ if(x>0){for(;;){}} return x && 1; }' });
// -> { complexity: 4, decisionPoints: 3, rating: 'simple', breakdown: { if:1, for:1, '&&/||':1 } }

metrics.adapters.summary({ code: sourceString, language: 'python' });
// -> { healthScore: 72, grade: 'B', flags: [...], metrics: { loc, cyclomatic, halstead, ... } }
```

## DRY boundary

Measures **source code** (complexity/quality). Distinct from **`changelog`** (commit/release tooling)
and the **`toolkit`** algorithm/graph utilities. Self-contained (Node built-ins + `../_shared/llm.js`).


---
Source: shared/engines/adapters/domain/code-metrics/README.md
Canonical: https://docs.leumas.tech/p/adapters/domain/code-metrics
