Skip to content

Latest commit

 

History

History
269 lines (201 loc) · 10 KB

File metadata and controls

269 lines (201 loc) · 10 KB

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 仓库:

    git clone https://github.com/basicmachines-co/basic-memory.git
    cd basic-memory
  2. Install Dependencies:

    # Using just (recommended)
    just install
    
    # Or using uv
    uv install -e ".[dev]"
    
    # Or using pip
    pip install -e ".[dev]"

    Note: Basic Memory uses just as a modern command runner. Install with brew install just or cargo install just.

  3. Activate the Virtual Environment

    source .venv/bin/activate
  4. Run the Tests:

    # 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. 复刻 the Repo: 复刻 the repository on GitHub and clone your copy.
  2. Create a Branch: Create a new branch for your feature or fix.
    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:
    # 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.
    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 提交 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. 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). 登录 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 提交

Sign your commit:

Using the -s or --signoff flag:

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:

# 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

# 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:

# 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 问题

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.

Thank You!

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