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; 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)
  --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 1.19.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 1.19.0
File Size Uploaded Provenance
knots-1.19.0.tar.gz 290.2 kB With provenance Details

Built distributions (wheels)

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

Total release size: 37.8 MB

Release files / knots-1.19.0.tar.gz

Download URL knots-1.19.0.tar.gz
Size 290.2 kB
Tags Source
SHA-256 checksum
How to use checksums
5ca86a10c59d7794ecfd52a7dc2a32d444d8d1a60a9ad607a879300528ff22bd
BLAKE2b-256 checksum
How to use checksums
bb8e9899e3ba6024a7b439fc81920ce195e009c17bbb512a37f946592b6e0f4c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 19, 2026.

Transparency log

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

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

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 19, 2026.

Transparency log

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

Download URL knots-1.19.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
4c02d45b62efb9bde1554d480a151de612a995ecafde34c9f005807a9ca30548
BLAKE2b-256 checksum
How to use checksums
7bbab9e89bb8b43f88676d1c69fc29b90bbeb431d6a0dc1146fcb92007277cc1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 19, 2026.

Transparency log

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

Download URL knots-1.19.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
9c596fddb8f47fa5a9013bc7e10e08106b65706a872817b423057e16ae8eb33f
BLAKE2b-256 checksum
How to use checksums
0918e33e5d8cc1b62249581ed57920899694048f312b721fa861881f745b6a5a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 19, 2026.

Transparency log

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

Download URL knots-1.19.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
557f81c59cc3f449ba9d286dff2101f0e444f6e86b4f78312d5e5df9fc87595e
BLAKE2b-256 checksum
How to use checksums
caa9e1594a019249ddf9528678119ecc246d1cec1371e81ea93d5e2ef390c864
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 19, 2026.

Transparency log

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

Download URL knots-1.19.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
74d8043f54c5b26c1049ef21b48252c5a176968bcd25bdccf37c8e83bc0e6403
BLAKE2b-256 checksum
How to use checksums
c869a055820c3857b4fae0fa060856b00f97a37dcccc2875bdb46976d7580208
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 19, 2026.

Transparency log

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

Download URL knots-1.19.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
9867582631383ba1747b48ec7375df7bf53b4b16b2255f992af00bc6422a4c8d
BLAKE2b-256 checksum
How to use checksums
c36f2259e8f2ba2ccd8ade065044e557580a0be32a7f0ec50cf652241be267fe
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 19, 2026.

Transparency log

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

Download URL knots-1.19.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
c683e68de3cf84e73552c4ea1abf7c03ed2ec3e588f2555b72d820834595eed9
BLAKE2b-256 checksum
How to use checksums
0bc1b2e25cb40ca4c49d4fd604aef61a9970a4a4750284cc874ade438727184b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 19, 2026.

Transparency log

Security for knots 1.19.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-1.19.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 19, 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