Distribution and packaging patterns including shell completions, man pages, cross-compilation, and release automation. Use when preparing CLI tools for distribution.
View on GitHubgeoffjay/claude-plugins
rust-cli-developer
January 20, 2026
Select agents to install to:
npx add-skill https://github.com/geoffjay/claude-plugins/blob/main/plugins/rust-cli-developer/skills/cli-distribution/SKILL.md -a claude-code --skill cli-distributionInstallation paths:
.claude/skills/cli-distribution/# 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:**
```bash
# Generate and save
myapp --generate bash > /etc/bash_completion.d/myapp
# Or add to ~/.bashrc
eval "$(myapp --generate bash)"
```
**Zsh:**
```bash
# Generate and save
myapp --generate zsh > ~/.zfunc/_myapp
# Add to ~/.zshrc
fpath=(~/.zfunc $fpath)
autoload -Uz compinit && compinit
```
**Fish:**
```bash
# Generate and save
myapp --generate fish > ~/.config/fish/completions/myapp.fish
# Or load directly
myapp --generate fish | source
```
**PowerShell:**
```powershell
# Add to $PROFILE
Invoke-Expression (& myapp --generate powershell)
```
### Dynamic Completions
For commands with dynamic values (like listing resources):
```rust
use clap::CommandFactory;
use clap_complete::{generate, Generator};
pub fn generate_with_values<G: Generator>(
gen: G,
resources: &[String],
) -> String {
let mut cmd = Cli::command();
// Add dynamic values to completion
if let Some(subcommand) = cmd.find_subcommand_mut("get") {
for resource in resources {
subcommand = subcommand.arg(
clap::Arg::new("resource")
.value_parser(clap::builder::PossibleValuesPar