Skip to main content

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) — ceilings calibrated on six open-source C codebases; predictive validation is a pilot so far (see Metrics Reference)
  • Multi-Language: C, C++, Rust, Python, JavaScript, TypeScript, Ada, Go, Java, C#, Kotlin, Swift, PHP, Fortran, Scala, and Lua — one CLI across supported languages; calibrate thresholds for your project
  • 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, and exit 3 when a selected file could not be analysed; recommended --aird-threshold 85
  • Pre-commit Hook: native integration, no shim scripts required
  • Validated: McCabe agrees with pmccabe's traditional (per-case) count on 98.00% of 30,461 C functions across six pinned corpora (nearly all differences are in functions with #if arms); Cognitive follows the SonarSource specification, including the recursion increment other implementations omit. See Metrics Reference

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

Running a prebuilt binary requires no C compiler or project build system. Building from source requires Rust and a native C/C++ compiler for the bundled tree-sitter grammars.

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 (GNU xargs)
find . -type f \( -name "*.c" -o -name "*.rs" \) -print0 | xargs -0 -r knots --format ndjson > metrics.ndjson

# Testability matrix
knots -m src/main.c

The AIRD gate is calibrated mainly on C; it rarely fires on Rust or JS/TS. See ADR-0003 before choosing project thresholds.

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:
  --supported-languages            List compiled languages and extensions, then exit
  -l, --language <LANG>             Restrict analysis to a language or extension (repeatable)
  -q, --quiet                       Suppress normal output; retain threshold violations
  --score-components               Add AIRD/AICP components to JSON, NDJSON, or CSV
  --count-anonymous-closures        Emit anonymous functions as separate entries
  -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
  --unreachable-blocks-threshold <N> Exit 1 if any function has more than this many unreachable (dead-code) basic blocks (C/C++/Rust only)
  --report <FILE>                   Write a detailed report in multi-file text mode (opt-in)
  --completion-report <FILE>        Write what the scan analysed, and each file it could not, as JSON (any --format)
  --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
  --find-duplicates                 Report structurally duplicated functions across the corpus (--recursive only)
  --tier <function|block>           Select duplicate fingerprint granularity (default: function)
  --include-fixture-pairs           Keep tests/pass vs tests/fail fixture pairs in --find-duplicates output (excluded by default)
  --include-trivial-duplicates      Keep small-body, low-repeat groups (getters, one-assert tests) in --find-duplicates output (excluded by default)
  --dump-duplicates <FILE>          Write a JSON snapshot of --find-duplicates results, for later comparison via --diff-duplicates
  --diff-duplicates <BEFORE> <AFTER>  Compare two --dump-duplicates snapshots and summarize resolved/new/shrank/grew groups; exits without needing corpus files
  -j, --jobs <N>                    Parallel analysis threads (0 = auto-detect, 1 = sequential, default: 0)
  -h, --help                        Print help
  -V, --version                     Print version

Documentation

Full documentation is in the docs/ directory (Sphinx/RST):

Acknowledgements

knots' numbers are checked against independent tools, and several of its fixes were found by disagreeing with one of them. The comparison tables are in validation/probes/TOOLS.md and the corpus results in validation/README.md.

  • pmccabe (Paul Bame, Hewlett-Packard): the reference for McCabe complexity on C. Its separate "traditional" and "modified" columns let knots' switch counting, and much else, be checked function by function across six C corpora.
  • SLOCCount (David A. Wheeler): the reference for physical SLOC, built on the same definition knots follows.
  • cloc (Al Danial): the most widely used line counter, and the second SLOC reference.
  • SLOC, also: tokei and scc.
  • McCabe and Cognitive Complexity, other languages:

The metrics themselves follow their published definitions:

  • T. J. McCabe, "A Complexity Measure" (1976), and G. J. Myers' extension to compound conditions (1977);
  • G. Ann Campbell, Cognitive Complexity (SonarSource, version 1.7, 2023);
  • R. E. Park, Software Size Measurement (CMU/SEI-92-TR-20, 1992);
  • J. Fitzpatrick's ABC metric (1997).

knots parses every language with tree-sitter and its community grammars. The validation corpora are open-source projects, pinned in validation/README.md.

Upstream contributions

