Dokumentation mit Claude Code generieren: README, API, ADR und Prüfung
Erzeuge README, OpenAPI, ADR und Changelog mit Claude Code und prüfe alles mit praktischen Node-Skripten.
Generierte Dokumentation braucht Belege
README, API-Spezifikation, ADR und Changelog altern oft schneller als der Code. Neue Features werden gebaut, Scripts werden umbenannt, Endpoints ändern sich, aber die Dokumentation bleibt auf dem alten Stand. Für neue Teammitglieder oder API-Nutzer ist das besonders teuer, weil sie zuerst der Dokumentation vertrauen.
Claude Code kann diesen Aufwand stark reduzieren. Die offizielle Seite Claude Code overview beschreibt Claude Code als Werkzeug, das Code liest, Dateien bearbeitet und Befehle ausführt. Genau deshalb darf man das Ergebnis aber nicht blind übernehmen. Ohne Belege kann Claude Code einen nicht existierenden Befehl oder eine erfundene API-Antwort sehr überzeugend dokumentieren.
Der bessere Ablauf lautet: zuerst belegbaren Repository-Kontext erzeugen, dann eine eng begrenzte Dokumentationsaufgabe ausführen, danach maschinell prüfen und erst dann veröffentlichen. Für die finale Nachweiskette passt dazu der Artikel zum Claude Code Verification Receipt Workflow.
Ablauf: Kontext, Generierung, Prüfung, Entscheidung
Die Anfrage “Verbessere das README” ist zu offen. Claude Code braucht klare Quellen: package.json, Git-Diff, aktuelle Commits, vorhandene Dokumente und relevante Codepfade.
flowchart LR
A["Code-Diff"] --> B["doc-context.mjs"]
B --> C["Claude Code Skill"]
C --> D["README / OpenAPI / ADR / CHANGELOG"]
D --> E["verify-docs.mjs"]
E --> F["Menschliche Entscheidung"]
ADR steht für Architecture Decision Record, also eine kurze Notiz darüber, warum eine technische Entscheidung getroffen wurde. OpenAPI beschreibt API-Routen, Requests und Responses in einem prüfbaren Format. Für Einsteiger reicht am Anfang eine kleine, korrekte Spezifikation. Vollständigkeit ist weniger wichtig als Verifizierbarkeit.
Repository-Kontext erzeugen
Speichere den folgenden Code als scripts/doc-context.mjs und führe node scripts/doc-context.mjs im Repository aus. Das Skript schreibt docs/_generated/doc-context.md, eine kompakte Arbeitsgrundlage für 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}`);
Diese Datei ist nicht für Leser gedacht. Sie ist Eingabe für den Agenten. Der Ordner docs/_generated trennt temporären Kontext von bewusst geschriebener Dokumentation.
Einen Skill für Dokumentations-Updates anlegen
Claude Code nutzt Skills für wiederholbare Abläufe. Die offizielle Dokumentation zu skills und slash commands erklärt, wie ein SKILL.md einen Befehl wie /docs-refresh bereitstellt. Bestehende .claude/commands/ funktionieren weiterhin, aber Skills sind der robustere Weg.
Lege .claude/skills/docs-refresh/SKILL.md an:
---
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.
“Documentation only” ist hier entscheidend. Claude Code kann auch Implementierungscode ändern; bei einer reinen Dokumentationsaufgabe sollte das ausgeschlossen sein. Für Teams lohnt sich zusätzlich ein Blick in den Claude Code Permissions Guide.
Beispiel 1: README als Onboarding-Runbook
Ein gutes README ist kein Werbetext. Es beantwortet für jemanden nach dem ersten Clone: Installation, Start, Tests, häufige Fehler und nächste Dokumente.
# 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`.
Formuliere die Aufgabe also nicht als “mach es klarer”, sondern als “schreibe für eine Person, die das Repository gerade frisch geklont hat”.
Beispiel 2: API-Spezifikation mit OpenAPI
Freitext-Dokumentation für APIs ist schwer zu prüfen. Lass Claude Code Routen, Validierung und Tests lesen und daraus docs/api/openapi.yaml aktualisieren.
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
Der typische Fehler ist Übervervollständigung. Wenn der Server open liefert, die Spezifikation aber todo schreibt, wirkt sie gut und ist trotzdem falsch.
Beispiel 3: ADR für Entscheidungen
Ein ADR ist kein Tätigkeitsbericht. Es hält Entscheidung, Kontext und Folgen fest.
# 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 kann den Entwurf liefern. Die Begründung muss das Team prüfen, weil der ADR später als gemeinsame Entscheidung gelesen wird.
Beispiel 4: Changelog unter Unreleased
Changelogs sollten nicht erst am Release-Tag entstehen. Lass Claude Code Einträge unter Unreleased entwerfen und Version sowie Datum offen lassen.
# 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`.
So bleiben Informationen erhalten, ohne einen Release vorzutäuschen.
Generierte Dokumentation prüfen
Speichere dieses Skript als scripts/verify-docs.mjs. Es prüft Pflichtdateien, Pflichtphrasen, ADR-Struktur, Code-Fences und offensichtliche Platzhalter.
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.");
Ergänze package.json:
{
"scripts": {
"docs:context": "node scripts/doc-context.mjs",
"docs:verify": "node scripts/verify-docs.mjs"
}
}
Die offizielle settings documentation zeigt, wie Projekt- und lokale Einstellungen getrennt werden. Ein einfacher Start erlaubt die Dokumentationsskripte und sperrt 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 *)"
]
}
}
Wenn du später automatische Prüfungen nach Dateiänderungen möchtest, lies die offizielle hooks reference. Starte manuell und automatisiere erst, wenn klar ist, welche Fehler wirklich blockieren sollen.
Häufige Fehler
Erster Fehler: erfundene Befehle. README-Kommandos müssen aus package.json, Makefile oder CI stammen.
Zweiter Fehler: erfundene API-Antworten. Eine schöne, aber falsche OpenAPI-Datei ist gefährlicher als eine unvollständige.
Dritter Fehler: Secrets in der Dokumentation. .env, Tokens, Kundennamen und interne URLs gehören nicht in generierte Docs.
Vierter Fehler: internen Kontext veröffentlichen. docs/_generated/doc-context.md ist Agenteninput, keine Nutzerseite.
Fünfter Fehler: Prüfung zu spät ausführen. Nutze docs:context und docs:verify, solange der Diff klein ist.
Templates, Produkte und Beratung
Für ein Einzelprojekt reichen die zwei Node-Skripte und der Skill docs-refresh. Für dauerhafte Projektregeln kombiniere den Ablauf mit dem CLAUDE.md Best Practices Guide.
Als leichter nächster Schritt hilft das kostenlose Claude Code Cheatsheet. Wenn du jede Woche README-, Review-, Debug- und Dokumentationsprompts wiederholst, spart ein Gumroad-Templatepaket Zeit.
Im Team ist die eigentliche Frage, wer freigibt, welche Dokumentationsfehler einen Release stoppen und wie Gumroad- oder Beratungs-CTAs geprüft werden. Dafür ist eine Einführungsberatung sinnvoller als eine allgemeine Vorlage.
Ergebnis meines Tests
Ich habe diesen Ablauf mit doc-context.md, getrennten Aufgaben für README, OpenAPI, ADR und CHANGELOG sowie verify-docs.mjs ausprobiert. Im Vergleich zu einem allgemeinen README-Prompt gab es weniger falsche Befehle, und ADRs blieben leichter prüfbar. API-Spezifikationen müssen weiterhin mit echten Responses abgeglichen werden. Das Ziel ist nicht vollautomatische Dokumentation, sondern schnelle Dokumentation mit sichtbaren Belegen und klarer Prüfstelle.
Kostenloses PDF: Claude-Code-Cheatsheet
E-Mail eintragen und eine Seite mit Befehlen, Review-Gewohnheiten und sicheren Workflows herunterladen.
Wir schützen Ihre Daten und senden keinen Spam.
Über den Autor
Masa
Engineer für praktische Claude-Code-Workflows und Team-Einführung.
Ähnliche Artikel
Claude Code Permission Safety Ladder: Zugriff kontrolliert erweitern
Von read-only zu begrenzten Änderungen, Prüfbefehlen und Deploy-Checks mit klarer Kontrolle.
Claude Code Small PR Proof Pack: kleine Änderungen reviewbar machen
Ein Proof Pack für Claude-Code-PRs: Diff, Checks, öffentliche URL, CTA-Pfad und Rollback.
Claude-Code-Review-Gate vor dem Commit
Vor dem Commit mit Claude Code prüfen: Diff, Build, öffentliche URL, Gumroad-Links, Beratung-CTA, fehlende Tests und fremde Dateien.