Configuring CommandApp and Commands

How to register commands with the CommandApp and configure global settings

When building a CLI with multiple commands, use CommandApp.Configure to register commands, set up aliases, and customize how your application appears in help output.

What We're Building

A multi-command CLI with add, remove, and list—each with aliases (like a for add) and descriptions shown in help:

Configuring CommandApp demonstration

Register Commands with Metadata

Use AddCommand<T>("name") to register each command, then chain methods to add descriptions, aliases, and examples:

var app = new CommandApp();
  
app.Configure(config =>
{
    // Set application identity for help output
    config.SetApplicationName("myapp");
    config.SetApplicationVersion("1.0.0");
  
    // Add commands with descriptions, aliases, and examples
    config.AddCommand<AddCommand>("add")
        .WithDescription("Add a new item")
        .WithAlias("a")
        .WithExample("add", "todo.txt")
        .WithExample("add", "notes.md", "--force");
  
    config.AddCommand<RemoveCommand>("remove")
        .WithDescription("Remove an item")
        .WithAlias("rm")
        .WithAlias("delete")
        .WithExample("remove", "old-file.txt");
  
    config.AddCommand<ListCommand>("list")
        .WithDescription("List all items")
        .WithAlias("ls");
  
#if DEBUG
    // Development-only settings
    config.PropagateExceptions();
    config.ValidateExamples();
#endif
});
  
return await app.RunAsync(args);

This produces help output like:

USAGE:
    myapp [COMMAND] [OPTIONS]
  
COMMANDS:
    add (a)              Add a new item
    remove (rm, delete)  Remove an item
    list (ls)            List all items

Users can invoke commands by name or any alias: myapp rm file.txt works the same as myapp remove file.txt.

Configure Global Settings

Access config.Settings to adjust parsing behavior:

var app = new CommandApp<ListCommand>();
  
app.Configure(config =>
{
    config.SetApplicationName("myapp");
  
    // Configure parsing behavior
    config.Settings.CaseSensitivity = CaseSensitivity.None;
    config.Settings.StrictParsing = false;
});
  
return await app.RunAsync(args);

Common settings include:

Setting Purpose
CaseSensitivity Control whether commands/options are case-sensitive
StrictParsing When false, unknown flags become remaining arguments instead of errors

Development Settings

During development, enable additional validation:

#if DEBUG
    config.PropagateExceptions();  // Get full stack traces
    config.ValidateExamples();     // Verify all WithExample calls are valid
#endif

ValidateExamples() catches typos in your examples at startup rather than confusing users at runtime.

See Also