Musoq.CommandLine
0.0.1
dotnet add package Musoq.CommandLine --version 0.0.1
NuGet\Install-Package Musoq.CommandLine -Version 0.0.1
<PackageReference Include="Musoq.CommandLine" Version="0.0.1" />
<PackageVersion Include="Musoq.CommandLine" Version="0.0.1" />
<PackageReference Include="Musoq.CommandLine" />
paket add Musoq.CommandLine --version 0.0.1
#r "nuget: Musoq.CommandLine, 0.0.1"
#:package Musoq.CommandLine@0.0.1
#addin nuget:?package=Musoq.CommandLine&version=0.0.1
#tool nuget:?package=Musoq.CommandLine&version=0.0.1
Musoq.CommandLine
Musoq.CommandLine is a generic, typed command-line framework for .NET 10. It keeps parsing, validation, help, completion, and execution in one immutable schema while leaving application output, dependency injection, hosting, and rich rendering under consumer control.
The production package is BCL-only. Presenters can use Spectre.Console or another UI library without coupling the command schema to that renderer.
Install the first public preview from NuGet.org:
<PackageReference Include="Musoq.CommandLine" Version="0.0.1" />
Quick start
var app = CommandLineApplication.Create("acme", root =>
{
root.Description("Deployment management.");
root.Command("deploy", command =>
{
var service = command.Argument<string>("service")
.Description("Service to deploy.");
var environment = command.Option("--environment", "production")
.Alias("-e")
.AllowedValues("production", "staging");
var dryRun = command.Flag("--dry-run");
command.ExampleWithDescription(
"Preview a staging deployment.",
"deploy", "payments", "--environment", "staging", "--dry-run");
command.HandleWithContext(async (context, cancellationToken) =>
{
await context.StandardOutput.WriteLineAsync(
$"{service.Get(context.Values)}:{environment.Get(context.Values)}:{dryRun.Get(context.Values)}");
return 0;
});
});
});
var result = await app.RunAsync(
["deploy", "payments", "-e", "staging", "--dry-run"],
new CommandLineRunContext(
CommandLinePresentationContext.Redirected(Console.Out, Console.Error)));
return result.ExitCode;
Typed handles return their declared cardinality directly—no settings POCO, string dictionary, adapter command, or cast is required. Service handlers use Handle<TService> and resolve TService only after parsing and validation succeed.
Cross-assembly modules can request application-owned invocation capabilities without referencing the host. Define a stable typed key on both sides and supply its value in CommandLineInvocationScope.Items:
var sendRequest = new CommandLineItemKey<
Func<HttpRequestMessage, CancellationToken, ValueTask<int>>>(
"example.http-request.v1");
command.HandleWithContext((context, cancellationToken) =>
context.GetRequiredItem(sendRequest)(request, cancellationToken));
Key equality includes both the stable name and T. A missing required key and a value stored under the wrong typed key fail with actionable exceptions after validation, when the invocation scope exists.
Advanced composition
Use CommandLineApplication.CreateBuilder for reusable parsers, middleware, help contributors, atomic ICommandModule contributions, and application-owned mounts. GrammarFragment<TBindings> shares static grammar without settings inheritance. ExpandAfter(...) returns an immutable typed dynamic namespace without rewriting argv. Chain .RequiresServices() when a provider needs parse-time application services; service-free completion then keeps static candidates instead of invoking that provider.
The lifecycle is independently testable:
Route(args)selects static metadata without services.ParseAsync(route, context)binds typed values and expands declared runtime grammar.ValidateAsync(parse, context)produces aValidatedInvocation.InvokeAsync(invocation, context)executes middleware and the handler.
RunAsync composes those phases with isolated writers, presenter, runtime, cancellation, timings, and explicit results. ICommandLineRuntime is the BCL-only seam for Autofac, Microsoft.Extensions.Hosting, or another consumer-owned host. Its context request identifies parse, help, and completion purposes so consumers can provide bounded, side-effect-free completion services.
Named nested boundaries are evaluated as alternative complete parses. Exploration is state-budgeted rather than exponential and returns boundary-search-limit instead of guessing when the configured budget is exhausted. Advanced consumers can tune the deterministic budget with ExploreBoundaryStatesAtMost(...).
Presentation
The framework creates semantic HelpDocument, DiagnosticDocument, and VersionDocument values. PlainTextCommandLinePresenter is the deterministic fallback. Implement ICommandLinePresenter to render the same documents with Spectre.Console, JSON, a GUI, or a remote protocol. Handler output remains application-owned.
Completion
The completion engine is shell-neutral. PowerShell, Bash, zsh, and fish adapters generate scripts around the versioned hidden completion protocol:
using Musoq.CommandLine.Completion.Shells;
var script = new PowerShellCompletionAdapter().GenerateScript(
new ShellCompletionScriptOptions(
Executable: "acme.exe",
CommandName: "acme",
Aliases: ["ac"]));
var bash = ShellCompletionAdapters.Get("bash");
The built-in adapters require tsv-v1 because they honor its replacement span, display text, description, kind, deprecation, append-space behavior, and file/directory directives. Protocol failures produce no new candidate and never leak diagnostics into the shell candidate stream. Terminals need no dedicated integration when they run a supported shell. A new shell implements IShellCompletionAdapter without changing parsing or schema contracts.
Migration contracts
CommandLineContract.Inspect(app) emits deterministic JSON without serializing handlers or services. CommandLineContract.Compare(baseline, current) classifies breaking and compatible command, symbol, alias, lifecycle, module, nested-boundary, and dynamic-grammar changes.
Production verification
The repository's permanent published-layout gate publishes a consumer application into an isolated directory and verifies framework/renderer dependencies, exact module placement, help, version, host-argument partitioning, static and service-backed completion, completion-script execution, malformed protocol handling, cancellation, and module invocation. It also packs Musoq.CommandLine and inspects the exact-version nupkg and snupkg: the runtime package must contain its XML documentation, README, release notes, and GitHub SourceLink symbols, contain no renderer artifacts, and declare no runtime package dependency. A clean smoke application then restores solely from that generated package and runs against it.
Run the framework tests and adapter verifier while changing the generic library:
dotnet test src/dotnet/Musoq.CommandLine.Tests/Musoq.CommandLine.Tests.csproj --configuration Release
./src/dotnet/Musoq.CommandLine.Tests/ShellVerification/verify-shell-adapters.ps1
Consumer schemas should persist CommandLineContract.Inspect(...) output and fail CI on an unreviewed diff. Applications remain responsible for host construction, rich presenters, module discovery and trust, and process-only cancellation/encoding behavior.
| Product | Versions 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. |
-
net10.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.0.1 | 233 | 7/14/2026 |
First public preview: typed parsing, semantic presentation, cross-shell completion, modules, dynamic grammar, typed invocation items, and a testable in-process runtime.