Skip to content

nullean/argh

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

119 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Nullean.Argh

NuGet CI License: MIT

Build full-featured .NET CLIs without writing a parser.

Methods become commands, XML docs become help text, records become option sets. A Roslyn source generator emits parsing, routing, dispatch, and help into your assembly at build time — no reflection, no runtime overhead, trimming- and AOT-safe by default.

Write vanilla C# and get a fully functional CLI in return: rich --help output, shell tab-completions for bash, zsh, and fish, and a machine-readable JSON schema ready for agentic use cases — all without writing a single line of plumbing code for any of it.

Heavily Inspired by ConsoleAppFramework (Cysharp) — rewritten from scratch with a different feature set, but ConsoleAppFramework laid out the path for source-generated CLI's in .NET.

Sample CLI help output (XmlDocShowcase)

Documentation

Full documentation →

Features

  • XML docs are your help text — summaries, param descriptions, remarks, and <example> blocks appear in --help automatically
  • Everything is generated C# — typed dispatch tree, option parsers, and help printers emitted directly into your assembly
  • MapGroup-style namespaces — nested command groups with their own help pages and scoped option types
  • DTO binding with [AsParameters] — records and classes expand into flags without a custom bind loop
  • Shell completions built-in — bash, zsh, fish; one install command per shell
  • Agent-ready schemamyapp __schema emits full JSON; conforms to cli-schema v1
  • Fuzzy matching — typos produce actionable errors with suggestions
  • DataAnnotations validation[Range], [StringLength], [AllowedValues], [Existing], and more — constraints in --help, failures exit 2
  • CancellationToken injection — add it to a handler, it tracks Ctrl+C (or host shutdown with Hosting)
  • Zero-dep or ME. native* — Nullean.Argh has no Microsoft.Extensions.* dependency; Nullean.Argh.Hosting plugs into IHost and DI

Packages

Package NuGet Description
Nullean.Argh NuGet Metapackage for console apps (Core + Interfaces)
Nullean.Argh.Hosting NuGet Microsoft.Extensions.Hosting integration
Nullean.Argh.Core NuGet Shared runtime + embedded source generator (transitive)
Nullean.Argh.Interfaces NuGet Contracts and attributes (transitive, or for shared libs)

Which package do I need?

Everything else is pulled in transitively.

Quick start

Console app

<PackageReference Include="Nullean.Argh" />
using Nullean.Argh;

var app = new ArghApp();
app.Map("hello", MyHandlers.SayHello);

return await app.RunAsync(args);

Hosted app

<PackageReference Include="Nullean.Argh.Hosting" />
using Microsoft.Extensions.Hosting;
using Nullean.Argh.Hosting;

var builder = Host.CreateApplicationBuilder(args);

builder.Services.AddArgh(args, b =>
{
    b.Map("hello", MyHandlers.SayHello);
});

await builder.Build().RunAsync();

Registration model

// Method group — direct typed dispatch
app.Map("deploy", DeployHandlers.Run);

// Lambda — one-liners
app.Map("greet", (string name) => Console.WriteLine($"Hello, {name}!"));

// Class — every public method becomes a command
app.Map<StorageHandlers>();

// Namespaces — nested command groups
app.MapNamespace<StorageCommands>("storage", ns =>
{
    ns.MapNamespace<BlobCommands>("blob");
});

Parameters

// Positional arguments
public static Task<int> Deploy([Argument] string environment) {}

// Named flags (auto kebab-case)
public static Task<int> Build(string outputDir, bool release = false) {}
// → --output-dir ./bin --release

// DTO binding
public record DeployOptions(string Environment, bool DryRun = false);
public static Task<int> Deploy([AsParameters] DeployOptions opts) {}

// Validation
public static void Run(
    [Range(1, 65535)] int port,
    [AllowedValues("dev", "staging", "prod")] string env) {}

Shell completions

eval "$(myapp __completion bash)"    # bash
source <(myapp __completion zsh)     # zsh
myapp __completion fish > ~/.config/fish/completions/myapp.fish  # fish

Schema

myapp __schema > cli-schema.json

Emits a full JSON description conforming to cli-schema v1 — feed it to an LLM, generate docs, or diff in CI.

Examples

See examples/ for complete working projects:

License

MIT

About

A source generator for command line parsing and command invocations.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages