Project 23: Documentation Generator (Auto-Docs on Commit)
Build a hook system that automatically generates or updates documentation when code changes - keeping docs in sync with implementation forever.
Learning Objectives
By completing this project, you will:
- Understand documentation debt and why it accumulates in software projects
- Master git diff analysis to detect meaningful code changes
- Implement incremental documentation updates rather than full rewrites
- Design multi-target documentation (JSDoc, README, CHANGELOG)
- Apply steering rules to maintain consistent documentation style
Deep Theoretical Foundation
The Documentation Debt Problem
Documentation is one of the first casualties of tight deadlines:
Documentation Debt Accumulation:
Week 1: Week 4: Week 12: Week 52:
┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐
│Code │ │Code │ │Code │ │Code │
│ 100%│ │ 400%│ │1200%│ │5200%│
├─────┤ ├─────┤ ├─────┤ ├─────┤
│Docs │ │Docs │ │Docs │ │Docs │
│ 100%│ │ 110%│ │ 150%│ │ 200%│
└─────┘ └─────┘ └─────┘ └─────┘
Gap: 0% 72% 88% 96%
↑ ↑ ↑ ↑
Perfect Growing Critical Hopeless
Why this happens:
- Writing docs feels like “extra work”
- Code changes faster than docs can track
- No immediate feedback when docs are wrong
- Reviewers don’t read docs carefully
The AI Solution:
┌──────────────────────────────────────────────────────────────────┐
│ Code Change Event │
└──────────────────────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────────────┐
│ Documentation Generator │
│ ┌────────────────┐ ┌────────────────┐ ┌────────────────┐ │
│ │ Analyze Change │──│ Generate Docs │──│ Apply Updates │ │
│ └────────────────┘ └────────────────┘ └────────────────┘ │
└──────────────────────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────────────┐
│ Documentation Always in Sync │
└──────────────────────────────────────────────────────────────────┘
Git Diff Analysis
Understanding git diffs is essential for detecting what documentation needs updating:
Git Diff Anatomy:
diff --git a/src/services/user.ts b/src/services/user.ts
index 1234567..abcdefg 100644
--- a/src/services/user.ts ◄── Old file
+++ b/src/services/user.ts ◄── New file
@@ -10,6 +10,15 @@ class UserService { ◄── Hunk header
(line 10, 6 lines old
line 10, 15 lines new)
async create(data: CreateUserDto) {
- return this.db.insert(data); ◄── Removed line
+ // Validate email format ◄── Added lines
+ if (!isValidEmail(data.email)) {
+ throw new ValidationError('Invalid email');
+ }
+ return this.db.insert(data);
}
// New method added ◄── Entirely new section
+ async findByEmail(email: string): Promise<User | null> {
+ return this.db.findOne({ email });
+ }
Diff Classification:
Change Types for Documentation:
┌─────────────────────────────────────────────────────────────────┐
│ Change Type │ Documentation Impact │
├─────────────────┼───────────────────────────────────────────────┤
│ New function │ Generate new JSDoc, update README API section│
│ Changed params │ Update JSDoc @param, check README examples │
│ New class │ Create class documentation block │
│ Removed export │ Remove from API docs, add CHANGELOG entry │
│ Bug fix │ CHANGELOG entry only │
│ Refactor │ Usually no doc changes needed │
└─────────────────────────────────────────────────────────────────┘
Documentation Layers
Modern projects have multiple documentation layers, each serving different audiences:
Documentation Layer Hierarchy:
Layer 1: INLINE (for developers reading code)
┌─────────────────────────────────────────────────────────────────┐
│ /** │
│ * Creates a new user with the given data. │
│ * @param data - User creation payload │
│ * @param data.email - Must be unique in system │
│ * @returns The created user with generated ID │
│ * @throws {ValidationError} If email format is invalid │
│ * @example │
│ * const user = await service.create({ email: 'a@b.com' }); │
│ */ │
│ async create(data: CreateUserDto): Promise<User> │
└─────────────────────────────────────────────────────────────────┘
Layer 2: README (for new developers)
┌─────────────────────────────────────────────────────────────────┐
│ ## User Service │
│ │
│ Handles user CRUD operations. │
│ │
│ ### Methods │
│ - `create(data)` - Create new user │
│ - `findById(id)` - Find user by ID │
│ - `update(id, data)` - Update existing user │
│ │
│ ### Example │
│ ```typescript │
│ const service = new UserService(db); │
│ await service.create({ email: 'user@example.com' }); │
│ ``` │
└─────────────────────────────────────────────────────────────────┘
Layer 3: CHANGELOG (for users/stakeholders)
┌─────────────────────────────────────────────────────────────────┐
│ ## [1.2.0] - 2024-01-15 │
│ │
│ ### Added │
│ - User service now validates email format before creation │
│ - New `findByEmail()` method for email-based lookups │
│ │
│ ### Changed │
│ - `create()` now throws ValidationError for invalid emails │
└─────────────────────────────────────────────────────────────────┘
Layer 4: API REFERENCE (for API consumers)
┌─────────────────────────────────────────────────────────────────┐
│ Generated from JSDoc → TypeDoc/Docusaurus │
└─────────────────────────────────────────────────────────────────┘
Incremental vs. Full Generation
Regenerating all documentation on every change is wasteful and loses human edits:
Full Regeneration (BAD):
┌─────────────────────────────────────────────────────────────────┐
│ │
│ Change 1 line of code → Regenerate 500 lines of docs │
│ │
│ Problems: │
│ • Slow (processes everything) │
│ • Loses manual improvements │
│ • Churns git history │
│ • May introduce inconsistencies │
│ │
└─────────────────────────────────────────────────────────────────┘
Incremental Updates (GOOD):
┌─────────────────────────────────────────────────────────────────┐
│ │
│ Change 1 line of code → Update 3 lines of docs │
│ │
│ Benefits: │
│ • Fast (only processes changes) │
│ • Preserves human edits elsewhere │
│ • Minimal git diff │
│ • Maintains consistency │
│ │
└─────────────────────────────────────────────────────────────────┘
Incremental Update Strategy:
1. Parse old file → AST with existing docs
2. Parse new file → AST with current code
3. Diff the ASTs → Identify changed functions/classes
4. For each change:
- If doc exists: Update in place
- If new export: Generate new doc
- If removed: Flag for removal
5. Preserve unchanged documentation
JSDoc Standard
JSDoc is the de facto standard for JavaScript/TypeScript documentation:
JSDoc Tag Reference:
┌─────────────────┬────────────────────────────────────────────────┐
│ Tag │ Purpose │
├─────────────────┼────────────────────────────────────────────────┤
│ @param {Type} │ Document function parameter │
│ @returns {Type} │ Document return value │
│ @throws {Error} │ Document exceptions thrown │
│ @example │ Provide usage example │
│ @deprecated │ Mark as deprecated with reason │
│ @see │ Reference related documentation │
│ @since │ Version when added │
│ @async │ Indicate async function │
│ @private │ Mark as internal/private │
│ @public │ Mark as public API │
└─────────────────┴────────────────────────────────────────────────┘
Real-World Analogy: The Technical Writer Assistant
Imagine having a technical writer who:
- Watches over your shoulder as you code
- Notices every change you make
- Updates the manual section by section
- Tracks what’s new for the release notes
- Never gets tired or forgets to update
That’s what you’re building - an AI documentation assistant that never sleeps.
Historical Context
Documentation tooling has evolved significantly:
Documentation Evolution:
1980s: Manual (man pages, comments)
└─► Hand-written, easily outdated
1990s: JavaDoc/Doxygen
└─► Generate from structured comments
2000s: Wiki-style (Confluence, MediaWiki)
└─► Collaborative but disconnected from code
2010s: Docs-as-Code (Sphinx, MkDocs)
└─► Version controlled with code
2020s: AI-Assisted ◄─── YOU ARE HERE
└─► Auto-generated, always synchronized
Book References
For deeper understanding:
- “Docs Like Code” by Anne Gentle - Treating documentation as code
- “Living Documentation” by Cyrille Martraire - Documentation that evolves with code
- “The Art of Readable Code” by Boswell & Foucher - Self-documenting code principles
- “Technical Writing for Software Developers” by Chris Chinchilla - Professional tech writing
Complete Project Specification
What You Are Building
A hook-based documentation system that:
- Triggers on code changes via PostToolUse hooks
- Analyzes git diffs to understand what changed
- Updates inline documentation (JSDoc/TSDoc)
- Maintains README sections for API documentation
- Generates CHANGELOG entries for version tracking
Functional Requirements
| Feature | Behavior |
|---|---|
| JSDoc Generation | Add/update JSDoc for new/changed functions |
| README Updates | Keep API sections synchronized |
| CHANGELOG Entries | Generate entries for significant changes |
| Style Consistency | Follow project documentation conventions |
| Human Override | Never overwrite intentional human edits |
Non-Functional Requirements
- Latency: Complete documentation updates within 15 seconds
- Accuracy: Generated docs accurately describe the code
- Non-Destructive: Never lose existing manual documentation
- Configurable: Support different documentation styles
Solution Architecture
High-Level Component Diagram
┌─────────────────────────────────────────────────────────────────────┐
│ Kiro CLI │
│ ┌─────────────────────────────────────────────────────────────────┐│
│ │ Agent Session ││
│ │ ││
│ │ [Writes/modifies src/services/user.ts] ││
│ │ │ ││
│ └─────────┼────────────────────────────────────────────────────────┘│
└────────────┼────────────────────────────────────────────────────────┘
│ postToolUse event
▼
┌─────────────────────────────────────────────────────────────────────┐
│ Documentation Generator Hook │
│ │
│ ┌───────────────┐ ┌───────────────┐ ┌───────────────┐ │
│ │ Git Diff │ │ Change │ │ Doc Target │ │
│ │ Analyzer │ │ Classifier │ │ Identifier │ │
│ │ • Parse diff │ │ • New func? │ │ • JSDoc? │ │
│ │ • Extract │ │ • Modified? │ │ • README? │ │
│ │ hunks │ │ • Removed? │ │ • CHANGELOG? │ │
│ └───────────────┘ └───────────────┘ └───────────────┘ │
│ │ │ │ │
│ └──────────────────┼──────────────────┘ │
│ ▼ │
│ ┌─────────────────────┐ │
│ │ AI Doc Generator │ │
│ │ • Build context │ │
│ │ • Call Kiro │ │
│ │ • Parse response │ │
│ └─────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────┐ │
│ │ Doc Applier │ │
│ │ • Merge updates │ │
│ │ • Preserve manual │ │
│ │ • Write files │ │
│ └─────────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
Data Flow: JSDoc Update
1. Code Change Detected
┌─────────────────────────────────────────────────────────────────┐
│ src/services/user.ts: │
│ │
│ - async create(data: CreateUserDto) { │
│ + async create(data: CreateUserDto, options?: CreateOptions) { │
│ return this.db.insert(data); │
│ } │
└─────────────────────────────────────────────────────────────────┘
│
▼
2. Change Classification
┌─────────────────────────────────────────────────────────────────┐
│ Change Type: MODIFIED_SIGNATURE │
│ Function: create │
│ Changes: │
│ - Added parameter: options?: CreateOptions │
│ Documentation Impact: │
│ - Update @param for new parameter │
│ - Review @example if it uses this function │
└─────────────────────────────────────────────────────────────────┘
│
▼
3. Existing Doc Analysis
┌─────────────────────────────────────────────────────────────────┐
│ Current JSDoc: │
│ /** │
│ * Creates a new user. │
│ * @param data - User creation payload │
│ * @returns The created user │
│ */ │
│ │
│ Missing: @param options documentation │
└─────────────────────────────────────────────────────────────────┘
│
▼
4. Generate Update
┌─────────────────────────────────────────────────────────────────┐
│ Updated JSDoc: │
│ /** │
│ * Creates a new user. │
│ * @param data - User creation payload │
│ * @param options - Optional creation configuration │
│ * @param options.skipValidation - Skip email validation │
│ * @returns The created user │
│ */ │
└─────────────────────────────────────────────────────────────────┘
Key Interfaces
// Change detection
interface CodeChange {
file: string;
type: 'added' | 'modified' | 'deleted';
functions: FunctionChange[];
classes: ClassChange[];
}
interface FunctionChange {
name: string;
changeType: 'new' | 'signature_changed' | 'body_changed' | 'removed';
oldSignature?: string;
newSignature?: string;
oldDoc?: string;
}
// Documentation targets
interface DocUpdate {
target: 'jsdoc' | 'readme' | 'changelog';
file: string;
location: {
startLine: number;
endLine: number;
} | 'append';
content: string;
operation: 'insert' | 'replace' | 'delete';
}
// Configuration
interface DocGeneratorConfig {
targets: ('jsdoc' | 'readme' | 'changelog')[];
jsdoc: {
style: 'jsdoc' | 'tsdoc';
includeExamples: boolean;
includeReturns: boolean;
includeSince: boolean;
};
readme: {
apiSection: string; // "## API Reference"
autoUpdate: boolean;
};
changelog: {
format: 'keepachangelog' | 'conventional';
unreleased: boolean;
};
}
Technology Choices
| Component | Technology | Rationale |
|---|---|---|
| Hook Runtime | Bun | Fast TypeScript execution |
| Git Operations | simple-git | Reliable diff parsing |
| AST Parsing | @typescript-eslint/parser | Accurate code analysis |
| Doc Generation | Kiro CLI | AI-powered content |
| Markdown Parsing | remark | README manipulation |
Phased Implementation Guide
Phase 1: Change Detection (Days 1-2)
Goal: Detect and classify code changes from git diff.
Tasks:
- Set up PostToolUse hook for
writetool - Run
git diffon the changed file - Parse diff to extract changed functions
- Classify changes (new, modified, deleted)
- Log classification results
Hints:
- Use
git diff HEAD -- <file>for uncommitted changes - Parse unified diff format with regex or library
- Focus on function/class level, not line level
Starter Code:
import simpleGit from 'simple-git';
async function analyzeChanges(filePath: string): Promise<CodeChange> {
const git = simpleGit();
const diff = await git.diff(['HEAD', '--', filePath]);
// Parse diff to extract function changes
const changes = parseDiff(diff);
return {
file: filePath,
type: determineChangeType(changes),
functions: extractFunctionChanges(changes),
classes: extractClassChanges(changes),
};
}
Phase 2: JSDoc Generation (Days 3-4)
Goal: Generate or update JSDoc comments for changed functions.
Tasks:
- Read the source file and parse to AST
- Identify functions that need documentation
- Build prompts for AI doc generation
- Generate JSDoc content via Kiro
- Insert/update docs in source file
Hints:
- Use TypeScript compiler API for accurate AST
- Preserve existing manual documentation when possible
- Format JSDoc with consistent indentation
Prompt Template:
const prompt = `
Generate JSDoc documentation for this TypeScript function.
Function:
\`\`\`typescript
${functionCode}
\`\`\`
Requirements:
- Include @param for each parameter with type and description
- Include @returns with type and description
- Include @throws if function can throw
- Include brief @example if helpful
- Keep description concise (1-2 sentences)
Output ONLY the JSDoc comment block (no code).
`;
Phase 3: README Updates (Days 5-6)
Goal: Keep README API sections synchronized with code.
Tasks:
- Parse README to find API documentation section
- Compare documented API with actual exports
- Generate updates for changed/new exports
- Apply updates while preserving structure
- Handle missing API sections gracefully
Hints:
- Use remark to parse and manipulate markdown
- Look for conventional sections like “## API” or “## Methods”
- Create section if it doesn’t exist
README Section Detection:
function findApiSection(markdown: string): { start: number; end: number } | null {
const lines = markdown.split('\n');
let start = -1;
let end = lines.length;
for (let i = 0; i < lines.length; i++) {
if (lines[i].match(/^##\s+(API|Methods|Reference)/i)) {
start = i;
} else if (start !== -1 && lines[i].match(/^##\s+/)) {
end = i;
break;
}
}
return start === -1 ? null : { start, end };
}
Phase 4: CHANGELOG Generation (Day 7)
Goal: Automatically generate CHANGELOG entries.
Tasks:
- Parse CHANGELOG.md to find [Unreleased] section
- Classify changes (Added, Changed, Deprecated, Removed, Fixed)
- Generate human-readable entries for each change
- Append to appropriate section
- Avoid duplicate entries
Hints:
- Follow Keep a Changelog format (keepachangelog.com)
- Check for existing similar entries before adding
- Date entries only on release, not during development
CHANGELOG Format:
## [Unreleased]
### Added
- `findByEmail()` method for email-based user lookups
### Changed
- `create()` now accepts optional `CreateOptions` parameter
- `update()` validates email format before updating
### Deprecated
- `findOne()` is deprecated, use `findById()` instead
### Removed
- `legacyCreate()` method removed
### Fixed
- Fixed race condition in `delete()` method
Testing Strategy
Unit Tests
describe('DocGenerator', () => {
describe('parseDiff', () => {
it('identifies new functions', () => {
const diff = `
+ async newMethod(): Promise<void> {
+ // implementation
+ }`;
const changes = parseDiff(diff);
expect(changes.functions).toContainEqual({
name: 'newMethod',
changeType: 'new',
});
});
it('identifies modified signatures', () => {
const diff = `
- async create(data: Data) {
+ async create(data: Data, options?: Options) {`;
const changes = parseDiff(diff);
expect(changes.functions[0].changeType).toBe('signature_changed');
});
});
describe('generateJSDoc', () => {
it('includes all parameters', async () => {
const func = 'async create(name: string, age: number): Promise<User>';
const doc = await generateJSDoc(func);
expect(doc).toContain('@param name');
expect(doc).toContain('@param age');
});
});
});
Integration Tests
describe('Full Pipeline', () => {
it('updates JSDoc when function changes', async () => {
// 1. Write initial file
await writeFile('src/test-service.ts', `
export function greet(name: string) {
return \`Hello, \${name}\`;
}
`);
// 2. Simulate hook trigger
await runDocGenerator('src/test-service.ts');
// 3. Verify JSDoc was added
const content = await readFile('src/test-service.ts');
expect(content).toContain('/**');
expect(content).toContain('@param name');
});
});
Manual Verification Checklist
# 1. Create a new function
echo 'export function newFunc(x: number): string { return x.toString(); }' >> src/utils.ts
# 2. Trigger Kiro to modify the file
kiro-cli --print "Add a docstring to newFunc in src/utils.ts"
# 3. Verify hook ran
# Check for documentation in the file
# 4. Verify README updated
# Check README.md for new function listing
# 5. Verify CHANGELOG entry
# Check CHANGELOG.md [Unreleased] section
Common Pitfalls and Debugging
Pitfall 1: Overwriting Manual Documentation
Symptom: Carefully crafted human docs get replaced with AI-generated ones
Prevention:
// Check for manual override marker
function shouldPreserveDoc(existingDoc: string): boolean {
// Markers that indicate human curation
const preserveMarkers = [
'@manual',
'@human-written',
'DO NOT AUTO-UPDATE',
];
return preserveMarkers.some(m => existingDoc.includes(m));
}
Pitfall 2: Git Diff Parsing Errors
Symptom: Hook crashes on complex diffs
Debugging:
# Save raw diff for inspection
git diff HEAD -- src/file.ts > /tmp/raw-diff.txt
# Test parsing separately
bun run parse-diff.ts < /tmp/raw-diff.txt
# Handle edge cases:
# - Binary files
# - Renamed files
# - Empty diffs
Pitfall 3: README Structure Corruption
Symptom: README formatting breaks after update
Prevention:
// Validate markdown structure before writing
import { unified } from 'unified';
import remarkParse from 'remark-parse';
import remarkStringify from 'remark-stringify';
async function safeMarkdownUpdate(original: string, updates: string): string {
// Parse both
const tree = unified().use(remarkParse).parse(updates);
// Validate structure
if (!isValidMarkdown(tree)) {
throw new Error('Generated markdown is invalid');
}
return unified().use(remarkStringify).stringify(tree);
}
Pitfall 4: CHANGELOG Duplicates
Symptom: Same entry appears multiple times
Prevention:
function isDuplicate(existing: string[], newEntry: string): boolean {
// Normalize and compare
const normalized = newEntry.toLowerCase().replace(/[^a-z0-9]/g, '');
return existing.some(e =>
e.toLowerCase().replace(/[^a-z0-9]/g, '') === normalized
);
}
Extensions and Challenges
Extension 1: API Documentation Website
Generate a full documentation website using TypeDoc:
# After JSDoc is in place
npx typedoc src/index.ts --out docs/
# Integrate into build process
npm run build && npm run docs
Extension 2: Documentation Coverage Report
Track what percentage of exports are documented:
Documentation Coverage Report:
┌─────────────────────────────────────────────────────────────────┐
│ File │ Exports │ Documented │ Coverage │
├───────────────────────────┼─────────┼────────────┼─────────────┤
│ src/services/user.ts │ 8 │ 8 │ 100% │
│ src/services/order.ts │ 12 │ 10 │ 83% │
│ src/utils/format.ts │ 5 │ 3 │ 60% │
├───────────────────────────┼─────────┼────────────┼─────────────┤
│ Total │ 25 │ 21 │ 84% │
└─────────────────────────────────────────────────────────────────┘
Extension 3: Multi-Language Support
Extend beyond TypeScript to Python, Go, etc.:
const docStyles: Record<Language, DocStyle> = {
typescript: { format: 'jsdoc', comment: '/**' },
python: { format: 'docstring', comment: '"""' },
go: { format: 'godoc', comment: '//' },
rust: { format: 'rustdoc', comment: '///' },
};
Extension 4: Interactive Approval
Add a review step before applying changes:
┌─────────────────────────────────────────────────────────────────┐
│ PROPOSED DOCUMENTATION UPDATES │
├─────────────────────────────────────────────────────────────────┤
│ │
│ [1] src/services/user.ts - Add JSDoc for create() │
│ Preview: /** Creates a new user. @param data... │
│ │
│ [2] README.md - Update API section │
│ Preview: Added create() method documentation │
│ │
│ [3] CHANGELOG.md - Add entry │
│ Preview: ### Added - create() method for user creation │
│ │
├─────────────────────────────────────────────────────────────────┤
│ Apply changes? [a]ll / [s]elect / [n]one │
└─────────────────────────────────────────────────────────────────┘
Extension 5: Documentation Linting
Validate generated documentation against style guide:
interface DocLintRule {
name: string;
validate: (doc: string) => { valid: boolean; message?: string };
}
const rules: DocLintRule[] = [
{
name: 'description-period',
validate: (doc) => ({
valid: doc.endsWith('.'),
message: 'Descriptions should end with a period',
}),
},
{
name: 'param-description',
validate: (doc) => ({
valid: !doc.match(/@param \w+ -?\s*$/m),
message: 'All @param must have descriptions',
}),
},
];
Real-World Connections
Industry Practices
Documentation automation is used by:
- Stripe: Auto-generates API reference from OpenAPI specs
- AWS: Uses doc-as-code for SDK documentation
- Microsoft: AI-assisted IntelliSense documentation
- Vercel: Automated README updates in Next.js
Production Considerations
| Concern | Solution |
|---|---|
| Quality assurance | Human review before release |
| Localization | AI can translate to other languages |
| Versioning | Docs versioned alongside code |
| Deprecation | Auto-flag deprecated API in docs |
| Search | Index generated docs for search |
Metrics That Matter
Track documentation health:
Documentation Metrics Dashboard:
┌─────────────────────────────────────────────────────────────────┐
│ Coverage: 84% ████████░░ │
│ Freshness: 97% █████████░ (docs updated within 24h of code)│
│ Completeness: 72% ███████░░░ (all params documented) │
│ Examples: 45% ████░░░░░░ (functions with @example) │
└─────────────────────────────────────────────────────────────────┘
Self-Assessment Checklist
Knowledge Verification
- Can you explain the git diff format and how to parse it?
- What are the different documentation layers and their purposes?
- Why is incremental update better than full regeneration?
- What JSDoc tags are essential for function documentation?
- How does Keep a Changelog format work?
Implementation Verification
- Hook triggers on code file changes
- Git diffs are correctly parsed and classified
- JSDoc is generated for new functions
- Existing documentation is preserved when appropriate
- README API sections stay synchronized
Quality Verification
- Generated docs accurately describe the code
- Formatting is consistent with project style
- Human-written documentation is never lost
- CHANGELOG entries are meaningful, not mechanical
Integration Verification
- Hook integrates seamlessly with normal Kiro workflow
- Performance is acceptable (< 15 seconds)
- Errors are handled gracefully
- Configuration allows customization
Summary
Building a documentation generator teaches you:
- Git Diff Analysis: Understanding code changes at a semantic level
- Multi-Target Documentation: Updating JSDoc, README, and CHANGELOG together
- Incremental Updates: Surgical documentation changes instead of regeneration
- Quality Preservation: Respecting and preserving human-written content
The techniques you have learned here - parsing diffs, classifying changes, and generating targeted updates - apply far beyond documentation. The same pattern works for code review summaries, release notes, and any workflow that reacts to code changes.
Next Project: P24-secret-scanner-hook.md - Security scanning with PreToolUse blocking hooks