Users have thirty years of muscle memory around POSIX flags. When -verbose works but --verbose does not, or when --port=3000 silently parses as --port with a positional =3000, users assume the tool is broken and stop typing. Non-standard flag syntax also breaks shell completions, wrapper scripts, and Makefile recipes that assume GNU conventions. A tool that invents its own flag grammar is a tool that will never be piped into anything.
Medium because broken POSIX conventions frustrate every user but rarely cause silent data corruption.
Use a standard argument parser (commander, yargs, click, cobra, clap) and avoid writing custom flag logic in src/cli/parse-args.ts or equivalent. Short flags must be -x, long flags must be --xxx, and boolean flags must be toggles, not require explicit true/false:
program
.option('-o, --output <path>', 'Output file')
.option('-v, --verbose', 'Verbose output')
ID: cli-quality.command-structure.posix-flags
Severity: medium
What to look for: Count all flags and options across every command. For each flag, check that options follow POSIX/GNU conventions: short flags are single dash + single letter (-v), long flags are double dash + word (--verbose). Verify that both --flag value and --flag=value syntax are supported (most frameworks handle this automatically). Check that boolean flags don't require a value (--verbose not --verbose true). Check that combined short flags work (-vf for -v -f) if multiple short flags exist.
Pass criteria: Flags use standard short/long syntax. Both space and = separators work for value flags (framework default behavior counts). Boolean flags are proper toggles. No non-standard flag syntax like --flag:value or single-dash long flags (-verbose) — 100% of flags must follow POSIX conventions (single dash for short, double dash for long). Report: "X flags found, all Y follow POSIX conventions."
Fail criteria: Non-standard flag syntax (single-dash long flags, colon separators), or boolean flags requiring explicit true/false values, or custom argument parsing that doesn't follow POSIX conventions.
Skip (N/A) when: The CLI accepts no flags or options — only positional arguments. All checks skip when no CLI entry point is detected.
Detail on fail: "Using single-dash long flags: '-output' instead of '--output'. Using '-verbose true' instead of '--verbose' as a boolean toggle" or "Custom flag parser does not support --flag=value syntax"
Remediation: POSIX flag conventions are what every CLI user expects. Most frameworks handle this correctly out of the box — the main risk is custom parsing:
// commander handles this automatically
program
.option('-o, --output <path>', 'Output file path')
.option('-v, --verbose', 'Enable verbose output') // boolean toggle, no value needed
.option('-n, --count <number>', 'Number of items', parseInt)
Avoid writing custom argument parsers. If you must, follow the GNU Argument Syntax conventions.