CLI Application Patterns Skill
Overview
The cli_app_pattern skill defines a reusable architectural pattern for deterministic, user-friendly Command Line Interface (CLI) applications. It provides guidance on structure, command organization, user interaction patterns, and best practices for creating professional-grade CLI tools.
Skill Metadata
- •Name: cli_app_pattern
- •Description: Defines reusable architectural patterns for deterministic, user-friendly CLI applications
- •Expected Input: CLI feature or behavior requirements
- •Expected Output: Recommended CLI structure, commands, and interaction patterns
- •Usage Example: Used to design CLI interface for Phase I Todo Console App
Constraints
- •No implementation code generation
- •Framework-agnostic patterns (applies to Click, Typer, Python Fire, argparse)
- •Single file implementation
- •Focus on architecture and user experience, not syntax
Core CLI Patterns
Pattern 1: Single-Command vs Multi-Command Architecture
Choose the appropriate CLI structure based on feature complexity:
**Decision Criteria**:
Single-Command CLI (Simple Function):
- ✓ One primary operation or function
- ✓ Fewer than 3 options/flags
- ✓ Example: `grep`, `cat`, simple utilities
- ✗ More than 3 operations
- ✗ Complex state management
Example:
```python
def todo_add(title: str, description: str = ""):
"""Add a new todo task"""
# Implementation
Multi-Command CLI (Command Groups):
- •✓ Multiple related operations
- •✓ 3 or more distinct commands
- •✓ CRUD operations (Create, Read, Update, Delete)
- •✓ State management across operations
- •✓ Example:
git,docker,aws-cli
Example:
class TodoCLI:
def add(self, title: str, description: str = ""):
"""Add a new task"""
def list(self, status: str = "all"):
"""List all tasks"""
def complete(self, task_id: int):
"""Mark task as complete"""
**Todo App Application**: The Phase I Todo App requires multi-command CLI because it has 5+ operations (add, list, update, delete, complete, etc.). ### Pattern 2: Command Naming Conventions Consistent, intuitive command naming improves usability: ```markdown **Naming Rules**: **Use Verbs (Actions)**: - ✓ `add`, `create`, `new` - Creating resources - ✓ `list`, `show`, `get` - Reading/retrieving - ✓ `update`, `edit`, `modify` - Modifying - ✓ `delete`, `remove`, `rm` - Deleting - ✓ `complete`, `finish`, `done` - State changes - ✗ Nouns as commands (bad: `task`, `item`) - ✗ Ambiguous terms (bad: `do`, `go`, `run` without context) **Standard Aliases**: - `list` → `ls` (common) - `delete` → `del`, `rm`, `remove` - `create` → `new`, `add` - `update` → `edit`, `modify` **Todo App Commands**: ```bash todo add "Buy milk" --description "2% from Safeway" todo list # or todo ls todo update 1 --title "Buy milk and eggs" todo complete 1 # or todo done 1 todo delete 1 # or todo rm 1
### Pattern 3: Argument and Option Design Consistent parameter patterns across commands: ```markdown **Argument Types**: Positional Arguments (Required): - First parameters after command - Essential for operation - No flags needed - Example: task ID, file path Options/Flags (Optional): - Prefixed with `--` or `-` - Optional parameters - Have default values - Example: `--verbose`, `--format json` Boolean Flags (Switches): - True/false without values - `--verbose` or `--verbose=true` - Shorthand: `-v` - Example: `--help`, `--dry-run` **Todo App Parameters**: ```bash # Positional: Required parameters todo add "Task title" # title is positional todo delete 1 # task_id is positional # Options: Optional parameters todo add "Title" --description "Details" # --description optional todo list --status incomplete # --status optional (default: all) todo list --format json # --format optional (default: table) # Boolean flags todo add "Title" --verbose # --verbose flag
### Pattern 4: Interactive Mode Patterns
When to use interactive prompts vs pure CLI:
```markdown
**Use Interactive Mode When**:
- ✓ Missing required information
- ✓ User preferences needed
- ✓ Confirmation of destructive actions
- ✓ Multi-step workflows
- ✓ Optional configuration gathering
**Avoid Interactive Mode When**:
- ✓ Scripting/automation needed
- ✓ Required parameters are always provided
- ✓ CI/CD pipeline execution
- ✓ Clear, complete command suffices
**Interactive Implementation**:
```python
# Check for missing required info
def add(title: str = None):
if not title:
title = input("Task title: ") # Interactive prompt
# Confirm destructive action
def delete(task_id: int, force: bool = False):
if not force:
confirm = input(f"Delete task {task_id}? [y/N]: ")
if confirm.lower() != 'y':
return
Todo App Interactive Examples:
# Interactive: Missing parameters todo add → Prompt: "Task title: " # Non-interactive: All parameters provided todo add "Buy milk" # Interactive confirmation todo delete 1 → Confirm: "Delete task 1? [y/N]: " # Non-interactive with force flag todo delete 1 --force
### Pattern 5: Output Formatting and Display
Clear, consistent output improves user experience:
```markdown
**Output Principles**:
Success Messages:
- ✓ Clear indication of success
- ✓ Show affected resources
- ✓ Provide relevant IDs or references
- ✗ Technical debug output
- ✗ Stack traces on success
Error Messages:
- ✓ Human-readable explanation
- ✓ Suggest correction/fix
- ✓ Include error code if applicable
- ✗ Internal stack traces (unless --verbose)
- ✗ Technical jargon without explanation
Tabular Data (Tables):
- Use for multiple records
- Include headers
- Align columns
- Example: `todo list` output
List Format:
- Simple, one per line
- Good for IDs, names
- Easy to pipe to other commands
JSON Format:
- Use `--format json` for scripting
- Machine-readable
- Consistent structure
- Include all relevant fields
**Todo App Output Examples**:
```bash
todo add "Buy milk"
→ Success: Created task #1: "Buy milk"
todo list
→
ID Title Status Created
-- ----------- ---------- ------------
1 Buy milk pending 2 minutes ago
2 Walk dog completed 1 hour ago
todo list --format json
→
[{"id": 1, "title": "Buy milk", "status": "pending"}]
todo delete 999
→ Error: Task #999 not found. Use 'todo list' to see available tasks.
### Pattern 6: State Management and Persistence
Handling application state across commands:
```markdown
**State Patterns**:
In-Memory (Phase I):
- ✓ Simple dictionary/list storage
- ✓ Lost when application exits
- ✓ Good for prototyping
- ✓ No file I/O overhead
- ✗ Data doesn't persist
- ✗ Not suitable for production
File-Based (Phase II+):
- ✓ JSON file storage
- ✓ Persist between sessions
- ✓ Easy to backup
- ✗ File corruption risk
- ✗ Concurrent access issues
Database (Phase III+):
- ✓ Persistent, reliable storage
- ✓ Concurrent access support
- ✓ Query capabilities
- ✗ Setup complexity
- ✗ External dependency
**Todo App State Evolution**:
```python
# Phase I: In-memory
tasks = {} # {id: Task object}
# Phase II: JSON file storage
import json
def save_tasks():
with open('tasks.json', 'w') as f:
json.dump(tasks, f)
# Phase III+: Database storage
# SQLModel with Neon DB
### Pattern 7: Command Grouping and Organization Organizing related commands into groups: ```markdown **Grouping Strategies**: Flat Commands (Simple): - All commands at top level - Good for < 7 commands - Easy to discover Command Groups (Complex): - Related commands grouped - Example: `git remote add`, `git remote remove` - Good for > 7 commands - Hierarchical organization **Todo App Command Organization**: ```bash # Flat structure (sufficient for basic todo) todo add todo list todo update todo delete todo complete # Could add groups if complexity grows todo task add todo task list todo task delete todo config set todo config get
### Pattern 8: Help and Documentation Comprehensive help improves usability: ```markdown **Help Patterns**: Top-Level Help: - Shows all available commands - Brief description for each - Usage example - Common flags Command-Specific Help: - Detailed description - All options and arguments - Examples - Exit codes (if applicable) Help Command: ```bash todo --help # or todo help # or todo list --help # Command-specific help
Help Content Structure:
{command}: {one-line description}
USAGE:
todo {command} [OPTIONS] [ARGS]
ARGS:
title Task title (required, positional)
OPTIONS:
-d, --description TEXT Task description (optional)
-v, --verbose Verbose output
-h, --help Show help message
EXAMPLES:
todo add "Buy milk"
todo add "Meeting" --description "Team standup at 10am"
EXIT CODES:
0 - Success
1 - General error
2 - Invalid arguments
### Pattern 9: Error Handling and Exit Codes Professional error handling patterns: ```markdown **Error Handling Strategy**: Input Validation: - ✓ Validate all parameters early - ✓ Clear error messages - ✓ Suggest correct usage - ✗ Fail silently or with cryptic errors Error Recovery: - ✓ Use exceptions appropriately - ✓ Clean up resources on error - ✓ Provide recovery suggestions Exit Codes: - 0 = Success - 1 = General error - 2 = Invalid arguments - Specific codes for specific errors (optional) **Todo App Error Examples**: ```bash todo add "" # Empty title → Error: Title cannot be empty. Usage: todo add "Your task" → Exit code: 2 todo complete 999 # Non-existent task → Error: Task #999 not found → Suggestion: Run 'todo list' to see available tasks → Exit code: 1 # With --verbose flag todo add "" --verbose → Error: Title cannot be empty → Debug: Input received: title='' → Usage: todo add "Your task" → Exit code: 2
### Pattern 10: Configuration and Defaults
Handling configuration and default values:
```markdown
**Configuration Sources** (Priority Order):
1. Command-line arguments (highest priority)
2. Environment variables
3. Config file (local)
4. Config file (global)
5. Application defaults (lowest priority)
**Configuration Pattern**:
```python
# Pseudocode for config resolution
def get_config():
# Start with defaults
config = DEFAULTS.copy()
# Override with global config file
if exists(GLOBAL_CONFIG):
config.update(load(GLOBAL_CONFIG))
# Override with local config file
if exists(LOCAL_CONFIG):
config.update(load(LOCAL_CONFIG))
# Override with environment variables
config.update(env_vars)
# Override with CLI arguments (highest priority)
config.update(cli_args)
return config
Todo App Configuration:
# Command-line args (highest priority)
todo list --sort priority
# Environment variables
export TODO_SORT=priority
todo list
# Config file (~/.todo/config.json or ./.todo.json)
{
"sort": "priority",
"display_format": "table"
}
## CLI Design Decision Matrix
| Factor | Single-Command | Multi-Command | Example |
|--------|---------------|---------------|---------|
| Operations | 1-2 | 3+ | `grep` vs `git` |
| Complexity | Simple function | Complex workflow | `cat` vs `docker` |
| Learning curve | Low | Medium-High | `ls` vs `aws-cli` |
| User experience | Quick but limited | Structured, scalable | `cal` vs `kubectl` |
## CLI Framework Recommendations
### For Phase I Todo (Simple CLI)
**Recommendation: Python Fire** (Simplest, zero boilerplate)
Pros:
- Single line: `fire.Fire()`
- Automatic from functions/classes
- No decorators needed
- Built-in help generation
- Handles types automatically
Cons:
- Less control over help formatting
- Limited compared to full frameworks
Example:
```python
import fire
class TodoCLI:
def add(self, title: str, description: str = ""):
"""Add a new task"""
# Implementation
def list(self):
"""List all tasks"""
# Implementation
if __name__ == '__main__':
fire.Fire(TodoCLI)
Alternative: Click
Recommendation: Click (For more control, production-grade)
Pros:
- •Full control over commands/options
- •Excellent documentation
- •Production battle-tested
- •Rich ecosystem
Cons:
- •More boilerplate (@click.command, @click.option)
- •Steeper learning curve
Example:
import click
@click.group()
def todo():
pass
@todo.command()
@click.argument('title')
@click.option('--description', default='')
def add(title, description):
"""Add a new task"""
pass
todo()
Alternative: Typer
Recommendation: Typer (Modern, type-hint based)
Pros:
- •Type hints for validation
- •Auto-generated help from type hints
- •Modern Python features
- •Fast to develop
Cons:
- •Newer framework (less mature)
- •Based on Click (some overhead)
Example:
import typer
app = typer.Typer()
@app.command()
def add(title: str, description: str = ""):
"""Add a new task"""
pass
if __name__ == '__main__':
app()
Usage Instructions
Command Line Interface (CLI)
# Design CLI for a feature claude --skill cli_app_pattern "Design CLI for todo add command with title and description" # Get pattern recommendations claude --skill cli_app_pattern "Should I use single or multi-command for my tool?" # Design complete CLI structure claude --skill cli_app_pattern "Design complete CLI structure for todo app with CRUD operations" # Framework recommendation claude --skill cli_app_pattern "Recommend CLI framework for simple todo app"
Interactive Mode
- •Describe the CLI features or requirements
- •Specify target complexity (simple utility vs complex tool)
- •The skill applies Patterns 1-10 to design CLI
- •Review recommended command structure and options
- •Get framework recommendations (Fire, Click, Typer, argparse)
- •Follow implementation guidance with code examples
Design Examples
Example 1: Todo Add Command
# Input: Design CLI for adding todos claude --skill cli_app_pattern "Design CLI for todo add" # Output: Command: add Structure: todo add "TITLE" [--description TEXT] Pattern: Single required positional (title) + optional option (description) Framework: Python Fire recommended Implementation: Function: add(title: str, description: str = "") Types: Automatically handled by Fire Help: Auto-generated from docstring
Example 2: Single vs Multi-Command Decision
# Input claude --skill cli_app_pattern "Single or multi-command for 5 CRUD operations?" # Output: Recommendation: Multi-command Rationale: - 5 distinct operations exceeds single-command threshold - CRUD pattern maps naturally to command structure - Better organization and discoverability - Easier to add future commands Commands to implement: - todo add - todo list - todo update - todo delete - todo complete
Example 3: Complete Todo CLI Design
# Input
claude --skill cli_app_pattern "Design complete CLI for Phase I todo app"
# Output:
Architecture: Multi-command CLI
Framework: Python Fire (simplest)
Commands:
1. todo add TITLE [--description TEXT]
- Positional: title (required)
- Option: --description (optional)
2. todo list [--status STATUS] [--format FORMAT]
- Option: --status [all|pending|completed] (default: all)
- Option: --format [table|json|list] (default: table)
3. todo update TASK_ID [--title TEXT] [--description TEXT]
- Positional: task_id (required)
- Option: --title (optional, update if provided)
- Option: --description (optional, update if provided)
4. todo delete TASK_ID [--force]
- Positional: task_id (required)
- Flag: --force (skip confirmation)
5. todo complete TASK_ID
- Positional: task_id (required)
6. todo --help
7. todo COMMAND --help (command-specific help)
State Management: In-memory dictionary (Phase I)
Output Format: Tabular display (list), JSON (--format json)
Error Handling: Clear messages with suggestions
Input Validation & Constraints
Required Input Format
- •Type: Feature description or CLI requirements
- •Format: Natural language or structured requirements
- •Minimum: At least one user interaction described
- •Context: Target complexity level (simple/medium/complex)
Input Schema Validation
The skill validates input against these criteria:
- •Must describe user interactions or operations
- •Should indicate if scripting/automation needed
- •Should specify output expectations
- •Optional: Mention existing patterns or examples
Invalid Input Handling
- •No features described: Returns error "Must provide CLI requirements"
- •Unclear scope: Asks for clarification on complexity
- •Contradictory requirements: Highlights conflicts and asks for resolution
Output Format Options
- •Recommendation: Complete CLI design document
- •Structure: Commands, options, examples, patterns referenced
- •Formats: Text, markdown code blocks with examples
- •Framework specific: Implementation examples for recommended framework
Version Compatibility
- •Claude Code Version: Compatible with v2.0 and above
- •Python Versions: 3.8+ (for modern frameworks)
- •Framework Support: Python Fire, Click, Typer, argparse
- •Last tested: 2026-01-27
Integration with Spec-Driven Development
The cli_app_pattern skill integrates with SDD workflow:
# 1. Create spec cspecs/phase-i/spec.md # 2. Optionally create plan specs/phase-i/plan.md # 3. Design CLI using this skill claude --skill cli_app_pattern "Design CLI for Phase I based on spec.md" # 4. Decompose into tasks claude --skill task_decomposer "Convert CLI design to tasks" # 5. Validate with constitution guard claude --skill constitution_guard "Validate CLI design and tasks" # 6. Implement with Claude Code following tasks
Advanced Topics
Configuration Management
- •Environment variables vs CLI args
- •Config file locations and precedence
- •Default value resolution
- •Cascading configuration
Internationalization
- •Multi-language help text
- •Locale-specific formatting
- •Time zone handling
- •Translation patterns
Testing CLI Applications
- •Unit testing CLI functions
- •Integration testing with subprocess
- •Mocking user input (stdin)
- •Testing interactive prompts
- •Exit code validation
CI/CD Integration
- •CLI in automated pipelines
- •Non-interactive mode requirements
- •Exit codes for pipeline status
- •Output parsing in scripts
Skill Version: 1.0.0 Last Updated: 2026-01-27 Compatibility: Claude Code v2.0+, Python 3.8+ Project: Hackathon II - Evolution of Todo
End of Skill Definition