Cli Developer

Cli Developer

Automate and integrate CLI Developer workflows for seamless development

Category: development Source: Jeffallan/claude-skills

CLI Developer is an AI skill that guides the design and implementation of command-line interface applications with professional-grade user experience. It covers argument parsing, subcommand architecture, output formatting, configuration management, error handling, and interactive features that produce polished, user-friendly terminal tools.

What Is This?

Overview

CLI Developer provides patterns and best practices for building command-line tools that follow established conventions. It addresses argument and flag parsing with help text generation, subcommand hierarchies for complex tools with multiple operations, output formatting for both human-readable and machine-parseable modes, configuration file support with environment variable overrides, progress indicators and interactive prompts for long-running operations, and error messaging that guides users toward resolution.

Who Should Use This

This skill serves developers building internal tooling for their teams, open source maintainers creating user-facing CLI applications, DevOps engineers automating workflows through command-line utilities, and platform teams building developer experience tools.

Why Use It?

Problems It Solves

Command-line tools built without consistent patterns produce confusing interfaces where users cannot predict flag names, output formats change unpredictably, and error messages provide no actionable guidance. Poor CLI design leads to documentation-heavy tools that users avoid in favor of manual processes.

Core Highlights

The skill follows POSIX conventions and GNU-style long flags for familiar user experience. Automatic help generation keeps documentation synchronized with the code. Structured output modes support both human reading and piping to other tools. Exit codes follow standard conventions for reliable scripting integration.

How to Use It?

Basic Usage

import argparse
import sys
import json

def create_parser():
    parser = argparse.ArgumentParser(
        prog="deploy",
        description="Deploy applications to production environments"
    )
    parser.add_argument("--env", choices=["staging", "production"],
                        required=True, help="Target environment")
    parser.add_argument("--dry-run", action="store_true",
                        help="Preview changes without applying")
    parser.add_argument("--format", choices=["text", "json"],
                        default="text", help="Output format")
    parser.add_argument("-v", "--verbose", action="count", default=0,
                        help="Increase verbosity (use -vv for debug)")

    sub = parser.add_subparsers(dest="command", required=True)
    deploy_cmd = sub.add_parser("app", help="Deploy an application")
    deploy_cmd.add_argument("name", help="Application name")
    deploy_cmd.add_argument("--version", required=True, help="Version tag")
    return parser

def main():
    parser = create_parser()
    args = parser.parse_args()
    if args.command == "app":
        deploy_app(args)

Real-World Examples

import sys

class CLIOutput:
    def __init__(self, format_type="text", verbose=0):
        self.format = format_type
        self.verbose = verbose

    def success(self, message, data=None):
        if self.format == "json":
            print(json.dumps({"status": "success", "message": message,
                              "data": data}))
        else:
            print(f"Success: {message}")
            if data and self.verbose > 0:
                for key, val in data.items():
                    print(f"  {key}: {val}")

    def error(self, message, hint=None, exit_code=1):
        if self.format == "json":
            print(json.dumps({"status": "error", "message": message,
                              "hint": hint}), file=sys.stderr)
        else:
            print(f"Error: {message}", file=sys.stderr)
            if hint:
                print(f"Hint: {hint}", file=sys.stderr)
        sys.exit(exit_code)

    def progress(self, current, total, label=""):
        if self.format == "text":
            pct = current / total * 100
            bar = "#" * int(pct // 2) + "-" * (50 - int(pct // 2))
            print(f"\r[{bar}] {pct:.0f}% {label}", end="", flush=True)

Advanced Tips

Support both --flag=value and --flag value syntax for maximum compatibility across shells. Implement shell completion scripts for bash and zsh to improve discoverability. Use stderr for progress and diagnostic output so stdout remains clean for piping to other tools.

When to Use It?

Use Cases

Use CLI Developer when building developer tools that automate repetitive tasks, when creating deployment or infrastructure management utilities, when wrapping complex APIs with a user-friendly command interface, or when designing internal tools that need to integrate into existing shell workflows.

Related Topics

Argparse and Click for Python CLI frameworks, Commander.js for Node CLI tools, Cobra for Go CLI applications, shell scripting, and terminal UI libraries like Rich and Ink all complement CLI development.

Important Notes

Requirements

A programming language with a mature argument parsing library. Understanding of target platform shell conventions (POSIX, Windows CMD, PowerShell). Clear specification of the commands, flags, and output formats the tool needs to support.

Usage Recommendations

Do: provide helpful error messages that include the correct syntax when a user provides invalid arguments. Support a --help flag on every command and subcommand with usage examples. Use standard exit codes: 0 for success, 1 for general errors, 2 for usage errors.

Don't: require positional arguments when named flags would be clearer and less error-prone. Mix human-readable text with machine-parseable output in the same stream. Silently ignore invalid flags, as this hides user mistakes.

Limitations

CLI tools cannot provide the visual feedback and discoverability that graphical interfaces offer. Complex multi-step workflows may become unwieldy when expressed as sequential commands. Cross-platform compatibility between Unix shells and Windows requires extra testing and occasional workarounds for path and encoding differences.