lurp 1.4.0

dotnet tool install --global lurp --version 1.4.0
                    
This package contains a .NET tool you can call from the shell/command line.
dotnet new tool-manifest
                    
if you are setting up this repo
dotnet tool install --local lurp --version 1.4.0
                    
This package contains a .NET tool you can call from the shell/command line.
#tool dotnet:?package=lurp&version=1.4.0
                    
nuke :add-package lurp --version 1.4.0
                    

Lurp: a Roslyn semantic map for .NET agents

CI NuGet

Lurp indexes a .NET solution into SQLite with Roslyn, so an agent gets a small, sufficient code neighborhood instead of re-grepping and re-parsing the whole thing for every question. It loads the solution through the compiler and stores symbols, typed relationships, source spans, and provenance in one database, then serves retrieval, semantic diffs, impact paths, and token-bounded context capsules. Index once, query as many times as you want, and get back exact source with evidence levels each time.

What the model sees

An interactive map of how Lurp structures an eCommerce codebase for agent consumption: symbols, relationships, evidence levels, and capsule boundaries as the model receives them.

Why this exists

An agent working a C# codebase today loops search → read → guess, reopening and re-parsing the whole solution for every question. Context windows fill up with irrelevant source, and the agent ends up rediscovering the same call graph on every turn.

Lurp flips that cost around. A one-time index builds a snapshot-bound semantic graph. After that, every query just reads persisted facts: no Roslyn reload, no re-grep. Capsules return the smallest neighborhood that's actually sufficient for the task, each fact states its provenance (compiler_provedruntime_unknown), and any omitted tier is named so you can fetch it separately.

The mental model

Command What it does
context Assemble a bounded capsule of relevant code from a symbol or source location.
impact Follow typed relationships outward and explain each path.
diff Show semantic changes between two snapshots.
search Full-text search over source and symbols.
grep Literal/exact-text search over source content with line numbers.
find-symbol Resolve a symbol by its fully-qualified name.
navigate Resolve an indexed declaration by file and line.
get-symbol Look up symbol metadata (signature, provenance, declaration spans).
get-source Retrieve source text for a document by relative path.
index Build or update the snapshot-bound map in index.db.
pin-snapshot Pin which snapshot reads default to when --snapshot= is omitted, without deleting or rewriting any snapshot.
annotate / get-annotations / retract-annotation Attach and retrieve user-authored annotations on symbols; retract (by annotation_id) any annotation regardless of provenance.
status Report whether the indexed snapshot still matches the workspace.
timings Per-step performance data for a snapshot.
outline List declarations in a document with line spans.
diagnostics List compiler diagnostics captured at index time.
dead-candidates List dead-code candidates: no incoming LIVE edge, after a suppression ladder that keeps public surface, EF/serialization conventions, process entry points, and generated/test code out of the default view.

Worked example

Index a solution, then build a context capsule from a source location:

lurp --mode=index --solution=MySolution.slnx --output-dir=./out
lurp --mode=context --file=src/Services/OrderService.cs --line=42 --output-dir=./out --output=summary

--output=summary prints the handoff facts instead of the full JSON capsule:

capsule OrderService.CreateAsync (Method)
  snapshot: f3bff523b103462be239655c9b753be3  intent: inspect  maxHops: 3
  content tokens:  283/8000  (estimatedTokens: the budget basis)
  delivery tokens: ~571  (estimatedArtifactTokens: whole emitted file; size the context window from this)
  truncated: true
  omitted: direct_callers (budget_exhausted) : fetch with --tier=direct_callers
  omitted: relevant_tests (budget_exhausted) : fetch with --tier=relevant_tests

When a tier is budget_exhausted, fetch it on its own with no budget applied:

lurp --mode=context --file=src/Services/OrderService.cs --line=42 --output-dir=./out --tier=direct_callers

Install

dotnet tool install --global lurp --version 1.4.0
lurp --mode=index --solution=path/to/Your.slnx --output-dir=./out

<details> <summary>Build from source & environment variables</summary>

dotnet build Lurp.slnx
dotnet run --project src -- --mode=index --solution=path/to/Your.slnx --output-dir=./out

