Skip to content
CLI Design logo

CLI Design

Design patterns and conventions for the vm0 CLI user experience

SKILL.md

Full skill instructions

CLI Design Skill

This skill defines the design patterns and conventions for the vm0 CLI. These patterns ensure a consistent, professional user experience across all commands.

When to Use This Skill

Use this skill when:

  • Writing new CLI commands
  • Reviewing CLI code in pull requests
  • Fixing inconsistencies in existing commands
  • Understanding CLI output conventions

Quick Reference

Symbols

SymbolColorUsage
✓chalk.greenSuccess, completion
✗chalk.redError, failure
⚠chalk.yellowWarning, deprecation
▶chalk.boldOperation started

Colors

ColorUsageExample
chalk.red()Errors✗ Not authenticated
chalk.green()Success✓ Created successfully
chalk.yellow()Warnings⚠ Field deprecated
chalk.cyan()Commands, codevm0 auth login
chalk.dim()Secondary infoTimestamps, hints
chalk.bold()Headers▶ Run started

Message Patterns

// Success
console.log(chalk.green(`✓ Created: ${name}`));

// Error
console.error(chalk.red(`✗ Not found: ${name}`));
console.error(chalk.dim("  Run: vm0 auth login"));

// Warning
console.log(chalk.yellow(`⚠ Field deprecated`));

// Empty state
console.log(chalk.dim("No items found"));

// Commands/​code examples
console.log(chalk.cyan("  vm0 compose <file>"));

The Five Rules

1. Use Unicode Symbols, Not ASCII

// ✅ Correct
console.error(chalk.red("✗ Failed"));
console.log(chalk.green("✓ Success"));

// ❌ Wrong
console.error(chalk.red("x Failed"));
console.error(chalk.red("Error: Failed"));

2. Two-Space Indentation for Details

console.error(chalk.red("✗ Operation failed"));
console.error(chalk.dim("  Details here"));      // 2 spaces
console.error(chalk.dim("  Run: vm0 help"));     // 2 spaces

3. No Periods in Messages

// ✅ Correct
console.log(chalk.dim("No items found"));
console.log(chalk.dim("Cancelled"));

// ❌ Wrong
console.log(chalk.dim("No items found."));
console.log(chalk.dim("Cancelled."));

4. Use Shared Utilities

// ✅ Correct - use shared utilities
import { formatBytes } from "../​../​lib/​utils/​file-utils";
import { promptConfirm } from "../​../​lib/​utils/​prompt-utils";

// ❌ Wrong - local implementations
function formatBytes(bytes: number) { ... }  // Duplicate!

5. Check Interactive Mode

import { isInteractive, promptText } from "../​../​lib/​utils/​prompt-utils";

if (options.name) {
  name = options.name;
} else if (!isInteractive()) {
  console.error(chalk.red("✗ --name required in non-interactive mode"));
  process.exit(1);
} else {
  name = await promptText("Enter name");
}

Detailed Guidelines

For comprehensive patterns and examples:

  • Colors & Symbols → Read colors.md
  • Output Formatting → Read output.md
  • Interactive Prompts → Read prompts.md
  • Error Handling → Read errors.md
  • Tables → Read tables.md

Common Violations

Wrong Error Symbol

// ❌ Wrong (lowercase x)
console.error(chalk.red("x Invalid input"));
console.error(chalk.red("Error: Invalid input"));

// ✅ Correct (Unicode ✗)
console.error(chalk.red("✗ Invalid input"));

Wrong Success Format

// ❌ Wrong
console.log(chalk.green("Done Created item"));

// ✅ Correct
console.log(chalk.green("✓ Created item"));

Custom Confirmation

// ❌ Wrong - custom readline
const rl = readline.createInterface({ ... });
rl.question("Confirm? (y/​N)", (answer) => { ... });

// ✅ Correct - use shared utility
import { promptConfirm } from "../​../​lib/​utils/​prompt-utils";
const confirmed = await promptConfirm("Confirm?");

Duplicate Utilities

// ❌ Wrong - local formatBytes
function formatBytes(bytes: number): string {
  // ... implementation
}

// ✅ Correct - import shared
import { formatBytes } from "../​../​lib/​utils/​file-utils";

File Locations

Shared Utilities

  • lib/​utils/​prompt-utils.ts - Interactive prompts
  • lib/​utils/​file-utils.ts - formatBytes, formatRelativeTime
  • lib/​events/​event-renderer.ts - Run event rendering

Example Commands

  • commands/​agent/​list.ts - Table output
  • commands/​init.ts - Interactive prompts
  • commands/​compose.ts - Complex workflow
  • commands/​credential/​set.ts - Error handling