Skip to content

■ SKILLS // SKILL SPECS

rust-cli-developer

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

■ [!] ON THIS PAGE ▼
■ INSTALL // npx @self.md/cli install rust-cli-developer
AuthorGeoff Johnson
Namespace@geoffjay/geoffjay-claude-plugins
Category#languages
Version1.0.0
Stars★ 7
Downloads↓ 19
Verification[ ✓ ] self.md verified

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

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

  • 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



</details>

## Source

[View on GitHub](https://github.com/geoffjay/claude-plugins)