toolchains/rust/cli/clap/SKILL.md
Build production Rust CLIs with Clap: subcommands, config layering, validation, exit codes, shell completions, and testable command surfaces
npx skillsauth add bobmatnyc/claude-mpm-skills clapInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Clap provides declarative command-line parsing with strong help output, validation, and subcommand support. Use it to build CLIs with predictable UX and testable execution paths.
✅ Correct: derive Parser
use clap::Parser;
#[derive(Parser, Debug)]
#[command(name = "mytool", version, about = "Example CLI")]
struct Args {
/// Enable verbose output
#[arg(long)]
verbose: bool,
/// Input file path
#[arg(value_name = "FILE")]
input: String,
}
fn main() {
let args = Args::parse();
if args.verbose {
eprintln!("verbose enabled");
}
println!("input={}", args.input);
}
❌ Wrong: parse multiple times
fn main() {
let _a = Args::parse();
let _b = Args::parse(); // duplicate parsing and inconsistent behavior
}
Model multi-mode CLIs with subcommands and shared global flags.
✅ Correct: global flags + subcommands
use clap::{Parser, Subcommand, ValueEnum};
#[derive(Parser, Debug)]
struct Args {
#[arg(long, global = true)]
verbose: bool,
#[arg(long, global = true, env = "MYTOOL_CONFIG")]
config: Option<String>,
#[command(subcommand)]
cmd: Command,
}
#[derive(Subcommand, Debug)]
enum Command {
Serve { #[arg(long, default_value_t = 3000)] port: u16 },
Migrate { #[arg(long, value_enum, default_value_t = Mode::Up)] mode: Mode },
}
#[derive(Copy, Clone, Debug, ValueEnum)]
enum Mode { Up, Down }
fn main() {
let args = Args::parse();
match args.cmd {
Command::Serve { port } => println!("serve on {}", port),
Command::Migrate { mode } => println!("migrate: {:?}", mode),
}
}
Prefer explicit precedence:
✅ Correct: merge config with CLI overrides
use clap::Parser;
use serde::Deserialize;
#[derive(Parser, Debug)]
struct Args {
#[arg(long, env = "APP_PORT")]
port: Option<u16>,
}
#[derive(Deserialize)]
struct FileConfig {
port: Option<u16>,
}
fn effective_port(args: &Args, file: &FileConfig) -> u16 {
args.port.or(file.port).unwrap_or(3000)
}
Map failures to stable exit codes. Return Result from command handlers and centralize printing.
✅ Correct: command returns Result
use std::process::ExitCode;
fn main() -> ExitCode {
match run() {
Ok(()) => ExitCode::SUCCESS,
Err(e) => {
eprintln!("{e}");
ExitCode::from(1)
}
}
}
fn run() -> Result<(), String> {
Ok(())
}
Test the binary surface (arguments, output, exit codes) without coupling to internals.
✅ Correct: integration test
use assert_cmd::Command;
#[test]
fn shows_help() {
Command::cargo_bin("mytool")
.unwrap()
.arg("--help")
.assert()
.success();
}
Generate completions for Bash/Zsh/Fish.
✅ Correct: emit completions
use clap::{CommandFactory, Parser};
use clap_complete::{generate, shells::Zsh};
use std::io;
fn print_zsh_completions() {
let mut cmd = super::Args::command();
generate(Zsh, &mut cmd, "mytool", &mut io::stdout());
}
main and pass a typed config down.unwrap; return stable exit codes and structured errors.development
Optimize web performance using Core Web Vitals, modern patterns (View Transitions, Speculation Rules), and framework-specific techniques
development
Best practices for documenting APIs and code interfaces, eliminating redundant documentation guidance per agent.
development
Comprehensive API design patterns covering REST, GraphQL, gRPC, versioning, authentication, and modern API best practices
development
Visual verification workflow for UI changes to accelerate code review and catch ...