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.
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.
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.
À propos de l'auteur
Masa
Ingénieur spécialisé dans les workflows pratiques avec Claude Code.
Articles liés
Échelle de sécurité des permissions Claude Code
Passer du read-only aux éditions limitées, preuves et checks de déploiement sans perdre le contrôle.
Claude Code Small PR Proof Pack : rendre les petits changements reviewables
Un pack de preuve pour PR Claude Code : diff, vérifications, URL publique, CTA et rollback.
Gate de review avant commit avec Claude Code
Review avant commit avec Claude Code : diff, build, URL publique, liens Gumroad, CTA consultation, tests manquants et fichiers hors scope.