Skip to main content

Aposlop

Aposlop

CI status crates.io version PyPI version License


Apos, the Slopbreaker

Slop always rolls downhill. Aposlop helps to push back.

Aposlop is a fast command-line tool. It finds duplicate code, excessive file length, and cyclomatic complexity.

Aposlop supports Go, Rust, Python, TypeScript, and TSX. Aposlop uses Tree-sitter to parse each supported language.

Documentation: https://aposlop.ezygang.digital/

Source Code: https://github.com/EzyGang/aposlop

Issues: https://github.com/EzyGang/aposlop/issues


Table of Contents


Why Aposlop?

Aposlop exists to find code slop from coding agents.

Coding agents can generate duplicate code, complex control flow, and oversized source files. These changes can enter a project faster than a reviewer can find them.

Text comparison does not find a duplicate after an agent renames identifiers or changes literals. A linter does not find repeated logic in different files or languages. A complexity limit does not identify repeated logic or growing file responsibilities.

Aposlop uses exact, normalized, and verified near-miss duplicate detection. It calculates cyclomatic complexity for each code block. It also reports supported source files that exceed their configured line limit.

Aposlop is fast enough for an agent validation loop. You can configure thresholds for each language and file extension. You can exclude paths or accept duplicate and complexity findings. These controls let a project accept known findings and continue development.

Feature Result
Type-1 detection Finds exact duplicates
Type-2 detection Finds duplicates after identifier or literal changes
Type-3 detection Finds verified near-miss duplicates
Complexity analysis Calculates complexity for each code block
File-length check Reports supported files above their effective limit
Terminal code view Shows every group instance with line numbers
JSON output Provides stable data for other tools
CI command Returns failure when findings remain
Local cache Reuses analysis for unchanged files
Update check Warns interactive users when a new release is available
How Aposlop works
  • Parse once. Tree-sitter providers extract blocks, identifiers, literals, comments, and complexity decisions.
  • Type-1. XXH3 groups exact token streams before complete equality verification.
  • Type-2. The same process compares streams with normalized identifiers and literals.
  • Type-3. Five-token shingles feed a prefix-filtered similarity join. Length and position filters prune candidates before Jaccard verification.
  • Grouping. Connected duplicate relations become one deterministic group with every source instance.
  • Complexity. Each block starts at 1 and adds unique language-specific decision captures. Nested blocks have independent scores.
  • File length. Each supported file keeps one physical line count for threshold reporting.
  • Cache. Versioned bincode data reuses unchanged analysis. File metadata and schema versions invalidate stale entries before atomic replacement.

Installation

Install script on Linux or macOS

Install cosign. Then run the installer:

curl -fsSLo install.sh https://github.com/EzyGang/aposlop/releases/latest/download/install.sh
sh install.sh

Install script on Windows

Install cosign. Then run the installer:

Invoke-WebRequest https://github.com/EzyGang/aposlop/releases/latest/download/install.ps1 -OutFile install.ps1
powershell -ExecutionPolicy Bypass -File .\install.ps1

Both scripts verify the archive checksum and Sigstore signatures.

Cargo

Install Aposlop from crates.io:

cargo install aposlop --locked

PyPI with uv

Install Aposlop as a global tool:

uv tool install aposlop

Run Aposlop without installing it:

uvx aposlop --help

Homebrew

Install Aposlop from the EzyGang Homebrew tap:

brew install EzyGang/tap/aposlop

From source

Install Aposlop from source. A stable Rust toolchain must support edition 2024.

git clone https://github.com/EzyGang/aposlop.git
cd aposlop
cargo install --path . --locked

Verify the installation:

aposlop --version
aposlop --help

Agent skills

Discover and install the bundled agent skills with npm:

npx skills@latest add EzyGang/aposlop

Or use pnpm:

pnpm dlx skills@latest add EzyGang/aposlop

The installer lists every bundled skill and lets you select the skills and target agents.

The aposlop skill teaches agents to configure Aposlop, inspect findings, and add Aposlop to validation workflows. The aposlop-code-changes skill helps agents desplop code through small, reuse-first changes that fix shared root causes. The aposlop-deslop-tests skill removes low-value tests and then simplifies production seams that only those tests required. The aposlop-deslop-turbo skill completes test deslop first, then minimizes applicable production logic without changing behavior.

The first two skills can activate automatically from the request context. The two deslop skills declare manual-only activation. Invoke /aposlop-deslop-tests or /aposlop-deslop-turbo manually when the agent supports slash commands. For other agents, select the named deslop skill through their skill interface. The skills do not install the Aposlop binary.

Update checks

