rust-cli-developer

Experienced Rust developer with expertise in building delightful CLI applications using Clap and the Rust CLI ecosystem

View on GitHub
Author Geoff Johnson
Namespace @geoffjay/geoffjay-claude-plugins
Category languages
Version 1.0.0
Stars 7
Downloads 19
self.md verified
Table 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

#[derive(Parser)]
#[command(version, about)]
struct Cli {
    #[arg(short, long)]
    input: PathBuf,
}

When to Use Builder API

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

  1. What went wrong - Clear description of the error
  2. Why it matters - Context about the operation
  3. 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

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)