Use Cases

Como desarrollar herramientas CLI con Claude Code

Aprende a desarrollar herramientas CLI usando Claude Code. Incluye ejemplos de codigo practicos y guia paso a paso.

Acelerando el desarrollo de herramientas CLI con Claude Code

Cuando quieres crear tu propia herramienta CLI, Claude Code es el companero ideal. Desde el parseo de argumentos, el diseno de subcomandos hasta la entrada/salida interactiva, solo necesitas describir que tipo de CLI quieres y se implementa automaticamente.

Estructura inicial del proyecto

> Crea un proyecto de herramienta CLI en TypeScript.
> Parsea argumentos con Commander, y configura ESLint y Prettier.
> Que se pueda ejecutar con npx ts-node src/index.ts.

Parseo de argumentos y subcomandos

Estructura basica de CLI usando Commander.

#!/usr/bin/env node
import { Command } from "commander";
import { version } from "../package.json";

const program = new Command();

program
  .name("mytool")
  .description("Herramienta CLI de gestion de proyectos")
  .version(version);

program
  .command("init")
  .description("Inicializar un proyecto")
  .option("-t, --template <name>", "Nombre de la plantilla", "default")
  .option("-d, --dir <path>", "Directorio de destino", ".")
  .action(async (options) => {
    console.log(`Inicializando con la plantilla "${options.template}"...`);
    await initProject(options.template, options.dir);
    console.log("Completado!");
  });

program
  .command("generate <type> <name>")
  .alias("g")
  .description("Generar archivos (component, hook, page)")
  .option("--dry-run", "Previsualizar sin crear archivos realmente")
  .action(async (type, name, options) => {
    if (options.dryRun) {
      console.log(`[dry-run] Se generara ${type} "${name}"`);
      return;
    }
    await generateFile(type, name);
  });

program
  .command("check")
  .description("Verificar el estado del proyecto")
  .action(async () => {
    await runHealthCheck();
  });

program.parse();

Entrada interactiva

Implementacion de entrada interactiva usando la biblioteca Inquirer.

import inquirer from "inquirer";
import chalk from "chalk";

interface ProjectConfig {
  name: string;
  framework: string;
  features: string[];
  packageManager: string;
}

async function interactiveInit(): Promise<ProjectConfig> {
  const answers = await inquirer.prompt([
    {
      type: "input",
      name: "name",
      message: "Nombre del proyecto:",
      validate: (input: string) =>
        /^[a-z0-9-]+$/.test(input) || "Solo se permiten letras minusculas, numeros y guiones",
    },
    {
      type: "list",
      name: "framework",
      message: "Framework:",
      choices: ["React", "Next.js", "Astro", "Vue"],
    },
    {
      type: "checkbox",
      name: "features",
      message: "Funcionalidades adicionales:",
      choices: [
        { name: "TypeScript", checked: true },
        { name: "ESLint", checked: true },
        { name: "Prettier", checked: true },
        { name: "Testing (Vitest)" },
        { name: "CI/CD (GitHub Actions)" },
      ],
    },
    {
      type: "list",
      name: "packageManager",
      message: "Gestor de paquetes:",
      choices: ["npm", "pnpm", "yarn"],
    },
  ]);

  console.log(chalk.green("\nConfiguracion:"));
  console.log(chalk.cyan(`  Nombre del proyecto: ${answers.name}`));
  console.log(chalk.cyan(`  Framework: ${answers.framework}`));
  console.log(chalk.cyan(`  Funcionalidades: ${answers.features.join(", ")}`));

  return answers;
}

Barra de progreso y spinner

Muestra visualmente el progreso del procesamiento.

import ora from "ora";
import cliProgress from "cli-progress";

async function processFiles(files: string[]) {
  const bar = new cliProgress.SingleBar({
    format: "Procesando |{bar}| {percentage}% | {value}/{total} archivos",
    barCompleteChar: "█",
    barIncompleteChar: "░",
  });

  bar.start(files.length, 0);

  for (const file of files) {
    await processFile(file);
    bar.increment();
  }

  bar.stop();
  console.log(chalk.green("Se completaron todos los archivos!"));
}

async function installDependencies(packages: string[]) {
  const spinner = ora("Instalando dependencias...").start();

  try {
    await execAsync(`npm install ${packages.join(" ")}`);
    spinner.succeed("Instalacion de dependencias completada");
  } catch (error) {
    spinner.fail("La instalacion fallo");
    throw error;
  }
}

Implementacion de tests

Tambien puedes pedir a Claude Code que escriba los tests de la herramienta CLI.

import { describe, it, expect } from "vitest";
import { execSync } from "child_process";

describe("mytool CLI", () => {
  it("puede mostrar la version", () => {
    const output = execSync("npx ts-node src/index.ts --version").toString();
    expect(output.trim()).toMatch(/^\d+\.\d+\.\d+$/);
  });

  it("puede mostrar la ayuda", () => {
    const output = execSync("npx ts-node src/index.ts --help").toString();
    expect(output).toContain("Herramienta CLI de gestion de proyectos");
    expect(output).toContain("init");
    expect(output).toContain("generate");
  });

  it("muestra error con un comando inexistente", () => {
    expect(() => {
      execSync("npx ts-node src/index.ts unknown 2>&1");
    }).toThrow();
  });
});

Para publicar como paquete npm, consulta publicacion de paquetes npm. Para el uso basico de Claude Code, consulta la guia de inicio, y para consejos de productividad, consulta los 10 tips para triplicar tu productividad.

Resumen

Con Claude Code, puedes desarrollar en poco tiempo herramientas CLI completas que incluyen parseo de argumentos, entrada interactiva, visualizacion de progreso y tests. Solo necesitas describir en lenguaje natural que comando necesitas para obtener una herramienta funcional.

Para mas informacion, consulta la documentacion oficial de Claude Code.

#Claude Code #CLI #Node.js #Commander #development tools