Tips & Tricks (Mis à jour: 02/06/2026)

Générer la documentation avec Claude Code : README, API, ADR et vérification

Générez README, OpenAPI, ADR et changelog avec Claude Code, puis vérifiez le résultat avec des scripts Node.

Générer la documentation avec Claude Code : README, API, ADR et vérification

Une documentation générée doit reposer sur des preuves

README, spécifications d’API, ADR et changelog prennent souvent du retard. Le développement avance, les scripts changent, les endpoints évoluent, mais la documentation reste dans l’état de la version précédente. Le jour où un nouveau membre rejoint l’équipe, il découvre que la commande indiquée ne marche plus.

Claude Code peut accélérer ce travail, car il lit le code, modifie des fichiers et exécute des commandes. La page officielle Claude Code overview présente justement cet usage dans le dépôt et les outils de développement. Mais il ne faut pas confondre rapidité et fiabilité. Sans preuve, Claude Code peut écrire une documentation fluide pour une commande inexistante ou une réponse API inventée.

La bonne approche consiste à fournir un contexte vérifiable, limiter la tâche à la documentation, puis contrôler le résultat. Cet article montre comment générer un README, une spécification OpenAPI, un ADR et un changelog avec Claude Code, puis comment les vérifier avec un script Node. Pour garder une trace de la validation, utilisez aussi le workflow de reçu de vérification Claude Code.

Le flux : contexte, génération, vérification, décision humaine

Demander simplement “améliore le README” laisse trop de place aux suppositions. Il faut d’abord définir les sources fiables : package.json, état git, commits récents, documentation existante et fichiers de code concernés.

flowchart LR
  A["Diff de code"] --> B["doc-context.mjs"]
  B --> C["Skill Claude Code"]
  C --> D["README / OpenAPI / ADR / CHANGELOG"]
  D --> E["verify-docs.mjs"]
  E --> F["Décision humaine"]

ADR signifie Architecture Decision Record : une courte note qui explique pourquoi une décision technique a été prise. OpenAPI décrit les routes, les corps de requête et les réponses dans un format vérifiable. L’objectif n’est pas de produire une documentation imposante, mais une documentation que l’on peut contrôler.

Créer un contexte de dépôt

Enregistrez ce fichier sous scripts/doc-context.mjs, puis lancez node scripts/doc-context.mjs à la racine du dépôt. Il génère docs/_generated/doc-context.md, un résumé destiné à Claude Code.

import { execSync } from "node:child_process";
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
import path from "node:path";

function run(command) {
  try {
    return execSync(command, {
      encoding: "utf8",
      stdio: ["ignore", "pipe", "pipe"],
    }).trim();
  } catch {
    return "";
  }
}

function readIfExists(filePath) {
  return existsSync(filePath) ? readFileSync(filePath, "utf8") : "";
}

const root = process.cwd();
const outDir = path.join(root, "docs", "_generated");
mkdirSync(outDir, { recursive: true });

const packageJson = readIfExists("package.json");
const packageSummary = packageJson
  ? JSON.stringify(JSON.parse(packageJson).scripts ?? {}, null, 2)
  : "{}";
const fence = String.fromCharCode(96, 96, 96);

const trackedFiles = run("git ls-files")
  .split(/\r?\n/)
  .filter(Boolean)
  .filter((file) => !file.startsWith("node_modules/"))
  .filter((file) => !file.startsWith("dist/"))
  .filter((file) => !file.startsWith(".git/"))
  .slice(0, 400);

const changedFiles = run("git status --short") || "(no uncommitted changes)";
const recentCommits = run("git log --oneline -8") || "(no commits found)";

const content = [
  "# Documentation Context",
  "",
  "## Package scripts",
  `${fence}json`,
  packageSummary,
  fence,
  "",
  "## Changed files",
  `${fence}text`,
  changedFiles,
  fence,
  "",
  "## Recent commits",
  `${fence}text`,
  recentCommits,
  fence,
  "",
  "## Tracked file sample",
  `${fence}text`,
  trackedFiles.join("\n"),
  fence,
  "",
].join("\n");

const outFile = path.join(outDir, "doc-context.md");
writeFileSync(outFile, content);
console.log(`Wrote ${outFile}`);

Ce fichier n’est pas une page publique. C’est un support de travail pour l’agent. Le séparer dans docs/_generated évite de mélanger les preuves temporaires avec la documentation rédigée pour les lecteurs.

Fixer la procédure dans un skill Claude Code

Claude Code permet de stocker des procédures répétables sous forme de skills. La documentation officielle skills and slash commands explique qu’un SKILL.md peut créer une commande comme /docs-refresh; les anciens fichiers .claude/commands/ restent utilisables.

Créez .claude/skills/docs-refresh/SKILL.md :

---
description: Refresh README, OpenAPI, ADR, and changelog from current code and generated documentation context.
---

## Inputs to inspect first

- Repository context: @docs/_generated/doc-context.md
- README: @README.md
- Existing docs: @docs
- Package metadata: @package.json

## Task

