# Conventional Commits Guide

This project uses [Conventional Commits](https://www.conventionalcommits.org/) for clear, structured commit history and automated changelog generation via [git-cliff](https://git-cliff.org/).

---

## Format

```
<type>[optional scope]: <description>

[optional body]

[optional footer(s)]
```

### Types

| Type | Description | Changelog Group |
|------|-------------|-----------------|
| `feat` | New feature | 🚀 Features |
| `fix` | Bug fix | 🐛 Bug Fixes |
| `docs` | Documentation only | 📚 Documentation |
| `style` | Code style (formatting, missing semi-colons, etc) | 🎨 Styling |
| `refactor` | Code change that neither fixes a bug nor adds a feature | 🚜 Refactor |
| `perf` | Performance improvement | ⚡ Performance |
| `test` | Adding or updating tests | 🧪 Testing |
| `chore` | Maintenance tasks, dependency updates | ⚙️ Miscellaneous |
| `ci` | CI/CD configuration changes | ⚙️ Miscellaneous |
| `revert` | Revert a previous commit | ◀️ Revert |

### Scope (Optional)

The scope provides additional context about what part of the codebase changed:
- `api` - API layer changes
- `adapters` - Database/service adapters
- `mcp` - MCP server
- `tests` - Test suite
- `deps` - Dependencies
- `config` - Configuration

Example: `feat(api): add health check endpoint`

### Breaking Changes

Add `!` after type/scope or add `BREAKING CHANGE:` footer:

```
feat!: rename search endpoint to query

BREAKING CHANGE: The /search endpoint has been renamed to /query
```

---

## Examples

### Good Commits ✅

```bash
# Feature with scope
feat(mcp): add code exploration tool

# Bug fix
fix: handle empty query results gracefully

# Documentation
docs: update API reference with new endpoints

# Refactor with breaking change
refactor!: replace Qdrant with pgvector

BREAKING CHANGE: Database migration required
```

### Commits That Need Normalization ⚠️

These will be automatically normalized by git-cliff preprocessors:

```bash
# Emoji prefixes (normalized to conventional)
🎨 Style: fix linting issues
# → style: fix linting issues

🔒 Fix Git Argument Injection
# → fix: Git Argument Injection

# Capitalized type
Fix: correct health path
# → fix: correct health path

# Atomic sweep commits
[atomic-sweep] validate graph inputs
# → chore(sweep): validate graph inputs
```

### Avoid ❌

```bash
# Too vague
"updates"
"fixes stuff"
"WIP"

# Non-descriptive
"changes"
"misc"

# Without type
"Add new feature"  # Should be: feat: add new feature
```

---

## Using with Claude Code

When committing via Claude Code, the commit message is pre-formatted with:
```
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
```

This is preserved and doesn't affect conventional commit parsing.

---

## Generating Changelog

### View unreleased changes
```bash
git-cliff --unreleased
```

### Generate full changelog
```bash
git-cliff -o CHANGELOG.md
```

### Generate changelog for specific version
```bash
git-cliff --tag v0.1.0
```

### Generate changelog since last tag
```bash
git-cliff --latest
```

---

## Configuration

The `cliff.toml` file controls changelog generation:

- **commit_preprocessors**: Normalize non-conventional commits (emojis, capitalization)
- **commit_parsers**: Group commits by type
- **filter_unconventional**: `false` (includes all commits, non-conventional go to "Other")
- **conventional_commits**: `true` (parse conventional format when present)

---

## Migration from Old Format

If you have old commits that don't follow conventional format:

1. **They'll still appear in changelog** under "💼 Other" section
2. **Preprocessors handle common patterns** (emoji prefixes, [atomic-sweep], etc.)
3. **Going forward, use conventional format** for better categorization

### Rewriting History (Optional, Advanced)

If you want to clean up recent commits:

```bash
# Interactive rebase to edit commit messages
git rebase -i HEAD~10

# In the editor, mark commits to reword:
# Change "pick" to "reword" (or "r")

# Git will prompt you to edit each marked commit message
```

**⚠️ Warning:** Only rewrite commits that haven't been pushed or if you're the only developer.

---

## Pre-commit Hook (Optional)

Install `commitizen` or `commitlint` to validate commits:

```bash
# Install commitlint
npm install -g @commitlint/cli @commitlint/config-conventional

# Add to .git/hooks/commit-msg
echo '#!/bin/sh
commitlint --edit $1' > .git/hooks/commit-msg
chmod +x .git/hooks/commit-msg
```

---

## Quick Reference

```bash
# Most common patterns
feat: add new feature
fix: resolve bug
docs: update documentation
refactor: restructure code
test: add test coverage
chore: update dependencies

# With scope
feat(api): add endpoint
fix(mcp): handle timeout

# Breaking change
feat!: rename API
```

---

For more details, see:
- [Conventional Commits spec](https://www.conventionalcommits.org/)
- [git-cliff documentation](https://git-cliff.org/docs/)
