Skip to content

Architecture

csls keeps distribution, compiler work, protocol contracts, and user interfaces in separate assemblies. The small launchers can use Native AOT while Roslyn and MSBuild remain in managed workers where dynamic project loading is available.

editor ── LSP stdio ── csls launcher ── server worker ── Roslyn and MSBuild
└── private control socket
├── CLI worker
├── Hex1b dashboard
└── MCP worker

The csls launcher supervises the server worker and gives it the inherited standard streams. The worker owns the LSP connection, request scheduler, Roslyn workspaces, and control socket. When the editor closes the protocol streams or sends the normal shutdown sequence, the launcher waits for that worker to exit.

CLI commands start a separate managed CLI worker. The worker attaches to the selected server session through its private control socket. The dashboard runs in that same worker and uses Hex1b for terminal rendering. csls-mcp uses its own Native AOT launcher and managed MCP worker. It can attach to an editor session or own a transient server session for one workspace.

Project Responsibility
Csls.App Native AOT csls launcher and command routing
Csls.Worker Managed language-server host and dependency injection
Csls.Server LSP handlers and capability negotiation
Csls.Workspaces SDK discovery, Roslyn workspaces, Razor mapping, and semantic edits
Csls.Core Bounded request scheduling, cancellation, tracing, and shared primitives
Csls.Protocol LSP payloads and source-generated JSON metadata
Csls.Rpc StreamJsonRpc registration, framing, and client callbacks
Csls.Control.Contracts Versioned local control requests and responses
Csls.Control Session discovery and local control transport
Csls.Control.Server Dashboard state, maintenance, queries, and guarded edit plans
Csls.Client Language-server client used by transient CLI and MCP sessions
Csls.Cli.Worker Session, query, edit, doctor, and dashboard commands
Csls.Dashboard Hex1b terminal interface
Csls.Mcp Native AOT csls-mcp launcher
Csls.Mcp.Worker Official C# MCP SDK tools, resources, and prompts
Csls.SourceGen Repository structure and documentation analyzers

Project references point toward contracts and compiler services. The protocol and control contract projects do not depend on UI or process hosts. This keeps wire types reusable and prevents editor behavior from leaking into the workspace layer.

Each configured folder owns a Roslyn workspace and solution. A load, reload, or topology change builds a new set of folders before publishing it as one immutable generation. Read requests capture that generation. Mutations wait for earlier reads, publish their new generation, then release later work.

Open documents are versioned overlays on the current solution. Reloads preserve those overlays for folders that remain active. Diagnostics, semantic tokens, and guarded edit plans record the generation and document version they were computed from, so stale results are not applied to newer source.

The request scheduler bounds queued work and separates concurrent reads, exclusive mutations, and background reads. Cancellation remains attached to the original request correlation identifier from admission through Roslyn execution.

The launchers contain command parsing and process supervision only. Native AOT keeps tool startup small without forcing Roslyn, MSBuild, Razor, editor integration, or MCP reflection into the native image. Managed workers are bundled inside each runtime package and are started with the selected .NET host.

See RPC and control for the two wire protocols and dependencies for the package boundary.