Metadata-Version: 2.4
Name: coderay
Version: 1.0.8
Summary: X-ray your codebase — semantic search, code graphs, file skeletons, and MCP server
Author-email: Bogdan Copocean <bogdancopocean@gmail.com>
License-Expression: MIT
Project-URL: Homepage, https://github.com/bogdan-copocean/coderay
Project-URL: Repository, https://github.com/bogdan-copocean/coderay
Project-URL: Issues, https://github.com/bogdan-copocean/coderay/issues
Keywords: semantic-search,code-indexer,mcp,code-graph,ai-assistant
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries
Classifier: Topic :: Text Processing :: Indexing
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: python-dotenv>=1.2.0
Requires-Dist: networkx>=3.4
Requires-Dist: tree-sitter>=0.25.0
Requires-Dist: tree-sitter-python>=0.25.0
Requires-Dist: lancedb>=0.29.0
Requires-Dist: pyyaml>=6.0.3
Requires-Dist: click>=8.3.0
Requires-Dist: filelock>=3.25.0
Requires-Dist: fastembed>=0.7.0
Requires-Dist: fastmcp==3.1.0
Requires-Dist: watchdog>=6.0.0
Requires-Dist: pathspec>=1.0.0
Provides-Extra: languages
Requires-Dist: tree-sitter-javascript>=0.25.0; extra == "languages"
Requires-Dist: tree-sitter-typescript>=0.23.2; extra == "languages"
Requires-Dist: tree-sitter-go>=0.25.0; extra == "languages"
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0; extra == "dev"
Requires-Dist: ruff>=0.8.0; extra == "dev"
Requires-Dist: mypy>=1.0.0; extra == "dev"
Provides-Extra: maintain
Requires-Dist: pylance>=0.15.0; extra == "maintain"
Provides-Extra: all
Requires-Dist: coderay[dev,languages,maintain]; extra == "all"
Dynamic: license-file

# CodeRay

A local, offline-first semantic code indexer. Builds a vector index,
call/import graph, and file skeletons — exposed as an MCP server for
AI coding assistants and a standalone CLI.

## What you get

| Capability | What it does | Why it matters | AI assistant benefit |
|---|---|---|---|
| **Semantic search** | Find code by meaning, not keywords. "where do we handle auth errors" returns results even if the code never uses that phrase. | Grep finds text. This finds *intent*. | Better context retrieval for plan and edit modes |
| **Blast radius** (`get_impact_radius`) | Given a function or module, show every node reachable within N hops via calls, imports, and inheritance. | Before changing `UserService.save()`, see exactly what breaks. | Safer refactors — agent sees downstream impact before editing |
| **File skeleton** (`get_file_skeleton`) | Signatures, docstrings, imports — no function bodies. The API surface of a file at a glance. | Understand a 500-line file in 30 lines without reading the implementation. | Drastically fewer tokens than reading the full file |
| **Index status** | Chunk count, schema version, branch, last commit, store health. | Confirm the index is fresh before relying on results. | Agent self-checks before trusting search results |

## Install

Create a virtual environment (recommended):

```bash
python -m venv .venv
source .venv/bin/activate
```

Then install:

```bash
pip install coderay
```

With all extras (JS/TS/Go support, MCP server tools):

```bash
pip install "coderay[all]"
```

For development:

```bash
git clone https://github.com/bogdan-copocean/coderay.git
cd coderay
python -m venv .venv && source .venv/bin/activate
pip install -e ".[all]"
```

## Quick start

```bash
cd /path/to/your/project
coderay watch --repo .   # keeps index fresh while you work (recommended)
coderay search "how does authentication work"
coderay graph --kind calls
coderay skeleton src/app/main.py
```

> **Use `watch`, not `build`.** `coderay build` is a one-off; while you work, the index will get stale. `coderay watch` re-indexes on file changes and is the go-to for active development.

## MCP server (Claude Code / Cursor)

Find the MCP executable path:

```bash
which coderay-mcp
```

Add to `~/.claude/claude_code_config.json` or Cursor MCP settings:

```json
{
  "mcpServers": {
    "coderay": {
      "command": "/path/to/your/.venv/bin/coderay-mcp",
      "args": [],
      "env": {
        "CODERAY_INDEX_DIR": "${workspaceFolder}/.index"
      }
    }
  }
}
```

Replace `/path/to/your/.venv/bin/coderay-mcp` with the output of `which coderay-mcp`.

**Important:** Set `CODERAY_INDEX_DIR` so the MCP server finds the index and graph
in your project. Cursor interpolates `${workspaceFolder}` to the workspace root.
Run `coderay build` (or `coderay watch`) from the project root first.

## CLI reference

| Command | Description |
|---|---|
| `coderay watch --repo . [--debounce N]` | **Recommended.** Watch for file changes, re-index automatically |
| `coderay build [--full] --repo .` | Build or incremental update. Use `--full` for full rebuild |
| `coderay search "query" [--top-k N]` | Semantic search |
| `coderay list [--by-file]` | List indexed chunks |
| `coderay status` | Index state, branch, commit, chunk count |
| `coderay maintain --repo .` | Compact index, reclaim space |
| `coderay skeleton FILE` | Print file skeleton |
| `coderay graph --kind calls\|imports` | List graph edges |

## Configuration

File discovery and ignoring are based on `.git` and `.gitignore`. The `.git` directory is excluded; files matching `.gitignore` are not indexed. Config `exclude_patterns` add extra exclusions on top of that.

Optional `config.yaml` in the index directory (default: `.index/config.yaml`):

```yaml
embedder:
  model: sentence-transformers/all-MiniLM-L6-v2
  dimensions: 384

index:
  exclude_patterns:  # besides .gitignore
    - "*.log"

semantic_search:
  boosting:
    penalties:
      - pattern: "(^|/)tests?/"
        factor: 0.5
      - pattern: "(^|/)test_[^/]+\\.py$"
        factor: 0.5
    bonuses:
      - pattern: "(^|/)src/"
        factor: 1.1
  metric: cosine

watcher:
  debounce: 2
  exclude_patterns:  # besides .gitignore
    - "*.log"

graph:
  exclude_modules: []   # module names to exclude from CALLS/IMPORTS edges
  include_modules: []  # force-include (override excludes)
```
