Use Cases

Comment développer des outils CLI avec Claude Code

Apprenez à développer des outils CLI avec Claude Code. Exemples de code pratiques et instructions étape par étape inclus.

Accélérer le développement d’outils CLI avec Claude Code

Quand vous souhaitez créer votre propre outil CLI, Claude Code est le partenaire idéal. Du parsing des arguments à la conception des sous-commandes, en passant par les entrées/sorties interactives, il suffit de décrire le CLI souhaité pour obtenir une implémentation.

Configuration initiale du projet

> Crée un projet d'outil CLI en TypeScript.
> Parse les arguments avec commander, configure eslint et prettier.
> Le rendre exécutable avec npx ts-node src/index.ts.

Parsing des arguments et sous-commandes

Structure de base d’un CLI utilisant Commander.

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

const program = new Command();

program
  .name("mytool")
  .description("Outil CLI de gestion de projet")
  .version(version);

program
  .command("init")
  .description("Initialiser un projet")
  .option("-t, --template <name>", "Nom du modèle", "default")
  .option("-d, --dir <path>", "Répertoire de destination", ".")
  .action(async (options) => {
    console.log(`Initialisation avec le modèle « ${options.template} »...`);
    await initProject(options.template, options.dir);
    console.log("Terminé !");
  });

program
  .command("generate <type> <name>")
  .alias("g")
  .description("Générer un fichier (component, hook, page)")
  .option("--dry-run", "Prévisualiser sans créer de fichiers")
  .action(async (type, name, options) => {
    if (options.dryRun) {
      console.log(`[dry-run] Génération de ${type} « ${name} »`);
      return;
    }
    await generateFile(type, name);
  });

program
  .command("check")
  .description("Vérifier l'état du projet")
  .action(async () => {
    await runHealthCheck();
  });

program.parse();

Saisie interactive

Implémentation de la saisie interactive avec la bibliothèque 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: "Nom du projet :",
      validate: (input: string) =>
        /^[a-z0-9-]+$/.test(input) || "Seuls les lettres minuscules, chiffres et tirets sont autorisés",
    },
    {
      type: "list",
      name: "framework",
      message: "Framework :",
      choices: ["React", "Next.js", "Astro", "Vue"],
    },
    {
      type: "checkbox",
      name: "features",
      message: "Fonctionnalités supplémentaires :",
      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: "Gestionnaire de paquets :",
      choices: ["npm", "pnpm", "yarn"],
    },
  ]);

  console.log(chalk.green("\nConfiguration :"));
  console.log(chalk.cyan(`  Nom du projet : ${answers.name}`));
  console.log(chalk.cyan(`  Framework : ${answers.framework}`));
  console.log(chalk.cyan(`  Fonctionnalités : ${answers.features.join(", ")}`));

  return answers;
}

Barre de progression et spinner

Affichage visuel de la progression du traitement.

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

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

  bar.start(files.length, 0);

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

  bar.stop();
  console.log(chalk.green("Traitement de tous les fichiers terminé !"));
}

async function installDependencies(packages: string[]) {
  const spinner = ora("Installation des dépendances...").start();

  try {
    await execAsync(`npm install ${packages.join(" ")}`);
    spinner.succeed("Installation des dépendances terminée");
  } catch (error) {
    spinner.fail("L'installation a échoué");
    throw error;
  }
}

Implémentation des tests

Les tests d’outils CLI peuvent aussi être demandés à Claude Code.

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

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

  it("peut afficher l'aide", () => {
    const output = execSync("npx ts-node src/index.ts --help").toString();
    expect(output).toContain("Outil CLI de gestion de projet");
    expect(output).toContain("init");
    expect(output).toContain("generate");
  });

  it("renvoie une erreur pour une commande inexistante", () => {
    expect(() => {
      execSync("npx ts-node src/index.ts unknown 2>&1");
    }).toThrow();
  });
});

Pour publier en tant que package npm, consultez Publication de packages npm. Pour les bases de Claude Code, consultez le guide de démarrage, et pour les astuces de productivité, consultez 10 astuces pour tripler votre productivité.

Résumé

Avec Claude Code, vous pouvez développer en peu de temps un outil CLI complet incluant le parsing des arguments, la saisie interactive, l’affichage de progression et les tests. Il suffit de décrire en langage naturel la commande souhaitée pour obtenir un outil fonctionnel immédiatement.

Pour plus de détails, consultez la documentation officielle de Claude Code.

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