# Contributing to Cleave

Guide for contributing to the Cleave project.

## Table of Contents

1. [Development Setup](#development-setup)
2. [Running Tests](#running-tests)
3. [Adding Patterns](#adding-patterns)
4. [Code Style](#code-style)
5. [Submitting PRs](#submitting-prs)
6. [Documentation](#documentation)

## Development Setup

### Prerequisites

- Python 3.11+
- Git
- pipx or pip

### Clone and Install

```bash
# Clone the repository
git clone git@github.com:styrene-lab/cleave.git
cd cleave

# Create virtual environment
python3 -m venv .venv
source .venv/bin/activate  # On Windows: .venv\Scripts\activate

# Install in editable mode with dev dependencies
pip install -e ".[dev,tui]"

# Install the skill
cleave install-skill

# Verify installation
cleave --version
pytest --version
```

### Project Structure

```
cleave/
├── src/cleave/
│   ├── core/              # Core logic (assessment, conflicts, reunify)
│   │   ├── assessment.py  # Pattern matching, complexity calculation
│   │   ├── conflicts.py   # Conflict detection
│   │   ├── reunify.py     # Reunification logic
│   │   ├── workspace.py   # Workspace management
│   │   └── ...
│   ├── tui/               # Terminal UI
│   │   ├── app.py         # Main TUI application
│   │   ├── backends/      # LLM backend integrations
│   │   ├── screens/       # TUI screens
│   │   ├── services/      # TUI services (session, history, etc.)
│   │   └── widgets/       # Custom Textual widgets
│   ├── skill/             # Claude Code skill
│   │   ├── __init__.py    # Skill entry point
│   │   └── SKILL.md       # Skill documentation
│   ├── cli.py             # CLI commands
│   └── __init__.py        # Package initialization
├── tests/                 # Test suite
│   ├── test_assessment.py
│   ├── test_conflicts.py
│   ├── test_reunify.py
│   └── ...
├── examples/              # Example CALF files and workflows
├── docs/                  # Documentation
├── pyproject.toml         # Project metadata and dependencies
└── README.md              # Main readme
```

## Running Tests

### Full Test Suite

```bash
# Run all tests
pytest

# Run with coverage
pytest --cov=src/cleave --cov-report=html

# View coverage report
open htmlcov/index.html  # macOS
xdg-open htmlcov/index.html  # Linux
```

### Specific Test Modules

```bash
# Test assessment logic
pytest tests/test_assessment.py -v

# Test conflict detection
pytest tests/test_conflicts.py -v

# Test reunification
pytest tests/test_reunify.py -v
```

### Test Markers

```bash
# Run only unit tests (fast)
pytest -m unit

# Run integration tests (slower)
pytest -m integration

# Skip slow tests
pytest -m "not slow"
```

### Writing Tests

Follow these patterns:

**Unit Test Example**:
```python
# tests/test_assessment.py
def test_complexity_calculation():
    """Test complexity formula with known inputs."""
    systems = 3
    modifiers = 2
    expected = (1 + systems) * (1 + 0.5 * modifiers)

    result = calculate_complexity(systems, modifiers)

    assert result == expected
```

**Integration Test Example**:
```python
# tests/test_workspace.py
def test_workspace_initialization(tmp_path):
    """Test workspace creation with manifest."""
    directive = "Add user authentication"
    children = ["Backend", "Frontend"]

    workspace = init_workspace(
        workspace_dir=tmp_path / ".cleave",
        directive=directive,
        children=children
    )

    assert (workspace / "manifest.yaml").exists()
    assert (workspace / "siblings.yaml").exists()
    assert (workspace / "0-task.md").exists()
```

## Adding Patterns

Patterns live in `src/cleave/core/assessment.py`.

### Pattern Definition

```python
# src/cleave/core/assessment.py

PATTERNS = [
    {
        "name": "Your Pattern Name",
        "keywords": ["keyword1", "keyword2", "keyword3"],
        "systems_base": 3,  # Expected number of systems
        "modifiers": {
            "modifier_name": True,  # Expected modifiers
        },
        "confidence_threshold": 0.80,
    },
    # ... existing patterns
]
```

### Pattern Fields Explained

- **name**: Human-readable pattern name (used in output)
- **keywords**: List of terms that trigger this pattern (lowercase)
- **systems_base**: Expected number of systems for this pattern
- **modifiers**: Dict of expected modifiers (`True` means this modifier is typical)
- **confidence_threshold**: Minimum confidence to consider this a match

### Adding a New Pattern

**Step 1: Define the pattern**

```python
{
    "name": "Notification System",
    "keywords": ["notification", "push", "email", "sms", "alert", "notify"],
    "systems_base": 3,  # API, Notification Service, Queue
    "modifiers": {
        "external_api": True,      # Email/SMS providers
        "state_coordination": True, # User preferences, delivery status
        "error_handling": True,    # Delivery failures, retries
    },
    "confidence_threshold": 0.75,
}
```

**Step 2: Add test cases**

```python
# tests/test_assessment.py

def test_notification_pattern_match():
    """Test notification pattern is recognized."""
    directive = "Add email and SMS notifications for order updates"

    result = match_pattern(directive)

    assert result["pattern"] == "Notification System"
    assert result["confidence"] >= 0.75
    assert result["systems"] >= 3
```

**Step 3: Test with real examples**

```bash
# Create test CALF file
cat > test-notification.calf << 'EOF'
Add email and SMS notifications for order updates. Users should
receive notifications when order is placed, shipped, and delivered.
Support notification preferences and delivery history.
EOF

# Test pattern matching
cleave match --directive "$(cat test-notification.calf)"
```

**Step 4: Calibrate**

Run actual cleave sessions and collect metrics:
```bash
/cleave
$(cat test-notification.calf)

# After completion
cleave metrics --workspace .cleave
```

Adjust `systems_base`, `modifiers`, or `confidence_threshold` based on results.

**Step 5: Document the pattern**

Add to `examples/patterns/`:

```bash
# Create example files
examples/patterns/notification-system.calf
examples/patterns/notification-system.md
```

### Pattern Quality Checklist

- [ ] Keywords are specific enough (not too generic like "add", "implement")
- [ ] Keywords cover variations (e.g., "auth", "authentication", "login")
- [ ] `systems_base` reflects typical system count for this pattern
- [ ] Modifiers match expected complexity factors
- [ ] Confidence threshold is achievable (tested on real directives)
- [ ] Test cases added to `tests/test_assessment.py`
- [ ] Example CALF file added to `examples/patterns/`
- [ ] Documentation added to `examples/patterns/<pattern>.md`

## Code Style

### Python Style Guide

Follow PEP 8 with these conventions:

- **Line length**: 100 characters (not 79)
- **Indentation**: 4 spaces (never tabs)
- **Quotes**: Double quotes for strings
- **Imports**: Grouped (stdlib, third-party, local)

### Formatting

Use `black` for formatting:

```bash
# Format all code
black src/ tests/

# Check formatting without changing files
black --check src/ tests/
```

### Linting

Use `ruff` for linting:

```bash
# Lint all code
ruff check src/ tests/

# Fix auto-fixable issues
ruff check --fix src/ tests/
```

### Type Hints

Use type hints for function signatures:

```python
def calculate_complexity(systems: int, modifiers: int) -> float:
    """Calculate complexity score."""
    return (1 + systems) * (1 + 0.5 * modifiers)
```

Run type checking with `mypy`:

```bash
mypy src/cleave
```

### Pre-Commit Hooks

Install pre-commit hooks:

```bash
# Install pre-commit
pip install pre-commit

# Install hooks
pre-commit install

# Run manually
pre-commit run --all-files
```

Hooks run automatically on `git commit`.

## Submitting PRs

### Before Submitting

1. **Run tests**: `pytest`
2. **Check formatting**: `black --check src/ tests/`
3. **Check linting**: `ruff check src/ tests/`
4. **Check types**: `mypy src/cleave`
5. **Update docs** if adding features

### PR Guidelines

**Title**: Use conventional commits format
```
feat: add notification pattern
fix: correct complexity calculation for nested cleaving
docs: add TUI usage guide
```

**Description**: Include
- What changed and why
- How to test the changes
- Related issues (if any)

**Example**:
```markdown
## Changes
- Added "Notification System" pattern to assessment.py
- Added tests for pattern matching
- Added example CALF file and documentation

## Testing
```bash
pytest tests/test_assessment.py::test_notification_pattern_match
cleave match --directive "$(cat examples/patterns/notification-system.calf)"
```

## Related Issues
Closes #42
```

### PR Workflow

1. **Fork the repository** (if external contributor)
2. **Create a branch**: `git checkout -b feat/notification-pattern`
3. **Make changes** and commit
4. **Push to GitHub**: `git push origin feat/notification-pattern`
5. **Open PR** on GitHub
6. **Address review feedback**
7. **Merge** after approval

### Commit Messages

Use conventional commits:

- `feat:` - New feature
- `fix:` - Bug fix
- `docs:` - Documentation changes
- `test:` - Test changes
- `refactor:` - Code refactoring
- `chore:` - Maintenance tasks

Examples:
```bash
git commit -m "feat: add notification pattern"
git commit -m "fix: correct complexity calculation for security modifiers"
git commit -m "docs: add advanced patterns guide"
```

## Documentation

### Updating Documentation

Documentation lives in:
- `README.md` - Main project readme
- `docs/guides/` - User guides
- `docs/architecture/` - Architecture documentation
- `examples/` - Working examples
- `src/cleave/skill/SKILL.md` - Claude Code skill documentation

### Documentation Standards

- **Tone**: Clear, concise, technical but friendly
- **Code examples**: Always include working examples
- **Commands**: Show full command with expected output
- **Structure**: Use hierarchical headings, tables of contents

### Adding a New Guide

1. Create markdown file in `docs/guides/`
2. Follow existing guide structure (see `getting-started.md`)
3. Update main `README.md` with link to new guide
4. Add examples to `examples/` if applicable

### Building Documentation Site (Future)

```bash
# Install mkdocs
pip install mkdocs mkdocs-material

# Serve locally
mkdocs serve

# Build static site
mkdocs build
```

## Release Process

(For maintainers)

### Version Bumping

Update version in `pyproject.toml`:

```toml
[project]
version = "0.2.0"
```

### Building Package

```bash
# Install build tools
pip install build twine

# Build distribution
python -m build

# Check distribution
twine check dist/*
```

### Publishing to PyPI

```bash
# Upload to TestPyPI (test first)
twine upload --repository testpypi dist/*

# Verify TestPyPI install
pipx install --index-url https://test.pypi.org/simple/ styrene-cleave

# Upload to PyPI
twine upload dist/*
```

### Tagging Release

```bash
# Create tag
git tag -a v0.2.0 -m "Release v0.2.0"

# Push tag
git push origin v0.2.0
```

### GitHub Release

Create GitHub release from tag, including:
- Changelog
- Notable features
- Breaking changes
- Installation instructions

## Getting Help

- **Issues**: [GitHub Issues](https://github.com/styrene-lab/cleave/issues)
- **Discussions**: [GitHub Discussions](https://github.com/styrene-lab/cleave/discussions)
- **Email**: cleave@styrene-lab.com

## Code of Conduct

Be respectful, constructive, and collaborative. We're all here to build better tools together.
