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.16.0.tar.gz (230.0 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.16.0-py3-none-win_amd64.whl (4.9 MB view details)

Uploaded Python 3Windows x86-64

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

Uploaded Python 3musllinux: musl 1.2+ x86-64

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

Uploaded Python 3musllinux: musl 1.2+ ARM64

knots-1.16.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (5.3 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ x86-64

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

Uploaded Python 3manylinux: glibc 2.17+ ARM64

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

Uploaded Python 3macOS 11.0+ ARM64

knots-1.16.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.16.0.tar.gz.

File metadata

  • Download URL: knots-1.16.0.tar.gz
  • Upload date:
  • Size: 230.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for knots-1.16.0.tar.gz
Algorithm Hash digest
SHA256 417d1872da51a7d75445ccecbf3bc5c2e7c4e7bef400a502492aa974b862fbf1
MD5 67dcee77d5e4d30107fa78ddcaf380ad
BLAKE2b-256 6557ed403c2511838addaeddc47f3bc6d2eaf132d250b9b427effe7d9c80c41a

See more details on using hashes here.

Provenance

The following attestation bundles were made for knots-1.16.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.16.0-py3-none-win_amd64.whl.

File metadata

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

File hashes

Hashes for knots-1.16.0-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 8eb81a031672bf54dac46ffc35cfd3efd0bbdcb5fe0bbe90fd3bebe115b2f28f
MD5 e169a8d7c0f6bb3478b18127cb907934
BLAKE2b-256 6ea3217e9f3a1b875dd4ecf4d467acffc577bdc94c0c8eff5ef5faecc064cf16

See more details on using hashes here.

Provenance

The following attestation bundles were made for knots-1.16.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.16.0-py3-none-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for knots-1.16.0-py3-none-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 32b41fc64f0a10435d27d52becd64434bad10ac8930c76e61bae5c4d3a2f0079
MD5 4bd824f723694d35d7195f8437605f34
BLAKE2b-256 3a2f43b41fb43e2f12b365c50c6c2cdd837b4efd714574f7017753733772aff0

See more details on using hashes here.

Provenance

The following attestation bundles were made for knots-1.16.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.16.0-py3-none-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for knots-1.16.0-py3-none-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 70cb008face19f13ebcc7c69df524e62ff30c46f2b1ffb4b0d48fad5df4cac88
MD5 c457d2d6eb1d3412ee24c43676816a2c
BLAKE2b-256 69f36a5772a2c4c46b6e3633f05fdd5216fcbc5b870415266100c6de7c556a20

See more details on using hashes here.

Provenance

The following attestation bundles were made for knots-1.16.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.16.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for knots-1.16.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 31bb9633d04ea219683fcbad73c5b060967849250b1a947a57f3383dd57b3d1a
MD5 fd8cdcdb941cb8cc89ab5f8aafeb3007
BLAKE2b-256 35d865aadff1b1009155f6b22c2c20f1e1e6f1508a885e60556e24cbaa7dd02b

See more details on using hashes here.

Provenance

The following attestation bundles were made for knots-1.16.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.16.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for knots-1.16.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 672c054de2d4fd8c4657ba1c1fb8c110f14b7ab03bd765f2141b7a89aa2e7d00
MD5 3021277b8d9d199693bcf20504b54a5b
BLAKE2b-256 e95597f7bd55e4326dfe26bc0267441d6de04a1c10eac898bd6fcae4e170d039

See more details on using hashes here.

Provenance

The following attestation bundles were made for knots-1.16.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.16.0-py3-none-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for knots-1.16.0-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 9ca8009696d15d1cd992f3cfbab0dde0d5ba74929e9e84a05444c00f57f8b6a7
MD5 89c61994a0ea9a8b6f7d2e2e5cdc2ecc
BLAKE2b-256 c18148ceb90a118adb2b15e6a9be3c84f4564aeb09b97d6886dd8fbc1974ebfc

See more details on using hashes here.

Provenance

The following attestation bundles were made for knots-1.16.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.16.0-py3-none-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for knots-1.16.0-py3-none-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 b5ed1e2781a87b67ccc9f800d26691fbfaaeb08c148bb1191d173c25f21f6aa7
MD5 30ef9e34d439b3feab0768b7f1a39cf8
BLAKE2b-256 42e9d33fea4ee282d4f9ac281b9344486b75d85776f8f3d0087ea5672273df55

See more details on using hashes here.

Provenance

The following attestation bundles were made for knots-1.16.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

This release

1.16.0 This release

8 files

1.15.1

8 files

1.15.0

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