Skip to main content

lint-claude

Automatically enforce your CLAUDE.md guidelines using Claude AI

PyPI version License: MIT Python 3.11+

The Problem

You've written a CLAUDE.md file with coding guidelines, architecture rules, and best practices for your project. But how do you ensure your team actually follows them?

Manual code reviews miss things. Reviewers can't remember every guideline, and catching violations is tedious and inconsistent.

Traditional linters are rigid. They can't understand context-specific rules like "use functional patterns for data transformations" or "avoid nested conditionals in business logic."

You need intelligent, automated guideline enforcement that understands your specific rules and checks every file change before it's merged.

The Solution

lint-claude uses Claude AI to analyze your code against your CLAUDE.md guidelines automatically. It catches violations during development and in CI/CD, ensuring consistent adherence to your team's standards.

# Check changed files before committing
uvx lint-claude --working

# In CI/CD: fail the build if guidelines are violated
uvx lint-claude --diff main

Smart & Fast:

  • Prompt caching reduces API costs by ~90%
  • File hashing skips unchanged files
  • Batch processing handles large projects efficiently
  • Git-aware checks only what changed

Team-Friendly:

  • Multiple scan modes (full, diff, working, staged)
  • CI/CD integration with exit codes
  • JSON output for custom tooling
  • Resume support for interrupted scans

Quick Start

1. Install with uvx (no installation needed)

# Run directly without installing
uvx lint-claude --help

Or install globally:

# Install with uv
uv tool install lint-claude

# Install with pip
pip install lint-claude

2. Set your API key

export ANTHROPIC_API_KEY="your-api-key-here"

Get your API key from Anthropic Console.

3. Create CLAUDE.md

Create a CLAUDE.md file in your project root with your guidelines:

# Project Guidelines

## Code Style
- Use descriptive variable names (no single letters except loop counters)
- Functions should be under 50 lines
- Prefer composition over inheritance

## Architecture
- Keep business logic in src/domain/
- All API calls must use the retry wrapper
- Database queries must be in repository classes

## Testing
- Every public function needs a test
- Test files must be colocated with source files

4. Run your first scan

# Check all files
uvx lint-claude --full

# Check only changed files (faster)
uvx lint-claude --working

That's it! Claude will analyze your code and report any guideline violations.

Usage

Scan Modes

# Full project scan
uvx lint-claude --full

# Check files changed from a branch (great for PRs)
uvx lint-claude --diff main
uvx lint-claude --diff origin/develop

# Check uncommitted changes (working directory)
uvx lint-claude --working

# Check only staged files (pre-commit hook)
uvx lint-claude --staged

Output Formats

# Human-readable output (default)
uvx lint-claude --full

# JSON output for tooling integration
uvx lint-claude --full --json

# Quiet mode (only errors)
uvx lint-claude --full --quiet

# Verbose mode (detailed logging)
uvx lint-claude --full --verbose

Configuration

Create .lint-claude.json in your project root:

{
  "include": ["**/*.py", "**/*.js", "**/*.ts"],
  "exclude": ["node_modules/**", "dist/**", "*.test.js"],
  "batch_size": 10,
  "max_file_size_mb": 1.0,
  "model": "claude-sonnet-4-5-20250929"
}

All settings are optional. Defaults work for most projects.

Available options:

Option Default Description
include ["**/*.py", "**/*.js", "**/*.ts"] Glob patterns for files to check
exclude See below Glob patterns to skip
batch_size 10 Files per API request (1-100)
max_file_size_mb 10.0 Skip files larger than this
model claude-sonnet-4-5-20250929 Claude model to use
api_key (env var) Override ANTHROPIC_API_KEY
api_timeout_seconds 300 API request timeout
rate_limit_rpm 50 API requests per minute

