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) — corpus-validated against 32,205 functions across 6 open-source C codebases
  • Multi-Language: C, C++, Rust, Python, JavaScript, TypeScript, Ada, Go, Java, C#, Kotlin, Swift, PHP, Fortran, Scala, and Lua — 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
  --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 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
  --find-duplicates                 Report structurally duplicated functions across the corpus (--recursive only)
  --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):

License

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

knots-1.15.0.tar.gz (221.5 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

knots-1.15.0-py3-none-win_amd64.whl (4.8 MB view details)

Uploaded Python 3Windows x86-64

knots-1.15.0-py3-none-musllinux_1_2_x86_64.whl (5.4 MB view details)

Uploaded Python 3musllinux: musl 1.2+ x86-64

knots-1.15.0-py3-none-musllinux_1_2_aarch64.whl (5.2 MB view details)

Uploaded Python 3musllinux: musl 1.2+ ARM64

knots-1.15.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (5.2 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ x86-64

knots-1.15.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (5.3 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ ARM64

knots-1.15.0-py3-none-macosx_11_0_arm64.whl (5.3 MB view details)

Uploaded Python 3macOS 11.0+ ARM64

knots-1.15.0-py3-none-macosx_10_12_x86_64.whl (5.1 MB view details)

Uploaded Python 3macOS 10.12+ x86-64

File details

Details for the file knots-1.15.0.tar.gz.

File metadata

  • Download URL: knots-1.15.0.tar.gz
  • Upload date:
  • Size: 221.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for knots-1.15.0.tar.gz
Algorithm Hash digest
SHA256 7a79e6af83c0b39cc38631fd4e85508ed21525124d8d26dc6502d4fca65d4841
MD5 58f725523946d37078d243e710c7dc3e
BLAKE2b-256 8927659cd5169290f2e9f1bfbbd51eef9ba975712c4d4f76a70ecc84ecc5c829

See more details on using hashes here.

Provenance

The following attestation bundles were made for knots-1.15.0.tar.gz:

Publisher: wheels.yml on brandon-arrendondo/knots

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file knots-1.15.0-py3-none-win_amd64.whl.

File metadata

  • Download URL: knots-1.15.0-py3-none-win_amd64.whl
  • Upload date:
  • Size: 4.8 MB
  • Tags: Python 3, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for knots-1.15.0-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 6b1e3eea905eb8dc46a699424d1b4c8d81dcfcd285bce8f4d75051d5559580b9
MD5 0882768a9b385797431332da751d406e
BLAKE2b-256 31a2813ee2f588e5b82691d6aabff2f44d7390629dabbe8967c313d76464a6f7

See more details on using hashes here.

Provenance

The following attestation bundles were made for knots-1.15.0-py3-none-win_amd64.whl:

Publisher: wheels.yml on brandon-arrendondo/knots

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file knots-1.15.0-py3-none-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for knots-1.15.0-py3-none-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 a7e0aed4d5c776ace9cb2a6885ca9f58086143ea066f4efbbe2a842b9341e646
MD5 8f3a2091396dcca5d28d86271c987579
BLAKE2b-256 dd8292403ec4ac6763cd593430aaab783141c2d7b7f26f1a4c5493499963ae0e

See more details on using hashes here.

Provenance

The following attestation bundles were made for knots-1.15.0-py3-none-musllinux_1_2_x86_64.whl:

Publisher: wheels.yml on brandon-arrendondo/knots

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file knots-1.15.0-py3-none-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for knots-1.15.0-py3-none-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 61e7d91c059f9154d4e1e0ce9928ca2b8d4f3c5c3f78da1119bbcdc2bd36ec66
MD5 a442c78e245d5bf7d51cc8ed2cfb0bcf
BLAKE2b-256 69f7c8e7f6d7d5121b9d14246e2b6c8854abf52dd6a88758ccfb48fdf5f5307f

See more details on using hashes here.

Provenance

The following attestation bundles were made for knots-1.15.0-py3-none-musllinux_1_2_aarch64.whl:

Publisher: wheels.yml on brandon-arrendondo/knots

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file knots-1.15.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for knots-1.15.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 74d3d7d6cb2c676ada158980149a8bdca8847e497275a2196ba1350e92fd0b50
MD5 3e5ef34f332bed4db6dd42a007409145
BLAKE2b-256 2b302e32db9f0d11d5515a644211fb7ef8d184ff48ce0fb2e50bb59758c28e09

See more details on using hashes here.

Provenance

The following attestation bundles were made for knots-1.15.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: wheels.yml on brandon-arrendondo/knots

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file knots-1.15.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for knots-1.15.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 7fd2fe8f3f4d1a4f7f1659f91952f4486383b2afd4378e4d2eed9313ccee13dc
MD5 269e9fcc36af271ea7eab05ed38fb2b2
BLAKE2b-256 4f3cc310d567a703c9ecd0cc87f65263adee100a6e98df25549f94fcc1e22983

See more details on using hashes here.

Provenance

The following attestation bundles were made for knots-1.15.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: wheels.yml on brandon-arrendondo/knots

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file knots-1.15.0-py3-none-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for knots-1.15.0-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 8eacebe43bb5268779f2f3859fb42258b2b57c16e132d43627dcf5e7b35ca398
MD5 416d99fe2a0d06467116d6218e186463
BLAKE2b-256 0e6c89c893c6ced4a1a017aa56a54a44ca9b51e2f5cda826661e4f7121e61c6c

See more details on using hashes here.

Provenance

The following attestation bundles were made for knots-1.15.0-py3-none-macosx_11_0_arm64.whl:

Publisher: wheels.yml on brandon-arrendondo/knots

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file knots-1.15.0-py3-none-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for knots-1.15.0-py3-none-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 6f07dec628e72bf2c25b161488540e158f83cd2491b741f33d082cb50d3733ae
MD5 facef1f091ee81e5bace0b00ac7d7a14
BLAKE2b-256 64529933b228c58848155437dc38453e10c5ed43609039a34591ecd38ce784dc

See more details on using hashes here.

Provenance

The following attestation bundles were made for knots-1.15.0-py3-none-macosx_10_12_x86_64.whl:

Publisher: wheels.yml on brandon-arrendondo/knots

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

1.16.0

8 files

1.15.1

8 files

This release

1.15.0 This release

8 files

1.14.0

8 files

1.13.1

8 files

1.13.0

8 files

1.12.0

8 files

1.11.0

8 files

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