Aposlop checks for a new GitHub release during interactive runs. It performs a network request at most once every 24 hours. It stores the latest result in the user cache directory. Non-interactive commands do not perform this check.

Set this environment variable to disable the check:

APOSLOP_NO_UPDATE_CHECK=1 aposlop .

Quick Start

Analyze the current directory:

aposlop .

Show the source for each duplicate:

aposlop . --terminal-output code

Run CI validation:

aposlop ci .

The ci command returns exit code 1 when a finding remains.

Write the complete report as JSON:

aposlop . --format json > aposlop-report.json

Read the full quick-start guide.


Core Features

Duplicate Detection

A block enters analysis when it meets the line and named-node limits.

Aposlop classifies block relations in this order:

  1. Type-1 requires identical canonical syntax.
  2. Type-2 allows different identifiers and literals.
  3. Type-3 requires a Jaccard similarity at or above the configured threshold.

Aposlop reports each connected set of duplicate relations as one group. Two blocks do not match when either contains the other in the same file. A TypeScript block can match a TSX block.

Read the duplicate model.

Cyclomatic Complexity

Each valid block has an initial complexity score of 1. Aposlop adds one for each language-specific decision. Decisions include branches, loops, alternatives, exception paths, conditional expressions, and short-circuit operations.

A nested block has an independent score. Nested blocks include functions, closures, lambdas, field initializers, and static blocks.

A violation requires:

score > complexity_threshold

Read the complexity model.

File Length

Aposlop reports a supported source file when its line count exceeds its effective maximum. The default maximum is 300 lines.

lines > max_file_lines

Use [file_length].exclude for check-specific gitignore-style exclusions. File-length violations cannot be suppressed with aposlop allow.

Read the file-length guide.

Language Support

Language Extensions
Go .go
Rust .rs
Python .py
TypeScript .ts
TSX .tsx

Aposlop ignores unsupported extensions. Aposlop follows standard ignore files such as .gitignore.

Read the language guides.

Output Formats

The terminal report is the default. It contains duplicate groups, complexity findings, file-length violations, diagnostics, and a summary.

aposlop . --format terminal

The JSON report contains the complete report and its schema version.

aposlop . --format json

The ci command shows only the status and finding counts.

aposlop ci .

Read the output guide.

Manual Exclusions

Aposlop assigns a deterministic five-character ID to each duplicate group or complexity finding.

Add a finding to the manual exclusions:

aposlop allow aB7_x

The command writes the ID to .aposlopignore. Delete the ID from that file to restore the finding. Aposlop reports valid IDs that match no current finding as unused ignores at the end of each report. Unused ignores do not change the process exit code. File-length violations have no finding ID and cannot be added to .aposlopignore.


Configuration

Aposlop reads <PATH>/.aposlop.toml. Aposlop uses built-in values when this file does not exist.

[core]
min_lines = 5
min_nodes = 30
exclude = ["tests/", "vendor/", "node_modules/", "target/"]
use_cache = true

[duplicates_detection]
type_1 = true
type_2 = true
type_3 = true
type_3_threshold = 0.85

[metrics]
calculate_complexity = true
complexity_threshold = 15

[file_length]
max_lines = 300
exclude = []

core.exclude and file_length.exclude use the same syntax as one .gitignore line. core.exclude removes matching paths from all analysis. file_length.exclude suppresses only file-length violations. Directory patterns match at any depth, while / anchors and ** recurse.

Language and extension tables can override max_file_lines and the existing analysis rules. Command-line values override all configuration-file layers.

Read the configuration guide.


CLI Quick Reference

Command or option Purpose
aposlop ci [PATH] Print a concise finding summary and fail when findings exist
aposlop allow <FINDING> [PATH] Add a finding to the target's manual exclusions
--format <terminal|json> Select the report format
--terminal-output <locations|code> Select terminal duplicate detail
--min-lines <N> Override the minimum block line count
--min-nodes <N> Override the minimum named-node count
--exclude <GLOB> Replace configured gitignore-style exclusion patterns
--use-cache <BOOL> Enable or disable the analysis cache
--type-1 <BOOL> Enable or disable Type-1 findings
--type-2 <BOOL> Enable or disable Type-2 findings
--type-3 <BOOL> Enable or disable Type-3 findings
--type-3-threshold <RATIO> Override the Type-3 threshold
--calculate-complexity <BOOL> Enable or disable complexity findings
--complexity-threshold <N> Override the complexity threshold
--max-file-lines <N> Override the maximum source-file line count

Read the complete CLI reference.


Contributing

Open a GitHub issue to discuss a large change. Then open a pull request.