Default exclude patterns (automatically skipped):

  • .venv/**, venv/**, env/** - Python virtual environments
  • __pycache__/**, *.pyc, *.pyo - Python cache files
  • .pytest_cache/**, .mypy_cache/**, .ruff_cache/** - Test/lint caches
  • node_modules/** - Node.js dependencies
  • dist/**, build/**, *.egg-info/** - Build outputs
  • .git/** - Version control
  • .vscode/**, .idea/** - IDE directories

Use snake_case (preferred) or camelCase for keys.

CI/CD Integration

lint-claude returns exit code 0 for clean scans and 1 when violations are found, making it perfect for CI/CD.

Use the official GitHub Action for the easiest integration:

name: CLAUDE.md Compliance

on: [pull_request]

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0  # Need full history for diff mode

      - name: Lint CLAUDE.md
        uses: vtemian/lint-claude@v0.3.1
        with:
          mode: 'diff'
          base-branch: 'origin/main'
          anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }}

Action Inputs

Input Description Default
mode Scan mode: full, diff, working, staged diff
base-branch Base branch for diff mode origin/main
anthropic-api-key API key (uses ANTHROPIC_API_KEY secret if not set) -
fail-on-violations Fail workflow if violations found true
output-format Output format: text or json text

Action Outputs

Output Description
violations-found Whether violations were found (true/false)
summary Summary of violations

More Examples

Full project scan:

- uses: vtemian/lint-claude@v0.3.1
  with:
    mode: 'full'

Comment violations on PR:

- name: Lint changed files
  id: lint
  uses: vtemian/lint-claude@v0.3.1
  with:
    mode: 'diff'
    fail-on-violations: 'false'

- name: Comment on PR
  if: steps.lint.outputs.violations-found == 'true'
  uses: actions/github-script@v7
  with:
    script: |
      github.rest.issues.createComment({
        issue_number: context.issue.number,
        owner: context.repo.owner,
        repo: context.repo.repo,
        body: `## ⚠️ CLAUDE.md Violations\n\n${{ steps.lint.outputs.summary }}`
      });

Check staged files only:

- uses: vtemian/lint-claude@v0.3.1
  with:
    mode: 'staged'

See example workflows for more.

Using uvx (Alternative)

If you prefer running the CLI directly:

name: CLAUDE.md Compliance

on: [pull_request]

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Check guidelines
        env:
          ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
        run: |
          uvx lint-claude --diff origin/main

GitLab CI

lint-claude:
  image: python:3.11
  script:
    - pip install uv
    - uvx lint-claude --diff origin/main
  only:
    - merge_requests

Pre-commit Hook

Add to .pre-commit-config.yaml:

repos:
  - repo: local
    hooks:
      - id: lint-claude
        name: CLAUDE.md compliance
        entry: uvx lint-claude --staged
        language: system
        pass_filenames: false

How It Works

  1. File Collection - Gathers files based on scan mode and include/exclude patterns
  2. Cache Check - Skips files unchanged since last scan (based on file hash + CLAUDE.md hash)
  3. Batch Processing - Groups files into batches (default 10, configurable)
  4. API Analysis - Sends batches to Claude with CLAUDE.md in cached system prompt
  5. Violation Detection - Parses Claude's structured XML response
  6. Result Caching - Stores results for future runs
  7. Reporting - Outputs violations with file paths and line numbers

Caching Strategy

lint-claude is designed to be fast and cost-effective:

  • Prompt Caching - CLAUDE.md is cached by Claude's API, reducing costs by ~90%
  • File Hash Cache - Only re-checks modified files (.lint-claude-cache.json)
  • CLAUDE.md Hash - Triggers full re-scan when guidelines change
  • Resume Support - Interrupted scans resume from last batch (.lint-claude-progress.json)

Example: Checking 100 files costs ~$0.50 on first run, then ~$0.05 for incremental checks.

Examples

Example Output

$ uvx lint-claude --working

🔍 Checking 3 files against CLAUDE.md...

❌ src/auth/login.py
  Line 45: Function `authenticate_user` is 73 lines long.
           Guideline requires functions under 50 lines.

  Line 12: Variable name `u` is not descriptive.
           Guideline requires descriptive names.

❌ src/api/users.py
  Line 23: Database query not in repository class.
           Guideline requires all database queries in repositories.

✅ src/utils/format.py - No violations

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Summary: 2 files with violations, 1 file clean

Exit code: 1

Example JSON Output

$ uvx lint-claude --staged --json
{
  "results": [
    {
      "file": "src/auth/login.py",
      "violations": [
        {
          "type": "error",
          "line": 45,
          "message": "Function `authenticate_user` is 73 lines long. Guideline requires functions under 50 lines."
        }
      ]
    }
  ],
  "summary": {
    "files_checked": 3,
    "files_with_violations": 2,
    "files_clean": 1,
    "total_violations": 3
  },
  "metrics": {
    "duration_seconds": 4.2,
    "cache_hit_rate": 0.67,
    "api_calls_made": 1
  }
}

Advanced Usage

Custom Model

Use different Claude models for different needs:

# Fast and cheap (Haiku)
uvx lint-claude --full --model claude-haiku-20250301

# More thorough (Opus)
uvx lint-claude --full --model claude-opus-20250229

# Default (Sonnet - best balance)
uvx lint-claude --full --model claude-sonnet-4-5-20250929

Batch Size Tuning

# Smaller batches (more accurate, more API calls)
uvx lint-claude --full --batch-size 5

# Larger batches (faster, cheaper, may miss context)
uvx lint-claude --full --batch-size 50

Skip Cache

# Force re-check all files
rm .lint-claude-cache.json
uvx lint-claude --full

Troubleshooting

API Rate Limits

If you hit rate limits, reduce RPM in config:

{
  "rate_limit_rpm": 30
}

Large Files Skipped

Files larger than 10MB are skipped by default. To check larger files:

{
  "max_file_size_mb": 20.0
}

Cost Concerns

  • Use --diff or --working instead of --full to check fewer files
  • Reduce batch_size for more granular caching
  • Use Haiku model for cheaper analysis

Cost estimate: ~$0.005 per file on first check, ~$0.0005 on cached re-checks.

Interrupted Scans

If a scan is interrupted, it will resume from the last completed batch:

# Resume automatically
uvx lint-claude --full

To start fresh:

rm .lint-claude-progress.json
uvx lint-claude --full

Documentation

Development

# Clone repository
git clone https://github.com/vtemian/lint-claude.git
cd lint-claude

# Install dependencies
uv sync

# Run tests
uv run pytest

# Run with coverage
uv run pytest --cov=claude_lint --cov-report=html

# Lint code
uv run ruff check src/

# Format code
uv run ruff format src/

# Type check
uv run mypy src/

License

MIT License - see LICENSE file for details.

Contributing

Contributions welcome! Please:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Make your changes
  4. Run tests (uv run pytest)
  5. Commit your changes (git commit -m 'Add amazing feature')
  6. Push to the branch (git push origin feature/amazing-feature)
  7. Open a Pull Request

FAQ

How is this different from traditional linters?

Traditional linters (ESLint, Pylint, Ruff) are rule-based and can't understand context. lint-claude uses AI to understand your specific guidelines in natural language, like "avoid god classes" or "use repository pattern for database access."

Does it replace traditional linters?

No, use both! Traditional linters catch syntax errors and common issues. lint-claude catches architectural and stylistic violations specific to your team's guidelines.

How much does it cost?

~$0.005 per file on first scan, ~$0.0005 on incremental scans. A typical PR with 10 changed files costs less than $0.01.

Can I use it offline?

No, it requires Claude API access. However, it caches aggressively to minimize API calls.

What models are supported?

All Claude 3+ models: Haiku, Sonnet, Opus. Sonnet (default) offers the best balance of speed, cost, and accuracy.

Can I customize the prompt?

The system prompt is fixed to ensure reliable output parsing. Customize behavior through your CLAUDE.md guidelines instead.

Acknowledgments

Support


Made with ❤️ by developers who believe in enforceable standards

Metadata

Release files for lint-claude 0.4.0

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

Source distribution (sdist)

Source distribution for lint-claude 0.4.0
File Size Uploaded
lint_claude-0.4.0.tar.gz 55.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for lint-claude 0.4.0
File Interpreter ABI Platform
lint_claude-0.4.0-py3-none-any.whl Python 3 none any Details

Total release size: 90.3 kB

Release files / lint_claude-0.4.0.tar.gz

Download URL lint_claude-0.4.0.tar.gz
Size 55.2 kB
Tags Source
SHA-256 checksum
How to use checksums
d1b7ccb7ede017d4ea9061bf42582473b5aec496df9dd8d08f3cc59973fa2626
BLAKE2b-256 checksum
How to use checksums
90955ccf00b7279ae659787fd506b798df7d35c690627788f82ff5168ce62c03
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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 Nov 24, 2025.

Transparency log

Release files / lint_claude-0.4.0-py3-none-any.whl

Download URL lint_claude-0.4.0-py3-none-any.whl
Size 35.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d3a61a29f8882a2f31c20d6b46f8369ce4598d305571b001f2938895e75b7b70
BLAKE2b-256 checksum
How to use checksums
e9f28b8391044fcb0b20abe27c076ea564dfbc3fe8e13b3700d3d0831b9e0678
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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 Nov 24, 2025.

Transparency log

Release history Release notifications | RSS feed

This release

0.4.0 This release

2 release files

0.3.2

2 release files

0.3.0

2 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