semlint
semlint is a small, local Python CLI for finding redundant information in agent instruction corpora: SKILL.md, AGENTS.md, prompts, rules, and other Markdown/text files.
It answers: how many tokens are consuming context without adding unique information, and where are they?
Quick start
uv sync
uv run semlint ./skills
uv run semlint ./skills ./rules/AGENTS.md
uv run semlint './skills/**/*.md' './prompts/*.txt'
uv run semlint ./skills --threshold 0.90 --min-block-tokens 10
uv run semlint ./skills --split markdown
uv run semlint ./skills --output json > report.json
uv run semlint ./skills --limit 10
uv run semlint ./skills -s asc similarity
uv run semlint ./skills --fail-above 0.10
uv run semlint self list
The command exits with 1 when --fail-above is exceeded and 2 for invalid input/errors.
Stronger semantic matching
SemHash with local Model2Vec embeddings is the default semantic engine. It loads its small CPU model on first run (and caches it locally). For an explicit alternate Model2Vec model, use:
uv run semlint ./skills --model minishlab/potion-base-8M --threshold 0.90
SemHash and Model2Vec run locally on CPU. No API, LLM, vector database, server, or GPU is needed.
Agent capability discovery
semlint self list prints one full command synopsis and help description per line. Optional arguments and options are bracketed inline. The listing is generated by inspecting the registered Typer command definitions, so it stays aligned with the CLI.
What it scans
- Accepts one or more file paths, directories, or glob patterns; recursively scans
.mdand.txtfiles and de-duplicates overlapping matches. - By default (
--split auto), uses Markdown block boundaries for.mdfiles and blank-line paragraph splitting for other supported text files. Markdown blocks include paragraphs (including list and blockquote paragraphs), fenced/indented code, HTML blocks, and tables. Headings and front matter are not treated as instruction blocks. - Use
--split paragraphto force blank-line splitting, or--split markdownto force Markdown parsing. - All modes preserve original source text and line ranges; none infer sections or rule IDs.
- Ignores blocks below
--min-block-tokens. - Clusters likely duplicates without modifying source files.
Similarity is intentionally configurable because generic phrases can be false positives. Review clusters before replacing instructions.
Output formats
Text is the default and uses Rich-formatted summary metrics, cluster separators, cluster summaries, then a blank line followed by blank-line-separated path:start-end locations and numbered source lines. By default, clusters sort by estimated redundant tokens (largest first); -s|--sort <asc|desc> <occurrences|similarity|estimated-savings> selects a different order. --limit N displays only the first N clusters while keeping corpus-wide metrics unchanged. Linters commonly use this compact location notation with a source code frame; Rich provides readable terminal rendering without introducing a separate diagnostic framework.
Choose JSON with --output json. Top-level fields include files_scanned, blocks_scanned, total_tokens, exact_duplicate_percentage, semantic_redundancy_percentage, estimated_unique_tokens, estimated_redundant_tokens, estimated_context_token_savings, and clusters. Clusters include similarity, all source blocks, and token/savings estimates—no canonical or action suggestions.
The savings estimate assumes retaining the shortest occurrence in each cluster; review the source blocks yourself before deciding what to consolidate. context_redundancy is token-weighted:
estimated_redundant_tokens / total_tokens
This is an estimate, not a tokenizer-specific bill. The initial version counts word tokens for transparent, consistent reporting.
Development
just build uses the installed doxxer binary to inject the next Git-derived version into pyproject.toml, runs uv build, then restores the 0.0.0 source placeholder. Install doxxer before building.
just build
Install the project and development tools with uv sync, then run static checks:
uv sync
uv run ruff check src
uv run ty check src
The project uses Python 3.13+, Pydantic BaseModels for domain and report models, and a modular src/semlint package (parser/scanner, SemHash clustering, metrics, reporting, and Typer CLI). Structured SemHash inputs and JSON report output are validated with Pydantic. It does not automatically edit files.
Metadata
Release files for semlint 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| semlint-0.1.0.tar.gz | 9.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| semlint-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 21.3 kB
Release files / semlint-0.1.0.tar.gz
| Download URL | semlint-0.1.0.tar.gz |
|---|---|
| Size | 9.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
5b183b49419907d897a3a263859b3764f8ef3de7cfb3ba52cefc87ec9dd08635
|
|
BLAKE2b-256 checksum How to use checksums |
71a017e3f71dfbf5ecdd92a1887c58547a59dedb02877007dc05cff39579072a
|
| 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 24, 2026.
Transparency logRelease files / semlint-0.1.0-py3-none-any.whl
| Download URL | semlint-0.1.0-py3-none-any.whl |
|---|---|
| Size | 11.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b117f49e40666e0ac664ffed0f18617ffae560b9348df463cb23f83127ee988f
|
|
BLAKE2b-256 checksum How to use checksums |
622e186f17b7c1fc0aa2f34a411c87905cb664ab3686baedc5bc276b2a6b8746
|
| 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 24, 2026.
Transparency log