Ctrl K
ComunidadGuías…

CONTRIBUTING.md

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# Contributing to Basic Memory

Thank you for considering contributing to Basic Memory! This document outlines the process for contributing to the
project and how to get started as a developer.

## Getting Started

### Development Environment

1. **Clone the Repository**:
   ```bash
   git clone https://github.com/basicmachines-co/basic-memory.git
   cd basic-memory
   ```

2. **Install Dependencies**:
   ```bash
   # Using just (recommended)
   just install
   
   # Or using uv
   uv install -e ".[dev]"
   
   # Or using pip
   pip install -e ".[dev]"
   ```

   > **Note**: Basic Memory uses [just](https://just.systems) as a modern command runner. Install with `brew install just` or `cargo install just`.

3. **Activate the Virtual Environment**
   ```bash
   source .venv/bin/activate
   ```

   **Keep dev state out of your everyday config.** The repo's `.envrc` sets
   `BASIC_MEMORY_CONFIG_DIR` to `~/.config/basic-memory-dev` for this checkout, so dev
   settings such as a Postgres backend never land in `~/.config/basic-memory`. With
   [direnv](https://direnv.net) installed, run `direnv allow` once per checkout or
   worktree. Without direnv, export the variable yourself before running `bm`:
   ```bash
   export BASIC_MEMORY_CONFIG_DIR=~/.config/basic-memory-dev
   ```
   direnv only acts in an interactive shell, so agents and scripts that run `bm` in a
   checkout should set the variable explicitly.

4. **Run the Tests**:
   ```bash
   # Run all tests with unified coverage (unit + integration)
   just test

   # Run unit tests only (fast, no coverage)
   just test-unit

   # Run integration tests only (fast, no coverage)
   just test-int

   # Generate HTML coverage report
   just coverage

   # Run a specific test
   pytest tests/path/to/test_file.py::test_function_name
   ```

### Development Workflow

1. **Fork the Repo**: Fork the repository on GitHub and clone your copy.
2. **Create a Branch**: Create a new branch for your feature or fix.
   ```bash
   git checkout -b feature/your-feature-name
   # or
   git checkout -b fix/issue-you-are-fixing
   ```
3. **Make Your Changes**: Implement your changes with appropriate test coverage.
4. **Check Code Quality**:
   ```bash
   # Run all checks at once
   just check
   
   # Or run individual checks
   just lint      # Run linting
   just format    # Format code
   just type-check  # Type checking
   ```
5. **Test Your Changes**: Ensure all tests pass locally and maintain 100% test coverage.
   ```bash
   just test
   ```
6. **Submit a PR**: Submit a pull request with a detailed description of your changes.

## LLM-Assisted Development

This project is designed for collaborative development between humans and LLMs (Large Language Models):

1. **CLAUDE.md**: The repository includes a `CLAUDE.md` file that serves as a project guide for both humans and LLMs.
   This file contains:
    - Key project information and architectural overview
    - Development commands and workflows
    - Code style guidelines
    - Documentation standards

2. **AI-Human Collaborative Workflow**:
    - We encourage using LLMs like Claude for code generation, reviews, and documentation
    - When possible, save context in markdown files that can be referenced later
    - This enables seamless knowledge transfer between different development sessions
    - Claude can help with implementation details while you focus on architecture and design

3. **Adding to CLAUDE.md**:
    - If you discover useful project information or common commands, consider adding them to CLAUDE.md
    - This helps all contributors (human and AI) maintain consistent knowledge of the project

## Pull Request Process

1. **Create a Pull Request**: Open a PR against the `main` branch with a clear title and description. PR titles must
   follow the semantic format `type(scope): summary`, enforced by CI — for example `fix(core): unresolve inbound
   relations on entity delete`. Allowed types: `feat`, `fix`, `chore`, `docs`, `style`, `refactor`, `perf`, `test`,
   `build`, `ci`. Allowed scopes: `core`, `cli`, `api`, `mcp`, `sync`, `ui`, `ci`, `deps`, `installer`, `plugins`,
   `skills`, `integrations`.
2. **Sign the Developer Certificate of Origin (DCO)**: All commits require a `Signed-off-by` line certifying that you
   have the right to submit your contributions. The DCO status check verifies this automatically when you create a PR.
   See [Signing Your Commits](#signing-your-commits) below, including how to fix commits you already pushed.
3. **Accept the Contributor License Agreement (CLA)**: All contributors must also accept the
   [Contributor License Agreement](CLA.md). The `license/cla` status check verifies this separately from the DCO check.
   There is no separate step outside GitHub: when you open your first PR, the CLA assistant bot comments with a link
   (also at [cla-assistant.io/basicmachines-co/basic-memory](https://cla-assistant.io/basicmachines-co/basic-memory)).
   Sign in with your GitHub account, agree, and the check turns green on its own. You sign once per GitHub account;
   it covers your future PRs too.
4. **PR Description**: Include:
    - What the PR changes
    - Why the change is needed
    - How you tested the changes
    - Any related issues (use "Fixes #123" to automatically close issues)
5. **Code Review**: Wait for code review and address any feedback.
6. **CI Checks**: Ensure all CI checks pass. Note that the test matrix runs only on pushes to this repository, so a PR
   from a fork gets the DCO, CLA, and static checks but not the full test suite. Run `just test` locally before
   asking for review.
7. **Merge**: Once approved, a maintainer will merge your PR. For fork PRs, a maintainer usually cherry-picks your
   commits onto an in-repo branch so the full matrix can run, opens a replacement PR that references yours, and
   rebase-merges it. Your commits land on `main` with your authorship and sign-off intact; the original PR is closed
   with a link to the replacement.

## Developer Certificate of Origin and CLA

Basic Memory requires both a DCO commit sign-off and CLA acceptance for pull requests.

The DCO sign-off means you certify that:

- You have the right to submit your contributions
- You're not knowingly submitting code with patent or copyright issues
- Your contributions are provided under the project's license (AGPL-3.0)

The CLA is a separate contributor agreement that allows Basic Machines LLC to incorporate, distribute, and relicense
accepted contributions. The `license/cla` check verifies CLA acceptance, while the DCO check verifies commit sign-off.

### Signing Your Commits

Sign your commit:

**Using the `-s` or `--signoff` flag**:

```bash
git commit -s -m "Your commit message"
```

This adds a `Signed-off-by: Your Name <you@example.com>` line to your commit message, certifying that you adhere to
the DCO. The name and email must match the commit's author (`git config user.name` / `user.email`), or the DCO check
fails.

If you already made commits without a sign-off, add it retroactively and force-push your branch:

```bash
# Sign off every commit on your branch (all commits since main)
git rebase --signoff origin/main
git push --force-with-lease
```

The sign-off certifies that you have the right to submit your contribution under the project's license and verifies your
agreement to the DCO.

## Code Style Guidelines

- **Python Version**: Python 3.12+ with full type annotations (3.12+ required for type parameter syntax)
- **Line Length**: 100 characters maximum
- **Formatting**: Use ruff for consistent styling
- **Import Order**: Standard lib, third-party, local imports
- **Naming**: Use snake_case for functions/variables, PascalCase for classes
- **Documentation**: Add docstrings to public functions, classes, and methods
- **Type Annotations**: Use type hints for all functions and methods

## Testing Guidelines

### Test Structure

Basic Memory uses two test directories with unified coverage reporting:

- **`tests/`**: Unit tests that test individual components in isolation
  - Fast execution with extensive mocking
  - Test individual functions, classes, and modules
  - Run with: `just test-unit` (no coverage, fast)

- **`test-int/`**: Integration tests that test real-world scenarios
  - Test full workflows with real database and file operations
  - Include performance benchmarks
  - More realistic but slower than unit tests
  - Run with: `just test-int` (no coverage, fast)

### Running Tests

```bash
# Run all tests with unified coverage report
just test

# Run only unit tests (fast iteration)
just test-unit

# Run only integration tests
just test-int

# Generate HTML coverage report
just coverage

# Run specific test
pytest tests/path/to/test_file.py::test_function_name

# Run tests excluding benchmarks
pytest -m "not benchmark"

# Run only benchmark tests
pytest -m benchmark test-int/test_sync_performance_benchmark.py
```

### Performance Benchmarks

The `test-int/test_sync_performance_benchmark.py` file contains performance benchmarks that measure sync and indexing speed:

- `test_benchmark_sync_100_files` - Small repository performance
- `test_benchmark_sync_500_files` - Medium repository performance
- `test_benchmark_sync_1000_files` - Large repository performance (marked slow)
- `test_benchmark_resync_no_changes` - Re-sync performance baseline

Run benchmarks with:
```bash
# Run all benchmarks (excluding slow ones)
pytest test-int/test_sync_performance_benchmark.py -v -m "benchmark and not slow"

# Run all benchmarks including slow ones
pytest test-int/test_sync_performance_benchmark.py -v -m benchmark

# Run specific benchmark
pytest test-int/test_sync_performance_benchmark.py::test_benchmark_sync_100_files -v
```

See `test-int/BENCHMARKS.md` for detailed benchmark documentation.

### Testing Best Practices

- **Coverage Target**: We aim for high test coverage for all code
- **Test Framework**: Use pytest for unit and integration tests
- **Mocking**: Avoid mocking in integration tests; use sparingly in unit tests
- **Edge Cases**: Test both normal operation and edge cases
- **Database Testing**: Use in-memory SQLite for testing database operations
- **Fixtures**: Use async pytest fixtures for setup and teardown
- **Markers**: Use `@pytest.mark.benchmark` for benchmarks, `@pytest.mark.slow` for slow tests

## Creating Issues

If you're planning to work on something, please create an issue first to discuss the approach. Include:

- A clear title and description
- Steps to reproduce if reporting a bug
- Expected behavior vs. actual behavior
- Any relevant logs or screenshots
- Your proposed solution, if you have one

## Code of Conduct

All contributors must follow the [Code of Conduct](CODE_OF_CONDUCT.md).

## Thank You!

Your contributions help make Basic Memory better. We appreciate your time and effort!