Skip to main content

nachui-cli-development

figueroaignacio/ui-skills · View source

$npx skills add github:figueroaignacio/ui-skills/skills/nachui-cli-development

Triggers when: “Use when modifying or extending CLI commands, prompts, build configurations, or API integrations in packages/cli.”

NachUI CLI Development Guide

You are modifying or expanding the official NachUI Command Line Interface (packages/cli). The CLI uses Commander for commands, Clack for prompts, and Kleur for console styling.

Directory Structure

  • src/index.ts: The CLI entry point that configures Commander and routes arguments.
  • src/commands/: Individual command implementations:
    • init.ts: Installs config files and prepares a workspace for NachUI.
    • add.ts: Downloads and adds primitives to the user's workspace.
    • list.ts: Lists available components in the registry.
    • update.ts: Updates local component files matching registry versions.
    • remove.ts: Safely cleans up installed components from a workspace.
  • src/lib/: Common utilities:
    • api.ts: Registry fetching and API requests.
    • package-manager.ts: Logic to detect the user's package manager (npm, pnpm, yarn, bun).

Development and Compilation Commands

Always run CLI build and check scripts from the root directory using workspace filters:
1# Run typescript type check
2pnpm --filter @repo/cli type-check
3
4# Compile CLI into dist using tsup (generates ESM/CJS bundles)
5pnpm --filter @repo/cli build
6
7# Start compiler in watch mode for development
8pnpm --filter @repo/cli dev

Designing CLI Commands with Commander

New commands must be added to the Commander instance in src/index.ts and their logic defined under src/commands/.
1import { Command } from 'commander';
2
3const program = new Command();
4
5program.name('nachui').description('Official CLI for NachUI').version('1.0.0');
6
7program
8 .command('my-command')
9 .description('Explain command actions')
10 .argument('[arg]', 'Optional command argument')
11 .option('-f, --force', 'Force execution')
12 .action(async (arg, options) => {
13 // Import execution logic dynamically to keep startup fast
14 const { myCommandAction } = await import('./commands/my-command');
15 await myCommandAction(arg, options);
16 });

Console Prompts & UI Style Guide (Clack & Kleur)

When designing user-facing console interfaces:
  1. Always wrap interactions in Clack's intro() and outro() statements.
  2. Use spinners for any network operations (e.g. fetching registry, downloading files).
  3. Use Kleur for text styling and colors:
    • Info / Dim: Use kleur.dim() for secondary advice or descriptions.
    • Success: Use kleur.green() or kleur.cyan().
    • Errors / Warnings: Use kleur.red() for failure states.
1import * as p from '@clack/prompts';
2import kleur from 'kleur';
3
4export async function myCommandAction() {
5 p.intro(kleur.cyan('NachUI Command'));
6
7 const result = await p.text({
8 message: 'Enter input details:',
9 placeholder: 'e.g., button',
10 validate: (value) => {
11 if (!value) return 'Value is required!';
12 },
13 });
14
15 if (p.isCancel(result)) {
16 p.cancel('Operation cancelled.');
17 process.exit(0);
18 }
19
20 const s = p.spinner();
21 s.start('Running task...');
22 // do work
23 s.stop(kleur.green('Task complete!'));
24
25 p.outro(kleur.cyan('Done!'));
26}

Error Handling & Cancellation Safety

  • Always handle p.isCancel(value) checks after every Clack prompt to exit cleanly when a user presses Ctrl+C.
  • Gracefully catch and log errors using kleur.red() before terminating the process with a non-zero exit code (process.exit(1)).
  • Do not leave orphaned file-write operations or incomplete configurations if a command crashes halfway.