Update documentation only where the current code, package scripts, or git diff prove that the text is stale.

Required outputs:

1. README: setup steps, commands, environment notes, and troubleshooting.
2. OpenAPI: update `docs/api/openapi.yaml` when API routes changed.
3. ADR: create `docs/adr/NNNN-short-title.md` when a new architectural decision is visible.
4. CHANGELOG: add a draft entry under `Unreleased` when user-facing behavior changed.

Rules:

- Do not invent endpoints, commands, environment variables, prices, or dates.
- If evidence is missing, write a short "needs confirmation" note instead of guessing.
- Keep secret names generic. Never copy `.env` values into docs.
- After editing, run `node scripts/verify-docs.mjs` and report the result.

La limite “documentation only” est essentielle. Claude Code peut modifier le code, donc une tâche documentaire doit rester explicitement documentaire. En équipe, complétez cela avec une politique de permissions, par exemple avec le guide des permissions Claude Code.

Cas 1 : un README pour l’onboarding

Un README utile n’est pas une brochure. Il doit aider une personne qui vient de cloner le dépôt à installer, lancer, tester et diagnostiquer les erreurs courantes.

# Task API

## Getting started

```bash
npm ci
npm run dev
```

## Commands

| Command | Purpose |
| --- | --- |
| `npm run dev` | Start the local server |
| `npm run test` | Run unit tests |
| `npm run docs:context` | Generate documentation context |
| `npm run docs:verify` | Verify documentation files |

## Troubleshooting

- If install fails, delete `node_modules` and run `npm ci` again.
- If API examples fail, confirm the server is running on the documented port.
- If generated docs mention unknown env vars, check `.env.example`, not `.env`.

La consigne donnée à Claude Code doit préciser le lecteur : “nouveau contributeur après un clone du dépôt” produit un résultat plus concret que “rends le README plus clair”.

Cas 2 : une spécification API en OpenAPI

Pour une API, le texte libre ne suffit pas. Demandez à Claude Code de lire les routes, les schémas de validation et les tests, puis de mettre à jour docs/api/openapi.yaml.

openapi: 3.1.0
info:
  title: Task API
  version: 0.1.0
  description: API for creating and listing tasks.
paths:
  /api/tasks:
    get:
      summary: List tasks
      responses:
        "200":
          description: Task list
          content:
            application/json:
              schema:
                type: object
                properties:
                  tasks:
                    type: array
                    items:
                      type: object
                      required: [id, title, status]
                      properties:
                        id:
                          type: string
                        title:
                          type: string
                        status:
                          type: string
                          enum: [todo, doing, done]
    post:
      summary: Create a task
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [title]
              properties:
                title:
                  type: string
      responses:
        "201":
          description: Created task

Le piège est la surcomplétion. Une spécification élégante mais fausse est pire qu’une spécification incomplète. Les champs incertains doivent rester à confirmer.

Cas 3 : un ADR pour garder la raison

Un ADR ne doit pas répéter la liste des tâches. Il doit documenter une décision, son contexte et ses conséquences.

# ADR-0001: Keep generated documentation under docs/_generated

## Status

Accepted

## Context

Claude Code needs a compact summary of the repository before refreshing documentation.
Putting generated context beside hand-written docs can confuse reviewers.

## Decision

Generated context files will be written to `docs/_generated/`.
Hand-written documentation stays in `docs/api`, `docs/adr`, and root README files.

## Consequences

- Reviewers can separate generated context from authored documentation.
- The context file can be regenerated before each documentation refresh.
- The verification script must ignore unstable generated content when checking prose quality.

Claude Code peut rédiger le brouillon, mais la décision finale appartient à l’équipe. Sinon, l’ADR devient une explication plausible sans valeur de gouvernance.

Cas 4 : un changelog en brouillon

Le changelog se rédige mieux avant le jour de release. Placez les entrées sous Unreleased et ne laissez pas Claude Code fixer une version ou une date non confirmée.

# Changelog

## Unreleased

### Added

- Added documentation context generation for README, API specs, ADRs, and changelog updates.

### Changed

- Updated the documentation refresh workflow to verify generated files before publication.

### Needs confirmation

- Confirm the final release version and release date before moving this entry out of `Unreleased`.

Cette forme garde l’information sans prétendre que la sortie a déjà eu lieu.

Vérifier les fichiers générés

Enregistrez ce script sous scripts/verify-docs.mjs. Il vérifie les fichiers obligatoires, les phrases clés, les titres ADR, les fences Markdown et les placeholders évidents.

import { existsSync, readdirSync, readFileSync } from "node:fs";
import path from "node:path";

const requiredFiles = [
  {
    file: "README.md",
    phrases: ["## Getting started", "## Commands"],
  },
  {
    file: "docs/api/openapi.yaml",
    phrases: ["openapi: 3.", "paths:"],
  },
  {
    file: "CHANGELOG.md",
    phrases: ["## Unreleased"],
  },
];

function read(file) {
  return readFileSync(file, "utf8");
}

