Skip to main content

cli-development

Best practices for building CLI applications across languages. Covers CLI design principles (Unix philosophy, command structure, subcommands vs flags), argument parsing (required/optional args, flags, environment variables, config files, precedence), user interface (help text, version info, progress indicators, color output, interactive prompts), output formatting (human-readable vs machine-readable JSON/YAML, exit codes), error handling (clear messages, suggestions, debug mode), cross-platform considerations (paths, line endings, terminal capabilities), testing strategies (integration tests, output verification, exit codes), documentation (README, man pages, built-in help), and language-specific libraries. Activate when working with CLI applications, command-line tools, argument parsing, CLI utilities, argument handling, commands, subcommands, CLI frameworks, or building command-line interfaces.

来源信息

仓库
ilude/claude-code-config
最近来源活动
2025年11月17日 23:00
检测到的 SKILL.md 语言
英语
星标
8
Forks
0

安装方式

默认使用会先检查来源的 Prompt;你也可以切换为直接命令,或下载本地副本。

检查来源文件

决定是否安装前,请先阅读 SKILL.md,以及 SkillsMP 当前展示的配套文件。

正在显示 SKILL.md

SKILL.md
来源说明 · 只读预览
name
cli-development
description
Best practices for building CLI applications across languages. Covers CLI design principles (Unix philosophy, command structure, subcommands vs flags), argument parsing (required/optional args, flags, environment variables, config files, precedence), user interface (help text, version info, progress indicators, color output, interactive prompts), output formatting (human-readable vs machine-readable JSON/YAML, exit codes), error handling (clear messages, suggestions, debug mode), cross-platform considerations (paths, line endings, terminal capabilities), testing strategies (integration tests, output verification, exit codes), documentation (README, man pages, built-in help), and language-specific libraries. Activate when working with CLI applications, command-line tools, argument parsing, CLI utilities, argument handling, commands, subcommands, CLI frameworks, or building command-line interfaces.
# CLI Development Guidelines Best practices for designing and implementing command-line interface (CLI) applications across programming languages. ## CLI Design Principles ### Unix Philosophy Follow the core Unix philosophy for robust, composable CLIs: - **Do one thing well** - Each command should have a single, well-defined responsibility - **Make it composable** - Design output to work as input to other programs - **Handle text streams** - CLIs work with stdin/stdout/stderr - **Exit cleanly** - Use appropriate exit codes (0 for success, non-zero for errors) - **Fail fast** - Detect and report problems immediately - **Be scriptable** - All functionality must be accessible from non-interactive contexts ### Command Structure #### Verb-Noun Pattern Organize commands using verb-noun relationships: ``` # Good: clear action and object git add <file> # verb: add, noun: file docker run <image> # verb: run, noun: image npm install <package> # verb: install, noun: package # Avoid: unclear structure git foo # ambiguous docker something # unclear what happens ``` #### Subcommands vs Flags **Use subcommands when:** - Commands have distinct behaviors or workflows - Different sets of options apply to different operations - You want clear logical grouping ``` git branch # subcommand git branch --list # subcommand with flag git branch --delete <name> # subcommand with flag and argument ``` **Use flags when:** - Modifying behavior of a single operation - Toggling optional features - Providing configuration ``` ls --color # flag modifies ls behavior grep -r --include # flags modify search behavior ``` **Never mix deeply:** ``` # Avoid: unclear hierarchy tool --verbose subcommand --debug --mode strict # Better: clear structure tool subcommand --verbose --debug --mode strict ``` ### Command Hierarchy Keep hierarchy shallow (max 2-3 levels): ``` # Good: clear, discoverable aws s3 ls aws ec2 describe-instances # Avoid: too deep cloud provider storage list all buckets ``` ## Argument Parsing ### Argument Types **Positional Arguments** - Required by default - Appear in specific positions - Use for primary input/object ```bash cp <source> <destination> # Two required positional arguments docker run <image> # One required positional argument ``` **Optional Arguments (with defaults)** - Used less frequently - Should have sensible defaults - Clearly documented ```bash npm install [directory] # Optional, defaults to current directory grep [options] <pattern> [file] # File argument optional ``` ### Flags and Options **Short Flags (-f)** - Single letter, used frequently - For common operations ```bash ls -l # long format grep -r # recursive tar -xvf # combined flags ``` **Long Flags (--flag)** - Verbose, self-documenting - For less-common operations - Preferred in scripts ```bash docker run --detach --name myapp npm install --save-dev grep --recursive --include="*.js" ``` **Flag Styles** ``` # Boolean flags --verbose # boolean true/false --color=always # explicit value # Flags with values --output file.txt # space-separated --output=file.txt # equals-separated # Accept both styles when possible --timeout 30 or --timeout=30 ``` ### Environment Variables **Convention:** Use SCREAMING_SNAKE_CASE for environment variables ```bash export DEBUG=1 export LOG_LEVEL=debug export API_TOKEN=secret ``` **Hierarchy (high to low precedence):** 1. Command-line flags (highest priority - most explicit) 2. Environment variables (middle - applies to multiple invocations) 3. Configuration file (lower - shared settings) 4. Built-in defaults (lowest priority - fallback) **Example precedence:** ```bash # If user runs with flag, it takes precedence tool --timeout 10 # Uses 10, ignores TIMEOUT env var # If no flag, check env var export TIMEOUT=5 tool # Uses 5 from TIMEOUT # If no flag or env var, use config file default tool --config config.yaml # Reads timeout from config.yaml # If nothing specified, use built-in default tool # Uses hardcoded default (e.g., 30) ``` ### Configuration Files **Location convention:** - Linux/macOS: `~/.config/app/config.yaml` or `~/.apprc` - Windows: `%APPDATA%\App\config.yaml` or `~\AppData\Local\App\config.yaml` - All platforms: `./config.yaml` (current directory, highest priority) **Format preference:** YAML > TOML > JSON > INI - YAML is human-readable and concise - TOML is simpler than YAML but supports nested structures - JSON is universal but verbose - INI is legacy **Example config file:** ```yaml # ~/.config/myapp/config.yaml debug: false log_level: info timeout: 30 output_format: json color: true api: endpoint: https://api.example.com timeout: 10 ``` **Load with proper precedence:** ```python # Python example import os from pathlib import Path import yaml def load_config(): # Built-in defaults config = { 'debug': False, 'timeout': 30, 'color': True } # Load from config file config_path = Path.home() / '.config' / 'myapp' / 'config.yaml' if config_path.exists(): with open(config_path) as f: file_config = yaml.safe_load(f) config.update(file_config) # Override with environment variables if os.getenv('DEBUG'): config['debug'] = os.getenv('DEBUG').lower() == 'true' if os.getenv('TIMEOUT'): config['timeout'] = int(os.getenv('TIMEOUT')) # Note: Command-line args handled by argument parser, applied after return config ``` ## User Interface ### Help Text **Provide comprehensive help:** ```bash $ tool --help Usage: tool [OPTIONS] COMMAND [ARGS]... A brief description of what this tool does. Options: -v, --verbose Increase output verbosity -q, --quiet Suppress non-error output -h, --help Show this message and exit --version Show version and exit Commands: add Add a new item list List all items delete Delete an item config Manage configuration Examples: tool add myitem tool list --format json tool delete --force For more information: https://docs.example.com ``` **Help text structure:** - Usage line: `Usage: tool [OPTIONS] COMMAND [ARGS]...` - Brief description (1-2 lines) - Options section (sorted: common first) - Commands section (if subcommands exist) - Examples section (show common patterns) - Additional resources (docs link, contact info) **Per-command help:** ```bash $ tool add --help Usage: tool add [OPTIONS] NAME Add a new item to the collection. Options: --description TEXT Item description --tags TEXT Comma-separated tags --priority INT Priority level (1-10) -h, --help Show this message and exit Examples: tool add "My Item" tool add "Task" --priority 5 --tags work,urgent ``` ### Version Information **Provide version with --version / -v:** ```bash $ tool --version tool 1.2.3 # For complex tools, show component versions $ tool --version tool 1.2.3 dependency-a: 2.1.0 dependency-b: 5.4.3 ``` **Store version in configuration:** ```python # __version__.py or __init__.py __version__ = "1.2.3" # In main CLI file import sys from . import __version__ @click.command() @click.option('--version', is_flag=True, help='Show version and exit') def main(version): if version: click.echo(f"tool {__version__}") sys.exit(0) ``` ### Progress Indicators **For long operations, show progress:** ```python # Python: using rich library from rich.progress import track import time for i in track(range(100), description="Processing..."): time.sleep(0.1) # Long operation ``` **Output format:** ``` Processing... [████████░░] 80% or Processing... ⠏ (spinning indicator) ``` ### Spinners and Progress Bars **Use spinners for indeterminate progress:** ``` Connecting to server... ⠋ Uploading file... ⠙ Waiting for response... ⠹ ``` **Use progress bars for determinate progress:** ``` Downloading [████████░░░░░░] 40% (2.1 MB / 5.3 MB) Processing [██████████████████░░] 90% ``` **Implement responsibly:** - Disable in non-interactive environments (detect piped output) - Respect `--no-progress` flag - Never output progress to stdout (use stderr) ### Color Output **Support color with disable option:** ```python # Python: using rich or click import click @click.command() @click.option('--color', type=click.Choice(['always', 'auto', 'never']), default='auto', help='Color output mode') def main(color): # auto: color if terminal supports it # always: force color (for piping to less -R) # never: disable color use_color = color == 'always' or (color == 'auto' and is_terminal()) ``` **Environment variable override:** ```bash # User can disable via environment NO_COLOR=1 tool # Disable color FORCE_COLOR=1 tool # Force color ``` **Terminal detection:** ```python import sys import os def supports_color(): # Check NO_COLOR env var if os.getenv('NO_COLOR'): return False # Check FORCE_COLOR env var if os.getenv('FORCE_COLOR'): return True # Check if stdout is a TTY return sys.stdout.isatty() ``` ### Interactive Prompts **Use for confirmations and user input:** ```python # Python: using click import click @click.command() @click.option('--force', is_flag=True, help='Skip confirmations') def delete_item(force): if not force: if not click.confirm('Are you sure you want to delete?'): click.echo("Cancelled") return # Proceed with deletion click.echo("Deleted") # Interactive selection choice = click.prompt( 'Choose an option', type=click.Choice(['a', 'b', 'c']), default='a' ) ``` **Guidelines:** - Ask for confirmation before destructive operations - Provide sensible defaults - Allow bypassing with `--force` flag - Never prompt in non-interactive contexts (detect piped input) ## Output Formatting ### Human-Readable Output **Default format for interactive use:** ``` $ tool list Name Status Modified ──────────────────────────────── Project A Active 2 hours ago Project B Inactive 3 days ago Project C Active 1 week ago ``` **Characteristics:** - Table format with clear columns - Natural language (e.g., "2 hours ago") - Colors for emphasis (when supported) - Sorted intelligently ### Machine-Readable Output **JSON format for scripting:** ```bash $ tool list --format json [ { "name": "Project A", "status": "active", "modified": "2024-01-15T14:30:00Z" }, { "name": "Project B", "status": "inactive", "modified": "2024-01-12T09:15:00Z" } ] ``` **YAML format (compact, readable):** ```bash $ tool list --format yaml - name: Project A status: active modified: 2024-01-15T14:30:00Z - name: Project B status: inactive modified: 2024-01-12T09:15:00Z ``` **CSV format (for spreadsheets):** ```bash $ tool list --format csv name,status,modified "Project A",active,2024-01-15T14:30:00Z "Project B",inactive,2024-01-12T09:15:00Z ``` **Implementation:** ```python import click import json import csv import io @click.command() @click.option('--format', type=click.Choice(['table', 'json', 'yaml', 'csv']), default='table', help='Output format') def list_items(format): items = get_items() if format == 'json': click.echo(json.dumps(items, indent=2)) elif format == 'csv': output = io.StringIO()
在 GitHub 查看
这个 SKILL.md 很大,SkillsMP 这里只预览前一段内容。 在 GitHub 查看