roscli is a Roslyn-native CLI for coding agents working on C#/.NET repositories.
It is designed to replace fragile text-only edits with semantic symbol targeting, structured edits, and workspace-aware diagnostics.
Text-first workflows are fast at first, then degrade on:
- ambiguous symbols and overloads
- cross-file or signature-sensitive refactors
- diagnostics that only make sense in project/solution context
roscli focuses directly on those failure modes:
- semantic navigation (
nav.*) - structured edits (
edit.*) - diagnostics/repair loops (
diag.*,repair.*) - low-churn calls for agents (
--brief true,query.batch,nav.find_symbol_batch)
Canonical pit-of-success guide: docs/PIT_OF_SUCCESS.md
Prerequisites:
- .NET 10 SDK
- a C#/.NET repository
Install:
dotnet tool install --global DNAKode.RoslynSkills.Cli --prereleaseBootstrap:
roscli --version
roscli llmstxt
roscli list-commands --stable-only --ids-only
roscli quickstartFirst semantic flow:
roscli nav.find_symbol src/MyProject/File.cs MySymbol --brief true --first-declaration true --max-results 20 --workspace-path src/MyProject/MyProject.csproj --require-workspace true
roscli edit.rename_symbol src/MyProject/File.cs 42 17 NewName --apply true --workspace-path src/MyProject/MyProject.csproj --require-workspace true
roscli diag.get_file_diagnostics src/MyProject/File.cs --workspace-path src/MyProject/MyProject.csproj --require-workspace trueUse this sequence to reduce retries and avoid tool-learning churn:
roscli llmstxtonce at session start.roscli list-commands --stable-only --ids-only.- Use direct commands (
nav.*,ctx.*,edit.*,diag.*) before exploratorydescribe-command. - Keep reads compact (
--brief true, bounded--max-results). - For project-backed code, force workspace semantics:
--workspace-path <.csproj|.sln|.slnx|dir> --require-workspace true. - Batch read-only discovery when possible:
query.batch,nav.find_symbol_batch. - Validate with diagnostics and build/tests before finalizing.
High-call performance mode:
scripts\roscli-warm.cmd
$env:ROSCLI_USE_PUBLISHED = "1"After changing RoslynSkills source, refresh published cache once:
$env:ROSCLI_REFRESH_PUBLISHED = "1"These are from recorded paired runs under artifacts/.
Source: artifacts/paired-guidance-surgical-codex-smoke-r2/paired-run-summary.md
- control (text-first):
round-trips=2,tokens=36914,duration=12.576s - treatment (roscli):
round-trips=1,tokens=18646,duration=11.484s, Roslyn1/1
Result: with a surgical prompt posture, semantic tooling reduced both round-trips and tokens.
Source family: artifacts/real-agent-runs/*change-signature-named-args-v1*/paired-run-summary.json
| Profile | Control (rt/tokens/sec) | Treatment (rt/tokens/sec) | Roslyn Calls (ok/attempted) |
|---|---|---|---|
skill-minimal |
1 / 25267 / 11.168 |
8 / 80681 / 50.986 |
7/7 |
surgical |
2 / 34722 / 18.157 |
4 / 57060 / 35.351 |
1/2 |
tool-only-v1 |
3 / 44173 / 20.813 |
5 / 62988 / 37.187 |
3/3 |
discovery-lite-v1 (r3) |
2 / 34793 / 16.442 |
4 / 57827 / 33.573 |
3/3 |
Command-sequence fragment from the high-overhead skill-minimal treatment:
roscli list-commands --ids-onlyroscli describe-command nav.find_symbolroscli describe-command edit.rename_symbolroscli nav.find_symbol ... Process ...roscli nav.find_symbol ... left ...roscli edit.rename_symbol ...roscli diag.get_file_diagnostics ...
Interpretation: Roslyn call success alone is not enough. Prompt posture and command-surface ergonomics determine whether semantic tooling is net-positive in end-to-end runs.
Roadmap note:
- TODO: evaluate first-class XAML-aware workflows alongside Roslyn C# semantics, and document recommended mixed-mode handling.
Use roscli for C#/.NET repo edits and diagnostics.
1) Run once: roscli llmstxt
2) Use stable commands first: roscli list-commands --stable-only --ids-only
3) Use describe-command only when argument shape is unclear
4) For project files require workspace semantics:
--workspace-path <.csproj|.sln|.slnx|dir> --require-workspace true
5) Prefer semantic nav/edit/diag commands before text fallback
6) Keep calls brief/bounded, batch read-only discovery when possible
7) Verify diagnostics/build/tests before final answer
Current catalog snapshot:
roscli list-commands --ids-only->47commands- maturity counts:
stable=33,advanced=11,experimental=3 roscli llmstxtdefaults to stable-only startup guidance (--fullfor complete catalog)
Command families:
nav.*: symbol/references/invocations/call-graph/navigationctx.*: file/member/search context retrievalanalyze.*: analysis slices and risk scansdiag.*: diagnostics snapshots and diffsedit.*: structured semantic edits and transactionsrepair.*: diagnostics-driven repair planning/applicationsession.*: non-destructive single-file edit loop (.cs/.csx)
This repo now also includes an XML/XAML-focused CLI lane, XmlSkills, with separate projects:
src/XmlSkills.Contractssrc/XmlSkills.Coresrc/XmlSkills.Clitests/XmlSkills.Cli.Tests
Install preview tool:
dotnet tool install --global DNAKode.XmlSkills.Cli --prereleaseStartup sequence:
xmlcli llmstxt
xmlcli list-commands --ids-only
xmlcli xml.validate_document App.xaml
xmlcli xml.file_outline App.xaml --brief true --max-nodes 120Current stable commands:
xml.backend_capabilitiesxml.validate_documentxml.file_outlinexml.find_elementsxml.replace_element_text(dry-run by default,--apply trueto persist)
Experimental research command:
xml.parse_compare(strictxdocumentvs tolerantlanguage_xmloutput)
Feature flag for experimental backend mode:
$env:XMLCLI_ENABLE_LANGUAGE_XML = "1"Research script:
powershell -ExecutionPolicy Bypass -File benchmarks/scripts/Run-XmlParserBackendComparison.ps1 -EnableLanguageXmlGuide: docs/xml/PIT_OF_SUCCESS.md
Use roscli for in-repo semantic coding tasks.
Use dotnet-inspect for external package/framework API intelligence.
Default Rich Lander companion tool for day-to-day .NET API/dependency questions: dotnet-inspect.
Attribution:
dotnet-inspect: https://github.com/richlander/dotnet-inspectdotnet-skills: https://github.com/richlander/dotnet-skills
Note:
dotnet-skillsis skill/package distribution arounddotnet-inspect, not the primary interactive inspection CLI.
Optional install:
dotnet tool install --global dotnet-inspectPractical split:
- package/API overload/version questions ->
dotnet-inspect - workspace symbol edits/diagnostics ->
roscli - migrations -> inspect external API first, then edit with roscli
GitHub releases:
Typical artifacts:
roslynskills-bundle-<version>.zipDNAKode.RoslynSkills.Cli.<version>.nupkgDNAKode.XmlSkills.Cli.<version>.nupkgroslynskills-research-skill-<version>.ziproslynskills-tight-skill-<version>.zip
Bundle includes:
bin/roscli(.cmd)bin/xmlcli(.cmd)mcp/RoslynSkills.McpServer.dlltransport/RoslynSkills.TransportServer.dllPIT_OF_SUCCESS.md- skills + references
- Claude.ai: Settings -> Capabilities -> Skills -> upload zip
- Claude Code: unzip into skills directory, then restart
Recommended:
roslynskills-tight-skill-<version>.zipfor low-churn production loopsroslynskills-research-skill-<version>.zipfor deeper guided workflows
If NuGet preview is not visible yet:
dotnet tool install --global DNAKode.RoslynSkills.Cli --prerelease --add-source https://api.nuget.org/v3/index.json --ignore-failed-sourcesIf you need an explicit version:
dotnet tool install --global DNAKode.RoslynSkills.Cli --version <version> --add-source https://api.nuget.org/v3/index.json --ignore-failed-sourcesIf installing from downloaded local nupkg:
dotnet tool install --global DNAKode.RoslynSkills.Cli --version <version> --add-source <folder-containing-nupkg> --ignore-failed-sourcesExample MCP server wiring:
- command:
dotnet - args:
"<unzipped>/mcp/RoslynSkills.McpServer.dll"
Example claude-mcp.json:
{
"mcpServers": {
"roslyn": {
"type": "stdio",
"command": "dotnet",
"args": ["<unzipped>/mcp/RoslynSkills.McpServer.dll"],
"env": {}
}
}
}Best results for Claude: MCP server + roslynskills-tight skill.
Current status:
- benchmark preflight probes
geminiplus Windows shims - recommended startup remains
llmstxt->list-commands-> targeted commands
Quick check:
gemini --version
roscli list-commands --stable-only --ids-onlyReference: docs/ECOSYSTEM_NOTES.md
Release/build pipelines:
.github/workflows/release-artifacts.yml.github/workflows/publish-nuget-preview.ymlscripts/release/Build-ReleaseArtifacts.ps1
Preview release process:
- Run
Publish NuGet Previewworkflow. - Set:
version: e.g.0.1.6-preview.18run_tests:truepublish:truepublish_release:true
Tag release process:
- push
v*tag ->Release Artifactsworkflow
Required secret:
NUGET_API_KEY
Local baseline validation:
dotnet test RoslynSkills.slnx -c ReleaseClaude skill validation scripts:
powershell -ExecutionPolicy Bypass -File scripts/skills/Validate-Skills.ps1
powershell -ExecutionPolicy Bypass -File scripts/skills/SmokeTest-ClaudeSkillLoad.ps1 -SkillName roslynskills-tightLSP comparator lane:
powershell -ExecutionPolicy Bypass -File benchmarks/scripts/Run-PairedAgentRuns.ps1 `
-IncludeMcpTreatment `
-IncludeClaudeLspTreatment `
-RoslynGuidanceProfile standardDesign notes: benchmarks/LSP_COMPARATOR_PLAN.md
Dual-lane local wrappers:
- stable lane:
scripts\roscli-stable.cmd ... - dev lane:
scripts\roscli-dev.cmd ... - XML lane:
scripts\xmlcli.cmd ...(xmlcli-stable,xmlcli-dev,xmlcli-warm)
Stable cache refresh:
set ROSCLI_STABLE_REFRESH=1 && scripts\roscli-stable.cmd list-commands --ids-onlyWrapper envs:
ROSCLI_CACHE_DIRROSCLI_USE_PUBLISHEDROSCLI_REFRESH_PUBLISHEDROSCLI_STALE_CHECK
Repository layout:
src/: contracts, core commands, CLI, benchmark toolingtests/: command/CLI/benchmark test suitesbenchmarks/: manifests, scripts, prompts, scoring, reportsdocs/PIT_OF_SUCCESS.md: canonical pit-of-success guidanceskills/: reusable agent skill packsAGENTS.md: execution doctrine and meta-learning logROSLYN_AGENTIC_CODING_RESEARCH_PROPOSAL.md: research design and gates
Run CLI from source:
dotnet run --project src/RoslynSkills.Cli -- list-commands --ids-onlyRepo-root wrappers:
scripts\roscli.cmd list-commands --ids-only
scripts\roscli.cmd ctx.file_outline src/RoslynSkills.Core/DefaultRegistryFactory.csMIT (LICENSE).
