Suite of tools to enhance the vibe coding process.
Project description
vibelint
Enhance your Python codebase's "vibe" for better maintainability and LLM interaction.
vibelint is a suite of tools designed to identify and help resolve common Python code smells and anti-patterns that can hinder developer understanding and confuse Large Language Models (LLMs) used in AI-assisted coding. It helps you visualize your project's structure, detect naming conflicts, and enforce coding conventions that promote clarity. It also helps you take flat snapshots of your entire codebase to feed into large-context LLM chat interfaces.
Table of Contents
- Why Use vibelint?
- Key Features
- Installation
- Usage
- Strategies for Namespace Cleanup
- Configuration
- Error Codes
- Contributing
- License
Why Use vibelint?
Modern Python codebases can become complex, leading to issues that aren't syntax errors but degrade maintainability and clarity:
- Hidden Namespace Conflicts: It's easy to accidentally define the same function or class name in multiple modules. While Python might resolve imports one way, developers (and LLMs) can be confused about which implementation is intended or active in a given context. Hard collisions (e.g., a module name clashing with a variable in
__init__.py) can even break imports unexpectedly. - Ambiguity for LLMs & Developers: Tools like Copilot or ChatGPT rely heavily on context. Missing
__all__definitions obscure a module's public API. Docstrings without clear file path references make it harder for both humans and AI to know where that code lives within the project structure, hindering understanding and accurate code generation/analysis. - Inconsistent Code Patterns: Issues like missing docstrings, improper
__all__usage, or incorrect shebangs create friction during development and code reviews.
vibelint helps you address these by:
- Revealing Structure: Clearly visualizing your project's namespace.
- Preventing Errors: Catching hard namespace collisions before they cause runtime import failures.
- Reducing Ambiguity: Identifying soft collisions and enforcing explicit APIs (
__all__) and contextual docstrings. - Improving Maintainability: Promoting consistent, understandable code patterns.
- Enhancing AI Collaboration: Providing clearer context (via docstring paths and snapshots) for better results from LLM coding assistants.
Key Features
- Namespace Visualization (
vibelint namespace): Generates a tree view of your project's Python namespace (packages, modules,__init__.pymembers). - Collision Detection (
vibelint check):- Hard Collisions: Name conflicts likely to break Python imports.
- Global Soft Collisions: Same name defined in multiple modules (potential ambiguity).
- Local Soft Collisions: Same name exported via
__all__in sibling modules (confusingimport *).
- Targeted Linting (
vibelint check):- Docstring Presence & Path: Checks for docstrings and enforces the inclusion of a standardized relative file path at the end.
__all__Enforcement: Ensures modules define their public API via__all__.- Shebang & Encoding: Validates script shebangs and encoding declarations.
- Codebase Snapshot (
vibelint snapshot): Creates a single Markdown file with a file tree and code contents, respecting includes/excludes – ideal for LLM context. - Comprehensive Reporting (
vibelint check -o report.md): Generates detailed Markdown reports summarizing all findings.
(Note: vibelint currently focuses on identifying issues, not automatically fixing them.)
Installation
pip install vibelint
vibelint requires Python 3.10 or higher.
- Note on TOML parsing: For Python 3.10,
vibelintrequires thetomlipackage. For Python 3.11+, it uses the built-intomllib. This dependency is handled automatically bypip.
Usage
Run vibelint commands from the root of your project (the directory containing pyproject.toml or .git).
Checking Your Codebase (Linting & Collisions)
This is the primary command to analyze your project.
vibelint check
This runs all configured linters and namespace collision checks, printing a summary and details of any issues found to the console. It will exit with a non-zero code if errors (like hard collisions or missing __all__ where required) are found.
Getting a Full Report
To get a detailed breakdown of all linting issues, the namespace structure, detected collisions, and the content of included files, use the -o or --output-report option with the check command:
vibelint check -o vibelint-report.md
This will generate a comprehensive Markdown file (e.g., vibelint-report.md) in your current directory. This report is useful for reviewing issues offline or sharing with your team.
Visualizing Your Namespace
To understand your project's Python structure:
vibelint namespace
This prints the namespace tree directly to your terminal.
- Save the tree to a file:
vibelint namespace -o namespace_tree.txt
Creating Code Snapshots
Generate a single Markdown file containing the project structure and file contents (useful for LLMs):
vibelint snapshot
This creates codebase_snapshot.md by default.
- Specify a different output file:
vibelint snapshot -o context_for_llm.md
The snapshot respects the include_globs, exclude_globs, and peek_globs defined in your configuration.
Getting Help
vibelint --help
vibelint check --help
vibelint namespace --help
vibelint snapshot --help
Strategies for Namespace Cleanup
The vibelint check command might report namespace collisions. Here’s a suggested strategy for addressing them:
-
Prioritize Hard Collisions: These are marked
[HARD]and are the most critical as they can break Python's import mechanism or lead to very unexpected behavior.- Cause: Typically a clash between a submodule/subpackage name and an object (variable, function, class) defined in a parent
__init__.py. For example, havingsrc/utils/directory and definingutils = ...insrc/__init__.py. - Fix: Rename one of the conflicting items. Usually, renaming the object in the
__init__.pyis less disruptive than renaming a whole directory/package. Choose a more descriptive name.
- Cause: Typically a clash between a submodule/subpackage name and an object (variable, function, class) defined in a parent
-
Address Local Soft Collisions (
__all__): These are marked[LOCAL_SOFT]and occur when multiple sibling modules (files in the same directory/package) export the same name via their__all__list. This mainly causes issues with wildcard imports (from package import *).- Review: Is it necessary for the same name to be part of the public API of multiple sibling modules?
- Fix Options:
- Rename the object in one of the modules.
- Remove the name from the
__all__list in one or more modules if it's not truly intended to be public from that specific module. - Reconsider the package structure – perhaps the conflicting objects should live elsewhere or be consolidated.
-
Review Global Soft Collisions (Definitions): These are marked
[GLOBAL_SOFT]and indicate the same name (function, class, top-level variable) is defined in multiple modules anywhere in the project. These usually don't cause runtime errors but create ambiguity for developers and LLMs.- Evaluate: Is the duplication intentional and necessary? Sometimes utility functions might be deliberately duplicated.
- Fix Options:
- If the logic is identical, consolidate the definition into a single shared module and import it where needed.
- If the logic differs but the name causes confusion, rename the object in one or more locations to be more specific.
- If the duplication is intentional (e.g., different implementations of an interface), ensure clear documentation distinguishes them. You might consider ignoring specific instances if the ambiguity is acceptable (see Configuration).
-
Use
vibelint namespace: Refer to the namespace visualization (vibelint namespace) output while refactoring to better understand the project structure you are modifying. -
Iterate: Don't try to fix everything at once. Start with hard collisions, then local soft, then global soft. Rerun
vibelint checkafter making changes.
Configuration
Configure vibelint by adding a [tool.vibelint] section to your pyproject.toml file.
# pyproject.toml
[tool.vibelint]
# Globs for files to include (relative to project root)
# Files matching these patterns will be considered for linting and snapshots.
include_globs = [
"src/**/*.py",
"tests/**/*.py",
"scripts/*.py",
"*.py" # Include top-level python files
]
# Globs for files/directories to exclude
# Files matching these are ignored, even if they match include_globs.
# Defaults usually cover common virtual envs, caches, etc.
exclude_globs = [
".git/**",
".tox/**",
"*.egg-info/**",
"build/**",
"dist/**",
"**/__pycache__/**",
".pytest_cache/**",
".ruff_cache/**",
"*.env*",
"**/.DS_Store",
# Add project-specific ignores:
"docs/**",
"data/**",
]
# List of allowed shebang lines for executable scripts (checked by VBL402)
# Only applies to files containing a `if __name__ == "__main__":` block.
allowed_shebangs = ["#!/usr/bin/env python3"]
# If true, enforce __all__ presence in __init__.py files (VBL301).
# If false (default), only issue a warning (VBL302) for missing __all__ in __init__.py.
error_on_missing_all_in_init = false
# List of VBL error/warning codes to ignore globally.
# Find codes in src/vibelint/error_codes.py or from `vibelint check` output.
ignore = ["VBL102"] # Example: Ignore missing path references in docstrings
# Threshold for confirming before processing many files during `check`.
# Set to a very large number (or use --yes flag) to disable confirmation.
large_dir_threshold = 500
# Glob patterns for files whose content should be truncated (peeked)
# instead of fully included in `vibelint snapshot` output.
# Useful for large data files, logs, etc.
# peek_globs = [
# "data/**/*.csv",
# "logs/*.log",
# ]
Disabling the Docstring Path Check
If you disagree with the convention of including the relative file path at the end of docstrings, you can disable the specific check (VBL102).
Add the code VBL102 to the ignore list in your pyproject.toml under the [tool.vibelint] section:
[tool.vibelint]
# ... other settings ...
ignore = ["VBL102"]
You can add multiple codes to the list to ignore other specific checks if needed, e.g., ignore = ["VBL102", "VBL302"].
Error Codes
vibelint uses specific codes (e.g., VBL101, VBL301, VBL402) to identify issues found by the check command. These codes help you understand the exact nature of the problem and allow for targeted configuration (e.g., ignoring specific codes).
You can find the definition of these codes in the source file: src/vibelint/error_codes.py.
- VBL1xx: Docstring issues (Presence, Path reference, Format)
- VBL2xx: Encoding cookie issues
- VBL3xx:
__all__export issues (Presence, Format) - VBL4xx: Shebang (
#!) issues (Presence, Validity) - VBL9xx: Internal processing errors
Contributing
Contributions are welcome! Please feel free to open issues for bug reports or feature requests, or submit pull requests on GitHub.
License
vibelint is licensed under the MIT License. See the LICENSE file for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file vibelint-0.1.2.tar.gz.
File metadata
- Download URL: vibelint-0.1.2.tar.gz
- Upload date:
- Size: 112.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ba7996ae39f5060d2e82e559710ff0025fa8cb6ffeb54dd4750e15dd91a5d281
|
|
| MD5 |
e1c472a6aa24a1f660358c96279dc78a
|
|
| BLAKE2b-256 |
39535af951278599c61ecb2cab7e0a84d5dd44e60117199c86ad7ebdf504a9ec
|
Provenance
The following attestation bundles were made for vibelint-0.1.2.tar.gz:
Publisher:
publish.yml on mithranm/vibelint
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
vibelint-0.1.2.tar.gz -
Subject digest:
ba7996ae39f5060d2e82e559710ff0025fa8cb6ffeb54dd4750e15dd91a5d281 - Sigstore transparency entry: 214573664
- Sigstore integration time:
-
Permalink:
mithranm/vibelint@56c67a8ba9a812fb3b6bf3e17d8e0ce90535a3fa -
Branch / Tag:
refs/heads/main - Owner: https://github.com/mithranm
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@56c67a8ba9a812fb3b6bf3e17d8e0ce90535a3fa -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file vibelint-0.1.2-py3-none-any.whl.
File metadata
- Download URL: vibelint-0.1.2-py3-none-any.whl
- Upload date:
- Size: 55.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
76bed98adc907323644bab0539fe063abfc32f0e950335e77b991068d59d6424
|
|
| MD5 |
8ca7426bbf30e8a38c5482e7b183e5d8
|
|
| BLAKE2b-256 |
18dd3da09205f985e33311d612214d3d4e0e3f067a76b52156be54541592a2a2
|
Provenance
The following attestation bundles were made for vibelint-0.1.2-py3-none-any.whl:
Publisher:
publish.yml on mithranm/vibelint
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
vibelint-0.1.2-py3-none-any.whl -
Subject digest:
76bed98adc907323644bab0539fe063abfc32f0e950335e77b991068d59d6424 - Sigstore transparency entry: 214573666
- Sigstore integration time:
-
Permalink:
mithranm/vibelint@56c67a8ba9a812fb3b6bf3e17d8e0ce90535a3fa -
Branch / Tag:
refs/heads/main - Owner: https://github.com/mithranm
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@56c67a8ba9a812fb3b6bf3e17d8e0ce90535a3fa -
Trigger Event:
workflow_dispatch
-
Statement type: