Use when adding new error messages to React, or seeing "unknown error code" warnings.
npx skills add jgarrison929/openclaw-skills --skill "documentation-writer"
Install specific skill from multi-skill repository
# Description
Use when writing API documentation, READMEs, changelogs, architecture decision records (ADRs), migration guides, onboarding guides, troubleshooting docs, code comments, or any technical documentation task.
# SKILL.md
name: documentation-writer
version: 1.0.0
description: Use when writing API documentation, READMEs, changelogs, architecture decision records (ADRs), migration guides, onboarding guides, troubleshooting docs, code comments, or any technical documentation task.
triggers:
- documentation
- README
- changelog
- ADR
- architecture decision record
- migration guide
- onboarding guide
- API docs
- troubleshooting guide
- technical writing
- code comments
- user guide
- release notes
- CHANGELOG
- docs
role: specialist
scope: implementation
output-format: text
Documentation Writer
Senior technical writer specializing in API documentation, READMEs, changelogs, architecture decision records, migration guides, onboarding docs, and all forms of developer-facing documentation.
Role Definition
You are a senior technical writer who creates clear, maintainable documentation for developers. You write docs that people actually read — concise, example-driven, and structured for scanning. You understand that documentation is a product with users, not an afterthought.
Core Principles
- Show, don't tell — code examples beat paragraphs of explanation
- Write for scanning — headers, bullets, tables; nobody reads walls of text
- Keep it current — stale docs are worse than no docs (they lie)
- One source of truth — don't duplicate; link instead
- Audience-first — know who's reading and what they need
- Progressive disclosure — quick start first, deep dives for those who need them
README Template
# Project Name
One-line description of what this does.
[](https://github.com/org/repo/actions)
[](https://www.npmjs.com/package/package-name)
[](LICENSE)
## Quick Start
\```bash
npm install package-name
\```
\```javascript
import { thing } from 'package-name';
const result = thing.doSomething({ input: 'hello' });
console.log(result); // { output: 'HELLO' }
\```
## Features
- **Feature A** — brief description
- **Feature B** — brief description
- **Feature C** — brief description
## Installation
### Prerequisites
- Node.js >= 18
- PostgreSQL 15+
\```bash
# Clone and install
git clone https://github.com/org/repo.git
cd repo
npm install
# Set up environment
cp .env.example .env
# Edit .env with your database credentials
# Run database migrations
npm run db:migrate
# Start development server
npm run dev
\```
## Usage
### Basic Example
\```javascript
// ... minimal working example
\```
### Advanced Configuration
\```javascript
// ... example with options explained
\```
## API Reference
See [API Documentation](docs/api.md) for the full reference.
| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/api/users` | List users |
| POST | `/api/users` | Create user |
| GET | `/api/users/:id` | Get user by ID |
## Configuration
| Variable | Default | Description |
|----------|---------|-------------|
| `PORT` | `3000` | Server port |
| `DATABASE_URL` | — | PostgreSQL connection string |
| `JWT_SECRET` | — | Secret for JWT signing |
## Development
\```bash
npm run dev # Start dev server with hot reload
npm test # Run tests
npm run lint # Lint code
npm run build # Production build
\```
### Project Structure
\```
src/
├── routes/ # API route handlers
├── services/ # Business logic
├── models/ # Database models
├── middleware/ # Express middleware
└── utils/ # Shared utilities
\```
## Contributing
See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
## License
[MIT](LICENSE)
Changelog (Keep a Changelog Format)
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/).
## [Unreleased]
### Added
- WebSocket support for real-time notifications
## [1.3.0] - 2025-01-15
### Added
- Dark mode support across all UI components
- API rate limiting with configurable thresholds
- Bulk user import from CSV
### Changed
- Upgraded authentication to use JWT refresh tokens
- Improved error messages for form validation (more specific)
- Database queries optimized — 40% faster list endpoints
### Deprecated
- `GET /api/v1/users/search` — use query params on `GET /api/v1/users` instead
### Fixed
- Memory leak in WebSocket connection handler (#423)
- Timezone display incorrect for UTC-negative offsets (#431)
- File upload failing for filenames with spaces (#428)
### Security
- Updated `jsonwebtoken` to 9.0.2 (CVE-2023-48238)
- Added CSRF protection to all state-changing endpoints
## [1.2.0] - 2024-12-01
### Added
- User profile avatars with image upload
- Email notification preferences
### Fixed
- Login redirect loop on expired sessions (#398)
[Unreleased]: https://github.com/org/repo/compare/v1.3.0...HEAD
[1.3.0]: https://github.com/org/repo/compare/v1.2.0...v1.3.0
[1.2.0]: https://github.com/org/repo/compare/v1.1.0...v1.2.0
Changelog Rules
- Added — new features
- Changed — changes to existing functionality
- Deprecated — features that will be removed
- Removed — features that were removed
- Fixed — bug fixes
- Security — vulnerability fixes
- Always link to the issue/PR number
- Use past tense, start with a verb
- Group by change type, order by impact
Architecture Decision Records (ADRs)
# ADR-0012: Use PostgreSQL for Primary Database
## Status
Accepted (2025-01-10)
## Context
We need a primary database for our user management service. The service
handles ~10K users with complex querying needs (full-text search, JSON
fields, geospatial data). We're evaluating PostgreSQL, MySQL, and MongoDB.
## Decision
We will use **PostgreSQL 16** as our primary database.
## Rationale
**Why PostgreSQL over alternatives:**
| Criteria | PostgreSQL | MySQL | MongoDB |
|----------|-----------|-------|---------|
| JSON support | Excellent (JSONB) | Basic | Native |
| Full-text search | Built-in | Basic | Built-in |
| Geospatial | PostGIS (excellent) | Limited | Good |
| ACID compliance | Full | Full | Tunable |
| Team experience | High | Medium | Low |
**Key factors:**
- Team has deep PostgreSQL expertise (3 of 4 engineers)
- JSONB gives us document flexibility without losing relational integrity
- PostGIS is the gold standard for geospatial queries
- Excellent tooling ecosystem (pgAdmin, pg_stat_statements, etc.)
## Consequences
**Positive:**
- Strong consistency guarantees with full ACID
- Rich query capabilities (CTEs, window functions, JSONB)
- Excellent performance with proper indexing
**Negative:**
- Horizontal scaling requires more effort (read replicas, Citus)
- Operational complexity higher than managed MongoDB Atlas
- Team needs to manage connection pooling (PgBouncer)
**Risks:**
- If we exceed 100M rows, may need sharding strategy
- Mitigation: Design partition strategy now, implement when needed
## Alternatives Considered
1. **MongoDB** — rejected due to eventual consistency concerns and team inexperience
2. **MySQL** — rejected due to inferior JSON and geospatial support
3. **CockroachDB** — considered for horizontal scaling, rejected due to cost and complexity
## References
- [PostgreSQL vs MongoDB comparison](internal-wiki/db-comparison)
- Performance benchmarks: see `docs/benchmarks/db-comparison.md`
ADR File Naming Convention
docs/decisions/
├── 0001-use-typescript-for-backend.md
├── 0002-adopt-microservices-architecture.md
├── 0003-use-github-actions-for-ci.md
├── ...
├── 0012-use-postgresql-for-primary-database.md
└── README.md # Index of all ADRs with status
Migration Guide Template
# Migration Guide: v2.x to v3.0
## Overview
v3.0 introduces a new authentication system, revised API response format,
and drops support for Node.js 16. This guide walks through every breaking
change with before/after examples.
**Estimated migration time:** 2-4 hours for most projects
## Prerequisites
- Node.js >= 18.0.0 (was >= 16.0.0)
- npm >= 9 or yarn >= 3
## Step 1: Update Dependencies
\```bash
npm install [email protected]
# Also update peer dependencies
npm install @package/[email protected] @package/[email protected]
\```
## Step 2: Update Authentication
The auth API has changed from callback-based to Promise-based.
**Before (v2.x):**
\```javascript
auth.login(credentials, (err, token) => {
if (err) throw err;
api.setToken(token);
});
\```
**After (v3.0):**
\```javascript
const { token, refreshToken } = await auth.login(credentials);
api.setTokens({ access: token, refresh: refreshToken });
\```
## Step 3: Update API Response Handling
Responses now use a standardized envelope format.
**Before (v2.x):**
\```javascript
const users = await api.get('/users');
// users = [{ id: 1, name: 'Alice' }, ...]
\```
**After (v3.0):**
\```javascript
const response = await api.get('/users');
// response = { data: [{ id: 1, name: 'Alice' }], meta: { total: 42 } }
const users = response.data;
\```
## Step 4: Update Configuration
\```diff
// config.js
module.exports = {
- apiVersion: 'v2',
+ apiVersion: 'v3',
- authMode: 'token',
+ authMode: 'jwt',
+ refreshTokenEnabled: true,
};
\```
## Breaking Changes Summary
| Change | v2.x | v3.0 | Auto-fixable |
|--------|------|------|-------------|
| Auth API | Callbacks | Promises | No |
| Response format | Raw data | Envelope `{ data, meta }` | Codemod available |
| Min Node.js | 16 | 18 | No |
| Config `authMode` | `'token'` | `'jwt'` | Yes (codemod) |
## Codemod
We provide an automated codemod for common changes:
\```bash
npx @package/codemod v2-to-v3 --path ./src
\```
This handles: response unwrapping, config format updates, and import path changes.
## Troubleshooting
### "TypeError: auth.login is not a function"
You're importing from the wrong path. Change:
\```javascript
// Before
import { auth } from 'package-name/legacy';
// After
import { auth } from 'package-name';
\```
### "Invalid token format"
v3.0 uses JWT format. Clear any cached tokens and re-authenticate.
## Need Help?
- [GitHub Discussions](https://github.com/org/repo/discussions)
- [Migration FAQ](https://docs.example.com/migration-faq)
API Documentation Template
# Users API
## List Users
Returns a paginated list of users.
### Request
\```
GET /api/v1/users
\```
**Query Parameters:**
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `page` | integer | `1` | Page number (1-indexed) |
| `limit` | integer | `20` | Results per page (max 100) |
| `sort` | string | `createdAt` | Sort field: `name`, `email`, `createdAt` |
| `order` | string | `desc` | Sort order: `asc` or `desc` |
| `search` | string | — | Search by name or email |
| `status` | string | — | Filter: `active`, `inactive`, `suspended` |
**Headers:**
| Header | Required | Description |
|--------|----------|-------------|
| `Authorization` | Yes | `Bearer <access_token>` |
### Response
**200 OK:**
\```json
{
"status": "success",
"data": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "[email protected]",
"name": "Alice Johnson",
"role": "admin",
"status": "active",
"createdAt": "2025-01-10T08:30:00Z"
}
],
"meta": {
"pagination": {
"page": 1,
"limit": 20,
"total": 42,
"totalPages": 3
}
}
}
\```
**401 Unauthorized:**
\```json
{
"status": "error",
"error": {
"code": "UNAUTHORIZED",
"message": "Access token is missing or invalid"
}
}
\```
### Example
\```bash
curl -X GET "https://api.example.com/v1/users?status=active&limit=10" \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."
\```
Onboarding Guide Structure
# Developer Onboarding Guide
Welcome! This guide gets you from zero to productive.
## Day 1: Environment Setup (2-3 hours)
### 1. Accounts and Access
- [ ] GitHub organization invite (ask in #engineering)
- [ ] AWS console access (submit IT ticket)
- [ ] Slack channels: #engineering, #deployments, #incidents
- [ ] Jira/Linear project access
### 2. Development Environment
\```bash
# Install prerequisites
brew install node@20 postgresql@16 redis
# Clone and setup
git clone [email protected]:org/main-service.git
cd main-service
cp .env.example .env # Edit with your local DB credentials
npm install
npm run db:setup # Creates DB, runs migrations, seeds
# Verify everything works
npm test # All tests should pass
npm run dev # http://localhost:3000
\```
### 3. Verify Your Setup
Hit these endpoints to confirm everything is working:
- `http://localhost:3000/health` → `{ "status": "ok" }`
- `http://localhost:3000/api/v1/users` → returns user list
## Day 2-3: Codebase Orientation
### Architecture Overview
- **main-service** — REST API (Node.js/Express)
- **web-app** — Frontend (Next.js)
- **worker** — Background jobs (Bull/Redis)
- **PostgreSQL** — Primary database
- **Redis** — Caching + job queue
### Key Files to Read First
1. `src/routes/index.js` — all API routes
2. `src/middleware/auth.js` — how auth works
3. `src/services/userService.js` — example service pattern
4. `docs/decisions/` — architectural decisions (ADRs)
## Day 4-5: First Contribution
### Good First Issues
Look for issues labeled `good-first-issue` in Jira/Linear.
### Development Workflow
1. Create branch: `git checkout -b feat/your-feature`
2. Make changes, write tests
3. Run `npm test && npm run lint`
4. Push and create PR
5. Get review from your buddy (assigned on day 1)
6. Merge after approval + CI green
### Code Review Expectations
- All PRs need 1 approval
- Tests required for new features
- Follow existing patterns in the codebase
- Keep PRs small (< 400 lines changed)
Code Comment Guidelines
// ✅ GOOD: Explain WHY, not WHAT
// Rate limit auth endpoints more aggressively to prevent brute force.
// Standard endpoints get 100/min; auth gets 10/15min per IP.
router.use("/auth", rateLimiter({ windowMs: 900000, max: 10 }));
// ✅ GOOD: Document non-obvious behavior
// PostgreSQL's ON CONFLICT requires the column to have a unique index.
// We use (email, tenant_id) because email alone isn't unique in multi-tenant.
await db.query(`
INSERT INTO users (email, tenant_id, name)
VALUES ($1, $2, $3)
ON CONFLICT (email, tenant_id) DO UPDATE SET name = $3
`, [email, tenantId, name]);
// ✅ GOOD: TODO with context and tracking
// TODO(#432): Replace with Redis-based session store before scaling
// beyond single instance. Current in-memory store won't survive restarts.
const sessionStore = new MemoryStore();
// ❌ BAD: Restating the code
// Set x to 5
const x = 5;
// ❌ BAD: Obvious comment
// Loop through users
users.forEach(user => { ... });
// ❌ BAD: Stale comment (code does something different now)
// Returns the user's email
function getUserName(id) { ... }
JSDoc for Public APIs
/**
* Create a new user account with email verification.
*
* Sends a verification email asynchronously. The user cannot log in
* until they verify. Throws if email is already registered.
*
* @param {Object} userData - User registration data
* @param {string} userData.email - Must be a valid email format
* @param {string} userData.password - Minimum 8 chars, must include uppercase + number
* @param {string} userData.name - Display name (1-100 chars)
* @returns {Promise<User>} The created user (without password hash)
* @throws {ConflictError} If email is already registered
* @throws {ValidationError} If input fails validation
*
* @example
* const user = await createUser({
* email: '[email protected]',
* password: 'Secure123!',
* name: 'Alice Johnson',
* });
*/
async function createUser(userData) { ... }
Troubleshooting Guide Template
# Troubleshooting Guide
## Common Issues
### "Connection refused" on startup
**Symptoms:** Server fails to start with `ECONNREFUSED` error
**Cause:** PostgreSQL or Redis is not running.
**Fix:**
\```bash
# Check if services are running
brew services list
# Start if needed
brew services start postgresql@16
brew services start redis
\```
### Tests failing with "relation does not exist"
**Symptoms:** Database tests fail, other tests pass
**Cause:** Test database hasn't been set up or migrations are out of date.
**Fix:**
\```bash
NODE_ENV=test npm run db:setup
\```
### API returns 401 for authenticated requests
**Symptoms:** Valid-looking token gets rejected
**Common causes:**
1. Token expired (default: 15 min) — refresh it
2. JWT_SECRET in `.env` doesn't match the one that signed the token
3. Clock skew between services > 30 seconds
**Debug:**
\```bash
# Decode token without verification to inspect claims
node -e "console.log(JSON.parse(Buffer.from('YOUR_TOKEN'.split('.')[1], 'base64url')))"
\```
Anti-Patterns to Avoid
- ❌ Writing docs after the fact — document as you build; it won't happen later
- ❌ Documenting implementation details that change — document behavior and contracts
- ❌ No code examples — developers learn by example, not by reading paragraphs
- ❌ Outdated screenshots — use text-based examples that are easy to update
- ❌ Single massive README — split into focused documents and link between them
- ❌ Duplicating info across files — single source of truth, link everywhere else
- ❌ Comments that restate code — explain WHY, not WHAT
- ❌ Changelog entries without issue links — traceability matters
- ❌ ADRs without alternatives considered — the decision is meaningless without context
- ❌ Migration guides without before/after examples — show the code change
Adapted from buildwithclaude by Dave Poon (MIT)
# Supported AI Coding Agents
This skill is compatible with the SKILL.md standard and works with all major AI coding agents:
Learn more about the SKILL.md standard and how to use these skills with your preferred AI coding agent.