rust-cli-developer
Experienced Rust developer with expertise in building delightful CLI applications using Clap and the Rust CLI ecosystem
View on GitHubTable of content
Experienced Rust developer with expertise in building delightful CLI applications using Clap and the Rust CLI ecosystem
Installation
npx claude-plugins install @geoffjay/geoffjay-claude-plugins/rust-cli-developer
Contents
Folders: agents, commands, skills
Included Skills
This plugin includes 4 skill definitions:
clap-patterns
Common Clap patterns and idioms for argument parsing, validation, and CLI design. Use when implementing CLI arguments with Clap v4+.
View skill definition
Clap Patterns Skill
Common patterns and idioms for using Clap v4+ effectively in Rust CLI applications.
Derive API vs Builder API
When to Use Derive API
- CLI structure known at compile time
- Want type safety and compile-time validation
- Prefer declarative style
- Standard CLI patterns are sufficient
#[derive(Parser)]
#[command(version, about)]
struct Cli {
#[arg(short, long)]
input: PathBuf,
}
When to Use Builder API
- CLI needs to be built dynamically at runtime
- Building plugin systems
- Arguments depend on configuration
- Need maximum flexibility
fn build_cli() -> Command {
Command::new("app")
.arg(Arg::new("input").short('i'))
}
Common Patterns
Global Options with Subcommands
#[derive(Parser)]
struct Cli {
#[arg(short, long, global = true, action = ArgAction::Count)]
verbose: u8,
#[command(subcommand)]
command: Commands,
}
Argument Groups for Mutual Exclusivity
#[derive(Parser)]
#[command(group(
ArgGroup::new("format")
.required(true)
.args(&["json", "yaml", "toml"])
))]
struct Cli {
#[arg(long)]
json: bool,
#[arg(long)]
yaml: bool,
#[arg(long)]
toml: bool,
}
Custom Value Parsers
fn parse_port(s: &str) -> Result<u16, String> {
let port: u16 = s.parse()
.map_err(|_| format!("`{s}` isn't a valid port"))?;
if (1024..=65535).contains(&port) {
Ok(port)
} else {
...(truncated)
</details>
### cli-configuration
> Configuration management patterns including file formats, precedence, environment variables, and XDG directories. Use when implementing configuration systems for CLI applications.
<details>
<summary>View skill definition</summary>
# CLI Configuration Skill
Patterns and best practices for managing configuration in command-line applications.
## Configuration Precedence
The standard precedence order (lowest to highest priority):
1. **Compiled defaults** - Hard-coded sensible defaults
2. **System config** - /etc/myapp/config.toml
3. **User config** - ~/.config/myapp/config.toml
4. **Project config** - ./myapp.toml or ./.myapp.toml
5. **Environment variables** - MYAPP_KEY=value
6. **CLI arguments** - --key value (highest priority)
```rust
use config::{Config as ConfigBuilder, Environment, File};
pub fn load_config(cli: &Cli) -> Result<Config> {
let mut builder = ConfigBuilder::builder()
// 1. Defaults
.set_default("port", 8080)?
.set_default("host", "localhost")?
.set_default("log_level", "info")?;
// 2. System config (if exists)
builder = builder
.add_source(File::with_name("/etc/myapp/config").required(false));
// 3. User config (if exists)
if let Some(config_dir) = dirs::config_dir() {
builder = builder.add_source(
File::from(config_dir.join("myapp/config.toml")).required(false)
);
}
// 4. Project config (if exists)
builder = builder
.add_source(File::with_name("myapp").required(false))
.add_source(File::with_name(".myapp").required(false));
// 5. CLI-specified config (if provided)
if let Some(config_path) = &cli.config {
builder = builder.add_source(File::from(con
...(truncated)
</details>
### cli-distribution
> Distribution and packaging patterns including shell completions, man pages, cross-compilation, and release automation. Use when preparing CLI tools for distribution.
<details>
<summary>View skill definition</summary>
# CLI Distribution Skill
Patterns and best practices for distributing Rust CLI applications to users.
## Shell Completion Generation
### Using clap_complete
```rust
use clap::{CommandFactory, Parser};
use clap_complete::{generate, Generator, Shell};
use std::io;
#[derive(Parser)]
struct Cli {
/// Generate shell completions
#[arg(long = "generate", value_enum)]
generator: Option<Shell>,
// ... other fields
}
fn print_completions<G: Generator>(gen: G, cmd: &mut clap::Command) {
generate(gen, cmd, cmd.get_name().to_string(), &mut io::stdout());
}
fn main() {
let cli = Cli::parse();
if let Some(generator) = cli.generator {
let mut cmd = Cli::command();
print_completions(generator, &mut cmd);
return;
}
// ... rest of application
}
Installation Instructions by Shell
Bash:
# Generate and save
myapp --generate bash > /etc/bash_completion.d/myapp
# Or add to ~/.bashrc
eval "$(myapp --generate bash)"
Zsh:
# Generate and save
myapp --generate zsh > ~/.zfunc/_myapp
# Add to ~/.zshrc
fpath=(~/.zfunc $fpath)
autoload -Uz compinit && compinit
Fish:
# Generate and save
myapp --generate fish > ~/.config/fish/completions/myapp.fish
# Or load directly
myapp --generate fish | source
PowerShell:
# Add to $PROFILE
Invoke-Expression (& myapp --generate powershell)
Dynamic Completions
For commands with dynamic values (like listing resources
…(truncated)
cli-ux-patterns
CLI user experience best practices for error messages, colors, progress indicators, and output formatting. Use when improving CLI usability and user experience.
View skill definition
CLI UX Patterns Skill
Best practices and patterns for creating delightful command-line user experiences.
Error Message Patterns
The Three Parts of Good Error Messages
- What went wrong - Clear description of the error
- Why it matters - Context about the operation
- How to fix it - Actionable suggestions
bail!(
"Failed to read config file: {}\n\n\
The application needs a valid configuration to start.\n\n\
To fix this:\n\
1. Create a config file: myapp init\n\
2. Or specify a different path: --config /path/to/config.toml\n\
3. Check file permissions: ls -l {}",
path.display(),
path.display()
);
Using miette for Rich Diagnostics
#[derive(Error, Debug, Diagnostic)]
#[error("Configuration error")]
#[diagnostic(
code(config::invalid),
url("https://docs.example.com/config"),
help("Check the syntax of your configuration file")
)]
struct ConfigError {
#[source_code]
src: String,
#[label("invalid value here")]
span: SourceSpan,
}
Color Usage Patterns
Semantic Colors
- Red - Errors, failures, destructive actions
- Yellow - Warnings, cautions
- Green - Success, completion, safe operations
- Blue - Information, hints, links
- Cyan - Highlights, emphasis
- Dim/Gray - Less important info, metadata
use owo_colors::OwoColorize;
// Status indicators with colors
println!("{} Build succeeded", "✓".green().bold());
println!("{} W
...(truncated)
</details>
## Source
[View on GitHub](https://github.com/geoffjay/claude-plugins)