A

Advisor Cli Developer

Comprehensive agent designed for agent, building, command, line. Includes structured workflows, validation checks, and reusable patterns for development tools.

AgentClipticsdevelopment toolsv1.0.0MIT
0 views0 copies

Advisor CLI Developer

A senior CLI development agent that helps you create intuitive, efficient command-line interfaces with expert knowledge in argument parsing, interactive prompts, terminal UI, and cross-platform compatibility.

When to Use This Agent

Choose Advisor CLI Developer when:

  • Building new CLI tools from scratch with proper argument parsing and help text
  • Adding interactive prompts, spinners, progress bars, or terminal UIs
  • Making CLI tools cross-platform (macOS, Linux, Windows)
  • Implementing shell completions, plugin systems, or configuration management
  • Migrating from one CLI framework to another (yargs to commander, argparse to click)

Consider alternatives when:

  • Building graphical desktop applications (use an Electron or Tauri agent)
  • Creating REST APIs or web services (use a backend development agent)
  • Writing shell scripts without a structured CLI framework (just write bash/zsh)

Quick Start

# .claude/agents/advisor-cli-developer.yml name: Advisor CLI Developer description: Build professional command-line interfaces model: claude-sonnet tools: - Read - Write - Edit - Bash - Glob - Grep

Example invocation:

claude "Build a CLI tool in Node.js using commander that manages local development environments with start, stop, status, and logs subcommands"

Core Concepts

CLI Framework Comparison

FrameworkLanguageStrengthsBest For
CommanderNode.jsSimple, declarativeQuick CLI tools
yargsNode.jsFeature-rich, auto-completeComplex CLIs
oclifNode.jsPlugin system, testingEnterprise CLIs
ClickPythonDecorators, composablePython tools
TyperPythonType hints, auto-docsModern Python CLIs
CobraGoSubcommands, completionsSystem tools
clapRustDerive macros, validationPerformance-critical CLIs

CLI Structure Pattern

// src/cli.ts — Commander-based CLI import { Command } from 'commander'; import { version } from '../package.json'; const program = new Command() .name('devenv') .description('Manage local development environments') .version(version); program .command('start') .description('Start a development environment') .option('-p, --port <number>', 'Port to bind', '3000') .option('-e, --env <name>', 'Environment name', 'development') .option('--detach', 'Run in background') .action(async (options) => { const { startEnvironment } = await import('./commands/start'); await startEnvironment(options); }); program .command('stop') .description('Stop a running environment') .argument('[name]', 'Environment name', 'default') .option('--force', 'Force stop without cleanup') .action(async (name, options) => { const { stopEnvironment } = await import('./commands/stop'); await stopEnvironment(name, options); }); program .command('logs') .description('View environment logs') .argument('[name]', 'Environment name', 'default') .option('-f, --follow', 'Follow log output') .option('-n, --lines <number>', 'Number of lines', '50') .action(async (name, options) => { const { viewLogs } = await import('./commands/logs'); await viewLogs(name, options); }); program.parse();

Interactive Terminal UI

import ora from 'ora'; import chalk from 'chalk'; import { confirm, select, input } from '@inquirer/prompts'; async function startEnvironment(options: StartOptions) { // Interactive prompts when options are missing const env = options.env ?? await select({ message: 'Select environment:', choices: [ { name: 'Development', value: 'development' }, { name: 'Staging', value: 'staging' }, { name: 'Production', value: 'production', disabled: 'Use deploy command' }, ], }); const spinner = ora('Starting environment...').start(); try { await launchServices(env, options.port); spinner.succeed(chalk.green(`Environment started on port ${options.port}`)); console.log(` ${chalk.bold('Environment ready!')} URL: ${chalk.cyan(`http://localhost:${options.port}`)} Env: ${chalk.yellow(env)} Logs: ${chalk.dim('devenv logs --follow')} Stop: ${chalk.dim('devenv stop')} `); } catch (error) { spinner.fail(chalk.red('Failed to start environment')); console.error(chalk.dim(error.message)); process.exit(1); } }

Configuration

ParameterDescriptionDefault
frameworkCLI framework (commander, yargs, oclif, click, cobra)Auto-detect
languageImplementation languageAuto-detect
interactiveInclude interactive promptstrue
completionsGenerate shell completions (bash, zsh, fish)true
config_formatConfig file format (json, yaml, toml)yaml
output_formatsSupported output formats (table, json, csv)["table", "json"]

Best Practices

  1. Support both interactive and non-interactive modes. CLI tools run in terminals by humans and in scripts by automation. Detect process.stdout.isTTY to determine the context. In interactive mode, show prompts, spinners, and colored output. In non-interactive mode (piped or scripted), skip prompts (require flags instead), disable colors, and output machine-parseable formats. A flag like --json or --no-interactive should always be available.

  2. Provide comprehensive help text at every command level. Every command and subcommand should have a description, usage examples, and option documentation. Include at least two usage examples showing common workflows. Use commander's .addHelpText('after', ...) to add examples after the auto-generated help. Users should never need to read external docs to use basic commands.

  3. Handle errors with actionable messages and appropriate exit codes. Never show raw stack traces to users. Catch errors and display a clear message explaining what went wrong and how to fix it. Use exit code 0 for success, 1 for general errors, and 2 for usage errors. If the error involves a missing dependency or configuration, tell the user the exact command to run to fix it.

  4. Respect standard CLI conventions. Follow POSIX conventions: -v for verbose, -q for quiet, -f for force, --help for help, --version for version. Support -- to separate flags from arguments. Read from stdin when no file argument is given. Write normal output to stdout and errors/diagnostics to stderr. These conventions let your tool integrate naturally with pipes and shell workflows.

  5. Implement configuration file discovery with sensible precedence. Search for configuration in order: command-line flags (highest priority), environment variables, project-local config (.devenvrc.yml), user-level config (~/.config/devenv/config.yml), system defaults (lowest priority). Use cosmiconfig or similar libraries to handle file discovery. Always allow every config option to be overridden via a flag.

Common Issues

Output formatting breaks in narrow terminal windows. Tables and formatted output overflow when the terminal is narrower than expected. Detect terminal width with process.stdout.columns and adjust formatting accordingly. Use text truncation with ellipsis for wide columns, switch from tables to vertical key-value layouts below certain widths, and never hardcode column widths.

Shell completions are not installed or stop working after updates. Users install completions once and forget about them. When the CLI adds new commands or options, the static completion script becomes stale. Generate completions dynamically where possible. For static completions, include a devenv completions command that outputs the latest script and instructions for installing it in each shell (bash, zsh, fish).

Ctrl+C handling leaves resources in an inconsistent state. When users press Ctrl+C during a long operation, the process exits immediately, leaving temp files, running child processes, or locked resources behind. Register SIGINT handlers that clean up before exiting. Use try/finally blocks around resource acquisition. For child processes, track PIDs and kill them in the signal handler before exiting.

Community

Reviews

Write a review

No reviews yet. Be the first to review this template!

Similar Templates