# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
**profile-inspect** is a Rust CLI tool for analyzing V8 CPU and heap profiles generated by Node.js/Chrome DevTools. It converts `.cpuprofile` and `.heapprofile` JSON files into human-readable analysis reports.
## Commands
```bash
# Build
cargo build # Debug build
cargo build --release # Release build
# Lint (MUST pass before committing)
cargo clippy # Run all configured lints
cargo fmt # Format code
# Test
cargo test # Run all tests
cargo test parser # Run tests matching "parser"
cargo test -- --nocapture # Show test output
# Run
cargo run -- cpu <profile.cpuprofile>
cargo run -- heap <profile.heapprofile>
cargo run -- diff <before> <after>
cargo run -- explain <profile> --function <name>
cargo run -- run --cpu npm test # Run command with profiling, analyze results
```
## Architecture
### Data Flow
```
V8 Profile JSON → Parser → ProfileIR → Analyzer → Analysis Results → Formatter → Output
```
### Module Structure
- **`cli/`** - Command handlers using `bpaf` for argument parsing
- **`types/`** - Raw V8 profile JSON deserialization (`CpuProfile`, `HeapProfile`)
- **`ir/`** - Intermediate representation (`Frame`, `Stack`, `Sample`, `ProfileIR`)
- **`parser/`** - V8 profile → IR conversion
- **`classify/`** - Frame classification by category (`App`, `Deps`, `NodeInternal`, `V8Internal`, `Native`)
- **`sourcemap/`** - Source map resolution for bundled code
- **`analysis/`** - Analysis algorithms (`CpuAnalyzer`, `HeapAnalyzer`, `ProfileDiffer`, `CallerCalleeAnalyzer`)
- **`output/`** - Formatters implementing `Formatter` trait (Markdown, JSON, Speedscope, Text, Collapsed)
### Key Types
- **`ProfileIR`** - Normalized intermediate representation, holds frames, stacks, and samples
- **`Frame`** - Single call frame with name, location, kind, and category
- **`FunctionStats`** - Analysis result with self/total time percentages
### Patterns
- **Builder Pattern**: Analyzers use chained methods (`.include_internals()`, `.min_percent()`, `.top_n()`)
- **Strategy Pattern**: `OutputFormat` enum + `Formatter` trait for pluggable output
- **IR Pattern**: All modules work with normalized `ProfileIR`, not raw V8 types
## Code Conventions
### Strict Linting
Pedantic and nursery clippy lints are enabled. Key requirements:
- No `dbg!()`, `todo!()`, `unimplemented!()`
- No `print!()` / `println!()` - use `eprintln!()` for CLI output
- Run `cargo clippy` before committing
### Error Handling
- Use `thiserror` for error types with `#[derive(Error)]`
- Two main error types: `ParseError` and `OutputError`
### Standard Derives
```rust
#[derive(Debug, Clone)] // Most types
#[derive(Debug, Clone, Serialize)] // Output types
#[derive(Debug, Deserialize)] // Input types (V8 JSON)
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] // IDs and enums
```
## Test Data
- `test-runner-profile/` - Real V8 profiles for integration tests
- `tests/fixtures.rs` - Synthetic profile builders for unit tests
- `examples/` - Example output files in various formats