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.
- Host: GitHub
- URL: https://github.com/orafaelfragoso/columbus
- Owner: orafaelfragoso
- License: mit
- Created: 2026-06-06T19:03:26.000Z (about 1 month ago)
- Default Branch: main
- Last Pushed: 2026-06-15T09:30:18.000Z (30 days ago)
- Last Synced: 2026-06-20T12:37:46.914Z (25 days ago)
- Topics: ai-agents, cli, code-context, code-search, developer-tools, golang, llm, local-first, tree-sitter
- Language: Go
- Homepage: https://pkg.go.dev/github.com/orafaelfragoso/columbus
- Size: 1.66 MB
- Stars: 2
- Watchers: 0
- Forks: 0
- Open Issues: 4
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
- Security: SECURITY.md
Awesome Lists containing this project
README

**The navigator your coding agent has been missing.**
[](https://github.com/orafaelfragoso/columbus/actions/workflows/ci.yml)
[](https://github.com/orafaelfragoso/columbus/actions/workflows/release.yml)
[](https://pkg.go.dev/github.com/orafaelfragoso/columbus)
[](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).