cslq 0.2.0

dotnet tool install --global cslq --version 0.2.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 cslq --version 0.2.0
                    
This package contains a .NET tool you can call from the shell/command line.
#tool dotnet:?package=cslq&version=0.2.0
                    
nuke :add-package cslq --version 0.2.0
                    

cslq

Semantic C# queries for coding agents, over Microsoft's official roslyn-language-server — the same engine behind the VS Code C# extension. cslq is a thin LSP client that turns LSP's URIs and zero-based ranges into path:line plus source context, so an agent can find every caller of a method instead of grepping for its name.

Install

cslq is built for coding agents, so there are two pieces: the tool on PATH, and the skill that makes an agent reach for it instead of grep. The tool on its own is inert — nothing will invoke it.

Prerequisites: the .NET 10 SDK and git. Nothing else — cslq fetches the language server itself on first run.

dotnet tool install -g cslq       # the tool
npx skills add idotta/cslq -g     # the skill, into every agent on the machine

The second command is npx skills, which installs skills/csharp-semantic-queries/SKILL.md from the repository into each agent's skills directory — ~/.claude/skills/csharp-semantic-queries/ for Claude Code. Drop -g to install into the current repository instead. Without npx, copy that one file there yourself: it is plain markdown with YAML frontmatter and needs nothing else on disk.

Or hand both steps to the agent:

Install cslq and its skill so you can answer C# questions semantically instead of grepping: run dotnet tool install -g cslq, then npx skills add idotta/cslq -g, then cslq restore. Then run cslq ready --root . here and tell me what it printed.

The first command that needs the language server restores it for you and says so:

cslq: the pinned language server is not restored; restoring it in <dir>. This is a one-time ~300 MB download.

<dir> is the tool's own manifest directory — the .config/dotnet-tools.json packed alongside the binary, never your repository. The restore is idempotent and later runs skip it. When an update brings a new pin, the restore that fetches it deletes every other version of the server from NuGet's global packages folder (~/.nuget/packages unless NUGET_PACKAGES or a NuGet.Config moves it) and says which, so updating weekly does not stack 300 MB payloads. cslq restore does it on demand, with no workspace, for a Dockerfile or a CI step that would rather not pay the download inside the first query.

Then, in the repository you want to query:

dotnet restore                 # not required, but a restore that fails is invisible without it
cslq ready --root <dir>

The server restores as part of its design-time build — measured on a never-restored solution, ready in 7 s. What it cannot do is tell you when that restore failed: every project then loads empty, and dotnet restore is what names the package.

--root must be the directory holding the .sln or .slnxcslq loads the projects that solution lists. A root with no solution at its top is an error, reported in about a second rather than after the timeout, and a solution one directory down does not count.

Use

cslq ready                                    # block until the workspace has loaded
cslq refs <symbol | file:line:col> [--max N]  # every reference, with context
cslq def <symbol | file:line:col>             # where it is declared
cslq impl <symbol | file:line:col>            # what implements or overrides it
cslq hover <symbol | file:line:col>           # what it is: type, signature, docs
cslq sym <query> [--max N]                    # search the workspace by name
cslq outline <file | symbol> [--max N]        # the declarations in one document
cslq diag [path] [--errors-only]              # compiler and analyzer diagnostics
cslq project <file>                           # which .csproj compiles it, for which TFM
cslq restore                                  # fetch the pinned language server, then exit
$ cslq refs Fixture.Core.Greeter.Greet --root fixture
App/Program.cs:9:35
   8 |     {
>  9 |         Console.WriteLine(Greeter.Greet("world"));
  10 |     }

Core/Greeter.cs:5:26
  4 | {
> 5 |     public static string Greet(string name) => $"Hello, {name}!";
  6 | }

Paths are relative to --root; lines and columns are one-based. Add --json for a { count, truncated, results } envelope.

The README on GitHub has the rest: the agent skill, measured latency and the shared daemon, every failure mode cslq handles, and the evidence behind the dependency choices.

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
0.2.0 0 9/11/2026
0.1.0 60 9/8/2026