An open API service indexing awesome lists of open source software.

https://github.com/orafaelfragoso/columbus

The navigator your coding agent has been missing โ€” a local-only, deterministic code-context server.
https://github.com/orafaelfragoso/columbus

ai-agents cli code-context code-search developer-tools golang llm local-first tree-sitter

Last synced: 14 days ago
JSON representation

The navigator your coding agent has been missing โ€” a local-only, deterministic code-context server.

Awesome Lists containing this project

README

          

Columbus โ€” local-only context server for LLM agents


**The navigator your coding agent has been missing.**

[![CI](https://github.com/orafaelfragoso/columbus/actions/workflows/ci.yml/badge.svg)](https://github.com/orafaelfragoso/columbus/actions/workflows/ci.yml)
[![Release](https://github.com/orafaelfragoso/columbus/actions/workflows/release.yml/badge.svg)](https://github.com/orafaelfragoso/columbus/actions/workflows/release.yml)
[![Go Reference](https://pkg.go.dev/badge/github.com/orafaelfragoso/columbus.svg)](https://pkg.go.dev/github.com/orafaelfragoso/columbus)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)

๐Ÿ“– **[Documentation & Guides](https://github.com/orafaelfragoso/columbus/wiki)** ยท [Quick Start](https://github.com/orafaelfragoso/columbus/wiki/Quick-Start) ยท [Using with your agent](https://github.com/orafaelfragoso/columbus/wiki/Using-Columbus-with-Your-Agent)

Your coding agent is brilliant at reasoning and bad at locating and remembering.
So it greps in the dark, reads whole files to use ten lines, and leans on stale
`.md` context that quietly lies.

**Columbus** is a **local-only, semantic code-context server** your agent calls
as a tool. Ask it โ€” in plain language โ€” where something is and get ranked,
LLM-ready context with **exact line ranges**, reconstructed live from your
working tree so it's **never stale**. It also owns your project's durable
memory, so the agent stops re-discovering the codebase every session.

_Local embeddings, no cloud, no LLM calls โ€” natural-language search that stays on
your machine._

> [!IMPORTANT]
> **It cannot go stale, because it never stores your code.** The database holds
> **metadata, git anchors and embedding vectors only** โ€” every snippet and exact
> line range is rebuilt live at query time by re-parsing the working tree. The
> vectors are a derived index, not your source; the answer always matches the
> code as it is *right now*.

Columbus does exactly three things:

1. **Index** โ€” chart the codebase with embedded tree-sitter and embed each
symbol/file on-device (metadata + git anchors + vectors, never your code).
2. **Search** โ€” natural-language semantic search: vector retrieval re-ranked by
deterministic heuristics, returning ranked context with exact line ranges.
3. **Memory** โ€” own the project's durable record: ADRs, plans and
documentation with tags, links, evidence anchors, and drift checks.

Embeddings run **on-device** with bundled Model2Vec assets
(`minishlab/potion-code-16M`); there are no LLM calls and nothing leaves your
machine. Ranking, "why relevant" text, and risk hints are deterministic.

## Why Columbus

The agent is great at the thinking. It's the *finding* and *remembering* that
bleed tokens and go wrong. Columbus takes that off its plate.

| Without Columbus | With Columbus |
|---|---|
| Greps for the exact word and misses the concept | **Natural-language** semantic search finds it by meaning |
| Reads whole files to find ten relevant lines | One call returns ranked context with **exact line ranges** |
| Context drifts; stale `.md` files confidently lie | Snippets rebuilt **live** from the working tree โ€” never stale |
| Re-discovers the codebase every session | **Durable memory** โ€” ADRs, plans & documentation persist |
| Repo cluttered with `.cursorrules` / scattered context files | Memory is queryable and **git-excluded**, not committed noise |
| Embeddings shipped to a cloud, per-query cost | **On-device** embeddings, zero LLM calls, nothing leaves your machine |

> [!NOTE]
> **Proof, measured.** A with/without study (tokens to first correct location,
> total session tokens, tool calls, run-to-run variance) is in progress โ€” real
> numbers will land here. _Placeholder; not yet published._

## Install

Requires Go 1.26+ and a C compiler for the embedded tree-sitter grammars.
Columbus is built with `-tags fts5`. The SQLite, vector, and embedding stack is
pure Go, so no ONNX, tokenizer, or SQLite native libraries are required.

### Release archives

Download the archive for your platform from
[Releases](https://github.com/orafaelfragoso/columbus/releases). Each archive
ships a single `columbus` binary with the model assets embedded, so local
natural-language (vector) search works out of the box with no network at
runtime.

### Build from source

```sh
brew install ripgrep ast-grep
make setup # fetch Model2Vec assets into internal/embed/assets
make install # built with -tags fts5 and CGO_ENABLED=1 by default
```

`git` is the only hard runtime dependency. `ripgrep` is the recommended search
fast-path (a pure-Go fallback covers the rest); `ast-grep` is optional. The
SQLite metadata store and `vec0` vector search use the pure-Go modernc driver;
the embedding engine uses a pure-Go Model2Vec runtime and embedded safetensors
weights.

## Quick start

```sh
columbus install # onboard: write .columbus.json, create db, first index + embed
columbus search "parse config" # ranked, LLM-ready context with exact line ranges
columbus reindex # re-chunk + re-embed only what changed
columbus view # full-screen dashboard (index stats + memory table)
columbus doctor # verify git, vec0, model runtime + index health
```

Then point your agent at Columbus as a tool (see
[Use it with your agent](#use-it-with-your-agent)). The agent stops grepping and
starts asking; `columbus view` gives *you* the live view of what it's doing.

## Documentation

Full guides and reference live in the **[Columbus Wiki](https://github.com/orafaelfragoso/columbus/wiki)**:

- [Your First Index & Search](https://github.com/orafaelfragoso/columbus/wiki/Your-First-Index-and-Search) โ€” guided tour with real output
- [Using Columbus with Your Agent](https://github.com/orafaelfragoso/columbus/wiki/Using-Columbus-with-Your-Agent) โ€” the skills model and `--json`/`--llm` contract
- [Never Stale: Live Reconstruction](https://github.com/orafaelfragoso/columbus/wiki/Never-Stale-Live-Reconstruction) โ€” why answers always match current code
- [Command Reference](https://github.com/orafaelfragoso/columbus/wiki/Command-search) ยท [Configuration](https://github.com/orafaelfragoso/columbus/wiki/Configuration) ยท [FAQ](https://github.com/orafaelfragoso/columbus/wiki/FAQ)

## How it works

The **chart** (the index) tells Columbus *where* things are. The **working
tree** tells it *what they currently say*. Because Columbus never caches the
"what," it can never lie about it.

```
your working tree โ”€โ”€(tree-sitter)โ”€โ”€โ–ถ index: metadata + git anchors (the chart)
โ”‚ โ”‚
โ”‚ agent: columbus search "parse config" โ”‚
โ–ผ โ–ผ
re-parse live โ—€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ rank deterministically
โ”‚
โ–ผ
ranked results + EXACT line ranges + "why relevant" โ”€โ”€โ–ถ LLM-ready
```

Indexing is incremental and cheap, but even a stale index can't produce a stale
*answer*: the snippet and line range you get back are reconstructed from the
file as it exists at query time.

## Use it with your agent

Columbus is a tool, not an autopilot. Your agent learns *when* and *how* to call
it through **skills** โ€” small instruction files that teach the agent the CLI
(when to `search` before editing, how to record a decision, how to read the
graph). The skills live in the **agent/plugin layer**, never in this binary,
which keeps Columbus a small, deterministic context server with no opinion on
your workflow.

The contract the agent consumes:

- **`--json`** โ€” a versioned, machine-readable contract with a canonical error
envelope. Stable to parse, safe to depend on.
- **`--llm`** โ€” markdown shaped for a context window: ranked results, exact line
ranges, and a short "why relevant" per hit.

Both are pure projections of the same typed result as the human `text` output โ€”
they can never silently diverge.

Search is **locate-first**: by default it returns ranked locations, signatures,
scores and graph edges โ€” the cheap "where to look" map โ€” and omits code bodies.
Add `--snippets` to attach bodies inline (capped with `--snippet-lines N`), or
pull a specific body on demand with `columbus show symbol`. Exact line ranges are
always present, so an agent can read first and drill down only where it matters.

```sh
columbus search "where do we parse config" --llm # ranked locations, no bodies (cheap)
columbus search "where do we parse config" --llm --snippets # same, with code bodies inline
columbus graphs --in internal/server --json # dependency graph as {nodes, edges}, machine-readable
```

> [!NOTE]
> **Columbus skills** (for Claude Code and other agents) are published separately
> as plugin assets. _Link coming soon._

## Commands

### Lifecycle

```sh
columbus install # onboard: write config, create db, first index + embed
columbus reindex # re-chunk + re-embed changes (also --full/--changed/--clean/--status)
columbus doctor # environment + project health (git, vec0, runtime, model, index)
columbus uninstall # remove config + delete the db (confirm; --yes when non-TTY)
columbus purge # clear all records + reset config to defaults (confirm; --yes)
```

### Search & navigate

```sh
columbus search "where do we parse config" # natural-language, ranked, LLM-ready results
columbus search "auth token check" --kind all # code hits + full-body memory section in one call
columbus show symbol Engine --in internal/search
columbus show file internal/store/store.go
columbus graphs --json # whole dependency graph as {nodes, edges}
columbus graphs --role impl --in internal/store # narrow + induce subgraph
```

Search is semantic: the query is embedded on-device and matched by vector
similarity, then re-ranked by deterministic heuristics. With no runtime library
present it degrades to keyword (FTS) ranking โ€” `columbus doctor` shows which.

One search is the **master query**: alongside the ranked code hits it returns a
MEMORIES section with the **full bodies** (plus tags, links, and evidence) of
the most relevant memories, and 1-hop graph edges (imports / imported-by /
tests) per code hit โ€” so an agent gets complete context in a single call, no
follow-up `show memory` needed.

### Memory (durable knowledge)

Three kinds โ€” `adr` (architecture decision), `plan` (durable implementation
plan), and `documentation` (everything else worth remembering). All of it is
embedded and surfaces in semantic `search` with full bodies.

```sh
columbus memory add adr --title "Use WAL" --body "readers never block writers" \
--evidence internal/store/store.go:30-40 --link symbol:Open --tag db
columbus memory add plan --title "Ship master search" --body "one query = full context"
columbus memory add documentation --title "Release process" --body "goreleaser + zig"
columbus memory update mem_001 --title "Use WAL mode" --add-tag sqlite
columbus memory list --kind adr --tag db
columbus memory remove mem_001 # destructive; id retired
```

Memories are a passive, durable record. Links and evidence anchors are
drift-checked against the indexed `file`/`symbol` targets; `show
file|symbol` lists in reverse the memories that reference that entity.

```sh
columbus show memory mem_001 # full body, tags, links, evidence
columbus search "WAL" --kind memory # memory-only search (full bodies)
columbus memory validate # evidence drift + link resolution report
```

### Import / export

```sh
columbus export --out memories.json # portable memory doc (schema v4)
columbus import memories.json # vectors are not exported โ€” reindex rebuilds them
```

### Dashboard

`columbus view` opens a full-screen, read-mostly terminal dashboard over the
indexed project: index freshness, file/symbol/embedding counts, memory counts,
and a full-width memory table. It auto-refreshes, so external `columbus
reindex`/agent edits appear on their own.

Keys: `โ†‘/โ†“` (or `j/k`) navigate ยท `enter` detail (full body, tags, links) ยท
`/` semantic search across code and memory (ranked results, snippets in
detail) ยท `esc` back ยท `r` refresh ยท `R` reindex (in-process) ยท `?` help ยท
`q` quit confirmation. It is a projection of the same data the JSON/LLM
commands expose; only `R` writes (it runs the indexer) โ€” memory is read-only.

## Output modes

`text` (default, human; color only on a TTY), `--json` (machine contract), and
`--llm` (markdown) are pure projections of the same typed result โ€” they can
never silently diverge. Color follows `--no-color`, then `NO_COLOR`,
`FORCE_COLOR`, `TERM=dumb`, and `CI`, in that order, before falling back to TTY
detection.

### Exit codes

| code | meaning |
|---|---|
| 0 | success (incl. "usable with warnings") |
| 1 | runtime error |
| 2 | usage error |
| 3 | not initialized / index missing |
| 4 | transient / retryable (e.g. index writer locked) |

## Design invariants

- **Data always reflects current project state.** The database stores
**metadata + git anchors only** โ€” never code lines or file bodies. Snippets
and exact line ranges are reconstructed **live** at query time by re-parsing
the working tree with tree-sitter.
- **The DB is a metadata + graph cache**, not a content store.
- **`git` is the only hard runtime dependency.** `ripgrep` is the recommended
search fast-path; a pure-Go fallback covers the rest. `ast-grep` is optional.
- **`--json` is a versioned API contract** with a canonical error envelope.

## Languages (V1)

TypeScript + TSX, JavaScript + JSX, Python, Go, Markdown. Adding a language is
a grammar + `.scm` queries + an extension mapping โ€” no core changes.

## Development

```sh
make test # go test -tags fts5 ./...
make vet
golangci-lint run ./...
make cover
```

See [CHANGELOG.md](CHANGELOG.md) for release history.

## Contributing

Contributions are welcome โ€” see [CONTRIBUTING.md](CONTRIBUTING.md) and the
[Code of Conduct](CODE_OF_CONDUCT.md). For security reports, see
[SECURITY.md](SECURITY.md).

## License

MIT โ€” see [LICENSE](LICENSE).