Metadata-Version: 2.4
Name: ravmem-server
Version: 0.1.0
Summary: RavMem Server — code knowledge graph engine with MCP-native AI augmentation
Author-email: RavMem <harpreet.singh@ravmem.com>
License-Expression: Elastic-2.0
Project-URL: Homepage, https://www.ravmem.com
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Operating System :: OS Independent
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: ravmem-cli>=0.1.0
Requires-Dist: arcadedb-python>=0.4.0
Requires-Dist: hnswlib>=0.8.0
Requires-Dist: fastembed>=0.3.0
Requires-Dist: tree-sitter>=0.22.0
Requires-Dist: tree-sitter-python>=0.21.0
Requires-Dist: tree-sitter-typescript>=0.21.0
Requires-Dist: tree-sitter-go>=0.21.0
Requires-Dist: fastapi>=0.115.0
Requires-Dist: uvicorn[standard]>=0.30.0
Requires-Dist: rank-bm25>=0.2.2
Requires-Dist: networkx>=3.3
Requires-Dist: scipy>=1.11.0
Requires-Dist: numpy>=1.26.0
Requires-Dist: pyyaml>=6.0
Requires-Dist: leidenalg>=0.10.0
Requires-Dist: igraph>=0.11.0
Requires-Dist: cryptography>=42.0.0
Provides-Extra: dev
Requires-Dist: pytest>=8.0.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.23.0; extra == "dev"
Requires-Dist: httpx<0.28.0,>=0.27.0; extra == "dev"
Provides-Extra: arcade
Provides-Extra: langs
Requires-Dist: tree-sitter-java>=0.21.0; extra == "langs"
Requires-Dist: tree-sitter-c-sharp>=0.21.0; extra == "langs"
Requires-Dist: tree-sitter-php>=0.22.0; extra == "langs"
Requires-Dist: tree-sitter-rust>=0.21.0; extra == "langs"
Requires-Dist: tree-sitter-kotlin>=0.3.0; extra == "langs"
Requires-Dist: tree-sitter-ruby>=0.21.0; extra == "langs"
Requires-Dist: tree-sitter-c>=0.21.0; extra == "langs"
Requires-Dist: tree-sitter-cpp>=0.22.0; extra == "langs"
Dynamic: license-file

# RavMem

A code knowledge graph engine that indexes codebases using AST parsing, builds a persistent knowledge graph, and exposes REST/MCP/WebSocket APIs for AI agent integration.

**Features:**
- 5-phase indexing pipeline (structure → parse → resolve → cluster → embed)
- Hybrid search: BM25 keyword + semantic vector search with Reciprocal Rank Fusion
- Blast-radius impact analysis via graph traversal
- Branch-aware indexing — each branch gets its own isolated index on the server
- Incremental re-indexing using `git diff` (or MD5 checksums for non-git repos)
- **O(1) branch creation** — ArcadeDB Copy-on-Write: new branch registers `parent_branch`; no files copied; unchanged symbols inherited by reference at query time
- Pre-flight divergence check with user prompt before large re-indexes
- Auto branch detection — CLI reads current git branch automatically
- Bounded async job queue (`RAVMEM_MAX_CONCURRENT_JOBS`, default 2), crash recovery, atomic index swaps
- MCP (Model Context Protocol) support for AI agents
- **ArcadeDB** graph backend (external Docker server); hnswlib vectors + SQLite metadata always local

---

> For a deep-dive into internals  -  storage schemas, pipeline mechanics, incremental indexing steps, branch copy optimization, engine caching, and the full data flow  -  see [ARCHITECTURE.md](ARCHITECTURE.md).

## Table of Contents

