# Contributing to knot
Contributions are welcome! Please ensure:
- All code passes `cargo clippy --all-targets -- -D warnings`
- Code is formatted with `cargo fmt`
- Changes are compatible with Rust 2024 edition (requires Rust 1.90+)
- Unit tests are added for new functionality
- E2E regression tests are added for bug fixes
- Performance regressions are validated with the benchmark framework before submitting PRs
- No `unsafe` code is introduced (except in unavoidable ONNX Runtime interop)
## Local Environment Setup
To run `knot` locally, you need Docker to spin up the required databases and the Rust toolchain to build the project.
1. **Prerequisites**: Ensure you have Docker (20.10+) and Rust 1.90+ installed.
2. **Clone the repository**:
```bash
git clone https://github.com/raultov/knot
cd knot
```
3. **Start the databases** (Qdrant for vector search and Neo4j for graph relationships):
```bash
docker compose up -d
```
*(Note: For running E2E tests, the scripts will automatically spin up ephemeral databases using `tests/docker-compose.e2e.yml`)*
4. **Configure environment variables**:
```bash
cp .env.example .env
```
5. **Build the project**:
```bash
cargo build --release
```
## Running Tests
`knot` employs a rigorous testing strategy including unit, end-to-end (E2E), and performance benchmarks.
### Unit Tests
Unit tests are typically located inline within the source modules and define the contract for parsing logic.
```bash
# Run all unit tests
cargo test
# Run tests for a specific module
cargo test --lib pipeline::parser
```
### End-to-End (E2E) Tests
E2E tests validate the full ingestion and querying pipeline. They are written first (BDD) and must fail before the logic is implemented.
```bash
# Run all E2E language suites
./tests/run_all_e2e.sh
# Run a specific language suite
./tests/run_rust_e2e.sh
./tests/run_kotlin_e2e.sh
./tests/run_e2e.sh # JS/TS/Java/HTML/CSS
```
### Performance Benchmarks
To validate optimizations and detect regressions:
```bash
# 1. Run Criterion unit benchmarks (throughput per language, etc.)
cargo bench --bench pipeline_bench
cargo bench --bench graph_upsert_bench
# 2. Run E2E integration benchmarks (captures full pipeline metrics)
./tests/benchmark_e2e.sh --focus rust_e2e --output-dir /tmp/perf_results
# 3. Compare against the baseline to ensure no regressions
scripts/compare_perf_metrics.sh /tmp/perf_results .perf_metrics/baseline.json
```
## Architecture Overview
`knot` follows a high-performance, dual-database architecture:
- **Vector Database (Qdrant)**: Stores embeddings for semantic code understanding.
- **Graph Database (Neo4j)**: Stores structural relationships (e.g., call graphs, inheritance).
The project is split into three main binaries:
- `knot-indexer` (`src/bin/knot-indexer.rs`): Parses source code via Tree-sitter, extracts entities, and builds the indexes. Uses parallel streaming (MPSC channels) to overlap CPU-bound embedding with I/O-bound ingestion.
- `knot` (`src/bin/knot.rs`): The standalone CLI tool for semantic search and reverse dependency lookup.
- `knot-mcp` (`src/bin/knot-mcp.rs`): The MCP server that exposes `knot` capabilities to AI clients (like Claude or Cursor).
## Where to Start? (Easy Modules to Touch)
If you are looking to contribute, here are the most accessible areas:
- **Adding or Fixing Language Support**: Look into `src/pipeline/parser/languages/`. Each language (like `java.rs`, `rust.rs`, `python.rs`) has a dedicated file where AST parsing is defined. This is the best place to start if you want to improve how a specific language is parsed or add a new one. You'll also likely need to modify or add Tree-sitter queries in the `queries/` directory.
- **Enhancing AI Tools (MCP)**: Check out `src/mcp_tools/`. If you want to improve the prompts, tool descriptions, or formatting returned to AI agents, this is the place.
- **CLI Improvements**: Modify `src/bin/knot.rs` to add new commands or improve output formatting for terminal users.