Run these checks before you submit the pull request:

cargo fmt --all -- --check
cargo clippy --workspace --all-targets --all-features -- -D warnings
cargo test --workspace --all-features
cargo run -- --help

License

You can use Aposlop under either license:

Metadata

Release files for aposlop 1.2.1

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

Built distributions (wheels)

Table of built distributions (wheels) for aposlop 1.2.1
File
aposlop-1.2.1-py3-none-win_arm64.whl Python 3 none Windows ARM64 Details
aposlop-1.2.1-py3-none-win_amd64.whl Python 3 none Windows x86-64 Details
aposlop-1.2.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl Python 3 none Linux glibc 2.17+ x86-64 Details
aposlop-1.2.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl Python 3 none Linux glibc 2.17+ ARM64 Details
aposlop-1.2.1-py3-none-macosx_11_0_arm64.whl Python 3 none macOS 11.0+ ARM64 Details
aposlop-1.2.1-py3-none-macosx_10_12_x86_64.whl Python 3 none macOS 10.12+ x86-64 Details

Total release size: 21.1 MB

Release files / aposlop-1.2.1-py3-none-win_arm64.whl

Download URL aposlop-1.2.1-py3-none-win_arm64.whl
Size 3.3 MB
Tags Python 3 Windows ARM64
SHA-256 checksum
How to use checksums
a5772267fc2c68c1195221ac2e53540ee3c226f056c640f148144193b8366a29
BLAKE2b-256 checksum
How to use checksums
24f8d1c3704648960eb76776bda1eeb7d3bf2cbdbc82a3968b8e0b239773ba5f
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 Sep 3, 2026.

Transparency log

Release files / aposlop-1.2.1-py3-none-win_amd64.whl

Download URL aposlop-1.2.1-py3-none-win_amd64.whl
Size 3.3 MB
Tags Python 3 Windows x86-64
SHA-256 checksum
How to use checksums
6038c171ae8f57dc3dce0066da286befd1326cd3df500af7ac5769a04928bacc
BLAKE2b-256 checksum
How to use checksums
74909c621767f790703dfd8dd8bb002995f75d54bccff641264d419af40472da
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 Sep 3, 2026.

Transparency log

Release files / aposlop-1.2.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL aposlop-1.2.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 3.8 MB
Tags Linux glibc 2.17+ x86-64 Python 3
SHA-256 checksum
How to use checksums
9948b0e3f662dac82b6e0c1a59ac6d9f70bf94cb9efdb59de9d2bd41e3567efd
BLAKE2b-256 checksum
How to use checksums
c7bd27f9afa77cdf1c399516387346b661389fa28032cc7ff4fbca8d6cefc897
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 Sep 3, 2026.

Transparency log

Release files / aposlop-1.2.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL aposlop-1.2.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 3.5 MB
Tags Linux glibc 2.17+ ARM64 Python 3
SHA-256 checksum
How to use checksums
b8930c7e2742ce2937d362c617a49413785dd7cc28a52fbf9e5a3d8e7aaf5db5
BLAKE2b-256 checksum
How to use checksums
f0d42715b192874a008b5d0a5f530ab07bd310cf8b6fe72298b815b7ba04671f
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 Sep 3, 2026.

Transparency log

Release files / aposlop-1.2.1-py3-none-macosx_11_0_arm64.whl

Download URL aposlop-1.2.1-py3-none-macosx_11_0_arm64.whl
Size 3.5 MB
Tags Python 3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
391e687c7e8862138ad5b867493e740abdb9d5c70cbf2db7a1229130536e42cf
BLAKE2b-256 checksum
How to use checksums
0478fc1b6963acd5b1b07393cd750595e778556f8a7a252fca77e2571b9b1256
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 Sep 3, 2026.

Transparency log

Release files / aposlop-1.2.1-py3-none-macosx_10_12_x86_64.whl

Download URL aposlop-1.2.1-py3-none-macosx_10_12_x86_64.whl
Size 3.7 MB
Tags Python 3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
0d2d1089ba518354777efea617704553455050542509417885db02b03bc21cac
BLAKE2b-256 checksum
How to use checksums
aa5b98e365f80596d6ddc1287bd4cf9b78a2e3e0aa5a8d793908e5de404488f5
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 Sep 3, 2026.

Transparency log

Release history Release notifications | RSS feed

1.2.2

6 release files

This release

1.2.1 This release

6 release files

1.2.0

6 release files

1.1.3

6 release files

1.1.2

6 release files

1.1.1

6 release files

1.1.0

6 release files

1.0.0

6 release 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