1. [Architecture Overview](#architecture-overview)
2. [Installation](#installation)
3. [Quick Start](#quick-start)
4. [Server Setup](#server-setup)
5. [CLI Client Setup](#cli-client-setup)
6. [Indexing a Repository](#indexing-a-repository)
7. [Querying the Index](#querying-the-index)
8. [Branch-Aware Indexing Walkthrough](#branch-aware-indexing-walkthrough)
9. [Docker](#docker)
10. [Python Client Library](#python-client-library)
11. [Manual Verification Checklist](#manual-verification-checklist)
12. [CLI Reference](#cli-reference)
13. [API Reference](#api-reference)
14. [Environment Variables](#environment-variables)
15. [Supported Languages](#supported-languages)
16. [Development & Tests](#development--tests)

---

## Architecture Overview

RavMem has two separate components:

```
+---------------------------------+     HTTP      +--------------------------------------+
|  CLI  (ravmem analyze/       | -------------> |  Server  (ravmem serve)           |
|        search/impact/remote)    |               |  - Owns all indexes                  |
|                                 |               |  - Per-branch isolated storage       |
|  Reads: ~/.ravmem/client.json|               |  - Async job queue                   |
|  Auto-detects: git branch       |               |  - Can run on host or in Docker      |
+---------------------------------+               +--------------------------------------+
```

**The CLI never indexes locally.** All indexing, search, and impact analysis runs on the server. Multiple users can work on different branches simultaneously  -  each branch has its own isolated index.

### Clustering

Phase 4 (cluster) runs two different algorithms depending on context:

| Mode | Algorithm | Cluster ID prefix | When |
|------|-----------|-------------------|------|
| Full index | **Leiden** (`leidenalg` + directed igraph) | `lc_` | `ravmem analyze` (first run / full reindex) |
| Incremental | **File-based** (path hash, O(n)) | `fc_` | `ravmem analyze` (incremental update) |
| Fallback | Louvain (`python-louvain`) | `c_` | Only if `leidenalg` not installed |

**Why this matters for agents:**
- `lc_abc123` — Leiden cross-file community, computed once on `main`, stable as long as the codebase structure is unchanged
- `fc_def456` — single-file cluster, assigned during incremental runs; always one cluster per source file (or per package for `__init__.py`)
- Mixed cluster types coexist in the same index — both are valid inputs to `get_cluster`

**Cluster ID stability:** Leiden IDs are anchored on the centroid (most-called) symbol's stable hash. File-based IDs are `sha256(file_path)[:12]`. Neither changes when `leidenalg` is upgraded. A file rename changes the `fc_` ID — this is correct (the file's identity changed).

**Performance:** Incremental clustering is O(changed symbols), not O(all symbols). On a 100K symbol codebase with 10 changed files, cluster phase time drops from ~15s to <1ms.

**Tuning:** See `RAVMEM_CLUSTER_RESOLUTION` (default 1.0), `RAVMEM_CLUSTER_MAX_SIZE` (default 500), `RAVMEM_CLUSTER_SUBCLUSTER_THRESHOLD` (default 200) in [Environment Variables](#environment-variables).

---

## Installation

**Requires Python 3.11.** Python 3.12+ breaks `torch`/`sentence-transformers` in the current dependency set.

```bash
cd context-engine/ravmem
python3.11 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
pip install --no-deps -e .

# Optional: extended language support (Java, C#, Rust, Kotlin, Ruby, PHP, C/C++)
pip install "ravmem[langs]"

# No extra install needed for ArcadeDB server backend —
# arcadedb-python HTTP client is already in core deps.
# The ArcadeDB server itself runs as a Docker container (see Docker section).

# Verify
ravmem --help
```

---

## Quick Start

```bash
# 1. Start the server
ravmem serve --port 7432

# 2. Configure the CLI to point at it
ravmem remote config --url http://localhost:7432

# 3. Register your repo
ravmem remote add /path/to/my-repo --name my-repo --default-branch main

# 4. Index (auto-detects your current git branch)
cd /path/to/my-repo
ravmem analyze . --project my-repo --wait

# 5. Search
ravmem search "authenticate" --project my-repo

# 6. Blast-radius analysis
ravmem impact "UserService" --project my-repo
```

---

## Server Setup

### Start the server

```bash
# Default (data stored in ~/.ravmem/server/)
ravmem serve --port 7432

# Custom data directory
RAVMEM_DATA_DIR=/var/lib/ravmem ravmem serve --port 7432

# With API key authentication
RAVMEM_API_KEY=mysecretkey ravmem serve --port 7432

# Increase concurrent indexing jobs (default: 2)
RAVMEM_MAX_CONCURRENT_JOBS=4 ravmem serve --port 7432

# Dev mode
ravmem serve --port 7432 --reload --verbose
```

### Server data layout

```
~/.ravmem/server/           (or $RAVMEM_DATA_DIR)
  server.db                     project registry (projects, branch_indexes, jobs)
  repos/
    my-project/
      repo/                     git clone (if registered via URL)
      branches/
        main/
          vectors/      hnswlib HNSW index (per-branch)
          meta.db       SQLite (checksums, centrality, job history)
          bm25.json     BM25 corpus
        feature-auth/
          vectors/  meta.db  bm25.json
          ← NO graph/ dir: all graph data lives in the ArcadeDB server

[ArcadeDB server — separate Docker container]
  /home/arcadedb/databases/codegraph/
          ← single shared database, ALL projects and ALL branches
          ← branch isolation via 'branch' property on every vertex (CoW)
          ← reads try current branch first, fall back to parent_branch
```

---

## CLI Client Setup

### Configure the CLI

```bash
# Point the CLI at your server
ravmem remote config --url http://localhost:7432

# With API key
ravmem remote config --url http://localhost:7432 --api-key mysecretkey

# Config saved to ~/.ravmem/client.json
```

### Register a project

```bash
# From a path already on the server filesystem
ravmem remote add /path/to/repo --name my-project

# From a git URL (server clones it)
ravmem remote add https://github.com/org/repo.git --name my-project

# Set the default/parent branch (controls copy-from-base optimization)
ravmem remote add /path/to/repo --name my-project --default-branch main

# List all registered projects
ravmem remote projects

# Set a default project (saves typing --project on every command)
ravmem remote use my-project
```

### Manage branches

```bash
# List indexed branches for a project
ravmem remote branches --project my-project

# Check branch status
ravmem remote status --project my-project --branch main

# Check a specific job
ravmem remote status --job-id 7

# Update the default/parent branch after registration
ravmem analyze . --project my-project --default-branch develop
```

---

## Indexing a Repository

All `analyze` commands auto-detect the current git branch. Use `--branch` to override.

```bash
# Full index (first run or forced)
ravmem analyze /path/to/repo --project my-project

# Incremental update (only files changed since last index)
ravmem analyze /path/to/repo --project my-project --incremental

# Wait for indexing to complete before returning
ravmem analyze /path/to/repo --project my-project --wait

# Index a specific branch (overrides git auto-detection)
ravmem analyze /path/to/repo --project my-project --branch feature/auth

# Change the default branch and trigger a full index
ravmem analyze /path/to/repo --project my-project --default-branch develop --wait

# CI mode  -  skip confirmation prompt on large diffs (>60% files changed)
ravmem analyze /path/to/repo --project my-project --yes --wait

# Trigger via the remote subcommand (explicit mode control)
ravmem remote index --project my-project --branch main --mode full --wait
ravmem remote index --project my-project --branch main --mode incremental --wait
ravmem remote index --project my-project --branch main --mode auto --wait
```

### Large-diff prompt

When `>60%` of files have changed since the last index (e.g. after switching to a very different branch or a heavy rebase), RavMem warns before triggering a full re-index:

```
Warning: 277/316 files changed since last index (88%).
This will trigger a full re-index.
Proceed? [y/N]:
```

Pass `--yes` / `-y` to skip this in CI pipelines.

---

## Querying the Index

All query commands auto-detect the current git branch from the repo path (`--repo` flag, default `.`).

### Search

```bash
# Search in current directory's repo (branch auto-detected)
ravmem search "authenticate" --project my-project

# Search a specific repo path and branch
ravmem search "database connection" --repo /path/to/repo --project my-project --limit 20

# Override branch explicitly
ravmem search "parse_token" --project my-project --branch feature/auth
```

### Impact analysis

```bash
# Find everything that depends on a symbol (callers, transitively)
ravmem impact "UserService" --project my-project

# Control traversal depth (default: 3)
ravmem impact "parse_config" --repo /path/to/repo --project my-project --depth 5

# Override branch explicitly
ravmem impact "Elasticsearch" --project my-project --branch main
```

---

## Branch-Aware Indexing Walkthrough

### Step 1: Start the server and register a project

```bash
ravmem serve --port 7432 &
ravmem remote config --url http://localhost:7432
ravmem remote add /path/to/my-repo --name my-repo --default-branch main
ravmem remote use my-repo
```

### Step 2: Index the default branch

```bash
cd /path/to/my-repo
git checkout main
ravmem analyze . --project my-repo --wait
# Indexing started on branch 'main': job_id=1
# Job 1 finished: done
```

### Step 3: Index a feature branch

No file copy — records `parent_branch=main` in the registry, then runs incremental from the merge-base. Only files you actually changed on the branch get re-parsed and stored as branch-local vertices. All unchanged symbols are inherited from `main` by reference at query time.

```bash
git checkout -b feature/auth-refactor
# ... make some changes ...
ravmem analyze . --project my-repo --wait
# Indexing started on branch 'feature/auth-refactor': job_id=2
# Job 2 finished: done  (~3s — no copy, only changed files re-parsed)
```

### Step 4: Switch branches  -  no cross-branch pollution

```bash
# Query feature branch
git checkout feature/auth-refactor
ravmem search "login" --project my-repo
# -> results from feature/auth-refactor index

# Switch back  -  main index is untouched
git checkout main
ravmem search "login" --project my-repo
# -> results from main index
```

### Step 5: Incremental update after new commits

```bash
git commit -m "refactor auth"
ravmem analyze . --project my-repo --incremental --wait
# Only changed files re-parsed; ~13s vs ~60s full
```

Auto mode rules:
- Same commit as last index -> **skip** (returns immediately)
- 30% files changed -> **incremental**
- >60% files changed -> **full reindex** (with user prompt)
- Force-push or rebase detected -> always **full reindex**

### Step 6: Poll a long-running job manually

```bash
ravmem remote index --project my-repo --branch main --mode full
# Indexing started: job_id=7

ravmem remote status --job-id 7
# or:
watch -n2 'curl -s http://localhost:7432/api/jobs/7 | python3 -m json.tool'
```

---

## Docker

The Docker setup follows the **same server/CLI separation** as a bare installation. The container runs only the server (`ravmem serve`). The CLI runs on the host (or in CI) and talks to the container over HTTP.

RavMem uses **ArcadeDB** as its graph backend. `docker compose up` starts two containers — ArcadeDB first (health-checked), then ravmem.

**You never install Java yourself.** Docker pulls `arcadedata/arcadedb:latest` from Docker Hub — that image bundles its own JRE. The ravmem image is pure Python.

```bash
# Build ravmem image
docker build -t ravmem:latest .

# Optional config
cat > .env << 'EOF'
RAVMEM_API_KEY=your-secret-key
RAVMEM_LOG_LEVEL=info
ARCADEDB_PASSWORD=changeme
EOF

# Start both containers
# Docker pulls arcadedata/arcadedb:latest automatically on first run
docker compose up -d

# What's running:
#   arcadedb  — ArcadeDB server (Java, port 2480 HTTP + 2424 binary)
#               image: arcadedata/arcadedb:latest (pre-built by ArcadeDB team)
#               data: arcadedb_data volume at /home/arcadedb/databases
#   ravmem    — FastAPI server (Python, port 7432)
#               waits for arcadedb health-check before starting

# Verify both are up
curl http://localhost:2480/api/v1/ready   # ArcadeDB health
curl http://localhost:7432/health          # ravmem health

# Configure CLI on the host
ravmem remote config --url http://localhost:7432 --api-key your-secret-key
```

ArcadeDB Studio (visual graph browser) is available at `http://localhost:2480` in a browser once the container is running.

---

### Mount a local repo into Docker

```bash
# Add to docker-compose.yml volumes section under ravmem:
#   - /home/user/projects:/repos:ro

# Or run manually (ravmem only — needs ArcadeDB already running separately):
MSYS_NO_PATHCONV=1 docker run -d \
  --name ravmem \
  -p 7432:7432 \
  -v ravmem_data:/data \
  -v /home/user/projects:/repos:ro \
  -e RAVMEM_DATA_DIR=/data \
  -e RAVMEM_API_KEY=mysecretkey \
  ravmem:latest

# Register using the path as seen inside the container
ravmem remote config --url http://localhost:7432 --api-key mysecretkey
ravmem remote add /repos/my-project --name my-project --default-branch main
```

> **Note (Windows Git Bash):** prefix `docker run` with `MSYS_NO_PATHCONV=1` to prevent Git Bash converting `/data` → `C:/Program Files/Git/data`. `docker compose up` handles this automatically.

> **Note:** When registering a repo mounted into Docker, use the path as it appears **inside the container** (e.g. `/repos/my-project`), not the host path. The server resolves paths from its own filesystem.

---

## Python Client Library

```python
from ravmem.client.api import RavMemClient

client = RavMemClient("http://localhost:7432", api_key="mysecretkey")

# Register a project
project = client.create_project(repo_path="/path/to/repo", name="my-project", default_branch="main")
print(project["id"])  # "my-project"

# Update default branch
client.update_project("my-project", default_branch="develop")

# Pre-flight divergence check
div = client.get_divergence("my-project", "feature/auth")
print(div["ratio"], div["recommend"])  # 0.12, "incremental"

# Trigger indexing and wait
result = client.index_branch("my-project", "main", mode="auto")
job = client.poll_job(result["job_id"])  # blocks until done
print(job["status"])  # "done"

# Search
results = client.search("my-project", "main", "authenticate", limit=10)
for r in results:
    sym = r["symbol"]
    print(f"{sym['name']} ({sym['kind']})  {sym['file']}:{sym['line_start']}  score={r['score']:.3f}")

# Impact analysis
impact = client.impact("my-project", "main", symbol_id="a1b2c3d4e5f6a7b8", depth=3)
print(f"{len(impact['affected'])} symbols affected")

# Symbol details
sym = client.get_symbol("my-project", "main", "a1b2c3d4e5f6a7b8")
print(sym["callers"], sym["callees"], sym["cluster"])

client.close()
```

---

## Manual Verification Checklist

### 1. Health check

```bash
curl -s http://localhost:7432/health | python3 -m json.tool
```
Expected: `{"status": "ok", "version": "0.2.0", ...}`

### 2. Register a project

```bash
curl -s -X POST http://localhost:7432/api/projects \
  -H "Content-Type: application/json" \
  -d '{"repo_path": "/path/to/repo", "name": "test-repo", "default_branch": "main"}' \
  | python3 -m json.tool
```

### 3. Update default branch

```bash
curl -s -X PATCH http://localhost:7432/api/projects/test-repo \
  -H "Content-Type: application/json" \
  -d '{"default_branch": "develop"}' | python3 -m json.tool
```

### 4. Trigger a full index

```bash
curl -s -X POST http://localhost:7432/api/projects/test-repo/branches/main/index \
  -H "Content-Type: application/json" \
  -d '{"mode": "full"}'
# Returns: {"job_id": 1}
```

### 5. Monitor job progress

```bash
curl -s http://localhost:7432/api/jobs/1 | python3 -m json.tool
# Fields: "status", "progress_pct", "current_phase"
```

### 6. Divergence pre-flight check

```bash
curl -s http://localhost:7432/api/projects/test-repo/branches/main/divergence \
  | python3 -m json.tool
# {"changed_files": 3, "total_files": 316, "ratio": 0.009, "recommend": "incremental", "force_push": false}
```

### 7. Verify index is ready

```bash
curl -s http://localhost:7432/api/projects/test-repo/branches/main/status | python3 -m json.tool
# "status": "ready", "symbol_count": >0
```

### 8. Search symbols

```bash
curl -s "http://localhost:7432/api/projects/test-repo/branches/main/search?q=your_function&limit=5" \
  | python3 -m json.tool
```

### 9. Impact analysis

```bash
# Get a symbol ID from search results first, then:
curl -s "http://localhost:7432/api/projects/test-repo/branches/main/impact/SYMBOL_ID?depth=3" \
  | python3 -m json.tool
```

### 10. Index a second branch (copy-from-base path)

```bash
curl -s -X POST http://localhost:7432/api/projects/test-repo/branches/feature-x/index \
  -H "Content-Type: application/json" \
  -d '{"mode": "auto"}'
```

### 11. Prometheus metrics

```bash
curl -s http://localhost:7432/api/metrics
```

### 12. API key authentication

```bash
# Without key  -  should return 401
curl -s http://localhost:7432/api/projects

# With key
curl -s http://localhost:7432/api/projects -H "Authorization: Bearer mysecretkey"

# /health is always exempt
curl -s http://localhost:7432/health
```

---

## CLI Reference

Full command reference for all ravmem CLI commands (server, code graph, knowledge graph, remote, and kg subcommands): **[docs/CLI_REFERENCE.md](docs/CLI_REFERENCE.md)**

---

## API Reference

All endpoints prefixed with `/api`.

### Projects

| Method | Path | Description |
|--------|------|-------------|
| `POST` | `/api/projects` | Register project (`{"repo_path": "...", "name": "...", "default_branch": "main"}` or `{"repo_url": "..."}`) |
| `GET` | `/api/projects` | List all projects |
| `GET` | `/api/projects/{id}` | Project details + indexed branches |
| `PATCH` | `/api/projects/{id}` | Update project (`{"default_branch": "develop"}`) |
| `DELETE` | `/api/projects/{id}` | Remove project and all indexes |

### Branches

| Method | Path | Description |
|--------|------|-------------|
| `POST` | `/api/projects/{id}/branches/{branch}/index` | Trigger indexing (`{"mode": "auto\|full\|incremental"}`) -> 202 `{"job_id": N}` |
| `GET` | `/api/projects/{id}/branches` | List branches + index status |
| `GET` | `/api/projects/{id}/branches/{branch}/status` | Index status + active job info |
| `GET` | `/api/projects/{id}/branches/{branch}/divergence` | Pre-flight divergence check -> `{changed_files, total_files, ratio, recommend, force_push}` |
| `DELETE` | `/api/projects/{id}/branches/{branch}/index` | Delete branch index |

### Queries

| Method | Path | Description |
|--------|------|-------------|
| `GET` | `/api/projects/{id}/branches/{branch}/search?q=&limit=` | Hybrid BM25 + semantic search |
| `GET` | `/api/projects/{id}/branches/{branch}/impact/{symbol_id}?depth=` | Blast-radius analysis |
| `GET` | `/api/projects/{id}/branches/{branch}/symbols/{symbol_id}` | Symbol details (callers, callees, cluster) |
| `GET` | `/api/projects/{id}/branches/{branch}/clusters` | List all clusters |
| `GET` | `/api/projects/{id}/branches/{branch}/graph` | Full knowledge graph (nodes + edges) |

### Jobs & Health

| Method | Path | Description |
|--------|------|-------------|
| `GET` | `/api/jobs/{job_id}` | Job status, progress_pct, current_phase |
| `GET` | `/api/metrics` | Prometheus-style metrics (text/plain) |
| `GET` | `/health` | Health check (always 200, no auth required) |

---

## Environment Variables

| Variable | Default | Description |
|----------|---------|-------------|
| `RAVMEM_DATA_DIR` | `~/.ravmem/server` | Server data directory (indexes + registry) |
| `RAVMEM_API_KEY` | _(empty  -  auth disabled)_ | Bearer token for all `/api/*` endpoints |
| `RAVMEM_LOG_LEVEL` | `info` | Logging verbosity (`debug`, `info`, `warning`) |
| `RAVMEM_MAX_CONCURRENT_JOBS` | `2` | Max simultaneous branch indexing jobs |
| `ARCADEDB_HOST` | `localhost` | ArcadeDB server host (`arcadedb` when using Docker Compose) |
| `ARCADEDB_PORT` | `2480` | ArcadeDB server port |
| `ARCADEDB_PASSWORD` | `arcadedb` | ArcadeDB root password |
| `RAVMEM_CLUSTER_SEED` | `42` | Leiden/Louvain random seed for deterministic clustering |
| `RAVMEM_CLUSTER_RESOLUTION` | `1.0` | Leiden resolution parameter — higher = more, smaller clusters |
| `RAVMEM_CLUSTER_MAX_SIZE` | `500` | Max symbols per cluster before automatic sub-clustering |
| `RAVMEM_CLUSTER_SUBCLUSTER_THRESHOLD` | `200` | Max symbols per sub-cluster |

---

## Supported Languages

| Language | Symbol Extraction | Import Resolution | Call Resolution |
|----------|------------------|-------------------|-----------------|
| Python | Full | Module path | Regex (0.6) |
| TypeScript | Full | Relative path | AST (0.6) |
| JavaScript | Full | Relative path | AST (0.6) |
| Go | Full |  -  |  -  |
| Java* | Full | FQN package | AST (0.6) |
| C#* | Full | Namespace | AST (0.6) |
| Rust* | Full | mod/use paths | AST (0.6) |
| Kotlin* | Full | FQN package | AST (0.6) |
| Ruby* | Full | require_relative | AST (0.6) |
| PHP* | Full | require/include | Regex (0.5) |
| C/C++* | Full | #include local | Regex (0.5) |

*Optional: `pip install "ravmem[langs]"`

---

## Development & Tests

```bash
# The venv lives in the codenexus dir but has all ravmem deps installed
# Activate it (Unix/macOS):
source D:/context_engine/context-engine-codenexus/codenexus/.venv/Scripts/activate

# Run all tests  (359 tests as of 2026-04-20)
python -m pytest tests/ -v

# Run specific suites
python -m pytest tests/test_storage.py -v         # storage backends
python -m pytest tests/test_indexer.py -v         # 5-phase pipeline
python -m pytest tests/test_engine.py -v          # search + impact engines
python -m pytest tests/test_mcp.py -v             # MCP endpoints
python -m pytest tests/test_registry.py -v        # server registry
python -m pytest tests/test_git_ops.py -v         # git helper functions
python -m pytest tests/test_branch_manager.py -v  # branch orchestration
python -m pytest tests/test_routes_projects.py -v # REST API routes
python -m pytest tests/test_api_client.py -v      # HTTP client library
python -m pytest tests/test_job_queue.py -v       # async job queue
python -m pytest tests/test_arcade_cow.py -v      # ArcadeDB CoW semantics (no server needed)

# Fast pipeline tests (skip 8s model load)
python -m pytest tests/test_indexer.py -v -k "not embed"
```