Environment variables LURP_SOLUTION_PATH and LURP_OUTPUT_DIR are equivalent to --solution= and --output-dir=. Requires .NET 10 SDK 10.0.301 (pinned via src/global.json rollForward=latestMajor; Roslyn 5.6 requires net10.0).

Installing a local build as the global tool: if you pack a local build and its version number matches the version already on nuget.org, dotnet tool install --global --add-source <path> lurp can silently install the nuget.org copy instead of yours. --add-source only appends a source; it does not remove nuget.org, and when two sources offer the same version, NuGet is free to pick either one. Use --source <path> instead — it replaces every other source, so only your local build is visible. Confirm afterward with lurp --version, which prints the schema/extractor/CLI-MCP-contract versions the installed binary was built with — compare that against the docs you're reading; a mismatch means dotnet tool install pulled an older published build than the repo this doc came from. This will bite again on every future local build that reuses an already-published version number; bump the local package version before packing, or always install with --source, never --add-source.

</details>

Common recipes

Task-first lookup for things you already know Lurp can do but not which mode does it:

Task Command
Find unused using directives lurp --mode=diagnostics --severity=hidden --id=CS8019 --output-dir=./out
Confirm the installed build matches these docs lurp --version
Find dead code, excluding public API and tests lurp --mode=dead-candidates --output-dir=./out
Search source text literally (not symbol search) lurp --mode=grep --query=<text> --output-dir=./out
See what changed between two indexing runs lurp --mode=diff --from-snapshot=<id> --to-snapshot=<id> --output-dir=./out
Pull just the code relevant to a change lurp --mode=context --file=<path> --line=<n> --output-dir=./out
Find every caller of a symbol lurp --mode=impact --symbol=<id> --direction=upstream --output-dir=./out

Framework adapters

Lurp models framework-mediated relationships through six adapters that emit ordinary typed facts into the shared model. Each fact retains its evidence level; see ARCHITECTURE.md for the ladder.

Adapter Facts emitted
ASP.NET Core RoutesTo (route → controller action)
Dependency Injection Registers (service → implementation)
MediatR request/notification → handler chains
EF Core entity, DbSet, and configuration relationships
Serialization DTO/property contract participation
Test TestedBy (production symbol → covering test)

Limitations

  • Single active TFM/configuration: one snapshot per index run.
  • Source generators not executed: GeneratedTreesIncluded=false; generated files under obj/ are path-filtered out.
  • Reflection string-literal candidates are name_candidate, not compiler_proved.
  • 3-snapshot retention: older snapshots and their document versions are pruned automatically, except a snapshot pinned via pin-snapshot, which pruning always skips.
  • Workspace must be restorable: MSBuildWorkspace requires a successful restore; no index without it.

Performance

Measurement Value
eNoteV2 (402 docs) full index ~48 s
eNoteV2 incremental (no changes) ~11 s
Capsule token estimates estimated_tokens (content) vs estimated_artifact_tokens (delivery)
Incremental↔full convergence 5 cycles; 0 changed docs after cycle 1

Status & roadmap

Shipped 1.1.0 as a global tool (dotnet tool install lurp); the source tree currently carries 1.4.0, pending publish. Schema v29, extractor 1.6.0. windows-latest CI plus a self-hosted real-parity gate on FIT-RS2-2026 + eNoteV2 (opt-in via real-parity PR label). Roadmap: multi-TFM and richer DI parameter-type matching are postponed by design (see DeclaredBoundaries).

Documentation & license

Also MCP: --mode=serve exposes 18 tools (lurp_context, lurp_get_source, lurp_outline, lurp_navigate, lurp_find_symbol, lurp_search, lurp_grep, lurp_impact, lurp_diff, lurp_get_symbol, lurp_get_annotations, lurp_retract_annotation, lurp_diagnostics, lurp_status, lurp_timings, lurp_refresh, lurp_index, lurp_dead_candidates) over stdio; all are read-only except lurp_index and lurp_retract_annotation (background re-index). Index first, then serve. See CLI_REFERENCE.md#mcp.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

This package has no dependencies.

Version Downloads Last Updated
1.4.0 0 8/21/2026
1.1.0 62 8/18/2026