Fixes in other metric tools that came out of reading their sources against the published definitions, listed once the maintainers have merged them:

  • multimetric: the --bugpredict old Halstead estimate multiplied effort by 2/3 instead of raising it to the 2/3 power (Halstead's E^(2/3)/3000). Reported in issue #213 and fixed by the maintainer in PR #214.

AI Assistance

knots was developed with assistance from Claude (Anthropic), used for code generation, the metrics and language support, bug fixes, and documentation. From October 2026, Codex (OpenAI) also contributed documentation fixes and the tooling that enforces the agent and commit guidelines. Each of its changes was reviewed before it was merged.

Many earlier commits have a Co-Authored-By: Claude trailer, but not every AI-assisted commit does, so the trailers are not a complete record. From October 2026 the contribution is acknowledged once, here, and not with a co-author trailer on each commit.

License

MIT. Copyright 2025-2026 BISSELL Homecare, Inc.

Metadata

Release files for knots 2.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for knots 2.0.0
File Size Uploaded Provenance
knots-2.0.0.tar.gz 310.2 kB With provenance Details

Built distributions (wheels)

Table of built distributions (wheels) for knots 2.0.0
File
knots-2.0.0-py3-none-win_amd64.whl Python 3 none Windows x86-64 Details
knots-2.0.0-py3-none-musllinux_1_2_x86_64.whl Python 3 none Linux musl 1.2+ x86-64 Details
knots-2.0.0-py3-none-musllinux_1_2_aarch64.whl Python 3 none Linux musl 1.2+ ARM64 Details
knots-2.0.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl Python 3 none Linux glibc 2.17+ x86-64 Details
knots-2.0.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl Python 3 none Linux glibc 2.17+ ARM64 Details
knots-2.0.0-py3-none-macosx_11_0_arm64.whl Python 3 none macOS 11.0+ ARM64 Details
knots-2.0.0-py3-none-macosx_10_12_x86_64.whl Python 3 none macOS 10.12+ x86-64 Details

Total release size: 38.0 MB

Release files / knots-2.0.0.tar.gz

Download URL knots-2.0.0.tar.gz
Size 310.2 kB
Tags Source
SHA-256 checksum
How to use checksums
c0c72512ba24d465e85352558e763135fabb32b8881cf60659cc66b91a8057a6
BLAKE2b-256 checksum
How to use checksums
b7bfc910569f0f7d510f15d23ad3c89a3b73e701676517fa9cf24ac01a46806d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 23, 2026.

Transparency log

Release files / knots-2.0.0-py3-none-win_amd64.whl

Download URL knots-2.0.0-py3-none-win_amd64.whl
Size 5.0 MB
Tags Python 3 Windows x86-64
SHA-256 checksum
How to use checksums
87db130a9f5ed9a96abf4698e2f2da20bce17b16cd73572f1ad562ff19aa1b0d
BLAKE2b-256 checksum
How to use checksums
eb70d116f1094f702aeafd601c50e7c81392f8aed55c37f21aaa736cb49ba658
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 23, 2026.

Transparency log

Release files / knots-2.0.0-py3-none-musllinux_1_2_x86_64.whl

Download URL knots-2.0.0-py3-none-musllinux_1_2_x86_64.whl
Size 5.6 MB
Tags Linux musl 1.2+ x86-64 Python 3
SHA-256 checksum
How to use checksums
91ae65bd9fd394e1efdc84a0e186184abed493ed9fa6566ec60b75a424ef2ef5
BLAKE2b-256 checksum
How to use checksums
2b1de5f7e9d71c95b9117668fa1ea790ed0d2588d8fff896e3d616adcbbd6228
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 23, 2026.

Transparency log

Release files / knots-2.0.0-py3-none-musllinux_1_2_aarch64.whl

Download URL knots-2.0.0-py3-none-musllinux_1_2_aarch64.whl
Size 5.4 MB
Tags Linux musl 1.2+ ARM64 Python 3
SHA-256 checksum
How to use checksums
ab4b634a5cd15dcd6fc2c6eb85673cb7b477f3e4f534d1ced1c657f0fb03e933
BLAKE2b-256 checksum
How to use checksums
26098d89417f66936f00ae14960549427473c67ccf105085047cb7d8f34e3749
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 23, 2026.

Transparency log

Release files / knots-2.0.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL knots-2.0.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 5.4 MB
Tags Linux glibc 2.17+ x86-64 Python 3
SHA-256 checksum
How to use checksums
3026f10afca7f467331927af733bc89faad1ad3d1b559217bd133b3b0d0083be
BLAKE2b-256 checksum
How to use checksums
2230e214bd5f3965971aae564b0aba30ac7638bf69e88eae98e8d396129fee4e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 23, 2026.

Transparency log

Release files / knots-2.0.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL knots-2.0.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 5.5 MB
Tags Linux glibc 2.17+ ARM64 Python 3
SHA-256 checksum
How to use checksums
b5e0cd146ac573e6c7d0f0b1e4d8a3fba26fca4c67e36d71d2a35bf2ad06d6bc
BLAKE2b-256 checksum
How to use checksums
95ae614a6d4e7eb04e0baa1c233ce430fa5e89a1fd161941fb7eadc69cba9738
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 23, 2026.

Transparency log

Release files / knots-2.0.0-py3-none-macosx_11_0_arm64.whl

Download URL knots-2.0.0-py3-none-macosx_11_0_arm64.whl
Size 5.4 MB
Tags Python 3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
46c7e5318005e9ad1403338d7ab569ce3c3bfc50259a4ce277f7d85919398d37
BLAKE2b-256 checksum
How to use checksums
f08eea4ea1911b59b2efc9c83e763c3a15f5965ed087283c53c53403c8dbd064
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 23, 2026.

Transparency log

Release files / knots-2.0.0-py3-none-macosx_10_12_x86_64.whl

Download URL knots-2.0.0-py3-none-macosx_10_12_x86_64.whl
Size 5.3 MB
Tags Python 3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
8c60d9d35a0bd8001521b3ef313a16101cd9ff061fbc3b48ded34fecc01fa604
BLAKE2b-256 checksum
How to use checksums
3f4335c28891ee524736f5cad0a49334b0f2c8f2d555a5cea941f93d9250ee74
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 23, 2026.

Transparency log

Security for knots 2.0.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 8 files in this release have been uploaded with provenance metadata.

Select from 8 files

Attestation for knots-2.0.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 23, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page