SeleneCode
local-first Β· deterministic Β· Rust

The knowledge graph your agent was missing.

SeleneCode parses your codebase into an embedded graph β€” every symbol, every call, every dynamic-dispatch hop β€” and serves it to AI agents over MCP. One structural question, one call, zero file reading. A single static binary; nothing ever leaves your machine.

$ curl -fsSL https://selenecode.com/install.sh | sh
Releases on GitHub β†—
the bet

Your agent burns thousands of tokens re-reading what a graph already knows.

Every session, every agent, re-derives the same structure: grep, read, guess, read again. Selene computes it once β€” deterministically, from the AST β€” and answers flow questions with the verbatim source, the call path, and the blast radius, together.

❯ selene explore "how does a request become a database write"

## Context for: how does a request become a database write
Found 42 relevant symbols across 1,214 indexed files.

### Flow
1. handle_request   (src/api/routes.rs:88)
2. validate_payload  (src/api/guard.rs:41)
3. Store::persist    (src/db/store.rs:203)  *(dynamic ~0.8)*

### Blast radius β€” 17 symbols across 6 files
### Source β€” verbatim, line-numbered, safe to edit from
…
Token economy: this answer β‰ˆ 5k tokens; the 75 files it distills
total β‰ˆ 237k tokens β€” 52Γ— less than pulling them into context.
the engine room

Rust all the way down, so there's nothing else to install.

Scanner, extraction, resolver, graph engine, MCP server β€” every crate is Rust, compiled to one static binary with the database inside it: SurrealDB embedded on RocksDB, full-text index included. That store opens in about 80 ms on a 344-file index, and on macOS and Linux the daemon holds it warm, so your agent's second question never pays it again. The one part that isn't Rust β€” the galaxy UI β€” ships pre-built into a single HTML file the binary carries, so cargo build never needs Node, and neither do you.

0.66Γ—index wall clock vs CodeGraph Β· selene-crates
0.93Γ—django Β· at parity
1.2–4.4 mscorridor traversal Β· Phase-1 fixture
0.18–0.45 swarm explore Β· 3rd–6th call

How to read these. What was timed is a cold, full selene index of the same source-only corpus by each tool, and lower is faster: 0.66Γ— means SeleneCode finished that index in 66% of CodeGraph's wall time β€” best-of-3, same machine (selene-crates and django measured 2026-09-09; codegraph-src's 0.77Γ— is the older 2026-07-17 window and has not been re-run). Faster never meant resolving less: a gate holds the Rust resolver to the TypeScript engine's edge identity at tolerance 0 over an 18-project corpus. django measured 1.03Γ— in the previous window, so the medium corpus reads as at parity β€” unresolved either way until a counter-balanced A/B says otherwise. VS Code scale has not been re-benchmarked since these optimizations. The millisecond band is corridor traversal and path-finding on the Phase-1 synthetic fixture, not hub-rooted queries, which are bound by result size.

✦

The model can't reach the index

selene index and selene sync never call a model, and a stock binary cannot reach one at all β€” the LLM crate is an optional dependency behind a feature that is off by default. Extraction itself is sync, with no async runtime on the path, and its parallel fan-out commits in a fixed order β€” so the ids never depend on which thread finished first.

✦

One batched query per hop

Callers, callees, impact and shortest path are Rust walks whose every adjacency expansion is one batched query over the whole frontier β€” never a query per node β€” so a traversal costs O(depth) round-trip pairs however wide the frontier gets, and each node's payload crosses the wire at most once per walk. On the Phase-1 benchmark graph β€” synthetic, 20,000 nodes and 102,008 edges β€” corridor traversal at depth 3–5 and 15-hop path-finding land at 1.2–4.4 ms. One crate touches the database; everything above it sees a single GraphStore trait.

✦

Made for every agent

selene install -t auto finds every agent on the machine and wires them all β€” eight targets across four config formats (JSON, TOML, JSONC, YAML). It rewrites exactly the selene entry and leaves every neighboring MCP server byte-identical; if the file will not round-trip losslessly it refuses to write at all. Your ~/.claude.json stays yours.

the atlas

Everything a codebase knows about itself, charted.

✦

Deterministic by oath

Extraction is AST-derived β€” never LLM-summarized. Same code in, same graph out, byte for byte. Gates hold it at tolerance 0.

✦

Dynamic dispatch, bridged

Callbacks, event emitters, React re-renders, framework routes β€” the hops grep can't follow are synthesized end-to-end, each marked with its confidence.

✦

Documents in the graph

Markdown, rst, txt β€” and the extracted text of pdf/docx β€” become sections whose code-mentions are resolved. "Why was X chosen?" answers from your own docs.

✦

The galaxy

selene viz renders your architecture as an interactive star map β€” Louvain call-clusters as named constellations, god-nodes, rare bridges. One offline file.

✦

Structural insight

Betweenness centrality finds the true bottlenecks degree can't see. Import cycles, orphan modules, one-edge surprises β€” selene insights, for humans and agents.

✦

A temporal axis

selene diff HEAD~5 β€” what changed in the graph since a revision, read straight from git objects. No checkout; your worktree is never touched.

✦

Memory between sessions

Every exploration is journaled locally. A new session recalls where the last one dug β€” knowledge compounds instead of evaporating.

✦

Yours, entirely

One static binary. Embedded database. Optional semantic search runs on local ONNX. No server, no API key, no telemetry β€” nothing leaves your machine, ever.

12languages, native tree-sitter
1static binary
0servers Β· api keys Β· telemetry
52Γ—measured token economy
beyond structure

Since August, the graph learns to explain itself.

selene enrich is optional and additive: it turns the call graph into a codebase you can actually tour β€” named Domains, the Flows that connect them, a computed read-order, and a galaxy you can watch build live. Every pass ships a real zero-LLM floor first; a model, if you point one at it, narrates instead of templating.

❯ selene enrich
Domains: 9 found (Louvain communities, named)
Flows:   23 found (entry points, hop chains resolved)
Tour:    11 stops, read-order computed
… zero-LLM floor: 0 provider calls made, 0 needed

❯ selene doctor
index       fresh Β· synced 3m ago Β· 19,061 nodes
enrichment  fresh Β· 118 calls avoided by the graph
provider    none configured β€” structure-only
✦

Domain β†’ Flow

Louvain call-clusters become named Domains; entry points become Flows carrying their resolved hop chain. Real names with zero LLM configured β€” plug one in and it narrates instead of templating.

✦

A guided tour

selene tour computes the onboarding read-order from the graph itself β€” the order to read the codebase in, not a hand-written README section.

✦

The galaxy, live

selene viz --open renders a starship UI as one offline HTML file; --watch serves it live on a local port. Five views share the rail β€” Galaxy (the map), Systems (Domains as star systems), Logbook (every ops/doc fact), Navigation (the path finder) and Mission (the tour). Pick a symbol and its Dossier opens: source, relationships, each edge's provenance.

✦

Watch it grow

Leave --watch open while an agent works: every new function or class bursts into the map with a supernova animation seconds after it's written, with a live index-size / RAM sparkline in the header.

✦

Ops and env, wired in

Dockerfiles, compose, CI YAML, Makefiles, Cargo.toml/ package.json/pyproject.toml, Terraform, SQL, .env β€” 13 formats, parsed at index time, with an edge from an env key straight to the code that reads it.

✦

--clear takes it back

Enrichment is additive and index-time. selene enrich --clear removes everything it added, and a gate holds the graph byte-identical to before it ran.

enter orbit

Two commands. Total.

$ curl -fsSL https://selenecode.com/install.sh | sh
> irm https://selenecode.com/install.ps1 | iex
$ brew install mess69/selenecode/selene
> scoop bucket add selenecode https://github.com/Mess69/selenecode-releases scoop install selene

Already on it? selene upgrade keeps it fresh β€” selene upgrade --check just looks, selene upgrade 0.2.0 pins.

Install the binary

Pick your platform above β€” prebuilt, checksum-verified, no Rust, no Node, nothing to compile.

Wire your project

selene install β€” indexes the repo, installs git hooks that keep the graph in sync, and registers the MCP server in Claude Code, Cursor, Codex, opencode…

Ask

Restart your agent and ask a structural question. It answers from the graph β€” verbatim source, call paths, blast radius β€” instead of burning context on Read/Grep.

Code is parsed locally. The graph lives locally. The answers are deterministic. Nothing leaves your machine β€” ever.

the selene invariants Β· held by gates, not promises