| name | implementing-cli-patterns |
| description | Implements CLI UX with output formatting, progress indicators, and prompts. Use when working on CLI output, chalk styling, ora spinners, inquirer prompts, progress bars, reporters, error formatting, or exit codes. Use when this capability is needed. |
| metadata | {"author":"saleor"} |
CLI User Experience Patterns
Overview
Implement consistent, user-friendly CLI interactions using the project's console module, progress tracking, and reporter patterns. All CLI output should go through src/cli/console.ts rather than raw console.log.
When to Use
- Implementing command output formatting
- Adding progress indicators for operations
- Creating interactive user prompts
- Formatting error messages for the terminal
- Designing reporter output for deploy/diff results
- Not for: Business logic, GraphQL operations, or service layer code
CLI Stack
| Tool | Purpose | Location |
|---|
| chalk | Colored terminal output | Via src/cli/console.ts |
| ora | Spinner/progress indicators | src/cli/progress.ts |
| @inquirer/prompts | Interactive user prompts | Commands layer |
| tslog | Structured logging | Internal logging |
Console Module
Located in src/cli/console.ts. Always use this instead of raw console.log:
| Method | Color | Prefix | Use For |
|---|
error() | Red | x | Error messages |
success() | Green | check | Success confirmations |
warning() | Yellow | warn | Warnings, degraded results |
hint() | Cyan | bulb | Actionable suggestions |
important() | Bold | - | Key information |
info() | Blue | i | Informational messages |
code() | Gray bg | - | Code/command snippets |
Import: import { console } from '@/cli/console';
Progress Indicators
- Single operations: Use
ora spinner with .start(), .succeed(), .fail()
- Bulk operations: Use
BulkOperationProgress from src/cli/progress.ts for progress bars with success/failure tracking
Interactive Prompts
Available prompt types from @inquirer/prompts:
| Prompt | Import | Use For |
|---|
confirm | @inquirer/prompts | Yes/no decisions, destructive action guards |
select | @inquirer/prompts | Single choice from options |
checkbox | @inquirer/prompts | Multi-select (e.g., entity selection) |
input | @inquirer/prompts | Text input with validation |
password | @inquirer/prompts | Masked input for tokens/secrets |
See references/prompt-patterns.md for full examples.
Reporter Patterns
Three main reporters in src/cli/reporters/:
| Reporter | Purpose | Key Output |
|---|
deployment-reporter | Deploy results | Table with created/updated/deleted/failed counts |
diff reporter | Diff results | + create (green), ~ update (blue), - delete (red) |
duplicate reporter | Validation issues | Duplicate identifiers with locations |
See references/reporter-patterns.md for full implementations.
Error Message Formatting
Two error formatters in the project:
formatError(error: BaseError): General errors with code, context, and suggestions
formatGraphQLError(error: GraphQLError): GraphQL-specific with operation name and path
Pattern: Show error message, then optional code/context in gray, then actionable suggestions via console.hint().
Exit Codes
export const ExitCodes = {
SUCCESS: 0,
GENERAL_ERROR: 1,
VALIDATION_ERROR: 2,
NETWORK_ERROR: 3,
AUTH_ERROR: 4,
CONFLICT_ERROR: 5,
} as const;
Always use named exit codes, never raw numbers.
Best Practices
- Use
src/cli/console.ts for all output (never raw console.log)
- Provide progress feedback for any operation over ~1 second
- Include actionable suggestions with every error message
- Confirm destructive operations with
confirm prompt
- Support non-interactive mode (skip prompts in CI/headless)
- Use consistent color semantics (green=success, red=error, yellow=warning)
Common Mistakes
| Mistake | Fix |
|---|
Using raw console.log | Import and use console from @/cli/console |
| Missing progress feedback | Add ora spinner for any async operation |
Raw exit codes (process.exit(1)) | Use ExitCodes.GENERAL_ERROR constants |
| Blocking prompts in CI | Check for --yes flag or CI env var to skip prompts |
| No suggestions on errors | Always add console.hint() with next steps |
| Debug output in production | Use tslog with appropriate log levels |
References
Related Skills
- Complete entity workflow: See
adding-entity-types for CLI integration patterns
- Error handling: See
reviewing-typescript-code for error message standards
Quick Reference Rule
For a condensed quick reference, see .claude/rules/cli-development.md (automatically loaded when editing src/cli/**/*.ts and src/commands/**/*.ts files).
Converted and distributed by TomeVault — claim your Tome and manage your conversions.