# Signature DSL
The signature DSL compresses a command's name, positional arguments, and
options into a single Dart string. `CommandSignature.parse`
(`lib/src/console/command_signature.dart:57`) splits that string at
registration time; the registry applies it to the underlying `ArgParser`.
---
## Contents
- [Overview](#overview)
- [Grammar](#grammar)
- [Token Types](#token-types)
- [Argument Modifiers](#argument-modifiers)
- [Option Modifiers](#option-modifiers)
- [Description Annotation](#description-annotation)
- [Name Validation](#name-validation)
- [Examples](#examples)
- [Related](#related)
---
## Overview
```dart
String get signature => 'cmd:name {arg} {arg?} {arg=default} {--flag} {--option=val}';
```
The signature string is the primary way to declare a command's surface. The
alternative is `configure(ArgParser)`, used when the DSL cannot express the
required structure (multi-allowed options, allowed-values lists).
Of the 21 built-in commands: **6** use the signature DSL, **5** use
`configure(ArgParser)` with flags, **10** have no flag surface.
---
## Grammar
```
signature := name (whitespace token)*
name := lowercase with optional colon-separated namespace
token := '{' (argument | option) '}'
argument := name [modifier] [' : ' description]
option := '--' name [value-spec] [' : ' description]
modifier := '?' | '*' | '?*' | '=' default
value-spec := '=' | '=' default
```
`CommandSignature.parse` (`command_signature.dart:57`) runs four stages:
1. **Extract name** (`command_signature.dart:65`): split on the first
whitespace or `{` via `RegExp(r'[\s{]')`; everything before is the name.
2. **Extract token blocks** (`command_signature.dart:82`): scan the tail with
`RegExp(r'\{([^}]+)\}')`; each capture is one token body.
3. **Classify each token** (`command_signature.dart:86`): bodies starting
with `--` route to `_parseOption`; others route to `_parseArgument`.
4. **Parse modifiers**: arguments check `=` first (default value), then
suffix `?*` / `*` / `?`. Options check `=` to distinguish a value option
from a boolean flag.
A ` : ` separator (`RegExp(r'\s+:\s+')`, `command_signature.dart:218`)
strips the description annotation before modifier parsing in both branches.
---
## Token Types
| Token form | Type | Read via |
|---|---|---|
| `{name}` | Positional argument | `ctx.input.argument('name')` |
| `{--name}` | Boolean flag | `ctx.input.flag('name')` |
| `{--name=}` | Value option, no default | `ctx.input.option('name')` |
| `{--name=default}` | Value option with default | `ctx.input.option('name')` |
---
## Argument Modifiers
| Syntax | `isOptional` | `isVariadic` | `defaultValue` | Behaviour |
|---|---|---|---|---|
| `{name}` | false | false | null | Required positional. |
| `{name?}` | true | false | null | Optional; `argument()` returns null when absent. |
| `{name=default}` | true | false | `"default"` | Inline default; implies optional. |
| `{name*}` | false | true | null | Variadic, one or more trailing values. |
| `{name?*}` | true | true | null | Optional variadic, zero or more. |
Modifiers are parsed in declaration order (`command_signature.dart:125`):
`=` check first, then suffix `?*` before `*` before `?`.
---
## Option Modifiers
| Syntax | `isFlag` | `defaultValue` | Behaviour |
|---|---|---|---|
| `{--flag}` | true | null | Boolean switch; absent means false. |
| `{--option=}` | false | null | Value option; `option()` returns null when absent. |
| `{--option=value}` | false | `"value"` | Value option with inline default. |
`CommandSignature.applyTo` (`command_signature.dart:103`) calls
`parser.addFlag` (with `negatable: false`) for booleans and
`parser.addOption(defaultsTo: opt.defaultValue)` for value options.
---
## Description Annotation
Append ` : text` after a token's name and modifiers to attach a description:
```
{name : Argument description}
{--flag : Boolean flag description}
{--option=default : Value option description}
```
`_splitDescription` (`command_signature.dart:205`) matches the first
`\s+:\s+` in the body and returns `(head, description)`. The `description`
flows into `ArgParser` as `help` for options and flags; for arguments it is
stored on `ArgumentSpec` for introspection.
---
## Name Validation
Both patterns are defined in `command_signature.dart:214-216`.
**Command name** (`_namePattern`):
```
^[a-z0-9_]+([:-][a-z0-9_]+)*$
```
Allows colon-namespaced or hyphen-namespaced segments (e.g. `plugin:install`,
`sync-monitors`). Uppercase, dots, or consecutive separators throw.
**Argument and option names** (`_argNamePattern`):
```
^[a-z0-9][a-z0-9_-]*$
```
Must start with a lowercase letter or digit; subsequent characters may
include underscores and hyphens. Both patterns throw `FormatException` at
parse time with the invalid value and expected pattern quoted in the message.
---
## Examples
### tinker (`lib/src/commands/tinker_command.dart:22`)
```dart
String get signature => 'tinker '
'{--eval= : Evaluate a single Dart expression in the running app, '
'print the formatted result on stdout, and exit. Pipe-friendly.}';
```
`CommandSignature` result: name `tinker`, no arguments, one value option
`eval` (`isFlag: false`, `defaultValue: null`). `ctx.input.option('eval')`
returns `null` in REPL mode and the expression string when `--eval` is set.
---
### plugin:install (`lib/src/commands/plugin_install_command.dart:67`)
```dart
String get signature => 'plugin:install '
'$baseFlags'
'{name : Plugin pubspec package name (e.g. magic_logger)} '
'{--provider= : Override the auto-derived provider class name} '
'{--bootstrap-command= : Sub-command to chain after registration} '
'{--use-yaml-only : Fail if install.yaml not found}';
```
`CommandSignature` result: name `plugin:install`, one required positional
argument `name`, three own options (`provider` value, `bootstrap-command`
value, `use-yaml-only` flag), plus the options from `baseFlags` expansion.
---
### plugin:uninstall (`lib/src/commands/plugin_uninstall_command.dart:54`)
```dart
String get signature => 'plugin:uninstall '
'$baseFlags'
'{name : Plugin pubspec package name}';
```
`CommandSignature` result: name `plugin:uninstall`, one required positional
argument `name`, no own options beyond those from `baseFlags` expansion.
---
## Related
- [`../commands/`](../commands/): per-command reference with full signature
listings and usage examples.