Every command in Spectre.Console.Cli receives its input through a CommandSettings class. Decorate properties with [CommandArgument] for positional parameters and [CommandOption] for named flags and options. The framework handles parsing, validation, and help generation automatically.
What We're Building
A file copy command with a required source path, optional destination, and various flags like --force and --buffer-size:
Define Arguments and Options
Use [CommandArgument] with a position index and template: angle brackets <name> for required arguments, square brackets [name] for optional ones. For named parameters, use [CommandOption] with short and/or long forms separated by |.
public class Settings : CommandSettings
{
// Required positional argument (angle brackets)
[CommandArgument(0, "<source>")]
[Description("The source file to copy")]
public string Source { get; init; } = string.Empty;
// Optional positional argument (square brackets)
[CommandArgument(1, "[destination]")]
[Description("The destination path (defaults to current directory)")]
public string? Destination { get; init; }
// Short and long option forms
[CommandOption("-f|--force")]
[Description("Overwrite existing files without prompting")]
public bool Force { get; init; }
// Option with a value
[CommandOption("-b|--buffer-size")]
[Description("Buffer size in KB for the copy operation")]
[DefaultValue(64)]
public int BufferSize { get; init; } = 64;
// Long-form only option
[CommandOption("--preserve-timestamps")]
[Description("Preserve original file timestamps")]
public bool PreserveTimestamps { get; init; }
// Short-form only option
[CommandOption("-v")]
[Description("Enable verbose output")]
public bool Verbose { get; init; }
}
This settings class produces the following usage:
USAGE:
myapp <source> [destination] [OPTIONS]
OPTIONS:
-f, --force Overwrite existing files without prompting
-b, --buffer-size <INT> Buffer size in KB for the copy operation [default: 64]
--preserve-timestamps Preserve original file timestamps
-v Enable verbose output
Boolean properties become flagsāusers include them to set true, omit them for false. Properties with [DefaultValue] show their defaults in help text.
Accept Multiple Values
For commands that process multiple files or need repeatable options, use array types. An array argument captures all remaining positional values and must be the last argument. Array options can be specified multiple times.
public class Settings : CommandSettings
{
// Array argument captures all remaining positional values
// Must be the last argument (highest position index)
[CommandArgument(0, "<files>")]
[Description("One or more files to process")]
public string[] Files { get; init; } = [];
// Array option - specify multiple times: --tag api --tag v2
[CommandOption("-t|--tag <TAG>")]
[Description("Tags to apply (can be specified multiple times)")]
public string[] Tags { get; init; } = [];
}
Users invoke this as:
myapp file1.txt file2.txt file3.txt --tag api --tag production
Use Enums for Constrained Values
When an option should only accept specific values, use an enum type. The framework validates input and displays allowed values in help text.
public class Settings : CommandSettings
{
[CommandArgument(0, "[project]")]
[Description("The project to build")]
public string? Project { get; init; }
// Enum option - framework validates and shows allowed values in help
[CommandOption("-l|--log-level")]
[Description("Set the logging verbosity")]
[DefaultValue(LogLevel.Normal)]
public LogLevel LogLevel { get; init; } = LogLevel.Normal;
// Enum option for build configuration
[CommandOption("-c|--configuration")]
[Description("Build configuration")]
[DefaultValue(Configuration.Debug)]
public Configuration Configuration { get; init; } = Configuration.Debug;
}
Invalid values produce a clear error message listing the allowed options.
See Also
- Using Flag Arguments - Optional flag values with FlagValue
- Using Dictionary and Lookup Options - Key-value pair options with dictionaries
- Using Custom Type Converters - Custom type conversion for complex types
- Making Options Required - Force users to provide specific options
- Attribute and Parameter Reference - Complete attribute documentation