# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project Overview

Vibelexity is a cognitive complexity analyzer for Python, TypeScript, and Go source files. It uses tree-sitter for AST parsing and computes per-function metrics: cognitive complexity (SonarSource spec), Halstead metrics, cyclomatic complexity, NPath complexity, Data Transformation Density (DTD), Maintainability Index (MI), and Logic Density Index (LDI). File-level metrics include LOC, LLOC, and SLOC.

## Commands

```bash
# Run the analyzer
uv run vibelexity <directory>
python main.py <directory>

# Run all tests
uv run pytest

# Run a single test file
uv run pytest tests/test_cognitive/test_python.py

# Run a specific test
uv run pytest tests/test_cognitive/test_python.py::test_function_name

# Install/sync dependencies
uv sync
```

## Architecture

The codebase follows a three-layer structure per language (Python, TypeScript, Go):

1. **Parsers** (`parsers/`): Tree-sitter AST parsing. Each language module exposes functions to parse source and extract function nodes.
2. **Metrics** (`metrics/`): Per-metric implementations organized as `metrics/<metric_name>/<language>.py`. Each computes a single metric from AST nodes.
3. **Analyzers** (`analyzers/`): Top-level file analyzers that orchestrate parsing and all metric computations, returning `FileComplexity` objects.

Key shared modules:
- `models.py`: Core dataclasses (`HalsteadMetrics`, `FunctionComplexity`, `FileComplexity`)
- `common.py`: Shared computation helpers (Halstead formulas, MI calculation, LOC/SLOC counting, boolean chain scoring)
- `fmt.py`: Terminal output formatting with ANSI colors
- `main.py`: CLI entry point (`cli()`) with argparse, file collection (respects .gitignore, excludes test files), analysis orchestration, aggregation, and output (text or `--json`)

## Data Flow

`cli()` in `main.py` collects source files → dispatches to language-specific `analyzers/*.py::analyze_file()` → each analyzer calls `parsers/*.py` for AST then `metrics/*/*.py` for each metric → results aggregated as `FileComplexity` lists → statistics computed (avg, median, p95, p99) and threshold violations detected → output as formatted text or JSON.

## Adding a New Metric

Add `metrics/<metric_name>/` with per-language modules, wire into each `analyzers/*.py`, add field to `FunctionComplexity` in `models.py`, and add aggregation/display logic in `main.py`.

## Adding a New Language

Add `parsers/<lang>.py`, `analyzers/<lang>.py`, per-metric modules in `metrics/*/`, and register the file extension in `main.py`.
