Multi-language code complexity analyzer with AI cost metrics (AIRD, AICP), SARIF/JSON/CSV output, and CI threshold enforcement
Project description
Knots
A fast multi-language code complexity analyzer built on tree-sitter. Knots measures traditional complexity metrics alongside two AI-specific cost scores — AIRD (AI Reasoning Difficulty) and AICP (AI Context Pressure) — to identify which functions are genuinely expensive to modify with AI assistance.
Features
- Multiple Complexity Metrics: McCabe, Cognitive, Nesting Depth, SLOC, ABC, Test Scoring
- AI Cost Metrics: AIRD (reasoning difficulty) and AICP (context pressure) — corpus-validated against 32,205 functions across 6 open-source C codebases
- Multi-Language: C, C++, Rust, Python, JavaScript, TypeScript, and Ada — same metrics and thresholds across all supported languages
- Testability Matrix: Categorize functions by complexity and testability
- Multiple Output Formats: text, SARIF, JSON, NDJSON (find/xargs-composable), CSV
- CI Threshold Enforcement: exit 1 on any threshold violation; recommended
--aird-threshold 85 - Pre-commit Hook: native integration, no shim scripts required
- Validated: McCabe matches pmccabe exactly; Cognitive matches Mozilla rust-code-analysis at 1.004× mean ratio (11,365 Rust functions)
Installation
Prebuilt binary from PyPI (no Rust toolchain, installs in seconds):
pipx install knots # or: uv tool install knots
From crates.io:
cargo install knots
Or from source:
git clone https://github.com/brandon-arrendondo/knots.git
cd knots
cargo build --release
No C compiler or build system required.
Quick Start
# Single file
knots src/main.c
# Recursive directory
knots -r src/
# CI gate — fail if any function has AIRD > 85
knots -r src/ --aird-threshold 85
# Adopt the gate on a legacy codebase: snapshot today, then fail only on regressions
knots -r src/ --aird-threshold 85 --baseline .knots-baseline.json --write-baseline
knots -r src/ --aird-threshold 85 --baseline .knots-baseline.json
# Gate only the functions you actually touched (no new debt in this change)
knots -r src/ --aird-threshold 85 --changed
# SARIF for GitHub Code Scanning
knots -r --format sarif src/ > knots.sarif
# Corpus analysis — one JSON record per function
find . -name "*.c" -o -name "*.rs" | xargs knots --format ndjson > metrics.ndjson
# Testability matrix
knots -m src/main.c
Complexity Indicators
Based on max(McCabe, cognitive):
| Range | Indicator | Meaning |
|---|---|---|
| 1–10 | 😊 Good | Low complexity, easy to maintain |
| 11–20 | 😐 Okay | Moderate complexity, monitor |
| 21–49 | 😠 Bad | High complexity, consider refactoring |
| 50+ | 😢 Critical | Urgent refactoring needed |
Command-Line Options
knots [OPTIONS] [FILE]...
knots [OPTIONS] --compile-commands <FILE>
Options:
-r, --recursive Recursively process all supported source files in directories
-v, --verbose Show detailed per-function analysis
-m, --matrix Show testability matrix categorization
--compile-commands <FILE> Use compile_commands.json to get file list
--include <FILE> Include filter rules from JSON file (whitelist)
--exclude <FILE> Exclude filter rules from JSON file (blacklist)
--exclude-path <PATTERN> Exclude files whose path matches this regex (repeatable)
--format <FORMAT> text (default) | sarif | json | ndjson | csv
--mccabe-threshold <N> Exit 1 if any function exceeds this McCabe complexity
--cognitive-threshold <N> Exit 1 if any function exceeds this cognitive complexity
--nesting-threshold <N> Exit 1 if any function exceeds this nesting depth
--sloc-threshold <N> Exit 1 if any function exceeds this SLOC count
--abc-threshold <F> Exit 1 if any function exceeds this ABC magnitude
--return-threshold <N> Exit 1 if any function exceeds this return count
--aird-threshold <N> Exit 1 if any function exceeds this AIRD (AI Reasoning Difficulty) score (recommended: 85)
--aicp-threshold <N> Exit 1 if any function exceeds this AICP (AI Context Pressure) score
--external-calls-threshold <N> Exit 1 if any function exceeds this external call count
--report <FILE> Write a detailed per-function report to this file (opt-in)
--baseline <FILE> Ratchet mode: gate only on regressions vs. this snapshot (see docs/baseline.rst)
--write-baseline Snapshot current scores to --baseline and exit without gating
--since <REF> Gate only functions overlapping lines changed since this git ref
--changed Gate only functions changed in the working tree (sugar for --since HEAD)
--explain <METRIC> Explain a metric (e.g. aird, aicp) and how to lower it, then exit
-h, --help Print help
-V, --version Print version
Documentation
Full documentation is in the docs/ directory (Sphinx/RST):
- Installation
- Quick Start & Usage Examples
- CLI Reference
- Metrics Reference — AIRD/AICP formulas, corpus validation
- Output Formats — JSON schema, SARIF, NDJSON corpus patterns
- CI Integration — GitHub Actions, pre-commit hook
- Baseline / Ratchet Mode — adopt the gate on legacy code, fail only on regressions
- Filter Rules —
--include/--excludewhitelists/blacklists - Test Quality Analysis — knots-test-complexity companion tool
- Alternatives Comparison — vs. lizard, rust-code-analysis, clippy; cognitive algorithm differences
- Troubleshooting
License
MIT
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
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file knots-1.12.0.tar.gz.
File metadata
- Download URL: knots-1.12.0.tar.gz
- Upload date:
- Size: 140.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c9fa408a233f03b45e1cb084051bf1486a1a616638737dd362711af7a6014ad0
|
|
| MD5 |
73acc8e9b27a4f35f71f9c93107dfdf7
|
|
| BLAKE2b-256 |
566f7d38a239d264538feaadb0ec61b9595c45d7113aff322d05442e8f03b3b0
|
Provenance
The following attestation bundles were made for knots-1.12.0.tar.gz:
Publisher:
wheels.yml on brandon-arrendondo/knots
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
knots-1.12.0.tar.gz -
Subject digest:
c9fa408a233f03b45e1cb084051bf1486a1a616638737dd362711af7a6014ad0 - Sigstore transparency entry: 1983514189
- Sigstore integration time:
-
Permalink:
brandon-arrendondo/knots@d6871d437a4e5b1d1c703f5bf4ed9c5db8fbcc1a -
Branch / Tag:
refs/tags/v1.12.0 - Owner: https://github.com/brandon-arrendondo
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
wheels.yml@d6871d437a4e5b1d1c703f5bf4ed9c5db8fbcc1a -
Trigger Event:
push
-
Statement type:
File details
Details for the file knots-1.12.0-py3-none-win_amd64.whl.
File metadata
- Download URL: knots-1.12.0-py3-none-win_amd64.whl
- Upload date:
- Size: 2.1 MB
- Tags: Python 3, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d04748d297816e18abec046a2f2c3f176b10c39dd9f284b35876bc3e6cbc9061
|
|
| MD5 |
8620ddfed93a133b3a8250c5cf83f97b
|
|
| BLAKE2b-256 |
1e7a17798d6c29ca77fd4be077df33cec8a2b57369d51d2d72fa4f4620d8c95c
|
Provenance
The following attestation bundles were made for knots-1.12.0-py3-none-win_amd64.whl:
Publisher:
wheels.yml on brandon-arrendondo/knots
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
knots-1.12.0-py3-none-win_amd64.whl -
Subject digest:
d04748d297816e18abec046a2f2c3f176b10c39dd9f284b35876bc3e6cbc9061 - Sigstore transparency entry: 1983514925
- Sigstore integration time:
-
Permalink:
brandon-arrendondo/knots@d6871d437a4e5b1d1c703f5bf4ed9c5db8fbcc1a -
Branch / Tag:
refs/tags/v1.12.0 - Owner: https://github.com/brandon-arrendondo
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
wheels.yml@d6871d437a4e5b1d1c703f5bf4ed9c5db8fbcc1a -
Trigger Event:
push
-
Statement type:
File details
Details for the file knots-1.12.0-py3-none-musllinux_1_2_x86_64.whl.
File metadata
- Download URL: knots-1.12.0-py3-none-musllinux_1_2_x86_64.whl
- Upload date:
- Size: 2.5 MB
- Tags: Python 3, musllinux: musl 1.2+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f842c65eac9d86d8cda9196d58e6054f5bd130a7ab5d4c051fd46fbd4509b65c
|
|
| MD5 |
73f31954a56672b10020d930d6e06475
|
|
| BLAKE2b-256 |
198904178e2e29645bb44c0c35bb8bbd3b9459a7238b34b3949f1dec3ab71a43
|
Provenance
The following attestation bundles were made for knots-1.12.0-py3-none-musllinux_1_2_x86_64.whl:
Publisher:
wheels.yml on brandon-arrendondo/knots
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
knots-1.12.0-py3-none-musllinux_1_2_x86_64.whl -
Subject digest:
f842c65eac9d86d8cda9196d58e6054f5bd130a7ab5d4c051fd46fbd4509b65c - Sigstore transparency entry: 1983515105
- Sigstore integration time:
-
Permalink:
brandon-arrendondo/knots@d6871d437a4e5b1d1c703f5bf4ed9c5db8fbcc1a -
Branch / Tag:
refs/tags/v1.12.0 - Owner: https://github.com/brandon-arrendondo
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
wheels.yml@d6871d437a4e5b1d1c703f5bf4ed9c5db8fbcc1a -
Trigger Event:
push
-
Statement type:
File details
Details for the file knots-1.12.0-py3-none-musllinux_1_2_aarch64.whl.
File metadata
- Download URL: knots-1.12.0-py3-none-musllinux_1_2_aarch64.whl
- Upload date:
- Size: 2.4 MB
- Tags: Python 3, musllinux: musl 1.2+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c5745dc545edf5ea45e6abd2fabc7e4db6705e8f4f20dd1bcc4f97faeab52384
|
|
| MD5 |
14077ab4dc11c516517f479edbf37696
|
|
| BLAKE2b-256 |
f436022f15f2966fcae2e583669a78cb7ff37a769f3bef5081fc7be39aaef263
|
Provenance
The following attestation bundles were made for knots-1.12.0-py3-none-musllinux_1_2_aarch64.whl:
Publisher:
wheels.yml on brandon-arrendondo/knots
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
knots-1.12.0-py3-none-musllinux_1_2_aarch64.whl -
Subject digest:
c5745dc545edf5ea45e6abd2fabc7e4db6705e8f4f20dd1bcc4f97faeab52384 - Sigstore transparency entry: 1983515351
- Sigstore integration time:
-
Permalink:
brandon-arrendondo/knots@d6871d437a4e5b1d1c703f5bf4ed9c5db8fbcc1a -
Branch / Tag:
refs/tags/v1.12.0 - Owner: https://github.com/brandon-arrendondo
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
wheels.yml@d6871d437a4e5b1d1c703f5bf4ed9c5db8fbcc1a -
Trigger Event:
push
-
Statement type:
File details
Details for the file knots-1.12.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: knots-1.12.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 2.4 MB
- Tags: Python 3, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ef3c20d0149ff6e5fc1f3c4a3196ca0c9305df463595687272607e727f3cae7b
|
|
| MD5 |
58005337b2cc6b5eb9126852c5a86415
|
|
| BLAKE2b-256 |
cc5d25d1d74e472988e9a156335b85d5092729e34f5e26f273fd7591460fa97a
|
Provenance
The following attestation bundles were made for knots-1.12.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:
Publisher:
wheels.yml on brandon-arrendondo/knots
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
knots-1.12.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl -
Subject digest:
ef3c20d0149ff6e5fc1f3c4a3196ca0c9305df463595687272607e727f3cae7b - Sigstore transparency entry: 1983514502
- Sigstore integration time:
-
Permalink:
brandon-arrendondo/knots@d6871d437a4e5b1d1c703f5bf4ed9c5db8fbcc1a -
Branch / Tag:
refs/tags/v1.12.0 - Owner: https://github.com/brandon-arrendondo
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
wheels.yml@d6871d437a4e5b1d1c703f5bf4ed9c5db8fbcc1a -
Trigger Event:
push
-
Statement type:
File details
Details for the file knots-1.12.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: knots-1.12.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 2.4 MB
- Tags: Python 3, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ed4e2c26ae199c89c410437335fcd2b2225a8ee8bd68df0718fe2ba08d938ce5
|
|
| MD5 |
8a2c612398d075ebf90275f5cf212e5c
|
|
| BLAKE2b-256 |
b227e1d4eac2ba2606db8c4816106dba2616cf6ff024107286e2329637b5e6f7
|
Provenance
The following attestation bundles were made for knots-1.12.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:
Publisher:
wheels.yml on brandon-arrendondo/knots
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
knots-1.12.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl -
Subject digest:
ed4e2c26ae199c89c410437335fcd2b2225a8ee8bd68df0718fe2ba08d938ce5 - Sigstore transparency entry: 1983515833
- Sigstore integration time:
-
Permalink:
brandon-arrendondo/knots@d6871d437a4e5b1d1c703f5bf4ed9c5db8fbcc1a -
Branch / Tag:
refs/tags/v1.12.0 - Owner: https://github.com/brandon-arrendondo
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
wheels.yml@d6871d437a4e5b1d1c703f5bf4ed9c5db8fbcc1a -
Trigger Event:
push
-
Statement type:
File details
Details for the file knots-1.12.0-py3-none-macosx_11_0_arm64.whl.
File metadata
- Download URL: knots-1.12.0-py3-none-macosx_11_0_arm64.whl
- Upload date:
- Size: 2.3 MB
- Tags: Python 3, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
83131c56072c8e1daca3838bb6bf55b9f768f17574442dee787ada76bf44b752
|
|
| MD5 |
e23f02914a0c341392573ea05cff787e
|
|
| BLAKE2b-256 |
e85398b5dc5cb771094b5d0af795698d26743da5033803f8a5696fed1ac165ee
|
Provenance
The following attestation bundles were made for knots-1.12.0-py3-none-macosx_11_0_arm64.whl:
Publisher:
wheels.yml on brandon-arrendondo/knots
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
knots-1.12.0-py3-none-macosx_11_0_arm64.whl -
Subject digest:
83131c56072c8e1daca3838bb6bf55b9f768f17574442dee787ada76bf44b752 - Sigstore transparency entry: 1983516719
- Sigstore integration time:
-
Permalink:
brandon-arrendondo/knots@d6871d437a4e5b1d1c703f5bf4ed9c5db8fbcc1a -
Branch / Tag:
refs/tags/v1.12.0 - Owner: https://github.com/brandon-arrendondo
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
wheels.yml@d6871d437a4e5b1d1c703f5bf4ed9c5db8fbcc1a -
Trigger Event:
push
-
Statement type:
File details
Details for the file knots-1.12.0-py3-none-macosx_10_12_x86_64.whl.
File metadata
- Download URL: knots-1.12.0-py3-none-macosx_10_12_x86_64.whl
- Upload date:
- Size: 2.3 MB
- Tags: Python 3, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e86c32e6e48d0fa882f1fd149985eb9948ade5e57955ee4ec7794dfba8de12ee
|
|
| MD5 |
a97936fb511bc459c671e52b6c7b0924
|
|
| BLAKE2b-256 |
2b3c4bf1e17bd3f228f77d06556b015b090271138ded2baf4766b4a1b4c837cc
|
Provenance
The following attestation bundles were made for knots-1.12.0-py3-none-macosx_10_12_x86_64.whl:
Publisher:
wheels.yml on brandon-arrendondo/knots
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
knots-1.12.0-py3-none-macosx_10_12_x86_64.whl -
Subject digest:
e86c32e6e48d0fa882f1fd149985eb9948ade5e57955ee4ec7794dfba8de12ee - Sigstore transparency entry: 1983514629
- Sigstore integration time:
-
Permalink:
brandon-arrendondo/knots@d6871d437a4e5b1d1c703f5bf4ed9c5db8fbcc1a -
Branch / Tag:
refs/tags/v1.12.0 - Owner: https://github.com/brandon-arrendondo
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
wheels.yml@d6871d437a4e5b1d1c703f5bf4ed9c5db8fbcc1a -
Trigger Event:
push
-
Statement type: