nyxCore/LIPInstall
nyxCore

Live code intelligence · Rust

LIP

The live code intelligence layer your tools are missing.

Persistent, incremental code graph. Blast-radius updates in 200–800 ms on a 500k-file repo where a full SCIP re-index takes an hour. SCIP import, LSP bridge, MCP server — one open protocol every editor, CI system, and AI agent can speak. MIT-licensed Rust, v2.3.5.

Current release

v2.3.5

Tier 1 parse / file

< 1 ms

Edit → re-verify

200–800 ms

Cache-hit lookup

24 ns

Tier 2 languages

4

MCP tools exposed

~40

Pipeline — 8 primitives

What it actually does

Every AI coding tool built its own code graph. LIP is the open one underneath.

Cursor, Copilot, Claude Code, Cody — all answering the same four questions (what breaks if I change this, who calls that, is this rename safe, which symbols depend on this version) with four incompatible proprietary graphs. LIP is the standard live layer for that work. These are the eight primitives it is built on.

Core

Blast-radius indexing

Reverse dependency graph per symbol. On save, LIP checks if the exported API surface changed. Unchanged → zero downstream work. Changed → only the files that import the touched symbols are re-verified, with risk level, direct vs transitive split, and depth-weighted confidence.

Tier 1 → 2

Progressive confidence

Tree-sitter parses under a millisecond per file — symbols and go-to-definition land the instant you open the repo. The compiler runs on the blast radius in the background and silently upgrades results to compiler-level precision. The IDE never blocks.

Tier 3

Federated dependency slices

External packages are content-addressed blobs. react@18.2.0 is indexed once by anyone on the team and keyed by content hash. Every subsequent machine pulls it in under a second. node_modules, target/, and .pub-cache never re-index locally again.

Agent-safe

Persistent annotations

Symbols carry key/value annotations — lip:fragile, team:owner, agent:note, lip:nyx-agent-lock — that survive file edits, daemon restarts, and CI runs. Agents use them to coordinate work and leave notes across sessions.

One round-trip

Batch API

BatchQuery runs N queries under a single database-lock acquisition: one Unix-socket round-trip instead of N. Planning a ten-symbol refactor costs one connection instead of thirty.

v1.3+

Semantic nearest-neighbour

Point LIP_EMBEDDING_URL at any OpenAI-compatible endpoint (Ollama, OpenAI, Together AI). QueryNearest, QueryNearestByText, QueryNearestBySymbol — plus batched variants — run against stored dense vectors. Embeddings invalidate on source change. Opt-in; every other capability works without.

v1.5

Push notifications

IndexChanged events broadcast to all active sessions immediately after every successful delta upsert, carrying the new indexed_files count and affected_uris. Clients invalidate precisely without polling.

v1.5 / v2.1

Protocol lifecycle

Handshake returns a semver plus monotonic protocol_version (now 2) and supported_messages — clients probe for individual calls instead of guessing. UnknownMessage keeps the socket open on version drift. --managed mode gives IDE integrations a parent-process watchdog.

Protocol fit — LSP · SCIP · LIP

Not a replacement. A missing layer.

LSP serves editors. SCIP audits CI. LIP keeps both fresh, always.

LSP is an in-memory editor protocol, scoped to open files. SCIP is a compiler-precise snapshot, generated by a long CI run. LIP is the persistent, incremental graph that sits underneath both — and it imports SCIP, bridges LSP, and adds the blast-radius semantics neither protocol has.

DimensionLSPSCIPLIP
ScopeOpen files onlyFull repo snapshotFull repo + deps, live
FreshnessSession lifetimeStale between CI runsAlways current, <1 ms/save
Change handlingFull re-parse per fileFull re-index O(N)Blast radius O(Δ + depth)
Blast radiusNoNot nativeFirst-class, bounded BFS
Cross-session persistenceNoRead-only snapshotWAL journal, survives restart
Annotations on symbolsNoNoYes — survive file changes
External depsNoneRe-indexes every runFederated CAS slices, shared
Agent integrationLimitedRead-only batchMCP, batch API, agent-lock
Cold start< 1 s30–90 min (large repo)< 30 s shallow + background

Tier 1 is syntactic (tree-sitter). Tier 2 is compiler-precise via rust-analyzer, typescript-language-server, pyright, or the Dart analyzer. Tier 3 is the federated dependency-slice cache.

Benchmarks — Apple Silicon, optimised build

What the wall clock actually shows

A single-file edit on a half-million-file repo finishes before you finish saving.

Measured on the Rust reference implementation, optimised release build, Apple Silicon. Tier 1 fixtures are ~60–80 line source files. Graph operations are measured against a warm cache where noted. Wire framing runs over the Unix-socket length-prefixed JSON transport.

Tier 1 indexer — per file
LanguageMeasuredBudgetMargin
Rust (tree-sitter)205 µs< 10 ms49× under budget
TypeScript (tree-sitter)234 µs< 10 ms42× under budget
Python (tree-sitter)279 µs< 10 ms35× under budget
Query graph — in-process
OperationMeasuredNotes
upsert_file92–104 nsO(1) HashMap + cache invalidation
file_symbols (cache hit)24 nsArc clone only
file_symbols (cache miss)26 µsFull tree-sitter re-parse
blast_radius (50 files)5.6 µsWarm cache
workspace_symbols (100 files)14.6 µsWarm cache
Wire framing — Unix socket, length-prefixed JSON

Round-trip, 64 B

6 µs

Round-trip, 64 KB

43 µs

Burst 1000 × 256 B

1.47 ms

The edit-to-ready claim, expanded

Single-file save on a 500k-file repository. SCIP re-indexes all 500k files in roughly an hour. LIP re-verifies the ten to two hundred files that actually import the changed symbols, in 200–800 ms. If the public API surface did not change, the downstream pass is skipped entirely — the common case costs cache-invalidation nanoseconds.

CLI — one shape, every surface

Talk to a running daemon

Start the daemon. Query it. Everything else is the same shape.

Every query — blast radius, references, annotations, nearest-neighbour, SCIP import — is a line of lip query. Every batch of N queries is one round-trip. Agents, editors, and CI all share the socket.

# Start the daemon — watches files, maintains the live graph
lip daemon --socket /tmp/lip.sock

# Go-to-definition at (file, line, col)
lip query definition file:///src/main.rs 42 10

# What breaks if I touch this symbol?
lip query blast-radius "lip://local/src/auth.rs#AuthService.verifyToken"

# Batch: N queries, one round-trip, one db-lock acquisition
lip query batch <<'EOF'
[
  {"type":"query_blast_radius", "symbol_uri":"lip://local/src/auth.rs#AuthService"},
  {"type":"query_references",  "symbol_uri":"lip://local/src/auth.rs#AuthService", "limit":50},
  {"type":"annotation_get",    "symbol_uri":"lip://local/src/auth.rs#AuthService", "key":"lip:fragile"}
]
EOF

# Import a SCIP artifact — upgrades symbols to Tier 2
lip import --from-scip index.scip

# Bridges: LSP for editors, MCP for agents
lip lsp --socket /tmp/lip.sock   # any LSP editor, no plugin
lip mcp --socket /tmp/lip.sock   # Claude Code, Cursor, CKB

Full reference: the README CLI section lists every subcommand including slice publish/fetch, stream-context, and the v1.6+ semantic primitives.

Surfaces — 4

One graph, four ways in

Editor, agent, CI, or registry. Pick the seam that fits.

LSP bridge

lip lsp speaks standard LSP over stdio. Any editor sees it as a language server — no plugin needed. The difference: answers come from a persistent live graph instead of an in-memory process that restarts cold.

MCP server

lip mcp exposes ~40 tools to Claude Code, Cursor, CKB, and any MCP client. Blast radius, references, annotations, semantic search, explain-match — every capability reachable from an agent over JSON-RPC 2.0.

SCIP import

lip import --from-scip index.scip ingests compiler-precise SCIP artifacts and upgrades symbols to Tier 2. LIP is not a SCIP replacement — it is the freshness layer on top of one.

Registry + slices

lip slice --cargo / --npm / --pub / --pip builds content-addressed dependency slices. Push to a shared registry, fetch by hash. The team indexes react@18.2.0 once, not once per machine.

Honest positioning — 03

What LIP is not

The adversary’s disclosure. Read before you install.

Ipcha Mistabra wrote this section. LIP is a daemon; it will sit in your workflow for months. Know what it will and will not do before it is there.

Disclosure

Not a replacement for SCIP.

SCIP has compiler-accurate precision in every language and is the right tool for data-flow analysis, taint tracking, compliance snapshots, and full CPG work. LIP imports SCIP artifacts and keeps them fresh incrementally — it does not generate them.

Disclosure

Not a replacement for LSP.

LIP ships an LSP bridge so any editor connects with zero plugin. It is not an editor protocol — it is a live, persistent graph that happens to speak LSP on one surface. Your Tier 2 precision still comes from rust-analyzer, tsserver, pyright, or the Dart analyzer.

Disclosure

Tier 2 precision is opt-in per language.

Tier 2 ships today for Rust, TypeScript, Python, and Dart. If the language-server binary is not on PATH, LIP degrades to Tier 1 (syntactic tree-sitter) for that language instead of lying about precision. No silent fallbacks to stale data.

Install — Rust 1.78+

Quick start

Three crates published. No system protoc required.

lip-core, lip-cli, and lip-registry are on crates.io. Cargo builds the workspace end-to-end. Tier 2 precision is opt-in per language: install the language-server binary you want on PATH, or stay on Tier 1.

# From crates.io
cargo install lip-cli

# Or from source
git clone https://github.com/nyxCore-Systems/LIP
cd LIP
cargo build --workspace
cargo test  --workspace

# Start the daemon; index your repo; let the editor connect
lip daemon --socket /tmp/lip.sock &
lip index ./src
lip lsp    --socket /tmp/lip.sock

# Opt in to semantic search (any OpenAI-compatible endpoint)
export LIP_EMBEDDING_URL=http://localhost:11434/v1/embeddings
export LIP_EMBEDDING_MODEL=nomic-embed-text
Get it on GitHub lip-cli on crates.io Release notes

MIT licensed · Rust 1.78+ · works on any repo

Before you wire it into an agent loop

Start with lip index on a shallow tree and the LSP bridge on your editor. Confirm Tier 1 answers look right, then add the Tier 2 language server for your primary language. Only then point an MCP client at it and enable the annotation locks. Skipping the calibration turns persistent agent-locks into stuck state you will have to clear by hand.

Metis says: the daemon is a contract, not a toy. Treat annotations as data, not as breadcrumbs.

See the rest of the nyxCore ecosystem Talk to the team LIP on GitHub See CKB, the layer above