function listMarkdownFiles(dir) {
  if (!existsSync(dir)) return [];
  return readdirSync(dir, { withFileTypes: true }).flatMap((entry) => {
    const fullPath = path.join(dir, entry.name);
    if (entry.isDirectory()) return listMarkdownFiles(fullPath);
    return entry.isFile() && /\.(md|mdx)$/.test(entry.name) ? [fullPath] : [];
  });
}

const errors = [];

for (const item of requiredFiles) {
  if (!existsSync(item.file)) {
    errors.push(`${item.file}: missing file`);
    continue;
  }

  const source = read(item.file);
  for (const phrase of item.phrases) {
    if (!source.includes(phrase)) {
      errors.push(`${item.file}: missing phrase "${phrase}"`);
    }
  }
}

for (const adr of listMarkdownFiles("docs/adr")) {
  const source = read(adr);
  for (const heading of ["## Status", "## Context", "## Decision", "## Consequences"]) {
    if (!source.includes(heading)) {
      errors.push(`${adr}: missing ${heading}`);
    }
  }
}

for (const file of ["README.md", "CHANGELOG.md", ...listMarkdownFiles("docs")]) {
  if (!existsSync(file)) continue;
  const source = read(file);
  const fenceMarker = String.fromCharCode(96, 96, 96);
  const fenceCount = (source.match(new RegExp(fenceMarker, "g")) ?? []).length;
  if (fenceCount % 2 !== 0) errors.push(`${file}: unbalanced code fence`);
  if (/TODO|TBD|REPLACE_ME/.test(source)) {
    errors.push(`${file}: unresolved placeholder remains`);
  }
}

if (errors.length > 0) {
  console.error("Documentation verification failed:");
  for (const error of errors) console.error(`- ${error}`);
  process.exit(1);
}

console.log("Documentation verification passed.");

Ajoutez les scripts au package.json :

{
  "scripts": {
    "docs:context": "node scripts/doc-context.mjs",
    "docs:verify": "node scripts/verify-docs.mjs"
  }
}

La documentation officielle settings explique comment séparer configuration projet et configuration locale. Un point de départ simple consiste à autoriser les scripts de documentation et refuser les secrets.

{
  "$schema": "https://json.schemastore.org/claude-code-settings.json",
  "permissions": {
    "allow": [
      "Bash(node scripts/doc-context.mjs)",
      "Bash(node scripts/verify-docs.mjs)",
      "Read(README.md)",
      "Read(docs/**)",
      "Read(src/**)"
    ],
    "deny": [
      "Read(.env)",
      "Read(.env.*)",
      "Read(secrets/**)",
      "Bash(curl *)"
    ]
  }
}

Pour automatiser après édition, consultez aussi la référence officielle des hooks. Commencez manuellement, puis automatisez seulement les vérifications qui doivent réellement bloquer.

Pièges fréquents

Premier piège : documenter une commande inexistante. Le README doit être ancré dans package.json, Makefile ou CI.

Deuxième piège : inventer le comportement de l’API. Une OpenAPI propre mais fausse crée plus de support qu’elle n’en évite.

Troisième piège : exposer des secrets. .env, tokens, noms de clients et URL internes ne doivent pas être lus ni recopiés.

Quatrième piège : publier le contexte généré. docs/_generated/doc-context.md est une entrée pour Claude Code, pas une page utilisateur.

Cinquième piège : vérifier trop tard. Exécutez docs:context et docs:verify tant que le diff reste petit.

Templates, produits et accompagnement

Pour un projet personnel, les deux scripts Node et le skill docs-refresh suffisent pour démarrer. Pour des consignes persistantes, combinez ce flux avec le guide CLAUDE.md best practices.

Pour garder les commandes de vérification sous la main, commencez par la fiche gratuite Claude Code. Si vous répétez chaque semaine les prompts README, revue, debug et documentation, un pack de templates Gumroad fait gagner du temps.

En équipe, la vraie difficulté est de décider qui valide, quelles erreurs bloquent la publication et comment vérifier les CTA Gumroad ou consultation. Pour cela, la consultation d’implémentation permet de construire les règles autour de votre dépôt réel.

Résultat de mon essai

J’ai testé ce flux en générant doc-context.md, puis en séparant README, OpenAPI, ADR et CHANGELOG avant de lancer verify-docs.mjs. Par rapport à une demande vague de README, les commandes inventées diminuent et les ADR restent plus faciles à relire. Les spécifications API doivent encore être comparées aux vraies réponses. Le bon objectif n’est donc pas une documentation entièrement automatique, mais une documentation rapide, fondée sur des preuves et arrêtée par une vérification claire.

#Claude Code #documentation #JSDoc #API specs #auto-generation
Gratuit

PDF gratuit: cheatsheet Claude Code

Saisissez votre email et téléchargez une page avec commandes, habitudes de review et workflow sûr.

Nous protégeons vos données et n'envoyons pas de spam.

Masa

À propos de l'auteur

Masa

Ingénieur spécialisé dans les workflows pratiques avec Claude Code.